diff --git a/src/d_main.cpp b/src/d_main.cpp index d1814813b..18b2e3709 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -1609,6 +1609,7 @@ void D_SRB2Main(void) // P_InitMapData(); basenummapheaders = nummapheaders; + basenumkartcupheaders = numkartcupheaders; CON_SetLoadingProgress(LOADED_IWAD); diff --git a/src/dehacked.c b/src/dehacked.c index ecd98fffe..0bb710a18 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -613,6 +613,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) if (gamedataadded) { basenummapheaders = nummapheaders; + basenumkartcupheaders = numkartcupheaders; G_LoadGameData(); } diff --git a/src/doomstat.h b/src/doomstat.h index 1107aef97..2e47ebc6c 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -423,7 +423,7 @@ struct cupheader_t }; extern cupheader_t *kartcupheaders; // Start of cup linked list -extern UINT16 numkartcupheaders; +extern UINT16 numkartcupheaders, basenumkartcupheaders; struct unloaded_cupheader_t { diff --git a/src/g_game.c b/src/g_game.c index 6e92351f3..190e38121 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -204,6 +204,7 @@ unloaded_mapheader_t *unloadedmapheaders = NULL; // Kart cup definitions cupheader_t *kartcupheaders = NULL; UINT16 numkartcupheaders = 0; +UINT16 basenumkartcupheaders = 0; unloaded_cupheader_t *unloadedcupheaders = NULL; diff --git a/src/menus/transient/level-select.c b/src/menus/transient/level-select.c index 9e5730263..c01f4c65f 100644 --- a/src/menus/transient/level-select.c +++ b/src/menus/transient/level-select.c @@ -313,15 +313,14 @@ boolean M_LevelListFromGametype(INT16 gt) levelsearch_t templevelsearch = levellist.levelsearch; // full copy size_t currentid = 0, highestunlockedid = 0; const size_t pagelen = sizeof(cupheader_t*) * (CUPMENU_COLUMNS * CUPMENU_ROWS); - boolean foundany = false, foundanythispage = false, currentvalid = false; + boolean foundany = false, currentvalid = false; + size_t deltaid = 0; G_GetBackupCupData( cupgrid.grandprix == true && cv_splitplayers.value <= 1 ); - templevelsearch.cup = kartcupheaders; - #if 0 // Make sure there's valid cups before going to this menu. -- rip sweet prince if (templevelsearch.cup == NULL) @@ -368,8 +367,89 @@ boolean M_LevelListFromGametype(INT16 gt) cupgrid.pageno = currentid / (CUPMENU_COLUMNS * CUPMENU_ROWS); \ currentvalid = true; - while (templevelsearch.cup) +#define GRID_TIDYLOCKED(rewind) \ + currentid -= rewind; \ + memset(&cupgrid.builtgrid[currentid], 0, pagelen); \ + deltaid = 0; + + boolean lostandfoundready = true; + // foundanythispage SHOULD start out as false... but if + // nothing is unlocked, the first page should never be wiped! + boolean foundanythispage = true; + + templevelsearch.cup = kartcupheaders; + while (true) { + // Handle reaching the end of the base-game cups. + if (lostandfoundready == true + && ( + templevelsearch.cup == NULL + || templevelsearch.cup->id == basenumkartcupheaders + ) + ) + { + lostandfoundready = false; + + if (deltaid != 0 && foundanythispage == false) + { + GRID_TIDYLOCKED(deltaid); + } + + size_t olddelta = deltaid; + if (cupgrid.grandprix == false) + { + cupheader_t *restore = templevelsearch.cup; + + templevelsearch.cup = &dummy_lostandfound; + templevelsearch.checklocked = true; + + if (M_GetFirstLevelInList(&temp, &templevelsearch) != NEXTMAP_INVALID) + { + foundany = foundanythispage = true; + GRID_INSERTCUP; + highestunlockedid = currentid; + + if (Playing() + ? (mapheaderinfo[gamemap-1] && mapheaderinfo[gamemap-1]->cup == NULL) + : (gt == -1 && levellist.levelsearch.cup == templevelsearch.cup)) + { + GRID_FOCUSCUP; + } + + currentid++; + deltaid = currentid % (CUPMENU_COLUMNS * CUPMENU_ROWS); + } + + templevelsearch.cup = restore; + } + + // Lost and Found marks the transition point between base + // and custom cups. Always force a page break between these + // (unless LnF is the only "cup" on the page, for sanity). + + if ( + (deltaid == 0) // a new page already + || (olddelta == 0 && deltaid == 1) // LnF is first and only entry + ) + ; // this page layout is fine + else + { + if (foundanythispage == false) + { + GRID_TIDYLOCKED(deltaid); + } + else + { + currentid += (CUPMENU_COLUMNS * CUPMENU_ROWS) - deltaid; + deltaid = 0; + foundanythispage = false; + } + } + } + + if (templevelsearch.cup == NULL) + break; + templevelsearch.checklocked = false; if (!M_CountLevelsToShowInList(&templevelsearch)) { @@ -397,59 +477,34 @@ boolean M_LevelListFromGametype(INT16 gt) } } - currentid++; + templevelsearch.cup = templevelsearch.cup->next; + + currentid++; + deltaid = currentid % (CUPMENU_COLUMNS * CUPMENU_ROWS); - // If the second row is locked and you've reached it, skip onward. if (secondrowlocked == true) { - size_t deltaid = currentid % (CUPMENU_COLUMNS * CUPMENU_ROWS); + // If the second row is locked and you've reached it, skip onward. if (deltaid >= CUPMENU_COLUMNS) { currentid += (CUPMENU_COLUMNS * CUPMENU_ROWS) - deltaid; + deltaid = 0; } } - // If you've gone a full page without anything valid, compress it down! - if ((currentid % (CUPMENU_COLUMNS * CUPMENU_ROWS)) == 0) + if (deltaid == 0) { if (foundanythispage == false) { - currentid -= (CUPMENU_COLUMNS * CUPMENU_ROWS); - memset(&cupgrid.builtgrid[currentid], 0, pagelen); + GRID_TIDYLOCKED((CUPMENU_COLUMNS * CUPMENU_ROWS)); } foundanythispage = false; } - - templevelsearch.cup = templevelsearch.cup->next; - } - - // Lost and found, a simplified version of the above loop. - if (cupgrid.grandprix == false) - { - templevelsearch.cup = &dummy_lostandfound; - templevelsearch.checklocked = true; - - if (M_GetFirstLevelInList(&temp, &templevelsearch) != NEXTMAP_INVALID) - { - foundany = true; - GRID_INSERTCUP; - highestunlockedid = currentid; - - if (Playing() - ? (mapheaderinfo[gamemap-1] && mapheaderinfo[gamemap-1]->cup == NULL) - : (gt == -1 && levellist.levelsearch.cup == templevelsearch.cup)) - { - GRID_FOCUSCUP; - } - - currentid++; - } - - templevelsearch.cup = NULL; } #undef GRID_INSERTCUP #undef GRID_FOCUSCUP +#undef GRID_TIDYLOCKED if (foundany == false) {