break;
case ev_float:
// LordHavoc: changed from %5.1f to %10.4f
- dpsnprintf (line, linelength, "%10.4f", val->_float);
+ dpsnprintf (line, linelength, FLOAT_LOSSLESS_FORMAT, val->_float);
break;
case ev_vector:
// LordHavoc: changed from %5.1f to %10.4f
- dpsnprintf (line, linelength, "'%10.4f %10.4f %10.4f'", val->vector[0], val->vector[1], val->vector[2]);
+ dpsnprintf (line, linelength, "'" VECTOR_LOSSLESS_FORMAT "'", val->vector[0], val->vector[1], val->vector[2]);
break;
case ev_pointer:
dpsnprintf (line, linelength, "pointer");
line[i] = '\0';
break;
case ev_entity:
- dpsnprintf (line, linelength, "%i", PRVM_NUM_FOR_EDICT(PRVM_PROG_TO_EDICT(val->edict)));
+ dpsnprintf (line, linelength, "%i", val->edict);
break;
case ev_function:
f = prog->functions + val->function;
dpsnprintf (line, linelength, "void");
break;
case ev_float:
- dpsnprintf (line, linelength, "%.9g", val->_float);
+ dpsnprintf (line, linelength, FLOAT_LOSSLESS_FORMAT, val->_float);
break;
case ev_vector:
- dpsnprintf (line, linelength, "%.9g %.9g %.9g", val->vector[0], val->vector[1], val->vector[2]);
+ dpsnprintf (line, linelength, VECTOR_LOSSLESS_FORMAT, val->vector[0], val->vector[1], val->vector[2]);
break;
default:
dpsnprintf (line, linelength, "bad type %i", type);
PRVM_LoadProgs
===============
*/
-void PRVM_Prog_Load(prvm_prog_t *prog, const char * filename, int numrequiredfunc, const char **required_func, int numrequiredfields, prvm_required_field_t *required_field, int numrequiredglobals, prvm_required_field_t *required_global)
+void PRVM_Prog_Load(prvm_prog_t *prog, const char * filename, unsigned char * data, fs_offset_t size, int numrequiredfunc, const char **required_func, int numrequiredfields, prvm_required_field_t *required_field, int numrequiredglobals, prvm_required_field_t *required_global)
{
int i;
dprograms_t *dprograms;
Host_LockSession(); // all progs can use the session cvar
Crypto_LoadKeys(); // all progs might use the keys at init time
- dprograms = (dprograms_t *)FS_LoadFile (filename, prog->progs_mempool, false, &filesize);
+ if (data)
+ {
+ dprograms = (dprograms_t *) data;
+ filesize = size;
+ }
+ else
+ dprograms = (dprograms_t *)FS_LoadFile (filename, prog->progs_mempool, false, &filesize);
if (dprograms == NULL || filesize < (fs_offset_t)sizeof(dprograms_t))
prog->error_cmd("PRVM_LoadProgs: couldn't load %s for %s", filename, prog->name);
// TODO bounds check header fields (e.g. numstatements), they must never go behind end of file
// we need to expand the globaldefs and fielddefs to include engine defs
prog->globaldefs = (ddef_t *)Mem_Alloc(prog->progs_mempool, (prog->progs_numglobaldefs + numrequiredglobals) * sizeof(ddef_t));
- prog->globals.fp = (prvm_vec_t *)Mem_Alloc(prog->progs_mempool, (prog->progs_numglobals + requiredglobalspace) * sizeof(prvm_vec_t));
+ prog->globals.fp = (prvm_vec_t *)Mem_Alloc(prog->progs_mempool, (prog->progs_numglobals + requiredglobalspace + 2) * sizeof(prvm_vec_t));
+ // + 2 is because of an otherwise occurring overrun in RETURN instruction
+ // when trying to return the last or second-last global
+ // (RETURN always returns a vector, there is no RETURN_F instruction)
prog->fielddefs = (ddef_t *)Mem_Alloc(prog->progs_mempool, (prog->progs_numfielddefs + numrequiredfields) * sizeof(ddef_t));
// we need to convert the statements to our memory format
prog->statements = (mstatement_t *)Mem_Alloc(prog->progs_mempool, prog->progs_numstatements * sizeof(mstatement_t));
}
// we're done with the file now
- Mem_Free(dprograms);
+ if(!data)
+ Mem_Free(dprograms);
dprograms = NULL;
// check required functions