mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Merge branch 'in-flight-menus' into 'master'
Course List QOL See merge request KartKrew/Kart!1867
This commit is contained in:
commit
ff20f38ffa
8 changed files with 224 additions and 71 deletions
|
|
@ -2490,6 +2490,7 @@ static void Command_connect(void)
|
|||
|
||||
// Menu restore state.
|
||||
restoreMenu = &PLAY_MP_OptSelectDef;
|
||||
currentMenu->lastOn = itemOn;
|
||||
|
||||
Music_Remap("menu", "NETMD2");
|
||||
|
||||
|
|
|
|||
|
|
@ -1999,14 +1999,14 @@ void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, INT32 splitflags, U
|
|||
|
||||
if (gamedata->collected[(stickermedalinfo.emblems[i]-emblemlocations)])
|
||||
{
|
||||
V_DrawSmallMappedPatch(workx, worky, splitflags,
|
||||
V_DrawMappedPatch(workx, worky, splitflags,
|
||||
static_cast<patch_t*>(W_CachePatchName(M_GetEmblemPatch(stickermedalinfo.emblems[i], false), PU_CACHE)),
|
||||
R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(stickermedalinfo.emblems[i]), GTC_CACHE)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
V_DrawSmallMappedPatch(workx, worky, splitflags,
|
||||
V_DrawMappedPatch(workx, worky, splitflags,
|
||||
static_cast<patch_t*>(W_CachePatchName("NEEDIT", PU_CACHE)),
|
||||
NULL
|
||||
);
|
||||
|
|
|
|||
14
src/k_menu.h
14
src/k_menu.h
|
|
@ -275,7 +275,6 @@ typedef enum
|
|||
ta_replay = 0,
|
||||
ta_guest,
|
||||
ta_ghosts,
|
||||
ta_spb,
|
||||
ta_spacer,
|
||||
ta_start,
|
||||
} ta_e;
|
||||
|
|
@ -824,7 +823,7 @@ typedef struct levelsearch_s {
|
|||
|
||||
#define M_LEVELLIST_SLIDETIME 4
|
||||
|
||||
extern struct levellist_s {
|
||||
typedef struct levellist_s {
|
||||
SINT8 cursor;
|
||||
menu_anim_t slide;
|
||||
UINT16 y;
|
||||
|
|
@ -834,7 +833,11 @@ extern struct levellist_s {
|
|||
UINT8 guessgt;
|
||||
levelsearch_t levelsearch;
|
||||
boolean netgame; // Start the game in an actual server
|
||||
} levellist;
|
||||
menu_t *backMenu;
|
||||
} levellist_t;
|
||||
|
||||
extern levellist_t levellist;
|
||||
extern levellist_t restorelevellist;
|
||||
|
||||
extern cupheader_t dummy_lostandfound;
|
||||
|
||||
|
|
@ -851,7 +854,8 @@ void M_CupSelectTick(void);
|
|||
void M_LevelSelectHandler(INT32 choice);
|
||||
void M_LevelSelectTick(void);
|
||||
|
||||
void M_LevelSelected(INT16 add);
|
||||
void M_LevelSelected(INT16 add, boolean menuupdate);
|
||||
boolean M_LevelSelectCupSwitch(boolean next, boolean skipones);
|
||||
|
||||
// dummy consvars for GP & match race setup
|
||||
extern consvar_t cv_dummygpdifficulty;
|
||||
|
|
@ -894,7 +898,7 @@ void M_PleaseWait(void);
|
|||
void M_PopupMasterServerRules(void);
|
||||
|
||||
// Time Attack
|
||||
void M_PrepareTimeAttack(INT32 choice);
|
||||
void M_PrepareTimeAttack(boolean menuupdate);
|
||||
void M_StartTimeAttack(INT32 choice);
|
||||
void M_ReplayTimeAttack(INT32 choice);
|
||||
void M_HandleStaffReplay(INT32 choice);
|
||||
|
|
|
|||
|
|
@ -533,26 +533,29 @@ menu_t *M_SpecificMenuRestore(menu_t *torestore)
|
|||
|| torestore == &PLAY_TimeAttackDef)
|
||||
{
|
||||
// Handle unlock restrictions
|
||||
|
||||
levellist = restorelevellist;
|
||||
|
||||
cupheader_t *currentcup = levellist.levelsearch.cup;
|
||||
|
||||
M_SetupGametypeMenu(-1);
|
||||
|
||||
if (levellist.newgametype == GT_RACE)
|
||||
if (levellist.levelsearch.tutorial)
|
||||
{
|
||||
M_SetupRaceMenu(-1);
|
||||
M_SetupDifficultyOptions((cupgrid.grandprix == false));
|
||||
M_InitExtras(-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
M_SetupGametypeMenu(-1);
|
||||
|
||||
if (levellist.newgametype == GT_RACE)
|
||||
{
|
||||
M_SetupRaceMenu(-1);
|
||||
M_SetupDifficultyOptions((cupgrid.grandprix == false));
|
||||
}
|
||||
}
|
||||
|
||||
if (!M_LevelListFromGametype(-1))
|
||||
{
|
||||
if (PLAY_LevelSelectDef.prevMenu == &PLAY_CupSelectDef)
|
||||
{
|
||||
torestore = PLAY_CupSelectDef.prevMenu;
|
||||
}
|
||||
else
|
||||
{
|
||||
torestore = PLAY_LevelSelectDef.prevMenu;
|
||||
}
|
||||
torestore = levellist.backMenu;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -560,19 +563,12 @@ menu_t *M_SpecificMenuRestore(menu_t *torestore)
|
|||
{
|
||||
torestore = &PLAY_CupSelectDef;
|
||||
}
|
||||
else if (torestore == &PLAY_TimeAttackDef)
|
||||
else if (levellist.levelsearch.timeattack)
|
||||
{
|
||||
M_PrepareTimeAttack(0);
|
||||
M_PrepareTimeAttack(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (torestore == &PLAY_RaceDifficultyDef)
|
||||
{
|
||||
// Handle a much smaller subset of unlock restrictions
|
||||
M_SetupGametypeMenu(-1);
|
||||
M_SetupRaceMenu(-1);
|
||||
M_SetupDifficultyOptions((cupgrid.grandprix == false));
|
||||
}
|
||||
else if (torestore == &PLAY_MP_OptSelectDef)
|
||||
{
|
||||
// Ticker init
|
||||
|
|
@ -671,8 +667,6 @@ void M_StartControlPanel(void)
|
|||
}
|
||||
}
|
||||
|
||||
M_PickMenuBGMap();
|
||||
|
||||
if (M_GameTrulyStarted() == false)
|
||||
{
|
||||
// Are you ready for the First Boot Experience?
|
||||
|
|
@ -717,14 +711,15 @@ void M_StartControlPanel(void)
|
|||
|
||||
M_PlayMenuJam();
|
||||
}
|
||||
|
||||
itemOn = currentMenu->lastOn;
|
||||
M_UpdateMenuBGImage(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
M_OpenPauseMenu();
|
||||
}
|
||||
|
||||
itemOn = currentMenu->lastOn;
|
||||
|
||||
CON_ToggleOff(); // move away console
|
||||
}
|
||||
|
||||
|
|
@ -745,6 +740,8 @@ void M_ClearMenus(boolean callexitmenufunc)
|
|||
COM_BufAddText(va("saveconfig \"%s\" -silent\n", configfile));
|
||||
#endif //Alam: But not on the Dreamcast's VMUs
|
||||
|
||||
currentMenu->lastOn = itemOn;
|
||||
|
||||
if (gamestate == GS_MENU) // Back to title screen
|
||||
{
|
||||
int i;
|
||||
|
|
|
|||
|
|
@ -52,6 +52,42 @@ boolean M_TimeAttackInputs(INT32 ch)
|
|||
return true;
|
||||
}
|
||||
|
||||
if (menucmd[pid].dpad_lr != 0
|
||||
&& !((currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_ARROWS
|
||||
|| (currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_CVAR)
|
||||
)
|
||||
{
|
||||
if (menucmd[pid].dpad_lr > 0)
|
||||
{
|
||||
levellist.cursor++;
|
||||
if (levellist.cursor >= levellist.mapcount)
|
||||
{
|
||||
M_LevelSelectCupSwitch(true, false);
|
||||
levellist.cursor = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
levellist.cursor--;
|
||||
if (levellist.cursor < 0)
|
||||
{
|
||||
M_LevelSelectCupSwitch(false, false);
|
||||
levellist.cursor = levellist.mapcount-1;
|
||||
}
|
||||
}
|
||||
|
||||
M_LevelSelectScrollDest();
|
||||
levellist.slide.start = 0;
|
||||
|
||||
M_LevelSelected(levellist.cursor, false);
|
||||
itemOn = ta_start;
|
||||
|
||||
S_StartSound(NULL, sfx_s3k5b);
|
||||
M_SetMenuDelay(pid);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -215,11 +251,12 @@ menu_t PLAY_TAGhostsDef = {
|
|||
};
|
||||
|
||||
// time attack stuff...
|
||||
void M_PrepareTimeAttack(INT32 choice)
|
||||
void M_PrepareTimeAttack(boolean menuupdate)
|
||||
{
|
||||
(void) choice;
|
||||
|
||||
timeattackmenu.ticker = 0;
|
||||
if (menuupdate)
|
||||
{
|
||||
timeattackmenu.ticker = 0;
|
||||
}
|
||||
|
||||
// Gametype guess
|
||||
if (levellist.guessgt != MAXGAMETYPES)
|
||||
|
|
@ -426,7 +463,7 @@ static void M_WriteGuestReplay(INT32 ch)
|
|||
Z_Free(rguest);
|
||||
Z_Free(gpath);
|
||||
|
||||
M_PrepareTimeAttack(0);
|
||||
M_PrepareTimeAttack(false);
|
||||
M_SetupNextMenu(&PLAY_TimeAttackDef, false);
|
||||
|
||||
// TODO the following isn't showing up and I'm not sure why
|
||||
|
|
|
|||
|
|
@ -129,7 +129,9 @@ static void M_StartCup(UINT8 entry)
|
|||
SV_StartSinglePlayerServer(levellist.newgametype, levellist.netgame);
|
||||
|
||||
M_ClearMenus(true);
|
||||
|
||||
restoreMenu = &PLAY_CupSelectDef;
|
||||
restorelevellist = levellist;
|
||||
|
||||
if (entry < roundqueue.size)
|
||||
{
|
||||
|
|
@ -265,12 +267,21 @@ void M_CupSelectHandler(INT32 choice)
|
|||
|
||||
M_SetMenuDelay(pid);
|
||||
|
||||
if (!newcup)
|
||||
{
|
||||
S_StartSound(NULL, sfx_s3kb2);
|
||||
return;
|
||||
}
|
||||
|
||||
levellist.levelsearch.cup = newcup;
|
||||
count = M_CountLevelsToShowInList(&levellist.levelsearch);
|
||||
|
||||
if ((!newcup)
|
||||
|| (count == 0)
|
||||
|| (cupgrid.grandprix == true && newcup->cachedlevels[0] == NEXTMAP_INVALID))
|
||||
if (count == 0
|
||||
|| (
|
||||
cupgrid.grandprix == true
|
||||
&& newcup->cachedlevels[0] == NEXTMAP_INVALID
|
||||
)
|
||||
)
|
||||
{
|
||||
S_StartSound(NULL, sfx_s3kb2);
|
||||
return;
|
||||
|
|
@ -300,7 +311,7 @@ void M_CupSelectHandler(INT32 choice)
|
|||
else if (count == 1 && levellist.levelsearch.timeattack == true)
|
||||
{
|
||||
currentMenu->transitionID = PLAY_TimeAttackDef.transitionID+1;
|
||||
M_LevelSelected(0);
|
||||
M_LevelSelected(0, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -37,7 +37,8 @@ menu_t PLAY_LevelSelectDef = {
|
|||
NULL
|
||||
};
|
||||
|
||||
struct levellist_s levellist;
|
||||
levellist_t levellist;
|
||||
levellist_t restorelevellist;
|
||||
|
||||
//
|
||||
// M_CanShowLevelInList
|
||||
|
|
@ -278,6 +279,8 @@ boolean M_LevelListFromGametype(INT16 gt)
|
|||
CV_SetValue(&cv_dummyspbattack, 0);
|
||||
}
|
||||
|
||||
levellist.backMenu = currentMenu;
|
||||
|
||||
if (gamestate == GS_MENU)
|
||||
{
|
||||
const char *music;
|
||||
|
|
@ -290,8 +293,8 @@ boolean M_LevelListFromGametype(INT16 gt)
|
|||
}
|
||||
else
|
||||
{
|
||||
music = currentMenu->music;
|
||||
bgroutine = currentMenu->bgroutine;
|
||||
music = levellist.backMenu->music;
|
||||
bgroutine = levellist.backMenu->bgroutine;
|
||||
}
|
||||
|
||||
menu_t *remap_menus[] = {
|
||||
|
|
@ -304,17 +307,18 @@ boolean M_LevelListFromGametype(INT16 gt)
|
|||
NULL
|
||||
};
|
||||
|
||||
size_t i;
|
||||
INT16 i, j;
|
||||
for (i = 0; remap_menus[i]; i++)
|
||||
{
|
||||
remap_menus[i]->music = music;
|
||||
remap_menus[i]->bgroutine = bgroutine;
|
||||
}
|
||||
|
||||
// Not for the time attack ones
|
||||
PLAY_CupSelectDef.menuitems[0].patch = \
|
||||
PLAY_LevelSelectDef.menuitems[0].patch = \
|
||||
currentMenu->menuitems[itemOn].patch;
|
||||
for (j = 0; j < remap_menus[i]->numitems; j++)
|
||||
{
|
||||
remap_menus[i]->menuitems[j].patch = \
|
||||
currentMenu->menuitems[itemOn].patch;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -548,10 +552,11 @@ boolean M_LevelListFromGametype(INT16 gt)
|
|||
cupgrid.pageno = 0;
|
||||
}
|
||||
|
||||
PLAY_CupSelectDef.prevMenu = levellist.backMenu;
|
||||
PLAY_LevelSelectDef.prevMenu = &PLAY_CupSelectDef;
|
||||
|
||||
if (gt != -1)
|
||||
{
|
||||
PLAY_CupSelectDef.prevMenu = currentMenu;
|
||||
PLAY_LevelSelectDef.prevMenu = &PLAY_CupSelectDef;
|
||||
M_SetupNextMenu(&PLAY_CupSelectDef, false);
|
||||
}
|
||||
|
||||
|
|
@ -597,15 +602,16 @@ boolean M_LevelListFromGametype(INT16 gt)
|
|||
M_LevelSelectScrollDest();
|
||||
levellist.slide.start = 0;
|
||||
|
||||
PLAY_LevelSelectDef.prevMenu = levellist.backMenu;
|
||||
|
||||
if (gt != -1)
|
||||
{
|
||||
if (levellist.levelsearch.tutorial && levellist.mapcount == 1)
|
||||
{
|
||||
M_LevelSelected(0); // Skip the list!
|
||||
M_LevelSelected(0, true); // Skip the list!
|
||||
}
|
||||
else
|
||||
{
|
||||
PLAY_LevelSelectDef.prevMenu = currentMenu;
|
||||
M_SetupNextMenu(&PLAY_LevelSelectDef, false);
|
||||
}
|
||||
}
|
||||
|
|
@ -658,7 +664,7 @@ void M_LevelSelectInit(INT32 choice)
|
|||
}
|
||||
}
|
||||
|
||||
void M_LevelSelected(INT16 add)
|
||||
void M_LevelSelected(INT16 add, boolean menuupdate)
|
||||
{
|
||||
UINT8 i = 0;
|
||||
INT16 map = M_GetFirstLevelInList(&i, &levellist.levelsearch);
|
||||
|
|
@ -685,13 +691,18 @@ void M_LevelSelected(INT16 add)
|
|||
|
||||
if (levellist.levelsearch.timeattack)
|
||||
{
|
||||
S_StartSound(NULL, sfx_s3k63);
|
||||
restorelevellist = levellist;
|
||||
|
||||
M_PrepareTimeAttack(0);
|
||||
M_PrepareTimeAttack(menuupdate);
|
||||
|
||||
PLAY_TimeAttackDef.lastOn = ta_start;
|
||||
PLAY_TimeAttackDef.prevMenu = currentMenu;
|
||||
M_SetupNextMenu(&PLAY_TimeAttackDef, false);
|
||||
if (menuupdate)
|
||||
{
|
||||
S_StartSound(NULL, sfx_s3k63);
|
||||
|
||||
PLAY_TimeAttackDef.lastOn = ta_start;
|
||||
PLAY_TimeAttackDef.prevMenu = currentMenu;
|
||||
M_SetupNextMenu(&PLAY_TimeAttackDef, false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -744,19 +755,17 @@ void M_LevelSelected(INT16 add)
|
|||
|
||||
D_MapChange(levellist.choosemap+1, levellist.newgametype, (cv_kartencore.value == 1), 1, 1, false, false);
|
||||
|
||||
if (!M_GameTrulyStarted() ||
|
||||
levellist.levelsearch.tutorial)
|
||||
{
|
||||
restoreMenu = currentMenu;
|
||||
}
|
||||
else if (levellist.netgame == true)
|
||||
if (levellist.netgame == true)
|
||||
{
|
||||
restoreMenu = &PLAY_MP_OptSelectDef;
|
||||
}
|
||||
else
|
||||
else /*if (!M_GameTrulyStarted() ||
|
||||
levellist.levelsearch.tutorial)*/
|
||||
{
|
||||
restoreMenu = &PLAY_RaceDifficultyDef;
|
||||
restoreMenu = currentMenu;
|
||||
}
|
||||
|
||||
restorelevellist = levellist;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -768,6 +777,87 @@ void M_LevelSelected(INT16 add)
|
|||
}
|
||||
}
|
||||
|
||||
boolean M_LevelSelectCupSwitch(boolean next, boolean skipones)
|
||||
{
|
||||
levelsearch_t templevelsearch = levellist.levelsearch;
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (next)
|
||||
{
|
||||
// Next
|
||||
if (++cupgrid.x >= CUPMENU_COLUMNS)
|
||||
{
|
||||
cupgrid.x = 0;
|
||||
if (++cupgrid.y >= CUPMENU_ROWS)
|
||||
{
|
||||
cupgrid.y = 0;
|
||||
if (++cupgrid.pageno >= cupgrid.numpages)
|
||||
{
|
||||
cupgrid.pageno = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Prev
|
||||
if (cupgrid.x == 0)
|
||||
{
|
||||
cupgrid.x = CUPMENU_COLUMNS;
|
||||
if (cupgrid.y == 0)
|
||||
{
|
||||
cupgrid.y = CUPMENU_ROWS;
|
||||
if (cupgrid.pageno == 0)
|
||||
{
|
||||
cupgrid.pageno = cupgrid.numpages;
|
||||
}
|
||||
cupgrid.pageno--;
|
||||
}
|
||||
cupgrid.y--;
|
||||
}
|
||||
cupgrid.x--;
|
||||
}
|
||||
|
||||
templevelsearch.cup = cupgrid.builtgrid[CUPMENU_CURSORID];
|
||||
|
||||
if (templevelsearch.cup == levellist.levelsearch.cup)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!templevelsearch.cup)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
UINT16 count = M_CountLevelsToShowInList(&templevelsearch);
|
||||
|
||||
if (count == 0
|
||||
// The following isn't ideal, but in addition to the
|
||||
// necessary programming work being extremely annoying,
|
||||
// I also just think being forced to switch between
|
||||
// Time Attack single-course views and multi-course
|
||||
// selections would just plain kind of look bad.
|
||||
// ~toast 250124 (ON A PLANE BACK FROM MAGFEST WOOOOOOOO)
|
||||
|| (skipones && count == 1))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
levellist.levelsearch = templevelsearch;
|
||||
|
||||
levellist.mapcount = count;
|
||||
if (levellist.cursor >= count)
|
||||
levellist.cursor = count-1;
|
||||
|
||||
M_LevelSelectScrollDest();
|
||||
levellist.slide.start = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void M_LevelSelectHandler(INT32 choice)
|
||||
{
|
||||
const UINT8 pid = 0;
|
||||
|
|
@ -795,13 +885,26 @@ void M_LevelSelectHandler(INT32 choice)
|
|||
S_StartSound(NULL, sfx_s3k5b);
|
||||
M_SetMenuDelay(pid);
|
||||
}
|
||||
else if (levellist.levelsearch.cup == NULL)
|
||||
; // Mode with no cup? No left/right input for you!
|
||||
else if (menucmd[pid].dpad_lr != 0)
|
||||
{
|
||||
if (M_LevelSelectCupSwitch(
|
||||
(menucmd[pid].dpad_lr > 0),
|
||||
levellist.levelsearch.timeattack)
|
||||
)
|
||||
{
|
||||
S_StartSound(NULL, sfx_s3k5b);
|
||||
M_SetMenuDelay(pid);
|
||||
}
|
||||
}
|
||||
|
||||
M_LevelSelectScrollDest();
|
||||
|
||||
if (M_MenuConfirmPressed(pid) /*|| M_MenuButtonPressed(pid, MBT_START)*/)
|
||||
{
|
||||
M_SetMenuDelay(pid);
|
||||
M_LevelSelected(levellist.cursor);
|
||||
M_LevelSelected(levellist.cursor, true);
|
||||
}
|
||||
else if (M_MenuBackPressed(pid))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ void M_OpenPauseMenu(void)
|
|||
pausemenu.openoffset.dist = 0;
|
||||
pausemenu.closing = false;
|
||||
|
||||
currentMenu->lastOn = mpause_continue; // Make sure we select "RESUME GAME" by default
|
||||
itemOn = currentMenu->lastOn = mpause_continue; // Make sure we select "RESUME GAME" by default
|
||||
|
||||
// Now the hilarious balancing act of deciding what options should be enabled and which ones shouldn't be!
|
||||
// By default, disable anything sensitive:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue