Beispiel #1
0
    static void PF_walkmove()
    {
        edict_t ent  = PROG_TO_EDICT(pr_global_struct.self);
        float   yaw  = G_FLOAT(q_shared.OFS_PARM0);
        float   dist = G_FLOAT(q_shared.OFS_PARM1);

        if (((int)ent.v.flags & (q_shared.FL_ONGROUND | q_shared.FL_FLY | q_shared.FL_SWIM)) == 0)
        {
            G_FLOAT((float)0);
            return;
        }

        yaw = (float)(yaw * Math.PI * 2.0 / 360.0);

        v3f move;

        move.x = (float)Math.Cos(yaw) * dist;
        move.y = (float)Math.Sin(yaw) * dist;
        move.z = 0;

        // save program state, because SV_movestep may call other progs
        dfunction_t oldf    = pr_xfunction;
        int         oldself = pr_global_struct.self;

        G_FLOAT((float)(SV_movestep(ent, ref move, true) ? 1 : 0));

        // restore program state
        pr_xfunction          = oldf;
        pr_global_struct.self = oldself;
    }
Beispiel #2
0
        /*
         * ====================
         * PR_LeaveFunction
         * ====================
         */
        static int PR_LeaveFunction()
        {
            int i, c;

            if (pr_depth <= 0)
            {
                sys_linux.Sys_Error("prog stack underflow");
            }

            // restore locals from the stack
            c = pr_xfunction.locals;
            localstack_used -= c;
            if (localstack_used < 0)
            {
                PR_RunError("PR_ExecuteProgram: locals stack underflow\n");
            }

            for (i = 0; i < c; i++)
            {
                pr_globals_write(pr_xfunction.parm_start + i, localstack[localstack_used + i]);
            }

            // up stack
            pr_depth--;
            pr_xfunction = pr_stack[pr_depth].f;
            return(pr_stack[pr_depth].s);
        }
Beispiel #3
0
    public static int PR_LeaveFunction()
    {
        if (pr_depth <= 0)
        {
            Sys_Error("prog stack underflow");
        }

        // restore locals from the stack
        int c = pr_xfunction.locals;

        localstack_used -= c;
        if (localstack_used < 0)
        {
            PR_RunError("PR_ExecuteProgram: locals stack underflow\n");
        }

        for (int i = 0; i < c; i++)
        {
            Set(pr_xfunction.parm_start + i, localstack[localstack_used + i]);
            //((int*)pr_globals)[pr_xfunction->parm_start + i] = localstack[localstack_used + i];
        }

        // up stack
        pr_depth--;
        pr_xfunction = pr_stack[pr_depth].f;

        return(pr_stack[pr_depth].s);
    }
Beispiel #4
0
    public static void PR_Profile_f()
    {
        if (pr_functions == null)
        {
            return;
        }

        dfunction_t best;
        int         num = 0;

        do
        {
            int max = 0;
            best = null;
            for (int i = 0; i < pr_functions.Length; i++)
            {
                dfunction_t f = pr_functions[i];
                if (f.profile > max)
                {
                    max  = f.profile;
                    best = f;
                }
            }
            if (best != null)
            {
                if (num < 10)
                {
                    Con_Printf("{0,7} {1}\n", best.profile, GetString(best.s_name));
                }
                num++;
                best.profile = 0;
            }
        } while (best != null);
    }
    static unsafe string PR_ValueString(etype_t type, void *val)
    {
        string result;

        type &= (etype_t) ~q_shared.DEF_SAVEGLOBAL;

        switch (type)
        {
        case etype_t.ev_string:
            result = GetString(*(int *)val);
            break;

        case etype_t.ev_entity:
            result = "entity " + NUM_FOR_EDICT(PROG_TO_EDICT(*(int *)val));
            break;

        case etype_t.ev_function:
            dfunction_t f = pr_functions[*(int *)val];
            result = GetString(f.s_name) + "()";
            break;

        case etype_t.ev_field:
            ddef_t def = ED_FieldAtOfs(*(int *)val);
            result = "." + GetString(def.s_name);
            break;

        case etype_t.ev_void:
            result = "void";
            break;

        case etype_t.ev_float:
            result = (*(float *)val).ToString("F1", CultureInfo.InvariantCulture.NumberFormat);
            break;

        case etype_t.ev_vector:
            result = String.Format(CultureInfo.InvariantCulture.NumberFormat,
                                   "{0,5:F1} {1,5:F1} {2,5:F1}", ((float *)val)[0], ((float *)val)[1], ((float *)val)[2]);
            break;

        case etype_t.ev_pointer:
            result = "pointer";
            break;

        default:
            result = "bad type " + type.ToString();
            break;
        }

        return(result);
    }
    static unsafe string PR_UglyValueString(etype_t type, eval_t *val)
    {
        type &= (etype_t) ~q_shared.DEF_SAVEGLOBAL;
        string result;

        switch (type)
        {
        case etype_t.ev_string:
            result = GetString(val->_string);
            break;

        case etype_t.ev_entity:
            result = NUM_FOR_EDICT(PROG_TO_EDICT(val->edict)).ToString();
            break;

        case etype_t.ev_function:
            dfunction_t f = pr_functions[val->function];
            result = GetString(f.s_name);
            break;

        case etype_t.ev_field:
            ddef_t def = ED_FieldAtOfs(val->_int);
            result = GetString(def.s_name);
            break;

        case etype_t.ev_void:
            result = "void";
            break;

        case etype_t.ev_float:
            result = val->_float.ToString("F6", CultureInfo.InvariantCulture.NumberFormat);
            break;

        case etype_t.ev_vector:
            result = String.Format(CultureInfo.InvariantCulture.NumberFormat,
                                   "{0:F6} {1:F6} {2:F6}", val->vector[0], val->vector[1], val->vector[2]);
            break;

        default:
            result = "bad type " + type.ToString();
            break;
        }

        return(result);
    }
Beispiel #7
0
        /*
         * ============================================================================
         * PR_ExecuteProgram
         *
         * The interpretation main loop
         * ============================================================================
         */

        /*
         * ====================
         * PR_EnterFunction
         *
         * Returns the new program statement counter
         * ====================
         */
        public static int PR_EnterFunction(dfunction_t f)
        {
            int i, j, c, o;

            pr_stack[pr_depth].s = pr_xstatement;
            pr_stack[pr_depth].f = pr_xfunction;
            pr_depth++;
            if (pr_depth >= MAX_STACK_DEPTH)
            {
                PR_RunError("stack overflow");
            }

            // save off any locals that the new function steps on
            c = f.locals;
            if (localstack_used + c > LOCALSTACK_SIZE)
            {
                PR_RunError("PR_ExecuteProgram: locals stack overflow\n");
            }

            for (i = 0; i < c; i++)
            {
                localstack[localstack_used + i] = cast_int(pr_globals_read(f.parm_start + i));
            }
            localstack_used += c;

            // copy parameters
            o = f.parm_start;
            for (i = 0; i < f.numparms; i++)
            {
                for (j = 0; j < f.parm_size[i]; j++)
                {
                    pr_globals_write(o, pr_globals_read(OFS_PARM0 + i * 3 + j));
                    o++;
                }
            }

            pr_xfunction = f;
            return(f.first_statement - 1);       // offset the s++
        }
Beispiel #8
0
    public static unsafe int PR_EnterFunction(dfunction_t f)
    {
        pr_stack[pr_depth].s = pr_xstatement;
        pr_stack[pr_depth].f = pr_xfunction;
        pr_depth++;
        if (pr_depth >= q_shared.MAX_STACK_DEPTH)
        {
            PR_RunError("stack overflow");
        }

        // save off any locals that the new function steps on
        int c = f.locals;

        if (localstack_used + c > q_shared.LOCALSTACK_SIZE)
        {
            PR_RunError("PR_ExecuteProgram: locals stack overflow\n");
        }

        for (int i = 0; i < c; i++)
        {
            localstack[localstack_used + i] = *(int *)Get(f.parm_start + i);
        }
        localstack_used += c;

        // copy parameters
        int o = f.parm_start;

        for (int i = 0; i < f.numparms; i++)
        {
            for (int j = 0; j < f.parm_size[i]; j++)
            {
                Set(o, *(int *)Get(q_shared.OFS_PARM0 + i * 3 + j));
                o++;
            }
        }

        pr_xfunction = f;
        return(f.first_statement - 1);   // offset the s++
    }
