qbool PR1_ClientSay(int isTeamSay, char *message) { qbool ret = false; if (mod_ChatMessage) { int j; // remove surrounding " if any. if (message[0] == '"' && (j = (int)strlen(message)) > 2 && message[j-1] == '"') { message++; // skip opening ". message[max(0,(int)strlen(message)-1)] = 0; // truncate closing ". } PR_SetTmpString(&G_INT(OFS_PARM0), message); G_FLOAT(OFS_PARM1) = (float)isTeamSay; PR_ExecuteProgram(mod_ChatMessage); ret = !!G_FLOAT(OFS_RETURN); } return ret; }
static def_t *GetArrayDef (const char *name, type_t *type, int *elementCount) { def_t *def; int count; int regCount; if (type->type == ev_field) { return GetFieldArrayDef(name, type, elementCount); } count = ParseArray(name, type); def = NewVarDef(name, type); // Precede the array register storage with the element count // for run-time boundary checking. G_INT(numpr_globals) = count-1; numpr_globals++; def->ofs = numpr_globals; regCount = count*type_size[type->type]; do { pr_global_defs[numpr_globals] = def; numpr_globals++; } while (--regCount); *elementCount = count; return def; }
void QCBUILTIN PF_cs_media_getproperty (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { const char *shader = PR_GetStringOfs(prinst, OFS_PARM0); const char *propname = PR_GetStringOfs(prinst, OFS_PARM1); const char *ret = NULL; cin_t *cin; cin = R_ShaderFindCinematic(shader); if (cin) ret = Media_Send_GetProperty(cin, propname); G_INT(OFS_RETURN) = ret?PR_TempString(prinst, ret):0; }
static def_t *GetFieldArrayDef (const char *name, type_t *type, int *elementCount) { def_t *def; int count; count = ParseArray(name, type); def = NewVarDef(name, type); def->ofs = numpr_globals; pr_global_defs[numpr_globals] = def; G_INT(numpr_globals) = pr.size_fields; numpr_globals++; pr.size_fields += type_size[type->aux_type->type]*count; *elementCount = count; return def; }
// All changes need to be in SV_SendEffect(), SV_ParseEffect(), // SV_SaveEffects(), SV_LoadEffects(), CL_ParseEffect() void SV_ParseEffect(sizebuf_t *sb) { int index; byte effect; effect = G_FLOAT(OFS_PARM0); for(index=0;index<MAX_EFFECTS;index++) if (!sv.Effects[index].type || (sv.Effects[index].expire_time && sv.Effects[index].expire_time <= sv.time)) break; if (index >= MAX_EFFECTS) { PR_RunError ("MAX_EFFECTS reached"); return; } // Con_Printf("Effect #%d\n",index); memset(&sv.Effects[index],0,sizeof(struct EffectT)); sv.Effects[index].type = effect; G_FLOAT(OFS_RETURN) = index; switch(effect) { case CE_RAIN: VectorCopy(G_VECTOR(OFS_PARM1),sv.Effects[index].Rain.min_org); VectorCopy(G_VECTOR(OFS_PARM2),sv.Effects[index].Rain.max_org); VectorCopy(G_VECTOR(OFS_PARM3),sv.Effects[index].Rain.e_size); VectorCopy(G_VECTOR(OFS_PARM4),sv.Effects[index].Rain.dir); sv.Effects[index].Rain.color = G_FLOAT(OFS_PARM5); sv.Effects[index].Rain.count = G_FLOAT(OFS_PARM6); sv.Effects[index].Rain.wait = G_FLOAT(OFS_PARM7); sv.Effects[index].Rain.next_time = 0; break; case CE_FOUNTAIN: VectorCopy(G_VECTOR(OFS_PARM1),sv.Effects[index].Fountain.pos); VectorCopy(G_VECTOR(OFS_PARM2),sv.Effects[index].Fountain.angle); VectorCopy(G_VECTOR(OFS_PARM3),sv.Effects[index].Fountain.movedir); sv.Effects[index].Fountain.color = G_FLOAT(OFS_PARM4); sv.Effects[index].Fountain.cnt = G_FLOAT(OFS_PARM5); break; case CE_QUAKE: VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].Quake.origin); sv.Effects[index].Quake.radius = G_FLOAT(OFS_PARM2); break; case CE_WHITE_SMOKE: case CE_GREEN_SMOKE: case CE_GREY_SMOKE: case CE_RED_SMOKE: case CE_SLOW_WHITE_SMOKE: case CE_TELESMK1: case CE_TELESMK2: case CE_GHOST: case CE_REDCLOUD: case CE_RIPPLE: VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].Smoke.origin); VectorCopy(G_VECTOR(OFS_PARM2), sv.Effects[index].Smoke.velocity); sv.Effects[index].Smoke.framelength = G_FLOAT(OFS_PARM3); sv.Effects[index].expire_time = sv.time + 1; break; case CE_ACID_MUZZFL: case CE_FLAMESTREAM: case CE_FLAMEWALL: case CE_FLAMEWALL2: case CE_ONFIRE: VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].Smoke.origin); VectorCopy(G_VECTOR(OFS_PARM2), sv.Effects[index].Smoke.velocity); sv.Effects[index].Smoke.framelength = 0.05; sv.Effects[index].Smoke.frame = G_FLOAT(OFS_PARM3); sv.Effects[index].expire_time = sv.time + 1; break; case CE_SM_WHITE_FLASH: case CE_YELLOWRED_FLASH: case CE_BLUESPARK: case CE_YELLOWSPARK: case CE_SM_CIRCLE_EXP: case CE_BG_CIRCLE_EXP: case CE_SM_EXPLOSION: case CE_SM_EXPLOSION2: case CE_BG_EXPLOSION: case CE_FLOOR_EXPLOSION: case CE_BLUE_EXPLOSION: case CE_REDSPARK: case CE_GREENSPARK: case CE_ICEHIT: case CE_MEDUSA_HIT: case CE_MEZZO_REFLECT: case CE_FLOOR_EXPLOSION2: case CE_XBOW_EXPLOSION: case CE_NEW_EXPLOSION: case CE_MAGIC_MISSILE_EXPLOSION: case CE_BONE_EXPLOSION: case CE_BLDRN_EXPL: case CE_ACID_HIT: case CE_ACID_SPLAT: case CE_ACID_EXPL: case CE_LBALL_EXPL: case CE_FIREWALL_SMALL: case CE_FIREWALL_MEDIUM: case CE_FIREWALL_LARGE: case CE_FBOOM: case CE_BOMB: case CE_BRN_BOUNCE: case CE_LSHOCK: VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].Smoke.origin); sv.Effects[index].expire_time = sv.time + 1; break; case CE_WHITE_FLASH: case CE_BLUE_FLASH: case CE_SM_BLUE_FLASH: case CE_HWSPLITFLASH: case CE_RED_FLASH: VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].Flash.origin); sv.Effects[index].expire_time = sv.time + 1; break; case CE_RIDER_DEATH: VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].RD.origin); break; case CE_TELEPORTERPUFFS: VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].Teleporter.origin); sv.Effects[index].expire_time = sv.time + 1; break; case CE_TELEPORTERBODY: VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].Teleporter.origin); VectorCopy(G_VECTOR(OFS_PARM2),sv.Effects[index].Teleporter.velocity[0]); sv.Effects[index].Teleporter.skinnum = G_FLOAT(OFS_PARM3); sv.Effects[index].expire_time = sv.time + 1; break; case CE_BONESHRAPNEL: case CE_HWBONEBALL: VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].Missile.origin); VectorCopy(G_VECTOR(OFS_PARM2),sv.Effects[index].Missile.velocity); VectorCopy(G_VECTOR(OFS_PARM3),sv.Effects[index].Missile.angle); VectorCopy(G_VECTOR(OFS_PARM2),sv.Effects[index].Missile.avelocity); sv.Effects[index].expire_time = sv.time + 10; break; case CE_BONESHARD: case CE_HWRAVENSTAFF: case CE_HWMISSILESTAR: case CE_HWEIDOLONSTAR: case CE_HWRAVENPOWER: VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].Missile.origin); VectorCopy(G_VECTOR(OFS_PARM2),sv.Effects[index].Missile.velocity); sv.Effects[index].expire_time = sv.time + 10; break; case CE_DEATHBUBBLES: VectorCopy(G_VECTOR(OFS_PARM2), sv.Effects[index].Bubble.offset); sv.Effects[index].Bubble.owner = G_EDICTNUM(OFS_PARM1); sv.Effects[index].Bubble.count = G_FLOAT(OFS_PARM3); sv.Effects[index].expire_time = sv.time + 30; break; case CE_HWDRILLA: VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].Missile.origin); VectorCopy(G_VECTOR(OFS_PARM2),sv.Effects[index].Missile.angle); sv.Effects[index].Missile.speed = G_FLOAT(OFS_PARM3); sv.Effects[index].expire_time = sv.time + 10; break; case CE_TRIPMINESTILL: VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].Chain.origin); VectorCopy(G_VECTOR(OFS_PARM2),sv.Effects[index].Chain.velocity); sv.Effects[index].expire_time = sv.time + 70; break; case CE_TRIPMINE: VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].Chain.origin); VectorCopy(G_VECTOR(OFS_PARM2),sv.Effects[index].Chain.velocity); sv.Effects[index].expire_time = sv.time + 10; break; case CE_SCARABCHAIN: VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].Chain.origin); sv.Effects[index].Chain.owner = G_EDICTNUM(OFS_PARM2); sv.Effects[index].Chain.material = G_INT(OFS_PARM3); sv.Effects[index].Chain.tag = G_INT(OFS_PARM4); sv.Effects[index].Chain.state = 0; sv.Effects[index].expire_time = sv.time + 15; break; case CE_HWSHEEPINATOR: VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].Xbow.origin[0]); VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].Xbow.origin[1]); VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].Xbow.origin[2]); VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].Xbow.origin[3]); VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].Xbow.origin[4]); VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].Xbow.origin[5]); VectorCopy(G_VECTOR(OFS_PARM2), sv.Effects[index].Xbow.angle); sv.Effects[index].Xbow.bolts = 5; sv.Effects[index].Xbow.activebolts = 31; sv.Effects[index].Xbow.randseed = 0; sv.Effects[index].Xbow.turnedbolts = 0; sv.Effects[index].expire_time = sv.time + 7; break; case CE_HWXBOWSHOOT: VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].Xbow.origin[0]); VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].Xbow.origin[1]); VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].Xbow.origin[2]); VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].Xbow.origin[3]); VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].Xbow.origin[4]); VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[index].Xbow.origin[5]); VectorCopy(G_VECTOR(OFS_PARM2), sv.Effects[index].Xbow.angle); sv.Effects[index].Xbow.bolts = G_FLOAT(OFS_PARM3); sv.Effects[index].Xbow.randseed = G_FLOAT(OFS_PARM4); sv.Effects[index].Xbow.turnedbolts = 0; if (sv.Effects[index].Xbow.bolts == 3) { sv.Effects[index].Xbow.activebolts = 7; } else { sv.Effects[index].Xbow.activebolts = 31; } sv.Effects[index].expire_time = sv.time + 15; break; default: // Sys_Error ("SV_ParseEffect: bad type"); PR_RunError ("SV_SendEffect: bad type"); } SV_SendEffect(sb,index); }
/* ============= ED_ParseEval Can parse either fields or globals returns false if error ============= */ qbool ED_ParseEpair (void *base, ddef_t *key, char *s) { int i; char string[128]; ddef_t *def; char *v, *w; void *d; dfunction_t *func; d = (void *)((int *)base + key->ofs); switch (key->type & ~DEF_SAVEGLOBAL) { case ev_string: *(string_t *)d = PR_SetString(ED_NewString (s)); break; case ev_float: *(float *)d = Q_atof (s); break; case ev_vector: strlcpy (string, s, sizeof(string)); v = string; w = string; for (i=0 ; i<3 ; i++) { while (*v && *v != ' ') v++; *v = 0; ((float *)d)[i] = Q_atof (w); w = v = v+1; } break; case ev_entity: *(int *)d = EDICT_TO_PROG(EDICT_NUM(Q_atoi (s))); break; case ev_field: def = ED_FindField (s); if (!def) { Con_Printf ("Can't find field %s\n", s); return false; } *(int *)d = G_INT(def->ofs); break; case ev_function: func = ED_FindFunction (s); if (!func) { Con_Printf ("Can't find function %s\n", s); return false; } *(func_t *)d = func - pr_functions; break; default: break; } return true; }
void PR_ExecuteProgram(func_t fnum) { int i; int s; eval_t *a, *b, *c; eval_t *ptr; dstatement_t *st; dfunction_t *f, *newf; int runaway; edict_t *ed; int exitdepth; int startFrame; int endFrame; float val; int case_type=-1; float switch_float; if(!fnum || fnum >= progs->numfunctions) { if(pr_global_struct->self) { ED_Print(PROG_TO_EDICT(pr_global_struct->self)); } Host_Error("PR_ExecuteProgram: NULL function"); } f = &pr_functions[fnum]; runaway = 100000; pr_trace = false; exitdepth = pr_depth; s = EnterFunction(f); #ifdef TIMESNAP_ACTIVE ProgsTimer(); // Init #endif while (1) { s++; // Next statement st = &pr_statements[s]; a = (eval_t *)&pr_globals[(unsigned short)st->a]; b = (eval_t *)&pr_globals[(unsigned short)st->b]; c = (eval_t *)&pr_globals[(unsigned short)st->c]; if(!--runaway) { PR_RunError("runaway loop error"); } #ifndef TIMESNAP_ACTIVE pr_xfunction->profile++; #endif pr_xstatement = s; if(pr_trace) { PrintStatement(st); } switch(st->op) { case OP_ADD_F: c->_float = a->_float + b->_float; break; case OP_ADD_V: c->vector[0] = a->vector[0] + b->vector[0]; c->vector[1] = a->vector[1] + b->vector[1]; c->vector[2] = a->vector[2] + b->vector[2]; break; case OP_SUB_F: c->_float = a->_float - b->_float; break; case OP_SUB_V: c->vector[0] = a->vector[0] - b->vector[0]; c->vector[1] = a->vector[1] - b->vector[1]; c->vector[2] = a->vector[2] - b->vector[2]; break; case OP_MUL_F: c->_float = a->_float * b->_float; break; case OP_MUL_V: c->_float = a->vector[0]*b->vector[0] + a->vector[1]*b->vector[1] + a->vector[2]*b->vector[2]; break; case OP_MUL_FV: c->vector[0] = a->_float * b->vector[0]; c->vector[1] = a->_float * b->vector[1]; c->vector[2] = a->_float * b->vector[2]; break; case OP_MUL_VF: c->vector[0] = b->_float * a->vector[0]; c->vector[1] = b->_float * a->vector[1]; c->vector[2] = b->_float * a->vector[2]; break; case OP_DIV_F: c->_float = a->_float / b->_float; break; case OP_BITAND: c->_float = (int)a->_float & (int)b->_float; break; case OP_BITOR: c->_float = (int)a->_float | (int)b->_float; break; case OP_GE: c->_float = a->_float >= b->_float; break; case OP_LE: c->_float = a->_float <= b->_float; break; case OP_GT: c->_float = a->_float > b->_float; break; case OP_LT: c->_float = a->_float < b->_float; break; case OP_AND: c->_float = a->_float && b->_float; break; case OP_OR: c->_float = a->_float || b->_float; break; case OP_NOT_F: c->_float = !a->_float; break; case OP_NOT_V: c->_float = !a->vector[0] && !a->vector[1] && !a->vector[2]; break; case OP_NOT_S: c->_float = !a->string || !pr_strings[a->string]; break; case OP_NOT_FNC: c->_float = !a->function; break; case OP_NOT_ENT: c->_float = (PROG_TO_EDICT(a->edict) == sv.edicts); break; case OP_EQ_F: c->_float = a->_float == b->_float; break; case OP_EQ_V: c->_float = (a->vector[0] == b->vector[0]) && (a->vector[1] == b->vector[1]) && (a->vector[2] == b->vector[2]); break; case OP_EQ_S: c->_float = !strcmp(pr_strings+a->string,pr_strings+b->string); break; case OP_EQ_E: c->_float = a->_int == b->_int; break; case OP_EQ_FNC: c->_float = a->function == b->function; break; case OP_NE_F: c->_float = a->_float != b->_float; break; case OP_NE_V: c->_float = (a->vector[0] != b->vector[0]) || (a->vector[1] != b->vector[1]) || (a->vector[2] != b->vector[2]); break; case OP_NE_S: c->_float = strcmp(pr_strings+a->string,pr_strings+b->string); break; case OP_NE_E: c->_float = a->_int != b->_int; break; case OP_NE_FNC: c->_float = a->function != b->function; break; case OP_STORE_F: case OP_STORE_ENT: case OP_STORE_FLD: // integers case OP_STORE_S: case OP_STORE_FNC: // pointers b->_int = a->_int; break; case OP_STORE_V: b->vector[0] = a->vector[0]; b->vector[1] = a->vector[1]; b->vector[2] = a->vector[2]; break; case OP_STOREP_F: case OP_STOREP_ENT: case OP_STOREP_FLD: // integers case OP_STOREP_S: case OP_STOREP_FNC: // pointers ptr = (eval_t *)((byte *)sv.edicts + b->_int); ptr->_int = a->_int; break; case OP_STOREP_V: ptr = (eval_t *)((byte *)sv.edicts + b->_int); ptr->vector[0] = a->vector[0]; ptr->vector[1] = a->vector[1]; ptr->vector[2] = a->vector[2]; break; case OP_MULSTORE_F: // f *= f b->_float *= a->_float; break; case OP_MULSTORE_V: // v *= f b->vector[0] *= a->_float; b->vector[1] *= a->_float; b->vector[2] *= a->_float; break; case OP_MULSTOREP_F: // e.f *= f ptr = (eval_t *)((byte *)sv.edicts+b->_int); c->_float = (ptr->_float *= a->_float); break; case OP_MULSTOREP_V: // e.v *= f ptr = (eval_t *)((byte *)sv.edicts+b->_int); c->vector[0] = (ptr->vector[0] *= a->_float); c->vector[0] = (ptr->vector[1] *= a->_float); c->vector[0] = (ptr->vector[2] *= a->_float); break; case OP_DIVSTORE_F: // f /= f b->_float /= a->_float; break; case OP_DIVSTOREP_F: // e.f /= f ptr = (eval_t *)((byte *)sv.edicts+b->_int); c->_float = (ptr->_float /= a->_float); break; case OP_ADDSTORE_F: // f += f b->_float += a->_float; break; case OP_ADDSTORE_V: // v += v b->vector[0] += a->vector[0]; b->vector[1] += a->vector[1]; b->vector[2] += a->vector[2]; break; case OP_ADDSTOREP_F: // e.f += f ptr = (eval_t *)((byte *)sv.edicts+b->_int); c->_float = (ptr->_float += a->_float); break; case OP_ADDSTOREP_V: // e.v += v ptr = (eval_t *)((byte *)sv.edicts+b->_int); c->vector[0] = (ptr->vector[0] += a->vector[0]); c->vector[1] = (ptr->vector[1] += a->vector[1]); c->vector[2] = (ptr->vector[2] += a->vector[2]); break; case OP_SUBSTORE_F: // f -= f b->_float -= a->_float; break; case OP_SUBSTORE_V: // v -= v b->vector[0] -= a->vector[0]; b->vector[1] -= a->vector[1]; b->vector[2] -= a->vector[2]; break; case OP_SUBSTOREP_F: // e.f -= f ptr = (eval_t *)((byte *)sv.edicts+b->_int); c->_float = (ptr->_float -= a->_float); break; case OP_SUBSTOREP_V: // e.v -= v ptr = (eval_t *)((byte *)sv.edicts+b->_int); c->vector[0] = (ptr->vector[0] -= a->vector[0]); c->vector[1] = (ptr->vector[1] -= a->vector[1]); c->vector[2] = (ptr->vector[2] -= a->vector[2]); break; case OP_ADDRESS: ed = PROG_TO_EDICT(a->edict); #ifdef PARANOID NUM_FOR_EDICT(ed); // Make sure it's in range #endif if(ed == (edict_t *)sv.edicts && sv.state == ss_active) { PR_RunError("assignment to world entity"); } c->_int = (byte *)((int *)&ed->v + b->_int)-(byte *)sv.edicts; break; case OP_LOAD_F: case OP_LOAD_FLD: case OP_LOAD_ENT: case OP_LOAD_S: case OP_LOAD_FNC: ed = PROG_TO_EDICT(a->edict); #ifdef PARANOID NUM_FOR_EDICT(ed); // Make sure it's in range #endif a = (eval_t *)((int *)&ed->v+b->_int); c->_int = a->_int; break; case OP_LOAD_V: ed = PROG_TO_EDICT(a->edict); #ifdef PARANOID NUM_FOR_EDICT(ed); // Make sure it's in range #endif a = (eval_t *)((int *)&ed->v + b->_int); c->vector[0] = a->vector[0]; c->vector[1] = a->vector[1]; c->vector[2] = a->vector[2]; break; case OP_FETCH_GBL_F: case OP_FETCH_GBL_S: case OP_FETCH_GBL_E: case OP_FETCH_GBL_FNC: i = (int)b->_float; if(i < 0 || i > G_INT((unsigned short)st->a - 1)) { PR_RunError("array index out of bounds: %d", i); } a = (eval_t *)&pr_globals[(unsigned short)st->a + i]; c->_int = a->_int; break; case OP_FETCH_GBL_V: i = (int)b->_float; if(i < 0 || i > G_INT((unsigned short)st->a - 1)) { PR_RunError("array index out of bounds: %d", i); } a = (eval_t *)&pr_globals[(unsigned short)st->a +((int)b->_float)*3]; c->vector[0] = a->vector[0]; c->vector[1] = a->vector[1]; c->vector[2] = a->vector[2]; break; case OP_IFNOT: if(!a->_int) { s += st->b-1; // -1 to offset the s++ } break; case OP_IF: if(a->_int) { s += st->b-1; // -1 to offset the s++ } break; case OP_GOTO: s += st->a-1; // -1 to offset the s++ break; case OP_CALL8: case OP_CALL7: case OP_CALL6: case OP_CALL5: case OP_CALL4: case OP_CALL3: case OP_CALL2: // Copy second arg to shared space VectorCopy(c->vector, G_VECTOR(OFS_PARM1)); case OP_CALL1: // Copy first arg to shared space VectorCopy(b->vector, G_VECTOR(OFS_PARM0)); case OP_CALL0: pr_argc = st->op-OP_CALL0; if(!a->function) { PR_RunError("NULL function"); } newf = &pr_functions[a->function]; if(newf->first_statement < 0) { // Built-in function i = -newf->first_statement; if(i >= pr_numbuiltins) { PR_RunError("Bad builtin call number"); } pr_builtins[i](); break; } // Normal function #ifdef TIMESNAP_ACTIVE pr_xfunction->profile += ProgsTimer(); #endif s = EnterFunction(newf); break; case OP_DONE: case OP_RETURN: pr_globals[OFS_RETURN] = pr_globals[(unsigned short)st->a]; pr_globals[OFS_RETURN+1] = pr_globals[(unsigned short)st->a+1]; pr_globals[OFS_RETURN+2] = pr_globals[(unsigned short)st->a+2]; #ifdef TIMESNAP_ACTIVE pr_xfunction->profile += ProgsTimer(); #endif s = LeaveFunction(); if(pr_depth == exitdepth) { // Done return; } break; case OP_STATE: ed = PROG_TO_EDICT(pr_global_struct->self); /* Id 1.07 changes #ifdef FPS_20 ed->v.nextthink = pr_global_struct->time + 0.05; #else ed->v.nextthink = pr_global_struct->time + 0.1; #endif */ ed->v.nextthink = pr_global_struct->time+HX_FRAME_TIME; if(a->_float != ed->v.frame) { ed->v.frame = a->_float; } ed->v.think = b->function; break; case OP_CSTATE: // Cycle state ed = PROG_TO_EDICT(pr_global_struct->self); ed->v.nextthink = pr_global_struct->time+HX_FRAME_TIME; ed->v.think = pr_xfunction-pr_functions; pr_global_struct->cycle_wrapped = false; startFrame = (int)a->_float; endFrame = (int)b->_float; if(startFrame <= endFrame) { // Increment if(ed->v.frame < startFrame || ed->v.frame > endFrame) { ed->v.frame = startFrame; break; } ed->v.frame++; if(ed->v.frame > endFrame) { pr_global_struct->cycle_wrapped = true; ed->v.frame = startFrame; } break; } // Decrement if(ed->v.frame > startFrame || ed->v.frame < endFrame) { ed->v.frame = startFrame; break; } ed->v.frame--; if(ed->v.frame < endFrame) { pr_global_struct->cycle_wrapped = true; ed->v.frame = startFrame; } break; case OP_CWSTATE: // Cycle weapon state ed = PROG_TO_EDICT(pr_global_struct->self); ed->v.nextthink = pr_global_struct->time+HX_FRAME_TIME; ed->v.think = pr_xfunction-pr_functions; pr_global_struct->cycle_wrapped = false; startFrame = (int)a->_float; endFrame = (int)b->_float; if(startFrame <= endFrame) { // Increment if(ed->v.weaponframe < startFrame || ed->v.weaponframe > endFrame) { ed->v.weaponframe = startFrame; break; } ed->v.weaponframe++; if(ed->v.weaponframe > endFrame) { pr_global_struct->cycle_wrapped = true; ed->v.weaponframe = startFrame; } break; } // Decrement if(ed->v.weaponframe > startFrame || ed->v.weaponframe < endFrame) { ed->v.weaponframe = startFrame; break; } ed->v.weaponframe--; if(ed->v.weaponframe < endFrame) { pr_global_struct->cycle_wrapped = true; ed->v.weaponframe = startFrame; } break; case OP_THINKTIME: ed = PROG_TO_EDICT(a->edict); #ifdef PARANOID NUM_FOR_EDICT(ed); // Make sure it's in range #endif if(ed == (edict_t *)sv.edicts && sv.state == ss_active) { PR_RunError("assignment to world entity"); } ed->v.nextthink = pr_global_struct->time+b->_float; break; case OP_BITSET: // f (+) f b->_float = (int)b->_float | (int)a->_float; break; case OP_BITSETP: // e.f (+) f ptr = (eval_t *)((byte *)sv.edicts+b->_int); ptr->_float = (int)ptr->_float | (int)a->_float; break; case OP_BITCLR: // f (-) f b->_float = (int)b->_float & ~((int)a->_float); break; case OP_BITCLRP: // e.f (-) f ptr = (eval_t *)((byte *)sv.edicts+b->_int); ptr->_float = (int)ptr->_float & ~((int)a->_float); break; case OP_RAND0: val = rand()*(1.0/RAND_MAX);//(rand()&0x7fff)/((float)0x7fff); G_FLOAT(OFS_RETURN) = val; break; case OP_RAND1: val = rand()*(1.0/RAND_MAX)*a->_float; G_FLOAT(OFS_RETURN) = val; break; case OP_RAND2: if(a->_float < b->_float) { val = a->_float+(rand()*(1.0/RAND_MAX) *(b->_float-a->_float)); } else { val = b->_float+(rand()*(1.0/RAND_MAX) *(a->_float-b->_float)); } G_FLOAT(OFS_RETURN) = val; break; case OP_RANDV0: val = rand()*(1.0/RAND_MAX); G_FLOAT(OFS_RETURN+0) = val; val = rand()*(1.0/RAND_MAX); G_FLOAT(OFS_RETURN+1) = val; val = rand()*(1.0/RAND_MAX); G_FLOAT(OFS_RETURN+2) = val; break; case OP_RANDV1: val = rand()*(1.0/RAND_MAX)*a->vector[0]; G_FLOAT(OFS_RETURN+0) = val; val = rand()*(1.0/RAND_MAX)*a->vector[1]; G_FLOAT(OFS_RETURN+1) = val; val = rand()*(1.0/RAND_MAX)*a->vector[2]; G_FLOAT(OFS_RETURN+2) = val; break; case OP_RANDV2: for(i = 0; i < 3; i++) { if(a->vector[i] < b->vector[i]) { val = a->vector[i]+(rand()*(1.0/RAND_MAX) *(b->vector[i]-a->vector[i])); } else { val = b->vector[i]+(rand()*(1.0/RAND_MAX) *(a->vector[i]-b->vector[i])); } G_FLOAT(OFS_RETURN+i) = val; } break; case OP_SWITCH_F: case_type = SWITCH_F; switch_float = a->_float; s += st->b-1; // -1 to offset the s++ break; case OP_SWITCH_V: PR_RunError("switch v not done yet!"); break; case OP_SWITCH_S: PR_RunError("switch s not done yet!"); break; case OP_SWITCH_E: PR_RunError("switch e not done yet!"); break; case OP_SWITCH_FNC: PR_RunError("switch fnc not done yet!"); break; case OP_CASERANGE: if (case_type!=SWITCH_F) PR_RunError("caserange f****d!"); if((switch_float >= a->_float) && (switch_float <= b->_float)) { s += st->c-1; // -1 to offset the s++ } break; case OP_CASE: switch (case_type) { case SWITCH_F: if(switch_float == a->_float) { s += st->b-1; // -1 to offset the s++ } break; case SWITCH_V: case SWITCH_S: case SWITCH_E: case SWITCH_FNC: PR_RunError("case not done yet!"); break; default: PR_RunError("f****d case!"); } break; default: PR_RunError("Bad opcode %i", st->op); } } }
void QCBUILTIN PF_cl_gethostcachestring (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) {G_INT(OFS_RETURN) = 0;}
void QCBUILTIN PF_cl_getextresponse(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { //this does something weird G_INT(OFS_RETURN) = 0; }
void PR_ExecuteProgram (func_t fnum) { eval_t *ptr, *a, *b, *c; float *vecptr; dstatement_t *st; dfunction_t *f, *newf; edict_t *ed; int jump_ofs; int exitdepth; int profile, startprofile; /* switch/case support: */ int case_type = -1; float switch_float = 0; if (!fnum || fnum >= progs->numfunctions) { if (*sv_globals.self) { ED_Print(PROG_TO_EDICT(*sv_globals.self)); } Host_Error("%s: NULL function", __thisfunc__); } f = &pr_functions[fnum]; pr_trace = false; exitdepth = pr_depth; st = &pr_statements[EnterFunction(f)]; startprofile = profile = 0; while (1) { st++; /* next statement */ a = OPA; b = OPB; c = OPC; if (++profile > 100000) { pr_xstatement = st - pr_statements; PR_RunError("runaway loop error"); } if (pr_trace) { PrintStatement(st); } switch (st->op) { case OP_ADD_F: c->_float = a->_float + b->_float; break; case OP_ADD_V: c->vector[0] = a->vector[0] + b->vector[0]; c->vector[1] = a->vector[1] + b->vector[1]; c->vector[2] = a->vector[2] + b->vector[2]; break; case OP_SUB_F: c->_float = a->_float - b->_float; break; case OP_SUB_V: c->vector[0] = a->vector[0] - b->vector[0]; c->vector[1] = a->vector[1] - b->vector[1]; c->vector[2] = a->vector[2] - b->vector[2]; break; case OP_MUL_F: c->_float = a->_float * b->_float; break; case OP_MUL_V: c->_float = a->vector[0] * b->vector[0] + a->vector[1] * b->vector[1] + a->vector[2] * b->vector[2]; break; case OP_MUL_FV: c->vector[0] = a->_float * b->vector[0]; c->vector[1] = a->_float * b->vector[1]; c->vector[2] = a->_float * b->vector[2]; break; case OP_MUL_VF: c->vector[0] = b->_float * a->vector[0]; c->vector[1] = b->_float * a->vector[1]; c->vector[2] = b->_float * a->vector[2]; break; case OP_DIV_F: c->_float = a->_float / b->_float; break; case OP_BITAND: c->_float = (int)a->_float & (int)b->_float; break; case OP_BITOR: c->_float = (int)a->_float | (int)b->_float; break; case OP_GE: c->_float = a->_float >= b->_float; break; case OP_LE: c->_float = a->_float <= b->_float; break; case OP_GT: c->_float = a->_float > b->_float; break; case OP_LT: c->_float = a->_float < b->_float; break; case OP_AND: c->_float = a->_float && b->_float; break; case OP_OR: c->_float = a->_float || b->_float; break; case OP_NOT_F: c->_float = !a->_float; break; case OP_NOT_V: c->_float = !a->vector[0] && !a->vector[1] && !a->vector[2]; break; case OP_NOT_S: c->_float = !a->string || !*PR_GetString(a->string); break; case OP_NOT_FNC: c->_float = !a->function; break; case OP_NOT_ENT: c->_float = (PROG_TO_EDICT(a->edict) == sv.edicts); break; case OP_EQ_F: c->_float = a->_float == b->_float; break; case OP_EQ_V: c->_float = (a->vector[0] == b->vector[0]) && (a->vector[1] == b->vector[1]) && (a->vector[2] == b->vector[2]); break; case OP_EQ_S: c->_float = !strcmp(PR_GetString(a->string), PR_GetString(b->string)); break; case OP_EQ_E: c->_float = a->_int == b->_int; break; case OP_EQ_FNC: c->_float = a->function == b->function; break; case OP_NE_F: c->_float = a->_float != b->_float; break; case OP_NE_V: c->_float = (a->vector[0] != b->vector[0]) || (a->vector[1] != b->vector[1]) || (a->vector[2] != b->vector[2]); break; case OP_NE_S: c->_float = strcmp(PR_GetString(a->string), PR_GetString(b->string)); break; case OP_NE_E: c->_float = a->_int != b->_int; break; case OP_NE_FNC: c->_float = a->function != b->function; break; case OP_STORE_F: case OP_STORE_ENT: case OP_STORE_FLD: // integers case OP_STORE_S: case OP_STORE_FNC: // pointers b->_int = a->_int; break; case OP_STORE_V: b->vector[0] = a->vector[0]; b->vector[1] = a->vector[1]; b->vector[2] = a->vector[2]; break; case OP_STOREP_F: case OP_STOREP_ENT: case OP_STOREP_FLD: // integers case OP_STOREP_S: case OP_STOREP_FNC: // pointers ptr = (eval_t *)((byte *)sv.edicts + b->_int); ptr->_int = a->_int; break; case OP_STOREP_V: ptr = (eval_t *)((byte *)sv.edicts + b->_int); ptr->vector[0] = a->vector[0]; ptr->vector[1] = a->vector[1]; ptr->vector[2] = a->vector[2]; break; case OP_MULSTORE_F: // f *= f b->_float *= a->_float; break; case OP_MULSTORE_V: // v *= f b->vector[0] *= a->_float; b->vector[1] *= a->_float; b->vector[2] *= a->_float; break; case OP_MULSTOREP_F: // e.f *= f ptr = (eval_t *)((byte *)sv.edicts + b->_int); c->_float = (ptr->_float *= a->_float); break; case OP_MULSTOREP_V: // e.v *= f ptr = (eval_t *)((byte *)sv.edicts + b->_int); c->vector[0] = (ptr->vector[0] *= a->_float); c->vector[0] = (ptr->vector[1] *= a->_float); c->vector[0] = (ptr->vector[2] *= a->_float); break; case OP_DIVSTORE_F: // f /= f b->_float /= a->_float; break; case OP_DIVSTOREP_F: // e.f /= f ptr = (eval_t *)((byte *)sv.edicts + b->_int); c->_float = (ptr->_float /= a->_float); break; case OP_ADDSTORE_F: // f += f b->_float += a->_float; break; case OP_ADDSTORE_V: // v += v b->vector[0] += a->vector[0]; b->vector[1] += a->vector[1]; b->vector[2] += a->vector[2]; break; case OP_ADDSTOREP_F: // e.f += f ptr = (eval_t *)((byte *)sv.edicts + b->_int); c->_float = (ptr->_float += a->_float); break; case OP_ADDSTOREP_V: // e.v += v ptr = (eval_t *)((byte *)sv.edicts + b->_int); c->vector[0] = (ptr->vector[0] += a->vector[0]); c->vector[1] = (ptr->vector[1] += a->vector[1]); c->vector[2] = (ptr->vector[2] += a->vector[2]); break; case OP_SUBSTORE_F: // f -= f b->_float -= a->_float; break; case OP_SUBSTORE_V: // v -= v b->vector[0] -= a->vector[0]; b->vector[1] -= a->vector[1]; b->vector[2] -= a->vector[2]; break; case OP_SUBSTOREP_F: // e.f -= f ptr = (eval_t *)((byte *)sv.edicts + b->_int); c->_float = (ptr->_float -= a->_float); break; case OP_SUBSTOREP_V: // e.v -= v ptr = (eval_t *)((byte *)sv.edicts + b->_int); c->vector[0] = (ptr->vector[0] -= a->vector[0]); c->vector[1] = (ptr->vector[1] -= a->vector[1]); c->vector[2] = (ptr->vector[2] -= a->vector[2]); break; case OP_ADDRESS: ed = PROG_TO_EDICT(a->edict); #ifdef PARANOID NUM_FOR_EDICT(ed); // Make sure it's in range #endif if (ed == (edict_t *)sv.edicts && sv.state == ss_active) { pr_xstatement = st - pr_statements; PR_RunError("assignment to world entity"); } c->_int = (byte *)((int *)&ed->v + b->_int) - (byte *)sv.edicts; break; case OP_LOAD_F: case OP_LOAD_FLD: case OP_LOAD_ENT: case OP_LOAD_S: case OP_LOAD_FNC: ed = PROG_TO_EDICT(a->edict); #ifdef PARANOID NUM_FOR_EDICT(ed); // Make sure it's in range #endif ptr = (eval_t *)((int *)&ed->v + b->_int); c->_int = ptr->_int; break; case OP_LOAD_V: ed = PROG_TO_EDICT(a->edict); #ifdef PARANOID NUM_FOR_EDICT(ed); // Make sure it's in range #endif ptr = (eval_t *)((int *)&ed->v + b->_int); c->vector[0] = ptr->vector[0]; c->vector[1] = ptr->vector[1]; c->vector[2] = ptr->vector[2]; break; case OP_FETCH_GBL_F: case OP_FETCH_GBL_S: case OP_FETCH_GBL_E: case OP_FETCH_GBL_FNC: { int i = (int)b->_float; if (i < 0 || i > G_INT(st->a - 1)) { pr_xstatement = st - pr_statements; PR_RunError("array index out of bounds: %d", i); } ptr = (eval_t *)&pr_globals[st->a + i]; c->_int = ptr->_int; } break; case OP_FETCH_GBL_V: { int i = (int)b->_float; if (i < 0 || i > G_INT(st->a - 1)) { pr_xstatement = st - pr_statements; PR_RunError("array index out of bounds: %d", i); } ptr = (eval_t *)&pr_globals[st->a + (i * 3)]; c->vector[0] = ptr->vector[0]; c->vector[1] = ptr->vector[1]; c->vector[2] = ptr->vector[2]; } break; case OP_IFNOT: if (!a->_int) { /* Pa3PyX: a, b, and c used to be signed shorts for progs v6, * now they are signed ints. The problem is, they were used * as signed sometimes and as unsigned other times - most of * the time they were used as unsigned with an explicit cast * in PR_ExecuteProgram(). When we convert the old progs to * to the new format in PR_ConvertOldStmts(), we zero-extend * them instead of sign-extending them for that reason: if we * sign-extend them, most of the code will not work - we will * have negative array offsets in PR_ExecuteProgram(), among * other things. Note that they are cast to unsigned short * in PR_ConvertOldStmts() prior to assigning them to what is * now int. There are a few instances where these shorts are * used as signed as in the case below where negative offsets * are needed. Since we now have a zero-extended number in a, * b, and c, we must change it back to signed short, so that * when it is added with and assigned to an int, the result * ends up sign-extended and we get a proper negative offset, * if there is one. */ jump_ofs = st->b; if (is_progs_v6) jump_ofs = (signed short)jump_ofs; st += jump_ofs - 1; /* -1 to offset the st++ */ } break; case OP_IF: if (a->_int) { jump_ofs = st->b; if (is_progs_v6) jump_ofs = (signed short)jump_ofs; st += jump_ofs - 1; /* -1 to offset the st++ */ } break; case OP_GOTO: jump_ofs = st->a; if (is_progs_v6) jump_ofs = (signed short)jump_ofs; st += jump_ofs - 1; /* -1 to offset the st++ */ break; case OP_CALL8: case OP_CALL7: case OP_CALL6: case OP_CALL5: case OP_CALL4: case OP_CALL3: case OP_CALL2: // Copy second arg to shared space vecptr = G_VECTOR(OFS_PARM1); VectorCopy(c->vector, vecptr); case OP_CALL1: // Copy first arg to shared space vecptr = G_VECTOR(OFS_PARM0); VectorCopy(b->vector, vecptr); case OP_CALL0: pr_xfunction->profile += profile - startprofile; startprofile = profile; pr_xstatement = st - pr_statements; pr_argc = st->op - OP_CALL0; if (!a->function) { PR_RunError("NULL function"); } newf = &pr_functions[a->function]; if (newf->first_statement < 0) { // Built-in function int i = -newf->first_statement; if (i >= pr_numbuiltins) { PR_RunError("Bad builtin call number %d", i); } pr_builtins[i](); break; } // Normal function st = &pr_statements[EnterFunction(newf)]; break; case OP_DONE: case OP_RETURN: { float *retptr = &pr_globals[OFS_RETURN]; float *valptr = &pr_globals[st->a]; pr_xfunction->profile += profile - startprofile; startprofile = profile; pr_xstatement = st - pr_statements; *retptr++ = *valptr++; *retptr++ = *valptr++; *retptr = *valptr; st = &pr_statements[LeaveFunction()]; if (pr_depth == exitdepth) { // Done return; } } break; case OP_STATE: ed = PROG_TO_EDICT(*sv_globals.self); /* Id 1.07 changes #ifdef FPS_20 ed->v.nextthink = *sv_globals.time + 0.05; #else ed->v.nextthink = *sv_globals.time + 0.1; #endif */ ed->v.nextthink = *sv_globals.time + HX_FRAME_TIME; ed->v.frame = a->_float; ed->v.think = b->function; break; case OP_CSTATE: // Cycle state { int startFrame, endFrame; ed = PROG_TO_EDICT(*sv_globals.self); ed->v.nextthink = *sv_globals.time + HX_FRAME_TIME; ed->v.think = pr_xfunction - pr_functions; *sv_globals.cycle_wrapped = false; startFrame = (int)a->_float; endFrame = (int)b->_float; if (startFrame <= endFrame) { // Increment if (ed->v.frame < startFrame || ed->v.frame > endFrame) { ed->v.frame = startFrame; } else { ed->v.frame++; if (ed->v.frame > endFrame) { *sv_globals.cycle_wrapped = true; ed->v.frame = startFrame; } } } else { // Decrement if (ed->v.frame > startFrame || ed->v.frame < endFrame) { ed->v.frame = startFrame; } else { ed->v.frame--; if (ed->v.frame < endFrame) { *sv_globals.cycle_wrapped = true; ed->v.frame = startFrame; } } } } break; case OP_CWSTATE: // Cycle weapon state { int startFrame, endFrame; ed = PROG_TO_EDICT(*sv_globals.self); ed->v.nextthink = *sv_globals.time + HX_FRAME_TIME; ed->v.think = pr_xfunction - pr_functions; *sv_globals.cycle_wrapped = false; startFrame = (int)a->_float; endFrame = (int)b->_float; if (startFrame <= endFrame) { // Increment if (ed->v.weaponframe < startFrame || ed->v.weaponframe > endFrame) { ed->v.weaponframe = startFrame; } else { ed->v.weaponframe++; if (ed->v.weaponframe > endFrame) { *sv_globals.cycle_wrapped = true; ed->v.weaponframe = startFrame; } } } else { // Decrement if (ed->v.weaponframe > startFrame || ed->v.weaponframe < endFrame) { ed->v.weaponframe = startFrame; } else { ed->v.weaponframe--; if (ed->v.weaponframe < endFrame) { *sv_globals.cycle_wrapped = true; ed->v.weaponframe = startFrame; } } } } break; case OP_THINKTIME: ed = PROG_TO_EDICT(a->edict); #ifdef PARANOID NUM_FOR_EDICT(ed); // Make sure it's in range #endif if (ed == (edict_t *)sv.edicts && sv.state == ss_active) { pr_xstatement = st - pr_statements; PR_RunError("assignment to world entity"); } ed->v.nextthink = *sv_globals.time + b->_float; break; case OP_BITSET: // f (+) f b->_float = (int)b->_float | (int)a->_float; break; case OP_BITSETP: // e.f (+) f ptr = (eval_t *)((byte *)sv.edicts + b->_int); ptr->_float = (int)ptr->_float | (int)a->_float; break; case OP_BITCLR: // f (-) f b->_float = (int)b->_float & ~((int)a->_float); break; case OP_BITCLRP: // e.f (-) f ptr = (eval_t *)((byte *)sv.edicts + b->_int); ptr->_float = (int)ptr->_float & ~((int)a->_float); break; case OP_RAND0: { float val; val = rand() * (1.0 / RAND_MAX); G_FLOAT(OFS_RETURN) = val; } break; case OP_RAND1: { float val; val = rand() * (1.0 / RAND_MAX) * a->_float; G_FLOAT(OFS_RETURN) = val; } break; case OP_RAND2: { float val; if (a->_float < b->_float) { val = a->_float + (rand() * (1.0 / RAND_MAX) * (b->_float - a->_float)); } else { val = b->_float + (rand() * (1.0 / RAND_MAX) * (a->_float - b->_float)); } G_FLOAT(OFS_RETURN) = val; } break; case OP_RANDV0: { float val; float *retptr = &G_FLOAT(OFS_RETURN); val = rand() * (1.0 / RAND_MAX); *retptr++ = val; val = rand() * (1.0 / RAND_MAX); *retptr++ = val; val = rand() * (1.0 / RAND_MAX); *retptr = val; } break; case OP_RANDV1: { float val; float *retptr = &G_FLOAT(OFS_RETURN); val = rand() * (1.0 / RAND_MAX) * a->vector[0]; *retptr++ = val; val = rand() * (1.0 / RAND_MAX) * a->vector[1]; *retptr++ = val; val = rand() * (1.0 / RAND_MAX) * a->vector[2]; *retptr = val; } break; case OP_RANDV2: { float val; int i; float *retptr = &G_FLOAT(OFS_RETURN); for (i = 0; i < 3; i++) { if (a->vector[i] < b->vector[i]) { val = a->vector[i] + (rand() * (1.0 / RAND_MAX) * (b->vector[i] - a->vector[i])); } else { val = b->vector[i] + (rand() * (1.0 / RAND_MAX) * (a->vector[i] - b->vector[i])); } *retptr++ = val; } } break; case OP_SWITCH_F: case_type = SWITCH_F; switch_float = a->_float; jump_ofs = st->b; if (is_progs_v6) jump_ofs = (signed short)jump_ofs; st += jump_ofs - 1; /* -1 to offset the st++ */ break; case OP_SWITCH_V: case OP_SWITCH_S: case OP_SWITCH_E: case OP_SWITCH_FNC: pr_xstatement = st - pr_statements; PR_RunError("%s not done yet!", pr_opnames[st->op]); break; case OP_CASERANGE: if (case_type != SWITCH_F) { pr_xstatement = st - pr_statements; PR_RunError("caserange f****d!"); } if ((switch_float >= a->_float) && (switch_float <= b->_float)) { jump_ofs = st->c; if (is_progs_v6) jump_ofs = (signed short)jump_ofs; st += jump_ofs - 1; /* -1 to offset the st++ */ } break; case OP_CASE: switch (case_type) { case SWITCH_F: if (switch_float == a->_float) { jump_ofs = st->b; if (is_progs_v6) jump_ofs = (signed short)jump_ofs; st += jump_ofs - 1; /* -1 to offset the st++ */ } break; case SWITCH_V: case SWITCH_S: case SWITCH_E: case SWITCH_FNC: pr_xstatement = st - pr_statements; PR_RunError("OP_CASE for %s not done yet!", pr_opnames[case_type + OP_SWITCH_F - SWITCH_F]); break; default: pr_xstatement = st - pr_statements; PR_RunError("f****d case!"); } break; default: pr_xstatement = st - pr_statements; PR_RunError("Bad opcode %i", st->op); } } /* end of while(1) loop */ }
void WriteData (int crc) { def_t *def; ddef_t *dd; dprograms_t progs; char tname[1024]; int h; unsigned int i; int size; for (def = pr.def_head.next ; def ; def = def->next) { if ((def->type->type == ev_field) && def->constant) { dd = &fields[numfielddefs]; numfielddefs++; dd->type = def->type->aux_type->type == ev_int ? ev_float : def->type->aux_type->type; if (def->save == 0) { strcpy(tname, def->name); strcat(tname, "__"); dd->s_name = CopyString(tname, 0); } else dd->s_name = CopyString (def->name, 0); dd->ofs = G_INT(def->ofs); } else if (pr_optimize_constant_names && def->constant && (def->type->type != ev_function)) { num_constant_names += strlen(def->name) + 1; num_constant_names += sizeof(ddef_t); continue; } else if (pr_optimize_unreferenced && pr_global_refs[def->ofs] <= 0) { if (!(def->type->type != ev_function)) { num_unreferenced += 1; continue; } } else if (pr_optimize_unreferenced && def->type->type == ev_vector) { if (pr_global_refs[def->ofs] + pr_global_refs[def->ofs + 1] + pr_global_refs[def->ofs +1] == 3) { num_unreferenced += 3; def = def->next; // def_x def = def->next; // def_y def = def->next; // def_z continue; } } dd = &globals[numglobaldefs]; dd->type = def->type->type == ev_int ? ev_float : def->type->type; if (def->save && ( dd->type != ev_field || def->constant != 1)) dd->type |= DEF_SAVEGLOBAL; if (def->name) { if (pr_optimize_locals && (def->scope || !(STRCMP(def->name, "IMMEDIATE")))) { num_locals_saved += strlen(def->name); dd->s_name = 0; } else dd->s_name = CopyString (def->name, 0); } dd->ofs = def->ofs; numglobaldefs++; } strofs = (strofs+3)&~3; if (strofs > INT_MAX) PR_ParseWarning(122, "strofs exceeds INT_MAX by %i", strofs - INT_MAX); if (numstatements > INT_MAX) PR_ParseWarning(123, "numstatements exceeds INT_MAX by %i", numstatements - INT_MAX); if (numfunctions > SHRT_MAX) PR_ParseWarning(124, "numfunctions exceeds SHRT_MAX by %i", numfunctions - SHRT_MAX); if (numglobaldefs > SHRT_MAX) PR_ParseWarning(125, "numglobaldefs exceeds SHRT_MAX by %i", numglobaldefs - SHRT_MAX); if (numfielddefs > SHRT_MAX) PR_ParseWarning(126, "numfielddefs exceeds SHRT_MAX by %i", numfielddefs - SHRT_MAX); if (numpr_globals > SHRT_MAX) PR_ParseWarning(127, "numpr_globals exceeds SHRT_MAX by %i", numpr_globals - SHRT_MAX); if (crc != NQ_PROGHEADER_CRC && crc != QW_PROGHEADER_CRC) PR_ParseWarning(208, "System defs do match internal crcs."); if (summary) { summary_print("----------- Summary -----------\n"); i = I_FloatTime() - StartTime; summary_print (" %02i:%02i elapsed time\n", (i / 60) % 59, i % 59); summary_print ("%6i strofs (MAX: %6i)\n", strofs, MAX_STRINGS ); summary_print ("%6i numstatements (MAX: %6i)\n", numstatements, MAX_STATEMENTS); summary_print ("%6i numfunctions (MAX: %6i)\n", numfunctions, SHRT_MAX); summary_print ("%6i numglobaldefs (MAX: %6i)\n", numglobaldefs, SHRT_MAX); summary_print ("%6i numfielddefs (MAX: %6i)\n", numfielddefs, SHRT_MAX); summary_print ("%6i numpr_globals (MAX: %6i)\n", numpr_globals, SHRT_MAX); } h = SafeOpenWrite (destfile); SafeWrite (h, &progs, sizeof(progs)); progs.ofs_strings = lseek (h, 0, SEEK_CUR); progs.numstrings = strofs; SafeWrite (h, strings, strofs); progs.ofs_statements = lseek (h, 0, SEEK_CUR); progs.numstatements = numstatements; for (i=0 ; i<numstatements ; i++) { statements[i].op = LittleShort(statements[i].op); statements[i].a = LittleShort(statements[i].a); statements[i].b = LittleShort(statements[i].b); statements[i].c = LittleShort(statements[i].c); } SafeWrite (h, statements, numstatements*sizeof(dstatement_t)); progs.ofs_functions = lseek (h, 0, SEEK_CUR); progs.numfunctions = numfunctions; for (i=0 ; i<numfunctions ; i++) { functions[i].first_statement = LittleLong (functions[i].first_statement); functions[i].parm_start = LittleLong (functions[i].parm_start); functions[i].s_name = LittleLong (functions[i].s_name < 0 || functions[i].s_name > strofs ? 0 : functions[i].s_name); functions[i].s_file = LittleLong (functions[i].s_file < 0 || functions[i].s_file > strofs ? 0 : functions[i].s_file); functions[i].numparms = LittleLong (functions[i].numparms > MAX_PARMS ? MAX_PARMS : functions[i].numparms); functions[i].locals = LittleLong (functions[i].locals); } SafeWrite (h, functions, numfunctions*sizeof(dfunction_t)); progs.ofs_globaldefs = lseek (h, 0, SEEK_CUR); progs.numglobaldefs = numglobaldefs; for (i=0 ; i<numglobaldefs ; i++) { globals[i].type = LittleShort (globals[i].type); globals[i].ofs = LittleShort (globals[i].ofs); globals[i].s_name = LittleLong (globals[i].s_name); } SafeWrite (h, globals, numglobaldefs*sizeof(ddef_t)); progs.ofs_fielddefs = lseek (h, 0, SEEK_CUR); progs.numfielddefs = numfielddefs; for (i=0 ; i<numfielddefs ; i++) { fields[i].type = LittleShort (fields[i].type); fields[i].ofs = LittleShort (fields[i].ofs); fields[i].s_name = LittleLong (fields[i].s_name < 0 || fields[i].s_name > strofs ? 0: fields[i].s_name); } SafeWrite (h, fields, numfielddefs*sizeof(ddef_t)); progs.ofs_globals = lseek (h, 0, SEEK_CUR); progs.numglobals = numpr_globals; for (i=0 ; i<numpr_globals ; i++) ((int *)pr_globals)[i] = LittleLong (((int *)pr_globals)[i]); SafeWrite (h, pr_globals, numpr_globals*4); i = (int)lseek(h, 0, SEEK_CUR); if (summary) summary_print ("%6i TOTAL SIZE\n", i); size = (i+16)&(~15); progs.entityfields = pr.size_fields; progs.version = PROG_VERSION; progs.crc = crc; if (summary) { summary_print("%6i Progheader CRC ", crc); if (crc == NQ_PROGHEADER_CRC) summary_print("( Quake )\n"); else if (crc == QW_PROGHEADER_CRC) summary_print("(Quake World)\n"); else summary_print("( UNKNOWN )\n"); } // byte swap the header and write it out for (i=0 ; i<sizeof(progs)/4 ; i++) ((int *)&progs)[i] = LittleLong ( ((int *)&progs)[i] ); lseek (h, 0, SEEK_SET); SafeWrite (h, &progs, sizeof(progs)); // look for progs if ((def = PR_GetDef(&type_entity, "progs", NULL, false, 0, 0))) { lseek(h, progs.ofs_globals + 4 * def->ofs, SEEK_SET); i = - (size + 112); SafeWrite (h, &i, 4); } for (def = pr.def_head.next ; def ; def = def->next) { if (def->type->arraysize) { lseek(h, progs.ofs_globals + 4 * def->ofs, SEEK_SET); i = (-(size + 112)) + progs.ofs_globals + 4 * (def->arraystart); //printf("filled in %s with %i\n", def->name, def->arraystart); SafeWrite (h, &i, 4); } } if (summary) { summary_print ("%6i precache_sounds(MAX: %6i)\n", numsounds, MAX_SOUNDS); summary_print ("%6i precache_models(MAX: %6i)\n", nummodels, MAX_MODELS); } close (h); if (summary) { if (pr_optimize_eliminate_temps || pr_optimize_shorten_ifs || pr_optimize_nonvec_parms || pr_optimize_constant_names || pr_optimize_defs || pr_optimize_hash_strings || pr_optimize_locals || pr_optimize_function_names || pr_optimize_filenames || pr_optimize_unreferenced || pr_optimize_logicops || pr_optimize_recycle || pr_optimize_constant_arithmetic) { summary_print("----------- Optimization Summary -----------\n"); if (pr_optimize_eliminate_temps) summary_print("%d stores shortened\n", num_stores_shortened); if (pr_optimize_shorten_ifs) summary_print("%d ifs shortened\n", num_ifs_shortened); if (pr_optimize_nonvec_parms) summary_print("%d non-vector parms\n", num_nonvec_parms); if (pr_optimize_constant_names) summary_print("%d bytes of constant defs/names eliminated\n", num_constant_names); if (pr_optimize_defs) summary_print("%d duplicate defs eliminated\n", num_defs); if (pr_optimize_hash_strings) summary_print("%d bytes of duplicate strings eliminated\n", num_strings); if (pr_optimize_locals) summary_print("%d bytes of immediate and local names eliminated\n", num_locals_saved); if (pr_optimize_function_names) summary_print("%d bytes of function names eliminated\n", num_funcs_saved); if (pr_optimize_filenames) summary_print("%d bytes of filenames eliminated\n", num_files_saved); if (pr_optimize_unreferenced) summary_print("%d unreferenced global defs eliminated\n", num_unreferenced); if (pr_optimize_logicops) summary_print("%d logic jumps added\n", num_logic_jumps); if (pr_optimize_recycle) summary_print("%d temporary globals recycled\n", num_recycled); if (pr_optimize_constant_arithmetic) summary_print("%d constant arithmetic statements eliminated\n", num_constant_ops_saved); } } }
void WriteData (int crc) { def_t *def; ddef_t *dd; dprograms_t progs; FILE *h; int i; for (def = pr.def_head.next ; def ; def = def->next) { if (def->type->type == ev_function) { // df = &functions[numfunctions]; // numfunctions++; } else if (def->type->type == ev_field) { dd = &fields[numfielddefs]; numfielddefs++; dd->type = def->type->aux_type->type; #ifdef HASH_DEF dd->s_name=def->s_name; #else dd->s_name = CopyString (def->name); #endif dd->ofs = G_INT(def->ofs); } dd = &globals[numglobaldefs]; numglobaldefs++; dd->type = def->type->type; if ( !def->initialized && def->type->type != ev_function && def->type->type != ev_field && def->scope == NULL) dd->type |= DEF_SAVEGLOBGAL; #ifdef HASH_DEF dd->s_name=def->s_name; #else dd->s_name = CopyString (def->name); #endif dd->ofs = def->ofs; } // PrintStrings (); // PrintFunctions (); // PrintFields (); // PrintGlobals (); strofs = (strofs+3)&~3; printf ("%6i strofs\n", strofs); printf ("%6i numstatements\n", numstatements); printf ("%6i numfunctions\n", numfunctions); printf ("%6i numglobaldefs\n", numglobaldefs); printf ("%6i numfielddefs\n", numfielddefs); printf ("%6i numpr_globals\n", numpr_globals); h = SafeOpenWrite (destfile); SafeWrite (h, &progs, sizeof(progs)); progs.ofs_strings = ftell (h); progs.numstrings = strofs; SafeWrite (h, strings, strofs); progs.ofs_statements = ftell (h); progs.numstatements = numstatements; for (i=0 ; i<numstatements ; i++) { statements[i].op = LittleShort(statements[i].op); statements[i].a = LittleShort(statements[i].a); statements[i].b = LittleShort(statements[i].b); statements[i].c = LittleShort(statements[i].c); } SafeWrite (h, statements, numstatements*sizeof(dstatement_t)); progs.ofs_functions = ftell (h); progs.numfunctions = numfunctions; for (i=0 ; i<numfunctions ; i++) { functions[i].first_statement = LittleLong (functions[i].first_statement); functions[i].parm_start = LittleLong (functions[i].parm_start); functions[i].s_name = LittleLong (functions[i].s_name); functions[i].s_file = LittleLong (functions[i].s_file); functions[i].numparms = LittleLong (functions[i].numparms); functions[i].locals = LittleLong (functions[i].locals); } SafeWrite (h, functions, numfunctions*sizeof(dfunction_t)); progs.ofs_globaldefs = ftell (h); progs.numglobaldefs = numglobaldefs; for (i=0 ; i<numglobaldefs ; i++) { globals[i].type = LittleShort (globals[i].type); globals[i].ofs = LittleShort (globals[i].ofs); globals[i].s_name = LittleLong (globals[i].s_name); } SafeWrite (h, globals, numglobaldefs*sizeof(ddef_t)); progs.ofs_fielddefs = ftell (h); progs.numfielddefs = numfielddefs; for (i=0 ; i<numfielddefs ; i++) { fields[i].type = LittleShort (fields[i].type); fields[i].ofs = LittleShort (fields[i].ofs); fields[i].s_name = LittleLong (fields[i].s_name); } SafeWrite (h, fields, numfielddefs*sizeof(ddef_t)); progs.ofs_globals = ftell (h); progs.numglobals = numpr_globals; for (i=0 ; i<numpr_globals ; i++) ((int *)pr_globals)[i] = LittleLong (((int *)pr_globals)[i]); SafeWrite (h, pr_globals, numpr_globals*4); printf ("%6i TOTAL SIZE\n", (int)ftell (h)); progs.entityfields = pr.size_fields; progs.version = PROG_VERSION; progs.crc = crc; // byte swap the header and write it out for (i=0 ; i<sizeof(progs)/4 ; i++) ((int *)&progs)[i] = LittleLong ( ((int *)&progs)[i] ); fseek (h, 0, SEEK_SET); SafeWrite (h, &progs, sizeof(progs)); fclose (h); }
/* ============= ED_ParseEval Can parse either fields or globals returns false if error ============= */ static qboolean ED_ParseEpair (void *base, ddef_t *key, const char *s) { int i; char string[128]; ddef_t *def; char *v, *w; void *d; dfunction_t *func; d = (void *)((int *)base + key->ofs); switch (key->type & ~DEF_SAVEGLOBAL) { case ev_string: *(string_t *)d = ED_NewString(s); break; case ev_float: *(float *)d = atof (s); break; case ev_vector: strcpy (string, s); v = string; w = string; for (i = 0; i < 3; i++) { while (*v && *v != ' ') v++; *v = 0; ((float *)d)[i] = atof (w); w = v = v+1; } break; case ev_entity: *(int *)d = EDICT_TO_PROG(EDICT_NUM(atoi (s))); break; case ev_field: def = ED_FindField (s); if (!def) { //johnfitz -- HACK -- suppress error becuase fog/sky fields might not be mentioned in defs.qc if (strncmp(s, "sky", 3) && strcmp(s, "fog")) Con_DPrintf ("Can't find field %s\n", s); return false; } *(int *)d = G_INT(def->ofs); break; case ev_function: func = ED_FindFunction (s); if (!func) { Con_Printf ("Can't find function %s\n", s); return false; } *(func_t *)d = func - pr_functions; break; default: break; } return true; }
static void WriteData (int crc) { def_t *def; ddef_t *dd; dstatement_v6_t *stmt6; ddef_v6_t *globals6, *fields6; qboolean v6able; dprograms_t progs; FILE *h; int i, localName; localName = (hcc_OptimizeNameTable) ? CopyString("LCL+") : 0; /* was "LOCAL+" in old HCC from the "H2_UTILS" package */ if (hcc_OptimizeStringHeap) printf ("compacting string heap\n"); for (def = pr.def_head.next; def; def = def->next) { if (def->type->type == ev_field) { dd = &fields[numfielddefs]; numfielddefs++; dd->type = def->type->aux_type->type; dd->s_name = (hcc_OptimizeStringHeap) ? CopyString(def->name) : /* name gets copied below : */ strofs; dd->ofs = G_INT(def->ofs); } dd = &globals[numglobaldefs]; numglobaldefs++; dd->type = def->type->type; if (!def->initialized && def->type->type != ev_function && def->type->type != ev_field && def->scope == NULL) { /* STR_ is a special case string constant */ if (strncmp(def->name,"STR_", 4) != 0 || hcc_Compat_STR_SAVEGLOBL) dd->type |= DEF_SAVEGLOBAL; } if (hcc_OptimizeNameTable && (def->scope != NULL || (!(dd->type & DEF_SAVEGLOBAL) && def->type->type < ev_field))) { dd->s_name = localName; } else { dd->s_name = CopyString(def->name); } dd->ofs = def->ofs; } // PrintStrings (); // PrintFunctions (); // PrintFields (); // PrintGlobals (); strofs = (strofs + 3) & ~3; printf("object file %s\n", destfile); printf(" registers: %10d / %10d (%10d bytes)\n", numpr_globals, MAX_REGS, numpr_globals*(int)sizeof(float)); printf(" statements: %10d / %10d (%10d bytes)\n", numstatements, MAX_STATEMENTS, numstatements*(int)sizeof(dstatement_t)); printf(" functions: %10d / %10d (%10d bytes)\n", numfunctions, MAX_FUNCTIONS, numfunctions*(int)sizeof(dfunction_t)); printf(" global defs: %10d / %10d (%10d bytes)\n", numglobaldefs, MAX_GLOBALS, numglobaldefs*(int)sizeof(ddef_t)); printf(" field defs: %10d / %10d (%10d bytes)\n", numfielddefs, MAX_FIELDS, numfielddefs*(int)sizeof(ddef_t)); printf(" string heap: %10d / %10d\n", strofs, MAX_STRINGS); printf(" entity fields: %10d\n", pr.size_fields); stmt6 = NULL; globals6 = NULL; fields6 = NULL; if (numpr_globals < 65536) v6able = true; else { v6able = false; if (hcc_version_req != PROG_VERSION_V7) printf("Too many registers: version 6 output not possible.\n"); } if (v6able && hcc_version_req != PROG_VERSION_V7) { v6able = (stmt6 = PR_GenV6Stmts(statements, numstatements)) != NULL; if ( v6able) v6able = (globals6 = PR_GenV6Defs(globals, numglobaldefs)) != NULL; if ( v6able) v6able = (fields6 = PR_GenV6Defs(fields, numfielddefs)) != NULL; if (!v6able) { if (stmt6) free (stmt6); if (globals6) free (globals6); } } if (!v6able) { if (hcc_version_req == PROG_VERSION_V6) COM_Error("Can not output version 6 progs: v6 limitations not complied with."); hcc_version_req = PROG_VERSION_V7; } else { if (hcc_version_req == -1) hcc_version_req = PROG_VERSION_V6; } h = SafeOpenWrite (destfile); SafeWrite (h, &progs, sizeof(progs)); progs.ofs_strings = ftell (h); progs.numstrings = strofs; SafeWrite (h, strings, strofs); progs.ofs_statements = ftell (h); progs.numstatements = numstatements; if (hcc_version_req == PROG_VERSION_V7) { for (i = 0; i < numstatements; i++) { statements[i].op = LittleShort(statements[i].op); statements[i].a = LittleLong(statements[i].a); statements[i].b = LittleLong(statements[i].b); statements[i].c = LittleLong(statements[i].c); } SafeWrite (h, statements, numstatements*sizeof(dstatement_t)); } else { SafeWrite (h, stmt6, numstatements*sizeof(dstatement_v6_t)); free (stmt6); } progs.ofs_functions = ftell (h); progs.numfunctions = numfunctions; for (i = 0; i < numfunctions; i++) { functions[i].first_statement = LittleLong (functions[i].first_statement); functions[i].parm_start = LittleLong (functions[i].parm_start); functions[i].s_name = LittleLong (functions[i].s_name); functions[i].s_file = LittleLong (functions[i].s_file); functions[i].numparms = LittleLong (functions[i].numparms); functions[i].locals = LittleLong (functions[i].locals); } SafeWrite (h, functions, numfunctions*sizeof(dfunction_t)); progs.ofs_globaldefs = ftell (h); progs.numglobaldefs = numglobaldefs; if (hcc_version_req == PROG_VERSION_V7) { for (i = 0; i < numglobaldefs; i++) { globals[i].type = LittleShort (globals[i].type); globals[i].ofs = LittleLong (globals[i].ofs); globals[i].s_name = LittleLong (globals[i].s_name); } SafeWrite (h, globals, numglobaldefs*sizeof(ddef_t)); } else { SafeWrite (h, globals6, numglobaldefs*sizeof(ddef_v6_t)); free (globals6); } progs.ofs_fielddefs = ftell (h); progs.numfielddefs = numfielddefs; if (hcc_version_req == PROG_VERSION_V7) { for (i = 0; i < numfielddefs; i++) { fields[i].type = LittleShort (fields[i].type); fields[i].ofs = LittleLong (fields[i].ofs); fields[i].s_name = LittleLong (fields[i].s_name); } SafeWrite (h, fields, numfielddefs*sizeof(ddef_t)); } else { SafeWrite (h, fields6, numfielddefs*sizeof(ddef_v6_t)); free (fields6); } progs.ofs_globals = ftell (h); progs.numglobals = numpr_globals; for (i = 0; i < numpr_globals; i++) ((int *)pr_globals)[i] = LittleLong (((int *)pr_globals)[i]); SafeWrite (h, pr_globals, numpr_globals*4); printf(" total size: %10d bytes\n", (int)ftell(h)); printf(" progs version: %10d\n", hcc_version_req); progs.entityfields = pr.size_fields; progs.version = hcc_version_req; progs.crc = crc; // byte swap the header and write it out for (i = 0; i < (int)sizeof(progs)/4; i++) ((int *)&progs)[i] = LittleLong ( ((int *)&progs)[i] ); fseek (h, 0, SEEK_SET); SafeWrite (h, &progs, sizeof(progs)); fclose (h); }
float SV_ChatFunc(const char *func) //parse a condition/function { globalvars_t *pr_globals; float result; int noted = false; const char *s, *os; char namebuf[64]; func_t f; int parm; while (*func <= ' ') func++; if (*func == '!') { noted = true; func++; } s = COM_ParseToken(func, NULL); if (*com_token == '(') {//open bracket //find correct close parm = 1; for (s = func+1; ; s++) { if (!*s) Sys_Error("No close bracket"); if (*s == ')') { parm--; if (!parm)break; } if (*s == '(') parm++; } func = strchr(func, '('); s=COM_ParseToken(s+1, NULL); if (!strncmp(com_token, "&&", 2)) result = SV_ChatFunc(func+1) && SV_ChatFunc(s); else if (!strncmp(com_token, "||", 2)) result = SV_ChatFunc(func+1) || SV_ChatFunc(s); else result = SV_ChatFunc(func+1); } else { strcpy(namebuf, com_token); //get first word while (*s <= ' ') s++; if (*s == '(') //if followed by brackets { s++; pr_globals = PR_globals(svprogfuncs, PR_CURRENT); parm = OFS_PARM0; while((s=COM_ParseToken(os = s, NULL))) { if (*com_token == ')') break; if (*com_token == ',') continue; if (com_tokentype == TTP_STRING) G_INT(parm) = PR_NewString(svprogfuncs, com_token); else if (!strcmp(com_token, "ent")) G_INT(parm) = EDICT_TO_PROG(svprogfuncs, host_client->chat.edict); else G_FLOAT(parm) = SV_ChatFunc(os); parm+=OFS_PARM1-OFS_PARM0; } f = PR_FindFunction(svprogfuncs, namebuf, PR_CURRENT); if (f) { PR_ExecuteProgram(svprogfuncs, f); } else Con_Printf("Failed to find function %s\n", namebuf); pr_globals = PR_globals(svprogfuncs, PR_CURRENT); result = G_FLOAT(OFS_RETURN); } else { //comparision operators if (!strncmp(s, "==", 2)) result = (SV_ChatGetValue(namebuf) == SV_ChatFunc(s+2)); else if (!strncmp(s, ">=", 2)) result = (SV_ChatGetValue(namebuf) >= SV_ChatFunc(s+2)); else if (!strncmp(s, "<=", 2)) result = (SV_ChatGetValue(namebuf) <= SV_ChatFunc(s+2)); else if (!strncmp(s, "!=", 2)) result = (SV_ChatGetValue(namebuf) != SV_ChatFunc(s+2)); else if (!strncmp(s, ">", 1)) result = (SV_ChatGetValue(namebuf) >= SV_ChatFunc(s+2)); else if (!strncmp(s, "<", 1)) result = (SV_ChatGetValue(namebuf) <= SV_ChatFunc(s+2)); //asignment operators else if (!strncmp(s, "=", 1)) result = (SV_ChatSetValue(namebuf, SV_ChatFunc(s+1))); else if (!strncmp(s, "+=", 2)) result = (SV_ChatSetValue(namebuf, SV_ChatGetValue(namebuf)+SV_ChatFunc(s+2))); else if (!strncmp(s, "-=", 2)) result = (SV_ChatSetValue(namebuf, SV_ChatGetValue(namebuf)-SV_ChatFunc(s+2))); else if (!strncmp(s, "*=", 2)) result = (SV_ChatSetValue(namebuf, SV_ChatGetValue(namebuf)*SV_ChatFunc(s+2))); else if (!strncmp(s, "/=", 2)) result = (SV_ChatSetValue(namebuf, SV_ChatGetValue(namebuf)/SV_ChatFunc(s+2))); else if (!strncmp(s, "|=", 2)) result = (SV_ChatSetValue(namebuf, (int)SV_ChatGetValue(namebuf)|(int)SV_ChatFunc(s+2))); else if (!strncmp(s, "&=", 2)) result = (SV_ChatSetValue(namebuf, (int)SV_ChatGetValue(namebuf)&(int)SV_ChatFunc(s+2))); //mathematical operators else if (!strncmp(s, "+", 1)) result = ( SV_ChatGetValue(namebuf)+SV_ChatFunc(s+1)); else if (!strncmp(s, "-", 1)) result = (SV_ChatGetValue(namebuf)-SV_ChatFunc(s+1)); else if (!strncmp(s, "*", 1)) result = (SV_ChatGetValue(namebuf)*SV_ChatFunc(s+1)); else if (!strncmp(s, "/", 1)) result = (SV_ChatGetValue(namebuf)/SV_ChatFunc(s+1)); else if (!strncmp(s, "|", 1)) result = ((int)SV_ChatGetValue(namebuf)|(int)SV_ChatFunc(s+1)); else if (!strncmp(s, "&", 1)) result = ((int)SV_ChatGetValue(namebuf)&(int)SV_ChatFunc(s+1)); //operatorless else result = SV_ChatGetValue(namebuf); } } if (noted) result = !result; return result; }