X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=prvm_edict.c;h=0dceb6900892eed0c61edf3cbb337f813daaddb9;hb=ba08e57c9d659bbe646cee4692b58db8598c985f;hp=1bf6e847d85bfab4a73666299e39ac20a7f2efad;hpb=ff690dc14daf8c520c49a10bf62cc4c5ca5b9d19;p=xonotic%2Fdarkplaces.git diff --git a/prvm_edict.c b/prvm_edict.c index 1bf6e847..0dceb690 100644 --- a/prvm_edict.c +++ b/prvm_edict.c @@ -20,6 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // AK new vm #include "quakedef.h" +#include "progsvm.h" prvm_prog_t *prog; @@ -70,7 +71,7 @@ void PRVM_MEM_Alloc() // set edict pointers for(i = 0; i < prog->max_edicts; i++) { - prog->edicts[i].e = (prvm_edict_private_t *)((qbyte *)prog->edictprivate + i * prog->edictprivate_size); + prog->edicts[i].p.e = (prvm_edict_private_t *)((qbyte *)prog->edictprivate + i * prog->edictprivate_size); prog->edicts[i].v = (void*)((qbyte *)prog->edictsfields + i * prog->edict_size); } } @@ -104,7 +105,7 @@ void PRVM_MEM_IncreaseEdicts() //set e and v pointers for(i = 0; i < prog->max_edicts; i++) { - prog->edicts[i].e = (prvm_edict_private_t *)((qbyte *)prog->edictprivate + i * prog->edictprivate_size); + prog->edicts[i].p.e = (prvm_edict_private_t *)((qbyte *)prog->edictprivate + i * prog->edictprivate_size); prog->edicts[i].v = (void*)((qbyte *)prog->edictsfields + i * prog->edict_size); } @@ -191,7 +192,7 @@ void PRVM_ED_ClearEdict (prvm_edict_t *e) { int num; memset (e->v, 0, prog->progs->entityfields * 4); - e->e->free = false; + e->p.e->free = false; // LordHavoc: for consistency set these here num = PRVM_NUM_FOR_EDICT(e) - 1; @@ -225,7 +226,7 @@ prvm_edict_t *PRVM_ED_Alloc (void) e = PRVM_EDICT_NUM(i); // the first couple seconds of server time can involve a lot of // freeing and allocating, so relax the replacement policy - if (e->e->free && ( e->e->freetime < 2 || (*prog->time - e->e->freetime) > 0.5 ) ) + if (e->p.e->free && ( e->p.e->freetime < 2 || (*prog->time - e->p.e->freetime) > 0.5 ) ) { PRVM_ED_ClearEdict (e); return e; @@ -261,8 +262,8 @@ void PRVM_ED_Free (prvm_edict_t *ed) PRVM_GCALL(free_edict)(ed); - ed->e->free = true; - ed->e->freetime = *prog->time; + ed->p.e->free = true; + ed->p.e->freetime = *prog->time; } //=========================================================================== @@ -383,7 +384,7 @@ char *PRVM_ValueString (etype_t type, prvm_eval_t *val) switch (type) { case ev_string: - sprintf (line, "%s", PRVM_GetString(val->string)); + strlcpy (line, PRVM_GetString (val->string), sizeof (line)); break; case ev_entity: n = val->edict; @@ -466,27 +467,27 @@ char *PRVM_UglyValueString (etype_t type, prvm_eval_t *val) line[i] = '\0'; break; case ev_entity: - snprintf (line, sizeof (line), "%i", PRVM_NUM_FOR_EDICT(PRVM_PROG_TO_EDICT(val->edict))); + dpsnprintf (line, sizeof (line), "%i", PRVM_NUM_FOR_EDICT(PRVM_PROG_TO_EDICT(val->edict))); break; case ev_function: f = pr_functions + val->function; - snprintf (line, sizeof (line), "%s", PRVM_GetString(f->s_name)); + strlcpy (line, PRVM_GetString (f->s_name), sizeof (line)); break; case ev_field: def = PRVM_ED_FieldAtOfs ( val->_int ); - snprintf (line, sizeof (line), ".%s", PRVM_GetString(def->s_name)); + dpsnprintf (line, sizeof (line), ".%s", PRVM_GetString(def->s_name)); break; case ev_void: - snprintf (line, sizeof (line), "void"); + dpsnprintf (line, sizeof (line), "void"); break; case ev_float: - snprintf (line, sizeof (line), "%f", val->_float); + dpsnprintf (line, sizeof (line), "%f", val->_float); break; case ev_vector: - snprintf (line, sizeof (line), "%f %f %f", val->vector[0], val->vector[1], val->vector[2]); + dpsnprintf (line, sizeof (line), "%f %f %f", val->vector[0], val->vector[1], val->vector[2]); break; default: - snprintf (line, sizeof (line), "bad type %i", type); + dpsnprintf (line, sizeof (line), "bad type %i", type); break; } @@ -557,7 +558,7 @@ For debugging */ // LordHavoc: optimized this to print out much more quickly (tempstring) // LordHavoc: changed to print out every 4096 characters (incase there are a lot of fields to print) -void PRVM_ED_Print (prvm_edict_t *ed) +void PRVM_ED_Print(prvm_edict_t *ed) { int l; ddef_t *d; @@ -567,9 +568,9 @@ void PRVM_ED_Print (prvm_edict_t *ed) int type; char tempstring[8192], tempstring2[260]; // temporary string buffers - if (ed->e->free) + if (ed->p.e->free) { - Con_Printf ("%s: FREE\n",PRVM_NAME); + Con_Printf("%s: FREE\n",PRVM_NAME); return; } @@ -595,7 +596,7 @@ void PRVM_ED_Print (prvm_edict_t *ed) if (strlen(name) > 256) { - strncpy(tempstring2, name, 256); + memcpy (tempstring2, name, 256); tempstring2[256] = tempstring2[257] = tempstring2[258] = '.'; tempstring2[259] = 0; name = tempstring2; @@ -608,7 +609,7 @@ void PRVM_ED_Print (prvm_edict_t *ed) name = PRVM_ValueString(d->type, (prvm_eval_t *)v); if (strlen(name) > 256) { - strncpy(tempstring2, name, 256); + memcpy (tempstring2, name, 256); tempstring2[256] = tempstring2[257] = tempstring2[258] = '.'; tempstring2[259] = 0; name = tempstring2; @@ -617,12 +618,12 @@ void PRVM_ED_Print (prvm_edict_t *ed) strcat(tempstring, "\n"); if (strlen(tempstring) >= 4096) { - Con_Printf("%s", tempstring); + Con_Print(tempstring); tempstring[0] = 0; } } if (tempstring[0]) - Con_Printf("%s", tempstring); + Con_Print(tempstring); } /* @@ -640,11 +641,11 @@ void PRVM_ED_Write (qfile_t *f, prvm_edict_t *ed) char *name; int type; - FS_Printf (f, "{\n"); + FS_Print(f, "{\n"); - if (ed->e->free) + if (ed->p.e->free) { - FS_Printf (f, "}\n"); + FS_Print(f, "}\n"); return; } @@ -665,16 +666,16 @@ void PRVM_ED_Write (qfile_t *f, prvm_edict_t *ed) if (j == prvm_type_size[type]) continue; - FS_Printf (f,"\"%s\" ",name); - FS_Printf (f,"\"%s\"\n", PRVM_UglyValueString(d->type, (prvm_eval_t *)v)); + FS_Printf(f,"\"%s\" ",name); + FS_Printf(f,"\"%s\"\n", PRVM_UglyValueString(d->type, (prvm_eval_t *)v)); } - FS_Printf (f, "}\n"); + FS_Print(f, "}\n"); } void PRVM_ED_PrintNum (int ent) { - PRVM_ED_Print (PRVM_EDICT_NUM(ent)); + PRVM_ED_Print(PRVM_EDICT_NUM(ent)); } /* @@ -698,7 +699,7 @@ void PRVM_ED_PrintEdicts_f (void) if(!PRVM_SetProgFromString(Cmd_Argv(1))) return; - Con_Printf ("%s: %i entities\n", PRVM_NAME, prog->num_edicts); + Con_Printf("%s: %i entities\n", PRVM_NAME, prog->num_edicts); for (i=0 ; inum_edicts ; i++) PRVM_ED_PrintNum (i); @@ -729,7 +730,7 @@ void PRVM_ED_PrintEdict_f (void) i = atoi (Cmd_Argv(2)); if (i >= prog->num_edicts) { - Con_Printf("Bad edict number\n"); + Con_Print("Bad edict number\n"); PRVM_End; return; } @@ -771,13 +772,13 @@ void PRVM_ED_Count_f (void) for (i=0 ; inum_edicts ; i++) { ent = PRVM_EDICT_NUM(i); - if (ent->e->free) + if (ent->p.e->free) continue; active++; } - Con_Printf ("num_edicts:%3i\n", prog->num_edicts); - Con_Printf ("active :%3i\n", active); + Con_Printf("num_edicts:%3i\n", prog->num_edicts); + Con_Printf("active :%3i\n", active); } PRVM_End; @@ -804,7 +805,7 @@ void PRVM_ED_WriteGlobals (qfile_t *f) char *name; int type; - FS_Printf (f,"{\n"); + FS_Print(f,"{\n"); for (i=0 ; iprogs->numglobaldefs ; i++) { def = &prog->globaldefs[i]; @@ -817,10 +818,10 @@ void PRVM_ED_WriteGlobals (qfile_t *f) continue; name = PRVM_GetString(def->s_name); - FS_Printf (f,"\"%s\" ", name); - FS_Printf (f,"\"%s\"\n", PRVM_UglyValueString(type, (prvm_eval_t *)&prog->globals[def->ofs])); + FS_Printf(f,"\"%s\" ", name); + FS_Printf(f,"\"%s\"\n", PRVM_UglyValueString(type, (prvm_eval_t *)&prog->globals[def->ofs])); } - FS_Printf (f,"}\n"); + FS_Print(f,"}\n"); } /* @@ -853,7 +854,7 @@ void PRVM_ED_ParseGlobals (const char *data) key = PRVM_ED_FindGlobal (keyname); if (!key) { - Con_DPrintf ("'%s' is not a global on %s\n", keyname, PRVM_NAME); + Con_DPrintf("'%s' is not a global on %s\n", keyname, PRVM_NAME); continue; } @@ -896,7 +897,6 @@ char *PRVM_ED_NewString (const char *string) return new; } - /* ============= PRVM_ED_ParseEval @@ -915,7 +915,7 @@ qboolean PRVM_ED_ParseEpair(prvm_edict_t *ent, ddef_t *key, const char *s) if (ent) val = (prvm_eval_t *)((int *)ent->v + key->ofs); else - val = (prvm_eval_t *)((int *)pr_globals + key->ofs); + val = (prvm_eval_t *)((int *)prog->globals + key->ofs); switch (key->type & ~DEF_SAVEGLOBAL) { case ev_string: @@ -965,14 +965,14 @@ qboolean PRVM_ED_ParseEpair(prvm_edict_t *ent, ddef_t *key, const char *s) Con_DPrintf("PRVM_ED_ParseEpair: Can't find field %s in %s\n", s, PRVM_NAME); return false; } - val->_int = PRVM_G_INT(def->ofs); + val->_int = def->ofs; break; case ev_function: func = PRVM_ED_FindFunction(s); if (!func) { - Con_Printf ("PRVM_ED_ParseEpair: Can't find function %s in %s\n", s, PRVM_NAME); + Con_Printf("PRVM_ED_ParseEpair: Can't find function %s in %s\n", s, PRVM_NAME); return false; } val->function = func - prog->functions; @@ -985,6 +985,41 @@ qboolean PRVM_ED_ParseEpair(prvm_edict_t *ent, ddef_t *key, const char *s) return true; } +/* +============= +PRVM_ED_EdictSet_f + +Console command to set a field of a specified edict +============= +*/ +void PRVM_ED_EdictSet_f(void) +{ + prvm_edict_t *ed; + ddef_t *key; + + if(Cmd_Argc() != 5) + { + Con_Print("prvm_edictset \n"); + return; + } + + PRVM_Begin; + if(!PRVM_SetProgFromString(Cmd_Argv(1))) + { + Con_Printf("Wrong program name %s !\n", Cmd_Argv(1)); + return; + } + + ed = PRVM_EDICT_NUM(atoi(Cmd_Argv(2))); + + if((key = PRVM_ED_FindField(Cmd_Argv(3))) == 0) + Con_Printf("Key %s not found !\n", Cmd_Argv(3)); + else + PRVM_ED_ParseEpair(ed, key, Cmd_Argv(4)); + + PRVM_End; +} + /* ==================== PRVM_ED_ParseEdict @@ -1004,10 +1039,6 @@ const char *PRVM_ED_ParseEdict (const char *data, prvm_edict_t *ent) init = false; -// clear it - if (ent != prog->edicts) // hack - memset (ent->v, 0, prog->progs->entityfields * 4); - // go through all the dictionary pairs while (1) { @@ -1058,7 +1089,7 @@ const char *PRVM_ED_ParseEdict (const char *data, prvm_edict_t *ent) key = PRVM_ED_FindField (keyname); if (!key) { - Con_DPrintf ("%s: '%s' is not a field\n", PRVM_NAME, keyname); + Con_DPrintf("%s: '%s' is not a field\n", PRVM_NAME, keyname); continue; } @@ -1074,7 +1105,7 @@ const char *PRVM_ED_ParseEdict (const char *data, prvm_edict_t *ent) } if (!init) - ent->e->free = true; + ent->p.e->free = true; return data; } @@ -1122,6 +1153,10 @@ void PRVM_ED_LoadFromFile (const char *data) else ent = PRVM_ED_Alloc(); + // clear it + if (ent != prog->edicts) // hack + memset (ent->v, 0, prog->progs->entityfields * 4); + data = PRVM_ED_ParseEdict (data, ent); parsed++; @@ -1134,15 +1169,15 @@ void PRVM_ED_LoadFromFile (const char *data) } // -// immediately call spawn function, but only if there is a self global +// immediately call spawn function, but only if there is a self global and a classname // if(prog->self && prog->flag & PRVM_FE_CLASSNAME) { string_t handle = *(string_t*)&((float*)ent->v)[PRVM_ED_FindFieldOffset("classname")]; if (!handle) { - Con_Printf ("No classname for:\n"); - PRVM_ED_Print (ent); + Con_Print("No classname for:\n"); + PRVM_ED_Print(ent); PRVM_ED_Free (ent); continue; } @@ -1154,8 +1189,8 @@ void PRVM_ED_LoadFromFile (const char *data) { if (developer.integer) // don't confuse non-developers with errors { - Con_Printf ("No spawn function for:\n"); - PRVM_ED_Print (ent); + Con_Print("No spawn function for:\n"); + PRVM_ED_Print(ent); } PRVM_ED_Free (ent); continue; @@ -1167,11 +1202,11 @@ void PRVM_ED_LoadFromFile (const char *data) } spawned++; - if (ent->e->free) + if (ent->p.e->free) died++; } - Con_DPrintf ("%s: %i new entities parsed, %i new inhibited, %i (%i new) spawned (whereas %i removed self, %i stayed)\n", PRVM_NAME, parsed, inhibited, prog->num_edicts, spawned, died, spawned - died); + Con_DPrintf("%s: %i new entities parsed, %i new inhibited, %i (%i new) spawned (whereas %i removed self, %i stayed)\n", PRVM_NAME, parsed, inhibited, prog->num_edicts, spawned, died, spawned - died); } // not used @@ -1198,7 +1233,7 @@ PRVM_ResetProg void PRVM_ResetProg() { - mempool_t *t1, *t2, *t3; + /*mempool_t *t1, *t2, *t3; t1 = prog->progs_mempool; t2 = prog->edictstring_mempool; @@ -1206,15 +1241,18 @@ void PRVM_ResetProg() Mem_EmptyPool(prog->progs_mempool); Mem_EmptyPool(prog->edictstring_mempool); - Mem_EmptyPool(prog->edicts_mempool); + Mem_EmptyPool(prog->edicts_mempool);*/ + Mem_FreePool(&prog->progs_mempool); + Mem_FreePool(&prog->edictstring_mempool); + Mem_FreePool(&prog->edicts_mempool); memset(prog,0,sizeof(prvm_prog_t)); - prog->time = &prog->_time; + /*prog->time = &prog->_time; prog->progs_mempool = t1; prog->edictstring_mempool = t2; - prog->edicts_mempool = t3; + prog->edicts_mempool = t3;*/ PRVM_GCALL(reset_cmd)(); } @@ -1229,22 +1267,16 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, char **required int i; dstatement_t *st; ddef_t *infielddefs; - void *temp; dfunction_t *dfunctions; Mem_EmptyPool(prog->progs_mempool); Mem_EmptyPool(prog->edictstring_mempool); - temp = FS_LoadFile (filename, false); - if (temp == 0) + prog->progs = (dprograms_t *)FS_LoadFile (filename, prog->progs_mempool, false); + if (prog->progs == NULL) PRVM_ERROR ("PRVM_LoadProgs: couldn't load %s for %s", filename, PRVM_NAME); - prog->progs = (dprograms_t *)Mem_Alloc(prog->progs_mempool, fs_filesize); - - memcpy(prog->progs, temp, fs_filesize); - Mem_Free(temp); - - Con_DPrintf ("%s programs occupy %iK.\n", PRVM_NAME, fs_filesize/1024); + Con_DPrintf("%s programs occupy %iK.\n", PRVM_NAME, fs_filesize/1024); pr_crc = CRC_Block((qbyte *)prog->progs, fs_filesize); @@ -1448,7 +1480,7 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, char **required prog->self = PRVM_ED_FindGlobal("self"); - if(PRVM_ED_FindGlobal("time")) + if( PRVM_ED_FindGlobal("time") && PRVM_ED_FindGlobal("time")->type & ev_float ) prog->time = &PRVM_G_FLOAT(PRVM_ED_FindGlobal("time")->ofs); if(PRVM_ED_FindField ("chain")) @@ -1462,6 +1494,7 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, char **required prog->flag |= PRVM_OP_STATE; PRVM_GCALL(reset_cmd)(); + PRVM_GCALL(init_cmd)(); // init mempools PRVM_MEM_Alloc(); @@ -1481,7 +1514,7 @@ void PRVM_Fields_f (void) /* if (!sv.active) { - Con_Printf("no progs loaded\n"); + Con_Print("no progs loaded\n"); return; } */ @@ -1500,7 +1533,7 @@ void PRVM_Fields_f (void) for (ednum = 0;ednum < prog->max_edicts;ednum++) { ed = PRVM_EDICT_NUM(ednum); - if (ed->e->free) + if (ed->p.e->free) continue; for (i = 1;i < prog->progs->numfielddefs;i++) { @@ -1562,7 +1595,7 @@ void PRVM_Fields_f (void) } if (strlen(name) > 256) { - strncpy(tempstring2, name, 256); + memcpy (tempstring2, name, 256); tempstring2[256] = tempstring2[257] = tempstring2[258] = '.'; tempstring2[259] = 0; name = tempstring2; @@ -1575,7 +1608,7 @@ void PRVM_Fields_f (void) strcat(tempstring, "\n"); if (strlen(tempstring) >= 4096) { - Con_Printf("%s", tempstring); + Con_Print(tempstring); tempstring[0] = 0; } if (counts[i]) @@ -1596,12 +1629,12 @@ void PRVM_Globals_f (void) // TODO /*if (!sv.active) { - Con_Printf("no progs loaded\n"); + Con_Print("no progs loaded\n"); return; }*/ if(Cmd_Argc () != 2) { - Con_Print ("prvm_globals \n"); + Con_Print("prvm_globals \n"); return; } @@ -1618,6 +1651,56 @@ void PRVM_Globals_f (void) PRVM_End; } +/* +=============== +PRVM_Global +=============== +*/ +void PRVM_Global_f(void) +{ + ddef_t *global; + if( Cmd_Argc() != 3 ) { + Con_Printf( "prvm_global \n" ); + return; + } + + PRVM_Begin; + if( !PRVM_SetProgFromString( Cmd_Argv(1) ) ) + return; + + global = PRVM_ED_FindGlobal( Cmd_Argv(2) ); + if( !global ) + Con_Printf( "No global '%s' in %s!\n", Cmd_Argv(2), Cmd_Argv(1) ); + else + Con_Printf( "%s: %s\n", Cmd_Argv(2), PRVM_ValueString( global->type, (prvm_eval_t *) &prog->globals[ global->ofs ] ) ); + PRVM_End; +} + +/* +=============== +PRVM_GlobalSet +=============== +*/ +void PRVM_GlobalSet_f(void) +{ + ddef_t *global; + if( Cmd_Argc() != 4 ) { + Con_Printf( "prvm_globalset \n" ); + return; + } + + PRVM_Begin; + if( !PRVM_SetProgFromString( Cmd_Argv(1) ) ) + return; + + global = PRVM_ED_FindGlobal( Cmd_Argv(2) ); + if( !global ) + Con_Printf( "No global '%s' in %s!\n", Cmd_Argv(2), Cmd_Argv(1) ); + else + PRVM_ED_ParseEpair( NULL, global, Cmd_Argv(3) ); + PRVM_End; +} + /* =============== PRVM_Init @@ -1631,6 +1714,9 @@ void PRVM_Init (void) Cmd_AddCommand ("prvm_profile", PRVM_Profile_f); Cmd_AddCommand ("prvm_fields", PRVM_Fields_f); Cmd_AddCommand ("prvm_globals", PRVM_Globals_f); + Cmd_AddCommand ("prvm_global", PRVM_Global_f); + Cmd_AddCommand ("prvm_globalset", PRVM_GlobalSet_f); + Cmd_AddCommand ("prvm_edictset", PRVM_ED_EdictSet_f); // LordHavoc: optional runtime bounds checking (speed drain, but worth it for security, on by default - breaks most QCCX features (used by CRMod and others)) Cvar_RegisterVariable (&prvm_boundscheck); Cvar_RegisterVariable (&prvm_traceqc); @@ -1650,11 +1736,12 @@ void PRVM_InitProg(int prognr) prog = &prog_list[prognr]; + if(prog->loaded) + PRVM_ResetProg(); + memset(prog, 0, sizeof(prvm_prog_t)); prog->time = &prog->_time; - - PRVM_GCALL(init_cmd)(); } int PRVM_GetProgNr()