From 24e5adeb2b586a3d5707e3dc61a464648952c6f2 Mon Sep 17 00:00:00 2001 From: Spoike Date: Mon, 13 Feb 2012 09:24:01 +0000 Subject: [PATCH] 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 --- engine/client/pr_csqc.c | 55 ++++-- engine/common/pr_bgcmd.c | 5 +- engine/gl/gl_alias.c | 3 + engine/qclib/pr_comp.h | 3 +- engine/qclib/qcc.h | 9 +- engine/qclib/qcc_pr_comp.c | 350 +++++++++++++++++++++---------------- engine/qclib/qccmain.c | 17 +- engine/server/pr_cmds.c | 2 +- 8 files changed, 273 insertions(+), 171 deletions(-) diff --git a/engine/client/pr_csqc.c b/engine/client/pr_csqc.c index 67c5117c3..25cd3afe3 100644 --- a/engine/client/pr_csqc.c +++ b/engine/client/pr_csqc.c @@ -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; + } } diff --git a/engine/common/pr_bgcmd.c b/engine/common/pr_bgcmd.c index 9c442f2bd..d9da67d97 100644 --- a/engine/common/pr_bgcmd.c +++ b/engine/common/pr_bgcmd.c @@ -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]) diff --git a/engine/gl/gl_alias.c b/engine/gl/gl_alias.c index 8d3ea2089..f5d7a1ddb 100644 --- a/engine/gl/gl_alias.c +++ b/engine/gl/gl_alias.c @@ -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; diff --git a/engine/qclib/pr_comp.h b/engine/qclib/pr_comp.h index c76e6b224..355908638 100644 --- a/engine/qclib/pr_comp.h +++ b/engine/qclib/pr_comp.h @@ -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 }; diff --git a/engine/qclib/qcc.h b/engine/qclib/qcc.h index aaf6533fa..1ee2ac62a 100644 --- a/engine/qclib/qcc.h +++ b/engine/qclib/qcc.h @@ -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; diff --git a/engine/qclib/qcc_pr_comp.c b/engine/qclib/qcc_pr_comp.c index bc6ea4560..d73fd6f1a 100644 --- a/engine/qclib/qcc_pr_comp.c +++ b/engine/qclib/qcc_pr_comp.c @@ -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", 6, ASSOC_RIGHT, &type_void, &type_void, &type_void}, {7, "", "PUSH", -1, ASSOC_RIGHT, &type_float, &type_void, &type_pointer}, {7, "", "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) diff --git a/engine/qclib/qccmain.c b/engine/qclib/qccmain.c index f6972a784..8c8493074 100644 --- a/engine/qclib/qccmain.c +++ b/engine/qclib/qccmain.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. diff --git a/engine/server/pr_cmds.c b/engine/server/pr_cmds.c index d6eb973a4..66bf861a5 100644 --- a/engine/server/pr_cmds.c +++ b/engine/server/pr_cmds.c @@ -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_???)