diff --git a/src/k_menu.h b/src/k_menu.h index cbc3c899a..eec2a59c1 100644 --- a/src/k_menu.h +++ b/src/k_menu.h @@ -200,6 +200,13 @@ typedef enum quitkart } main_e; +extern menuitem_t MAIN_Goner[]; +extern menu_t MAIN_GonerDef; + +void M_GonerTick(void); +void M_GonerProfile(INT32 choice); +void M_GonerTutorial(INT32 choice); + extern menuitem_t PLAY_CharSelect[]; extern menu_t PLAY_CharSelectDef; @@ -331,6 +338,8 @@ typedef enum extern menuitem_t OPTIONS_EditProfile[]; extern menu_t OPTIONS_EditProfileDef; +void M_StartEditProfile(INT32 c); + extern menuitem_t OPTIONS_ProfileControls[]; extern menu_t OPTIONS_ProfileControlsDef; @@ -990,6 +999,9 @@ boolean M_OptionsInputs(INT32 ch); boolean M_OptionsQuit(void); // resets buttons when you quit the options. void M_OptionsChangeBGColour(INT16 newcolour); // changes the background colour for options +void M_VideoOptions(INT32 choice); +void M_SoundOptions(INT32 choice); + void M_HandleItemToggles(INT32 choice); // For item toggling void M_EraseData(INT32 choice); // For data erasing void M_CheckProfileData(INT32 choice); // check if we have profiles. diff --git a/src/k_menufunc.c b/src/k_menufunc.c index 8fbc292d1..ef6863594 100644 --- a/src/k_menufunc.c +++ b/src/k_menufunc.c @@ -357,6 +357,11 @@ void M_PlayMenuJam(void) menu_t *refMenu = (menuactive ? currentMenu : restoreMenu); static boolean musicstatepermitted = false; + if (M_GameTrulyStarted() == false) + { + return; + } + if (challengesmenu.pending) { Music_StopAll(); @@ -558,7 +563,16 @@ void M_StartControlPanel(void) Music_Stop("title"); - if (cv_currprofile.value == -1) // Only ask once per session. + if (M_GameTrulyStarted() == false) + { + // Are you ready for the First Boot Experience? + M_ResetOptions(); + currentMenu = &MAIN_GonerDef; + currentMenu->lastOn = 0; + Music_Remap("menu_nocred", "_GONER"); + Music_Play("menu_nocred"); + } + else 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. M_ResetOptions(); @@ -570,8 +584,9 @@ void M_StartControlPanel(void) // options don't need initializing here. // make sure we don't overstep that. - if (optionsmenu.profilen > PR_GetNumProfiles()) - optionsmenu.profilen = PR_GetNumProfiles(); + const INT32 maxp = PR_GetNumProfiles(); + if (optionsmenu.profilen > maxp) + optionsmenu.profilen = maxp; else if (optionsmenu.profilen < 0) optionsmenu.profilen = 0; diff --git a/src/menus/CMakeLists.txt b/src/menus/CMakeLists.txt index 2fdbb8719..b3549df12 100644 --- a/src/menus/CMakeLists.txt +++ b/src/menus/CMakeLists.txt @@ -6,6 +6,7 @@ target_sources(SRB2SDL2 PRIVATE extras-statistics.c extras-wrong.c main-1.c + main-goner.c main-profile-select.c options-1.c options-data-1.c diff --git a/src/menus/main-goner.c b/src/menus/main-goner.c new file mode 100644 index 000000000..ad0ffd3d4 --- /dev/null +++ b/src/menus/main-goner.c @@ -0,0 +1,111 @@ +/// \file menus/main-goner.c +/// \brief The Goner Setup. + +#include "../k_menu.h" + +menuitem_t MAIN_Goner[] = +{ + {IT_STRING | IT_CALL, "Quit", + "CONCLUDE OBSERVATIONS NOW.", NULL, + {.routine = M_QuitSRB2}, 0, 0}, + + {IT_STRING | IT_CVAR | IT_CV_STRING, "Password", "ATTEMPT ADMINISTRATOR ACCESS.", + NULL, {.cvar = &cv_dummyextraspassword}, 0, 0}, + + {IT_STRING | IT_CALL, "Video Options", "CONFIGURE OCULAR PATHWAYS.", + NULL, {.routine = M_VideoOptions}, 0, 0}, + + {IT_STRING | IT_CALL, "Sound Options", "CALIBRATE AURAL DATASTREAM.", + NULL, {.routine = M_SoundOptions}, 0, 0}, + + {IT_STRING | IT_CALL, "Profile Setup", + "ASSIGN VEHICLE INPUTS.", NULL, + {.routine = M_GonerProfile}, 0, 0}, + + {IT_STRING | IT_CALL, "Begin Tutorial", + "PREPARE FOR INTEGRATION.", NULL, + {.routine = M_GonerTutorial}, 0, 0}, +}; + +menu_t MAIN_GonerDef = { + sizeof (MAIN_Goner) / sizeof (menuitem_t), + NULL, + 0, + MAIN_Goner, + 32, 80, + 0, 0, + 0, + "_OCEAN", + 0, 0, + M_DrawGenericMenu, + M_GonerTick, + NULL, + NULL, + NULL, +}; + +void M_GonerTick(void) +{ + if (menutyping.active == false && cv_dummyextraspassword.string[0] != '\0') + { + // Challenges are not interpreted at this stage. + // See M_ExtraTick for the full behaviour. + + cht_Interpret(cv_dummyextraspassword.string); + CV_StealthSet(&cv_dummyextraspassword, ""); + } +} + +void M_GonerProfile(INT32 choice) +{ + (void)choice; + + optionsmenu.profilen = cv_ttlprofilen.value; + + const INT32 maxp = PR_GetNumProfiles(); + if (optionsmenu.profilen > maxp) + optionsmenu.profilen = maxp; + else if (optionsmenu.profilen < 1) + { + // Assume the first one is what we want..?? + CV_StealthSetValue(&cv_ttlprofilen, 1); + optionsmenu.profilen = 1; + } + + M_ResetOptions(); + + // This will create a new profile if necessary. + M_StartEditProfile(MA_YES); + PR_ApplyProfilePretend(optionsmenu.profilen, 0); +} + +void M_GonerTutorial(INT32 choice) +{ + (void)choice; + + if (cv_currprofile.value == -1) + { + const INT32 maxp = PR_GetNumProfiles(); + INT32 profilen = cv_ttlprofilen.value; + if (profilen >= maxp) + profilen = maxp-1; + else if (profilen < 1) + profilen = 1; + + PR_ApplyProfile(profilen, 0); + } + + // Please also see M_LevelSelectInit as called in extras-1.c + levellist.netgame = false; + levellist.levelsearch.checklocked = true; + cupgrid.grandprix = false; + levellist.levelsearch.timeattack = false; + + if (!M_LevelListFromGametype(GT_TUTORIAL)) + { + // The game is incapable of progression, but I can't bring myself to put an I_Error here. + M_StartMessage("SURVEY_PROGRAM", + "YOU ACCEPT EVERYTHING THAT WILL HAPPEN FROM NOW ON.", + &M_QuitResponse, MM_YESNO, "I agree", "Cancel"); + } +} diff --git a/src/menus/options-1.c b/src/menus/options-1.c index 5d5ff5660..9f43cc6aa 100644 --- a/src/menus/options-1.c +++ b/src/menus/options-1.c @@ -13,11 +13,11 @@ menuitem_t OPTIONS_Main[] = {IT_STRING | IT_CALL, "Profile Setup", "Remap keys & buttons to your likings.", NULL, {.routine = M_ProfileSelectInit}, 0, 0}, - {IT_STRING | IT_SUBMENU, "Video Options", "Change video settings such as the resolution.", - NULL, {.submenu = &OPTIONS_VideoDef}, 0, 0}, + {IT_STRING | IT_CALL, "Video Options", "Change video settings such as the resolution.", + NULL, {.routine = M_VideoOptions}, 0, 0}, {IT_STRING | IT_SUBMENU, "Sound Options", "Adjust various sound settings such as the volume.", - NULL, {.submenu = &OPTIONS_SoundDef}, 0, 0}, + NULL, {.routine = M_SoundOptions}, 0, 0}, {IT_STRING | IT_SUBMENU, "HUD Options", "Options related to the Heads-Up Display.", NULL, {.submenu = &OPTIONS_HUDDef}, 0, 0}, @@ -203,6 +203,23 @@ void M_OptionsTick(void) if (shitsfree) shitsfree--; } +static void M_OptionsMenuGoto(menu_t *assignment) +{ + assignment->prevMenu = currentMenu; + M_SetupNextMenu(assignment, false); +} + +void M_VideoOptions(INT32 choice) +{ + (void)choice; + M_OptionsMenuGoto(&OPTIONS_VideoDef); +} + +void M_SoundOptions(INT32 choice) +{ + (void)choice; + M_OptionsMenuGoto(&OPTIONS_SoundDef); +} boolean M_OptionsInputs(INT32 ch) { diff --git a/src/menus/options-profiles-1.c b/src/menus/options-profiles-1.c index bb194a2ee..9a697e1b6 100644 --- a/src/menus/options-profiles-1.c +++ b/src/menus/options-profiles-1.c @@ -61,7 +61,7 @@ void M_FirstPickProfile(INT32 c) } // Start menu edition. Call this with MA_YES if not used with a textbox. -static void M_StartEditProfile(INT32 c) +void M_StartEditProfile(INT32 c) { const INT32 maxp = PR_GetNumProfiles(); @@ -114,6 +114,7 @@ static void M_StartEditProfile(INT32 c) OPTIONS_EditProfile[popt_char].status |= IT_TRANSTEXT; } + OPTIONS_EditProfileDef.prevMenu = currentMenu; M_SetupNextMenu(&OPTIONS_EditProfileDef, false); return; } diff --git a/src/menus/options-profiles-edit-1.c b/src/menus/options-profiles-edit-1.c index ba57a2419..04ee24990 100644 --- a/src/menus/options-profiles-edit-1.c +++ b/src/menus/options-profiles-edit-1.c @@ -3,6 +3,7 @@ #include "../k_menu.h" #include "../s_sound.h" +#include "../m_cond.h" menuitem_t OPTIONS_EditProfile[] = { {IT_STRING | IT_CVAR | IT_CV_STRING, "Profile Name", "6-character long name to identify this Profile.", @@ -76,9 +77,17 @@ static boolean M_ProfileEditEnd(const UINT8 pid) static void M_ProfileEditExit(void) { - optionsmenu.toptx = 160; - optionsmenu.topty = 35; - optionsmenu.resetprofile = true; // Reset profile after the transition is done. + if (M_GameTrulyStarted() == true) + { + optionsmenu.toptx = 160; + optionsmenu.topty = 35; + optionsmenu.resetprofile = true; // Reset profile after the transition is done. + } + else + { + M_ResetOptions(); // Reset all options variables otherwise things are gonna go reaaal bad lol. + optionsmenu.profile = NULL; // Make sure to get rid of that, too. + } PR_SaveProfiles(); // save profiles after we do that. } diff --git a/src/menus/transient/level-select.c b/src/menus/transient/level-select.c index c60cd9695..9b22207e0 100644 --- a/src/menus/transient/level-select.c +++ b/src/menus/transient/level-select.c @@ -714,7 +714,11 @@ void M_LevelSelected(INT16 add) D_MapChange(levellist.choosemap+1, levellist.newgametype, (cv_kartencore.value == 1), 1, 1, false, false); - if (levellist.levelsearch.tutorial) + if (M_GameTrulyStarted() == false) + { + // No restoreMenu set. + } + else if (levellist.levelsearch.tutorial) { restoreMenu = currentMenu; }