Example #1
0
void QCBUILTIN PF_cl_GetBindMap (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
	int bm[2];
	Key_GetBindMap(bm);
	G_VECTOR(OFS_RETURN)[0] = bm[0];
	G_VECTOR(OFS_RETURN)[1] = bm[1];
	G_VECTOR(OFS_RETURN)[2] = 0;
}
void SV_ParseMultiEffect (sizebuf_t *sb)
{
	int	idx, count;
	byte	effect;
	vec3_t	orig, vel;

	MultiEffectIdCount = 0;
	effect = G_FLOAT(OFS_PARM0);
	switch (effect)
	{
	case CE_HWRAVENPOWER:
		// need to set aside 3 effect ids
		MSG_WriteByte (sb, svc_multieffect);
		MSG_WriteByte (sb, effect);

		VectorCopy(G_VECTOR(OFS_PARM1), orig);
		MSG_WriteCoord(sb, orig[0]);
		MSG_WriteCoord(sb, orig[1]);
		MSG_WriteCoord(sb, orig[2]);
		VectorCopy(G_VECTOR(OFS_PARM2), vel);
		MSG_WriteCoord(sb, vel[0]);
		MSG_WriteCoord(sb, vel[1]);
		MSG_WriteCoord(sb, vel[2]);
		for (count = 0 ; count < 3 ; count++)
		{
			for (idx = 0 ; idx < MAX_EFFECTS ; idx++)
			{
				if (!sv.Effects[idx].type || 
						(sv.Effects[idx].expire_time && sv.Effects[idx].expire_time <= sv.time))
					break;
			}
			if (idx >= MAX_EFFECTS)
			{
				PR_RunError ("MAX_EFFECTS reached");
				return;
			}
			MSG_WriteByte(sb, idx);
			sv.Effects[idx].type = CE_HWRAVENPOWER;
			VectorCopy(orig, sv.Effects[idx].ef.Missile.origin);
			VectorCopy(vel, sv.Effects[idx].ef.Missile.velocity);
			sv.Effects[idx].expire_time = sv.time + 10;
			MultiEffectIds[count] = idx;
		}
		break;

	default:
		PR_RunError ("%s: bad type", __thisfunc__);
	}
}
Example #3
0
// #493 vector(string name) gecko_get_texture_extent
void QCBUILTIN PF_cs_media_get_texture_extent (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
	const char *shader = PR_GetStringOfs(prinst, OFS_PARM0);
	float *ret = G_VECTOR(OFS_RETURN);
	int sx = 0, sy = 0;
	float aspect = 0;
	cin_t *cin;
	cin = R_ShaderFindCinematic(shader);
	if (cin)
		Media_Send_GetSize(cin, &sx, &sy, &aspect);
	ret[0] = sx;
	ret[1] = sy;
	ret[2] = aspect;
}
Example #4
0
//a bit pointless really
void QCBUILTIN PF_cl_getresolution (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
	float mode = G_FLOAT(OFS_PARM0);
//	qboolean fixedmodes = (prinst->callargc >= 2)?!G_FLOAT(OFS_PARM1):false; //if true, we should return sane-sized modes suitable for a window... or the mod could make up its own, but whatever.
	float *ret = G_VECTOR(OFS_RETURN);
	int w, h;

	w=h=0;
	if (mode == -1)
	{
		int bpp, rate;
		Sys_GetDesktopParameters(&w, &h, &bpp, &rate);
	}
	else
		M_Vid_GetMode(mode, &w, &h);

	ret[0] = w;
	ret[1] = h;
	ret[2] = (w&&h)?1:0;
}
Example #5
0
// All changes need to be in SV_SendEffect(), SV_ParseEffect(),
// SV_SaveEffects(), SV_LoadEffects(), CL_ParseEffect()
void SV_ParseEffect (sizebuf_t *sb)
{
	int		idx;
	byte		effect;

	effect = G_FLOAT(OFS_PARM0);

	for (idx = 0 ; idx < MAX_EFFECTS ; idx++)
	{
		if (!sv.Effects[idx].type || 
				(sv.Effects[idx].expire_time && sv.Effects[idx].expire_time <= sv.time))
			break;
	}

	if (idx >= MAX_EFFECTS)
	{
		PR_RunError ("MAX_EFFECTS reached");
		return;
	}

//	Con_Printf("Effect #%d\n", idx);

	memset(&sv.Effects[idx], 0, sizeof(struct EffectT));

	sv.Effects[idx].type = effect;
	G_FLOAT(OFS_RETURN) = idx;

	switch (effect)
	{
	case CE_RAIN:
		VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[idx].ef.Rain.min_org);
		VectorCopy(G_VECTOR(OFS_PARM2), sv.Effects[idx].ef.Rain.max_org);
		VectorCopy(G_VECTOR(OFS_PARM3), sv.Effects[idx].ef.Rain.e_size);
		VectorCopy(G_VECTOR(OFS_PARM4), sv.Effects[idx].ef.Rain.dir);
		sv.Effects[idx].ef.Rain.color = G_FLOAT(OFS_PARM5);
		sv.Effects[idx].ef.Rain.count = G_FLOAT(OFS_PARM6);
		sv.Effects[idx].ef.Rain.wait = G_FLOAT(OFS_PARM7);

		sv.Effects[idx].ef.Rain.next_time = 0;
		break;

	case CE_SNOW:
		VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[idx].ef.Rain.min_org);
		VectorCopy(G_VECTOR(OFS_PARM2), sv.Effects[idx].ef.Rain.max_org);
		sv.Effects[idx].ef.Rain.flags = G_FLOAT(OFS_PARM3);
		VectorCopy(G_VECTOR(OFS_PARM4), sv.Effects[idx].ef.Rain.dir);
		sv.Effects[idx].ef.Rain.count = G_FLOAT(OFS_PARM5);
		//sv.Effects[idx].Rain.veer = G_FLOAT(OFS_PARM6);
		//sv.Effects[idx].Rain.wait = 0.10;
		sv.Effects[idx].ef.Rain.next_time = 0;
		break;

	case CE_FOUNTAIN:
		VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[idx].ef.Fountain.pos);
		VectorCopy(G_VECTOR(OFS_PARM2), sv.Effects[idx].ef.Fountain.angle);
		VectorCopy(G_VECTOR(OFS_PARM3), sv.Effects[idx].ef.Fountain.movedir);
		sv.Effects[idx].ef.Fountain.color = G_FLOAT(OFS_PARM4);
		sv.Effects[idx].ef.Fountain.cnt = G_FLOAT(OFS_PARM5);
		break;

	case CE_QUAKE:
		VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[idx].ef.Quake.origin);
		sv.Effects[idx].ef.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:
		VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[idx].ef.Smoke.origin);
		VectorCopy(G_VECTOR(OFS_PARM2), sv.Effects[idx].ef.Smoke.velocity);
		sv.Effects[idx].ef.Smoke.framelength = G_FLOAT(OFS_PARM3);
		sv.Effects[idx].ef.Smoke.frame = 0;
		sv.Effects[idx].expire_time = sv.time + 1;
		break;

	case CE_ACID_MUZZFL:
	case CE_FLAMESTREAM:
	case CE_FLAMEWALL:
	case CE_FLAMEWALL2:
	case CE_ONFIRE:
	/* mission pack */
		VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[idx].ef.Smoke.origin);
		VectorCopy(G_VECTOR(OFS_PARM2), sv.Effects[idx].ef.Smoke.velocity);
		sv.Effects[idx].ef.Smoke.framelength = 0.05;
		sv.Effects[idx].ef.Smoke.frame = G_FLOAT(OFS_PARM3);
		sv.Effects[idx].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_LG_EXPLOSION:
	case CE_FLOOR_EXPLOSION:
	case CE_FLOOR_EXPLOSION3:
	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[idx].ef.Smoke.origin);
		sv.Effects[idx].expire_time = sv.time + 1;
		break;

	case CE_WHITE_FLASH:
	case CE_BLUE_FLASH:
	case CE_SM_BLUE_FLASH:
	case CE_RED_FLASH:
		VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[idx].ef.Flash.origin);
		sv.Effects[idx].expire_time = sv.time + 1;
		break;

	case CE_RIDER_DEATH:
		VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[idx].ef.RD.origin);
		break;

	case CE_GRAVITYWELL:
		VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[idx].ef.RD.origin);
		sv.Effects[idx].ef.RD.color = G_FLOAT(OFS_PARM2);
		sv.Effects[idx].ef.RD.lifetime = G_FLOAT(OFS_PARM3);
		break;

	case CE_TELEPORTERPUFFS:
		VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[idx].ef.Teleporter.origin);
		sv.Effects[idx].expire_time = sv.time + 1;
		break;

	case CE_TELEPORTERBODY:
		VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[idx].ef.Teleporter.origin);
		VectorCopy(G_VECTOR(OFS_PARM2), sv.Effects[idx].ef.Teleporter.velocity[0]);
		sv.Effects[idx].ef.Teleporter.skinnum = G_FLOAT(OFS_PARM3);
		sv.Effects[idx].expire_time = sv.time + 1;
		break;

	case CE_BONESHARD:
	case CE_BONESHRAPNEL:
		VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[idx].ef.Missile.origin);
		VectorCopy(G_VECTOR(OFS_PARM2), sv.Effects[idx].ef.Missile.velocity);
		VectorCopy(G_VECTOR(OFS_PARM3), sv.Effects[idx].ef.Missile.angle);
		VectorCopy(G_VECTOR(OFS_PARM2), sv.Effects[idx].ef.Missile.avelocity);
		sv.Effects[idx].expire_time = sv.time + 10;
		break;

	case CE_CHUNK:
		VectorCopy(G_VECTOR(OFS_PARM1), sv.Effects[idx].ef.Chunk.origin);
		sv.Effects[idx].ef.Chunk.type = G_FLOAT(OFS_PARM2);
		VectorCopy(G_VECTOR(OFS_PARM3), sv.Effects[idx].ef.Chunk.srcVel);
		sv.Effects[idx].ef.Chunk.numChunks = G_FLOAT(OFS_PARM4);
		sv.Effects[idx].expire_time = sv.time + 3;
		break;

	default:
		PR_RunError ("%s: bad type", __thisfunc__);
	}

	SV_SendEffect(sb, idx);
}
Example #6
0
// 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);
}
Example #7
0
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);
	}
}

}
Example #8
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 */
}