Beispiel #1
0
static void
bi_Menu_GetIndex (progs_t *pr)
{
	if (menu) {
		R_INT (pr) = menu->cur_item;
	} else {
		R_INT (pr) = -1;
	}
}
Beispiel #2
0
int
Menu_KeyEvent (knum_t key, short unicode, qboolean down)
{
	menu_item_t *item;
	int         ret;

	if (!menu)
		return 0;
	if (menu->keyevent) {
		run_menu_pre ();
		PR_RESET_PARAMS (&menu_pr_state);
		P_INT (&menu_pr_state, 0) = key;
		P_INT (&menu_pr_state, 1) = unicode;
		P_INT (&menu_pr_state, 2) = down;
		PR_ExecuteProgram (&menu_pr_state, menu->keyevent);
		ret = R_INT (&menu_pr_state);
		run_menu_post ();
		if (ret)
			return 1;
	} else if (menu->items && menu->items[menu->cur_item]->func
			   && menu->items[menu->cur_item]->allkeys) {
		run_menu_pre ();
		PR_PushFrame (&menu_pr_state);
		item = menu->items[menu->cur_item];
		PR_RESET_PARAMS (&menu_pr_state);
		P_STRING (&menu_pr_state, 0) = PR_SetTempString (&menu_pr_state,
														 item->text);
		P_INT (&menu_pr_state, 1) = key;
		PR_ExecuteProgram (&menu_pr_state, item->func);
		PR_PopFrame (&menu_pr_state);
		ret = R_INT (&menu_pr_state);
		run_menu_post ();
		if (ret)
			return 1;
	}
	if (!menu || !menu->items)
		return 0;
	switch (key) {
		case QFK_DOWN:
		case QFM_WHEEL_DOWN:
			bi_Menu_Next (&menu_pr_state);
			return 1;
		case QFK_UP:
		case QFM_WHEEL_UP:
			bi_Menu_Prev (&menu_pr_state);
			return 1;
		case QFK_RETURN:
		case QFM_BUTTON1:
			bi_Menu_Enter (&menu_pr_state);
			return 1;
		default:
			return 0;
	}
}
Beispiel #3
0
int
call_progs_main (progs_t *pr, int argc, const char **argv)
{
	int         i;
	dfunction_t *dfunc;
	func_t      progs_main = 0;
	string_t   *pr_argv;

	if ((dfunc = PR_FindFunction (pr, "main"))) {
		progs_main = dfunc - pr->pr_functions;
	} else {
		PR_Undefined (pr, "function", "main");
		return -1;
	}

	PR_PushFrame (pr);
	pr_argv = PR_Zone_Malloc (pr, (argc + 1) * 4);
	for (i = 0; i < argc; i++)
		pr_argv[i] = PR_SetTempString (pr, argv[1 + i]);
	pr_argv[i] = 0;
	PR_RESET_PARAMS (pr);
	P_INT (pr, 0) = argc;
	P_POINTER (pr, 1) = PR_SetPointer (pr, pr_argv);
	PR_ExecuteProgram (pr, progs_main);
	PR_PopFrame (pr);
	PR_Zone_Free (pr, pr_argv);
	return R_INT (pr);
}
Beispiel #4
0
/*
	PF_padstr

	string(string st, float len) padstr
*/
static void
PF_padstr (progs_t *pr)
{
	const char *st;
	size_t      i, padlen, givenlen;
	char       *padding;

	st = P_GSTRING (pr, 0);
	padlen = (unsigned int) P_FLOAT (pr, 1);
	givenlen = strlen (st);

	// Check if nothing should be done due to error or no need to..
	if ( (padlen <= givenlen)) {			// nothing should be done
		R_INT (pr) = P_STRING (pr, 0);		// return given string
		return;
	}
	// ok, lets pad it!
	padlen -= givenlen;
	padding = alloca (padlen + 1);

	for (i = 0; i < padlen; i++)
		padding[i] = ' ';
	padding[i] = '\0';

	R_STRING (pr) = PR_CatStrings (pr, st, padding);
}
Beispiel #5
0
static void
quit_f (void)
{
	int         ret;

	if (confirm_quit->int_val && menu_quit) {
		run_menu_pre ();
		PR_ExecuteProgram (&menu_pr_state, menu_quit);
		ret = R_INT (&menu_pr_state);
		run_menu_post ();
		if (!ret)
			return;
	}
	bi_Menu_Quit (&menu_pr_state);
}
Beispiel #6
0
int
main (int argc, char **argv)
{
	dfunction_t *dfunc;
	func_t      main_func = 0;
	const char *name = "progs.dat";
	string_t   *pr_argv;
	int         pr_argc = 1, i;

	i = parse_options (argc, argv);
	argc -= i;
	argv += i;

	init_qf ();

	if (argc > 0)
		name = argv[0];

	if (!load_progs (name))
		Sys_Error ("couldn't load %s", name);

	PR_PushFrame (&pr);
	if (argc > 2)
		pr_argc = argc - 1;
	pr_argv = PR_Zone_Malloc (&pr, (pr_argc + 1) * 4);
	pr_argv[0] = PR_SetTempString (&pr, name);
	for (i = 1; i < pr_argc; i++)
		pr_argv[i] = PR_SetTempString (&pr, argv[1 + i]);
	pr_argv[i] = 0;

	if ((dfunc = PR_FindFunction (&pr, ".main"))
		|| (dfunc = PR_FindFunction (&pr, "main")))
		main_func = dfunc - pr.pr_functions;
	else
		PR_Undefined (&pr, "function", "main");
	PR_RESET_PARAMS (&pr);
	P_INT (&pr, 0) = pr_argc;
	P_POINTER (&pr, 1) = PR_SetPointer (&pr, pr_argv);
	PR_ExecuteProgram (&pr, main_func);
	PR_PopFrame (&pr);
	if (options.flote)
		return R_FLOAT (&pr);
	return R_INT (&pr);
}
Beispiel #7
0
/*
	PR_ExecuteProgram

	The interpretation main loop
*/
VISIBLE void
PR_ExecuteProgram (progs_t * pr, func_t fnum)
{
	int         exitdepth, profile, startprofile;
	pr_uint_t   pointer;
	dstatement_t *st;
	edict_t    *ed;
	pr_type_t  *ptr;
	pr_type_t   old_val = {0}, *watch = 0;

	// make a stack frame
	exitdepth = pr->pr_depth;
	startprofile = profile = 0;

	Sys_PushSignalHook (signal_hook, pr);

	if (!PR_CallFunction (pr, fnum)) {
		// called a builtin instead of progs code
		Sys_PopSignalHook ();
		return;
	}
	st = pr->pr_statements + pr->pr_xstatement;

	if (pr->watch) {
		watch = pr->watch;
		old_val = *watch;
	}

	while (1) {
		pr_type_t  *op_a, *op_b, *op_c;

		st++;
		++pr->pr_xstatement;
		if (pr->pr_xstatement != st - pr->pr_statements)
			PR_RunError (pr, "internal error");
		if (++profile > 1000000 && !pr->no_exec_limit) {
			PR_RunError (pr, "runaway loop error");
		}

		op_a = pr->pr_globals + st->a;
		op_b = pr->pr_globals + st->b;
		op_c = pr->pr_globals + st->c;

		if (pr->pr_trace)
			PR_PrintStatement (pr, st, 1);

		switch (st->op) {
			case OP_ADD_F:
				OPC.float_var = OPA.float_var + OPB.float_var;
				break;
			case OP_ADD_V:
				VectorAdd (OPA.vector_var, OPB.vector_var, OPC.vector_var);
				break;
			case OP_ADD_Q:
				QuatAdd (OPA.quat_var, OPB.quat_var, OPC.quat_var);
				break;
			case OP_ADD_S:
				OPC.string_var = PR_CatStrings (pr,
												PR_GetString (pr,
															  OPA.string_var),
												PR_GetString (pr,
															  OPB.string_var));
				break;
			case OP_SUB_F:
				OPC.float_var = OPA.float_var - OPB.float_var;
				break;
			case OP_SUB_V:
				VectorSubtract (OPA.vector_var, OPB.vector_var, OPC.vector_var);
				break;
			case OP_SUB_Q:
				QuatSubtract (OPA.quat_var, OPB.quat_var, OPC.quat_var);
				break;
			case OP_MUL_F:
				OPC.float_var = OPA.float_var * OPB.float_var;
				break;
			case OP_MUL_V:
				OPC.float_var = DotProduct (OPA.vector_var, OPB.vector_var);
				break;
			case OP_MUL_FV:
				{
					// avoid issues with the likes of x = x.x * x;
					// makes for faster code, too
					float       scale = OPA.float_var;
					VectorScale (OPB.vector_var, scale, OPC.vector_var);
				}
				break;
			case OP_MUL_VF:
				{
					// avoid issues with the likes of x = x * x.x;
					// makes for faster code, too
					float       scale = OPB.float_var;
					VectorScale (OPA.vector_var, scale, OPC.vector_var);
				}
				break;
			case OP_MUL_Q:
				QuatMult (OPA.quat_var, OPB.quat_var, OPC.quat_var);
				break;
			case OP_MUL_QV:
				QuatMultVec (OPA.quat_var, OPB.vector_var, OPC.vector_var);
				break;
			case OP_MUL_FQ:
				{
					// avoid issues with the likes of x = x.s * x;
					// makes for faster code, too
					float       scale = OPA.float_var;
					QuatScale (OPB.quat_var, scale, OPC.quat_var);
				}
				break;
			case OP_MUL_QF:
				{
					// avoid issues with the likes of x = x * x.s;
					// makes for faster code, too
					float       scale = OPB.float_var;
					QuatScale (OPA.quat_var, scale, OPC.quat_var);
				}
				break;
			case OP_CONJ_Q:
				QuatConj (OPA.quat_var, OPC.quat_var);
				break;
			case OP_DIV_F:
				OPC.float_var = OPA.float_var / OPB.float_var;
				break;
			case OP_BITAND:
				OPC.float_var = (int) OPA.float_var & (int) OPB.float_var;
				break;
			case OP_BITOR:
				OPC.float_var = (int) OPA.float_var | (int) OPB.float_var;
				break;
			case OP_BITXOR_F:
				OPC.float_var = (int) OPA.float_var ^ (int) OPB.float_var;
				break;
			case OP_BITNOT_F:
				OPC.float_var = ~ (int) OPA.float_var;
				break;
			case OP_SHL_F:
				OPC.float_var = (int) OPA.float_var << (int) OPB.float_var;
				break;
			case OP_SHR_F:
				OPC.float_var = (int) OPA.float_var >> (int) OPB.float_var;
				break;
			case OP_SHL_I:
				OPC.integer_var = OPA.integer_var << OPB.integer_var;
				break;
			case OP_SHR_I:
				OPC.integer_var = OPA.integer_var >> OPB.integer_var;
				break;
			case OP_SHR_U:
				OPC.uinteger_var = OPA.uinteger_var >> OPB.integer_var;
				break;
			case OP_GE_F:
				OPC.float_var = OPA.float_var >= OPB.float_var;
				break;
			case OP_LE_F:
				OPC.float_var = OPA.float_var <= OPB.float_var;
				break;
			case OP_GT_F:
				OPC.float_var = OPA.float_var > OPB.float_var;
				break;
			case OP_LT_F:
				OPC.float_var = OPA.float_var < OPB.float_var;
				break;
			case OP_AND:	// OPA and OPB have to be float for -0.0
				OPC.integer_var = FNZ (OPA) && FNZ (OPB);
				break;
			case OP_OR:		// OPA and OPB have to be float for -0.0
				OPC.integer_var = FNZ (OPA) || FNZ (OPB);
				break;
			case OP_NOT_F:
				OPC.integer_var = !FNZ (OPA);
				break;
			case OP_NOT_V:
				OPC.integer_var = VectorIsZero (OPA.vector_var);
				break;
			case OP_NOT_Q:
				OPC.integer_var = QuatIsZero (OPA.quat_var);
				break;
			case OP_NOT_S:
				OPC.integer_var = !OPA.string_var ||
					!*PR_GetString (pr, OPA.string_var);
				break;
			case OP_NOT_FN:
				OPC.integer_var = !OPA.func_var;
				break;
			case OP_NOT_ENT:
				OPC.integer_var = !OPA.entity_var;
				break;
			case OP_EQ_F:
				OPC.integer_var = OPA.float_var == OPB.float_var;
				break;
			case OP_EQ_V:
				OPC.integer_var = VectorCompare (OPA.vector_var,
												 OPB.vector_var);
				break;
			case OP_EQ_Q:
				OPC.integer_var = QuatCompare (OPA.quat_var, OPB.quat_var);
				break;
			case OP_EQ_E:
				OPC.integer_var = OPA.integer_var == OPB.integer_var;
				break;
			case OP_EQ_FN:
				OPC.integer_var = OPA.func_var == OPB.func_var;
				break;
			case OP_NE_F:
				OPC.integer_var = OPA.float_var != OPB.float_var;
				break;
			case OP_NE_V:
				OPC.integer_var = !VectorCompare (OPA.vector_var,
												  OPB.vector_var);
				break;
			case OP_NE_Q:
				OPC.integer_var = !QuatCompare (OPA.quat_var, OPB.quat_var);
				break;
			case OP_LE_S:
			case OP_GE_S:
			case OP_LT_S:
			case OP_GT_S:
			case OP_NE_S:
			case OP_EQ_S:
				{
					int cmp = strcmp (PR_GetString (pr, OPA.string_var),
									  PR_GetString (pr, OPB.string_var));
					switch (st->op) {
						case OP_LE_S: cmp = (cmp <= 0); break;
						case OP_GE_S: cmp = (cmp >= 0); break;
						case OP_LT_S: cmp = (cmp < 0); break;
						case OP_GT_S: cmp = (cmp > 0); break;
						case OP_NE_S: break;
						case OP_EQ_S: cmp = !cmp; break;
						default:      break;
					}
					OPC.integer_var = cmp;
				}
				break;
			case OP_NE_E:
				OPC.integer_var = OPA.integer_var != OPB.integer_var;
				break;
			case OP_NE_FN:
				OPC.integer_var = OPA.func_var != OPB.func_var;
				break;

			// ==================
			case OP_STORE_F:
			case OP_STORE_ENT:
			case OP_STORE_FLD:			// integers
			case OP_STORE_S:
			case OP_STORE_FN:			// pointers
			case OP_STORE_I:
			case OP_STORE_P:
				OPB.integer_var = OPA.integer_var;
				break;
			case OP_STORE_V:
				VectorCopy (OPA.vector_var, OPB.vector_var);
				break;
			case OP_STORE_Q:
				QuatCopy (OPA.quat_var, OPB.quat_var);
				break;

			case OP_STOREP_F:
			case OP_STOREP_ENT:
			case OP_STOREP_FLD:		// integers
			case OP_STOREP_S:
			case OP_STOREP_FN:		// pointers
			case OP_STOREP_I:
			case OP_STOREP_P:
				pointer = OPB.integer_var;
				if (pr_boundscheck->int_val) {
					PR_BoundsCheck (pr, pointer, ev_integer);
				}
				ptr = pr->pr_globals + pointer;
				ptr->integer_var = OPA.integer_var;
				break;
			case OP_STOREP_V:
				pointer = OPB.integer_var;
				if (pr_boundscheck->int_val) {
					PR_BoundsCheck (pr, pointer, ev_vector);
				}
				ptr = pr->pr_globals + pointer;
				VectorCopy (OPA.vector_var, ptr->vector_var);
				break;
			case OP_STOREP_Q:
				pointer = OPB.integer_var;
				if (pr_boundscheck->int_val) {
					PR_BoundsCheck (pr, pointer, ev_quat);
				}
				ptr = pr->pr_globals + pointer;
				QuatCopy (OPA.quat_var, ptr->quat_var);
				break;

			case OP_ADDRESS:
				if (pr_boundscheck->int_val) {
					if (OPA.entity_var < 0
						|| OPA.entity_var >= pr->pr_edictareasize)
						PR_RunError (pr, "Progs attempted to address an out "
									 "of bounds edict");
					if (OPA.entity_var == 0 && pr->null_bad)
						PR_RunError (pr, "assignment to world entity");
					if (OPB.uinteger_var >= pr->progs->entityfields)
						PR_RunError (pr, "Progs attempted to address an "
									 "invalid field in an edict");
				}
				ed = PROG_TO_EDICT (pr, OPA.entity_var);
				OPC.integer_var = &ed->v[OPB.integer_var] - pr->pr_globals;
				break;
			case OP_ADDRESS_VOID:
			case OP_ADDRESS_F:
			case OP_ADDRESS_V:
			case OP_ADDRESS_Q:
			case OP_ADDRESS_S:
			case OP_ADDRESS_ENT:
			case OP_ADDRESS_FLD:
			case OP_ADDRESS_FN:
			case OP_ADDRESS_I:
			case OP_ADDRESS_P:
				OPC.integer_var = st->a;
				break;

			case OP_LOAD_F:
			case OP_LOAD_FLD:
			case OP_LOAD_ENT:
			case OP_LOAD_S:
			case OP_LOAD_FN:
			case OP_LOAD_I:
			case OP_LOAD_P:
				if (pr_boundscheck->int_val) {
					if (OPA.entity_var < 0
						|| OPA.entity_var >= pr->pr_edictareasize)
						PR_RunError (pr, "Progs attempted to read an out of "
									 "bounds edict number");
					if (OPB.uinteger_var >= pr->progs->entityfields)
						PR_RunError (pr, "Progs attempted to read an invalid "
									 "field in an edict");
				}
				ed = PROG_TO_EDICT (pr, OPA.entity_var);
				OPC.integer_var = ed->v[OPB.integer_var].integer_var;
				break;
			case OP_LOAD_V:
				if (pr_boundscheck->int_val) {
					if (OPA.entity_var < 0
						|| OPA.entity_var >= pr->pr_edictareasize)
						PR_RunError (pr, "Progs attempted to read an out of "
									 "bounds edict number");
					if (OPB.uinteger_var + 2 >= pr->progs->entityfields)
						PR_RunError (pr, "Progs attempted to read an invalid "
									 "field in an edict");
				}
				ed = PROG_TO_EDICT (pr, OPA.entity_var);
				memcpy (&OPC, &ed->v[OPB.integer_var], 3 * sizeof (OPC));
				break;
			case OP_LOAD_Q:
				if (pr_boundscheck->int_val) {
					if (OPA.entity_var < 0
						|| OPA.entity_var >= pr->pr_edictareasize)
						PR_RunError (pr, "Progs attempted to read an out of "
									 "bounds edict number");
					if (OPB.uinteger_var + 3 >= pr->progs->entityfields)
						PR_RunError (pr, "Progs attempted to read an invalid "
									 "field in an edict");
				}
				ed = PROG_TO_EDICT (pr, OPA.entity_var);
				memcpy (&OPC, &ed->v[OPB.integer_var], 3 * sizeof (OPC));
				break;

			case OP_LOADB_F:
			case OP_LOADB_S:
			case OP_LOADB_ENT:
			case OP_LOADB_FLD:
			case OP_LOADB_FN:
			case OP_LOADB_I:
			case OP_LOADB_P:
				pointer = OPA.integer_var + OPB.integer_var;
				if (pr_boundscheck->int_val) {
					PR_BoundsCheck (pr, pointer, ev_integer);
				}
				ptr = pr->pr_globals + pointer;
				OPC.integer_var = ptr->integer_var;
				break;
			case OP_LOADB_V:
				pointer = OPA.integer_var + OPB.integer_var;
				if (pr_boundscheck->int_val) {
					PR_BoundsCheck (pr, pointer, ev_vector);
				}
				ptr = pr->pr_globals + pointer;
				VectorCopy (ptr->vector_var, OPC.vector_var);
				break;
			case OP_LOADB_Q:
				pointer = OPA.integer_var + OPB.integer_var;
				if (pr_boundscheck->int_val) {
					PR_BoundsCheck (pr, pointer, ev_quat);
				}
				ptr = pr->pr_globals + pointer;
				QuatCopy (ptr->quat_var, OPC.quat_var);
				break;

			case OP_LOADBI_F:
			case OP_LOADBI_S:
			case OP_LOADBI_ENT:
			case OP_LOADBI_FLD:
			case OP_LOADBI_FN:
			case OP_LOADBI_I:
			case OP_LOADBI_P:
				pointer = OPA.integer_var + (short) st->b;
				if (pr_boundscheck->int_val) {
					PR_BoundsCheck (pr, pointer, ev_integer);
				}
				ptr = pr->pr_globals + pointer;
				OPC.integer_var = ptr->integer_var;
				break;
			case OP_LOADBI_V:
				pointer = OPA.integer_var + (short) st->b;
				if (pr_boundscheck->int_val) {
					PR_BoundsCheck (pr, pointer, ev_vector);
				}
				ptr = pr->pr_globals + pointer;
				VectorCopy (ptr->vector_var, OPC.vector_var);
				break;
			case OP_LOADBI_Q:
				pointer = OPA.integer_var + (short) st->b;
				if (pr_boundscheck->int_val) {
					PR_BoundsCheck (pr, pointer, ev_quat);
				}
				ptr = pr->pr_globals + pointer;
				QuatCopy (ptr->quat_var, OPC.quat_var);
				break;

			case OP_LEA:
				pointer = OPA.integer_var + OPB.integer_var;
				OPC.integer_var = pointer;
				break;

			case OP_LEAI:
				pointer = OPA.integer_var + (short) st->b;
				OPC.integer_var = pointer;
				break;

			case OP_STOREB_F:
			case OP_STOREB_S:
			case OP_STOREB_ENT:
			case OP_STOREB_FLD:
			case OP_STOREB_FN:
			case OP_STOREB_I:
			case OP_STOREB_P:
				pointer = OPB.integer_var + OPC.integer_var;
				if (pr_boundscheck->int_val) {
					PR_BoundsCheck (pr, pointer, ev_integer);
				}
				ptr = pr->pr_globals + pointer;
				ptr->integer_var = OPA.integer_var;
				break;
			case OP_STOREB_V:
				pointer = OPB.integer_var + OPC.integer_var;
				if (pr_boundscheck->int_val) {
					PR_BoundsCheck (pr, pointer, ev_vector);
				}
				ptr = pr->pr_globals + pointer;
				VectorCopy (OPA.vector_var, ptr->vector_var);
				break;
			case OP_STOREB_Q:
				pointer = OPB.integer_var + OPC.integer_var;
				if (pr_boundscheck->int_val) {
					PR_BoundsCheck (pr, pointer, ev_quat);
				}
				ptr = pr->pr_globals + pointer;
				QuatCopy (OPA.quat_var, ptr->quat_var);
				break;

			case OP_STOREBI_F:
			case OP_STOREBI_S:
			case OP_STOREBI_ENT:
			case OP_STOREBI_FLD:
			case OP_STOREBI_FN:
			case OP_STOREBI_I:
			case OP_STOREBI_P:
				pointer = OPB.integer_var + (short) st->c;
				if (pr_boundscheck->int_val) {
					PR_BoundsCheck (pr, pointer, ev_integer);
				}
				ptr = pr->pr_globals + pointer;
				ptr->integer_var = OPA.integer_var;
				break;
			case OP_STOREBI_V:
				pointer = OPB.integer_var + (short) st->c;
				if (pr_boundscheck->int_val) {
					PR_BoundsCheck (pr, pointer, ev_vector);
				}
				ptr = pr->pr_globals + pointer;
				VectorCopy (OPA.vector_var, ptr->vector_var);
				break;
			case OP_STOREBI_Q:
				pointer = OPB.integer_var + (short) st->c;
				if (pr_boundscheck->int_val) {
					PR_BoundsCheck (pr, pointer, ev_quat);
				}
				ptr = pr->pr_globals + pointer;
				QuatCopy (OPA.quat_var, ptr->quat_var);
				break;

			// ==================
			case OP_IFNOT:
				if (!OPA.integer_var) {
					pr->pr_xstatement += (short)st->b - 1;	// offset the st++
					st = pr->pr_statements + pr->pr_xstatement;
				}
				break;
			case OP_IF:
				if (OPA.integer_var) {
					pr->pr_xstatement += (short)st->b - 1;	// offset the st++
					st = pr->pr_statements + pr->pr_xstatement;
				}
				break;
			case OP_IFBE:
				if (OPA.integer_var <= 0) {
					pr->pr_xstatement += (short)st->b - 1;	// offset the st++
					st = pr->pr_statements + pr->pr_xstatement;
				}
				break;
			case OP_IFB:
				if (OPA.integer_var < 0) {
					pr->pr_xstatement += (short)st->b - 1;	// offset the st++
					st = pr->pr_statements + pr->pr_xstatement;
				}
				break;
			case OP_IFAE:
				if (OPA.integer_var >= 0) {
					pr->pr_xstatement += (short)st->b - 1;	// offset the st++
					st = pr->pr_statements + pr->pr_xstatement;
				}
				break;
			case OP_IFA:
				if (OPA.integer_var > 0) {
					pr->pr_xstatement += (short)st->b - 1;	// offset the st++
					st = pr->pr_statements + pr->pr_xstatement;
				}
				break;
			case OP_GOTO:
				pr->pr_xstatement += (short)st->a - 1;		// offset the st++
				st = pr->pr_statements + pr->pr_xstatement;
				break;
			case OP_JUMP:
				if (pr_boundscheck->int_val
					&& (OPA.uinteger_var >= pr->progs->numstatements)) {
					PR_RunError (pr, "Invalid jump destination");
				}
				pr->pr_xstatement = OPA.uinteger_var - 1;	// offset the st++
				st = pr->pr_statements + pr->pr_xstatement;
				break;
			case OP_JUMPB:
				pointer = st->a + OPB.integer_var;
				if (pr_boundscheck->int_val) {
					PR_BoundsCheck (pr, pointer, ev_integer);
				}
				ptr = pr->pr_globals + pointer;
				pointer = ptr->integer_var;
				if (pr_boundscheck->int_val
					&& (pointer >= pr->progs->numstatements)) {
					PR_RunError (pr, "Invalid jump destination");
				}
				pr->pr_xstatement = pointer - 1;			// offset the st++
				st = pr->pr_statements + pr->pr_xstatement;
				break;

			case OP_RCALL2:
			case OP_RCALL3:
			case OP_RCALL4:
			case OP_RCALL5:
			case OP_RCALL6:
			case OP_RCALL7:
			case OP_RCALL8:
				pr->pr_params[1] = &OPC;
				goto op_rcall;
			case OP_RCALL1:
				pr->pr_params[1] = pr->pr_real_params[1];
op_rcall:
				pr->pr_params[0] = &OPB;
				pr->pr_argc = st->op - OP_RCALL1 + 1;
				goto op_call;
			case OP_CALL0:
			case OP_CALL1:
			case OP_CALL2:
			case OP_CALL3:
			case OP_CALL4:
			case OP_CALL5:
			case OP_CALL6:
			case OP_CALL7:
			case OP_CALL8:
				PR_RESET_PARAMS (pr);
				pr->pr_argc = st->op - OP_CALL0;
op_call:
				pr->pr_xfunction->profile += profile - startprofile;
				startprofile = profile;
				PR_CallFunction (pr, OPA.func_var);
				st = pr->pr_statements + pr->pr_xstatement;
				break;
			case OP_DONE:
			case OP_RETURN:
				if (!st->a)
					memset (&R_INT (pr), 0,
							pr->pr_param_size * sizeof (OPA));
				else if (&R_INT (pr) != &OPA.integer_var)
					memcpy (&R_INT (pr), &OPA,
							pr->pr_param_size * sizeof (OPA));
				// fallthrough
			case OP_RETURN_V:
				pr->pr_xfunction->profile += profile - startprofile;
				startprofile = profile;
				PR_LeaveFunction (pr);
				st = pr->pr_statements + pr->pr_xstatement;
				if (pr->pr_depth == exitdepth) {
					if (pr->pr_trace && pr->pr_depth <= pr->pr_trace_depth)
						pr->pr_trace = false;
					Sys_PopSignalHook ();
					return;					// all done
				}
				break;
			case OP_STATE:
				ed = PROG_TO_EDICT (pr, *pr->globals.self);
				ed->v[pr->fields.nextthink].float_var = *pr->globals.time +
					0.1;
				ed->v[pr->fields.frame].float_var = OPA.float_var;
				ed->v[pr->fields.think].func_var = OPB.func_var;
				break;
			case OP_STATE_F:
				ed = PROG_TO_EDICT (pr, *pr->globals.self);
				ed->v[pr->fields.nextthink].float_var = *pr->globals.time +
					OPC.float_var;
				ed->v[pr->fields.frame].float_var = OPA.float_var;
				ed->v[pr->fields.think].func_var = OPB.func_var;
				break;
			case OP_ADD_I:
				OPC.integer_var = OPA.integer_var + OPB.integer_var;
				break;
			case OP_SUB_I:
				OPC.integer_var = OPA.integer_var - OPB.integer_var;
				break;
			case OP_MUL_I:
				OPC.integer_var = OPA.integer_var * OPB.integer_var;
				break;
/*
			case OP_DIV_VF:
				{
					float       temp = 1.0f / OPB.float_var;
					VectorScale (OPA.vector_var, temp, OPC.vector_var);
				}
				break;
*/
			case OP_DIV_I:
				OPC.integer_var = OPA.integer_var / OPB.integer_var;
				break;
			case OP_MOD_I:
				OPC.integer_var = OPA.integer_var % OPB.integer_var;
				break;
			case OP_MOD_F:
				OPC.float_var = (int) OPA.float_var % (int) OPB.float_var;
				break;
			case OP_CONV_IF:
				OPC.float_var = OPA.integer_var;
				break;
			case OP_CONV_FI:
				OPC.integer_var = OPA.float_var;
				break;
			case OP_BITAND_I:
				OPC.integer_var = OPA.integer_var & OPB.integer_var;
				break;
			case OP_BITOR_I:
				OPC.integer_var = OPA.integer_var | OPB.integer_var;
				break;
			case OP_BITXOR_I:
				OPC.integer_var = OPA.integer_var ^ OPB.integer_var;
				break;
			case OP_BITNOT_I:
				OPC.integer_var = ~OPA.integer_var;
				break;

			case OP_GE_I:
			case OP_GE_P:
				OPC.integer_var = OPA.integer_var >= OPB.integer_var;
				break;
			case OP_GE_U:
				OPC.integer_var = OPA.uinteger_var >= OPB.uinteger_var;
				break;
			case OP_LE_I:
			case OP_LE_P:
				OPC.integer_var = OPA.integer_var <= OPB.integer_var;
				break;
			case OP_LE_U:
				OPC.integer_var = OPA.uinteger_var <= OPB.uinteger_var;
				break;
			case OP_GT_I:
			case OP_GT_P:
				OPC.integer_var = OPA.integer_var > OPB.integer_var;
				break;
			case OP_GT_U:
				OPC.integer_var = OPA.uinteger_var > OPB.uinteger_var;
				break;
			case OP_LT_I:
			case OP_LT_P:
				OPC.integer_var = OPA.integer_var < OPB.integer_var;
				break;
			case OP_LT_U:
				OPC.integer_var = OPA.uinteger_var < OPB.uinteger_var;
				break;

			case OP_AND_I:
				OPC.integer_var = OPA.integer_var && OPB.integer_var;
				break;
			case OP_OR_I:
				OPC.integer_var = OPA.integer_var || OPB.integer_var;
				break;
			case OP_NOT_I:
			case OP_NOT_P:
				OPC.integer_var = !OPA.integer_var;
				break;
			case OP_EQ_I:
			case OP_EQ_P:
				OPC.integer_var = OPA.integer_var == OPB.integer_var;
				break;
			case OP_NE_I:
			case OP_NE_P:
				OPC.integer_var = OPA.integer_var != OPB.integer_var;
				break;

			case OP_MOVEI:
				memmove (&OPC, &OPA, st->b * 4);
				break;
			case OP_MOVEP:
				if (pr_boundscheck->int_val) {
					PR_BoundsCheckSize (pr, OPC.integer_var, OPB.uinteger_var);
					PR_BoundsCheckSize (pr, OPA.integer_var, OPB.uinteger_var);
				}
				memmove (pr->pr_globals + OPC.integer_var,
						 pr->pr_globals + OPA.integer_var,
						 OPB.uinteger_var * 4);
				break;
			case OP_MOVEPI:
				if (pr_boundscheck->int_val) {
					PR_BoundsCheckSize (pr, OPC.integer_var, st->b);
					PR_BoundsCheckSize (pr, OPA.integer_var, st->b);
				}
				memmove (pr->pr_globals + OPC.integer_var,
						 pr->pr_globals + OPA.integer_var,
						 st->b * 4);
				break;

// LordHavoc: to be enabled when Progs version 7 (or whatever it will be numbered) is finalized
/*
			case OP_BOUNDCHECK:
				if (OPA.integer_var < 0 || OPA.integer_var >= st->b) {
					PR_RunError (pr, "Progs boundcheck failed at line number "
					"%d, value is < 0 or >= %d", st->b, st->c);
				}
				break;

*/
			default:
				PR_RunError (pr, "Bad opcode %i", st->op);
		}
		if (watch && watch->integer_var != old_val.integer_var
			&& (!pr->wp_conditional
				|| watch->integer_var == pr->wp_val.integer_var))
			PR_RunError (pr, "watchpoint hit: %d -> %d", old_val.integer_var,
						 watch->integer_var);
	}
}
Beispiel #8
0
static void
PF_colstr (progs_t *pr)
{
	const char *srcstr;
	unsigned char *result;
	unsigned    action;
	size_t      len, i;

	srcstr = P_GSTRING (pr, 0);
	action = (unsigned) P_FLOAT (pr, 1);
	len = strlen (srcstr);

	// Check for errors, if any, return given string
	if (len == 0 || action > COLSTR_NUMBERV) {
		R_INT (pr) = P_STRING (pr, 0);	// return given string
		return;
	}
	// Process string..
	result = alloca (len + 1);
	strcpy ((char *) result, srcstr);

	switch (action) {
		case COLSTR_WHITE:

			for (i = 0; i < len; i++) {
				if (result[i] > 160)	// is red char
					result[i] -= 128;
			}

			break;

		case COLSTR_MIX1:

			for (i = 0; i < len; i++) {
				if (i & 0x01) {
					if (result[i] < 128 && result[i] > 32)	// is white char
						result[i] += 128;
				} else {
					if (result[i] > 160)	// is red char
						result[i] -= 128;
				}
			}

			break;

		case COLSTR_RED:

			for (i = 0; i < len; i++) {
				if (result[i] < 128 && result[i] > 32)	// is white char
					result[i] += 128;
			}

			break;

		case COLSTR_MIX2:

			for (i = 0; i < len; i++) {
				if (i & 0x01) {
					if (result[i] > 160)	// is red char
						result[i] -= 128;
				} else {
					if (result[i] < 128 && result[i] > 32)	// is white char
						result[i] += 128;
				}
			}

			break;

		case COLSTR_NUMBER:

			for (i = 0; i < len; i++) {
				if (result[i] > 47 && result[i] < 58)	// is a white number
					result[i] -= 30;
			}

			break;

		case COLSTR_NUMBERV:

			for (i = 0; i < len; i++) {
				if (result[i] > 47 && result[i] < 58)	// is a white number
					result[i] += 98;
			}
	}

	RETURN_STRING (pr, (char *) result);
}
Beispiel #9
0
void
Menu_Draw (view_t *view)
{
	menu_pic_t *m_pic;
	int         i, x, y;
	menu_item_t *item;

	if (!menu)
		return;

	x = view->xabs;
	y = view->yabs;

	if (menu->fadescreen)
		r_funcs->Draw_FadeScreen ();

	*menu_pr_state.globals.time = *con_data.realtime;

	if (menu->draw) {
		int         ret;

		run_menu_pre ();
		PR_RESET_PARAMS (&menu_pr_state);
		P_INT (&menu_pr_state, 0) = x;
		P_INT (&menu_pr_state, 1) = y;
		PR_ExecuteProgram (&menu_pr_state, menu->draw);
		ret = R_INT (&menu_pr_state);
		run_menu_post ();
		if (!ret)
			return;
	}


	for (m_pic = menu->pics; m_pic; m_pic = m_pic->next) {
		qpic_t     *pic = r_funcs->Draw_CachePic (m_pic->name, 1);
		if (!pic)
			continue;
		if (m_pic->width > 0 && m_pic->height > 0)
			r_funcs->Draw_SubPic (x + m_pic->x, y + m_pic->y, pic,
						 m_pic->srcx, m_pic->srcy,
						 m_pic->width, m_pic->height);
		else
			r_funcs->Draw_Pic (x + m_pic->x, y + m_pic->y, pic);
	}
	for (i = 0; i < menu->num_items; i++) {
		if (menu->items[i]->text) {
			r_funcs->Draw_String (x + menu->items[i]->x + 8,
								  y + menu->items[i]->y,
						 menu->items[i]->text);
		}
	}
	if (!menu->items)
		return;
	item = menu->items[menu->cur_item];
	if (menu->cursor) {
		run_menu_pre ();
		PR_RESET_PARAMS (&menu_pr_state);
		P_INT (&menu_pr_state, 0) = x + item->x;
		P_INT (&menu_pr_state, 1) = y + item->y;
		PR_ExecuteProgram (&menu_pr_state, menu->cursor);
		run_menu_post ();
	} else {
		r_funcs->Draw_Character (x + item->x, y + item->y,
								 12 + ((int) (*con_data.realtime * 4) & 1));
	}
}