]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - prvm_edict.c
Underwater sound filter: simplify code, improve cvar description
[xonotic/darkplaces.git] / prvm_edict.c
index a03d0bd1352a636b3d18b11edb51bb8b18017a29..01847ab9db3d2a981bda238bb230e04f77d41503 100644 (file)
@@ -22,6 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #include "quakedef.h"
 #include "progsvm.h"
 #include "csprogs.h"
+#include "prvm_cmds.h"
 
 prvm_prog_t prvm_prog_list[PRVM_PROG_MAX];
 
@@ -220,8 +221,9 @@ const char *PRVM_AllocationOrigin(prvm_prog_t *prog)
        if(prog->leaktest_active)
        if(prog->depth > 0) // actually in QC code and not just parsing the entities block of a map/savegame
        {
-               buf = (char *)PRVM_Alloc(256);
-               PRVM_ShortStackTrace(prog, buf, 256);
+               // bones_was_here: this is the smallest 64 multiple that avoids truncation in Xonotic (was 256)
+               buf = (char *)PRVM_Alloc(448);
+               PRVM_ShortStackTrace(prog, buf, 448);
        }
        return buf;
 }
@@ -1122,7 +1124,7 @@ static void PRVM_GameCommand(cmd_state_t *cmd, const char *whichprogs, const cha
                s = Cmd_Args(cmd);
 
                restorevm_tempstringsbuf_cursize = prog->tempstringsbuf.cursize;
-               PRVM_G_INT(OFS_PARM0) = PRVM_SetTempString(prog, s ? s : "");
+               PRVM_G_INT(OFS_PARM0) = PRVM_SetTempString(prog, s ? s : "", s ? strlen(s) : 0);
                prog->ExecuteProgram(prog, PRVM_allfunction(GameCommand), "QC function GameCommand is missing");
                prog->tempstringsbuf.cursize = restorevm_tempstringsbuf_cursize;
        }
