mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-03-21 09:51:41 +00:00
[gamecode] Add double time state instructions
This has been a long-held wishlist item, really, and I thought I might as well take the opportunity to add the instructions. The double versions of STATE require both the nextthink field and time global to be double (but they're not resolved properly yet: marked with "FIXME double time" comments). Also, the frame number for double time state is integer rather than float.
This commit is contained in:
parent
d57712975e
commit
2b82533526
9 changed files with 87 additions and 45 deletions
|
@ -1962,7 +1962,8 @@ struct progs_s {
|
|||
/// \name globals and fields needed by the VM
|
||||
///@{
|
||||
struct {
|
||||
float *time; ///< required for OP_STATE
|
||||
double *dtime; ///< required for OP_STATE d
|
||||
float *ftime; ///< required for OP_STATE f
|
||||
pr_int_t *self; ///< required for OP_STATE
|
||||
pointer_t *stack; ///< required for OP_(PUSH|POP)*
|
||||
} globals;
|
||||
|
|
|
@ -134,7 +134,7 @@ menu_resolve_globals (progs_t *pr)
|
|||
|
||||
if (!(def = PR_FindGlobal (pr, sym = "time")))
|
||||
goto error;
|
||||
menu_pr_state.globals.time = &G_FLOAT (pr, def->ofs);
|
||||
menu_pr_state.globals.ftime = &G_FLOAT (pr, def->ofs);//FIXME double time
|
||||
return 1;
|
||||
error:
|
||||
Sys_Printf ("%s: undefined symbol %s\n", pr->progs_name, sym);
|
||||
|
@ -672,7 +672,7 @@ Menu_Draw (view_t *view)
|
|||
if (menu->fadescreen)
|
||||
r_funcs->Draw_FadeScreen ();
|
||||
|
||||
*menu_pr_state.globals.time = *con_data.realtime;
|
||||
*menu_pr_state.globals.ftime = *con_data.realtime;//FIXME double time
|
||||
|
||||
if (menu->draw) {
|
||||
int ret;
|
||||
|
@ -729,7 +729,7 @@ void
|
|||
Menu_Draw_Hud (view_t *view)
|
||||
{
|
||||
run_menu_pre ();
|
||||
*menu_pr_state.globals.time = *con_data.realtime;
|
||||
*menu_pr_state.globals.ftime = *con_data.realtime;//FIXME double time
|
||||
|
||||
PR_ExecuteProgram (&menu_pr_state, menu_draw_hud);
|
||||
run_menu_post ();
|
||||
|
|
|
@ -19,14 +19,16 @@ bitmap_txt = """
|
|||
1 1010 t100 swizzle
|
||||
1 1011 tooo vecops
|
||||
1 1101 01oo move
|
||||
1 1101 0111 convert (conversion mode in st->b)
|
||||
1 1101 11oo memset
|
||||
1 1101 1111 with (mode in st->a, value in st->b, reg in st->c)
|
||||
1 1101 c111 statef
|
||||
1 1110 c1cc branch
|
||||
1 1110 t111 state
|
||||
1 1110 c111 stated
|
||||
1 1111 00mm lea
|
||||
1 1111 01td vecops2
|
||||
1 1111 1nnn
|
||||
1 1111 10nn
|
||||
1 1111 1100 convert (conversion mode in st->b)
|
||||
1 1111 1101 with (mode in st->a, value in st->b, reg in st->c)
|
||||
1 1111 1110
|
||||
1 1111 1111 hops
|
||||
"""
|
||||
|
||||
|
@ -328,19 +330,32 @@ shiftops_formats = {
|
|||
],
|
||||
},
|
||||
}
|
||||
state_formats = {
|
||||
"opcode": "OP_STATE_{state[t]}",
|
||||
"mnemonic": "state.{state[t]}",
|
||||
statef_formats = {
|
||||
"opcode": "OP_STATE_{state[c]}",
|
||||
"mnemonic": "state.{state[c]}",
|
||||
"opname": "state",
|
||||
"format": "{state_fmt[t]}",
|
||||
"format": "{state_fmt[c]}",
|
||||
"widths": "1, 1, 1",
|
||||
"types": "ev_float, ev_func, {state_types[t]}",
|
||||
"types": "ev_float, ev_func, {state_types[c]}",
|
||||
"args": {
|
||||
"state": ["ft", "ftt"],
|
||||
"state_fmt": ["%Ga, %Gb", "%Ga, %Gb, %Gc"],
|
||||
"state_types": ["ev_invalid", "ev_float"],
|
||||
},
|
||||
}
|
||||
stated_formats = {
|
||||
"opcode": "OP_STATE_{state[c]}",
|
||||
"mnemonic": "state.{state[c]}",
|
||||
"opname": "state",
|
||||
"format": "{state_fmt[c]}",
|
||||
"widths": "1, 1, 1",
|
||||
"types": "ev_float, ev_func, {state_types[c]}",
|
||||
"args": {
|
||||
"state": ["dt", "dtt"],
|
||||
"state_fmt": ["%Ga, %Gb", "%Ga, %Gb, %Gc"],
|
||||
"state_types": ["ev_invalid", "ev_double"],
|
||||
},
|
||||
}
|
||||
store_formats = {
|
||||
"opcode": "OP_STORE_{op_mode[mm]}_{ss+1}",
|
||||
"mnemonic": "store",
|
||||
|
@ -476,7 +491,8 @@ group_map = {
|
|||
"popregs": popregs_formats,
|
||||
"scale": scale_formats,
|
||||
"shiftops": shiftops_formats,
|
||||
"state": state_formats,
|
||||
"statef": statef_formats,
|
||||
"stated": stated_formats,
|
||||
"store": store_formats,
|
||||
"string": string_formats,
|
||||
"swizzle": swizzle_formats,
|
||||
|
|
|
@ -79,9 +79,9 @@ ED_Alloc (progs_t *pr)
|
|||
e = EDICT_NUM (pr, i);
|
||||
// the first couple seconds of server time can involve a lot of
|
||||
// freeing and allocating, so relax the replacement policy
|
||||
if (e->free && (!pr->globals.time
|
||||
if (e->free && (!pr->globals.ftime//FIXME double time
|
||||
|| e->freetime < 2
|
||||
|| *pr->globals.time - e->freetime > 0.5)) {
|
||||
|| *pr->globals.ftime - e->freetime > 0.5)) {
|
||||
ED_ClearEdict (pr, e, 0);
|
||||
return e;
|
||||
}
|
||||
|
@ -123,8 +123,8 @@ ED_Free (progs_t *pr, edict_t *ed)
|
|||
ED_ClearEdict (pr, ed, 0);
|
||||
}
|
||||
ed->free = true;
|
||||
if (pr->globals.time)
|
||||
ed->freetime = *pr->globals.time;
|
||||
if (pr->globals.ftime)//FIXME double time
|
||||
ed->freetime = *pr->globals.ftime;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -199,7 +199,7 @@ ED_Count (progs_t *pr)
|
|||
for (i = 0; i < *pr->num_edicts; i++) {
|
||||
ent = EDICT_NUM (pr, i);
|
||||
if (ent->free) {
|
||||
if (pr->globals.time && *pr->globals.time - ent->freetime <= 0.5)
|
||||
if (pr->globals.ftime && *pr->globals.ftime - ent->freetime <= 0.5)//FIXME double time
|
||||
zombie++;
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -1482,7 +1482,7 @@ op_call:
|
|||
int nextthink = pr->fields.nextthink + self;
|
||||
int frame = pr->fields.frame + self;
|
||||
int think = pr->fields.think + self;
|
||||
float time = *pr->globals.time + 0.1;
|
||||
float time = *pr->globals.ftime + 0.1;
|
||||
pr->pr_edict_area[nextthink].float_var = time;
|
||||
pr->pr_edict_area[frame].float_var = OPA(float);
|
||||
pr->pr_edict_area[think].func_var = OPB(uint);
|
||||
|
@ -1494,7 +1494,7 @@ op_call:
|
|||
int nextthink = pr->fields.nextthink + self;
|
||||
int frame = pr->fields.frame + self;
|
||||
int think = pr->fields.think + self;
|
||||
float time = *pr->globals.time + OPC(float);
|
||||
float time = *pr->globals.ftime + OPC(float);
|
||||
pr->pr_edict_area[nextthink].float_var = time;
|
||||
pr->pr_edict_area[frame].float_var = OPA(float);
|
||||
pr->pr_edict_area[think].func_var = OPB(uint);
|
||||
|
@ -2891,9 +2891,13 @@ pr_exec_ruamoko (progs_t *pr, int exitdepth)
|
|||
MM(ivec4) = STK(ivec4);
|
||||
break;
|
||||
// 0 0100
|
||||
// spare
|
||||
// 0 0101
|
||||
// spare
|
||||
// 0 0110
|
||||
// spare
|
||||
// 0 0111
|
||||
// spare
|
||||
|
||||
#define OP_cmp_1(OP, T, rt, cmp, ct) \
|
||||
case OP_##OP##_##T##_1: \
|
||||
|
@ -2936,7 +2940,6 @@ pr_exec_ruamoko (progs_t *pr, int exitdepth)
|
|||
OP_cmp(GE, >=);
|
||||
// 0 1110
|
||||
OP_cmp(LE, <=);
|
||||
|
||||
// 0 1111
|
||||
// spare
|
||||
|
||||
|
@ -3276,12 +3279,16 @@ pr_exec_ruamoko (progs_t *pr, int exitdepth)
|
|||
memmove (pr->pr_globals + OPC(int), pr->pr_globals + OPA(int),
|
||||
st->b * sizeof (pr_type_t));
|
||||
break;
|
||||
case OP_CONV:
|
||||
switch (st->b) {
|
||||
#include "libs/gamecode/pr_convert.cinc"
|
||||
default:
|
||||
PR_RunError (pr, "invalid conversion code: %04o",
|
||||
st->b);
|
||||
case OP_STATE_ft:
|
||||
{
|
||||
int self = *pr->globals.self;
|
||||
int nextthink = pr->fields.nextthink + self;
|
||||
int frame = pr->fields.frame + self;
|
||||
int think = pr->fields.think + self;
|
||||
float time = *pr->globals.ftime + 0.1;
|
||||
pr->pr_edict_area[nextthink].float_var = time;
|
||||
pr->pr_edict_area[frame].float_var = OPA(float);
|
||||
pr->pr_edict_area[think].func_var = op_b->func_var;
|
||||
}
|
||||
break;
|
||||
OP_cmp_T (GE, U, long, lvec2, lvec4, >=, ulong, ulvec2, ulvec4);
|
||||
|
@ -3294,8 +3301,17 @@ pr_exec_ruamoko (progs_t *pr, int exitdepth)
|
|||
case OP_MEMSET_PI:
|
||||
pr_memset (pr->pr_globals + OPC(int), OPA(int), st->b);
|
||||
break;
|
||||
case OP_WITH:
|
||||
pr_with (pr, st);
|
||||
case OP_STATE_ftt:
|
||||
{
|
||||
int self = *pr->globals.self;
|
||||
int nextthink = pr->fields.nextthink + self;
|
||||
int frame = pr->fields.frame + self;
|
||||
int think = pr->fields.think + self;
|
||||
float time = *pr->globals.ftime + OPC(float);
|
||||
pr->pr_edict_area[nextthink].float_var = time;
|
||||
pr->pr_edict_area[frame].float_var = OPA(float);
|
||||
pr->pr_edict_area[think].func_var = op_b->func_var;
|
||||
}
|
||||
break;
|
||||
// 1 1110
|
||||
OP_cmp_T (LE, u, int, ivec2, ivec4, <=, uint, uivec2, uivec4);
|
||||
|
@ -3317,15 +3333,15 @@ pr_exec_ruamoko (progs_t *pr, int exitdepth)
|
|||
st = pr->pr_statements + pr->pr_xstatement;
|
||||
}
|
||||
break;
|
||||
case OP_STATE_ft:
|
||||
case OP_STATE_dt:
|
||||
{
|
||||
int self = *pr->globals.self;
|
||||
int nextthink = pr->fields.nextthink + self;
|
||||
int frame = pr->fields.frame + self;
|
||||
int think = pr->fields.think + self;
|
||||
float time = *pr->globals.time + 0.1;
|
||||
pr->pr_edict_area[nextthink].float_var = time;
|
||||
pr->pr_edict_area[frame].float_var = OPA(float);
|
||||
double time = *pr->globals.dtime + 0.1;
|
||||
*(double *) (&pr->pr_edict_area[nextthink]) = time;
|
||||
pr->pr_edict_area[frame].integer_var = OPA(int);
|
||||
pr->pr_edict_area[think].func_var = op_b->func_var;
|
||||
}
|
||||
break;
|
||||
|
@ -3348,15 +3364,15 @@ pr_exec_ruamoko (progs_t *pr, int exitdepth)
|
|||
st = pr->pr_statements + pr->pr_xstatement;
|
||||
}
|
||||
break;
|
||||
case OP_STATE_ftt:
|
||||
case OP_STATE_dtt:
|
||||
{
|
||||
int self = *pr->globals.self;
|
||||
int nextthink = pr->fields.nextthink + self;
|
||||
int frame = pr->fields.frame + self;
|
||||
int think = pr->fields.think + self;
|
||||
float time = *pr->globals.time + OPC(float);
|
||||
pr->pr_edict_area[nextthink].float_var = time;
|
||||
pr->pr_edict_area[frame].float_var = OPA(float);
|
||||
double time = *pr->globals.dtime + OPC(double);
|
||||
*(double *) (&pr->pr_edict_area[nextthink]) = time;
|
||||
pr->pr_edict_area[frame].integer_var = OPA(int);
|
||||
pr->pr_edict_area[think].func_var = op_b->func_var;
|
||||
}
|
||||
break;
|
||||
|
@ -3384,8 +3400,17 @@ pr_exec_ruamoko (progs_t *pr, int exitdepth)
|
|||
OPC(dvec4) = vqmuld (OPA(dvec4), OPB(dvec4));
|
||||
break;
|
||||
// 10nn spare
|
||||
// 1100 spare
|
||||
// 1101 spare
|
||||
case OP_CONV:
|
||||
switch (st->b) {
|
||||
#include "libs/gamecode/pr_convert.cinc"
|
||||
default:
|
||||
PR_RunError (pr, "invalid conversion code: %04o",
|
||||
st->b);
|
||||
}
|
||||
break;
|
||||
case OP_WITH:
|
||||
pr_with (pr, st);
|
||||
break;
|
||||
// 1110 spare
|
||||
#define OP_hop2(vec, op) ((vec)[0] op (vec)[1])
|
||||
#define OP_hop3(vec, op) ((vec)[0] op (vec)[1] op (vec)[2])
|
||||
|
|
|
@ -143,9 +143,9 @@ PR_ResolveGlobals (progs_t *pr)
|
|||
pr->pr_param_alignment = G_INT (pr, def->ofs);
|
||||
}
|
||||
memcpy (pr->pr_real_params, pr->pr_params, sizeof (pr->pr_params));
|
||||
if (!pr->globals.time) {
|
||||
if (!pr->globals.ftime) {//FIXME double time
|
||||
if ((def = PR_FindGlobal (pr, "time")))
|
||||
pr->globals.time = &G_FLOAT (pr, def->ofs);
|
||||
pr->globals.ftime = &G_FLOAT (pr, def->ofs);
|
||||
}
|
||||
if (!pr->globals.self) {
|
||||
if ((def = PR_FindGlobal (pr, ".self"))
|
||||
|
|
|
@ -1637,7 +1637,7 @@ PR_Check_Opcodes (progs_t *pr)
|
|||
int pushpop_ok = 0;
|
||||
pr_uint_t i;
|
||||
|
||||
if (pr->globals.time && pr->globals.self && pr->fields.nextthink != -1
|
||||
if (pr->globals.ftime && pr->globals.self && pr->fields.nextthink != -1
|
||||
&& pr->fields.think != -1 && pr->fields.frame != -1) {
|
||||
state_ok = 1;
|
||||
}
|
||||
|
|
|
@ -460,7 +460,7 @@ resolve (progs_t *pr)
|
|||
resolve_fields (pr, nq_opt_fields, 0);
|
||||
// progs engine needs these globals anyway
|
||||
sv_pr_state.globals.self = sv_globals.self;
|
||||
sv_pr_state.globals.time = sv_globals.time;
|
||||
sv_pr_state.globals.ftime = sv_globals.time;//FIXME double time
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -493,7 +493,7 @@ resolve (progs_t *pr)
|
|||
resolve_fields (pr, qw_opt_fields, 0);
|
||||
// progs engine needs these globals anyway
|
||||
sv_pr_state.globals.self = sv_globals.self;
|
||||
sv_pr_state.globals.time = sv_globals.time;
|
||||
sv_pr_state.globals.ftime = sv_globals.time;//FIXME double time
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue