X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=prvm_cmds.c;h=1f4baee33fd94c9dc960f9e79a3002ae0409121a;hb=a26c29e7adac278a87059324e40868823c752680;hp=b2ae2599708e539e036e65def0df403f9b15650a;hpb=41f1138b4a171ebb11be1418ed5579a8935b5516;p=xonotic%2Fdarkplaces.git diff --git a/prvm_cmds.c b/prvm_cmds.c index b2ae2599..1f4baee3 100644 --- a/prvm_cmds.c +++ b/prvm_cmds.c @@ -6,6 +6,22 @@ #include "prvm_cmds.h" +// LordHavoc: changed this to NOT use a return statement, so that it can be used in functions that must return a value +void VM_Warning(const char *fmt, ...) +{ + va_list argptr; + char msg[MAX_INPUTLINE]; + + va_start(argptr,fmt); + dpvsnprintf(msg,sizeof(msg),fmt,argptr); + va_end(argptr); + + Con_Print(msg); + // TODO: either add a cvar/cmd to control the state dumping or replace some of the calls with Con_Printf [9/13/2006 Black] + //PRVM_PrintState(); +} + + //============================================================================ // Common @@ -14,20 +30,8 @@ static char vm_string_temp[VM_STRINGTEMP_BUFFERS][VM_STRINGTEMP_LENGTH]; static int vm_string_tempindex = 0; -// qc file handling -#define MAX_VMFILES 256 -#define MAX_PRVMFILES MAX_VMFILES * PRVM_MAXPROGS -#define VM_FILES ((qfile_t**)(vm_files + PRVM_GetProgNr() * MAX_VMFILES)) - -qfile_t *vm_files[MAX_PRVMFILES]; - -// qc fs search handling -#define MAX_VMSEARCHES 128 -#define TOTAL_VMSEARCHES MAX_VMSEARCHES * PRVM_MAXPROGS -#define VM_SEARCHLIST ((fssearch_t**)(vm_fssearchlist + PRVM_GetProgNr() * MAX_VMSEARCHES)) - -fssearch_t *vm_fssearchlist[TOTAL_VMSEARCHES]; - +// TODO: (move vm_files and vm_fssearchlist to prvm_prog_t struct) +// TODO: move vm_files and vm_fssearchlist back [9/13/2006 Black] char *VM_GetTempString(void) { char *s; @@ -123,7 +127,7 @@ void VM_error (void) PRVM_ED_Print(ed); } - PRVM_ERROR ("%s: Program error in function %s:\n%s\n", PRVM_NAME, PRVM_GetString(prog->xfunction->s_name), string); + PRVM_ERROR ("%s: Program error in function %s:\n%s\nTip: read above for entity information\n", PRVM_NAME, PRVM_GetString(prog->xfunction->s_name), string); } /* @@ -153,7 +157,7 @@ void VM_objerror (void) else // objerror has to display the object fields -> else call PRVM_ERROR ("VM_objecterror: self not defined !"); - Con_Printf("%s OBJECT ERROR in %s:\n%s\n", PRVM_NAME, PRVM_GetString(prog->xfunction->s_name), string); + Con_Printf("%s OBJECT ERROR in %s:\n%s\nTip: read above for entity information\n", PRVM_NAME, PRVM_GetString(prog->xfunction->s_name), string); } /* @@ -188,7 +192,7 @@ void VM_bprint (void) if(!sv.active) { - Con_Printf("VM_bprint: game is not server(%s) !\n", PRVM_NAME); + VM_Warning("VM_bprint: game is not server(%s) !\n", PRVM_NAME); return; } @@ -215,7 +219,7 @@ void VM_sprint (void) clientnum = (int)PRVM_G_FLOAT(OFS_PARM0); if (!sv.active || clientnum < 0 || clientnum >= svs.maxclients || !svs.clients[clientnum].active) { - Con_Printf("VM_sprint: %s: invalid client or server is not active !\n", PRVM_NAME); + VM_Warning("VM_sprint: %s: invalid client or server is not active !\n", PRVM_NAME); return; } @@ -442,8 +446,8 @@ void VM_localsound(void) if(!S_LocalSound (s)) { - Con_Printf("VM_localsound: Failed to play %s for %s !\n", s, PRVM_NAME); PRVM_G_FLOAT(OFS_RETURN) = -4; + VM_Warning("VM_localsound: Failed to play %s for %s !\n", s, PRVM_NAME); return; } @@ -520,7 +524,7 @@ void VM_cvar_string(void) cvar_string = Cvar_VariableString(name); - strcpy(out, cvar_string); + strlcpy(out, cvar_string, VM_STRINGTEMP_LENGTH); PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(out); } @@ -551,7 +555,7 @@ void VM_cvar_defstring (void) cvar_string = Cvar_VariableDefString(name); - strcpy(out, cvar_string); + strlcpy(out, cvar_string, VM_STRINGTEMP_LENGTH); PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(out); } @@ -700,19 +704,19 @@ void VM_itof(void) /* ======================== -VM_itoe +VM_ftoe -intt ftoi(float num) +entity ftoe(float num) ======================== */ -void VM_ftoi(void) +void VM_ftoe(void) { int ent; - VM_SAFEPARMCOUNT(1, VM_ftoi); + VM_SAFEPARMCOUNT(1, VM_ftoe); ent = (int)PRVM_G_FLOAT(OFS_PARM0); - if(PRVM_PROG_TO_EDICT(ent)->priv.required->free) - PRVM_ERROR ("VM_ftoe: %s tried to access a freed entity (entity %i)!", PRVM_NAME, ent); + if (ent < 0 || ent >= MAX_EDICTS || PRVM_PROG_TO_EDICT(ent)->priv.required->free) + ent = 0; // return world instead of a free or invalid entity PRVM_G_INT(OFS_RETURN) = ent; } @@ -749,13 +753,18 @@ void VM_remove (void) VM_SAFEPARMCOUNT(1, VM_remove); ed = PRVM_G_EDICT(OFS_PARM0); - if( PRVM_NUM_FOR_EDICT(ed) <= prog->reserved_edicts ) { - Con_DPrint( "VM_remove: tried to remove the null entity or a reserved entity!\n" ); - } else if( ed->priv.required->free ) { - Con_DPrint( "VM_remove: tried to remove an already freed entity!\n" ); - } else { - PRVM_ED_Free (ed); + if( PRVM_NUM_FOR_EDICT(ed) <= prog->reserved_edicts ) + { + if (developer.integer >= 1) + VM_Warning( "VM_remove: tried to remove the null entity or a reserved entity!\n" ); + } + else if( ed->priv.required->free ) + { + if (developer.integer >= 1) + VM_Warning( "VM_remove: tried to remove an already freed entity!\n" ); } + else + PRVM_ED_Free (ed); // if (ed == prog->edicts) // PRVM_ERROR ("remove: tried to remove world"); // if (PRVM_NUM_FOR_EDICT(ed) <= sv.maxclients) @@ -783,12 +792,11 @@ void VM_find (void) f = PRVM_G_INT(OFS_PARM1); s = PRVM_G_STRING(OFS_PARM2); - if (!s || !s[0]) - { - // return reserved edict 0 (could be used for whatever the prog wants) - VM_RETURN_EDICT(prog->edicts); - return; - } + // LordHavoc: apparently BloodMage does a find(world, weaponmodel, "") and + // expects it to find all the monsters, so we must be careful to support + // searching for "" + if (!s) + s = ""; for (e++ ; e < prog->num_edicts ; e++) { @@ -798,7 +806,7 @@ void VM_find (void) continue; t = PRVM_E_STRING(ed,f); if (!t) - continue; + t = ""; if (!strcmp(t,s)) { VM_RETURN_EDICT(ed); @@ -876,11 +884,12 @@ void VM_findchain (void) f = PRVM_G_INT(OFS_PARM0); s = PRVM_G_STRING(OFS_PARM1); - if (!s || !s[0]) - { - VM_RETURN_EDICT(prog->edicts); - return; - } + + // LordHavoc: apparently BloodMage does a find(world, weaponmodel, "") and + // expects it to find all the monsters, so we must be careful to support + // searching for "" + if (!s) + s = ""; ent = PRVM_NEXT_EDICT(prog->edicts); for (i = 1;i < prog->num_edicts;i++, ent = PRVM_NEXT_EDICT(ent)) @@ -890,7 +899,7 @@ void VM_findchain (void) continue; t = PRVM_E_STRING(ent,f); if (!t) - continue; + t = ""; if (strcmp(t,s)) continue; @@ -975,6 +984,8 @@ void VM_findflags (void) ed = PRVM_EDICT_NUM(e); if (ed->priv.required->free) continue; + if (!PRVM_E_FLOAT(ed,f)) + continue; if ((int)PRVM_E_FLOAT(ed,f) & s) { VM_RETURN_EDICT(ed); @@ -1019,6 +1030,8 @@ void VM_findchainflags (void) prog->xfunction->builtinsprofile++; if (ent->priv.required->free) continue; + if (!PRVM_E_FLOAT(ent,f)) + continue; if (!((int)PRVM_E_FLOAT(ent,f) & s)) continue; @@ -1126,15 +1139,14 @@ float rint(float) */ void VM_rint (void) { - float f; - + float f; VM_SAFEPARMCOUNT(1,VM_rint); f = PRVM_G_FLOAT(OFS_PARM0); if (f > 0) - PRVM_G_FLOAT(OFS_RETURN) = (int)(f + 0.5); + PRVM_G_FLOAT(OFS_RETURN) = floor(f + 0.5); else - PRVM_G_FLOAT(OFS_RETURN) = (int)(f - 0.5); + PRVM_G_FLOAT(OFS_RETURN) = ceil(f - 0.5); } /* @@ -1215,7 +1227,7 @@ void VM_changelevel (void) if(!sv.active) { - Con_Printf("VM_changelevel: game is not server (%s)\n", PRVM_NAME); + VM_Warning("VM_changelevel: game is not server (%s)\n", PRVM_NAME); return; } @@ -1333,7 +1345,7 @@ void VM_registercvar (void) // check for overlap with a command if (Cmd_Exists (name)) { - Con_Printf("VM_registercvar: %s is a command\n", name); + VM_Warning("VM_registercvar: %s is a command\n", name); return; } @@ -1482,34 +1494,35 @@ setcolor(clientent, value) void VM_Files_Init(void) { - memset(VM_FILES, 0, sizeof(qfile_t*[MAX_VMFILES])); + int i; + for (i = 0;i < PRVM_MAX_OPENFILES;i++) + prog->openfiles[i] = NULL; } void VM_Files_CloseAll(void) { int i; - for (i = 0;i < MAX_VMFILES;i++) + for (i = 0;i < PRVM_MAX_OPENFILES;i++) { - if (VM_FILES[i]) - FS_Close(VM_FILES[i]); - //VM_FILES[i] = NULL; + if (prog->openfiles[i]) + FS_Close(prog->openfiles[i]); + prog->openfiles[i] = NULL; } - memset(VM_FILES,0,sizeof(qfile_t*[MAX_VMFILES])); // this should be faster (is it ?) } qfile_t *VM_GetFileHandle( int index ) { - if (index < 0 || index >= MAX_VMFILES) + if (index < 0 || index >= PRVM_MAX_OPENFILES) { Con_Printf("VM_GetFileHandle: invalid file handle %i used in %s\n", index, PRVM_NAME); return NULL; } - if (VM_FILES[index] == NULL) + if (prog->openfiles[index] == NULL) { Con_Printf("VM_GetFileHandle: no such file handle %i (or file has been closed) in %s\n", index, PRVM_NAME); return NULL; } - return VM_FILES[index]; + return prog->openfiles[index]; } /* @@ -1529,13 +1542,13 @@ void VM_fopen(void) VM_SAFEPARMCOUNT(2,VM_fopen); - for (filenum = 0;filenum < MAX_VMFILES;filenum++) - if (VM_FILES[filenum] == NULL) + for (filenum = 0;filenum < PRVM_MAX_OPENFILES;filenum++) + if (prog->openfiles[filenum] == NULL) break; - if (filenum >= MAX_VMFILES) + if (filenum >= PRVM_MAX_OPENFILES) { - Con_Printf("VM_fopen: %s ran out of file handles (%i)\n", PRVM_NAME, MAX_VMFILES); PRVM_G_FLOAT(OFS_RETURN) = -2; + VM_Warning("VM_fopen: %s ran out of file handles (%i)\n", PRVM_NAME, PRVM_MAX_OPENFILES); return; } mode = (int)PRVM_G_FLOAT(OFS_PARM1); @@ -1551,27 +1564,27 @@ void VM_fopen(void) modestring = "wb"; break; default: - Con_Printf("VM_fopen: %s: no such mode %i (valid: 0 = read, 1 = append, 2 = write)\n", PRVM_NAME, mode); PRVM_G_FLOAT(OFS_RETURN) = -3; + VM_Warning("VM_fopen: %s: no such mode %i (valid: 0 = read, 1 = append, 2 = write)\n", PRVM_NAME, mode); return; } filename = PRVM_G_STRING(OFS_PARM0); - VM_FILES[filenum] = FS_Open(va("data/%s", filename), modestring, false, false); - if (VM_FILES[filenum] == NULL && mode == 0) - VM_FILES[filenum] = FS_Open(va("%s", filename), modestring, false, false); + prog->openfiles[filenum] = FS_Open(va("data/%s", filename), modestring, false, false); + if (prog->openfiles[filenum] == NULL && mode == 0) + prog->openfiles[filenum] = FS_Open(va("%s", filename), modestring, false, false); - if (VM_FILES[filenum] == NULL) + if (prog->openfiles[filenum] == NULL) { - if (developer.integer >= 10) - Con_Printf("VM_fopen: %s: %s mode %s failed\n", PRVM_NAME, filename, modestring); PRVM_G_FLOAT(OFS_RETURN) = -1; + if (developer.integer >= 100) + VM_Warning("VM_fopen: %s: %s mode %s failed\n", PRVM_NAME, filename, modestring); } else { - if (developer.integer >= 10) - Con_Printf("VM_fopen: %s: %s mode %s opened as #%i\n", PRVM_NAME, filename, modestring, filenum); PRVM_G_FLOAT(OFS_RETURN) = filenum; + if (developer.integer >= 100) + Con_Printf("VM_fopen: %s: %s mode %s opened as #%i\n", PRVM_NAME, filename, modestring, filenum); } } @@ -1590,20 +1603,20 @@ void VM_fclose(void) VM_SAFEPARMCOUNT(1,VM_fclose); filenum = (int)PRVM_G_FLOAT(OFS_PARM0); - if (filenum < 0 || filenum >= MAX_VMFILES) + if (filenum < 0 || filenum >= PRVM_MAX_OPENFILES) { - Con_Printf("VM_fclose: invalid file handle %i used in %s\n", filenum, PRVM_NAME); + VM_Warning("VM_fclose: invalid file handle %i used in %s\n", filenum, PRVM_NAME); return; } - if (VM_FILES[filenum] == NULL) + if (prog->openfiles[filenum] == NULL) { - Con_Printf("VM_fclose: no such file handle %i (or file has been closed) in %s\n", filenum, PRVM_NAME); + VM_Warning("VM_fclose: no such file handle %i (or file has been closed) in %s\n", filenum, PRVM_NAME); return; } - if (developer.integer >= 10) + FS_Close(prog->openfiles[filenum]); + prog->openfiles[filenum] = NULL; + if (developer.integer >= 100) Con_Printf("VM_fclose: %s: #%i closed\n", PRVM_NAME, filenum); - FS_Close(VM_FILES[filenum]); - VM_FILES[filenum] = NULL; } /* @@ -1623,20 +1636,20 @@ void VM_fgets(void) VM_SAFEPARMCOUNT(1,VM_fgets); filenum = (int)PRVM_G_FLOAT(OFS_PARM0); - if (filenum < 0 || filenum >= MAX_VMFILES) + if (filenum < 0 || filenum >= PRVM_MAX_OPENFILES) { - Con_Printf("VM_fgets: invalid file handle %i used in %s\n", filenum, PRVM_NAME); + VM_Warning("VM_fgets: invalid file handle %i used in %s\n", filenum, PRVM_NAME); return; } - if (VM_FILES[filenum] == NULL) + if (prog->openfiles[filenum] == NULL) { - Con_Printf("VM_fgets: no such file handle %i (or file has been closed) in %s\n", filenum, PRVM_NAME); + VM_Warning("VM_fgets: no such file handle %i (or file has been closed) in %s\n", filenum, PRVM_NAME); return; } end = 0; for (;;) { - c = FS_Getc(VM_FILES[filenum]); + c = FS_Getc(prog->openfiles[filenum]); if (c == '\r' || c == '\n' || c < 0) break; if (end < VM_STRINGTEMP_LENGTH - 1) @@ -1646,9 +1659,9 @@ void VM_fgets(void) // remove \n following \r if (c == '\r') { - c = FS_Getc(VM_FILES[filenum]); + c = FS_Getc(prog->openfiles[filenum]); if (c != '\n') - FS_UnGetc(VM_FILES[filenum], (unsigned char)c); + FS_UnGetc(prog->openfiles[filenum], (unsigned char)c); } if (developer.integer >= 100) Con_Printf("fgets: %s: %s\n", PRVM_NAME, string); @@ -1675,19 +1688,19 @@ void VM_fputs(void) VM_SAFEPARMCOUNT(2,VM_fputs); filenum = (int)PRVM_G_FLOAT(OFS_PARM0); - if (filenum < 0 || filenum >= MAX_VMFILES) + if (filenum < 0 || filenum >= PRVM_MAX_OPENFILES) { - Con_Printf("VM_fputs: invalid file handle %i used in %s\n", filenum, PRVM_NAME); + VM_Warning("VM_fputs: invalid file handle %i used in %s\n", filenum, PRVM_NAME); return; } - if (VM_FILES[filenum] == NULL) + if (prog->openfiles[filenum] == NULL) { - Con_Printf("VM_fputs: no such file handle %i (or file has been closed) in %s\n", filenum, PRVM_NAME); + VM_Warning("VM_fputs: no such file handle %i (or file has been closed) in %s\n", filenum, PRVM_NAME); return; } VM_VarString(1, string, sizeof(string)); if ((stringlength = (int)strlen(string))) - FS_Write(VM_FILES[filenum], string, stringlength); + FS_Write(prog->openfiles[filenum], string, stringlength); if (developer.integer >= 100) Con_Printf("fputs: %s: %s\n", PRVM_NAME, string); } @@ -1795,12 +1808,14 @@ void VM_strzone(void) { char *out; char string[VM_STRINGTEMP_LENGTH]; + size_t alloclen; VM_SAFEPARMCOUNT(1,VM_strzone); VM_VarString(0, string, sizeof(string)); - PRVM_G_INT(OFS_RETURN) = PRVM_AllocString(strlen(string) + 1, &out); - strcpy(out, string); + alloclen = strlen(string) + 1; + PRVM_G_INT(OFS_RETURN) = PRVM_AllocString(alloclen, &out); + memcpy(out, string, alloclen); } /* @@ -1836,7 +1851,7 @@ void VM_clcommand (void) i = (int)PRVM_G_FLOAT(OFS_PARM0); if (!sv.active || i < 0 || i >= svs.maxclients || !svs.clients[i].active) { - Con_Printf("VM_clientcommand: %s: invalid client/server is not active !\n", PRVM_NAME); + VM_Warning("VM_clientcommand: %s: invalid client/server is not active !\n", PRVM_NAME); return; } @@ -1872,13 +1887,15 @@ void VM_tokenize (void) pos = 0; while(COM_ParseToken(&p, false)) { + size_t tokenlen; if (num_tokens >= (int)(sizeof(tokens)/sizeof(tokens[0]))) break; - if (pos + strlen(com_token) + 1 > sizeof(tokenbuf)) + tokenlen = strlen(com_token) + 1; + if (pos + tokenlen > sizeof(tokenbuf)) break; tokens[num_tokens++] = tokenbuf + pos; - strcpy(tokenbuf + pos, com_token); - pos += strlen(com_token) + 1; + memcpy(tokenbuf + pos, com_token, tokenlen); + pos += tokenlen; } PRVM_G_FLOAT(OFS_RETURN) = num_tokens; @@ -2003,9 +2020,9 @@ void VM_getostype(void) OS_MAC - not supported */ -#ifdef _WIN32 +#ifdef WIN32 PRVM_G_FLOAT(OFS_RETURN) = 0; -#elif defined _MAC +#elif defined(MACOSX) PRVM_G_FLOAT(OFS_RETURN) = 2; #else PRVM_G_FLOAT(OFS_RETURN) = 1; @@ -2079,7 +2096,7 @@ void VM_parseentitydata(void) data = PRVM_G_STRING(OFS_PARM1); // parse the opening brace - if (!COM_ParseToken(&data, false) || com_token[0] != '{' ) + if (!COM_ParseTokenConsole(&data) || com_token[0] != '{' ) PRVM_ERROR ("VM_parseentitydata: %s: Couldn't parse entity data:\n%s", PRVM_NAME, data ); PRVM_ED_ParseEdict (data, ent); @@ -2106,8 +2123,8 @@ void VM_loadfromfile(void) // \ is a windows-ism (so it's naughty to use it, / works on all platforms) if ((filename[0] == '.' && filename[1] == '.') || filename[0] == '/' || strrchr(filename, ':') || strrchr(filename, '\\')) { - Con_Printf("VM_loadfromfile: %s dangerous or non-portable filename \"%s\" not allowed. (contains : or \\ or begins with .. or /)\n", PRVM_NAME, filename); PRVM_G_FLOAT(OFS_RETURN) = -4; + VM_Warning("VM_loadfromfile: %s dangerous or non-portable filename \"%s\" not allowed. (contains : or \\ or begins with .. or /)\n", PRVM_NAME, filename); return; } @@ -2143,17 +2160,21 @@ void VM_modulo(void) void VM_Search_Init(void) { - memset(VM_SEARCHLIST,0,sizeof(fssearch_t*[MAX_VMSEARCHES])); + int i; + for (i = 0;i < PRVM_MAX_OPENSEARCHES;i++) + prog->opensearches[i] = NULL; } void VM_Search_Reset(void) { int i; // reset the fssearch list - for(i = 0; i < MAX_VMSEARCHES; i++) - if(VM_SEARCHLIST[i]) - FS_FreeSearch(VM_SEARCHLIST[i]); - memset(VM_SEARCHLIST,0,sizeof(fssearch_t*[MAX_VMSEARCHES])); + for(i = 0; i < PRVM_MAX_OPENSEARCHES; i++) + { + if(prog->opensearches[i]) + FS_FreeSearch(prog->opensearches[i]); + prog->opensearches[i] = NULL; + } } /* @@ -2178,18 +2199,18 @@ void VM_search_begin(void) caseinsens = (int)PRVM_G_FLOAT(OFS_PARM1); quiet = (int)PRVM_G_FLOAT(OFS_PARM2); - for(handle = 0; handle < MAX_VMSEARCHES; handle++) - if(!VM_SEARCHLIST[handle]) + for(handle = 0; handle < PRVM_MAX_OPENSEARCHES; handle++) + if(!prog->opensearches[handle]) break; - if(handle >= MAX_VMSEARCHES) + if(handle >= PRVM_MAX_OPENSEARCHES) { - Con_Printf("VM_search_begin: %s ran out of search handles (%i)\n", PRVM_NAME, MAX_VMSEARCHES); PRVM_G_FLOAT(OFS_RETURN) = -2; + VM_Warning("VM_search_begin: %s ran out of search handles (%i)\n", PRVM_NAME, PRVM_MAX_OPENSEARCHES); return; } - if(!(VM_SEARCHLIST[handle] = FS_Search(pattern,caseinsens, quiet))) + if(!(prog->opensearches[handle] = FS_Search(pattern,caseinsens, quiet))) PRVM_G_FLOAT(OFS_RETURN) = -1; else PRVM_G_FLOAT(OFS_RETURN) = handle; @@ -2209,19 +2230,19 @@ void VM_search_end(void) handle = (int)PRVM_G_FLOAT(OFS_PARM0); - if(handle < 0 || handle >= MAX_VMSEARCHES) + if(handle < 0 || handle >= PRVM_MAX_OPENSEARCHES) { - Con_Printf("VM_search_end: invalid handle %i used in %s\n", handle, PRVM_NAME); + VM_Warning("VM_search_end: invalid handle %i used in %s\n", handle, PRVM_NAME); return; } - if(VM_SEARCHLIST[handle] == NULL) + if(prog->opensearches[handle] == NULL) { - Con_Printf("VM_search_end: no such handle %i in %s\n", handle, PRVM_NAME); + VM_Warning("VM_search_end: no such handle %i in %s\n", handle, PRVM_NAME); return; } - FS_FreeSearch(VM_SEARCHLIST[handle]); - VM_SEARCHLIST[handle] = NULL; + FS_FreeSearch(prog->opensearches[handle]); + prog->opensearches[handle] = NULL; } /* @@ -2238,18 +2259,18 @@ void VM_search_getsize(void) handle = (int)PRVM_G_FLOAT(OFS_PARM0); - if(handle < 0 || handle >= MAX_VMSEARCHES) + if(handle < 0 || handle >= PRVM_MAX_OPENSEARCHES) { - Con_Printf("VM_search_getsize: invalid handle %i used in %s\n", handle, PRVM_NAME); + VM_Warning("VM_search_getsize: invalid handle %i used in %s\n", handle, PRVM_NAME); return; } - if(VM_SEARCHLIST[handle] == NULL) + if(prog->opensearches[handle] == NULL) { - Con_Printf("VM_search_getsize: no such handle %i in %s\n", handle, PRVM_NAME); + VM_Warning("VM_search_getsize: no such handle %i in %s\n", handle, PRVM_NAME); return; } - PRVM_G_FLOAT(OFS_RETURN) = VM_SEARCHLIST[handle]->numfilenames; + PRVM_G_FLOAT(OFS_RETURN) = prog->opensearches[handle]->numfilenames; } /* @@ -2268,24 +2289,24 @@ void VM_search_getfilename(void) handle = (int)PRVM_G_FLOAT(OFS_PARM0); filenum = (int)PRVM_G_FLOAT(OFS_PARM1); - if(handle < 0 || handle >= MAX_VMSEARCHES) + if(handle < 0 || handle >= PRVM_MAX_OPENSEARCHES) { - Con_Printf("VM_search_getfilename: invalid handle %i used in %s\n", handle, PRVM_NAME); + VM_Warning("VM_search_getfilename: invalid handle %i used in %s\n", handle, PRVM_NAME); return; } - if(VM_SEARCHLIST[handle] == NULL) + if(prog->opensearches[handle] == NULL) { - Con_Printf("VM_search_getfilename: no such handle %i in %s\n", handle, PRVM_NAME); + VM_Warning("VM_search_getfilename: no such handle %i in %s\n", handle, PRVM_NAME); return; } - if(filenum < 0 || filenum >= VM_SEARCHLIST[handle]->numfilenames) + if(filenum < 0 || filenum >= prog->opensearches[handle]->numfilenames) { - Con_Printf("VM_search_getfilename: invalid filenum %i in %s\n", filenum, PRVM_NAME); + VM_Warning("VM_search_getfilename: invalid filenum %i in %s\n", filenum, PRVM_NAME); return; } tmp = VM_GetTempString(); - strcpy(tmp, VM_SEARCHLIST[handle]->filenames[filenum]); + strlcpy(tmp, prog->opensearches[handle]->filenames[filenum], VM_STRINGTEMP_LENGTH); PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(tmp); } @@ -2393,8 +2414,8 @@ void VM_drawcharacter(void) character = (char) PRVM_G_FLOAT(OFS_PARM1); if(character == 0) { - Con_Printf("VM_drawcharacter: %s passed null character !\n",PRVM_NAME); PRVM_G_FLOAT(OFS_RETURN) = -1; + VM_Warning("VM_drawcharacter: %s passed null character !\n",PRVM_NAME); return; } @@ -2405,8 +2426,8 @@ void VM_drawcharacter(void) if(flag < DRAWFLAG_NORMAL || flag >=DRAWFLAG_NUMFLAGS) { - Con_Printf("VM_drawcharacter: %s: wrong DRAWFLAG %i !\n",PRVM_NAME,flag); PRVM_G_FLOAT(OFS_RETURN) = -2; + VM_Warning("VM_drawcharacter: %s: wrong DRAWFLAG %i !\n",PRVM_NAME,flag); return; } @@ -2415,8 +2436,8 @@ void VM_drawcharacter(void) if(!scale[0] || !scale[1]) { - Con_Printf("VM_drawcharacter: scale %s is null !\n", (scale[0] == 0) ? ((scale[1] == 0) ? "x and y" : "x") : "y"); PRVM_G_FLOAT(OFS_RETURN) = -3; + VM_Warning("VM_drawcharacter: scale %s is null !\n", (scale[0] == 0) ? ((scale[1] == 0) ? "x and y" : "x") : "y"); return; } @@ -2441,8 +2462,8 @@ void VM_drawstring(void) string = PRVM_G_STRING(OFS_PARM1); if(!string) { - Con_Printf("VM_drawstring: %s passed null string !\n",PRVM_NAME); PRVM_G_FLOAT(OFS_RETURN) = -1; + VM_Warning("VM_drawstring: %s passed null string !\n",PRVM_NAME); return; } @@ -2455,15 +2476,15 @@ void VM_drawstring(void) if(flag < DRAWFLAG_NORMAL || flag >=DRAWFLAG_NUMFLAGS) { - Con_Printf("VM_drawstring: %s: wrong DRAWFLAG %i !\n",PRVM_NAME,flag); PRVM_G_FLOAT(OFS_RETURN) = -2; + VM_Warning("VM_drawstring: %s: wrong DRAWFLAG %i !\n",PRVM_NAME,flag); return; } if(!scale[0] || !scale[1]) { - Con_Printf("VM_drawstring: scale %s is null !\n", (scale[0] == 0) ? ((scale[1] == 0) ? "x and y" : "x") : "y"); PRVM_G_FLOAT(OFS_RETURN) = -3; + VM_Warning("VM_drawstring: scale %s is null !\n", (scale[0] == 0) ? ((scale[1] == 0) ? "x and y" : "x") : "y"); return; } @@ -2492,8 +2513,8 @@ void VM_drawpic(void) if(!picname) { - Con_Printf("VM_drawpic: %s passed null picture name !\n", PRVM_NAME); PRVM_G_FLOAT(OFS_RETURN) = -1; + VM_Warning("VM_drawpic: %s passed null picture name !\n", PRVM_NAME); return; } @@ -2502,8 +2523,8 @@ void VM_drawpic(void) // is pic cached ? no function yet for that if(!1) { - Con_Printf("VM_drawpic: %s: %s not cached !\n", PRVM_NAME, picname); PRVM_G_FLOAT(OFS_RETURN) = -4; + VM_Warning("VM_drawpic: %s: %s not cached !\n", PRVM_NAME, picname); return; } @@ -2514,8 +2535,8 @@ void VM_drawpic(void) if(flag < DRAWFLAG_NORMAL || flag >=DRAWFLAG_NUMFLAGS) { - Con_Printf("VM_drawstring: %s: wrong DRAWFLAG %i !\n",PRVM_NAME,flag); PRVM_G_FLOAT(OFS_RETURN) = -2; + VM_Warning("VM_drawstring: %s: wrong DRAWFLAG %i !\n",PRVM_NAME,flag); return; } @@ -2548,8 +2569,8 @@ void VM_drawfill(void) if(flag < DRAWFLAG_NORMAL || flag >=DRAWFLAG_NUMFLAGS) { - Con_Printf("VM_drawstring: %s: wrong DRAWFLAG %i !\n",PRVM_NAME,flag); PRVM_G_FLOAT(OFS_RETURN) = -2; + VM_Warning("VM_drawstring: %s: wrong DRAWFLAG %i !\n",PRVM_NAME,flag); return; } @@ -2639,7 +2660,7 @@ void VM_keynumtostring (void) tmp = VM_GetTempString(); - strcpy(tmp, Key_KeynumToString(keynum)); + strlcpy(tmp, Key_KeynumToString(keynum), VM_STRINGTEMP_LENGTH); PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(tmp); } @@ -2851,72 +2872,80 @@ void VM_InitPolygons (void) vm_polygons_initialized = true; } -void VM_DrawPolygonCallback (const entity_render_t *ent, int surfacenumber, const rtlight_t *rtlight) +void VM_DrawPolygonCallback (const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist) { - const vm_polygon_t *p = &vm_polygons[surfacenumber]; - int flags = p->flags & 0x0f; + int surfacelistindex; + // LordHavoc: FIXME: this is stupid code + for (surfacelistindex = 0;surfacelistindex < numsurfaces;surfacelistindex++) + { + const vm_polygon_t *p = &vm_polygons[surfacelist[surfacelistindex]]; + int flags = p->flags & 0x0f; - if(flags == DRAWFLAG_ADDITIVE) - GL_BlendFunc(GL_SRC_ALPHA, GL_ONE); - else if(flags == DRAWFLAG_MODULATE) - GL_BlendFunc(GL_DST_COLOR, GL_ZERO); - else if(flags == DRAWFLAG_2XMODULATE) - GL_BlendFunc(GL_DST_COLOR,GL_SRC_COLOR); - else - GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + if(flags == DRAWFLAG_ADDITIVE) + GL_BlendFunc(GL_SRC_ALPHA, GL_ONE); + else if(flags == DRAWFLAG_MODULATE) + GL_BlendFunc(GL_DST_COLOR, GL_ZERO); + else if(flags == DRAWFLAG_2XMODULATE) + GL_BlendFunc(GL_DST_COLOR,GL_SRC_COLOR); + else + GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - R_Mesh_TexBind(0, R_GetTexture(p->tex)); + R_Mesh_TexBind(0, R_GetTexture(p->tex)); - //[515]: is speed is max ? - if(p->flags & VM_POLYGON_FLLINES) //[515]: lines - { - qglLineWidth(p->data[13]); - qglBegin(GL_LINE_LOOP); - qglTexCoord1f (p->data[12]); - qglColor4f (p->data[20], p->data[21], p->data[22], p->data[23]); - qglVertex3f (p->data[0] , p->data[1], p->data[2]); + CHECKGLERROR + //[515]: is speed is max ? + if(p->flags & VM_POLYGON_FLLINES) //[515]: lines + { + qglLineWidth(p->data[13]);CHECKGLERROR + qglBegin(GL_LINE_LOOP); + qglTexCoord1f (p->data[12]); + qglColor4f (p->data[20], p->data[21], p->data[22], p->data[23]); + qglVertex3f (p->data[0] , p->data[1], p->data[2]); - qglTexCoord1f (p->data[14]); - qglColor4f (p->data[24], p->data[25], p->data[26], p->data[27]); - qglVertex3f (p->data[3] , p->data[4], p->data[5]); + qglTexCoord1f (p->data[14]); + qglColor4f (p->data[24], p->data[25], p->data[26], p->data[27]); + qglVertex3f (p->data[3] , p->data[4], p->data[5]); - if(p->flags & VM_POLYGON_FL3V) - { - qglTexCoord1f (p->data[16]); + if(p->flags & VM_POLYGON_FL3V) + { + qglTexCoord1f (p->data[16]); + qglColor4f (p->data[28], p->data[29], p->data[30], p->data[31]); + qglVertex3f (p->data[6] , p->data[7], p->data[8]); + + if(p->flags & VM_POLYGON_FL4V) + { + qglTexCoord1f (p->data[18]); + qglColor4f (p->data[32], p->data[33], p->data[34], p->data[35]); + qglVertex3f (p->data[9] , p->data[10], p->data[11]); + } + } + qglEnd(); + CHECKGLERROR + } + else + { + qglBegin(GL_POLYGON); + qglTexCoord2f (p->data[12], p->data[13]); + qglColor4f (p->data[20], p->data[21], p->data[22], p->data[23]); + qglVertex3f (p->data[0] , p->data[1], p->data[2]); + + qglTexCoord2f (p->data[14], p->data[15]); + qglColor4f (p->data[24], p->data[25], p->data[26], p->data[27]); + qglVertex3f (p->data[3] , p->data[4], p->data[5]); + + qglTexCoord2f (p->data[16], p->data[17]); qglColor4f (p->data[28], p->data[29], p->data[30], p->data[31]); qglVertex3f (p->data[6] , p->data[7], p->data[8]); if(p->flags & VM_POLYGON_FL4V) { - qglTexCoord1f (p->data[18]); + qglTexCoord2f (p->data[18], p->data[19]); qglColor4f (p->data[32], p->data[33], p->data[34], p->data[35]); qglVertex3f (p->data[9] , p->data[10], p->data[11]); } - } - qglEnd(); - } - else - { - qglBegin(GL_POLYGON); - qglTexCoord2f (p->data[12], p->data[13]); - qglColor4f (p->data[20], p->data[21], p->data[22], p->data[23]); - qglVertex3f (p->data[0] , p->data[1], p->data[2]); - - qglTexCoord2f (p->data[14], p->data[15]); - qglColor4f (p->data[24], p->data[25], p->data[26], p->data[27]); - qglVertex3f (p->data[3] , p->data[4], p->data[5]); - - qglTexCoord2f (p->data[16], p->data[17]); - qglColor4f (p->data[28], p->data[29], p->data[30], p->data[31]); - qglVertex3f (p->data[6] , p->data[7], p->data[8]); - - if(p->flags & VM_POLYGON_FL4V) - { - qglTexCoord2f (p->data[18], p->data[19]); - qglColor4f (p->data[32], p->data[33], p->data[34], p->data[35]); - qglVertex3f (p->data[9] , p->data[10], p->data[11]); - } - qglEnd(); + qglEnd(); + CHECKGLERROR + } } } @@ -2958,7 +2987,7 @@ void VM_R_PolygonBegin (void) VM_InitPolygons(); if(vm_polygonbegin) { - Con_Printf("VM_R_PolygonBegin: called twice without VM_R_PolygonEnd after first\n"); + VM_Warning("VM_R_PolygonBegin: called twice without VM_R_PolygonEnd after first\n"); return; } if(vm_drawpolygons_num >= vm_polygons_num) @@ -2975,7 +3004,7 @@ void VM_R_PolygonBegin (void) if(picname[0]) p->tex = Draw_CachePic(picname, true)->tex; else - p->tex = r_texture_notexture; + p->tex = r_texture_white; p->flags = (unsigned char)PRVM_G_FLOAT(OFS_PARM1); vm_current_vertices = 0; vm_polygonbegin = true; @@ -3000,7 +3029,7 @@ void VM_R_PolygonVertex (void) if(!vm_polygonbegin) { - Con_Printf("VM_R_PolygonVertex: VM_R_PolygonBegin wasn't called\n"); + VM_Warning("VM_R_PolygonVertex: VM_R_PolygonBegin wasn't called\n"); return; } coords = PRVM_G_VECTOR(OFS_PARM0); @@ -3011,14 +3040,13 @@ void VM_R_PolygonVertex (void) p = &vm_polygons[vm_drawpolygons_num]; if(vm_current_vertices > 4) { - Con_Printf("VM_R_PolygonVertex: may have 4 vertices max\n"); + VM_Warning("VM_R_PolygonVertex: may have 4 vertices max\n"); return; } p->data[vm_current_vertices*3] = coords[0]; p->data[1+vm_current_vertices*3] = coords[1]; - if(!(p->flags & VM_POLYGON_FL2D)) - p->data[2+vm_current_vertices*3] = coords[2]; + p->data[2+vm_current_vertices*3] = coords[2]; p->data[12+vm_current_vertices*2] = tx[0]; if(!(p->flags & VM_POLYGON_FLLINES)) @@ -3042,9 +3070,10 @@ void VM_R_PolygonEnd (void) { if(!vm_polygonbegin) { - Con_Printf("VM_R_PolygonEnd: VM_R_PolygonBegin wasn't called\n"); + VM_Warning("VM_R_PolygonEnd: VM_R_PolygonBegin wasn't called\n"); return; } + vm_polygonbegin = false; if(vm_current_vertices > 2 || (vm_current_vertices >= 2 && vm_polygons[vm_drawpolygons_num].flags & VM_POLYGON_FLLINES)) { if(vm_polygons[vm_drawpolygons_num].flags & VM_POLYGON_FL2D) //[515]: don't use qcpolygons memory if 2D @@ -3053,8 +3082,7 @@ void VM_R_PolygonEnd (void) vm_drawpolygons_num++; } else - Con_Printf("VM_R_PolygonEnd: %i vertices isn't a good choice\n", vm_current_vertices); - vm_polygonbegin = false; + VM_Warning("VM_R_PolygonEnd: %i vertices isn't a good choice\n", vm_current_vertices); } void VM_AddPolygonsToMeshQueue (void) @@ -3063,7 +3091,7 @@ void VM_AddPolygonsToMeshQueue (void) if(!vm_drawpolygons_num) return; for(i = 0;i < vm_drawpolygons_num;i++) - R_MeshQueue_Add(VM_DrawPolygonCallback, NULL, i, NULL); + VM_DrawPolygonCallback(NULL, NULL, i, NULL); vm_drawpolygons_num = 0; } @@ -3251,7 +3279,7 @@ void VM_altstr_set( void ) return; } - strcpy( out, in ); + strlcpy(out, in, VM_STRINGTEMP_LENGTH); PRVM_G_INT( OFS_RETURN ) = PRVM_SetEngineString( outstr ); } @@ -3290,7 +3318,7 @@ void VM_altstr_ins(void) for( ; *set ; *out++ = *set++ ); *out++ = '\''; - strcpy( out, in ); + strlcpy(out, in, VM_STRINGTEMP_LENGTH); PRVM_G_INT( OFS_RETURN ) = PRVM_SetEngineString( outstr ); } @@ -3427,7 +3455,7 @@ void VM_buf_del (void) BufStr_ClearBuffer((int)PRVM_G_FLOAT(OFS_PARM0)); else { - Con_Printf("VM_buf_del: invalid buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), PRVM_NAME); + VM_Warning("VM_buf_del: invalid buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), PRVM_NAME); return; } } @@ -3448,7 +3476,7 @@ void VM_buf_getsize (void) if(!b) { PRVM_G_FLOAT(OFS_RETURN) = -1; - Con_Printf("VM_buf_getsize: invalid buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), PRVM_NAME); + VM_Warning("VM_buf_getsize: invalid buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), PRVM_NAME); return; } else @@ -3471,19 +3499,19 @@ void VM_buf_copy (void) b1 = BUFSTR_BUFFER((int)PRVM_G_FLOAT(OFS_PARM0)); if(!b1) { - Con_Printf("VM_buf_copy: invalid source buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), PRVM_NAME); + VM_Warning("VM_buf_copy: invalid source buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), PRVM_NAME); return; } i = (int)PRVM_G_FLOAT(OFS_PARM1); if(i == (int)PRVM_G_FLOAT(OFS_PARM0)) { - Con_Printf("VM_buf_copy: source == destination (%i) in %s\n", i, PRVM_NAME); + VM_Warning("VM_buf_copy: source == destination (%i) in %s\n", i, PRVM_NAME); return; } b2 = BUFSTR_BUFFER(i); if(!b2) { - Con_Printf("VM_buf_copy: invalid destination buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM1), PRVM_NAME); + VM_Warning("VM_buf_copy: invalid destination buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM1), PRVM_NAME); return; } @@ -3495,13 +3523,15 @@ void VM_buf_copy (void) for(i=0;inum_strings;i++) if(b1->strings[i] && b1->strings[i][0]) { - b2->strings[i] = (char *)Z_Malloc(strlen(b1->strings[i])+1); + size_t stringlen; + stringlen = strlen(b1->strings[i]) + 1; + b2->strings[i] = (char *)Z_Malloc(stringlen); if(!b2->strings[i]) { - Con_Printf("VM_buf_copy: not enough memory for buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM1), PRVM_NAME); + VM_Warning("VM_buf_copy: not enough memory for buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM1), PRVM_NAME); break; } - strcpy(b2->strings[i], b1->strings[i]); + memcpy(b2->strings[i], b1->strings[i], stringlen); } } @@ -3522,12 +3552,12 @@ void VM_buf_sort (void) b = BUFSTR_BUFFER((int)PRVM_G_FLOAT(OFS_PARM0)); if(!b) { - Con_Printf("VM_buf_sort: invalid buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), PRVM_NAME); + VM_Warning("VM_buf_sort: invalid buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), PRVM_NAME); return; } if(b->num_strings <= 0) { - Con_Printf("VM_buf_sort: tried to sort empty buffer %i in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), PRVM_NAME); + VM_Warning("VM_buf_sort: tried to sort empty buffer %i in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), PRVM_NAME); return; } buf_sortpower = (int)PRVM_G_FLOAT(OFS_PARM1); @@ -3575,7 +3605,7 @@ void VM_buf_implode (void) PRVM_G_INT(OFS_RETURN) = 0; if(!b) { - Con_Printf("VM_buf_implode: invalid buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), PRVM_NAME); + VM_Warning("VM_buf_implode: invalid buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), PRVM_NAME); return; } if(!b->num_strings) @@ -3589,17 +3619,13 @@ void VM_buf_implode (void) l += strlen(b->strings[i]); if(l>=4095) break; - k = strcat(k, b->strings[i]); - if(!k) - break; + strlcat(k, b->strings[i], VM_STRINGTEMP_LENGTH); if(sep && (i != b->num_strings-1)) { l += strlen(sep); if(l>=4095) break; - k = strcat(k, sep); - if(!k) - break; + strlcat(k, sep, VM_STRINGTEMP_LENGTH); } } PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(k); @@ -3621,13 +3647,13 @@ void VM_bufstr_get (void) b = BUFSTR_BUFFER((int)PRVM_G_FLOAT(OFS_PARM0)); if(!b) { - Con_Printf("VM_bufstr_get: invalid buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), PRVM_NAME); + VM_Warning("VM_bufstr_get: invalid buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), PRVM_NAME); return; } strindex = (int)PRVM_G_FLOAT(OFS_PARM1); if(strindex < 0 || strindex > MAX_QCSTR_STRINGS) { - Con_Printf("VM_bufstr_get: invalid string index %i used in %s\n", strindex, PRVM_NAME); + VM_Warning("VM_bufstr_get: invalid string index %i used in %s\n", strindex, PRVM_NAME); return; } PRVM_G_INT(OFS_RETURN) = 0; @@ -3649,6 +3675,7 @@ void VM_bufstr_set (void) int bufindex, strindex; qcstrbuffer_t *b; const char *news; + size_t alloclen; VM_SAFEPARMCOUNT(3, VM_bufstr_set); @@ -3656,25 +3683,26 @@ void VM_bufstr_set (void) b = BUFSTR_BUFFER(bufindex); if(!b) { - Con_Printf("VM_bufstr_set: invalid buffer %i used in %s\n", bufindex, PRVM_NAME); + VM_Warning("VM_bufstr_set: invalid buffer %i used in %s\n", bufindex, PRVM_NAME); return; } strindex = (int)PRVM_G_FLOAT(OFS_PARM1); if(strindex < 0 || strindex > MAX_QCSTR_STRINGS) { - Con_Printf("VM_bufstr_set: invalid string index %i used in %s\n", strindex, PRVM_NAME); + VM_Warning("VM_bufstr_set: invalid string index %i used in %s\n", strindex, PRVM_NAME); return; } news = PRVM_G_STRING(OFS_PARM2); if(!news) { - Con_Printf("VM_bufstr_set: null string used in %s\n", PRVM_NAME); + VM_Warning("VM_bufstr_set: null string used in %s\n", PRVM_NAME); return; } if(b->strings[strindex]) Z_Free(b->strings[strindex]); - b->strings[strindex] = (char *)Z_Malloc(strlen(news)+1); - strcpy(b->strings[strindex], news); + alloclen = strlen(news) + 1; + b->strings[strindex] = (char *)Z_Malloc(alloclen); + memcpy(b->strings[strindex], news, alloclen); } /* @@ -3690,6 +3718,7 @@ void VM_bufstr_add (void) int bufindex, order, strindex; qcstrbuffer_t *b; const char *string; + size_t alloclen; VM_SAFEPARMCOUNT(3, VM_bufstr_add); @@ -3698,13 +3727,13 @@ void VM_bufstr_add (void) PRVM_G_FLOAT(OFS_RETURN) = -1; if(!b) { - Con_Printf("VM_bufstr_add: invalid buffer %i used in %s\n", bufindex, PRVM_NAME); + VM_Warning("VM_bufstr_add: invalid buffer %i used in %s\n", bufindex, PRVM_NAME); return; } string = PRVM_G_STRING(OFS_PARM1); if(!string) { - Con_Printf("VM_bufstr_add: null string used in %s\n", PRVM_NAME); + VM_Warning("VM_bufstr_add: null string used in %s\n", PRVM_NAME); return; } @@ -3716,7 +3745,7 @@ void VM_bufstr_add (void) strindex = BufStr_FindFreeString(b); if(strindex < 0) { - Con_Printf("VM_bufstr_add: buffer %i has no free string slots in %s\n", bufindex, PRVM_NAME); + VM_Warning("VM_bufstr_add: buffer %i has no free string slots in %s\n", bufindex, PRVM_NAME); return; } } @@ -3725,7 +3754,7 @@ void VM_bufstr_add (void) { if(b->num_strings == MAX_QCSTR_STRINGS) { - Con_Printf("VM_bufstr_add: buffer %i has no free string slots in %s\n", bufindex, PRVM_NAME); + VM_Warning("VM_bufstr_add: buffer %i has no free string slots in %s\n", bufindex, PRVM_NAME); return; } b->strings[b->num_strings] = NULL; @@ -3733,8 +3762,9 @@ void VM_bufstr_add (void) } if(b->strings[strindex]) Z_Free(b->strings[strindex]); - b->strings[strindex] = (char *)Z_Malloc(strlen(string)+1); - strcpy(b->strings[strindex], string); + alloclen = strlen(string) + 1; + b->strings[strindex] = (char *)Z_Malloc(alloclen); + memcpy(b->strings[strindex], string, alloclen); PRVM_G_FLOAT(OFS_RETURN) = strindex; } @@ -3754,13 +3784,13 @@ void VM_bufstr_free (void) b = BUFSTR_BUFFER((int)PRVM_G_FLOAT(OFS_PARM0)); if(!b) { - Con_Printf("VM_bufstr_free: invalid buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), PRVM_NAME); + VM_Warning("VM_bufstr_free: invalid buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), PRVM_NAME); return; } i = (int)PRVM_G_FLOAT(OFS_PARM1); if(i < 0 || i > MAX_QCSTR_STRINGS) { - Con_Printf("VM_bufstr_free: invalid string index %i used in %s\n", i, PRVM_NAME); + VM_Warning("VM_bufstr_free: invalid string index %i used in %s\n", i, PRVM_NAME); return; } if(b->strings[i])