Beispiel #9
0
    public static void PR_StackTrace()
    {
        if (pr_depth == 0)
        {
            Con_Printf("<NO STACK>\n");
            return;
        }

        pr_stack[pr_depth].f = pr_xfunction;
        for (int i = pr_depth; i >= 0; i--)
        {
            dfunction_t f = pr_stack[i].f;

            if (f == null)
            {
                Con_Printf("<NO FUNCTION>\n");
            }
            else
            {
                Con_Printf("{0,12} : {1}\n", GetString(f.s_file), GetString(f.s_name));
            }
        }
    }
Beispiel #10
0
        /*
        ====================
        PR_LeaveFunction
        ====================
        */
        static int PR_LeaveFunction()
        {
            int		i, c;

            if (pr_depth <= 0)
                sys_linux.Sys_Error ("prog stack underflow");

            // restore locals from the stack
            c = pr_xfunction.locals;
            localstack_used -= c;
            if (localstack_used < 0)
                PR_RunError ("PR_ExecuteProgram: locals stack underflow\n");

            for (i = 0; i < c; i++)
                pr_globals_write(pr_xfunction.parm_start + i, localstack[localstack_used + i]);

            // up stack
            pr_depth--;
            pr_xfunction = pr_stack[pr_depth].f;
            return pr_stack[pr_depth].s;
        }