@@ -1852,7 +1854,8 @@ static po_t *PRVM_PO_Load(const char *filename, const char *filename2, mempool_t
                                        break;
                                if((size_t)(q - p) >= (size_t) sizeof(inbuf))
                                        break;
-                               dp_strlcpy(inbuf, p, q - p); // not - 1, because this adds a NUL
+                               memcpy(inbuf, p, q - p - 1);
+                               inbuf[q - p - 1] = '\0';
                                PRVM_PO_ParseString(decodedbuf + decodedpos, inbuf, sizeof(decodedbuf) - decodedpos);
                                decodedpos += strlen(decodedbuf + decodedpos);
                                if(*q == '\r')
@@ -1970,12 +1973,12 @@ static void PRVM_LoadLNO( prvm_prog_t *prog, const char *progname ) {
        }
 
        header = (unsigned int *) lno;
-       if( header[ 0 ] == *(unsigned int *) "LNOF" &&
-               LittleLong( header[ 1 ] ) == 1 &&
-               (unsigned int)LittleLong( header[ 2 ] ) == (unsigned int)prog->progs_numglobaldefs &&
-               (unsigned int)LittleLong( header[ 3 ] ) == (unsigned int)prog->progs_numglobals &&
-               (unsigned int)LittleLong( header[ 4 ] ) == (unsigned int)prog->progs_numfielddefs &&
-               (unsigned int)LittleLong( header[ 5 ] ) == (unsigned int)prog->progs_numstatements )
+       if (memcmp(lno, "LNOF", 4) == 0
+       && LittleLong( header[ 1 ] ) == 1
+       && (unsigned int)LittleLong( header[ 2 ] ) == (unsigned int)prog->progs_numglobaldefs
+       && (unsigned int)LittleLong( header[ 3 ] ) == (unsigned int)prog->progs_numglobals
+       && (unsigned int)LittleLong( header[ 4 ] ) == (unsigned int)prog->progs_numfielddefs
+       && (unsigned int)LittleLong( header[ 5 ] ) == (unsigned int)prog->progs_numstatements)
        {
                prog->statement_linenums = (int *)Mem_Alloc(prog->progs_mempool, prog->progs_numstatements * sizeof( int ) );
                memcpy( prog->statement_linenums, header + 6, prog->progs_numstatements * sizeof( int ) );
@@ -1992,7 +1995,7 @@ static void PRVM_LoadLNO( prvm_prog_t *prog, const char *progname ) {
 
 /*
 ===============
-PRVM_LoadProgs
+PRVM_Prog_Load
 ===============
 */
 static void PRVM_UpdateBreakpoints(prvm_prog_t *prog);
@@ -2030,7 +2033,7 @@ void PRVM_Prog_Load(prvm_prog_t *prog, const char * filename, unsigned char * da
        int structtype = 0;
 
        if (prog->loaded)
-               prog->error_cmd("PRVM_LoadProgs: there is already a %s program loaded!", prog->name );
+               prog->error_cmd("%s: there is already a %s program loaded!", __func__, prog->name);
 
        Host_LockSession(); // all progs can use the session cvar
        Crypto_LoadKeys(); // all progs might use the keys at init time
@@ -2043,7 +2046,7 @@ void PRVM_Prog_Load(prvm_prog_t *prog, const char * filename, unsigned char * da
        else
                dprograms = (dprograms_t *)FS_LoadFile (filename, prog->progs_mempool, false, &filesize);
        if (dprograms == NULL || filesize < (fs_offset_t)sizeof(dprograms_t))
-               prog->error_cmd("PRVM_LoadProgs: couldn't load %s for %s", filename, prog->name);
+               prog->error_cmd("%s: couldn't load \"%s\" for %s", __func__, filename, prog->name);
        // TODO bounds check header fields (e.g. numstatements), they must never go behind end of file
 
        prog->profiletime = Sys_DirtyTime();
@@ -2136,7 +2139,7 @@ void PRVM_Prog_Load(prvm_prog_t *prog, const char * filename, unsigned char * da
                prog->functions[i].locals = LittleLong(infunctions[i].locals);
                memcpy(prog->functions[i].parm_size, infunctions[i].parm_size, sizeof(infunctions[i].parm_size));
                if(prog->functions[i].first_statement >= prog->numstatements)
-                       prog->error_cmd("PRVM_LoadProgs: out of bounds function statement (function %d) in %s", i, prog->name);
+                       prog->error_cmd("%s: out of bounds function statement (function %d) in %s", __func__, i, prog->name);
                // TODO bounds check parm_start, s_name, s_file, numparms, locals, parm_size
        }
 
@@ -2184,7 +2187,7 @@ void PRVM_Prog_Load(prvm_prog_t *prog, const char * filename, unsigned char * da
                {
                        prog->fielddefs[i].type = LittleLong(infielddefs32[i].type);
                        if (prog->fielddefs[i].type & DEF_SAVEGLOBAL)
-                               prog->error_cmd("PRVM_LoadProgs: prog->fielddefs[i].type & DEF_SAVEGLOBAL in %s", prog->name);
+                               prog->error_cmd("%s: prog->fielddefs[i].type & DEF_SAVEGLOBAL in %s", __func__, prog->name);
                        prog->fielddefs[i].ofs = LittleLong(infielddefs32[i].ofs);
                        prog->fielddefs[i].s_name = LittleLong(infielddefs32[i].s_name);
                        // TODO bounds check ofs, s_name
@@ -2195,7 +2198,7 @@ void PRVM_Prog_Load(prvm_prog_t *prog, const char * filename, unsigned char * da
                {
                        prog->fielddefs[i].type = (unsigned short)LittleShort(infielddefs16[i].type);
                        if (prog->fielddefs[i].type & DEF_SAVEGLOBAL)
-                               prog->error_cmd("PRVM_LoadProgs: prog->fielddefs[i].type & DEF_SAVEGLOBAL in %s", prog->name);
+                               prog->error_cmd("%s: prog->fielddefs[i].type & DEF_SAVEGLOBAL in %s", __func__, prog->name);
                        prog->fielddefs[i].ofs = (unsigned short)LittleShort(infielddefs16[i].ofs);
                        prog->fielddefs[i].s_name = LittleLong(infielddefs16[i].s_name);
                        // TODO bounds check ofs, s_name
@@ -2267,7 +2270,7 @@ void PRVM_Prog_Load(prvm_prog_t *prog, const char * filename, unsigned char * da
                case OP_IFNOT:
                        b = (short)b;
                        if (a >= prog->progs_numglobals || b + i < 0 || b + i >= prog->progs_numstatements)
-                               prog->error_cmd("PRVM_LoadProgs: out of bounds IF/IFNOT (statement %d) in %s", i, prog->name);
+                               prog->error_cmd("%s: out of bounds IF/IFNOT (statement %d) in %s", __func__, i, prog->name);
                        prog->statements[i].op = op;
                        prog->statements[i].operand[0] = remapglobal(a);
                        prog->statements[i].operand[1] = -1;
@@ -2277,7 +2280,7 @@ void PRVM_Prog_Load(prvm_prog_t *prog, const char * filename, unsigned char * da
                case OP_GOTO:
                        a = (short)a;
                        if (a + i < 0 || a + i >= prog->progs_numstatements)
-                               prog->error_cmd("PRVM_LoadProgs: out of bounds GOTO (statement %d) in %s", i, prog->name);
+                               prog->error_cmd("%s: out of bounds GOTO (statement %d) in %s", __func__, i, prog->name);
                        prog->statements[i].op = op;
                        prog->statements[i].operand[0] = -1;
                        prog->statements[i].operand[1] = -1;
@@ -2285,7 +2288,7 @@ void PRVM_Prog_Load(prvm_prog_t *prog, const char * filename, unsigned char * da
                        prog->statements[i].jumpabsolute = i + a;
                        break;
                default:
-                       Con_DPrintf("PRVM_LoadProgs: unknown opcode %d at statement %d in %s\n", (int)op, i, prog->name);
+                       Con_DPrintf("%s: unknown opcode %d at statement %d in %s\n", __func__, (int)op, i, prog->name);
 
                        //make sure its something well defined.
                        prog->statements[i].op = OP_BOUNDCHECK;
@@ -2398,7 +2401,7 @@ void PRVM_Prog_Load(prvm_prog_t *prog, const char * filename, unsigned char * da
                case OP_LOAD_FNC:
                case OP_LOAD_V:
                        if (a >= prog->progs_numglobals || b >= prog->progs_numglobals || c >= prog->progs_numglobals)
-                               prog->error_cmd("PRVM_LoadProgs: out of bounds global index (statement %d)", i);
+                               prog->error_cmd("%s: out of bounds global index (statement %d)", __func__, i);
                        prog->statements[i].op = op;
                        prog->statements[i].operand[0] = remapglobal(a);
                        prog->statements[i].operand[1] = remapglobal(b);
@@ -2412,7 +2415,7 @@ void PRVM_Prog_Load(prvm_prog_t *prog, const char * filename, unsigned char * da
                case OP_NOT_FNC:
                case OP_NOT_ENT:
                        if (a >= prog->progs_numglobals || c >= prog->progs_numglobals)
-                               prog->error_cmd("PRVM_LoadProgs: out of bounds global index (statement %d) in %s", i, prog->name);
+                               prog->error_cmd("%s: out of bounds global index (statement %d) in %s", __func__, i, prog->name);
                        prog->statements[i].op = op;
                        prog->statements[i].operand[0] = remapglobal(a);
                        prog->statements[i].operand[1] = -1;
@@ -2426,7 +2429,7 @@ void PRVM_Prog_Load(prvm_prog_t *prog, const char * filename, unsigned char * da
                case OP_STOREP_S:
                case OP_STOREP_FNC:
                        if (c)  //Spike -- DP is alergic to pointers in QC. Try to avoid too many nasty surprises.
-                               Con_DPrintf("PRVM_LoadProgs: storep-with-offset is not permitted in %s\n", prog->name);
+                               Con_DPrintf("%s: storep-with-offset is not permitted in %s\n", __func__, prog->name);
                        //fallthrough
                case OP_STORE_F:
                case OP_STORE_ENT:
@@ -2437,7 +2440,7 @@ void PRVM_Prog_Load(prvm_prog_t *prog, const char * filename, unsigned char * da
                case OP_STOREP_V:
                case OP_STORE_V:
                        if (a >= prog->progs_numglobals || b >= prog->progs_numglobals)
-                               prog->error_cmd("PRVM_LoadProgs: out of bounds global index (statement %d) in %s", i, prog->name);
+                               prog->error_cmd("%s: out of bounds global index (statement %d) in %s", __func__, i, prog->name);
                        prog->statements[i].op = op;
                        prog->statements[i].operand[0] = remapglobal(a);
                        prog->statements[i].operand[1] = remapglobal(b);
@@ -2462,9 +2465,9 @@ void PRVM_Prog_Load(prvm_prog_t *prog, const char * filename, unsigned char * da
                case OP_DONE:
                case OP_RETURN:
                        if ( a >= prog->progs_numglobals)
-                               prog->error_cmd("PRVM_LoadProgs: out of bounds global index (statement %d) in %s", i, prog->name);
+                               prog->error_cmd("%s: out of bounds global index (statement %d) in %s", __func__, i, prog->name);
                        if (b || c)     //Spike -- added this check just as a diagnostic...
-                               Con_DPrintf("PRVM_LoadProgs: unexpected offset on call opcode in %s. Hexen2 format is not supported\n", prog->name);
+                               Con_DPrintf("%s: unexpected offset on call opcode in %s. Hexen2 format is not supported\n", __func__, prog->name);
                        prog->statements[i].op = op;
                        prog->statements[i].operand[0] = remapglobal(a);
                        prog->statements[i].operand[1] = -1;
@@ -2475,7 +2478,7 @@ void PRVM_Prog_Load(prvm_prog_t *prog, const char * filename, unsigned char * da
        }
        if(prog->numstatements < 1)
        {
-               prog->error_cmd("PRVM_LoadProgs: empty program in %s", prog->name);
+               prog->error_cmd("%s: empty program in %s", __func__, prog->name);
        }
        else switch(prog->statements[prog->numstatements - 1].op)
        {
@@ -2484,7 +2487,7 @@ void PRVM_Prog_Load(prvm_prog_t *prog, const char * filename, unsigned char * da
                case OP_DONE:
                        break;
                default:
-                       prog->error_cmd("PRVM_LoadProgs: program may fall off the edge (does not end with RETURN, GOTO or DONE) in %s", prog->name);
+                       prog->error_cmd("%s: program may fall off the edge (does not end with RETURN, GOTO or DONE) in %s", __func__, prog->name);
                        break;
        }
 
@@ -2592,14 +2595,14 @@ void PRVM_Prog_Load(prvm_prog_t *prog, const char * filename, unsigned char * da
                {
                        prvm_eval_t *val = PRVM_GLOBALFIELDVALUE(prog->globaldefs[i].ofs);
                        cvar = Cvar_FindVar(prog->console_cmd->cvars, name + 9, prog->console_cmd->cvars_flagsmask);
-                       //Con_Printf("PRVM_LoadProgs: autocvar global %s in %s, processing...\n", name, prog->name);
+                       //Con_Printf("%s: autocvar global %s in %s, processing...\n", __func__, name, prog->name);
                        if(!cvar)
                        {
                                const char *value;
                                char buf[128];
                                int prec[3];
                                float f;
-                               Con_DPrintf("PRVM_LoadProgs: no cvar for autocvar global %s in %s, creating...\n", name, prog->name);
+                               Con_DPrintf("%s: no cvar for autocvar global %s in %s, creating...\n", __func__, name, prog->name);
                                switch(prog->globaldefs[i].type & ~DEF_SAVEGLOBAL)
                                {
                                        case ev_float:
@@ -2638,7 +2641,7 @@ void PRVM_Prog_Load(prvm_prog_t *prog, const char * filename, unsigned char * da
                                                value = PRVM_GetString(prog, val->string);
                                                break;
                                        default:
-                                               Con_Printf("PRVM_LoadProgs: invalid type of autocvar global %s in %s\n", name, prog->name);
+                                               Con_Printf("%s: invalid type of autocvar global %s in %s\n", __func__, name, prog->name);
                                                goto fail;
                                }
                                cvar = Cvar_Get(prog->console_cmd->cvars, name + 9, value, prog->console_cmd->cvars_flagsmask, NULL);
@@ -2648,7 +2651,7 @@ void PRVM_Prog_Load(prvm_prog_t *prog, const char * filename, unsigned char * da
                                        cvar->globaldefindex_stringno[prog - prvm_prog_list] = val->string;
                                }
                                if(!cvar)
-                                       prog->error_cmd("PRVM_LoadProgs: could not create cvar for autocvar global %s in %s", name, prog->name);
+                                       prog->error_cmd("%s: could not create cvar for autocvar global %s in %s", __func__, name, prog->name);
                                cvar->globaldefindex[prog - prvm_prog_list] = i;
                        }
                        else if((cvar->flags & CF_PRIVATE) == 0)
@@ -2682,13 +2685,13 @@ void PRVM_Prog_Load(prvm_prog_t *prog, const char * filename, unsigned char * da
                                                cvar->globaldefindex_stringno[prog - prvm_prog_list] = val->string;
                                                break;
                                        default:
-                                               Con_Printf("PRVM_LoadProgs: invalid type of autocvar global %s in %s\n", name, prog->name);
+                                               Con_Printf("%s: invalid type of autocvar global %s in %s\n", __func__, name, prog->name);
                                                goto fail;
                                }
                                cvar->globaldefindex[prog - prvm_prog_list] = i;
                        }
                        else
-                               Con_Printf("PRVM_LoadProgs: private cvar for autocvar global %s in %s\n", name, prog->name);
+                               Con_Printf("%s: private cvar for autocvar global %s in %s\n", __func__, name, prog->name);
                }
 fail:
                ;
@@ -3365,23 +3368,23 @@ int PRVM_SetEngineString(prvm_prog_t *prog, const char *s)
 //  restores it on return, so multiple recursive calls can share the same
 //  buffer)
 // the buffer size is automatically grown as needed
-
-int PRVM_SetTempString(prvm_prog_t *prog, const char *s)
+int PRVM_SetTempString(prvm_prog_t *prog, const char *s, size_t slen)
 {
-       int size;
+       size_t size;
        char *t;
-       if (!s)
+
+       if (!s || slen >= VM_TEMPSTRING_MAXSIZE)
                return 0;
-       size = (int)strlen(s) + 1;
+       size = slen + 1;
        if (developer_insane.integer)
-               Con_DPrintf("PRVM_SetTempString %s: cursize %i, size %i\n", prog->name, prog->tempstringsbuf.cursize, size);
-       if (prog->tempstringsbuf.maxsize < prog->tempstringsbuf.cursize + size)
+               Con_DPrintf("PRVM_SetTempString %s: cursize %i, new tempstring size %lu\n", prog->name, prog->tempstringsbuf.cursize, (unsigned long)size);
+       if ((size_t)prog->tempstringsbuf.maxsize < prog->tempstringsbuf.cursize + size)
        {
                sizebuf_t old = prog->tempstringsbuf;
                if (prog->tempstringsbuf.cursize + size >= 1<<28)
-                       prog->error_cmd("PRVM_SetTempString %s: ran out of tempstring memory!  (refusing to grow tempstring buffer over 256MB, cursize %i, size %i)\n", prog->name, prog->tempstringsbuf.cursize, size);
+                       prog->error_cmd("PRVM_SetTempString %s: ran out of tempstring memory!  (refusing to grow tempstring buffer over 256MB, cursize %i, new tempstring size %lu)\n", prog->name, prog->tempstringsbuf.cursize, (unsigned long)size);
                prog->tempstringsbuf.maxsize = max(prog->tempstringsbuf.maxsize, 65536);
-               while (prog->tempstringsbuf.maxsize < prog->tempstringsbuf.cursize + size)
+               while ((size_t)prog->tempstringsbuf.maxsize < prog->tempstringsbuf.cursize + size)
                        prog->tempstringsbuf.maxsize *= 2;
                if (prog->tempstringsbuf.maxsize != old.maxsize || prog->tempstringsbuf.data == NULL)
                {