mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-03-24 03:32:22 +00:00
Level select no longer assumes that games will always be linear
- If a level is in-between two with the same header, it would previously create two headers with the same name. Now it groups all levels with the same header together. - Previously, a header would only be visible if its first map was visible. Now it will show the header if you've visited any level under the header. For SUGOI.
This commit is contained in:
parent
1355a82aa5
commit
381ead4d7e
1 changed files with 148 additions and 47 deletions
195
src/m_menu.c
195
src/m_menu.c
|
@ -5166,34 +5166,75 @@ static boolean M_GametypeHasLevels(INT32 gt)
|
|||
|
||||
static INT32 M_CountRowsToShowOnPlatter(INT32 gt)
|
||||
{
|
||||
INT32 mapnum = 0, prevmapnum = 0, col = 0, rows = 0;
|
||||
INT32 col = 0, rows = 0;
|
||||
INT32 mapIterate = 0;
|
||||
INT32 headingIterate = 0;
|
||||
boolean mapAddedAlready[NUMMAPS];
|
||||
|
||||
while (mapnum < NUMMAPS)
|
||||
memset(mapAddedAlready, 0, sizeof mapAddedAlready);
|
||||
|
||||
for (mapIterate = 0; mapIterate < NUMMAPS; mapIterate++)
|
||||
{
|
||||
if (M_CanShowLevelOnPlatter(mapnum, gt))
|
||||
boolean forceNewRow = true;
|
||||
|
||||
if (mapAddedAlready[mapIterate] == true)
|
||||
{
|
||||
if (rows == 0)
|
||||
// Already added under another heading
|
||||
continue;
|
||||
}
|
||||
|
||||
if (M_CanShowLevelOnPlatter(mapIterate, gt) == false)
|
||||
{
|
||||
// Don't show this one
|
||||
continue;
|
||||
}
|
||||
|
||||
for (headingIterate = mapIterate; headingIterate < NUMMAPS; headingIterate++)
|
||||
{
|
||||
boolean wide = false;
|
||||
|
||||
if (mapAddedAlready[headingIterate] == true)
|
||||
{
|
||||
// Already added under another heading
|
||||
continue;
|
||||
}
|
||||
|
||||
if (M_CanShowLevelOnPlatter(headingIterate, gt) == false)
|
||||
{
|
||||
// Don't show this one
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!fastcmp(mapheaderinfo[mapIterate]->selectheading, mapheaderinfo[headingIterate]->selectheading))
|
||||
{
|
||||
// Headers don't match
|
||||
continue;
|
||||
}
|
||||
|
||||
wide = (mapheaderinfo[headingIterate]->menuflags & LF2_WIDEICON);
|
||||
|
||||
// preparing next position to drop mapnum into
|
||||
if (col == 2 // no more space on the row?
|
||||
|| wide || forceNewRow)
|
||||
{
|
||||
col = 0;
|
||||
rows++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (col == 2
|
||||
|| (mapheaderinfo[prevmapnum]->menuflags & LF2_WIDEICON)
|
||||
|| (mapheaderinfo[mapnum]->menuflags & LF2_WIDEICON)
|
||||
|| !(fastcmp(mapheaderinfo[mapnum]->selectheading, mapheaderinfo[prevmapnum]->selectheading)))
|
||||
{
|
||||
col = 0;
|
||||
rows++;
|
||||
}
|
||||
else
|
||||
col++;
|
||||
col++;
|
||||
}
|
||||
prevmapnum = mapnum;
|
||||
|
||||
// Done adding this one
|
||||
mapAddedAlready[headingIterate] = true;
|
||||
forceNewRow = wide;
|
||||
}
|
||||
mapnum++;
|
||||
}
|
||||
|
||||
if (levellistmode == LLM_CREATESERVER)
|
||||
{
|
||||
rows++;
|
||||
}
|
||||
|
||||
return rows;
|
||||
}
|
||||
|
@ -5223,7 +5264,10 @@ static void M_CacheLevelPlatter(void)
|
|||
static boolean M_PrepareLevelPlatter(INT32 gt, boolean nextmappick)
|
||||
{
|
||||
INT32 numrows = M_CountRowsToShowOnPlatter(gt);
|
||||
INT32 mapnum = 0, prevmapnum = 0, col = 0, row = 0, startrow = 0;
|
||||
INT32 col = 0, row = 0, startrow = 0;
|
||||
INT32 mapIterate = 0; // First level of map loop -- find starting points for select headings
|
||||
INT32 headingIterate = 0; // Second level of map loop -- finding maps that match mapIterate's heading.
|
||||
boolean mapAddedAlready[NUMMAPS];
|
||||
|
||||
if (!numrows)
|
||||
return false;
|
||||
|
@ -5240,6 +5284,8 @@ static boolean M_PrepareLevelPlatter(INT32 gt, boolean nextmappick)
|
|||
// done here so lsrow and lscol can be set if cv_nextmap is on the platter
|
||||
lsrow = lscol = lshli = lsoffs[0] = lsoffs[1] = 0;
|
||||
|
||||
memset(mapAddedAlready, 0, sizeof mapAddedAlready);
|
||||
|
||||
if (levellistmode == LLM_CREATESERVER)
|
||||
{
|
||||
sprintf(levelselect.rows[0].header, "Gametype");
|
||||
|
@ -5251,31 +5297,75 @@ static boolean M_PrepareLevelPlatter(INT32 gt, boolean nextmappick)
|
|||
char_notes = NULL;
|
||||
}
|
||||
|
||||
while (mapnum < NUMMAPS)
|
||||
for (mapIterate = 0; mapIterate < NUMMAPS; mapIterate++)
|
||||
{
|
||||
if (M_CanShowLevelOnPlatter(mapnum, gt))
|
||||
INT32 headerRow = -1;
|
||||
boolean anyAvailable = false;
|
||||
boolean forceNewRow = true;
|
||||
|
||||
if (mapAddedAlready[mapIterate] == true)
|
||||
{
|
||||
const UINT8 actnum = mapheaderinfo[mapnum]->actnum;
|
||||
const boolean headingisname = (fastcmp(mapheaderinfo[mapnum]->selectheading, mapheaderinfo[mapnum]->lvlttl));
|
||||
const boolean wide = (mapheaderinfo[mapnum]->menuflags & LF2_WIDEICON);
|
||||
// Already added under another heading
|
||||
continue;
|
||||
}
|
||||
|
||||
if (M_CanShowLevelOnPlatter(mapIterate, gt) == false)
|
||||
{
|
||||
// Don't show this one
|
||||
continue;
|
||||
}
|
||||
|
||||
for (headingIterate = mapIterate; headingIterate < NUMMAPS; headingIterate++)
|
||||
{
|
||||
UINT8 actnum = 0;
|
||||
boolean headingisname = false;
|
||||
boolean wide = false;
|
||||
|
||||
if (mapAddedAlready[headingIterate] == true)
|
||||
{
|
||||
// Already added under another heading
|
||||
continue;
|
||||
}
|
||||
|
||||
if (M_CanShowLevelOnPlatter(headingIterate, gt) == false)
|
||||
{
|
||||
// Don't show this one
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!fastcmp(mapheaderinfo[mapIterate]->selectheading, mapheaderinfo[headingIterate]->selectheading))
|
||||
{
|
||||
// Headers don't match
|
||||
continue;
|
||||
}
|
||||
|
||||
actnum = mapheaderinfo[headingIterate]->actnum;
|
||||
headingisname = (fastcmp(mapheaderinfo[headingIterate]->selectheading, mapheaderinfo[headingIterate]->lvlttl));
|
||||
wide = (mapheaderinfo[headingIterate]->menuflags & LF2_WIDEICON);
|
||||
|
||||
// preparing next position to drop mapnum into
|
||||
if (levelselect.rows[startrow].maplist[0])
|
||||
{
|
||||
if (col == 2 // no more space on the row?
|
||||
|| wide
|
||||
|| (mapheaderinfo[prevmapnum]->menuflags & LF2_WIDEICON)
|
||||
|| !(fastcmp(mapheaderinfo[mapnum]->selectheading, mapheaderinfo[prevmapnum]->selectheading))) // a new heading is starting?
|
||||
|| wide || forceNewRow)
|
||||
{
|
||||
col = 0;
|
||||
row++;
|
||||
}
|
||||
else
|
||||
{
|
||||
col++;
|
||||
}
|
||||
}
|
||||
|
||||
levelselect.rows[row].maplist[col] = mapnum+1; // putting the map on the platter
|
||||
levelselect.rows[row].mapavailable[col] = M_LevelAvailableOnPlatter(mapnum);
|
||||
if (headerRow == -1)
|
||||
{
|
||||
// Set where the header row is meant to be
|
||||
headerRow = row;
|
||||
}
|
||||
|
||||
levelselect.rows[row].maplist[col] = headingIterate+1; // putting the map on the platter
|
||||
levelselect.rows[row].mapavailable[col] = M_LevelAvailableOnPlatter(headingIterate);
|
||||
|
||||
if ((lswide(row) = wide)) // intentionally assignment
|
||||
{
|
||||
|
@ -5283,7 +5373,7 @@ static boolean M_PrepareLevelPlatter(INT32 gt, boolean nextmappick)
|
|||
levelselect.rows[row].mapavailable[2] = levelselect.rows[row].mapavailable[1] = levelselect.rows[row].mapavailable[0];
|
||||
}
|
||||
|
||||
if (nextmappick && cv_nextmap.value == mapnum+1) // A little quality of life improvement.
|
||||
if (nextmappick && cv_nextmap.value == headingIterate+1) // A little quality of life improvement.
|
||||
{
|
||||
lsrow = row;
|
||||
lscol = col;
|
||||
|
@ -5292,6 +5382,8 @@ static boolean M_PrepareLevelPlatter(INT32 gt, boolean nextmappick)
|
|||
// individual map name
|
||||
if (levelselect.rows[row].mapavailable[col])
|
||||
{
|
||||
anyAvailable = true;
|
||||
|
||||
if (headingisname)
|
||||
{
|
||||
if (actnum)
|
||||
|
@ -5302,7 +5394,7 @@ static boolean M_PrepareLevelPlatter(INT32 gt, boolean nextmappick)
|
|||
else if (wide)
|
||||
{
|
||||
// Yes, with LF2_WIDEICON it'll continue on over into the next 17+1 char block. That's alright; col is always zero, the string is contiguous, and the maximum length is lvlttl[22] + ' ' + ZONE + ' ' + INT32, which is about 39 or so - barely crossing into the third column.
|
||||
char* mapname = G_BuildMapTitle(mapnum+1);
|
||||
char* mapname = G_BuildMapTitle(headingIterate+1);
|
||||
strcpy(levelselect.rows[row].mapnames[col], (const char *)mapname);
|
||||
Z_Free(mapname);
|
||||
}
|
||||
|
@ -5311,9 +5403,9 @@ static boolean M_PrepareLevelPlatter(INT32 gt, boolean nextmappick)
|
|||
char mapname[22+1+11]; // lvlttl[22] + ' ' + INT32
|
||||
|
||||
if (actnum)
|
||||
sprintf(mapname, "%s %d", mapheaderinfo[mapnum]->lvlttl, actnum);
|
||||
sprintf(mapname, "%s %d", mapheaderinfo[headingIterate]->lvlttl, actnum);
|
||||
else
|
||||
strcpy(mapname, mapheaderinfo[mapnum]->lvlttl);
|
||||
strcpy(mapname, mapheaderinfo[headingIterate]->lvlttl);
|
||||
|
||||
if (strlen(mapname) >= 17)
|
||||
strcpy(mapname+17-3, "...");
|
||||
|
@ -5322,27 +5414,36 @@ static boolean M_PrepareLevelPlatter(INT32 gt, boolean nextmappick)
|
|||
}
|
||||
}
|
||||
else
|
||||
sprintf(levelselect.rows[row].mapnames[col], "???");
|
||||
|
||||
// creating header text
|
||||
if (!col && ((row == startrow) || !(fastcmp(mapheaderinfo[mapnum]->selectheading, mapheaderinfo[levelselect.rows[row-1].maplist[0]-1]->selectheading))))
|
||||
{
|
||||
if (!levelselect.rows[row].mapavailable[col])
|
||||
sprintf(levelselect.rows[row].header, "???");
|
||||
else
|
||||
{
|
||||
sprintf(levelselect.rows[row].header, "%s", mapheaderinfo[mapnum]->selectheading);
|
||||
if (!(mapheaderinfo[mapnum]->levelflags & LF_NOZONE) && headingisname)
|
||||
{
|
||||
sprintf(levelselect.rows[row].header + strlen(levelselect.rows[row].header), " ZONE");
|
||||
}
|
||||
}
|
||||
sprintf(levelselect.rows[row].mapnames[col], "???");
|
||||
}
|
||||
|
||||
prevmapnum = mapnum;
|
||||
// Done adding this one
|
||||
mapAddedAlready[headingIterate] = true;
|
||||
forceNewRow = wide;
|
||||
}
|
||||
|
||||
mapnum++;
|
||||
if (headerRow == -1)
|
||||
{
|
||||
// Shouldn't happen
|
||||
continue;
|
||||
}
|
||||
|
||||
// creating header text
|
||||
if (anyAvailable == false)
|
||||
{
|
||||
sprintf(levelselect.rows[headerRow].header, "???");
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(levelselect.rows[headerRow].header, "%s", mapheaderinfo[mapIterate]->selectheading);
|
||||
|
||||
if (!(mapheaderinfo[mapIterate]->levelflags & LF_NOZONE)
|
||||
&& fastcmp(mapheaderinfo[mapIterate]->selectheading, mapheaderinfo[mapIterate]->lvlttl))
|
||||
{
|
||||
sprintf(levelselect.rows[headerRow].header + strlen(levelselect.rows[headerRow].header), " ZONE");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SYMMETRICAL_PLATTER
|
||||
|
|
Loading…
Reference in a new issue