diff --git a/src/k_menu.h b/src/k_menu.h index 3165de130..5dea1c177 100644 --- a/src/k_menu.h +++ b/src/k_menu.h @@ -259,6 +259,8 @@ typedef enum ta_start, } ta_e; +// If you add another Time Attach submenu, remember to catch level-select.c's music/bgroutine update + extern menuitem_t PLAY_TAReplay[]; extern menu_t PLAY_TAReplayDef; @@ -1184,6 +1186,7 @@ boolean M_DrawCharacterSprite(INT16 x, INT16 y, INT16 skin, UINT8 spr2, UINT8 ro void M_DrawCup(cupheader_t *cup, fixed_t x, fixed_t y, INT32 lockedTic, boolean isTrophy, UINT8 placement); void M_DrawCupSelect(void); void M_DrawLevelSelect(void); +void M_DrawSealedBack(void); void M_DrawTimeAttack(void); void M_DrawRaceDifficulty(void); diff --git a/src/k_menudraw.c b/src/k_menudraw.c index 9c9f67ead..47569a85f 100644 --- a/src/k_menudraw.c +++ b/src/k_menudraw.c @@ -3080,6 +3080,47 @@ void M_DrawLevelSelect(void) M_DrawCupTitle(tay, &levellist.levelsearch); } +static boolean M_LevelSelectToTimeAttackTransitionHelper(void) +{ + if (menutransition.tics == 0) + return false; + + return \ + ( + menutransition.startmenu == &PLAY_LevelSelectDef + && menutransition.endmenu == &PLAY_TimeAttackDef + ) || ( + menutransition.endmenu == &PLAY_LevelSelectDef + && menutransition.startmenu == &PLAY_TimeAttackDef + ); +} + +void M_DrawSealedBack(void) +{ + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); + + if (currentMenu != &PLAY_LevelSelectDef + && currentMenu != &PLAY_CupSelectDef) + return; + + INT32 translucencylevel = 7; + if (M_LevelSelectToTimeAttackTransitionHelper()) + { + translucencylevel += menutransition.tics/3; + + if (translucencylevel >= 10) + return; + } + + V_DrawFixedPatch( + 0, 0, + FRACUNIT, + translucencylevel << V_ALPHASHIFT, + W_CachePatchName("MENUI008", PU_CACHE), + R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_BLACK, GTC_CACHE) + ); +} + void M_DrawTimeAttack(void) { UINT16 map = levellist.choosemap; @@ -3088,27 +3129,95 @@ void M_DrawTimeAttack(void) INT16 rightedge = 149+t+155; INT16 opty = 140; INT32 w; - patch_t *minimap = NULL; UINT8 i; - M_DrawLevelSelectBlock(0, 2, map, true, false); - - //V_DrawFill(24-t, 82, 100, 100, 36); // size test - V_DrawScaledPatch(149+t, 70, 0, W_CachePatchName("BESTTIME", PU_CACHE)); - if (currentMenu == &PLAY_TimeAttackDef && mapheaderinfo[map]) + if (!mapheaderinfo[map]) { - tic_t timerec = 0; - tic_t laprec = 0; + V_DrawRightAlignedString(rightedge-12, opty, 0, "No map!?"); + return; + } + + { + patch_t *minimap = NULL; + INT32 minimapx = 76, minimapy = 130; + + if (M_LevelSelectToTimeAttackTransitionHelper()) + minimapx -= t; + + if (levellist.newgametype == GT_SPECIAL) + { + // Star Within The Seal + +#define SEAL_PULSELEN ((6*TICRATE)/5) // The rate of O_SSTAR3 + INT32 crossfade = (timeattackmenu.ticker % (2*SEAL_PULSELEN)) - SEAL_PULSELEN; + if (crossfade < 0) + crossfade = -crossfade; + crossfade = (crossfade * 10)/SEAL_PULSELEN; +#undef SEAL_PULSELEN + + if (crossfade != 10) + { + minimap = W_CachePatchName( + "K_FINB05", + PU_CACHE + ); + + V_DrawScaledPatch( + minimapx, minimapy, + 0, minimap + ); + } + + if (crossfade != 0) + { + minimap = W_CachePatchName( + "K_FINB04", + PU_CACHE + ); + + V_DrawScaledPatch( + minimapx, minimapy, + (10-crossfade)<minimapPic)) + { + V_DrawScaledPatch( + minimapx - (SHORT(minimap->width)/2), + minimapy - (SHORT(minimap->height)/2), + 0, minimap + ); + } + } + + if (currentMenu == &PLAY_TimeAttackDef) + { + tic_t timerec = mapheaderinfo[map]->records.time; + tic_t laprec = mapheaderinfo[map]->records.lap; UINT32 timeheight = 82; - if ((minimap = mapheaderinfo[map]->minimapPic)) - V_DrawScaledPatch(24-t, 82, 0, minimap); - - timerec = mapheaderinfo[map]->records.time; - laprec = mapheaderinfo[map]->records.lap; - if ((gametypes[levellist.newgametype]->rules & GTR_CIRCUIT) && (mapheaderinfo[map]->numlaps != 1)) { @@ -3142,6 +3251,9 @@ void M_DrawTimeAttack(void) else opty = 80; + // Done after to overlay material + M_DrawLevelSelectBlock(0, 2, map, true, false); + for (i = 0; i < currentMenu->numitems; i++) { UINT32 f = (i == itemOn) ? highlightflags : 0; diff --git a/src/menus/play-local-race-time-attack.c b/src/menus/play-local-race-time-attack.c index 2074a3326..5f1ed6954 100644 --- a/src/menus/play-local-race-time-attack.c +++ b/src/menus/play-local-race-time-attack.c @@ -121,7 +121,7 @@ menu_t PLAY_TAReplayDef = { 2, 5, M_DrawTimeAttack, NULL, - NULL, + M_TimeAttackTick, NULL, NULL, NULL @@ -167,7 +167,7 @@ menu_t PLAY_TAReplayGuestDef = { 2, 5, M_DrawTimeAttack, NULL, - NULL, + M_TimeAttackTick, NULL, NULL, NULL @@ -208,7 +208,7 @@ menu_t PLAY_TAGhostsDef = { 2, 5, M_DrawTimeAttack, NULL, - NULL, + M_TimeAttackTick, NULL, NULL, NULL @@ -219,6 +219,8 @@ void M_PrepareTimeAttack(INT32 choice) { (void) choice; + timeattackmenu.ticker = 0; + // Gametype guess if (levellist.guessgt != MAXGAMETYPES) { diff --git a/src/menus/transient/cup-select.c b/src/menus/transient/cup-select.c index d6a5a4410..6cd4052f8 100644 --- a/src/menus/transient/cup-select.c +++ b/src/menus/transient/cup-select.c @@ -276,11 +276,13 @@ void M_CupSelectHandler(INT32 choice) } else if (count == 1 && levellist.levelsearch.timeattack == true) { - PLAY_TimeAttackDef.transitionID = currentMenu->transitionID+1; + currentMenu->transitionID = PLAY_TimeAttackDef.transitionID+1; M_LevelSelected(0); } else { + currentMenu->transitionID = PLAY_LevelSelectDef.transitionID; + // Keep cursor position if you select the same cup again, reset if it's a different cup if (oldcup != newcup || levellist.cursor >= count) { diff --git a/src/menus/transient/level-select.c b/src/menus/transient/level-select.c index 928cabf46..09e69e3b3 100644 --- a/src/menus/transient/level-select.c +++ b/src/menus/transient/level-select.c @@ -18,17 +18,6 @@ menuitem_t PLAY_LevelSelect[] = {IT_NOTHING | IT_KEYHANDLER, NULL, NULL, NULL, {.routine = M_LevelSelectHandler}, 0, 0}, }; -static void M_DrawLevelSelectBack(void) -{ - if (!levellist.levelsearch.tutorial) - { - M_DrawMenuBackground(); - return; - } - - M_DrawExtrasBack(); -} - menu_t PLAY_LevelSelectDef = { sizeof(PLAY_LevelSelect) / sizeof(menuitem_t), &PLAY_CupSelectDef, @@ -40,7 +29,7 @@ menu_t PLAY_LevelSelectDef = { NULL, 2, 5, M_DrawLevelSelect, - M_DrawLevelSelectBack, + NULL, M_LevelSelectTick, NULL, NULL, @@ -293,16 +282,43 @@ boolean M_LevelListFromGametype(INT16 gt) CV_SetValue(&cv_dummyspbattack, 0); } - PLAY_CupSelectDef.music = \ - PLAY_LevelSelectDef.music = \ - PLAY_TimeAttackDef.music = \ - currentMenu->music; - if (gamestate == GS_MENU) { - PLAY_CupSelectDef.menuitems[0].patch = \ - PLAY_LevelSelectDef.menuitems[0].patch = \ - currentMenu->menuitems[itemOn].patch; + const char *music; + void (*bgroutine)(void); + + if (gt == GT_SPECIAL) + { + music = "SSTAR3"; + bgroutine = M_DrawSealedBack; + } + else + { + music = currentMenu->music; + bgroutine = currentMenu->bgroutine; + + // Not for the time attack ones + PLAY_CupSelectDef.menuitems[0].patch = \ + PLAY_LevelSelectDef.menuitems[0].patch = \ + currentMenu->menuitems[itemOn].patch; + } + + menu_t *remap_menus[] = { + &PLAY_CupSelectDef, + &PLAY_LevelSelectDef, + &PLAY_TimeAttackDef, + &PLAY_TAReplayDef, + &PLAY_TAReplayGuestDef, + &PLAY_TAGhostsDef, + NULL + }; + + size_t i; + for (i = 0; remap_menus[i]; i++) + { + remap_menus[i]->music = music; + remap_menus[i]->bgroutine = bgroutine; + } } } @@ -311,6 +327,8 @@ boolean M_LevelListFromGametype(INT16 gt) if (levellist.levelsearch.cupmode) { + PLAY_CupSelectDef.transitionID = PLAY_LevelSelectDef.transitionID; + const boolean secondrowlocked = M_CupSecondRowLocked(); if (cupgrid.cache_secondrowlocked != secondrowlocked) { @@ -786,8 +804,6 @@ void M_LevelSelectHandler(INT32 choice) if (M_MenuConfirmPressed(pid) /*|| M_MenuButtonPressed(pid, MBT_START)*/) { M_SetMenuDelay(pid); - - PLAY_TimeAttackDef.transitionID = currentMenu->transitionID; M_LevelSelected(levellist.cursor); } else if (M_MenuBackPressed(pid))