Beispiel #1
0
        /// <summary>
        /// PR_LeaveFunction
        /// </summary>
        private static int LeaveFunction()
        {
            if (_Depth <= 0)
            {
                sys.Error("prog stack underflow");
            }

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

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

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

            // up stack
            _Depth--;
            xFunction = _Stack[_Depth].f;

            return(_Stack[_Depth].s);
        }
Beispiel #2
0
        // PR_Profile_f
        private static void Profile_f()
        {
            if (_Functions == null)
            {
                return;
            }

            dfunction_t best;
            int         num = 0;

            do
            {
                int max = 0;
                best = null;
                for (int i = 0; i < _Functions.Length; i++)
                {
                    dfunction_t f = _Functions[i];
                    if (f.profile > max)
                    {
                        max  = f.profile;
                        best = f;
                    }
                }
                if (best != null)
                {
                    if (num < 10)
                    {
                        Con.Print("{0,7} {1}\n", best.profile, GetString(best.s_name));
                    }
                    num++;
                    best.profile = 0;
                }
            } while(best != null);
        }
Beispiel #3
0
        /// <summary>
        /// PF_walkmove
        /// float(float yaw, float dist) walkmove
        /// </summary>
        static void PF_walkmove()
        {
            edict_t ent  = Server.ProgToEdict(Progs.GlobalStruct.self);
            float   yaw  = GetFloat(OFS.OFS_PARM0);
            float   dist = GetFloat(OFS.OFS_PARM1);

            if (((int)ent.v.flags & (EdictFlags.FL_ONGROUND | EdictFlags.FL_FLY | EdictFlags.FL_SWIM)) == 0)
            {
                ReturnFloat(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    = Progs.xFunction;
            int         oldself = Progs.GlobalStruct.self;

            ReturnFloat(Server.MoveStep(ent, ref move, true) ? 1 : 0);

            // restore program state
            Progs.xFunction         = oldf;
            Progs.GlobalStruct.self = oldself;
        }
Beispiel #4
0
        /// <summary>
        /// PR_ValueString
        /// </summary>
        static unsafe string ValueString(etype_t type, void *val)
        {
            string result;

            type &= (etype_t) ~DEF_SAVEGLOBAL;

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

            case etype_t.ev_entity:
                result = "entity " + Server.NumForEdict(Server.ProgToEdict(*(int *)val));
                break;

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

            case etype_t.ev_field:
                ddef_t def = FindField(*(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);
        }
Beispiel #5
0
        /// <summary>
        /// PR_UglyValueString
        /// Returns a string describing *data in a type specific manner
        /// Easier to parse than PR_ValueString
        /// </summary>
        static unsafe string UglyValueString(etype_t type, eval_t *val)
        {
            type &= (etype_t) ~DEF_SAVEGLOBAL;
            string result;

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

            case etype_t.ev_entity:
                result = Server.NumForEdict(Server.ProgToEdict(val->edict)).ToString();
                break;

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

            case etype_t.ev_field:
                ddef_t def = FindField(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 #6
0
        /// <summary>
        /// PR_EnterFunction
        /// Returns the new program statement counter
        /// </summary>
        private static unsafe int EnterFunction(dfunction_t f)
        {
            _Stack[_Depth].s = _xStatement;
            _Stack[_Depth].f = xFunction;
            _Depth++;
            if (_Depth >= MAX_STACK_DEPTH)
            {
                RunError("stack overflow");
            }

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

            if (_LocalStackUsed + c > LOCALSTACK_SIZE)
            {
                RunError("PR_ExecuteProgram: locals stack overflow\n");
            }

            for (int i = 0; i < c; i++)
            {
                _LocalStack[_LocalStackUsed + i] = *(int *)Get(f.parm_start + i);
            }
            _LocalStackUsed += 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(OFS.OFS_PARM0 + i * 3 + j));
                    o++;
                }
            }

            xFunction = f;
            return(f.first_statement - 1);       // offset the s++
        }
Beispiel #7
0
        /// <summary>
        /// PR_StackTrace
        /// </summary>
        private static void StackTrace()
        {
            if (_Depth == 0)
            {
                Con.Print("<NO STACK>\n");
                return;
            }

            _Stack[_Depth].f = progs.xFunction;
            for (int i = _Depth; i >= 0; i--)
            {
                dfunction_t f = _Stack[i].f;

                if (f == null)
                {
                    Con.Print("<NO FUNCTION>\n");
                }
                else
                {
                    Con.Print("{0,12} : {1}\n", GetString(f.s_file), GetString(f.s_name));
                }
            }
        }
Beispiel #8
0
        private static int _Argc;       // pr_argc

        /// <summary>
        /// PR_ExecuteProgram
        /// </summary>
        public unsafe static void Execute(int fnum)
        {
            if (fnum < 1 || fnum >= _Functions.Length)
            {
                if (progs.GlobalStruct.self != 0)
                {
                    Print(server.ProgToEdict(progs.GlobalStruct.self));
                }
                host.Error("PR_ExecuteProgram: NULL function");
            }

            dfunction_t f = _Functions[fnum];

            int runaway = 100000;

            Trace = false;

            // make a stack frame
            int exitdepth = _Depth;

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

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

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

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

                xFunction.profile++;
                _xStatement = s;

                if (Trace)
                {
                    PrintStatement(ref _Statements[s]);
                }

                switch ((OP)_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 = (server.ProgToEdict(a->edict) == server.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 = server.ProgToEdict(a->edict);
                    if (ed == server.sv.edicts[0] && server.IsActive)
                    {
                        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 = server.ProgToEdict(a->edict);
                    ed.LoadInt(b->_int, c);
                    break;

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

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

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

                case OP.OP_GOTO:
                    s += _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:
                    _Argc = _Statements[s].op - (int)OP.OP_CALL0;
                    if (a->function == 0)
                    {
                        RunError("NULL function");
                    }

                    dfunction_t newf = _Functions[a->function];

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

                    s = EnterFunction(newf);
                    break;

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

                    s = LeaveFunction();
                    if (_Depth == exitdepth)
                    {
                        return;                 // all done
                    }
                    break;

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

                default:
                    RunError("Bad opcode %i", _Statements[s].op);
                    break;
                }
            }
        }
Beispiel #9
0
        /// <summary>
        /// PR_LeaveFunction
        /// </summary>
        static int LeaveFunction()
        {
            if (_Depth <= 0)
                Sys.Error("prog stack underflow");

            // restore locals from the stack
            int c = xFunction.locals;
            _LocalStackUsed -= c;
            if (_LocalStackUsed < 0)
                RunError("PR_ExecuteProgram: locals stack underflow\n");

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

            // up stack
            _Depth--;
            xFunction = _Stack[_Depth].f;

            return _Stack[_Depth].s;
        }
Beispiel #10
0
        /// <summary>
        /// PR_EnterFunction
        /// Returns the new program statement counter
        /// </summary>
        static unsafe int EnterFunction(dfunction_t f)
        {
            _Stack[_Depth].s = _xStatement;
            _Stack[_Depth].f = xFunction;
            _Depth++;
            if (_Depth >= MAX_STACK_DEPTH)
                RunError("stack overflow");

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

            for (int i = 0; i < c; i++)
                _LocalStack[_LocalStackUsed + i] = *(int*)Get(f.parm_start + i);
            _LocalStackUsed += 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(OFS.OFS_PARM0 + i * 3 + j));
                    o++;
                }
            }

            xFunction = f;
            return f.first_statement - 1;	// offset the s++
        }