X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=menu.c;h=c09abda45607d87d3a67eb22f02c091db70456e1;hb=e97faa7f06e7821c32fb675cecb474e07ce55df6;hp=263e06bdbc12e73139d3e867b4c9187e1b9c3aa1;hpb=f5afebcef735508a40a20fb2a5a1b81e2ac8af8f;p=xonotic%2Fdarkplaces.git diff --git a/menu.c b/menu.c index 263e06bd..c09abda4 100644 --- a/menu.c +++ b/menu.c @@ -33,7 +33,7 @@ static cvar_t forceqmenu = { 0, "forceqmenu", "0", "enables the quake menu inste static int NehGameType; enum m_state_e m_state; -char m_return_reason[32]; +char m_return_reason[128]; void M_Menu_Main_f (void); void M_Menu_SinglePlayer_f (void); @@ -107,7 +107,7 @@ static void M_ModList_Key (int key, int ascii); static qboolean m_entersound; ///< play after drawing a frame, so caching won't disrupt the sound -void M_Update_Return_Reason(char *s) +void M_Update_Return_Reason(const char *s) { strlcpy(m_return_reason, s, sizeof(m_return_reason)); if (s) @@ -121,8 +121,8 @@ void M_Update_Return_Reason(char *s) #define NumberOfNehahraDemos 34 typedef struct nehahrademonames_s { - char *name; - char *desc; + const char *name; + const char *desc; } nehahrademonames_t; static nehahrademonames_t NehahraDemos[NumberOfNehahraDemos] = @@ -167,8 +167,8 @@ static float menu_x, menu_y, menu_width, menu_height; static void M_Background(int width, int height) { - menu_width = bound(1, width, vid_conwidth.integer); - menu_height = bound(1, height, vid_conheight.integer); + menu_width = bound(1.0f, (float)width, vid_conwidth.value); + menu_height = bound(1.0f, (float)height, vid_conheight.value); menu_x = (vid_conwidth.integer - menu_width) * 0.5; menu_y = (vid_conheight.integer - menu_height) * 0.5; //DrawQ_Fill(menu_x, menu_y, menu_width, menu_height, 0, 0, 0, 0.5, 0); @@ -187,30 +187,30 @@ static void M_DrawCharacter (float cx, float cy, int num) char temp[2]; temp[0] = num; temp[1] = 0; - DrawQ_String_Font(menu_x + cx, menu_y + cy, temp, 1, 8, 8, 1, 1, 1, 1, 0, NULL, true, FONT_MENU); + DrawQ_String(menu_x + cx, menu_y + cy, temp, 1, 8, 8, 1, 1, 1, 1, 0, NULL, true, FONT_MENU); } static void M_PrintColored(float cx, float cy, const char *str) { - DrawQ_String_Font(menu_x + cx, menu_y + cy, str, 0, 8, 8, 1, 1, 1, 1, 0, NULL, false, FONT_MENU); + DrawQ_String(menu_x + cx, menu_y + cy, str, 0, 8, 8, 1, 1, 1, 1, 0, NULL, false, FONT_MENU); } static void M_Print(float cx, float cy, const char *str) { - DrawQ_String_Font(menu_x + cx, menu_y + cy, str, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true, FONT_MENU); + DrawQ_String(menu_x + cx, menu_y + cy, str, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true, FONT_MENU); } static void M_PrintRed(float cx, float cy, const char *str) { - DrawQ_String_Font(menu_x + cx, menu_y + cy, str, 0, 8, 8, 1, 0, 0, 1, 0, NULL, true, FONT_MENU); + DrawQ_String(menu_x + cx, menu_y + cy, str, 0, 8, 8, 1, 0, 0, 1, 0, NULL, true, FONT_MENU); } static void M_ItemPrint(float cx, float cy, const char *str, int unghosted) { if (unghosted) - DrawQ_String_Font(menu_x + cx, menu_y + cy, str, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true, FONT_MENU); + DrawQ_String(menu_x + cx, menu_y + cy, str, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true, FONT_MENU); else - DrawQ_String_Font(menu_x + cx, menu_y + cy, str, 0, 8, 8, 0.4, 0.4, 0.4, 1, 0, NULL, true, FONT_MENU); + DrawQ_String(menu_x + cx, menu_y + cy, str, 0, 8, 8, 0.4, 0.4, 0.4, 1, 0, NULL, true, FONT_MENU); } static void M_DrawPic(float cx, float cy, const char *picname) @@ -270,23 +270,23 @@ static void M_DrawTextBox(float x, float y, float width, float height) /* ================ -M_ToggleMenu_f +M_ToggleMenu ================ */ -void M_ToggleMenu_f (void) +void M_ToggleMenu(int mode) { m_entersound = true; if ((key_dest != key_menu && key_dest != key_menu_grabbed) || m_state != m_main) { - if(Cmd_Argc() == 2 && !strcmp(Cmd_Argv(1), "1")) - return; + if(mode == 0) + return; // the menu is off, and we want it off M_Menu_Main_f (); } else { - if(Cmd_Argc() == 2 && !strcmp(Cmd_Argv(1), "0")) - return; + if(mode == 1) + return; // the menu is on, and we want it on key_dest = key_game; m_state = m_none; } @@ -362,8 +362,35 @@ void M_Menu_Main_f (void) { const char *s; s = "gfx/mainmenu"; + if (gamemode == GAME_NEHAHRA) { + if (FS_FileExists("maps/neh1m4.bsp")) + { + if (FS_FileExists("hearing.dem")) + { + Con_DPrint("Main menu: Nehahra movie and game detected.\n"); + NehGameType = TYPE_BOTH; + } + else + { + Con_DPrint("Nehahra game detected.\n"); + NehGameType = TYPE_GAME; + } + } + else + { + if (FS_FileExists("hearing.dem")) + { + Con_DPrint("Nehahra movie detected.\n"); + NehGameType = TYPE_DEMO; + } + else + { + Con_DPrint("Nehahra not found.\n"); + NehGameType = TYPE_GAME; // could just complain, but... + } + } if (NehGameType == TYPE_DEMO) MAIN_ITEMS = 4; else if (NehGameType == TYPE_GAME) @@ -817,12 +844,13 @@ static int loadable[MAX_SAVEGAMES]; static void M_ScanSaves (void) { - int i, j, len; + int i, j; + size_t len; char name[MAX_OSPATH]; char buf[SAVEGAME_COMMENT_LENGTH + 256]; const char *t; qfile_t *f; - int version; +// int version; for (i=0 ; i= numcommands) + Sys_Error ("M_Init: The key binding list only contains sections"); } } -static void M_UnbindCommand (char *command) +#define NUMKEYS 5 + +static void M_UnbindCommand (const char *command) { int j; - char *b; + const char *b; for (j = 0; j < (int)sizeof (keybindings[0]) / (int)sizeof (keybindings[0][0]); j++) { @@ -2591,7 +2628,7 @@ static void M_Keys_Draw (void) else M_Print(16, y, bindnames[i][1]); - M_FindKeysForCommand (bindnames[i][0], keys); + Key_FindKeysForCommand (bindnames[i][0], keys, NUMKEYS, 0); // LordHavoc: redesigned to print more than 2 keys, inspired by Tomaz's MiniRacer if (keys[0] == -1) @@ -2672,7 +2709,7 @@ static void M_Keys_Key (int k, int ascii) break; case K_ENTER: // go into bind mode - M_FindKeysForCommand (bindnames[keys_cursor][0], keys); + Key_FindKeysForCommand (bindnames[keys_cursor][0], keys, NUMKEYS, 0); S_LocalSound ("sound/misc/menu2.wav"); if (keys[NUMKEYS - 1] != -1) M_UnbindCommand (bindnames[keys_cursor][0]); @@ -3124,12 +3161,12 @@ static void M_Credits_Key (int key, int ascii) //============================================================================= /* QUIT MENU */ -static char *m_quit_message[9]; +static const char *m_quit_message[9]; static int m_quit_prevstate; static qboolean wasInMenus; -static int M_QuitMessage(char *line1, char *line2, char *line3, char *line4, char *line5, char *line6, char *line7, char *line8) +static int M_QuitMessage(const char *line1, const char *line2, const char *line3, const char *line4, const char *line5, const char *line6, const char *line7, const char *line8) { m_quit_message[0] = line1; m_quit_message[1] = line2; @@ -3309,8 +3346,8 @@ static void M_LanConfig_Draw (void) { cachepic_t *p; int basex; - char *startJoin; - char *protocol; + const char *startJoin; + const char *protocol; M_Background(320, 200); @@ -3473,20 +3510,20 @@ static void M_LanConfig_Key (int key, int ascii) typedef struct level_s { - char *name; - char *description; + const char *name; + const char *description; } level_t; typedef struct episode_s { - char *description; + const char *description; int firstLevel; int levels; } episode_t; typedef struct gamelevels_s { - char *gamename; + const char *gamename; level_t *levels; episode_t *episodes; int numepisodes; @@ -3896,26 +3933,9 @@ static gameinfo_t gamelist[] = {GAME_OPENQUARTZ, &openquartzgame, &openquartzgame}, {GAME_DEFEATINDETAIL2, &defeatindetail2game, &defeatindetail2game}, {GAME_PRYDON, &prydongame, &prydongame}, - {GAME_NORMAL, NULL, NULL} // terminator }; -static gamelevels_t *lookupgameinfo(void) -{ - int i = 0; - while (gamelist[i].gameid != gamemode) - { - if (gamelist[i].notregistered == NULL) - { - i = 0; - break; - } - i++; - } - if (registered.integer) - return gamelist[i].registered; - else - return gamelist[i].notregistered; -} +static gamelevels_t *gameoptions_levels = NULL; static int startepisode; static int startlevel; @@ -3925,6 +3945,7 @@ static double m_serverInfoMessageTime; void M_Menu_GameOptions_f (void) { + int i; key_dest = key_menu; m_state = m_gameoptions; m_entersound = true; @@ -3932,6 +3953,11 @@ void M_Menu_GameOptions_f (void) maxplayers = svs.maxclients; if (maxplayers < 2) maxplayers = min(8, MAX_SCOREBOARD); + // pick game level list based on gamemode (use GAME_NORMAL if no matches) + gameoptions_levels = registered.integer ? gamelist[0].registered : gamelist[0].notregistered; + for (i = 0;i < (int)(sizeof(gamelist)/sizeof(gamelist[0]));i++) + if (gamelist[i].gameid == gamemode) + gameoptions_levels = registered.integer ? gamelist[i].registered : gamelist[i].notregistered; } @@ -3943,7 +3969,6 @@ void M_GameOptions_Draw (void) { cachepic_t *p; int x; - gamelevels_t *g; M_Background(320, 200); @@ -3993,7 +4018,7 @@ void M_GameOptions_Draw (void) M_Print(0, 72, " Teamplay"); if (gamemode == GAME_ROGUE) { - char *msg; + const char *msg; switch((int)teamplay.integer) { @@ -4009,7 +4034,7 @@ void M_GameOptions_Draw (void) } else { - char *msg; + const char *msg; switch (teamplay.integer) { @@ -4067,17 +4092,15 @@ void M_GameOptions_Draw (void) M_DrawTextBox (0, 132, 38, 1); M_Print(8, 140, hostname.string); - g = lookupgameinfo(); - if (gamemode != GAME_GOODVSBAD2) { M_Print(0, 160, " Episode"); - M_Print(160, 160, g->episodes[startepisode].description); + M_Print(160, 160, gameoptions_levels->episodes[startepisode].description); } M_Print(0, 168, " Level"); - M_Print(160, 168, g->levels[g->episodes[startepisode].firstLevel + startlevel].description); - M_Print(160, 176, g->levels[g->episodes[startepisode].firstLevel + startlevel].name); + M_Print(160, 168, gameoptions_levels->levels[gameoptions_levels->episodes[startepisode].firstLevel + startlevel].description); + M_Print(160, 176, gameoptions_levels->levels[gameoptions_levels->episodes[startepisode].firstLevel + startlevel].name); // line cursor if (gameoptions_cursor == 9) @@ -4105,7 +4128,6 @@ void M_GameOptions_Draw (void) static void M_NetStart_Change (int dir) { - gamelevels_t *g; int count; switch (gameoptions_cursor) @@ -4242,12 +4264,11 @@ static void M_NetStart_Change (int dir) if (gamemode == GAME_GOODVSBAD2) break; startepisode += dir; - g = lookupgameinfo(); if (startepisode < 0) - startepisode = g->numepisodes - 1; + startepisode = gameoptions_levels->numepisodes - 1; - if (startepisode >= g->numepisodes) + if (startepisode >= gameoptions_levels->numepisodes) startepisode = 0; startlevel = 0; @@ -4255,12 +4276,11 @@ static void M_NetStart_Change (int dir) case 11: startlevel += dir; - g = lookupgameinfo(); if (startlevel < 0) - startlevel = g->episodes[startepisode].levels - 1; + startlevel = gameoptions_levels->episodes[startepisode].levels - 1; - if (startlevel >= g->episodes[startepisode].levels) + if (startlevel >= gameoptions_levels->episodes[startepisode].levels) startlevel = 0; break; } @@ -4268,7 +4288,6 @@ static void M_NetStart_Change (int dir) static void M_GameOptions_Key (int key, int ascii) { - gamelevels_t *g; int l; char hostnamebuf[128]; @@ -4314,8 +4333,7 @@ static void M_GameOptions_Key (int key, int ascii) Cbuf_AddText ("disconnect\n"); Cbuf_AddText ( va ("maxplayers %u\n", maxplayers) ); - g = lookupgameinfo(); - Cbuf_AddText ( va ("map %s\n", g->levels[g->episodes[startepisode].firstLevel + startlevel].name) ); + Cbuf_AddText ( va ("map %s\n", gameoptions_levels->levels[gameoptions_levels->episodes[startepisode].firstLevel + startlevel].name) ); return; } @@ -4400,9 +4418,10 @@ static void M_ServerList_Draw (void) { for (n = start;n < end;n++) { + serverlist_entry_t *entry = ServerList_GetViewEntry(n); DrawQ_Fill(menu_x, menu_y + y, 640, 16, n == slist_cursor ? (0.5 + 0.2 * sin(realtime * M_PI)) : 0, 0, 0, 0.5, 0); - M_PrintColored(0, y, serverlist_viewlist[n]->line1);y += 8; - M_PrintColored(0, y, serverlist_viewlist[n]->line2);y += 8; + M_PrintColored(0, y, entry->line1);y += 8; + M_PrintColored(0, y, entry->line2);y += 8; } } else if (realtime - masterquerytime > 10) @@ -4456,7 +4475,7 @@ static void M_ServerList_Key(int k, int ascii) case K_ENTER: S_LocalSound ("sound/misc/menu2.wav"); if (serverlist_viewcount) - Cbuf_AddText(va("connect \"%s\"\n", serverlist_viewlist[slist_cursor]->info.cname)); + Cbuf_AddText(va("connect \"%s\"\n", ServerList_GetViewEntry(slist_cursor)->info.cname)); break; default: @@ -4486,7 +4505,6 @@ typedef struct modlist_entry_s static int modlist_cursor; //static int modlist_viewcount; -#define MODLIST_TOTALSIZE 256 static int modlist_count = 0; static modlist_entry_t modlist[MODLIST_TOTALSIZE]; @@ -4497,7 +4515,7 @@ void ModList_RebuildList(void) stringlistinit(&list); listdirectory(&list, fs_basedir, ""); - stringlistsort(&list); + stringlistsort(&list, true); modlist_count = 0; modlist_numenabled = fs_numgamedirs; for (i = 0;i < list.numstrings;i++) @@ -4505,9 +4523,8 @@ void ModList_RebuildList(void) if (modlist_count >= MODLIST_TOTALSIZE) break; // check all dirs to see if they "appear" to be mods // reject any dirs that are part of the base game - // (such as "id1" and "hipnotic" when in GAME_HIPNOTIC mode) if (gamedirname1 && !strcasecmp(gamedirname1, list.strings[i])) continue; - if (gamedirname2 && !strcasecmp(gamedirname2, list.strings[i])) continue; + //if (gamedirname2 && !strcasecmp(gamedirname2, list.strings[i])) continue; if (FS_CheckNastyPath (list.strings[i], true)) continue; if (!FS_CheckGameDir(list.strings[i])) continue; @@ -4694,7 +4711,7 @@ static void M_ModList_Key(int k, int ascii) static void M_KeyEvent(int key, int ascii, qboolean downevent); static void M_Draw(void); -void M_ToggleMenu_f(void); +void M_ToggleMenu(int mode); static void M_Shutdown(void); void M_Init (void) @@ -4721,64 +4738,6 @@ void M_Init (void) Cmd_AddCommand ("menu_transfusion_episode", M_Menu_Transfusion_Episode_f, "open the transfusion episode select menu"); Cmd_AddCommand ("menu_transfusion_skill", M_Menu_Transfusion_Skill_f, "open the transfusion skill select menu"); Cmd_AddCommand ("menu_credits", M_Menu_Credits_f, "open the credits menu"); - - if (gamemode == GAME_TRANSFUSION) - { - numcommands = sizeof(transfusionbindnames) / sizeof(transfusionbindnames[0]); - bindnames = transfusionbindnames; - } - else if (gamemode == GAME_GOODVSBAD2) - { - numcommands = sizeof(goodvsbad2bindnames) / sizeof(goodvsbad2bindnames[0]); - bindnames = goodvsbad2bindnames; - } - else - { - numcommands = sizeof(quakebindnames) / sizeof(quakebindnames[0]); - bindnames = quakebindnames; - } - - // Make sure "keys_cursor" doesn't start on a section in the binding list - keys_cursor = 0; - while (bindnames[keys_cursor][0][0] == '\0') - { - keys_cursor++; - - // Only sections? There may be a problem somewhere... - if (keys_cursor >= numcommands) - Sys_Error ("M_Init: The key binding list only contains sections"); - } - - - if (gamemode == GAME_NEHAHRA) - { - if (FS_FileExists("maps/neh1m4.bsp")) - { - if (FS_FileExists("hearing.dem")) - { - Con_Print("Nehahra movie and game detected.\n"); - NehGameType = TYPE_BOTH; - } - else - { - Con_Print("Nehahra game detected.\n"); - NehGameType = TYPE_GAME; - } - } - else - { - if (FS_FileExists("hearing.dem")) - { - Con_Print("Nehahra movie detected.\n"); - NehGameType = TYPE_DEMO; - } - else - { - Con_Print("Nehahra not found.\n"); - NehGameType = TYPE_GAME; // could just complain, but... - } - } - } } void M_Draw (void) @@ -5033,20 +4992,20 @@ void M_KeyEvent (int key, int ascii, qboolean downevent) } -void M_Shutdown(void) +void M_NewMap(void) { - // reset key_dest - key_dest = key_game; } -void M_Restart(void) +void M_Shutdown(void) { + // reset key_dest + key_dest = key_game; } //============================================================================ // Menu prog handling -static char *m_required_func[] = { +static const char *m_required_func[] = { "m_init", "m_keydown", "m_draw", @@ -5056,6 +5015,164 @@ static char *m_required_func[] = { static int m_numrequiredfunc = sizeof(m_required_func) / sizeof(char*); +static prvm_required_field_t m_required_fields[] = +{ +#define PRVM_DECLARE_serverglobalfloat(x) +#define PRVM_DECLARE_serverglobalvector(x) +#define PRVM_DECLARE_serverglobalstring(x) +#define PRVM_DECLARE_serverglobaledict(x) +#define PRVM_DECLARE_serverglobalfunction(x) +#define PRVM_DECLARE_clientglobalfloat(x) +#define PRVM_DECLARE_clientglobalvector(x) +#define PRVM_DECLARE_clientglobalstring(x) +#define PRVM_DECLARE_clientglobaledict(x) +#define PRVM_DECLARE_clientglobalfunction(x) +#define PRVM_DECLARE_menuglobalfloat(x) +#define PRVM_DECLARE_menuglobalvector(x) +#define PRVM_DECLARE_menuglobalstring(x) +#define PRVM_DECLARE_menuglobaledict(x) +#define PRVM_DECLARE_menuglobalfunction(x) +#define PRVM_DECLARE_serverfieldfloat(x) +#define PRVM_DECLARE_serverfieldvector(x) +#define PRVM_DECLARE_serverfieldstring(x) +#define PRVM_DECLARE_serverfieldedict(x) +#define PRVM_DECLARE_serverfieldfunction(x) +#define PRVM_DECLARE_clientfieldfloat(x) +#define PRVM_DECLARE_clientfieldvector(x) +#define PRVM_DECLARE_clientfieldstring(x) +#define PRVM_DECLARE_clientfieldedict(x) +#define PRVM_DECLARE_clientfieldfunction(x) +#define PRVM_DECLARE_menufieldfloat(x) {ev_float, #x}, +#define PRVM_DECLARE_menufieldvector(x) {ev_vector, #x}, +#define PRVM_DECLARE_menufieldstring(x) {ev_string, #x}, +#define PRVM_DECLARE_menufieldedict(x) {ev_entity, #x}, +#define PRVM_DECLARE_menufieldfunction(x) {ev_function, #x}, +#define PRVM_DECLARE_serverfunction(x) +#define PRVM_DECLARE_clientfunction(x) +#define PRVM_DECLARE_menufunction(x) +#define PRVM_DECLARE_field(x) +#define PRVM_DECLARE_global(x) +#define PRVM_DECLARE_function(x) +#include "prvm_offsets.h" +#undef PRVM_DECLARE_serverglobalfloat +#undef PRVM_DECLARE_serverglobalvector +#undef PRVM_DECLARE_serverglobalstring +#undef PRVM_DECLARE_serverglobaledict +#undef PRVM_DECLARE_serverglobalfunction +#undef PRVM_DECLARE_clientglobalfloat +#undef PRVM_DECLARE_clientglobalvector +#undef PRVM_DECLARE_clientglobalstring +#undef PRVM_DECLARE_clientglobaledict +#undef PRVM_DECLARE_clientglobalfunction +#undef PRVM_DECLARE_menuglobalfloat +#undef PRVM_DECLARE_menuglobalvector +#undef PRVM_DECLARE_menuglobalstring +#undef PRVM_DECLARE_menuglobaledict +#undef PRVM_DECLARE_menuglobalfunction +#undef PRVM_DECLARE_serverfieldfloat +#undef PRVM_DECLARE_serverfieldvector +#undef PRVM_DECLARE_serverfieldstring +#undef PRVM_DECLARE_serverfieldedict +#undef PRVM_DECLARE_serverfieldfunction +#undef PRVM_DECLARE_clientfieldfloat +#undef PRVM_DECLARE_clientfieldvector +#undef PRVM_DECLARE_clientfieldstring +#undef PRVM_DECLARE_clientfieldedict +#undef PRVM_DECLARE_clientfieldfunction +#undef PRVM_DECLARE_menufieldfloat +#undef PRVM_DECLARE_menufieldvector +#undef PRVM_DECLARE_menufieldstring +#undef PRVM_DECLARE_menufieldedict +#undef PRVM_DECLARE_menufieldfunction +#undef PRVM_DECLARE_serverfunction +#undef PRVM_DECLARE_clientfunction +#undef PRVM_DECLARE_menufunction +#undef PRVM_DECLARE_field +#undef PRVM_DECLARE_global +#undef PRVM_DECLARE_function +}; + +static int m_numrequiredfields = sizeof(m_required_fields) / sizeof(m_required_fields[0]); + +static prvm_required_field_t m_required_globals[] = +{ +#define PRVM_DECLARE_serverglobalfloat(x) +#define PRVM_DECLARE_serverglobalvector(x) +#define PRVM_DECLARE_serverglobalstring(x) +#define PRVM_DECLARE_serverglobaledict(x) +#define PRVM_DECLARE_serverglobalfunction(x) +#define PRVM_DECLARE_clientglobalfloat(x) +#define PRVM_DECLARE_clientglobalvector(x) +#define PRVM_DECLARE_clientglobalstring(x) +#define PRVM_DECLARE_clientglobaledict(x) +#define PRVM_DECLARE_clientglobalfunction(x) +#define PRVM_DECLARE_menuglobalfloat(x) {ev_float, #x}, +#define PRVM_DECLARE_menuglobalvector(x) {ev_vector, #x}, +#define PRVM_DECLARE_menuglobalstring(x) {ev_string, #x}, +#define PRVM_DECLARE_menuglobaledict(x) {ev_entity, #x}, +#define PRVM_DECLARE_menuglobalfunction(x) {ev_function, #x}, +#define PRVM_DECLARE_serverfieldfloat(x) +#define PRVM_DECLARE_serverfieldvector(x) +#define PRVM_DECLARE_serverfieldstring(x) +#define PRVM_DECLARE_serverfieldedict(x) +#define PRVM_DECLARE_serverfieldfunction(x) +#define PRVM_DECLARE_clientfieldfloat(x) +#define PRVM_DECLARE_clientfieldvector(x) +#define PRVM_DECLARE_clientfieldstring(x) +#define PRVM_DECLARE_clientfieldedict(x) +#define PRVM_DECLARE_clientfieldfunction(x) +#define PRVM_DECLARE_menufieldfloat(x) +#define PRVM_DECLARE_menufieldvector(x) +#define PRVM_DECLARE_menufieldstring(x) +#define PRVM_DECLARE_menufieldedict(x) +#define PRVM_DECLARE_menufieldfunction(x) +#define PRVM_DECLARE_serverfunction(x) +#define PRVM_DECLARE_clientfunction(x) +#define PRVM_DECLARE_menufunction(x) +#define PRVM_DECLARE_field(x) +#define PRVM_DECLARE_global(x) +#define PRVM_DECLARE_function(x) +#include "prvm_offsets.h" +#undef PRVM_DECLARE_serverglobalfloat +#undef PRVM_DECLARE_serverglobalvector +#undef PRVM_DECLARE_serverglobalstring +#undef PRVM_DECLARE_serverglobaledict +#undef PRVM_DECLARE_serverglobalfunction +#undef PRVM_DECLARE_clientglobalfloat +#undef PRVM_DECLARE_clientglobalvector +#undef PRVM_DECLARE_clientglobalstring +#undef PRVM_DECLARE_clientglobaledict +#undef PRVM_DECLARE_clientglobalfunction +#undef PRVM_DECLARE_menuglobalfloat +#undef PRVM_DECLARE_menuglobalvector +#undef PRVM_DECLARE_menuglobalstring +#undef PRVM_DECLARE_menuglobaledict +#undef PRVM_DECLARE_menuglobalfunction +#undef PRVM_DECLARE_serverfieldfloat +#undef PRVM_DECLARE_serverfieldvector +#undef PRVM_DECLARE_serverfieldstring +#undef PRVM_DECLARE_serverfieldedict +#undef PRVM_DECLARE_serverfieldfunction +#undef PRVM_DECLARE_clientfieldfloat +#undef PRVM_DECLARE_clientfieldvector +#undef PRVM_DECLARE_clientfieldstring +#undef PRVM_DECLARE_clientfieldedict +#undef PRVM_DECLARE_clientfieldfunction +#undef PRVM_DECLARE_menufieldfloat +#undef PRVM_DECLARE_menufieldvector +#undef PRVM_DECLARE_menufieldstring +#undef PRVM_DECLARE_menufieldedict +#undef PRVM_DECLARE_menufieldfunction +#undef PRVM_DECLARE_serverfunction +#undef PRVM_DECLARE_clientfunction +#undef PRVM_DECLARE_menufunction +#undef PRVM_DECLARE_field +#undef PRVM_DECLARE_global +#undef PRVM_DECLARE_function +}; + +static int m_numrequiredglobals = sizeof(m_required_globals) / sizeof(m_required_globals[0]); + void MR_SetRouting (qboolean forceold); void MP_Error(const char *format, ...) DP_FUNC_PRINTF(1); @@ -5103,9 +5220,9 @@ void MP_KeyEvent (int key, int ascii, qboolean downevent) prog->globals.generic[OFS_PARM0] = (float) key; prog->globals.generic[OFS_PARM1] = (float) ascii; if (downevent) - PRVM_ExecuteProgram(prog->funcoffsets.m_keydown,"m_keydown(float key, float ascii) required"); - else if (prog->funcoffsets.m_keyup) - PRVM_ExecuteProgram(prog->funcoffsets.m_keyup,"m_keyup(float key, float ascii) required"); + PRVM_ExecuteProgram(PRVM_menufunction(m_keydown),"m_keydown(float key, float ascii) required"); + else if (PRVM_menufunction(m_keyup)) + PRVM_ExecuteProgram(PRVM_menufunction(m_keyup),"m_keyup(float key, float ascii) required"); PRVM_End; } @@ -5132,7 +5249,7 @@ void MP_Draw (void) // FIXME: this really shouldnt error out lest we have a very broken refdef state...? // or does it kill the server too? - PRVM_ExecuteProgram(prog->funcoffsets.m_draw,"m_draw() required"); + PRVM_ExecuteProgram(PRVM_menufunction(m_draw),"m_draw() required"); PRVM_End; @@ -5142,13 +5259,23 @@ void MP_Draw (void) R_SelectScene( RST_CLIENT ); } -void MP_ToggleMenu_f (void) +void MP_ToggleMenu(int mode) { PRVM_Begin; PRVM_SetProg(PRVM_MENUPROG); - PRVM_ExecuteProgram(prog->funcoffsets.m_toggle,"m_toggle() required"); + prog->globals.generic[OFS_PARM0] = (float) mode; + PRVM_ExecuteProgram(PRVM_menufunction(m_toggle),"m_toggle() required"); + + PRVM_End; +} +void MP_NewMap(void) +{ + PRVM_Begin; + PRVM_SetProg(PRVM_MENUPROG); + if (PRVM_menufunction(m_newmap)) + PRVM_ExecuteProgram(PRVM_menufunction(m_newmap),"m_newmap() required"); PRVM_End; } @@ -5157,7 +5284,7 @@ void MP_Shutdown (void) PRVM_Begin; PRVM_SetProg(PRVM_MENUPROG); - PRVM_ExecuteProgram(prog->funcoffsets.m_shutdown,"m_shutdown() required"); + PRVM_ExecuteProgram(PRVM_menufunction(m_shutdown),"m_shutdown() required"); // reset key_dest key_dest = key_game; @@ -5173,7 +5300,6 @@ void MP_Init (void) PRVM_Begin; PRVM_InitProg(PRVM_MENUPROG); - prog->headercrc = M_PROGHEADER_CRC; prog->edictprivate_size = 0; // no private struct used prog->name = M_NAME; prog->num_edicts = 1; @@ -5189,7 +5315,7 @@ void MP_Init (void) // allocate the mempools prog->progs_mempool = Mem_AllocPool(M_PROG_FILENAME, 0, NULL); - PRVM_LoadProgs(M_PROG_FILENAME, m_numrequiredfunc, m_required_func, 0, NULL, 0, NULL); + PRVM_LoadProgs(M_PROG_FILENAME, m_numrequiredfunc, m_required_func, m_numrequiredfields, m_required_fields, m_numrequiredglobals, m_required_globals); // note: OP_STATE is not supported by menu qc, we don't even try to detect // it here @@ -5197,75 +5323,59 @@ void MP_Init (void) in_client_mouse = true; // call the prog init - PRVM_ExecuteProgram(prog->funcoffsets.m_init,"m_init() required"); + PRVM_ExecuteProgram(PRVM_menufunction(m_init),"m_init() required"); PRVM_End; } -void MP_Restart(void) -{ - MP_Init(); -} - //============================================================================ // Menu router void (*MR_KeyEvent) (int key, int ascii, qboolean downevent); void (*MR_Draw) (void); -void (*MR_ToggleMenu_f) (void); +void (*MR_ToggleMenu) (int mode); void (*MR_Shutdown) (void); +void (*MR_NewMap) (void); void MR_SetRouting(qboolean forceold) { - static qboolean m_init = FALSE, mp_init = FALSE; - // if the menu prog isnt available or forceqmenu ist set, use the old menu if(!FS_FileExists(M_PROG_FILENAME) || forceqmenu.integer || forceold) { // set menu router function pointers MR_KeyEvent = M_KeyEvent; MR_Draw = M_Draw; - MR_ToggleMenu_f = M_ToggleMenu_f; + MR_ToggleMenu = M_ToggleMenu; MR_Shutdown = M_Shutdown; - - // init - if(!m_init) - { - M_Init(); - m_init = TRUE; - } - else - M_Restart(); + MR_NewMap = M_NewMap; + M_Init(); } else { // set menu router function pointers MR_KeyEvent = MP_KeyEvent; MR_Draw = MP_Draw; - MR_ToggleMenu_f = MP_ToggleMenu_f; + MR_ToggleMenu = MP_ToggleMenu; MR_Shutdown = MP_Shutdown; - - if(!mp_init) - { - MP_Init(); - mp_init = TRUE; - } - else - MP_Restart(); + MR_NewMap = MP_NewMap; + MP_Init(); } } void MR_Restart(void) { - MR_Shutdown (); + if(MR_Shutdown) + MR_Shutdown (); MR_SetRouting (FALSE); } void Call_MR_ToggleMenu_f(void) { + int m; + m = ((Cmd_Argc() < 2) ? -1 : atoi(Cmd_Argv(1))); Host_StartVideo(); - if(MR_ToggleMenu_f) - MR_ToggleMenu_f(); + if(MR_ToggleMenu) + MR_ToggleMenu(m); } void MR_Init_Commands(void)