diff --git a/src/k_menu.h b/src/k_menu.h index f5f4f20e7..3d0cc3272 100644 --- a/src/k_menu.h +++ b/src/k_menu.h @@ -268,6 +268,10 @@ extern menu_t OPTIONS_DataDiscordDef; extern menuitem_t OPTIONS_DataErase[]; extern menu_t OPTIONS_DataEraseDef; +// EXTRAS +extern menuitem_t EXTRAS_Main[]; +extern menu_t EXTRAS_MainDef; + // PAUSE extern menuitem_t PAUSE_Main[]; extern menu_t PAUSE_MainDef; @@ -565,6 +569,27 @@ void M_EraseData(INT32 choice); // For data erasing void M_VideoModeMenu(INT32 choice); void M_HandleVideoModes(INT32 ch); + +// Extras menu: +extern struct extrasmenu_s { + + tic_t ticker; // How long the menu's been open for + INT16 offset; // To make the icons move smoothly when we transition! + + // For moving the button when we get into a submenu. it's smooth and cool! (normal x/y and target x/y.) + // this is only used during menu transitions. (and will probably remain unused until we get the statistics menu + INT16 extx; + INT16 exty; + INT16 textx; + INT16 texty; + +} extrasmenu; + +void M_InitExtras(INT32 choice); // init for the struct +void M_ExtrasTick(void); +boolean M_ExtrasInputs(INT32 ch); +boolean M_ExtrasQuit(void); // resets buttons when you quit + // Pause menu: // Keep track of some pause menu data for visual goodness. @@ -660,6 +685,10 @@ void M_DrawGenericOptions(void); void M_DrawVideoModes(void); void M_DrawItemToggles(void); +// Extras menu: +void M_DrawExtrasMovingButton(void); +void M_DrawExtras(void); + // Misc menus: #define LOCATIONSTRING1 "Visit \x83SRB2.ORG/MODS\x80 to get & make addons!" #define LOCATIONSTRING2 "Visit \x88SRB2.ORG/MODS\x80 to get & make addons!" diff --git a/src/k_menudef.c b/src/k_menudef.c index 9754ae366..6260e9ea5 100644 --- a/src/k_menudef.c +++ b/src/k_menudef.c @@ -31,9 +31,9 @@ menuitem_t MainMenu[] = "Cut to the chase and start the race!", NULL, M_CharacterSelectInit, 0, 0}, - {IT_STRING, "Extra", + {IT_STRING | IT_CALL, "Extras", "Check out some bonus features.", "MENUI001", - NULL, 0, 0}, + M_InitExtras, 0, 0}, {IT_STRING, "Options", "Configure your controls, settings, and preferences.", NULL, @@ -1103,6 +1103,40 @@ menu_t OPTIONS_DataEraseDef = { NULL, }; + + +// extras menu +menuitem_t EXTRAS_Main[] = +{ + + {IT_STRING | IT_CALL, "Addons", "Add files to customize your experience.", + NULL, NULL, 0, 0}, + + {IT_STRING | IT_CALL, "Replay Hut", "Play the replays you've saved throughout your many races & battles!", + NULL, NULL, 0, 0}, + + {IT_STRING | IT_CALL, "Statistics", "Look back on some of your greatest achievements such as your playtime and wins!", + NULL, NULL, 0, 0}, + + {IT_STRING | IT_TRANSTEXT, "Extras Checklist", "View the requirement for some of the secret content you can unlock!", + NULL, NULL, 0, 0}, +}; + +// the extras menu essentially reuses the options menu stuff +menu_t EXTRAS_MainDef = { + sizeof (EXTRAS_Main) / sizeof (menuitem_t), + &MainDef, + 0, + EXTRAS_Main, + 0, 0, + 0, 0, + 2, 10, + M_DrawExtras, + M_ExtrasTick, + NULL, + M_ExtrasInputs +}; + // ------------------- // In-game/pause menus // ------------------- diff --git a/src/k_menudraw.c b/src/k_menudraw.c index f529585d2..1ddbd40d4 100644 --- a/src/k_menudraw.c +++ b/src/k_menudraw.c @@ -2108,6 +2108,60 @@ void M_DrawItemToggles(void) } +// EXTRAS: +// Copypasted from options but separate either way in case we want it to look more unique later down the line. +void M_DrawExtrasMovingButton(void) +{ + patch_t *butt = W_CachePatchName("OPT_BUTT", PU_CACHE); + UINT8 *c = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_PLAGUE, GTC_CACHE); + + V_DrawFixedPatch((extrasmenu.extx)*FRACUNIT, (extrasmenu.exty)*FRACUNIT, FRACUNIT, 0, butt, c); + V_DrawCenteredGamemodeString((extrasmenu.extx)-3, (extrasmenu.exty) - 16, V_ALLOWLOWERCASE, c, EXTRAS_MainDef.menuitems[EXTRAS_MainDef.lastOn].text); +} + +void M_DrawExtras(void) +{ + UINT8 i; + INT32 x = 140 - (48*itemOn) + extrasmenu.offset; + INT32 y = 70 + extrasmenu.offset; + patch_t *buttback = W_CachePatchName("OPT_BUTT", PU_CACHE); + patch_t *bg = W_CachePatchName("M_XTRABG", PU_CACHE); + + UINT8 *c = NULL; + + V_DrawFixedPatch(0, 0, FRACUNIT, 0, bg, NULL); + + for (i=0; i < currentMenu->numitems; i++) + { + INT32 py = y - (itemOn*48); + INT32 px = x - menutransition.tics*64; + INT32 tflag = 0; + + if (i == itemOn) + c = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_PLAGUE, GTC_CACHE); + else + c = R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_BLACK, GTC_CACHE); + + if (currentMenu->menuitems[i].status & IT_TRANSTEXT) + tflag = V_TRANSLUCENT; + + if (!(menutransition.tics && i == itemOn)) + { + V_DrawFixedPatch(px*FRACUNIT, py*FRACUNIT, FRACUNIT, 0, buttback, c); + V_DrawCenteredGamemodeString(px-3, py - 16, V_ALLOWLOWERCASE|tflag, (i == itemOn ? c : NULL), currentMenu->menuitems[i].text); + } + + y += 48; + x += 48; + } + + M_DrawMenuTooltips(); + + if (menutransition.tics) + M_DrawExtrasMovingButton(); + +} + // // INGAME / PAUSE MENUS // diff --git a/src/k_menufunc.c b/src/k_menufunc.c index 902a38d33..cd5b09a94 100644 --- a/src/k_menufunc.c +++ b/src/k_menufunc.c @@ -3378,6 +3378,103 @@ void M_HandleItemToggles(INT32 choice) } +// Extras menu; +// this is copypasted from the options menu but all of these are different functions in case we ever want it to look more unique + +struct extrasmenu_s extrasmenu; + +void M_InitExtras(INT32 choice) +{ + (void)choice; + + extrasmenu.ticker = 0; + extrasmenu.offset = 0; + + extrasmenu.extx = 0; + extrasmenu.exty = 0; + extrasmenu.textx = 0; + extrasmenu.texty = 0; + + M_SetupNextMenu(&EXTRAS_MainDef, false); +} + +// For statistics, will maybe remain unused for a while +boolean M_ExtrasQuit(void) +{ + extrasmenu.textx = 140-1; + extrasmenu.texty = 70+1; + + return true; // Always allow quitting, duh. +} + +void M_ExtrasTick(void) +{ + extrasmenu.offset /= 2; + extrasmenu.ticker++; + + extrasmenu.extx += (extrasmenu.textx - extrasmenu.extx)/2; + extrasmenu.exty += (extrasmenu.texty - extrasmenu.exty)/2; + + if (abs(extrasmenu.extx - extrasmenu.exty) < 2) + { + extrasmenu.extx = extrasmenu.textx; + extrasmenu.exty = extrasmenu.texty; // Avoid awkward 1 px errors. + } + + // Move the button for cool animations + if (currentMenu == &EXTRAS_MainDef) + { + M_ExtrasQuit(); // reset the options button. + } + else + { + extrasmenu.textx = 160; + extrasmenu.texty = 50; + } +} + +boolean M_ExtrasInputs(INT32 ch) +{ + + switch (ch) + { + case KEY_DOWNARROW: + { + extrasmenu.offset += 48; + M_NextOpt(); + S_StartSound(NULL, sfx_menu1); + + if (itemOn == 0) + extrasmenu.offset -= currentMenu->numitems*48; + + return true; + } + case KEY_UPARROW: + { + extrasmenu.offset -= 48; + M_PrevOpt(); + S_StartSound(NULL, sfx_menu1); + + if (itemOn == currentMenu->numitems-1) + extrasmenu.offset += currentMenu->numitems*48; + + return true; + } + case KEY_ENTER: + { + + if (currentMenu->menuitems[itemOn].status & IT_TRANSTEXT) + return true; // No. + + extrasmenu.extx = 140; + extrasmenu.exty = 70; // Default position for the currently selected option. + + return false; // Don't eat. + } + } + return false; +} + // ===================== // PAUSE / IN-GAME MENUS // =====================