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:
Spoike 2012-02-13 09:24:01 +00:00
parent ad32917970
commit 24e5adeb2b
8 changed files with 273 additions and 171 deletions

View File

@ -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;
}
}

View File

@ -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])

View File

@ -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;

View File

@ -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
};

View File

@ -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;

View File

@ -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)

View File

@ -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.

View File

@ -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_???)