mirror of
https://github.com/nzp-team/fteqw.git
synced 2025-01-19 06:51:11 +00:00
qcc: added somevec[0] to read somevec_x
qcc: fixed struct->ptrfield = ptrvalue qcc: fixed spam with unused struct members qcc: fixed str[0][0] and similar situations. bgqc: fixed sprintf builtin's vector prints. csqc: added flags field to beginpolygon. value&4 will draw the poly immediately (orthographic projection). git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@3988 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
ad32917970
commit
24e5adeb2b
8 changed files with 273 additions and 171 deletions
|
@ -920,13 +920,17 @@ static void QCBUILTIN PF_R_AddEntityMask(progfuncs_t *prinst, struct globalvars_
|
|||
}
|
||||
}
|
||||
|
||||
static shader_t *csqc_shadern;
|
||||
static int csqc_startpolyvert;
|
||||
static shader_t *csqc_poly_shader;
|
||||
static int csqc_poly_startvert;
|
||||
static int csqc_poly_startidx;
|
||||
static int csqc_poly_flags;
|
||||
// #306 void(string texturename) R_BeginPolygon (EXT_CSQC_???)
|
||||
static void QCBUILTIN PF_R_PolygonBegin(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
csqc_shadern = R_RegisterSkin(PR_GetStringOfs(prinst, OFS_PARM0), NULL);
|
||||
csqc_startpolyvert = cl_numstrisvert;
|
||||
csqc_poly_shader = R_RegisterSkin(PR_GetStringOfs(prinst, OFS_PARM0), NULL);
|
||||
csqc_poly_startvert = cl_numstrisvert;
|
||||
csqc_poly_startidx = cl_numstrisidx;
|
||||
csqc_poly_flags = (*prinst->callargc > 1)?G_FLOAT(OFS_PARM1):0;
|
||||
}
|
||||
|
||||
// #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex (EXT_CSQC_???)
|
||||
|
@ -953,8 +957,12 @@ static void QCBUILTIN PF_R_PolygonEnd(progfuncs_t *prinst, struct globalvars_s *
|
|||
scenetris_t *t;
|
||||
int i;
|
||||
int nv;
|
||||
|
||||
if (!csqc_poly_shader)
|
||||
return;
|
||||
|
||||
/*if the shader didn't change, continue with the old poly*/
|
||||
if (cl_numstris && cl_stris[cl_numstris-1].shader == csqc_shadern)
|
||||
if (cl_numstris && cl_stris[cl_numstris-1].shader == csqc_poly_shader)
|
||||
t = &cl_stris[cl_numstris-1];
|
||||
else
|
||||
{
|
||||
|
@ -964,14 +972,14 @@ static void QCBUILTIN PF_R_PolygonEnd(progfuncs_t *prinst, struct globalvars_s *
|
|||
cl_stris = BZ_Realloc(cl_stris, sizeof(*cl_stris)*cl_maxstris);
|
||||
}
|
||||
t = &cl_stris[cl_numstris++];
|
||||
t->shader = csqc_shadern;
|
||||
t->shader = csqc_poly_shader;
|
||||
t->firstidx = cl_numstrisidx;
|
||||
t->firstvert = csqc_startpolyvert;
|
||||
t->firstvert = csqc_poly_startvert;
|
||||
t->numvert = 0;
|
||||
t->numidx = 0;
|
||||
}
|
||||
|
||||
nv = cl_numstrisvert-csqc_startpolyvert;
|
||||
nv = cl_numstrisvert-csqc_poly_startvert;
|
||||
if (cl_numstrisidx+(nv-2)*3 > cl_maxstrisidx)
|
||||
{
|
||||
cl_maxstrisidx=cl_numstrisidx+(nv-2)*3 + 64;
|
||||
|
@ -985,11 +993,34 @@ static void QCBUILTIN PF_R_PolygonEnd(progfuncs_t *prinst, struct globalvars_s *
|
|||
cl_strisidx[cl_numstrisidx++] = t->numvert + i-1;
|
||||
cl_strisidx[cl_numstrisidx++] = t->numvert + i;
|
||||
}
|
||||
t->numidx = cl_numstrisidx - t->firstidx;
|
||||
t->numvert += cl_numstrisvert-csqc_startpolyvert;
|
||||
|
||||
/*set up ready for the next poly*/
|
||||
csqc_startpolyvert = cl_numstrisvert;
|
||||
if (csqc_poly_flags & 4)
|
||||
{
|
||||
mesh_t mesh;
|
||||
memset(&mesh, 0, sizeof(mesh));
|
||||
mesh.colors4f_array = cl_strisvertc + csqc_poly_startvert;
|
||||
|
||||
mesh.xyz_array = cl_strisvertv + csqc_poly_startvert;
|
||||
mesh.st_array = cl_strisvertt + csqc_poly_startvert;
|
||||
mesh.colors4f_array = cl_strisvertc + csqc_poly_startvert;
|
||||
mesh.indexes = cl_strisidx + csqc_poly_startidx;
|
||||
mesh.numindexes = cl_numstrisidx - csqc_poly_startidx;
|
||||
mesh.numvertexes = cl_numstrisvert-csqc_poly_startvert;
|
||||
/*undo the positions so we don't draw the same verts more than once*/
|
||||
cl_numstrisvert = csqc_poly_startvert;
|
||||
cl_numstrisidx = csqc_poly_startidx;
|
||||
|
||||
BE_DrawMesh_Single(csqc_poly_shader, &mesh, NULL, &csqc_poly_shader->defaulttextures, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
t->numidx = cl_numstrisidx - t->firstidx;
|
||||
t->numvert += cl_numstrisvert-csqc_poly_startvert;
|
||||
|
||||
/*set up ready for the next poly*/
|
||||
csqc_poly_startvert = cl_numstrisvert;
|
||||
csqc_poly_startidx = cl_numstrisidx;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -3098,7 +3098,6 @@ void QCBUILTIN PF_sprintf (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|||
int isfloat;
|
||||
static int dummyivec[3] = {0, 0, 0};
|
||||
static float dummyvec[3] = {0, 0, 0};
|
||||
char vabuf[1024];
|
||||
|
||||
#define PRINTF_ALTERNATE 1
|
||||
#define PRINTF_ZEROPAD 2
|
||||
|
@ -3335,13 +3334,13 @@ nolength:
|
|||
case 'v': case 'V':
|
||||
f[-2] += 'g' - 'v';
|
||||
if(precision < 0) // not set
|
||||
Q_snprintfz(o, end - o, va(vabuf, sizeof(vabuf), "%s %s %s", /* NESTED SPRINTF IS NESTED */ formatbuf, formatbuf, formatbuf),
|
||||
Q_snprintfz(o, end - o, va("%s %s %s", /* NESTED SPRINTF IS NESTED */ formatbuf, formatbuf, formatbuf),
|
||||
width, (isfloat ? (double) GETARG_VECTOR(thisarg)[0] : (double) GETARG_INTVECTOR(thisarg)[0]),
|
||||
width, (isfloat ? (double) GETARG_VECTOR(thisarg)[1] : (double) GETARG_INTVECTOR(thisarg)[1]),
|
||||
width, (isfloat ? (double) GETARG_VECTOR(thisarg)[2] : (double) GETARG_INTVECTOR(thisarg)[2])
|
||||
);
|
||||
else
|
||||
Q_snprintfz(o, end - o, va(vabuf, sizeof(vabuf), "%s %s %s", /* NESTED SPRINTF IS NESTED */ formatbuf, formatbuf, formatbuf),
|
||||
Q_snprintfz(o, end - o, va("%s %s %s", /* NESTED SPRINTF IS NESTED */ formatbuf, formatbuf, formatbuf),
|
||||
width, precision, (isfloat ? (double) GETARG_VECTOR(thisarg)[0] : (double) GETARG_INTVECTOR(thisarg)[0]),
|
||||
width, precision, (isfloat ? (double) GETARG_VECTOR(thisarg)[1] : (double) GETARG_INTVECTOR(thisarg)[1]),
|
||||
width, precision, (isfloat ? (double) GETARG_VECTOR(thisarg)[2] : (double) GETARG_INTVECTOR(thisarg)[2])
|
||||
|
|
|
@ -1873,6 +1873,9 @@ void BE_GenPolyBatches(batch_t **batches)
|
|||
|
||||
for (i = 0; i < cl_numstris; i++)
|
||||
{
|
||||
if (!cl_stris[i].numidx)
|
||||
continue;
|
||||
|
||||
b = BE_GetTempBatch();
|
||||
if (!b)
|
||||
return;
|
||||
|
|
|
@ -304,7 +304,7 @@ enum qcop_e {
|
|||
OP_BOUNDCHECK,
|
||||
|
||||
//back to ones that we do use.
|
||||
OP_STOREP_P,
|
||||
OP_UNUSED, //used to be OP_STOREP_P, which is now emulated with OP_STOREP_I, fteqcc nor fte generated it
|
||||
OP_PUSH, //push 4octets onto the local-stack (which is ALWAYS poped on function return). Returns a pointer.
|
||||
OP_POP, //pop those ones that were pushed (don't over do it). Needs assembler.
|
||||
|
||||
|
@ -354,6 +354,7 @@ enum qcop_e {
|
|||
OP_MULSTOREP_VI,
|
||||
|
||||
OP_LOADA_STRUCT,
|
||||
OP_STOREP_P,
|
||||
|
||||
OP_NUMOPS
|
||||
};
|
||||
|
|
|
@ -343,10 +343,11 @@ typedef struct QCC_def_s
|
|||
int s_line;
|
||||
|
||||
int arraysize;
|
||||
pbool shared;
|
||||
pbool saved;
|
||||
pbool isstatic;
|
||||
pbool subscoped_away;
|
||||
pbool shared:1;
|
||||
pbool saved:1;
|
||||
pbool isstatic:1;
|
||||
pbool subscoped_away:1;
|
||||
pbool followptr:1;
|
||||
|
||||
temp_t *temp;
|
||||
} QCC_def_t;
|
||||
|
|
|
@ -494,7 +494,7 @@ QCC_opcode_t pr_opcodes[] =
|
|||
|
||||
{7, "<>", "BOUNDCHECK", -1, ASSOC_LEFT, &type_integer, NULL, NULL},
|
||||
|
||||
{7, "=", "STOREP_P", 6, ASSOC_RIGHT, &type_pointer, &type_pointer, &type_void},
|
||||
{7, "<UNUSED>", "UNUSED", 6, ASSOC_RIGHT, &type_void, &type_void, &type_void},
|
||||
{7, "<PUSH>", "PUSH", -1, ASSOC_RIGHT, &type_float, &type_void, &type_pointer},
|
||||
{7, "<POP>", "POP", -1, ASSOC_RIGHT, &type_float, &type_void, &type_void},
|
||||
|
||||
|
@ -545,6 +545,8 @@ QCC_opcode_t pr_opcodes[] =
|
|||
|
||||
{7, "=", "LOADA_STRUCT", 6, ASSOC_LEFT, &type_float, &type_integer, &type_float},
|
||||
|
||||
{7, "=", "STOREP_P", 6, ASSOC_RIGHT, &type_pointer, &type_pointer, &type_pointer},
|
||||
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
|
@ -744,6 +746,8 @@ QCC_opcode_t *opcodeprioritized[TOP_PRIORITY+1][128] =
|
|||
|
||||
NULL
|
||||
}, { //6
|
||||
&pr_opcodes[OP_STOREP_P],
|
||||
|
||||
&pr_opcodes[OP_STORE_F],
|
||||
&pr_opcodes[OP_STORE_V],
|
||||
&pr_opcodes[OP_STORE_S],
|
||||
|
@ -764,7 +768,6 @@ QCC_opcode_t *opcodeprioritized[TOP_PRIORITY+1][128] =
|
|||
&pr_opcodes[OP_STOREP_I],
|
||||
&pr_opcodes[OP_STOREP_IF],
|
||||
&pr_opcodes[OP_STOREP_FI],
|
||||
&pr_opcodes[OP_STOREP_P],
|
||||
|
||||
&pr_opcodes[OP_DIVSTORE_F],
|
||||
&pr_opcodes[OP_DIVSTORE_I],
|
||||
|
@ -925,7 +928,6 @@ pbool QCC_OPCodeValid(QCC_opcode_t *op)
|
|||
|
||||
//stores into a pointer (generated from 'ent.field=XXX')
|
||||
case OP_STOREP_I: //no worse than the other OP_STOREP_X functions
|
||||
case OP_STOREP_P:
|
||||
//reads from an entity field
|
||||
case OP_LOAD_I: //no worse than the other OP_LOAD_X functions.
|
||||
case OP_LOAD_P:
|
||||
|
@ -2300,6 +2302,10 @@ QCC_def_t *QCC_PR_Statement (QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var_
|
|||
var_c = var_a;
|
||||
break;
|
||||
|
||||
case OP_STOREP_P:
|
||||
op = &pr_opcodes[OP_STOREP_I];
|
||||
break;
|
||||
|
||||
case OP_BITCLR:
|
||||
//b = var, a = bit field.
|
||||
|
||||
|
@ -2996,7 +3002,7 @@ QCC_def_t *QCC_PR_GenerateFunctionCall (QCC_def_t *func, QCC_def_t *arglist[], i
|
|||
continue;
|
||||
}
|
||||
|
||||
if (arglist[i]->type->size>1 || !opt_nonvec_parms)
|
||||
if (arglist[i]->type->size == 3 || !opt_nonvec_parms)
|
||||
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STORE_V], arglist[i], d, (QCC_dstatement_t **)0xffffffff));
|
||||
else
|
||||
{
|
||||
|
@ -3662,6 +3668,7 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func) //warning, the func could
|
|||
e->ofs = OFS_PARM0+2;
|
||||
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STORE_F], QCC_MakeFloatConst(pr_immediate.vector[2]), e, (QCC_dstatement_t **)0xffffffff));
|
||||
e->ofs = OFS_PARM0;
|
||||
e->type = type_vector;
|
||||
|
||||
QCC_PR_Lex();
|
||||
}
|
||||
|
@ -4226,110 +4233,31 @@ void QCC_PR_EmitClassFromFunction(QCC_def_t *scope, char *tname)
|
|||
locals_end = numpr_globals + basetype->size;
|
||||
df->locals = locals_end - df->parm_start;
|
||||
}
|
||||
/*
|
||||
============
|
||||
PR_ParseValue
|
||||
|
||||
Returns the global ofs for the current token
|
||||
============
|
||||
*/
|
||||
QCC_def_t *QCC_PR_ParseValue (QCC_type_t *assumeclass, pbool allowarrayassign)
|
||||
QCC_def_t *QCC_PR_ParseArrayPointer (QCC_def_t *d, pbool allowarrayassign)
|
||||
{
|
||||
QCC_def_t *d, *od, *tmp, *idx;
|
||||
QCC_type_t *t;
|
||||
char *name;
|
||||
QCC_type_t *t;
|
||||
QCC_def_t *idx;
|
||||
QCC_def_t *tmp;
|
||||
QCC_dstatement_t *st;
|
||||
|
||||
char membername[2048];
|
||||
|
||||
// if the token is an immediate, allocate a constant for it
|
||||
if (pr_token_type == tt_immediate)
|
||||
return QCC_PR_ParseImmediate ();
|
||||
|
||||
if (QCC_PR_CheckToken("[")) //reacc support
|
||||
{ //looks like a funky vector. :)
|
||||
vec3_t v;
|
||||
pr_immediate_type = type_vector;
|
||||
v[0] = pr_immediate._float;
|
||||
QCC_PR_Lex();
|
||||
v[1] = pr_immediate._float;
|
||||
QCC_PR_Lex();
|
||||
v[2] = pr_immediate._float;
|
||||
pr_immediate.vector[0] = v[0];
|
||||
pr_immediate.vector[1] = v[1];
|
||||
pr_immediate.vector[2] = v[2];
|
||||
pr_immediate_type = type_vector;
|
||||
d = QCC_PR_ParseImmediate();
|
||||
QCC_PR_Expect("]");
|
||||
return d;
|
||||
}
|
||||
name = QCC_PR_ParseName ();
|
||||
|
||||
if (assumeclass && assumeclass->parentclass) // 'testvar' becomes 'self::testvar'
|
||||
{ //try getting a member.
|
||||
QCC_type_t *type;
|
||||
type = assumeclass;
|
||||
d = NULL;
|
||||
while(type != type_entity && type)
|
||||
{
|
||||
sprintf(membername, "%s::"MEMBERFIELDNAME, type->name, name);
|
||||
d = QCC_PR_GetDef (NULL, membername, pr_scope, false, 0, false);
|
||||
if (d)
|
||||
break;
|
||||
|
||||
type = type->parentclass;
|
||||
}
|
||||
if (!d)
|
||||
d = QCC_PR_GetDef (NULL, name, pr_scope, false, 0, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// look through the defs
|
||||
d = QCC_PR_GetDef (NULL, name, pr_scope, false, 0, false);
|
||||
}
|
||||
|
||||
if (!d)
|
||||
{
|
||||
if ( (!strcmp(name, "random" )) ||
|
||||
(!strcmp(name, "randomv")) ||
|
||||
(!strcmp(name, "sizeof")) ||
|
||||
(!strcmp(name, "entnum")) ||
|
||||
(!strcmp(name, "_"))) //intrinsics, any old function with no args will do.
|
||||
{
|
||||
d = QCC_PR_GetDef (type_function, name, NULL, true, 0, false);
|
||||
d->initialized = 0;
|
||||
}
|
||||
else if (keyword_class && !strcmp(name, "this"))
|
||||
{
|
||||
if (!pr_classtype)
|
||||
QCC_PR_ParseError(ERR_NOTANAME, "Cannot use 'this' outside of an OO function\n");
|
||||
od = QCC_PR_GetDef(NULL, "self", NULL, true, 0, false);
|
||||
d = QCC_PR_DummyDef(pr_classtype, "this", pr_scope, 0, od->ofs, true, false);
|
||||
}
|
||||
else if (keyword_class && !strcmp(name, "super"))
|
||||
{
|
||||
if (!pr_classtype)
|
||||
QCC_PR_ParseError(ERR_NOTANAME, "Cannot use 'super' outside of an OO function\n");
|
||||
od = QCC_PR_GetDef(NULL, "self", NULL, true, 0, false);
|
||||
d = QCC_PR_DummyDef(pr_classtype, "super", pr_scope, 0, od->ofs, true, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
d = QCC_PR_GetDef (type_variant, name, pr_scope, true, 0, false);
|
||||
if (!d)
|
||||
QCC_PR_ParseError (ERR_UNKNOWNVALUE, "Unknown value \"%s\"", name);
|
||||
else
|
||||
{
|
||||
QCC_PR_ParseWarning (ERR_UNKNOWNVALUE, "Unknown value \"%s\".", name);
|
||||
}
|
||||
}
|
||||
}
|
||||
pbool allowarray;
|
||||
|
||||
t = d->type;
|
||||
idx = NULL;
|
||||
while(1)
|
||||
{
|
||||
if (QCC_PR_CheckToken("["))
|
||||
allowarray = false;
|
||||
if (idx)
|
||||
allowarray = t->arraysize>0;
|
||||
else if (!idx)
|
||||
{
|
||||
allowarray = d->arraysize ||
|
||||
(d->type->type == ev_pointer) ||
|
||||
(d->type->type == ev_string) ||
|
||||
(d->type->type == ev_vector);
|
||||
}
|
||||
|
||||
if (allowarray && QCC_PR_CheckToken("["))
|
||||
{
|
||||
tmp = QCC_PR_Expression (TOP_PRIORITY, 0);
|
||||
QCC_PR_Expect("]");
|
||||
|
@ -4342,10 +4270,29 @@ QCC_def_t *QCC_PR_ParseValue (QCC_type_t *assumeclass, pbool allowarrayassign)
|
|||
{
|
||||
/*no bounds checks on pointer dereferences*/
|
||||
}
|
||||
else if (!idx && d->type->type == ev_string)
|
||||
else if (!idx && d->type->type == ev_string && !d->arraysize)
|
||||
{
|
||||
/*automatic runtime bounds checks on strings, I'm not going to check this too much...*/
|
||||
}
|
||||
else if (!idx && d->type->type == ev_vector && !d->arraysize)
|
||||
{
|
||||
if (tmp->constant)
|
||||
{
|
||||
unsigned int i;
|
||||
if (tmp->type->type == ev_integer)
|
||||
i = G_INT(tmp->ofs);
|
||||
else if (tmp->type->type == ev_float)
|
||||
i = G_FLOAT(tmp->ofs);
|
||||
if (i < 0 || i >= 3)
|
||||
QCC_PR_ParseErrorPrintDef(0, d, "(vector) array index out of bounds");
|
||||
}
|
||||
else if (QCC_OPCodeValid(&pr_opcodes[OP_LOADA_F]))
|
||||
{
|
||||
tmp = QCC_SupplyConversion(tmp, ev_integer, true);
|
||||
QCC_PR_SimpleStatement (OP_BOUNDCHECK, tmp->ofs, 3, 0, false);
|
||||
}
|
||||
t = type_float;
|
||||
}
|
||||
else if (!((!idx)?d->arraysize:t->arraysize))
|
||||
{
|
||||
QCC_PR_ParseErrorPrintDef(0, d, "array index on non-array");
|
||||
|
@ -4452,6 +4399,11 @@ QCC_def_t *QCC_PR_ParseValue (QCC_type_t *assumeclass, pbool allowarrayassign)
|
|||
{
|
||||
d = QCC_PR_Statement(&pr_opcodes[OP_LOADP_C], d, QCC_SupplyConversion(idx, ev_float, true), NULL);
|
||||
}
|
||||
else if (d->type->type == ev_vector && d->arraysize == 0)
|
||||
{
|
||||
d = QCC_PR_Statement(&pr_opcodes[OP_LOADA_F], d, QCC_SupplyConversion(idx, ev_integer, true), NULL);
|
||||
d->type = type_float;
|
||||
}
|
||||
else if (QCC_OPCodeValid(&pr_opcodes[OP_LOADA_F]))
|
||||
{
|
||||
/*don't care about assignments. the code can convert an OP_LOADA_F to an OP_ADDRESS on assign*/
|
||||
|
@ -4524,6 +4476,8 @@ QCC_def_t *QCC_PR_ParseValue (QCC_type_t *assumeclass, pbool allowarrayassign)
|
|||
qcc_usefulstatement=true;
|
||||
d = QCC_PR_GenerateFunctionCall(funcretr, args, 2);
|
||||
d->type = t;
|
||||
|
||||
return d;
|
||||
}
|
||||
else if (QCC_OPCodeValid(&pr_opcodes[OP_FETCH_GBL_F]))
|
||||
{
|
||||
|
@ -4578,8 +4532,113 @@ QCC_def_t *QCC_PR_ParseValue (QCC_type_t *assumeclass, pbool allowarrayassign)
|
|||
d = QCC_PR_GenerateFunctionCall(funcretr, args, 1);
|
||||
d->type = t;
|
||||
}
|
||||
|
||||
/*parse recursively*/
|
||||
d = QCC_PR_ParseArrayPointer(d, allowarrayassign);
|
||||
}
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
PR_ParseValue
|
||||
|
||||
Returns the global ofs for the current token
|
||||
============
|
||||
*/
|
||||
QCC_def_t *QCC_PR_ParseValue (QCC_type_t *assumeclass, pbool allowarrayassign)
|
||||
{
|
||||
QCC_def_t *d, *od, *tmp;
|
||||
QCC_type_t *t;
|
||||
char *name;
|
||||
|
||||
char membername[2048];
|
||||
|
||||
// if the token is an immediate, allocate a constant for it
|
||||
if (pr_token_type == tt_immediate)
|
||||
return QCC_PR_ParseImmediate ();
|
||||
|
||||
if (QCC_PR_CheckToken("[")) //reacc support
|
||||
{ //looks like a funky vector. :)
|
||||
vec3_t v;
|
||||
pr_immediate_type = type_vector;
|
||||
v[0] = pr_immediate._float;
|
||||
QCC_PR_Lex();
|
||||
v[1] = pr_immediate._float;
|
||||
QCC_PR_Lex();
|
||||
v[2] = pr_immediate._float;
|
||||
pr_immediate.vector[0] = v[0];
|
||||
pr_immediate.vector[1] = v[1];
|
||||
pr_immediate.vector[2] = v[2];
|
||||
pr_immediate_type = type_vector;
|
||||
d = QCC_PR_ParseImmediate();
|
||||
QCC_PR_Expect("]");
|
||||
return d;
|
||||
}
|
||||
name = QCC_PR_ParseName ();
|
||||
|
||||
if (assumeclass && assumeclass->parentclass) // 'testvar' becomes 'self::testvar'
|
||||
{ //try getting a member.
|
||||
QCC_type_t *type;
|
||||
type = assumeclass;
|
||||
d = NULL;
|
||||
while(type != type_entity && type)
|
||||
{
|
||||
sprintf(membername, "%s::"MEMBERFIELDNAME, type->name, name);
|
||||
d = QCC_PR_GetDef (NULL, membername, pr_scope, false, 0, false);
|
||||
if (d)
|
||||
break;
|
||||
|
||||
type = type->parentclass;
|
||||
}
|
||||
if (!d)
|
||||
d = QCC_PR_GetDef (NULL, name, pr_scope, false, 0, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// look through the defs
|
||||
d = QCC_PR_GetDef (NULL, name, pr_scope, false, 0, false);
|
||||
}
|
||||
|
||||
if (!d)
|
||||
{
|
||||
if ( (!strcmp(name, "random" )) ||
|
||||
(!strcmp(name, "randomv")) ||
|
||||
(!strcmp(name, "sizeof")) ||
|
||||
(!strcmp(name, "entnum")) ||
|
||||
(!strcmp(name, "_"))) //intrinsics, any old function with no args will do.
|
||||
{
|
||||
d = QCC_PR_GetDef (type_function, name, NULL, true, 0, false);
|
||||
d->initialized = 0;
|
||||
}
|
||||
else if (keyword_class && !strcmp(name, "this"))
|
||||
{
|
||||
if (!pr_classtype)
|
||||
QCC_PR_ParseError(ERR_NOTANAME, "Cannot use 'this' outside of an OO function\n");
|
||||
od = QCC_PR_GetDef(NULL, "self", NULL, true, 0, false);
|
||||
d = QCC_PR_DummyDef(pr_classtype, "this", pr_scope, 0, od->ofs, true, false);
|
||||
}
|
||||
else if (keyword_class && !strcmp(name, "super"))
|
||||
{
|
||||
if (!pr_classtype)
|
||||
QCC_PR_ParseError(ERR_NOTANAME, "Cannot use 'super' outside of an OO function\n");
|
||||
od = QCC_PR_GetDef(NULL, "self", NULL, true, 0, false);
|
||||
d = QCC_PR_DummyDef(pr_classtype, "super", pr_scope, 0, od->ofs, true, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
d = QCC_PR_GetDef (type_variant, name, pr_scope, true, 0, false);
|
||||
if (!d)
|
||||
QCC_PR_ParseError (ERR_UNKNOWNVALUE, "Unknown value \"%s\"", name);
|
||||
else
|
||||
{
|
||||
QCC_PR_ParseWarning (ERR_UNKNOWNVALUE, "Unknown value \"%s\".", name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
d = QCC_PR_ParseArrayPointer(d, allowarrayassign);
|
||||
|
||||
t = d->type;
|
||||
if (keyword_class && t->type == ev_entity && t->parentclass && (QCC_PR_CheckToken(".") || QCC_PR_CheckToken("->")))
|
||||
|
@ -4783,45 +4842,46 @@ QCC_def_t *QCC_PR_Term (void)
|
|||
e = QCC_PR_Expression (UNARY_PRIORITY, EXPR_DISALLOW_COMMA);
|
||||
t = e->type->type;
|
||||
|
||||
if (t != ev_pointer)
|
||||
QCC_PR_ParseError (ERR_BADNOTTYPE, "type mismatch for *");
|
||||
|
||||
|
||||
|
||||
switch(e->type->aux_type->type)
|
||||
if (t == ev_string)
|
||||
e2 = QCC_PR_Statement(&pr_opcodes[OP_LOADP_C], e, QCC_MakeFloatConst(0), NULL);
|
||||
else if (t == ev_pointer)
|
||||
{
|
||||
case ev_float:
|
||||
e2 = QCC_PR_Statement (&pr_opcodes[OP_LOADP_F], e, 0, NULL);
|
||||
break;
|
||||
case ev_string:
|
||||
e2 = QCC_PR_Statement (&pr_opcodes[OP_LOADP_S], e, 0, NULL);
|
||||
break;
|
||||
case ev_vector:
|
||||
e2 = QCC_PR_Statement (&pr_opcodes[OP_LOADP_V], e, 0, NULL);
|
||||
break;
|
||||
case ev_entity:
|
||||
e2 = QCC_PR_Statement (&pr_opcodes[OP_LOADP_ENT], e, 0, NULL);
|
||||
break;
|
||||
case ev_field:
|
||||
e2 = QCC_PR_Statement (&pr_opcodes[OP_LOADP_FLD], e, 0, NULL);
|
||||
break;
|
||||
case ev_function:
|
||||
e2 = QCC_PR_Statement (&pr_opcodes[OP_LOADP_FLD], e, 0, NULL);
|
||||
break;
|
||||
case ev_integer:
|
||||
e2 = QCC_PR_Statement (&pr_opcodes[OP_LOADP_I], e, 0, NULL);
|
||||
break;
|
||||
case ev_pointer:
|
||||
e2 = QCC_PR_Statement (&pr_opcodes[OP_LOADP_I], e, 0, NULL);
|
||||
break;
|
||||
switch(e->type->aux_type->type)
|
||||
{
|
||||
case ev_float:
|
||||
e2 = QCC_PR_Statement (&pr_opcodes[OP_LOADP_F], e, 0, NULL);
|
||||
break;
|
||||
case ev_string:
|
||||
e2 = QCC_PR_Statement (&pr_opcodes[OP_LOADP_S], e, 0, NULL);
|
||||
break;
|
||||
case ev_vector:
|
||||
e2 = QCC_PR_Statement (&pr_opcodes[OP_LOADP_V], e, 0, NULL);
|
||||
break;
|
||||
case ev_entity:
|
||||
e2 = QCC_PR_Statement (&pr_opcodes[OP_LOADP_ENT], e, 0, NULL);
|
||||
break;
|
||||
case ev_field:
|
||||
e2 = QCC_PR_Statement (&pr_opcodes[OP_LOADP_FLD], e, 0, NULL);
|
||||
break;
|
||||
case ev_function:
|
||||
e2 = QCC_PR_Statement (&pr_opcodes[OP_LOADP_FLD], e, 0, NULL);
|
||||
break;
|
||||
case ev_integer:
|
||||
e2 = QCC_PR_Statement (&pr_opcodes[OP_LOADP_I], e, 0, NULL);
|
||||
break;
|
||||
case ev_pointer:
|
||||
e2 = QCC_PR_Statement (&pr_opcodes[OP_LOADP_I], e, 0, NULL);
|
||||
break;
|
||||
|
||||
default:
|
||||
QCC_PR_ParseError (ERR_BADNOTTYPE, "type mismatch for * (unrecognised type)");
|
||||
e2 = NULL;
|
||||
break;
|
||||
default:
|
||||
QCC_PR_ParseError (ERR_BADNOTTYPE, "type mismatch for * (unrecognised type)");
|
||||
e2 = NULL;
|
||||
break;
|
||||
}
|
||||
e2->type = e->type->aux_type;
|
||||
}
|
||||
|
||||
e2->type = e->type->aux_type;
|
||||
else
|
||||
QCC_PR_ParseError (ERR_BADNOTTYPE, "type mismatch for *");
|
||||
return e2;
|
||||
}
|
||||
else if (QCC_PR_CheckToken ("-"))
|
||||
|
@ -5156,21 +5216,15 @@ QCC_def_t *QCC_PR_Expression (int priority, int exprflags)
|
|||
//this kills the add 0.
|
||||
e->ofs = statements[numstatements-1].a;
|
||||
numstatements--;
|
||||
|
||||
if (e->type->type != ev_pointer)
|
||||
{
|
||||
type_pointer->aux_type->type = e->type->type;
|
||||
e->type = type_pointer;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
statements[numstatements-1].op = OP_POINTER_ADD;
|
||||
if (e->type->type != ev_pointer)
|
||||
{
|
||||
type_pointer->aux_type->type = e->type->type;
|
||||
e->type = type_pointer;
|
||||
}
|
||||
}
|
||||
if (e->type != type_pointer)
|
||||
{
|
||||
type_pointer->aux_type->type = e->type->type;
|
||||
e->type = type_pointer;
|
||||
}
|
||||
}
|
||||
if ( !simplestore && statements[numstatements-1].op == OP_LOADP_C && e->ofs == statements[numstatements-1].c)
|
||||
|
|
|
@ -700,6 +700,18 @@ pbool QCC_WriteData (int crc)
|
|||
|
||||
for (def = pr.def_head.next ; def ; def = def->next)
|
||||
{
|
||||
if ((def->type->type == ev_struct || def->type->type == ev_union || def->arraysize) && def->deftail)
|
||||
{
|
||||
QCC_def_t *d;
|
||||
d = def;
|
||||
while (d != def->deftail)
|
||||
{
|
||||
d = d->next;
|
||||
h = d->references;
|
||||
d->references += def->references;
|
||||
def->references += h;
|
||||
}
|
||||
}
|
||||
if (def->type->type == ev_vector || (def->type->type == ev_field && def->type->aux_type->type == ev_vector))
|
||||
{ //do the references, so we don't get loadsa not referenced VEC_HULL_MINS_x
|
||||
sprintf(element, "%s_x", def->name);
|
||||
|
@ -841,9 +853,10 @@ pbool QCC_WriteData (int crc)
|
|||
continue;
|
||||
if (dd->ofs == qcc_globals[h].ofs)
|
||||
{
|
||||
if (dd->type != qcc_globals[h].type)
|
||||
if ((dd->type&~DEF_SAVEGLOBAL) != (qcc_globals[h].type&~DEF_SAVEGLOBAL))
|
||||
{
|
||||
if (dd->type != ev_vector && qcc_globals[h].type != ev_float)
|
||||
if (!(((dd->type&~DEF_SAVEGLOBAL) == ev_vector && (qcc_globals[h].type&~DEF_SAVEGLOBAL) == ev_float) ||
|
||||
((dd->type&~DEF_SAVEGLOBAL) == ev_struct || (dd->type&~DEF_SAVEGLOBAL) == ev_union)))
|
||||
QCC_PR_Warning(0, NULL, 0, "Mismatched union global types (%s and %s)", strings+dd->s_name, strings+qcc_globals[h].s_name);
|
||||
}
|
||||
//remove the saveglobal flag on the duplicate globals.
|
||||
|
|
|
@ -8942,7 +8942,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
|||
|
||||
{"dynamiclight_add",PF_Fixme, 0, 0, 0, 305, "float(vector org, float radius, vector lightcolours)"},// (EXT_CSQC)
|
||||
|
||||
{"R_BeginPolygon", PF_Fixme, 0, 0, 0, 306, "void(string texturename)"},// (EXT_CSQC_???)
|
||||
{"R_BeginPolygon", PF_Fixme, 0, 0, 0, 306, "void(string texturename, optional float flags)"},// (EXT_CSQC_???)
|
||||
{"R_PolygonVertex", PF_Fixme, 0, 0, 0, 307, "void(vector org, vector texcoords, vector rgb, float alpha)"},// (EXT_CSQC_???)
|
||||
{"R_EndPolygon", PF_Fixme, 0, 0, 0, 308, "void()"},// (EXT_CSQC_???)
|
||||
|
||||
|
|
Loading…
Reference in a new issue