Beispiel #11
0
        /*
        ====================
        PR_ExecuteProgram
        ====================
        */
        public static void PR_ExecuteProgram(dfunction_t fnum)
        {
            /*	        eval_t	*a, *b, *c;*/
            int			    s;
            dstatement_t    st;
            dfunction_t     newf;
            /*dfunction_t	*f;*/
            int		        runaway;
            int		        i;
            edict_t	        ed;
            int		        exitdepth;
            //eval_t	*ptr;

            /*if (!fnum || fnum >= progs.numfunctions)
            {
                if (pr_global_struct.self)
                    ED_Print (PROG_TO_EDICT(pr_global_struct.self));
                Host_Error ("PR_ExecuteProgram: NULL function");
            }

            f = &pr_functions[fnum];*/

            runaway = 100000;
            pr_trace = false;

            // make a stack frame
            exitdepth = pr_depth;

            s = PR_EnterFunction (fnum);

            while (true)
            {
                s++;	// next statement

                st = pr_statements[s];

                if (--runaway == 0)
                    PR_RunError("runaway loop error");

                pr_xfunction.profile++;
                pr_xstatement = s;

                if (pr_trace)
                    PR_PrintStatement(st);

                if (st.c == 7505)
                    st.c = st.c;

                bool eval;
                switch ((opcode_t)st.op)
                {
                    case opcode_t.OP_ADD_F:
                        //c->_float = a->_float + b->_float;
                        pr_globals_write(st.c, (double)(cast_float(pr_globals_read(st.a)) + cast_float(pr_globals_read(st.b))));
                        break;
                    case opcode_t.OP_ADD_V:
                        /*c->vector[0] = a->vector[0] + b->vector[0];
                        c->vector[1] = a->vector[1] + b->vector[1];
                        c->vector[2] = a->vector[2] + b->vector[2];*/
                        pr_globals_write(st.c, (double)(cast_float(pr_globals_read(st.a)) + cast_float(pr_globals_read(st.b))));
                        pr_globals_write(st.c + 1, (double)(cast_float(pr_globals_read(st.a + 1)) + cast_float(pr_globals_read(st.b + 1))));
                        pr_globals_write(st.c + 2, (double)(cast_float(pr_globals_read(st.a + 2)) + cast_float(pr_globals_read(st.b + 2))));
                        break;

                    case opcode_t.OP_SUB_F:
                        //c->_float = a->_float - b->_float;
                        pr_globals_write(st.c, (double)(cast_float(pr_globals_read(st.a)) - cast_float(pr_globals_read(st.b))));
                        break;
                    case opcode_t.OP_SUB_V:
                        /*c->vector[0] = a->vector[0] - b->vector[0];
                        c->vector[1] = a->vector[1] - b->vector[1];
                        c->vector[2] = a->vector[2] - b->vector[2];*/
                        pr_globals_write(st.c, (double)(cast_float(pr_globals_read(st.a)) - cast_float(pr_globals_read(st.b))));
                        pr_globals_write(st.c + 1, (double)(cast_float(pr_globals_read(st.a + 1)) - cast_float(pr_globals_read(st.b + 1))));
                        pr_globals_write(st.c + 2, (double)(cast_float(pr_globals_read(st.a + 2)) - cast_float(pr_globals_read(st.b + 2))));
                        break;

                    case opcode_t.OP_MUL_F:
                        //c->_float = a->_float * b->_float;
                        pr_globals_write(st.c, (double)(cast_float(pr_globals_read(st.a)) * cast_float(pr_globals_read(st.b))));
                        break;
                    case opcode_t.OP_MUL_V:
                        /*c->_float = a->vector[0] * b->vector[0]
                                + a->vector[1] * b->vector[1]
                                + a->vector[2] * b->vector[2];*/
                        double res = (double)(cast_float(pr_globals_read(st.a)) * cast_float(pr_globals_read(st.b))
                                                + cast_float(pr_globals_read(st.a + 1)) * cast_float(pr_globals_read(st.b + 1))
                                                + cast_float(pr_globals_read(st.a + 2)) * cast_float(pr_globals_read(st.b + 2)));
                        pr_globals_write(st.c, res);
                        break;
                    /*case opcode_t.OP_MUL_FV:
                        c->vector[0] = a->_float * b->vector[0];
                        c->vector[1] = a->_float * b->vector[1];
                        c->vector[2] = a->_float * b->vector[2];
                        break;*/
                    case opcode_t.OP_MUL_VF:
                        /*c->vector[0] = b->_float * a->vector[0];
                        c->vector[1] = b->_float * a->vector[1];
                        c->vector[2] = b->_float * a->vector[2];*/
                        pr_globals_write(st.c, (double)(cast_float(pr_globals_read(st.b)) * cast_float(pr_globals_read(st.a))));
                        pr_globals_write(st.c + 1, (double)(cast_float(pr_globals_read(st.b + 1)) * cast_float(pr_globals_read(st.a + 1))));
                        pr_globals_write(st.c + 2, (double)(cast_float(pr_globals_read(st.b + 2)) * cast_float(pr_globals_read(st.a + 2))));
                        break;

                    case opcode_t.OP_BITAND:
                        //c->_float = (int)a->_float & (int)b->_float;
                        pr_globals_write(st.c, (double)((int)cast_float(pr_globals_read(st.a)) & (int)cast_float(pr_globals_read(st.b))));
                        break;

                    case opcode_t.OP_BITOR:
                        //c->_float = (int)a->_float | (int)b->_float;
                        pr_globals_write(st.c, (double)((int)cast_float(pr_globals_read(st.a)) | (int)cast_float(pr_globals_read(st.b))));
                        break;

                    case opcode_t.OP_GE:
                        //c->_float = a->_float >= b->_float;
                        pr_globals_write(st.c, (double)(cast_float(pr_globals_read(st.a)) >= cast_float(pr_globals_read(st.b)) ? 1 : 0));
                        break;
                    case opcode_t.OP_LE:
                        //c->_float = a->_float <= b->_float;
                        pr_globals_write(st.c, (double)(cast_float(pr_globals_read(st.a)) <= cast_float(pr_globals_read(st.b)) ? 1 : 0));
                        break;
                    case opcode_t.OP_GT:
                        //c->_float = a->_float > b->_float;
                        pr_globals_write(st.c, (double)(cast_float(pr_globals_read(st.a)) > cast_float(pr_globals_read(st.b)) ? 1 : 0));
                        break;
                    case opcode_t.OP_LT:
                        //c->_float = a->_float < b->_float;
                        pr_globals_write(st.c, (double)(cast_float(pr_globals_read(st.a)) < cast_float(pr_globals_read(st.b)) ? 1 : 0));
                        break;
                    case opcode_t.OP_AND:
                        //c->_float = a->_float && b->_float;
                        pr_globals_write(st.c, (double)(cast_float(pr_globals_read(st.a)) != 0 && cast_float(pr_globals_read(st.b)) != 0 ? 1 : 0));
                        break;
                    case opcode_t.OP_OR:
                        //c->_float = a->_float || b->_float;
                        pr_globals_write(st.c, (double)(cast_float(pr_globals_read(st.a)) != 0 || cast_float(pr_globals_read(st.b)) != 0 ? 1 : 0));
                        break;

                    case opcode_t.OP_NOT_F:
                        //c->_float = !a->_float;
                        pr_globals_write(st.c, (double)(cast_float(pr_globals_read(st.a)) == 0 ? 1 : 0));
                        break;
                    case opcode_t.OP_NOT_S:
                        //c->_float = !a->string || !pr_strings[a->string];
                        int astring = cast_int(pr_globals_read(st.a));
                        pr_globals_write(st.c, (double)(((astring == 0) || (pr_string(astring) == null)) ? 1 : 0));
                        break;
                    case opcode_t.OP_NOT_FNC:
                        //c->_float = !a->function;
                        pr_globals_write(st.c, (double)(cast_int(pr_globals_read(st.a)) == 0 ? 1 : 0));
                        break;
                    case opcode_t.OP_NOT_ENT:
                        //c->_float = (PROG_TO_EDICT(a->edict) == sv.edicts);
                        pr_globals_write(st.c, (double)(PROG_TO_EDICT(cast_int(pr_globals_read(st.a))) == server.sv.edicts[0] ? 1 : 0));
                        break;

                    case opcode_t.OP_EQ_F:
                        //c->_float = a->_float == b->_float;
                        pr_globals_write(st.c, (double)(cast_float(pr_globals_read(st.a)) == cast_float(pr_globals_read(st.b)) ? 1 : 0));
                        break;
                    case opcode_t.OP_EQ_V:
                        /*c->_float = (a->vector[0] == b->vector[0]) &&
                                    (a->vector[1] == b->vector[1]) &&
                                    (a->vector[2] == b->vector[2]);*/
                        eval = (cast_float(pr_globals_read(st.a)) == cast_float(pr_globals_read(st.b))) &&
                               (cast_float(pr_globals_read(st.a + 1)) == cast_float(pr_globals_read(st.b + 1))) &&
                               (cast_float(pr_globals_read(st.a + 2)) == cast_float(pr_globals_read(st.b + 2)));
                        pr_globals_write(st.c, (double)(eval ? 1 : 0));
                        break;
                    case opcode_t.OP_EQ_S:
                        //c->_float = !strcmp(pr_strings+a->string,pr_strings+b->string);
                        pr_globals_write(st.c, (double)(pr_string(cast_int(pr_globals_read(st.a))).CompareTo(pr_string(cast_int(pr_globals_read(st.b)))) == 0 ? 1 : 0));
                        break;

                    case opcode_t.OP_NE_V:
                        /*c->_float = (a->vector[0] != b->vector[0]) ||
                                    (a->vector[1] != b->vector[1]) ||
                                    (a->vector[2] != b->vector[2]);*/
                        eval = (cast_float(pr_globals_read(st.a)) != cast_float(pr_globals_read(st.b))) ||
                               (cast_float(pr_globals_read(st.a + 1)) != cast_float(pr_globals_read(st.b + 1))) ||
                               (cast_float(pr_globals_read(st.a + 2)) != cast_float(pr_globals_read(st.b + 2)));
                        pr_globals_write(st.c, (double)(eval ? 1 : 0));
                        break;

                    //==================
                    case opcode_t.OP_STORE_F:
                    case opcode_t.OP_STORE_ENT:
                    case opcode_t.OP_STORE_FLD:		// integers
                    case opcode_t.OP_STORE_S:
                    case opcode_t.OP_STORE_FNC:		// pointers
                        pr_globals_write(st.b, pr_globals_read(st.a));
                        break;
                    case opcode_t.OP_STORE_V:
                        /*b->vector[0] = a->vector[0];
                        b->vector[1] = a->vector[1];
                        b->vector[2] = a->vector[2];*/
                        pr_globals_write(st.b, (double)cast_float(pr_globals_read(st.a)));
                        pr_globals_write(st.b + 1, (double)cast_float(pr_globals_read(st.a + 1)));
                        pr_globals_write(st.b + 2, (double)cast_float(pr_globals_read(st.a + 2)));
                        break;

                    case opcode_t.OP_STOREP_F:
                    case opcode_t.OP_STOREP_ENT:
                    case opcode_t.OP_STOREP_FLD:		// integers
                    case opcode_t.OP_STOREP_S:
                    case opcode_t.OP_STOREP_FNC:		// pointers
                        //ptr = (eval_t*)((byte*)sv.edicts + b->_int);
                        //ptr->_int = a->_int;
                        writeptr(cast_int(pr_globals_read(st.b)), cast_int(pr_globals_read(st.a)));
                        break;
                    case opcode_t.OP_STOREP_V:
                        //ptr = (eval_t*)((byte*)sv.edicts + b->_int);
                        //ptr->vector[0] = a->vector[0];
                        //ptr->vector[1] = a->vector[1];
                        //ptr->vector[2] = a->vector[2];
                        writeptr(cast_int(pr_globals_read(st.b)), cast_int(pr_globals_read(st.a)));
                        writeptr(cast_int(pr_globals_read(st.b)) + 1, cast_int(pr_globals_read(st.a + 1)));
                        writeptr(cast_int(pr_globals_read(st.b)) + 2, cast_int(pr_globals_read(st.a + 2)));
                        break;

                    case opcode_t.OP_ADDRESS:
                        ed = PROG_TO_EDICT(cast_int(pr_globals_read(st.a)));
                        if (ed == server.sv.edicts[0] && server.sv.state == server.server_state_t.ss_active)
                            PR_RunError ("assignment to world entity");
                        //c->_int = (byte *)((int *)&ed->v + b->_int) - (byte *)sv.edicts;
                        pr_globals_write(st.c, ed.index * pr_edict_size + 96 + cast_int(pr_globals_read(st.b)) * 4);
                        break;

                    case opcode_t.OP_LOAD_F:
                    case opcode_t.OP_LOAD_FLD:
                    case opcode_t.OP_LOAD_ENT:
                    case opcode_t.OP_LOAD_S:
                    case opcode_t.OP_LOAD_FNC:
                        ed = PROG_TO_EDICT(cast_int(pr_globals_read(st.a)));
                        //a = (eval_t *)((int *)&ed->v + b->_int);
                        //c->_int = a->_int;
                        pr_globals_write(st.c, cast_int(readptr(ed.index * pr_edict_size + 96 + cast_int(pr_globals_read(st.b)) * 4)));
                        break;

                    case opcode_t.OP_LOAD_V:
                        ed = PROG_TO_EDICT(cast_int(pr_globals_read(st.a)));
                        //a = (eval_t *)((int *)&ed->v + b->_int);
                        //c->vector[0] = a->vector[0];
                        //c->vector[1] = a->vector[1];
                        //c->vector[2] = a->vector[2];
                        pr_globals_write(st.c, (double)cast_float(readptr(ed.index * pr_edict_size + 96 + cast_int(pr_globals_read(st.b)) * 4)));
                        pr_globals_write(st.c + 1, (double)cast_float(readptr(ed.index * pr_edict_size + 96 + (cast_int(pr_globals_read(st.b)) + 1) * 4)));
                        pr_globals_write(st.c + 2, (double)cast_float(readptr(ed.index * pr_edict_size + 96 + (cast_int(pr_globals_read(st.b)) + 2) * 4)));
                        break;

                    //==================

                    case opcode_t.OP_IFNOT:
                        if (cast_int(pr_globals_read(st.a)) == 0)
                            s += st.b - 1;	// offset the s++
                        break;

                    case opcode_t.OP_IF:
                        if (cast_int(pr_globals_read(st.a)) != 0)
                            s += st.b - 1;	// offset the s++
                        break;

                    case opcode_t.OP_GOTO:
                        s += st.a - 1;	// offset the s++
                        break;

                    case opcode_t.OP_CALL0:
                    case opcode_t.OP_CALL1:
                    case opcode_t.OP_CALL2:
                    case opcode_t.OP_CALL3:
                    case opcode_t.OP_CALL4:
                    case opcode_t.OP_CALL5:
                    case opcode_t.OP_CALL6:
                    case opcode_t.OP_CALL7:
                    case opcode_t.OP_CALL8:
                        pr_argc = st.op - (int)opcode_t.OP_CALL0;
                        int afunction = cast_int(pr_globals_read(st.a));
                        if (afunction == 0)
                            PR_RunError("NULL function");

                        newf = pr_functions[afunction];

                        if (newf.first_statement < 0)
                        {	// negative statements are built in functions
                            i = -newf.first_statement;
                            if (i >= pr_numbuiltins)
                                PR_RunError("Bad builtin call number");
                            pr_builtins[i]();
                            break;
                        }

                        s = PR_EnterFunction(newf);
                        break;

                    case opcode_t.OP_DONE:
                    case opcode_t.OP_RETURN:
                        pr_globals_write(OFS_RETURN, pr_globals_read(st.a));
                        pr_globals_write(OFS_RETURN + 1, pr_globals_read(st.a + 1));
                        pr_globals_write(OFS_RETURN + 2, pr_globals_read(st.a + 2));

                        s = PR_LeaveFunction();
                        if (pr_depth == exitdepth)
                            return;		// all done
                        break;

                    case opcode_t.OP_STATE:
                        ed = PROG_TO_EDICT(pr_global_struct[0].self);
                        ed.v.nextthink = pr_global_struct[0].time + 0.1;
                        if (cast_float(pr_globals_read(st.a)) != ed.v.frame)
                        {
                            ed.v.frame = cast_float(pr_globals_read(st.a));
                        }
                        ed.v.think = cast_int(pr_globals_read(st.b));
                        break;

                    default:
                        break;
                }
            }
        }
