X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=prvm_cmds.c;h=67cd6f9af97bbfe018e211cd9168c2708cf1a9c6;hb=c1d9e759b83908c5398daf43a94f8585b9c7356a;hp=0b4fb015b32a5798be9b43617e7dceb41420e548;hpb=f7942c3a41dbea29b68274312abf47c2755a7606;p=xonotic%2Fdarkplaces.git diff --git a/prvm_cmds.c b/prvm_cmds.c index 0b4fb015..67cd6f9a 100644 --- a/prvm_cmds.c +++ b/prvm_cmds.c @@ -1,7 +1,7 @@ // AK // Basically every vm builtin cmd should be in here. -// All 3 builtin list and extension lists can be found here -// cause large (I think they will) are from pr_cmds the same copyright like in pr_cms +// All 3 builtin and extension lists can be found here +// cause large (I think they will) parts are from pr_cmds the same copyright like in pr_cmds // also applies here @@ -57,7 +57,7 @@ float sin(float) float cos(float) float sqrt(float) vector randomvec() -float registercvar (string name, string value) +float registercvar (string name, string value, float flags) float min(float a, float b, ...[float]) float max(float a, float b, ...[float]) float bound(float min, float value, float max) @@ -86,6 +86,16 @@ float gettime() loadfromdata(string data) loadfromfile(string file) float mod(float val, float m) +const string str_cvar (string) + crash() + stackdump() + +float search_begin(string pattern, float caseinsensitive, float quiet) +void search_end(float handle) +float search_getsize(float handle) +string search_getfilename(float handle, float num) + +string chr(float ascii) perhaps only : Menu : WriteMsg =============================== @@ -119,9 +129,20 @@ menu cmd list: =============== setkeydest(float dest) -float getkeydest +float getkeydest() setmousetarget(float target) float getmousetarget(void) + + callfunction(...,string function_name) + writetofile(float fhandle, entity ent) +float isfunction(string function_name) +vector getresolution(float number) +string keynumtostring(float keynum) +string findkeysforcommand(string command) +float gethostcachevalue(float type) +string gethostcachestring(float type, float hostnr) + + */ #include "quakedef.h" @@ -154,9 +175,9 @@ mempool_t *vm_strings_mempool[PRVM_MAXPROGS]; // temp string handling // LordHavoc: added this to semi-fix the problem of using many ftos calls in a print -#define STRINGTEMP_BUFFERS 16 -#define STRINGTEMP_LENGTH 4096 -static char vm_string_temp[STRINGTEMP_BUFFERS][STRINGTEMP_LENGTH]; +#define VM_STRINGTEMP_BUFFERS 16 +#define VM_STRINGTEMP_LENGTH 4096 +static char vm_string_temp[VM_STRINGTEMP_BUFFERS][VM_STRINGTEMP_LENGTH]; static int vm_string_tempindex = 0; // qc cvar @@ -171,11 +192,18 @@ int vm_currentqc_cvar; 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]; + static char *VM_GetTempString(void) { char *s; s = vm_string_temp[vm_string_tempindex]; - vm_string_tempindex = (vm_string_tempindex + 1) % STRINGTEMP_BUFFERS; + vm_string_tempindex = (vm_string_tempindex + 1) % VM_STRINGTEMP_BUFFERS; return s; } @@ -259,14 +287,14 @@ error(value) void VM_error (void) { prvm_edict_t *ed; - char string[STRINGTEMP_LENGTH]; + char string[VM_STRINGTEMP_LENGTH]; VM_VarString(0, string, sizeof(string)); - Con_Printf ("======%S ERROR in %s:\n%s\n", PRVM_NAME, PRVM_GetString(prog->xfunction->s_name), string); + Con_Printf("======%S ERROR in %s:\n%s\n", PRVM_NAME, PRVM_GetString(prog->xfunction->s_name), string); if(prog->self) { ed = PRVM_G_EDICT(prog->self->ofs); - PRVM_ED_Print (ed); + PRVM_ED_Print(ed); } PRVM_ERROR ("%s: Program error", PRVM_NAME); @@ -285,14 +313,14 @@ objerror(value) void VM_objerror (void) { prvm_edict_t *ed; - char string[STRINGTEMP_LENGTH]; + char string[VM_STRINGTEMP_LENGTH]; VM_VarString(0, string, sizeof(string)); - 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\n", PRVM_NAME, PRVM_GetString(prog->xfunction->s_name), string); if(prog->self) { ed = PRVM_G_EDICT (prog->self->ofs); - PRVM_ED_Print (ed); + PRVM_ED_Print(ed); PRVM_ED_Free (ed); } @@ -312,7 +340,7 @@ print(string) */ void VM_print (void) { - char string[STRINGTEMP_LENGTH]; + char string[VM_STRINGTEMP_LENGTH]; VM_VarString(0, string, sizeof(string)); Con_Print(string); @@ -329,16 +357,16 @@ bprint(...[string]) */ void VM_bprint (void) { - char string[STRINGTEMP_LENGTH]; + char string[VM_STRINGTEMP_LENGTH]; if(!sv.active) { - Con_Printf("VM_bprint: game is not server(%s) !", PRVM_NAME); + Con_Printf("VM_bprint: game is not server(%s) !\n", PRVM_NAME); return; } VM_VarString(0, string, sizeof(string)); - SV_BroadcastPrintf("%s", string); + SV_BroadcastPrint(string); } /* @@ -354,13 +382,13 @@ void VM_sprint (void) { client_t *client; int clientnum; - char string[STRINGTEMP_LENGTH]; + char string[VM_STRINGTEMP_LENGTH]; //find client for this entity clientnum = 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 !", PRVM_NAME); + Con_Printf("VM_sprint: %s: invalid client or server is not active !\n", PRVM_NAME); return; } @@ -383,7 +411,7 @@ centerprint(clientent, value) */ void VM_centerprint (void) { - char string[STRINGTEMP_LENGTH]; + char string[VM_STRINGTEMP_LENGTH]; VM_VarString(0, string, sizeof(string)); SCR_CenterPrint(string); @@ -601,14 +629,14 @@ void VM_localsound(void) s = PRVM_G_STRING(OFS_PARM0); - if(!S_GetCached(s)) + if(!S_GetCached(s, true)) { Con_Printf("VM_localsound: %s : %s not cached !\n", PRVM_NAME, s); PRVM_G_FLOAT(OFS_RETURN) = -4; return; } - S_LocalSound(s); + S_LocalSound(s, true); PRVM_G_FLOAT(OFS_RETURN) = 1; } @@ -657,6 +685,35 @@ void VM_cvar (void) PRVM_G_FLOAT(OFS_RETURN) = Cvar_VariableValue(PRVM_G_STRING(OFS_PARM0)); } +/* +================= +VM_str_cvar + +const string str_cvar (string) +================= +*/ +void VM_str_cvar(void) +{ + char *out, *name; + const char *cvar_string; + VM_SAFEPARMCOUNT(1,VM_str_cvar); + + name = PRVM_G_STRING(OFS_PARM0); + + if(!name) + PRVM_ERROR("VM_str_cvar: %s: null string\n", PRVM_NAME); + + VM_CheckEmptyString(name); + + out = VM_GetTempString(); + + cvar_string = Cvar_VariableString(name); + + strcpy(out, cvar_string); + + PRVM_G_INT(OFS_PARM0) = PRVM_SetString(out); +} + /* ================= VM_cvar_set @@ -680,7 +737,7 @@ dprint(...[string]) */ void VM_dprint (void) { - char string[STRINGTEMP_LENGTH]; + char string[VM_STRINGTEMP_LENGTH]; if (developer.integer) { VM_VarString(0, string, sizeof(string)); @@ -778,7 +835,7 @@ float stof(...[string]) */ void VM_stof(void) { - char string[STRINGTEMP_LENGTH]; + char string[VM_STRINGTEMP_LENGTH]; VM_VarString(0, string, sizeof(string)); PRVM_G_FLOAT(OFS_RETURN) = atof(string); } @@ -803,7 +860,7 @@ void VM_spawn (void) ========= VM_remove -entity remove() +remove(entity e) ========= */ @@ -1052,14 +1109,14 @@ void VM_precache_sound (void) PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0); VM_CheckEmptyString (s); - if(S_GetCached(s)) + if(S_GetCached(s, true)) { Con_Printf("VM_precache_sound: %s already cached (%s)\n", s, PRVM_NAME); return; } - if(!S_PrecacheSound(s,true)) - Con_Printf("VM_prache_sound: Failed to load %s for %s\n", s, PRVM_NAME); + if(!S_PrecacheSound(s,true, true)) + Con_Printf("VM_precache_sound: Failed to load %s for %s\n", s, PRVM_NAME); } /* @@ -1078,6 +1135,36 @@ void VM_coredump (void) Cbuf_AddText("\n"); } +/* +========= +VM_stackdump + +stackdump() +========= +*/ +void PRVM_StackTrace(void); +void VM_stackdump (void) +{ + VM_SAFEPARMCOUNT(0, VM_stackdump); + + PRVM_StackTrace(); +} + +/* +========= +VM_crash + +crash() +========= +*/ + +void VM_crash(void) +{ + VM_SAFEPARMCOUNT(0, VM_crash); + + PRVM_ERROR("Crash called by %s\n",PRVM_NAME); +} + /* ========= VM_traceon @@ -1403,19 +1490,25 @@ void VM_randomvec (void) ========= VM_registercvar -float registercvar (string name, string value) +float registercvar (string name, string value, float flags) ========= */ void VM_registercvar (void) { char *name, *value; cvar_t *variable; + int flags; - VM_SAFEPARMCOUNT(2,VM_registercvar); + VM_SAFEPARMCOUNT(3,VM_registercvar); name = PRVM_G_STRING(OFS_PARM0); value = PRVM_G_STRING(OFS_PARM1); + flags = PRVM_G_FLOAT(OFS_PARM2); PRVM_G_FLOAT(OFS_RETURN) = 0; + + if(flags > CVAR_MAXFLAGSVAL) + return; + // first check to see if it has already been defined if (Cvar_FindVar (name)) return; @@ -1423,7 +1516,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); + Con_Printf("VM_registercvar: %s is a command\n", name); return; } @@ -1432,6 +1525,7 @@ void VM_registercvar (void) // copy the name and value variable = &vm_qc_cvar[vm_currentqc_cvar++]; + variable->flags = flags; variable->name = Z_Malloc (strlen(name)+1); strcpy (variable->name, name); variable->string = Z_Malloc (strlen(value)+1); @@ -1564,7 +1658,7 @@ setcolor(clientent, value) if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active) { - Con_Printf ("tried to setcolor a non-client\n"); + Con_Print("tried to setcolor a non-client\n"); return; } @@ -1636,7 +1730,7 @@ 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); + 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; return; } @@ -1652,6 +1746,9 @@ void VM_fopen(void) return; } VM_FILES[filenum] = FS_Open(va("data/%s", filename), modestring, false); + if (VM_FILES[filenum] == NULL && mode == 0) + VM_FILES[filenum] = FS_Open(va("%s", filename), modestring, false); + if (VM_FILES[filenum] == NULL) PRVM_G_FLOAT(OFS_RETURN) = -1; else @@ -1698,7 +1795,7 @@ string fgets(float fhandle) void VM_fgets(void) { int c, end; - static char string[STRINGTEMP_LENGTH]; + static char string[VM_STRINGTEMP_LENGTH]; int filenum; VM_SAFEPARMCOUNT(1,VM_fgets); @@ -1720,7 +1817,7 @@ void VM_fgets(void) c = FS_Getc(VM_FILES[filenum]); if (c == '\r' || c == '\n' || c < 0) break; - if (end < STRINGTEMP_LENGTH - 1) + if (end < VM_STRINGTEMP_LENGTH - 1) string[end++] = c; } string[end] = 0; @@ -1746,7 +1843,7 @@ fputs(float fhandle, string s) void VM_fputs(void) { int stringlength; - char string[STRINGTEMP_LENGTH]; + char string[VM_STRINGTEMP_LENGTH]; int filenum; VM_SAFEPARMCOUNT(2,VM_fputs); @@ -1804,11 +1901,11 @@ void VM_strcat(void) { char *s; - if(prog->argc <= 2) + if(prog->argc < 2) PRVM_ERROR("VM_strcat wrong parameter count (min. 2 expected ) !\n"); s = VM_GetTempString(); - VM_VarString(0, s, STRINGTEMP_LENGTH); + VM_VarString(0, s, VM_STRINGTEMP_LENGTH); PRVM_G_INT(OFS_RETURN) = PRVM_SetString(s); } @@ -1835,7 +1932,7 @@ void VM_substring(void) if (!s) s = ""; for (i = 0;i < start && *s;i++, s++); - for (i = 0;i < STRINGTEMP_LENGTH - 1 && *s && i < length;i++, s++) + for (i = 0;i < VM_STRINGTEMP_LENGTH - 1 && *s && i < length;i++, s++) string[i] = *s; string[i] = 0; PRVM_G_INT(OFS_RETURN) = PRVM_SetString(string); @@ -1851,7 +1948,7 @@ vector stov(string s) //vector(string s) stov = #117; // returns vector value from a string void VM_stov(void) { - char string[STRINGTEMP_LENGTH]; + char string[VM_STRINGTEMP_LENGTH]; VM_SAFEPARMCOUNT(1,VM_stov); @@ -1913,7 +2010,7 @@ void VM_clcommand (void) i = 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 !", PRVM_NAME); + Con_Printf("VM_clientcommand: %s: invalid client/server is not active !\n", PRVM_NAME); return; } @@ -2020,6 +2117,7 @@ void PF_setattachment (void) for (i = 0;i < model->data_overridetagnamesforskin[(unsigned int)tagentity->v->skin].num_overridetagnames;i++) if (!strcmp(tagname, model->data_overridetagnamesforskin[(unsigned int)tagentity->v->skin].data_overridetagnames[i].name)) v->_float = i + 1; + // FIXME: use a model function to get tag info (need to handle skeletal) if (v->_float == 0 && model->alias.aliasnum_tags) for (i = 0;i < model->alias.aliasnum_tags;i++) if (!strcmp(tagname, model->alias.aliasdata_tags[i].name)) @@ -2074,6 +2172,32 @@ void VM_clientstate(void) PRVM_G_FLOAT(OFS_RETURN) = cls.state; } +/* +========= +VM_getostype + +float getostype(void) +========= +*/ // not used at the moment -> not included in the common list +void VM_getostype(void) +{ + VM_SAFEPARMCOUNT(0,VM_getostype); + + /* + OS_WINDOWS + OS_LINUX + OS_MAC - not supported + */ + +#ifdef _WIN32 + PRVM_G_FLOAT(OFS_RETURN) = 0; +#elif defined _MAC + PRVM_G_FLOAT(OFS_RETURN) = 2; +#else + PRVM_G_FLOAT(OFS_RETURN) = 1; +#endif +} + /* ========= VM_getmousepos @@ -2146,7 +2270,7 @@ void VM_loadfromfile(void) } // not conform with VM_fopen - data = FS_LoadFile(filename, false); + data = FS_LoadFile(filename, tempmempool, false); if (data == NULL) PRVM_G_FLOAT(OFS_RETURN) = -1; @@ -2175,6 +2299,174 @@ void VM_modulo(void) PRVM_G_FLOAT(OFS_RETURN) = (float) (val % m); } +void VM_Search_Init(void) +{ + memset(VM_SEARCHLIST,0,sizeof(fssearch_t*[MAX_VMSEARCHES])); +} + +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])); +} + +/* +========= +VM_search_begin + +float search_begin(string pattern, float caseinsensitive, float quiet) +========= +*/ +void VM_search_begin(void) +{ + int handle; + char *pattern; + int caseinsens, quiet; + + VM_SAFEPARMCOUNT(3, VM_search_begin); + + pattern = PRVM_G_STRING(OFS_PARM0); + + VM_CheckEmptyString(pattern); + + caseinsens = PRVM_G_FLOAT(OFS_PARM1); + quiet = PRVM_G_FLOAT(OFS_PARM2); + + for(handle = 0; handle < MAX_VMSEARCHES; handle++) + if(!VM_SEARCHLIST[handle]) + break; + + if(handle >= MAX_VMSEARCHES) + { + Con_Printf("VM_search_begin: %s ran out of search handles (%i)\n", PRVM_NAME, MAX_VMSEARCHES); + PRVM_G_FLOAT(OFS_RETURN) = -2; + return; + } + + if(!(VM_SEARCHLIST[handle] = FS_Search(pattern,caseinsens, quiet))) + PRVM_G_FLOAT(OFS_RETURN) = -1; + else + PRVM_G_FLOAT(OFS_RETURN) = handle; +} + +/* +========= +VM_search_end + +void search_end(float handle) +========= +*/ +void VM_search_end(void) +{ + int handle; + VM_SAFEPARMCOUNT(1, VM_search_end); + + handle = PRVM_G_FLOAT(OFS_PARM0); + + if(handle < 0 || handle >= MAX_VMSEARCHES) + { + Con_Printf("VM_search_end: invalid handle %i used in %s\n", handle, PRVM_NAME); + return; + } + if(VM_SEARCHLIST[handle] == NULL) + { + Con_Printf("VM_search_end: no such handle %i in %s\n", handle, PRVM_NAME); + return; + } + + FS_FreeSearch(VM_SEARCHLIST[handle]); + VM_SEARCHLIST[handle] = NULL; +} + +/* +========= +VM_search_getsize + +float search_getsize(float handle) +========= +*/ +void VM_search_getsize(void) +{ + int handle; + VM_SAFEPARMCOUNT(1, VM_M_search_getsize); + + handle = PRVM_G_FLOAT(OFS_PARM0); + + if(handle < 0 || handle >= MAX_VMSEARCHES) + { + Con_Printf("VM_search_getsize: invalid handle %i used in %s\n", handle, PRVM_NAME); + return; + } + if(VM_SEARCHLIST[handle] == NULL) + { + Con_Printf("VM_search_getsize: no such handle %i in %s\n", handle, PRVM_NAME); + return; + } + + PRVM_G_FLOAT(OFS_RETURN) = VM_SEARCHLIST[handle]->numfilenames; +} + +/* +========= +VM_search_getfilename + +string search_getfilename(float handle, float num) +========= +*/ +void VM_search_getfilename(void) +{ + int handle, filenum; + char *tmp; + VM_SAFEPARMCOUNT(2, VM_search_getfilename); + + handle = PRVM_G_FLOAT(OFS_PARM0); + filenum = PRVM_G_FLOAT(OFS_PARM1); + + if(handle < 0 || handle >= MAX_VMSEARCHES) + { + Con_Printf("VM_search_getfilename: invalid handle %i used in %s\n", handle, PRVM_NAME); + return; + } + if(VM_SEARCHLIST[handle] == NULL) + { + Con_Printf("VM_search_getfilename: no such handle %i in %s\n", handle, PRVM_NAME); + return; + } + if(filenum < 0 || filenum >= VM_SEARCHLIST[handle]->numfilenames) + { + Con_Printf("VM_search_getfilename: invalid filenum %i in %s\n", filenum, PRVM_NAME); + return; + } + + tmp = VM_GetTempString(); + strcpy(tmp, VM_SEARCHLIST[handle]->filenames[filenum]); + + PRVM_G_INT(OFS_RETURN) = PRVM_SetString(tmp); +} + +/* +========= +VM_chr + +string chr(float ascii) +========= +*/ +void VM_chr(void) +{ + char *tmp; + VM_SAFEPARMCOUNT(1, VM_chr); + + tmp = VM_GetTempString(); + tmp[0] = (unsigned char) PRVM_G_FLOAT(OFS_PARM0); + tmp[1] = 0; + + PRVM_G_INT(OFS_RETURN) = PRVM_SetString(tmp); +} + //============================================================================= // Draw builtins (client & menu) @@ -2276,7 +2568,7 @@ void VM_drawcharacter(void) } if(pos[2] || scale[2]) - Con_Printf("VM_drawcharacter: z value%c from %s discarded",(pos[2] && scale[2]) ? 's' : 0,((pos[2] && scale[2]) ? "pos and scale" : (pos[2] ? "pos" : "scale"))); + Con_Printf("VM_drawcharacter: z value%c from %s discarded\n",(pos[2] && scale[2]) ? 's' : 0,((pos[2] && scale[2]) ? "pos and scale" : (pos[2] ? "pos" : "scale"))); if(!scale[0] || !scale[1]) { @@ -2333,7 +2625,7 @@ void VM_drawstring(void) } if(pos[2] || scale[2]) - Con_Printf("VM_drawstring: z value%c from %s discarded",(pos[2] && scale[2]) ? 's' : 0,((pos[2] && scale[2]) ? "pos and scale" : (pos[2] ? "pos" : "scale"))); + Con_Printf("VM_drawstring: z value%c from %s discarded\n",(pos[2] && scale[2]) ? 's' : 0,((pos[2] && scale[2]) ? "pos and scale" : (pos[2] ? "pos" : "scale"))); DrawQ_String (pos[0], pos[1], string, 0, scale[0], scale[1], rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM4), flag); PRVM_G_FLOAT(OFS_RETURN) = 1; @@ -2385,7 +2677,7 @@ void VM_drawpic(void) } if(pos[2] || size[2]) - Con_Printf("VM_drawstring: z value%c from %s discarded",(pos[2] && size[2]) ? 's' : 0,((pos[2] && size[2]) ? "pos and size" : (pos[2] ? "pos" : "size"))); + Con_Printf("VM_drawstring: z value%c from %s discarded\n",(pos[2] && size[2]) ? 's' : 0,((pos[2] && size[2]) ? "pos and size" : (pos[2] ? "pos" : "size"))); DrawQ_Pic(pos[0], pos[1], pic, size[0], size[1], rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM4), flag); PRVM_G_FLOAT(OFS_RETURN) = 1; @@ -2419,7 +2711,7 @@ void VM_drawfill(void) } if(pos[2] || size[2]) - Con_Printf("VM_drawstring: z value%c from %s discarded",(pos[2] && size[2]) ? 's' : 0,((pos[2] && size[2]) ? "pos and size" : (pos[2] ? "pos" : "size"))); + Con_Printf("VM_drawstring: z value%c from %s discarded\n",(pos[2] && size[2]) ? 's' : 0,((pos[2] && size[2]) ? "pos and size" : (pos[2] ? "pos" : "size"))); DrawQ_Pic(pos[0], pos[1], 0, size[0], size[1], rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM3), flag); PRVM_G_FLOAT(OFS_RETURN) = 1; @@ -2439,8 +2731,8 @@ void VM_drawsetcliparea(void) x = bound(0,PRVM_G_FLOAT(OFS_PARM0),vid.conwidth); y = bound(0,PRVM_G_FLOAT(OFS_PARM1),vid.conheight); - w = bound(0,PRVM_G_FLOAT(OFS_PARM2),x); - h = bound(0,PRVM_G_FLOAT(OFS_PARM3),y); + w = bound(0,PRVM_G_FLOAT(OFS_PARM2),(vid.conwidth - x)); + h = bound(0,PRVM_G_FLOAT(OFS_PARM3),(vid.conheight - y)); DrawQ_SetClipArea(x,y,w,h); } @@ -2490,13 +2782,16 @@ void VM_getimagesize(void) void VM_Cmd_Init(void) { // only init the stuff for the current prog - VM_STRINGS_MEMPOOL = Mem_AllocPool(va("vm_stringsmempool[%s]",PRVM_NAME)); - VM_Files_Init(); + VM_STRINGS_MEMPOOL = Mem_AllocPool(va("vm_stringsmempool[%s]",PRVM_NAME), 0, NULL); + VM_Files_Init(); + VM_Search_Init(); } void VM_Cmd_Reset(void) { - Mem_EmptyPool(VM_STRINGS_MEMPOOL); + //Mem_EmptyPool(VM_STRINGS_MEMPOOL); + Mem_FreePool(&VM_STRINGS_MEMPOOL); + VM_Search_Reset(); VM_Files_CloseAll(); } @@ -2648,6 +2943,284 @@ void VM_M_getkeydest(void) } } +/* +========= +VM_M_callfunction + + callfunction(...,string function_name) +========= +*/ +mfunction_t *PRVM_ED_FindFunction (const char *name); +void VM_M_callfunction(void) +{ + mfunction_t *func; + char *s; + + if(prog->argc == 0) + PRVM_ERROR("VM_M_callfunction: 1 parameter is required !\n"); + + s = PRVM_G_STRING(OFS_PARM0 + (prog->argc - 1)); + + if(!s) + PRVM_ERROR("VM_M_callfunction: null string !\n"); + + VM_CheckEmptyString(s); + + func = PRVM_ED_FindFunction(s); + + if(!func) + PRVM_ERROR("VM_M_callfunciton: function %s not found !\n", s); + else if (func->first_statement < 0) + { + // negative statements are built in functions + int builtinnumber = -func->first_statement; + prog->xfunction->builtinsprofile++; + if (builtinnumber < prog->numbuiltins && prog->builtins[builtinnumber]) + prog->builtins[builtinnumber](); + else + PRVM_ERROR("No such builtin #%i in %s", builtinnumber, PRVM_NAME); + } + else if(func > 0) + { + prog->argc--; + PRVM_ExecuteProgram(func - prog->functions,""); + prog->argc++; + } +} + +/* +========= +VM_M_isfunction + +float isfunction(string function_name) +========= +*/ +mfunction_t *PRVM_ED_FindFunction (const char *name); +void VM_M_isfunction(void) +{ + mfunction_t *func; + char *s; + + VM_SAFEPARMCOUNT(1, VM_M_isfunction); + + s = PRVM_G_STRING(OFS_PARM0); + + if(!s) + PRVM_ERROR("VM_M_isfunction: null string !\n"); + + VM_CheckEmptyString(s); + + func = PRVM_ED_FindFunction(s); + + if(!func) + PRVM_G_FLOAT(OFS_RETURN) = false; + else + PRVM_G_FLOAT(OFS_RETURN) = true; +} + +/* +========= +VM_M_writetofile + + writetofile(float fhandle, entity ent) +========= +*/ +void VM_M_writetofile(void) +{ + prvm_edict_t * ent; + int filenum; + + VM_SAFEPARMCOUNT(2, VM_M_writetofile); + + filenum = PRVM_G_FLOAT(OFS_PARM0); + if (filenum < 0 || filenum >= MAX_VMFILES) + { + Con_Printf("VM_fputs: invalid file handle %i used in %s\n", filenum, PRVM_NAME); + return; + } + if (VM_FILES[filenum] == NULL) + { + Con_Printf("VM_fputs: no such file handle %i (or file has been closed) in %s\n", filenum, PRVM_NAME); + return; + } + + ent = PRVM_G_EDICT(OFS_PARM1); + if(ent->e->free) + { + Con_Printf("VM_M_writetofile: %s: entity %i is free !\n", PRVM_NAME, PRVM_EDICT_NUM(OFS_PARM1)); + return; + } + + PRVM_ED_Write (VM_FILES[filenum], ent); +} + +/* +========= +VM_M_getresolution + +vector getresolution(float number) +========= +*/ +extern unsigned short video_resolutions[][2]; +void VM_M_getresolution(void) +{ + int nr; + VM_SAFEPARMCOUNT(1, VM_getresolution); + + nr = PRVM_G_FLOAT(OFS_PARM0); + + + PRVM_G_VECTOR(OFS_RETURN)[0] = video_resolutions[nr][0]; + PRVM_G_VECTOR(OFS_RETURN)[1] = video_resolutions[nr][1]; + PRVM_G_VECTOR(OFS_RETURN)[2] = 0; +} + +/* +========= +VM_M_keynumtostring + +string keynumtostring(float keynum) +========= +*/ +void VM_M_keynumtostring(void) +{ + int keynum; + char *tmp; + VM_SAFEPARMCOUNT(1, VM_M_keynumtostring); + + keynum = PRVM_G_FLOAT(OFS_PARM0); + + tmp = VM_GetTempString(); + + strcpy(tmp, Key_KeynumToString(keynum)); + + PRVM_G_INT(OFS_RETURN) = PRVM_SetString(tmp); +} + +/* +========= +VM_M_findkeysforcommand + +string findkeysforcommand(string command) + +the returned string is an altstring +========= +*/ +#define NUMKEYS 5 // TODO: merge the constant in keys.c with this one somewhen + +void M_FindKeysForCommand(char *command, int *keys); +void VM_M_findkeysforcommand(void) +{ + char *cmd, *ret; + int keys[NUMKEYS]; + int i; + + VM_SAFEPARMCOUNT(1, VM_M_findkeysforcommand); + + cmd = PRVM_G_STRING(OFS_PARM0); + + VM_CheckEmptyString(cmd); + + (ret = VM_GetTempString())[0] = 0; + + M_FindKeysForCommand(cmd, keys); + + for(i = 0; i < NUMKEYS; i++) + ret = strcat(ret, va(" \'%i\'", keys[i])); + + PRVM_G_INT(OFS_RETURN) = PRVM_SetString(ret); +} + +/* +========= +VM_M_gethostcachecount + +float gethostcachevalue(float type) +========= +*/ +/* + type: +0 hostcachecount +1 masterquerycount +2 masterreplycount +3 serverquerycount +4 serverreplycount +*/ +void VM_M_gethostcachevalue( void ) +{ + int type; + VM_SAFEPARMCOUNT ( 1, VM_M_gethostcachevalue ); + + PRVM_G_FLOAT( OFS_RETURN ) = 0; + + type = PRVM_G_FLOAT( OFS_PARM0 ); + if( type < 0 || type > 4 ) + Con_Printf( "VM_M_gethostcachevalue: bad type %i!\n", type ); + else switch(type) + { + case 0: + PRVM_G_FLOAT ( OFS_RETURN ) = hostCacheCount; + return; + case 1: + PRVM_G_FLOAT ( OFS_RETURN ) = masterquerycount; + return; + case 2: + PRVM_G_FLOAT ( OFS_RETURN ) = masterreplycount; + return; + case 3: + PRVM_G_FLOAT ( OFS_RETURN ) = serverquerycount; + return; + case 4: + PRVM_G_FLOAT ( OFS_RETURN ) = serverreplycount; + return; + } +} + +/* +========= +VM_M_gethostcachestring + +string gethostcachestring(float type, float hostnr) +========= +*/ +/* +0 Get CName +1 Get line1 +2 Get line2 +*/ +void VM_M_gethostcachestring(void) +{ + int type; + int hostnr; + + VM_SAFEPARMCOUNT(2, VM_M_gethostcachestring); + + PRVM_G_INT(OFS_RETURN) = 0; + + type = PRVM_G_FLOAT(OFS_PARM0); + + if(type < 0 || type > 2) + { + Con_Print("VM_M_gethostcachestring: bad string type requested!\n"); + return; + } + + hostnr = PRVM_G_FLOAT(OFS_PARM1); + + if(hostnr < 0 || hostnr >= hostCacheCount) + { + Con_Print("VM_M_gethostcachestring: bad hostnr passed!\n"); + return; + } + + if( type == 0 ) + PRVM_G_INT( OFS_RETURN ) = PRVM_SetString( hostcache[hostnr].cname ); + else if( type == 1 ) + PRVM_G_INT( OFS_RETURN ) = PRVM_SetString( hostcache[hostnr].line1 ); + else + PRVM_G_INT( OFS_RETURN ) = PRVM_SetString( hostcache[hostnr].line2 ); +} + prvm_builtin_t vm_m_builtins[] = { 0, // to be consistent with the old vm // common builtings (mostly) @@ -2721,7 +3294,15 @@ prvm_builtin_t vm_m_builtins[] = { VM_loadfromdata, VM_loadfromfile, VM_modulo, // 70 - e10, // 80 + VM_str_cvar, + VM_crash, + VM_stackdump, // 73 + VM_search_begin, + VM_search_end, + VM_search_getsize, + VM_search_getfilename, // 77 + VM_chr, //78 + 0,0,// 80 e10, // 90 e10, // 100 e100, // 200 @@ -2762,7 +3343,15 @@ prvm_builtin_t vm_m_builtins[] = { VM_M_setkeydest, VM_M_getkeydest, VM_M_setmousetarget, - VM_M_getmousetarget + VM_M_getmousetarget, + VM_M_callfunction, + VM_M_writetofile, + VM_M_isfunction, + VM_M_getresolution, + VM_M_keynumtostring, + VM_M_findkeysforcommand,// 610 + VM_M_gethostcachevalue, + VM_M_gethostcachestring // 612 }; const int vm_m_numbuiltins = sizeof(vm_m_builtins) / sizeof(prvm_builtin_t); @@ -2774,6 +3363,6 @@ void VM_M_Cmd_Init(void) void VM_M_Cmd_Reset(void) { - VM_Cmd_Init(); + //VM_Cmd_Init(); + VM_Cmd_Reset(); } -