[gamecode] Wrap most uses of PR_RESET_PARAMS with push/pop frame

rua_obj was skipped because that looks to be a bit more work and should
be a separate commit.

This is to avoid the stack getting mangled when calling progs functions
with parameters.
This commit is contained in:
Bill Currie 2022-02-05 10:24:02 +09:00
parent 529253e6d9
commit 01345ba675
5 changed files with 40 additions and 50 deletions

View file

@ -683,12 +683,14 @@ Menu_Draw (view_t *view)
int ret;
run_menu_pre ();
PR_PushFrame (&menu_pr_state);
PR_RESET_PARAMS (&menu_pr_state);
P_INT (&menu_pr_state, 0) = x;
P_INT (&menu_pr_state, 1) = y;
menu_pr_state.pr_argc = 2;
PR_ExecuteProgram (&menu_pr_state, menu->draw);
ret = R_INT (&menu_pr_state);
PR_PopFrame (&menu_pr_state);
run_menu_post ();
if (!ret)
return;
@ -718,11 +720,13 @@ Menu_Draw (view_t *view)
item = menu->items[menu->cur_item];
if (menu->cursor) {
run_menu_pre ();
PR_PushFrame (&menu_pr_state);
PR_RESET_PARAMS (&menu_pr_state);
P_INT (&menu_pr_state, 0) = x + item->x;
P_INT (&menu_pr_state, 1) = y + item->y;
menu_pr_state.pr_argc = 2;
PR_ExecuteProgram (&menu_pr_state, menu->cursor);
PR_PopFrame (&menu_pr_state);
run_menu_post ();
} else {
r_funcs->Draw_Character (x + item->x, y + item->y,
@ -751,6 +755,7 @@ menu_key_event (const IE_event_t *ie_event)
return 0;
if (menu->keyevent) {
run_menu_pre ();
PR_PushFrame (&menu_pr_state);
PR_RESET_PARAMS (&menu_pr_state);
P_INT (&menu_pr_state, 0) = key.code;
P_INT (&menu_pr_state, 1) = key.unicode;
@ -758,6 +763,7 @@ menu_key_event (const IE_event_t *ie_event)
menu_pr_state.pr_argc = 3;
PR_ExecuteProgram (&menu_pr_state, menu->keyevent);
ret = R_INT (&menu_pr_state);
PR_PopFrame (&menu_pr_state);
run_menu_post ();
if (ret)
return 1;
@ -772,8 +778,8 @@ menu_key_event (const IE_event_t *ie_event)
P_INT (&menu_pr_state, 1) = key.code;
menu_pr_state.pr_argc = 2;
PR_ExecuteProgram (&menu_pr_state, item->func);
PR_PopFrame (&menu_pr_state);
ret = R_INT (&menu_pr_state);
PR_PopFrame (&menu_pr_state);
run_menu_post ();
if (ret)
return 1;

View file

@ -283,6 +283,7 @@ rua_listener_func (rua_in_cookie_t *cookie, const void *input)
{
progs_t *pr = cookie->pr;
PR_PushFrame (pr);
PR_RESET_PARAMS (pr);
P_POINTER (pr, 0) = cookie->data;
P_POINTER (pr, 1) = PR_SetPointer (pr, input);//FIXME check input
pr->pr_argc = 2;

View file

@ -72,12 +72,15 @@ rua_compare (const void *a, const void *b, void *_f)
{
function_t *f = _f;
PR_PushFrame (f->pr);
PR_RESET_PARAMS (f->pr);
P_POINTER (f->pr, 0) = PR_SetPointer (f->pr, a);
P_POINTER (f->pr, 1) = PR_SetPointer (f->pr, b);
f->pr->pr_argc = 2;
PR_ExecuteProgram (f->pr, f->func);
return R_INT (f->pr);
int cmp = R_INT (f->pr);
PR_PopFrame (f->pr);
return cmp;
}
static void

View file

@ -213,19 +213,29 @@ typedef struct sv_data_s {
#define EDICT_FROM_AREA(l) (STRUCT_FROM_LINK(l,sv_data_t,area)->edict)
static inline void
sv_pr_touch (edict_t *self, edict_t *other)
sv_pr_exec (edict_t *self, edict_t *other, pr_func_t func)
{
pr_int_t this;
*sv_globals.self = EDICT_TO_PROG (&sv_pr_state, self);
*sv_globals.other = EDICT_TO_PROG (&sv_pr_state, other);
if ((this = sv_pr_state.fields.this) != -1) {
PR_PushFrame (&sv_pr_state);
PR_RESET_PARAMS (&sv_pr_state);
P_INT (&sv_pr_state, 0) = E_POINTER (self, this);
P_INT (&sv_pr_state, 1) = 0;
P_INT (&sv_pr_state, 2) = E_POINTER (other, this);
}
PR_ExecuteProgram (&sv_pr_state, SVfunc (self, touch));
PR_ExecuteProgram (&sv_pr_state, func);
if ((this = sv_pr_state.fields.this) != -1) {
PR_PopFrame (&sv_pr_state);
}
}
static inline void
sv_pr_touch (edict_t *self, edict_t *other)
{
sv_pr_exec (self, other, SVfunc (self, touch));
}
static inline void
@ -236,33 +246,13 @@ sv_pr_use (edict_t *self, edict_t *other)
static inline void
sv_pr_think (edict_t *self)
{
pr_int_t this;
*sv_globals.self = EDICT_TO_PROG (&sv_pr_state, self);
*sv_globals.other = 0;
if ((this = sv_pr_state.fields.this) != -1) {
PR_RESET_PARAMS (&sv_pr_state);
P_INT (&sv_pr_state, 0) = E_POINTER (self, this);
P_INT (&sv_pr_state, 1) = 0;
P_INT (&sv_pr_state, 2) = 0;
}
PR_ExecuteProgram (&sv_pr_state, SVfunc (self, think));
sv_pr_exec (self, 0, SVfunc (self, think));
}
static inline void
sv_pr_blocked (edict_t *self, edict_t *other)
{
pr_int_t this;
*sv_globals.self = EDICT_TO_PROG (&sv_pr_state, self);
*sv_globals.other = EDICT_TO_PROG (&sv_pr_state, other);
if ((this = sv_pr_state.fields.this) != -1) {
PR_RESET_PARAMS (&sv_pr_state);
P_INT (&sv_pr_state, 0) = E_POINTER (self, this);
P_INT (&sv_pr_state, 1) = 0;
P_INT (&sv_pr_state, 2) = E_POINTER (other, this);
}
PR_ExecuteProgram (&sv_pr_state, SVfunc (self, blocked));
sv_pr_exec (self, other, SVfunc (self, blocked));
}
#endif // __sv_progs_h

View file

@ -218,19 +218,29 @@ typedef struct sv_data_s {
#define EDICT_FROM_AREA(l) (STRUCT_FROM_LINK(l,sv_data_t,area)->edict)
static inline void
sv_pr_touch (edict_t *self, edict_t *other)
sv_pr_exec (edict_t *self, edict_t *other, pr_func_t func)
{
pr_int_t this;
*sv_globals.self = EDICT_TO_PROG (&sv_pr_state, self);
*sv_globals.other = EDICT_TO_PROG (&sv_pr_state, other);
if ((this = sv_pr_state.fields.this) != -1) {
PR_PushFrame (&sv_pr_state);
PR_RESET_PARAMS (&sv_pr_state);
P_INT (&sv_pr_state, 0) = E_POINTER (self, this);
P_INT (&sv_pr_state, 1) = 0;
P_INT (&sv_pr_state, 2) = E_POINTER (other, this);
}
PR_ExecuteProgram (&sv_pr_state, SVfunc (self, touch));
PR_ExecuteProgram (&sv_pr_state, func);
if ((this = sv_pr_state.fields.this) != -1) {
PR_PopFrame (&sv_pr_state);
}
}
static inline void
sv_pr_touch (edict_t *self, edict_t *other)
{
sv_pr_exec (self, other, SVfunc (self, touch));
}
static inline void
@ -241,33 +251,13 @@ sv_pr_use (edict_t *self, edict_t *other)
static inline void
sv_pr_think (edict_t *self)
{
pr_int_t this;
*sv_globals.self = EDICT_TO_PROG (&sv_pr_state, self);
*sv_globals.other = 0;
if ((this = sv_pr_state.fields.this) != -1) {
PR_RESET_PARAMS (&sv_pr_state);
P_INT (&sv_pr_state, 0) = E_POINTER (self, this);
P_INT (&sv_pr_state, 1) = 0;
P_INT (&sv_pr_state, 2) = 0;
}
PR_ExecuteProgram (&sv_pr_state, SVfunc (self, think));
sv_pr_exec (self, 0, SVfunc (self, think));
}
static inline void
sv_pr_blocked (edict_t *self, edict_t *other)
{
pr_int_t this;
*sv_globals.self = EDICT_TO_PROG (&sv_pr_state, self);
*sv_globals.other = EDICT_TO_PROG (&sv_pr_state, other);
if ((this = sv_pr_state.fields.this) != -1) {
PR_RESET_PARAMS (&sv_pr_state);
P_INT (&sv_pr_state, 0) = E_POINTER (self, this);
P_INT (&sv_pr_state, 1) = 0;
P_INT (&sv_pr_state, 2) = E_POINTER (other, this);
}
PR_ExecuteProgram (&sv_pr_state, SVfunc (self, blocked));
sv_pr_exec (self, other, SVfunc (self, blocked));
}
#endif // __sv_progs_h