Beispiel #12
0
        /*
        ============================================================================
        PR_ExecuteProgram

        The interpretation main loop
        ============================================================================
        */
        /*
        ====================
        PR_EnterFunction

        Returns the new program statement counter
        ====================
        */
        public static int PR_EnterFunction(dfunction_t f)
        {
            int i, j, c, o;

            pr_stack[pr_depth].s = pr_xstatement;
            pr_stack[pr_depth].f = pr_xfunction;
            pr_depth++;
            if (pr_depth >= MAX_STACK_DEPTH)
                PR_RunError("stack overflow");

            // save off any locals that the new function steps on
            c = f.locals;
            if (localstack_used + c > LOCALSTACK_SIZE)
                PR_RunError("PR_ExecuteProgram: locals stack overflow\n");

            for (i = 0; i < c; i++)
                localstack[localstack_used + i] = cast_int(pr_globals_read(f.parm_start + i));
            localstack_used += c;

            // copy parameters
            o = f.parm_start;
            for (i = 0; i < f.numparms; i++)
            {
                for (j = 0; j < f.parm_size[i]; j++)
                {
                    pr_globals_write(o, pr_globals_read(OFS_PARM0 + i * 3 + j));
                    o++;
                }
            }

            pr_xfunction = f;
            return f.first_statement - 1;	// offset the s++
        }
