X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=prvm_cmds.c;h=55a7584edcca90fe4e367452140eb9e342de47ab;hb=ade77d4b90e983862f20725be7f605f9d34ffc12;hp=bf26c4b4e3c5e86e9630b11863319d67ad3c854a;hpb=28620abb9561ae4dfd3626c69912af0aa2e941df;p=xonotic%2Fdarkplaces.git diff --git a/prvm_cmds.c b/prvm_cmds.c index bf26c4b4..55a7584e 100644 --- a/prvm_cmds.c +++ b/prvm_cmds.c @@ -1,169 +1,21 @@ // 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 - -/* -============================================================================ -common cmd list: -================= - - checkextension(string) - error(...[string]) - objerror(...[string) - print(...[strings]) - bprint(...[string]) - sprint(float clientnum,...[string]) - centerprint(...[string]) -vector normalize(vector) -float vlen(vector) -float vectoyaw(vector) -vector vectoangles(vector) -float random() - cmd(string) - float cvar (string) - cvar_set (string,string) - dprint(...[string]) -string ftos(float) -float fabs(float) -string vtos(vector) -string etos(entity) -float stof(...[string]) -entity spawn() - remove(entity e) -entity find(entity start, .string field, string match) - -entity findfloat(entity start, .float field, float match) -entity findentity(entity start, .entity field, entity match) - -entity findchain(.string field, string match) - -entity findchainfloat(.string field, float match) -entity findchainentity(.string field, entity match) - -string precache_file(string) -string precache_sound (string sample) - coredump() - traceon() - traceoff() - eprint(entity e) -float rint(float) -float floor(float) -float ceil(float) -entity nextent(entity) -float sin(float) -float cos(float) -float sqrt(float) -vector randomvec() -float registercvar (string name, string value) -float min(float a, float b, ...[float]) -float max(float a, float b, ...[float]) -float bound(float min, float value, float max) -float pow(float a, float b) - copyentity(entity src, entity dst) -float fopen(string filename, float mode) - fclose(float fhandle) -string fgets(float fhandle) - fputs(float fhandle, string s) -float strlen(string s) -string strcat(string,string,...[string]) -string substring(string s, float start, float length) -vector stov(string s) -string strzone(string s) - strunzone(string s) -float tokenize(string s) -string argv(float n) -float isserver() -float clientcount() -float clientstate() - clientcommand(float client, string s) (for client and menu) - changelevel(string map) - localsound(string sample) -vector getmousepos() -float gettime() - loadfromdata(string data) - loadfromfile(string file) -float mod(float val, float m) - -perhaps only : Menu : WriteMsg -=============================== - - WriteByte(float data, float dest, float desto) - WriteChar(float data, float dest, float desto) - WriteShort(float data, float dest, float desto) - WriteLong(float data, float dest, float desto) - WriteAngle(float data, float dest, float desto) - WriteCoord(float data, float dest, float desto) - WriteString(string data, float dest, float desto) - WriteEntity(entity data, float dest, float desto) - -Client & Menu : draw functions -=============================== - -float iscachedpic(string pic) -string precache_pic(string pic) - freepic(string s) -float drawcharacter(vector position, float character, vector scale, vector rgb, float alpha, float flag) -float drawstring(vector position, string text, vector scale, vector rgb, float alpha, float flag) -float drawpic(vector position, string pic, vector size, vector rgb, float alpha, float flag) -float drawfill(vector position, vector size, vector rgb, float alpha, float flag) - drawsetcliparea(float x, float y, float width, float height) - drawresetcliparea() -vector getimagesize(string pic) - - -============================================================================== -menu cmd list: -=============== - - setkeydest(float dest) -float getkeydest - setmousetarget(float target) -float getmousetarget(void) -*/ - -#include "quakedef.h" -#include "progdefs.h" -#include "clprogdefs.h" -#include "mprogdefs.h" - -//============================================================================ -// nice helper macros - -#ifndef VM_NOPARMCHECK -#define VM_SAFEPARMCOUNT(p,f) if(prog->argc != p) PRVM_ERROR(#f " wrong parameter count (" #p " expected ) !\n") -#else -#define VM_SAFEPARMCOUNT(p,f) -#endif - -#define VM_RETURN_EDICT(e) (((int *)prog->globals)[OFS_RETURN] = PRVM_EDICT_TO_PROG(e)) - -#define VM_STRINGS_MEMPOOL vm_strings_mempool[PRVM_GetProgNr()] - -#define e10 0,0,0,0,0,0,0,0,0,0 -#define e100 e10,e10,e10,e10,e10,e10,e10,e10,e10,e10 -#define e1000 e100,e100,e100,e100,e100,e100,e100,e100,e100,e100 +#include "prvm_cmds.h" //============================================================================ // Common -// string zone mempool -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 -#define MAX_QC_CVARS 128 * PRVM_MAXPROGS -cvar_t vm_qc_cvar[MAX_QC_CVARS]; -int vm_currentqc_cvar; - // qc file handling #define MAX_VMFILES 256 #define MAX_PRVMFILES MAX_VMFILES * PRVM_MAXPROGS @@ -171,15 +23,22 @@ int vm_currentqc_cvar; qfile_t *vm_files[MAX_PRVMFILES]; -static char *VM_GetTempString(void) +// 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]; + +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; } -void VM_CheckEmptyString (char *s) +void VM_CheckEmptyString (const char *s) { if (s[0] <= ' ') PRVM_ERROR ("%s: Bad string", PRVM_NAME); @@ -215,7 +74,7 @@ checkextension(extensionname) */ // kind of helper function -static qboolean checkextension(char *name) +static qboolean checkextension(const char *name) { int len; char *e, *start; @@ -259,14 +118,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 +144,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 +171,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 +188,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,19 +213,17 @@ 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; } - + client = svs.clients + clientnum; - if (!client->netconnection) - return; VM_VarString(1, string, sizeof(string)); MSG_WriteChar(&client->message,svc_print); MSG_WriteString(&client->message, string); @@ -383,7 +240,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); @@ -534,13 +391,9 @@ float random() */ void VM_random (void) { - float num; - VM_SAFEPARMCOUNT(0,VM_random); - num = (rand ()&0x7fff) / ((float)0x7fff); - - PRVM_G_FLOAT(OFS_RETURN) = num; + PRVM_G_FLOAT(OFS_RETURN) = lhrandom(0, 1); } /* @@ -595,20 +448,19 @@ localsound(string sample) */ void VM_localsound(void) { - char *s; - + const char *s; + VM_SAFEPARMCOUNT(1,VM_localsound); s = PRVM_G_STRING(OFS_PARM0); - if(!S_GetCached(s)) + if(!S_LocalSound (s)) { - Con_Printf("VM_localsound: %s : %s not cached !\n", PRVM_NAME, s); + Con_Printf("VM_localsound: Failed to play %s for %s !\n", s, PRVM_NAME); PRVM_G_FLOAT(OFS_RETURN) = -4; return; - } + } - S_LocalSound(s); PRVM_G_FLOAT(OFS_RETURN) = 1; } @@ -657,6 +509,36 @@ void VM_cvar (void) PRVM_G_FLOAT(OFS_RETURN) = Cvar_VariableValue(PRVM_G_STRING(OFS_PARM0)); } +/* +================= +VM_cvar_string + +const string VM_cvar_string (string) +================= +*/ +void VM_cvar_string(void) +{ + char *out; + const char *name; + const char *cvar_string; + VM_SAFEPARMCOUNT(1,VM_cvar_string); + + 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_RETURN) = PRVM_SetEngineString(out); +} + /* ================= VM_cvar_set @@ -680,7 +562,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)); @@ -710,7 +592,7 @@ void VM_ftos (void) sprintf(s, "%i", (int)v); else sprintf(s, "%f", v); - PRVM_G_INT(OFS_RETURN) = PRVM_SetString(s); + PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(s); } /* @@ -747,7 +629,7 @@ void VM_vtos (void) s = VM_GetTempString(); sprintf (s, "'%5.1f %5.1f %5.1f'", PRVM_G_VECTOR(OFS_PARM0)[0], PRVM_G_VECTOR(OFS_PARM0)[1], PRVM_G_VECTOR(OFS_PARM0)[2]); - PRVM_G_INT(OFS_RETURN) = PRVM_SetString(s); + PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(s); } /* @@ -766,7 +648,7 @@ void VM_etos (void) s = VM_GetTempString(); sprintf (s, "entity %i", PRVM_G_EDICTNUM(OFS_PARM0)); - PRVM_G_INT(OFS_RETURN) = PRVM_SetString(s); + PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(s); } /* @@ -778,11 +660,43 @@ 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); } +/* +======================== +VM_itof + +float itof(intt ent) +======================== +*/ +void VM_itof(void) +{ + VM_SAFEPARMCOUNT(1, VM_itof); + PRVM_G_FLOAT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0); +} + +/* +======================== +VM_itoe + +intt ftoi(float num) +======================== +*/ +void VM_ftoi(void) +{ + int ent; + VM_SAFEPARMCOUNT(1, VM_ftoi); + + ent = 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)!\n", PRVM_NAME, ent); + + PRVM_G_INT(OFS_RETURN) = ent; +} + /* ========= VM_spawn @@ -803,7 +717,7 @@ void VM_spawn (void) ========= VM_remove -entity remove() +remove(entity e) ========= */ @@ -834,7 +748,7 @@ void VM_find (void) { int e; int f; - char *s, *t; + const char *s, *t; prvm_edict_t *ed; VM_SAFEPARMCOUNT(3,VM_find); @@ -854,7 +768,7 @@ void VM_find (void) { prog->xfunction->builtinsprofile++; ed = PRVM_EDICT_NUM(e); - if (ed->e->free) + if (ed->priv.required->free) continue; t = PRVM_E_STRING(ed,f); if (!t) @@ -895,7 +809,7 @@ void VM_findfloat (void) { prog->xfunction->builtinsprofile++; ed = PRVM_EDICT_NUM(e); - if (ed->e->free) + if (ed->priv.required->free) continue; if (PRVM_E_FLOAT(ed,f) == s) { @@ -922,7 +836,7 @@ void VM_findchain (void) int i; int f; int chain_of; - char *s, *t; + const char *s, *t; prvm_edict_t *ent, *chain; VM_SAFEPARMCOUNT(2,VM_findchain); @@ -947,7 +861,7 @@ void VM_findchain (void) for (i = 1;i < prog->num_edicts;i++, ent = PRVM_NEXT_EDICT(ent)) { prog->xfunction->builtinsprofile++; - if (ent->e->free) + if (ent->priv.required->free) continue; t = PRVM_E_STRING(ent,f); if (!t) @@ -955,7 +869,7 @@ void VM_findchain (void) if (strcmp(t,s)) continue; - PRVM_E_FLOAT(ent,chain_of) = PRVM_NUM_FOR_EDICT(chain); + PRVM_E_INT(ent,chain_of) = PRVM_NUM_FOR_EDICT(chain); chain = ent; } @@ -996,12 +910,12 @@ void VM_findchainfloat (void) for (i = 1;i < prog->num_edicts;i++, ent = PRVM_NEXT_EDICT(ent)) { prog->xfunction->builtinsprofile++; - if (ent->e->free) + if (ent->priv.required->free) continue; - if (E_FLOAT(ent,f) != s) + if (PRVM_E_FLOAT(ent,f) != s) continue; - PRVM_E_FLOAT(ent,chain_of) = PRVM_NUM_FOR_EDICT(chain); + PRVM_E_INT(ent,chain_of) = PRVM_EDICT_TO_PROG(chain); chain = ent; } @@ -1044,22 +958,16 @@ string precache_sound (string sample) */ void VM_precache_sound (void) { - char *s; + const char *s; VM_SAFEPARMCOUNT(1, VM_precache_sound); s = PRVM_G_STRING(OFS_PARM0); PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0); VM_CheckEmptyString (s); - - if(S_GetCached(s)) - { - 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(snd_initialized.integer && !S_PrecacheSound (s,true, true)) + Con_Printf("VM_precache_sound: Failed to load %s for %s\n", s, PRVM_NAME); } /* @@ -1078,6 +986,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 @@ -1192,7 +1130,7 @@ void VM_nextent (void) return; } ent = PRVM_EDICT_NUM(i); - if (!ent->e->free) + if (!ent->priv.required->free) { VM_RETURN_EDICT(ent); return; @@ -1274,12 +1212,12 @@ void VM_WriteLong (void) void VM_WriteAngle (void) { - MSG_WriteAngle (VM_WriteDest(), PRVM_G_FLOAT(OFS_PARM0)); + MSG_WriteAngle (VM_WriteDest(), PRVM_G_FLOAT(OFS_PARM0), sv.protocol); } void VM_WriteCoord (void) { - MSG_WriteDPCoord (VM_WriteDest(), PRVM_G_FLOAT(OFS_PARM0)); + MSG_WriteCoord (VM_WriteDest(), PRVM_G_FLOAT(OFS_PARM0), sv.protocol); } void VM_WriteString (void) @@ -1304,13 +1242,13 @@ changelevel(string map) */ void VM_changelevel (void) { - char *s; + const char *s; VM_SAFEPARMCOUNT(1, VM_changelevel); if(!sv.active) { - Con_Printf("VM_changelevel: game is not server (%s)\n", PRVM_NAME); + Con_Printf("VM_changelevel: game is not server (%s)\n", PRVM_NAME); return; } @@ -1319,7 +1257,7 @@ void VM_changelevel (void) return; svs.changelevel_issued = true; - s = G_STRING(OFS_PARM0); + s = PRVM_G_STRING(OFS_PARM0); Cbuf_AddText (va("changelevel %s\n",s)); } @@ -1403,19 +1341,24 @@ 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; + const char *name, *value; + 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,22 +1366,12 @@ 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; } - if (vm_currentqc_cvar >= MAX_QC_CVARS) - PRVM_ERROR ("VM_registercvar: ran out of cvar slots (%i)\n", MAX_QC_CVARS); - -// copy the name and value - variable = &vm_qc_cvar[vm_currentqc_cvar++]; - variable->name = Z_Malloc (strlen(name)+1); - strcpy (variable->name, name); - variable->string = Z_Malloc (strlen(value)+1); - strcpy (variable->string, value); - variable->value = atof (value); + Cvar_Get(name, value, flags); - Cvar_RegisterVariable(variable); PRVM_G_FLOAT(OFS_RETURN) = 1; // success } @@ -1490,7 +1423,7 @@ void VM_max (void) for (i = 1;i < prog->argc;i++) if (PRVM_G_FLOAT((OFS_PARM0+i*3)) > f) f = PRVM_G_FLOAT((OFS_PARM0+i*3)); - G_FLOAT(OFS_RETURN) = f; + PRVM_G_FLOAT(OFS_RETURN) = f; } else PRVM_ERROR("VM_max: %s must supply at least 2 floats\n", PRVM_NAME); @@ -1541,7 +1474,7 @@ void VM_copyentity (void) VM_SAFEPARMCOUNT(2,VM_copyentity); in = PRVM_G_EDICT(OFS_PARM0); out = PRVM_G_EDICT(OFS_PARM1); - memcpy(out->v, in->v, prog->progs->entityfields * 4); + memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4); } /* @@ -1564,7 +1497,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; } @@ -1597,6 +1530,21 @@ void VM_Files_CloseAll(void) 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) + { + Con_Printf("VM_GetFileHandle: invalid file handle %i used in %s\n", index, PRVM_NAME); + return NULL; + } + if (VM_FILES[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]; +} + /* ========= VM_fopen @@ -1610,7 +1558,7 @@ float fopen(string filename, float mode) void VM_fopen(void) { int filenum, mode; - char *modestring, *filename; + const char *modestring, *filename; VM_SAFEPARMCOUNT(2,VM_fopen); @@ -1636,7 +1584,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; } @@ -1651,7 +1599,10 @@ void VM_fopen(void) PRVM_G_FLOAT(OFS_RETURN) = -4; return; } - VM_FILES[filenum] = FS_Open(va("data/%s", filename), modestring, false); + 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); + if (VM_FILES[filenum] == NULL) PRVM_G_FLOAT(OFS_RETURN) = -1; else @@ -1698,7 +1649,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,17 +1671,21 @@ 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; // remove \n following \r if (c == '\r') + { c = FS_Getc(VM_FILES[filenum]); - if (developer.integer) + if (c != '\n') + FS_UnGetc(VM_FILES[filenum], (unsigned char)c); + } + if (developer.integer >= 3) Con_Printf("fgets: %s: %s\n", PRVM_NAME, string); - if (c >= 0) - PRVM_G_INT(OFS_RETURN) = PRVM_SetString(string); + if (c >= 0 || end) + PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(string); else PRVM_G_INT(OFS_RETURN) = 0; } @@ -1746,7 +1701,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); @@ -1779,7 +1734,7 @@ float strlen(string s) //float(string s) strlen = #114; // returns how many characters are in a string void VM_strlen(void) { - char *s; + const char *s; VM_SAFEPARMCOUNT(1,VM_strlen); @@ -1804,12 +1759,12 @@ void VM_strcat(void) { char *s; - if(prog->argc <= 2) - PRVM_ERROR("VM_strcat wrong parameter count (min. 2 expected ) !\n"); - + if(prog->argc < 1) + PRVM_ERROR("VM_strcat wrong parameter count (min. 1 expected ) !\n"); + s = VM_GetTempString(); - VM_VarString(0, s, STRINGTEMP_LENGTH); - PRVM_G_INT(OFS_RETURN) = PRVM_SetString(s); + VM_VarString(0, s, VM_STRINGTEMP_LENGTH); + PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(s); } /* @@ -1824,7 +1779,8 @@ string substring(string s, float start, float length) void VM_substring(void) { int i, start, length; - char *s, *string; + const char *s; + char *string; VM_SAFEPARMCOUNT(3,VM_substring); @@ -1835,10 +1791,10 @@ 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); + PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(string); } /* @@ -1851,7 +1807,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); @@ -1869,14 +1825,15 @@ string strzone(string s) //string(string s) strzone = #118; // makes a copy of a string into the string zone and returns it, this is often used to keep around a tempstring for longer periods of time (tempstrings are replaced often) void VM_strzone(void) { - char *in, *out; + const char *in; + char *out; VM_SAFEPARMCOUNT(1,VM_strzone); in = PRVM_G_STRING(OFS_PARM0); - out = Mem_Alloc(VM_STRINGS_MEMPOOL, strlen(in) + 1); + out = PRVM_AllocString(strlen(in) + 1); strcpy(out, in); - PRVM_G_INT(OFS_RETURN) = PRVM_SetString(out); + PRVM_G_INT(OFS_RETURN) = PRVM_SetQCString(out); } /* @@ -1890,8 +1847,7 @@ strunzone(string s) void VM_strunzone(void) { VM_SAFEPARMCOUNT(1,VM_strunzone); - - Mem_Free(PRVM_G_STRING(OFS_PARM0)); + PRVM_FreeString((char *)PRVM_G_STRING(OFS_PARM0)); } /* @@ -1913,7 +1869,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; } @@ -1938,8 +1894,7 @@ static char **tokens = NULL; static int max_tokens, num_tokens = 0; void VM_tokenize (void) { - const char *p; - char *str; + const char *p, *str; VM_SAFEPARMCOUNT(1,VM_tokenize); @@ -1984,9 +1939,9 @@ void VM_argv (void) token_num = PRVM_G_FLOAT(OFS_PARM0); if (token_num >= 0 && token_num < num_tokens) - PRVM_G_INT(OFS_RETURN) = PRVM_SetString(tokens[token_num]); + PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(tokens[token_num]); else - PRVM_G_INT(OFS_RETURN) = PRVM_SetString(""); + PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(NULL); } /* @@ -2020,9 +1975,10 @@ 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; - 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)) + // FIXME: use a model function to get tag info (need to handle skeletal) + if (v->_float == 0 && model->num_tags) + for (i = 0;i < model->num_tags;i++) + if (!strcmp(tagname, model->data_tags[i].name)) v->_float = i + 1; if (v->_float == 0) Con_DPrintf("setattachment(edict %i, edict %i, string \"%s\"): tried to find tag named \"%s\" on entity %i (model \"%s\") but could not find it\n", NUM_FOR_EDICT(e), NUM_FOR_EDICT(tagentity), tagname, tagname, NUM_FOR_EDICT(tagentity), model->name); @@ -2074,6 +2030,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 @@ -2085,9 +2067,9 @@ void VM_getmousepos(void) { VM_SAFEPARMCOUNT(0,VM_getmousepos); - - PRVM_G_VECTOR(OFS_RETURN)[0] = in_mouse_x; - PRVM_G_VECTOR(OFS_RETURN)[1] = in_mouse_y; + + PRVM_G_VECTOR(OFS_RETURN)[0] = in_mouse_x * vid_conwidth.integer / vid.width; + PRVM_G_VECTOR(OFS_RETURN)[1] = in_mouse_y * vid_conheight.integer / vid.height; PRVM_G_VECTOR(OFS_RETURN)[2] = 0; } @@ -2119,6 +2101,34 @@ void VM_loadfromdata(void) PRVM_ED_LoadFromFile(PRVM_G_STRING(OFS_PARM0)); } +/* +======================== +VM_parseentitydata + +parseentitydata(entity ent, string data) +======================== +*/ +void VM_parseentitydata(void) +{ + prvm_edict_t *ent; + const char *data; + + VM_SAFEPARMCOUNT(2, VM_parseentitydata); + + // get edict and test it + ent = PRVM_G_EDICT(OFS_PARM0); + if (ent->priv.required->free) + PRVM_ERROR ("VM_parseentitydata: %s: Can only set already spawned entities (entity %i is free)!\n", PRVM_NAME, PRVM_NUM_FOR_EDICT(ent)); + + data = PRVM_G_STRING(OFS_PARM1); + + // parse the opening brace + if (!COM_ParseToken(&data, false) || com_token[0] != '{' ) + PRVM_ERROR ("VM_parseentitydata: %s: Couldn't parse entity data:\n%s\n", PRVM_NAME, data ); + + PRVM_ED_ParseEdict (data, ent); +} + /* ========= VM_loadfromfile @@ -2128,11 +2138,11 @@ loadfromfile(string file) */ void VM_loadfromfile(void) { - char *filename; + const char *filename; qbyte *data; - + VM_SAFEPARMCOUNT(1,VM_loadfromfile); - + filename = PRVM_G_STRING(OFS_PARM0); // .. is parent directory on many platforms // / is parent directory on Amiga @@ -2145,13 +2155,15 @@ void VM_loadfromfile(void) return; } - data = FS_LoadFile(va("data/%s", filename), false); + // not conform with VM_fopen + data = FS_LoadFile(filename, tempmempool, false); if (data == NULL) PRVM_G_FLOAT(OFS_RETURN) = -1; - + PRVM_ED_LoadFromFile(data); - Mem_Free(data); + if(data) + Mem_Free(data); } @@ -2173,6 +2185,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; + const 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_SetEngineString(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_SetEngineString(tmp); +} + //============================================================================= // Draw builtins (client & menu) @@ -2187,33 +2367,34 @@ void VM_iscachedpic(void) { VM_SAFEPARMCOUNT(1,VM_iscachedpic); - // drawq hasnt such a function, thus always return true - PRVM_G_FLOAT(OFS_RETURN) = TRUE; + // drawq hasnt such a function, thus always return true + PRVM_G_FLOAT(OFS_RETURN) = false; } /* ========= VM_precache_pic -string precache_pic(string pic) +string precache_pic(string pic) ========= */ void VM_precache_pic(void) { - char *s; - + const char *s; + VM_SAFEPARMCOUNT(1, VM_precache_pic); - + s = PRVM_G_STRING(OFS_PARM0); PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0); - + if(!s) PRVM_ERROR ("VM_precache_pic: %s: NULL\n", PRVM_NAME); VM_CheckEmptyString (s); - - if(!Draw_CachePic(s)) - PRVM_G_INT(OFS_RETURN) = PRVM_SetString(""); + + // AK Draw_CachePic is supposed to always return a valid pointer + if( Draw_CachePic(s, false)->tex == r_texture_notexture ) + PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(NULL); } /* @@ -2225,17 +2406,17 @@ freepic(string s) */ void VM_freepic(void) { - char *s; + const char *s; VM_SAFEPARMCOUNT(1,VM_freepic); s = PRVM_G_STRING(OFS_PARM0); - + if(!s) PRVM_ERROR ("VM_freepic: %s: NULL\n"); - + VM_CheckEmptyString (s); - + Draw_FreePic(s); } @@ -2260,21 +2441,21 @@ void VM_drawcharacter(void) PRVM_G_FLOAT(OFS_RETURN) = -1; return; } - + pos = PRVM_G_VECTOR(OFS_PARM0); scale = PRVM_G_VECTOR(OFS_PARM2); rgb = PRVM_G_VECTOR(OFS_PARM3); flag = (int)PRVM_G_FLOAT(OFS_PARM5); - + 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; return; } - + 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]) { @@ -2285,7 +2466,7 @@ void VM_drawcharacter(void) DrawQ_String (pos[0], pos[1], &character, 1, scale[0], scale[1], rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM4), flag); PRVM_G_FLOAT(OFS_RETURN) = 1; -} +} /* ========= @@ -2297,10 +2478,10 @@ float drawstring(vector position, string text, vector scale, vector rgb, float a void VM_drawstring(void) { float *pos,*scale,*rgb; - char *string; + const char *string; int flag; VM_SAFEPARMCOUNT(6,VM_drawstring); - + string = PRVM_G_STRING(OFS_PARM1); if(!string) { @@ -2308,21 +2489,21 @@ void VM_drawstring(void) PRVM_G_FLOAT(OFS_RETURN) = -1; return; } - - VM_CheckEmptyString(string); - + + //VM_CheckEmptyString(string); Why should it be checked - perhaps the menu wants to support the precolored letters, too? + pos = PRVM_G_VECTOR(OFS_PARM0); scale = PRVM_G_VECTOR(OFS_PARM2); rgb = PRVM_G_VECTOR(OFS_PARM3); flag = (int)PRVM_G_FLOAT(OFS_PARM5); - + 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; 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"); @@ -2331,8 +2512,8 @@ 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; } @@ -2345,7 +2526,7 @@ float drawpic(vector position, string pic, vector size, vector rgb, float alpha, */ void VM_drawpic(void) { - char *pic; + const char *pic; float *size, *pos, *rgb; int flag; @@ -2356,7 +2537,7 @@ void VM_drawpic(void) if(!pic) { Con_Printf("VM_drawpic: %s passed null picture name !\n", PRVM_NAME); - PRVM_G_FLOAT(OFS_RETURN) = -1; + PRVM_G_FLOAT(OFS_RETURN) = -1; return; } @@ -2369,7 +2550,7 @@ void VM_drawpic(void) PRVM_G_FLOAT(OFS_RETURN) = -4; return; } - + pos = PRVM_G_VECTOR(OFS_PARM0); size = PRVM_G_VECTOR(OFS_PARM2); rgb = PRVM_G_VECTOR(OFS_PARM3); @@ -2383,8 +2564,8 @@ 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; } @@ -2400,25 +2581,25 @@ void VM_drawfill(void) { float *size, *pos, *rgb; int flag; - + VM_SAFEPARMCOUNT(5,VM_drawfill); - - + + pos = PRVM_G_VECTOR(OFS_PARM0); size = PRVM_G_VECTOR(OFS_PARM1); rgb = PRVM_G_VECTOR(OFS_PARM2); flag = (int) PRVM_G_FLOAT(OFS_PARM4); - + 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; return; } - + 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; } @@ -2435,12 +2616,12 @@ void VM_drawsetcliparea(void) float x,y,w,h; VM_SAFEPARMCOUNT(4,VM_drawsetcliparea); - 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); + x = bound(0, PRVM_G_FLOAT(OFS_PARM0), vid_conwidth.integer); + y = bound(0, PRVM_G_FLOAT(OFS_PARM1), vid_conheight.integer); + w = bound(0, PRVM_G_FLOAT(OFS_PARM2) + PRVM_G_FLOAT(OFS_PARM0) - x, (vid_conwidth.integer - x)); + h = bound(0, PRVM_G_FLOAT(OFS_PARM3) + PRVM_G_FLOAT(OFS_PARM1) - y, (vid_conheight.integer - y)); - DrawQ_SetClipArea(x,y,w,h); + DrawQ_SetClipArea(x, y, w, h); } /* @@ -2466,312 +2647,361 @@ vector getimagesize(string pic) */ void VM_getimagesize(void) { - char *p; + const char *p; cachepic_t *pic; VM_SAFEPARMCOUNT(1,VM_getimagesize); - + p = PRVM_G_STRING(OFS_PARM0); if(!p) PRVM_ERROR("VM_getimagepos: %s passed null picture name !\n", PRVM_NAME); - + VM_CheckEmptyString (p); - pic = Draw_CachePic (p); + pic = Draw_CachePic (p, false); PRVM_G_VECTOR(OFS_RETURN)[0] = pic->width; PRVM_G_VECTOR(OFS_RETURN)[1] = pic->height; PRVM_G_VECTOR(OFS_RETURN)[2] = 0; } -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(); -} +// CL_Video interface functions -void VM_Cmd_Reset(void) +/* +======================== +VM_cin_open + +float cin_open(string file, string name) +======================== +*/ +void VM_cin_open( void ) { - Mem_EmptyPool(VM_STRINGS_MEMPOOL); - VM_Files_CloseAll(); -} + const char *file; + const char *name; -//============================================================================ -// Server + VM_SAFEPARMCOUNT( 2, VM_cin_open ); + + file = PRVM_G_STRING( OFS_PARM0 ); + name = PRVM_G_STRING( OFS_PARM1 ); -char *vm_sv_extensions = -""; + VM_CheckEmptyString( file ); + VM_CheckEmptyString( name ); -prvm_builtin_t vm_sv_builtins[] = { -0 // to be consistent with the old vm -}; + if( CL_OpenVideo( file, name, MENUOWNER ) ) + PRVM_G_FLOAT( OFS_RETURN ) = 1; + else + PRVM_G_FLOAT( OFS_RETURN ) = 0; +} -const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t); +/* +======================== +VM_cin_close -void VM_SV_Cmd_Init(void) +void cin_close(string name) +======================== +*/ +void VM_cin_close( void ) { + const char *name; + + VM_SAFEPARMCOUNT( 1, VM_cin_close ); + + name = PRVM_G_STRING( OFS_PARM0 ); + VM_CheckEmptyString( name ); + + CL_CloseVideo( CL_GetVideo( name ) ); } -void VM_SV_Cmd_Reset(void) +/* +======================== +VM_cin_setstate +void cin_setstate(string name, float type) +======================== +*/ +void VM_cin_setstate( void ) { -} + const char *name; + clvideostate_t state; + clvideo_t *video; -//============================================================================ -// Client + VM_SAFEPARMCOUNT( 2, VM_cin_netstate ); + + name = PRVM_G_STRING( OFS_PARM0 ); + VM_CheckEmptyString( name ); -char *vm_cl_extensions = -""; + state = PRVM_G_FLOAT( OFS_PARM1 ); -prvm_builtin_t vm_cl_builtins[] = { -0 // to be consistent with the old vm -}; + video = CL_GetVideo( name ); + if( video && state > CLVIDEO_UNUSED && state < CLVIDEO_STATECOUNT ) + CL_SetVideoState( video, state ); +} -const int vm_cl_numbuiltins = sizeof(vm_cl_builtins) / sizeof(prvm_builtin_t); +/* +======================== +VM_cin_getstate -void VM_CL_Cmd_Init(void) +float cin_getstate(string name) +======================== +*/ +void VM_cin_getstate( void ) { + const char *name; + clvideo_t *video; + + VM_SAFEPARMCOUNT( 1, VM_cin_getstate ); + + name = PRVM_G_STRING( OFS_PARM0 ); + VM_CheckEmptyString( name ); + + video = CL_GetVideo( name ); + if( video ) + PRVM_G_FLOAT( OFS_RETURN ) = (int)video->state; + else + PRVM_G_FLOAT( OFS_RETURN ) = 0; } -void VM_CL_Cmd_Reset(void) +/* +======================== +VM_cin_restart + +void cin_restart(string name) +======================== +*/ +void VM_cin_restart( void ) { -} + const char *name; + clvideo_t *video; -//============================================================================ -// Menu + VM_SAFEPARMCOUNT( 1, VM_cin_restart ); + + name = PRVM_G_STRING( OFS_PARM0 ); + VM_CheckEmptyString( name ); + + video = CL_GetVideo( name ); + if( video ) + CL_RestartVideo( video ); +} -char *vm_m_extensions = -""; +//////////////////////////////////////// +// AltString functions +//////////////////////////////////////// /* -========= -VM_M_setmousetarget +======================== +VM_altstr_count -setmousetarget(float target) -========= +float altstr_count(string) +======================== */ -void VM_M_setmousetarget(void) +void VM_altstr_count( void ) { - VM_SAFEPARMCOUNT(1, VM_M_setmousetarget); + const char *altstr, *pos; + int count; - switch((int)PRVM_G_FLOAT(OFS_PARM0)) - { - case 1: - in_client_mouse = false; - break; - case 2: - in_client_mouse = true; - break; - default: - PRVM_ERROR("VM_M_setmousetarget: wrong destination %i !\n",PRVM_G_FLOAT(OFS_PARM0)); + VM_SAFEPARMCOUNT( 1, VM_altstr_count ); + + altstr = PRVM_G_STRING( OFS_PARM0 ); + //VM_CheckEmptyString( altstr ); + + for( count = 0, pos = altstr ; *pos ; pos++ ) { + if( *pos == '\\' ) { + if( !*++pos ) { + break; + } + } else if( *pos == '\'' ) { + count++; + } } + + PRVM_G_FLOAT( OFS_RETURN ) = (float) (count / 2); } /* -========= -VM_M_getmousetarget +======================== +VM_altstr_prepare -float getmousetarget -========= +string altstr_prepare(string) +======================== */ -void VM_M_getmousetarget(void) +void VM_altstr_prepare( void ) { - VM_SAFEPARMCOUNT(0,VM_M_getmousetarget); + char *outstr, *out; + const char *instr, *in; + int size; - if(in_client_mouse) - PRVM_G_FLOAT(OFS_RETURN) = 2; - else - PRVM_G_FLOAT(OFS_RETURN) = 1; -} - + VM_SAFEPARMCOUNT( 1, VM_altstr_prepare ); + + instr = PRVM_G_STRING( OFS_PARM0 ); + //VM_CheckEmptyString( instr ); + outstr = VM_GetTempString(); + for( out = outstr, in = instr, size = VM_STRINGTEMP_LENGTH - 1 ; size && *in ; size--, in++, out++ ) + if( *in == '\'' ) { + *out++ = '\\'; + *out = '\''; + size--; + } else + *out = *in; + *out = 0; + + PRVM_G_INT( OFS_RETURN ) = PRVM_SetEngineString( outstr ); +} /* -========= -VM_M_setkeydest +======================== +VM_altstr_get -setkeydest(float dest) -========= +string altstr_get(string, float) +======================== */ -void VM_M_setkeydest(void) +void VM_altstr_get( void ) { - VM_SAFEPARMCOUNT(1,VM_M_setkeydest); + const char *altstr, *pos; + char *outstr, *out; + int count, size; - switch((int)PRVM_G_FLOAT(OFS_PARM0)) - { - case 0: - // key_game - key_dest = key_game; - break; - case 2: - // key_menu - key_dest = key_menu; - break; - case 1: - // key_message - // key_dest = key_message - // break; - default: - PRVM_ERROR("VM_M_setkeydest: wrong destination %i !\n",prog->globals[OFS_PARM0]); + VM_SAFEPARMCOUNT( 2, VM_altstr_get ); + + altstr = PRVM_G_STRING( OFS_PARM0 ); + //VM_CheckEmptyString( altstr ); + + count = PRVM_G_FLOAT( OFS_PARM1 ); + count = count * 2 + 1; + + for( pos = altstr ; *pos && count ; pos++ ) + if( *pos == '\\' ) { + if( !*++pos ) + break; + } else if( *pos == '\'' ) + count--; + + if( !*pos ) { + PRVM_G_INT( OFS_RETURN ) = PRVM_SetEngineString( NULL ); + return; } + + outstr = VM_GetTempString(); + for( out = outstr, size = VM_STRINGTEMP_LENGTH - 1 ; size && *pos ; size--, pos++, out++ ) + if( *pos == '\\' ) { + if( !*++pos ) + break; + *out = *pos; + size--; + } else if( *pos == '\'' ) + break; + else + *out = *pos; + + *out = 0; + PRVM_G_INT( OFS_RETURN ) = PRVM_SetEngineString( outstr ); } /* -========= -VM_M_getkeydest +======================== +VM_altstr_set -float getkeydest -========= +string altstr_set(string altstr, float num, string set) +======================== */ -void VM_M_getkeydest(void) +void VM_altstr_set( void ) { - VM_SAFEPARMCOUNT(0,VM_M_getkeydest); + int num; + const char *altstr, *str; + const char *in; + char *outstr, *out; - // key_game = 0, key_message = 1, key_menu = 2, unknown = 3 - switch(key_dest) - { - case key_game: - PRVM_G_FLOAT(OFS_RETURN) = 0; - break; - case key_menu: - PRVM_G_FLOAT(OFS_RETURN) = 2; - break; - case key_message: - // not supported - // PRVM_G_FLOAT(OFS_RETURN) = 1; - // break; - default: - PRVM_G_FLOAT(OFS_RETURN) = 3; - } -} - -prvm_builtin_t vm_m_builtins[] = { - 0, // to be consistent with the old vm - // common builtings (mostly) - VM_checkextension, - VM_error, - VM_objerror, - VM_print, - VM_bprint, - VM_sprint, - VM_centerprint, - VM_normalize, - VM_vlen, - VM_vectoyaw, // #10 - VM_vectoangles, - VM_random, - VM_localcmd, - VM_cvar, - VM_cvar_set, - VM_dprint, - VM_ftos, - VM_fabs, - VM_vtos, - VM_etos, // 20 - VM_stof, - VM_spawn, - VM_remove, - VM_find, - VM_findfloat, - VM_findchain, - VM_findchainfloat, - VM_precache_file, - VM_precache_sound, - VM_coredump, // 30 - VM_traceon, - VM_traceoff, - VM_eprint, - VM_rint, - VM_floor, - VM_ceil, - VM_nextent, - VM_sin, - VM_cos, - VM_sqrt, // 40 - VM_randomvec, - VM_registercvar, - VM_min, - VM_max, - VM_bound, - VM_pow, - VM_copyentity, - VM_fopen, - VM_fclose, - VM_fgets, // 50 - VM_fputs, - VM_strlen, - VM_strcat, - VM_substring, - VM_stov, - VM_strzone, - VM_strunzone, - VM_tokenize, - VM_argv, - VM_isserver, // 60 - VM_clientcount, - VM_clientstate, - VM_clcommand, - VM_changelevel, - VM_localsound, - VM_getmousepos, - VM_gettime, - VM_loadfromdata, - VM_loadfromfile, - VM_modulo, // 70 - e10, // 80 - e10, // 90 - e10, // 100 - e100, // 200 - e100, // 300 - e100, // 400 - // msg functions - VM_WriteByte, - VM_WriteChar, - VM_WriteShort, - VM_WriteLong, - VM_WriteAngle, - VM_WriteCoord, - VM_WriteString, - VM_WriteEntity, // 408 - 0, - 0, // 410 - e10, // 420 - e10, // 430 - e10, // 440 - e10, // 450 - // draw functions - VM_iscachedpic, - VM_precache_pic, - VM_freepic, - VM_drawcharacter, - VM_drawstring, - VM_drawpic, - VM_drawfill, - VM_drawsetcliparea, - VM_drawresetcliparea, - VM_getimagesize,// 460 - e10, // 470 - e10, // 480 - e10, // 490 - e10, // 500 - e100, // 600 - // menu functions - VM_M_setkeydest, - VM_M_getkeydest, - VM_M_setmousetarget, - VM_M_getmousetarget -}; - -const int vm_m_numbuiltins = sizeof(vm_m_builtins) / sizeof(prvm_builtin_t); - -void VM_M_Cmd_Init(void) -{ - VM_Cmd_Init(); -} - -void VM_M_Cmd_Reset(void) -{ - VM_Cmd_Init(); + VM_SAFEPARMCOUNT( 3, VM_altstr_set ); + + altstr = PRVM_G_STRING( OFS_PARM0 ); + //VM_CheckEmptyString( altstr ); + + num = PRVM_G_FLOAT( OFS_PARM1 ); + + str = PRVM_G_STRING( OFS_PARM2 ); + //VM_CheckEmptyString( str ); + + outstr = out = VM_GetTempString(); + for( num = num * 2 + 1, in = altstr; *in && num; *out++ = *in++ ) + if( *in == '\\' ) { + if( !*++in ) { + break; + } + } else if( *in == '\'' ) { + num--; + } + + if( !in ) { + PRVM_G_INT( OFS_RETURN ) = PRVM_SetEngineString( altstr ); + return; + } + // copy set in + for( ; *str; *out++ = *str++ ); + // now jump over the old content + for( ; *in ; in++ ) + if( *in == '\'' || (*in == '\\' && !*++in) ) + break; + + if( !in ) { + PRVM_G_INT( OFS_RETURN ) = PRVM_SetEngineString( NULL ); + return; + } + + strcpy( out, in ); + PRVM_G_INT( OFS_RETURN ) = PRVM_SetEngineString( outstr ); } +/* +======================== +VM_altstr_ins +insert after num +string altstr_ins(string altstr, float num, string set) +======================== +*/ +void VM_altstr_ins(void) +{ + int num; + const char *setstr; + const char *set; + const char *instr; + const char *in; + char *outstr; + char *out; + + in = instr = PRVM_G_STRING( OFS_PARM0 ); + num = PRVM_G_FLOAT( OFS_PARM1 ); + set = setstr = PRVM_G_STRING( OFS_PARM2 ); + + out = outstr = VM_GetTempString(); + for( num = num * 2 + 2 ; *in && num > 0 ; *out++ = *in++ ) + if( *in == '\\' ) { + if( !*++in ) { + break; + } + } else if( *in == '\'' ) { + num--; + } + + *out++ = '\''; + for( ; *set ; *out++ = *set++ ); + *out++ = '\''; + + strcpy( out, in ); + PRVM_G_INT( OFS_RETURN ) = PRVM_SetEngineString( outstr ); +} + +void VM_Cmd_Init(void) +{ + // only init the stuff for the current prog + VM_Files_Init(); + VM_Search_Init(); +} + +void VM_Cmd_Reset(void) +{ + CL_PurgeOwner( MENUOWNER ); + VM_Search_Reset(); + VM_Files_CloseAll(); +} + +