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); }
static int cpqw_user_cmd (void) { int argc, i; progs_t *pr = &sv_pr_state; if (cpqw_funcs.ClientCommand) { argc = Cmd_Argc (); if (argc > 7) argc = 7; *sv_globals.time = sv.time; *sv_globals.self = EDICT_TO_PROG (&sv_pr_state, sv_player); PR_PushFrame (pr); P_FLOAT (pr, 0) = argc; for (i = 0; i < argc; i++) P_STRING (pr, i + 1) = PR_SetTempString (pr, Cmd_Argv (i)); for (; i < 7; i++) P_STRING (pr, i + 1) = 0; PR_ExecuteProgram (pr, cpqw_funcs.ClientCommand); PR_PopFrame (pr); return (int) R_FLOAT (pr); } return 0; }
static void bi_Menu_Enter (progs_t *pr) { menu_item_t *item; if (!menu) return; item = menu->items[menu->cur_item]; if (item->func) { run_menu_pre (); PR_PushFrame (&menu_pr_state); 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) = 0; PR_ExecuteProgram (&menu_pr_state, item->func); PR_PopFrame (&menu_pr_state); run_menu_post (); } else { menu = item; if (menu->enter_hook) { run_menu_pre (); PR_ExecuteProgram (&menu_pr_state, menu->enter_hook); run_menu_post (); } } }
void SV_SetLocalinfo (const char *key, const char *value) { char *oldvalue = 0; if (sv_funcs.LocalinfoChanged) oldvalue = strdup (Info_ValueForKey (localinfo, key)); if (*value) Info_SetValueForKey (localinfo, key, value, !sv_highchars->int_val); else Info_RemoveKey (localinfo, key); if (sv_funcs.LocalinfoChanged) { *sv_globals.time = sv.time; *sv_globals.self = 0; PR_PushFrame (&sv_pr_state); PR_RESET_PARAMS (&sv_pr_state); P_STRING (&sv_pr_state, 0) = PR_SetTempString (&sv_pr_state, key); P_STRING (&sv_pr_state, 1) = PR_SetTempString (&sv_pr_state, oldvalue); P_STRING (&sv_pr_state, 2) = PR_SetTempString (&sv_pr_state, value); PR_ExecuteProgram (&sv_pr_state, sv_funcs.LocalinfoChanged); PR_PopFrame (&sv_pr_state); } if (oldvalue) free (oldvalue); }
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; } }
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); }
/** Setup the stackframe prior to calling a progs function. Saves all local data the called function will trample on and copies the parameters used by the function into the function's local data space. \param pr pointer to progs_t VM struct \param f pointer to the descriptor for the called function \note Passing a descriptor for a builtin function will result in undefined behavior. */ static void PR_EnterFunction (progs_t *pr, bfunction_t *f) { pr_int_t i, j, c, o; pr_int_t k; pr_int_t count = 0; int size[2] = {0, 0}; long paramofs = 0; long offs; PR_PushFrame (pr); if (f->numparms > 0) { for (i = 0; i < 2 && i < f->numparms; i++) { paramofs += f->parm_size[i]; size[i] = f->parm_size[i]; } count = i; } else if (f->numparms < 0) { for (i = 0; i < 2 && i < -f->numparms - 1; i++) { paramofs += f->parm_size[i]; size[i] = f->parm_size[i]; } for (; i < 2; i++) { paramofs += pr->pr_param_size; size[i] = pr->pr_param_size; } count = i; } for (i = 0; i < count && i < pr->pr_argc; i++) { offs = (pr->pr_params[i] - pr->pr_globals) - f->parm_start; if (offs >= 0 && offs < paramofs) { memcpy (pr->pr_real_params[i], pr->pr_params[i], size[i] * sizeof (pr_type_t)); pr->pr_params[i] = pr->pr_real_params[i]; } } //Sys_Printf("%s:\n", PR_GetString(pr,f->s_name)); pr->pr_xfunction = f; pr->pr_xstatement = f->first_statement - 1; // offset the st++ // save off any locals that the new function steps on c = f->locals; if (pr->localstack_used + c > LOCALSTACK_SIZE) PR_RunError (pr, "PR_EnterFunction: locals stack overflow"); memcpy (&pr->localstack[pr->localstack_used], &pr->pr_globals[f->parm_start], sizeof (pr_type_t) * c); pr->localstack_used += c; if (pr_deadbeef_locals->int_val) for (k = f->parm_start; k < f->parm_start + c; k++) pr->pr_globals[k].integer_var = 0xdeadbeef; // copy parameters o = f->parm_start; if (f->numparms >= 0) { for (i = 0; i < f->numparms; i++) { for (j = 0; j < f->parm_size[i]; j++) { memcpy (&pr->pr_globals[o], &P_INT (pr, i) + j, sizeof (pr_type_t)); o++; } } } else { pr_type_t *argc = &pr->pr_globals[o++]; pr_type_t *argv = &pr->pr_globals[o++]; for (i = 0; i < -f->numparms - 1; i++) { for (j = 0; j < f->parm_size[i]; j++) { memcpy (&pr->pr_globals[o], &P_INT (pr, i) + j, sizeof (pr_type_t)); o++; } } argc->integer_var = pr->pr_argc - i; argv->integer_var = o; if (i < MAX_PARMS) { memcpy (&pr->pr_globals[o], &P_INT (pr, i), (MAX_PARMS - i) * pr->pr_param_size * sizeof (pr_type_t)); } } }