Beispiel #13
0
        /*
         * ====================
         * PR_ExecuteProgram
         * ====================
         */
        public static void PR_ExecuteProgram(dfunction_t fnum)
        {
/*	        eval_t	*a, *b, *c;*/
            int          s;
            dstatement_t st;
            dfunction_t  newf;
            /*dfunction_t	*f;*/
            int     runaway;
            int     i;
            edict_t ed;
            int     exitdepth;

            //eval_t	*ptr;

            /*if (!fnum || fnum >= progs.numfunctions)
             * {
             *      if (pr_global_struct.self)
             *              ED_Print (PROG_TO_EDICT(pr_global_struct.self));
             *      Host_Error ("PR_ExecuteProgram: NULL function");
             * }
             *
             * f = &pr_functions[fnum];*/

            runaway  = 100000;
            pr_trace = false;

            // make a stack frame
            exitdepth = pr_depth;

            s = PR_EnterFunction(fnum);

            while (true)
            {
                s++;            // next statement

                st = pr_statements[s];

                if (--runaway == 0)
                {
                    PR_RunError("runaway loop error");
                }

                pr_xfunction.profile++;
                pr_xstatement = s;

                if (pr_trace)
                {
                    PR_PrintStatement(st);
                }

                if (st.c == 7505)
                {
                    st.c = st.c;
                }

                bool eval;
                switch ((opcode_t)st.op)
                {
                case opcode_t.OP_ADD_F:
                    //c->_float = a->_float + b->_float;
                    pr_globals_write(st.c, (double)(cast_float(pr_globals_read(st.a)) + cast_float(pr_globals_read(st.b))));
                    break;

                case opcode_t.OP_ADD_V:
                    /*c->vector[0] = a->vector[0] + b->vector[0];
                    *  c->vector[1] = a->vector[1] + b->vector[1];
                    *  c->vector[2] = a->vector[2] + b->vector[2];*/
                    pr_globals_write(st.c, (double)(cast_float(pr_globals_read(st.a)) + cast_float(pr_globals_read(st.b))));
                    pr_globals_write(st.c + 1, (double)(cast_float(pr_globals_read(st.a + 1)) + cast_float(pr_globals_read(st.b + 1))));
                    pr_globals_write(st.c + 2, (double)(cast_float(pr_globals_read(st.a + 2)) + cast_float(pr_globals_read(st.b + 2))));
                    break;

                case opcode_t.OP_SUB_F:
                    //c->_float = a->_float - b->_float;
                    pr_globals_write(st.c, (double)(cast_float(pr_globals_read(st.a)) - cast_float(pr_globals_read(st.b))));
                    break;

                case opcode_t.OP_SUB_V:
                    /*c->vector[0] = a->vector[0] - b->vector[0];
                    *  c->vector[1] = a->vector[1] - b->vector[1];
                    *  c->vector[2] = a->vector[2] - b->vector[2];*/
                    pr_globals_write(st.c, (double)(cast_float(pr_globals_read(st.a)) - cast_float(pr_globals_read(st.b))));
                    pr_globals_write(st.c + 1, (double)(cast_float(pr_globals_read(st.a + 1)) - cast_float(pr_globals_read(st.b + 1))));
                    pr_globals_write(st.c + 2, (double)(cast_float(pr_globals_read(st.a + 2)) - cast_float(pr_globals_read(st.b + 2))));
                    break;

                case opcode_t.OP_MUL_F:
                    //c->_float = a->_float * b->_float;
                    pr_globals_write(st.c, (double)(cast_float(pr_globals_read(st.a)) * cast_float(pr_globals_read(st.b))));
                    break;

                case opcode_t.OP_MUL_V:
                    /*c->_float = a->vector[0] * b->vector[0]
                     + a->vector[1] * b->vector[1]
                     + a->vector[2] * b->vector[2];*/
                    double res = (double)(cast_float(pr_globals_read(st.a)) * cast_float(pr_globals_read(st.b))
                                          + cast_float(pr_globals_read(st.a + 1)) * cast_float(pr_globals_read(st.b + 1))
                                          + cast_float(pr_globals_read(st.a + 2)) * cast_float(pr_globals_read(st.b + 2)));
                    pr_globals_write(st.c, res);
                    break;

                /*case opcode_t.OP_MUL_FV:
                 *  c->vector[0] = a->_float * b->vector[0];
                 *  c->vector[1] = a->_float * b->vector[1];
                 *  c->vector[2] = a->_float * b->vector[2];
                 *  break;*/
                case opcode_t.OP_MUL_VF:
                    /*c->vector[0] = b->_float * a->vector[0];
                    *  c->vector[1] = b->_float * a->vector[1];
                    *  c->vector[2] = b->_float * a->vector[2];*/
                    pr_globals_write(st.c, (double)(cast_float(pr_globals_read(st.b)) * cast_float(pr_globals_read(st.a))));
                    pr_globals_write(st.c + 1, (double)(cast_float(pr_globals_read(st.b + 1)) * cast_float(pr_globals_read(st.a + 1))));
                    pr_globals_write(st.c + 2, (double)(cast_float(pr_globals_read(st.b + 2)) * cast_float(pr_globals_read(st.a + 2))));
                    break;

                case opcode_t.OP_BITAND:
                    //c->_float = (int)a->_float & (int)b->_float;
                    pr_globals_write(st.c, (double)((int)cast_float(pr_globals_read(st.a)) & (int)cast_float(pr_globals_read(st.b))));
                    break;

                case opcode_t.OP_BITOR:
                    //c->_float = (int)a->_float | (int)b->_float;
                    pr_globals_write(st.c, (double)((int)cast_float(pr_globals_read(st.a)) | (int)cast_float(pr_globals_read(st.b))));
                    break;

                case opcode_t.OP_GE:
                    //c->_float = a->_float >= b->_float;
                    pr_globals_write(st.c, (double)(cast_float(pr_globals_read(st.a)) >= cast_float(pr_globals_read(st.b)) ? 1 : 0));
                    break;

                case opcode_t.OP_LE:
                    //c->_float = a->_float <= b->_float;
                    pr_globals_write(st.c, (double)(cast_float(pr_globals_read(st.a)) <= cast_float(pr_globals_read(st.b)) ? 1 : 0));
                    break;

                case opcode_t.OP_GT:
                    //c->_float = a->_float > b->_float;
                    pr_globals_write(st.c, (double)(cast_float(pr_globals_read(st.a)) > cast_float(pr_globals_read(st.b)) ? 1 : 0));
                    break;

                case opcode_t.OP_LT:
                    //c->_float = a->_float < b->_float;
                    pr_globals_write(st.c, (double)(cast_float(pr_globals_read(st.a)) < cast_float(pr_globals_read(st.b)) ? 1 : 0));
                    break;

                case opcode_t.OP_AND:
                    //c->_float = a->_float && b->_float;
                    pr_globals_write(st.c, (double)(cast_float(pr_globals_read(st.a)) != 0 && cast_float(pr_globals_read(st.b)) != 0 ? 1 : 0));
                    break;

                case opcode_t.OP_OR:
                    //c->_float = a->_float || b->_float;
                    pr_globals_write(st.c, (double)(cast_float(pr_globals_read(st.a)) != 0 || cast_float(pr_globals_read(st.b)) != 0 ? 1 : 0));
                    break;

                case opcode_t.OP_NOT_F:
                    //c->_float = !a->_float;
                    pr_globals_write(st.c, (double)(cast_float(pr_globals_read(st.a)) == 0 ? 1 : 0));
                    break;

                case opcode_t.OP_NOT_S:
                    //c->_float = !a->string || !pr_strings[a->string];
                    int astring = cast_int(pr_globals_read(st.a));
                    pr_globals_write(st.c, (double)(((astring == 0) || (pr_string(astring) == null)) ? 1 : 0));
                    break;

                case opcode_t.OP_NOT_FNC:
                    //c->_float = !a->function;
                    pr_globals_write(st.c, (double)(cast_int(pr_globals_read(st.a)) == 0 ? 1 : 0));
                    break;

                case opcode_t.OP_NOT_ENT:
                    //c->_float = (PROG_TO_EDICT(a->edict) == sv.edicts);
                    pr_globals_write(st.c, (double)(PROG_TO_EDICT(cast_int(pr_globals_read(st.a))) == server.sv.edicts[0] ? 1 : 0));
                    break;

                case opcode_t.OP_EQ_F:
                    //c->_float = a->_float == b->_float;
                    pr_globals_write(st.c, (double)(cast_float(pr_globals_read(st.a)) == cast_float(pr_globals_read(st.b)) ? 1 : 0));
                    break;

                case opcode_t.OP_EQ_V:
                    /*c->_float = (a->vector[0] == b->vector[0]) &&
                     *          (a->vector[1] == b->vector[1]) &&
                     *          (a->vector[2] == b->vector[2]);*/
                    eval = (cast_float(pr_globals_read(st.a)) == cast_float(pr_globals_read(st.b))) &&
                           (cast_float(pr_globals_read(st.a + 1)) == cast_float(pr_globals_read(st.b + 1))) &&
                           (cast_float(pr_globals_read(st.a + 2)) == cast_float(pr_globals_read(st.b + 2)));
                    pr_globals_write(st.c, (double)(eval ? 1 : 0));
                    break;

                case opcode_t.OP_EQ_S:
                    //c->_float = !strcmp(pr_strings+a->string,pr_strings+b->string);
                    pr_globals_write(st.c, (double)(pr_string(cast_int(pr_globals_read(st.a))).CompareTo(pr_string(cast_int(pr_globals_read(st.b)))) == 0 ? 1 : 0));
                    break;

                case opcode_t.OP_NE_V:
                    /*c->_float = (a->vector[0] != b->vector[0]) ||
                     *          (a->vector[1] != b->vector[1]) ||
                     *          (a->vector[2] != b->vector[2]);*/
                    eval = (cast_float(pr_globals_read(st.a)) != cast_float(pr_globals_read(st.b))) ||
                           (cast_float(pr_globals_read(st.a + 1)) != cast_float(pr_globals_read(st.b + 1))) ||
                           (cast_float(pr_globals_read(st.a + 2)) != cast_float(pr_globals_read(st.b + 2)));
                    pr_globals_write(st.c, (double)(eval ? 1 : 0));
                    break;

                //==================
                case opcode_t.OP_STORE_F:
                case opcode_t.OP_STORE_ENT:
                case opcode_t.OP_STORE_FLD:             // integers
                case opcode_t.OP_STORE_S:
                case opcode_t.OP_STORE_FNC:             // pointers
                    pr_globals_write(st.b, pr_globals_read(st.a));
                    break;

                case opcode_t.OP_STORE_V:
                    /*b->vector[0] = a->vector[0];
                    *  b->vector[1] = a->vector[1];
                    *  b->vector[2] = a->vector[2];*/
                    pr_globals_write(st.b, (double)cast_float(pr_globals_read(st.a)));
                    pr_globals_write(st.b + 1, (double)cast_float(pr_globals_read(st.a + 1)));
                    pr_globals_write(st.b + 2, (double)cast_float(pr_globals_read(st.a + 2)));
                    break;

                case opcode_t.OP_STOREP_F:
                case opcode_t.OP_STOREP_ENT:
                case opcode_t.OP_STOREP_FLD:                    // integers
                case opcode_t.OP_STOREP_S:
                case opcode_t.OP_STOREP_FNC:                    // pointers
                    //ptr = (eval_t*)((byte*)sv.edicts + b->_int);
                    //ptr->_int = a->_int;
                    writeptr(cast_int(pr_globals_read(st.b)), cast_int(pr_globals_read(st.a)));
                    break;

                case opcode_t.OP_STOREP_V:
                    //ptr = (eval_t*)((byte*)sv.edicts + b->_int);
                    //ptr->vector[0] = a->vector[0];
                    //ptr->vector[1] = a->vector[1];
                    //ptr->vector[2] = a->vector[2];
                    writeptr(cast_int(pr_globals_read(st.b)), cast_int(pr_globals_read(st.a)));
                    writeptr(cast_int(pr_globals_read(st.b)) + 1, cast_int(pr_globals_read(st.a + 1)));
                    writeptr(cast_int(pr_globals_read(st.b)) + 2, cast_int(pr_globals_read(st.a + 2)));
                    break;

                case opcode_t.OP_ADDRESS:
                    ed = PROG_TO_EDICT(cast_int(pr_globals_read(st.a)));
                    if (ed == server.sv.edicts[0] && server.sv.state == server.server_state_t.ss_active)
                    {
                        PR_RunError("assignment to world entity");
                    }
                    //c->_int = (byte *)((int *)&ed->v + b->_int) - (byte *)sv.edicts;
                    pr_globals_write(st.c, ed.index * pr_edict_size + 96 + cast_int(pr_globals_read(st.b)) * 4);
                    break;

                case opcode_t.OP_LOAD_F:
                case opcode_t.OP_LOAD_FLD:
                case opcode_t.OP_LOAD_ENT:
                case opcode_t.OP_LOAD_S:
                case opcode_t.OP_LOAD_FNC:
                    ed = PROG_TO_EDICT(cast_int(pr_globals_read(st.a)));
                    //a = (eval_t *)((int *)&ed->v + b->_int);
                    //c->_int = a->_int;
                    pr_globals_write(st.c, cast_int(readptr(ed.index * pr_edict_size + 96 + cast_int(pr_globals_read(st.b)) * 4)));
                    break;

                case opcode_t.OP_LOAD_V:
                    ed = PROG_TO_EDICT(cast_int(pr_globals_read(st.a)));
                    //a = (eval_t *)((int *)&ed->v + b->_int);
                    //c->vector[0] = a->vector[0];
                    //c->vector[1] = a->vector[1];
                    //c->vector[2] = a->vector[2];
                    pr_globals_write(st.c, (double)cast_float(readptr(ed.index * pr_edict_size + 96 + cast_int(pr_globals_read(st.b)) * 4)));
                    pr_globals_write(st.c + 1, (double)cast_float(readptr(ed.index * pr_edict_size + 96 + (cast_int(pr_globals_read(st.b)) + 1) * 4)));
                    pr_globals_write(st.c + 2, (double)cast_float(readptr(ed.index * pr_edict_size + 96 + (cast_int(pr_globals_read(st.b)) + 2) * 4)));
                    break;

                //==================

                case opcode_t.OP_IFNOT:
                    if (cast_int(pr_globals_read(st.a)) == 0)
                    {
                        s += st.b - 1;          // offset the s++
                    }
                    break;

                case opcode_t.OP_IF:
                    if (cast_int(pr_globals_read(st.a)) != 0)
                    {
                        s += st.b - 1;          // offset the s++
                    }
                    break;

                case opcode_t.OP_GOTO:
                    s += st.a - 1;      // offset the s++
                    break;

                case opcode_t.OP_CALL0:
                case opcode_t.OP_CALL1:
                case opcode_t.OP_CALL2:
                case opcode_t.OP_CALL3:
                case opcode_t.OP_CALL4:
                case opcode_t.OP_CALL5:
                case opcode_t.OP_CALL6:
                case opcode_t.OP_CALL7:
                case opcode_t.OP_CALL8:
                    pr_argc = st.op - (int)opcode_t.OP_CALL0;
                    int afunction = cast_int(pr_globals_read(st.a));
                    if (afunction == 0)
                    {
                        PR_RunError("NULL function");
                    }

                    newf = pr_functions[afunction];

                    if (newf.first_statement < 0)
                    {           // negative statements are built in functions
                        i = -newf.first_statement;
                        if (i >= pr_numbuiltins)
                        {
                            PR_RunError("Bad builtin call number");
                        }
                        pr_builtins[i]();
                        break;
                    }

                    s = PR_EnterFunction(newf);
                    break;

                case opcode_t.OP_DONE:
                case opcode_t.OP_RETURN:
                    pr_globals_write(OFS_RETURN, pr_globals_read(st.a));
                    pr_globals_write(OFS_RETURN + 1, pr_globals_read(st.a + 1));
                    pr_globals_write(OFS_RETURN + 2, pr_globals_read(st.a + 2));

                    s = PR_LeaveFunction();
                    if (pr_depth == exitdepth)
                    {
                        return;                 // all done
                    }
                    break;

                case opcode_t.OP_STATE:
                    ed             = PROG_TO_EDICT(pr_global_struct[0].self);
                    ed.v.nextthink = pr_global_struct[0].time + 0.1;
                    if (cast_float(pr_globals_read(st.a)) != ed.v.frame)
                    {
                        ed.v.frame = cast_float(pr_globals_read(st.a));
                    }
                    ed.v.think = cast_int(pr_globals_read(st.b));
                    break;

                default:
                    break;
                }
            }
        }
