From afb1f2aebcd0d0fbaa0c1622ba078ebf33e835c8 Mon Sep 17 00:00:00 2001 From: danij Date: Tue, 18 Feb 2014 00:18:44 +0000 Subject: [PATCH] libcommon: Switched g_game.c, hu_menu.c to C++ --- doomsday/plugins/common/common.pri | 4 +- doomsday/plugins/common/include/hu_lib.h | 118 +- doomsday/plugins/common/include/hu_menu.h | 6 +- doomsday/plugins/common/include/hu_stuff.h | 47 +- doomsday/plugins/common/include/m_ctrl.h | 8 + doomsday/plugins/common/include/x_hair.h | 9 +- .../common/src/{g_game.c => g_game.cpp} | 407 +- doomsday/plugins/common/src/hu_menu.c | 6590 ---------------- doomsday/plugins/common/src/hu_menu.cpp | 6687 +++++++++++++++++ doomsday/plugins/doom/include/d_console.h | 8 + doomsday/plugins/doom/include/m_cheat.h | 8 + doomsday/plugins/doom/include/p_setup.h | 9 + doomsday/plugins/doom64/include/d_console.h | 8 + doomsday/plugins/doom64/include/p_setup.h | 9 + doomsday/plugins/heretic/include/h_console.h | 8 + doomsday/plugins/heretic/include/in_lude.h | 14 +- doomsday/plugins/heretic/include/m_cheat.h | 8 + doomsday/plugins/heretic/include/p_setup.h | 9 + doomsday/plugins/hexen/include/in_lude.h | 14 +- doomsday/plugins/hexen/include/m_cheat.h | 8 + doomsday/plugins/hexen/include/p_setup.h | 9 + doomsday/plugins/hexen/include/x_console.h | 8 + 22 files changed, 7176 insertions(+), 6820 deletions(-) rename doomsday/plugins/common/src/{g_game.c => g_game.cpp} (93%) delete mode 100644 doomsday/plugins/common/src/hu_menu.c create mode 100644 doomsday/plugins/common/src/hu_menu.cpp diff --git a/doomsday/plugins/common/common.pri b/doomsday/plugins/common/common.pri index c9f7964fff..9c986457a6 100644 --- a/doomsday/plugins/common/common.pri +++ b/doomsday/plugins/common/common.pri @@ -88,7 +88,7 @@ SOURCES += \ $$common_src/g_controls.c \ $$common_src/g_defs.c \ $$common_src/g_eventsequence.cpp \ - $$common_src/g_game.c \ + $$common_src/g_game.cpp \ $$common_src/g_update.c \ $$common_src/gamerules.c \ $$common_src/gamestatereader.cpp \ @@ -100,7 +100,7 @@ SOURCES += \ $$common_src/hu_inventory.c \ $$common_src/hu_lib.c \ $$common_src/hu_log.c \ - $$common_src/hu_menu.c \ + $$common_src/hu_menu.cpp \ $$common_src/hu_msg.c \ $$common_src/hu_pspr.c \ $$common_src/hu_stuff.cpp \ diff --git a/doomsday/plugins/common/include/hu_lib.h b/doomsday/plugins/common/include/hu_lib.h index 09dde3fd64..259c714611 100644 --- a/doomsday/plugins/common/include/hu_lib.h +++ b/doomsday/plugins/common/include/hu_lib.h @@ -214,6 +214,10 @@ typedef struct mn_object_s { int timer; } mn_object_t; +#ifdef __cplusplus +extern "C" { +#endif + mn_obtype_e MNObject_Type(const mn_object_t* obj); struct mn_page_s* MNObject_Page(const mn_object_t* obj); @@ -298,6 +302,10 @@ dd_bool MNObject_HasAction(mn_object_t* obj, mn_actionid_t action); */ int MNObject_ExecAction(mn_object_t* obj, mn_actionid_t action, void* paramaters); +#ifdef __cplusplus +} // extern "C" +#endif + typedef enum { MENU_COLOR1 = 0, MENU_COLOR2, @@ -380,6 +388,10 @@ typedef struct mn_page_s { int timer; } mn_page_t; +#ifdef __cplusplus +extern "C" { +#endif + void MNPage_Initialize(mn_page_t* page); /// Call the ticker routine for each object. @@ -461,6 +473,10 @@ int MNPage_LineHeight(mn_page_t *page/*, lineOffset = 0*/); /// @return Current time in tics since page activation. int MNPage_Timer(mn_page_t* page); +#ifdef __cplusplus +} // extern "C" +#endif + /** * Rect objects. */ @@ -472,6 +488,10 @@ typedef struct mndata_rect_s { patchid_t patch; } mndata_rect_t; +#ifdef __cplusplus +extern "C" { +#endif + mn_object_t* MNRect_New(void); void MNRect_Delete(mn_object_t* ob); @@ -488,6 +508,10 @@ void MNRect_UpdateGeometry(mn_object_t* ob, mn_page_t* page); */ void MNRect_SetBackgroundPatch(mn_object_t* ob, patchid_t patch); +#ifdef __cplusplus +} // extern "C" +#endif + /** * @defgroup mnTextFlags MNText Flags */ @@ -508,6 +532,10 @@ typedef struct mndata_text_s { int flags; } mndata_text_t; +#ifdef __cplusplus +extern "C" { +#endif + mn_object_t* MNText_New(void); void MNText_Delete(mn_object_t* ob); @@ -517,6 +545,10 @@ void MNText_UpdateGeometry(mn_object_t* ob, mn_page_t* page); int MNText_SetFlags(mn_object_t* ob, flagop_t op, int flags); +#ifdef __cplusplus +} // extern "C" +#endif + /** * @defgroup mnButtonFlags MNButton Flags */ @@ -544,6 +576,10 @@ typedef struct mndata_button_s { int flags; } mndata_button_t; +#ifdef __cplusplus +extern "C" { +#endif + mn_object_t* MNButton_New(void); void MNButton_Delete(mn_object_t* ob); @@ -554,6 +590,10 @@ void MNButton_UpdateGeometry(mn_object_t* ob, mn_page_t* page); int MNButton_SetFlags(mn_object_t* ob, flagop_t op, int flags); +#ifdef __cplusplus +} // extern "C" +#endif + /** * Edit field. */ @@ -587,6 +627,10 @@ typedef struct mndata_edit_s { int data2; } mndata_edit_t; +#ifdef __cplusplus +extern "C" { +#endif + mn_object_t* MNEdit_New(void); void MNEdit_Delete(mn_object_t* ob); @@ -617,6 +661,10 @@ const ddstring_t* MNEdit_Text(mn_object_t* ob); */ void MNEdit_SetText(mn_object_t* ob, int flags, const char* string); +#ifdef __cplusplus +} // extern "C" +#endif + /** * List selection. */ @@ -641,6 +689,10 @@ typedef struct mndata_list_s { int numvis; } mndata_list_t; +#ifdef __cplusplus +extern "C" { +#endif + mn_object_t* MNList_New(void); void MNList_Delete(mn_object_t* ob); @@ -693,6 +745,10 @@ dd_bool MNList_SelectItem(mn_object_t* ob, int flags, int itemIndex); */ dd_bool MNList_SelectItemByValue(mn_object_t* ob, int flags, int itemIndex); +#ifdef __cplusplus +} // extern "C" +#endif + /** * Color preview box. */ @@ -711,6 +767,10 @@ typedef struct mndata_colorbox_s { void* data4; } mndata_colorbox_t; +#ifdef __cplusplus +extern "C" { +#endif + mn_object_t* MNColorBox_New(void); void MNColorBox_Delete(mn_object_t* ob); @@ -777,6 +837,10 @@ dd_bool MNColorBox_SetAlphaf(mn_object_t* ob, int flags, float alpha); */ dd_bool MNColorBox_CopyColor(mn_object_t* ob, int flags, const mn_object_t* otherObj); +#ifdef __cplusplus +} // extern "C" +#endif + /** * Graphical slider. */ @@ -811,6 +875,10 @@ typedef struct mndata_slider_s { void* data5; } mndata_slider_t; +#ifdef __cplusplus +extern "C" { +#endif + mn_object_t* MNSlider_New(void); void MNSlider_Delete(mn_object_t* ob); @@ -839,6 +907,10 @@ float MNSlider_Value(const mn_object_t* ob); */ void MNSlider_SetValue(mn_object_t* ob, int flags, float value); +#ifdef __cplusplus +} // extern "C" +#endif + /** * Mobj preview visual. */ @@ -852,6 +924,10 @@ typedef struct mndata_mobjpreview_s { int plrClass; /// Player class identifier. } mndata_mobjpreview_t; +#ifdef __cplusplus +extern "C" { +#endif + mn_object_t* MNMobjPreview_New(void); void MNMobjPreview_Delete(mn_object_t* ob); @@ -864,6 +940,10 @@ void MNMobjPreview_SetTranslationMap(mn_object_t* ob, int tMap); void MNMobjPreview_Drawer(mn_object_t* ob, const Point2Raw* origin); void MNMobjPreview_UpdateGeometry(mn_object_t* ob, mn_page_t* page); +#ifdef __cplusplus +} // extern "C" +#endif + // Menu render state: typedef struct mn_rendstate_s { float pageAlpha; @@ -872,7 +952,8 @@ typedef struct mn_rendstate_s { float textColors[MENU_COLOR_COUNT][4]; fontid_t textFonts[MENU_FONT_COUNT]; } mn_rendstate_t; -extern const mn_rendstate_t* mnRendState; + +DENG_EXTERN_C mn_rendstate_t const *mnRendState; /** * @defgroup menuEffectFlags Menu Effect Flags @@ -885,6 +966,10 @@ extern const mn_rendstate_t* mnRendState; #define MEF_EVERYTHING (MEF_TEXT_TYPEIN|MEF_TEXT_SHADOW|MEF_TEXT_GLITTER) ///@} +#ifdef __cplusplus +extern "C" { +#endif + short MN_MergeMenuEffectWithDrawTextFlags(short f); mn_object_t* MN_MustFindObjectOnPage(mn_page_t* page, int group, int flags); @@ -896,6 +981,10 @@ void MN_DrawPage(mn_page_t* page, float alpha, dd_bool showFocusCursor); */ void Hu_MenuCommand(menucommand_e cmd); +#ifdef __cplusplus +} // extern "C" +#endif + typedef enum { GUI_NONE, GUI_BOX, @@ -982,6 +1071,10 @@ typedef struct uiwidget_s { void* typedata; } uiwidget_t; +#ifdef __cplusplus +extern "C" { +#endif + void GUI_DrawWidget(uiwidget_t* obj, const Point2Raw* origin); void GUI_DrawWidgetXY(uiwidget_t* obj, int x, int y); @@ -1018,6 +1111,10 @@ void UIWidget_SetMaximumSize(uiwidget_t* obj, const Size2Raw* size); void UIWidget_SetMaximumWidth(uiwidget_t* obj, int width); +#ifdef __cplusplus +} // extern "C" +#endif + /** * @defgroup uiWidgetGroupFlags UIWidget Group Flags */ @@ -1039,12 +1136,20 @@ typedef struct { uiwidgetid_t* widgetIds; } guidata_group_t; +#ifdef __cplusplus +extern "C" { +#endif + void UIGroup_AddWidget(uiwidget_t* obj, uiwidget_t* other); int UIGroup_Flags(uiwidget_t* obj); void UIGroup_SetFlags(uiwidget_t* obj, int flags); void UIGroup_UpdateGeometry(uiwidget_t* obj); +#ifdef __cplusplus +} // extern "C" +#endif + typedef struct { int value; } guidata_health_t; @@ -1206,6 +1311,10 @@ typedef struct { } guidata_flight_t; #endif +#ifdef __cplusplus +extern "C" { +#endif + void GUI_Register(void); void GUI_Init(void); @@ -1225,9 +1334,14 @@ uiwidgetid_t GUI_CreateWidget(guiwidgettype_t type, int player, int alignFlags, uiwidgetid_t GUI_CreateGroup(int groupFlags, int player, int alignFlags, order_t order, int padding); +#ifdef __cplusplus +} // extern "C" +#endif + typedef struct ui_rendstate_s { float pageAlpha; } ui_rendstate_t; -extern const ui_rendstate_t* uiRendState; + +DENG_EXTERN_C const ui_rendstate_t* uiRendState; #endif /* LIBCOMMON_UI_LIBRARY_H */ diff --git a/doomsday/plugins/common/include/hu_menu.h b/doomsday/plugins/common/include/hu_menu.h index ee04b9ec53..5a722ab16b 100644 --- a/doomsday/plugins/common/include/hu_menu.h +++ b/doomsday/plugins/common/include/hu_menu.h @@ -33,6 +33,9 @@ #include "dd_types.h" #include "hu_lib.h" +DENG_EXTERN_C int menuTime; +DENG_EXTERN_C dd_bool menuNominatingQuickSaveSlot; + #ifdef __cplusplus extern "C" { #endif @@ -86,9 +89,6 @@ extern "C" { #define MENU_CURSOR_FRAMECOUNT 2 #define MENU_CURSOR_TICSPERFRAME 8 -extern int menuTime; -extern dd_bool menuNominatingQuickSaveSlot; - /// Register the console commands, variables, etc..., of this module. void Hu_MenuRegister(void); diff --git a/doomsday/plugins/common/include/hu_stuff.h b/doomsday/plugins/common/include/hu_stuff.h index cffc25ec81..8087232852 100644 --- a/doomsday/plugins/common/include/hu_stuff.h +++ b/doomsday/plugins/common/include/hu_stuff.h @@ -27,10 +27,26 @@ #include "doomsday.h" #include "gl_drawpatch.h" -#ifdef __cplusplus -extern "C" { +DENG_EXTERN_C patchid_t *pMapNames; // Name graphics of each map. +DENG_EXTERN_C uint pMapNamesSize; + +#if __JHERETIC__ || __JHEXEN__ +DENG_EXTERN_C patchid_t pInvItemBox; +DENG_EXTERN_C patchid_t pInvSelectBox; +DENG_EXTERN_C patchid_t pInvPageLeft[2]; +DENG_EXTERN_C patchid_t pInvPageRight[2]; #endif +#if __JDOOM__ || __JDOOM64__ +// Quit messages. +#define NUM_QUITMESSAGES 22 +DENG_EXTERN_C char const *endmsg[NUM_QUITMESSAGES + 1]; +#endif + +DENG_EXTERN_C dd_bool shiftdown; +DENG_EXTERN_C char const shiftXForm[]; +DENG_EXTERN_C patchid_t borderPatches[8]; + // The fonts. typedef enum { GF_FIRST = 1, @@ -50,6 +66,9 @@ typedef enum { NUM_GAME_FONTS } gamefontid_t; +DENG_EXTERN_C fontid_t fonts[NUM_GAME_FONTS]; +#define FID(idx) (fonts[idx]) + // Vector graphics. enum { VG_FIRST = 1, @@ -67,30 +86,10 @@ enum { NUM_VECTOR_GRAPHICS }; /* svgid_t*/ -#define FID(idx) (fonts[idx]) - -extern fontid_t fonts[NUM_GAME_FONTS]; - -extern patchid_t* pMapNames; // Name graphics of each map. -extern uint pMapNamesSize; - -#if __JHERETIC__ || __JHEXEN__ -extern patchid_t pInvItemBox; -extern patchid_t pInvSelectBox; -extern patchid_t pInvPageLeft[2]; -extern patchid_t pInvPageRight[2]; -#endif - -#if __JDOOM__ || __JDOOM64__ -// Quit messages. -#define NUM_QUITMESSAGES 22 -extern const char* endmsg[NUM_QUITMESSAGES + 1]; +#ifdef __cplusplus +extern "C" { #endif -extern dd_bool shiftdown; -extern const char shiftXForm[]; -extern patchid_t borderPatches[8]; - void Hu_LoadData(void); void Hu_Drawer(void); void Hu_Ticker(void); diff --git a/doomsday/plugins/common/include/m_ctrl.h b/doomsday/plugins/common/include/m_ctrl.h index 050a80f5ea..3e5c6a3919 100644 --- a/doomsday/plugins/common/include/m_ctrl.h +++ b/doomsday/plugins/common/include/m_ctrl.h @@ -31,6 +31,10 @@ #include "hu_lib.h" +#ifdef __cplusplus +extern "C" { +#endif + void Hu_MenuInitControlsPage(void); void Hu_MenuDrawControlsPage(mn_page_t* page, const Point2Raw* origin); void Hu_MenuControlGrabDrawer(const char* niceName, float alpha); @@ -57,4 +61,8 @@ void MNBindings_UpdateGeometry(mn_object_t* ob, mn_page_t* page); const char* MNBindings_ControlName(mn_object_t* ob); +#ifdef __cplusplus +} // extern "C" +#endif + #endif /// LIBCOMMON_MENU_CONTROLS diff --git a/doomsday/plugins/common/include/x_hair.h b/doomsday/plugins/common/include/x_hair.h index 4a937079ad..1bbcb435f8 100644 --- a/doomsday/plugins/common/include/x_hair.h +++ b/doomsday/plugins/common/include/x_hair.h @@ -23,9 +23,12 @@ #ifndef LIBCOMMON_HUD_CROSSHAIR_H #define LIBCOMMON_HUD_CROSSHAIR_H - #define NUM_XHAIRS (5) +#ifdef __cplusplus +extern "C" { +#endif + void X_Drawer(int player); /** @@ -33,4 +36,8 @@ void X_Drawer(int player); */ void X_Register(void); +#ifdef __cplusplus +} // extern "C" +#endif + #endif // LIBCOMMON_HUD_CROSSHAIR_H diff --git a/doomsday/plugins/common/src/g_game.c b/doomsday/plugins/common/src/g_game.cpp similarity index 93% rename from doomsday/plugins/common/src/g_game.c rename to doomsday/plugins/common/src/g_game.cpp index 7e2517995b..1341f21728 100644 --- a/doomsday/plugins/common/src/g_game.c +++ b/doomsday/plugins/common/src/g_game.cpp @@ -80,30 +80,30 @@ struct missileinfo_s { MonsterMissileInfo[] = { #if __JDOOM__ || __JDOOM64__ - {MT_BRUISERSHOT, {15, 20}}, - {MT_HEADSHOT, {10, 20}}, - {MT_TROOPSHOT, {10, 20}}, + { MT_BRUISERSHOT, {15, 20} }, + { MT_HEADSHOT, {10, 20} }, + { MT_TROOPSHOT, {10, 20} }, # if __JDOOM64__ - {MT_BRUISERSHOTRED, {15, 20}}, - {MT_NTROSHOT, {20, 40}}, + { MT_BRUISERSHOTRED, {15, 20} }, + { MT_NTROSHOT, {20, 40} }, # endif #elif __JHERETIC__ - {MT_IMPBALL, {10, 20}}, - {MT_MUMMYFX1, {9, 18}}, - {MT_KNIGHTAXE, {9, 18}}, - {MT_REDAXE, {9, 18}}, - {MT_BEASTBALL, {12, 20}}, - {MT_WIZFX1, {18, 24}}, - {MT_SNAKEPRO_A, {14, 20}}, - {MT_SNAKEPRO_B, {14, 20}}, - {MT_HEADFX1, {13, 20}}, - {MT_HEADFX3, {10, 18}}, - {MT_MNTRFX1, {20, 26}}, - {MT_MNTRFX2, {14, 20}}, - {MT_SRCRFX1, {20, 28}}, - {MT_SOR2FX1, {20, 28}}, + { MT_IMPBALL, {10, 20} }, + { MT_MUMMYFX1, {9, 18} }, + { MT_KNIGHTAXE, {9, 18} }, + { MT_REDAXE, {9, 18} }, + { MT_BEASTBALL, {12, 20} }, + { MT_WIZFX1, {18, 24} }, + { MT_SNAKEPRO_A, {14, 20} }, + { MT_SNAKEPRO_B, {14, 20} }, + { MT_HEADFX1, {13, 20} }, + { MT_HEADFX3, {10, 18} }, + { MT_MNTRFX1, {20, 26} }, + { MT_MNTRFX2, {14, 20} }, + { MT_SRCRFX1, {20, 28} }, + { MT_SOR2FX1, {20, 28} }, #endif - {-1, {-1, -1}} // Terminator + { mobjtype_t(-1), {-1, -1} } }; #endif @@ -120,44 +120,45 @@ D_CMD(SaveGame); D_CMD(OpenSaveMenu); D_CMD(WarpMap); -void G_PlayerReborn(int player); -void G_DoReborn(int playernum); +void G_PlayerReborn(int player); +void G_DoReborn(int playernum); dd_bool G_StartDebriefing(); -typedef struct { +struct loadmap_params_t +{ Uri *mapUri; dd_bool revisit; -} loadmap_params_t; -int G_DoLoadMap(loadmap_params_t* params); - -void G_DoLoadGame(void); -void G_DoPlayDemo(void); -void G_DoMapCompleted(void); -void G_DoEndDebriefing(void); -void G_DoVictory(void); -void G_DoLeaveMap(void); -void G_DoRestartMap(void); -void G_DoSaveGame(void); -void G_DoScreenShot(void); -void G_DoQuitGame(void); - -void G_StopDemo(void); +}; +int G_DoLoadMap(loadmap_params_t *parm); + +void G_DoLoadGame(); +void G_DoPlayDemo(); +void G_DoMapCompleted(); +void G_DoEndDebriefing(); +void G_DoVictory(); +void G_DoLeaveMap(); +void G_DoRestartMap(); +void G_DoSaveGame(); +void G_DoScreenShot(); +void G_DoQuitGame(); + +void G_StopDemo(); /** * Updates game status cvars for the specified player. */ -void G_UpdateGSVarsForPlayer(player_t* pl); +void G_UpdateGSVarsForPlayer(player_t *pl); /** * Updates game status cvars for the current map. */ -void G_UpdateGSVarsForMap(void); +void G_UpdateGSVarsForMap(); -void R_LoadVectorGraphics(void); +void R_LoadVectorGraphics(); -int Hook_DemoStop(int hookType, int val, void* parameters); +int Hook_DemoStop(int hookType, int val, void *parm); -static void G_InitNewGame(void); +static void G_InitNewGame(); game_config_t cfg; // The global cfg. @@ -178,7 +179,7 @@ dd_bool secretExit; #endif #if __JHEXEN__ -uint mapHub = 0; +uint mapHub; #endif dd_bool monsterInfight; @@ -188,20 +189,20 @@ player_t players[MAXPLAYERS]; int totalKills, totalItems, totalSecret; // For intermission. dd_bool singledemo; // Quit after playing a demo from cmdline. -dd_bool briefDisabled = false; +dd_bool briefDisabled; dd_bool precache = true; // If @c true, load all graphics at start. -dd_bool customPal = false; // If @c true, a non-IWAD palette is in use. +dd_bool customPal; // If @c true, a non-IWAD palette is in use. #if __JDOOM__ || __JDOOM64__ || __JHERETIC__ wbstartstruct_t wmInfo; // Params for world map / intermission. #endif // Game Action Variables: -int gaSaveGameSlot = 0; +int gaSaveGameSlot; dd_bool gaSaveGameGenerateName = true; -ddstring_t* gaSaveGameName; -int gaLoadGameSlot = 0; +ddstring_t *gaSaveGameName; +int gaLoadGameSlot; #if __JDOOM__ || __JDOOM64__ mobj_t *bodyQueue[BODYQUEUESIZE]; @@ -209,22 +210,22 @@ int bodyQueueSlot; #endif // vars used with game status cvars -int gsvEpisode = 0; -int gsvMap = 0; +int gsvEpisode; +int gsvMap; char *gsvMapAuthor = "Unknown"; int gsvMapMusic = -1; char *gsvMapTitle = "Unknown"; -int gsvInMap = 0; -int gsvCurrentMusic = 0; +int gsvInMap; +int gsvCurrentMusic; -int gsvArmor = 0; -int gsvHealth = 0; +int gsvArmor; +int gsvHealth; #if !__JHEXEN__ -int gsvKills = 0; -int gsvItems = 0; -int gsvSecrets = 0; +int gsvKills; +int gsvItems; +int gsvSecrets; #endif int gsvCurrentWeapon; @@ -412,7 +413,7 @@ static GameRuleset dRules; static gameaction_t gameAction; static dd_bool quitInProgress; -void G_Register(void) +void G_Register() { int i; @@ -435,7 +436,7 @@ void G_Register(void) #endif } -dd_bool G_QuitInProgress(void) +dd_bool G_QuitInProgress() { return quitInProgress; } @@ -448,7 +449,7 @@ void G_SetGameAction(gameaction_t action) gameAction = action; } -gameaction_t G_GameAction(void) +gameaction_t G_GameAction() { return gameAction; } @@ -457,7 +458,7 @@ gameaction_t G_GameAction(void) * Common Pre Game Initialization routine. * Game-specfic pre init actions should be placed in eg D_PreInit() (for jDoom) */ -void G_CommonPreInit(void) +void G_CommonPreInit() { int i, j; @@ -576,7 +577,7 @@ void Mobj_UpdateTranslationClassAndMap(mobj_t* mo) } #endif // __JHEXEN__ -void R_LoadColorPalettes(void) +void R_LoadColorPalettes() { #define PALLUMPNAME "PLAYPAL" #define PALENTRIES (256) @@ -691,59 +692,60 @@ void R_LoadColorPalettes(void) * @todo Read this information from a definition (ideally with more user * friendly mnemonics...). */ -void R_LoadVectorGraphics(void) +void R_LoadVectorGraphics() { -#define R (1.0f) -#define NUMITEMS(x) (sizeof(x)/sizeof((x)[0])) +#define R (1.0f) +#define NUMITEMS(x) (sizeof(x)/sizeof((x)[0])) +#define Pt Point2Rawf - const Point2Rawf keyPoints[] = { - {-3 * R / 4, 0}, {-3 * R / 4, -R / 4}, // Mid tooth. - { 0, 0}, { -R, 0}, { -R, -R / 2}, // Shaft and end tooth. + Point2Rawf const keyPoints[] = { + Pt(-3 * R / 4, 0), Pt(-3 * R / 4, -R / 4), // Mid tooth. + Pt( 0, 0), Pt( -R, 0), Pt( -R, -R / 2), // Shaft and end tooth. - { 0, 0}, {R / 4, -R / 2}, // Bow. - {R / 2, -R / 2}, {R / 2, R / 2}, - {R / 4, R / 2}, { 0, 0}, + Pt( 0, 0), Pt(R / 4, -R / 2), // Bow. + Pt(R / 2, -R / 2), Pt(R / 2, R / 2), + Pt(R / 4, R / 2), Pt( 0, 0), }; - const def_svgline_t key[] = { + def_svgline_t const key[] = { { 2, &keyPoints[ 0] }, { 3, &keyPoints[ 2] }, { 6, &keyPoints[ 5] } }; - const Point2Rawf thintrianglePoints[] = { - {-R / 2, R - R / 2}, - { R, 0}, // ` - {-R / 2, -R + R / 2}, // / - {-R / 2, R - R / 2} // |> + Point2Rawf const thintrianglePoints[] = { + Pt(-R / 2, R - R / 2), + Pt( R, 0), // ` + Pt(-R / 2, -R + R / 2), // / + Pt(-R / 2, R - R / 2) // |> }; - const def_svgline_t thintriangle[] = { + def_svgline_t const thintriangle[] = { { 4, thintrianglePoints }, }; #if __JDOOM__ || __JDOOM64__ - const Point2Rawf arrowPoints[] = { - { -R + R / 8, 0}, { R, 0}, // ----- - { R - R / 2, -R / 4}, { R, 0}, { R - R / 2, R / 4}, // -----> - {-R - R / 8, -R / 4}, { -R + R / 8, 0}, {-R - R / 8, R / 4}, // >----> - {-R + R / 8, -R / 4}, {-R + 3 * R / 8, 0}, {-R + R / 8, R / 4}, // >>---> + Point2Rawf const arrowPoints[] = { + Pt( -R + R / 8, 0 ), Pt( R, 0), // ----- + Pt( R - R / 2, -R / 4), Pt( R, 0), Pt( R - R / 2, R / 4), // -----> + Pt(-R - R / 8, -R / 4), Pt( -R + R / 8, 0), Pt(-R - R / 8, R / 4), // >----> + Pt(-R + R / 8, -R / 4), Pt(-R + 3 * R / 8, 0), Pt(-R + R / 8, R / 4), // >>---> }; - const def_svgline_t arrow[] = { + def_svgline_t const arrow[] = { { 2, &arrowPoints[ 0] }, { 3, &arrowPoints[ 2] }, { 3, &arrowPoints[ 5] }, { 3, &arrowPoints[ 8] } }; #elif __JHERETIC__ || __JHEXEN__ - const Point2Rawf arrowPoints[] = { - {-R + R / 4, 0}, { 0, 0}, // center line. - {-R + R / 4, R / 8}, { R, 0}, {-R + R / 4, -R / 8}, // blade + Point2Rawf const arrowPoints[] = { + Pt(-R + R / 4, 0), Pt( 0, 0), // center line. + Pt(-R + R / 4, R / 8), Pt( R, 0), Pt(-R + R / 4, -R / 8), // blade - {-R + R / 8, -R / 4}, {-R + R / 4, -R / 4}, // guard - {-R + R / 4, R / 4}, {-R + R / 8, R / 4}, - {-R + R / 8, -R / 4}, + Pt(-R + R / 8, -R / 4), Pt(-R + R / 4, -R / 4), // guard + Pt(-R + R / 4, R / 4), Pt(-R + R / 8, R / 4), + Pt(-R + R / 8, -R / 4), - {-R + R / 8, -R / 8}, {-R - R / 4, -R / 8}, // hilt - {-R - R / 4, R / 8}, {-R + R / 8, R / 8}, + Pt(-R + R / 8, -R / 8), Pt(-R - R / 4, -R / 8), // hilt + Pt(-R - R / 4, R / 8), Pt(-R + R / 8, R / 8), }; - const def_svgline_t arrow[] = { + def_svgline_t const arrow[] = { { 2, &arrowPoints[ 0] }, { 3, &arrowPoints[ 2] }, { 5, &arrowPoints[ 5] }, @@ -751,22 +753,22 @@ void R_LoadVectorGraphics(void) }; #endif #if __JDOOM__ - const Point2Rawf cheatarrowPoints[] = { - { -R + R / 8, 0}, { R, 0}, // ----- - { R - R / 2, -R / 4}, { R, 0}, { R - R / 2, R / 4}, // -----> - {-R - R / 8, -R / 4}, { -R + R / 8, 0}, {-R - R / 8, R / 4}, // >----> - {-R + R / 8, -R / 4}, {-R + 3 * R / 8, 0}, {-R + R / 8, R / 4}, // >>---> + Point2Rawf const cheatarrowPoints[] = { + Pt( -R + R / 8, 0 ), Pt( R, 0), // ----- + Pt( R - R / 2, -R / 4), Pt( R, 0), Pt( R - R / 2, R / 4), // -----> + Pt(-R - R / 8, -R / 4), Pt( -R + R / 8, 0), Pt(-R - R / 8, R / 4), // >----> + Pt(-R + R / 8, -R / 4), Pt(-R + 3 * R / 8, 0), Pt(-R + R / 8, R / 4), // >>---> - { -R / 2, 0}, { -R / 2, -R / 6}, // >>-d---> - {-R / 2 + R / 6, -R / 6}, {-R / 2 + R / 6, R / 4}, + Pt( -R / 2, 0), Pt( -R / 2, -R / 6), // >>-d---> + Pt(-R / 2 + R / 6, -R / 6), Pt(-R / 2 + R / 6, R / 4), - { -R / 6, 0}, { -R / 6, -R / 6}, // >>-dd--> - { 0, -R / 6}, { 0, R / 4}, + Pt( -R / 6, 0), Pt( -R / 6, -R / 6), // >>-dd--> + Pt( 0, -R / 6), Pt( 0, R / 4), - { R / 6, R / 4}, { R / 6, -R / 7}, // >>-ddt-> - {R / 6 + R / 32, -R / 7 - R / 32}, {R / 6 + R / 10, -R / 7} + Pt( R / 6, R / 4), Pt( R / 6, -R / 7), // >>-ddt-> + Pt(R / 6 + R / 32, -R / 7 - R / 32), Pt(R / 6 + R / 10, -R / 7) }; - const def_svgline_t cheatarrow[] = { + def_svgline_t const cheatarrow[] = { { 2, &cheatarrowPoints[ 0] }, { 3, &cheatarrowPoints[ 2] }, { 3, &cheatarrowPoints[ 5] }, @@ -777,50 +779,50 @@ void R_LoadVectorGraphics(void) }; #endif - const Point2Rawf crossPoints[] = { // + (open center) - {-R, 0}, {-R / 5 * 2, 0}, - { 0, -R}, { 0, -R / 5 * 2}, - { R, 0}, { R / 5 * 2, 0}, - { 0, R}, { 0, R / 5 * 2} + Point2Rawf const crossPoints[] = { // + (open center) + Pt(-R, 0), Pt(-R / 5 * 2, 0), + Pt( 0, -R), Pt( 0, -R / 5 * 2), + Pt( R, 0), Pt( R / 5 * 2, 0), + Pt( 0, R), Pt( 0, R / 5 * 2) }; - const def_svgline_t cross[] = { + def_svgline_t const cross[] = { { 2, &crossPoints[0] }, { 2, &crossPoints[2] }, { 2, &crossPoints[4] }, { 2, &crossPoints[6] } }; - const Point2Rawf twinanglesPoints[] = { // > < - {-R, -R * 10 / 14}, {-(R - (R * 10 / 14)), 0}, {-R, R * 10 / 14}, // > - { R, -R * 10 / 14}, { R - (R * 10 / 14) , 0}, { R, R * 10 / 14}, // < + Point2Rawf const twinanglesPoints[] = { // > < + Pt(-R, -R * 10 / 14), Pt(-(R - (R * 10 / 14)), 0), Pt(-R, R * 10 / 14), // > + Pt( R, -R * 10 / 14), Pt( R - (R * 10 / 14) , 0), Pt( R, R * 10 / 14), // < }; - const def_svgline_t twinangles[] = { + def_svgline_t const twinangles[] = { { 3, &twinanglesPoints[0] }, { 3, &twinanglesPoints[3] } }; - const Point2Rawf squarePoints[] = { // square - {-R, -R}, {-R, R}, - { R, R}, { R, -R}, - {-R, -R} + Point2Rawf const squarePoints[] = { // square + Pt(-R, -R), Pt(-R, R), + Pt( R, R), Pt( R, -R), + Pt(-R, -R) }; - const def_svgline_t square[] = { + def_svgline_t const square[] = { { 5, squarePoints }, }; - const Point2Rawf squarecornersPoints[] = { // square (open center) - { -R, -R / 2}, {-R, -R}, {-R / 2, -R}, // topleft - {R / 2, -R}, { R, -R}, { R, -R / 2}, // topright - { -R, R / 2}, {-R, R}, {-R / 2, R}, // bottomleft - {R / 2, R}, { R, R}, { R, R / 2}, // bottomright + Point2Rawf const squarecornersPoints[] = { // square (open center) + Pt( -R, -R / 2), Pt(-R, -R), Pt(-R / 2, -R), // topleft + Pt(R / 2, -R), Pt( R, -R), Pt( R, -R / 2), // topright + Pt( -R, R / 2), Pt(-R, R), Pt(-R / 2, R), // bottomleft + Pt(R / 2, R), Pt( R, R), Pt( R, R / 2), // bottomright }; - const def_svgline_t squarecorners[] = { + def_svgline_t const squarecorners[] = { { 3, &squarecornersPoints[ 0] }, { 3, &squarecornersPoints[ 3] }, { 3, &squarecornersPoints[ 6] }, { 3, &squarecornersPoints[ 9] } }; - const Point2Rawf anglePoints[] = { // v - {-R, -R}, { 0, 0}, { R, -R} + Point2Rawf const anglePoints[] = { // v + Pt(-R, -R), Pt(0, 0), Pt(R, -R) }; - const def_svgline_t angle[] = { + def_svgline_t const angle[] = { { 3, anglePoints } }; @@ -838,8 +840,9 @@ void R_LoadVectorGraphics(void) R_NewSvg(VG_XHAIR4, squarecorners, NUMITEMS(squarecorners)); R_NewSvg(VG_XHAIR5, angle, NUMITEMS(angle)); -#undef NUMITEMS +#undef P #undef R +#undef NUMITEMS } /** @@ -856,7 +859,7 @@ fontid_t R_MustFindFontForName(const char* name) exit(1); // Unreachable. } -void R_InitRefresh(void) +void R_InitRefresh() { if(IS_DEDICATED) return; @@ -895,7 +898,7 @@ void R_InitRefresh(void) } } -void R_InitHud(void) +void R_InitHud() { Hu_LoadData(); @@ -919,7 +922,7 @@ void R_InitHud(void) * Game-specific post init actions should be placed in eg D_PostInit() * (for jDoom) and NOT here. */ -void G_CommonPostInit(void) +void G_CommonPostInit() { R_InitRefresh(); FI_StackInit(); @@ -954,7 +957,7 @@ void G_CommonPostInit(void) * Common game shutdown routine. * @note Game-specific actions should be placed in G_Shutdown rather than here. */ -void G_CommonShutdown(void) +void G_CommonShutdown() { Plug_RemoveHook(HOOK_DEMO_STOP, Hook_DemoStop); @@ -979,7 +982,7 @@ void G_CommonShutdown(void) * * @return The current game state. */ -gamestate_t G_GameState(void) +gamestate_t G_GameState() { return gameState; } @@ -987,8 +990,8 @@ gamestate_t G_GameState(void) static char const *getGameStateStr(gamestate_t state) { struct statename_s { - gamestate_t state; - const char* name; + gamestate_t state; + char const *name; } stateNames[] = { { GS_MAP, "GS_MAP" }, @@ -997,21 +1000,20 @@ static char const *getGameStateStr(gamestate_t state) { GS_STARTUP, "GS_STARTUP" }, { GS_WAITING, "GS_WAITING" }, { GS_INFINE, "GS_INFINE" }, - { -1, NULL } + { gamestate_t(-1), 0 } }; - uint i; - - for(i = 0; stateNames[i].name; ++i) + for(uint i = 0; stateNames[i].name; ++i) + { if(stateNames[i].state == state) return stateNames[i].name; - - return NULL; + } + return 0; } /** * Called when the gameui binding context is active. Triggers the menu. */ -int G_UIResponder(event_t* ev) +int G_UIResponder(event_t *ev) { // Handle "Press any key to continue" messages. if(Hu_MsgResponder(ev)) @@ -1108,7 +1110,7 @@ dd_bool G_StartFinale(const char* script, int flags, finale_mode_t mode, const c return true; } -void G_StartTitle(void) +void G_StartTitle() { ddfinale_t fin; @@ -1122,7 +1124,7 @@ void G_StartTitle(void) G_StartFinale(fin.script, FF_LOCAL, FIMODE_NORMAL, "title"); } -void G_StartHelp(void) +void G_StartHelp() { ddfinale_t fin; @@ -1146,7 +1148,7 @@ void G_StartHelp(void) * Prints a banner to the console containing information pertinent to the * current map (e.g., map title, author...). */ -static void printMapBanner(void) +static void printMapBanner() { char const *title = P_MapTitle(0/*current map*/); @@ -1175,7 +1177,7 @@ static void printMapBanner(void) App_Log(DE2_LOG_MAP, ""); } -void G_BeginMap(void) +void G_BeginMap() { G_ChangeGameState(GS_MAP); @@ -1213,7 +1215,7 @@ int G_EndGameResponse(msgresponse_t response, int userValue, void *userPointer) return true; } -void G_EndGame(void) +void G_EndGame() { if(G_QuitInProgress()) return; @@ -1412,14 +1414,14 @@ void G_UpdateGSVarsForPlayer(player_t* pl) for(i = 0; i < NUM_INVENTORYITEM_TYPES; ++i) { if(pl->plr->inGame && gameState == GS_MAP) - gsvInvItems[i] = P_InventoryCount(plrnum, IIT_FIRST + i); + gsvInvItems[i] = P_InventoryCount(plrnum, inventoryitemtype_t(IIT_FIRST + i)); else gsvInvItems[i] = 0; } #endif } -void G_UpdateGSVarsForMap(void) +void G_UpdateGSVarsForMap() { char const *mapAuthor = P_MapAuthor(0/*current map*/, false/*don't supress*/); char const *mapTitle = P_MapTitle(0/*current map*/); @@ -1431,7 +1433,7 @@ void G_UpdateGSVarsForMap(void) Con_SetString2("map-name", mapTitle, SVF_WRITE_OVERRIDE); } -void G_DoQuitGame(void) +void G_DoQuitGame() { #define QUITWAIT_MILLISECONDS 1500 @@ -1533,7 +1535,7 @@ void G_QueMapMusic(Uri const *mapUri) S_PauseMusic(true); } -static void runGameAction(void) +static void runGameAction() { gameaction_t currentAction; @@ -1598,7 +1600,7 @@ static void runGameAction(void) /** * Do needed reborns for any fallen players. */ -static void rebornPlayers(void) +static void rebornPlayers() { int i; for(i = 0; i < MAXPLAYERS; ++i) @@ -1640,7 +1642,7 @@ static void rebornPlayers(void) */ void G_Ticker(timespan_t ticLength) { - static gamestate_t oldGameState = -1; + static gamestate_t oldGameState = gamestate_t(-1); // Always tic: Hu_FogEffectTicker(ticLength); @@ -1760,14 +1762,13 @@ void G_PlayerLeaveMap(int player) int flightPower; #endif player_t *p = &players[player]; - dd_bool newHub = true; #if __JHEXEN__ + dd_bool newHub = true; + { Uri *nextMapUri = G_ComposeMapUri(gameEpisode, nextMap); - newHub = (P_MapInfo(0/*current map*/)->hub != P_MapInfo(nextMapUri)->hub); - Uri_Delete(nextMapUri); } #endif @@ -1781,7 +1782,7 @@ void G_PlayerLeaveMap(int player) // Empty the inventory of excess items for(i = 0; i < NUM_INVENTORYITEM_TYPES; ++i) { - inventoryitemtype_t type = IIT_FIRST + i; + inventoryitemtype_t type = inventoryitemtype_t(IIT_FIRST + i); uint count = P_InventoryCount(player, type); if(count) @@ -1836,7 +1837,7 @@ void G_PlayerLeaveMap(int player) p->update |= PSF_MORPH_TIME; if(p->morphTics) { - p->readyWeapon = p->plr->mo->special1; // Restore weapon. + p->readyWeapon = weapontype_t(p->plr->mo->special1); // Restore weapon. p->morphTics = 0; } #endif @@ -2162,7 +2163,7 @@ void G_DoReborn(int plrNum) G_SetGameAction(GA_RESTARTMAP); } -static void G_InitNewGame(void) +static void G_InitNewGame() { #if __JHEXEN__ SaveSlots_ClearSlot(saveSlots, BASE_SLOT); @@ -2228,7 +2229,7 @@ static void G_ApplyNewGameRules() if(gameRules.skill < SM_NOTHINGS) gameRules.skill = SM_NOTHINGS; if(gameRules.skill > NUM_SKILL_MODES - 1) - gameRules.skill = NUM_SKILL_MODES - 1; + gameRules.skill = skillmode_t(NUM_SKILL_MODES - 1); #if __JDOOM__ || __JHERETIC__ || __JDOOM64__ if(!IS_NETGAME) @@ -2315,7 +2316,7 @@ void G_LeaveMap(uint newMap, uint _entryPoint, dd_bool _secretExit) /** * @return @c true, if the game has been completed. */ -dd_bool G_IfVictory(void) +dd_bool G_IfVictory() { #if __JDOOM64__ if(gameMap == 27) @@ -2375,7 +2376,7 @@ static int prepareIntermission(void* paramaters) return 0; } -void G_DoMapCompleted(void) +void G_DoMapCompleted() { int i; @@ -2470,7 +2471,7 @@ void G_DoMapCompleted(void) } #if __JDOOM__ || __JDOOM64__ -void G_PrepareWIData(void) +void G_PrepareWIData() { AutoStr *mapPath = Uri_Compose(gameMapUri); wbstartstruct_t *info = &wmInfo; @@ -2517,7 +2518,7 @@ dd_bool G_StartDebriefing() return G_StartFinale(fin.script, 0, FIMODE_AFTER, 0); } -void G_IntermissionDone(void) +void G_IntermissionDone() { // We have left Intermission, however if there is an InFine for debriefing // we should run it now. @@ -2549,7 +2550,7 @@ void G_IntermissionDone(void) G_SetGameAction(GA_LEAVEMAP); } -void G_DoEndDebriefing(void) +void G_DoEndDebriefing() { briefDisabled = true; G_IntermissionDone(); @@ -2580,7 +2581,7 @@ static void backupPlayersInHub(playerbackup_t playerBackup[MAXPLAYERS]) // Make a copy of the inventory states also. for(k = 0; k < NUM_INVENTORYITEM_TYPES; ++k) { - pb->numInventoryItems[k] = P_InventoryCount(i, k); + pb->numInventoryItems[k] = P_InventoryCount(i, inventoryitemtype_t(k)); } pb->readyItem = P_InventoryReadyItem(i); } @@ -2620,7 +2621,7 @@ static void restorePlayersInHub(playerbackup_t playerBackup[MAXPLAYERS], uint ma for(m = 0; m < pb->numInventoryItems[k]; ++m) { - P_InventoryGive(i, k, true); + P_InventoryGive(i, inventoryitemtype_t(k), true); } } P_InventorySetReadyItem(i, pb->readyItem); @@ -2698,7 +2699,7 @@ static void restorePlayersInHub(playerbackup_t playerBackup[MAXPLAYERS], uint ma // Bring up the best weapon. if(bestWeapon) { - plr->pendingWeapon = bestWeapon; + plr->pendingWeapon = weapontype_t(bestWeapon); } } } @@ -2754,7 +2755,7 @@ static int G_SaveStateWorker(void* parameters) return result; } -void G_DoLeaveMap(void) +void G_DoLeaveMap() { #if __JHEXEN__ playerbackup_t playerBackup[MAXPLAYERS]; @@ -2914,7 +2915,7 @@ void G_DoLeaveMap(void) } } -void G_DoRestartMap(void) +void G_DoRestartMap() { #if __JHEXEN__ // This is a restart, so we won't brief again. @@ -2953,7 +2954,7 @@ void G_DoRestartMap(void) #endif } -dd_bool G_IsLoadGamePossible(void) +dd_bool G_IsLoadGamePossible() { return !(IS_CLIENT && !Get(DD_PLAYBACK)); } @@ -2984,7 +2985,7 @@ dd_bool G_LoadGame(int slot) /** * Called by G_Ticker based on gameaction. */ -void G_DoLoadGame(void) +void G_DoLoadGame() { #if __JHEXEN__ dd_bool mustCopyBaseToAutoSlot = (gaLoadGameSlot != AUTO_SLOT); @@ -3002,7 +3003,7 @@ void G_DoLoadGame(void) #endif } -dd_bool G_IsSaveGamePossible(void) +dd_bool G_IsSaveGamePossible() { player_t* player; @@ -3049,7 +3050,7 @@ dd_bool G_SaveGame(int slot) return G_SaveGame2(slot, NULL); } -AutoStr *G_GenerateSaveGameName(void) +AutoStr *G_GenerateSaveGameName() { AutoStr *str = AutoStr_New(); int time = mapTime / TICRATE, hours, seconds, minutes; @@ -3088,7 +3089,7 @@ AutoStr *G_GenerateSaveGameName(void) /** * Called by G_Ticker based on gameaction. */ -void G_DoSaveGame(void) +void G_DoSaveGame() { savestateworker_params_t p; char const *name; @@ -3308,7 +3309,7 @@ int G_QuitGameResponse(msgresponse_t response, int userValue, void* userPointer) return true; } -void G_QuitGame(void) +void G_QuitGame() { char const *endString; if(G_QuitInProgress()) return; @@ -3404,7 +3405,7 @@ AutoStr *G_IdentityKeyForLegacyGamemode(int gamemode, int saveVersion) return AutoStr_FromTextStd(identityKeys[gamemode]); } -char const *P_GetGameModeName(void) +char const *P_GetGameModeName() { static char const *dm = "deathmatch"; static char const *coop = "cooperative"; @@ -3417,7 +3418,7 @@ char const *P_GetGameModeName(void) return sp; } -uint G_GenerateSessionId(void) +uint G_GenerateSessionId() { return Timer_RealMilliseconds() + (mapTime << 24); } @@ -3440,7 +3441,7 @@ uint G_LogicalMapNumber(uint episode, uint map) #endif } -uint G_CurrentLogicalMapNumber(void) +uint G_CurrentLogicalMapNumber() { return G_LogicalMapNumber(gameEpisode, gameMap); } @@ -3722,7 +3723,7 @@ void G_PrintFormattedMapList(uint episode, char const** files, uint count) * Print a list of all currently available maps and the location of the * source file/directory which contains them. */ -void G_PrintMapList(void) +void G_PrintMapList() { #if __JDOOM__ uint maxEpisodes = (gameModeBits & GM_ANY_DOOM)? 9 : 1; @@ -3803,7 +3804,7 @@ int G_DebriefingEnabled(Uri const *mapUri, ddfinale_t *fin) * Stops both playback and a recording. Called at critical points like * starting a new game, or ending the game in the menu. */ -void G_StopDemo(void) +void G_StopDemo() { DD_Execute(true, "stopdemo"); } @@ -3846,7 +3847,7 @@ int Hook_DemoStop(int hookType, int val, void* paramaters) return true; } -void G_ScreenShot(void) +void G_ScreenShot() { G_SetGameAction(GA_SCREENSHOT); } @@ -3856,7 +3857,7 @@ void G_ScreenShot(void) * file name base. * @return Composed file name. */ -static AutoStr* composeScreenshotFileName(void) +static AutoStr* composeScreenshotFileName() { GameInfo gameInfo; AutoStr* name; @@ -3880,7 +3881,7 @@ static AutoStr* composeScreenshotFileName(void) return name; } -void G_DoScreenShot(void) +void G_DoScreenShot() { AutoStr* fileName = composeScreenshotFileName(); if(fileName && M_ScreenShot(Str_Text(fileName), 24)) @@ -3897,7 +3898,7 @@ void G_DoScreenShot(void) fileName? F_PrettyPath(Str_Text(fileName)) : "(null)"); } -static void openLoadMenu(void) +static void openLoadMenu() { Hu_MenuCommand(MCMD_OPEN); /// @todo This should be called automatically when opening the page @@ -3906,7 +3907,7 @@ static void openLoadMenu(void) Hu_MenuSetActivePage(Hu_MenuFindPageByName("LoadGame")); } -static void openSaveMenu(void) +static void openSaveMenu() { Hu_MenuCommand(MCMD_OPEN); /// @todo This should be called automatically when opening the page @@ -3917,6 +3918,8 @@ static void openSaveMenu(void) D_CMD(OpenLoadMenu) { + DENG_UNUSED(src); DENG_UNUSED(argc); DENG_UNUSED(argv); + if(!G_IsLoadGamePossible()) return false; openLoadMenu(); return true; @@ -3924,6 +3927,8 @@ D_CMD(OpenLoadMenu) D_CMD(OpenSaveMenu) { + DENG_UNUSED(src); DENG_UNUSED(argc); DENG_UNUSED(argv); + if(!G_IsSaveGamePossible()) return false; openSaveMenu(); return true; @@ -3941,6 +3946,8 @@ int loadGameConfirmResponse(msgresponse_t response, int userValue, void* userPoi D_CMD(LoadGame) { + DENG_UNUSED(src); + dd_bool const confirm = (argc == 3 && !stricmp(argv[2], "confirm")); int slot; @@ -4006,6 +4013,8 @@ D_CMD(LoadGame) D_CMD(QuickLoadGame) { + DENG_UNUSED(src); DENG_UNUSED(argc); DENG_UNUSED(argv); + /// @todo Implement console command scripts? return DD_Execute(true, "loadgame quick"); } @@ -4025,6 +4034,8 @@ int saveGameConfirmResponse(msgresponse_t response, int userValue, void* userPoi D_CMD(SaveGame) { + DENG_UNUSED(src); + const dd_bool confirm = (argc >= 3 && !stricmp(argv[argc-1], "confirm")); player_t* player = &players[CONSOLEPLAYER]; int slot; @@ -4103,6 +4114,8 @@ D_CMD(SaveGame) D_CMD(QuickSaveGame) { + DENG_UNUSED(src); DENG_UNUSED(argc); DENG_UNUSED(argv); + /// @todo Implement console command scripts? return DD_Execute(true, "savegame quick"); } @@ -4146,16 +4159,16 @@ int deleteSaveGameConfirmResponse(msgresponse_t response, int userValue, void* u D_CMD(DeleteGameSave) { - dd_bool const confirm = (argc >= 3 && !stricmp(argv[argc-1], "confirm")); - player_t *player = &players[CONSOLEPLAYER]; - int slot; + DENG_UNUSED(src); + + bool const confirm = (argc >= 3 && !stricmp(argv[argc-1], "confirm")); if(G_QuitInProgress()) return false; // Ensure we have up-to-date info. SaveSlots_UpdateAllSaveInfo(saveSlots); - slot = SaveSlots_ParseSlotIdentifier(saveSlots, argv[1]); + int slot = SaveSlots_ParseSlotIdentifier(saveSlots, argv[1]); if(SaveSlots_SlotIsUserWritable(saveSlots, slot) && SaveSlots_SlotInUse(saveSlots, slot)) { @@ -4187,24 +4200,32 @@ D_CMD(DeleteGameSave) D_CMD(HelpScreen) { + DENG_UNUSED(src); DENG_UNUSED(argc); DENG_UNUSED(argv); + G_StartHelp(); return true; } D_CMD(EndGame) { + DENG_UNUSED(src); DENG_UNUSED(argc); DENG_UNUSED(argv); + G_EndGame(); return true; } D_CMD(CycleTextureGamma) { + DENG_UNUSED(src); DENG_UNUSED(argc); DENG_UNUSED(argv); + R_CycleGammaLevel(); return true; } D_CMD(ListMaps) { + DENG_UNUSED(src); DENG_UNUSED(argc); DENG_UNUSED(argv); + App_Log(DE2_RES_MSG, "Available maps:"); G_PrintMapList(); return true; diff --git a/doomsday/plugins/common/src/hu_menu.c b/doomsday/plugins/common/src/hu_menu.c deleted file mode 100644 index dafe5b1f34..0000000000 --- a/doomsday/plugins/common/src/hu_menu.c +++ /dev/null @@ -1,6590 +0,0 @@ -/**\file hu_menu.c - *\section License - * License: GPL - * Online License Link: http://www.gnu.org/licenses/gpl.html - * - *\author Copyright © 2003-2013 Jaakko Keränen - *\author Copyright © 2005-2013 Daniel Swanson - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include - -#include "common.h" - -#include "m_argv.h" -#include "hu_chat.h" -#include "hu_log.h" -#include "hu_msg.h" -#include "hu_stuff.h" -#include "am_map.h" -#include "x_hair.h" -#include "player.h" -#include "g_controls.h" -#include "p_saveg.h" -#include "g_common.h" -#include "r_common.h" -#include "m_ctrl.h" - -#include "hu_menu.h" - -/// Original game line height for pages that employ the fixed layout (in 320x200 pixels). -#if __JDOOM__ -# define FIXED_LINE_HEIGHT (15+1) -#else -# define FIXED_LINE_HEIGHT (19+1) -#endif - -typedef struct cvarbutton_s { - char active; - const char* cvarname; - const char* yes; - const char* no; - int mask; -} cvarbutton_t; - -int Hu_MenuActionSetActivePage(mn_object_t* ob, mn_actionid_t action, void* parameters); -int Hu_MenuActionInitNewGame(mn_object_t* ob, mn_actionid_t action, void* parameters); - -int Hu_MenuSelectLoadGame(mn_object_t* ob, mn_actionid_t action, void* parameters); -int Hu_MenuSelectSaveGame(mn_object_t* ob, mn_actionid_t action, void* parameters); -#if __JHEXEN__ -int Hu_MenuSelectFiles(mn_object_t* ob, mn_actionid_t action, void* parameters); -#endif -int Hu_MenuSelectPlayerSetup(mn_object_t* ob, mn_actionid_t action, void* parameters); -int Hu_MenuSelectJoinGame(mn_object_t* ob, mn_actionid_t action, void* parameters); - -#if __JDOOM__ || __JHERETIC__ || __JHEXEN__ -int Hu_MenuSelectHelp(mn_object_t* ob, mn_actionid_t action, void* parameters); -#endif -int Hu_MenuSelectControlPanelLink(mn_object_t* ob, mn_actionid_t action, void* parameters); - -int Hu_MenuSelectSingleplayer(mn_object_t* ob, mn_actionid_t action, void* parameters); -int Hu_MenuSelectMultiplayer(mn_object_t* ob, mn_actionid_t action, void* parameters); -#if __JDOOM__ || __JHERETIC__ -int Hu_MenuFocusEpisode(mn_object_t* ob, mn_actionid_t action, void* parameters); -int Hu_MenuActivateNotSharewareEpisode(mn_object_t* ob, mn_actionid_t action, void* parameters); -#endif -#if __JHEXEN__ -int Hu_MenuFocusOnPlayerClass(mn_object_t* ob, mn_actionid_t action, void* parameters); -int Hu_MenuSelectPlayerClass(mn_object_t* ob, mn_actionid_t action, void* parameters); -#endif -int Hu_MenuFocusSkillMode(mn_object_t* ob, mn_actionid_t action, void* parameters); -int Hu_MenuSelectLoadSlot(mn_object_t* ob, mn_actionid_t action, void* parameters); -int Hu_MenuSelectQuitGame(mn_object_t* ob, mn_actionid_t action, void* parameters); -int Hu_MenuSelectEndGame(mn_object_t* ob, mn_actionid_t action, void* parameters); -int Hu_MenuSelectAcceptPlayerSetup(mn_object_t* ob, mn_actionid_t action, void* parameters); - -int Hu_MenuSelectSaveSlot(mn_object_t* ob, mn_actionid_t action, void* parameters); - -int Hu_MenuChangeWeaponPriority(mn_object_t* ob, mn_actionid_t action, void* parameters); -#if __JHEXEN__ -int Hu_MenuSelectPlayerSetupPlayerClass(mn_object_t* ob, mn_actionid_t action, void* parameters); -#endif -int Hu_MenuSelectPlayerColor(mn_object_t* ob, mn_actionid_t action, void* parameters); - -#if __JHEXEN__ -void Hu_MenuPlayerClassBackgroundTicker(mn_object_t* ob); -void Hu_MenuPlayerClassPreviewTicker(mn_object_t* ob); -#endif - -#if __JHERETIC__ || __JHEXEN__ -void Hu_MenuDrawMainPage(mn_page_t* page, const Point2Raw* origin); -#endif - -void Hu_MenuDrawGameTypePage(mn_page_t* page, const Point2Raw* origin); -void Hu_MenuDrawSkillPage(mn_page_t* page, const Point2Raw* origin); -#if __JHEXEN__ -void Hu_MenuDrawPlayerClassPage(mn_page_t* page, const Point2Raw* origin); -#endif -#if __JDOOM__ || __JHERETIC__ -void Hu_MenuDrawEpisodePage(mn_page_t* page, const Point2Raw* origin); -#endif -void Hu_MenuDrawOptionsPage(mn_page_t* page, const Point2Raw* origin); -void Hu_MenuDrawWeaponsPage(mn_page_t* page, const Point2Raw* origin); -void Hu_MenuDrawLoadGamePage(mn_page_t* page, const Point2Raw* origin); -void Hu_MenuDrawSaveGamePage(mn_page_t* page, const Point2Raw* origin); -void Hu_MenuDrawMultiplayerPage(mn_page_t* page, const Point2Raw* origin); -void Hu_MenuDrawPlayerSetupPage(mn_page_t* page, const Point2Raw* origin); - -int Hu_MenuColorWidgetCmdResponder(mn_page_t* page, menucommand_e cmd); - -static void initAllPages(void); -static void destroyAllPages(void); - -static void initAllObjectsOnAllPages(void); -static void updatePageObjects(mn_page_t* page); - -static void Hu_MenuUpdateCursorState(void); - -static dd_bool Hu_MenuHasCursorRotation(mn_object_t* obj); - -cvarbutton_t mnCVarButtons[] = { - { 0, "ctl-aim-noauto" }, -#if __JHERETIC__ || __JHEXEN__ - { 0, "ctl-inventory-mode", "Scroll", "Cursor" }, - { 0, "ctl-inventory-use-immediate" }, - { 0, "ctl-inventory-use-next" }, - { 0, "ctl-inventory-wrap" }, -#endif - { 0, "ctl-look-spring" }, - { 0, "ctl-run" }, -#if __JDOOM__ || __JDOOM64__ - { 0, "game-anybossdeath666" }, -#endif -#if __JDOOM__ || __JHERETIC__ || __JDOOM64__ - { 0, "game-corpse-sliding" }, -#endif -#if __JDOOM__ || __JDOOM64__ - { 0, "game-maxskulls" }, -#endif -#if __JDOOM__ || __JHERETIC__ || __JDOOM64__ - { 0, "game-monsters-stuckindoors" }, - { 0, "game-monsters-floatoverblocking" }, - { 0, "game-objects-clipping" }, - { 0, "game-objects-falloff" }, -#endif -#if __JDOOM__ || __JDOOM64__ - { 0, "game-objects-gibcrushednonbleeders" }, -#endif -#if __JDOOM__ || __JHERETIC__ || __JDOOM64__ - { 0, "game-objects-neverhangoverledges" }, - { 0, "game-player-wallrun-northonly" }, -#endif -#if __JDOOM__ - { 0, "game-raiseghosts" }, -#endif - { 0, "game-save-confirm" }, - { 0, "game-save-confirm-loadonreborn" }, -#if !__JHEXEN__ - { 0, "game-save-auto-loadonreborn" }, -#endif - { 0, "game-save-last-loadonreborn" }, -#if __JDOOM__ || __JDOOM64__ - { 0, "game-skullsinwalls" }, -#if __JDOOM__ - { 0, "game-vilechase-usevileradius" }, -#endif - { 0, "game-zombiescanexit" }, -#endif -#if __JDOOM__ || __JDOOM64__ || __JHERETIC__ - { 0, "hud-ammo" }, - { 0, "hud-armor" }, -#endif -#if __JDOOM__ || __JDOOM64__ || __JHERETIC__ - { 0, "hud-cheat-counter-show-mapopen" }, -#endif -#if __JHERETIC__ || __JHEXEN__ - { 0, "hud-currentitem" }, -#endif -#if __JDOOM__ - { 0, "hud-face" }, - { 0, "hud-face-ouchfix" }, -#endif - { 0, "hud-health" }, -#if __JHERETIC__ || __JHEXEN__ - { 0, "hud-inventory-slot-showempty" }, -#endif -#if __JDOOM__ || __JDOOM64__ || __JHERETIC__ - { 0, "hud-keys" }, -#endif -#if __JDOOM__ - { 0, "hud-keys-combine" }, -#endif -#if __JHEXEN__ - { 0, "hud-mana" }, -#endif -#if __JDOOM64__ - { 0, "hud-power" }, -#endif -#if __JDOOM__ || __JDOOM64__ - { 0, "hud-status-weaponslots-ownedfix" }, -#endif - { 0, "hud-unhide-damage" }, - { 0, "hud-unhide-pickup-ammo" }, - { 0, "hud-unhide-pickup-armor" }, - { 0, "hud-unhide-pickup-health" }, -#if __JHERETIC__ || __JHEXEN__ - { 0, "hud-unhide-pickup-invitem" }, -#endif - { 0, "hud-unhide-pickup-powerup" }, - { 0, "hud-unhide-pickup-key" }, - { 0, "hud-unhide-pickup-weapon" }, - { 0, "map-door-colors" }, - { 0, "msg-show" }, -#if __JDOOM__ || __JDOOM64__ - { 0, "player-autoswitch-berserk" }, -#endif - { 0, "player-autoswitch-notfiring" }, -#if __JDOOM__ || __JHERETIC__ || __JDOOM64__ - { 0, "player-jump" }, -#endif - { 0, "player-weapon-cycle-sequential" }, - { 0, "player-weapon-nextmode" }, -#if __JDOOM64__ - { 0, "player-weapon-recoil" }, -#endif -#if __JDOOM__ || __JDOOM64__ - { 0, "server-game-bfg-freeaim" }, -#endif - { 0, "server-game-coop-nodamage" }, -#if __JDOOM__ || __JDOOM64__ - { 0, "server-game-coop-nothing" }, - { 0, "server-game-coop-noweapons" }, - { 0, "server-game-coop-respawn-items" }, -#endif -#if __JHEXEN__ - { 0, "server-game-deathmatch" }, -#endif -#if __JDOOM__ || __JDOOM64__ || __JHERETIC__ - { 0, "server-game-jump" }, -#endif -#if __JDOOM__ || __JDOOM64__ - { 0, "server-game-nobfg" }, -#endif - { 0, "server-game-nomonsters" }, -#if __JDOOM__ || __JDOOM64__ || __JHERETIC__ - { 0, "server-game-noteamdamage" }, -#endif - { 0, "server-game-radiusattack-nomaxz" }, -#if __JHEXEN__ - { 0, "server-game-randclass" }, -#endif -#if __JDOOM__ || __JDOOM64__ || __JHERETIC__ - { 0, "server-game-respawn" }, -#endif - { 0, "view-cross-vitality" }, - { 0, 0 } -}; - -int menuTime = 0; -dd_bool menuNominatingQuickSaveSlot = false; - -static mn_page_t* menuActivePage = NULL; -static dd_bool menuActive = false; - -static float mnAlpha = 0; // Alpha level for the entire menu. -static float mnTargetAlpha = 0; // Target alpha for the entire UI. - -static skillmode_t mnSkillmode = SM_MEDIUM; -static int mnEpisode = 0; -#if __JHEXEN__ -static int mnPlrClass = PCLASS_FIGHTER; -#endif - -static int frame = 0; // Used by any graphic animations that need to be pumped. - -static dd_bool colorWidgetActive = false; - -// Present cursor state. -static dd_bool cursorHasRotation = false; -static float cursorAngle = 0; -static int cursorAnimCounter = 0; -static int cursorAnimFrame = 0; - -#if __JHERETIC__ -static char notDesignedForMessage[80]; -#endif - -static patchid_t pMainTitle; -#if __JDOOM__ || __JDOOM64__ -static patchid_t pNewGame; -static patchid_t pSkill; -static patchid_t pEpisode; -static patchid_t pNGame; -static patchid_t pOptions; -static patchid_t pLoadGame; -static patchid_t pSaveGame; -static patchid_t pReadThis; -static patchid_t pQuitGame; -static patchid_t pOptionsTitle; - -static patchid_t pSkillModeNames[NUM_SKILL_MODES]; -#endif -#if __JDOOM__ -static patchid_t pEpisodeNames[4]; -#endif - -#if __JHEXEN__ -static patchid_t pPlayerClassBG[3]; -static patchid_t pBullWithFire[8]; -#endif - -#if __JHERETIC__ -static patchid_t pRotatingSkull[18]; -#endif - -static patchid_t pCursors[MENU_CURSOR_FRAMECOUNT]; - -#if __JDOOM64__ -mndata_slider_t sld_hud_viewsize = { 3, 11, 0, 1, false, "view-size" }; -#else -mndata_slider_t sld_hud_viewsize = { 3, 13, 0, 1, false, "view-size" }; -#endif -mndata_slider_t sld_hud_uptime = { 0, 60, 0, 1.f, true, "hud-timer", "Disabled", NULL, " second", " seconds" }; -mndata_slider_t sld_hud_xhair_size = { 0, 1, 0, .1f, true, "view-cross-size" }; -mndata_slider_t sld_hud_xhair_angle = { 0, 1, 0, .0625f, true, "view-cross-angle" }; -mndata_slider_t sld_hud_xhair_opacity = { 0, 1, 0, .1f, true, "view-cross-a" }; -mndata_slider_t sld_hud_size = { 0, 1, 0, .1f, true, "hud-scale" }; -mndata_slider_t sld_hud_cntr_size = { 0, 1, 0, .1f, true, "hud-cheat-counter-scale" }; -mndata_slider_t sld_hud_sbar_size = { 0, 1, 0, .1f, true, "hud-status-size" }; -mndata_slider_t sld_hud_sbar_opacity = { 0, 1, 0, .1f, true, "hud-status-alpha" }; -mndata_slider_t sld_hud_msg_size = { 0, 1, 0, .1f, true, "msg-scale" }; -mndata_slider_t sld_hud_msg_uptime = { 0, 60, 0, 1.f, true, "msg-uptime", "Disabled", NULL, " second", " seconds" }; - -mndata_colorbox_t cbox_hud_color = { - 0, 0, 0, 0, 0, 0, true, - "hud-color-r", "hud-color-g", "hud-color-b", "hud-color-a" -}; - -mndata_colorbox_t cbox_hud_msg_color = { - 0, 0, 0, 0, 0, 0, false, - "msg-color-r", "msg-color-g", "msg-color-b" -}; - -mndata_listitem_t listit_hud_xhair_symbols[] = { - { "None", 0 }, - { "Cross", 1 }, - { "Twin Angles", 2 }, - { "Square", 3 }, - { "Open Square", 4 }, - { "Angle", 5 } -}; -mndata_list_t list_hud_xhair_symbol = { - listit_hud_xhair_symbols, NUMLISTITEMS(listit_hud_xhair_symbols), "view-cross-type" -}; - -mndata_colorbox_t cbox_hud_xhair_color = { - 0, 0, 0, 0, 0, 0, false, - "view-cross-r", "view-cross-g", "view-cross-b", -}; - -#if __JDOOM__ || __JDOOM64__ || __JHERETIC__ -mndata_listitem_t listit_hud_killscounter_displaymethods[] = { - { "Hidden", 0 }, - { "Count", CCH_KILLS }, - { "Percent", CCH_KILLS_PRCNT }, - { "Count+Percent", CCH_KILLS | CCH_KILLS_PRCNT }, -}; -mndata_list_t list_hud_cntr_kills = { - listit_hud_killscounter_displaymethods, - NUMLISTITEMS(listit_hud_killscounter_displaymethods), - "hud-cheat-counter", CCH_KILLS | CCH_KILLS_PRCNT -}; - -mndata_listitem_t listit_hud_itemscounter_displaymethods[] = { - { "Hidden", 0 }, - { "Count", CCH_ITEMS }, - { "Percent", CCH_ITEMS_PRCNT }, - { "Count+Percent", CCH_ITEMS | CCH_ITEMS_PRCNT }, -}; -mndata_list_t list_hud_cntr_items = { - listit_hud_itemscounter_displaymethods, - NUMLISTITEMS(listit_hud_itemscounter_displaymethods), - "hud-cheat-counter", CCH_ITEMS | CCH_ITEMS_PRCNT -}; - -mndata_listitem_t listit_hud_secretscounter_displaymethods[] = { - { "Hidden", 0 }, - { "Count", CCH_SECRETS }, - { "Percent", CCH_SECRETS_PRCNT }, - { "Count+Percent", CCH_SECRETS | CCH_SECRETS_PRCNT }, -}; -mndata_list_t list_hud_cntr_secrets = { - listit_hud_secretscounter_displaymethods, - NUMLISTITEMS(listit_hud_secretscounter_displaymethods), - "hud-cheat-counter", CCH_SECRETS | CCH_SECRETS_PRCNT -}; -#endif - -mndata_text_t txt_hud_view_size = { "View Size" }; -#if __JDOOM__ -mndata_text_t txt_hud_single_key_display = { "Single Key Display" }; -#endif -mndata_text_t txt_hud_autohide = { "AutoHide" }; -mndata_text_t txt_hud_unhide_events = { "UnHide Events" }; -mndata_text_t txt_hud_unhide_receive_damage = { "Receive Damage" }; -mndata_text_t txt_hud_unhide_pickup_health = { "Pickup Health" }; -mndata_text_t txt_hud_unhide_pickup_armor = { "Pickup Armor" }; -mndata_text_t txt_hud_unhide_pickup_powerup = { "Pickup Powerup" }; -mndata_text_t txt_hud_unhide_pickup_weapon = { "Pickup Weapon" }; -#if __JHEXEN__ -mndata_text_t txt_hud_unhide_pickup_ammo = { "Pickup Mana" }; -#else -mndata_text_t txt_hud_unhide_pickup_ammo = { "Pickup Ammo" }; -#endif -mndata_text_t txt_hud_unhide_pickup_key = { "Pickup Key" }; -#if __JHERETIC__ || __JHEXEN__ -mndata_text_t txt_hud_unhide_pickup_item = { "Pickup Item" }; -#endif - -mndata_text_t txt_hud_messages = { "Messages" }; -mndata_text_t txt_hud_msg_shown = { "Shown" }; -mndata_text_t txt_hud_msg_size = { "Size" }; -mndata_text_t txt_hud_msg_color = { "Color" }; -mndata_text_t txt_hud_msg_uptime = { "Uptime" }; - -mndata_text_t txt_hud_crosshair = { "Crosshair" }; -mndata_text_t txt_hud_xhair_symbol = { "Symbol" }; -mndata_text_t txt_hud_xhair_size = { "Size" }; -mndata_text_t txt_hud_xhair_angle = { "Angle" }; -mndata_text_t txt_hud_xhair_opacity = { "Opacity" }; -mndata_text_t txt_hud_xhair_vitality_color = { "Vitality Color" }; -mndata_text_t txt_hud_xhair_color = { "Color" }; - -#if __JDOOM__ || __JHERETIC__ || __JHEXEN__ -mndata_text_t txt_hud_statusbar = { "Statusbar" }; -mndata_text_t txt_hud_sbar_size = { "Size" }; -mndata_text_t txt_hud_sbar_opacity = { "Opacity" }; -#endif -#if __JDOOM__ || __JDOOM64__ || __JHERETIC__ -mndata_text_t txt_hud_counters = { "Counters" }; -mndata_text_t txt_hud_cntr_kills = { "Kills" }; -mndata_text_t txt_hud_cntr_items = { "Items" }; -mndata_text_t txt_hud_cntr_secrets = { "Secrets" }; -mndata_text_t txt_hud_cntr_size = { "Size" }; -#endif - -mndata_text_t txt_hud_fullscreen = { "Fullscreen" }; -mndata_text_t txt_hud_full_size = { "Size" }; -mndata_text_t txt_hud_full_text_color = { "Text Color" }; -#if __JHEXEN__ -mndata_text_t txt_hud_full_show_mana = { "Show Mana" }; -#endif -#if __JDOOM__ || __JDOOM64__ || __JHERETIC__ -mndata_text_t txt_hud_full_show_ammo = { "Show Ammo" }; -mndata_text_t txt_hud_full_show_armor = { "Show Armor" }; -#endif -#if __JDOOM64__ -mndata_text_t txt_hud_full_show_powerkeys = { "Show PowerKeys" }; -#endif -#if __JDOOM__ -mndata_text_t txt_hud_full_show_status = { "Show Status" }; -#endif -mndata_text_t txt_hud_full_show_health = { "Show Health" }; -#if __JDOOM__ || __JDOOM64__ || __JHERETIC__ -mndata_text_t txt_hud_full_show_keys = { "Show Keys" }; -#endif -#if __JHERETIC__ || __JHEXEN__ -mndata_text_t txt_hud_full_show_readyitem = { "Show Ready-Item" }; -#endif -#if __JDOOM__ || __JDOOM64__ || __JHERETIC__ -mndata_text_t txt_hud_cntr_mapopen = { "Automap Only" }; -#endif - -mndata_button_t btn_hud_single_key_display = { true, "hud-keys-combine" }; -mndata_button_t btn_hud_unhide_receive_damage = { true, "hud-unhide-damage" }; -mndata_button_t btn_hud_unhide_pickup_health = { true, "hud-unhide-pickup-health" }; -mndata_button_t btn_hud_unhide_pickup_armor = { true, "hud-unhide-pickup-armor" }; -mndata_button_t btn_hud_unhide_pickup_powerup = { true, "hud-unhide-pickup-powerup" }; -mndata_button_t btn_hud_unhide_pickup_weapon = { true, "hud-unhide-pickup-weapon" }; -mndata_button_t btn_hud_unhide_pickup_ammo = { true, "hud-unhide-pickup-ammo" }; -mndata_button_t btn_hud_unhide_pickup_key = { true, "hud-unhide-pickup-key" }; -#if __JHERETIC__ || __JHEXEN__ -mndata_button_t btn_hud_unhide_pickup_item = { true, "hud-unhide-pickup-invitem" }; -#endif -mndata_button_t btn_hud_msg_shown = { true, "msg-show" }; -mndata_button_t btn_hud_xhair_vitality_color = { true, "view-cross-vitality" }; -#if __JHEXEN__ -mndata_button_t btn_hud_full_show_mana = { true, "hud-mana" }; -#endif -#if __JDOOM__ || __JDOOM64__ || __JHERETIC__ -mndata_button_t btn_hud_full_show_ammo = { true, "hud-ammo" }; -mndata_button_t btn_hud_full_show_armor = { true, "hud-armor" }; -#endif -#if __JDOOM64__ -mndata_button_t btn_hud_full_show_powerkeys = { true, "hud-power" }; -#endif -#if __JDOOM__ -mndata_button_t btn_hud_full_show_face = { true, "hud-face" }; -#endif -mndata_button_t btn_hud_full_show_health = { true, "hud-health" }; -#if __JDOOM__ || __JDOOM64__ || __JHERETIC__ -mndata_button_t btn_hud_full_show_keys = { true, "hud-keys" }; -#endif -#if __JHERETIC__ || __JHEXEN__ -mndata_button_t btn_hud_full_show_readyitem = { true, "hud-currentitem" }; -#endif -#if __JDOOM__ || __JDOOM64__ || __JHERETIC__ -mndata_button_t btn_hud_cntr_mapopen = { true, "hud-cheat-counter-show-mapopen" }; -#endif - -static mn_object_t HudMenuObjects[] = { - { MN_TEXT, 0, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_view_size }, - { MN_SLIDER, 0, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR1, MNSlider_Ticker, MNSlider_UpdateGeometry, MNSlider_Drawer, { Hu_MenuCvarSlider, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNSlider_CommandResponder, NULL, NULL, &sld_hud_viewsize }, -#if __JDOOM__ - { MN_TEXT, 0, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_single_key_display }, - { MN_BUTTON, 0, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR3, MNButton_Ticker, MNButton_UpdateGeometry, MNButton_Drawer, { Hu_MenuCvarButton, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNButton_CommandResponder, NULL, NULL, &btn_hud_single_key_display }, -#endif - { MN_TEXT, 0, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_autohide }, - { MN_SLIDER, 0, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR3, MNSlider_Ticker, MNSlider_TextualValueUpdateGeometry, MNSlider_TextualValueDrawer, { Hu_MenuCvarSlider, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNSlider_CommandResponder, NULL, NULL, &sld_hud_uptime }, - - { MN_TEXT, 1, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR2, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_unhide_events }, - { MN_TEXT, 1, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_unhide_receive_damage }, - { MN_BUTTON, 1, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR3, MNButton_Ticker, MNButton_UpdateGeometry, MNButton_Drawer, { Hu_MenuCvarButton, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNButton_CommandResponder, NULL, NULL, &btn_hud_unhide_receive_damage }, - { MN_TEXT, 1, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_unhide_pickup_health }, - { MN_BUTTON, 1, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR3, MNButton_Ticker, MNButton_UpdateGeometry, MNButton_Drawer, { Hu_MenuCvarButton, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNButton_CommandResponder, NULL, NULL, &btn_hud_unhide_pickup_health }, - { MN_TEXT, 1, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_unhide_pickup_armor }, - { MN_BUTTON, 1, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR3, MNButton_Ticker, MNButton_UpdateGeometry, MNButton_Drawer, { Hu_MenuCvarButton, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNButton_CommandResponder, NULL, NULL, &btn_hud_unhide_pickup_armor }, - { MN_TEXT, 1, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_unhide_pickup_powerup }, - { MN_BUTTON, 1, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR3, MNButton_Ticker, MNButton_UpdateGeometry, MNButton_Drawer, { Hu_MenuCvarButton, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNButton_CommandResponder, NULL, NULL, &btn_hud_unhide_pickup_powerup }, - { MN_TEXT, 1, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_unhide_pickup_weapon }, - { MN_BUTTON, 1, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR3, MNButton_Ticker, MNButton_UpdateGeometry, MNButton_Drawer, { Hu_MenuCvarButton, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNButton_CommandResponder, NULL, NULL, &btn_hud_unhide_pickup_weapon }, - { MN_TEXT, 1, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_unhide_pickup_ammo }, - { MN_BUTTON, 1, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR3, MNButton_Ticker, MNButton_UpdateGeometry, MNButton_Drawer, { Hu_MenuCvarButton, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNButton_CommandResponder, NULL, NULL, &btn_hud_unhide_pickup_ammo }, - { MN_TEXT, 1, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_unhide_pickup_key }, - { MN_BUTTON, 1, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR3, MNButton_Ticker, MNButton_UpdateGeometry, MNButton_Drawer, { Hu_MenuCvarButton, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNButton_CommandResponder, NULL, NULL, &btn_hud_unhide_pickup_key }, -#if __JHERETIC__ || __JHEXEN__ - { MN_TEXT, 1, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_unhide_pickup_item }, - { MN_BUTTON, 1, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR3, MNButton_Ticker, MNButton_UpdateGeometry, MNButton_Drawer, { Hu_MenuCvarButton, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNButton_CommandResponder, NULL, NULL, &btn_hud_unhide_pickup_item }, -#endif - - { MN_TEXT, 2, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR2, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_messages }, - { MN_TEXT, 2, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_msg_shown }, - { MN_BUTTON, 2, 0, { 0, 0 }, 'm',MENU_FONT1, MENU_COLOR3, MNButton_Ticker, MNButton_UpdateGeometry, MNButton_Drawer, { Hu_MenuCvarButton, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNButton_CommandResponder, NULL, NULL, &btn_hud_msg_shown }, - { MN_TEXT, 2, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_msg_uptime }, - { MN_SLIDER, 2, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR3, MNSlider_Ticker, MNSlider_TextualValueUpdateGeometry, MNSlider_TextualValueDrawer, { Hu_MenuCvarSlider, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNSlider_CommandResponder, NULL, NULL, &sld_hud_msg_uptime }, - { MN_TEXT, 2, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_msg_size }, - { MN_SLIDER, 2, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR1, MNSlider_Ticker, MNSlider_UpdateGeometry, MNSlider_Drawer, { Hu_MenuCvarSlider, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNSlider_CommandResponder, NULL, NULL, &sld_hud_msg_size }, - { MN_TEXT, 2, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_msg_color }, - { MN_COLORBOX, 2, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR1, MNColorBox_Ticker, MNColorBox_UpdateGeometry, MNColorBox_Drawer, { Hu_MenuCvarColorBox, Hu_MenuCvarColorBox, Hu_MenuActivateColorWidget, NULL, NULL, Hu_MenuDefaultFocusAction }, MNColorBox_CommandResponder, NULL, NULL, &cbox_hud_msg_color }, - - { MN_TEXT, 3, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR2, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_crosshair }, - { MN_TEXT, 3, 0, { 0, 0 }, 'c',MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_xhair_symbol }, - { MN_LISTINLINE, 3, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR3, MNListInline_Ticker, MNListInline_UpdateGeometry, MNListInline_Drawer, { Hu_MenuCvarList, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNListInline_CommandResponder, NULL, NULL, &list_hud_xhair_symbol }, - { MN_TEXT, 3, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_xhair_size }, - { MN_SLIDER, 3, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR1, MNSlider_Ticker, MNSlider_UpdateGeometry, MNSlider_Drawer, { Hu_MenuCvarSlider, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNSlider_CommandResponder, NULL, NULL, &sld_hud_xhair_size }, - { MN_TEXT, 3, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_xhair_angle }, - { MN_SLIDER, 3, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR1, MNSlider_Ticker, MNSlider_UpdateGeometry, MNSlider_Drawer, { Hu_MenuCvarSlider, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNSlider_CommandResponder, NULL, NULL, &sld_hud_xhair_angle }, - { MN_TEXT, 3, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_xhair_opacity }, - { MN_SLIDER, 3, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR1, MNSlider_Ticker, MNSlider_UpdateGeometry, MNSlider_Drawer, { Hu_MenuCvarSlider, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNSlider_CommandResponder, NULL, NULL, &sld_hud_xhair_opacity }, - { MN_TEXT, 3, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_xhair_vitality_color }, - { MN_BUTTON, 3, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR3, MNButton_Ticker, MNButton_UpdateGeometry, MNButton_Drawer, { Hu_MenuCvarButton, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNButton_CommandResponder, NULL, NULL, &btn_hud_xhair_vitality_color }, - { MN_TEXT, 3, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_xhair_color }, - { MN_COLORBOX, 3, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR1, MNColorBox_Ticker, MNColorBox_UpdateGeometry, MNColorBox_Drawer, { Hu_MenuCvarColorBox, Hu_MenuCvarColorBox, Hu_MenuActivateColorWidget, NULL, NULL, Hu_MenuDefaultFocusAction }, MNColorBox_CommandResponder, NULL, NULL, &cbox_hud_xhair_color }, - -#if __JDOOM__ || __JHERETIC__ || __JHEXEN__ - { MN_TEXT, 4, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR2, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_statusbar }, - { MN_TEXT, 4, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_sbar_size }, - { MN_SLIDER, 4, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR1, MNSlider_Ticker, MNSlider_UpdateGeometry, MNSlider_Drawer, { Hu_MenuCvarSlider, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNSlider_CommandResponder, NULL, NULL, &sld_hud_sbar_size }, - { MN_TEXT, 4, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_sbar_opacity }, - { MN_SLIDER, 4, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR1, MNSlider_Ticker, MNSlider_UpdateGeometry, MNSlider_Drawer, { Hu_MenuCvarSlider, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNSlider_CommandResponder, NULL, NULL, &sld_hud_sbar_opacity }, -#endif -#if __JDOOM__ || __JDOOM64__ || __JHERETIC__ - { MN_TEXT, 5, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR2, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_counters }, - { MN_TEXT, 5, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_cntr_items }, - { MN_LISTINLINE, 5, 0, { 0, 0 }, 'i',MENU_FONT1, MENU_COLOR3, MNListInline_Ticker, MNListInline_UpdateGeometry, MNListInline_Drawer, { Hu_MenuCvarList, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNListInline_CommandResponder, NULL, NULL, &list_hud_cntr_items }, - { MN_TEXT, 5, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_cntr_kills }, - { MN_LISTINLINE, 5, 0, { 0, 0 }, 'k',MENU_FONT1, MENU_COLOR3, MNListInline_Ticker, MNListInline_UpdateGeometry, MNListInline_Drawer, { Hu_MenuCvarList, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNListInline_CommandResponder, NULL, NULL, &list_hud_cntr_kills }, - { MN_TEXT, 5, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_cntr_secrets }, - { MN_LISTINLINE, 5, 0, { 0, 0 }, 's',MENU_FONT1, MENU_COLOR3, MNListInline_Ticker, MNListInline_UpdateGeometry, MNListInline_Drawer, { Hu_MenuCvarList, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNListInline_CommandResponder, NULL, NULL, &list_hud_cntr_secrets }, - { MN_TEXT, 5, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_cntr_mapopen }, - { MN_BUTTON, 5, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR3, MNButton_Ticker, MNButton_UpdateGeometry, MNButton_Drawer, { Hu_MenuCvarButton, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNButton_CommandResponder, NULL, NULL, &btn_hud_cntr_mapopen }, - { MN_TEXT, 5, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_cntr_size }, - { MN_SLIDER, 5, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR1, MNSlider_Ticker, MNSlider_UpdateGeometry, MNSlider_Drawer, { Hu_MenuCvarSlider, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNSlider_CommandResponder, NULL, NULL, &sld_hud_cntr_size }, -#endif - - { MN_TEXT, 6, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR2, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_fullscreen }, - { MN_TEXT, 6, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_full_size }, - { MN_SLIDER, 6, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR1, MNSlider_Ticker, MNSlider_UpdateGeometry, MNSlider_Drawer, { Hu_MenuCvarSlider, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNSlider_CommandResponder, NULL, NULL, &sld_hud_size }, - { MN_TEXT, 6, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_full_text_color }, - { MN_COLORBOX, 6, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR1, MNColorBox_Ticker, MNColorBox_UpdateGeometry, MNColorBox_Drawer, { Hu_MenuCvarColorBox, Hu_MenuCvarColorBox, Hu_MenuActivateColorWidget, NULL, NULL, Hu_MenuDefaultFocusAction }, MNColorBox_CommandResponder, NULL, NULL, &cbox_hud_color }, -#if __JHEXEN__ - { MN_TEXT, 6, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_full_show_mana }, - { MN_BUTTON, 6, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR3, MNButton_Ticker, MNButton_UpdateGeometry, MNButton_Drawer, { Hu_MenuCvarButton, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNButton_CommandResponder, NULL, NULL, &btn_hud_full_show_mana }, -#endif -#if __JDOOM__ || __JDOOM64__ || __JHERETIC__ - { MN_TEXT, 6, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_full_show_ammo }, - { MN_BUTTON, 6, 0, { 0, 0 }, 'a',MENU_FONT1, MENU_COLOR3, MNButton_Ticker, MNButton_UpdateGeometry, MNButton_Drawer, { Hu_MenuCvarButton, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNButton_CommandResponder, NULL, NULL, &btn_hud_full_show_ammo }, - { MN_TEXT, 6, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_full_show_armor }, - { MN_BUTTON, 6, 0, { 0, 0 }, 'r',MENU_FONT1, MENU_COLOR3, MNButton_Ticker, MNButton_UpdateGeometry, MNButton_Drawer, { Hu_MenuCvarButton, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNButton_CommandResponder, NULL, NULL, &btn_hud_full_show_armor }, -#endif -#if __JDOOM64__ - { MN_TEXT, 6, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_full_show_powerkeys }, - { MN_BUTTON, 6, 0, { 0, 0 }, 'p',MENU_FONT1, MENU_COLOR3, MNButton_Ticker, MNButton_UpdateGeometry, MNButton_Drawer, { Hu_MenuCvarButton, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNButton_CommandResponder, NULL, NULL, &btn_hud_full_show_powerkeys }, -#endif -#if __JDOOM__ - { MN_TEXT, 6, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_full_show_status }, - { MN_BUTTON, 6, 0, { 0, 0 }, 'f',MENU_FONT1, MENU_COLOR3, MNButton_Ticker, MNButton_UpdateGeometry, MNButton_Drawer, { Hu_MenuCvarButton, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNButton_CommandResponder, NULL, NULL, &btn_hud_full_show_face }, -#endif - { MN_TEXT, 6, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_full_show_health }, - { MN_BUTTON, 6, 0, { 0, 0 }, 'h',MENU_FONT1, MENU_COLOR3, MNButton_Ticker, MNButton_UpdateGeometry, MNButton_Drawer, { Hu_MenuCvarButton, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNButton_CommandResponder, NULL, NULL, &btn_hud_full_show_health }, -#if __JDOOM__ || __JDOOM64__ || __JHERETIC__ - { MN_TEXT, 6, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_full_show_keys }, - { MN_BUTTON, 6, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR3, MNButton_Ticker, MNButton_UpdateGeometry, MNButton_Drawer, { Hu_MenuCvarButton, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNButton_CommandResponder, NULL, NULL, &btn_hud_full_show_keys }, -#endif -#if __JHERETIC__ || __JHEXEN__ - { MN_TEXT, 6, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_full_show_readyitem }, - { MN_BUTTON, 6, 0, { 0, 0 }, 0, MENU_FONT1, MENU_COLOR3, MNButton_Ticker, MNButton_UpdateGeometry, MNButton_Drawer, { Hu_MenuCvarButton, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNButton_CommandResponder, NULL, NULL, &btn_hud_full_show_readyitem }, -#endif - { MN_NONE } -}; - -static dd_bool inited = false; - -typedef struct { - mn_page_t* page; - ddstring_t name; // Symbolic name. -} pagerecord_t; - -static int pageCount; -static pagerecord_t* pages; - -// Cvars for the menu: -cvartemplate_t menuCVars[] = { - { "menu-scale", 0, CVT_FLOAT, &cfg.menuScale, .1f, 1 }, - { "menu-stretch", 0, CVT_BYTE, &cfg.menuScaleMode, SCALEMODE_FIRST, SCALEMODE_LAST }, - { "menu-flash-r", 0, CVT_FLOAT, &cfg.menuTextFlashColor[CR], 0, 1 }, - { "menu-flash-g", 0, CVT_FLOAT, &cfg.menuTextFlashColor[CG], 0, 1 }, - { "menu-flash-b", 0, CVT_FLOAT, &cfg.menuTextFlashColor[CB], 0, 1 }, - { "menu-flash-speed", 0, CVT_INT, &cfg.menuTextFlashSpeed, 0, 50 }, - { "menu-cursor-rotate", 0, CVT_BYTE, &cfg.menuCursorRotate, 0, 1 }, - { "menu-effect", 0, CVT_INT, &cfg.menuEffectFlags, 0, MEF_EVERYTHING }, - { "menu-color-r", 0, CVT_FLOAT, &cfg.menuTextColors[0][CR], 0, 1 }, - { "menu-color-g", 0, CVT_FLOAT, &cfg.menuTextColors[0][CG], 0, 1 }, - { "menu-color-b", 0, CVT_FLOAT, &cfg.menuTextColors[0][CB], 0, 1 }, - { "menu-colorb-r", 0, CVT_FLOAT, &cfg.menuTextColors[1][CR], 0, 1 }, - { "menu-colorb-g", 0, CVT_FLOAT, &cfg.menuTextColors[1][CG], 0, 1 }, - { "menu-colorb-b", 0, CVT_FLOAT, &cfg.menuTextColors[1][CB], 0, 1 }, - { "menu-colorc-r", 0, CVT_FLOAT, &cfg.menuTextColors[2][CR], 0, 1 }, - { "menu-colorc-g", 0, CVT_FLOAT, &cfg.menuTextColors[2][CG], 0, 1 }, - { "menu-colorc-b", 0, CVT_FLOAT, &cfg.menuTextColors[2][CB], 0, 1 }, - { "menu-colord-r", 0, CVT_FLOAT, &cfg.menuTextColors[3][CR], 0, 1 }, - { "menu-colord-g", 0, CVT_FLOAT, &cfg.menuTextColors[3][CG], 0, 1 }, - { "menu-colord-b", 0, CVT_FLOAT, &cfg.menuTextColors[3][CB], 0, 1 }, - { "menu-glitter", 0, CVT_FLOAT, &cfg.menuTextGlitter, 0, 1 }, - { "menu-fog", 0, CVT_INT, &cfg.hudFog, 0, 5 }, - { "menu-shadow", 0, CVT_FLOAT, &cfg.menuShadow, 0, 1 }, - { "menu-patch-replacement", 0, CVT_INT, &cfg.menuPatchReplaceMode, PRM_FIRST, PRM_LAST }, - { "menu-slam", 0, CVT_BYTE, &cfg.menuSlam, 0, 1 }, - { "menu-hotkeys", 0, CVT_BYTE, &cfg.menuShortcutsEnabled, 0, 1 }, -#if __JDOOM__ || __JDOOM64__ - { "menu-quitsound", 0, CVT_INT, &cfg.menuQuitSound, 0, 1 }, -#endif - { "menu-save-suggestname", 0, CVT_BYTE, &cfg.menuGameSaveSuggestName, 0, 1 }, - - // Aliases for obsolete cvars: - { "menu-turningskull", 0, CVT_BYTE, &cfg.menuCursorRotate, 0, 1 }, - { NULL } -}; - -// Console commands for the menu: -ccmdtemplate_t menuCCmds[] = { - { "menu", "s", CCmdMenuOpen }, - { "menu", "", CCmdMenuOpen }, - { "menuup", "", CCmdMenuCommand }, - { "menudown", "", CCmdMenuCommand }, - { "menupageup", "", CCmdMenuCommand }, - { "menupagedown", "", CCmdMenuCommand }, - { "menuleft", "", CCmdMenuCommand }, - { "menuright", "", CCmdMenuCommand }, - { "menuselect", "", CCmdMenuCommand }, - { "menudelete", "", CCmdMenuCommand }, - { "menuback", "", CCmdMenuCommand }, - { NULL } -}; - -void Hu_MenuRegister(void) -{ - int i; - for(i = 0; menuCVars[i].path; ++i) - Con_AddVariable(menuCVars + i); - for(i = 0; menuCCmds[i].name; ++i) - Con_AddCommand(menuCCmds + i); -} - -static dd_bool chooseCloseMethod(void) -{ - // If we aren't using a transition then we can close normally and allow our - // own menu fade-out animation to be used instead. - return Con_GetInteger("con-transition-tics") == 0? MCMD_CLOSE : MCMD_CLOSEFAST; -} - -mn_page_t* Hu_MenuFindPageByName(const char* name) -{ - if(name && name[0]) - { - int i; - for(i = 0; i < pageCount; ++i) - { - pagerecord_t* rec = pages + i; - if(!stricmp(name, Str_Text(&rec->name))) - { - return rec->page; - } - } - } - return NULL; -} - -/// @todo Make this state an object property flag. -/// @return @c true if the rotation of a cursor on this object should be animated. -static dd_bool Hu_MenuHasCursorRotation(mn_object_t* obj) -{ - assert(obj); - return (!(MNObject_Flags(obj) & MNF_DISABLED) && - (MNObject_Type(obj) == MN_LISTINLINE || MNObject_Type(obj) == MN_SLIDER)); -} - -/// To be called to re-evaluate the state of the cursor (e.g., when focus changes). -static void Hu_MenuUpdateCursorState(void) -{ - if(menuActive) - { - mn_page_t* page; - mn_object_t* obj; - - if(colorWidgetActive) - page = Hu_MenuFindPageByName("ColorWidget"); - else - page = Hu_MenuActivePage(); - - obj = MNPage_FocusObject(page); - if(obj) - { - cursorHasRotation = Hu_MenuHasCursorRotation(obj); - return; - } - } - cursorHasRotation = false; -} - -void Hu_MenuLoadResources(void) -{ - char buffer[9]; - int i; - -#if __JDOOM__ || __JDOOM64__ - pMainTitle = R_DeclarePatch("M_DOOM"); -#elif __JHERETIC__ || __JHEXEN__ - pMainTitle = R_DeclarePatch("M_HTIC"); -#endif - -#if __JDOOM__ || __JDOOM64__ - pNewGame = R_DeclarePatch("M_NEWG"); - pSkill = R_DeclarePatch("M_SKILL"); - pEpisode = R_DeclarePatch("M_EPISOD"); - pNGame = R_DeclarePatch("M_NGAME"); - pOptions = R_DeclarePatch("M_OPTION"); - pLoadGame = R_DeclarePatch("M_LOADG"); - pSaveGame = R_DeclarePatch("M_SAVEG"); - pReadThis = R_DeclarePatch("M_RDTHIS"); - pQuitGame = R_DeclarePatch("M_QUITG"); - pOptionsTitle = R_DeclarePatch("M_OPTTTL"); -#endif - -#if __JDOOM__ || __JDOOM64__ - pSkillModeNames[SM_BABY] = R_DeclarePatch("M_JKILL"); - pSkillModeNames[SM_EASY] = R_DeclarePatch("M_ROUGH"); - pSkillModeNames[SM_MEDIUM] = R_DeclarePatch("M_HURT"); - pSkillModeNames[SM_HARD] = R_DeclarePatch("M_ULTRA"); -# if __JDOOM__ - pSkillModeNames[SM_NIGHTMARE] = R_DeclarePatch("M_NMARE"); -# endif -#endif - -#if __JDOOM__ - if(gameModeBits & (GM_DOOM_SHAREWARE|GM_DOOM|GM_DOOM_ULTIMATE)) - { - pEpisodeNames[0] = R_DeclarePatch("M_EPI1"); - pEpisodeNames[1] = R_DeclarePatch("M_EPI2"); - pEpisodeNames[2] = R_DeclarePatch("M_EPI3"); - } - if(gameModeBits & GM_DOOM_ULTIMATE) - { - pEpisodeNames[3] = R_DeclarePatch("M_EPI4"); - } -#endif - -#if __JHERETIC__ - for(i = 0; i < 18; ++i) - { - dd_snprintf(buffer, 9, "M_SKL%02d", i); - pRotatingSkull[i] = R_DeclarePatch(buffer); - } -#endif - -#if __JHEXEN__ - for(i = 0; i < 7; ++i) - { - dd_snprintf(buffer, 9, "FBUL%c0", 'A'+i); - pBullWithFire[i] = R_DeclarePatch(buffer); - } - - pPlayerClassBG[0] = R_DeclarePatch("M_FBOX"); - pPlayerClassBG[1] = R_DeclarePatch("M_CBOX"); - pPlayerClassBG[2] = R_DeclarePatch("M_MBOX"); -#endif - - for(i = 0; i < MENU_CURSOR_FRAMECOUNT; ++i) - { -#if __JDOOM__ || __JDOOM64__ - dd_snprintf(buffer, 9, "M_SKULL%d", i+1); -#else - dd_snprintf(buffer, 9, "M_SLCTR%d", i+1); -#endif - pCursors[i] = R_DeclarePatch(buffer); - } -} - -void Hu_MenuInitColorWidgetPage(void) -{ -#if __JHERETIC__ || __JHEXEN__ - const Point2Raw origin = { 98, 60 }; -#else - const Point2Raw origin = { 124, 60 }; -#endif - mn_object_t* objects, *ob; - const uint numObjects = 10; - mn_page_t* page; - - page = Hu_MenuNewPage("ColorWidget", &origin, MPF_NEVER_SCROLL, Hu_MenuPageTicker, NULL, Hu_MenuColorWidgetCmdResponder, NULL); - MNPage_SetPredefinedFont(page, MENU_FONT1, FID(GF_FONTA)); - - objects = Z_Calloc(sizeof(*objects) * numObjects, PU_GAMESTATIC, 0); - if(!objects) Con_Error("Hu_MenuInitColorWidgetPage: Failed on allocation of %lu bytes for menu objects.", (unsigned long) (sizeof(*objects) * numObjects)); - - ob = objects; - - ob->_type = MN_COLORBOX; - ob->_flags = MNF_ID0|MNF_NO_FOCUS; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNColorBox_Ticker; - ob->updateGeometry = MNColorBox_UpdateGeometry; - ob->drawer = MNColorBox_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_colorbox_t), PU_GAMESTATIC, 0); - { mndata_colorbox_t* cbox = (mndata_colorbox_t*)ob->_typedata; - cbox->width = SCREENHEIGHT/7; - cbox->height = SCREENHEIGHT/7; - cbox->rgbaMode = true; - } - ob++; - - ob->_type = MN_TEXT; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Red"; - } - ob++; - - ob->_type = MN_SLIDER; - ob->_flags = MNF_ID1; - ob->_shortcut = 'r'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNSlider_Ticker; - ob->updateGeometry = MNSlider_UpdateGeometry; - ob->drawer = MNSlider_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuUpdateColorWidgetColor; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNSlider_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_slider_t), PU_GAMESTATIC, 0); - ob->data2 = CR; - { mndata_slider_t* sld = (mndata_slider_t*)ob->_typedata; - sld->min = 0; - sld->max = 1; - sld->value = 0; - sld->step = .05f; - sld->floatMode = true; - } - ob++; - - ob->_type = MN_TEXT; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Green"; - } - ob++; - - ob->_type = MN_SLIDER; - ob->_flags = MNF_ID2; - ob->_shortcut = 'g'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNSlider_Ticker; - ob->updateGeometry = MNSlider_UpdateGeometry; - ob->drawer = MNSlider_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuUpdateColorWidgetColor; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNSlider_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_slider_t), PU_GAMESTATIC, 0); - ob->data2 = CG; - { mndata_slider_t* sld = (mndata_slider_t*)ob->_typedata; - sld->min = 0; - sld->max = 1; - sld->value = 0; - sld->step = .05f; - sld->floatMode = true; - } - ob++; - - ob->_type = MN_TEXT; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Blue"; - } - ob++; - - ob->_type = MN_SLIDER; - ob->_flags = MNF_ID3; - ob->_shortcut = 'b'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNSlider_Ticker; - ob->updateGeometry = MNSlider_UpdateGeometry; - ob->drawer = MNSlider_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuUpdateColorWidgetColor; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNSlider_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_slider_t), PU_GAMESTATIC, 0); - ob->data2 = CB; - { mndata_slider_t* sld = (mndata_slider_t*)ob->_typedata; - sld->min = 0; - sld->max = 1; - sld->value = 0; - sld->step = .05f; - sld->floatMode = true; - } - ob++; - - ob->_type = MN_TEXT; - ob->_flags = MNF_ID4; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Opacity"; - } - ob++; - - ob->_type = MN_SLIDER; - ob->_flags = MNF_ID5; - ob->_shortcut = 'o'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNSlider_Ticker; - ob->updateGeometry = MNSlider_UpdateGeometry; - ob->drawer = MNSlider_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuUpdateColorWidgetColor; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNSlider_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_slider_t), PU_GAMESTATIC, 0); - ob->data2 = CA; - { mndata_slider_t* sld = (mndata_slider_t*)ob->_typedata; - sld->min = 0; - sld->max = 1; - sld->value = 0; - sld->step = .05f; - sld->floatMode = true; - } - ob++; - - ob->_type = MN_NONE; - - page->objects = objects; -} - -void Hu_MenuInitMainPage(void) -{ -#if __JHEXEN__ || __JHERETIC__ - Point2Raw origin = { 110, 56 }; - uint numObjects = 6; -#else - Point2Raw origin = { 97, 64 }; -# if __JDOOM64__ - uint numObjects = 7; -# else - uint numObjects = 8; -# endif -#endif - mn_object_t* objects, *ob; - mn_page_t* page; - int y; - -#if __JDOOM__ - if(gameModeBits & GM_ANY_DOOM2) - origin.y += 8; -#endif - -#if __JDOOM__ || __JDOOM64__ - page = Hu_MenuNewPage("Main", &origin, MPF_LAYOUT_FIXED|MPF_NEVER_SCROLL, Hu_MenuPageTicker, NULL, NULL, NULL); -#else - page = Hu_MenuNewPage("Main", &origin, MPF_LAYOUT_FIXED|MPF_NEVER_SCROLL, Hu_MenuPageTicker, Hu_MenuDrawMainPage, NULL, NULL); -#endif - MNPage_SetPredefinedFont(page, MENU_FONT1, FID(GF_FONTB)); - - objects = Z_Calloc(sizeof(*objects) * numObjects, PU_GAMESTATIC, 0); - if(!objects) Con_Error("Hu_MenuInitMainPage: Failed on allocation of %lu bytes for menu objects.", (unsigned long) (sizeof(*objects) * numObjects)); - - ob = objects; - y = 0; - -#if __JDOOM__ || __JDOOM64__ - ob->_type = MN_TEXT; - ob->_origin.x = -3; - ob->_origin.y = -70; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->patch = &pMainTitle; - } - ob++; -#endif - - ob->_type = MN_BUTTON; - ob->_origin.y = y; - ob->_shortcut = 'n'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuActionSetActivePage; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->data1 = "GameType"; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; -#if defined(__JDOOM__) && !defined(__JDOOM64__) - btn->patch = &pNGame; -#else - btn->text = "New Game"; -#endif - } - ob++; y += FIXED_LINE_HEIGHT; - - ob->_type = MN_BUTTON; - ob->_origin.y = y; - ob->_shortcut = 'o'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuActionSetActivePage; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->data1 = "Options"; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; -#if defined(__JDOOM__) && !defined(__JDOOM64__) - btn->patch = &pOptions; -#else - btn->text = "Options"; -#endif - } - ob++; y += FIXED_LINE_HEIGHT; - -#if __JDOOM__ || __JDOOM64__ - ob->_type = MN_BUTTON; - ob->_origin.y = y; - ob->_shortcut = 'l'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuSelectLoadGame; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; -# if __JDOOM64__ - btn->text = "Load Game"; -# else - btn->patch = &pLoadGame; -# endif - } - ob++; y += FIXED_LINE_HEIGHT; - - ob->_type = MN_BUTTON; - ob->_origin.y = y; - ob->_shortcut = 's'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuSelectSaveGame; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; -# if __JDOOM64__ - btn->text = "Save Game"; -# else - btn->patch = &pSaveGame; -# endif - } - ob++; y += FIXED_LINE_HEIGHT; -#else - ob->_type = MN_BUTTON; - ob->_origin.y = y; - ob->_shortcut = 'f'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuActionSetActivePage; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->data1 = "Files"; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->text = "Game Files"; - } - ob++; y += FIXED_LINE_HEIGHT; -#endif - -#if !__JDOOM64__ - ob->_type = MN_BUTTON; - ob->_origin.y = y; -# if __JDOOM__ - ob->_flags = MNF_ID0; - ob->_shortcut = 'r'; -# else - ob->_shortcut = 'i'; -# endif - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuSelectHelp; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; -# if defined(__JDOOM__) - btn->patch = &pReadThis; -# else - btn->text = "Info"; -# endif - } - ob++; y += FIXED_LINE_HEIGHT; -#endif - - ob->_type = MN_BUTTON; -#if __JDOOM__ - ob->_flags = MNF_ID1; -#endif - ob->_origin.y = y; - ob->_shortcut = 'q'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuSelectQuitGame; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; -#if defined(__JDOOM__) && !defined(__JDOOM64__) - btn->patch = &pQuitGame; -#else - btn->text = "Quit Game"; -#endif - } - ob++; y += FIXED_LINE_HEIGHT; - - ob->_type = MN_NONE; - - page->objects = objects; -} - -void Hu_MenuInitGameTypePage(void) -{ -#if __JDOOM__ || __JDOOM64__ - Point2Raw origin = { 97, 65 }; -#else - Point2Raw origin = { 104, 65 }; -#endif - mn_object_t* objects, *ob; - const uint numObjects = 3; - mn_page_t* page; - int y; - - page = Hu_MenuNewPage("GameType", &origin, 0, Hu_MenuPageTicker, Hu_MenuDrawGameTypePage, NULL, NULL); - MNPage_SetPredefinedFont(page, MENU_FONT1, FID(GF_FONTB)); - MNPage_SetPreviousPage(page, Hu_MenuFindPageByName("Main")); - - objects = Z_Calloc(sizeof(*objects) * numObjects, PU_GAMESTATIC, 0); - if(!objects) Con_Error("Hu_MenuInitGameTypeMenu: Failed on allocation of %lu bytes for menu objects.", (unsigned long) (sizeof(*objects) * numObjects)); - - ob = objects; - y = 0; - - ob->_type = MN_BUTTON; - ob->_origin.y = y; - ob->_shortcut = 's'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuSelectSingleplayer; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->text = (const char*)TXT_SINGLEPLAYER; - } - ob++; y += FIXED_LINE_HEIGHT; - - ob->_type = MN_BUTTON; - ob->_origin.y = y; - ob->_shortcut = 'm'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuSelectMultiplayer; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->text = (const char*)TXT_MULTIPLAYER; - } - ob++; y += FIXED_LINE_HEIGHT; - - ob->_type = MN_NONE; - - page->objects = objects; -} - -void Hu_MenuInitSkillPage(void) -{ -#if __JHEXEN__ - const Point2Raw origin = { 120, 44 }; -#elif __JHERETIC__ - const Point2Raw origin = { 38, 30 }; -#else - const Point2Raw origin = { 48, 63 }; -#endif - int skillButtonFlags[NUM_SKILL_MODES] = { - MNF_ID0, - MNF_ID1, - MNF_ID2 | MNF_DEFAULT, - MNF_ID3, -# if !__JDOOM64__ - MNF_ID4 -# endif - }; -#if !__JHEXEN__ - int skillButtonTexts[NUM_SKILL_MODES] = { - TXT_SKILL1, - TXT_SKILL2, - TXT_SKILL3, - TXT_SKILL4, -# if !__JDOOM64__ - TXT_SKILL5 -# endif - }; -#endif - mn_object_t* objects, *ob; - const uint numObjects = NUM_SKILL_MODES + 1; - mn_page_t* page; - int y; - - page = Hu_MenuNewPage("Skill", &origin, MPF_LAYOUT_FIXED|MPF_NEVER_SCROLL, Hu_MenuPageTicker, Hu_MenuDrawSkillPage, NULL, NULL); - MNPage_SetPredefinedFont(page, MENU_FONT1, FID(GF_FONTB)); -#if __JHEXEN__ - MNPage_SetPreviousPage(page, Hu_MenuFindPageByName("PlayerClass")); -#elif __JHERETIC__ - MNPage_SetPreviousPage(page, Hu_MenuFindPageByName("Episode")); -#elif __JDOOM64__ - MNPage_SetPreviousPage(page, Hu_MenuFindPageByName("GameType")); -#else // __JDOOM__ - if(gameModeBits & (GM_ANY_DOOM2|GM_DOOM_CHEX)) - { - MNPage_SetPreviousPage(page, Hu_MenuFindPageByName("GameType")); - } - else - { - MNPage_SetPreviousPage(page, Hu_MenuFindPageByName("Episode")); - } -#endif - - objects = Z_Calloc(sizeof(*objects) * numObjects, PU_GAMESTATIC, 0); - if(!objects) Con_Error("Hu_MenuInitSkillPage: Failed on allocation of %lu bytes for menu objects.", (unsigned long) (sizeof(*objects) * numObjects)); - - ob = objects; - y = 0; - - { uint i; - for(i = 0; i < NUM_SKILL_MODES; ++i, ob++, y += FIXED_LINE_HEIGHT) - { - ob->_type = MN_BUTTON; - ob->_flags = skillButtonFlags[i]; -#if !__JHEXEN__ - ob->_shortcut = GET_TXT(skillButtonTexts[i])[0]; -#endif - ob->_origin.y = y; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuActionInitNewGame; - ob->actions[MNA_FOCUS].callback = Hu_MenuFocusSkillMode; - ob->cmdResponder = MNButton_CommandResponder; - ob->data2 = (int)(SM_BABY + i); - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); -#if !__JHEXEN__ - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->text = INT2PTR(const char, skillButtonTexts[i]); -# if __JDOOM__ || __JDOOM64__ - btn->patch = &pSkillModeNames[i]; -# endif - } -#endif - }} - - ob->_type = MN_NONE; - - page->objects = objects; - -#if __JDOOM__ - if(gameMode != doom2_hacx && gameMode != doom_chex) - { - mn_object_t* ob = MN_MustFindObjectOnPage(page, 0, MNF_ID4); - MNButton_SetFlags(ob, FO_SET, MNBUTTON_NO_ALTTEXT); - } -#endif -} - -void Hu_MenuInitMultiplayerPage(void) -{ -#if __JHERETIC__ || __JHEXEN__ - const Point2Raw origin = { 97, 65 }; -#else - const Point2Raw origin = { 97, 65 }; -#endif - mn_object_t* objects, *ob; - const uint numObjects = 3; - mn_page_t* page; - - page = Hu_MenuNewPage("Multiplayer", &origin, 0, Hu_MenuPageTicker, Hu_MenuDrawMultiplayerPage, NULL, NULL); - MNPage_SetPredefinedFont(page, MENU_FONT1, FID(GF_FONTB)); - MNPage_SetPreviousPage(page, Hu_MenuFindPageByName("GameType")); - - objects = Z_Calloc(sizeof(*objects) * numObjects, PU_GAMESTATIC, 0); - if(!objects) Con_Error("Hu_MenuInitMultiplayerMenu: Failed on allocation of %lu bytes for menu objects.", (unsigned long) (sizeof(*objects) * numObjects)); - - ob = objects; - - ob->_type = MN_BUTTON; - ob->_flags = MNF_ID0; - ob->_shortcut = 'j'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuSelectJoinGame; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->text = "Join Game"; - } - ob++; - - ob->_type = MN_BUTTON; - ob->_shortcut = 's'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuSelectPlayerSetup; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->text = "Player Setup"; - } - ob++; - - ob->_type = MN_NONE; - - page->objects = objects; -} - -void Hu_MenuInitPlayerSetupPage(void) -{ -#if __JHERETIC__ || __JHEXEN__ - const Point2Raw origin = { 70, 44 }; -#else - const Point2Raw origin = { 70, 54 }; -#endif - mn_object_t* objects, *ob; - mn_page_t* page; - uint numObjects; - - page = Hu_MenuNewPage("PlayerSetup", &origin, 0, Hu_MenuPageTicker, Hu_MenuDrawPlayerSetupPage, NULL, NULL); - MNPage_SetPredefinedFont(page, MENU_FONT1, FID(GF_FONTA)); - MNPage_SetPredefinedFont(page, MENU_FONT2, FID(GF_FONTB)); - MNPage_SetPreviousPage(page, Hu_MenuFindPageByName("Multiplayer")); - -#if __JHEXEN__ - numObjects = 8; -#else - numObjects = 6; -#endif - objects = Z_Calloc(sizeof(*objects) * numObjects, PU_GAMESTATIC, 0); - if(!objects) Con_Error("Hu_MenuInitPlayerSetupMenu: Failed on allocation of %lu bytes for player setup menu objects.", (unsigned long) (sizeof(*objects) * numObjects)); - - ob = objects; - - ob->_type = MN_MOBJPREVIEW; - ob->_origin.x = SCREENWIDTH/2 - origin.x; - ob->_origin.y = 60; - ob->_flags = MNF_ID0 | MNF_POSITION_FIXED; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNMobjPreview_Ticker; - ob->updateGeometry = MNMobjPreview_UpdateGeometry; - ob->drawer = MNMobjPreview_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_mobjpreview_t), PU_GAMESTATIC, 0); - ob++; - - ob->_type = MN_EDIT; - ob->_flags = MNF_ID1 | MNF_LAYOUT_OFFSET; - ob->_origin.y = 75; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNEdit_Ticker; - ob->updateGeometry = MNEdit_UpdateGeometry; - ob->drawer = MNEdit_Drawer; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNEdit_CommandResponder; - ob->responder = MNEdit_Responder; - ob->_typedata = Z_Calloc(sizeof(mndata_edit_t), PU_GAMESTATIC, 0); - { mndata_edit_t* edit = (mndata_edit_t*)ob->_typedata; - Str_Init(&edit->text); - Str_Init(&edit->oldtext); - edit->data1 = "net-name"; - edit->maxLength = 24; - } - ob++; - -#if __JHEXEN__ - ob->_type = MN_TEXT; - ob->_flags = MNF_LAYOUT_OFFSET; - ob->_origin.y = 5; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Class"; - } - ob++; - - ob->_type = MN_LISTINLINE; - ob->_flags = MNF_ID2; - ob->_shortcut = 'c'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR3; - ob->ticker = MNListInline_Ticker; - ob->updateGeometry = MNListInline_UpdateGeometry; - ob->drawer = MNListInline_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuSelectPlayerSetupPlayerClass; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNListInline_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_list_t), PU_GAMESTATIC, 0); - { mndata_list_t* list = (mndata_list_t*)ob->_typedata; - list->count = 3; - list->items = (mndata_listitem_t*)Z_Calloc(sizeof(mndata_listitem_t) * list->count, PU_GAMESTATIC, 0); - - { mndata_listitem_t* item = list->items; - item->text = (const char*)TXT_PLAYERCLASS1; - item->data = PCLASS_FIGHTER; - item++; - - item->text = (const char*)TXT_PLAYERCLASS2; - item->data = PCLASS_CLERIC; - item++; - - item->text = (const char*)TXT_PLAYERCLASS3; - item->data = PCLASS_MAGE; - } - } - ob++; -#endif - - ob->_type = MN_TEXT; -#ifdef __JHERETIC__ - ob->_flags = MNF_LAYOUT_OFFSET; - ob->_origin.y = 5; -#endif - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Color"; - } - ob++; - - // Setup the player color selection list. - ob->_type = MN_LISTINLINE; - ob->_flags = MNF_ID3; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR3; - ob->ticker = MNListInline_Ticker; - ob->updateGeometry = MNListInline_UpdateGeometry; - ob->drawer = MNListInline_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuSelectPlayerColor; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNListInline_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_list_t), PU_GAMESTATIC, 0); - { mndata_list_t* list = (mndata_list_t*)ob->_typedata; -#if __JHEXEN__ - // Hexen v1.0 has only four player colors. - list->count = (gameMode == hexen_v10? 4 : NUMPLAYERCOLORS) + 1/*auto*/; -#else - list->count = NUMPLAYERCOLORS + 1/*auto*/; -#endif - list->items = (mndata_listitem_t*)Z_Calloc(sizeof(mndata_listitem_t) * list->count, PU_GAMESTATIC, 0); - - /// @todo Read these names from Text definitions. - { mndata_listitem_t* item = list->items; -#if __JHEXEN__ - item->text = "Red"; item->data = 0; - item++; - - item->text = "Blue"; item->data = 1; - item++; - - item->text = "Yellow"; item->data = 2; - item++; - - item->text = "Green"; item->data = 3; - item++; - - // Hexen v1.0 has only four player colors. - if(gameMode != hexen_v10) - { - item->text = "Jade"; item->data = 4; - item++; - - item->text = "White"; item->data = 5; - item++; - - item->text = "Hazel"; item->data = 6; - item++; - - item->text = "Purple"; item->data = 7; - item++; - } - - item->text = "Automatic"; item->data = 8; -#elif __JHERETIC__ - item->text = "Green"; item->data = 0; - item++; - - item->text = "Orange"; item->data = 1; - item++; - - item->text = "Red"; item->data = 2; - item++; - - item->text = "Blue"; item->data = 3; - item++; - - item->text = "Automatic"; item->data = 4; -#else - item->text = "Green"; item->data = 0; - item++; - - item->text = "Indigo"; item->data = 1; - item++; - - item->text = "Brown"; item->data = 2; - item++; - - item->text = "Red"; item->data = 3; - item++; - - item->text = "Automatic"; item->data = 4; -#endif - } - } - ob++; - - ob->_type = MN_BUTTON; - ob->_shortcut = 's'; - ob->_pageFontIdx = MENU_FONT2; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuSelectAcceptPlayerSetup; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->text = "Save Changes"; - } - ob++; - - ob->_type = MN_NONE; - - page->objects = objects; -} - -void Hu_MenuInitSaveOptionsPage(void) -{ - const Point2Raw origin = { 60, 50 }; - mn_object_t* objects, *ob; -#if !__JHEXEN__ - const uint numObjects = 10; -#else - const uint numObjects = 8; -#endif - mn_page_t* page; - - page = Hu_MenuNewPage("SaveOptions", &origin, 0, Hu_MenuPageTicker, NULL, NULL, NULL); - MNPage_SetTitle(page, "Save Options"); - MNPage_SetPredefinedFont(page, MENU_FONT1, FID(GF_FONTA)); - MNPage_SetPreviousPage(page, Hu_MenuFindPageByName("Options")); - - objects = Z_Calloc(sizeof(*objects) * numObjects, PU_GAMESTATIC, 0); - if(!objects) Con_Error("Hu_MenuInitSaveOptionsPage: Failed on allocation of %lu bytes for menu objects.", (unsigned long) (sizeof(*objects) * numObjects)); - - ob = objects; - - ob->_type = MN_TEXT; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Confirm quick load/save"; - } - ob++; - - ob->_type = MN_BUTTON; - ob->_shortcut = 'q'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR3; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->staydownMode = true; - btn->data = "game-save-confirm"; - } - ob++; - - ob->_type = MN_TEXT; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Confirm reborn load"; - } - ob++; - - ob->_type = MN_BUTTON; - ob->_shortcut = 'r'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR3; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->staydownMode = true; - btn->data = "game-save-confirm-loadonreborn"; - } - ob++; - - ob->_type = MN_TEXT; - ob->_group = 1; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR2; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Reborn preferences"; - } - ob++; - -#if !__JHEXEN__ - ob->_type = MN_TEXT; - ob->_group = 1; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Load auto save"; - } - ob++; - - ob->_type = MN_BUTTON; - ob->_group = 1; - ob->_shortcut = 'a'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR3; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->staydownMode = true; - btn->data = "game-save-auto-loadonreborn"; - } - ob++; -#endif - - ob->_type = MN_TEXT; - ob->_group = 1; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Load last save"; - } - ob++; - - ob->_type = MN_BUTTON; - ob->_group = 1; - ob->_shortcut = 'a'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR3; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->staydownMode = true; - btn->data = "game-save-last-loadonreborn"; - } - ob++; - - ob->_type = MN_NONE; - - page->objects = objects; -} - -#if __JHERETIC__ || __JHEXEN__ -void Hu_MenuInitFilesPage(void) -{ - Point2Raw origin = { 110, 60 }; - mn_object_t* objects, *ob; - const uint numObjects = 3; - mn_page_t* page; - int y; - - page = Hu_MenuNewPage("Files", &origin, MPF_LAYOUT_FIXED|MPF_NEVER_SCROLL, Hu_MenuPageTicker, NULL, NULL, NULL); - MNPage_SetPredefinedFont(page, MENU_FONT1, FID(GF_FONTB)); - MNPage_SetPreviousPage(page, Hu_MenuFindPageByName("Main")); - - objects = Z_Calloc(sizeof(*objects) * numObjects, PU_GAMESTATIC, 0); - if(!objects) Con_Error("Hu_MenuInitFilesMenu: Failed on allocation of %lu bytes for menu objects.", (unsigned long) (sizeof(*objects) * numObjects)); - - ob = objects; - y = 0; - - ob->_type = MN_BUTTON; - ob->_origin.y = y; - ob->_shortcut = 'l'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuSelectLoadGame; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->text = "Load Game"; - } - ob++; y += FIXED_LINE_HEIGHT; - - ob->_type = MN_BUTTON; - ob->_origin.y = y; - ob->_shortcut = 's'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuSelectSaveGame; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->text = "Save Game"; - } - ob++; y += FIXED_LINE_HEIGHT; - - ob->_type = MN_NONE; - - page->objects = objects; -} -#endif - -static void deleteGameSave(int slot) -{ - DD_Executef(true, "deletegamesave %i", slot); -} - -int Hu_MenuLoadSlotCommandResponder(mn_object_t* ob, menucommand_e cmd) -{ - DENG_ASSERT(ob && ob->_type == MN_EDIT); - if(MCMD_DELETE == cmd && - (ob->_flags & MNF_FOCUS) && !(ob->_flags & MNF_ACTIVE) && !(ob->_flags & MNF_DISABLED)) - { - mndata_edit_t* edit = (mndata_edit_t*)ob->_typedata; - deleteGameSave(edit->data2); - return true; - } - return MNObject_DefaultCommandResponder(ob, cmd); -} - -int Hu_MenuSaveSlotCommandResponder(mn_object_t* ob, menucommand_e cmd) -{ - assert(ob); - if(MCMD_DELETE == cmd && - (ob->_flags & MNF_FOCUS) && !(ob->_flags & MNF_ACTIVE) && !(ob->_flags & MNF_DISABLED)) - { - mndata_edit_t* edit = (mndata_edit_t*)ob->_typedata; - deleteGameSave(edit->data2); - return true; - } - return MNEdit_CommandResponder(ob, cmd); -} - -void Hu_MenuInitLoadGameAndSaveGamePages(void) -{ -#if __JDOOM__ || __JDOOM64__ - Point2Raw const origin = { 80, 54 }; -#else - Point2Raw const origin = { 70, 30 }; -#endif - mn_object_t *loadMenuObjects, *saveMenuObjects; - mndata_edit_t *saveSlots; - mn_page_t *page; - int const saveSlotObjectIds[NUMSAVESLOTS] = { - MNF_ID0, MNF_ID1, MNF_ID2, MNF_ID3, MNF_ID4, MNF_ID5, -#if !__JHEXEN__ - MNF_ID6, MNF_ID7 -#endif - }; - int i, y; - - saveSlots = Z_Calloc(sizeof(*saveSlots) * NUMSAVESLOTS, PU_GAMESTATIC, 0); - if(!saveSlots) Con_Error("Hu_MenuInitLoadGameAndSaveGamePages: Failed on allocation of %lu bytes for load/save menu edit fields.", (unsigned long) (sizeof(*saveSlots) * NUMSAVESLOTS)); - - for(i = 0; i < NUMSAVESLOTS; ++i) - { - mndata_edit_t* slot = saveSlots + i; - slot->emptyString = (const char*) TXT_EMPTYSTRING; - slot->data2 = i; - slot->maxLength = 24; - } - - loadMenuObjects = Z_Calloc(sizeof(*loadMenuObjects) * (NUMSAVESLOTS+1), PU_GAMESTATIC, 0); - if(!loadMenuObjects) Con_Error("Hu_MenuInitLoadGameAndSaveGamePages: Failed on allocation of %lu bytes for load menu objects.", (unsigned long) (sizeof(*loadMenuObjects) * (NUMSAVESLOTS+1))); - - y = 0; - for(i = 0; i < NUMSAVESLOTS; ++i, y += FIXED_LINE_HEIGHT) - { - mn_object_t* ob = loadMenuObjects + i; - mndata_edit_t* edit = saveSlots + i; - ob->_type = MN_EDIT; - ob->_origin.x = 0; - ob->_origin.y = y; - ob->_flags = saveSlotObjectIds[i] | MNF_DISABLED; - ob->_shortcut = '0' + i; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->updateGeometry = MNEdit_UpdateGeometry; - ob->drawer = MNEdit_Drawer; - ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuSelectLoadSlot; - ob->actions[MNA_FOCUSOUT].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = Hu_MenuLoadSlotCommandResponder; - ob->_typedata = edit; - ob->data2 = saveSlotObjectIds[i]; - Str_Init(&edit->text); - Str_Init(&edit->oldtext); - } - loadMenuObjects[i]._type = MN_NONE; - - saveMenuObjects = Z_Calloc(sizeof(*saveMenuObjects) * (NUMSAVESLOTS+1), PU_GAMESTATIC, 0); - if(!saveMenuObjects) Con_Error("initAllPages: Failed on allocation of %lu bytes for save menu objects.", (unsigned long) (sizeof(*saveMenuObjects) * (NUMSAVESLOTS+1))); - - y = 0; - for(i = 0; i < NUMSAVESLOTS; ++i, y += FIXED_LINE_HEIGHT) - { - mn_object_t* ob = saveMenuObjects + i; - mndata_edit_t* edit = saveSlots + i; - ob->_type = MN_EDIT; - ob->_origin.x = 0; - ob->_origin.y = y; - ob->_flags = saveSlotObjectIds[i]; - ob->_shortcut = '0' + i; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->updateGeometry = MNEdit_UpdateGeometry; - ob->drawer = MNEdit_Drawer; - ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuSelectSaveSlot; - ob->actions[MNA_ACTIVE].callback = Hu_MenuSaveSlotEdit; - ob->actions[MNA_FOCUSOUT].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = Hu_MenuSaveSlotCommandResponder; - ob->responder = MNEdit_Responder; - ob->_typedata = edit; - ob->data2 = saveSlotObjectIds[i]; - } - saveMenuObjects[i]._type = MN_NONE; - - page = Hu_MenuNewPage("LoadGame", &origin, MPF_LAYOUT_FIXED|MPF_NEVER_SCROLL, Hu_MenuPageTicker, Hu_MenuDrawLoadGamePage, NULL, NULL); - MNPage_SetPredefinedFont(page, MENU_FONT1, FID(GF_FONTA)); - MNPage_SetPreviousPage(page, Hu_MenuFindPageByName("Main")); - page->objects = loadMenuObjects; - - page = Hu_MenuNewPage("SaveGame", &origin, MPF_LAYOUT_FIXED|MPF_NEVER_SCROLL, Hu_MenuPageTicker, Hu_MenuDrawSaveGamePage, NULL, NULL); - MNPage_SetPredefinedFont(page, MENU_FONT1, FID(GF_FONTA)); - MNPage_SetPreviousPage(page, Hu_MenuFindPageByName("Main")); - page->objects = saveMenuObjects; -} - -void Hu_MenuInitOptionsPage(void) -{ -#if __JHERETIC__ || __JHEXEN__ - const Point2Raw origin = { 110, 63 }; -#else - const Point2Raw origin = { 110, 63 }; -#endif - mn_object_t* objects, *ob; -#if __JHERETIC__ || __JHEXEN__ - const uint numObjects = 13; -#else - const uint numObjects = 12; -#endif - mn_page_t* page; - - page = Hu_MenuNewPage("Options", &origin, 0, Hu_MenuPageTicker, Hu_MenuDrawOptionsPage, NULL, NULL); - MNPage_SetPredefinedFont(page, MENU_FONT1, FID(GF_FONTA)); - MNPage_SetPreviousPage(page, Hu_MenuFindPageByName("Main")); - - objects = Z_Calloc(sizeof(*objects) * numObjects, PU_GAMESTATIC, 0); - if(!objects) Con_Error("Hu_MenuInitOptionsPage: Failed on allocation of %lu bytes for menu objects.", (unsigned long) (sizeof(*objects) * numObjects)); - - ob = objects; - - ob->_type = MN_BUTTON; - ob->_shortcut = 'e'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuSelectEndGame; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->text = "End Game"; - } - ob++; - - ob->_type = MN_BUTTON; - ob->_shortcut = 't'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuSelectControlPanelLink; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->text = "Show Taskbar"; - } - ob++; - - ob->_type = MN_BUTTON; - ob->_shortcut = 'c'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuActionSetActivePage; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->data1 = "ControlOptions"; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->text = "Controls"; - } - ob++; - - ob->_type = MN_BUTTON; - ob->_shortcut = 'g'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuActionSetActivePage; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->data1 = "GameplayOptions"; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->text = "Gameplay"; - } - ob++; - - ob->_type = MN_BUTTON; - ob->_shortcut = 's'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuActionSetActivePage; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->data1 = "SaveOptions"; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->text = "Game saves"; - } - ob++; - - ob->_type = MN_BUTTON; - ob->_shortcut = 'h'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuActionSetActivePage; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->data1 = "HUDOptions"; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->text = "HUD"; - } - ob++; - - ob->_type = MN_BUTTON; - ob->_shortcut = 'a'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuActionSetActivePage; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->data1 = "AutomapOptions"; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->text = "Automap"; - } - ob++; - - ob->_type = MN_BUTTON; - ob->_shortcut = 'w'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuActionSetActivePage; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->data1 = "WeaponOptions"; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->text = "Weapons"; - } - ob++; - -#if __JHERETIC__ || __JHEXEN__ - ob->_type = MN_BUTTON; - ob->_shortcut = 'i'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuActionSetActivePage; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->data1 = "InventoryOptions"; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->text = "Inventory"; - } - ob++; -#endif - - ob->_type = MN_BUTTON; - ob->_shortcut = 's'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuActionSetActivePage; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->data1 = "SoundOptions"; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->text = "Sound"; - } - ob++; - - /* - ob->_type = MN_BUTTON; - ob->_shortcut = 'm'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuSelectControlPanelLink; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->data2 = 2; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->text = "Mouse"; - } - ob++; - - ob->_type = MN_BUTTON; - ob->_shortcut = 'j'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuSelectControlPanelLink; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->data2 = 2; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->text = "Joystick"; - } - ob++;*/ - - ob->_type = MN_NONE; - - page->objects = objects; -} - -void Hu_MenuInitGameplayOptionsPage(void) -{ -#if __JHEXEN__ - const Point2Raw origin = { 88, 25 }; -#elif __JHERETIC__ - const Point2Raw origin = { 30, 40 }; -#else - const Point2Raw origin = { 30, 40 }; -#endif - mn_object_t* objects, *ob; -#if __JDOOM64__ - const uint numObjects = 40; -#elif __JDOOM__ - const uint numObjects = 42; -#elif __JHERETIC__ - const uint numObjects = 24; -#elif __JHEXEN__ - const uint numObjects = 7; -#endif - mn_page_t* page; - - page = Hu_MenuNewPage("GameplayOptions", &origin, 0, Hu_MenuPageTicker, NULL, NULL, NULL); - MNPage_SetTitle(page, "Gameplay Options"); - MNPage_SetPredefinedFont(page, MENU_FONT1, FID(GF_FONTA)); - MNPage_SetPreviousPage(page, Hu_MenuFindPageByName("Options")); - - objects = Z_Calloc(sizeof(*objects) * numObjects, PU_GAMESTATIC, 0); - if(!objects) Con_Error("Hu_MenuInitGameplayOptionsPage: Failed on allocation of %lu bytes for menu objects.", (unsigned long) (sizeof(*objects) * numObjects)); - - ob = objects; - - ob->_type = MN_TEXT; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Always Run"; - } - ob++; - - ob->_type = MN_BUTTON; - ob->_shortcut = 'r'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR3; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->staydownMode = true; - btn->data = "ctl-run"; - } - ob++; - - ob->_type = MN_TEXT; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Use LookSpring"; - } - ob++; - - ob->_type = MN_BUTTON; - ob->_shortcut = 'l'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR3; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->staydownMode = true; - btn->data = "ctl-look-spring"; - } - ob++; - - ob->_type = MN_TEXT; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Disable AutoAim"; - } - ob++; - - ob->_type = MN_BUTTON; - ob->_shortcut = 'a'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR3; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->staydownMode = true; - btn->data = "ctl-aim-noauto"; - } - ob++; - -#if __JDOOM__ || __JHERETIC__ || __JDOOM64__ - ob->_type = MN_TEXT; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Allow Jumping"; - } - ob++; - - ob->_type = MN_BUTTON; - ob->_shortcut = 'j'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR3; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->staydownMode = true; - btn->data = "player-jump"; - } - ob++; -#endif - -#if __JDOOM64__ - ob->_type = MN_TEXT; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Weapon Recoil"; - } - ob++; - - ob->_type = MN_BUTTON; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR3; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->staydownMode = true; - btn->data = "player-weapon-recoil"; - } - ob++; -#endif - -#if __JDOOM__ || __JHERETIC__ || __JDOOM64__ - ob->_type = MN_TEXT; - ob->_group = 1; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR2; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Compatibility"; - } - ob++; - -# if __JDOOM__ || __JDOOM64__ - ob->_type = MN_TEXT; - ob->_group = 1; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Any Boss Trigger 666"; - } - ob++; - - ob->_type = MN_BUTTON; - ob->_group = 1; - ob->_shortcut = 'b'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR3; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->staydownMode = true; - btn->data = "game-anybossdeath666"; - } - ob++; - -# if !__JDOOM64__ - ob->_type = MN_TEXT; - ob->_group = 1; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Av Resurrects Ghosts"; - } - ob++; - - ob->_type = MN_BUTTON; - ob->_group = 1; - ob->_shortcut = 'g'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR3; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->staydownMode = true; - btn->data = "game-raiseghosts"; - } - ob++; - -# if __JDOOM__ - ob->_type = MN_TEXT; - ob->_group = 1; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "VileChase uses Av radius"; - } - ob++; - - ob->_type = MN_BUTTON; - ob->_group = 1; - ob->_shortcut = 'g'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR3; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->staydownMode = true; - btn->data = "game-vilechase-usevileradius"; - } - ob++; -# endif -# endif // !__JDOOM64__ - - ob->_type = MN_TEXT; - ob->_group = 1; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "PE Limited To 21 Lost Souls"; - } - ob++; - - ob->_type = MN_BUTTON; - ob->_group = 1; - ob->_shortcut = 'p'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR3; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->staydownMode = true; - btn->data = "game-maxskulls"; - } - ob++; - - ob->_type = MN_TEXT; - ob->_group = 1; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "LS Can Get Stuck Inside Walls"; - } - ob++; - - ob->_type = MN_BUTTON; - ob->_group = 1; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR3; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->staydownMode = true; - btn->data = "game-skullsinwalls"; - } - ob++; -# endif // __JDOOM__ || __JDOOM64__ - - ob->_type = MN_TEXT; - ob->_group = 1; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Monsters Fly Over Obstacles"; - } - ob++; - - ob->_type = MN_BUTTON; - ob->_group = 1; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR3; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->staydownMode = true; - btn->data = "game-monsters-floatoverblocking"; - } - ob++; - - ob->_type = MN_TEXT; - ob->_group = 1; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Monsters Can Get Stuck In Doors"; - } - ob++; - - ob->_type = MN_BUTTON; - ob->_group = 1; - ob->_shortcut = 'd'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR3; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->staydownMode = true; - btn->data = "game-monsters-stuckindoors"; - } - ob++; - - ob->_type = MN_TEXT; - ob->_group = 1; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Some Objects Never Hang Over Ledges"; - } - ob++; - - ob->_type = MN_BUTTON; - ob->_group = 1; - ob->_shortcut = 'h'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR3; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->staydownMode = true; - btn->data = "game-objects-neverhangoverledges"; - } - ob++; - - ob->_type = MN_TEXT; - ob->_group = 1; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Objects Fall Under Own Weight"; - } - ob++; - - ob->_type = MN_BUTTON; - ob->_group = 1; - ob->_shortcut = 'f'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR3; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->staydownMode = true; - btn->data = "game-objects-falloff"; - } - ob++; - -#if __JDOOM__ || __JDOOM64__ - ob->_type = MN_TEXT; - ob->_group = 1; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "All Crushed Objects Become A Pile Of Gibs"; - } - ob++; - - ob->_type = MN_BUTTON; - ob->_group = 1; - ob->_shortcut = 'g'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR3; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->staydownMode = true; - btn->data = "game-objects-gibcrushednonbleeders"; - } - ob++; -#endif - - ob->_type = MN_TEXT; - ob->_group = 1; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Corpses Slide Down Stairs"; - } - ob++; - - ob->_type = MN_BUTTON; - ob->_group = 1; - ob->_shortcut = 's'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR3; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->staydownMode = true; - btn->data = "game-corpse-sliding"; - } - ob++; - - ob->_type = MN_TEXT; - ob->_group = 1; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Use Exactly Doom's Clipping Code"; - } - ob++; - - ob->_type = MN_BUTTON; - ob->_group = 1; - ob->_shortcut = 'c'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR3; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->staydownMode = true; - btn->data = "game-objects-clipping"; - } - ob++; - - ob->_type = MN_TEXT; - ob->_group = 1; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = " ^If Not NorthOnly WallRunning"; - } - ob++; - - ob->_type = MN_BUTTON; - ob->_group = 1; - ob->_shortcut = 'w'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR3; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->staydownMode = true; - btn->data = "game-player-wallrun-northonly"; - } - ob++; - -# if __JDOOM__ || __JDOOM64__ - ob->_type = MN_TEXT; - ob->_group = 1; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Zombie Players Can Exit Maps"; - } - ob++; - - ob->_type = MN_BUTTON; - ob->_group = 1; - ob->_shortcut = 'e'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR3; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->staydownMode = true; - btn->data = "game-zombiescanexit"; - } - ob++; - - ob->_type = MN_TEXT; - ob->_group = 1; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Fix Ouch Face"; - } - ob++; - - ob->_type = MN_BUTTON; - ob->_group = 1; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR3; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->staydownMode = true; - btn->data = "hud-face-ouchfix"; - } - ob++; - - ob->_type = MN_TEXT; - ob->_group = 1; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Fix Weapon Slot Display"; - } - ob++; - - ob->_type = MN_BUTTON; - ob->_group = 1; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR3; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->staydownMode = true; - btn->data = "hud-status-weaponslots-ownedfix"; - } - ob++; -# endif // __JDOOM__ || __JDOOM64__ -#endif // __JDOOM__ || __JHERETIC__ || __JDOOM64__ - - ob->_type = MN_NONE; - - page->objects = objects; -} - -void Hu_MenuInitHUDOptionsPage(void) -{ -#if __JDOOM__ || __JDOOM64__ - const Point2Raw origin = { 97, 40 }; -#else - const Point2Raw origin = { 97, 28 }; -#endif - mn_page_t* page; - - page = Hu_MenuNewPage("HudOptions", &origin, 0, Hu_MenuPageTicker, NULL, NULL, NULL); - MNPage_SetTitle(page, "HUD Options"); - MNPage_SetPredefinedFont(page, MENU_FONT1, FID(GF_FONTA)); - MNPage_SetPreviousPage(page, Hu_MenuFindPageByName("Options")); - page->objects = HudMenuObjects; -} - -void Hu_MenuInitAutomapOptionsPage(void) -{ -#if __JHERETIC__ || __JHEXEN__ - const Point2Raw origin = { 64, 28 }; -#else - const Point2Raw origin = { 70, 40 }; -#endif - mn_object_t* objects, *ob; -#if __JDOOM64__ - const uint numObjects = 26; -#else - const uint numObjects = 27; -#endif - mn_page_t* page; - - page = Hu_MenuNewPage("AutomapOptions", &origin, 0, Hu_MenuPageTicker, NULL, NULL, NULL); - MNPage_SetTitle(page, "Automap Options"); - MNPage_SetPredefinedFont(page, MENU_FONT1, FID(GF_FONTA)); - MNPage_SetPreviousPage(page, Hu_MenuFindPageByName("Options")); - - objects = Z_Calloc(sizeof(*objects) * numObjects, PU_GAMESTATIC, 0); - if(!objects) Con_Error("Hu_MenuInitAutomapOptionsPage: Failed on allocation of %lu bytes for menu objects.", (unsigned long) (sizeof(*objects) * numObjects)); - - ob = objects; - - ob->_type = MN_TEXT; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Background Opacity"; - } - ob++; - - ob->_type = MN_SLIDER; - ob->_shortcut = 'o'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNSlider_Ticker; - ob->updateGeometry = MNSlider_UpdateGeometry; - ob->drawer = MNSlider_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarSlider; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNSlider_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_slider_t), PU_GAMESTATIC, 0); - { mndata_slider_t* sld = (mndata_slider_t*)ob->_typedata; - sld->min = 0; - sld->max = 1; - sld->value = 0; - sld->step = 0.1f; - sld->floatMode = true; - sld->data1 = "map-opacity"; - } - ob++; - - ob->_type = MN_TEXT; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Line Opacity"; - } - ob++; - - ob->_type = MN_SLIDER; - ob->_shortcut = 'l'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNSlider_Ticker; - ob->updateGeometry = MNSlider_UpdateGeometry; - ob->drawer = MNSlider_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarSlider; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNSlider_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_slider_t), PU_GAMESTATIC, 0); - { mndata_slider_t* sld = (mndata_slider_t*)ob->_typedata; - sld->min = 0; - sld->max = 1; - sld->value = 0; - sld->step = 0.1f; - sld->floatMode = true; - sld->data1 = "map-line-opacity"; - } - ob++; - - ob->_type = MN_TEXT; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Line Width"; - } - ob++; - - ob->_type = MN_SLIDER; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNSlider_Ticker; - ob->updateGeometry = MNSlider_UpdateGeometry; - ob->drawer = MNSlider_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarSlider; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNSlider_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_slider_t), PU_GAMESTATIC, 0); - { mndata_slider_t* sld = (mndata_slider_t*)ob->_typedata; - sld->min = .1f; - sld->max = 2; - sld->value = 0; - sld->step = 0.1f; - sld->floatMode = true; - sld->data1 = "map-line-width"; - } - ob++; - - ob->_type = MN_TEXT; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "HUD Display"; - } - ob++; - -#if !__JDOOM64__ - ob->_type = MN_LISTINLINE; - ob->_shortcut = 'h'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR3; - ob->ticker = MNListInline_Ticker; - ob->updateGeometry = MNListInline_UpdateGeometry; - ob->drawer = MNListInline_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarList; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNListInline_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_list_t), PU_GAMESTATIC, 0); - { mndata_list_t* list = (mndata_list_t*)ob->_typedata; - mndata_listitem_t* item; - - list->data = "map-huddisplay"; - list->count = 3; - item = list->items = (mndata_listitem_t*)Z_Calloc(sizeof(mndata_listitem_t) * list->count, PU_GAMESTATIC, 0); - - item->text = "None"; - item->data = 0; - item++; - - item->text = "Current"; - item->data = 1; - item++; - - item->text = "Statusbar"; - item->data = 2; - } - ob++; -#endif - - ob->_type = MN_TEXT; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Door Colors"; - } - ob++; - - ob->_type = MN_BUTTON; - ob->_shortcut = 'd'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR3; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->staydownMode = true; - btn->data = "map-door-colors"; - } - ob++; - - ob->_type = MN_TEXT; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Door Glow"; - } - ob++; - - ob->_type = MN_SLIDER; - ob->_shortcut = 'g'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNSlider_Ticker; - ob->updateGeometry = MNSlider_UpdateGeometry; - ob->drawer = MNSlider_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarSlider; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNSlider_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_slider_t), PU_GAMESTATIC, 0); - { mndata_slider_t* sld = (mndata_slider_t*)ob->_typedata; - sld->min = 0; - sld->max = 200; - sld->value = 0; - sld->step = 5; - sld->floatMode = true; - sld->data1 = "map-door-glow"; - } - ob++; - - ob->_type = MN_TEXT; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Use Custom Colors"; - } - ob++; - - ob->_type = MN_LISTINLINE; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR3; - ob->ticker = MNListInline_Ticker; - ob->updateGeometry = MNListInline_UpdateGeometry; - ob->drawer = MNListInline_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarList; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNListInline_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_list_t), PU_GAMESTATIC, 0); - { mndata_list_t* list = (mndata_list_t*)ob->_typedata; - mndata_listitem_t* item; - - list->count = 3; - item = list->items = (mndata_listitem_t*)Z_Calloc(sizeof(mndata_listitem_t) * list->count, PU_GAMESTATIC, 0); - list->data = "map-customcolors"; - - item->text = "Never"; - item->data = 0; - item++; - - item->text = "Auto"; - item->data = 1; - item++; - - item->text = "Always"; - item->data = 2; - } - ob++; - - ob->_type = MN_TEXT; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Wall"; - } - ob++; - - ob->_type = MN_COLORBOX; - ob->_shortcut = 'w'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNColorBox_Ticker; - ob->updateGeometry = MNColorBox_UpdateGeometry; - ob->drawer = MNColorBox_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarColorBox; - ob->actions[MNA_ACTIVE].callback = Hu_MenuActivateColorWidget; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNColorBox_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_colorbox_t), PU_GAMESTATIC, 0); - { mndata_colorbox_t* cbox = (mndata_colorbox_t*)ob->_typedata; - cbox->data1 = "map-wall-r"; - cbox->data2 = "map-wall-g"; - cbox->data3 = "map-wall-b"; - } - ob++; - - ob->_type = MN_TEXT; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Floor Height Change"; - } - ob++; - - ob->_type = MN_COLORBOX; - ob->_shortcut = 'f'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNColorBox_Ticker; - ob->updateGeometry = MNColorBox_UpdateGeometry; - ob->drawer = MNColorBox_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarColorBox; - ob->actions[MNA_ACTIVE].callback = Hu_MenuActivateColorWidget; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNColorBox_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_colorbox_t), PU_GAMESTATIC, 0); - { mndata_colorbox_t* cbox = (mndata_colorbox_t*)ob->_typedata; - cbox->data1 = "map-wall-floorchange-r"; - cbox->data2 = "map-wall-floorchange-g"; - cbox->data3 = "map-wall-floorchange-b"; - } - ob++; - - ob->_type = MN_TEXT; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Ceiling Height Change"; - } - ob++; - - ob->_type = MN_COLORBOX; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNColorBox_Ticker; - ob->updateGeometry = MNColorBox_UpdateGeometry; - ob->drawer = MNColorBox_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarColorBox; - ob->actions[MNA_ACTIVE].callback = Hu_MenuActivateColorWidget; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNColorBox_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_colorbox_t), PU_GAMESTATIC, 0); - { mndata_colorbox_t* cbox = (mndata_colorbox_t*)ob->_typedata; - cbox->data1 = "map-wall-ceilingchange-r"; - cbox->data2 = "map-wall-ceilingchange-g"; - cbox->data3 = "map-wall-ceilingchange-b"; - } - ob++; - - ob->_type = MN_TEXT; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Unseen"; - } - ob++; - - ob->_type = MN_COLORBOX; - ob->_shortcut = 'u'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNColorBox_Ticker; - ob->updateGeometry = MNColorBox_UpdateGeometry; - ob->drawer = MNColorBox_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarColorBox; - ob->actions[MNA_ACTIVE].callback = Hu_MenuActivateColorWidget; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNColorBox_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_colorbox_t), PU_GAMESTATIC, 0); - { mndata_colorbox_t* cbox = (mndata_colorbox_t*)ob->_typedata; - cbox->data1 = "map-wall-unseen-r"; - cbox->data2 = "map-wall-unseen-g"; - cbox->data3 = "map-wall-unseen-b"; - } - ob++; - - ob->_type = MN_TEXT; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Thing"; - } - ob++; - - ob->_type = MN_COLORBOX; - ob->_shortcut = 't'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNColorBox_Ticker; - ob->updateGeometry = MNColorBox_UpdateGeometry; - ob->drawer = MNColorBox_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarColorBox; - ob->actions[MNA_ACTIVE].callback = Hu_MenuActivateColorWidget; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNColorBox_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_colorbox_t), PU_GAMESTATIC, 0); - { mndata_colorbox_t* cbox = (mndata_colorbox_t*)ob->_typedata; - cbox->data1 = "map-mobj-r"; - cbox->data2 = "map-mobj-g"; - cbox->data3 = "map-mobj-b"; - } - ob++; - - ob->_type = MN_TEXT; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Background"; - } - ob++; - - ob->_type = MN_COLORBOX; - ob->_shortcut = 'b'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNColorBox_Ticker; - ob->updateGeometry = MNColorBox_UpdateGeometry; - ob->drawer = MNColorBox_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarColorBox; - ob->actions[MNA_ACTIVE].callback = Hu_MenuActivateColorWidget; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNColorBox_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_colorbox_t), PU_GAMESTATIC, 0); - { mndata_colorbox_t* cbox = (mndata_colorbox_t*)ob->_typedata; - cbox->data1 = "map-background-r"; - cbox->data2 = "map-background-g"; - cbox->data3 = "map-background-b"; - } - ob++; - - ob->_type = MN_NONE; - - page->objects = objects; -} - -static int compareWeaponPriority(const void* _a, const void* _b) -{ - const mndata_listitem_t* a = (const mndata_listitem_t*)_a; - const mndata_listitem_t* b = (const mndata_listitem_t*)_b; - int i = 0, aIndex = -1, bIndex = -1; - - do - { - if(cfg.weaponOrder[i] == a->data) - aIndex = i; - if(cfg.weaponOrder[i] == b->data) - bIndex = i; - } while(!(aIndex != -1 && bIndex != -1) && ++i < NUM_WEAPON_TYPES); - - if(aIndex > bIndex) return 1; - if(aIndex < bIndex) return -1; - return 0; // Should never happen. -} - -void Hu_MenuInitWeaponsPage(void) -{ -#if __JDOOM__ || __JDOOM64__ - const Point2Raw origin = { 78, 40 }; -#elif __JHERETIC__ - const Point2Raw origin = { 78, 26 }; -#elif __JHEXEN__ - const Point2Raw origin = { 78, 38 }; -#endif - mn_object_t* objects, *ob; -#if __JDOOM__ || __JDOOM64__ - const uint numObjects = 17; -#elif __JHERETIC__ || __JHEXEN__ - const uint numObjects = 15; -#endif - const struct { - const char* text; - int data; - } weaponOrder[NUM_WEAPON_TYPES+1] = { -#if __JDOOM__ || __JDOOM64__ - { (const char*)TXT_WEAPON1, WT_FIRST }, - { (const char*)TXT_WEAPON2, WT_SECOND }, - { (const char*)TXT_WEAPON3, WT_THIRD }, - { (const char*)TXT_WEAPON4, WT_FOURTH }, - { (const char*)TXT_WEAPON5, WT_FIFTH }, - { (const char*)TXT_WEAPON6, WT_SIXTH }, - { (const char*)TXT_WEAPON7, WT_SEVENTH }, - { (const char*)TXT_WEAPON8, WT_EIGHTH }, - { (const char*)TXT_WEAPON9, WT_NINETH }, -# if __JDOOM64__ - { (const char*)TXT_WEAPON10, WT_TENTH }, -# endif -#elif __JHERETIC__ - { (const char*)TXT_TXT_WPNSTAFF, WT_FIRST }, - { (const char*)TXT_TXT_WPNWAND, WT_SECOND }, - { (const char*)TXT_TXT_WPNCROSSBOW, WT_THIRD }, - { (const char*)TXT_TXT_WPNBLASTER, WT_FOURTH }, - { (const char*)TXT_TXT_WPNSKULLROD, WT_FIFTH }, - { (const char*)TXT_TXT_WPNPHOENIXROD, WT_SIXTH }, - { (const char*)TXT_TXT_WPNMACE, WT_SEVENTH }, - { (const char*)TXT_TXT_WPNGAUNTLETS, WT_EIGHTH }, -#elif __JHEXEN__ - /** - * @todo We should allow different weapon preferences per player-class. - */ - { "First", WT_FIRST }, - { "Second", WT_SECOND }, - { "Third", WT_THIRD }, - { "Fourth", WT_FOURTH }, -#endif - { 0 } - }; - mn_page_t* page; - - page = Hu_MenuNewPage("WeaponOptions", &origin, 0, Hu_MenuPageTicker, Hu_MenuDrawWeaponsPage, NULL, NULL); - MNPage_SetTitle(page, "Weapons Options"); - MNPage_SetPredefinedFont(page, MENU_FONT1, FID(GF_FONTA)); - MNPage_SetPreviousPage(page, Hu_MenuFindPageByName("Options")); - - objects = Z_Calloc(sizeof(*objects) * numObjects, PU_GAMESTATIC, 0); - if(!objects) Con_Error("Hu_MenuInitWeaponOptionsPage: Failed on allocation of %lu bytes for menu objects.", (unsigned long) (sizeof(*objects) * numObjects)); - - ob = objects; - - ob->_type = MN_TEXT; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR2; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Priority Order"; - } - ob++; - - ob->_type = MN_LIST; - ob->_flags = MNF_ID0; - ob->_shortcut = 'p'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR3; - ob->ticker = MNList_Ticker; - ob->updateGeometry = MNList_UpdateGeometry; - ob->drawer = MNList_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuChangeWeaponPriority; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNList_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_list_t), PU_GAMESTATIC, 0); - { mndata_list_t* list = (mndata_list_t*)ob->_typedata; - mndata_listitem_t* item; - uint i; - - list->count = NUM_WEAPON_TYPES; - item = list->items = (mndata_listitem_t*)Z_Calloc(sizeof(mndata_listitem_t) * list->count, PU_GAMESTATIC, 0); - - for(i = 0; weaponOrder[i].text; ++i, item++) - { - item->text = weaponOrder[i].text; - item->data = weaponOrder[i].data; - } - qsort(list->items, list->count, sizeof(mndata_listitem_t), compareWeaponPriority); - } - ob++; - - ob->_type = MN_TEXT; - ob->_group = 1; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR2; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Cycling"; - } - ob++; - - ob->_type = MN_TEXT; - ob->_group = 1; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Use Priority Order"; - } - ob++; - - ob->_type = MN_BUTTON; - ob->_group = 1; - ob->_shortcut = 'o'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR3; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->staydownMode = true; - btn->data = "player-weapon-nextmode"; - } - ob++; - - ob->_type = MN_TEXT; - ob->_group = 1; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Sequential"; - } - ob++; - - ob->_type = MN_BUTTON; - ob->_group = 1; - ob->_shortcut = 's'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR3; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->staydownMode = true; - btn->data = "player-weapon-cycle-sequential"; - } - ob++; - - ob->_type = MN_TEXT; - ob->_group = 2; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR2; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Autoswitch"; - } - ob++; - - ob->_type = MN_TEXT; - ob->_group = 2; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Pickup Weapon"; - } - ob++; - - ob->_type = MN_LISTINLINE; - ob->_group = 2; - ob->_shortcut = 'w'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR3; - ob->ticker = MNListInline_Ticker; - ob->updateGeometry = MNListInline_UpdateGeometry; - ob->drawer = MNListInline_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarList; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNListInline_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_list_t), PU_GAMESTATIC, 0); - { mndata_list_t* list = (mndata_list_t*)ob->_typedata; - mndata_listitem_t* item; - - list->count = 3; - item = list->items = (mndata_listitem_t*)Z_Calloc(sizeof(mndata_listitem_t) * list->count, PU_GAMESTATIC, 0); - list->data = "player-autoswitch"; - - item->text = "Never"; - item->data = 0; - item++; - - item->text = "If Better"; - item->data = 1; - item++; - - item->text = "Always"; - item->data = 2; - } - ob++; - - ob->_type = MN_TEXT; - ob->_group = 2; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = " If Not Firing"; - } - ob++; - - ob->_type = MN_BUTTON; - ob->_group = 2; - ob->_shortcut = 'f'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR3; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->staydownMode = true; - btn->data = "player-autoswitch-notfiring"; - } - ob++; - - ob->_type = MN_TEXT; - ob->_group = 2; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Pickup Ammo"; - } - ob++; - - ob->_type = MN_LISTINLINE; - ob->_group = 2; - ob->_shortcut = 'a'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR3; - ob->ticker = MNListInline_Ticker; - ob->updateGeometry = MNListInline_UpdateGeometry; - ob->drawer = MNListInline_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarList; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNListInline_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_list_t), PU_GAMESTATIC, 0); - { mndata_list_t* list = (mndata_list_t*)ob->_typedata; - mndata_listitem_t* item; - - list->count = 3; - item = list->items = (mndata_listitem_t*)Z_Calloc(sizeof(mndata_listitem_t) * list->count, PU_GAMESTATIC, 0); - list->data = "player-autoswitch-ammo"; - - item->text = "Never"; - item->data = 0; - item++; - - item->text = "If Better"; - item->data = 1; - item++; - - item->text = "Always"; - item->data = 2; - } - ob++; - -#if __JDOOM__ || __JDOOM64__ - ob->_type = MN_TEXT; - ob->_group = 2; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Pickup Beserk"; - } - ob++; - - ob->_type = MN_BUTTON; - ob->_group = 2; - ob->_shortcut = 'b'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR3; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->staydownMode = true; - btn->data = "player-autoswitch-berserk"; - } - ob++; -#endif - - ob->_type = MN_NONE; - - page->objects = objects; -} - -#if __JHERETIC__ || __JHEXEN__ -void Hu_MenuInitInventoryOptionsPage(void) -{ - const Point2Raw origin = { 78, 48 }; - mn_object_t* objects, *ob; - const uint numObjects = 16; - mn_page_t* page; - - page = Hu_MenuNewPage("InventoryOptions", &origin, 0, Hu_MenuPageTicker, NULL, NULL, NULL); - MNPage_SetTitle(page, "Inventory Options"); - MNPage_SetPredefinedFont(page, MENU_FONT1, FID(GF_FONTA)); - MNPage_SetPreviousPage(page, Hu_MenuFindPageByName("Options")); - - objects = Z_Calloc(sizeof(*objects) * numObjects, PU_GAMESTATIC, 0); - - if(!objects) Con_Error("Hu_MenuInitInventoryPage: Failed on allocation of %lu bytes for menu objects.", (unsigned long) (sizeof(*objects) * numObjects)); - ob = objects; - - ob->_type = MN_TEXT; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Select Mode"; - } - ob++; - - ob->_type = MN_BUTTON; - ob->_shortcut = 's'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR3; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->staydownMode = true; - btn->data = "ctl-inventory-mode"; - } - ob++; - - ob->_type = MN_TEXT; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Wrap Around"; - } - ob++; - - ob->_type = MN_BUTTON; - ob->_shortcut = 'w'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR3; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->staydownMode = true; - btn->data = "ctl-inventory-wrap"; - } - ob++; - - ob->_type = MN_TEXT; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Choose And Use"; - } - ob++; - - ob->_type = MN_BUTTON; - ob->_shortcut = 'c'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR3; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->staydownMode = true; - btn->data = "ctl-inventory-use-immediate"; - } - ob++; - - ob->_type = MN_TEXT; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Select Next If Use Failed"; - } - ob++; - - ob->_type = MN_BUTTON; - ob->_shortcut = 'n'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR3; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->staydownMode = true; - btn->data = "ctl-inventory-use-next"; - } - ob++; - - ob->_type = MN_TEXT; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "AutoHide"; - } - ob++; - - ob->_type = MN_SLIDER; - ob->_shortcut = 'h'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR3; - ob->ticker = MNSlider_Ticker; - ob->updateGeometry = MNSlider_TextualValueUpdateGeometry; - ob->drawer = MNSlider_TextualValueDrawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarSlider; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNSlider_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_slider_t), PU_GAMESTATIC, 0); - { mndata_slider_t* sld = (mndata_slider_t*)ob->_typedata; - sld->min = 0; - sld->max = 30; - sld->value = 0; - sld->step = 1.f; - sld->floatMode = true; - sld->data1 = "hud-inventory-timer"; - sld->data2 = "Disabled"; - sld->data4 = " second"; - sld->data5 = " seconds"; - } - ob++; - - ob->_type = MN_TEXT; - ob->_group = 1; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR2; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Fullscreen HUD"; - } - ob++; - - ob->_type = MN_TEXT; - ob->_group = 1; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Max Visible Slots"; - } - ob++; - - ob->_type = MN_SLIDER; - ob->_group = 1; - ob->_shortcut = 'v'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR3; - ob->ticker = MNSlider_Ticker; - ob->updateGeometry = MNSlider_TextualValueUpdateGeometry; - ob->drawer = MNSlider_TextualValueDrawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarSlider; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNSlider_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_slider_t), PU_GAMESTATIC, 0); - { mndata_slider_t* sld = (mndata_slider_t*)ob->_typedata; - sld->min = 0; - sld->max = 16; - sld->value = 0; - sld->step = 1; - sld->floatMode = false; - sld->data1 = "hud-inventory-slot-max"; - sld->data2 = "Automatic"; - } - ob++; - - ob->_type = MN_TEXT; - ob->_group = 1; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Show Empty Slots"; - } - ob++; - - ob->_type = MN_BUTTON; - ob->_group = 1; - ob->_shortcut = 'e'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR3; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->staydownMode = true; - btn->data = "hud-inventory-slot-showempty"; - } - ob++; - - ob->_type = MN_NONE; - - page->objects = objects; -} -#endif - -void Hu_MenuInitSoundOptionsPage(void) -{ -#if __JHEXEN__ - const Point2Raw origin = { 97, 25 }; -#elif __JHERETIC__ - const Point2Raw origin = { 97, 30 }; -#elif __JDOOM__ || __JDOOM64__ - const Point2Raw origin = { 97, 40 }; -#endif - mn_object_t* objects, *ob; - const uint numObjects = 6; - mn_page_t* page; - - page = Hu_MenuNewPage("SoundOptions", &origin, 0, Hu_MenuPageTicker, NULL, NULL, NULL); - MNPage_SetTitle(page, "Sound Options"); - MNPage_SetPredefinedFont(page, MENU_FONT1, FID(GF_FONTA)); - MNPage_SetPreviousPage(page, Hu_MenuFindPageByName("Options")); - - objects = Z_Calloc(sizeof(*objects) * numObjects, PU_GAMESTATIC, 0); - if(!objects) Con_Error("Hu_MenuInitFilesMenu: Failed on allocation of %lu bytes for menu objects.", (unsigned long) (sizeof(*objects) * numObjects)); - - ob = objects; - - ob->_type = MN_TEXT; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "SFX Volume"; - } - ob++; - - ob->_type = MN_SLIDER; - ob->_shortcut = 's'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNSlider_Ticker; - ob->updateGeometry = MNSlider_UpdateGeometry; - ob->drawer = MNSlider_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarSlider; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNSlider_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_slider_t), PU_GAMESTATIC, 0); - { mndata_slider_t* sld = (mndata_slider_t*)ob->_typedata; - sld->min = 0; - sld->max = 255; - sld->value = 0; - sld->step = 5; - sld->floatMode = false; - sld->data1 = "sound-volume"; - } - ob++; - - ob->_type = MN_TEXT; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNText_Ticker; - ob->updateGeometry = MNText_UpdateGeometry; - ob->drawer = MNText_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); - { mndata_text_t* text = (mndata_text_t*)ob->_typedata; - text->text = "Music Volume"; - } - ob++; - - ob->_type = MN_SLIDER; - ob->_shortcut = 'm'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNSlider_Ticker; - ob->updateGeometry = MNSlider_UpdateGeometry; - ob->drawer = MNSlider_Drawer; - ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarSlider; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNSlider_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_slider_t), PU_GAMESTATIC, 0); - { mndata_slider_t* sld = (mndata_slider_t*)ob->_typedata; - sld->min = 0; - sld->max = 255; - sld->value = 0; - sld->step = 5; - sld->floatMode = false; - sld->data1 = "music-volume"; - } - ob++; - - /* - ob->_type = MN_BUTTON; - ob->_shortcut = 'p'; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->ticker = MNButton_Ticker; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->drawer = MNButton_Drawer; - ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuSelectControlPanelLink; - ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; - ob->cmdResponder = MNButton_CommandResponder; - ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); - ob->data2 = 1; - { mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - btn->text = "Open Audio Panel"; - } - ob++; - */ - - ob->_type = MN_NONE; - - page->objects = objects; -} - -#if __JDOOM__ || __JHERETIC__ -/** - * Construct the episode selection menu. - */ -void Hu_MenuInitEpisodePage(void) -{ -#if __JDOOM__ - const Point2Raw origin = { 48, 63 }; -#else - const Point2Raw origin = { 80, 50 }; -#endif - int i, y, numEpisodes; - mn_object_t* objects, *ob; - mndata_button_t* buttons, *btn; - mn_page_t* page; - -#if __JDOOM__ - if(gameModeBits & (GM_ANY_DOOM2|GM_DOOM_CHEX)) - numEpisodes = 0; - else if(gameMode == doom_ultimate) - numEpisodes = 4; - else - numEpisodes = 3; -#else // __JHERETIC__ - if(gameMode == heretic_extended) - numEpisodes = 6; - else - numEpisodes = 3; -#endif - - // Allocate the menu objects array. - objects = Z_Calloc(sizeof(mn_object_t) * (numEpisodes+1), PU_GAMESTATIC, 0); - buttons = Z_Calloc(sizeof(mndata_button_t) * (numEpisodes), PU_GAMESTATIC, 0); - - ob = objects; - btn = buttons; - y = 0; - for(i = 0; i < numEpisodes; ++i) - { - ob->_type = MN_BUTTON; - ob->_origin.x = 0; - ob->_origin.y = y; - btn->text = GET_TXT(TXT_EPISODE1 + i); - if(isalnum(btn->text[0])) - ob->_shortcut = tolower(btn->text[0]); -#if __JDOOM__ - btn->patch = &pEpisodeNames[i]; -#endif - ob->_typedata = btn; - ob->ticker = MNButton_Ticker; - ob->drawer = MNButton_Drawer; - ob->cmdResponder = MNButton_CommandResponder; - ob->updateGeometry = MNButton_UpdateGeometry; - - if(i != 0 -#if __JHERETIC__ - && gameMode == heretic_shareware -#else - && gameMode == doom_shareware -#endif - ) - { - ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuActivateNotSharewareEpisode; - } - else - { - ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuActionSetActivePage; - ob->data1 = "Skill"; -#if __JHERETIC__ - if(gameMode == heretic_extended && i == 5) - { - ob->_flags |= MNF_ID0; - } -#endif - } - - ob->actions[MNA_FOCUS].callback = Hu_MenuFocusEpisode; - ob->data2 = i; - ob->_pageFontIdx = MENU_FONT1; - ob++; - btn++; - y += FIXED_LINE_HEIGHT; - } - ob->_type = MN_NONE; - - page = Hu_MenuNewPage("Episode", &origin, MPF_LAYOUT_FIXED|MPF_NEVER_SCROLL, Hu_MenuPageTicker, Hu_MenuDrawEpisodePage, NULL, NULL); - MNPage_SetPredefinedFont(page, MENU_FONT1, FID(GF_FONTB)); - MNPage_SetPreviousPage(page, Hu_MenuFindPageByName("GameType")); - - page->objects = objects; -} -#endif - -#if __JHEXEN__ -/** - * Construct the player class selection menu. - */ -void Hu_MenuInitPlayerClassPage(void) -{ - const Point2Raw pageOrigin = { 66, 66 }; - mndata_button_t* buttons, *btn; - uint i, n, count; - mn_object_t* objects, *ob; - mn_page_t* page; - int y; - - // First determine the number of selectable player classes. - count = 0; - for(i = 0; i < NUM_PLAYER_CLASSES; ++i) - { - classinfo_t* info = PCLASS_INFO(i); - if(info->userSelectable) - ++count; - } - - // Allocate the menu objects. - objects = Z_Calloc(sizeof(mn_object_t) * (count+4), PU_GAMESTATIC, 0); - buttons = Z_Calloc(sizeof(mndata_button_t) * (count+1), PU_GAMESTATIC, 0); - - // Add the selectable classes. - y = 0; - n = 0; - ob = objects; - btn = buttons; - while(n < count) - { - classinfo_t* info = PCLASS_INFO(n++); - - if(!info->userSelectable) continue; - - ob->_type = MN_BUTTON; - btn->text = info->niceName; - ob->_typedata = btn; - ob->_origin.x = 0; - ob->_origin.y = y; - ob->drawer = MNButton_Drawer; - ob->ticker = MNButton_Ticker; - ob->cmdResponder = MNButton_CommandResponder; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuSelectPlayerClass; - ob->actions[MNA_FOCUS].callback = Hu_MenuFocusOnPlayerClass; - ob->data2 = (int)info->plrClass; - ob->_shortcut = tolower(btn->text[0]); - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob++; - btn++; - y += FIXED_LINE_HEIGHT; - } - - // Random class button. - ob->_type = MN_BUTTON; - btn->text = GET_TXT(TXT_RANDOMPLAYERCLASS); - ob->_typedata = btn; - ob->_origin.x = 0; - ob->_origin.y = y; - ob->drawer = MNButton_Drawer; - ob->ticker = MNButton_Ticker; - ob->cmdResponder = MNButton_CommandResponder; - ob->updateGeometry = MNButton_UpdateGeometry; - ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuSelectPlayerClass; - ob->actions[MNA_FOCUS].callback = Hu_MenuFocusOnPlayerClass; - ob->data2 = (int)PCLASS_NONE; - ob->_shortcut = tolower(btn->text[0]); - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob++; - - // Mobj preview background. - ob->_type = MN_RECT; - ob->_flags = MNF_NO_FOCUS|MNF_ID1; - ob->_origin.x = 108; - ob->_origin.y = -58; - ob->drawer = MNRect_Drawer; - ob->ticker = Hu_MenuPlayerClassBackgroundTicker; - ob->updateGeometry = MNRect_UpdateGeometry; - ob->_pageFontIdx = MENU_FONT1; - ob->_pageColorIdx = MENU_COLOR1; - ob->_typedata = Z_Calloc(sizeof(mndata_rect_t), PU_GAMESTATIC, 0); - ob++; - - // Mobj preview. - ob->_type = MN_MOBJPREVIEW; - ob->_flags = MNF_ID0; - ob->_origin.x = 108 + 55; - ob->_origin.y = -58 + 76; - ob->ticker = Hu_MenuPlayerClassPreviewTicker; - ob->updateGeometry = MNMobjPreview_UpdateGeometry; - ob->drawer = MNMobjPreview_Drawer; - ob->_typedata = Z_Calloc(sizeof(mndata_mobjpreview_t), PU_GAMESTATIC, 0); - ob++; - - // Terminate. - ob->_type = MN_NONE; - - page = Hu_MenuNewPage("PlayerClass", &pageOrigin, MPF_LAYOUT_FIXED|MPF_NEVER_SCROLL, Hu_MenuPageTicker, Hu_MenuDrawPlayerClassPage, NULL, NULL); - MNPage_SetPredefinedFont(page, MENU_FONT1, FID(GF_FONTB)); - MNPage_SetPreviousPage(page, Hu_MenuFindPageByName("GameType")); - - page->objects = objects; -} -#endif - -mn_page_t* MNPage_New(const Point2Raw* origin, int flags, - void (*ticker) (struct mn_page_s* page), - void (*drawer) (struct mn_page_s* page, const Point2Raw* origin), - int (*cmdResponder) (struct mn_page_s* page, menucommand_e cmd), - void* userData) -{ - mn_page_t* page = (mn_page_t*) malloc(sizeof(*page)); - fontid_t fontId; - int i; - - if(!page) Con_Error("MNPage::New: Failed on allocation of %lu bytes for new MenuPage.", (unsigned long) sizeof(*page)); - - page->origin.x = origin? origin->x : 0; - page->origin.y = origin? origin->y : 0; - - page->flags = flags; - - page->objects = NULL; - page->objectsCount = 0; - - page->ticker = ticker; - page->drawer = drawer; - page->cmdResponder = cmdResponder; - page->previous = NULL; - page->userData = userData; - - Str_Init(&page->title); - - fontId = FID(GF_FONTA); - for(i = 0; i < MENU_FONT_COUNT; ++i) - page->fonts[i] = fontId; - - memset(page->colors, 0, sizeof(page->colors)); - page->colors[0] = 0; - page->colors[1] = 1; - page->colors[2] = 2; - - page->focus = -1; /// @todo Make this a page flag. - page->geometry = Rect_New(); - - return page; -} - -static mn_page_t* addPageToCollection(mn_page_t* page, const char* name) -{ - if(page) - { - pagerecord_t* rec; - - pages = (pagerecord_t*)realloc(pages, sizeof(*pages) * ++pageCount); - if(!pages) Con_Error("addPageToCollection: Failed on (re)allocation of %lu bytes enlarging Pages collection.", (unsigned long) sizeof(*pages) * pageCount); - - rec = &pages[pageCount-1]; - rec->page = page; - Str_Init(&rec->name); Str_Set(&rec->name, name); - } - return page; -} - -mn_page_t* Hu_MenuNewPage(const char* name, const Point2Raw* origin, int flags, - void (*ticker) (struct mn_page_s* page), - void (*drawer) (struct mn_page_s* page, const Point2Raw* origin), - int (*cmdResponder) (struct mn_page_s* page, menucommand_e cmd), - void* userData) -{ - if(!name || !name[0]) - { - DENG_ASSERT(!"Hu_MenuNewPage: Attempt to create page with an invalid name"); - return NULL; - } - - return addPageToCollection(MNPage_New(origin, flags, ticker, drawer, cmdResponder, userData), name); -} - -void Hu_MenuInit(void) -{ - cvarbutton_t* cvb; - - if(inited) return; - - pageCount = 0; - pages = NULL; - - mnAlpha = mnTargetAlpha = 0; - menuActivePage = NULL; - menuActive = false; - cursorHasRotation = false; - cursorAngle = 0; - cursorAnimFrame = 0; - cursorAnimCounter = MENU_CURSOR_TICSPERFRAME; - - DD_Execute(true, "deactivatebcontext menu"); - - Hu_MenuLoadResources(); - - // Set default Yes/No strings. - for(cvb = mnCVarButtons; cvb->cvarname; cvb++) - { - if(!cvb->yes) cvb->yes = "Yes"; - if(!cvb->no) cvb->no = "No"; - } - - initAllPages(); - initAllObjectsOnAllPages(); - -#if __JDOOM__ - if(gameModeBits & GM_ANY_DOOM2) - { - mn_object_t* ob = MN_MustFindObjectOnPage(Hu_MenuFindPageByName("Main"), 0, MNF_ID0); // Read This! - MNObject_SetFlags(ob, FO_SET, MNF_DISABLED|MNF_HIDDEN|MNF_NO_FOCUS); - - ob = MN_MustFindObjectOnPage(Hu_MenuFindPageByName("Main"), 0, MNF_ID1); // Quit Game - MNObject_SetFixedY(ob, MNObject_FixedY(ob) - FIXED_LINE_HEIGHT); - } -#endif - - inited = true; -} - -void Hu_MenuShutdown(void) -{ - if(!inited) return; - - destroyAllPages(); - inited = false; -} - -dd_bool Hu_MenuIsActive(void) -{ - return menuActive; -} - -void Hu_MenuSetAlpha(float alpha) -{ - // The menu's alpha will start moving towards this target value. - mnTargetAlpha = alpha; -} - -float Hu_MenuAlpha(void) -{ - return mnAlpha; -} - -void Hu_MenuTicker(timespan_t ticLength) -{ -#define MENUALPHA_FADE_STEP (.07f) - - float diff = 0; - - // Move towards the target alpha level for the entire menu. - diff = mnTargetAlpha - mnAlpha; - if(fabs(diff) > MENUALPHA_FADE_STEP) - { - mnAlpha += (float)(MENUALPHA_FADE_STEP * ticLength * TICRATE * (diff > 0? 1 : -1)); - } - else - { - mnAlpha = mnTargetAlpha; - } - - if(!menuActive) return; - - // Animate cursor rotation? - if(cfg.menuCursorRotate) - { - if(cursorHasRotation) - { - cursorAngle += (float)(5 * ticLength * TICRATE); - } - else if(cursorAngle != 0) - { - float rewind = (float)(MENU_CURSOR_REWIND_SPEED * ticLength * TICRATE); - if(cursorAngle <= rewind || cursorAngle >= 360 - rewind) - cursorAngle = 0; - else if(cursorAngle < 180) - cursorAngle -= rewind; - else - cursorAngle += rewind; - } - - if(cursorAngle >= 360) - cursorAngle -= 360; - } - - // Time to think? Updates on 35Hz game ticks. - if(!DD_IsSharpTick()) return; - - // Advance menu time. - menuTime++; - - // Animate the cursor graphic? - if(--cursorAnimCounter <= 0) - { - cursorAnimFrame++; - cursorAnimCounter = MENU_CURSOR_TICSPERFRAME; - if(cursorAnimFrame > MENU_CURSOR_FRAMECOUNT-1) - cursorAnimFrame = 0; - } - - // Used for Heretic's rotating skulls. - frame = (menuTime / 3) % 18; - - // Call the active page's ticker. - menuActivePage->ticker(menuActivePage); - -#undef MENUALPHA_FADE_STEP -} - -mn_page_t* Hu_MenuActivePage(void) -{ - return menuActivePage; -} - -void Hu_MenuSetActivePage2(mn_page_t* page, dd_bool canReactivate) -{ - if(!menuActive) return; - if(!page) return; - - if(!(Get(DD_DEDICATED) || Get(DD_NOVIDEO))) - { - FR_ResetTypeinTimer(); - } - - cursorAngle = 0; // Stop cursor rotation animation dead (don't rewind). - menuNominatingQuickSaveSlot = false; - - if(menuActivePage == page) - { - if(!canReactivate) return; - MNPage_ClearFocusObject(page); - } - - updatePageObjects(page); - - // This is now the "active" page. - menuActivePage = page; - MNPage_Initialize(page); -} - -void Hu_MenuSetActivePage(mn_page_t* page) -{ - Hu_MenuSetActivePage2(page, false/*don't reactivate*/); -} - -dd_bool Hu_MenuIsVisible(void) -{ - return (menuActive || mnAlpha > .0001f); -} - -int Hu_MenuDefaultFocusAction(mn_object_t* ob, mn_actionid_t action, void* parameters) -{ - DENG_UNUSED(parameters); - if(MNA_FOCUS != action) return 1; - Hu_MenuUpdateCursorState(); - return 0; -} - -void Hu_MenuDrawFocusCursor(int x, int y, int focusObjectHeight, float alpha) -{ -#if __JDOOM__ || __JDOOM64__ -# define OFFSET_X (-22) -# define OFFSET_Y (-2) -#elif __JHERETIC__ || __JHEXEN__ -# define OFFSET_X (-16) -# define OFFSET_Y (3) -#endif - - const int cursorIdx = cursorAnimFrame; - const float angle = cursorAngle; - patchid_t pCursor = pCursors[cursorIdx % MENU_CURSOR_FRAMECOUNT]; - float scale, pos[2]; - patchinfo_t info; - - if(!R_GetPatchInfo(pCursor, &info)) - return; - - scale = MIN_OF((float) (focusObjectHeight * 1.267f) / info.geometry.size.height, 1); - pos[VX] = x + OFFSET_X * scale; - pos[VY] = y + OFFSET_Y * scale + focusObjectHeight/2; - - DGL_MatrixMode(DGL_MODELVIEW); - DGL_PushMatrix(); - - DGL_Translatef(pos[VX], pos[VY], 0); - DGL_Scalef(scale, scale, 1); - DGL_Rotatef(angle, 0, 0, 1); - - DGL_Enable(DGL_TEXTURE_2D); - DGL_Color4f(1, 1, 1, alpha); - - GL_DrawPatchXY3(pCursor, 0, 0, 0, DPF_NO_OFFSET); - - DGL_Disable(DGL_TEXTURE_2D); - - DGL_MatrixMode(DGL_MODELVIEW); - DGL_PopMatrix(); - -#undef OFFSET_Y -#undef OFFSET_X -} - -void Hu_MenuDrawPageTitle(const char* title, int x, int y) -{ - if(!title || !title[0]) return; - - DGL_Enable(DGL_TEXTURE_2D); - FR_SetFont(FID(GF_FONTB)); - FR_SetColorv(cfg.menuTextColors[0]); - FR_SetAlpha(mnRendState->pageAlpha); - - FR_DrawTextXY3(title, x, y, ALIGN_TOP, MN_MergeMenuEffectWithDrawTextFlags(0)); - - DGL_Disable(DGL_TEXTURE_2D); -} - -void Hu_MenuDrawPageHelp(const char* help, int x, int y) -{ - if(!help || !help[0]) return; - - DGL_Enable(DGL_TEXTURE_2D); - FR_SetFont(FID(GF_FONTA)); - FR_SetColorv(cfg.menuTextColors[1]); - FR_SetAlpha(mnRendState->pageAlpha); - - FR_DrawTextXY3(help, x, y, ALIGN_BOTTOM, MN_MergeMenuEffectWithDrawTextFlags(0)); - - DGL_Disable(DGL_TEXTURE_2D); -} - -static void drawOverlayBackground(float darken) -{ - DGL_SetNoMaterial(); - DGL_DrawRectf2Color(0, 0, SCREENWIDTH, SCREENHEIGHT, 0, 0, 0, darken); -} - -static void beginOverlayDraw(void) -{ -#define SMALL_SCALE .75f - - DGL_MatrixMode(DGL_MODELVIEW); - DGL_PushMatrix(); - - DGL_Translatef(SCREENWIDTH/2, SCREENHEIGHT/2, 0); - DGL_Scalef(SMALL_SCALE, SMALL_SCALE, 1); - DGL_Translatef(-(SCREENWIDTH/2), -(SCREENHEIGHT/2), 0); - -#undef SMALL_SCALE -} - -static void endOverlayDraw(void) -{ - DGL_MatrixMode(DGL_MODELVIEW); - DGL_PopMatrix(); -} - -void Hu_MenuDrawer(void) -{ -#define OVERLAY_DARKEN .7f - - dgl_borderedprojectionstate_t bp; - dd_bool showFocusCursor = true; - mn_object_t* focusObj; - - if(!Hu_MenuIsVisible()) return; - - GL_ConfigureBorderedProjection(&bp, 0, SCREENWIDTH, SCREENHEIGHT, - Get(DD_WINDOW_WIDTH), Get(DD_WINDOW_HEIGHT), cfg.menuScaleMode); - GL_BeginBorderedProjection(&bp); - - // First determine whether the focus cursor should be visible. - focusObj = MNPage_FocusObject(Hu_MenuActivePage()); - if(focusObj && (MNObject_Flags(focusObj) & MNF_ACTIVE)) - { - if(MNObject_Type(focusObj) == MN_COLORBOX || MNObject_Type(focusObj) == MN_BINDINGS) - { - showFocusCursor = false; - } - } - - DGL_MatrixMode(DGL_MODELVIEW); - DGL_PushMatrix(); - - DGL_Translatef(SCREENWIDTH/2, SCREENHEIGHT/2, 0); - DGL_Scalef(cfg.menuScale, cfg.menuScale, 1); - DGL_Translatef(-(SCREENWIDTH/2), -(SCREENHEIGHT/2), 0); - - MN_DrawPage(Hu_MenuActivePage(), mnAlpha, showFocusCursor); - - DGL_MatrixMode(DGL_MODELVIEW); - DGL_PopMatrix(); - - GL_EndBorderedProjection(&bp); - - // Drawing any overlays? - if(focusObj && (MNObject_Flags(focusObj) & MNF_ACTIVE)) - { - switch(MNObject_Type(focusObj)) - { - case MN_COLORBOX: - case MN_BINDINGS: - drawOverlayBackground(OVERLAY_DARKEN); - GL_BeginBorderedProjection(&bp); - - beginOverlayDraw(); - if(MNObject_Type(focusObj) == MN_BINDINGS) - { - Hu_MenuControlGrabDrawer(MNBindings_ControlName(focusObj), 1); - } - else - { - MN_DrawPage(Hu_MenuFindPageByName("ColorWidget"), 1, true); - } - endOverlayDraw(); - - GL_EndBorderedProjection(&bp); - break; - default: break; - } - } - -#undef OVERLAY_DARKEN -} - -void Hu_MenuPageTicker(mn_page_t* page) -{ - // Normal ticker actions first. - MNPage_Ticker(page); - - /// @todo Move game-menu specific page tick functionality here. -} - -void Hu_MenuNavigatePage(mn_page_t* page, int pageDelta) -{ -#if 0 - int index; - assert(page); - - oldIndex = index = MAX_OF(0, page->focus); - - if(pageDelta < 0) - { - index = MAX_OF(0, index - page->numVisObjects); - } - else - { - index = MIN_OF(page->objectsCount-1, index + page->numVisObjects); - } - - // Don't land on empty objects. - while((page->objects[index].flags & (MNF_DISABLED | MNF_NO_FOCUS)) && (index > 0)) - index--; - while((page->objects[index].flags & (MNF_DISABLED | MNF_NO_FOCUS)) && index < page->objectsCount) - index++; - - if(index != oldIndex) - { - S_LocalSound(SFX_MENU_NAV_RIGHT, NULL); - MNPage_SetFocus(page, page->objects + index); - } -#endif -} - -static void initPageObjects(mn_page_t* page) -{ - mn_object_t* ob; - assert(page); - - page->objectsCount = 0; - - for(ob = page->objects; MNObject_Type(ob) != MN_NONE; ob++) - { - page->objectsCount += 1; - - ob->_page = page; - ob->_geometry = Rect_New(); - - ob->timer = 0; - MNObject_SetFlags(ob, FO_CLEAR, MNF_FOCUS); - - if(0 != ob->_shortcut) - { - int shortcut = ob->_shortcut; - ob->_shortcut = 0; // Clear invalid defaults. - MNObject_SetShortcut(ob, shortcut); - } - - switch(MNObject_Type(ob)) - { - case MN_TEXT: { - mndata_text_t* txt = (mndata_text_t*)ob->_typedata; - MNObject_SetFlags(ob, FO_SET, MNF_NO_FOCUS); - - if(txt->text && (PTR2INT(txt->text) > 0 && PTR2INT(txt->text) < NUMTEXT)) - { - txt->text = GET_TXT(PTR2INT(txt->text)); - } - break; } - - case MN_BUTTON: { - const mn_actioninfo_t* action = MNObject_Action(ob, MNA_MODIFIED); - mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - - if(btn->text && (PTR2INT(btn->text) > 0 && PTR2INT(btn->text) < NUMTEXT)) - { - btn->text = GET_TXT(PTR2INT(btn->text)); - /// @todo Should not be done here. - MNObject_SetShortcut(ob, btn->text[0]); - } - break; } - - case MN_EDIT: { - mndata_edit_t* edit = (mndata_edit_t*) ob->_typedata; - - if(edit->emptyString && (PTR2INT(edit->emptyString) > 0 && PTR2INT(edit->emptyString) < NUMTEXT)) - { - edit->emptyString = GET_TXT(PTR2INT(edit->emptyString)); - } - break; } - - case MN_LIST: - case MN_LISTINLINE: { - mndata_list_t* list = (mndata_list_t*) ob->_typedata; - int i; - - for(i = 0; i < list->count; ++i) - { - mndata_listitem_t* item = &((mndata_listitem_t*)list->items)[i]; - if(item->text && (PTR2INT(item->text) > 0 && PTR2INT(item->text) < NUMTEXT)) - { - item->text = GET_TXT(PTR2INT(item->text)); - } - } - break; } - - case MN_COLORBOX: { - mndata_colorbox_t* cbox = (mndata_colorbox_t*) ob->_typedata; - - if(!cbox->rgbaMode) - cbox->a = 1.f; - if(0 >= cbox->width) - cbox->width = MNDATA_COLORBOX_WIDTH; - if(0 >= cbox->height) - cbox->height = MNDATA_COLORBOX_HEIGHT; - break; } - - case MN_MOBJPREVIEW: - MNObject_SetFlags(ob, FO_SET, MNF_NO_FOCUS); - break; - - default: break; - } - } -} - -/** - * Main task is to update objects linked to cvars. - */ -static void updatePageObjects(mn_page_t* page) -{ - mn_object_t* ob; - assert(page); - - for(ob = page->objects; MNObject_Type(ob) != MN_NONE; ob++) - { - switch(MNObject_Type(ob)) - { - case MN_TEXT: - case MN_MOBJPREVIEW: - MNObject_SetFlags(ob, FO_SET, MNF_NO_FOCUS); - break; - - case MN_BUTTON: { - const mn_actioninfo_t* action = MNObject_Action(ob, MNA_MODIFIED); - mndata_button_t* btn = (mndata_button_t*)ob->_typedata; - - if(action && action->callback == Hu_MenuCvarButton) - { - cvarbutton_t* cvb; - if(ob->data1) - { - // This button has already been initialized. - cvb = (cvarbutton_t*) ob->data1; - cvb->active = (Con_GetByte(cvb->cvarname) & (cvb->mask? cvb->mask : ~0)) != 0; - //strcpy(obj->text, cvb->active ? cvb->yes : cvb->no); - btn->text = cvb->active ? cvb->yes : cvb->no; - continue; - } - - // Find the cvarbutton representing this one. - for(cvb = mnCVarButtons; cvb->cvarname; cvb++) - { - if(!strcmp(btn->data, cvb->cvarname) && ob->data2 == cvb->mask) - { - cvb->active = (Con_GetByte(cvb->cvarname) & (cvb->mask? cvb->mask : ~0)) != 0; - ob->data1 = (void*) cvb; - btn->yes = cvb->yes; - btn->no = cvb->no; - btn->text = (cvb->active ? btn->yes : btn->no); - break; - } - } - cvb = NULL; - } - break; } - - case MN_LIST: - case MN_LISTINLINE: { - const mn_actioninfo_t* action = MNObject_Action(ob, MNA_MODIFIED); - mndata_list_t* list = (mndata_list_t*) ob->_typedata; - - if(action && action->callback == Hu_MenuCvarList) - { - MNList_SelectItemByValue(ob, MNLIST_SIF_NO_ACTION, Con_GetInteger(list->data)); - } - break; } - - case MN_EDIT: { - const mn_actioninfo_t* action = MNObject_Action(ob, MNA_MODIFIED); - mndata_edit_t* edit = (mndata_edit_t*) ob->_typedata; - - if(action && action->callback == Hu_MenuCvarEdit) - { - MNEdit_SetText(ob, MNEDIT_STF_NO_ACTION, Con_GetString(edit->data1)); - } - break; } - - case MN_SLIDER: { - const mn_actioninfo_t* action = MNObject_Action(ob, MNA_MODIFIED); - mndata_slider_t* sldr = (mndata_slider_t*) ob->_typedata; - if(action && action->callback == Hu_MenuCvarSlider) - { - float value; - if(sldr->floatMode) - value = Con_GetFloat(sldr->data1); - else - value = Con_GetInteger(sldr->data1); - MNSlider_SetValue(ob, MNSLIDER_SVF_NO_ACTION, value); - } - break; } - - case MN_COLORBOX: { - mndata_colorbox_t* cbox = (mndata_colorbox_t*) ob->_typedata; - const mn_actioninfo_t* action = MNObject_Action(ob, MNA_MODIFIED); - - if(action && action->callback == Hu_MenuCvarColorBox) - { - float rgba[4]; - rgba[CR] = Con_GetFloat(cbox->data1); - rgba[CG] = Con_GetFloat(cbox->data2); - rgba[CB] = Con_GetFloat(cbox->data3); - rgba[CA] = (cbox->rgbaMode? Con_GetFloat(cbox->data4) : 1.f); - MNColorBox_SetColor4fv(ob, MNCOLORBOX_SCF_NO_ACTION, rgba); - } - break; } - - default: break; - } - } -} - -static void destroyPageObjects(mn_page_t* page) -{ - mn_object_t* obj; - if(!page) return; - for(obj = page->objects; MNObject_Type(obj) != MN_NONE; obj++) - { - if(obj->_geometry) - { - Rect_Delete(obj->_geometry); - obj->_geometry = NULL; - } - } -} - -static void destroyPage(mn_page_t* page) -{ - if(!page) return; - - destroyPageObjects(page); - - Str_Free(&page->title); - - if(page->geometry) - { - Rect_Delete(page->geometry); - page->geometry = NULL; - } - - free(page); -} - -static void initAllPages(void) -{ - Hu_MenuInitColorWidgetPage(); - Hu_MenuInitMainPage(); - Hu_MenuInitGameTypePage(); -#if __JDOOM__ || __JHERETIC__ - Hu_MenuInitEpisodePage(); -#endif -#if __JHEXEN__ - Hu_MenuInitPlayerClassPage(); -#endif - Hu_MenuInitSkillPage(); - Hu_MenuInitMultiplayerPage(); - Hu_MenuInitPlayerSetupPage(); -#if __JHERETIC__ || __JHEXEN__ - Hu_MenuInitFilesPage(); -#endif - Hu_MenuInitLoadGameAndSaveGamePages(); - Hu_MenuInitOptionsPage(); - Hu_MenuInitGameplayOptionsPage(); - Hu_MenuInitSaveOptionsPage(); - Hu_MenuInitHUDOptionsPage(); - Hu_MenuInitAutomapOptionsPage(); - Hu_MenuInitWeaponsPage(); -#if __JHERETIC__ || __JHEXEN__ - Hu_MenuInitInventoryOptionsPage(); -#endif - Hu_MenuInitSoundOptionsPage(); - Hu_MenuInitControlsPage(); -} - -static void destroyAllPages(void) -{ - int i; - if(!pages) return; - for(i = 0; i < pageCount; ++i) - { - pagerecord_t* rec = pages + i; - destroyPage(rec->page); - Str_Free(&rec->name); - } - free(pages); -} - -static void initAllObjectsOnAllPages(void) -{ - int i; - for(i = 0; i < pageCount; ++i) - { - pagerecord_t* rec = pages + i; - initPageObjects(rec->page); - } -} - -int Hu_MenuColorWidgetCmdResponder(mn_page_t* page, menucommand_e cmd) -{ - assert(page); - switch(cmd) - { - case MCMD_NAV_OUT: { - mn_object_t* obj = (mn_object_t*)page->userData; - MNObject_SetFlags(obj, FO_CLEAR, MNF_ACTIVE); - S_LocalSound(SFX_MENU_CANCEL, NULL); - colorWidgetActive = false; - - /// @kludge We should re-focus on the object instead. - cursorAngle = 0; // Stop cursor rotation animation dead (don't rewind). - Hu_MenuUpdateCursorState(); - /// kludge end. - return true; - } - case MCMD_NAV_PAGEUP: - case MCMD_NAV_PAGEDOWN: - return true; // Eat these. - case MCMD_SELECT: { - mn_object_t* obj = (mn_object_t*)page->userData; - MNObject_SetFlags(obj, FO_CLEAR, MNF_ACTIVE); - S_LocalSound(SFX_MENU_ACCEPT, NULL); - colorWidgetActive = false; - MNColorBox_CopyColor(obj, 0, MN_MustFindObjectOnPage(page, 0, MNF_ID0)); - - /// @kludge We should re-focus on the object instead. - cursorAngle = 0; // Stop cursor rotation animation dead (don't rewind). - Hu_MenuUpdateCursorState(); - /// kludge end. - return true; - } - default: - break; - } - return false; -} - -static void fallbackCommandResponder(mn_page_t* page, menucommand_e cmd) -{ - assert(page); - switch(cmd) - { - case MCMD_NAV_PAGEUP: - case MCMD_NAV_PAGEDOWN: - S_LocalSound(cmd == MCMD_NAV_PAGEUP? SFX_MENU_NAV_UP : SFX_MENU_NAV_DOWN, NULL); - Hu_MenuNavigatePage(page, cmd == MCMD_NAV_PAGEUP? -1 : +1); - break; - - case MCMD_NAV_UP: - case MCMD_NAV_DOWN: { - mn_object_t* obj = MNPage_FocusObject(page); - // An object on this page must have focus in order to navigate. - if(obj) - { - int i = 0, giveFocus = page->focus; - do - { - giveFocus += (cmd == MCMD_NAV_UP? -1 : 1); - if(giveFocus < 0) - giveFocus = page->objectsCount - 1; - else if(giveFocus >= page->objectsCount) - giveFocus = 0; - } while(++i < page->objectsCount && (MNObject_Flags(page->objects + giveFocus) & (MNF_DISABLED | MNF_NO_FOCUS | MNF_HIDDEN))); - - if(giveFocus != page->focus) - { - S_LocalSound(cmd == MCMD_NAV_UP? SFX_MENU_NAV_UP : SFX_MENU_NAV_DOWN, NULL); - MNPage_SetFocus(page, page->objects + giveFocus); - } - } - break; - } - case MCMD_NAV_OUT: - if(!page->previous) - { - S_LocalSound(SFX_MENU_CLOSE, NULL); - Hu_MenuCommand(MCMD_CLOSE); - } - else - { - S_LocalSound(SFX_MENU_CANCEL, NULL); - Hu_MenuSetActivePage(page->previous); - } - break; - default: -// DEBUG_Message("Warning: fallbackCommandResponder: Command %i not processed, ignoring.\n", (int) cmd); - break; - } -} - -/// Depending on the current menu state some commands require translating. -static menucommand_e translateCommand(menucommand_e cmd) -{ - // If a close command is received while currently working with a selected - // "active" widget - interpret the command instead as "navigate out". - if(menuActive && (cmd == MCMD_CLOSE || cmd == MCMD_CLOSEFAST)) - { - mn_object_t* obj = MNPage_FocusObject(Hu_MenuActivePage()); - if(obj) - { - switch(MNObject_Type(obj)) - { - case MN_EDIT: - case MN_LIST: - case MN_COLORBOX: - if(MNObject_Flags(obj) & MNF_ACTIVE) - { - cmd = MCMD_NAV_OUT; - } - break; - default: - break; - } - } - } - return cmd; -} - -void Hu_MenuCommand(menucommand_e cmd) -{ - mn_page_t* page; - mn_object_t* obj; - - cmd = translateCommand(cmd); - - // Determine the page which will respond to this command. - if(colorWidgetActive) - page = Hu_MenuFindPageByName("ColorWidget"); - else - page = Hu_MenuActivePage(); - - if(cmd == MCMD_CLOSE || cmd == MCMD_CLOSEFAST) - { - if(menuActive) - { - //BusyMode_FreezeGameForBusyMode(); - - menuNominatingQuickSaveSlot = false; - - Hu_FogEffectSetAlphaTarget(0); - - if(cmd == MCMD_CLOSEFAST) - { // Hide the menu instantly. - mnAlpha = mnTargetAlpha = 0; - } - else - { - mnTargetAlpha = 0; - } - - if(cmd != MCMD_CLOSEFAST) - S_LocalSound(SFX_MENU_CLOSE, NULL); - - menuActive = false; - - // Disable the menu binding context. - DD_Execute(true, "deactivatebcontext menu"); - } - return; - } - - // No other commands are responded to once shutdown has begun. - if(G_QuitInProgress()) - { - return; - } - - if(!menuActive) - { - if(MCMD_OPEN == cmd) - { - // If anyone is currently chatting; the menu cannot be opened. - int i; - for(i = 0; i < MAXPLAYERS; ++i) - { - if(ST_ChatIsActive(i)) - return; - } - - S_LocalSound(SFX_MENU_OPEN, NULL); - - //Con_Open(false); - - Hu_FogEffectSetAlphaTarget(1); - Hu_MenuSetAlpha(1); - menuActive = true; - menuTime = 0; - - menuActivePage = NULL; // Always re-activate this page. - Hu_MenuSetActivePage(Hu_MenuFindPageByName("Main")); - - // Enable the menu binding class - DD_Execute(true, "activatebcontext menu"); - B_SetContextFallback("menu", Hu_MenuFallbackResponder); - } - return; - } - - // Try the current focus object. - obj = MNPage_FocusObject(page); - if(obj && obj->cmdResponder) - { - if(obj->cmdResponder(obj, cmd)) - return; - } - - // Try the page's cmd responder. - if(page->cmdResponder) - { - if(page->cmdResponder(page, cmd)) - return; - } - - fallbackCommandResponder(page, cmd); -} - -int Hu_MenuPrivilegedResponder(event_t* ev) -{ - if(Hu_MenuIsActive()) - { - mn_object_t* obj = MNPage_FocusObject(Hu_MenuActivePage()); - if(obj && !(MNObject_Flags(obj) & MNF_DISABLED)) - { - if(obj->privilegedResponder) - { - return obj->privilegedResponder(obj, ev); - } - } - } - return false; -} - -int Hu_MenuResponder(event_t* ev) -{ - if(Hu_MenuIsActive()) - { - mn_object_t* obj = MNPage_FocusObject(Hu_MenuActivePage()); - if(obj && !(MNObject_Flags(obj) & MNF_DISABLED)) - { - if(obj->responder) - { - return obj->responder(obj, ev); - } - } - } - return false; // Not eaten. -} - -int Hu_MenuFallbackResponder(event_t* ev) -{ - mn_page_t* page = Hu_MenuActivePage(); - - if(!Hu_MenuIsActive() || !page) return false; - - if(cfg.menuShortcutsEnabled) - { - if(ev->type == EV_KEY && (ev->state == EVS_DOWN || ev->state == EVS_REPEAT)) - { - int i; - for(i = 0; i < page->objectsCount; ++i) - { - mn_object_t* obj = &page->objects[i]; - if(MNObject_Flags(obj) & (MNF_DISABLED | MNF_NO_FOCUS | MNF_HIDDEN)) - continue; - - if(MNObject_Shortcut(obj) == ev->data1) - { - MNPage_SetFocus(page, obj); - return true; - } - } - } - } - return false; -} - -/** - * User wants to load this game - */ -int Hu_MenuSelectLoadSlot(mn_object_t* obj, mn_actionid_t action, void* parameters) -{ - mndata_edit_t* edit = (mndata_edit_t*)obj->_typedata; - const int saveSlot = edit->data2; - mn_page_t* saveGamePage; - - DENG_UNUSED(parameters); - - if(MNA_ACTIVEOUT != action) return 1; - - saveGamePage = Hu_MenuFindPageByName("SaveGame"); - MNPage_SetFocus(saveGamePage, MNPage_FindObject(saveGamePage, 0, obj->data2)); - - G_LoadGame(saveSlot); - Hu_MenuCommand(chooseCloseMethod()); - return 0; -} - -#if __JHERETIC__ || __JHEXEN__ -void Hu_MenuDrawMainPage(mn_page_t* page, const Point2Raw* origin) -{ -#define TITLEOFFSET_X (-22) -#define TITLEOFFSET_Y (-56) - -#if __JHEXEN__ - int frame = (menuTime / 5) % 7; -#endif - - DGL_Enable(DGL_TEXTURE_2D); - DGL_Color4f(1, 1, 1, mnRendState->pageAlpha); - FR_SetFont(FID(GF_FONTB)); - FR_SetColorAndAlpha(1, 1, 1, mnRendState->pageAlpha); - - WI_DrawPatchXY3(pMainTitle, Hu_ChoosePatchReplacement(cfg.menuPatchReplaceMode, pMainTitle), - origin->x + TITLEOFFSET_X, origin->y + TITLEOFFSET_Y, ALIGN_TOPLEFT, 0, MN_MergeMenuEffectWithDrawTextFlags(0)); -#if __JHEXEN__ - GL_DrawPatchXY(pBullWithFire[(frame + 2) % 7], origin->x - 73, origin->y + 24); - GL_DrawPatchXY(pBullWithFire[frame], origin->x + 168, origin->y + 24); -#elif __JHERETIC__ - GL_DrawPatchXY(pRotatingSkull[17 - frame], origin->x - 70, origin->y - 46); - GL_DrawPatchXY(pRotatingSkull[frame], origin->x + 122, origin->y - 46); -#endif - - DGL_Disable(DGL_TEXTURE_2D); - -#undef TITLEOFFSET_Y -#undef TITLEOFFSET_X -} -#endif - -void Hu_MenuDrawGameTypePage(mn_page_t* page, const Point2Raw* origin) -{ - Hu_MenuDrawPageTitle(GET_TXT(TXT_PICKGAMETYPE), SCREENWIDTH/2, origin->y - 28); -} - -#if __JHERETIC__ -static void composeNotDesignedForMessage(const char* str) -{ - char* buf = notDesignedForMessage, *in, tmp[2]; - - buf[0] = 0; - tmp[1] = 0; - - // Get the message template. - in = GET_TXT(TXT_NOTDESIGNEDFOR); - - for(; *in; in++) - { - if(in[0] == '%') - { - if(in[1] == '1') - { - strcat(buf, str); - in++; - continue; - } - - if(in[1] == '%') - in++; - } - tmp[0] = *in; - strcat(buf, tmp); - } -} -#endif - -#if __JHEXEN__ -/** - * A specialization of MNRect_Ticker() which implements the animation logic - * for the player class selection page's player visual background. - */ -void Hu_MenuPlayerClassBackgroundTicker(mn_object_t* ob) -{ - mn_object_t* mop; - assert(ob); - - // Determine our selection according to the current focus object. - /// @todo Do not search for the focus object, flag the "random" - /// state through a focus action. - mop = MNPage_FocusObject(MNObject_Page(ob)); - if(mop) - { - playerclass_t pClass = (playerclass_t) mop->data2; - if(pClass == PCLASS_NONE) - { - // Random class. - /// @todo Use this object's timer instead of menuTime. - pClass = (menuTime / 5); - } - - /// @todo Only change here if in the "random" state. - pClass %= 3; // Number of user-selectable classes. - - MNRect_SetBackgroundPatch(ob, pPlayerClassBG[pClass]); - } - - // Call MNRect's ticker now we've done our own processing. - MNRect_Ticker(ob); -} - -/** - * A specialization of MNMobjPreview_Ticker() which implements the animation - * logic for the player class selection page's player visual. - */ -void Hu_MenuPlayerClassPreviewTicker(mn_object_t* ob) -{ - mn_object_t* mop; - assert(ob); - - // Determine our selection according to the current focus object. - /// @todo Do not search for the focus object, flag the "random" - /// state through a focus action. - mop = MNPage_FocusObject(MNObject_Page(ob)); - if(mop) - { - playerclass_t pClass = (playerclass_t) mop->data2; - if(pClass == PCLASS_NONE) - { - // Random class. - /// @todo Use this object's timer instead of menuTime. - pClass = PCLASS_FIRST + (menuTime / 5); - pClass %= 3; // Number of user-selectable classes. - - MNMobjPreview_SetPlayerClass(ob, pClass); - MNMobjPreview_SetMobjType(ob, PCLASS_INFO(pClass)->mobjType); - } - - // Fighter is Yellow, others Red by default. - MNMobjPreview_SetTranslationClass(ob, pClass); - MNMobjPreview_SetTranslationMap(ob, pClass == PCLASS_FIGHTER? 2 : 0); - } - - // Call MNMobjPreview's ticker now we've done our own processing. - MNMobjPreview_Ticker(ob); -} - -void Hu_MenuDrawPlayerClassPage(mn_page_t* page, const Point2Raw* origin) -{ - DGL_Enable(DGL_TEXTURE_2D); - FR_SetFont(FID(GF_FONTB)); - FR_SetColorAndAlpha(cfg.menuTextColors[0][CR], cfg.menuTextColors[0][CG], cfg.menuTextColors[0][CB], mnRendState->pageAlpha); - - FR_DrawTextXY3("Choose class:", origin->x - 32, origin->y - 42, ALIGN_TOPLEFT, - MN_MergeMenuEffectWithDrawTextFlags(0)); - - DGL_Disable(DGL_TEXTURE_2D); -} -#endif - -#if __JDOOM__ || __JHERETIC__ -void Hu_MenuDrawEpisodePage(mn_page_t* page, const Point2Raw* origin) -{ -#if __JHERETIC__ - // Inform the user episode 6 is designed for deathmatch only. - mn_object_t* obj = MNPage_FindObject(page, 0, MNF_ID0); - if(obj && obj == MNPage_FocusObject(page)) - { - const char* str = notDesignedForMessage; - Point2Raw origin; - - composeNotDesignedForMessage(GET_TXT(TXT_SINGLEPLAYER)); - - origin.x = SCREENWIDTH/2; - origin.y = (SCREENHEIGHT/2) + ((SCREENHEIGHT/2-5)/cfg.menuScale); - - Hu_MenuDrawPageHelp(notDesignedForMessage, origin.x, origin.y); - } -#else // __JDOOM__ - DGL_Enable(DGL_TEXTURE_2D); - DGL_Color4f(1, 1, 1, mnRendState->pageAlpha); - - FR_SetFont(FID(GF_FONTB)); - FR_SetColorv(cfg.menuTextColors[0]); - FR_SetAlpha(mnRendState->pageAlpha); - - WI_DrawPatchXY3(pEpisode, Hu_ChoosePatchReplacement(cfg.menuPatchReplaceMode, pEpisode), - origin->x + 7, origin->y - 25, ALIGN_TOPLEFT, 0, MN_MergeMenuEffectWithDrawTextFlags(0)); - - DGL_Disable(DGL_TEXTURE_2D); -#endif -} -#endif - -void Hu_MenuDrawSkillPage(mn_page_t* page, const Point2Raw* origin) -{ -#if __JDOOM__ || __JDOOM64__ - DGL_Enable(DGL_TEXTURE_2D); - DGL_Color4f(1, 1, 1, mnRendState->pageAlpha); - FR_SetFont(FID(GF_FONTB)); - FR_SetColorAndAlpha(cfg.menuTextColors[0][CR], cfg.menuTextColors[0][CG], cfg.menuTextColors[0][CB], mnRendState->pageAlpha); - - WI_DrawPatchXY3(pNewGame, Hu_ChoosePatchReplacement(cfg.menuPatchReplaceMode, pNewGame), - origin->x + 48, origin->y - 49, ALIGN_TOPLEFT, 0, MN_MergeMenuEffectWithDrawTextFlags(0)); - WI_DrawPatchXY3(pSkill, Hu_ChoosePatchReplacement(cfg.menuPatchReplaceMode, pSkill), - origin->x + 6, origin->y - 25, ALIGN_TOPLEFT, 0, MN_MergeMenuEffectWithDrawTextFlags(0)); - - DGL_Disable(DGL_TEXTURE_2D); -#elif __JHEXEN__ - Hu_MenuDrawPageTitle("Choose Skill Level:", origin->x + 36, origin->y - 28); -#endif -} - -void Hu_MenuUpdateGameSaveWidgets(void) -{ - int const saveSlotObjectIds[NUMSAVESLOTS] = { - MNF_ID0, MNF_ID1, MNF_ID2, MNF_ID3, MNF_ID4, MNF_ID5, -#if !__JHEXEN__ - MNF_ID6, MNF_ID7 -#endif - }; - mn_page_t *page; - int i; - - if(!menuActive) return; - - // Prompt a refresh of the game-save info. We don't yet actively monitor - // the contents of the game-save paths, so instead we settle for manual - // updates whenever the save/load menu is opened. - SaveSlots_UpdateAllSaveInfo(saveSlots); - - // Update widgets. - page = Hu_MenuFindPageByName("LoadGame"); - for(i = 0; i < NUMSAVESLOTS; ++i) - { - mn_object_t *obj = MN_MustFindObjectOnPage(page, 0, saveSlotObjectIds[i]); - mndata_edit_t *edit = (mndata_edit_t *) obj->_typedata; - char const *text = ""; - - MNObject_SetFlags(obj, FO_SET, MNF_DISABLED); - if(SaveSlots_SlotInUse(saveSlots, edit->data2)) - { - SaveInfo *info = SaveSlots_SaveInfo(saveSlots, edit->data2); - text = Str_Text(SaveInfo_Description(info)); - MNObject_SetFlags(obj, FO_CLEAR, MNF_DISABLED); - } - MNEdit_SetText(obj, MNEDIT_STF_NO_ACTION, text); - } -} - -/** - * Called after the save name has been modified and to action the game-save. - */ -int Hu_MenuSelectSaveSlot(mn_object_t* ob, mn_actionid_t action, void* parameters) -{ - mndata_edit_t* edit = (mndata_edit_t*)ob->_typedata; - const int saveSlot = edit->data2; - mn_page_t* page; - - DENG_UNUSED(parameters); - - if(MNA_ACTIVEOUT != action) return 1; - - if(menuNominatingQuickSaveSlot) - { - Con_SetInteger("game-save-quick-slot", saveSlot); - menuNominatingQuickSaveSlot = false; - } - - if(!G_SaveGame2(saveSlot, Str_Text(MNEdit_Text(ob)))) return 0; - - page = Hu_MenuFindPageByName("SaveGame"); - MNPage_SetFocus(page, MN_MustFindObjectOnPage(page, 0, ob->data2)); - - page = Hu_MenuFindPageByName("LoadGame"); - MNPage_SetFocus(page, MN_MustFindObjectOnPage(page, 0, ob->data2)); - - Hu_MenuCommand(chooseCloseMethod()); - return 0; -} - -int Hu_MenuCvarButton(mn_object_t* obj, mn_actionid_t action, void* parameters) -{ - mndata_button_t* btn = (mndata_button_t*)obj->_typedata; - const cvarbutton_t* cb = obj->data1; - cvartype_t varType = Con_GetVariableType(cb->cvarname); - int value; - - DENG_UNUSED(parameters); - if(MNA_MODIFIED != action) return 1; - - //strcpy(btn->text, cb->active? cb->yes : cb->no); - btn->text = cb->active? cb->yes : cb->no; - - if(CVT_NULL == varType) return 0; - - if(cb->mask) - { - value = Con_GetInteger(cb->cvarname); - if(cb->active) - { - value |= cb->mask; - } - else - { - value &= ~cb->mask; - } - } - else - { - value = cb->active; - } - - Con_SetInteger2(cb->cvarname, value, SVF_WRITE_OVERRIDE); - return 0; -} - -int Hu_MenuCvarList(mn_object_t* obj, mn_actionid_t action, void* parameters) -{ - const mndata_list_t* list = (mndata_list_t*) obj->_typedata; - const mndata_listitem_t* item; - cvartype_t varType; - int value; - - DENG_UNUSED(parameters); - if(MNA_MODIFIED != action) return 1; - - if(MNList_Selection(obj) < 0) return 0; // Hmm? - - varType = Con_GetVariableType(list->data); - if(CVT_NULL == varType) return 0; - - item = &((mndata_listitem_t*) list->items)[list->selection]; - if(list->mask) - { - value = Con_GetInteger(list->data); - value = (value & ~list->mask) | (item->data & list->mask); - } - else - { - value = item->data; - } - - switch(varType) - { - case CVT_INT: - Con_SetInteger2(list->data, value, SVF_WRITE_OVERRIDE); - break; - case CVT_BYTE: - Con_SetInteger2(list->data, (byte) value, SVF_WRITE_OVERRIDE); - break; - default: - Con_Error("Hu_MenuCvarList: Unsupported variable type %i", (int)varType); - break; - } - return 0; -} - -int Hu_MenuSaveSlotEdit(mn_object_t* obj, mn_actionid_t action, void* parameters) -{ - DENG_UNUSED(parameters); - - if(MNA_ACTIVE != action) return 1; - - // Are we suggesting a new name? - if(cfg.menuGameSaveSuggestName) - { - AutoStr* suggestName = G_GenerateSaveGameName(); - MNEdit_SetText(obj, MNEDIT_STF_NO_ACTION, Str_Text(suggestName)); - } - return 0; -} - -int Hu_MenuCvarEdit(mn_object_t* ob, mn_actionid_t action, void* parameters) -{ - const mndata_edit_t* edit = (mndata_edit_t*)ob->_typedata; - cvartype_t varType = Con_GetVariableType(edit->data1); - - DENG_UNUSED(parameters); - - if(MNA_MODIFIED != action) return 1; - - switch(varType) - { - case CVT_CHARPTR: - Con_SetString2(edit->data1, Str_Text(MNEdit_Text(ob)), SVF_WRITE_OVERRIDE); - break; - case CVT_URIPTR: { - /// @todo Sanitize and validate against known schemas. - Uri* uri = Uri_NewWithPath2(Str_Text(MNEdit_Text(ob)), RC_NULL); - Con_SetUri2(edit->data1, uri, SVF_WRITE_OVERRIDE); - Uri_Delete(uri); - break; - } - default: break; - } - return 0; -} - -int Hu_MenuCvarSlider(mn_object_t* obj, mn_actionid_t action, void* parameters) -{ - const mndata_slider_t* sldr = obj->_typedata; - cvartype_t varType = Con_GetVariableType(sldr->data1); - float value = MNSlider_Value(obj); - - DENG_UNUSED(parameters); - if(MNA_MODIFIED != action) return 1; - - if(CVT_NULL == varType) return 0; - - switch(varType) - { - case CVT_FLOAT: - if(sldr->step >= .01f) - { - Con_SetFloat2(sldr->data1, (int) (100 * value) / 100.0f, SVF_WRITE_OVERRIDE); - } - else - { - Con_SetFloat2(sldr->data1, value, SVF_WRITE_OVERRIDE); - } - break; - case CVT_INT: - Con_SetInteger2(sldr->data1, (int) value, SVF_WRITE_OVERRIDE); - break; - case CVT_BYTE: - Con_SetInteger2(sldr->data1, (byte) value, SVF_WRITE_OVERRIDE); - break; - default: - break; - } - return 0; -} - -int Hu_MenuActivateColorWidget(mn_object_t* obj, mn_actionid_t action, void* parameters) -{ - mn_object_t* cboxMix, *sldrRed, *sldrGreen, *sldrBlue, *textAlpha, *sldrAlpha; - mn_page_t* colorWidgetPage = Hu_MenuFindPageByName("ColorWidget"); - - DENG_UNUSED(parameters); - if(action != MNA_ACTIVE) return 1; - - cboxMix = MN_MustFindObjectOnPage(colorWidgetPage, 0, MNF_ID0); - sldrRed = MN_MustFindObjectOnPage(colorWidgetPage, 0, MNF_ID1); - sldrGreen = MN_MustFindObjectOnPage(colorWidgetPage, 0, MNF_ID2); - sldrBlue = MN_MustFindObjectOnPage(colorWidgetPage, 0, MNF_ID3); - textAlpha = MN_MustFindObjectOnPage(colorWidgetPage, 0, MNF_ID4); - sldrAlpha = MN_MustFindObjectOnPage(colorWidgetPage, 0, MNF_ID5); - - colorWidgetActive = true; - - MNPage_Initialize(colorWidgetPage); - colorWidgetPage->userData = obj; - - MNColorBox_CopyColor(cboxMix, 0, obj); - MNSlider_SetValue(sldrRed, MNSLIDER_SVF_NO_ACTION, MNColorBox_Redf(obj)); - MNSlider_SetValue(sldrGreen, MNSLIDER_SVF_NO_ACTION, MNColorBox_Greenf(obj)); - MNSlider_SetValue(sldrBlue, MNSLIDER_SVF_NO_ACTION, MNColorBox_Bluef(obj)); - MNSlider_SetValue(sldrAlpha, MNSLIDER_SVF_NO_ACTION, MNColorBox_Alphaf(obj)); - - MNObject_SetFlags(textAlpha, (MNColorBox_RGBAMode(obj)? FO_CLEAR : FO_SET), MNF_DISABLED|MNF_HIDDEN); - MNObject_SetFlags(sldrAlpha, (MNColorBox_RGBAMode(obj)? FO_CLEAR : FO_SET), MNF_DISABLED|MNF_HIDDEN); - - return 0; -} - -int Hu_MenuCvarColorBox(mn_object_t* obj, mn_actionid_t action, void* parameters) -{ - mndata_colorbox_t* cbox = (mndata_colorbox_t*)obj->_typedata; - DENG_UNUSED(parameters); - if(action != MNA_MODIFIED) return 1; - // MNColorBox's current color has already been updated and we know - // that at least one of the color components have changed. - // So our job is to simply update the associated cvars. - Con_SetFloat2(cbox->data1, MNColorBox_Redf(obj), SVF_WRITE_OVERRIDE); - Con_SetFloat2(cbox->data2, MNColorBox_Greenf(obj), SVF_WRITE_OVERRIDE); - Con_SetFloat2(cbox->data3, MNColorBox_Bluef(obj), SVF_WRITE_OVERRIDE); - if(MNColorBox_RGBAMode(obj)) - Con_SetFloat2(cbox->data4, MNColorBox_Alphaf(obj), SVF_WRITE_OVERRIDE); - return 0; -} - -void Hu_MenuDrawLoadGamePage(mn_page_t* page, const Point2Raw* origin) -{ - DENG_UNUSED(page); - - DGL_Enable(DGL_TEXTURE_2D); - DGL_Color4f(1, 1, 1, mnRendState->pageAlpha); - FR_SetFont(FID(GF_FONTB)); - FR_SetColorAndAlpha(cfg.menuTextColors[0][CR], cfg.menuTextColors[0][CG], cfg.menuTextColors[0][CB], mnRendState->pageAlpha); - -#if __JHERETIC__ || __JHEXEN__ - FR_DrawTextXY3("Load Game", SCREENWIDTH/2, origin->y-20, ALIGN_TOP, MN_MergeMenuEffectWithDrawTextFlags(0)); -#else - WI_DrawPatchXY3(pLoadGame, Hu_ChoosePatchReplacement(cfg.menuPatchReplaceMode, pLoadGame), - origin->x - 8, origin->y - 26, ALIGN_TOPLEFT, 0, MN_MergeMenuEffectWithDrawTextFlags(0)); -#endif - DGL_Disable(DGL_TEXTURE_2D); - - { Point2Raw helpOrigin; - helpOrigin.x = SCREENWIDTH/2; - helpOrigin.y = (SCREENHEIGHT/2) + ((SCREENHEIGHT/2-5)/cfg.menuScale); - Hu_MenuDrawPageHelp("Select to load, [Del] to clear", helpOrigin.x, helpOrigin.y); - } -} - -void Hu_MenuDrawSaveGamePage(mn_page_t* page, const Point2Raw* origin) -{ - DENG_UNUSED(page); - -#if __JHERETIC__ || __JHEXEN__ - Hu_MenuDrawPageTitle("Save Game", SCREENWIDTH/2, origin->y - 20); -#else - DGL_Enable(DGL_TEXTURE_2D); - DGL_Color4f(1, 1, 1, mnRendState->pageAlpha); - FR_SetFont(FID(GF_FONTB)); - FR_SetColorAndAlpha(cfg.menuTextColors[0][CR], cfg.menuTextColors[0][CG], cfg.menuTextColors[0][CB], mnRendState->pageAlpha); - - WI_DrawPatchXY3(pSaveGame, Hu_ChoosePatchReplacement(cfg.menuPatchReplaceMode, pSaveGame), - origin->x - 8, origin->y - 26, ALIGN_TOPLEFT, 0, MN_MergeMenuEffectWithDrawTextFlags(0)); - - DGL_Disable(DGL_TEXTURE_2D); -#endif - - { Point2Raw helpOrigin; - helpOrigin.x = SCREENWIDTH/2; - helpOrigin.y = (SCREENHEIGHT/2) + ((SCREENHEIGHT/2-5)/cfg.menuScale); - Hu_MenuDrawPageHelp("Select to save, [Del] to clear", helpOrigin.x, helpOrigin.y); - } -} - -#if __JDOOM__ || __JHERETIC__ || __JHEXEN__ -int Hu_MenuSelectHelp(mn_object_t* obj, mn_actionid_t action, void* parameters) -{ - DENG_UNUSED(parameters); - if(MNA_ACTIVEOUT != action) return 1; - G_StartHelp(); - return 0; -} -#endif - -void Hu_MenuDrawOptionsPage(mn_page_t* page, const Point2Raw* origin) -{ -#if __JHERETIC__ || __JHEXEN__ - Hu_MenuDrawPageTitle("Options", origin->x + 42, origin->y - 38); -#else - DGL_Enable(DGL_TEXTURE_2D); - DGL_Color4f(1, 1, 1, mnRendState->pageAlpha); - FR_SetFont(FID(GF_FONTB)); - FR_SetColorAndAlpha(cfg.menuTextColors[0][CR], cfg.menuTextColors[0][CG], cfg.menuTextColors[0][CB], mnRendState->pageAlpha); - - WI_DrawPatchXY3(pOptionsTitle, Hu_ChoosePatchReplacement(cfg.menuPatchReplaceMode, pOptionsTitle), - origin->x + 42, origin->y - 20, ALIGN_TOP, 0, MN_MergeMenuEffectWithDrawTextFlags(0)); - - DGL_Disable(DGL_TEXTURE_2D); -#endif -} - -void Hu_MenuDrawWeaponsPage(mn_page_t* page, const Point2Raw* offset) -{ - // Inform the user how to change the order. - if(MNPage_FocusObject(page) == MN_MustFindObjectOnPage(page, 0, MNF_ID0)) - { - const char* helpText = "Use left/right to move weapon up/down"; - Point2Raw origin; - origin.x = SCREENWIDTH/2; - origin.y = (SCREENHEIGHT/2) + ((SCREENHEIGHT/2-5)/cfg.menuScale); - Hu_MenuDrawPageHelp(helpText, origin.x, origin.y); - } -} - -void Hu_MenuDrawMultiplayerPage(mn_page_t* page, const Point2Raw* origin) -{ - Hu_MenuDrawPageTitle(GET_TXT(TXT_MULTIPLAYER), SCREENWIDTH/2, origin->y - 28); -} - -void Hu_MenuDrawPlayerSetupPage(mn_page_t* page, const Point2Raw* origin) -{ - Hu_MenuDrawPageTitle(GET_TXT(TXT_PLAYERSETUP), SCREENWIDTH/2, origin->y - 28); -} - -int Hu_MenuActionSetActivePage(mn_object_t* obj, mn_actionid_t action, void* parameters) -{ - assert(obj); - DENG_UNUSED(parameters); - if(MNA_ACTIVEOUT != action) return 1; - Hu_MenuSetActivePage(Hu_MenuFindPageByName((char*)obj->data1)); - return 0; -} - -int Hu_MenuUpdateColorWidgetColor(mn_object_t* obj, mn_actionid_t action, void* parameters) -{ - float value = MNSlider_Value(obj); - mn_object_t* cboxMix = MN_MustFindObjectOnPage(Hu_MenuFindPageByName("ColorWidget"), 0, MNF_ID0); - - DENG_UNUSED(parameters); - if(MNA_MODIFIED != action) return 1; - - switch(obj->data2) - { - case CR: MNColorBox_SetRedf( cboxMix, MNCOLORBOX_SCF_NO_ACTION, value); break; - case CG: MNColorBox_SetGreenf(cboxMix, MNCOLORBOX_SCF_NO_ACTION, value); break; - case CB: MNColorBox_SetBluef( cboxMix, MNCOLORBOX_SCF_NO_ACTION, value); break; - case CA: MNColorBox_SetAlphaf(cboxMix, MNCOLORBOX_SCF_NO_ACTION, value); break; - default: - Con_Error("Hu_MenuUpdateColorWidgetColor: Invalid value (%i) for data2.", obj->data2); - } - return 0; -} - -int Hu_MenuChangeWeaponPriority(mn_object_t* obj, mn_actionid_t action, void* parameters) -{ - DENG_UNUSED(parameters); - if(MNA_MODIFIED != action) return 1; - /*int choice = option >> NUM_WEAPON_TYPES; - int temp; - - if(option & RIGHT_DIR) - { - if(choice < NUM_WEAPON_TYPES-1) - { - temp = cfg.weaponOrder[choice+1]; - cfg.weaponOrder[choice+1] = cfg.weaponOrder[choice]; - cfg.weaponOrder[choice] = temp; - } - } - else - { - if(choice > 0) - { - temp = cfg.weaponOrder[choice]; - cfg.weaponOrder[choice] = cfg.weaponOrder[choice-1]; - cfg.weaponOrder[choice-1] = temp; - } - }*/ - return 0; -} - -int Hu_MenuSelectSingleplayer(mn_object_t* ob, mn_actionid_t action, void* parameters) -{ - DENG_UNUSED(parameters); - - if(MNA_ACTIVEOUT != action) return 1; - - if(IS_NETGAME) - { - Hu_MsgStart(MSG_ANYKEY, NEWGAME, NULL, 0, NULL); - return 0; - } - -#if __JHEXEN__ - Hu_MenuSetActivePage(Hu_MenuFindPageByName("PlayerClass")); -#elif __JHERETIC__ - Hu_MenuSetActivePage(Hu_MenuFindPageByName("Episode")); -#elif __JDOOM64__ - Hu_MenuSetActivePage(Hu_MenuFindPageByName("Skill")); -#else // __JDOOM__ - if(gameModeBits & (GM_ANY_DOOM2|GM_DOOM_CHEX)) - Hu_MenuSetActivePage(Hu_MenuFindPageByName("Skill")); - else - Hu_MenuSetActivePage(Hu_MenuFindPageByName("Episode")); -#endif - return 0; -} - -int Hu_MenuSelectMultiplayer(mn_object_t* obj, mn_actionid_t action, void* parameters) -{ - mn_page_t* multiplayerPage = Hu_MenuFindPageByName("Multiplayer"); - mn_object_t* labelObj = MN_MustFindObjectOnPage(multiplayerPage, 0, MNF_ID0); - mndata_button_t* btn = (mndata_button_t*)labelObj->_typedata; - - DENG_UNUSED(parameters); - if(MNA_ACTIVEOUT != action) return 1; - - // Set the appropriate label. - if(IS_NETGAME) - { - btn->text = "Disconnect"; - } - else - { - btn->text = "Join Game"; - } - Hu_MenuSetActivePage(multiplayerPage); - return 0; -} - -int Hu_MenuSelectJoinGame(mn_object_t* ob, mn_actionid_t action, void* parameters) -{ - DENG_UNUSED(ob); - DENG_UNUSED(parameters); - - if(MNA_ACTIVEOUT != action) return 1; - if(IS_NETGAME) - { - DD_Execute(false, "net disconnect"); - Hu_MenuCommand(MCMD_CLOSE); - return 0; - } - - DD_Execute(false, "net setup client"); - return 0; -} - -int Hu_MenuSelectPlayerSetup(mn_object_t* ob, mn_actionid_t action, void* parameters) -{ - mn_page_t* playerSetupPage = Hu_MenuFindPageByName("PlayerSetup"); - mn_object_t* mop = MN_MustFindObjectOnPage(playerSetupPage, 0, MNF_ID0); - mn_object_t* name = MN_MustFindObjectOnPage(playerSetupPage, 0, MNF_ID1); - mn_object_t* color = MN_MustFindObjectOnPage(playerSetupPage, 0, MNF_ID3); -#if __JHEXEN__ - mn_object_t* class_; -#endif - - DENG_UNUSED(ob); - DENG_UNUSED(parameters); - if(MNA_ACTIVEOUT != action) return 1; - -#if __JHEXEN__ - MNMobjPreview_SetMobjType(mop, PCLASS_INFO(cfg.netClass)->mobjType); - MNMobjPreview_SetPlayerClass(mop, cfg.netClass); -#else - MNMobjPreview_SetMobjType(mop, MT_PLAYER); - MNMobjPreview_SetPlayerClass(mop, PCLASS_PLAYER); -#endif - MNMobjPreview_SetTranslationClass(mop, 0); - MNMobjPreview_SetTranslationMap(mop, cfg.netColor); - - MNList_SelectItemByValue(color, MNLIST_SIF_NO_ACTION, cfg.netColor); -#if __JHEXEN__ - class_ = MN_MustFindObjectOnPage(playerSetupPage, 0, MNF_ID2); - MNList_SelectItemByValue(class_, MNLIST_SIF_NO_ACTION, cfg.netClass); -#endif - - MNEdit_SetText(name, MNEDIT_STF_NO_ACTION|MNEDIT_STF_REPLACEOLD, Con_GetString("net-name")); - - Hu_MenuSetActivePage(playerSetupPage); - return 0; -} - -#if __JHEXEN__ -int Hu_MenuSelectPlayerSetupPlayerClass(mn_object_t* ob, mn_actionid_t action, void* parameters) -{ - int selection; - - DENG_UNUSED(parameters); - if(MNA_MODIFIED != action) return 1; - - selection = MNList_Selection(ob); - if(selection >= 0) - { - mn_object_t* mop = MN_MustFindObjectOnPage(MNObject_Page(ob), 0, MNF_ID0); - MNMobjPreview_SetPlayerClass(mop, selection); - MNMobjPreview_SetMobjType(mop, PCLASS_INFO(selection)->mobjType); - } - return 0; -} -#endif - -int Hu_MenuSelectPlayerColor(mn_object_t* ob, mn_actionid_t action, void* parameters) -{ - int selection; - - DENG_UNUSED(parameters); - if(MNA_MODIFIED != action) return 1; - - // The color translation map is stored in the list item data member. - selection = MNList_ItemData(ob, MNList_Selection(ob)); - if(selection >= 0) - { - mn_object_t* mop = MN_MustFindObjectOnPage(MNObject_Page(ob), 0, MNF_ID0); - MNMobjPreview_SetTranslationMap(mop, selection); - } - return 0; -} - -int Hu_MenuSelectAcceptPlayerSetup(mn_object_t* ob, mn_actionid_t action, void* parameters) -{ - mn_object_t* plrNameEdit = MN_MustFindObjectOnPage(MNObject_Page(ob), 0, MNF_ID1); -#if __JHEXEN__ - mn_object_t* plrClassList = MN_MustFindObjectOnPage(MNObject_Page(ob), 0, MNF_ID2); -#endif - mn_object_t* plrColorList = MN_MustFindObjectOnPage(MNObject_Page(ob), 0, MNF_ID3); - char buf[300]; - - DENG_UNUSED(parameters); - -#if __JHEXEN__ - cfg.netClass = MNList_Selection(plrClassList); -#endif - // The color translation map is stored in the list item data member. - cfg.netColor = MNList_ItemData(plrColorList, MNList_Selection(plrColorList)); - - if(MNA_ACTIVEOUT != action) return 1; - - strcpy(buf, "net-name "); - M_StrCatQuoted(buf, Str_Text(MNEdit_Text(plrNameEdit)), 300); - DD_Execute(false, buf); - - if(IS_NETGAME) - { - strcpy(buf, "setname "); - M_StrCatQuoted(buf, Str_Text(MNEdit_Text(plrNameEdit)), 300); - DD_Execute(false, buf); -#if __JHEXEN__ - // Must do 'setclass' first; the real class and color do not change - // until the server sends us a notification -- this means if we do - // 'setcolor' first, the 'setclass' after it will override the color - // change (or such would appear to be the case). - DD_Executef(false, "setclass %i", cfg.netClass); -#endif - DD_Executef(false, "setcolor %i", cfg.netColor); - } - - Hu_MenuSetActivePage(Hu_MenuFindPageByName("Multiplayer")); - return 0; -} - -int Hu_MenuSelectQuitGame(mn_object_t* ob, mn_actionid_t action, void* parameters) -{ - DENG_UNUSED(ob); - DENG_UNUSED(parameters); - if(MNA_ACTIVEOUT != action) return 1; - G_QuitGame(); - return 0; -} - -int Hu_MenuSelectEndGame(mn_object_t* ob, mn_actionid_t action, void* parameters) -{ - DENG_UNUSED(ob); - DENG_UNUSED(parameters); - if(MNA_ACTIVEOUT != action) return 1; - G_EndGame(); - return 0; -} - -int Hu_MenuSelectLoadGame(mn_object_t* ob, mn_actionid_t action, void* parameters) -{ - DENG_UNUSED(ob); - DENG_UNUSED(parameters); - - if(MNA_ACTIVEOUT != action) return 1; - - if(!Get(DD_DEDICATED)) - { - if(IS_CLIENT && !Get(DD_PLAYBACK)) - { - Hu_MsgStart(MSG_ANYKEY, LOADNET, NULL, 0, NULL); - return 0; - } - } - - Hu_MenuUpdateGameSaveWidgets(); - Hu_MenuSetActivePage(Hu_MenuFindPageByName("LoadGame")); - return 0; -} - -int Hu_MenuSelectSaveGame(mn_object_t* ob, mn_actionid_t action, void* parameters) -{ - player_t* player = &players[CONSOLEPLAYER]; - - DENG_UNUSED(ob); - DENG_UNUSED(parameters); - - if(MNA_ACTIVEOUT != action) return 1; - if(!Get(DD_DEDICATED)) - { - if(IS_CLIENT) - { -#if __JDOOM__ || __JDOOM64__ - Hu_MsgStart(MSG_ANYKEY, SAVENET, NULL, 0, NULL); -#endif - return 0; - } - - if(G_GameState() != GS_MAP) - { - Hu_MsgStart(MSG_ANYKEY, SAVEOUTMAP, NULL, 0, NULL); - return 0; - } - - if(player->playerState == PST_DEAD) - { - Hu_MsgStart(MSG_ANYKEY, SAVEDEAD, NULL, 0, NULL); - return 0; - } - } - - Hu_MenuCommand(MCMD_OPEN); - Hu_MenuUpdateGameSaveWidgets(); - Hu_MenuSetActivePage(Hu_MenuFindPageByName("SaveGame")); - return 0; -} - -#if __JHEXEN__ -int Hu_MenuSelectPlayerClass(mn_object_t* ob, mn_actionid_t action, void* parameters) -{ - mn_page_t* skillPage = Hu_MenuFindPageByName("Skill"); - int option = ob->data2; - mn_object_t* skillObj; - const char* text; - - DENG_UNUSED(parameters); - - if(MNA_ACTIVEOUT != action) return 1; - if(IS_NETGAME) - { - P_SetMessage(&players[CONSOLEPLAYER], LMF_NO_HIDE, "You can't start a new game from within a netgame!"); - return 0; - } - - if(option < 0) - { // Random class. - // Number of user-selectable classes. - mnPlrClass = (menuTime / 5) % 3; - } - else - { - mnPlrClass = option; - } - - skillObj = MN_MustFindObjectOnPage(skillPage, 0, MNF_ID0); - text = GET_TXT(PCLASS_INFO(mnPlrClass)->skillModeNames[SM_BABY]); - ((mndata_button_t*)skillObj->_typedata)->text = text; - MNObject_SetShortcut(skillObj, text[0]); - - skillObj = MN_MustFindObjectOnPage(skillPage, 0, MNF_ID1); - text = GET_TXT(PCLASS_INFO(mnPlrClass)->skillModeNames[SM_EASY]); - ((mndata_button_t*)skillObj->_typedata)->text = text; - MNObject_SetShortcut(skillObj, text[0]); - - skillObj = MN_MustFindObjectOnPage(skillPage, 0, MNF_ID2); - text = GET_TXT(PCLASS_INFO(mnPlrClass)->skillModeNames[SM_MEDIUM]); - ((mndata_button_t*)skillObj->_typedata)->text = text; - MNObject_SetShortcut(skillObj, text[0]); - - skillObj = MN_MustFindObjectOnPage(skillPage, 0, MNF_ID3); - text = GET_TXT(PCLASS_INFO(mnPlrClass)->skillModeNames[SM_HARD]); - ((mndata_button_t*)skillObj->_typedata)->text = text; - MNObject_SetShortcut(skillObj, text[0]); - - skillObj = MN_MustFindObjectOnPage(skillPage, 0, MNF_ID4); - text = GET_TXT(PCLASS_INFO(mnPlrClass)->skillModeNames[SM_NIGHTMARE]); - ((mndata_button_t*)skillObj->_typedata)->text = text; - MNObject_SetShortcut(skillObj, text[0]); - - switch(mnPlrClass) - { - case PCLASS_FIGHTER: MNPage_SetX(skillPage, 120); break; - case PCLASS_CLERIC: MNPage_SetX(skillPage, 116); break; - case PCLASS_MAGE: MNPage_SetX(skillPage, 112); break; - } - Hu_MenuSetActivePage(skillPage); - return 0; -} - -int Hu_MenuFocusOnPlayerClass(mn_object_t* ob, mn_actionid_t action, void* parameters) -{ - playerclass_t plrClass = (playerclass_t)ob->data2; - mn_object_t* mop; - - DENG_UNUSED(parameters); - if(MNA_FOCUS != action) return 1; - - mop = MN_MustFindObjectOnPage(MNObject_Page(ob), 0, MNF_ID0); - MNMobjPreview_SetPlayerClass(mop, plrClass); - MNMobjPreview_SetMobjType(mop, (PCLASS_NONE == plrClass? MT_NONE : PCLASS_INFO(plrClass)->mobjType)); - - Hu_MenuDefaultFocusAction(ob, action, parameters); - return 0; -} -#endif - -#if __JDOOM__ || __JHERETIC__ -int Hu_MenuFocusEpisode(mn_object_t* ob, mn_actionid_t action, void* parameters) -{ - DENG_UNUSED(parameters); - if(MNA_FOCUS != action) return 1; - mnEpisode = ob->data2; - Hu_MenuDefaultFocusAction(ob, action, parameters); - return 0; -} - -int Hu_MenuConfirmOrderCommericalVersion(msgresponse_t response, int userValue, void* userPointer) -{ - G_StartHelp(); - return true; -} - -int Hu_MenuActivateNotSharewareEpisode(mn_object_t* ob, mn_actionid_t action, void* parameters) -{ - DENG_UNUSED(ob); - DENG_UNUSED(parameters); - if(MNA_ACTIVEOUT != action) return 1; - Hu_MsgStart(MSG_ANYKEY, SWSTRING, Hu_MenuConfirmOrderCommericalVersion, 0, NULL); - return 0; -} -#endif - -int Hu_MenuFocusSkillMode(mn_object_t* ob, mn_actionid_t action, void* parameters) -{ - assert(ob); - DENG_UNUSED(parameters); - if(MNA_FOCUS != action) return 1; - mnSkillmode = (skillmode_t)ob->data2; - Hu_MenuDefaultFocusAction(ob, action, parameters); - return 0; -} - -#if __JDOOM__ -int Hu_MenuConfirmInitNewGame(msgresponse_t response, int userValue, void* userPointer) -{ - if(response == MSG_YES) - { - Hu_MenuInitNewGame(true); - } - return true; -} -#endif - -void Hu_MenuInitNewGame(dd_bool confirmed) -{ - GameRuleset newRules = gameRules; - Uri *newMapUri = 0; - -#if __JDOOM__ - if(!confirmed && SM_NIGHTMARE == mnSkillmode) - { - Hu_MsgStart(MSG_YESNO, NIGHTMARE, Hu_MenuConfirmInitNewGame, 0, NULL); - return; - } -#endif - - Hu_MenuCommand(chooseCloseMethod()); - -#if __JHEXEN__ - cfg.playerClass[CONSOLEPLAYER] = mnPlrClass; -#endif - - newRules.skill = mnSkillmode; -#if __JHEXEN__ - newMapUri = G_ComposeMapUri(mnEpisode, P_TranslateMap(0)); -#else - newMapUri = G_ComposeMapUri(mnEpisode, 0); -#endif - - G_DeferredNewGame(newMapUri, 0/*default*/, &newRules); - Uri_Delete(newMapUri); -} - -int Hu_MenuActionInitNewGame(mn_object_t* ob, mn_actionid_t action, void* parameters) -{ - DENG_UNUSED(ob); - DENG_UNUSED(parameters); - if(MNA_ACTIVEOUT != action) return 1; - Hu_MenuInitNewGame(false); - return 0; -} - -int Hu_MenuSelectControlPanelLink(mn_object_t* ob, mn_actionid_t action, void* parameters) -{ -#define NUM_PANEL_NAMES 1 - - static const char* panelNames[NUM_PANEL_NAMES] = { - "taskbar" //, - //"panel audio", - //"panel input" - }; - int idx = ob->data2; - - DENG_UNUSED(parameters); - if(MNA_ACTIVEOUT != action) return 1; - - if(idx < 0 || idx > NUM_PANEL_NAMES - 1) - idx = 0; - - DD_Execute(true, panelNames[idx]); - return 0; - -#undef NUM_PANEL_NAMES -} - -D_CMD(MenuOpen) -{ - if(argc > 1) - { - if(!stricmp(argv[1], "open")) - { - Hu_MenuCommand(MCMD_OPEN); - return true; - } - if(!stricmp(argv[1], "close")) - { - Hu_MenuCommand(MCMD_CLOSE); - return true; - } - - { - mn_page_t* page = Hu_MenuFindPageByName(argv[1]); - if(page) - { - Hu_MenuCommand(MCMD_OPEN); - Hu_MenuSetActivePage(page); - return true; - } - } - return false; - } - - Hu_MenuCommand(!menuActive? MCMD_OPEN : MCMD_CLOSE); - return true; -} - -/** - * Routes console commands for menu actions and navigation into the menu subsystem. - */ -D_CMD(MenuCommand) -{ - if(menuActive) - { - const char* cmd = argv[0] + 4; - if(!stricmp(cmd, "up")) - { - Hu_MenuCommand(MCMD_NAV_UP); - return true; - } - if(!stricmp(cmd, "down")) - { - Hu_MenuCommand(MCMD_NAV_DOWN); - return true; - } - if(!stricmp(cmd, "left")) - { - Hu_MenuCommand(MCMD_NAV_LEFT); - return true; - } - if(!stricmp(cmd, "right")) - { - Hu_MenuCommand(MCMD_NAV_RIGHT); - return true; - } - if(!stricmp(cmd, "back")) - { - Hu_MenuCommand(MCMD_NAV_OUT); - return true; - } - if(!stricmp(cmd, "delete")) - { - Hu_MenuCommand(MCMD_DELETE); - return true; - } - if(!stricmp(cmd, "select")) - { - Hu_MenuCommand(MCMD_SELECT); - return true; - } - if(!stricmp(cmd, "pagedown")) - { - Hu_MenuCommand(MCMD_NAV_PAGEDOWN); - return true; - } - if(!stricmp(cmd, "pageup")) - { - Hu_MenuCommand(MCMD_NAV_PAGEUP); - return true; - } - } - return false; -} diff --git a/doomsday/plugins/common/src/hu_menu.cpp b/doomsday/plugins/common/src/hu_menu.cpp new file mode 100644 index 0000000000..2597b43e28 --- /dev/null +++ b/doomsday/plugins/common/src/hu_menu.cpp @@ -0,0 +1,6687 @@ +/** @file hu_menu.cpp Menu widget stuff, episode selection and such. + * + * @authors Copyright © 2003-2013 Jaakko Keränen + * @authors Copyright © 2005-2013 Daniel Swanson + * + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. You should have received a copy of the GNU + * General Public License along with this program; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#include "common.h" +#include "hu_menu.h" + +#include "m_argv.h" +#include "hu_chat.h" +#include "hu_log.h" +#include "hu_msg.h" +#include "hu_stuff.h" +#include "am_map.h" +#include "x_hair.h" +#include "player.h" +#include "g_controls.h" +#include "p_saveg.h" +#include "g_common.h" +#include "r_common.h" +#include "m_ctrl.h" +#include +#include +#include +#include +#include +#include +#include + +/// Original game line height for pages that employ the fixed layout (in 320x200 pixels). +#if __JDOOM__ +# define FIXED_LINE_HEIGHT (15+1) +#else +# define FIXED_LINE_HEIGHT (19+1) +#endif + +typedef struct cvarbutton_s { + char active; + char const *cvarname; + char const *yes; + char const *no; + int mask; +} cvarbutton_t; + +int Hu_MenuActionSetActivePage(mn_object_t *ob, mn_actionid_t action, void *parameters); +int Hu_MenuActionInitNewGame(mn_object_t *ob, mn_actionid_t action, void *parameters); + +int Hu_MenuSelectLoadGame(mn_object_t *ob, mn_actionid_t action, void *parameters); +int Hu_MenuSelectSaveGame(mn_object_t *ob, mn_actionid_t action, void *parameters); +#if __JHEXEN__ +int Hu_MenuSelectFiles(mn_object_t *ob, mn_actionid_t action, void *parameters); +#endif +int Hu_MenuSelectPlayerSetup(mn_object_t *ob, mn_actionid_t action, void *parameters); +int Hu_MenuSelectJoinGame(mn_object_t *ob, mn_actionid_t action, void *parameters); + +#if __JDOOM__ || __JHERETIC__ || __JHEXEN__ +int Hu_MenuSelectHelp(mn_object_t *ob, mn_actionid_t action, void *parameters); +#endif +int Hu_MenuSelectControlPanelLink(mn_object_t *ob, mn_actionid_t action, void *parameters); + +int Hu_MenuSelectSingleplayer(mn_object_t *ob, mn_actionid_t action, void *parameters); +int Hu_MenuSelectMultiplayer(mn_object_t *ob, mn_actionid_t action, void *parameters); +#if __JDOOM__ || __JHERETIC__ +int Hu_MenuFocusEpisode(mn_object_t *ob, mn_actionid_t action, void *parameters); +int Hu_MenuActivateNotSharewareEpisode(mn_object_t *ob, mn_actionid_t action, void *parameters); +#endif +#if __JHEXEN__ +int Hu_MenuFocusOnPlayerClass(mn_object_t *ob, mn_actionid_t action, void *parameters); +int Hu_MenuSelectPlayerClass(mn_object_t *ob, mn_actionid_t action, void *parameters); +#endif +int Hu_MenuFocusSkillMode(mn_object_t *ob, mn_actionid_t action, void *parameters); +int Hu_MenuSelectLoadSlot(mn_object_t *ob, mn_actionid_t action, void *parameters); +int Hu_MenuSelectQuitGame(mn_object_t *ob, mn_actionid_t action, void *parameters); +int Hu_MenuSelectEndGame(mn_object_t *ob, mn_actionid_t action, void *parameters); +int Hu_MenuSelectAcceptPlayerSetup(mn_object_t *ob, mn_actionid_t action, void *parameters); + +int Hu_MenuSelectSaveSlot(mn_object_t *ob, mn_actionid_t action, void *parameters); + +int Hu_MenuChangeWeaponPriority(mn_object_t *ob, mn_actionid_t action, void *parameters); +#if __JHEXEN__ +int Hu_MenuSelectPlayerSetupPlayerClass(mn_object_t *ob, mn_actionid_t action, void *parameters); +#endif +int Hu_MenuSelectPlayerColor(mn_object_t *ob, mn_actionid_t action, void *parameters); + +#if __JHEXEN__ +void Hu_MenuPlayerClassBackgroundTicker(mn_object_t *ob); +void Hu_MenuPlayerClassPreviewTicker(mn_object_t *ob); +#endif + +#if __JHERETIC__ || __JHEXEN__ +void Hu_MenuDrawMainPage(mn_page_t *page, Point2Raw const *origin); +#endif + +void Hu_MenuDrawGameTypePage(mn_page_t *page, Point2Raw const *origin); +void Hu_MenuDrawSkillPage(mn_page_t *page, Point2Raw const *origin); +#if __JHEXEN__ +void Hu_MenuDrawPlayerClassPage(mn_page_t *page, Point2Raw const *origin); +#endif +#if __JDOOM__ || __JHERETIC__ +void Hu_MenuDrawEpisodePage(mn_page_t *page, Point2Raw const *origin); +#endif +void Hu_MenuDrawOptionsPage(mn_page_t *page, Point2Raw const *origin); +void Hu_MenuDrawWeaponsPage(mn_page_t *page, Point2Raw const *origin); +void Hu_MenuDrawLoadGamePage(mn_page_t *page, Point2Raw const *origin); +void Hu_MenuDrawSaveGamePage(mn_page_t *page, Point2Raw const *origin); +void Hu_MenuDrawMultiplayerPage(mn_page_t *page, Point2Raw const *origin); +void Hu_MenuDrawPlayerSetupPage(mn_page_t *page, Point2Raw const *origin); + +int Hu_MenuColorWidgetCmdResponder(mn_page_t *page, menucommand_e cmd); + +static void initAllPages(); +static void destroyAllPages(); + +static void initAllObjectsOnAllPages(); +static void updatePageObjects(mn_page_t *page); + +static void Hu_MenuUpdateCursorState(); + +static dd_bool Hu_MenuHasCursorRotation(mn_object_t *obj); + +cvarbutton_t mnCVarButtons[] = { + { 0, "ctl-aim-noauto" }, +#if __JHERETIC__ || __JHEXEN__ + { 0, "ctl-inventory-mode", "Scroll", "Cursor" }, + { 0, "ctl-inventory-use-immediate" }, + { 0, "ctl-inventory-use-next" }, + { 0, "ctl-inventory-wrap" }, +#endif + { 0, "ctl-look-spring" }, + { 0, "ctl-run" }, +#if __JDOOM__ || __JDOOM64__ + { 0, "game-anybossdeath666" }, +#endif +#if __JDOOM__ || __JHERETIC__ || __JDOOM64__ + { 0, "game-corpse-sliding" }, +#endif +#if __JDOOM__ || __JDOOM64__ + { 0, "game-maxskulls" }, +#endif +#if __JDOOM__ || __JHERETIC__ || __JDOOM64__ + { 0, "game-monsters-stuckindoors" }, + { 0, "game-monsters-floatoverblocking" }, + { 0, "game-objects-clipping" }, + { 0, "game-objects-falloff" }, +#endif +#if __JDOOM__ || __JDOOM64__ + { 0, "game-objects-gibcrushednonbleeders" }, +#endif +#if __JDOOM__ || __JHERETIC__ || __JDOOM64__ + { 0, "game-objects-neverhangoverledges" }, + { 0, "game-player-wallrun-northonly" }, +#endif +#if __JDOOM__ + { 0, "game-raiseghosts" }, +#endif + { 0, "game-save-confirm" }, + { 0, "game-save-confirm-loadonreborn" }, +#if !__JHEXEN__ + { 0, "game-save-auto-loadonreborn" }, +#endif + { 0, "game-save-last-loadonreborn" }, +#if __JDOOM__ || __JDOOM64__ + { 0, "game-skullsinwalls" }, +#if __JDOOM__ + { 0, "game-vilechase-usevileradius" }, +#endif + { 0, "game-zombiescanexit" }, +#endif +#if __JDOOM__ || __JDOOM64__ || __JHERETIC__ + { 0, "hud-ammo" }, + { 0, "hud-armor" }, +#endif +#if __JDOOM__ || __JDOOM64__ || __JHERETIC__ + { 0, "hud-cheat-counter-show-mapopen" }, +#endif +#if __JHERETIC__ || __JHEXEN__ + { 0, "hud-currentitem" }, +#endif +#if __JDOOM__ + { 0, "hud-face" }, + { 0, "hud-face-ouchfix" }, +#endif + { 0, "hud-health" }, +#if __JHERETIC__ || __JHEXEN__ + { 0, "hud-inventory-slot-showempty" }, +#endif +#if __JDOOM__ || __JDOOM64__ || __JHERETIC__ + { 0, "hud-keys" }, +#endif +#if __JDOOM__ + { 0, "hud-keys-combine" }, +#endif +#if __JHEXEN__ + { 0, "hud-mana" }, +#endif +#if __JDOOM64__ + { 0, "hud-power" }, +#endif +#if __JDOOM__ || __JDOOM64__ + { 0, "hud-status-weaponslots-ownedfix" }, +#endif + { 0, "hud-unhide-damage" }, + { 0, "hud-unhide-pickup-ammo" }, + { 0, "hud-unhide-pickup-armor" }, + { 0, "hud-unhide-pickup-health" }, +#if __JHERETIC__ || __JHEXEN__ + { 0, "hud-unhide-pickup-invitem" }, +#endif + { 0, "hud-unhide-pickup-powerup" }, + { 0, "hud-unhide-pickup-key" }, + { 0, "hud-unhide-pickup-weapon" }, + { 0, "map-door-colors" }, + { 0, "msg-show" }, +#if __JDOOM__ || __JDOOM64__ + { 0, "player-autoswitch-berserk" }, +#endif + { 0, "player-autoswitch-notfiring" }, +#if __JDOOM__ || __JHERETIC__ || __JDOOM64__ + { 0, "player-jump" }, +#endif + { 0, "player-weapon-cycle-sequential" }, + { 0, "player-weapon-nextmode" }, +#if __JDOOM64__ + { 0, "player-weapon-recoil" }, +#endif +#if __JDOOM__ || __JDOOM64__ + { 0, "server-game-bfg-freeaim" }, +#endif + { 0, "server-game-coop-nodamage" }, +#if __JDOOM__ || __JDOOM64__ + { 0, "server-game-coop-nothing" }, + { 0, "server-game-coop-noweapons" }, + { 0, "server-game-coop-respawn-items" }, +#endif +#if __JHEXEN__ + { 0, "server-game-deathmatch" }, +#endif +#if __JDOOM__ || __JDOOM64__ || __JHERETIC__ + { 0, "server-game-jump" }, +#endif +#if __JDOOM__ || __JDOOM64__ + { 0, "server-game-nobfg" }, +#endif + { 0, "server-game-nomonsters" }, +#if __JDOOM__ || __JDOOM64__ || __JHERETIC__ + { 0, "server-game-noteamdamage" }, +#endif + { 0, "server-game-radiusattack-nomaxz" }, +#if __JHEXEN__ + { 0, "server-game-randclass" }, +#endif +#if __JDOOM__ || __JDOOM64__ || __JHERETIC__ + { 0, "server-game-respawn" }, +#endif + { 0, "view-cross-vitality" }, + { 0, 0 } +}; + +int menuTime; +dd_bool menuNominatingQuickSaveSlot; + +static mn_page_t *menuActivePage; +static dd_bool menuActive; + +static float mnAlpha; // Alpha level for the entire menu. +static float mnTargetAlpha; // Target alpha for the entire UI. + +static skillmode_t mnSkillmode = SM_MEDIUM; +static int mnEpisode; +#if __JHEXEN__ +static int mnPlrClass = PCLASS_FIGHTER; +#endif + +static int frame; // Used by any graphic animations that need to be pumped. + +static dd_bool colorWidgetActive; + +// Present cursor state. +static dd_bool cursorHasRotation; +static float cursorAngle; +static int cursorAnimCounter; +static int cursorAnimFrame; + +#if __JHERETIC__ +static char notDesignedForMessage[80]; +#endif + +static patchid_t pMainTitle; +#if __JDOOM__ || __JDOOM64__ +static patchid_t pNewGame; +static patchid_t pSkill; +static patchid_t pEpisode; +static patchid_t pNGame; +static patchid_t pOptions; +static patchid_t pLoadGame; +static patchid_t pSaveGame; +static patchid_t pReadThis; +static patchid_t pQuitGame; +static patchid_t pOptionsTitle; + +static patchid_t pSkillModeNames[NUM_SKILL_MODES]; +#endif +#if __JDOOM__ +static patchid_t pEpisodeNames[4]; +#endif + +#if __JHEXEN__ +static patchid_t pPlayerClassBG[3]; +static patchid_t pBullWithFire[8]; +#endif + +#if __JHERETIC__ +static patchid_t pRotatingSkull[18]; +#endif + +static patchid_t pCursors[MENU_CURSOR_FRAMECOUNT]; + +#if __JDOOM64__ +mndata_slider_t sld_hud_viewsize = { 3, 11, 0, 1, false, "view-size" }; +#else +mndata_slider_t sld_hud_viewsize = { 3, 13, 0, 1, false, "view-size" }; +#endif +mndata_slider_t sld_hud_uptime = { 0, 60, 0, 1.f, true, "hud-timer", "Disabled", NULL, " second", " seconds" }; +mndata_slider_t sld_hud_xhair_size = { 0, 1, 0, .1f, true, "view-cross-size" }; +mndata_slider_t sld_hud_xhair_angle = { 0, 1, 0, .0625f, true, "view-cross-angle" }; +mndata_slider_t sld_hud_xhair_opacity = { 0, 1, 0, .1f, true, "view-cross-a" }; +mndata_slider_t sld_hud_size = { 0, 1, 0, .1f, true, "hud-scale" }; +mndata_slider_t sld_hud_cntr_size = { 0, 1, 0, .1f, true, "hud-cheat-counter-scale" }; +mndata_slider_t sld_hud_sbar_size = { 0, 1, 0, .1f, true, "hud-status-size" }; +mndata_slider_t sld_hud_sbar_opacity = { 0, 1, 0, .1f, true, "hud-status-alpha" }; +mndata_slider_t sld_hud_msg_size = { 0, 1, 0, .1f, true, "msg-scale" }; +mndata_slider_t sld_hud_msg_uptime = { 0, 60, 0, 1.f, true, "msg-uptime", "Disabled", NULL, " second", " seconds" }; + +mndata_colorbox_t cbox_hud_color = { + 0, 0, 0, 0, 0, 0, true, + "hud-color-r", "hud-color-g", "hud-color-b", "hud-color-a" +}; + +mndata_colorbox_t cbox_hud_msg_color = { + 0, 0, 0, 0, 0, 0, false, + "msg-color-r", "msg-color-g", "msg-color-b" +}; + +mndata_listitem_t listit_hud_xhair_symbols[] = { + { "None", 0 }, + { "Cross", 1 }, + { "Twin Angles", 2 }, + { "Square", 3 }, + { "Open Square", 4 }, + { "Angle", 5 } +}; +mndata_list_t list_hud_xhair_symbol = { + listit_hud_xhair_symbols, NUMLISTITEMS(listit_hud_xhair_symbols), "view-cross-type" +}; + +mndata_colorbox_t cbox_hud_xhair_color = { + 0, 0, 0, 0, 0, 0, false, + "view-cross-r", "view-cross-g", "view-cross-b", +}; + +#if __JDOOM__ || __JDOOM64__ || __JHERETIC__ +mndata_listitem_t listit_hud_killscounter_displaymethods[] = { + { "Hidden", 0 }, + { "Count", CCH_KILLS }, + { "Percent", CCH_KILLS_PRCNT }, + { "Count+Percent", CCH_KILLS | CCH_KILLS_PRCNT }, +}; +mndata_list_t list_hud_cntr_kills = { + listit_hud_killscounter_displaymethods, + NUMLISTITEMS(listit_hud_killscounter_displaymethods), + "hud-cheat-counter", CCH_KILLS | CCH_KILLS_PRCNT +}; + +mndata_listitem_t listit_hud_itemscounter_displaymethods[] = { + { "Hidden", 0 }, + { "Count", CCH_ITEMS }, + { "Percent", CCH_ITEMS_PRCNT }, + { "Count+Percent", CCH_ITEMS | CCH_ITEMS_PRCNT }, +}; +mndata_list_t list_hud_cntr_items = { + listit_hud_itemscounter_displaymethods, + NUMLISTITEMS(listit_hud_itemscounter_displaymethods), + "hud-cheat-counter", CCH_ITEMS | CCH_ITEMS_PRCNT +}; + +mndata_listitem_t listit_hud_secretscounter_displaymethods[] = { + { "Hidden", 0 }, + { "Count", CCH_SECRETS }, + { "Percent", CCH_SECRETS_PRCNT }, + { "Count+Percent", CCH_SECRETS | CCH_SECRETS_PRCNT }, +}; +mndata_list_t list_hud_cntr_secrets = { + listit_hud_secretscounter_displaymethods, + NUMLISTITEMS(listit_hud_secretscounter_displaymethods), + "hud-cheat-counter", CCH_SECRETS | CCH_SECRETS_PRCNT +}; +#endif + +mndata_text_t txt_hud_view_size = { "View Size" }; +#if __JDOOM__ +mndata_text_t txt_hud_single_key_display = { "Single Key Display" }; +#endif +mndata_text_t txt_hud_autohide = { "AutoHide" }; +mndata_text_t txt_hud_unhide_events = { "UnHide Events" }; +mndata_text_t txt_hud_unhide_receive_damage = { "Receive Damage" }; +mndata_text_t txt_hud_unhide_pickup_health = { "Pickup Health" }; +mndata_text_t txt_hud_unhide_pickup_armor = { "Pickup Armor" }; +mndata_text_t txt_hud_unhide_pickup_powerup = { "Pickup Powerup" }; +mndata_text_t txt_hud_unhide_pickup_weapon = { "Pickup Weapon" }; +#if __JHEXEN__ +mndata_text_t txt_hud_unhide_pickup_ammo = { "Pickup Mana" }; +#else +mndata_text_t txt_hud_unhide_pickup_ammo = { "Pickup Ammo" }; +#endif +mndata_text_t txt_hud_unhide_pickup_key = { "Pickup Key" }; +#if __JHERETIC__ || __JHEXEN__ +mndata_text_t txt_hud_unhide_pickup_item = { "Pickup Item" }; +#endif + +mndata_text_t txt_hud_messages = { "Messages" }; +mndata_text_t txt_hud_msg_shown = { "Shown" }; +mndata_text_t txt_hud_msg_size = { "Size" }; +mndata_text_t txt_hud_msg_color = { "Color" }; +mndata_text_t txt_hud_msg_uptime = { "Uptime" }; + +mndata_text_t txt_hud_crosshair = { "Crosshair" }; +mndata_text_t txt_hud_xhair_symbol = { "Symbol" }; +mndata_text_t txt_hud_xhair_size = { "Size" }; +mndata_text_t txt_hud_xhair_angle = { "Angle" }; +mndata_text_t txt_hud_xhair_opacity = { "Opacity" }; +mndata_text_t txt_hud_xhair_vitality_color = { "Vitality Color" }; +mndata_text_t txt_hud_xhair_color = { "Color" }; + +#if __JDOOM__ || __JHERETIC__ || __JHEXEN__ +mndata_text_t txt_hud_statusbar = { "Statusbar" }; +mndata_text_t txt_hud_sbar_size = { "Size" }; +mndata_text_t txt_hud_sbar_opacity = { "Opacity" }; +#endif +#if __JDOOM__ || __JDOOM64__ || __JHERETIC__ +mndata_text_t txt_hud_counters = { "Counters" }; +mndata_text_t txt_hud_cntr_kills = { "Kills" }; +mndata_text_t txt_hud_cntr_items = { "Items" }; +mndata_text_t txt_hud_cntr_secrets = { "Secrets" }; +mndata_text_t txt_hud_cntr_size = { "Size" }; +#endif + +mndata_text_t txt_hud_fullscreen = { "Fullscreen" }; +mndata_text_t txt_hud_full_size = { "Size" }; +mndata_text_t txt_hud_full_text_color = { "Text Color" }; +#if __JHEXEN__ +mndata_text_t txt_hud_full_show_mana = { "Show Mana" }; +#endif +#if __JDOOM__ || __JDOOM64__ || __JHERETIC__ +mndata_text_t txt_hud_full_show_ammo = { "Show Ammo" }; +mndata_text_t txt_hud_full_show_armor = { "Show Armor" }; +#endif +#if __JDOOM64__ +mndata_text_t txt_hud_full_show_powerkeys = { "Show PowerKeys" }; +#endif +#if __JDOOM__ +mndata_text_t txt_hud_full_show_status = { "Show Status" }; +#endif +mndata_text_t txt_hud_full_show_health = { "Show Health" }; +#if __JDOOM__ || __JDOOM64__ || __JHERETIC__ +mndata_text_t txt_hud_full_show_keys = { "Show Keys" }; +#endif +#if __JHERETIC__ || __JHEXEN__ +mndata_text_t txt_hud_full_show_readyitem = { "Show Ready-Item" }; +#endif +#if __JDOOM__ || __JDOOM64__ || __JHERETIC__ +mndata_text_t txt_hud_cntr_mapopen = { "Automap Only" }; +#endif + +mndata_button_t btn_hud_single_key_display = { true, "hud-keys-combine" }; +mndata_button_t btn_hud_unhide_receive_damage = { true, "hud-unhide-damage" }; +mndata_button_t btn_hud_unhide_pickup_health = { true, "hud-unhide-pickup-health" }; +mndata_button_t btn_hud_unhide_pickup_armor = { true, "hud-unhide-pickup-armor" }; +mndata_button_t btn_hud_unhide_pickup_powerup = { true, "hud-unhide-pickup-powerup" }; +mndata_button_t btn_hud_unhide_pickup_weapon = { true, "hud-unhide-pickup-weapon" }; +mndata_button_t btn_hud_unhide_pickup_ammo = { true, "hud-unhide-pickup-ammo" }; +mndata_button_t btn_hud_unhide_pickup_key = { true, "hud-unhide-pickup-key" }; +#if __JHERETIC__ || __JHEXEN__ +mndata_button_t btn_hud_unhide_pickup_item = { true, "hud-unhide-pickup-invitem" }; +#endif +mndata_button_t btn_hud_msg_shown = { true, "msg-show" }; +mndata_button_t btn_hud_xhair_vitality_color = { true, "view-cross-vitality" }; +#if __JHEXEN__ +mndata_button_t btn_hud_full_show_mana = { true, "hud-mana" }; +#endif +#if __JDOOM__ || __JDOOM64__ || __JHERETIC__ +mndata_button_t btn_hud_full_show_ammo = { true, "hud-ammo" }; +mndata_button_t btn_hud_full_show_armor = { true, "hud-armor" }; +#endif +#if __JDOOM64__ +mndata_button_t btn_hud_full_show_powerkeys = { true, "hud-power" }; +#endif +#if __JDOOM__ +mndata_button_t btn_hud_full_show_face = { true, "hud-face" }; +#endif +mndata_button_t btn_hud_full_show_health = { true, "hud-health" }; +#if __JDOOM__ || __JDOOM64__ || __JHERETIC__ +mndata_button_t btn_hud_full_show_keys = { true, "hud-keys" }; +#endif +#if __JHERETIC__ || __JHEXEN__ +mndata_button_t btn_hud_full_show_readyitem = { true, "hud-currentitem" }; +#endif +#if __JDOOM__ || __JDOOM64__ || __JHERETIC__ +mndata_button_t btn_hud_cntr_mapopen = { true, "hud-cheat-counter-show-mapopen" }; +#endif + +static mn_object_t HudMenuObjects[] = { + { MN_TEXT, 0, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_view_size }, + { MN_SLIDER, 0, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR1, MNSlider_Ticker, MNSlider_UpdateGeometry, MNSlider_Drawer, { Hu_MenuCvarSlider, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNSlider_CommandResponder, NULL, NULL, &sld_hud_viewsize }, +#if __JDOOM__ + { MN_TEXT, 0, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_single_key_display }, + { MN_BUTTON, 0, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR3, MNButton_Ticker, MNButton_UpdateGeometry, MNButton_Drawer, { Hu_MenuCvarButton, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNButton_CommandResponder, NULL, NULL, &btn_hud_single_key_display }, +#endif + { MN_TEXT, 0, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_autohide }, + { MN_SLIDER, 0, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR3, MNSlider_Ticker, MNSlider_TextualValueUpdateGeometry, MNSlider_TextualValueDrawer, { Hu_MenuCvarSlider, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNSlider_CommandResponder, NULL, NULL, &sld_hud_uptime }, + + { MN_TEXT, 1, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR2, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_unhide_events }, + { MN_TEXT, 1, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_unhide_receive_damage }, + { MN_BUTTON, 1, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR3, MNButton_Ticker, MNButton_UpdateGeometry, MNButton_Drawer, { Hu_MenuCvarButton, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNButton_CommandResponder, NULL, NULL, &btn_hud_unhide_receive_damage }, + { MN_TEXT, 1, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_unhide_pickup_health }, + { MN_BUTTON, 1, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR3, MNButton_Ticker, MNButton_UpdateGeometry, MNButton_Drawer, { Hu_MenuCvarButton, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNButton_CommandResponder, NULL, NULL, &btn_hud_unhide_pickup_health }, + { MN_TEXT, 1, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_unhide_pickup_armor }, + { MN_BUTTON, 1, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR3, MNButton_Ticker, MNButton_UpdateGeometry, MNButton_Drawer, { Hu_MenuCvarButton, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNButton_CommandResponder, NULL, NULL, &btn_hud_unhide_pickup_armor }, + { MN_TEXT, 1, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_unhide_pickup_powerup }, + { MN_BUTTON, 1, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR3, MNButton_Ticker, MNButton_UpdateGeometry, MNButton_Drawer, { Hu_MenuCvarButton, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNButton_CommandResponder, NULL, NULL, &btn_hud_unhide_pickup_powerup }, + { MN_TEXT, 1, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_unhide_pickup_weapon }, + { MN_BUTTON, 1, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR3, MNButton_Ticker, MNButton_UpdateGeometry, MNButton_Drawer, { Hu_MenuCvarButton, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNButton_CommandResponder, NULL, NULL, &btn_hud_unhide_pickup_weapon }, + { MN_TEXT, 1, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_unhide_pickup_ammo }, + { MN_BUTTON, 1, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR3, MNButton_Ticker, MNButton_UpdateGeometry, MNButton_Drawer, { Hu_MenuCvarButton, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNButton_CommandResponder, NULL, NULL, &btn_hud_unhide_pickup_ammo }, + { MN_TEXT, 1, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_unhide_pickup_key }, + { MN_BUTTON, 1, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR3, MNButton_Ticker, MNButton_UpdateGeometry, MNButton_Drawer, { Hu_MenuCvarButton, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNButton_CommandResponder, NULL, NULL, &btn_hud_unhide_pickup_key }, +#if __JHERETIC__ || __JHEXEN__ + { MN_TEXT, 1, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_unhide_pickup_item }, + { MN_BUTTON, 1, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR3, MNButton_Ticker, MNButton_UpdateGeometry, MNButton_Drawer, { Hu_MenuCvarButton, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNButton_CommandResponder, NULL, NULL, &btn_hud_unhide_pickup_item }, +#endif + + { MN_TEXT, 2, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR2, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_messages }, + { MN_TEXT, 2, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_msg_shown }, + { MN_BUTTON, 2, 0, Point2Raw(), 'm',MENU_FONT1, MENU_COLOR3, MNButton_Ticker, MNButton_UpdateGeometry, MNButton_Drawer, { Hu_MenuCvarButton, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNButton_CommandResponder, NULL, NULL, &btn_hud_msg_shown }, + { MN_TEXT, 2, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_msg_uptime }, + { MN_SLIDER, 2, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR3, MNSlider_Ticker, MNSlider_TextualValueUpdateGeometry, MNSlider_TextualValueDrawer, { Hu_MenuCvarSlider, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNSlider_CommandResponder, NULL, NULL, &sld_hud_msg_uptime }, + { MN_TEXT, 2, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_msg_size }, + { MN_SLIDER, 2, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR1, MNSlider_Ticker, MNSlider_UpdateGeometry, MNSlider_Drawer, { Hu_MenuCvarSlider, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNSlider_CommandResponder, NULL, NULL, &sld_hud_msg_size }, + { MN_TEXT, 2, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_msg_color }, + { MN_COLORBOX, 2, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR1, MNColorBox_Ticker, MNColorBox_UpdateGeometry, MNColorBox_Drawer, { Hu_MenuCvarColorBox, Hu_MenuCvarColorBox, Hu_MenuActivateColorWidget, NULL, NULL, Hu_MenuDefaultFocusAction }, MNColorBox_CommandResponder, NULL, NULL, &cbox_hud_msg_color }, + + { MN_TEXT, 3, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR2, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_crosshair }, + { MN_TEXT, 3, 0, Point2Raw(), 'c',MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_xhair_symbol }, + { MN_LISTINLINE, 3, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR3, MNListInline_Ticker, MNListInline_UpdateGeometry, MNListInline_Drawer, { Hu_MenuCvarList, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNListInline_CommandResponder, NULL, NULL, &list_hud_xhair_symbol }, + { MN_TEXT, 3, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_xhair_size }, + { MN_SLIDER, 3, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR1, MNSlider_Ticker, MNSlider_UpdateGeometry, MNSlider_Drawer, { Hu_MenuCvarSlider, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNSlider_CommandResponder, NULL, NULL, &sld_hud_xhair_size }, + { MN_TEXT, 3, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_xhair_angle }, + { MN_SLIDER, 3, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR1, MNSlider_Ticker, MNSlider_UpdateGeometry, MNSlider_Drawer, { Hu_MenuCvarSlider, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNSlider_CommandResponder, NULL, NULL, &sld_hud_xhair_angle }, + { MN_TEXT, 3, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_xhair_opacity }, + { MN_SLIDER, 3, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR1, MNSlider_Ticker, MNSlider_UpdateGeometry, MNSlider_Drawer, { Hu_MenuCvarSlider, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNSlider_CommandResponder, NULL, NULL, &sld_hud_xhair_opacity }, + { MN_TEXT, 3, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_xhair_vitality_color }, + { MN_BUTTON, 3, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR3, MNButton_Ticker, MNButton_UpdateGeometry, MNButton_Drawer, { Hu_MenuCvarButton, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNButton_CommandResponder, NULL, NULL, &btn_hud_xhair_vitality_color }, + { MN_TEXT, 3, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_xhair_color }, + { MN_COLORBOX, 3, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR1, MNColorBox_Ticker, MNColorBox_UpdateGeometry, MNColorBox_Drawer, { Hu_MenuCvarColorBox, Hu_MenuCvarColorBox, Hu_MenuActivateColorWidget, NULL, NULL, Hu_MenuDefaultFocusAction }, MNColorBox_CommandResponder, NULL, NULL, &cbox_hud_xhair_color }, + +#if __JDOOM__ || __JHERETIC__ || __JHEXEN__ + { MN_TEXT, 4, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR2, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_statusbar }, + { MN_TEXT, 4, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_sbar_size }, + { MN_SLIDER, 4, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR1, MNSlider_Ticker, MNSlider_UpdateGeometry, MNSlider_Drawer, { Hu_MenuCvarSlider, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNSlider_CommandResponder, NULL, NULL, &sld_hud_sbar_size }, + { MN_TEXT, 4, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_sbar_opacity }, + { MN_SLIDER, 4, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR1, MNSlider_Ticker, MNSlider_UpdateGeometry, MNSlider_Drawer, { Hu_MenuCvarSlider, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNSlider_CommandResponder, NULL, NULL, &sld_hud_sbar_opacity }, +#endif +#if __JDOOM__ || __JDOOM64__ || __JHERETIC__ + { MN_TEXT, 5, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR2, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_counters }, + { MN_TEXT, 5, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_cntr_items }, + { MN_LISTINLINE, 5, 0, Point2Raw(), 'i',MENU_FONT1, MENU_COLOR3, MNListInline_Ticker, MNListInline_UpdateGeometry, MNListInline_Drawer, { Hu_MenuCvarList, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNListInline_CommandResponder, NULL, NULL, &list_hud_cntr_items }, + { MN_TEXT, 5, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_cntr_kills }, + { MN_LISTINLINE, 5, 0, Point2Raw(), 'k',MENU_FONT1, MENU_COLOR3, MNListInline_Ticker, MNListInline_UpdateGeometry, MNListInline_Drawer, { Hu_MenuCvarList, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNListInline_CommandResponder, NULL, NULL, &list_hud_cntr_kills }, + { MN_TEXT, 5, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_cntr_secrets }, + { MN_LISTINLINE, 5, 0, Point2Raw(), 's',MENU_FONT1, MENU_COLOR3, MNListInline_Ticker, MNListInline_UpdateGeometry, MNListInline_Drawer, { Hu_MenuCvarList, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNListInline_CommandResponder, NULL, NULL, &list_hud_cntr_secrets }, + { MN_TEXT, 5, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_cntr_mapopen }, + { MN_BUTTON, 5, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR3, MNButton_Ticker, MNButton_UpdateGeometry, MNButton_Drawer, { Hu_MenuCvarButton, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNButton_CommandResponder, NULL, NULL, &btn_hud_cntr_mapopen }, + { MN_TEXT, 5, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_cntr_size }, + { MN_SLIDER, 5, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR1, MNSlider_Ticker, MNSlider_UpdateGeometry, MNSlider_Drawer, { Hu_MenuCvarSlider, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNSlider_CommandResponder, NULL, NULL, &sld_hud_cntr_size }, +#endif + + { MN_TEXT, 6, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR2, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_fullscreen }, + { MN_TEXT, 6, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_full_size }, + { MN_SLIDER, 6, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR1, MNSlider_Ticker, MNSlider_UpdateGeometry, MNSlider_Drawer, { Hu_MenuCvarSlider, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNSlider_CommandResponder, NULL, NULL, &sld_hud_size }, + { MN_TEXT, 6, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_full_text_color }, + { MN_COLORBOX, 6, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR1, MNColorBox_Ticker, MNColorBox_UpdateGeometry, MNColorBox_Drawer, { Hu_MenuCvarColorBox, Hu_MenuCvarColorBox, Hu_MenuActivateColorWidget, NULL, NULL, Hu_MenuDefaultFocusAction }, MNColorBox_CommandResponder, NULL, NULL, &cbox_hud_color }, +#if __JHEXEN__ + { MN_TEXT, 6, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_full_show_mana }, + { MN_BUTTON, 6, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR3, MNButton_Ticker, MNButton_UpdateGeometry, MNButton_Drawer, { Hu_MenuCvarButton, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNButton_CommandResponder, NULL, NULL, &btn_hud_full_show_mana }, +#endif +#if __JDOOM__ || __JDOOM64__ || __JHERETIC__ + { MN_TEXT, 6, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_full_show_ammo }, + { MN_BUTTON, 6, 0, Point2Raw(), 'a',MENU_FONT1, MENU_COLOR3, MNButton_Ticker, MNButton_UpdateGeometry, MNButton_Drawer, { Hu_MenuCvarButton, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNButton_CommandResponder, NULL, NULL, &btn_hud_full_show_ammo }, + { MN_TEXT, 6, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_full_show_armor }, + { MN_BUTTON, 6, 0, Point2Raw(), 'r',MENU_FONT1, MENU_COLOR3, MNButton_Ticker, MNButton_UpdateGeometry, MNButton_Drawer, { Hu_MenuCvarButton, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNButton_CommandResponder, NULL, NULL, &btn_hud_full_show_armor }, +#endif +#if __JDOOM64__ + { MN_TEXT, 6, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_full_show_powerkeys }, + { MN_BUTTON, 6, 0, Point2Raw(), 'p',MENU_FONT1, MENU_COLOR3, MNButton_Ticker, MNButton_UpdateGeometry, MNButton_Drawer, { Hu_MenuCvarButton, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNButton_CommandResponder, NULL, NULL, &btn_hud_full_show_powerkeys }, +#endif +#if __JDOOM__ + { MN_TEXT, 6, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_full_show_status }, + { MN_BUTTON, 6, 0, Point2Raw(), 'f',MENU_FONT1, MENU_COLOR3, MNButton_Ticker, MNButton_UpdateGeometry, MNButton_Drawer, { Hu_MenuCvarButton, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNButton_CommandResponder, NULL, NULL, &btn_hud_full_show_face }, +#endif + { MN_TEXT, 6, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_full_show_health }, + { MN_BUTTON, 6, 0, Point2Raw(), 'h',MENU_FONT1, MENU_COLOR3, MNButton_Ticker, MNButton_UpdateGeometry, MNButton_Drawer, { Hu_MenuCvarButton, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNButton_CommandResponder, NULL, NULL, &btn_hud_full_show_health }, +#if __JDOOM__ || __JDOOM64__ || __JHERETIC__ + { MN_TEXT, 6, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_full_show_keys }, + { MN_BUTTON, 6, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR3, MNButton_Ticker, MNButton_UpdateGeometry, MNButton_Drawer, { Hu_MenuCvarButton, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNButton_CommandResponder, NULL, NULL, &btn_hud_full_show_keys }, +#endif +#if __JHERETIC__ || __JHEXEN__ + { MN_TEXT, 6, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR1, MNText_Ticker, MNText_UpdateGeometry, MNText_Drawer, { NULL }, NULL, NULL, NULL, &txt_hud_full_show_readyitem }, + { MN_BUTTON, 6, 0, Point2Raw(), 0, MENU_FONT1, MENU_COLOR3, MNButton_Ticker, MNButton_UpdateGeometry, MNButton_Drawer, { Hu_MenuCvarButton, NULL, NULL, NULL, NULL, Hu_MenuDefaultFocusAction }, MNButton_CommandResponder, NULL, NULL, &btn_hud_full_show_readyitem }, +#endif + { MN_NONE } +}; + +static dd_bool inited; + +struct pagerecord_t +{ + mn_page_t *page; + ddstring_t name; // Symbolic name. +}; + +static int pageCount; +static pagerecord_t *pages; + +// Cvars for the menu: +cvartemplate_t menuCVars[] = { + { "menu-scale", 0, CVT_FLOAT, &cfg.menuScale, .1f, 1 }, + { "menu-stretch", 0, CVT_BYTE, &cfg.menuScaleMode, SCALEMODE_FIRST, SCALEMODE_LAST }, + { "menu-flash-r", 0, CVT_FLOAT, &cfg.menuTextFlashColor[CR], 0, 1 }, + { "menu-flash-g", 0, CVT_FLOAT, &cfg.menuTextFlashColor[CG], 0, 1 }, + { "menu-flash-b", 0, CVT_FLOAT, &cfg.menuTextFlashColor[CB], 0, 1 }, + { "menu-flash-speed", 0, CVT_INT, &cfg.menuTextFlashSpeed, 0, 50 }, + { "menu-cursor-rotate", 0, CVT_BYTE, &cfg.menuCursorRotate, 0, 1 }, + { "menu-effect", 0, CVT_INT, &cfg.menuEffectFlags, 0, MEF_EVERYTHING }, + { "menu-color-r", 0, CVT_FLOAT, &cfg.menuTextColors[0][CR], 0, 1 }, + { "menu-color-g", 0, CVT_FLOAT, &cfg.menuTextColors[0][CG], 0, 1 }, + { "menu-color-b", 0, CVT_FLOAT, &cfg.menuTextColors[0][CB], 0, 1 }, + { "menu-colorb-r", 0, CVT_FLOAT, &cfg.menuTextColors[1][CR], 0, 1 }, + { "menu-colorb-g", 0, CVT_FLOAT, &cfg.menuTextColors[1][CG], 0, 1 }, + { "menu-colorb-b", 0, CVT_FLOAT, &cfg.menuTextColors[1][CB], 0, 1 }, + { "menu-colorc-r", 0, CVT_FLOAT, &cfg.menuTextColors[2][CR], 0, 1 }, + { "menu-colorc-g", 0, CVT_FLOAT, &cfg.menuTextColors[2][CG], 0, 1 }, + { "menu-colorc-b", 0, CVT_FLOAT, &cfg.menuTextColors[2][CB], 0, 1 }, + { "menu-colord-r", 0, CVT_FLOAT, &cfg.menuTextColors[3][CR], 0, 1 }, + { "menu-colord-g", 0, CVT_FLOAT, &cfg.menuTextColors[3][CG], 0, 1 }, + { "menu-colord-b", 0, CVT_FLOAT, &cfg.menuTextColors[3][CB], 0, 1 }, + { "menu-glitter", 0, CVT_FLOAT, &cfg.menuTextGlitter, 0, 1 }, + { "menu-fog", 0, CVT_INT, &cfg.hudFog, 0, 5 }, + { "menu-shadow", 0, CVT_FLOAT, &cfg.menuShadow, 0, 1 }, + { "menu-patch-replacement", 0, CVT_INT, &cfg.menuPatchReplaceMode, PRM_FIRST, PRM_LAST }, + { "menu-slam", 0, CVT_BYTE, &cfg.menuSlam, 0, 1 }, + { "menu-hotkeys", 0, CVT_BYTE, &cfg.menuShortcutsEnabled, 0, 1 }, +#if __JDOOM__ || __JDOOM64__ + { "menu-quitsound", 0, CVT_INT, &cfg.menuQuitSound, 0, 1 }, +#endif + { "menu-save-suggestname", 0, CVT_BYTE, &cfg.menuGameSaveSuggestName, 0, 1 }, + + // Aliases for obsolete cvars: + { "menu-turningskull", 0, CVT_BYTE, &cfg.menuCursorRotate, 0, 1 }, + { NULL } +}; + +// Console commands for the menu: +ccmdtemplate_t menuCCmds[] = { + { "menu", "s", CCmdMenuOpen }, + { "menu", "", CCmdMenuOpen }, + { "menuup", "", CCmdMenuCommand }, + { "menudown", "", CCmdMenuCommand }, + { "menupageup", "", CCmdMenuCommand }, + { "menupagedown", "", CCmdMenuCommand }, + { "menuleft", "", CCmdMenuCommand }, + { "menuright", "", CCmdMenuCommand }, + { "menuselect", "", CCmdMenuCommand }, + { "menudelete", "", CCmdMenuCommand }, + { "menuback", "", CCmdMenuCommand }, + { NULL } +}; + +void Hu_MenuRegister() +{ + int i; + for(i = 0; menuCVars[i].path; ++i) + Con_AddVariable(menuCVars + i); + for(i = 0; menuCCmds[i].name; ++i) + Con_AddCommand(menuCCmds + i); +} + +static menucommand_e chooseCloseMethod() +{ + // If we aren't using a transition then we can close normally and allow our + // own menu fade-out animation to be used instead. + return Con_GetInteger("con-transition-tics") == 0? MCMD_CLOSE : MCMD_CLOSEFAST; +} + +mn_page_t* Hu_MenuFindPageByName(const char* name) +{ + if(name && name[0]) + { + int i; + for(i = 0; i < pageCount; ++i) + { + pagerecord_t* rec = pages + i; + if(!stricmp(name, Str_Text(&rec->name))) + { + return rec->page; + } + } + } + return NULL; +} + +/// @todo Make this state an object property flag. +/// @return @c true if the rotation of a cursor on this object should be animated. +static dd_bool Hu_MenuHasCursorRotation(mn_object_t *obj) +{ + assert(obj); + return (!(MNObject_Flags(obj) & MNF_DISABLED) && + (MNObject_Type(obj) == MN_LISTINLINE || MNObject_Type(obj) == MN_SLIDER)); +} + +/// To be called to re-evaluate the state of the cursor (e.g., when focus changes). +static void Hu_MenuUpdateCursorState() +{ + if(menuActive) + { + mn_page_t *page; + mn_object_t *obj; + + if(colorWidgetActive) + page = Hu_MenuFindPageByName("ColorWidget"); + else + page = Hu_MenuActivePage(); + + obj = MNPage_FocusObject(page); + if(obj) + { + cursorHasRotation = Hu_MenuHasCursorRotation(obj); + return; + } + } + cursorHasRotation = false; +} + +void Hu_MenuLoadResources() +{ + char buffer[9]; + int i; + +#if __JDOOM__ || __JDOOM64__ + pMainTitle = R_DeclarePatch("M_DOOM"); +#elif __JHERETIC__ || __JHEXEN__ + pMainTitle = R_DeclarePatch("M_HTIC"); +#endif + +#if __JDOOM__ || __JDOOM64__ + pNewGame = R_DeclarePatch("M_NEWG"); + pSkill = R_DeclarePatch("M_SKILL"); + pEpisode = R_DeclarePatch("M_EPISOD"); + pNGame = R_DeclarePatch("M_NGAME"); + pOptions = R_DeclarePatch("M_OPTION"); + pLoadGame = R_DeclarePatch("M_LOADG"); + pSaveGame = R_DeclarePatch("M_SAVEG"); + pReadThis = R_DeclarePatch("M_RDTHIS"); + pQuitGame = R_DeclarePatch("M_QUITG"); + pOptionsTitle = R_DeclarePatch("M_OPTTTL"); +#endif + +#if __JDOOM__ || __JDOOM64__ + pSkillModeNames[SM_BABY] = R_DeclarePatch("M_JKILL"); + pSkillModeNames[SM_EASY] = R_DeclarePatch("M_ROUGH"); + pSkillModeNames[SM_MEDIUM] = R_DeclarePatch("M_HURT"); + pSkillModeNames[SM_HARD] = R_DeclarePatch("M_ULTRA"); +# if __JDOOM__ + pSkillModeNames[SM_NIGHTMARE] = R_DeclarePatch("M_NMARE"); +# endif +#endif + +#if __JDOOM__ + if(gameModeBits & (GM_DOOM_SHAREWARE|GM_DOOM|GM_DOOM_ULTIMATE)) + { + pEpisodeNames[0] = R_DeclarePatch("M_EPI1"); + pEpisodeNames[1] = R_DeclarePatch("M_EPI2"); + pEpisodeNames[2] = R_DeclarePatch("M_EPI3"); + } + if(gameModeBits & GM_DOOM_ULTIMATE) + { + pEpisodeNames[3] = R_DeclarePatch("M_EPI4"); + } +#endif + +#if __JHERETIC__ + for(i = 0; i < 18; ++i) + { + dd_snprintf(buffer, 9, "M_SKL%02d", i); + pRotatingSkull[i] = R_DeclarePatch(buffer); + } +#endif + +#if __JHEXEN__ + for(i = 0; i < 7; ++i) + { + dd_snprintf(buffer, 9, "FBUL%c0", 'A'+i); + pBullWithFire[i] = R_DeclarePatch(buffer); + } + + pPlayerClassBG[0] = R_DeclarePatch("M_FBOX"); + pPlayerClassBG[1] = R_DeclarePatch("M_CBOX"); + pPlayerClassBG[2] = R_DeclarePatch("M_MBOX"); +#endif + + for(i = 0; i < MENU_CURSOR_FRAMECOUNT; ++i) + { +#if __JDOOM__ || __JDOOM64__ + dd_snprintf(buffer, 9, "M_SKULL%d", i+1); +#else + dd_snprintf(buffer, 9, "M_SLCTR%d", i+1); +#endif + pCursors[i] = R_DeclarePatch(buffer); + } +} + +void Hu_MenuInitColorWidgetPage() +{ +#if __JHERETIC__ || __JHEXEN__ + Point2Raw const origin(98, 60); +#else + Point2Raw const origin(124, 60); +#endif + uint const numObjects = 10; + + mn_page_t *page = Hu_MenuNewPage("ColorWidget", &origin, MPF_NEVER_SCROLL, Hu_MenuPageTicker, NULL, Hu_MenuColorWidgetCmdResponder, NULL); + MNPage_SetPredefinedFont(page, MENU_FONT1, FID(GF_FONTA)); + + mn_object_t *objects = (mn_object_t *)Z_Calloc(sizeof(*objects) * numObjects, PU_GAMESTATIC, 0); + mn_object_t *ob = objects; + + ob->_type = MN_COLORBOX; + ob->_flags = MNF_ID0 | MNF_NO_FOCUS; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNColorBox_Ticker; + ob->updateGeometry = MNColorBox_UpdateGeometry; + ob->drawer = MNColorBox_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_colorbox_t), PU_GAMESTATIC, 0); + { + mndata_colorbox_t *cbox = (mndata_colorbox_t *)ob->_typedata; + cbox->width = SCREENHEIGHT / 7; + cbox->height = SCREENHEIGHT / 7; + cbox->rgbaMode = true; + } + ob++; + + ob->_type = MN_TEXT; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Red"; + } + ob++; + + ob->_type = MN_SLIDER; + ob->_flags = MNF_ID1; + ob->_shortcut = 'r'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNSlider_Ticker; + ob->updateGeometry = MNSlider_UpdateGeometry; + ob->drawer = MNSlider_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuUpdateColorWidgetColor; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNSlider_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_slider_t), PU_GAMESTATIC, 0); + ob->data2 = CR; + { + mndata_slider_t *sld = (mndata_slider_t *)ob->_typedata; + sld->min = 0; + sld->max = 1; + sld->value = 0; + sld->step = .05f; + sld->floatMode = true; + } + ob++; + + ob->_type = MN_TEXT; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Green"; + } + ob++; + + ob->_type = MN_SLIDER; + ob->_flags = MNF_ID2; + ob->_shortcut = 'g'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNSlider_Ticker; + ob->updateGeometry = MNSlider_UpdateGeometry; + ob->drawer = MNSlider_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuUpdateColorWidgetColor; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNSlider_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_slider_t), PU_GAMESTATIC, 0); + ob->data2 = CG; + { + mndata_slider_t *sld = (mndata_slider_t *)ob->_typedata; + sld->min = 0; + sld->max = 1; + sld->value = 0; + sld->step = .05f; + sld->floatMode = true; + } + ob++; + + ob->_type = MN_TEXT; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Blue"; + } + ob++; + + ob->_type = MN_SLIDER; + ob->_flags = MNF_ID3; + ob->_shortcut = 'b'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNSlider_Ticker; + ob->updateGeometry = MNSlider_UpdateGeometry; + ob->drawer = MNSlider_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuUpdateColorWidgetColor; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNSlider_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_slider_t), PU_GAMESTATIC, 0); + ob->data2 = CB; + { + mndata_slider_t *sld = (mndata_slider_t *)ob->_typedata; + sld->min = 0; + sld->max = 1; + sld->value = 0; + sld->step = .05f; + sld->floatMode = true; + } + ob++; + + ob->_type = MN_TEXT; + ob->_flags = MNF_ID4; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Opacity"; + } + ob++; + + ob->_type = MN_SLIDER; + ob->_flags = MNF_ID5; + ob->_shortcut = 'o'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNSlider_Ticker; + ob->updateGeometry = MNSlider_UpdateGeometry; + ob->drawer = MNSlider_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuUpdateColorWidgetColor; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNSlider_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_slider_t), PU_GAMESTATIC, 0); + ob->data2 = CA; + { + mndata_slider_t *sld = (mndata_slider_t *)ob->_typedata; + sld->min = 0; + sld->max = 1; + sld->value = 0; + sld->step = .05f; + sld->floatMode = true; + } + ob++; + + ob->_type = MN_NONE; + + page->objects = objects; +} + +void Hu_MenuInitMainPage() +{ +#if __JHEXEN__ || __JHERETIC__ + Point2Raw origin(110, 56); + uint numObjects = 6; +#else + Point2Raw origin(97, 64); +# if __JDOOM64__ + uint numObjects = 7; +# else + uint numObjects = 8; +# endif +#endif + +#if __JDOOM__ + if(gameModeBits & GM_ANY_DOOM2) + { + origin.y += 8; + } +#endif + +#if __JDOOM__ || __JDOOM64__ + mn_page_t *page = Hu_MenuNewPage("Main", &origin, MPF_LAYOUT_FIXED|MPF_NEVER_SCROLL, Hu_MenuPageTicker, NULL, NULL, NULL); +#else + mn_page_t *page = Hu_MenuNewPage("Main", &origin, MPF_LAYOUT_FIXED|MPF_NEVER_SCROLL, Hu_MenuPageTicker, Hu_MenuDrawMainPage, NULL, NULL); +#endif + MNPage_SetPredefinedFont(page, MENU_FONT1, FID(GF_FONTB)); + + mn_object_t *objects = (mn_object_t *)Z_Calloc(sizeof(*objects) * numObjects, PU_GAMESTATIC, 0); + mn_object_t *ob = objects; + + int y = 0; + +#if __JDOOM__ || __JDOOM64__ + ob->_type = MN_TEXT; + ob->_origin.x = -3; + ob->_origin.y = -70; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->patch = &pMainTitle; + } + ob++; +#endif + + ob->_type = MN_BUTTON; + ob->_origin.y = y; + ob->_shortcut = 'n'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuActionSetActivePage; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->data1 = "GameType"; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; +#if defined(__JDOOM__) && !defined(__JDOOM64__) + btn->patch = &pNGame; +#else + btn->text = "New Game"; +#endif + } + ob++; y += FIXED_LINE_HEIGHT; + + ob->_type = MN_BUTTON; + ob->_origin.y = y; + ob->_shortcut = 'o'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuActionSetActivePage; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->data1 = "Options"; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; +#if defined(__JDOOM__) && !defined(__JDOOM64__) + btn->patch = &pOptions; +#else + btn->text = "Options"; +#endif + } + ob++; y += FIXED_LINE_HEIGHT; + +#if __JDOOM__ || __JDOOM64__ + ob->_type = MN_BUTTON; + ob->_origin.y = y; + ob->_shortcut = 'l'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuSelectLoadGame; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; +# if __JDOOM64__ + btn->text = "Load Game"; +# else + btn->patch = &pLoadGame; +# endif + } + ob++; y += FIXED_LINE_HEIGHT; + + ob->_type = MN_BUTTON; + ob->_origin.y = y; + ob->_shortcut = 's'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuSelectSaveGame; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; +# if __JDOOM64__ + btn->text = "Save Game"; +# else + btn->patch = &pSaveGame; +# endif + } + ob++; y += FIXED_LINE_HEIGHT; + +#else + ob->_type = MN_BUTTON; + ob->_origin.y = y; + ob->_shortcut = 'f'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuActionSetActivePage; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->data1 = "Files"; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->text = "Game Files"; + } + ob++; y += FIXED_LINE_HEIGHT; +#endif + +#if !__JDOOM64__ + ob->_type = MN_BUTTON; + ob->_origin.y = y; +# if __JDOOM__ + ob->_flags = MNF_ID0; + ob->_shortcut = 'r'; +# else + ob->_shortcut = 'i'; +# endif + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuSelectHelp; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; +# if defined(__JDOOM__) + btn->patch = &pReadThis; +# else + btn->text = "Info"; +# endif + } + ob++; y += FIXED_LINE_HEIGHT; +#endif + + ob->_type = MN_BUTTON; +#if __JDOOM__ + ob->_flags = MNF_ID1; +#endif + ob->_origin.y = y; + ob->_shortcut = 'q'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuSelectQuitGame; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; +#if defined(__JDOOM__) && !defined(__JDOOM64__) + btn->patch = &pQuitGame; +#else + btn->text = "Quit Game"; +#endif + } + ob++; y += FIXED_LINE_HEIGHT; + + ob->_type = MN_NONE; + + page->objects = objects; +} + +void Hu_MenuInitGameTypePage() +{ +#if __JDOOM__ || __JDOOM64__ + Point2Raw origin(97, 65); +#else + Point2Raw origin(104, 65); +#endif + uint const numObjects = 3; + + mn_page_t *page = Hu_MenuNewPage("GameType", &origin, 0, Hu_MenuPageTicker, Hu_MenuDrawGameTypePage, NULL, NULL); + MNPage_SetPredefinedFont(page, MENU_FONT1, FID(GF_FONTB)); + MNPage_SetPreviousPage(page, Hu_MenuFindPageByName("Main")); + + mn_object_t *objects = (mn_object_t *)Z_Calloc(sizeof(*objects) * numObjects, PU_GAMESTATIC, 0); + mn_object_t *ob = objects; + + int y = 0; + + ob->_type = MN_BUTTON; + ob->_origin.y = y; + ob->_shortcut = 's'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuSelectSingleplayer; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->text = (char const *)TXT_SINGLEPLAYER; + } + ob++; y += FIXED_LINE_HEIGHT; + + ob->_type = MN_BUTTON; + ob->_origin.y = y; + ob->_shortcut = 'm'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuSelectMultiplayer; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->text = (char const *)TXT_MULTIPLAYER; + } + ob++; y += FIXED_LINE_HEIGHT; + + ob->_type = MN_NONE; + + page->objects = objects; +} + +void Hu_MenuInitSkillPage() +{ +#if __JHEXEN__ + Point2Raw const origin(120, 44); +#elif __JHERETIC__ + Point2Raw const origin(38, 30); +#else + Point2Raw const origin(48, 63); +#endif + int skillButtonFlags[NUM_SKILL_MODES] = { + MNF_ID0, + MNF_ID1, + MNF_ID2 | MNF_DEFAULT, + MNF_ID3, +# if !__JDOOM64__ + MNF_ID4 +# endif + }; +#if !__JHEXEN__ + int skillButtonTexts[NUM_SKILL_MODES] = { + TXT_SKILL1, + TXT_SKILL2, + TXT_SKILL3, + TXT_SKILL4, +# if !__JDOOM64__ + TXT_SKILL5 +# endif + }; +#endif + uint const numObjects = NUM_SKILL_MODES + 1; + + mn_page_t *page = Hu_MenuNewPage("Skill", &origin, MPF_LAYOUT_FIXED|MPF_NEVER_SCROLL, Hu_MenuPageTicker, Hu_MenuDrawSkillPage, NULL, NULL); + MNPage_SetPredefinedFont(page, MENU_FONT1, FID(GF_FONTB)); +#if __JHEXEN__ + MNPage_SetPreviousPage(page, Hu_MenuFindPageByName("PlayerClass")); +#elif __JHERETIC__ + MNPage_SetPreviousPage(page, Hu_MenuFindPageByName("Episode")); +#elif __JDOOM64__ + MNPage_SetPreviousPage(page, Hu_MenuFindPageByName("GameType")); +#else // __JDOOM__ + if(gameModeBits & (GM_ANY_DOOM2|GM_DOOM_CHEX)) + { + MNPage_SetPreviousPage(page, Hu_MenuFindPageByName("GameType")); + } + else + { + MNPage_SetPreviousPage(page, Hu_MenuFindPageByName("Episode")); + } +#endif + + mn_object_t *objects = (mn_object_t *)Z_Calloc(sizeof(*objects) * numObjects, PU_GAMESTATIC, 0); + mn_object_t *ob = objects; + + int y = 0; + + for(uint i = 0; i < NUM_SKILL_MODES; ++i, ob++, y += FIXED_LINE_HEIGHT) + { + ob->_type = MN_BUTTON; + ob->_flags = skillButtonFlags[i]; +#if !__JHEXEN__ + ob->_shortcut = GET_TXT(skillButtonTexts[i])[0]; +#endif + ob->_origin.y = y; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuActionInitNewGame; + ob->actions[MNA_FOCUS ].callback = Hu_MenuFocusSkillMode; + ob->cmdResponder = MNButton_CommandResponder; + ob->data2 = (int)(SM_BABY + i); + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); +#if !__JHEXEN__ + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->text = INT2PTR(const char, skillButtonTexts[i]); +# if __JDOOM__ || __JDOOM64__ + btn->patch = &pSkillModeNames[i]; +# endif + } +#endif + } + + ob->_type = MN_NONE; + + page->objects = objects; + +#if __JDOOM__ + if(gameMode != doom2_hacx && gameMode != doom_chex) + { + mn_object_t *ob = MN_MustFindObjectOnPage(page, 0, MNF_ID4); + MNButton_SetFlags(ob, FO_SET, MNBUTTON_NO_ALTTEXT); + } +#endif +} + +void Hu_MenuInitMultiplayerPage() +{ +#if __JHERETIC__ || __JHEXEN__ + Point2Raw const origin(97, 65); +#else + Point2Raw const origin(97, 65); +#endif + uint const numObjects = 3; + + mn_page_t *page = Hu_MenuNewPage("Multiplayer", &origin, 0, Hu_MenuPageTicker, Hu_MenuDrawMultiplayerPage, NULL, NULL); + MNPage_SetPredefinedFont(page, MENU_FONT1, FID(GF_FONTB)); + MNPage_SetPreviousPage(page, Hu_MenuFindPageByName("GameType")); + + mn_object_t *objects = (mn_object_t *)Z_Calloc(sizeof(*objects) * numObjects, PU_GAMESTATIC, 0); + mn_object_t *ob = objects; + + ob->_type = MN_BUTTON; + ob->_flags = MNF_ID0; + ob->_shortcut = 'j'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuSelectJoinGame; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->text = "Join Game"; + } + ob++; + + ob->_type = MN_BUTTON; + ob->_shortcut = 's'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuSelectPlayerSetup; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->text = "Player Setup"; + } + ob++; + + ob->_type = MN_NONE; + + page->objects = objects; +} + +void Hu_MenuInitPlayerSetupPage() +{ +#if __JHERETIC__ || __JHEXEN__ + Point2Raw const origin(70, 44); +#else + Point2Raw const origin(70, 54); +#endif +#if __JHEXEN__ + uint numObjects = 8; +#else + uint numObjects = 6; +#endif + + mn_page_t *page = Hu_MenuNewPage("PlayerSetup", &origin, 0, Hu_MenuPageTicker, Hu_MenuDrawPlayerSetupPage, NULL, NULL); + MNPage_SetPredefinedFont(page, MENU_FONT1, FID(GF_FONTA)); + MNPage_SetPredefinedFont(page, MENU_FONT2, FID(GF_FONTB)); + MNPage_SetPreviousPage(page, Hu_MenuFindPageByName("Multiplayer")); + + mn_object_t *objects = (mn_object_t *)Z_Calloc(sizeof(*objects) * numObjects, PU_GAMESTATIC, 0); + mn_object_t *ob = objects; + + ob->_type = MN_MOBJPREVIEW; + ob->_origin.x = SCREENWIDTH/2 - origin.x; + ob->_origin.y = 60; + ob->_flags = MNF_ID0 | MNF_POSITION_FIXED; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNMobjPreview_Ticker; + ob->updateGeometry = MNMobjPreview_UpdateGeometry; + ob->drawer = MNMobjPreview_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_mobjpreview_t), PU_GAMESTATIC, 0); + ob++; + + ob->_type = MN_EDIT; + ob->_flags = MNF_ID1 | MNF_LAYOUT_OFFSET; + ob->_origin.y = 75; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNEdit_Ticker; + ob->updateGeometry = MNEdit_UpdateGeometry; + ob->drawer = MNEdit_Drawer; + ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNEdit_CommandResponder; + ob->responder = MNEdit_Responder; + ob->_typedata = Z_Calloc(sizeof(mndata_edit_t), PU_GAMESTATIC, 0); + { + mndata_edit_t *edit = (mndata_edit_t *)ob->_typedata; + Str_Init(&edit->text); + Str_Init(&edit->oldtext); + edit->data1 = "net-name"; + edit->maxLength = 24; + } + ob++; + +#if __JHEXEN__ + ob->_type = MN_TEXT; + ob->_flags = MNF_LAYOUT_OFFSET; + ob->_origin.y = 5; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Class"; + } + ob++; + + ob->_type = MN_LISTINLINE; + ob->_flags = MNF_ID2; + ob->_shortcut = 'c'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR3; + ob->ticker = MNListInline_Ticker; + ob->updateGeometry = MNListInline_UpdateGeometry; + ob->drawer = MNListInline_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuSelectPlayerSetupPlayerClass; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNListInline_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_list_t), PU_GAMESTATIC, 0); + { + mndata_list_t *list = (mndata_list_t *)ob->_typedata; + list->count = 3; + list->items = (mndata_listitem_t*)Z_Calloc(sizeof(mndata_listitem_t) * list->count, PU_GAMESTATIC, 0); + + { + mndata_listitem_t *item = (mndata_listitem_t *)list->items; + item->text = (char const *)TXT_PLAYERCLASS1; + item->data = PCLASS_FIGHTER; + item++; + + item->text = (char const *)TXT_PLAYERCLASS2; + item->data = PCLASS_CLERIC; + item++; + + item->text = (char const *)TXT_PLAYERCLASS3; + item->data = PCLASS_MAGE; + } + } + ob++; +#endif + + ob->_type = MN_TEXT; +#ifdef __JHERETIC__ + ob->_flags = MNF_LAYOUT_OFFSET; + ob->_origin.y = 5; +#endif + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t*)ob->_typedata; + text->text = "Color"; + } + ob++; + + // Setup the player color selection list. + ob->_type = MN_LISTINLINE; + ob->_flags = MNF_ID3; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR3; + ob->ticker = MNListInline_Ticker; + ob->updateGeometry = MNListInline_UpdateGeometry; + ob->drawer = MNListInline_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuSelectPlayerColor; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNListInline_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_list_t), PU_GAMESTATIC, 0); + { + mndata_list_t *list = (mndata_list_t *)ob->_typedata; +#if __JHEXEN__ + // Hexen v1.0 has only four player colors. + list->count = (gameMode == hexen_v10? 4 : NUMPLAYERCOLORS) + 1/*auto*/; +#else + list->count = NUMPLAYERCOLORS + 1/*auto*/; +#endif + list->items = (mndata_listitem_t *)Z_Calloc(sizeof(mndata_listitem_t) * list->count, PU_GAMESTATIC, 0); + + /// @todo Read these names from Text definitions. + { + mndata_listitem_t *item = (mndata_listitem_t *)list->items; +#if __JHEXEN__ + item->text = "Red"; item->data = 0; + item++; + + item->text = "Blue"; item->data = 1; + item++; + + item->text = "Yellow"; item->data = 2; + item++; + + item->text = "Green"; item->data = 3; + item++; + + // Hexen v1.0 has only four player colors. + if(gameMode != hexen_v10) + { + item->text = "Jade"; item->data = 4; + item++; + + item->text = "White"; item->data = 5; + item++; + + item->text = "Hazel"; item->data = 6; + item++; + + item->text = "Purple"; item->data = 7; + item++; + } + + item->text = "Automatic"; item->data = 8; +#elif __JHERETIC__ + item->text = "Green"; item->data = 0; + item++; + + item->text = "Orange"; item->data = 1; + item++; + + item->text = "Red"; item->data = 2; + item++; + + item->text = "Blue"; item->data = 3; + item++; + + item->text = "Automatic"; item->data = 4; +#else + item->text = "Green"; item->data = 0; + item++; + + item->text = "Indigo"; item->data = 1; + item++; + + item->text = "Brown"; item->data = 2; + item++; + + item->text = "Red"; item->data = 3; + item++; + + item->text = "Automatic"; item->data = 4; +#endif + } + } + ob++; + + ob->_type = MN_BUTTON; + ob->_shortcut = 's'; + ob->_pageFontIdx = MENU_FONT2; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuSelectAcceptPlayerSetup; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->text = "Save Changes"; + } + ob++; + + ob->_type = MN_NONE; + + page->objects = objects; +} + +void Hu_MenuInitSaveOptionsPage() +{ + Point2Raw const origin(60, 50); +#if !__JHEXEN__ + uint const numObjects = 10; +#else + uint const numObjects = 8; +#endif + + mn_page_t *page = Hu_MenuNewPage("SaveOptions", &origin, 0, Hu_MenuPageTicker, NULL, NULL, NULL); + MNPage_SetTitle(page, "Save Options"); + MNPage_SetPredefinedFont(page, MENU_FONT1, FID(GF_FONTA)); + MNPage_SetPreviousPage(page, Hu_MenuFindPageByName("Options")); + + mn_object_t *objects = (mn_object_t *)Z_Calloc(sizeof(*objects) * numObjects, PU_GAMESTATIC, 0); + mn_object_t *ob = objects; + + ob->_type = MN_TEXT; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t*)ob->_typedata; + text->text = "Confirm quick load/save"; + } + ob++; + + ob->_type = MN_BUTTON; + ob->_shortcut = 'q'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR3; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->staydownMode = true; + btn->data = "game-save-confirm"; + } + ob++; + + ob->_type = MN_TEXT; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Confirm reborn load"; + } + ob++; + + ob->_type = MN_BUTTON; + ob->_shortcut = 'r'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR3; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->staydownMode = true; + btn->data = "game-save-confirm-loadonreborn"; + } + ob++; + + ob->_type = MN_TEXT; + ob->_group = 1; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR2; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Reborn preferences"; + } + ob++; + +#if !__JHEXEN__ + ob->_type = MN_TEXT; + ob->_group = 1; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Load auto save"; + } + ob++; + + ob->_type = MN_BUTTON; + ob->_group = 1; + ob->_shortcut = 'a'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR3; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->staydownMode = true; + btn->data = "game-save-auto-loadonreborn"; + } + ob++; +#endif + + ob->_type = MN_TEXT; + ob->_group = 1; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Load last save"; + } + ob++; + + ob->_type = MN_BUTTON; + ob->_group = 1; + ob->_shortcut = 'a'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR3; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->staydownMode = true; + btn->data = "game-save-last-loadonreborn"; + } + ob++; + + ob->_type = MN_NONE; + + page->objects = objects; +} + +#if __JHERETIC__ || __JHEXEN__ +void Hu_MenuInitFilesPage() +{ + Point2Raw origin(110, 60); + uint const numObjects = 3; + + mn_page_t *page = Hu_MenuNewPage("Files", &origin, MPF_LAYOUT_FIXED|MPF_NEVER_SCROLL, Hu_MenuPageTicker, NULL, NULL, NULL); + MNPage_SetPredefinedFont(page, MENU_FONT1, FID(GF_FONTB)); + MNPage_SetPreviousPage(page, Hu_MenuFindPageByName("Main")); + + mn_object_t *objects = (mn_object_t *)Z_Calloc(sizeof(*objects) * numObjects, PU_GAMESTATIC, 0); + mn_object_t *ob = objects; + + int y = 0; + + ob->_type = MN_BUTTON; + ob->_origin.y = y; + ob->_shortcut = 'l'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuSelectLoadGame; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->text = "Load Game"; + } + ob++; y += FIXED_LINE_HEIGHT; + + ob->_type = MN_BUTTON; + ob->_origin.y = y; + ob->_shortcut = 's'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuSelectSaveGame; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->text = "Save Game"; + } + ob++; y += FIXED_LINE_HEIGHT; + + ob->_type = MN_NONE; + + page->objects = objects; +} +#endif + +static void deleteGameSave(int slot) +{ + DD_Executef(true, "deletegamesave %i", slot); +} + +int Hu_MenuLoadSlotCommandResponder(mn_object_t *ob, menucommand_e cmd) +{ + DENG_ASSERT(ob && ob->_type == MN_EDIT); + if(MCMD_DELETE == cmd && + (ob->_flags & MNF_FOCUS) && !(ob->_flags & MNF_ACTIVE) && !(ob->_flags & MNF_DISABLED)) + { + mndata_edit_t* edit = (mndata_edit_t*)ob->_typedata; + deleteGameSave(edit->data2); + return true; + } + return MNObject_DefaultCommandResponder(ob, cmd); +} + +int Hu_MenuSaveSlotCommandResponder(mn_object_t *ob, menucommand_e cmd) +{ + assert(ob); + if(MCMD_DELETE == cmd && + (ob->_flags & MNF_FOCUS) && !(ob->_flags & MNF_ACTIVE) && !(ob->_flags & MNF_DISABLED)) + { + mndata_edit_t* edit = (mndata_edit_t*)ob->_typedata; + deleteGameSave(edit->data2); + return true; + } + return MNEdit_CommandResponder(ob, cmd); +} + +void Hu_MenuInitLoadGameAndSaveGamePages() +{ +#if __JDOOM__ || __JDOOM64__ + Point2Raw const origin(80, 54); +#else + Point2Raw const origin(70, 30); +#endif + int const saveSlotObjectIds[NUMSAVESLOTS] = { + MNF_ID0, MNF_ID1, MNF_ID2, MNF_ID3, MNF_ID4, MNF_ID5, +#if !__JHEXEN__ + MNF_ID6, MNF_ID7 +#endif + }; + + mndata_edit_t *saveSlots = (mndata_edit_t *)Z_Calloc(sizeof(*saveSlots) * NUMSAVESLOTS, PU_GAMESTATIC, 0); + + for(int i = 0; i < NUMSAVESLOTS; ++i) + { + mndata_edit_t *slot = saveSlots + i; + slot->emptyString = (const char*) TXT_EMPTYSTRING; + slot->data2 = i; + slot->maxLength = 24; + } + + mn_object_t *loadMenuObjects = (mn_object_t *)Z_Calloc(sizeof(*loadMenuObjects) * (NUMSAVESLOTS+1), PU_GAMESTATIC, 0); + + int y = 0; + + int i = 0; + for(; i < NUMSAVESLOTS; ++i, y += FIXED_LINE_HEIGHT) + { + mn_object_t *ob = loadMenuObjects + i; + mndata_edit_t *edit = saveSlots + i; + + ob->_type = MN_EDIT; + ob->_origin.x = 0; + ob->_origin.y = y; + ob->_flags = saveSlotObjectIds[i] | MNF_DISABLED; + ob->_shortcut = '0' + i; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->updateGeometry = MNEdit_UpdateGeometry; + ob->drawer = MNEdit_Drawer; + ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuSelectLoadSlot; + ob->actions[MNA_FOCUSOUT ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = Hu_MenuLoadSlotCommandResponder; + ob->_typedata = edit; + ob->data2 = saveSlotObjectIds[i]; + Str_Init(&edit->text); + Str_Init(&edit->oldtext); + } + loadMenuObjects[i]._type = MN_NONE; + + mn_object_t *saveMenuObjects = (mn_object_t *)Z_Calloc(sizeof(*saveMenuObjects) * (NUMSAVESLOTS+1), PU_GAMESTATIC, 0); + + y = 0; + + i = 0; + for(; i < NUMSAVESLOTS; ++i, y += FIXED_LINE_HEIGHT) + { + mn_object_t *ob = saveMenuObjects + i; + mndata_edit_t *edit = saveSlots + i; + + ob->_type = MN_EDIT; + ob->_origin.x = 0; + ob->_origin.y = y; + ob->_flags = saveSlotObjectIds[i]; + ob->_shortcut = '0' + i; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->updateGeometry = MNEdit_UpdateGeometry; + ob->drawer = MNEdit_Drawer; + ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuSelectSaveSlot; + ob->actions[MNA_ACTIVE ].callback = Hu_MenuSaveSlotEdit; + ob->actions[MNA_FOCUSOUT ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = Hu_MenuSaveSlotCommandResponder; + ob->responder = MNEdit_Responder; + ob->_typedata = edit; + ob->data2 = saveSlotObjectIds[i]; + } + saveMenuObjects[i]._type = MN_NONE; + + mn_page_t *page = Hu_MenuNewPage("LoadGame", &origin, MPF_LAYOUT_FIXED|MPF_NEVER_SCROLL, Hu_MenuPageTicker, Hu_MenuDrawLoadGamePage, NULL, NULL); + MNPage_SetPredefinedFont(page, MENU_FONT1, FID(GF_FONTA)); + MNPage_SetPreviousPage(page, Hu_MenuFindPageByName("Main")); + page->objects = loadMenuObjects; + + page = Hu_MenuNewPage("SaveGame", &origin, MPF_LAYOUT_FIXED|MPF_NEVER_SCROLL, Hu_MenuPageTicker, Hu_MenuDrawSaveGamePage, NULL, NULL); + MNPage_SetPredefinedFont(page, MENU_FONT1, FID(GF_FONTA)); + MNPage_SetPreviousPage(page, Hu_MenuFindPageByName("Main")); + page->objects = saveMenuObjects; +} + +void Hu_MenuInitOptionsPage() +{ +#if __JHERETIC__ || __JHEXEN__ + Point2Raw const origin(110, 63); +#else + Point2Raw const origin(110, 63); +#endif +#if __JHERETIC__ || __JHEXEN__ + uint const numObjects = 13; +#else + uint const numObjects = 12; +#endif + + mn_page_t *page = Hu_MenuNewPage("Options", &origin, 0, Hu_MenuPageTicker, Hu_MenuDrawOptionsPage, NULL, NULL); + MNPage_SetPredefinedFont(page, MENU_FONT1, FID(GF_FONTA)); + MNPage_SetPreviousPage(page, Hu_MenuFindPageByName("Main")); + + mn_object_t *objects = (mn_object_t *)Z_Calloc(sizeof(*objects) * numObjects, PU_GAMESTATIC, 0); + mn_object_t *ob = objects; + + ob->_type = MN_BUTTON; + ob->_shortcut = 'e'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuSelectEndGame; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->text = "End Game"; + } + ob++; + + ob->_type = MN_BUTTON; + ob->_shortcut = 't'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuSelectControlPanelLink; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->text = "Show Taskbar"; + } + ob++; + + ob->_type = MN_BUTTON; + ob->_shortcut = 'c'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuActionSetActivePage; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->data1 = "ControlOptions"; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->text = "Controls"; + } + ob++; + + ob->_type = MN_BUTTON; + ob->_shortcut = 'g'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuActionSetActivePage; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->data1 = "GameplayOptions"; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->text = "Gameplay"; + } + ob++; + + ob->_type = MN_BUTTON; + ob->_shortcut = 's'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuActionSetActivePage; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->data1 = "SaveOptions"; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->text = "Game saves"; + } + ob++; + + ob->_type = MN_BUTTON; + ob->_shortcut = 'h'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuActionSetActivePage; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->data1 = "HUDOptions"; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->text = "HUD"; + } + ob++; + + ob->_type = MN_BUTTON; + ob->_shortcut = 'a'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuActionSetActivePage; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->data1 = "AutomapOptions"; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->text = "Automap"; + } + ob++; + + ob->_type = MN_BUTTON; + ob->_shortcut = 'w'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuActionSetActivePage; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->data1 = "WeaponOptions"; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->text = "Weapons"; + } + ob++; + +#if __JHERETIC__ || __JHEXEN__ + ob->_type = MN_BUTTON; + ob->_shortcut = 'i'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuActionSetActivePage; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->data1 = "InventoryOptions"; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->text = "Inventory"; + } + ob++; +#endif + + ob->_type = MN_BUTTON; + ob->_shortcut = 's'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuActionSetActivePage; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->data1 = "SoundOptions"; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->text = "Sound"; + } + ob++; + + /* + ob->_type = MN_BUTTON; + ob->_shortcut = 'm'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuSelectControlPanelLink; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->data2 = 2; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->text = "Mouse"; + } + ob++; + + ob->_type = MN_BUTTON; + ob->_shortcut = 'j'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuSelectControlPanelLink; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->data2 = 2; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->text = "Joystick"; + } + ob++;*/ + + ob->_type = MN_NONE; + + page->objects = objects; +} + +void Hu_MenuInitGameplayOptionsPage() +{ +#if __JHEXEN__ + Point2Raw const origin(88, 25); +#elif __JHERETIC__ + Point2Raw const origin(30, 40); +#else + Point2Raw const origin(30, 40); +#endif +#if __JDOOM64__ + uint const numObjects = 40; +#elif __JDOOM__ + uint const numObjects = 42; +#elif __JHERETIC__ + uint const numObjects = 24; +#elif __JHEXEN__ + uint const numObjects = 7; +#endif + + mn_page_t *page = Hu_MenuNewPage("GameplayOptions", &origin, 0, Hu_MenuPageTicker, NULL, NULL, NULL); + MNPage_SetTitle(page, "Gameplay Options"); + MNPage_SetPredefinedFont(page, MENU_FONT1, FID(GF_FONTA)); + MNPage_SetPreviousPage(page, Hu_MenuFindPageByName("Options")); + + mn_object_t *objects = (mn_object_t *)Z_Calloc(sizeof(*objects) * numObjects, PU_GAMESTATIC, 0); + mn_object_t *ob = objects; + + ob->_type = MN_TEXT; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Always Run"; + } + ob++; + + ob->_type = MN_BUTTON; + ob->_shortcut = 'r'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR3; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t*)ob->_typedata; + btn->staydownMode = true; + btn->data = "ctl-run"; + } + ob++; + + ob->_type = MN_TEXT; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t*)ob->_typedata; + text->text = "Use LookSpring"; + } + ob++; + + ob->_type = MN_BUTTON; + ob->_shortcut = 'l'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR3; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t*)ob->_typedata; + btn->staydownMode = true; + btn->data = "ctl-look-spring"; + } + ob++; + + ob->_type = MN_TEXT; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Disable AutoAim"; + } + ob++; + + ob->_type = MN_BUTTON; + ob->_shortcut = 'a'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR3; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->staydownMode = true; + btn->data = "ctl-aim-noauto"; + } + ob++; + +#if __JDOOM__ || __JHERETIC__ || __JDOOM64__ + ob->_type = MN_TEXT; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Allow Jumping"; + } + ob++; + + ob->_type = MN_BUTTON; + ob->_shortcut = 'j'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR3; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->staydownMode = true; + btn->data = "player-jump"; + } + ob++; +#endif + +#if __JDOOM64__ + ob->_type = MN_TEXT; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Weapon Recoil"; + } + ob++; + + ob->_type = MN_BUTTON; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR3; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->staydownMode = true; + btn->data = "player-weapon-recoil"; + } + ob++; +#endif + +#if __JDOOM__ || __JHERETIC__ || __JDOOM64__ + ob->_type = MN_TEXT; + ob->_group = 1; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR2; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Compatibility"; + } + ob++; + +# if __JDOOM__ || __JDOOM64__ + ob->_type = MN_TEXT; + ob->_group = 1; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Any Boss Trigger 666"; + } + ob++; + + ob->_type = MN_BUTTON; + ob->_group = 1; + ob->_shortcut = 'b'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR3; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->staydownMode = true; + btn->data = "game-anybossdeath666"; + } + ob++; + +# if !__JDOOM64__ + ob->_type = MN_TEXT; + ob->_group = 1; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Av Resurrects Ghosts"; + } + ob++; + + ob->_type = MN_BUTTON; + ob->_group = 1; + ob->_shortcut = 'g'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR3; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->staydownMode = true; + btn->data = "game-raiseghosts"; + } + ob++; + +# if __JDOOM__ + ob->_type = MN_TEXT; + ob->_group = 1; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "VileChase uses Av radius"; + } + ob++; + + ob->_type = MN_BUTTON; + ob->_group = 1; + ob->_shortcut = 'g'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR3; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->staydownMode = true; + btn->data = "game-vilechase-usevileradius"; + } + ob++; +# endif +# endif // !__JDOOM64__ + + ob->_type = MN_TEXT; + ob->_group = 1; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "PE Limited To 21 Lost Souls"; + } + ob++; + + ob->_type = MN_BUTTON; + ob->_group = 1; + ob->_shortcut = 'p'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR3; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->staydownMode = true; + btn->data = "game-maxskulls"; + } + ob++; + + ob->_type = MN_TEXT; + ob->_group = 1; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "LS Can Get Stuck Inside Walls"; + } + ob++; + + ob->_type = MN_BUTTON; + ob->_group = 1; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR3; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->staydownMode = true; + btn->data = "game-skullsinwalls"; + } + ob++; +# endif // __JDOOM__ || __JDOOM64__ + + ob->_type = MN_TEXT; + ob->_group = 1; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Monsters Fly Over Obstacles"; + } + ob++; + + ob->_type = MN_BUTTON; + ob->_group = 1; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR3; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->staydownMode = true; + btn->data = "game-monsters-floatoverblocking"; + } + ob++; + + ob->_type = MN_TEXT; + ob->_group = 1; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Monsters Can Get Stuck In Doors"; + } + ob++; + + ob->_type = MN_BUTTON; + ob->_group = 1; + ob->_shortcut = 'd'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR3; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->staydownMode = true; + btn->data = "game-monsters-stuckindoors"; + } + ob++; + + ob->_type = MN_TEXT; + ob->_group = 1; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Some Objects Never Hang Over Ledges"; + } + ob++; + + ob->_type = MN_BUTTON; + ob->_group = 1; + ob->_shortcut = 'h'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR3; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->staydownMode = true; + btn->data = "game-objects-neverhangoverledges"; + } + ob++; + + ob->_type = MN_TEXT; + ob->_group = 1; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Objects Fall Under Own Weight"; + } + ob++; + + ob->_type = MN_BUTTON; + ob->_group = 1; + ob->_shortcut = 'f'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR3; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->staydownMode = true; + btn->data = "game-objects-falloff"; + } + ob++; + +#if __JDOOM__ || __JDOOM64__ + ob->_type = MN_TEXT; + ob->_group = 1; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "All Crushed Objects Become A Pile Of Gibs"; + } + ob++; + + ob->_type = MN_BUTTON; + ob->_group = 1; + ob->_shortcut = 'g'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR3; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->staydownMode = true; + btn->data = "game-objects-gibcrushednonbleeders"; + } + ob++; +#endif + + ob->_type = MN_TEXT; + ob->_group = 1; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Corpses Slide Down Stairs"; + } + ob++; + + ob->_type = MN_BUTTON; + ob->_group = 1; + ob->_shortcut = 's'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR3; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->staydownMode = true; + btn->data = "game-corpse-sliding"; + } + ob++; + + ob->_type = MN_TEXT; + ob->_group = 1; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Use Exactly Doom's Clipping Code"; + } + ob++; + + ob->_type = MN_BUTTON; + ob->_group = 1; + ob->_shortcut = 'c'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR3; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->staydownMode = true; + btn->data = "game-objects-clipping"; + } + ob++; + + ob->_type = MN_TEXT; + ob->_group = 1; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = " ^If Not NorthOnly WallRunning"; + } + ob++; + + ob->_type = MN_BUTTON; + ob->_group = 1; + ob->_shortcut = 'w'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR3; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->staydownMode = true; + btn->data = "game-player-wallrun-northonly"; + } + ob++; + +# if __JDOOM__ || __JDOOM64__ + ob->_type = MN_TEXT; + ob->_group = 1; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Zombie Players Can Exit Maps"; + } + ob++; + + ob->_type = MN_BUTTON; + ob->_group = 1; + ob->_shortcut = 'e'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR3; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->staydownMode = true; + btn->data = "game-zombiescanexit"; + } + ob++; + + ob->_type = MN_TEXT; + ob->_group = 1; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Fix Ouch Face"; + } + ob++; + + ob->_type = MN_BUTTON; + ob->_group = 1; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR3; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->staydownMode = true; + btn->data = "hud-face-ouchfix"; + } + ob++; + + ob->_type = MN_TEXT; + ob->_group = 1; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Fix Weapon Slot Display"; + } + ob++; + + ob->_type = MN_BUTTON; + ob->_group = 1; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR3; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->staydownMode = true; + btn->data = "hud-status-weaponslots-ownedfix"; + } + ob++; +# endif // __JDOOM__ || __JDOOM64__ +#endif // __JDOOM__ || __JHERETIC__ || __JDOOM64__ + + ob->_type = MN_NONE; + + page->objects = objects; +} + +void Hu_MenuInitHUDOptionsPage() +{ +#if __JDOOM__ || __JDOOM64__ + Point2Raw const origin(97, 40); +#else + Point2Raw const origin(97, 28); +#endif + + mn_page_t *page = Hu_MenuNewPage("HudOptions", &origin, 0, Hu_MenuPageTicker, NULL, NULL, NULL); + MNPage_SetTitle(page, "HUD Options"); + MNPage_SetPredefinedFont(page, MENU_FONT1, FID(GF_FONTA)); + MNPage_SetPreviousPage(page, Hu_MenuFindPageByName("Options")); + page->objects = HudMenuObjects; +} + +void Hu_MenuInitAutomapOptionsPage() +{ +#if __JHERETIC__ || __JHEXEN__ + Point2Raw const origin(64, 28); +#else + Point2Raw const origin(70, 40); +#endif +#if __JDOOM64__ + uint const numObjects = 26; +#else + uint const numObjects = 27; +#endif + + mn_page_t *page = Hu_MenuNewPage("AutomapOptions", &origin, 0, Hu_MenuPageTicker, NULL, NULL, NULL); + MNPage_SetTitle(page, "Automap Options"); + MNPage_SetPredefinedFont(page, MENU_FONT1, FID(GF_FONTA)); + MNPage_SetPreviousPage(page, Hu_MenuFindPageByName("Options")); + + mn_object_t *objects = (mn_object_t *)Z_Calloc(sizeof(*objects) * numObjects, PU_GAMESTATIC, 0); + mn_object_t *ob = objects; + + ob->_type = MN_TEXT; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Background Opacity"; + } + ob++; + + ob->_type = MN_SLIDER; + ob->_shortcut = 'o'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNSlider_Ticker; + ob->updateGeometry = MNSlider_UpdateGeometry; + ob->drawer = MNSlider_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarSlider; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNSlider_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_slider_t), PU_GAMESTATIC, 0); + { + mndata_slider_t *sld = (mndata_slider_t *)ob->_typedata; + sld->min = 0; + sld->max = 1; + sld->value = 0; + sld->step = 0.1f; + sld->floatMode = true; + sld->data1 = "map-opacity"; + } + ob++; + + ob->_type = MN_TEXT; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Line Opacity"; + } + ob++; + + ob->_type = MN_SLIDER; + ob->_shortcut = 'l'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNSlider_Ticker; + ob->updateGeometry = MNSlider_UpdateGeometry; + ob->drawer = MNSlider_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarSlider; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNSlider_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_slider_t), PU_GAMESTATIC, 0); + { + mndata_slider_t *sld = (mndata_slider_t *)ob->_typedata; + sld->min = 0; + sld->max = 1; + sld->value = 0; + sld->step = 0.1f; + sld->floatMode = true; + sld->data1 = "map-line-opacity"; + } + ob++; + + ob->_type = MN_TEXT; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Line Width"; + } + ob++; + + ob->_type = MN_SLIDER; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNSlider_Ticker; + ob->updateGeometry = MNSlider_UpdateGeometry; + ob->drawer = MNSlider_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarSlider; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNSlider_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_slider_t), PU_GAMESTATIC, 0); + { + mndata_slider_t *sld = (mndata_slider_t *)ob->_typedata; + sld->min = .1f; + sld->max = 2; + sld->value = 0; + sld->step = 0.1f; + sld->floatMode = true; + sld->data1 = "map-line-width"; + } + ob++; + + ob->_type = MN_TEXT; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "HUD Display"; + } + ob++; + +#if !__JDOOM64__ + ob->_type = MN_LISTINLINE; + ob->_shortcut = 'h'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR3; + ob->ticker = MNListInline_Ticker; + ob->updateGeometry = MNListInline_UpdateGeometry; + ob->drawer = MNListInline_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarList; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNListInline_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_list_t), PU_GAMESTATIC, 0); + { + mndata_list_t *list = (mndata_list_t *)ob->_typedata; + + list->data = "map-huddisplay"; + list->count = 3; + list->items = (mndata_listitem_t *)Z_Calloc(sizeof(mndata_listitem_t) * list->count, PU_GAMESTATIC, 0); + + mndata_listitem_t *item = (mndata_listitem_t *)list->items; + item->text = "None"; + item->data = 0; + item++; + + item->text = "Current"; + item->data = 1; + item++; + + item->text = "Statusbar"; + item->data = 2; + } + ob++; +#endif + + ob->_type = MN_TEXT; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Door Colors"; + } + ob++; + + ob->_type = MN_BUTTON; + ob->_shortcut = 'd'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR3; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->staydownMode = true; + btn->data = "map-door-colors"; + } + ob++; + + ob->_type = MN_TEXT; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Door Glow"; + } + ob++; + + ob->_type = MN_SLIDER; + ob->_shortcut = 'g'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNSlider_Ticker; + ob->updateGeometry = MNSlider_UpdateGeometry; + ob->drawer = MNSlider_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarSlider; + ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNSlider_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_slider_t), PU_GAMESTATIC, 0); + { + mndata_slider_t *sld = (mndata_slider_t *)ob->_typedata; + sld->min = 0; + sld->max = 200; + sld->value = 0; + sld->step = 5; + sld->floatMode = true; + sld->data1 = "map-door-glow"; + } + ob++; + + ob->_type = MN_TEXT; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Use Custom Colors"; + } + ob++; + + ob->_type = MN_LISTINLINE; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR3; + ob->ticker = MNListInline_Ticker; + ob->updateGeometry = MNListInline_UpdateGeometry; + ob->drawer = MNListInline_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarList; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNListInline_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_list_t), PU_GAMESTATIC, 0); + { + mndata_list_t *list = (mndata_list_t *)ob->_typedata; + + list->count = 3; + list->items = (mndata_listitem_t *)Z_Calloc(sizeof(mndata_listitem_t) * list->count, PU_GAMESTATIC, 0); + list->data = "map-customcolors"; + + mndata_listitem_t *item = (mndata_listitem_t *)list->items; + item->text = "Never"; + item->data = 0; + item++; + + item->text = "Auto"; + item->data = 1; + item++; + + item->text = "Always"; + item->data = 2; + } + ob++; + + ob->_type = MN_TEXT; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Wall"; + } + ob++; + + ob->_type = MN_COLORBOX; + ob->_shortcut = 'w'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNColorBox_Ticker; + ob->updateGeometry = MNColorBox_UpdateGeometry; + ob->drawer = MNColorBox_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarColorBox; + ob->actions[MNA_ACTIVE ].callback = Hu_MenuActivateColorWidget; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNColorBox_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_colorbox_t), PU_GAMESTATIC, 0); + { + mndata_colorbox_t *cbox = (mndata_colorbox_t *)ob->_typedata; + cbox->data1 = "map-wall-r"; + cbox->data2 = "map-wall-g"; + cbox->data3 = "map-wall-b"; + } + ob++; + + ob->_type = MN_TEXT; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Floor Height Change"; + } + ob++; + + ob->_type = MN_COLORBOX; + ob->_shortcut = 'f'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNColorBox_Ticker; + ob->updateGeometry = MNColorBox_UpdateGeometry; + ob->drawer = MNColorBox_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarColorBox; + ob->actions[MNA_ACTIVE ].callback = Hu_MenuActivateColorWidget; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNColorBox_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_colorbox_t), PU_GAMESTATIC, 0); + { + mndata_colorbox_t *cbox = (mndata_colorbox_t *)ob->_typedata; + cbox->data1 = "map-wall-floorchange-r"; + cbox->data2 = "map-wall-floorchange-g"; + cbox->data3 = "map-wall-floorchange-b"; + } + ob++; + + ob->_type = MN_TEXT; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Ceiling Height Change"; + } + ob++; + + ob->_type = MN_COLORBOX; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNColorBox_Ticker; + ob->updateGeometry = MNColorBox_UpdateGeometry; + ob->drawer = MNColorBox_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarColorBox; + ob->actions[MNA_ACTIVE ].callback = Hu_MenuActivateColorWidget; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNColorBox_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_colorbox_t), PU_GAMESTATIC, 0); + { + mndata_colorbox_t *cbox = (mndata_colorbox_t *)ob->_typedata; + cbox->data1 = "map-wall-ceilingchange-r"; + cbox->data2 = "map-wall-ceilingchange-g"; + cbox->data3 = "map-wall-ceilingchange-b"; + } + ob++; + + ob->_type = MN_TEXT; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Unseen"; + } + ob++; + + ob->_type = MN_COLORBOX; + ob->_shortcut = 'u'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNColorBox_Ticker; + ob->updateGeometry = MNColorBox_UpdateGeometry; + ob->drawer = MNColorBox_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarColorBox; + ob->actions[MNA_ACTIVE ].callback = Hu_MenuActivateColorWidget; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNColorBox_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_colorbox_t), PU_GAMESTATIC, 0); + { + mndata_colorbox_t *cbox = (mndata_colorbox_t *)ob->_typedata; + cbox->data1 = "map-wall-unseen-r"; + cbox->data2 = "map-wall-unseen-g"; + cbox->data3 = "map-wall-unseen-b"; + } + ob++; + + ob->_type = MN_TEXT; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Thing"; + } + ob++; + + ob->_type = MN_COLORBOX; + ob->_shortcut = 't'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNColorBox_Ticker; + ob->updateGeometry = MNColorBox_UpdateGeometry; + ob->drawer = MNColorBox_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarColorBox; + ob->actions[MNA_ACTIVE ].callback = Hu_MenuActivateColorWidget; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNColorBox_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_colorbox_t), PU_GAMESTATIC, 0); + { + mndata_colorbox_t *cbox = (mndata_colorbox_t *)ob->_typedata; + cbox->data1 = "map-mobj-r"; + cbox->data2 = "map-mobj-g"; + cbox->data3 = "map-mobj-b"; + } + ob++; + + ob->_type = MN_TEXT; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Background"; + } + ob++; + + ob->_type = MN_COLORBOX; + ob->_shortcut = 'b'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNColorBox_Ticker; + ob->updateGeometry = MNColorBox_UpdateGeometry; + ob->drawer = MNColorBox_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarColorBox; + ob->actions[MNA_ACTIVE ].callback = Hu_MenuActivateColorWidget; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNColorBox_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_colorbox_t), PU_GAMESTATIC, 0); + { + mndata_colorbox_t *cbox = (mndata_colorbox_t *)ob->_typedata; + cbox->data1 = "map-background-r"; + cbox->data2 = "map-background-g"; + cbox->data3 = "map-background-b"; + } + ob++; + + ob->_type = MN_NONE; + + page->objects = objects; +} + +static int compareWeaponPriority(void const *_a, void const *_b) +{ + mndata_listitem_t const *a = (mndata_listitem_t const *)_a; + mndata_listitem_t const *b = (mndata_listitem_t const *)_b; + int i = 0, aIndex = -1, bIndex = -1; + + do + { + if(cfg.weaponOrder[i] == a->data) + { + aIndex = i; + } + if(cfg.weaponOrder[i] == b->data) + { + bIndex = i; + } + } while(!(aIndex != -1 && bIndex != -1) && ++i < NUM_WEAPON_TYPES); + + if(aIndex > bIndex) return 1; + if(aIndex < bIndex) return -1; + return 0; // Should never happen. +} + +void Hu_MenuInitWeaponsPage() +{ +#if __JDOOM__ || __JDOOM64__ + Point2Raw const origin(78, 40); +#elif __JHERETIC__ + Point2Raw const origin(78, 26); +#elif __JHEXEN__ + Point2Raw const origin(78, 38); +#endif +#if __JDOOM__ || __JDOOM64__ + uint const numObjects = 17; +#elif __JHERETIC__ || __JHEXEN__ + uint const numObjects = 15; +#endif + const struct { + char const *text; + int data; + } weaponOrder[NUM_WEAPON_TYPES+1] = { +#if __JDOOM__ || __JDOOM64__ + { (char const *)TXT_WEAPON1, WT_FIRST }, + { (char const *)TXT_WEAPON2, WT_SECOND }, + { (char const *)TXT_WEAPON3, WT_THIRD }, + { (char const *)TXT_WEAPON4, WT_FOURTH }, + { (char const *)TXT_WEAPON5, WT_FIFTH }, + { (char const *)TXT_WEAPON6, WT_SIXTH }, + { (char const *)TXT_WEAPON7, WT_SEVENTH }, + { (char const *)TXT_WEAPON8, WT_EIGHTH }, + { (char const *)TXT_WEAPON9, WT_NINETH }, +# if __JDOOM64__ + { (char const *)TXT_WEAPON10, WT_TENTH }, +# endif +#elif __JHERETIC__ + { (char const *)TXT_TXT_WPNSTAFF, WT_FIRST }, + { (char const *)TXT_TXT_WPNWAND, WT_SECOND }, + { (char const *)TXT_TXT_WPNCROSSBOW, WT_THIRD }, + { (char const *)TXT_TXT_WPNBLASTER, WT_FOURTH }, + { (char const *)TXT_TXT_WPNSKULLROD, WT_FIFTH }, + { (char const *)TXT_TXT_WPNPHOENIXROD, WT_SIXTH }, + { (char const *)TXT_TXT_WPNMACE, WT_SEVENTH }, + { (char const *)TXT_TXT_WPNGAUNTLETS, WT_EIGHTH }, +#elif __JHEXEN__ + /** + * @todo We should allow different weapon preferences per player-class. + */ + { "First", WT_FIRST }, + { "Second", WT_SECOND }, + { "Third", WT_THIRD }, + { "Fourth", WT_FOURTH }, +#endif + { 0 } + }; + + mn_page_t *page = Hu_MenuNewPage("WeaponOptions", &origin, 0, Hu_MenuPageTicker, Hu_MenuDrawWeaponsPage, NULL, NULL); + MNPage_SetTitle(page, "Weapons Options"); + MNPage_SetPredefinedFont(page, MENU_FONT1, FID(GF_FONTA)); + MNPage_SetPreviousPage(page, Hu_MenuFindPageByName("Options")); + + mn_object_t *objects = (mn_object_t *)Z_Calloc(sizeof(*objects) * numObjects, PU_GAMESTATIC, 0); + mn_object_t *ob = objects; + + ob->_type = MN_TEXT; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR2; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Priority Order"; + } + ob++; + + ob->_type = MN_LIST; + ob->_flags = MNF_ID0; + ob->_shortcut = 'p'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR3; + ob->ticker = MNList_Ticker; + ob->updateGeometry = MNList_UpdateGeometry; + ob->drawer = MNList_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuChangeWeaponPriority; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNList_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_list_t), PU_GAMESTATIC, 0); + { + mndata_list_t *list = (mndata_list_t *)ob->_typedata; + + list->count = NUM_WEAPON_TYPES; + list->items = (mndata_listitem_t *)Z_Calloc(sizeof(mndata_listitem_t) * list->count, PU_GAMESTATIC, 0); + + mndata_listitem_t *item = (mndata_listitem_t *)list->items; + for(int i = 0; weaponOrder[i].text; ++i, item++) + { + item->text = weaponOrder[i].text; + item->data = weaponOrder[i].data; + } + qsort(list->items, list->count, sizeof(mndata_listitem_t), compareWeaponPriority); + } + ob++; + + ob->_type = MN_TEXT; + ob->_group = 1; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR2; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Cycling"; + } + ob++; + + ob->_type = MN_TEXT; + ob->_group = 1; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Use Priority Order"; + } + ob++; + + ob->_type = MN_BUTTON; + ob->_group = 1; + ob->_shortcut = 'o'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR3; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->staydownMode = true; + btn->data = "player-weapon-nextmode"; + } + ob++; + + ob->_type = MN_TEXT; + ob->_group = 1; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Sequential"; + } + ob++; + + ob->_type = MN_BUTTON; + ob->_group = 1; + ob->_shortcut = 's'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR3; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->staydownMode = true; + btn->data = "player-weapon-cycle-sequential"; + } + ob++; + + ob->_type = MN_TEXT; + ob->_group = 2; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR2; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Autoswitch"; + } + ob++; + + ob->_type = MN_TEXT; + ob->_group = 2; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Pickup Weapon"; + } + ob++; + + ob->_type = MN_LISTINLINE; + ob->_group = 2; + ob->_shortcut = 'w'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR3; + ob->ticker = MNListInline_Ticker; + ob->updateGeometry = MNListInline_UpdateGeometry; + ob->drawer = MNListInline_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarList; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNListInline_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_list_t), PU_GAMESTATIC, 0); + { + mndata_list_t *list = (mndata_list_t *)ob->_typedata; + + list->count = 3; + list->items = (mndata_listitem_t *)Z_Calloc(sizeof(mndata_listitem_t) * list->count, PU_GAMESTATIC, 0); + list->data = "player-autoswitch"; + + mndata_listitem_t *item = (mndata_listitem_t *)list->items; + item->text = "Never"; + item->data = 0; + item++; + + item->text = "If Better"; + item->data = 1; + item++; + + item->text = "Always"; + item->data = 2; + } + ob++; + + ob->_type = MN_TEXT; + ob->_group = 2; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = " If Not Firing"; + } + ob++; + + ob->_type = MN_BUTTON; + ob->_group = 2; + ob->_shortcut = 'f'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR3; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->staydownMode = true; + btn->data = "player-autoswitch-notfiring"; + } + ob++; + + ob->_type = MN_TEXT; + ob->_group = 2; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Pickup Ammo"; + } + ob++; + + ob->_type = MN_LISTINLINE; + ob->_group = 2; + ob->_shortcut = 'a'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR3; + ob->ticker = MNListInline_Ticker; + ob->updateGeometry = MNListInline_UpdateGeometry; + ob->drawer = MNListInline_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarList; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNListInline_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_list_t), PU_GAMESTATIC, 0); + { + mndata_list_t *list = (mndata_list_t *)ob->_typedata; + + list->count = 3; + list->items = (mndata_listitem_t *)Z_Calloc(sizeof(mndata_listitem_t) * list->count, PU_GAMESTATIC, 0); + list->data = "player-autoswitch-ammo"; + + mndata_listitem_t *item = (mndata_listitem_t *)list->items; + item->text = "Never"; + item->data = 0; + item++; + + item->text = "If Better"; + item->data = 1; + item++; + + item->text = "Always"; + item->data = 2; + } + ob++; + +#if __JDOOM__ || __JDOOM64__ + ob->_type = MN_TEXT; + ob->_group = 2; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Pickup Beserk"; + } + ob++; + + ob->_type = MN_BUTTON; + ob->_group = 2; + ob->_shortcut = 'b'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR3; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->staydownMode = true; + btn->data = "player-autoswitch-berserk"; + } + ob++; +#endif + + ob->_type = MN_NONE; + + page->objects = objects; +} + +#if __JHERETIC__ || __JHEXEN__ +void Hu_MenuInitInventoryOptionsPage() +{ + Point2Raw const origin(78, 48); + uint const numObjects = 16; + + mn_page_t *page = Hu_MenuNewPage("InventoryOptions", &origin, 0, Hu_MenuPageTicker, NULL, NULL, NULL); + MNPage_SetTitle(page, "Inventory Options"); + MNPage_SetPredefinedFont(page, MENU_FONT1, FID(GF_FONTA)); + MNPage_SetPreviousPage(page, Hu_MenuFindPageByName("Options")); + + mn_object_t *objects = (mn_object_t *)Z_Calloc(sizeof(*objects) * numObjects, PU_GAMESTATIC, 0); + mn_object_t *ob = objects; + + ob->_type = MN_TEXT; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Select Mode"; + } + ob++; + + ob->_type = MN_BUTTON; + ob->_shortcut = 's'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR3; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->staydownMode = true; + btn->data = "ctl-inventory-mode"; + } + ob++; + + ob->_type = MN_TEXT; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Wrap Around"; + } + ob++; + + ob->_type = MN_BUTTON; + ob->_shortcut = 'w'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR3; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->staydownMode = true; + btn->data = "ctl-inventory-wrap"; + } + ob++; + + ob->_type = MN_TEXT; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Choose And Use"; + } + ob++; + + ob->_type = MN_BUTTON; + ob->_shortcut = 'c'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR3; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->staydownMode = true; + btn->data = "ctl-inventory-use-immediate"; + } + ob++; + + ob->_type = MN_TEXT; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Select Next If Use Failed"; + } + ob++; + + ob->_type = MN_BUTTON; + ob->_shortcut = 'n'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR3; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->staydownMode = true; + btn->data = "ctl-inventory-use-next"; + } + ob++; + + ob->_type = MN_TEXT; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "AutoHide"; + } + ob++; + + ob->_type = MN_SLIDER; + ob->_shortcut = 'h'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR3; + ob->ticker = MNSlider_Ticker; + ob->updateGeometry = MNSlider_TextualValueUpdateGeometry; + ob->drawer = MNSlider_TextualValueDrawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarSlider; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNSlider_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_slider_t), PU_GAMESTATIC, 0); + { + mndata_slider_t *sld = (mndata_slider_t *)ob->_typedata; + sld->min = 0; + sld->max = 30; + sld->value = 0; + sld->step = 1.f; + sld->floatMode = true; + sld->data1 = "hud-inventory-timer"; + sld->data2 = "Disabled"; + sld->data4 = " second"; + sld->data5 = " seconds"; + } + ob++; + + ob->_type = MN_TEXT; + ob->_group = 1; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR2; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Fullscreen HUD"; + } + ob++; + + ob->_type = MN_TEXT; + ob->_group = 1; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Max Visible Slots"; + } + ob++; + + ob->_type = MN_SLIDER; + ob->_group = 1; + ob->_shortcut = 'v'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR3; + ob->ticker = MNSlider_Ticker; + ob->updateGeometry = MNSlider_TextualValueUpdateGeometry; + ob->drawer = MNSlider_TextualValueDrawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarSlider; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNSlider_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_slider_t), PU_GAMESTATIC, 0); + { + mndata_slider_t *sld = (mndata_slider_t *)ob->_typedata; + sld->min = 0; + sld->max = 16; + sld->value = 0; + sld->step = 1; + sld->floatMode = false; + sld->data1 = "hud-inventory-slot-max"; + sld->data2 = "Automatic"; + } + ob++; + + ob->_type = MN_TEXT; + ob->_group = 1; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Show Empty Slots"; + } + ob++; + + ob->_type = MN_BUTTON; + ob->_group = 1; + ob->_shortcut = 'e'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR3; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarButton; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->staydownMode = true; + btn->data = "hud-inventory-slot-showempty"; + } + ob++; + + ob->_type = MN_NONE; + + page->objects = objects; +} +#endif + +void Hu_MenuInitSoundOptionsPage() +{ +#if __JHEXEN__ + Point2Raw const origin(97, 25); +#elif __JHERETIC__ + Point2Raw const origin(97, 30); +#elif __JDOOM__ || __JDOOM64__ + Point2Raw const origin(97, 40); +#endif + uint const numObjects = 6; + + mn_page_t *page = Hu_MenuNewPage("SoundOptions", &origin, 0, Hu_MenuPageTicker, NULL, NULL, NULL); + MNPage_SetTitle(page, "Sound Options"); + MNPage_SetPredefinedFont(page, MENU_FONT1, FID(GF_FONTA)); + MNPage_SetPreviousPage(page, Hu_MenuFindPageByName("Options")); + + mn_object_t *objects = (mn_object_t *)Z_Calloc(sizeof(*objects) * numObjects, PU_GAMESTATIC, 0); + mn_object_t *ob = objects; + + ob->_type = MN_TEXT; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "SFX Volume"; + } + ob++; + + ob->_type = MN_SLIDER; + ob->_shortcut = 's'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNSlider_Ticker; + ob->updateGeometry = MNSlider_UpdateGeometry; + ob->drawer = MNSlider_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarSlider; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNSlider_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_slider_t), PU_GAMESTATIC, 0); + { + mndata_slider_t *sld = (mndata_slider_t *)ob->_typedata; + sld->min = 0; + sld->max = 255; + sld->value = 0; + sld->step = 5; + sld->floatMode = false; + sld->data1 = "sound-volume"; + } + ob++; + + ob->_type = MN_TEXT; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNText_Ticker; + ob->updateGeometry = MNText_UpdateGeometry; + ob->drawer = MNText_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_text_t), PU_GAMESTATIC, 0); + { + mndata_text_t *text = (mndata_text_t *)ob->_typedata; + text->text = "Music Volume"; + } + ob++; + + ob->_type = MN_SLIDER; + ob->_shortcut = 'm'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNSlider_Ticker; + ob->updateGeometry = MNSlider_UpdateGeometry; + ob->drawer = MNSlider_Drawer; + ob->actions[MNA_MODIFIED].callback = Hu_MenuCvarSlider; + ob->actions[MNA_FOCUS].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNSlider_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_slider_t), PU_GAMESTATIC, 0); + { + mndata_slider_t *sld = (mndata_slider_t *)ob->_typedata; + sld->min = 0; + sld->max = 255; + sld->value = 0; + sld->step = 5; + sld->floatMode = false; + sld->data1 = "music-volume"; + } + ob++; + + /* + ob->_type = MN_BUTTON; + ob->_shortcut = 'p'; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->ticker = MNButton_Ticker; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->drawer = MNButton_Drawer; + ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuSelectControlPanelLink; + ob->actions[MNA_FOCUS ].callback = Hu_MenuDefaultFocusAction; + ob->cmdResponder = MNButton_CommandResponder; + ob->_typedata = Z_Calloc(sizeof(mndata_button_t), PU_GAMESTATIC, 0); + ob->data2 = 1; + { + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + btn->text = "Open Audio Panel"; + } + ob++; + */ + + ob->_type = MN_NONE; + + page->objects = objects; +} + +#if __JDOOM__ || __JHERETIC__ +/** + * Construct the episode selection menu. + */ +void Hu_MenuInitEpisodePage() +{ +#if __JDOOM__ + Point2Raw const origin(48, 63); +#else + Point2Raw const origin(80, 50); +#endif + + int numEpisodes; +#if __JDOOM__ + if(gameModeBits & (GM_ANY_DOOM2|GM_DOOM_CHEX)) + numEpisodes = 0; + else if(gameMode == doom_ultimate) + numEpisodes = 4; + else + numEpisodes = 3; +#else // __JHERETIC__ + if(gameMode == heretic_extended) + numEpisodes = 6; + else + numEpisodes = 3; +#endif + + // Allocate the menu objects array. + mn_object_t *objects = (mn_object_t *)Z_Calloc( sizeof(mn_object_t) * (numEpisodes + 1), PU_GAMESTATIC, 0); + mndata_button_t *buttons = (mndata_button_t *)Z_Calloc(sizeof(mndata_button_t) * (numEpisodes), PU_GAMESTATIC, 0); + + mn_object_t *ob = objects; + mndata_button_t *btn = buttons; + + int y = 0; + + for(int i = 0; i < numEpisodes; ++i) + { + ob->_type = MN_BUTTON; + ob->_origin.x = 0; + ob->_origin.y = y; + + btn->text = GET_TXT(TXT_EPISODE1 + i); + if(isalnum(btn->text[0])) + { + ob->_shortcut = tolower(btn->text[0]); + } +#if __JDOOM__ + btn->patch = &pEpisodeNames[i]; +#endif + + ob->_typedata = btn; + ob->ticker = MNButton_Ticker; + ob->drawer = MNButton_Drawer; + ob->cmdResponder = MNButton_CommandResponder; + ob->updateGeometry = MNButton_UpdateGeometry; + + if(i != 0 +#if __JHERETIC__ + && gameMode == heretic_shareware +#else + && gameMode == doom_shareware +#endif + ) + { + ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuActivateNotSharewareEpisode; + } + else + { + ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuActionSetActivePage; + ob->data1 = "Skill"; +#if __JHERETIC__ + if(gameMode == heretic_extended && i == 5) + { + ob->_flags |= MNF_ID0; + } +#endif + } + + ob->actions[MNA_FOCUS].callback = Hu_MenuFocusEpisode; + ob->data2 = i; + ob->_pageFontIdx = MENU_FONT1; + ob++; + btn++; + y += FIXED_LINE_HEIGHT; + } + ob->_type = MN_NONE; + + mn_page_t *page = Hu_MenuNewPage("Episode", &origin, MPF_LAYOUT_FIXED|MPF_NEVER_SCROLL, Hu_MenuPageTicker, Hu_MenuDrawEpisodePage, NULL, NULL); + MNPage_SetPredefinedFont(page, MENU_FONT1, FID(GF_FONTB)); + MNPage_SetPreviousPage(page, Hu_MenuFindPageByName("GameType")); + + page->objects = objects; +} +#endif + +#if __JHEXEN__ +/** + * Construct the player class selection menu. + */ +void Hu_MenuInitPlayerClassPage() +{ + Point2Raw const pageOrigin(66, 66); + + // First determine the number of selectable player classes. + int count = 0; + for(int i = 0; i < NUM_PLAYER_CLASSES; ++i) + { + classinfo_t *info = PCLASS_INFO(i); + if(info->userSelectable) + { + ++count; + } + } + + // Allocate the menu objects. + mn_object_t *objects = (mn_object_t *)Z_Calloc( sizeof(mn_object_t) * (count+4), PU_GAMESTATIC, 0); + mndata_button_t *buttons = (mndata_button_t *)Z_Calloc(sizeof(mndata_button_t) * (count+1), PU_GAMESTATIC, 0); + + uint y = 0; + + // Add the selectable classes. + mn_object_t *ob = objects; + mndata_button_t *btn = buttons; + + int n = 0; + while(n < count) + { + classinfo_t *info = PCLASS_INFO(n++); + + if(!info->userSelectable) continue; + + ob->_type = MN_BUTTON; + + btn->text = info->niceName; + + ob->_typedata = btn; + ob->_origin.x = 0; + ob->_origin.y = y; + ob->drawer = MNButton_Drawer; + ob->ticker = MNButton_Ticker; + ob->cmdResponder = MNButton_CommandResponder; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuSelectPlayerClass; + ob->actions[MNA_FOCUS ].callback = Hu_MenuFocusOnPlayerClass; + ob->data2 = (int)info->plrClass; + ob->_shortcut = tolower(btn->text[0]); + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + + ob++; + btn++; + y += FIXED_LINE_HEIGHT; + } + + // Random class button. + ob->_type = MN_BUTTON; + + btn->text = GET_TXT(TXT_RANDOMPLAYERCLASS); + + ob->_typedata = btn; + ob->_origin.x = 0; + ob->_origin.y = y; + ob->drawer = MNButton_Drawer; + ob->ticker = MNButton_Ticker; + ob->cmdResponder = MNButton_CommandResponder; + ob->updateGeometry = MNButton_UpdateGeometry; + ob->actions[MNA_ACTIVEOUT].callback = Hu_MenuSelectPlayerClass; + ob->actions[MNA_FOCUS ].callback = Hu_MenuFocusOnPlayerClass; + ob->data2 = (int)PCLASS_NONE; + ob->_shortcut = tolower(btn->text[0]); + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob++; + + // Mobj preview background. + ob->_type = MN_RECT; + ob->_flags = MNF_NO_FOCUS|MNF_ID1; + ob->_origin.x = 108; + ob->_origin.y = -58; + ob->drawer = MNRect_Drawer; + ob->ticker = Hu_MenuPlayerClassBackgroundTicker; + ob->updateGeometry = MNRect_UpdateGeometry; + ob->_pageFontIdx = MENU_FONT1; + ob->_pageColorIdx = MENU_COLOR1; + ob->_typedata = Z_Calloc(sizeof(mndata_rect_t), PU_GAMESTATIC, 0); + ob++; + + // Mobj preview. + ob->_type = MN_MOBJPREVIEW; + ob->_flags = MNF_ID0; + ob->_origin.x = 108 + 55; + ob->_origin.y = -58 + 76; + ob->ticker = Hu_MenuPlayerClassPreviewTicker; + ob->updateGeometry = MNMobjPreview_UpdateGeometry; + ob->drawer = MNMobjPreview_Drawer; + ob->_typedata = Z_Calloc(sizeof(mndata_mobjpreview_t), PU_GAMESTATIC, 0); + ob++; + + // Terminate. + ob->_type = MN_NONE; + + mn_page_t *page = Hu_MenuNewPage("PlayerClass", &pageOrigin, MPF_LAYOUT_FIXED|MPF_NEVER_SCROLL, Hu_MenuPageTicker, Hu_MenuDrawPlayerClassPage, NULL, NULL); + MNPage_SetPredefinedFont(page, MENU_FONT1, FID(GF_FONTB)); + MNPage_SetPreviousPage(page, Hu_MenuFindPageByName("GameType")); + + page->objects = objects; +} +#endif + +mn_page_t *MNPage_New(Point2Raw const *origin, int flags, + void (*ticker) (struct mn_page_s *page), + void (*drawer) (struct mn_page_s *page, Point2Raw const *origin), + int (*cmdResponder) (struct mn_page_s *page, menucommand_e cmd), + void *userData) +{ + mn_page_t *page = (mn_page_t *) M_Malloc(sizeof(*page)); + + page->origin.x = origin? origin->x : 0; + page->origin.y = origin? origin->y : 0; + page->flags = flags; + page->objects = 0; + page->objectsCount = 0; + page->ticker = ticker; + page->drawer = drawer; + page->cmdResponder = cmdResponder; + page->previous = 0; + page->userData = userData; + Str_Init(&page->title); + + fontid_t fontId = FID(GF_FONTA); + for(int i = 0; i < MENU_FONT_COUNT; ++i) + { + page->fonts[i] = fontId; + } + + de::zap(page->colors); + page->colors[0] = 0; + page->colors[1] = 1; + page->colors[2] = 2; + page->focus = -1; /// @todo Make this a page flag. + page->geometry = Rect_New(); + + return page; +} + +static mn_page_t *addPageToCollection(mn_page_t *page, char const *name) +{ + if(page) + { + pages = (pagerecord_t *)M_Realloc(pages, sizeof(*pages) * ++pageCount); + + pagerecord_t *rec = &pages[pageCount-1]; + rec->page = page; + Str_Init(&rec->name); Str_Set(&rec->name, name); + } + return page; +} + +mn_page_t* Hu_MenuNewPage(const char* name, Point2Raw const *origin, int flags, + void (*ticker) (struct mn_page_s* page), + void (*drawer) (struct mn_page_s* page, Point2Raw const *origin), + int (*cmdResponder) (struct mn_page_s* page, menucommand_e cmd), + void* userData) +{ + if(!name || !name[0]) + { + DENG_ASSERT(!"Hu_MenuNewPage: Attempt to create page with an invalid name"); + return NULL; + } + + return addPageToCollection(MNPage_New(origin, flags, ticker, drawer, cmdResponder, userData), name); +} + +void Hu_MenuInit() +{ + cvarbutton_t* cvb; + + if(inited) return; + + pageCount = 0; + pages = NULL; + + mnAlpha = mnTargetAlpha = 0; + menuActivePage = NULL; + menuActive = false; + cursorHasRotation = false; + cursorAngle = 0; + cursorAnimFrame = 0; + cursorAnimCounter = MENU_CURSOR_TICSPERFRAME; + + DD_Execute(true, "deactivatebcontext menu"); + + Hu_MenuLoadResources(); + + // Set default Yes/No strings. + for(cvb = mnCVarButtons; cvb->cvarname; cvb++) + { + if(!cvb->yes) cvb->yes = "Yes"; + if(!cvb->no) cvb->no = "No"; + } + + initAllPages(); + initAllObjectsOnAllPages(); + +#if __JDOOM__ + if(gameModeBits & GM_ANY_DOOM2) + { + mn_object_t *ob = MN_MustFindObjectOnPage(Hu_MenuFindPageByName("Main"), 0, MNF_ID0); // Read This! + MNObject_SetFlags(ob, FO_SET, MNF_DISABLED|MNF_HIDDEN|MNF_NO_FOCUS); + + ob = MN_MustFindObjectOnPage(Hu_MenuFindPageByName("Main"), 0, MNF_ID1); // Quit Game + MNObject_SetFixedY(ob, MNObject_FixedY(ob) - FIXED_LINE_HEIGHT); + } +#endif + + inited = true; +} + +void Hu_MenuShutdown() +{ + if(!inited) return; + + destroyAllPages(); + inited = false; +} + +dd_bool Hu_MenuIsActive() +{ + return menuActive; +} + +void Hu_MenuSetAlpha(float alpha) +{ + // The menu's alpha will start moving towards this target value. + mnTargetAlpha = alpha; +} + +float Hu_MenuAlpha() +{ + return mnAlpha; +} + +void Hu_MenuTicker(timespan_t ticLength) +{ +#define MENUALPHA_FADE_STEP (.07f) + + float diff = 0; + + // Move towards the target alpha level for the entire menu. + diff = mnTargetAlpha - mnAlpha; + if(fabs(diff) > MENUALPHA_FADE_STEP) + { + mnAlpha += (float)(MENUALPHA_FADE_STEP * ticLength * TICRATE * (diff > 0? 1 : -1)); + } + else + { + mnAlpha = mnTargetAlpha; + } + + if(!menuActive) return; + + // Animate cursor rotation? + if(cfg.menuCursorRotate) + { + if(cursorHasRotation) + { + cursorAngle += (float)(5 * ticLength * TICRATE); + } + else if(cursorAngle != 0) + { + float rewind = (float)(MENU_CURSOR_REWIND_SPEED * ticLength * TICRATE); + if(cursorAngle <= rewind || cursorAngle >= 360 - rewind) + cursorAngle = 0; + else if(cursorAngle < 180) + cursorAngle -= rewind; + else + cursorAngle += rewind; + } + + if(cursorAngle >= 360) + cursorAngle -= 360; + } + + // Time to think? Updates on 35Hz game ticks. + if(!DD_IsSharpTick()) return; + + // Advance menu time. + menuTime++; + + // Animate the cursor graphic? + if(--cursorAnimCounter <= 0) + { + cursorAnimFrame++; + cursorAnimCounter = MENU_CURSOR_TICSPERFRAME; + if(cursorAnimFrame > MENU_CURSOR_FRAMECOUNT-1) + cursorAnimFrame = 0; + } + + // Used for Heretic's rotating skulls. + frame = (menuTime / 3) % 18; + + // Call the active page's ticker. + menuActivePage->ticker(menuActivePage); + +#undef MENUALPHA_FADE_STEP +} + +mn_page_t* Hu_MenuActivePage() +{ + return menuActivePage; +} + +void Hu_MenuSetActivePage2(mn_page_t *page, dd_bool canReactivate) +{ + if(!menuActive) return; + if(!page) return; + + if(!(Get(DD_DEDICATED) || Get(DD_NOVIDEO))) + { + FR_ResetTypeinTimer(); + } + + cursorAngle = 0; // Stop cursor rotation animation dead (don't rewind). + menuNominatingQuickSaveSlot = false; + + if(menuActivePage == page) + { + if(!canReactivate) return; + MNPage_ClearFocusObject(page); + } + + updatePageObjects(page); + + // This is now the "active" page. + menuActivePage = page; + MNPage_Initialize(page); +} + +void Hu_MenuSetActivePage(mn_page_t *page) +{ + Hu_MenuSetActivePage2(page, false/*don't reactivate*/); +} + +dd_bool Hu_MenuIsVisible() +{ + return (menuActive || mnAlpha > .0001f); +} + +int Hu_MenuDefaultFocusAction(mn_object_t *ob, mn_actionid_t action, void *parameters) +{ + DENG_UNUSED(parameters); + if(MNA_FOCUS != action) return 1; + Hu_MenuUpdateCursorState(); + return 0; +} + +void Hu_MenuDrawFocusCursor(int x, int y, int focusObjectHeight, float alpha) +{ +#if __JDOOM__ || __JDOOM64__ +# define OFFSET_X (-22) +# define OFFSET_Y (-2) +#elif __JHERETIC__ || __JHEXEN__ +# define OFFSET_X (-16) +# define OFFSET_Y (3) +#endif + + const int cursorIdx = cursorAnimFrame; + const float angle = cursorAngle; + patchid_t pCursor = pCursors[cursorIdx % MENU_CURSOR_FRAMECOUNT]; + float scale, pos[2]; + patchinfo_t info; + + if(!R_GetPatchInfo(pCursor, &info)) + return; + + scale = MIN_OF((float) (focusObjectHeight * 1.267f) / info.geometry.size.height, 1); + pos[VX] = x + OFFSET_X * scale; + pos[VY] = y + OFFSET_Y * scale + focusObjectHeight/2; + + DGL_MatrixMode(DGL_MODELVIEW); + DGL_PushMatrix(); + + DGL_Translatef(pos[VX], pos[VY], 0); + DGL_Scalef(scale, scale, 1); + DGL_Rotatef(angle, 0, 0, 1); + + DGL_Enable(DGL_TEXTURE_2D); + DGL_Color4f(1, 1, 1, alpha); + + GL_DrawPatchXY3(pCursor, 0, 0, 0, DPF_NO_OFFSET); + + DGL_Disable(DGL_TEXTURE_2D); + + DGL_MatrixMode(DGL_MODELVIEW); + DGL_PopMatrix(); + +#undef OFFSET_Y +#undef OFFSET_X +} + +void Hu_MenuDrawPageTitle(const char* title, int x, int y) +{ + if(!title || !title[0]) return; + + DGL_Enable(DGL_TEXTURE_2D); + FR_SetFont(FID(GF_FONTB)); + FR_SetColorv(cfg.menuTextColors[0]); + FR_SetAlpha(mnRendState->pageAlpha); + + FR_DrawTextXY3(title, x, y, ALIGN_TOP, MN_MergeMenuEffectWithDrawTextFlags(0)); + + DGL_Disable(DGL_TEXTURE_2D); +} + +void Hu_MenuDrawPageHelp(const char* help, int x, int y) +{ + if(!help || !help[0]) return; + + DGL_Enable(DGL_TEXTURE_2D); + FR_SetFont(FID(GF_FONTA)); + FR_SetColorv(cfg.menuTextColors[1]); + FR_SetAlpha(mnRendState->pageAlpha); + + FR_DrawTextXY3(help, x, y, ALIGN_BOTTOM, MN_MergeMenuEffectWithDrawTextFlags(0)); + + DGL_Disable(DGL_TEXTURE_2D); +} + +static void drawOverlayBackground(float darken) +{ + DGL_SetNoMaterial(); + DGL_DrawRectf2Color(0, 0, SCREENWIDTH, SCREENHEIGHT, 0, 0, 0, darken); +} + +static void beginOverlayDraw() +{ +#define SMALL_SCALE .75f + + DGL_MatrixMode(DGL_MODELVIEW); + DGL_PushMatrix(); + + DGL_Translatef(SCREENWIDTH/2, SCREENHEIGHT/2, 0); + DGL_Scalef(SMALL_SCALE, SMALL_SCALE, 1); + DGL_Translatef(-(SCREENWIDTH/2), -(SCREENHEIGHT/2), 0); + +#undef SMALL_SCALE +} + +static void endOverlayDraw() +{ + DGL_MatrixMode(DGL_MODELVIEW); + DGL_PopMatrix(); +} + +void Hu_MenuDrawer() +{ +#define OVERLAY_DARKEN .7f + + dgl_borderedprojectionstate_t bp; + dd_bool showFocusCursor = true; + mn_object_t* focusObj; + + if(!Hu_MenuIsVisible()) return; + + GL_ConfigureBorderedProjection(&bp, 0, SCREENWIDTH, SCREENHEIGHT, + Get(DD_WINDOW_WIDTH), Get(DD_WINDOW_HEIGHT), scalemode_t(cfg.menuScaleMode)); + GL_BeginBorderedProjection(&bp); + + // First determine whether the focus cursor should be visible. + focusObj = MNPage_FocusObject(Hu_MenuActivePage()); + if(focusObj && (MNObject_Flags(focusObj) & MNF_ACTIVE)) + { + if(MNObject_Type(focusObj) == MN_COLORBOX || MNObject_Type(focusObj) == MN_BINDINGS) + { + showFocusCursor = false; + } + } + + DGL_MatrixMode(DGL_MODELVIEW); + DGL_PushMatrix(); + + DGL_Translatef(SCREENWIDTH/2, SCREENHEIGHT/2, 0); + DGL_Scalef(cfg.menuScale, cfg.menuScale, 1); + DGL_Translatef(-(SCREENWIDTH/2), -(SCREENHEIGHT/2), 0); + + MN_DrawPage(Hu_MenuActivePage(), mnAlpha, showFocusCursor); + + DGL_MatrixMode(DGL_MODELVIEW); + DGL_PopMatrix(); + + GL_EndBorderedProjection(&bp); + + // Drawing any overlays? + if(focusObj && (MNObject_Flags(focusObj) & MNF_ACTIVE)) + { + switch(MNObject_Type(focusObj)) + { + case MN_COLORBOX: + case MN_BINDINGS: + drawOverlayBackground(OVERLAY_DARKEN); + GL_BeginBorderedProjection(&bp); + + beginOverlayDraw(); + if(MNObject_Type(focusObj) == MN_BINDINGS) + { + Hu_MenuControlGrabDrawer(MNBindings_ControlName(focusObj), 1); + } + else + { + MN_DrawPage(Hu_MenuFindPageByName("ColorWidget"), 1, true); + } + endOverlayDraw(); + + GL_EndBorderedProjection(&bp); + break; + default: break; + } + } + +#undef OVERLAY_DARKEN +} + +void Hu_MenuPageTicker(mn_page_t *page) +{ + // Normal ticker actions first. + MNPage_Ticker(page); + + /// @todo Move game-menu specific page tick functionality here. +} + +void Hu_MenuNavigatePage(mn_page_t *page, int pageDelta) +{ +#if 0 + int index; + assert(page); + + oldIndex = index = MAX_OF(0, page->focus); + + if(pageDelta < 0) + { + index = MAX_OF(0, index - page->numVisObjects); + } + else + { + index = MIN_OF(page->objectsCount-1, index + page->numVisObjects); + } + + // Don't land on empty objects. + while((page->objects[index].flags & (MNF_DISABLED | MNF_NO_FOCUS)) && (index > 0)) + index--; + while((page->objects[index].flags & (MNF_DISABLED | MNF_NO_FOCUS)) && index < page->objectsCount) + index++; + + if(index != oldIndex) + { + S_LocalSound(SFX_MENU_NAV_RIGHT, NULL); + MNPage_SetFocus(page, page->objects + index); + } +#endif +} + +static void initPageObjects(mn_page_t *page) +{ + mn_object_t *ob; + assert(page); + + page->objectsCount = 0; + + for(ob = page->objects; MNObject_Type(ob) != MN_NONE; ob++) + { + page->objectsCount += 1; + + ob->_page = page; + ob->_geometry = Rect_New(); + + ob->timer = 0; + MNObject_SetFlags(ob, FO_CLEAR, MNF_FOCUS); + + if(0 != ob->_shortcut) + { + int shortcut = ob->_shortcut; + ob->_shortcut = 0; // Clear invalid defaults. + MNObject_SetShortcut(ob, shortcut); + } + + switch(MNObject_Type(ob)) + { + case MN_TEXT: { + mndata_text_t *txt = (mndata_text_t *)ob->_typedata; + MNObject_SetFlags(ob, FO_SET, MNF_NO_FOCUS); + + if(txt->text && (PTR2INT(txt->text) > 0 && PTR2INT(txt->text) < NUMTEXT)) + { + txt->text = GET_TXT(PTR2INT(txt->text)); + } + break; } + + case MN_BUTTON: { + /*mn_actioninfo_t const *action = MNObject_Action(ob, MNA_MODIFIED);*/ + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + + if(btn->text && (PTR2INT(btn->text) > 0 && PTR2INT(btn->text) < NUMTEXT)) + { + btn->text = GET_TXT(PTR2INT(btn->text)); + /// @todo Should not be done here. + MNObject_SetShortcut(ob, btn->text[0]); + } + break; } + + case MN_EDIT: { + mndata_edit_t *edit = (mndata_edit_t *) ob->_typedata; + + if(edit->emptyString && (PTR2INT(edit->emptyString) > 0 && PTR2INT(edit->emptyString) < NUMTEXT)) + { + edit->emptyString = GET_TXT(PTR2INT(edit->emptyString)); + } + break; } + + case MN_LIST: + case MN_LISTINLINE: { + mndata_list_t *list = (mndata_list_t *) ob->_typedata; + + for(int i = 0; i < list->count; ++i) + { + mndata_listitem_t *item = &((mndata_listitem_t *)list->items)[i]; + if(item->text && (PTR2INT(item->text) > 0 && PTR2INT(item->text) < NUMTEXT)) + { + item->text = GET_TXT(PTR2INT(item->text)); + } + } + break; } + + case MN_COLORBOX: { + mndata_colorbox_t *cbox = (mndata_colorbox_t *) ob->_typedata; + + if(!cbox->rgbaMode) + cbox->a = 1.f; + if(0 >= cbox->width) + cbox->width = MNDATA_COLORBOX_WIDTH; + if(0 >= cbox->height) + cbox->height = MNDATA_COLORBOX_HEIGHT; + break; } + + case MN_MOBJPREVIEW: + MNObject_SetFlags(ob, FO_SET, MNF_NO_FOCUS); + break; + + default: break; + } + } +} + +/** + * Main task is to update objects linked to cvars. + */ +static void updatePageObjects(mn_page_t *page) +{ + DENG_ASSERT(page != 0); + + mn_object_t *ob; + for(ob = page->objects; MNObject_Type(ob) != MN_NONE; ob++) + { + switch(MNObject_Type(ob)) + { + case MN_TEXT: + case MN_MOBJPREVIEW: + MNObject_SetFlags(ob, FO_SET, MNF_NO_FOCUS); + break; + + case MN_BUTTON: { + mn_actioninfo_t const *action = MNObject_Action(ob, MNA_MODIFIED); + mndata_button_t *btn = (mndata_button_t *)ob->_typedata; + + if(action && action->callback == Hu_MenuCvarButton) + { + cvarbutton_t *cvb; + if(ob->data1) + { + // This button has already been initialized. + cvb = (cvarbutton_t *) ob->data1; + cvb->active = (Con_GetByte(cvb->cvarname) & (cvb->mask? cvb->mask : ~0)) != 0; + //strcpy(obj->text, cvb->active ? cvb->yes : cvb->no); + btn->text = cvb->active ? cvb->yes : cvb->no; + continue; + } + + // Find the cvarbutton representing this one. + for(cvb = mnCVarButtons; cvb->cvarname; cvb++) + { + if(!strcmp((char const *)btn->data, cvb->cvarname) && ob->data2 == cvb->mask) + { + cvb->active = (Con_GetByte(cvb->cvarname) & (cvb->mask? cvb->mask : ~0)) != 0; + ob->data1 = (void*) cvb; + + btn->yes = cvb->yes; + btn->no = cvb->no; + btn->text = (cvb->active ? btn->yes : btn->no); + break; + } + } + cvb = 0; + } + break; } + + case MN_LIST: + case MN_LISTINLINE: { + mn_actioninfo_t const *action = MNObject_Action(ob, MNA_MODIFIED); + mndata_list_t *list = (mndata_list_t *) ob->_typedata; + + if(action && action->callback == Hu_MenuCvarList) + { + MNList_SelectItemByValue(ob, MNLIST_SIF_NO_ACTION, Con_GetInteger((char const *)list->data)); + } + break; } + + case MN_EDIT: { + mn_actioninfo_t const *action = MNObject_Action(ob, MNA_MODIFIED); + mndata_edit_t *edit = (mndata_edit_t *) ob->_typedata; + + if(action && action->callback == Hu_MenuCvarEdit) + { + MNEdit_SetText(ob, MNEDIT_STF_NO_ACTION, Con_GetString((char const *)edit->data1)); + } + break; } + + case MN_SLIDER: { + mn_actioninfo_t const *action = MNObject_Action(ob, MNA_MODIFIED); + mndata_slider_t *sldr = (mndata_slider_t *) ob->_typedata; + if(action && action->callback == Hu_MenuCvarSlider) + { + float value; + if(sldr->floatMode) + value = Con_GetFloat((char const *)sldr->data1); + else + value = Con_GetInteger((char const *)sldr->data1); + MNSlider_SetValue(ob, MNSLIDER_SVF_NO_ACTION, value); + } + break; } + + case MN_COLORBOX: { + mndata_colorbox_t *cbox = (mndata_colorbox_t *) ob->_typedata; + mn_actioninfo_t const *action = MNObject_Action(ob, MNA_MODIFIED); + + if(action && action->callback == Hu_MenuCvarColorBox) + { + float rgba[4]; + rgba[CR] = Con_GetFloat((char const *)cbox->data1); + rgba[CG] = Con_GetFloat((char const *)cbox->data2); + rgba[CB] = Con_GetFloat((char const *)cbox->data3); + rgba[CA] = (cbox->rgbaMode? Con_GetFloat((char const *)cbox->data4) : 1.f); + MNColorBox_SetColor4fv(ob, MNCOLORBOX_SCF_NO_ACTION, rgba); + } + break; } + + default: break; + } + } +} + +static void destroyPageObjects(mn_page_t *page) +{ + mn_object_t *obj; + if(!page) return; + for(obj = page->objects; MNObject_Type(obj) != MN_NONE; obj++) + { + if(obj->_geometry) + { + Rect_Delete(obj->_geometry); + obj->_geometry = NULL; + } + } +} + +static void destroyPage(mn_page_t *page) +{ + if(!page) return; + + destroyPageObjects(page); + + Str_Free(&page->title); + + if(page->geometry) + { + Rect_Delete(page->geometry); + page->geometry = NULL; + } + + free(page); +} + +static void initAllPages() +{ + Hu_MenuInitColorWidgetPage(); + Hu_MenuInitMainPage(); + Hu_MenuInitGameTypePage(); +#if __JDOOM__ || __JHERETIC__ + Hu_MenuInitEpisodePage(); +#endif +#if __JHEXEN__ + Hu_MenuInitPlayerClassPage(); +#endif + Hu_MenuInitSkillPage(); + Hu_MenuInitMultiplayerPage(); + Hu_MenuInitPlayerSetupPage(); +#if __JHERETIC__ || __JHEXEN__ + Hu_MenuInitFilesPage(); +#endif + Hu_MenuInitLoadGameAndSaveGamePages(); + Hu_MenuInitOptionsPage(); + Hu_MenuInitGameplayOptionsPage(); + Hu_MenuInitSaveOptionsPage(); + Hu_MenuInitHUDOptionsPage(); + Hu_MenuInitAutomapOptionsPage(); + Hu_MenuInitWeaponsPage(); +#if __JHERETIC__ || __JHEXEN__ + Hu_MenuInitInventoryOptionsPage(); +#endif + Hu_MenuInitSoundOptionsPage(); + Hu_MenuInitControlsPage(); +} + +static void destroyAllPages() +{ + int i; + if(!pages) return; + for(i = 0; i < pageCount; ++i) + { + pagerecord_t* rec = pages + i; + destroyPage(rec->page); + Str_Free(&rec->name); + } + free(pages); +} + +static void initAllObjectsOnAllPages() +{ + int i; + for(i = 0; i < pageCount; ++i) + { + pagerecord_t* rec = pages + i; + initPageObjects(rec->page); + } +} + +int Hu_MenuColorWidgetCmdResponder(mn_page_t *page, menucommand_e cmd) +{ + assert(page); + switch(cmd) + { + case MCMD_NAV_OUT: { + mn_object_t *obj = (mn_object_t*)page->userData; + MNObject_SetFlags(obj, FO_CLEAR, MNF_ACTIVE); + S_LocalSound(SFX_MENU_CANCEL, NULL); + colorWidgetActive = false; + + /// @kludge We should re-focus on the object instead. + cursorAngle = 0; // Stop cursor rotation animation dead (don't rewind). + Hu_MenuUpdateCursorState(); + /// kludge end. + return true; + } + case MCMD_NAV_PAGEUP: + case MCMD_NAV_PAGEDOWN: + return true; // Eat these. + case MCMD_SELECT: { + mn_object_t *obj = (mn_object_t*)page->userData; + MNObject_SetFlags(obj, FO_CLEAR, MNF_ACTIVE); + S_LocalSound(SFX_MENU_ACCEPT, NULL); + colorWidgetActive = false; + MNColorBox_CopyColor(obj, 0, MN_MustFindObjectOnPage(page, 0, MNF_ID0)); + + /// @kludge We should re-focus on the object instead. + cursorAngle = 0; // Stop cursor rotation animation dead (don't rewind). + Hu_MenuUpdateCursorState(); + /// kludge end. + return true; + } + default: + break; + } + return false; +} + +static void fallbackCommandResponder(mn_page_t *page, menucommand_e cmd) +{ + assert(page); + switch(cmd) + { + case MCMD_NAV_PAGEUP: + case MCMD_NAV_PAGEDOWN: + S_LocalSound(cmd == MCMD_NAV_PAGEUP? SFX_MENU_NAV_UP : SFX_MENU_NAV_DOWN, NULL); + Hu_MenuNavigatePage(page, cmd == MCMD_NAV_PAGEUP? -1 : +1); + break; + + case MCMD_NAV_UP: + case MCMD_NAV_DOWN: { + mn_object_t *obj = MNPage_FocusObject(page); + // An object on this page must have focus in order to navigate. + if(obj) + { + int i = 0, giveFocus = page->focus; + do + { + giveFocus += (cmd == MCMD_NAV_UP? -1 : 1); + if(giveFocus < 0) + giveFocus = page->objectsCount - 1; + else if(giveFocus >= page->objectsCount) + giveFocus = 0; + } while(++i < page->objectsCount && (MNObject_Flags(page->objects + giveFocus) & (MNF_DISABLED | MNF_NO_FOCUS | MNF_HIDDEN))); + + if(giveFocus != page->focus) + { + S_LocalSound(cmd == MCMD_NAV_UP? SFX_MENU_NAV_UP : SFX_MENU_NAV_DOWN, NULL); + MNPage_SetFocus(page, page->objects + giveFocus); + } + } + break; + } + case MCMD_NAV_OUT: + if(!page->previous) + { + S_LocalSound(SFX_MENU_CLOSE, NULL); + Hu_MenuCommand(MCMD_CLOSE); + } + else + { + S_LocalSound(SFX_MENU_CANCEL, NULL); + Hu_MenuSetActivePage(page->previous); + } + break; + default: +// DEBUG_Message("Warning: fallbackCommandResponder: Command %i not processed, ignoring.\n", (int) cmd); + break; + } +} + +/// Depending on the current menu state some commands require translating. +static menucommand_e translateCommand(menucommand_e cmd) +{ + // If a close command is received while currently working with a selected + // "active" widget - interpret the command instead as "navigate out". + if(menuActive && (cmd == MCMD_CLOSE || cmd == MCMD_CLOSEFAST)) + { + mn_object_t *obj = MNPage_FocusObject(Hu_MenuActivePage()); + if(obj) + { + switch(MNObject_Type(obj)) + { + case MN_EDIT: + case MN_LIST: + case MN_COLORBOX: + if(MNObject_Flags(obj) & MNF_ACTIVE) + { + cmd = MCMD_NAV_OUT; + } + break; + default: + break; + } + } + } + return cmd; +} + +void Hu_MenuCommand(menucommand_e cmd) +{ + mn_page_t *page; + mn_object_t *obj; + + cmd = translateCommand(cmd); + + // Determine the page which will respond to this command. + if(colorWidgetActive) + page = Hu_MenuFindPageByName("ColorWidget"); + else + page = Hu_MenuActivePage(); + + if(cmd == MCMD_CLOSE || cmd == MCMD_CLOSEFAST) + { + if(menuActive) + { + //BusyMode_FreezeGameForBusyMode(); + + menuNominatingQuickSaveSlot = false; + + Hu_FogEffectSetAlphaTarget(0); + + if(cmd == MCMD_CLOSEFAST) + { // Hide the menu instantly. + mnAlpha = mnTargetAlpha = 0; + } + else + { + mnTargetAlpha = 0; + } + + if(cmd != MCMD_CLOSEFAST) + S_LocalSound(SFX_MENU_CLOSE, NULL); + + menuActive = false; + + // Disable the menu binding context. + DD_Execute(true, "deactivatebcontext menu"); + } + return; + } + + // No other commands are responded to once shutdown has begun. + if(G_QuitInProgress()) + { + return; + } + + if(!menuActive) + { + if(MCMD_OPEN == cmd) + { + // If anyone is currently chatting; the menu cannot be opened. + int i; + for(i = 0; i < MAXPLAYERS; ++i) + { + if(ST_ChatIsActive(i)) + return; + } + + S_LocalSound(SFX_MENU_OPEN, NULL); + + //Con_Open(false); + + Hu_FogEffectSetAlphaTarget(1); + Hu_MenuSetAlpha(1); + menuActive = true; + menuTime = 0; + + menuActivePage = NULL; // Always re-activate this page. + Hu_MenuSetActivePage(Hu_MenuFindPageByName("Main")); + + // Enable the menu binding class + DD_Execute(true, "activatebcontext menu"); + B_SetContextFallback("menu", Hu_MenuFallbackResponder); + } + return; + } + + // Try the current focus object. + obj = MNPage_FocusObject(page); + if(obj && obj->cmdResponder) + { + if(obj->cmdResponder(obj, cmd)) + return; + } + + // Try the page's cmd responder. + if(page->cmdResponder) + { + if(page->cmdResponder(page, cmd)) + return; + } + + fallbackCommandResponder(page, cmd); +} + +int Hu_MenuPrivilegedResponder(event_t* ev) +{ + if(Hu_MenuIsActive()) + { + mn_object_t *obj = MNPage_FocusObject(Hu_MenuActivePage()); + if(obj && !(MNObject_Flags(obj) & MNF_DISABLED)) + { + if(obj->privilegedResponder) + { + return obj->privilegedResponder(obj, ev); + } + } + } + return false; +} + +int Hu_MenuResponder(event_t* ev) +{ + if(Hu_MenuIsActive()) + { + mn_object_t *obj = MNPage_FocusObject(Hu_MenuActivePage()); + if(obj && !(MNObject_Flags(obj) & MNF_DISABLED)) + { + if(obj->responder) + { + return obj->responder(obj, ev); + } + } + } + return false; // Not eaten. +} + +int Hu_MenuFallbackResponder(event_t* ev) +{ + mn_page_t *page = Hu_MenuActivePage(); + + if(!Hu_MenuIsActive() || !page) return false; + + if(cfg.menuShortcutsEnabled) + { + if(ev->type == EV_KEY && (ev->state == EVS_DOWN || ev->state == EVS_REPEAT)) + { + int i; + for(i = 0; i < page->objectsCount; ++i) + { + mn_object_t *obj = &page->objects[i]; + if(MNObject_Flags(obj) & (MNF_DISABLED | MNF_NO_FOCUS | MNF_HIDDEN)) + continue; + + if(MNObject_Shortcut(obj) == ev->data1) + { + MNPage_SetFocus(page, obj); + return true; + } + } + } + } + return false; +} + +/** + * User wants to load this game + */ +int Hu_MenuSelectLoadSlot(mn_object_t *obj, mn_actionid_t action, void *parameters) +{ + mndata_edit_t* edit = (mndata_edit_t*)obj->_typedata; + const int saveSlot = edit->data2; + mn_page_t* saveGamePage; + + DENG_UNUSED(parameters); + + if(MNA_ACTIVEOUT != action) return 1; + + saveGamePage = Hu_MenuFindPageByName("SaveGame"); + MNPage_SetFocus(saveGamePage, MNPage_FindObject(saveGamePage, 0, obj->data2)); + + G_LoadGame(saveSlot); + Hu_MenuCommand(chooseCloseMethod()); + return 0; +} + +#if __JHERETIC__ || __JHEXEN__ +void Hu_MenuDrawMainPage(mn_page_t *page, Point2Raw const *origin) +{ +#define TITLEOFFSET_X (-22) +#define TITLEOFFSET_Y (-56) + +#if __JHEXEN__ + int frame = (menuTime / 5) % 7; +#endif + + DGL_Enable(DGL_TEXTURE_2D); + DGL_Color4f(1, 1, 1, mnRendState->pageAlpha); + FR_SetFont(FID(GF_FONTB)); + FR_SetColorAndAlpha(1, 1, 1, mnRendState->pageAlpha); + + WI_DrawPatchXY3(pMainTitle, Hu_ChoosePatchReplacement(patchreplacemode_t(cfg.menuPatchReplaceMode), pMainTitle), + origin->x + TITLEOFFSET_X, origin->y + TITLEOFFSET_Y, ALIGN_TOPLEFT, 0, MN_MergeMenuEffectWithDrawTextFlags(0)); +#if __JHEXEN__ + GL_DrawPatchXY(pBullWithFire[(frame + 2) % 7], origin->x - 73, origin->y + 24); + GL_DrawPatchXY(pBullWithFire[frame], origin->x + 168, origin->y + 24); +#elif __JHERETIC__ + GL_DrawPatchXY(pRotatingSkull[17 - frame], origin->x - 70, origin->y - 46); + GL_DrawPatchXY(pRotatingSkull[frame], origin->x + 122, origin->y - 46); +#endif + + DGL_Disable(DGL_TEXTURE_2D); + +#undef TITLEOFFSET_Y +#undef TITLEOFFSET_X +} +#endif + +void Hu_MenuDrawGameTypePage(mn_page_t *page, Point2Raw const *origin) +{ + Hu_MenuDrawPageTitle(GET_TXT(TXT_PICKGAMETYPE), SCREENWIDTH/2, origin->y - 28); +} + +#if __JHERETIC__ +static void composeNotDesignedForMessage(const char* str) +{ + char* buf = notDesignedForMessage, *in, tmp[2]; + + buf[0] = 0; + tmp[1] = 0; + + // Get the message template. + in = GET_TXT(TXT_NOTDESIGNEDFOR); + + for(; *in; in++) + { + if(in[0] == '%') + { + if(in[1] == '1') + { + strcat(buf, str); + in++; + continue; + } + + if(in[1] == '%') + in++; + } + tmp[0] = *in; + strcat(buf, tmp); + } +} +#endif + +#if __JHEXEN__ +/** + * A specialization of MNRect_Ticker() which implements the animation logic + * for the player class selection page's player visual background. + */ +void Hu_MenuPlayerClassBackgroundTicker(mn_object_t *ob) +{ + DENG_ASSERT(ob != 0); + + // Determine our selection according to the current focus object. + /// @todo Do not search for the focus object, flag the "random" + /// state through a focus action. + if(mn_object_t *mop = MNPage_FocusObject(MNObject_Page(ob))) + { + playerclass_t pClass = (playerclass_t) mop->data2; + if(pClass == PCLASS_NONE) + { + // Random class. + /// @todo Use this object's timer instead of menuTime. + pClass = playerclass_t(menuTime / 5); + } + + /// @todo Only change here if in the "random" state. + pClass = playerclass_t(int(pClass) % 3); // Number of user-selectable classes. + + MNRect_SetBackgroundPatch(ob, pPlayerClassBG[pClass]); + } + + // Call MNRect's ticker now we've done our own processing. + MNRect_Ticker(ob); +} + +/** + * A specialization of MNMobjPreview_Ticker() which implements the animation + * logic for the player class selection page's player visual. + */ +void Hu_MenuPlayerClassPreviewTicker(mn_object_t *ob) +{ + DENG_ASSERT(ob != 0); + + // Determine our selection according to the current focus object. + /// @todo Do not search for the focus object, flag the "random" + /// state through a focus action. + if(mn_object_t *mop = MNPage_FocusObject(MNObject_Page(ob))) + { + playerclass_t pClass = (playerclass_t) mop->data2; + if(pClass == PCLASS_NONE) + { + // Random class. + /// @todo Use this object's timer instead of menuTime. + pClass = playerclass_t(PCLASS_FIRST + (menuTime / 5)); + pClass = playerclass_t(int(pClass) % 3); // Number of user-selectable classes. + + MNMobjPreview_SetPlayerClass(ob, pClass); + MNMobjPreview_SetMobjType(ob, PCLASS_INFO(pClass)->mobjType); + } + + // Fighter is Yellow, others Red by default. + MNMobjPreview_SetTranslationClass(ob, pClass); + MNMobjPreview_SetTranslationMap(ob, pClass == PCLASS_FIGHTER? 2 : 0); + } + + // Call MNMobjPreview's ticker now we've done our own processing. + MNMobjPreview_Ticker(ob); +} + +void Hu_MenuDrawPlayerClassPage(mn_page_t *page, Point2Raw const *origin) +{ + DGL_Enable(DGL_TEXTURE_2D); + FR_SetFont(FID(GF_FONTB)); + FR_SetColorAndAlpha(cfg.menuTextColors[0][CR], cfg.menuTextColors[0][CG], cfg.menuTextColors[0][CB], mnRendState->pageAlpha); + + FR_DrawTextXY3("Choose class:", origin->x - 32, origin->y - 42, ALIGN_TOPLEFT, + MN_MergeMenuEffectWithDrawTextFlags(0)); + + DGL_Disable(DGL_TEXTURE_2D); +} +#endif + +#if __JDOOM__ || __JHERETIC__ +void Hu_MenuDrawEpisodePage(mn_page_t *page, Point2Raw const *origin) +{ +#if __JHERETIC__ + DENG_UNUSED(origin); + + // Inform the user episode 6 is designed for deathmatch only. + mn_object_t *obj = MNPage_FindObject(page, 0, MNF_ID0); + if(obj && obj == MNPage_FocusObject(page)) + { + Point2Raw origin; + + composeNotDesignedForMessage(GET_TXT(TXT_SINGLEPLAYER)); + + origin.x = SCREENWIDTH/2; + origin.y = (SCREENHEIGHT/2) + ((SCREENHEIGHT/2-5)/cfg.menuScale); + + Hu_MenuDrawPageHelp(notDesignedForMessage, origin.x, origin.y); + } +#else // __JDOOM__ + DGL_Enable(DGL_TEXTURE_2D); + DGL_Color4f(1, 1, 1, mnRendState->pageAlpha); + + FR_SetFont(FID(GF_FONTB)); + FR_SetColorv(cfg.menuTextColors[0]); + FR_SetAlpha(mnRendState->pageAlpha); + + WI_DrawPatchXY3(pEpisode, Hu_ChoosePatchReplacement(patchreplacemode_t(cfg.menuPatchReplaceMode), pEpisode), + origin->x + 7, origin->y - 25, ALIGN_TOPLEFT, 0, MN_MergeMenuEffectWithDrawTextFlags(0)); + + DGL_Disable(DGL_TEXTURE_2D); +#endif +} +#endif + +void Hu_MenuDrawSkillPage(mn_page_t *page, Point2Raw const *origin) +{ +#if __JDOOM__ || __JDOOM64__ + DGL_Enable(DGL_TEXTURE_2D); + DGL_Color4f(1, 1, 1, mnRendState->pageAlpha); + FR_SetFont(FID(GF_FONTB)); + FR_SetColorAndAlpha(cfg.menuTextColors[0][CR], cfg.menuTextColors[0][CG], cfg.menuTextColors[0][CB], mnRendState->pageAlpha); + + WI_DrawPatchXY3(pNewGame, Hu_ChoosePatchReplacement(patchreplacemode_t(cfg.menuPatchReplaceMode), pNewGame), + origin->x + 48, origin->y - 49, ALIGN_TOPLEFT, 0, MN_MergeMenuEffectWithDrawTextFlags(0)); + WI_DrawPatchXY3(pSkill, Hu_ChoosePatchReplacement(patchreplacemode_t(cfg.menuPatchReplaceMode), pSkill), + origin->x + 6, origin->y - 25, ALIGN_TOPLEFT, 0, MN_MergeMenuEffectWithDrawTextFlags(0)); + + DGL_Disable(DGL_TEXTURE_2D); +#elif __JHEXEN__ + Hu_MenuDrawPageTitle("Choose Skill Level:", origin->x + 36, origin->y - 28); +#endif +} + +void Hu_MenuUpdateGameSaveWidgets() +{ + int const saveSlotObjectIds[NUMSAVESLOTS] = { + MNF_ID0, MNF_ID1, MNF_ID2, MNF_ID3, MNF_ID4, MNF_ID5, +#if !__JHEXEN__ + MNF_ID6, MNF_ID7 +#endif + }; + mn_page_t *page; + int i; + + if(!menuActive) return; + + // Prompt a refresh of the game-save info. We don't yet actively monitor + // the contents of the game-save paths, so instead we settle for manual + // updates whenever the save/load menu is opened. + SaveSlots_UpdateAllSaveInfo(saveSlots); + + // Update widgets. + page = Hu_MenuFindPageByName("LoadGame"); + for(i = 0; i < NUMSAVESLOTS; ++i) + { + mn_object_t *obj = MN_MustFindObjectOnPage(page, 0, saveSlotObjectIds[i]); + mndata_edit_t *edit = (mndata_edit_t *) obj->_typedata; + char const *text = ""; + + MNObject_SetFlags(obj, FO_SET, MNF_DISABLED); + if(SaveSlots_SlotInUse(saveSlots, edit->data2)) + { + SaveInfo *info = SaveSlots_SaveInfo(saveSlots, edit->data2); + text = Str_Text(SaveInfo_Description(info)); + MNObject_SetFlags(obj, FO_CLEAR, MNF_DISABLED); + } + MNEdit_SetText(obj, MNEDIT_STF_NO_ACTION, text); + } +} + +/** + * Called after the save name has been modified and to action the game-save. + */ +int Hu_MenuSelectSaveSlot(mn_object_t *ob, mn_actionid_t action, void *parameters) +{ + mndata_edit_t* edit = (mndata_edit_t*)ob->_typedata; + const int saveSlot = edit->data2; + mn_page_t *page; + + DENG_UNUSED(parameters); + + if(MNA_ACTIVEOUT != action) return 1; + + if(menuNominatingQuickSaveSlot) + { + Con_SetInteger("game-save-quick-slot", saveSlot); + menuNominatingQuickSaveSlot = false; + } + + if(!G_SaveGame2(saveSlot, Str_Text(MNEdit_Text(ob)))) return 0; + + page = Hu_MenuFindPageByName("SaveGame"); + MNPage_SetFocus(page, MN_MustFindObjectOnPage(page, 0, ob->data2)); + + page = Hu_MenuFindPageByName("LoadGame"); + MNPage_SetFocus(page, MN_MustFindObjectOnPage(page, 0, ob->data2)); + + Hu_MenuCommand(chooseCloseMethod()); + return 0; +} + +int Hu_MenuCvarButton(mn_object_t *obj, mn_actionid_t action, void *parameters) +{ + mndata_button_t *btn = (mndata_button_t *)obj->_typedata; + cvarbutton_t const *cb = (cvarbutton_t *)obj->data1; + cvartype_t varType = Con_GetVariableType(cb->cvarname); + int value; + + DENG_UNUSED(parameters); + if(MNA_MODIFIED != action) return 1; + + //strcpy(btn->text, cb->active? cb->yes : cb->no); + btn->text = cb->active? cb->yes : cb->no; + + if(CVT_NULL == varType) return 0; + + if(cb->mask) + { + value = Con_GetInteger(cb->cvarname); + if(cb->active) + { + value |= cb->mask; + } + else + { + value &= ~cb->mask; + } + } + else + { + value = cb->active; + } + + Con_SetInteger2(cb->cvarname, value, SVF_WRITE_OVERRIDE); + return 0; +} + +int Hu_MenuCvarList(mn_object_t *obj, mn_actionid_t action, void *parameters) +{ + mndata_list_t const *list = (mndata_list_t *) obj->_typedata; + mndata_listitem_t const *item; + cvartype_t varType; + int value; + + DENG_UNUSED(parameters); + if(MNA_MODIFIED != action) return 1; + + if(MNList_Selection(obj) < 0) return 0; // Hmm? + + varType = Con_GetVariableType((char const *)list->data); + if(CVT_NULL == varType) return 0; + + item = &((mndata_listitem_t *) list->items)[list->selection]; + if(list->mask) + { + value = Con_GetInteger((char const *)list->data); + value = (value & ~list->mask) | (item->data & list->mask); + } + else + { + value = item->data; + } + + switch(varType) + { + case CVT_INT: + Con_SetInteger2((char const *)list->data, value, SVF_WRITE_OVERRIDE); + break; + case CVT_BYTE: + Con_SetInteger2((char const *)list->data, (byte) value, SVF_WRITE_OVERRIDE); + break; + default: + Con_Error("Hu_MenuCvarList: Unsupported variable type %i", (int)varType); + break; + } + return 0; +} + +int Hu_MenuSaveSlotEdit(mn_object_t *obj, mn_actionid_t action, void *parameters) +{ + DENG_UNUSED(parameters); + + if(MNA_ACTIVE != action) return 1; + + // Are we suggesting a new name? + if(cfg.menuGameSaveSuggestName) + { + AutoStr* suggestName = G_GenerateSaveGameName(); + MNEdit_SetText(obj, MNEDIT_STF_NO_ACTION, Str_Text(suggestName)); + } + return 0; +} + +int Hu_MenuCvarEdit(mn_object_t *ob, mn_actionid_t action, void *parameters) +{ + mndata_edit_t const *edit = (mndata_edit_t *)ob->_typedata; + cvartype_t varType = Con_GetVariableType((char const *)edit->data1); + + DENG_UNUSED(parameters); + + if(MNA_MODIFIED != action) return 1; + + switch(varType) + { + case CVT_CHARPTR: + Con_SetString2((char const *)edit->data1, Str_Text(MNEdit_Text(ob)), SVF_WRITE_OVERRIDE); + break; + + case CVT_URIPTR: { + /// @todo Sanitize and validate against known schemas. + Uri *uri = Uri_NewWithPath2(Str_Text(MNEdit_Text(ob)), RC_NULL); + Con_SetUri2((char const *)edit->data1, uri, SVF_WRITE_OVERRIDE); + Uri_Delete(uri); + break; } + + default: break; + } + return 0; +} + +int Hu_MenuCvarSlider(mn_object_t *obj, mn_actionid_t action, void *parameters) +{ + mndata_slider_t const *sldr = (mndata_slider_t *)obj->_typedata; + cvartype_t varType = Con_GetVariableType((char const *)sldr->data1); + float value = MNSlider_Value(obj); + + DENG_UNUSED(parameters); + if(MNA_MODIFIED != action) return 1; + + if(CVT_NULL == varType) return 0; + + switch(varType) + { + case CVT_FLOAT: + if(sldr->step >= .01f) + { + Con_SetFloat2((char const *)sldr->data1, (int) (100 * value) / 100.0f, SVF_WRITE_OVERRIDE); + } + else + { + Con_SetFloat2((char const *)sldr->data1, value, SVF_WRITE_OVERRIDE); + } + break; + case CVT_INT: + Con_SetInteger2((char const *)sldr->data1, (int) value, SVF_WRITE_OVERRIDE); + break; + case CVT_BYTE: + Con_SetInteger2((char const *)sldr->data1, (byte) value, SVF_WRITE_OVERRIDE); + break; + default: + break; + } + return 0; +} + +int Hu_MenuActivateColorWidget(mn_object_t *obj, mn_actionid_t action, void *parameters) +{ + mn_object_t* cboxMix, *sldrRed, *sldrGreen, *sldrBlue, *textAlpha, *sldrAlpha; + mn_page_t* colorWidgetPage = Hu_MenuFindPageByName("ColorWidget"); + + DENG_UNUSED(parameters); + if(action != MNA_ACTIVE) return 1; + + cboxMix = MN_MustFindObjectOnPage(colorWidgetPage, 0, MNF_ID0); + sldrRed = MN_MustFindObjectOnPage(colorWidgetPage, 0, MNF_ID1); + sldrGreen = MN_MustFindObjectOnPage(colorWidgetPage, 0, MNF_ID2); + sldrBlue = MN_MustFindObjectOnPage(colorWidgetPage, 0, MNF_ID3); + textAlpha = MN_MustFindObjectOnPage(colorWidgetPage, 0, MNF_ID4); + sldrAlpha = MN_MustFindObjectOnPage(colorWidgetPage, 0, MNF_ID5); + + colorWidgetActive = true; + + MNPage_Initialize(colorWidgetPage); + colorWidgetPage->userData = obj; + + MNColorBox_CopyColor(cboxMix, 0, obj); + MNSlider_SetValue(sldrRed, MNSLIDER_SVF_NO_ACTION, MNColorBox_Redf(obj)); + MNSlider_SetValue(sldrGreen, MNSLIDER_SVF_NO_ACTION, MNColorBox_Greenf(obj)); + MNSlider_SetValue(sldrBlue, MNSLIDER_SVF_NO_ACTION, MNColorBox_Bluef(obj)); + MNSlider_SetValue(sldrAlpha, MNSLIDER_SVF_NO_ACTION, MNColorBox_Alphaf(obj)); + + MNObject_SetFlags(textAlpha, (MNColorBox_RGBAMode(obj)? FO_CLEAR : FO_SET), MNF_DISABLED|MNF_HIDDEN); + MNObject_SetFlags(sldrAlpha, (MNColorBox_RGBAMode(obj)? FO_CLEAR : FO_SET), MNF_DISABLED|MNF_HIDDEN); + + return 0; +} + +int Hu_MenuCvarColorBox(mn_object_t *obj, mn_actionid_t action, void *parameters) +{ + mndata_colorbox_t* cbox = (mndata_colorbox_t*)obj->_typedata; + DENG_UNUSED(parameters); + if(action != MNA_MODIFIED) return 1; + // MNColorBox's current color has already been updated and we know + // that at least one of the color components have changed. + // So our job is to simply update the associated cvars. + Con_SetFloat2((char const *)cbox->data1, MNColorBox_Redf(obj), SVF_WRITE_OVERRIDE); + Con_SetFloat2((char const *)cbox->data2, MNColorBox_Greenf(obj), SVF_WRITE_OVERRIDE); + Con_SetFloat2((char const *)cbox->data3, MNColorBox_Bluef(obj), SVF_WRITE_OVERRIDE); + if(MNColorBox_RGBAMode(obj)) + { + Con_SetFloat2((char const *)cbox->data4, MNColorBox_Alphaf(obj), SVF_WRITE_OVERRIDE); + } + return 0; +} + +void Hu_MenuDrawLoadGamePage(mn_page_t *page, Point2Raw const *origin) +{ + DENG_UNUSED(page); + + DGL_Enable(DGL_TEXTURE_2D); + DGL_Color4f(1, 1, 1, mnRendState->pageAlpha); + FR_SetFont(FID(GF_FONTB)); + FR_SetColorAndAlpha(cfg.menuTextColors[0][CR], cfg.menuTextColors[0][CG], cfg.menuTextColors[0][CB], mnRendState->pageAlpha); + +#if __JHERETIC__ || __JHEXEN__ + FR_DrawTextXY3("Load Game", SCREENWIDTH/2, origin->y-20, ALIGN_TOP, MN_MergeMenuEffectWithDrawTextFlags(0)); +#else + WI_DrawPatchXY3(pLoadGame, Hu_ChoosePatchReplacement(patchreplacemode_t(cfg.menuPatchReplaceMode), pLoadGame), + origin->x - 8, origin->y - 26, ALIGN_TOPLEFT, 0, MN_MergeMenuEffectWithDrawTextFlags(0)); +#endif + DGL_Disable(DGL_TEXTURE_2D); + + { Point2Raw helpOrigin; + helpOrigin.x = SCREENWIDTH/2; + helpOrigin.y = (SCREENHEIGHT/2) + ((SCREENHEIGHT/2-5)/cfg.menuScale); + Hu_MenuDrawPageHelp("Select to load, [Del] to clear", helpOrigin.x, helpOrigin.y); + } +} + +void Hu_MenuDrawSaveGamePage(mn_page_t *page, Point2Raw const *origin) +{ + DENG_UNUSED(page); + +#if __JHERETIC__ || __JHEXEN__ + Hu_MenuDrawPageTitle("Save Game", SCREENWIDTH/2, origin->y - 20); +#else + DGL_Enable(DGL_TEXTURE_2D); + DGL_Color4f(1, 1, 1, mnRendState->pageAlpha); + FR_SetFont(FID(GF_FONTB)); + FR_SetColorAndAlpha(cfg.menuTextColors[0][CR], cfg.menuTextColors[0][CG], cfg.menuTextColors[0][CB], mnRendState->pageAlpha); + + WI_DrawPatchXY3(pSaveGame, Hu_ChoosePatchReplacement(patchreplacemode_t(cfg.menuPatchReplaceMode), pSaveGame), + origin->x - 8, origin->y - 26, ALIGN_TOPLEFT, 0, MN_MergeMenuEffectWithDrawTextFlags(0)); + + DGL_Disable(DGL_TEXTURE_2D); +#endif + + { Point2Raw helpOrigin; + helpOrigin.x = SCREENWIDTH/2; + helpOrigin.y = (SCREENHEIGHT/2) + ((SCREENHEIGHT/2-5)/cfg.menuScale); + Hu_MenuDrawPageHelp("Select to save, [Del] to clear", helpOrigin.x, helpOrigin.y); + } +} + +#if __JDOOM__ || __JHERETIC__ || __JHEXEN__ +int Hu_MenuSelectHelp(mn_object_t *obj, mn_actionid_t action, void *parameters) +{ + DENG_UNUSED(parameters); + if(MNA_ACTIVEOUT != action) return 1; + G_StartHelp(); + return 0; +} +#endif + +void Hu_MenuDrawOptionsPage(mn_page_t *page, Point2Raw const *origin) +{ +#if __JHERETIC__ || __JHEXEN__ + Hu_MenuDrawPageTitle("Options", origin->x + 42, origin->y - 38); +#else + DGL_Enable(DGL_TEXTURE_2D); + DGL_Color4f(1, 1, 1, mnRendState->pageAlpha); + FR_SetFont(FID(GF_FONTB)); + FR_SetColorAndAlpha(cfg.menuTextColors[0][CR], cfg.menuTextColors[0][CG], cfg.menuTextColors[0][CB], mnRendState->pageAlpha); + + WI_DrawPatchXY3(pOptionsTitle, Hu_ChoosePatchReplacement(patchreplacemode_t(cfg.menuPatchReplaceMode), pOptionsTitle), + origin->x + 42, origin->y - 20, ALIGN_TOP, 0, MN_MergeMenuEffectWithDrawTextFlags(0)); + + DGL_Disable(DGL_TEXTURE_2D); +#endif +} + +void Hu_MenuDrawWeaponsPage(mn_page_t *page, Point2Raw const *offset) +{ + // Inform the user how to change the order. + if(MNPage_FocusObject(page) == MN_MustFindObjectOnPage(page, 0, MNF_ID0)) + { + const char* helpText = "Use left/right to move weapon up/down"; + Point2Raw origin; + origin.x = SCREENWIDTH/2; + origin.y = (SCREENHEIGHT/2) + ((SCREENHEIGHT/2-5)/cfg.menuScale); + Hu_MenuDrawPageHelp(helpText, origin.x, origin.y); + } +} + +void Hu_MenuDrawMultiplayerPage(mn_page_t *page, Point2Raw const *origin) +{ + Hu_MenuDrawPageTitle(GET_TXT(TXT_MULTIPLAYER), SCREENWIDTH/2, origin->y - 28); +} + +void Hu_MenuDrawPlayerSetupPage(mn_page_t *page, Point2Raw const *origin) +{ + Hu_MenuDrawPageTitle(GET_TXT(TXT_PLAYERSETUP), SCREENWIDTH/2, origin->y - 28); +} + +int Hu_MenuActionSetActivePage(mn_object_t *obj, mn_actionid_t action, void *parameters) +{ + assert(obj); + DENG_UNUSED(parameters); + if(MNA_ACTIVEOUT != action) return 1; + Hu_MenuSetActivePage(Hu_MenuFindPageByName((char*)obj->data1)); + return 0; +} + +int Hu_MenuUpdateColorWidgetColor(mn_object_t *obj, mn_actionid_t action, void *parameters) +{ + float value = MNSlider_Value(obj); + mn_object_t* cboxMix = MN_MustFindObjectOnPage(Hu_MenuFindPageByName("ColorWidget"), 0, MNF_ID0); + + DENG_UNUSED(parameters); + if(MNA_MODIFIED != action) return 1; + + switch(obj->data2) + { + case CR: MNColorBox_SetRedf( cboxMix, MNCOLORBOX_SCF_NO_ACTION, value); break; + case CG: MNColorBox_SetGreenf(cboxMix, MNCOLORBOX_SCF_NO_ACTION, value); break; + case CB: MNColorBox_SetBluef( cboxMix, MNCOLORBOX_SCF_NO_ACTION, value); break; + case CA: MNColorBox_SetAlphaf(cboxMix, MNCOLORBOX_SCF_NO_ACTION, value); break; + default: + Con_Error("Hu_MenuUpdateColorWidgetColor: Invalid value (%i) for data2.", obj->data2); + } + return 0; +} + +int Hu_MenuChangeWeaponPriority(mn_object_t *obj, mn_actionid_t action, void *parameters) +{ + DENG_UNUSED(parameters); + if(MNA_MODIFIED != action) return 1; + /*int choice = option >> NUM_WEAPON_TYPES; + int temp; + + if(option & RIGHT_DIR) + { + if(choice < NUM_WEAPON_TYPES-1) + { + temp = cfg.weaponOrder[choice+1]; + cfg.weaponOrder[choice+1] = cfg.weaponOrder[choice]; + cfg.weaponOrder[choice] = temp; + } + } + else + { + if(choice > 0) + { + temp = cfg.weaponOrder[choice]; + cfg.weaponOrder[choice] = cfg.weaponOrder[choice-1]; + cfg.weaponOrder[choice-1] = temp; + } + }*/ + return 0; +} + +int Hu_MenuSelectSingleplayer(mn_object_t *ob, mn_actionid_t action, void *parameters) +{ + DENG_UNUSED(parameters); + + if(MNA_ACTIVEOUT != action) return 1; + + if(IS_NETGAME) + { + Hu_MsgStart(MSG_ANYKEY, NEWGAME, NULL, 0, NULL); + return 0; + } + +#if __JHEXEN__ + Hu_MenuSetActivePage(Hu_MenuFindPageByName("PlayerClass")); +#elif __JHERETIC__ + Hu_MenuSetActivePage(Hu_MenuFindPageByName("Episode")); +#elif __JDOOM64__ + Hu_MenuSetActivePage(Hu_MenuFindPageByName("Skill")); +#else // __JDOOM__ + if(gameModeBits & (GM_ANY_DOOM2|GM_DOOM_CHEX)) + Hu_MenuSetActivePage(Hu_MenuFindPageByName("Skill")); + else + Hu_MenuSetActivePage(Hu_MenuFindPageByName("Episode")); +#endif + return 0; +} + +int Hu_MenuSelectMultiplayer(mn_object_t *obj, mn_actionid_t action, void *parameters) +{ + mn_page_t* multiplayerPage = Hu_MenuFindPageByName("Multiplayer"); + mn_object_t* labelObj = MN_MustFindObjectOnPage(multiplayerPage, 0, MNF_ID0); + mndata_button_t* btn = (mndata_button_t*)labelObj->_typedata; + + DENG_UNUSED(parameters); + if(MNA_ACTIVEOUT != action) return 1; + + // Set the appropriate label. + if(IS_NETGAME) + { + btn->text = "Disconnect"; + } + else + { + btn->text = "Join Game"; + } + Hu_MenuSetActivePage(multiplayerPage); + return 0; +} + +int Hu_MenuSelectJoinGame(mn_object_t *ob, mn_actionid_t action, void *parameters) +{ + DENG_UNUSED(ob); + DENG_UNUSED(parameters); + + if(MNA_ACTIVEOUT != action) return 1; + if(IS_NETGAME) + { + DD_Execute(false, "net disconnect"); + Hu_MenuCommand(MCMD_CLOSE); + return 0; + } + + DD_Execute(false, "net setup client"); + return 0; +} + +int Hu_MenuSelectPlayerSetup(mn_object_t *ob, mn_actionid_t action, void *parameters) +{ + mn_page_t* playerSetupPage = Hu_MenuFindPageByName("PlayerSetup"); + mn_object_t* mop = MN_MustFindObjectOnPage(playerSetupPage, 0, MNF_ID0); + mn_object_t* name = MN_MustFindObjectOnPage(playerSetupPage, 0, MNF_ID1); + mn_object_t* color = MN_MustFindObjectOnPage(playerSetupPage, 0, MNF_ID3); +#if __JHEXEN__ + mn_object_t* class_; +#endif + + DENG_UNUSED(ob); + DENG_UNUSED(parameters); + if(MNA_ACTIVEOUT != action) return 1; + +#if __JHEXEN__ + MNMobjPreview_SetMobjType(mop, PCLASS_INFO(cfg.netClass)->mobjType); + MNMobjPreview_SetPlayerClass(mop, cfg.netClass); +#else + MNMobjPreview_SetMobjType(mop, MT_PLAYER); + MNMobjPreview_SetPlayerClass(mop, PCLASS_PLAYER); +#endif + MNMobjPreview_SetTranslationClass(mop, 0); + MNMobjPreview_SetTranslationMap(mop, cfg.netColor); + + MNList_SelectItemByValue(color, MNLIST_SIF_NO_ACTION, cfg.netColor); +#if __JHEXEN__ + class_ = MN_MustFindObjectOnPage(playerSetupPage, 0, MNF_ID2); + MNList_SelectItemByValue(class_, MNLIST_SIF_NO_ACTION, cfg.netClass); +#endif + + MNEdit_SetText(name, MNEDIT_STF_NO_ACTION|MNEDIT_STF_REPLACEOLD, Con_GetString("net-name")); + + Hu_MenuSetActivePage(playerSetupPage); + return 0; +} + +#if __JHEXEN__ +int Hu_MenuSelectPlayerSetupPlayerClass(mn_object_t *ob, mn_actionid_t action, void *parameters) +{ + int selection; + + DENG_UNUSED(parameters); + if(MNA_MODIFIED != action) return 1; + + selection = MNList_Selection(ob); + if(selection >= 0) + { + mn_object_t* mop = MN_MustFindObjectOnPage(MNObject_Page(ob), 0, MNF_ID0); + MNMobjPreview_SetPlayerClass(mop, selection); + MNMobjPreview_SetMobjType(mop, PCLASS_INFO(selection)->mobjType); + } + return 0; +} +#endif + +int Hu_MenuSelectPlayerColor(mn_object_t *ob, mn_actionid_t action, void *parameters) +{ + int selection; + + DENG_UNUSED(parameters); + if(MNA_MODIFIED != action) return 1; + + // The color translation map is stored in the list item data member. + selection = MNList_ItemData(ob, MNList_Selection(ob)); + if(selection >= 0) + { + mn_object_t* mop = MN_MustFindObjectOnPage(MNObject_Page(ob), 0, MNF_ID0); + MNMobjPreview_SetTranslationMap(mop, selection); + } + return 0; +} + +int Hu_MenuSelectAcceptPlayerSetup(mn_object_t *ob, mn_actionid_t action, void *parameters) +{ + mn_object_t* plrNameEdit = MN_MustFindObjectOnPage(MNObject_Page(ob), 0, MNF_ID1); +#if __JHEXEN__ + mn_object_t* plrClassList = MN_MustFindObjectOnPage(MNObject_Page(ob), 0, MNF_ID2); +#endif + mn_object_t* plrColorList = MN_MustFindObjectOnPage(MNObject_Page(ob), 0, MNF_ID3); + char buf[300]; + + DENG_UNUSED(parameters); + +#if __JHEXEN__ + cfg.netClass = MNList_Selection(plrClassList); +#endif + // The color translation map is stored in the list item data member. + cfg.netColor = MNList_ItemData(plrColorList, MNList_Selection(plrColorList)); + + if(MNA_ACTIVEOUT != action) return 1; + + strcpy(buf, "net-name "); + M_StrCatQuoted(buf, Str_Text(MNEdit_Text(plrNameEdit)), 300); + DD_Execute(false, buf); + + if(IS_NETGAME) + { + strcpy(buf, "setname "); + M_StrCatQuoted(buf, Str_Text(MNEdit_Text(plrNameEdit)), 300); + DD_Execute(false, buf); +#if __JHEXEN__ + // Must do 'setclass' first; the real class and color do not change + // until the server sends us a notification -- this means if we do + // 'setcolor' first, the 'setclass' after it will override the color + // change (or such would appear to be the case). + DD_Executef(false, "setclass %i", cfg.netClass); +#endif + DD_Executef(false, "setcolor %i", cfg.netColor); + } + + Hu_MenuSetActivePage(Hu_MenuFindPageByName("Multiplayer")); + return 0; +} + +int Hu_MenuSelectQuitGame(mn_object_t *ob, mn_actionid_t action, void *parameters) +{ + DENG_UNUSED(ob); + DENG_UNUSED(parameters); + if(MNA_ACTIVEOUT != action) return 1; + G_QuitGame(); + return 0; +} + +int Hu_MenuSelectEndGame(mn_object_t *ob, mn_actionid_t action, void *parameters) +{ + DENG_UNUSED(ob); + DENG_UNUSED(parameters); + if(MNA_ACTIVEOUT != action) return 1; + G_EndGame(); + return 0; +} + +int Hu_MenuSelectLoadGame(mn_object_t *ob, mn_actionid_t action, void *parameters) +{ + DENG_UNUSED(ob); + DENG_UNUSED(parameters); + + if(MNA_ACTIVEOUT != action) return 1; + + if(!Get(DD_DEDICATED)) + { + if(IS_CLIENT && !Get(DD_PLAYBACK)) + { + Hu_MsgStart(MSG_ANYKEY, LOADNET, NULL, 0, NULL); + return 0; + } + } + + Hu_MenuUpdateGameSaveWidgets(); + Hu_MenuSetActivePage(Hu_MenuFindPageByName("LoadGame")); + return 0; +} + +int Hu_MenuSelectSaveGame(mn_object_t *ob, mn_actionid_t action, void *parameters) +{ + player_t* player = &players[CONSOLEPLAYER]; + + DENG_UNUSED(ob); + DENG_UNUSED(parameters); + + if(MNA_ACTIVEOUT != action) return 1; + if(!Get(DD_DEDICATED)) + { + if(IS_CLIENT) + { +#if __JDOOM__ || __JDOOM64__ + Hu_MsgStart(MSG_ANYKEY, SAVENET, NULL, 0, NULL); +#endif + return 0; + } + + if(G_GameState() != GS_MAP) + { + Hu_MsgStart(MSG_ANYKEY, SAVEOUTMAP, NULL, 0, NULL); + return 0; + } + + if(player->playerState == PST_DEAD) + { + Hu_MsgStart(MSG_ANYKEY, SAVEDEAD, NULL, 0, NULL); + return 0; + } + } + + Hu_MenuCommand(MCMD_OPEN); + Hu_MenuUpdateGameSaveWidgets(); + Hu_MenuSetActivePage(Hu_MenuFindPageByName("SaveGame")); + return 0; +} + +#if __JHEXEN__ +int Hu_MenuSelectPlayerClass(mn_object_t *ob, mn_actionid_t action, void *parameters) +{ + mn_page_t* skillPage = Hu_MenuFindPageByName("Skill"); + int option = ob->data2; + mn_object_t* skillObj; + const char* text; + + DENG_UNUSED(parameters); + + if(MNA_ACTIVEOUT != action) return 1; + if(IS_NETGAME) + { + P_SetMessage(&players[CONSOLEPLAYER], LMF_NO_HIDE, "You can't start a new game from within a netgame!"); + return 0; + } + + if(option < 0) + { // Random class. + // Number of user-selectable classes. + mnPlrClass = (menuTime / 5) % 3; + } + else + { + mnPlrClass = option; + } + + skillObj = MN_MustFindObjectOnPage(skillPage, 0, MNF_ID0); + text = GET_TXT(PCLASS_INFO(mnPlrClass)->skillModeNames[SM_BABY]); + ((mndata_button_t*)skillObj->_typedata)->text = text; + MNObject_SetShortcut(skillObj, text[0]); + + skillObj = MN_MustFindObjectOnPage(skillPage, 0, MNF_ID1); + text = GET_TXT(PCLASS_INFO(mnPlrClass)->skillModeNames[SM_EASY]); + ((mndata_button_t*)skillObj->_typedata)->text = text; + MNObject_SetShortcut(skillObj, text[0]); + + skillObj = MN_MustFindObjectOnPage(skillPage, 0, MNF_ID2); + text = GET_TXT(PCLASS_INFO(mnPlrClass)->skillModeNames[SM_MEDIUM]); + ((mndata_button_t*)skillObj->_typedata)->text = text; + MNObject_SetShortcut(skillObj, text[0]); + + skillObj = MN_MustFindObjectOnPage(skillPage, 0, MNF_ID3); + text = GET_TXT(PCLASS_INFO(mnPlrClass)->skillModeNames[SM_HARD]); + ((mndata_button_t*)skillObj->_typedata)->text = text; + MNObject_SetShortcut(skillObj, text[0]); + + skillObj = MN_MustFindObjectOnPage(skillPage, 0, MNF_ID4); + text = GET_TXT(PCLASS_INFO(mnPlrClass)->skillModeNames[SM_NIGHTMARE]); + ((mndata_button_t*)skillObj->_typedata)->text = text; + MNObject_SetShortcut(skillObj, text[0]); + + switch(mnPlrClass) + { + case PCLASS_FIGHTER: MNPage_SetX(skillPage, 120); break; + case PCLASS_CLERIC: MNPage_SetX(skillPage, 116); break; + case PCLASS_MAGE: MNPage_SetX(skillPage, 112); break; + } + Hu_MenuSetActivePage(skillPage); + return 0; +} + +int Hu_MenuFocusOnPlayerClass(mn_object_t *ob, mn_actionid_t action, void *parameters) +{ + playerclass_t plrClass = (playerclass_t)ob->data2; + mn_object_t* mop; + + DENG_UNUSED(parameters); + if(MNA_FOCUS != action) return 1; + + mop = MN_MustFindObjectOnPage(MNObject_Page(ob), 0, MNF_ID0); + MNMobjPreview_SetPlayerClass(mop, plrClass); + MNMobjPreview_SetMobjType(mop, (PCLASS_NONE == plrClass? MT_NONE : PCLASS_INFO(plrClass)->mobjType)); + + Hu_MenuDefaultFocusAction(ob, action, parameters); + return 0; +} +#endif + +#if __JDOOM__ || __JHERETIC__ +int Hu_MenuFocusEpisode(mn_object_t *ob, mn_actionid_t action, void *parameters) +{ + DENG_UNUSED(parameters); + if(MNA_FOCUS != action) return 1; + mnEpisode = ob->data2; + Hu_MenuDefaultFocusAction(ob, action, parameters); + return 0; +} + +int Hu_MenuConfirmOrderCommericalVersion(msgresponse_t response, int userValue, void* userPointer) +{ + G_StartHelp(); + return true; +} + +int Hu_MenuActivateNotSharewareEpisode(mn_object_t *ob, mn_actionid_t action, void *parameters) +{ + DENG_UNUSED(ob); + DENG_UNUSED(parameters); + if(MNA_ACTIVEOUT != action) return 1; + Hu_MsgStart(MSG_ANYKEY, SWSTRING, Hu_MenuConfirmOrderCommericalVersion, 0, NULL); + return 0; +} +#endif + +int Hu_MenuFocusSkillMode(mn_object_t *ob, mn_actionid_t action, void *parameters) +{ + assert(ob); + DENG_UNUSED(parameters); + if(MNA_FOCUS != action) return 1; + mnSkillmode = (skillmode_t)ob->data2; + Hu_MenuDefaultFocusAction(ob, action, parameters); + return 0; +} + +#if __JDOOM__ +int Hu_MenuConfirmInitNewGame(msgresponse_t response, int userValue, void* userPointer) +{ + if(response == MSG_YES) + { + Hu_MenuInitNewGame(true); + } + return true; +} +#endif + +void Hu_MenuInitNewGame(dd_bool confirmed) +{ + GameRuleset newRules = gameRules; + Uri *newMapUri = 0; + +#if __JDOOM__ + if(!confirmed && SM_NIGHTMARE == mnSkillmode) + { + Hu_MsgStart(MSG_YESNO, NIGHTMARE, Hu_MenuConfirmInitNewGame, 0, NULL); + return; + } +#endif + + Hu_MenuCommand(chooseCloseMethod()); + +#if __JHEXEN__ + cfg.playerClass[CONSOLEPLAYER] = playerclass_t(mnPlrClass); +#endif + + newRules.skill = mnSkillmode; +#if __JHEXEN__ + newMapUri = G_ComposeMapUri(mnEpisode, P_TranslateMap(0)); +#else + newMapUri = G_ComposeMapUri(mnEpisode, 0); +#endif + + G_DeferredNewGame(newMapUri, 0/*default*/, &newRules); + Uri_Delete(newMapUri); +} + +int Hu_MenuActionInitNewGame(mn_object_t *ob, mn_actionid_t action, void *parameters) +{ + DENG_UNUSED(ob); + DENG_UNUSED(parameters); + if(MNA_ACTIVEOUT != action) return 1; + Hu_MenuInitNewGame(false); + return 0; +} + +int Hu_MenuSelectControlPanelLink(mn_object_t *ob, mn_actionid_t action, void *parameters) +{ +#define NUM_PANEL_NAMES 1 + + static const char* panelNames[NUM_PANEL_NAMES] = { + "taskbar" //, + //"panel audio", + //"panel input" + }; + int idx = ob->data2; + + DENG_UNUSED(parameters); + if(MNA_ACTIVEOUT != action) return 1; + + if(idx < 0 || idx > NUM_PANEL_NAMES - 1) + idx = 0; + + DD_Execute(true, panelNames[idx]); + return 0; + +#undef NUM_PANEL_NAMES +} + +D_CMD(MenuOpen) +{ + if(argc > 1) + { + if(!stricmp(argv[1], "open")) + { + Hu_MenuCommand(MCMD_OPEN); + return true; + } + if(!stricmp(argv[1], "close")) + { + Hu_MenuCommand(MCMD_CLOSE); + return true; + } + + { + mn_page_t *page = Hu_MenuFindPageByName(argv[1]); + if(page) + { + Hu_MenuCommand(MCMD_OPEN); + Hu_MenuSetActivePage(page); + return true; + } + } + return false; + } + + Hu_MenuCommand(!menuActive? MCMD_OPEN : MCMD_CLOSE); + return true; +} + +/** + * Routes console commands for menu actions and navigation into the menu subsystem. + */ +D_CMD(MenuCommand) +{ + if(menuActive) + { + const char* cmd = argv[0] + 4; + if(!stricmp(cmd, "up")) + { + Hu_MenuCommand(MCMD_NAV_UP); + return true; + } + if(!stricmp(cmd, "down")) + { + Hu_MenuCommand(MCMD_NAV_DOWN); + return true; + } + if(!stricmp(cmd, "left")) + { + Hu_MenuCommand(MCMD_NAV_LEFT); + return true; + } + if(!stricmp(cmd, "right")) + { + Hu_MenuCommand(MCMD_NAV_RIGHT); + return true; + } + if(!stricmp(cmd, "back")) + { + Hu_MenuCommand(MCMD_NAV_OUT); + return true; + } + if(!stricmp(cmd, "delete")) + { + Hu_MenuCommand(MCMD_DELETE); + return true; + } + if(!stricmp(cmd, "select")) + { + Hu_MenuCommand(MCMD_SELECT); + return true; + } + if(!stricmp(cmd, "pagedown")) + { + Hu_MenuCommand(MCMD_NAV_PAGEDOWN); + return true; + } + if(!stricmp(cmd, "pageup")) + { + Hu_MenuCommand(MCMD_NAV_PAGEUP); + return true; + } + } + return false; +} diff --git a/doomsday/plugins/doom/include/d_console.h b/doomsday/plugins/doom/include/d_console.h index c621e38a72..c0f32a1f69 100644 --- a/doomsday/plugins/doom/include/d_console.h +++ b/doomsday/plugins/doom/include/d_console.h @@ -33,6 +33,14 @@ # error "Using jDoom headers without __JDOOM__" #endif +#ifdef __cplusplus +extern "C" { +#endif + void G_ConsoleRegistration(void); +#ifdef __cplusplus +} // extern "C" +#endif + #endif /* LIBDOOM_DCONSOLE_H */ diff --git a/doomsday/plugins/doom/include/m_cheat.h b/doomsday/plugins/doom/include/m_cheat.h index aa9c5a2f18..0a97e72915 100644 --- a/doomsday/plugins/doom/include/m_cheat.h +++ b/doomsday/plugins/doom/include/m_cheat.h @@ -27,9 +27,17 @@ # error "Using jDoom headers without __JDOOM__" #endif +#ifdef __cplusplus +extern "C" { +#endif + /** * Register event sequence callbacks for all cheats. */ void G_RegisterCheats(void); +#ifdef __cplusplus +} // extern "C" +#endif + #endif // LIBDOOM_M_CHEAT_H diff --git a/doomsday/plugins/doom/include/p_setup.h b/doomsday/plugins/doom/include/p_setup.h index 4dd703fc81..d3485ac0e9 100644 --- a/doomsday/plugins/doom/include/p_setup.h +++ b/doomsday/plugins/doom/include/p_setup.h @@ -50,8 +50,17 @@ enum { MO_TAG }; +#ifdef __cplusplus +extern "C" { +#endif + void P_RegisterMapObjs(void); int P_HandleMapDataPropertyValue(uint id, int dtype, int prop, valuetype_t type, void *data); int P_HandleMapObjectStatusReport(int code, uint id, int dtype, void *data); + +#ifdef __cplusplus +} // extern "C" +#endif + #endif diff --git a/doomsday/plugins/doom64/include/d_console.h b/doomsday/plugins/doom64/include/d_console.h index d042408345..cc6463b223 100644 --- a/doomsday/plugins/doom64/include/d_console.h +++ b/doomsday/plugins/doom64/include/d_console.h @@ -33,6 +33,14 @@ # error "Using jDoom64 headers without __JDOOM64__" #endif +#ifdef __cplusplus +extern "C" { +#endif + void G_ConsoleRegistration(void); +#ifdef __cplusplus +} // extern "C" +#endif + #endif /* LIBDOOM64_CONSOLE_H */ diff --git a/doomsday/plugins/doom64/include/p_setup.h b/doomsday/plugins/doom64/include/p_setup.h index 5dab7593bf..a8f364f253 100644 --- a/doomsday/plugins/doom64/include/p_setup.h +++ b/doomsday/plugins/doom64/include/p_setup.h @@ -66,10 +66,19 @@ enum { MO_XX2 }; +#ifdef __cplusplus +extern "C" { +#endif + void P_RegisterMapObjs(void); int P_HandleMapDataPropertyValue(uint id, int dtype, int prop, valuetype_t type, void* data); int P_HandleMapObjectStatusReport(int code, uint id, int dtype, void* data); + +#ifdef __cplusplus +} // extern "C" +#endif + #endif /* LIBDOOM64_SETUP_H */ diff --git a/doomsday/plugins/heretic/include/h_console.h b/doomsday/plugins/heretic/include/h_console.h index 167b3f332f..d89d3c6bdc 100644 --- a/doomsday/plugins/heretic/include/h_console.h +++ b/doomsday/plugins/heretic/include/h_console.h @@ -33,6 +33,14 @@ # error "Using jHeretic headers without __JHERETIC__" #endif +#ifdef __cplusplus +extern "C" { +#endif + void G_ConsoleRegistration(void); +#ifdef __cplusplus +} // extern "C" +#endif + #endif /* LIBHERETIC_CONSOLE_H */ diff --git a/doomsday/plugins/heretic/include/in_lude.h b/doomsday/plugins/heretic/include/in_lude.h index 6e68f71c7e..a20483dc16 100644 --- a/doomsday/plugins/heretic/include/in_lude.h +++ b/doomsday/plugins/heretic/include/in_lude.h @@ -34,9 +34,13 @@ #include "h_player.h" -extern dd_bool intermission; -extern int interState; -extern int interTime; +DENG_EXTERN_C dd_bool intermission; +DENG_EXTERN_C int interState; +DENG_EXTERN_C int interTime; + +#ifdef __cplusplus +extern "C" { +#endif /// To be called to register the console commands and variables of this module. void WI_Register(void); @@ -56,4 +60,8 @@ void IN_InitStats(void); void IN_InitDeathmatchStats(void); void IN_InitNetgameStats(void); +#ifdef __cplusplus +} // extern "C" +#endif + #endif diff --git a/doomsday/plugins/heretic/include/m_cheat.h b/doomsday/plugins/heretic/include/m_cheat.h index 18bc5c6e13..543c70ad61 100644 --- a/doomsday/plugins/heretic/include/m_cheat.h +++ b/doomsday/plugins/heretic/include/m_cheat.h @@ -27,9 +27,17 @@ # error "Using jHeretic headers without __JHERETIC__" #endif +#ifdef __cplusplus +extern "C" { +#endif + /** * Register event sequence callbacks for all cheats. */ void G_RegisterCheats(void); +#ifdef __cplusplus +} // extern "C" +#endif + #endif // LIBHERETIC_M_CHEAT_H diff --git a/doomsday/plugins/heretic/include/p_setup.h b/doomsday/plugins/heretic/include/p_setup.h index f112801984..3364750bdb 100644 --- a/doomsday/plugins/heretic/include/p_setup.h +++ b/doomsday/plugins/heretic/include/p_setup.h @@ -50,8 +50,17 @@ enum { MO_TAG }; +#ifdef __cplusplus +extern "C" { +#endif + void P_RegisterMapObjs(void); int P_HandleMapDataPropertyValue(uint id, int dtype, int prop, valuetype_t type, void* data); int P_HandleMapObjectStatusReport(int code, uint id, int dtype, void* data); + +#ifdef __cplusplus +} // extern "C" +#endif + #endif diff --git a/doomsday/plugins/hexen/include/in_lude.h b/doomsday/plugins/hexen/include/in_lude.h index 5c2d1b56b0..1c6e1f4738 100644 --- a/doomsday/plugins/hexen/include/in_lude.h +++ b/doomsday/plugins/hexen/include/in_lude.h @@ -32,8 +32,14 @@ # error "Using jHexen headers without __JHEXEN__" #endif -extern dd_bool intermission; -extern int interState; +#include "h2def.h" + +DENG_EXTERN_C dd_bool intermission; +DENG_EXTERN_C int interState; + +#ifdef __cplusplus +extern "C" { +#endif /// To be called to register the console commands and variables of this module. void WI_Register(void); @@ -44,4 +50,8 @@ void IN_Ticker(void); void IN_Drawer(void); void IN_SkipToNext(void); +#ifdef __cplusplus +} // extern "C" +#endif + #endif diff --git a/doomsday/plugins/hexen/include/m_cheat.h b/doomsday/plugins/hexen/include/m_cheat.h index c905f68ae9..c68692fa88 100644 --- a/doomsday/plugins/hexen/include/m_cheat.h +++ b/doomsday/plugins/hexen/include/m_cheat.h @@ -27,9 +27,17 @@ # error "Using jHexen headers without __JHEXEN__" #endif +#ifdef __cplusplus +extern "C" { +#endif + /** * Register event sequence callbacks for all cheats. */ void G_RegisterCheats(void); +#ifdef __cplusplus +} // extern "C" +#endif + #endif // LIBHEXEN_M_CHEAT_H diff --git a/doomsday/plugins/hexen/include/p_setup.h b/doomsday/plugins/hexen/include/p_setup.h index bddbb86507..a131a12b72 100644 --- a/doomsday/plugins/hexen/include/p_setup.h +++ b/doomsday/plugins/hexen/include/p_setup.h @@ -57,8 +57,17 @@ enum { MO_SPECIAL }; +#ifdef __cplusplus +extern "C" { +#endif + void P_RegisterMapObjs(void); int P_HandleMapDataPropertyValue(uint id, int dtype, int prop, valuetype_t type, void *data); int P_HandleMapObjectStatusReport(int code, uint id, int dtype, void *data); + +#ifdef __cplusplus +} // extern "C" +#endif + #endif diff --git a/doomsday/plugins/hexen/include/x_console.h b/doomsday/plugins/hexen/include/x_console.h index ce11fa4d1b..14c840a656 100644 --- a/doomsday/plugins/hexen/include/x_console.h +++ b/doomsday/plugins/hexen/include/x_console.h @@ -32,6 +32,14 @@ # error "Using jHexen headers without __JHEXEN__" #endif +#ifdef __cplusplus +extern "C" { +#endif + void G_ConsoleRegistration(void); +#ifdef __cplusplus +} // extern "C" +#endif + #endif /* LIBHEXEN_CONSOLE_H */