int break_statement;
int break_stack_index;
int watch_global;
- prvm_vec_t watch_global_value;
+ etype_t watch_global_type;
+ prvm_eval_t watch_global_value;
int watch_edict;
int watch_field;
- prvm_vec_t watch_edictfield_value;
+ etype_t watch_field_type;
+ prvm_eval_t watch_edictfield_value;
mfunction_t *xfunction;
int xstatement;
void PRVM_StackTrace(prvm_prog_t *prog);
void PRVM_Breakpoint(prvm_prog_t *prog, int stack_index, const char *text);
+void PRVM_Watchpoint(prvm_prog_t *prog, int stack_index, const char *text, etype_t type, prvm_eval_t *o, prvm_eval_t *n);
void VM_Warning(prvm_prog_t *prog, const char *fmt, ...) DP_FUNC_PRINTF(2);
}
memset(prog,0,sizeof(prvm_prog_t));
prog->break_statement = -1;
- prog->watch_global = -1;
- prog->watch_edict = -1;
+ prog->watch_global_type = ev_void;
+ prog->watch_field_type = ev_void;
}
/*
Host_Savegame_to(prog, va(vabuf, sizeof(vabuf), "breakpoint-%s.dmp", prog->name));
}
+void PRVM_Watchpoint(prvm_prog_t *prog, int stack_index, const char *text, etype_t type, prvm_eval_t *o, prvm_eval_t *n)
+{
+ size_t sz = sizeof(prvm_vec_t) * ((type & ~DEF_SAVEGLOBAL) == ev_vector ? 3 : 1);
+ if (memcmp(o, n, sz))
+ {
+ char buf[1024];
+ char valuebuf_o[128];
+ char valuebuf_n[128];
+ PRVM_UglyValueString(prog, type, o, valuebuf_o, sizeof(valuebuf_o));
+ PRVM_UglyValueString(prog, type, n, valuebuf_n, sizeof(valuebuf_n));
+ dpsnprintf(buf, sizeof(buf), "%s: %s -> %s", text, valuebuf_o, valuebuf_n);
+ PRVM_Breakpoint(prog, stack_index, buf);
+ memcpy(o, n, sz);
+ }
+}
+
static void PRVM_UpdateBreakpoints(prvm_prog_t *prog)
{
debug_data_t *debug = &debug_data[prog - prvm_prog_list];
if( !global )
{
Con_Printf( "%s progs: no global named '%s' to watch!\n", prog->name, debug->watch_global );
- prog->watch_global = -1;
+ prog->watch_global_type = ev_void;
}
else
{
+ size_t sz = sizeof(prvm_vec_t) * ((global->type & ~DEF_SAVEGLOBAL) == ev_vector ? 3 : 1);
prog->watch_global = global->ofs;
- prog->watch_global_value = PRVM_GLOBALFIELDFLOAT(prog->watch_global);
+ prog->watch_global_type = global->type;
+ memcpy(&prog->watch_global_value, PRVM_GLOBALFIELDVALUE(prog->watch_global), sz);
}
- if (prog->watch_global >= -1)
+ if (prog->watch_global_type != ev_void)
Con_Printf("%s progs: global watchpoint is at global index %d\n", prog->name, prog->watch_global);
}
else
- prog->watch_global = -1;
+ prog->watch_global_type = ev_void;
if (debug->watch_field[0])
{
if( !field )
{
Con_Printf( "%s progs: no field named '%s' to watch!\n", prog->name, debug->watch_field );
- prog->watch_edict = -1;
+ prog->watch_field_type = ev_void;
}
else
{
+ size_t sz = sizeof(prvm_vec_t) * ((field->type & ~DEF_SAVEGLOBAL) == ev_vector ? 3 : 1);
prog->watch_edict = debug->watch_edict;
prog->watch_field = field->ofs;
+ prog->watch_field_type = field->type;
if (prog->watch_edict < prog->num_edicts)
- prog->watch_edictfield_value = PRVM_EDICTFIELDFLOAT(PRVM_EDICT_NUM(prog->watch_edict), prog->watch_field);
+ memcpy(&prog->watch_edictfield_value, PRVM_EDICTFIELDVALUE(PRVM_EDICT_NUM(prog->watch_edict), prog->watch_field), sz);
else
- prog->watch_edictfield_value = 0;
+ memset(&prog->watch_edictfield_value, 0, sz);
}
- if (prog->watch_edict >= -1)
+ if (prog->watch_edict != ev_void)
Con_Printf("%s progs: edict field watchpoint is at edict %d field index %d\n", prog->name, prog->watch_edict, prog->watch_field);
}
else
- prog->watch_edict = -1;
+ prog->watch_field_type = ev_void;
}
static void PRVM_Breakpoint_f(void)
#if PRVMSLOWINTERPRETER
{
- char vabuf[1024];
- if (prog->watch_global >= 0)
+ if (prog->watch_global_type != ev_void)
{
- prvm_vec_t f = PRVM_GLOBALFIELDFLOAT(prog->watch_global);
- if (memcmp(&f, &prog->watch_global_value, sizeof(f)))
- {
- prog->xstatement = st + 1 - prog->statements;
- PRVM_Breakpoint(prog, 1, va(vabuf, sizeof(vabuf), "Global watchpoint hit by engine: " FLOAT_LOSSLESS_FORMAT " -> " FLOAT_LOSSLESS_FORMAT, prog->watch_global_value, f));
- prog->watch_global_value = f;
- }
+ prvm_eval_t *f = PRVM_GLOBALFIELDVALUE(prog->watch_global);
+ prog->xstatement = st + 1 - prog->statements;
+ PRVM_Watchpoint(prog, 1, "Global watchpoint hit by engine", prog->watch_global_type, &prog->watch_global_value, f);
}
- if (prog->watch_edict >= 0 && prog->watch_edict < prog->max_edicts)
+ if (prog->watch_field_type != ev_void && prog->watch_edict < prog->max_edicts)
{
- prvm_vec_t f = PRVM_EDICTFIELDFLOAT(prog->edicts + prog->watch_edict, prog->watch_field);
- if (memcmp(&f, &prog->watch_edictfield_value, sizeof(f)))
- {
- prog->xstatement = st + 1 - prog->statements;
- PRVM_Breakpoint(prog, 1, va(vabuf, sizeof(vabuf), "Entityfield watchpoint hit by engine: " FLOAT_LOSSLESS_FORMAT " -> " FLOAT_LOSSLESS_FORMAT, prog->watch_edictfield_value, f));
- prog->watch_edictfield_value = f;
- }
+ prvm_vec_t *f = PRVM_EDICTFIELDVALUE(prog->edicts + prog->watch_edict, prog->watch_field);
+ prog->xstatement = st + 1 - prog->statements;
+ PRVM_Watchpoint(prog, 1, "Entityfield watchpoint hit by engine", prog->watch_field_type, &prog->watch_edictfield_value, f);
}
}
#endif
}
#if PRVMSLOWINTERPRETER
{
- char vabuf[1024];
- if (prog->watch_global >= 0)
+ if (prog->watch_global_type != ev_void)
{
- prvm_vec_t f = PRVM_GLOBALFIELDFLOAT(prog->watch_global);
- if (memcmp(&f, &prog->watch_global_value, sizeof(f)))
- {
- prog->xstatement = st - prog->statements;
- PRVM_Breakpoint(prog, 0, va(vabuf, sizeof(vabuf), "Global watchpoint hit: " FLOAT_LOSSLESS_FORMAT " -> " FLOAT_LOSSLESS_FORMAT, prog->watch_global_value, f));
- prog->watch_global_value = f;
- }
+ prvm_eval_t *f = PRVM_GLOBALFIELDVALUE(prog->watch_global);
+ prog->xstatement = st - prog->statements;
+ PRVM_Watchpoint(prog, 0, "Global watchpoint hit", prog->watch_global_type, &prog->watch_global_value, f);
}
- if (prog->watch_edict >= 0 && prog->watch_edict < prog->max_edicts)
+ if (prog->watch_field_type != ev_void && prog->watch_edict < prog->max_edicts)
{
- prvm_vec_t f = PRVM_EDICTFIELDFLOAT(prog->edicts + prog->watch_edict, prog->watch_field);
- if (memcmp(&f, &prog->watch_edictfield_value, sizeof(f)))
- {
- prog->xstatement = st - prog->statements;
- PRVM_Breakpoint(prog, 0, va(vabuf, sizeof(vabuf), "Entityfield watchpoint hit: " FLOAT_LOSSLESS_FORMAT " -> " FLOAT_LOSSLESS_FORMAT, prog->watch_edictfield_value, f));
- prog->watch_edictfield_value = f;
- }
+ prvm_vec_t *f = PRVM_EDICTFIELDVALUE(prog->edicts + prog->watch_edict, prog->watch_field);
+ prog->xstatement = st - prog->statements;
+ PRVM_Watchpoint(prog, 0, "Entityfield watchpoint hit", prog->watch_field_type, &prog->watch_edictfield_value, f);
}
}
#endif