Beispiel #14
0
        /*
        ====================
        PR_ExecuteProgram
        ====================
        */
        public static void PR_ExecuteProgram(dfunction_t fnum)
        {
            /*	        eval_t	*a, *b, *c;*/
            int s;
            dstatement_t st;
            dstatement_t_alt st_;
            dfunction_t newf;
            /*dfunction_t	*f;*/
            int runaway;
            int i;
            edict_t ed;
            int exitdepth;
            eval_t ptr;
              //try{
            /*if (!fnum || fnum >= progs.numfunctions)
            {
                if (pr_global_struct.self)
                    ED_Print (PROG_TO_EDICT(pr_global_struct.self));
                Host_Error ("PR_ExecuteProgram: NULL function");
            }

            f = &pr_functions[fnum];*/

            runaway = 100000;
            pr_trace = true;

            // make a stack frame
            exitdepth = pr_depth;

            s = PR_EnterFunction(fnum);

            while (true)
            {
                s++; // next statement
                prNum++;

                st = pr_statements[s];
                st_ = new dstatement_t_alt(st);
                eval_t a = st_.a;
                eval_t b = st_.b;
                eval_t c = st_.c;

                if (--runaway == 0)
                    PR_RunError("runaway loop error");

                pr_xfunction.profile++;
                pr_xstatement = s;

                if (pr_trace)
                {
                    //PR_PrintStatement(st);
                    //Debug.WriteLine(string.Format("a {0}: {1} {2} {3}", st.a, pr_globals_read(st.a), pr_globals_read(st.a + 1), pr_globals_read(st.a + 2)));
                    //Debug.WriteLine(string.Format("b {0}: {1} {2} {3}", st.b, pr_globals_read(st.b), pr_globals_read(st.b + 1), pr_globals_read(st.b + 2)));
                    //Debug.WriteLine(string.Format("c {0}: {1} {2} {3}", st.c, pr_globals_read(st.c), pr_globals_read(st.c + 1), pr_globals_read(st.c + 2)));
                    //PR_StackTraceStr();
                }

                //Debug.WriteLine(string.Format("prNum: {0}", prNum));
                //Debug.WriteLine(string.Format("a: {0}", a, b, c));
                //Debug.WriteLine(string.Format("b: {1}", a, b, c));
                //Debug.WriteLine(string.Format("c: {2}", a, b, c));
                switch ((opcode_t)st.op)
                {
                    case opcode_t.OP_ADD_F:
                        c._float = a._float + b._float;
                        break;
                    case opcode_t.OP_ADD_V:
                        //var testWith = (float)a.vector[0] + (float)b.vector[0];
                        //var testWithout = a.vector[0] + b.vector[0];
                        //var testWithout2 = (float) (a.vector[0] + b.vector[0]);
                        //var testglv1 = (globalval)testWith;
                        //var testglv2 = (globalval)testWithout;
                        //var testglv3 = (globalval)testWithout2;
                        //var testWith4 = (globalval)((float)a.vector[0] + (float)b.vector[0]);
                        //var testWithout4 = (globalval)(a.vector[0] + b.vector[0]);
                        //var testWithout24 = (globalval)((float) (a.vector[0] + b.vector[0]));

                        c.vector[0] = a.vector[0] + b.vector[0];
                        c.vector[1] = a.vector[1] + b.vector[1];
                        c.vector[2] = a.vector[2] + b.vector[2];
                        break;

                    case opcode_t.OP_SUB_F:
                        c._float = a._float - b._float;
                        break;
                    case opcode_t.OP_SUB_V:
                        c.vector[0] = a.vector[0] - b.vector[0];
                        c.vector[1] = a.vector[1] - b.vector[1];
                        c.vector[2] = a.vector[2] - b.vector[2];
                        break;

                    case opcode_t.OP_MUL_F:
                        c._float = a._float * b._float;
                        break;
                    case opcode_t.OP_MUL_V:
                        c._float = a.vector[0] * b.vector[0]
                                + a.vector[1] * b.vector[1]
                                + a.vector[2] * b.vector[2];
                        break;
                    case opcode_t.OP_MUL_FV:
                        c.vector[0] = a._float * b.vector[0];
                        c.vector[1] = a._float * b.vector[1];
                        c.vector[2] = a._float * b.vector[2];
                        break;
                    case opcode_t.OP_MUL_VF:
                        c.vector[0] = b._float * a.vector[0];
                        c.vector[1] = b._float * a.vector[1];
                        c.vector[2] = b._float * a.vector[2];
                        break;
                    case opcode_t.OP_DIV_F:
                        c._float = a._float / b._float;
                        break;

                    case opcode_t.OP_BITAND:
                        c._float = (int)a._float & (int)b._float;
                        break;

                    case opcode_t.OP_BITOR:
                        c._float = (int)a._float | (int)b._float;
                        break;

                    case opcode_t.OP_GE:
                        c._float_b = a._float >= b._float;
                        break;
                    case opcode_t.OP_LE:
                        c._float_b = a._float <= b._float ;
                        break;
                    case opcode_t.OP_GT:
                        c._float_b = a._float > b._float;
                        break;
                    case opcode_t.OP_LT:
                        c._float_b = a._float < b._float ;
                        break;
                    case opcode_t.OP_AND:
                        c._float_b = a._float != 0 && b._float != 0 ;
                        break;
                    case opcode_t.OP_OR:
                        c._float_b = a._float != 0 || b._float != 0;
                        break;

                    case opcode_t.OP_NOT_F:
                        c._float_b = !a._float_b;
                        break;
                    case opcode_t.OP_NOT_S:
                        c._float_b = (a.@string == 0) || string.IsNullOrEmpty(pr_string(a.@string));
                        break;
                    case opcode_t.OP_NOT_FNC:
                        c._float_b = a.function == 0;
                        break;
                    case opcode_t.OP_NOT_ENT:
                        c._float_b = (PROG_TO_EDICT(a.edict) == server.sv.edicts[0]);
                        break;

                    case opcode_t.OP_EQ_F:
                        c._float_b = a._float == b._float;
                        break;
                    case opcode_t.OP_EQ_V:
                        c._float_b = (a.vector[0] == b.vector[0]) &&
                                    (a.vector[1] == b.vector[1]) &&
                                    (a.vector[2] == b.vector[2]);
                        break;
                    case opcode_t.OP_EQ_S:
                        c._float_b = pr_string(a.@string).CompareTo(pr_string(b.@string)) == 0;
                        break;
                    case   opcode_t. OP_EQ_E:
                       	c._float_b = a._int == b._int;
                        break;

                    case opcode_t.OP_NE_F:
                        c._float_b = a._float != b._float;
                        break;

                    case opcode_t.OP_NE_V:
                        c._float_b = (a.vector[0] != b.vector[0]) ||
                                    (a.vector[1] != b.vector[1]) ||
                                    (a.vector[2] != b.vector[2]);
                        break;

                    case opcode_t.OP_NE_S:
                        c._float = pr_string(a.@string).CompareTo(pr_string(b.@string));
                        break;

                    case opcode_t.OP_NE_E:
                        c._float_b = a._int != b._int;
                        break;

                    case opcode_t.OP_NE_FNC:
                        c._float_b = a.function != b.function;
                        break;

                        //==================
                    case opcode_t.OP_STORE_F:
                    case opcode_t.OP_STORE_ENT:
                    case opcode_t.OP_STORE_FLD: // integers
                    case opcode_t.OP_STORE_S:
                    case opcode_t.OP_STORE_FNC: // pointers
                        b._int = a._int;
                        break;
                    case opcode_t.OP_STORE_V:
                        //b.vector[0] = a.vector[0];
                        //TIODO: SOME NUMBERS ARE ALWASY NAN! NEED TO DO SOMETHING ELSE? ALWAYS STORE AS INT?
                        //b._int = a._int; // todo: fix properly, this is a work around for if there's a NaN - which acts differently in JS. not all float values can convert to int I guess...?
                        //maybe pass globalval instead of float?
                        // log out everythingh and compare to original quake?
                        // break point if NaN
                        // dont cast to float?

                        // COULD USE REFLECTION TO GET FIELDS DIRECTLY AND INTERACT WITH THEM
                        // and or use "dynamic" and skip the cast_float stuff
                        // eval_t can be a wrapper around, and globals funcs will get field Type info
                        b.vector[0] = a.vector[0];
                        b.vector[1] = a.vector[1];
                        b.vector[2] = a.vector[2];
                        break;

                    case opcode_t.OP_STOREP_F:
                    case opcode_t.OP_STOREP_ENT:
                    case opcode_t.OP_STOREP_FLD: // integers
                    case opcode_t.OP_STOREP_S:
                    case opcode_t.OP_STOREP_FNC: // pointers
                        //ptr = (eval_t*)((byte*)sv.edicts + b->_int);
                        //ptr->_int = a->_int;
                        //todo ptr = sv.edicts[b._int];
                        //ptr._int = a._int;

                        //var test = server.sv.edicts[b._int];
                        writeptr(b._int, a._int);
                        break;
                    case opcode_t.OP_STOREP_V:
                        //ptr = (eval_t*)((byte*)sv.edicts + b->_int);
                        //ptr->vector[0] = a->vector[0];
                        //ptr->vector[1] = a->vector[1];
                        //ptr->vector[2] = a->vector[2];

                        //ptr = getptr(b._int); //sv.edicts[b._int];
                        //ptr.vector[0] = a.vector[0] etc

                        writeptr(b._int, a.vector[0], 0);
                        writeptr(b._int, a.vector[1], 1);
                        writeptr(b._int, a.vector[2], 2);
                        break;

                    case opcode_t.OP_ADDRESS:
                        ed = PROG_TO_EDICT(a._int);
                        if (ed == server.sv.edicts[0] && server.sv.state == server.server_state_t.ss_active)
                            PR_RunError("assignment to world entity");
                        //c->_int = (byte *)((int *)&ed->v + b->_int) - (byte *)sv.edicts;
                        c._int = ed.index * pr_edict_size + 96 + b._int * 4;
                        break;

                    case opcode_t.OP_LOAD_F:
                    case opcode_t.OP_LOAD_FLD:
                    case opcode_t.OP_LOAD_ENT:
                    case opcode_t.OP_LOAD_S:
                    case opcode_t.OP_LOAD_FNC:
                        ed = PROG_TO_EDICT(a._int);
                        //a = (eval_t *)((int *)&ed->v + b->_int);
                        //c->_int = a->_int;
                        c._int = cast_int(readptr(ed.index * pr_edict_size + 96 + b._int * 4));
                        break;

                    case opcode_t.OP_LOAD_V:
                        ed = PROG_TO_EDICT(a.edict);
                        //a = (eval_t *)((int *)&ed->v + b->_int);
                        //c.vector[0] = a.vector[0];
                        //c.vector[1] = a.vector[1];
                        //c.vector[2] = a.vector[2];
                        c.vector[0] = cast_float(readptr(ed.index * pr_edict_size + 96 + b._int * 4));
                        c.vector[1] = cast_float(readptr(ed.index * pr_edict_size + 96 + (b._int + 1) * 4));
                        c.vector[2] = cast_float(readptr(ed.index * pr_edict_size + 96 + (b._int + 2) * 4));

                        break;

                        //==================

                    case opcode_t.OP_IFNOT:
                        if (a._int == 0)
                            s += st.b - 1; // offset the s++
                        break;

                    case opcode_t.OP_IF:
                        if (a._int != 0)
                            s += st.b - 1; // offset the s++
                        break;

                    case opcode_t.OP_GOTO:
                        s += st.a - 1; // offset the s++
                        break;

                    case opcode_t.OP_CALL0:
                    case opcode_t.OP_CALL1:
                    case opcode_t.OP_CALL2:
                    case opcode_t.OP_CALL3:
                    case opcode_t.OP_CALL4:
                    case opcode_t.OP_CALL5:
                    case opcode_t.OP_CALL6:
                    case opcode_t.OP_CALL7:
                    case opcode_t.OP_CALL8:
                        pr_argc = st.op - (int)opcode_t.OP_CALL0;
                        int afunction = a.function;
                        if (afunction == 0)
                            PR_RunError("NULL function");

                        newf = pr_functions[afunction];

                        if (newf.first_statement < 0)
                        {
                            // negative statements are built in functions
                            i = -newf.first_statement;
                            if (i >= pr_numbuiltins)
                                PR_RunError("Bad builtin call number");
                            //Debug.WriteLine("pr_builtins " + i);
                            if (pr_builtins[i] == null)
                                Debug.WriteLine("pr_builtins " + i + " does not exist");
                            pr_builtins[i]();
                            break;
                        }

                        s = PR_EnterFunction(newf);
                        break;

                    case opcode_t.OP_DONE:
                    case opcode_t.OP_RETURN:
                        pr_globals_write(OFS_RETURN, pr_globals_read(st.a));
                        pr_globals_write(OFS_RETURN + 1, pr_globals_read(st.a + 1));
                        pr_globals_write(OFS_RETURN + 2, pr_globals_read(st.a + 2));

                        s = PR_LeaveFunction();
                        if (pr_depth == exitdepth)
                            return; // all done
                        break;

                    case opcode_t.OP_STATE:
                        ed = PROG_TO_EDICT(pr_global_struct[0].self);
                        ed.v.nextthink = pr_global_struct[0].time + 0.1;
                        if (a._float != ed.v.frame)
                        {
                            ed.v.frame = a._float;
                        }
                        ed.v.think = b.function;
                        break;

                    default:
                        Debug.WriteLine("******Bad opcode " + ((opcode_t)st.op) + " prNum: " + prNum);
                        // todo: this works fine on winquake. need to comment out here
                        //PR_RunError("Bad opcode " + st.op);
                        break;
                }
            }
            //}
            //catch
            //{
            //    Debug.WriteLine("broked");
            //}
        }
