engine side quaternion support

This commit is contained in:
Bill Currie 2004-04-08 00:56:30 +00:00
parent 39685d0c63
commit 8d6f634f30
3 changed files with 167 additions and 6 deletions

View file

@ -36,7 +36,7 @@ typedef enum {
ev_field, ev_field,
ev_func, ev_func,
ev_pointer, // end of v6 types ev_pointer, // end of v6 types
ev_quaternion, ev_quat,
ev_integer, ev_integer,
ev_uinteger, ev_uinteger,
ev_short, // value is embedded in the opcode ev_short, // value is embedded in the opcode
@ -288,6 +288,23 @@ typedef enum {
OP_CONV_UI, OP_CONV_UI,
OP_STATE_F, OP_STATE_F,
OP_ADD_Q,
OP_SUB_Q,
OP_MUL_Q,
OP_MUL_QF,
OP_MUL_FQ,
OP_NOT_Q,
OP_EQ_Q,
OP_NE_Q,
OP_STORE_Q,
OP_STOREB_Q,
OP_STOREBI_Q,
OP_STOREP_Q,
OP_LOAD_Q,
OP_LOADB_Q,
OP_LOADBI_Q,
OP_ADDRESS_Q,
} pr_opcode_e; } pr_opcode_e;
typedef struct opcode_s { typedef struct opcode_s {
@ -340,6 +357,7 @@ typedef union pr_type_u {
func_t func_var; func_t func_var;
int entity_var; int entity_var;
float vector_var[1]; // really 3, but this structure must be 32 bits float vector_var[1]; // really 3, but this structure must be 32 bits
float quat_var[1]; // really 4, but this structure must be 32 bits
int integer_var; int integer_var;
pointer_t pointer_var; pointer_t pointer_var;
unsigned int uinteger_var; unsigned int uinteger_var;

View file

@ -302,6 +302,9 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
case OP_ADD_V: case OP_ADD_V:
VectorAdd (OPA.vector_var, OPB.vector_var, OPC.vector_var); VectorAdd (OPA.vector_var, OPB.vector_var, OPC.vector_var);
break; break;
case OP_ADD_Q:
QuatAdd (OPA.quat_var, OPB.quat_var, OPC.quat_var);
break;
case OP_ADD_S: case OP_ADD_S:
{ {
const char *a = PR_GetString (pr, OPA.string_var); const char *a = PR_GetString (pr, OPA.string_var);
@ -320,6 +323,9 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
case OP_SUB_V: case OP_SUB_V:
VectorSubtract (OPA.vector_var, OPB.vector_var, OPC.vector_var); VectorSubtract (OPA.vector_var, OPB.vector_var, OPC.vector_var);
break; break;
case OP_SUB_Q:
QuatSubtract (OPA.quat_var, OPB.quat_var, OPC.quat_var);
break;
case OP_MUL_F: case OP_MUL_F:
OPC.float_var = OPA.float_var * OPB.float_var; OPC.float_var = OPA.float_var * OPB.float_var;
break; break;
@ -332,6 +338,15 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
case OP_MUL_VF: case OP_MUL_VF:
VectorScale (OPA.vector_var, OPB.float_var, OPC.vector_var); VectorScale (OPA.vector_var, OPB.float_var, OPC.vector_var);
break; break;
case OP_MUL_Q:
QuatMult (OPA.quat_var, OPB.quat_var, OPC.quat_var);
break;
case OP_MUL_FQ:
QuatScale (OPB.quat_var, OPA.float_var, OPC.quat_var);
break;
case OP_MUL_QF:
QuatScale (OPA.quat_var, OPB.float_var, OPC.quat_var);
break;
case OP_DIV_F: case OP_DIV_F:
OPC.float_var = OPA.float_var / OPB.float_var; OPC.float_var = OPA.float_var / OPB.float_var;
break; break;
@ -387,6 +402,9 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
case OP_NOT_V: case OP_NOT_V:
OPC.integer_var = VectorIsZero (OPA.vector_var); OPC.integer_var = VectorIsZero (OPA.vector_var);
break; break;
case OP_NOT_Q:
OPC.integer_var = QuatIsZero (OPA.quat_var);
break;
case OP_NOT_S: case OP_NOT_S:
OPC.integer_var = !OPA.string_var || OPC.integer_var = !OPA.string_var ||
!*PR_GetString (pr, OPA.string_var); !*PR_GetString (pr, OPA.string_var);
@ -404,6 +422,9 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
OPC.integer_var = VectorCompare (OPA.vector_var, OPC.integer_var = VectorCompare (OPA.vector_var,
OPB.vector_var); OPB.vector_var);
break; break;
case OP_EQ_Q:
OPC.integer_var = QuatCompare (OPA.quat_var, OPB.quat_var);
break;
case OP_EQ_E: case OP_EQ_E:
OPC.integer_var = OPA.integer_var == OPB.integer_var; OPC.integer_var = OPA.integer_var == OPB.integer_var;
break; break;
@ -417,6 +438,9 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
OPC.integer_var = !VectorCompare (OPA.vector_var, OPC.integer_var = !VectorCompare (OPA.vector_var,
OPB.vector_var); OPB.vector_var);
break; break;
case OP_NE_Q:
OPC.integer_var = !QuatCompare (OPA.quat_var, OPB.quat_var);
break;
case OP_LE_S: case OP_LE_S:
case OP_GE_S: case OP_GE_S:
case OP_LT_S: case OP_LT_S:
@ -459,6 +483,9 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
case OP_STORE_V: case OP_STORE_V:
VectorCopy (OPA.vector_var, OPB.vector_var); VectorCopy (OPA.vector_var, OPB.vector_var);
break; break;
case OP_STORE_Q:
QuatCopy (OPA.quat_var, OPB.quat_var);
break;
case OP_STOREP_F: case OP_STOREP_F:
case OP_STOREP_ENT: case OP_STOREP_ENT:
@ -477,6 +504,11 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
ptr = pr->pr_globals + OPB.integer_var; ptr = pr->pr_globals + OPB.integer_var;
VectorCopy (OPA.vector_var, ptr->vector_var); VectorCopy (OPA.vector_var, ptr->vector_var);
break; break;
case OP_STOREP_Q:
//FIXME put bounds checking back
ptr = pr->pr_globals + OPB.integer_var;
QuatCopy (OPA.quat_var, ptr->quat_var);
break;
case OP_ADDRESS: case OP_ADDRESS:
if (pr_boundscheck->int_val) { if (pr_boundscheck->int_val) {
@ -495,6 +527,7 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
break; break;
case OP_ADDRESS_F: case OP_ADDRESS_F:
case OP_ADDRESS_V: case OP_ADDRESS_V:
case OP_ADDRESS_Q:
case OP_ADDRESS_S: case OP_ADDRESS_S:
case OP_ADDRESS_ENT: case OP_ADDRESS_ENT:
case OP_ADDRESS_FLD: case OP_ADDRESS_FLD:
@ -529,11 +562,24 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
if (pr_boundscheck->int_val) { if (pr_boundscheck->int_val) {
if (OPA.entity_var < 0 if (OPA.entity_var < 0
|| OPA.entity_var >= pr->pr_edictareasize) || OPA.entity_var >= pr->pr_edictareasize)
PR_RunError (pr, "Progs attempted to read an out of " PR_RunError (pr, "Progs attempted to read an out of "
"bounds edict number"); "bounds edict number");
if (OPB.uinteger_var + 2 >= pr->progs->entityfields) if (OPB.uinteger_var + 2 >= pr->progs->entityfields)
PR_RunError (pr, "Progs attempted to read an invalid " PR_RunError (pr, "Progs attempted to read an invalid "
"field in an edict"); "field in an edict");
}
ed = PROG_TO_EDICT (pr, OPA.entity_var);
memcpy (&OPC, &ed->v[OPB.integer_var], 3 * sizeof (OPC));
break;
case OP_LOAD_Q:
if (pr_boundscheck->int_val) {
if (OPA.entity_var < 0
|| OPA.entity_var >= pr->pr_edictareasize)
PR_RunError (pr, "Progs attempted to read an out of "
"bounds edict number");
if (OPB.uinteger_var + 3 >= pr->progs->entityfields)
PR_RunError (pr, "Progs attempted to read an invalid "
"field in an edict");
} }
ed = PROG_TO_EDICT (pr, OPA.entity_var); ed = PROG_TO_EDICT (pr, OPA.entity_var);
memcpy (&OPC, &ed->v[OPB.integer_var], 3 * sizeof (OPC)); memcpy (&OPC, &ed->v[OPB.integer_var], 3 * sizeof (OPC));
@ -558,6 +604,12 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
ptr = pr->pr_globals + pointer; ptr = pr->pr_globals + pointer;
VectorCopy (ptr->vector_var, OPC.vector_var); VectorCopy (ptr->vector_var, OPC.vector_var);
break; break;
case OP_LOADB_Q:
//FIXME put bounds checking in
pointer = OPA.integer_var + OPB.integer_var;
ptr = pr->pr_globals + pointer;
QuatCopy (ptr->quat_var, OPC.quat_var);
break;
case OP_LOADBI_F: case OP_LOADBI_F:
case OP_LOADBI_S: case OP_LOADBI_S:
@ -578,6 +630,12 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
ptr = pr->pr_globals + pointer; ptr = pr->pr_globals + pointer;
VectorCopy (ptr->vector_var, OPC.vector_var); VectorCopy (ptr->vector_var, OPC.vector_var);
break; break;
case OP_LOADBI_Q:
//FIXME put bounds checking in
pointer = OPA.integer_var + (short) st->b;
ptr = pr->pr_globals + pointer;
QuatCopy (ptr->quat_var, OPC.quat_var);
break;
case OP_LEA: case OP_LEA:
pointer = OPA.integer_var + OPB.integer_var; pointer = OPA.integer_var + OPB.integer_var;
@ -608,6 +666,12 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
ptr = pr->pr_globals + pointer; ptr = pr->pr_globals + pointer;
VectorCopy (OPA.vector_var, ptr->vector_var); VectorCopy (OPA.vector_var, ptr->vector_var);
break; break;
case OP_STOREB_Q:
//FIXME put bounds checking in
pointer = OPB.integer_var + OPC.integer_var;
ptr = pr->pr_globals + pointer;
QuatCopy (OPA.quat_var, ptr->quat_var);
break;
case OP_STOREBI_F: case OP_STOREBI_F:
case OP_STOREBI_S: case OP_STOREBI_S:
@ -628,6 +692,12 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
ptr = pr->pr_globals + pointer; ptr = pr->pr_globals + pointer;
VectorCopy (OPA.vector_var, ptr->vector_var); VectorCopy (OPA.vector_var, ptr->vector_var);
break; break;
case OP_STOREBI_Q:
//FIXME put bounds checking in
pointer = OPB.integer_var + (short) st->c;
ptr = pr->pr_globals + pointer;
QuatCopy (OPA.quat_var, ptr->quat_var);
break;
// ================== // ==================
case OP_IFNOT: case OP_IFNOT:

View file

@ -57,7 +57,7 @@ int pr_type_size[ev_type_count] = {
1, // ev_field 1, // ev_field
1, // ev_func 1, // ev_func
1, // ev_pointer 1, // ev_pointer
4, // ev_quaternion 4, // ev_quat
1, // ev_integer 1, // ev_integer
1, // ev_uinteger 1, // ev_uinteger
0, // ev_short value in opcode 0, // ev_short value in opcode
@ -121,6 +121,18 @@ opcode_t pr_opcodes[] = {
ev_vector, ev_float, ev_vector, ev_vector, ev_float, ev_vector,
PROG_ID_VERSION, PROG_ID_VERSION,
}, },
{"*", "mul.q", OP_MUL_Q, false,
ev_quat, ev_quat, ev_quat,
PROG_ID_VERSION,
},
{"*", "mul.fq", OP_MUL_FQ, false,
ev_float, ev_quat, ev_quat,
PROG_ID_VERSION,
},
{"*", "mul.qf", OP_MUL_QF, false,
ev_quat, ev_float, ev_quat,
PROG_ID_VERSION,
},
{"/", "div.f", OP_DIV_F, false, {"/", "div.f", OP_DIV_F, false,
ev_float, ev_float, ev_float, ev_float, ev_float, ev_float,
@ -135,6 +147,10 @@ opcode_t pr_opcodes[] = {
ev_vector, ev_vector, ev_vector, ev_vector, ev_vector, ev_vector,
PROG_ID_VERSION, PROG_ID_VERSION,
}, },
{"+", "add.q", OP_ADD_Q, false,
ev_quat, ev_quat, ev_quat,
PROG_ID_VERSION,
},
{"+", "add.s", OP_ADD_S, false, {"+", "add.s", OP_ADD_S, false,
ev_string, ev_string, ev_string, ev_string, ev_string, ev_string,
PROG_VERSION, PROG_VERSION,
@ -148,6 +164,10 @@ opcode_t pr_opcodes[] = {
ev_vector, ev_vector, ev_vector, ev_vector, ev_vector, ev_vector,
PROG_ID_VERSION, PROG_ID_VERSION,
}, },
{"-", "sub.q", OP_SUB_Q, false,
ev_quat, ev_quat, ev_quat,
PROG_ID_VERSION,
},
{"==", "eq.f", OP_EQ_F, false, {"==", "eq.f", OP_EQ_F, false,
ev_float, ev_float, ev_integer, ev_float, ev_float, ev_integer,
@ -157,6 +177,10 @@ opcode_t pr_opcodes[] = {
ev_vector, ev_vector, ev_integer, ev_vector, ev_vector, ev_integer,
PROG_ID_VERSION, PROG_ID_VERSION,
}, },
{"==", "eq.q", OP_EQ_Q, false,
ev_quat, ev_quat, ev_integer,
PROG_ID_VERSION,
},
{"==", "eq.s", OP_EQ_S, false, {"==", "eq.s", OP_EQ_S, false,
ev_string, ev_string, ev_integer, ev_string, ev_string, ev_integer,
PROG_ID_VERSION, PROG_ID_VERSION,
@ -178,6 +202,10 @@ opcode_t pr_opcodes[] = {
ev_vector, ev_vector, ev_integer, ev_vector, ev_vector, ev_integer,
PROG_ID_VERSION, PROG_ID_VERSION,
}, },
{"!=", "ne.q", OP_NE_Q, false,
ev_quat, ev_quat, ev_integer,
PROG_ID_VERSION,
},
{"!=", "ne.s", OP_NE_S, false, {"!=", "ne.s", OP_NE_S, false,
ev_string, ev_string, ev_integer, ev_string, ev_string, ev_integer,
PROG_ID_VERSION, PROG_ID_VERSION,
@ -234,6 +262,11 @@ opcode_t pr_opcodes[] = {
PROG_ID_VERSION, PROG_ID_VERSION,
"%Ga.%Gb, %gc", "%Ga.%Gb, %gc",
}, },
{".", "load.q", OP_LOAD_Q, false,
ev_entity, ev_field, ev_quat,
PROG_ID_VERSION,
"%Ga.%Gb, %gc",
},
{".", "load.s", OP_LOAD_S, false, {".", "load.s", OP_LOAD_S, false,
ev_entity, ev_field, ev_string, ev_entity, ev_field, ev_string,
PROG_ID_VERSION, PROG_ID_VERSION,
@ -280,6 +313,11 @@ opcode_t pr_opcodes[] = {
PROG_VERSION, PROG_VERSION,
"*(%Ga + %Gb), %gc", "*(%Ga + %Gb), %gc",
}, },
{".", "loadb.q", OP_LOADB_Q, false,
ev_pointer, ev_integer, ev_quat,
PROG_VERSION,
"*(%Ga + %Gb), %gc",
},
{".", "loadb.s", OP_LOADB_S, false, {".", "loadb.s", OP_LOADB_S, false,
ev_pointer, ev_integer, ev_string, ev_pointer, ev_integer, ev_string,
PROG_VERSION, PROG_VERSION,
@ -326,6 +364,11 @@ opcode_t pr_opcodes[] = {
PROG_VERSION, PROG_VERSION,
"*(%Ga + %sb), %gc", "*(%Ga + %sb), %gc",
}, },
{".", "loadbi.q", OP_LOADBI_Q, false,
ev_pointer, ev_short, ev_quat,
PROG_VERSION,
"*(%Ga + %sb), %gc",
},
{".", "loadbi.s", OP_LOADBI_S, false, {".", "loadbi.s", OP_LOADBI_S, false,
ev_pointer, ev_short, ev_string, ev_pointer, ev_short, ev_string,
PROG_VERSION, PROG_VERSION,
@ -377,6 +420,11 @@ opcode_t pr_opcodes[] = {
PROG_VERSION, PROG_VERSION,
"%Ga, %gc", "%Ga, %gc",
}, },
{"&", "address.q", OP_ADDRESS_Q, false,
ev_quat, ev_void, ev_pointer,
PROG_VERSION,
"%Ga, %gc",
},
{"&", "address.s", OP_ADDRESS_S, false, {"&", "address.s", OP_ADDRESS_S, false,
ev_string, ev_void, ev_pointer, ev_string, ev_void, ev_pointer,
PROG_VERSION, PROG_VERSION,
@ -456,6 +504,11 @@ opcode_t pr_opcodes[] = {
PROG_ID_VERSION, PROG_ID_VERSION,
"%Ga, %gb", "%Ga, %gb",
}, },
{"=", "store.q", OP_STORE_Q, true,
ev_quat, ev_quat, ev_void,
PROG_ID_VERSION,
"%Ga, %gb",
},
{"=", "store.s", OP_STORE_S, true, {"=", "store.s", OP_STORE_S, true,
ev_string, ev_string, ev_void, ev_string, ev_string, ev_void,
PROG_ID_VERSION, PROG_ID_VERSION,
@ -502,6 +555,11 @@ opcode_t pr_opcodes[] = {
PROG_ID_VERSION, PROG_ID_VERSION,
"%Ga, *%Gb", "%Ga, *%Gb",
}, },
{".=", "storep.q", OP_STOREP_Q, true,
ev_quat, ev_pointer, ev_void,
PROG_ID_VERSION,
"%Ga, *%Gb",
},
{".=", "storep.s", OP_STOREP_S, true, {".=", "storep.s", OP_STOREP_S, true,
ev_string, ev_pointer, ev_void, ev_string, ev_pointer, ev_void,
PROG_ID_VERSION, PROG_ID_VERSION,
@ -548,6 +606,11 @@ opcode_t pr_opcodes[] = {
PROG_VERSION, PROG_VERSION,
"%Ga, *(%Gb + %Gc)", "%Ga, *(%Gb + %Gc)",
}, },
{".=", "storeb.q", OP_STOREB_Q, true,
ev_quat, ev_pointer, ev_integer,
PROG_VERSION,
"%Ga, *(%Gb + %Gc)",
},
{".=", "storeb.s", OP_STOREB_S, true, {".=", "storeb.s", OP_STOREB_S, true,
ev_string, ev_pointer, ev_integer, ev_string, ev_pointer, ev_integer,
PROG_VERSION, PROG_VERSION,
@ -594,6 +657,11 @@ opcode_t pr_opcodes[] = {
PROG_VERSION, PROG_VERSION,
"%Ga, *(%Gb + %sc)", "%Ga, *(%Gb + %sc)",
}, },
{".=", "storebi.q", OP_STOREBI_Q, true,
ev_quat, ev_pointer, ev_short,
PROG_VERSION,
"%Ga, *(%Gb + %sc)",
},
{".=", "storebi.s", OP_STOREBI_S, true, {".=", "storebi.s", OP_STOREBI_S, true,
ev_string, ev_pointer, ev_short, ev_string, ev_pointer, ev_short,
PROG_VERSION, PROG_VERSION,
@ -646,6 +714,11 @@ opcode_t pr_opcodes[] = {
PROG_ID_VERSION, PROG_ID_VERSION,
"%Ga, %gc", "%Ga, %gc",
}, },
{"!", "not.q", OP_NOT_Q, false,
ev_quat, ev_void, ev_integer,
PROG_ID_VERSION,
"%Ga, %gc",
},
{"!", "not.s", OP_NOT_S, false, {"!", "not.s", OP_NOT_S, false,
ev_string, ev_void, ev_integer, ev_string, ev_void, ev_integer,
PROG_ID_VERSION, PROG_ID_VERSION,