Merge branch 'menu-flow-polish' into 'master'

Menu flow polish

See merge request KartKrew/Kart!907
This commit is contained in:
Oni 2023-02-02 03:52:37 +00:00
commit b3a299e7e6
56 changed files with 850 additions and 360 deletions

View file

@ -1859,7 +1859,15 @@ void CV_RevertNetVars(void)
{
if (cvar->revert.v.string != NULL)
{
Setvalue(cvar, cvar->revert.v.string, false);
Setvalue(
cvar,
cvar->revert.v.string,
#ifdef DEVELOP
(cvar == &cv_cheats)
#else
false
#endif
);
if (cvar->revert.allocated)
{

View file

@ -1533,7 +1533,8 @@ static boolean CL_FinishedFileList(void)
{
D_QuitNetGame();
CL_Reset();
D_StartTitle();
D_ClearState();
M_StartControlPanel();
M_StartMessage(M_GetText(
"You have too many WAD files loaded\n"
"to add ones the server is using.\n"
@ -1546,7 +1547,8 @@ static boolean CL_FinishedFileList(void)
{
D_QuitNetGame();
CL_Reset();
D_StartTitle();
D_ClearState();
M_StartControlPanel();
M_StartMessage(M_GetText(
"You have the wrong addons loaded.\n\n"
"To play on this server, restart\n"
@ -1585,7 +1587,8 @@ static boolean CL_FinishedFileList(void)
{
D_QuitNetGame();
CL_Reset();
D_StartTitle();
D_ClearState();
M_StartControlPanel();
M_StartMessage(M_GetText(
"An error occured when trying to\n"
"download missing addons.\n"
@ -1713,7 +1716,8 @@ static boolean CL_ServerConnectionSearchTicker(tic_t *asksent)
D_QuitNetGame();
CL_Reset();
D_StartTitle();
D_ClearState();
M_StartControlPanel();
M_StartMessage(va(
"Your EXE differs from the server.\n"
@ -1864,7 +1868,8 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic
CONS_Printf(M_GetText("Network game synchronization aborted.\n"));
D_QuitNetGame();
CL_Reset();
D_StartTitle();
D_ClearState();
M_StartControlPanel();
M_StartMessage(M_GetText(
"The direct download encountered an error.\n"
"See the logfile for more info.\n"
@ -1893,7 +1898,8 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic
CONS_Printf(M_GetText("Network game synchronization aborted.\n"));
D_QuitNetGame();
CL_Reset();
D_StartTitle();
D_ClearState();
M_StartControlPanel();
M_StartMessage(M_GetText(
"5 minute wait time exceeded.\n"
"You may retry connection.\n"
@ -1982,7 +1988,8 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic
D_QuitNetGame();
CL_Reset();
D_StartTitle();
D_ClearState();
M_StartControlPanel();
return false;
}
@ -2507,6 +2514,14 @@ static void Command_connect(void)
SplitScreen_OnChange();
}
// Menu restore state.
restoreMenu = &PLAY_MP_OptSelectDef;
S_ChangeMusicInternal("NETMD2", true);
if (setup_numplayers == 0)
{
setup_numplayers = 1;
}
CL_ConnectToServer();
}
@ -3142,7 +3157,8 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
D_QuitNetGame();
CL_Reset();
D_StartTitle();
D_ClearState();
M_StartControlPanel();
if (msg == KICK_MSG_CON_FAIL)
M_StartMessage(M_GetText("Server closed connection\n(Synch failure)\nPress (B)\n"), NULL, MM_NOTHING);
@ -4169,7 +4185,8 @@ static void HandleShutdown(SINT8 node)
LUA_HookBool(false, HOOK(GameQuit));
D_QuitNetGame();
CL_Reset();
D_StartTitle();
D_ClearState();
M_StartControlPanel();
M_StartMessage(M_GetText("Server has shutdown\n\nPress (B)\n"), NULL, MM_NOTHING);
}
@ -4184,7 +4201,8 @@ static void HandleTimeout(SINT8 node)
LUA_HookBool(false, HOOK(GameQuit));
D_QuitNetGame();
CL_Reset();
D_StartTitle();
D_ClearState();
M_StartControlPanel();
M_StartMessage(M_GetText("Server Timeout\n\nPress (B)\n"), NULL, MM_NOTHING);
}
@ -4370,7 +4388,8 @@ static void HandlePacketFromAwayNode(SINT8 node)
D_QuitNetGame();
CL_Reset();
D_StartTitle();
D_ClearState();
M_StartControlPanel();
if (reason[1] == '|')
{

View file

@ -915,31 +915,12 @@ void D_SRB2Loop(void)
// =========================================================================
//
// D_StartTitle
// D_ClearState
//
void D_StartTitle(void)
void D_ClearState(void)
{
INT32 i;
S_StopMusic();
if (netgame)
{
G_SetGamestate(GS_WAITINGPLAYERS); // hack to prevent a command repeat
if (server)
{
i = G_GetFirstMapOfGametype(gametype)+1;
if (i > nummapheaders)
I_Error("D_StartTitle: No valid map ID found!?");
COM_BufAddText(va("map %s\n", G_BuildMapName(i)));
}
return;
}
// okay, stop now
// (otherwise the game still thinks we're playing!)
SV_StopServer();
@ -979,15 +960,25 @@ void D_StartTitle(void)
memset(gamekeydown, 0, sizeof (gamekeydown));
memset(deviceResponding, false, sizeof (deviceResponding));
F_StartTitleScreen();
M_ClearMenus(false);
// Reset the palette
if (rendermode != render_none)
V_SetPaletteLump("PLAYPAL");
// The title screen is obviously not a tutorial! (Unless I'm mistaken)
tutorialmode = false;
G_SetGamestate(GS_NULL);
}
//
// D_StartTitle
//
void D_StartTitle(void)
{
S_StopMusic();
D_ClearState();
F_StartTitleScreen();
M_ClearMenus(false);
}
//

View file

@ -57,6 +57,7 @@ const char *D_Home(void);
//
// BASE LEVEL
//
void D_ClearState(void);
void D_StartTitle(void);
#ifdef __cplusplus

View file

@ -2971,6 +2971,7 @@ static void Command_Map_f(void)
if (!Playing())
{
multiplayer = true;
restoreMenu = NULL;
}
}
@ -5782,7 +5783,10 @@ void Command_ExitGame_f(void)
closefilemenu(true);
if (!modeattacking)
D_StartTitle();
{
D_ClearState();
M_StartControlPanel();
}
}
void Command_Retry_f(void)

View file

@ -1638,9 +1638,14 @@ void F_GameEndDrawer(void)
void F_GameEndTicker(void)
{
if (timetonext > 0)
{
timetonext--;
}
else
D_StartTitle();
{
nextmap = NEXTMAP_TITLE;
G_EndGame();
}
}

View file

@ -4009,8 +4009,6 @@ void G_StopDemo(void)
Z_Free(demobuf.buffer);
demobuf.buffer = NULL;
demo.playback = false;
if (demo.title)
modeattacking = false;
demo.title = false;
demo.timing = false;
singletics = false;

View file

@ -2990,7 +2990,8 @@ void G_ExitLevel(void)
{
D_QuitNetGame();
CL_Reset();
D_StartTitle();
D_ClearState();
M_StartControlPanel();
}
}
else
@ -4003,15 +4004,7 @@ void G_AfterIntermission(void)
if (demo.playback)
{
G_StopDemo();
#if 0
if (demo.inreplayhut)
M_ReplayHut(0);
else
#endif
D_StartTitle();
M_PlaybackQuit(0);
return;
}
else if (demo.recording && (modeattacking || demo.savemode != DSM_NOTSAVING))
@ -4170,8 +4163,8 @@ void G_EndGame(void)
{
if (nextmap == NEXTMAP_CEREMONY) // end game with ceremony
{
D_StartTitle(); //F_StartEnding(); -- temporary
return;
/*F_StartEnding(); -- temporary
return;*/
}
if (nextmap == NEXTMAP_CREDITS) // end game with credits
{
@ -4185,8 +4178,28 @@ void G_EndGame(void)
}
}
// direct or competitive multiplayer, so go back to title screen.
D_StartTitle();
// In a netgame, don't unwittingly boot everyone.
if (netgame)
{
S_StopMusic();
G_SetGamestate(GS_WAITINGPLAYERS); // hack to prevent a command repeat
if (server)
{
UINT16 map = G_GetFirstMapOfGametype(gametype)+1;
if (map > nummapheaders)
I_Error("G_EndGame: No valid map ID found!?");
COM_BufAddText(va("map %s\n", G_BuildMapName(map)));
}
return;
}
// Time to return to the menu.
D_ClearState();
M_StartControlPanel();
}
//

View file

@ -2018,7 +2018,7 @@ static void HU_DrawDemoInfo(void)
V_DrawRightAlignedThinString(BASEVIDWIDTH-2, BASEVIDHEIGHT-10, V_ALLOWLOWERCASE, demo.titlename);
}
if (modeattacking)
if (modeattacking & ATTACKING_TIME)
{
V_DrawRightAlignedString((BASEVIDWIDTH/2)-4, BASEVIDHEIGHT-24, V_YELLOWMAP|V_MONOSPACE, "BEST TIME:");
if (hu_demotime != UINT32_MAX)
@ -2028,7 +2028,10 @@ static void HU_DrawDemoInfo(void)
G_TicsToCentiseconds(hu_demotime)));
else
V_DrawString((BASEVIDWIDTH/2)+4, BASEVIDHEIGHT-24, V_MONOSPACE, "--'--\"--");
}
if (modeattacking & ATTACKING_LAP)
{
V_DrawRightAlignedString((BASEVIDWIDTH/2)-4, BASEVIDHEIGHT-16, V_YELLOWMAP|V_MONOSPACE, "BEST LAP:");
if (hu_demolap != UINT32_MAX)
V_DrawString((BASEVIDWIDTH/2)+4, BASEVIDHEIGHT-16, V_MONOSPACE, va("%i'%02i\"%02i",

View file

@ -154,6 +154,7 @@ struct menu_t
INT16 x, y; // x, y of menu
INT16 extra1, extra2; // Can be whatever really! Options menu uses extra1 for bg colour.
const char *music; // Track to play in M_PlayMenuJam. NULL for default, "." to stop
INT16 transitionID; // only transition if IDs match
INT16 transitionTics; // tics for transitions out
@ -466,7 +467,10 @@ typedef enum
void Moviemode_option_Onchange(void);
extern menu_t *currentMenu;
extern menu_t *restoreMenu;
extern char dummystaffname[22];
extern consvar_t cv_dummystaff;
extern INT16 itemOn; // menu item skull is on, Hack by Tails 09-18-2002
extern INT16 skullAnimCounter; // skull animation counter
@ -582,6 +586,7 @@ boolean M_MenuExtraPressed(UINT8 pid);
boolean M_MenuExtraHeld(UINT8 pid);
void M_StartControlPanel(void);
menu_t *M_SpecificMenuRestore(menu_t *torestore);
void M_ClearMenus(boolean callexitmenufunc);
void M_SelectableClearMenus(INT32 choice);
void M_SetupNextMenu(menu_t *menudef, boolean nofade);
@ -589,9 +594,10 @@ void M_GoBack(INT32 choice);
void M_Ticker(void);
void M_Init(void);
void M_PlayMenuJam(void);
void M_MenuTypingInput(INT32 key);
extern menu_t MessageDef;
void M_StartMessage(const char *string, void *routine, menumessagetype_t itemtype);
void M_StopMessage(INT32 choice);
void M_DrawMenuMessage(void);
@ -784,6 +790,7 @@ extern struct mpmenu_s {
} mpmenu;
// Time Attack
void M_PrepareTimeAttack(INT32 choice);
void M_StartTimeAttack(INT32 choice);
void M_ReplayTimeAttack(INT32 choice);
void M_HandleStaffReplay(INT32 choice);
@ -1179,6 +1186,7 @@ boolean M_StatisticsInputs(INT32 ch);
0,\
source,\
x, y,\
NULL,\
0, 0,\
M_DrawGenericMenu,\
NULL,\
@ -1195,7 +1203,8 @@ boolean M_StatisticsInputs(INT32 ch);
0,\
source,\
0, 0,\
0, 0, \
0, 0,\
NULL,\
1, 5,\
M_DrawKartGamemodeMenu,\
NULL,\
@ -1211,7 +1220,8 @@ boolean M_StatisticsInputs(INT32 ch);
0,\
source,\
0, 0,\
0, 0, \
0, 0,\
"EXTRAS",\
1, 5,\
M_DrawImageDef,\
NULL,\

View file

@ -237,7 +237,7 @@ static void M_DrawMenuParty(void)
UINT16 color;
UINT8 *colormap;
if (setup_numplayers == 0 || currentMenu == &PLAY_CharSelectDef)
if (setup_numplayers == 0 || currentMenu == &PLAY_CharSelectDef || currentMenu == &MISC_ChallengesDef)
{
return;
}
@ -505,9 +505,6 @@ void M_DrawMenuMessage(void)
void M_Drawer(void)
{
if (currentMenu == &MessageDef)
menuactive = true;
if (menuwipe)
F_WipeStartScreen();
@ -2364,11 +2361,11 @@ static void M_MPOptDrawer(menu_t *m, INT16 extend[3][3])
if (extend[i][2])
{
for (j=0; j < extend[i][2]/2; j++)
for (j=0; j <= extend[i][2]/2; j++)
{
// Draw rectangles that look like the current selected item starting from the top of the actual selection graphic and going up to where it's supposed to go.
// With colour 169 (that's the index of the shade of black the plague colourization gives us. ...No I don't like using a magic number either.
V_DrawFill(x + (extend[i][2]/2) - j - (buttback->width/2), (y + extend[i][2]) - (2*j), 225, 2, 169);
V_DrawFill((x-1) + (extend[i][2]/2) - j - (buttback->width/2), (y + extend[i][2]) - (2*j), 226, 2, 169);
}
}
V_DrawFixedPatch((x + (extend[i][2]/2)) *FRACUNIT, (y + extend[i][2])*FRACUNIT, FRACUNIT, 0, buttback, colormap);
@ -3794,8 +3791,6 @@ void M_DrawPause(void)
}
}
tic_t playback_last_menu_interaction_leveltime = 0;
void M_DrawPlaybackMenu(void)
{
INT16 i;
@ -3804,56 +3799,6 @@ void M_DrawPlaybackMenu(void)
UINT32 transmap = max(0, (INT32)(leveltime - playback_last_menu_interaction_leveltime - 4*TICRATE)) / 5;
transmap = min(8, transmap) << V_ALPHASHIFT;
if (leveltime - playback_last_menu_interaction_leveltime >= 6*TICRATE)
playback_last_menu_interaction_leveltime = leveltime - 6*TICRATE;
// Toggle items
if (paused && !demo.rewinding)
{
PAUSE_PlaybackMenu[playback_pause].status = PAUSE_PlaybackMenu[playback_fastforward].status = PAUSE_PlaybackMenu[playback_rewind].status = IT_DISABLED;
PAUSE_PlaybackMenu[playback_resume].status = PAUSE_PlaybackMenu[playback_advanceframe].status = PAUSE_PlaybackMenu[playback_backframe].status = IT_CALL|IT_STRING;
if (itemOn >= playback_rewind && itemOn <= playback_fastforward)
itemOn += playback_backframe - playback_rewind;
}
else
{
PAUSE_PlaybackMenu[playback_pause].status = PAUSE_PlaybackMenu[playback_fastforward].status = PAUSE_PlaybackMenu[playback_rewind].status = IT_CALL|IT_STRING;
PAUSE_PlaybackMenu[playback_resume].status = PAUSE_PlaybackMenu[playback_advanceframe].status = PAUSE_PlaybackMenu[playback_backframe].status = IT_DISABLED;
if (itemOn >= playback_backframe && itemOn <= playback_advanceframe)
itemOn -= playback_backframe - playback_rewind;
}
if (modeattacking)
{
for (i = playback_viewcount; i <= playback_view4; i++)
PAUSE_PlaybackMenu[i].status = IT_DISABLED;
//PAUSE_PlaybackMenu[playback_moreoptions].mvar1 = 72;
//PAUSE_PlaybackMenu[playback_quit].mvar1 = 88;
PAUSE_PlaybackMenu[playback_quit].mvar1 = 72;
//currentMenu->x = BASEVIDWIDTH/2 - 52;
currentMenu->x = BASEVIDWIDTH/2 - 44;
}
else
{
PAUSE_PlaybackMenu[playback_viewcount].status = IT_ARROWS|IT_STRING;
for (i = 0; i <= splitscreen; i++)
PAUSE_PlaybackMenu[playback_view1+i].status = IT_ARROWS|IT_STRING;
for (i = splitscreen+1; i < 4; i++)
PAUSE_PlaybackMenu[playback_view1+i].status = IT_DISABLED;
//PAUSE_PlaybackMenu[playback_moreoptions].mvar1 = 156;
//PAUSE_PlaybackMenu[playback_quit].mvar1 = 172;
PAUSE_PlaybackMenu[playback_quit].mvar1 = 156;
//currentMenu->x = BASEVIDWIDTH/2 - 94;
currentMenu->x = BASEVIDWIDTH/2 - 88;
}
// wip
//M_DrawTextBox(currentMenu->x-68, currentMenu->y-7, 15, 15);
//M_DrawCenteredMenu();
@ -3866,7 +3811,7 @@ void M_DrawPlaybackMenu(void)
{
if (modeattacking) continue;
if (splitscreen >= i - playback_view1)
if (r_splitscreen >= i - playback_view1)
{
INT32 ply = displayplayers[i - playback_view1];
@ -3898,18 +3843,18 @@ void M_DrawPlaybackMenu(void)
{
char *str;
if (!(i == playback_viewcount && splitscreen == 3))
if (!(i == playback_viewcount && r_splitscreen == 3))
V_DrawCharacter(BASEVIDWIDTH/2 - 4, currentMenu->y + 28 - (skullAnimCounter/5),
'\x1A' | V_SNAPTOTOP|highlightflags, false); // up arrow
if (!(i == playback_viewcount && splitscreen == 0))
if (!(i == playback_viewcount && r_splitscreen == 0))
V_DrawCharacter(BASEVIDWIDTH/2 - 4, currentMenu->y + 48 + (skullAnimCounter/5),
'\x1B' | V_SNAPTOTOP|highlightflags, false); // down arrow
switch (i)
{
case playback_viewcount:
str = va("%d", splitscreen+1);
str = va("%d", r_splitscreen+1);
break;
case playback_view1:
@ -3944,18 +3889,18 @@ static void M_DrawReplayHutReplayInfo(menudemo_t *demoref)
switch (demoref->type)
{
case MD_NOTLOADED:
V_DrawCenteredString(160, 40, V_SNAPTOTOP, "Loading replay information...");
V_DrawCenteredString(160, 40, 0, "Loading replay information...");
break;
case MD_INVALID:
V_DrawCenteredString(160, 40, V_SNAPTOTOP|warningflags, "This replay cannot be played.");
V_DrawCenteredString(160, 40, warningflags, "This replay cannot be played.");
break;
case MD_SUBDIR:
break; // Can't think of anything to draw here right now
case MD_OUTDATED:
V_DrawThinString(17, 64, V_SNAPTOTOP|V_ALLOWLOWERCASE|V_TRANSLUCENT|highlightflags, "Recorded on an outdated version.");
V_DrawThinString(17, 64, V_ALLOWLOWERCASE|V_TRANSLUCENT|highlightflags, "Recorded on an outdated version.");
/* FALLTHRU */
default:
// Draw level stuff
@ -3964,7 +3909,7 @@ static void M_DrawReplayHutReplayInfo(menudemo_t *demoref)
K_DrawMapThumbnail(
x<<FRACBITS, y<<FRACBITS,
80<<FRACBITS,
V_SNAPTOTOP|((demoref->kartspeed & DF_ENCORE) ? V_FLIP : 0),
((demoref->kartspeed & DF_ENCORE) ? V_FLIP : 0),
demoref->map,
NULL);
@ -3972,7 +3917,7 @@ static void M_DrawReplayHutReplayInfo(menudemo_t *demoref)
{
static angle_t rubyfloattime = 0;
const fixed_t rubyheight = FINESINE(rubyfloattime>>ANGLETOFINESHIFT);
V_DrawFixedPatch((x+40)<<FRACBITS, ((y+25)<<FRACBITS) - (rubyheight<<1), FRACUNIT, V_SNAPTOTOP, W_CachePatchName("RUBYICON", PU_CACHE), NULL);
V_DrawFixedPatch((x+40)<<FRACBITS, ((y+25)<<FRACBITS) - (rubyheight<<1), FRACUNIT, 0, W_CachePatchName("RUBYICON", PU_CACHE), NULL);
rubyfloattime += FixedMul(ANGLE_MAX/NEWTICRATE, renderdeltatics);
}
@ -3981,14 +3926,14 @@ static void M_DrawReplayHutReplayInfo(menudemo_t *demoref)
if (demoref->map < nummapheaders && mapheaderinfo[demoref->map])
{
char *title = G_BuildMapTitle(demoref->map+1);
V_DrawString(x, y, V_SNAPTOTOP, title);
V_DrawString(x, y, 0, title);
Z_Free(title);
}
else
V_DrawString(x, y, V_SNAPTOTOP|V_ALLOWLOWERCASE|V_TRANSLUCENT, "Level is not loaded.");
V_DrawString(x, y, V_ALLOWLOWERCASE|V_TRANSLUCENT, "Level is not loaded.");
if (demoref->numlaps)
V_DrawThinString(x, y+9, V_SNAPTOTOP|V_ALLOWLOWERCASE, va("(%d laps)", demoref->numlaps));
V_DrawThinString(x, y+9, V_ALLOWLOWERCASE, va("(%d laps)", demoref->numlaps));
{
const char *gtstring;
@ -4004,42 +3949,42 @@ static void M_DrawReplayHutReplayInfo(menudemo_t *demoref)
gtstring = va("%s (%s)", gtstring, kartspeed_cons_t[(demoref->kartspeed & ~DF_ENCORE) + 1].strvalue);
}
V_DrawString(x, y+20, V_SNAPTOTOP|V_ALLOWLOWERCASE, gtstring);
V_DrawString(x, y+20, V_ALLOWLOWERCASE, gtstring);
}
if (!demoref->standings[0].ranking)
{
// No standings were loaded!
V_DrawString(x, y+39, V_SNAPTOTOP|V_ALLOWLOWERCASE|V_TRANSLUCENT, "No standings available.");
V_DrawString(x, y+39, V_ALLOWLOWERCASE|V_TRANSLUCENT, "No standings available.");
break;
}
V_DrawThinString(x, y+29, V_SNAPTOTOP|highlightflags, "WINNER");
V_DrawString(x+38, y+30, V_SNAPTOTOP|V_ALLOWLOWERCASE, demoref->standings[0].name);
V_DrawThinString(x, y+29, highlightflags, "WINNER");
V_DrawString(x+38, y+30, V_ALLOWLOWERCASE, demoref->standings[0].name);
if (demoref->gametype >= 0)
{
if (gametypes[demoref->gametype]->rules & GTR_POINTLIMIT)
{
V_DrawThinString(x, y+39, V_SNAPTOTOP|highlightflags, "SCORE");
V_DrawThinString(x, y+39, highlightflags, "SCORE");
}
else
{
V_DrawThinString(x, y+39, V_SNAPTOTOP|highlightflags, "TIME");
V_DrawThinString(x, y+39, highlightflags, "TIME");
}
if (demoref->standings[0].timeorscore == (UINT32_MAX-1))
{
V_DrawThinString(x+32, y+39, V_SNAPTOTOP, "NO CONTEST");
V_DrawThinString(x+32, y+39, 0, "NO CONTEST");
}
else if (gametypes[demoref->gametype]->rules & GTR_POINTLIMIT)
{
V_DrawString(x+32, y+40, V_SNAPTOTOP, va("%d", demoref->standings[0].timeorscore));
V_DrawString(x+32, y+40, 0, va("%d", demoref->standings[0].timeorscore));
}
else
{
V_DrawRightAlignedString(x+84, y+40, V_SNAPTOTOP, va("%d'%02d\"%02d",
V_DrawRightAlignedString(x+84, y+40, 0, va("%d'%02d\"%02d",
G_TicsToMinutes(demoref->standings[0].timeorscore, true),
G_TicsToSeconds(demoref->standings[0].timeorscore),
G_TicsToCentiseconds(demoref->standings[0].timeorscore)
@ -4069,7 +4014,7 @@ static void M_DrawReplayHutReplayInfo(menudemo_t *demoref)
GTC_MENUCACHE);
}
V_DrawMappedPatch(BASEVIDWIDTH-15 - SHORT(patch->width), y+20, V_SNAPTOTOP, patch, colormap);
V_DrawMappedPatch(BASEVIDWIDTH-15 - SHORT(patch->width), y+20, 0, patch, colormap);
break;
}
@ -4134,9 +4079,9 @@ void M_DrawReplayHut(void)
cursory = localy;
if ((currentMenu->menuitems[i].status & IT_DISPLAY)==IT_STRING)
V_DrawString(x, localy, V_SNAPTOTOP|V_SNAPTOLEFT, currentMenu->menuitems[i].text);
V_DrawString(x, localy, 0, currentMenu->menuitems[i].text);
else
V_DrawString(x, localy, V_SNAPTOTOP|V_SNAPTOLEFT|highlightflags, currentMenu->menuitems[i].text);
V_DrawString(x, localy, highlightflags, currentMenu->menuitems[i].text);
}
y += currentMenu->menuitems[replaylistitem].mvar1;
@ -4160,7 +4105,7 @@ void M_DrawReplayHut(void)
if (extrasmenu.demolist[i].type == MD_SUBDIR)
{
localx += 8;
V_DrawScaledPatch(x - 4, localy, V_SNAPTOTOP|V_SNAPTOLEFT, W_CachePatchName(dirmenu[i][DIR_TYPE] == EXT_UP ? "M_RBACK" : "M_RFLDR", PU_CACHE));
V_DrawScaledPatch(x - 4, localy, 0, W_CachePatchName(dirmenu[i][DIR_TYPE] == EXT_UP ? "M_RBACK" : "M_RFLDR", PU_CACHE));
}
if (itemOn == replaylistitem && i == (INT16)dir_on[menudepthleft])
@ -4190,27 +4135,27 @@ void M_DrawReplayHut(void)
}
}
V_DrawString(localx - (extrasmenu.replayScrollTitle>>1), localy, V_SNAPTOTOP|V_SNAPTOLEFT|highlightflags|V_ALLOWLOWERCASE, extrasmenu.demolist[i].title);
V_DrawString(localx - (extrasmenu.replayScrollTitle>>1), localy, highlightflags|V_ALLOWLOWERCASE, extrasmenu.demolist[i].title);
}
else
V_DrawString(localx, localy, V_SNAPTOTOP|V_SNAPTOLEFT|V_ALLOWLOWERCASE, extrasmenu.demolist[i].title);
V_DrawString(localx, localy, V_ALLOWLOWERCASE, extrasmenu.demolist[i].title);
}
// Draw scrollbar
y = sizedirmenu*10 + currentMenu->menuitems[replaylistitem].mvar1 + 30;
if (y > SCALEDVIEWHEIGHT-80)
{
V_DrawFill(BASEVIDWIDTH-4, 75, 4, SCALEDVIEWHEIGHT-80, V_SNAPTOTOP|V_SNAPTORIGHT|159);
V_DrawFill(BASEVIDWIDTH-3, 76 + (SCALEDVIEWHEIGHT-80) * replayhutmenuy / y, 2, (((SCALEDVIEWHEIGHT-80) * (SCALEDVIEWHEIGHT-80))-1) / y - 1, V_SNAPTOTOP|V_SNAPTORIGHT|149);
V_DrawFill(BASEVIDWIDTH-4, 75, 4, SCALEDVIEWHEIGHT-80, 159);
V_DrawFill(BASEVIDWIDTH-3, 76 + (SCALEDVIEWHEIGHT-80) * replayhutmenuy / y, 2, (((SCALEDVIEWHEIGHT-80) * (SCALEDVIEWHEIGHT-80))-1) / y - 1, 149);
}
// Draw the cursor
V_DrawScaledPatch(currentMenu->x - 24, cursory, V_SNAPTOTOP|V_SNAPTOLEFT,
V_DrawScaledPatch(currentMenu->x - 24, cursory, 0,
W_CachePatchName("M_CURSOR", PU_CACHE));
V_DrawString(currentMenu->x, cursory, V_SNAPTOTOP|V_SNAPTOLEFT|highlightflags, currentMenu->menuitems[itemOn].text);
V_DrawString(currentMenu->x, cursory, highlightflags, currentMenu->menuitems[itemOn].text);
// Now draw some replay info!
V_DrawFill(10, 10, 300, 60, V_SNAPTOTOP|159);
V_DrawFill(10, 10, 300, 60, 159);
if (itemOn == replaylistitem)
{
@ -4234,17 +4179,17 @@ void M_DrawReplayStartMenu(void)
patch_t *patch;
UINT8 *colormap;
V_DrawRightAlignedString(BASEVIDWIDTH-100, STARTY + i*20, V_SNAPTOTOP|highlightflags, va("%2d", demoref->standings[i].ranking));
V_DrawThinString(BASEVIDWIDTH-96, STARTY + i*20, V_SNAPTOTOP|V_ALLOWLOWERCASE, demoref->standings[i].name);
V_DrawRightAlignedString(BASEVIDWIDTH-100, STARTY + i*20,highlightflags, va("%2d", demoref->standings[i].ranking));
V_DrawThinString(BASEVIDWIDTH-96, STARTY + i*20, V_ALLOWLOWERCASE, demoref->standings[i].name);
if (demoref->standings[i].timeorscore == UINT32_MAX-1)
V_DrawThinString(BASEVIDWIDTH-92, STARTY + i*20 + 9, V_SNAPTOTOP, "NO CONTEST");
V_DrawThinString(BASEVIDWIDTH-92, STARTY + i*20 + 9, 0, "NO CONTEST");
else if (demoref->gametype < 0)
;
else if (gametypes[demoref->gametype]->rules & GTR_POINTLIMIT)
V_DrawString(BASEVIDWIDTH-92, STARTY + i*20 + 9, V_SNAPTOTOP, va("%d", demoref->standings[i].timeorscore));
V_DrawString(BASEVIDWIDTH-92, STARTY + i*20 + 9, 0, va("%d", demoref->standings[i].timeorscore));
else
V_DrawRightAlignedString(BASEVIDWIDTH-40, STARTY + i*20 + 9, V_SNAPTOTOP, va("%d'%02d\"%02d",
V_DrawRightAlignedString(BASEVIDWIDTH-40, STARTY + i*20 + 9, 0, va("%d'%02d\"%02d",
G_TicsToMinutes(demoref->standings[i].timeorscore, true),
G_TicsToSeconds(demoref->standings[i].timeorscore),
G_TicsToCentiseconds(demoref->standings[i].timeorscore)
@ -4272,7 +4217,7 @@ void M_DrawReplayStartMenu(void)
GTC_MENUCACHE);
}
V_DrawMappedPatch(BASEVIDWIDTH-5 - SHORT(patch->width), STARTY + i*20, V_SNAPTOTOP, patch, colormap);
V_DrawMappedPatch(BASEVIDWIDTH-5 - SHORT(patch->width), STARTY + i*20, 0, patch, colormap);
}
#undef STARTY
@ -4300,10 +4245,10 @@ void M_DrawReplayStartMenu(void)
}
}
V_DrawFill(10, 10, 300, 60, V_SNAPTOTOP|159);
V_DrawFill(10, 10, 300, 60, 159);
M_DrawReplayHutReplayInfo(demoref);
V_DrawString(10, 72, V_SNAPTOTOP|highlightflags|V_ALLOWLOWERCASE, demoref->title);
V_DrawString(10, 72, highlightflags|V_ALLOWLOWERCASE, demoref->title);
// Draw a warning prompt if needed
switch (demoref->addonstatus)
@ -4329,7 +4274,7 @@ void M_DrawReplayStartMenu(void)
return;
}
V_DrawSmallString(4, BASEVIDHEIGHT-14, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, warning);
V_DrawSmallString(4, BASEVIDHEIGHT-14, V_ALLOWLOWERCASE, warning);
}
// Draw misc menus:

View file

@ -35,6 +35,7 @@ boolean fromlevelselect = false;
// current menudef
menu_t *currentMenu = &MAIN_ProfilesDef;
menu_t *restoreMenu = NULL;
char dummystaffname[22];
@ -81,7 +82,7 @@ static CV_PossibleValue_t dummystaff_cons_t[] = {{0, "MIN"}, {100, "MAX"}, {0, N
static consvar_t cv_dummyteam = CVAR_INIT ("dummyteam", "Spectator", CV_HIDDEN, dummyteam_cons_t, NULL);
//static cv_dummyspectate = CVAR_INITconsvar_t ("dummyspectate", "Spectator", CV_HIDDEN, dummyspectate_cons_t, NULL);
static consvar_t cv_dummyscramble = CVAR_INIT ("dummyscramble", "Random", CV_HIDDEN, dummyscramble_cons_t, NULL);
static consvar_t cv_dummystaff = CVAR_INIT ("dummystaff", "0", CV_HIDDEN|CV_CALL, dummystaff_cons_t, Dummystaff_OnChange);
consvar_t cv_dummystaff = CVAR_INIT ("dummystaff", "0", CV_HIDDEN|CV_CALL, dummystaff_cons_t, Dummystaff_OnChange);
consvar_t cv_dummyspectate = CVAR_INIT ("dummyspectate", "Spectator", CV_HIDDEN, dummyspectate_cons_t, NULL);
// ==========================================================================
@ -355,6 +356,101 @@ boolean M_Responder(event_t *ev)
return true;
}
void M_PlayMenuJam(void)
{
menu_t *refMenu = (menuactive ? currentMenu : restoreMenu);
if (challengesmenu.pending)
return;
if (Playing())
return;
if (refMenu != NULL && refMenu->music != NULL)
{
if (refMenu->music[0] == '.' && refMenu->music[1] == '\0')
{
S_StopMusic();
}
else
{
S_ChangeMusicInternal(refMenu->music, true);
}
return;
}
if (cv_menujam_update.value)
{
CV_AddValue(&cv_menujam, 1);
CV_SetValue(&cv_menujam_update, 0);
}
S_ChangeMusicInternal(cv_menujam.string, true);
}
//
// M_SpecificMenuRestore
//
menu_t *M_SpecificMenuRestore(menu_t *torestore)
{
// I'd advise the following not be a switch case because they're pointers...
if (torestore == &PLAY_CupSelectDef
|| torestore == &PLAY_LevelSelectDef
|| torestore == &PLAY_TimeAttackDef)
{
// Handle unlock restrictions
cupheader_t *currentcup = levellist.levelsearch.cup;
M_SetupGametypeMenu(-1);
if (levellist.newgametype == GT_RACE)
{
M_SetupRaceMenu(-1);
}
if (!M_LevelListFromGametype(-1))
{
if (PLAY_LevelSelectDef.prevMenu == &PLAY_CupSelectDef)
{
torestore = PLAY_CupSelectDef.prevMenu;
}
else
{
torestore = PLAY_LevelSelectDef.prevMenu;
}
}
else
{
if (currentcup != NULL && levellist.levelsearch.cup == NULL)
{
torestore = &PLAY_CupSelectDef;
}
else if (torestore == &PLAY_TimeAttackDef)
{
M_PrepareTimeAttack(0);
}
}
}
else if (torestore == &EXTRAS_ReplayHutDef)
{
// Handle modifications to the folder while playing
M_ReplayHut(0);
if (demo.inreplayhut == false)
{
torestore = &EXTRAS_MainDef;
}
}
else if (torestore == &PLAY_MP_OptSelectDef)
{
// Ticker init
M_MPOptSelectInit(-1);
}
return torestore;
}
//
// M_StartControlPanel
//
@ -370,40 +466,41 @@ void M_StartControlPanel(void)
}
// intro might call this repeatedly
if (menuactive)
if (menuactive && gamestate != GS_NULL)
{
CON_ToggleOff(); // move away console
return;
}
if (gamestate == GS_TITLESCREEN) // Set up menu state
if (gamestate == GS_TITLESCREEN && restoreMenu == NULL) // Set up menu state
{
// No instantly skipping the titlescreen.
// (We can change this timer later when extra animation is added.)
if (finalecount < 1)
return;
G_SetGamestate(GS_MENU);
gameaction = ga_nothing;
paused = false;
CON_ToggleOff();
if (cv_menujam_update.value)
{
CV_AddValue(&cv_menujam, 1);
CV_SetValue(&cv_menujam_update, 0);
}
S_ChangeMusicInternal(cv_menujam.string, true);
}
menuactive = true;
if (!Playing())
if (demo.playback)
{
currentMenu = &PAUSE_PlaybackMenuDef;
}
else if (!Playing())
{
M_StopMessage(0); // Doesn't work with MM_YESNO or MM_EVENTHANDLER... but good enough to get the game as it is currently functional again
if (gamestate != GS_MENU)
{
G_SetGamestate(GS_MENU);
gameaction = ga_nothing;
paused = false;
CON_ToggleOff();
modeattacking = ATTACKING_NONE;
}
if (cv_currprofile.value == -1) // Only ask once per session.
{
// Make sure the profile data is ready now since we need to select a profile.
@ -427,19 +524,17 @@ void M_StartControlPanel(void)
}
else
{
currentMenu = M_InterruptMenuWithChallenges(&MainDef);
if (restoreMenu == NULL)
restoreMenu = &MainDef;
currentMenu = M_SpecificMenuRestore(M_InterruptMenuWithChallenges(restoreMenu));
restoreMenu = NULL;
}
M_PlayMenuJam();
}
else
{
if (demo.playback)
{
currentMenu = &PAUSE_PlaybackMenuDef;
}
else
{
M_OpenPauseMenu();
}
M_OpenPauseMenu();
}
itemOn = currentMenu->lastOn;
@ -464,9 +559,6 @@ void M_ClearMenus(boolean callexitmenufunc)
COM_BufAddText(va("saveconfig \"%s\" -silent\n", configfile));
#endif //Alam: But not on the Dreamcast's VMUs
if (currentMenu == &MessageDef) // Oh sod off!
currentMenu = &MainDef; // Not like it matters
if (gamestate == GS_MENU) // Back to title screen
D_StartTitle();
@ -551,6 +643,7 @@ void M_SetupNextMenu(menu_t *menudef, boolean notransition)
}
M_UpdateMenuBGImage(false);
M_PlayMenuJam();
}
void M_GoBack(INT32 choice)
@ -772,6 +865,13 @@ static void M_HandleMenuInput(void)
lr = menucmd[pid].dpad_lr;
ud = menucmd[pid].dpad_ud;
// If we ever add a second horizontal menu, make it a menu_t property, not an extra check.
if (currentMenu == &PAUSE_PlaybackMenuDef)
{
ud = menucmd[pid].dpad_lr;
lr = -menucmd[pid].dpad_ud;
}
// LR does nothing in the default menu, just remap as dpad.
if (menucmd[pid].buttons & MBT_L) { lr--; }
if (menucmd[pid].buttons & MBT_R) { lr++; }

View file

@ -28,6 +28,7 @@ menu_t EXTRAS_MainDef = {
EXTRAS_Main,
0, 0,
0, 0,
"EXTRAS",
2, 5,
M_DrawExtras,
M_ExtrasTick,

View file

@ -23,6 +23,7 @@ menu_t MISC_AddonsDef = {
MISC_AddonsMenu,
50, 28,
0, 0,
"EXTRAS",
0, 0,
M_DrawAddons,
M_AddonsRefresh,

View file

@ -20,6 +20,7 @@ menu_t MISC_ChallengesDef = {
MISC_ChallengesStatsDummyMenu,
BASEVIDWIDTH/2, 32,
0, 0,
"EXTRAS",
98, 0,
M_DrawChallenges,
M_ChallengesTick,
@ -37,6 +38,7 @@ menu_t MISC_StatisticsDef = {
MISC_ChallengesStatsDummyMenu,
280, 185,
0, 0,
"EXTRAS",
98, 0,
M_DrawStatistics,
NULL,
@ -47,51 +49,6 @@ menu_t MISC_StatisticsDef = {
struct challengesmenu_s challengesmenu;
menu_t *M_InterruptMenuWithChallenges(menu_t *desiredmenu)
{
UINT8 i;
M_UpdateUnlockablesAndExtraEmblems(false);
if ((challengesmenu.pending = challengesmenu.requestnew = (M_GetNextAchievedUnlock() < MAXUNLOCKABLES)))
{
MISC_ChallengesDef.prevMenu = desiredmenu;
}
if (challengesmenu.pending || desiredmenu == NULL)
{
challengesmenu.currentunlock = MAXUNLOCKABLES;
challengesmenu.unlockcondition = NULL;
M_PopulateChallengeGrid();
if (gamedata->challengegrid)
challengesmenu.extradata = M_ChallengeGridExtraData();
memset(setup_explosions, 0, sizeof(setup_explosions));
memset(&challengesmenu.unlockcount, 0, sizeof(challengesmenu.unlockcount));
for (i = 0; i < MAXUNLOCKABLES; i++)
{
if (!unlockables[i].conditionset)
{
continue;
}
challengesmenu.unlockcount[CC_TOTAL]++;
if (!gamedata->unlocked[i])
{
continue;
}
challengesmenu.unlockcount[CC_UNLOCKED]++;
}
return &MISC_ChallengesDef;
}
return desiredmenu;
}
static void M_ChallengesAutoFocus(UINT8 unlockid, boolean fresh)
{
UINT8 i;
@ -196,6 +153,57 @@ static void M_ChallengesAutoFocus(UINT8 unlockid, boolean fresh)
}
}
menu_t *M_InterruptMenuWithChallenges(menu_t *desiredmenu)
{
UINT8 i;
UINT16 newunlock = M_GetNextAchievedUnlock();
M_UpdateUnlockablesAndExtraEmblems(false);
if ((challengesmenu.pending = (newunlock < MAXUNLOCKABLES)))
{
S_StopMusic();
MISC_ChallengesDef.prevMenu = desiredmenu;
}
if (challengesmenu.pending || desiredmenu == NULL)
{
challengesmenu.requestnew = false;
challengesmenu.currentunlock = MAXUNLOCKABLES;
challengesmenu.unlockcondition = NULL;
M_PopulateChallengeGrid();
if (gamedata->challengegrid)
challengesmenu.extradata = M_ChallengeGridExtraData();
memset(setup_explosions, 0, sizeof(setup_explosions));
memset(&challengesmenu.unlockcount, 0, sizeof(challengesmenu.unlockcount));
for (i = 0; i < MAXUNLOCKABLES; i++)
{
if (!unlockables[i].conditionset)
{
continue;
}
challengesmenu.unlockcount[CC_TOTAL]++;
if (!gamedata->unlocked[i])
{
continue;
}
challengesmenu.unlockcount[CC_UNLOCKED]++;
}
if (challengesmenu.pending)
M_ChallengesAutoFocus(newunlock, true);
return &MISC_ChallengesDef;
}
return desiredmenu;
}
void M_Challenges(INT32 choice)
{
UINT8 i;
@ -249,7 +257,6 @@ void M_ChallengesTick(void)
{
const UINT8 pid = 0;
UINT8 i, newunlock = MAXUNLOCKABLES;
boolean fresh = (challengesmenu.currentunlock >= MAXUNLOCKABLES);
// Ticking
challengesmenu.ticker++;
@ -274,7 +281,7 @@ void M_ChallengesTick(void)
if ((newunlock = M_GetNextAchievedUnlock()) < MAXUNLOCKABLES)
{
// We got one!
M_ChallengesAutoFocus(newunlock, fresh);
M_ChallengesAutoFocus(newunlock, false);
}
else
{
@ -376,7 +383,11 @@ void M_ChallengesTick(void)
if (challengesmenu.fade > 0)
{
// Fade decrease.
challengesmenu.fade--;
if (--challengesmenu.fade == 0)
{
// Play music the moment control returns.
M_PlayMenuJam();
}
}
}
}
@ -416,6 +427,8 @@ boolean M_ChallengesInputs(INT32 ch)
{
if (M_MenuBackPressed(pid) || start)
{
currentMenu->prevMenu = M_SpecificMenuRestore(currentMenu->prevMenu);
M_GoBack(0);
M_SetMenuDelay(pid);

View file

@ -26,11 +26,12 @@ menu_t EXTRAS_ReplayHutDef =
EXTRAS_ReplayHut,
30, 80,
0, 0,
0, 0,
"REPLAY",
41, 1,
M_DrawReplayHut,
NULL,
NULL,
M_QuitReplayHut,
NULL,
NULL
};
@ -58,7 +59,8 @@ menu_t EXTRAS_ReplayStartDef =
EXTRAS_ReplayStart,
27, 80,
0, 0,
0, 0,
"REPLAY",
41, 1,
M_DrawReplayStartMenu,
NULL,
NULL,
@ -102,37 +104,38 @@ void M_ReplayHut(INT32 choice)
{
(void)choice;
extrasmenu.replayScrollTitle = 0;
extrasmenu.replayScrollDelay = TICRATE;
extrasmenu.replayScrollDir = 1;
if (!demo.inreplayhut)
if (demo.inreplayhut)
{
demo.rewinding = false;
CL_ClearRewinds();
}
else
{
snprintf(menupath, 1024, "%s"PATHSEP"media"PATHSEP"replay"PATHSEP"online"PATHSEP, srb2home);
menupathindex[(menudepthleft = menudepth-1)] = strlen(menupath);
}
if (!preparefilemenu(false, true))
{
M_StartMessage("No replays found.\n\nPress (B)\n", NULL, MM_NOTHING);
demo.inreplayhut = false;
return;
}
else if (!demo.inreplayhut)
{
dir_on[menudepthleft] = 0;
demo.inreplayhut = true;
}
extrasmenu.replayScrollTitle = 0; extrasmenu.replayScrollDelay = TICRATE; extrasmenu.replayScrollDir = 1;
extrasmenu.replayScrollTitle = 0;
extrasmenu.replayScrollDelay = TICRATE;
extrasmenu.replayScrollDir = 1;
M_PrepReplayList();
menuactive = true;
M_SetupNextMenu(&EXTRAS_ReplayHutDef, false);
//G_SetGamestate(GS_TIMEATTACK);
//titlemapinaction = TITLEMAP_OFF; // Nope don't give us HOMs please
if (!demo.inreplayhut)
M_SetupNextMenu(&EXTRAS_ReplayHutDef, false);
demo.rewinding = false;
CL_ClearRewinds();
//S_ChangeMusicInternal("replst", true);
demo.inreplayhut = true;
}
// key handler
@ -223,11 +226,11 @@ void M_HandleReplayHutList(INT32 choice)
M_PrepReplayList();
break;
default:
// We can't just use M_SetupNextMenu because that'll run ReplayDef's quitroutine and boot us back to the title screen!
currentMenu->lastOn = itemOn;
currentMenu = &EXTRAS_ReplayStartDef;
M_SetupNextMenu(&EXTRAS_ReplayStartDef, true);
extrasmenu.replayScrollTitle = 0; extrasmenu.replayScrollDelay = TICRATE; extrasmenu.replayScrollDir = 1;
extrasmenu.replayScrollTitle = 0;
extrasmenu.replayScrollDelay = TICRATE;
extrasmenu.replayScrollDir = 1;
switch (extrasmenu.demolist[dir_on[menudepthleft]].addonstatus)
{
@ -267,16 +270,13 @@ void M_HandleReplayHutList(INT32 choice)
boolean M_QuitReplayHut(void)
{
// D_StartTitle does its own wipe, since GS_TIMEATTACK is now a complete gamestate.
menuactive = false;
D_StartTitle();
if (extrasmenu.demolist)
Z_Free(extrasmenu.demolist);
extrasmenu.demolist = NULL;
demo.inreplayhut = false;
M_GoBack(0);
return true;
}
@ -284,6 +284,8 @@ void M_HutStartReplay(INT32 choice)
{
(void)choice;
restoreMenu = &EXTRAS_ReplayHutDef;
M_ClearMenus(false);
demo.loadfiles = (itemOn == 0);
demo.ignorefiles = (itemOn != 0);

View file

@ -15,6 +15,7 @@ menu_t MAIN_ProfilesDef = {
MAIN_Profiles,
32, 80,
SKINCOLOR_ULTRAMARINE, 0,
NULL,
2, 5,
M_DrawProfileSelect,
M_OptionsTick,

View file

@ -43,6 +43,7 @@ menu_t OPTIONS_MainDef = {
OPTIONS_Main,
0, 0,
SKINCOLOR_SLATE, 0,
NULL,
2, 5,
M_DrawOptions,
M_OptionsTick,

View file

@ -36,6 +36,7 @@ menu_t OPTIONS_DataDef = {
OPTIONS_Data,
48, 80,
SKINCOLOR_BLUEBERRY, 0,
NULL,
2, 5,
M_DrawGenericOptions,
M_OptionsTick,

View file

@ -43,6 +43,7 @@ menu_t OPTIONS_DataAddonDef = {
OPTIONS_DataAddon,
48, 80,
SKINCOLOR_BLUEBERRY, 0,
NULL,
2, 5,
M_DrawGenericOptions,
M_OptionsTick,

View file

@ -33,6 +33,7 @@ menu_t OPTIONS_DataDiscordDef = {
OPTIONS_DataDiscord,
48, 80,
SKINCOLOR_BLUEBERRY, 0,
NULL,
2, 5,
M_DrawGenericOptions,
M_OptionsTick,

View file

@ -35,7 +35,8 @@ menu_t OPTIONS_DataEraseDef = {
0,
OPTIONS_DataErase,
48, 80,
SKINCOLOR_BLUEBERRY, 0,
SKINCOLOR_BLACK, 0,
"SHWDN2", // Danger.
2, 5,
M_DrawGenericOptions,
M_OptionsTick,

View file

@ -16,7 +16,8 @@ menu_t OPTIONS_DataProfileEraseDef = {
0,
OPTIONS_DataProfileErase,
48, 80,
SKINCOLOR_BLUEBERRY, 0,
SKINCOLOR_BLACK, 0,
"SHWDN2", // Danger.
2, 5,
M_DrawProfileErase,
M_OptionsTick,

View file

@ -19,6 +19,7 @@ menu_t OPTIONS_DataReplayDef = {
OPTIONS_DataReplay,
48, 80,
SKINCOLOR_BLUEBERRY, 0,
NULL,
2, 5,
M_DrawGenericOptions,
M_OptionsTick,

View file

@ -37,6 +37,7 @@ menu_t OPTIONS_DataScreenshotDef = {
OPTIONS_DataScreenshot,
48, 80,
SKINCOLOR_BLUEBERRY, 0,
NULL,
2, 5,
M_DrawGenericOptions,
M_OptionsTick,

View file

@ -51,6 +51,7 @@ menu_t OPTIONS_GameplayDef = {
OPTIONS_Gameplay,
48, 80,
SKINCOLOR_SCARLET, 0,
NULL,
2, 5,
M_DrawGenericOptions,
M_OptionsTick,

View file

@ -54,6 +54,7 @@ menu_t OPTIONS_GameplayItemsDef = {
OPTIONS_GameplayItems,
14, 40,
SKINCOLOR_SCARLET, 0,
NULL,
2, 5,
M_DrawItemToggles,
M_OptionsTick,

View file

@ -48,6 +48,7 @@ menu_t OPTIONS_HUDDef = {
OPTIONS_HUD,
48, 80,
SKINCOLOR_SUNSLAM, 0,
NULL,
2, 5,
M_DrawGenericOptions,
M_OptionsTick,

View file

@ -45,6 +45,7 @@ menu_t OPTIONS_HUDOnlineDef = {
OPTIONS_HUDOnline,
48, 80,
SKINCOLOR_SUNSLAM, 0,
NULL,
2, 5,
M_DrawGenericOptions,
M_OptionsTick,

View file

@ -17,6 +17,7 @@ menu_t OPTIONS_ProfilesDef = {
OPTIONS_Profiles,
32, 80,
SKINCOLOR_ULTRAMARINE, 0,
NULL,
2, 5,
M_DrawProfileSelect,
M_OptionsTick,
@ -47,7 +48,11 @@ void M_FirstPickProfile(INT32 c)
optionsmenu.profile = NULL; // Make sure to get rid of that, too.
PR_ApplyProfile(optionsmenu.profilen, 0);
M_SetupNextMenu(M_InterruptMenuWithChallenges(&MainDef), false);
if (restoreMenu == NULL)
restoreMenu = &MainDef;
M_SetupNextMenu(M_SpecificMenuRestore(M_InterruptMenuWithChallenges(restoreMenu)), false);
restoreMenu = NULL;
// Tell the game this is the last profile we picked.
CV_StealthSetValue(&cv_ttlprofilen, optionsmenu.profilen);

View file

@ -29,6 +29,7 @@ menu_t OPTIONS_EditProfileDef = {
OPTIONS_EditProfile,
32, 80,
SKINCOLOR_ULTRAMARINE, 0,
NULL,
2, 5,
M_DrawEditProfile,
M_HandleProfileEdit,

View file

@ -103,6 +103,7 @@ menu_t OPTIONS_ProfileControlsDef = {
OPTIONS_ProfileControls,
32, 80,
SKINCOLOR_ULTRAMARINE, 0,
NULL,
3, 5,
M_DrawProfileControls,
M_HandleProfileControls,

View file

@ -55,6 +55,7 @@ menu_t OPTIONS_ServerDef = {
OPTIONS_Server,
48, 70, // This menu here is slightly higher because there's a lot of options...
SKINCOLOR_VIOLET, 0,
NULL,
2, 5,
M_DrawGenericOptions,
M_OptionsTick,

View file

@ -53,6 +53,7 @@ menu_t OPTIONS_ServerAdvancedDef = {
OPTIONS_ServerAdvanced,
48, 70, // This menu here is slightly higher because there's a lot of options...
SKINCOLOR_VIOLET, 0,
NULL,
2, 5,
M_DrawGenericOptions,
M_OptionsTick,

View file

@ -57,6 +57,7 @@ menu_t OPTIONS_SoundDef = {
OPTIONS_Sound,
48, 80,
SKINCOLOR_THUNDER, 0,
NULL,
2, 5,
M_DrawGenericOptions,
M_OptionsTick,

View file

@ -59,6 +59,7 @@ menu_t OPTIONS_VideoDef = {
OPTIONS_Video,
32, 80,
SKINCOLOR_PLAGUE, 0,
NULL,
2, 5,
M_DrawGenericOptions,
M_OptionsTick,

View file

@ -51,6 +51,7 @@ menu_t OPTIONS_VideoOGLDef = {
OPTIONS_VideoOGL,
32, 80,
SKINCOLOR_PLAGUE, 0,
NULL,
2, 5,
M_DrawGenericOptions,
M_OptionsTick,

View file

@ -19,6 +19,7 @@ menu_t OPTIONS_VideoModesDef = {
OPTIONS_VideoModes,
48, 80,
SKINCOLOR_PLAGUE, 0,
NULL,
2, 5,
M_DrawVideoModes,
M_OptionsTick,

View file

@ -17,6 +17,7 @@ menu_t PLAY_CharSelectDef = {
PLAY_CharSelect,
0, 0,
0, 0,
NULL,
0, 0,
M_DrawCharacterSelect,
M_CharacterSelectTick,

View file

@ -25,9 +25,8 @@ menu_t PLAY_GamemodesDef = KARTGAMEMODEMENU(PLAY_GamemodesMenu, &PLAY_MainDef);
void M_SetupGametypeMenu(INT32 choice)
{
(void)choice;
PLAY_GamemodesDef.prevMenu = currentMenu;
if (choice != -1)
PLAY_GamemodesDef.prevMenu = currentMenu;
// Battle and Capsules (and Special) disabled
PLAY_GamemodesMenu[1].status = IT_DISABLED;
@ -65,5 +64,6 @@ void M_SetupGametypeMenu(INT32 choice)
}
}
M_SetupNextMenu(&PLAY_GamemodesDef, false);
if (choice != -1)
M_SetupNextMenu(&PLAY_GamemodesDef, false);
}

View file

@ -6,7 +6,7 @@
menuitem_t PLAY_RaceGamemodesMenu[] =
{
{IT_STRING | IT_CALL, "Grand Prix", "Compete for the best rank over five races!",
{IT_STRING | IT_CALL, "Grand Prix", "Compete for the best rank over five rounds!",
NULL, {.routine = M_SetupDifficultySelect}, 0, 0},
{IT_STRING | IT_CALL, "Match Race", "Play by your own rules in a specialized, single race!",
@ -22,9 +22,8 @@ menu_t PLAY_RaceGamemodesDef = KARTGAMEMODEMENU(PLAY_RaceGamemodesMenu, &PLAY_Ga
void M_SetupRaceMenu(INT32 choice)
{
(void)choice;
PLAY_RaceGamemodesDef.prevMenu = currentMenu;
if (choice != -1)
PLAY_RaceGamemodesDef.prevMenu = currentMenu;
// Time Attack disabled
PLAY_RaceGamemodesMenu[2].status = IT_DISABLED;
@ -36,5 +35,6 @@ void M_SetupRaceMenu(INT32 choice)
PLAY_RaceGamemodesMenu[2].status = IT_STRING | IT_CALL;
}
M_SetupNextMenu(&PLAY_RaceGamemodesDef, false);
if (choice != -1)
M_SetupNextMenu(&PLAY_RaceGamemodesDef, false);
}

View file

@ -39,6 +39,7 @@ menu_t PLAY_RaceDifficultyDef = {
PLAY_RaceDifficulty,
0, 0,
0, 0,
NULL,
1, 5,
M_DrawRaceDifficulty,
NULL,

View file

@ -8,6 +8,7 @@
#include "../v_video.h"
#include "../d_main.h" // srb2home
#include "../m_misc.h" // M_MkdirEach
#include "../z_zone.h" // Z_StrDup/Z_Free
// see ta_e
menuitem_t PLAY_TimeAttack[] =
@ -26,6 +27,7 @@ menu_t PLAY_TimeAttackDef = {
PLAY_TimeAttack,
0, 0,
0, 0,
NULL,
2, 5,
M_DrawTimeAttack,
NULL,
@ -35,6 +37,18 @@ menu_t PLAY_TimeAttackDef = {
};
typedef enum
{
tareplay_besttime = 0,
tareplay_bestlap,
tareplay_gap1,
tareplay_last,
tareplay_guest,
tareplay_staff,
tareplay_gap2,
tareplay_back
} tareplay_e;
menuitem_t PLAY_TAReplay[] =
{
{IT_STRING | IT_CALL, "Replay Best Time", NULL, NULL, {.routine = M_ReplayTimeAttack}, 0, 0},
@ -55,6 +69,7 @@ menu_t PLAY_TAReplayDef = {
PLAY_TAReplay,
0, 0,
0, 0,
NULL,
2, 5,
M_DrawTimeAttack,
NULL,
@ -63,6 +78,18 @@ menu_t PLAY_TAReplayDef = {
NULL
};
typedef enum
{
taguest_header = 0,
taguest_besttime,
taguest_bestlap,
taguest_last,
taguest_gap1,
taguest_delete,
taguest_gap2,
taguest_back
} taguest_e;
menuitem_t PLAY_TAReplayGuest[] =
{
{IT_HEADERTEXT|IT_HEADER, "Save as guest...", NULL, NULL, {NULL}, 0, 0},
@ -86,6 +113,7 @@ menu_t PLAY_TAReplayGuestDef = {
PLAY_TAReplayGuest,
0, 0,
0, 0,
NULL,
2, 5,
M_DrawTimeAttack,
NULL,
@ -94,6 +122,17 @@ menu_t PLAY_TAReplayGuestDef = {
NULL
};
typedef enum
{
taghost_besttime = 0,
taghost_bestlap,
taghost_last,
taghost_guest,
taghost_staff,
taghost_gap1,
taghost_back
} taghost_e;
menuitem_t PLAY_TAGhosts[] =
{
{IT_STRING | IT_CVAR, "Best Time", NULL, NULL, {.cvar = &cv_ghost_besttime}, 0, 0},
@ -113,6 +152,7 @@ menu_t PLAY_TAGhostsDef = {
PLAY_TAGhosts,
0, 0,
0, 0,
NULL,
2, 5,
M_DrawTimeAttack,
NULL,
@ -134,6 +174,117 @@ consvar_t cv_ghost_guest = CVAR_INIT ("ghost_guest", "Show", CV_SAVE, gh
consvar_t cv_ghost_staff = CVAR_INIT ("ghost_staff", "Show", CV_SAVE, ghost2_cons_t, NULL);
// time attack stuff...
void M_PrepareTimeAttack(INT32 choice)
{
(void) choice;
if (levellist.guessgt != MAXGAMETYPES)
{
levellist.newgametype = levellist.guessgt;
if (!(gametypes[levellist.newgametype]->tol & mapheaderinfo[levellist.choosemap]->typeoflevel))
{
INT32 guess = G_GuessGametypeByTOL(mapheaderinfo[levellist.choosemap]->typeoflevel);
if (guess != -1)
levellist.newgametype = guess;
}
}
{
// see also p_setup.c's P_LoadRecordGhosts
char *gpath = Z_StrDup(va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, G_BuildMapName(levellist.choosemap+1)));
UINT8 active;
if (!gpath)
return;
CV_StealthSetValue(&cv_dummystaff, 0);
active = false;
PLAY_TimeAttack[ta_guest].status = IT_DISABLED;
PLAY_TimeAttack[ta_replay].status = IT_DISABLED;
PLAY_TimeAttack[ta_ghosts].status = IT_DISABLED;
// Check if file exists, if not, disable options
PLAY_TAReplay[tareplay_besttime].status =
PLAY_TAReplayGuest[taguest_besttime].status = IT_DISABLED;
if (FIL_FileExists(va("%s-%s-time-best.lmp", gpath, cv_skin[0].string)))
{
PLAY_TAReplay[tareplay_besttime].status = IT_STRING|IT_CALL;
PLAY_TAReplayGuest[taguest_besttime].status = IT_STRING|IT_CALL;
active |= (1|2|4);
}
else if (PLAY_TAReplayGuestDef.lastOn == taguest_besttime)
PLAY_TAReplayGuestDef.lastOn = taguest_back;
PLAY_TAReplay[tareplay_bestlap].status =
PLAY_TAReplayGuest[taguest_bestlap].status =
PLAY_TAGhosts[taghost_bestlap].status = IT_DISABLED;
if ((gametypes[levellist.newgametype]->rules & GTR_CIRCUIT)
&& (mapheaderinfo[levellist.choosemap]->numlaps != 1)
&& FIL_FileExists(va("%s-%s-lap-best.lmp", gpath, cv_skin[0].string)))
{
PLAY_TAReplay[tareplay_bestlap].status = IT_STRING|IT_CALL;
PLAY_TAReplayGuest[taguest_bestlap].status = IT_STRING|IT_CALL;
PLAY_TAGhosts[taghost_bestlap].status = IT_STRING|IT_CVAR;
active |= (1|2|4);
}
else if (PLAY_TAReplayGuestDef.lastOn == taguest_bestlap)
PLAY_TAReplayGuestDef.lastOn = taguest_back;
PLAY_TAReplay[tareplay_last].status =
PLAY_TAReplayGuest[taguest_last].status = IT_DISABLED;
if (FIL_FileExists(va("%s-%s-last.lmp", gpath, cv_skin[0].string)))
{
PLAY_TAReplay[tareplay_last].status = IT_STRING|IT_CALL;
PLAY_TAReplayGuest[taguest_last].status = IT_STRING|IT_CALL;
active |= (1|2|4);
}
else if (PLAY_TAReplayGuestDef.lastOn == taguest_last)
PLAY_TAReplayGuestDef.lastOn = taguest_back;
PLAY_TAReplay[tareplay_guest].status =
PLAY_TAGhosts[taghost_guest].status =
PLAY_TAReplayGuest[taguest_delete].status = IT_DISABLED;
if (FIL_FileExists(va("%s-guest.lmp", gpath)))
{
PLAY_TAReplay[tareplay_guest].status = IT_STRING|IT_CALL;
PLAY_TAReplayGuest[taguest_delete].status = IT_STRING|IT_CALL;
PLAY_TAGhosts[taghost_guest].status = IT_STRING|IT_CVAR;
active |= (1|2|4);
}
else if (PLAY_TAReplayGuestDef.lastOn == taguest_delete)
PLAY_TAReplayGuestDef.lastOn = taguest_back;
PLAY_TAReplay[tareplay_staff].status =
PLAY_TAGhosts[taghost_staff].status = IT_DISABLED;
#ifdef STAFFGHOSTS
CV_SetValue(&cv_dummystaff, 1);
if (cv_dummystaff.value)
{
PLAY_TAReplay[tareplay_staff].status = IT_STRING|IT_KEYHANDLER;
PLAY_TAGhosts[taghost_staff].status = IT_STRING|IT_CVAR;
CV_StealthSetValue(&cv_dummystaff, 1);
active |= 1|4;
}
#endif //#ifdef STAFFGHOSTS
if (active & 1)
PLAY_TimeAttack[ta_replay].status = IT_STRING|IT_SUBMENU;
else if (PLAY_TimeAttackDef.lastOn == ta_replay)
PLAY_TimeAttackDef.lastOn = ta_start;
if (active & 2)
PLAY_TimeAttack[ta_guest].status = IT_STRING|IT_SUBMENU;
else if (PLAY_TimeAttackDef.lastOn == ta_guest)
PLAY_TimeAttackDef.lastOn = ta_start;
//if (active & 4) -- for possible future use
PLAY_TimeAttack[ta_ghosts].status = IT_STRING|IT_SUBMENU;
/*else if (PLAY_TimeAttackDef.lastOn == ta_ghosts)
PLAY_TimeAttackDef.lastOn = ta_start;*/
Z_Free(gpath);
}
}
void M_HandleStaffReplay(INT32 choice)
{
// @TODO:
@ -142,14 +293,111 @@ void M_HandleStaffReplay(INT32 choice)
void M_ReplayTimeAttack(INT32 choice)
{
// @TODO:
(void) choice;
const char *which;
restoreMenu = &PLAY_TimeAttackDef;
M_ClearMenus(true);
demo.loadfiles = false;
demo.ignorefiles = true; // Just assume that record attack replays have the files needed
switch (choice)
{
default:
case tareplay_besttime:
which = "time-best";
break;
case tareplay_bestlap:
which = "lap-best";
break;
case tareplay_last:
which = "last";
break;
case tareplay_guest:
G_DoPlayDemo(va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(levellist.choosemap+1)));
return;
}
G_DoPlayDemo(va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(levellist.choosemap+1), cv_skin[0].string, which));
}
static const char *TA_GuestReplay_Str = NULL;
static void M_WriteGuestReplay(INT32 ch)
{
char *gpath, *rguest;
UINT8 *buf;
size_t len = 0;
if (ch != MA_YES)
return;
gpath = Z_StrDup(va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, G_BuildMapName(levellist.choosemap+1)));
if (TA_GuestReplay_Str != NULL)
{
len = FIL_ReadFile(va("%s-%s-%s.lmp", gpath, cv_skin[0].string, TA_GuestReplay_Str), &buf);
if (!len)
{
M_StartMessage("Replay to copy no longer exists!", NULL, MM_NOTHING);
Z_Free(gpath);
return;
}
}
rguest = Z_StrDup(va("%s-guest.lmp", gpath));
if (FIL_FileExists(rguest))
{
//M_StopMessage(0);
remove(rguest);
}
if (len)
{
FIL_WriteFile(rguest, buf, len);
}
Z_Free(rguest);
Z_Free(gpath);
M_PrepareTimeAttack(0);
M_SetupNextMenu(&PLAY_TimeAttackDef, false);
// TODO the following isn't showing up and I'm not sure why
//M_StartMessage(va("Guest replay data %s.", (len ? "saved" : "erased")), NULL, MM_NOTHING);
}
void M_SetGuestReplay(INT32 choice)
{
// @TODO:
(void) choice;
switch (choice)
{
case taguest_besttime:
TA_GuestReplay_Str = "time-best";
break;
case taguest_bestlap:
TA_GuestReplay_Str = "lap-best";
break;
case taguest_last:
TA_GuestReplay_Str = "last";
break;
case taguest_delete:
default:
TA_GuestReplay_Str = NULL;
break;
}
if (FIL_FileExists(va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(levellist.choosemap+1))))
{
M_StartMessage(va("Are you sure you want to\n%s the guest replay data?\n\nPress (A) to confirm or (B) to cancel", (TA_GuestReplay_Str != NULL ? "overwrite" : "delete")), FUNCPTRCAST(M_WriteGuestReplay), MM_YESNO);
}
else if (TA_GuestReplay_Str != NULL)
{
M_WriteGuestReplay(MA_YES);
}
}
void M_StartTimeAttack(INT32 choice)
@ -205,6 +453,8 @@ void M_StartTimeAttack(INT32 choice)
else
G_RecordDemo(nameofdemo);
restoreMenu = &PLAY_TimeAttackDef;
M_ClearMenus(true);
D_MapChange(levellist.choosemap+1, levellist.newgametype, (cv_dummygpencore.value == 1), 1, 1, false, false);
}

View file

@ -23,6 +23,7 @@ menu_t PLAY_MP_OptSelectDef = {
PLAY_MP_OptSelect,
0, 0,
0, 0,
"NETMD2",
-1, 1,
M_DrawMPOptSelect,
M_MPOptSelectTick,
@ -47,23 +48,21 @@ boolean M_MPResetOpts(void)
void M_MPOptSelectInit(INT32 choice)
{
INT16 arrcpy[3][3] = {{0,68,0}, {0,12,0}, {0,74,0}};
UINT8 i = 0, j = 0; // To copy the array into the struct
const UINT32 forbidden = GTR_FORBIDMP;
(void)choice;
mpmenu.modechoice = 0;
mpmenu.ticker = 0;
for (; i < 3; i++)
for (j = 0; j < 3; j++)
mpmenu.modewinextend[i][j] = arrcpy[i][j]; // I miss Lua already
memcpy(&mpmenu.modewinextend, &arrcpy, sizeof(mpmenu.modewinextend));
// Guarantee menugametype is good
M_NextMenuGametype(forbidden);
M_PrevMenuGametype(forbidden);
M_SetupNextMenu(&PLAY_MP_OptSelectDef, false);
if (choice != -1)
{
M_SetupNextMenu(&PLAY_MP_OptSelectDef, false);
}
}
void M_MPOptSelectTick(void)
@ -73,12 +72,26 @@ void M_MPOptSelectTick(void)
// 3 Because we have 3 options in the menu
for (; i < 3; i++)
{
if (mpmenu.modewinextend[i][0])
mpmenu.modewinextend[i][2] += 8;
if (mpmenu.modewinextend[i][0] != 0)
{
if (mpmenu.modewinextend[i][2] < (mpmenu.modewinextend[i][1] - 8))
{
mpmenu.modewinextend[i][2] = (((2*mpmenu.modewinextend[i][1]) + mpmenu.modewinextend[i][2])/3);
mpmenu.modewinextend[i][2] -= (mpmenu.modewinextend[i][2] & 1); // prevent jitter, bias closed
}
else
{
mpmenu.modewinextend[i][2] = mpmenu.modewinextend[i][1];
}
}
else if (mpmenu.modewinextend[i][2] > 8)
{
mpmenu.modewinextend[i][2] /= 3;
mpmenu.modewinextend[i][2] += (mpmenu.modewinextend[i][2] & 1); // prevent jitter, bias open
}
else
mpmenu.modewinextend[i][2] -= 8;
mpmenu.modewinextend[i][2] = min(mpmenu.modewinextend[i][1], max(0, mpmenu.modewinextend[i][2]));
//CONS_Printf("%d - %d,%d,%d\n", i, mpmenu.modewinextend[i][0], mpmenu.modewinextend[i][1], mpmenu.modewinextend[i][2]);
{
mpmenu.modewinextend[i][2] = 0;
}
}
}

View file

@ -33,6 +33,7 @@ menu_t PLAY_MP_HostDef = {
PLAY_MP_Host,
0, 0,
0, 0,
"NETMD2",
-1, 1, // 1 frame transition.... This is really just because I don't want the black fade when we press esc, hehe
M_DrawMPHost,
M_MPOptSelectTick, // This handles the unfolding options

View file

@ -38,6 +38,7 @@ menu_t PLAY_MP_JoinIPDef = {
PLAY_MP_JoinIP,
0, 0,
0, 0,
"NETMD2",
-1, 1, // 1 frame transition.... This is really just because I don't want the black fade when we press esc, hehe
M_DrawMPJoinIP,
M_MPOptSelectTick, // This handles the unfolding options

View file

@ -16,6 +16,7 @@ menu_t PLAY_MP_RoomSelectDef = {
PLAY_MP_RoomSelect,
0, 0,
0, 0,
"NETMD2",
0, 0,
M_DrawMPRoomSelect,
M_MPRoomSelectTick,

View file

@ -29,6 +29,7 @@ menu_t PLAY_MP_ServerBrowserDef = {
PLAY_MP_ServerBrowser,
32, 36,
0, 0,
"NETMD2",
0, 0,
M_DrawMPServerBrowser,
M_MPServerBrowserTick,

View file

@ -20,6 +20,7 @@ menu_t PLAY_CupSelectDef = {
PLAY_CupSelect,
0, 0,
0, 0,
NULL,
2, 5,
M_DrawCupSelect,
M_CupSelectTick,
@ -157,6 +158,8 @@ void M_CupSelectHandler(INT32 choice)
);
M_ClearMenus(true);
restoreMenu = &PLAY_CupSelectDef;
}
else if (count == 1)
{

View file

@ -21,6 +21,7 @@ menu_t PLAY_LevelSelectDef = {
PLAY_LevelSelect,
0, 0,
0, 0,
NULL,
2, 5,
M_DrawLevelSelect,
M_LevelSelectTick,
@ -195,13 +196,14 @@ void M_LevelSelectScrollDest(void)
levellist.dest = (6*m)-3;
}
// Builds the level list we'll be using from the gametype we're choosing and send us to the apropriate menu.
// Builds the level list we'll be using from the gametype we're choosing and send us to the apropriate menu.
// A gt of -1 means the menu is being restored.
boolean M_LevelListFromGametype(INT16 gt)
{
static boolean first = true;
UINT8 temp = 0;
if (first || gt != levellist.newgametype || levellist.guessgt != MAXGAMETYPES)
if (gt != -1 && (first || gt != levellist.newgametype || levellist.guessgt != MAXGAMETYPES))
{
if (first)
{
@ -224,7 +226,6 @@ boolean M_LevelListFromGametype(INT16 gt)
}
levellist.levelsearch.cupmode = (!(gametypes[gt]->rules & GTR_NOCUPSELECT));
levellist.levelsearch.cup = NULL;
first = false;
}
@ -237,7 +238,7 @@ 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;
boolean foundany = false, currentvalid = false;
templevelsearch.cup = kartcupheaders;
@ -297,11 +298,15 @@ boolean M_LevelListFromGametype(INT16 gt)
if (M_GetFirstLevelInList(&temp, &templevelsearch) != NEXTMAP_INVALID)
{
highestunlockedid = currentid;
if (Playing() && mapheaderinfo[gamemap-1] && mapheaderinfo[gamemap-1]->cup == templevelsearch.cup)
if (Playing()
? (mapheaderinfo[gamemap-1] && mapheaderinfo[gamemap-1]->cup == templevelsearch.cup)
: (gt == -1 && levellist.levelsearch.cup == templevelsearch.cup))
{
cupgrid.x = currentid % CUPMENU_COLUMNS;
cupgrid.y = (currentid / CUPMENU_COLUMNS) % CUPMENU_ROWS;
cupgrid.pageno = currentid / (CUPMENU_COLUMNS * CUPMENU_ROWS);
currentvalid = true;
}
}
@ -314,15 +319,23 @@ boolean M_LevelListFromGametype(INT16 gt)
return false;
}
if (currentvalid == false)
{
levellist.levelsearch.cup = NULL;
}
cupgrid.numpages = (highestunlockedid / (CUPMENU_COLUMNS * CUPMENU_ROWS)) + 1;
if (cupgrid.pageno >= cupgrid.numpages)
{
cupgrid.pageno = 0;
}
PLAY_CupSelectDef.prevMenu = currentMenu;
PLAY_LevelSelectDef.prevMenu = &PLAY_CupSelectDef;
M_SetupNextMenu(&PLAY_CupSelectDef, false);
if (gt != -1)
{
PLAY_CupSelectDef.prevMenu = currentMenu;
PLAY_LevelSelectDef.prevMenu = &PLAY_CupSelectDef;
M_SetupNextMenu(&PLAY_CupSelectDef, false);
}
return true;
}
@ -344,8 +357,11 @@ boolean M_LevelListFromGametype(INT16 gt)
M_LevelSelectScrollDest();
levellist.y = levellist.dest;
PLAY_LevelSelectDef.prevMenu = currentMenu;
M_SetupNextMenu(&PLAY_LevelSelectDef, false);
if (gt != -1)
{
PLAY_LevelSelectDef.prevMenu = currentMenu;
M_SetupNextMenu(&PLAY_LevelSelectDef, false);
}
return true;
}
@ -424,8 +440,7 @@ void M_LevelSelected(INT16 add)
{
S_StartSound(NULL, sfx_s3k63);
if (levellist.guessgt != MAXGAMETYPES)
levellist.newgametype = G_GuessGametypeByTOL(levellist.levelsearch.typeoflevel);
M_PrepareTimeAttack(0);
PLAY_TimeAttackDef.lastOn = ta_start;
PLAY_TimeAttackDef.prevMenu = currentMenu;
@ -479,6 +494,15 @@ void M_LevelSelected(INT16 add)
CV_StealthSet(&cv_kartspeed, (cv_dummykartspeed.value == KARTSPEED_NORMAL) ? "Auto" : cv_dummykartspeed.string);
D_MapChange(levellist.choosemap+1, levellist.newgametype, (cv_kartencore.value == 1), 1, 1, false, false);
if (levellist.netgame == true)
{
restoreMenu = &PLAY_MP_OptSelectDef;
}
else
{
restoreMenu = &PLAY_LevelSelectDef;
}
}
else
{

View file

@ -4,28 +4,6 @@
#include "../../k_menu.h"
#include "../../z_zone.h"
static menuitem_t MessageMenu[] =
{
// TO HACK
{0, NULL, NULL, NULL, {NULL}, 0, 0}
};
menu_t MessageDef =
{
1, // # of menu items
NULL, // previous menu (TO HACK)
0, // lastOn, flags (TO HACK)
MessageMenu, // menuitem_t ->
0, 0, // x, y (TO HACK)
0, 0, // extra1, extra2
0, 0, // transition tics
NULL, // drawing routine ->
NULL, // ticker routine
NULL, // init routine
NULL, // quit routine
NULL // input routine
};
// message prompt struct
struct menumessage_s menumessage;
@ -158,7 +136,10 @@ void M_HandleMenuMessage(void)
boolean btnok = M_MenuBackPressed(pid);
if (menumessage.fadetimer < 9)
{
menumessage.fadetimer++;
return;
}
switch (menumessage.flags)
{

View file

@ -63,6 +63,7 @@ menu_t PAUSE_MainDef = {
PAUSE_Main,
0, 0,
0, 0,
NULL,
1, 10, // For transition with some menus!
M_DrawPause,
M_PauseTick,

View file

@ -9,25 +9,27 @@
#include "../../p_local.h" // P_InitCameraCmd
#include "../../d_main.h" // D_StartTitle
static void M_PlaybackTick(void);
menuitem_t PAUSE_PlaybackMenu[] =
{
{IT_CALL | IT_STRING, "Hide Menu (Esc)", NULL, "M_PHIDE", {.routine = M_SelectableClearMenus}, 0, 0},
{IT_CALL | IT_STRING, "Hide Menu", NULL, "M_PHIDE", {.routine = M_SelectableClearMenus}, 0, 0},
{IT_CALL | IT_STRING, "Rewind ([)", NULL, "M_PREW", {.routine = M_PlaybackRewind}, 20, 0},
{IT_CALL | IT_STRING, "Pause (\\)", NULL, "M_PPAUSE", {.routine = M_PlaybackPause}, 36, 0},
{IT_CALL | IT_STRING, "Fast-Forward (])", NULL, "M_PFFWD", {.routine = M_PlaybackFastForward}, 52, 0},
{IT_CALL | IT_STRING, "Backup Frame ([)", NULL, "M_PSTEPB", {.routine = M_PlaybackRewind}, 20, 0},
{IT_CALL | IT_STRING, "Resume", NULL, "M_PRESUM", {.routine = M_PlaybackPause}, 36, 0},
{IT_CALL | IT_STRING, "Advance Frame (])", NULL, "M_PFADV", {.routine = M_PlaybackAdvance}, 52, 0},
{IT_CALL | IT_STRING, "Rewind", NULL, "M_PREW", {.routine = M_PlaybackRewind}, 20, 0},
{IT_CALL | IT_STRING, "Pause", NULL, "M_PPAUSE", {.routine = M_PlaybackPause}, 36, 0},
{IT_CALL | IT_STRING, "Fast-Forward", NULL, "M_PFFWD", {.routine = M_PlaybackFastForward}, 52, 0},
{IT_CALL | IT_STRING, "Backup Frame", NULL, "M_PSTEPB", {.routine = M_PlaybackRewind}, 20, 0},
{IT_CALL | IT_STRING, "Resume", NULL, "M_PRESUM", {.routine = M_PlaybackPause}, 36, 0},
{IT_CALL | IT_STRING, "Advance Frame", NULL, "M_PFADV", {.routine = M_PlaybackAdvance}, 52, 0},
{IT_ARROWS | IT_STRING, "View Count (- and =)", NULL, "M_PVIEWS", {.routine = M_PlaybackSetViews}, 72, 0},
{IT_ARROWS | IT_STRING, "Viewpoint (1)", NULL, "M_PNVIEW", {.routine = M_PlaybackAdjustView}, 88, 0},
{IT_ARROWS | IT_STRING, "Viewpoint 2 (2)", NULL, "M_PNVIEW", {.routine = M_PlaybackAdjustView}, 104, 0},
{IT_ARROWS | IT_STRING, "Viewpoint 3 (3)", NULL, "M_PNVIEW", {.routine = M_PlaybackAdjustView}, 120, 0},
{IT_ARROWS | IT_STRING, "Viewpoint 4 (4)", NULL, "M_PNVIEW", {.routine = M_PlaybackAdjustView}, 136, 0},
{IT_ARROWS | IT_STRING, "View Count", NULL, "M_PVIEWS", {.routine = M_PlaybackSetViews}, 72, 0},
{IT_ARROWS | IT_STRING, "Viewpoint", NULL, "M_PNVIEW", {.routine = M_PlaybackAdjustView}, 88, 0},
{IT_ARROWS | IT_STRING, "Viewpoint 2", NULL, "M_PNVIEW", {.routine = M_PlaybackAdjustView}, 104, 0},
{IT_ARROWS | IT_STRING, "Viewpoint 3", NULL, "M_PNVIEW", {.routine = M_PlaybackAdjustView}, 120, 0},
{IT_ARROWS | IT_STRING, "Viewpoint 4", NULL, "M_PNVIEW", {.routine = M_PlaybackAdjustView}, 136, 0},
{IT_CALL | IT_STRING, "Toggle Free Camera (')", NULL, "M_PVIEWS", {.routine = M_PlaybackToggleFreecam}, 156, 0},
{IT_CALL | IT_STRING, "Stop Playback", NULL, "M_PEXIT", {.routine = M_PlaybackQuit}, 172, 0},
{IT_CALL | IT_STRING, "Toggle Free Camera", NULL, "M_PVIEWS", {.routine = M_PlaybackToggleFreecam}, 156, 0},
{IT_CALL | IT_STRING, "Stop Playback", NULL, "M_PEXIT", {.routine = M_PlaybackQuit}, 172, 0},
};
menu_t PAUSE_PlaybackMenuDef = {
@ -37,9 +39,10 @@ menu_t PAUSE_PlaybackMenuDef = {
PAUSE_PlaybackMenu,
BASEVIDWIDTH/2 - 88, 2,
0, 0,
NULL,
0, 0,
M_DrawPlaybackMenu,
NULL,
M_PlaybackTick,
NULL,
NULL,
NULL
@ -47,23 +50,84 @@ menu_t PAUSE_PlaybackMenuDef = {
void M_EndModeAttackRun(void)
{
boolean dotitle = demo.title;
G_CheckDemoStatus(); // Cancel recording
if (gamestate == GS_LEVEL || gamestate == GS_INTERMISSION)
Command_ExitGame_f();
Command_ExitGame_f(); // Clear a bunch of state
M_StartControlPanel();
modeattacking = ATTACKING_NONE; // Kept until now because of Command_ExitGame_f
currentMenu = &PLAY_TimeAttackDef;
itemOn = currentMenu->lastOn;
G_SetGamestate(GS_MENU);
S_ChangeMusicInternal("menu", true);
modeattacking = ATTACKING_NONE;
if (dotitle)
{
D_StartTitle();
}
else
{
D_ClearState();
M_StartControlPanel();
}
}
// Replay Playback Menu
tic_t playback_last_menu_interaction_leveltime = 0;
static void M_PlaybackTick(void)
{
INT16 i;
if (leveltime - playback_last_menu_interaction_leveltime >= 6*TICRATE)
playback_last_menu_interaction_leveltime = leveltime - 6*TICRATE;
// Toggle items
if (paused && !demo.rewinding)
{
PAUSE_PlaybackMenu[playback_pause].status = PAUSE_PlaybackMenu[playback_fastforward].status = PAUSE_PlaybackMenu[playback_rewind].status = IT_DISABLED;
PAUSE_PlaybackMenu[playback_resume].status = PAUSE_PlaybackMenu[playback_advanceframe].status = PAUSE_PlaybackMenu[playback_backframe].status = IT_CALL|IT_STRING;
if (itemOn >= playback_rewind && itemOn <= playback_fastforward)
itemOn += playback_backframe - playback_rewind;
}
else
{
PAUSE_PlaybackMenu[playback_pause].status = PAUSE_PlaybackMenu[playback_fastforward].status = PAUSE_PlaybackMenu[playback_rewind].status = IT_CALL|IT_STRING;
PAUSE_PlaybackMenu[playback_resume].status = PAUSE_PlaybackMenu[playback_advanceframe].status = PAUSE_PlaybackMenu[playback_backframe].status = IT_DISABLED;
if (itemOn >= playback_backframe && itemOn <= playback_advanceframe)
itemOn -= playback_backframe - playback_rewind;
}
if (modeattacking)
{
for (i = playback_viewcount; i <= playback_view4; i++)
PAUSE_PlaybackMenu[i].status = IT_DISABLED;
//PAUSE_PlaybackMenu[playback_moreoptions].mvar1 = 72;
//PAUSE_PlaybackMenu[playback_quit].mvar1 = 88;
PAUSE_PlaybackMenu[playback_quit].mvar1 = 72;
//currentMenu->x = BASEVIDWIDTH/2 - 52;
currentMenu->x = BASEVIDWIDTH/2 - 44;
}
else
{
PAUSE_PlaybackMenu[playback_viewcount].status = IT_ARROWS|IT_STRING;
for (i = 0; i <= r_splitscreen; i++)
PAUSE_PlaybackMenu[playback_view1+i].status = IT_ARROWS|IT_STRING;
for (i = r_splitscreen+1; i < 4; i++)
PAUSE_PlaybackMenu[playback_view1+i].status = IT_DISABLED;
//PAUSE_PlaybackMenu[playback_moreoptions].mvar1 = 156;
//PAUSE_PlaybackMenu[playback_quit].mvar1 = 172;
PAUSE_PlaybackMenu[playback_quit].mvar1 = 156;
//currentMenu->x = BASEVIDWIDTH/2 - 94;
currentMenu->x = BASEVIDWIDTH/2 - 88;
}
}
void M_SetPlaybackMenuPointer(void)
{
itemOn = playback_pause;
@ -141,12 +205,12 @@ void M_PlaybackSetViews(INT32 choice)
{
if (choice > 0)
{
if (splitscreen < 3)
G_AdjustView(splitscreen + 2, 0, true);
if (r_splitscreen < 3)
G_AdjustView(r_splitscreen + 2, 0, true);
}
else if (splitscreen)
else if (r_splitscreen)
{
splitscreen--;
r_splitscreen--;
R_ExecuteSetViewSize();
}
}
@ -188,7 +252,7 @@ void M_PlaybackQuit(INT32 choice)
G_StopDemo();
if (demo.inreplayhut)
M_ReplayHut(choice);
M_StartControlPanel();
else if (modeattacking)
M_EndModeAttackRun();
else

View file

@ -7139,7 +7139,7 @@ static void P_ResetSpawnpoints(void)
static void P_LoadRecordGhosts(void)
{
// see also k_menu.c's Nextmap_OnChange
// see also /menus/play-local-race-time-attack.c's M_PrepareTimeAttack
char *gpath;
INT32 i;
@ -7200,7 +7200,7 @@ static void P_LoadRecordGhosts(void)
{
lumpnum_t l;
UINT8 j = 1;
// TODO: Use map header to determine lump name
// TODO: Use vres for lumps
while (j <= 99 && (l = W_CheckNumForLongName(va("%sS%02u",G_BuildMapName(gamemap),j))) != LUMPERROR)
{
G_AddGhost(va("%sS%02u",G_BuildMapName(gamemap),j));

View file

@ -3038,8 +3038,8 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
fixed_t f1, f2;
fixed_t speed;
fixed_t playerScale = FixedDiv(player->mo->scale, mapobjectscale);
fixed_t scaleDiff = playerScale - FRACUNIT;
fixed_t playerScale;
fixed_t scaleDiff;
fixed_t cameraScale = mapobjectscale;
thiscam->old_x = thiscam->x;
@ -3064,6 +3064,9 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
return true;
}
playerScale = FixedDiv(player->mo->scale, mapobjectscale);
scaleDiff = playerScale - FRACUNIT;
if (thiscam == &camera[1]) // Camera 2
{
num = 1;

View file

@ -31,6 +31,7 @@
#include "m_cond.h" // for conditionsets
#include "lua_hook.h" // MusicChange hook
#include "byteptr.h"
#include "k_menu.h" // M_PlayMenuJam
#ifdef HW3SOUND
// 3D Sound Interface
@ -2651,9 +2652,13 @@ void GameDigiMusic_OnChange(void)
{
P_RestoreMusic(&players[consoleplayer]);
}
else if (S_MusicExists("menu"))
else if (gamestate == GS_TITLESCREEN)
{
S_ChangeMusicInternal("menu", looptitle);
S_ChangeMusicInternal("_title", looptitle);
}
else
{
M_PlayMenuJam();
}
}
else