Beispiel #15
0
    public unsafe static void PR_ExecuteProgram(int fnum)
    {
        if (fnum < 1 || fnum >= pr_functions.Length)
        {
            if (pr_global_struct.self != 0)
            {
                ED_Print(PROG_TO_EDICT(pr_global_struct.self));
            }
            Host_Error("PR_ExecuteProgram: NULL function");
        }

        dfunction_t f = pr_functions[fnum];

        int runaway = 100000;

        pr_trace = false;

        // make a stack frame
        int exitdepth = pr_depth;

        int     ofs;
        int     s = PR_EnterFunction(f);
        edict_t ed;

        while (true)
        {
            s++;        // next statement

            eval_t *a = (eval_t *)Get(pr_statements[s].a);
            eval_t *b = (eval_t *)Get(pr_statements[s].b);
            eval_t *c = (eval_t *)Get(pr_statements[s].c);

            if (--runaway == 0)
            {
                PR_RunError("runaway loop error");
            }

            pr_xfunction.profile++;
            pr_xstatement = s;

            if (pr_trace)
            {
                PR_PrintStatement(ref pr_statements[s]);
            }

            switch ((OP)pr_statements[s].op)
            {
            case OP.OP_ADD_F:
                c->_float = a->_float + b->_float;
                break;

            case OP.OP_ADD_V:
                c->vector[0] = a->vector[0] + b->vector[0];
                c->vector[1] = a->vector[1] + b->vector[1];
                c->vector[2] = a->vector[2] + b->vector[2];
                break;

            case OP.OP_SUB_F:
                c->_float = a->_float - b->_float;
                break;

            case OP.OP_SUB_V:
                c->vector[0] = a->vector[0] - b->vector[0];
                c->vector[1] = a->vector[1] - b->vector[1];
                c->vector[2] = a->vector[2] - b->vector[2];
                break;

            case OP.OP_MUL_F:
                c->_float = a->_float * b->_float;
                break;

            case OP.OP_MUL_V:
                c->_float = a->vector[0] * b->vector[0]
                            + a->vector[1] * b->vector[1]
                            + a->vector[2] * b->vector[2];
                break;

            case OP.OP_MUL_FV:
                c->vector[0] = a->_float * b->vector[0];
                c->vector[1] = a->_float * b->vector[1];
                c->vector[2] = a->_float * b->vector[2];
                break;

            case OP.OP_MUL_VF:
                c->vector[0] = b->_float * a->vector[0];
                c->vector[1] = b->_float * a->vector[1];
                c->vector[2] = b->_float * a->vector[2];
                break;

            case OP.OP_DIV_F:
                c->_float = a->_float / b->_float;
                break;

            case OP.OP_BITAND:
                c->_float = (int)a->_float & (int)b->_float;
                break;

            case OP.OP_BITOR:
                c->_float = (int)a->_float | (int)b->_float;
                break;


            case OP.OP_GE:
                c->_float = (a->_float >= b->_float) ? 1 : 0;
                break;

            case OP.OP_LE:
                c->_float = (a->_float <= b->_float) ? 1 : 0;
                break;

            case OP.OP_GT:
                c->_float = (a->_float > b->_float) ? 1 : 0;
                break;

            case OP.OP_LT:
                c->_float = (a->_float < b->_float) ? 1 : 0;
                break;

            case OP.OP_AND:
                c->_float = (a->_float != 0 && b->_float != 0) ? 1 : 0;
                break;

            case OP.OP_OR:
                c->_float = (a->_float != 0 || b->_float != 0) ? 1 : 0;
                break;

            case OP.OP_NOT_F:
                c->_float = (a->_float != 0) ? 0 : 1;
                break;

            case OP.OP_NOT_V:
                c->_float = (a->vector[0] == 0 && a->vector[1] == 0 && a->vector[2] == 0) ? 1 : 0;
                break;

            case OP.OP_NOT_S:
                c->_float = (a->_string == 0 || String.IsNullOrEmpty(GetString(a->_string))) ? 1 : 0;
                break;

            case OP.OP_NOT_FNC:
                c->_float = (a->function == 0) ? 1 : 0;
                break;

            case OP.OP_NOT_ENT:
                c->_float = (PROG_TO_EDICT(a->edict) == sv.edicts[0]) ? 1 : 0;
                break;

            case OP.OP_EQ_F:
                c->_float = (a->_float == b->_float) ? 1 : 0;
                break;

            case OP.OP_EQ_V:
                c->_float = ((a->vector[0] == b->vector[0]) &&
                             (a->vector[1] == b->vector[1]) &&
                             (a->vector[2] == b->vector[2])) ? 1 : 0;
                break;

            case OP.OP_EQ_S:
                c->_float = (GetString(a->_string) == GetString(b->_string)) ? 1 : 0;     //!strcmp(pr_strings + a->_string, pr_strings + b->_string);
                break;

            case OP.OP_EQ_E:
                c->_float = (a->_int == b->_int) ? 1 : 0;
                break;

            case OP.OP_EQ_FNC:
                c->_float = (a->function == b->function) ? 1 : 0;
                break;


            case OP.OP_NE_F:
                c->_float = (a->_float != b->_float) ? 1 : 0;
                break;

            case OP.OP_NE_V:
                c->_float = ((a->vector[0] != b->vector[0]) ||
                             (a->vector[1] != b->vector[1]) || (a->vector[2] != b->vector[2])) ? 1 : 0;
                break;

            case OP.OP_NE_S:
                c->_float = (GetString(a->_string) != GetString(b->_string)) ? 1 : 0;     //strcmp(pr_strings + a->_string, pr_strings + b->_string);
                break;

            case OP.OP_NE_E:
                c->_float = (a->_int != b->_int) ? 1 : 0;
                break;

            case OP.OP_NE_FNC:
                c->_float = (a->function != b->function) ? 1 : 0;
                break;

            case OP.OP_STORE_F:
            case OP.OP_STORE_ENT:
            case OP.OP_STORE_FLD:               // integers
            case OP.OP_STORE_S:
            case OP.OP_STORE_FNC:               // pointers
                b->_int = a->_int;
                break;

            case OP.OP_STORE_V:
                b->vector[0] = a->vector[0];
                b->vector[1] = a->vector[1];
                b->vector[2] = a->vector[2];
                break;

            case OP.OP_STOREP_F:
            case OP.OP_STOREP_ENT:
            case OP.OP_STOREP_FLD:              // integers
            case OP.OP_STOREP_S:
            case OP.OP_STOREP_FNC:              // pointers
                ed = EdictFromAddr(b->_int, out ofs);
                ed.StoreInt(ofs, a);
                break;

            case OP.OP_STOREP_V:
                ed = EdictFromAddr(b->_int, out ofs);
                ed.StoreVector(ofs, a);
                break;

            case OP.OP_ADDRESS:
                ed = PROG_TO_EDICT(a->edict);
                if (ed == sv.edicts[0] && sv.active)
                {
                    PR_RunError("assignment to world entity");
                }
                c->_int = MakeAddr(a->edict, b->_int);
                break;

            case OP.OP_LOAD_F:
            case OP.OP_LOAD_FLD:
            case OP.OP_LOAD_ENT:
            case OP.OP_LOAD_S:
            case OP.OP_LOAD_FNC:
                ed = PROG_TO_EDICT(a->edict);
                ed.LoadInt(b->_int, c);
                break;

            case OP.OP_LOAD_V:
                ed = PROG_TO_EDICT(a->edict);
                ed.LoadVector(b->_int, c);
                break;

            case OP.OP_IFNOT:
                if (a->_int == 0)
                {
                    s += pr_statements[s].b - 1;        // offset the s++
                }
                break;

            case OP.OP_IF:
                if (a->_int != 0)
                {
                    s += pr_statements[s].b - 1;        // offset the s++
                }
                break;

            case OP.OP_GOTO:
                s += pr_statements[s].a - 1;            // offset the s++
                break;

            case OP.OP_CALL0:
            case OP.OP_CALL1:
            case OP.OP_CALL2:
            case OP.OP_CALL3:
            case OP.OP_CALL4:
            case OP.OP_CALL5:
            case OP.OP_CALL6:
            case OP.OP_CALL7:
            case OP.OP_CALL8:
                pr_argc = pr_statements[s].op - (int)OP.OP_CALL0;
                if (a->function == 0)
                {
                    PR_RunError("NULL function");
                }

                dfunction_t newf = pr_functions[a->function];

                if (newf.first_statement < 0)
                {
                    // negative statements are built in functions
                    int i = -newf.first_statement;
                    if (i >= pr_builtins.Length)
                    {
                        PR_RunError("Bad builtin call number");
                    }
                    Execute(i);
                    break;
                }

                s = PR_EnterFunction(newf);
                break;

            case OP.OP_DONE:
            case OP.OP_RETURN:
                float *ptr = (float *)_GlobalStructAddr;
                int    sta = pr_statements[s].a;
                ptr[q_shared.OFS_RETURN + 0] = *(float *)Get(sta);
                ptr[q_shared.OFS_RETURN + 1] = *(float *)Get(sta + 1);
                ptr[q_shared.OFS_RETURN + 2] = *(float *)Get(sta + 2);

                s = PR_LeaveFunction();
                if (pr_depth == exitdepth)
                {
                    return;             // all done
                }
                break;

            case OP.OP_STATE:
                ed = PROG_TO_EDICT(pr_global_struct.self);
#if FPS_20
                ed->v.nextthink = pr_global_struct->time + 0.05;
#else
                ed.v.nextthink = pr_global_struct.time + 0.1f;
#endif
                if (a->_float != ed.v.frame)
                {
                    ed.v.frame = a->_float;
                }
                ed.v.think = b->function;
                break;

            default:
                PR_RunError("Bad opcode %i", pr_statements[s].op);
                break;
            }
        }
    }