diff --git a/src/d_main.c b/src/d_main.c index 295130374..4a20ccace 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1023,7 +1023,8 @@ void D_StartTitle(void) advancedemo = false; F_StartTitleScreen(); - currentMenu = &MainDef; // reset the current menu ID + M_InitOptions(0); // Make sure the option menu is ready to go since we need to select a profile. + currentMenu = &MAIN_ProfilesDef; // reset the current menu ID // Reset the palette if (rendermode != render_none) @@ -1178,7 +1179,7 @@ static void IdentifyVersion(void) #ifdef USE_PATCH_FILE D_AddFile(startupiwads, va(pandf,srb2waddir,PATCHNAME)); // SPECIFIC HACK TO NEW-MENUS SO THAT MY DUMBASS STOPS FORGETTING TO ADD THE FILE (rip :youfuckedup:) - D_AddFile(startupiwads, va(pandf,srb2waddir,"newmenus.pk3")); + D_AddFile(startupiwads, va(pandf,srb2waddir,"newmenus.pk3")); #endif //// #undef TEXTURESNAME diff --git a/src/d_netcmd.c b/src/d_netcmd.c index eb2c7388d..ffef4ec32 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -303,15 +303,19 @@ consvar_t cv_followercolor[MAXSPLITSCREENPLAYERS] = { // last selected profile, unaccessible cvar only set internally but is saved. // It's used to know what profile to autoload you to when you get into the character setup. -static CV_PossibleValue_t lastprofile_cons_t[] = {{0, "MIN"}, {MAXPROFILES, "MAX"}, {0, NULL}}; +static CV_PossibleValue_t lastprofile_cons_t[] = {{-1, "MIN"}, {MAXPROFILES, "MAX"}, {0, NULL}}; consvar_t cv_lastprofile[MAXSPLITSCREENPLAYERS] = { - CVAR_INIT ("lastprofile", "1", CV_SAVE|CV_HIDDEN, lastprofile_cons_t, NULL), - CVAR_INIT ("lastprofile2", "1", CV_SAVE|CV_HIDDEN, lastprofile_cons_t, NULL), - CVAR_INIT ("lastprofile3", "1", CV_SAVE|CV_HIDDEN, lastprofile_cons_t, NULL), - CVAR_INIT ("lastprofile4", "1", CV_SAVE|CV_HIDDEN, lastprofile_cons_t, NULL), + CVAR_INIT ("lastprofile", "0", CV_SAVE|CV_HIDDEN, lastprofile_cons_t, NULL), + CVAR_INIT ("lastprofile2", "0", CV_SAVE|CV_HIDDEN, lastprofile_cons_t, NULL), + CVAR_INIT ("lastprofile3", "0", CV_SAVE|CV_HIDDEN, lastprofile_cons_t, NULL), + CVAR_INIT ("lastprofile4", "0", CV_SAVE|CV_HIDDEN, lastprofile_cons_t, NULL), }; +// currently loaded profile for P1 menuing. +// You choose this profile when starting the game, this will also set lastprofile[0] +consvar_t cv_currprofile = CVAR_INIT ("currprofile", "-1", CV_HIDDEN, lastprofile_cons_t, NULL); + consvar_t cv_skipmapcheck = CVAR_INIT ("skipmapcheck", "Off", CV_SAVE, CV_OnOff, NULL); INT32 cv_debug; @@ -876,6 +880,8 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_lastprofile[i]); } + CV_RegisterVar(&cv_currprofile); + // preferred number of players CV_RegisterVar(&cv_splitplayers); diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 7a385ba92..bcaa051b9 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -25,6 +25,10 @@ extern consvar_t cv_follower[MAXSPLITSCREENPLAYERS]; extern consvar_t cv_followercolor[MAXSPLITSCREENPLAYERS]; extern consvar_t cv_lastprofile[MAXSPLITSCREENPLAYERS]; +// current profile loaded. +// Used to know how to make the options menu behave among other things. +extern consvar_t cv_currprofile; + // preferred number of players extern consvar_t cv_splitplayers; diff --git a/src/f_finale.c b/src/f_finale.c index d28fa3d9d..14a353bef 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -67,7 +67,7 @@ mobj_t *titlemapcameraref = NULL; // menu presentation state char curbgname[9]; SINT8 curfadevalue; -INT32 curbgcolor; +INT32 curbgcolor = 31; // Please stop assaulting my eyes. INT32 curbgxspeed; INT32 curbgyspeed; boolean curbghide; diff --git a/src/k_menu.h b/src/k_menu.h index 004fc1bef..d2f9a52e7 100644 --- a/src/k_menu.h +++ b/src/k_menu.h @@ -224,6 +224,10 @@ typedef enum extern menuitem_t OPTIONS_Profiles[]; extern menu_t OPTIONS_ProfilesDef; +// Separate menu to avoid spaghetti code etc. +extern menuitem_t MAIN_Profiles[]; +extern menu_t MAIN_ProfilesDef; + extern menuitem_t OPTIONS_EditProfile[]; extern menu_t OPTIONS_EditProfileDef; @@ -710,6 +714,7 @@ extern consvar_t cv_dummyprofilename; extern consvar_t cv_dummyprofileplayername; extern consvar_t cv_dummyprofilekickstart; +void M_ResetOptions(void); void M_InitOptions(INT32 choice); // necessary for multiplayer since there's some options we won't want to access void M_OptionsTick(void); boolean M_OptionsInputs(INT32 ch); @@ -726,6 +731,7 @@ void M_HandleProfileSelect(INT32 ch); // profile edition void M_HandleProfileEdit(void); void M_ProfileDeviceSelect(INT32 choice); +void M_ConfirmProfile(INT32 choice); boolean M_ProfileEditInputs(INT32 ch); void M_HandleProfileControls(void); diff --git a/src/k_menudef.c b/src/k_menudef.c index 068863b43..fb74d2b63 100644 --- a/src/k_menudef.c +++ b/src/k_menudef.c @@ -431,6 +431,27 @@ menu_t OPTIONS_ProfilesDef = { NULL, }; +// Duplicate for main profile select. +menuitem_t MAIN_Profiles[] = { + {IT_KEYHANDLER | IT_NOTHING, NULL, "Select a profile to use or create a new Profile.", + NULL, {.routine = M_HandleProfileSelect}, 0, 0}, // dummy menuitem for the control func +}; + +menu_t MAIN_ProfilesDef = { + sizeof (MAIN_Profiles) / sizeof (menuitem_t), + NULL, + 0, + MAIN_Profiles, + 32, 80, + SKINCOLOR_ULTRAMARINE, 0, + 2, 10, + M_DrawProfileSelect, + M_OptionsTick, + NULL, + NULL, + NULL, +}; + menuitem_t OPTIONS_EditProfile[] = { {IT_STRING | IT_CVAR | IT_CV_STRING, "Profile Name", "6-character long name to identify this Profile.", @@ -444,6 +465,10 @@ menuitem_t OPTIONS_EditProfile[] = { {IT_STRING | IT_CALL, "Controls", "Select the button mappings for this Profile.", NULL, {.routine = M_ProfileDeviceSelect}, 0, 0}, + + {IT_STRING | IT_CALL, "Confirm", "Confirm changes.", + NULL, {.routine = M_ConfirmProfile}, 0, 0}, + }; menu_t OPTIONS_EditProfileDef = { diff --git a/src/k_menudraw.c b/src/k_menudraw.c index a151345cb..69d952b47 100644 --- a/src/k_menudraw.c +++ b/src/k_menudraw.c @@ -2622,7 +2622,7 @@ void M_DrawEditProfile(void) V_DrawGamemodeString(x + (menutransition.tics*32), y - 6, V_ALLOWLOWERCASE, colormap, currentMenu->menuitems[i].text); // Cvar specific handling - switch (currentMenu->menuitems[i].status & IT_TYPE) + /*switch (currentMenu->menuitems[i].status & IT_TYPE) { case IT_CVAR: { @@ -2639,7 +2639,7 @@ void M_DrawEditProfile(void) break; } } - } + }*/ y += 34; diff --git a/src/k_menufunc.c b/src/k_menufunc.c index 39ff7c2b4..ccb198196 100644 --- a/src/k_menufunc.c +++ b/src/k_menufunc.c @@ -85,7 +85,7 @@ boolean menuactive = false; boolean fromlevelselect = false; // current menudef -menu_t *currentMenu = &MainDef; +menu_t *currentMenu = &OPTIONS_ProfilesDef; char dummystaffname[22]; @@ -976,8 +976,20 @@ void M_StartControlPanel(void) } else if (!Playing()) { - currentMenu = &MainDef; + // options don't need initializing here. + PR_ApplyProfile(0, 0); // apply guest profile to player 0 by default. + // this is to garantee that the controls aren't fucked up. + + currentMenu = &MAIN_ProfilesDef; + optionsmenu.profilen = cv_lastprofile[0].value; + + // make sure we don't overstep that. + if (optionsmenu.profilen > PR_GetNumProfiles()) + optionsmenu.profilen = PR_GetNumProfiles(); + itemOn = 0; + + CV_StealthSetValue(&cv_currprofile, -1); // Make sure to reset that. } else { @@ -3670,6 +3682,26 @@ void M_MPRoomSelectInit(INT32 choice) // Options menu: struct optionsmenu_s optionsmenu; +void M_ResetOptions(void) +{ + optionsmenu.ticker = 0; + optionsmenu.offset = 0; + + optionsmenu.optx = 0; + optionsmenu.opty = 0; + optionsmenu.toptx = 0; + optionsmenu.topty = 0; + + // BG setup: + optionsmenu.currcolour = OPTIONS_MainDef.extra1; + optionsmenu.lastcolour = 0; + optionsmenu.fade = 0; + + // For profiles: + memset(setup_player, 0, sizeof(setup_player)); + optionsmenu.profile = NULL; +} + void M_InitOptions(INT32 choice) { (void)choice; @@ -3689,18 +3721,7 @@ void M_InitOptions(INT32 choice) if (gamestate != GS_MENU) OPTIONS_MainDef.menuitems[mopt_profiles].status = IT_STRING | IT_TRANSTEXT; - optionsmenu.ticker = 0; - optionsmenu.offset = 0; - - optionsmenu.optx = 0; - optionsmenu.opty = 0; - optionsmenu.toptx = 0; - optionsmenu.topty = 0; - - // BG setup: - optionsmenu.currcolour = OPTIONS_MainDef.extra1; - optionsmenu.lastcolour = 0; - optionsmenu.fade = 0; + M_ResetOptions(); // So that pause doesn't go to the main menu... OPTIONS_MainDef.prevMenu = currentMenu; @@ -3711,9 +3732,6 @@ void M_InitOptions(INT32 choice) Moviemode_option_Onchange(); Addons_option_Onchange(); - // For profiles: - memset(setup_player, 0, sizeof(setup_player)); - M_SetupNextMenu(&OPTIONS_MainDef, false); } @@ -3925,6 +3943,65 @@ void M_VideoModeMenu(INT32 choice) M_SetupNextMenu(&OPTIONS_VideoModesDef, false); } +// Select the current profile for menu use and go to maindef. +static void M_FirstPickProfile(INT32 c) +{ + if (c == MA_YES) + { + 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. + + CV_StealthSetValue(&cv_currprofile, optionsmenu.profilen); + PR_ApplyProfile(optionsmenu.profilen, 0); + M_SetupNextMenu(&MainDef, false); + + // Tell the game this is the last profile we picked. + CV_StealthSetValue(&cv_lastprofile[0], optionsmenu.profilen); + + // Save em! + PR_SaveProfiles(); + return; + } +} + +// Start menu edition. Call this with MA_YES if not used with a textbox. +static void M_StartEditProfile(INT32 c) +{ + + const INT32 maxp = PR_GetNumProfiles(); + + if (c == MA_YES) + { + if (optionsmenu.profilen == maxp) + PR_InitNewProfile(); // initialize the new profile. + + optionsmenu.profile = PR_GetProfile(optionsmenu.profilen); + + // This is now used to move the card we've selected. + optionsmenu.optx = 160; + optionsmenu.opty = 35; + optionsmenu.toptx = 130/2; + optionsmenu.topty = 0; + + // setup cvars + if (optionsmenu.profile->version) + { + CV_StealthSet(&cv_dummyprofilename, optionsmenu.profile->profilename); + CV_StealthSet(&cv_dummyprofileplayername, optionsmenu.profile->playername); + CV_StealthSetValue(&cv_dummyprofilekickstart, optionsmenu.profile->kickstartaccel); + } + else + { + CV_StealthSet(&cv_dummyprofilename, ""); + CV_StealthSet(&cv_dummyprofileplayername, ""); + CV_StealthSetValue(&cv_dummyprofilekickstart, 0); // off + } + + M_SetupNextMenu(&OPTIONS_EditProfileDef, false); + return; + } +} + void M_HandleProfileSelect(INT32 ch) { const UINT8 pid = 0; @@ -3964,42 +4041,44 @@ void M_HandleProfileSelect(INT32 ch) else if (M_MenuConfirmPressed(pid)) { - if (optionsmenu.profilen == 0) // Guest profile, you can't edit that one! + // Boot profile setup has already been done. + if (cv_currprofile.value > -1) { - S_StartSound(NULL, sfx_s3k7b); - M_StartMessage(M_GetText("Guest Profile cannot be edited.\nTo change parameters,\ncreate a new Profile."), NULL, MM_NOTHING); - M_SetMenuDelay(pid); - return; - } - S_StartSound(NULL, sfx_menu1); + if (optionsmenu.profilen == 0) // Guest profile, you can't edit that one! + { + S_StartSound(NULL, sfx_s3k7b); + M_StartMessage(M_GetText("Guest Profile cannot be edited.\nTo change parameters,\ncreate a new Profile."), NULL, MM_NOTHING); + M_SetMenuDelay(pid); + return; + } - if (optionsmenu.profilen == maxp) - PR_InitNewProfile(); // initialize the new profile. + S_StartSound(NULL, sfx_menu1); - optionsmenu.profile = PR_GetProfile(optionsmenu.profilen); - - // This is now used to move the card we've selected. - optionsmenu.optx = 160; - optionsmenu.opty = 35; - optionsmenu.toptx = 130/2; - optionsmenu.topty = 0; - - // setup cvars - if (optionsmenu.profile->version) - { - CV_StealthSet(&cv_dummyprofilename, optionsmenu.profile->profilename); - CV_StealthSet(&cv_dummyprofileplayername, optionsmenu.profile->playername); - CV_StealthSetValue(&cv_dummyprofilekickstart, optionsmenu.profile->kickstartaccel); + M_StartEditProfile(MA_YES); } else { - CV_StealthSet(&cv_dummyprofilename, ""); - CV_StealthSet(&cv_dummyprofileplayername, ""); - CV_StealthSetValue(&cv_dummyprofilekickstart, 0); // off + // We're on the profile selection screen. + if (optionsmenu.profilen == 0) + { + M_StartMessage(M_GetText("Are you sure you wish\nto use the Guest Profile?\nThis profile cannot be customised.\nIt is recommended to create\na new Profile instead.\n\n(Press A to confirm)"), FUNCPTRCAST(M_FirstPickProfile), MM_YESNO); + M_SetMenuDelay(pid); + return; + } + else if (optionsmenu.profilen == maxp) + { + M_StartMessage(M_GetText("Create a new Profile?\n\n(Press A to confirm)"), FUNCPTRCAST(M_StartEditProfile), MM_YESNO); + M_SetMenuDelay(pid); + return; + } + else + { + M_StartMessage(M_GetText("Are you sure you wish to\nselect this profile?\n\n(Press A to confirm)"), FUNCPTRCAST(M_FirstPickProfile), MM_YESNO); + M_SetMenuDelay(pid); + return; + } } - - M_SetupNextMenu(&OPTIONS_EditProfileDef, false); } else if (M_MenuBackPressed(pid)) @@ -4015,48 +4094,66 @@ void M_HandleProfileSelect(INT32 ch) } } +// Returns true if the profile can be saved, false otherwise. Also starts messages if necessary. +static boolean M_ProfileEditEnd(const UINT8 pid) +{ + UINT8 i; + + // check if some profiles have the same name + for (i = 0; i < PR_GetNumProfiles(); i++) + { + profile_t *check = PR_GetProfile(i); + + // For obvious reasons don't check if our name is the same as our name.... + if (check != optionsmenu.profile) + { + if (!(strcmp(optionsmenu.profile->profilename, check->profilename))) + { + S_StartSound(NULL, sfx_s3k7b); + M_StartMessage(M_GetText("Another Profile uses the same\nname identifier.\nPlease change the name\nof the Profile to save it."), NULL, MM_NOTHING); + M_SetMenuDelay(pid); + return false; + } + } + } + + if (optionsmenu.profilen == 0) // Guest profile, you can't edit that one! + { + S_StartSound(NULL, sfx_s3k7b); + M_StartMessage(M_GetText("Guest Profile cannot be edited.\nTo change parameters,\ncreate a new Profile."), NULL, MM_NOTHING); + M_SetMenuDelay(pid); + return false; + } + + return true; +} + +static void M_ProfileEditExit(void) +{ + optionsmenu.toptx = 160; + optionsmenu.topty = 35; + optionsmenu.resetprofile = true; // Reset profile after the transition is done. + + PR_SaveProfiles(); // save profiles after we do that. +} + // For profile edit, just make sure going back resets the card to its position, the rest is taken care of automatically. boolean M_ProfileEditInputs(INT32 ch) { - const UINT8 pid = 0; - UINT8 i; + (void) ch; + const UINT8 pid = 0; if (M_MenuBackPressed(pid)) { - // check if some profiles have the same name - for (i = 0; i < PR_GetNumProfiles(); i++) + if (M_ProfileEditEnd(pid)) { - profile_t *check = PR_GetProfile(i); - - // For obvious reasons don't check if our name is the same as our name.... - if (check != optionsmenu.profile) - { - if (!(strcmp(optionsmenu.profile->profilename, check->profilename))) - { - S_StartSound(NULL, sfx_s3k7b); - M_StartMessage(M_GetText("Another Profile uses the same\nname identifier.\nPlease change the name\nof the Profile to save it."), NULL, MM_NOTHING); - M_SetMenuDelay(pid); - return true; - } - } + M_ProfileEditExit(); + if (cv_currprofile.value == -1) + M_SetupNextMenu(&MAIN_ProfilesDef, false); + else + M_GoBack(0); } - - if (optionsmenu.profilen == 0) // Guest profile, you can't edit that one! - { - S_StartSound(NULL, sfx_s3k7b); - M_StartMessage(M_GetText("Guest Profile cannot be edited.\nTo change parameters,\ncreate a new Profile."), NULL, MM_NOTHING); - M_SetMenuDelay(pid); - return true; - } - - optionsmenu.toptx = 160; - optionsmenu.topty = 35; - optionsmenu.resetprofile = true; // Reset profile after the transition is done. - - PR_SaveProfiles(); // save profiles after we do that. - - M_GoBack(0); return true; } @@ -4088,6 +4185,28 @@ void M_HandleProfileEdit(void) strncpy(optionsmenu.profile->playername, cv_dummyprofileplayername.string, MAXPLAYERNAME); } +// Confirm Profile edi via button. +void M_ConfirmProfile(INT32 choice) +{ + const UINT8 pid = 0; + (void) choice; + + if (M_ProfileEditEnd(pid)) + { + if (cv_currprofile.value > -1) + { + M_ProfileEditExit(); + M_GoBack(0); + } + else + { + M_StartMessage(M_GetText("Are you sure you wish to\nselect this profile?\n\n(Press A to confirm)"), FUNCPTRCAST(M_FirstPickProfile), MM_YESNO); + M_SetMenuDelay(pid); + } + } + return; +} + // special menuitem key handler for video mode list void M_HandleVideoModes(INT32 ch) {