mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-21 12:01:05 +00:00
Use a three-option menu instead of a yes/no prompt
This commit is contained in:
parent
c53da609b1
commit
b1f15a35ba
3 changed files with 227 additions and 26 deletions
249
src/m_menu.c
249
src/m_menu.c
|
@ -140,7 +140,7 @@ static char *char_notes = NULL;
|
|||
|
||||
boolean menuactive = false;
|
||||
boolean fromlevelselect = false;
|
||||
tic_t shieldbuttonprompt = 0; // Show a prompt about the new Shield button for old configs // TODO: 2.3: Remove
|
||||
tic_t shieldprompt_timer = 0; // Show a prompt about the new Shield button for old configs // TODO: 2.3: Remove
|
||||
|
||||
typedef enum
|
||||
{
|
||||
|
@ -3162,7 +3162,7 @@ static void Command_Manual_f(void)
|
|||
if (modeattacking)
|
||||
return;
|
||||
M_StartControlPanel();
|
||||
if (shieldbuttonprompt) return; // TODO: 2.3: Delete this line
|
||||
if (shieldprompt_timer) return; // TODO: 2.3: Delete this line
|
||||
currentMenu = &MISC_HelpDef;
|
||||
itemOn = 0;
|
||||
}
|
||||
|
@ -3342,7 +3342,7 @@ boolean M_Responder(event_t *ev)
|
|||
if (modeattacking)
|
||||
return true;
|
||||
M_StartControlPanel();
|
||||
if (shieldbuttonprompt) return true; // TODO: 2.3: Delete this line
|
||||
if (shieldprompt_timer) return true; // TODO: 2.3: Delete this line
|
||||
M_Options(0);
|
||||
// Uncomment the below if you want the menu to reset to the top each time like before. M_SetupNextMenu will fix it automatically.
|
||||
//OP_SoundOptionsDef.lastOn = 0;
|
||||
|
@ -3353,7 +3353,7 @@ boolean M_Responder(event_t *ev)
|
|||
if (modeattacking)
|
||||
return true;
|
||||
M_StartControlPanel();
|
||||
if (shieldbuttonprompt) return true; // TODO: 2.3: Delete this line
|
||||
if (shieldprompt_timer) return true; // TODO: 2.3: Delete this line
|
||||
M_Options(0);
|
||||
M_VideoModeMenu(0);
|
||||
return true;
|
||||
|
@ -3365,7 +3365,7 @@ boolean M_Responder(event_t *ev)
|
|||
if (modeattacking)
|
||||
return true;
|
||||
M_StartControlPanel();
|
||||
if (shieldbuttonprompt) return true; // TODO: 2.3: Delete this line
|
||||
if (shieldprompt_timer) return true; // TODO: 2.3: Delete this line
|
||||
M_Options(0);
|
||||
M_SetupNextMenu(&OP_MainDef);
|
||||
return true;
|
||||
|
@ -3636,27 +3636,230 @@ void M_Drawer(void)
|
|||
}
|
||||
}
|
||||
|
||||
// Handle the "Do you want to assign Shield Ability now?" pop-up for old configs // TODO: 2.3: Remove
|
||||
static void M_ShieldButtonResponse(INT32 ch)
|
||||
// Handle the "Do you want to assign Shield Ability now?" pop-up for old configs // TODO: 2.3: Remove this line...
|
||||
static UINT8 shieldprompt_currentchoice = 0; // ...and this line...
|
||||
|
||||
static void M_ShieldPromptUseDefaults(void) // ...and this function
|
||||
{
|
||||
if (I_GetTime() <= shieldbuttonprompt) // Don't mash past the pop-up by accident!
|
||||
// With a default config from v2.2.10 to v2.2.13, the B button will be set to Custom 1,
|
||||
// and Controls per Key defaults to "One", so it will override the default Shield button.
|
||||
// A default config from v2.2.0 to v2.2.9 has Next Weapon on B, so it suffers from this too.
|
||||
|
||||
// So for "Use default Shield Ability buttons", we should update old configs to mitigate gamepad conflicts
|
||||
// (even with "Several" Controls per Key!), and show a message with the default bindings
|
||||
|
||||
for (setupcontrols = gamecontrol; true; setupcontrols = gamecontrolbis) // Do stuff for both P1 and P2
|
||||
{
|
||||
stopstopmessage = true;
|
||||
return;
|
||||
INT32 JOY1 = (setupcontrols == gamecontrol) ? KEY_JOY1 : KEY_2JOY1; // Is this for P1 or for P2?
|
||||
|
||||
if ((setupcontrols[GC_CUSTOM1][0] == JOY1+1 || setupcontrols[GC_CUSTOM1][1] == JOY1+1)
|
||||
&& (setupcontrols[GC_CUSTOM2][0] == JOY1+3 || setupcontrols[GC_CUSTOM2][1] == JOY1+3)
|
||||
&& (setupcontrols[GC_CUSTOM3][0] == JOY1+8 || setupcontrols[GC_CUSTOM3][1] == JOY1+8))
|
||||
{
|
||||
// If the player has v2.2.13's default gamepad Custom 1/2/3 buttons,
|
||||
// shuffle Custom 1/2/3 around to make room for Shield Ability on B
|
||||
UINT8 shield_slot = (setupcontrols[GC_SHIELD ][0] == KEY_NULL ) ? 0 : 1;
|
||||
UINT8 custom1_slot = (setupcontrols[GC_CUSTOM1][0] == JOY1+1) ? 0 : 1;
|
||||
UINT8 custom2_slot = (setupcontrols[GC_CUSTOM2][0] == JOY1+3) ? 0 : 1;
|
||||
UINT8 custom3_slot = (setupcontrols[GC_CUSTOM3][0] == JOY1+8) ? 0 : 1;
|
||||
|
||||
setupcontrols[GC_SHIELD ][shield_slot ] = JOY1+1; // Assign Shield Ability to B
|
||||
setupcontrols[GC_CUSTOM1][custom1_slot] = JOY1+3; // Move Custom 1 from B to Y
|
||||
setupcontrols[GC_CUSTOM2][custom2_slot] = JOY1+8; // Move Custom 2 from Y to LS
|
||||
setupcontrols[GC_CUSTOM3][custom3_slot] = KEY_NULL; // Unassign Custom 3 from LS...
|
||||
// (The alternative would be to check and update the ENTIRE gamepad layout.
|
||||
// That'd be nice, but it would mess with people that are used to the old defaults.)
|
||||
}
|
||||
else if ((setupcontrols[GC_WEAPONNEXT][0] == JOY1+1 || setupcontrols[GC_WEAPONNEXT][1] == JOY1+1)
|
||||
&& (setupcontrols[GC_WEAPONPREV][0] == JOY1+2 || setupcontrols[GC_WEAPONPREV][1] == JOY1+2))
|
||||
{
|
||||
// Or if the user has a default config from v2.2.0 to v2.2.9,
|
||||
// the B button will be Next Weapon, and X will be Previous Weapon.
|
||||
// It's "safe" to discard one of them, you just have to press X multiple times to select in the other direction
|
||||
UINT8 shield_slot = (setupcontrols[GC_SHIELD ][0] == KEY_NULL ) ? 0 : 1;
|
||||
UINT8 nweapon_slot = (setupcontrols[GC_WEAPONNEXT][0] == JOY1+1) ? 0 : 1;
|
||||
UINT8 pweapon_slot = (setupcontrols[GC_WEAPONPREV][0] == JOY1+2) ? 0 : 1;
|
||||
|
||||
setupcontrols[GC_SHIELD ][shield_slot ] = JOY1+1; // Assign Shield Ability to B
|
||||
setupcontrols[GC_WEAPONNEXT][nweapon_slot] = JOY1+3; // Move Next Weapon from B to X
|
||||
setupcontrols[GC_WEAPONPREV][pweapon_slot] = KEY_NULL; // Unassign Previous Weapon from X
|
||||
}
|
||||
|
||||
if (setupcontrols == gamecontrolbis) // If we've already updated both players, break out
|
||||
break;
|
||||
}
|
||||
|
||||
S_StartSound(NULL, sfx_menu1);
|
||||
noFurtherInput = true;
|
||||
shieldbuttonprompt = 0;
|
||||
|
||||
if (ch == 'y' || ch == KEY_ENTER)
|
||||
// Now, show a message about the default Shield Ability bindings
|
||||
if ((gamecontrol[GC_SHIELD][0] == KEY_LALT && gamecontrol[GC_SHIELD][1] == KEY_JOY1+1)
|
||||
|| (gamecontrol[GC_SHIELD][0] == KEY_JOY1+1 && gamecontrol[GC_SHIELD][1] == KEY_LALT))
|
||||
{
|
||||
stopstopmessage = true; // Stop MessageDef from calling M_SetupNextMenu automatically
|
||||
OP_ChangeControlsDef.lastOn = 8; // Highlight Shield Ability in the controls menu
|
||||
M_Setup1PControlsMenu(ch); // Set up P1's controls menu and call M_SetupNextMenu
|
||||
// Left Alt and the B button are both assigned
|
||||
M_StartMessage(M_GetText("Shield Ability defaults to\nthe \x82""Left Alt\x80"" key on keyboard,\nand the \x85""B button\x80"" on gamepads."
|
||||
"\n\nYou can always reassign it\nin the Options menu later."
|
||||
"\n\n\nPress 'Enter' to continue\n"),
|
||||
NULL, MM_NOTHING);
|
||||
MessageDef.x = 43; // Change the pop-up message's background position/width
|
||||
MessageDef.lastOn = (MessageDef.lastOn & ~0xFF) | 27;
|
||||
}
|
||||
else if (gamecontrol[GC_SHIELD][0] == KEY_LALT || gamecontrol[GC_SHIELD][1] == KEY_LALT)
|
||||
{
|
||||
// Left Alt is assigned, but the B button isn't.
|
||||
M_StartMessage(M_GetText("Shield Ability defaults to\nthe \x82""Left Alt\x80"" key on keyboard.\nThe \x85""B button\x80"" on gamepads was taken."
|
||||
"\n\nYou can always reassign it\nin the Options menu later."
|
||||
"\n\n\nPress 'Enter' to continue\n"),
|
||||
NULL, MM_NOTHING);
|
||||
MessageDef.x = 24; // Change the pop-up message's background position/width
|
||||
MessageDef.lastOn = (MessageDef.lastOn & ~0xFF) | 32;
|
||||
}
|
||||
else if (gamecontrol[GC_SHIELD][0] == KEY_JOY1+1 || gamecontrol[GC_SHIELD][1] == KEY_JOY1+1)
|
||||
{
|
||||
// The B button is assigned, but Left Alt isn't
|
||||
M_StartMessage(M_GetText("Shield Ability defaults to\nthe \x85""B button\x80"" on gamepads.\nThe \x82""Left Alt\x80"" key on keyboard was taken."
|
||||
"\n\nYou can always reassign it\nin the Options menu later."
|
||||
"\n\n\nPress 'Enter' to continue\n"),
|
||||
NULL, MM_NOTHING);
|
||||
MessageDef.x = 8; // Change the pop-up message's background position/width
|
||||
MessageDef.lastOn = (MessageDef.lastOn & ~0xFF) | 36;
|
||||
}
|
||||
else if (gamecontrol[GC_SHIELD][0] == KEY_NULL && gamecontrol[GC_SHIELD][1] == KEY_NULL)
|
||||
{
|
||||
// Neither Left Alt nor the B button are assigned
|
||||
M_StartMessage(M_GetText("Shield Ability is unassigned!\nThe \x82""Left Alt\x80"" key on keyboard and\nthe \x85""B button\x80"" on gamepads were taken."
|
||||
"\n\nYou should assign Shield Ability\nin the Options menu later."
|
||||
"\n\n\nPress 'Enter' to continue\n"),
|
||||
NULL, MM_NOTHING);
|
||||
MessageDef.x = 19; // Change the pop-up message's background position/width
|
||||
MessageDef.lastOn = (MessageDef.lastOn & ~0xFF) | 33;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Neither Left Alt nor the B button are assigned... but something else is???
|
||||
// (This can technically happen if you edit your config or use setcontrol in the console before opening the menu)
|
||||
char keystr[16+16+2+7+1]; // Two 16-char keys + two colour codes + "' and '" + null
|
||||
|
||||
if (gamecontrol[GC_SHIELD][0] != KEY_NULL && gamecontrol[GC_SHIELD][1] != KEY_NULL)
|
||||
STRBUFCPY(keystr, va("%s\x80""' and '\x82""%s",
|
||||
G_KeyNumToName(gamecontrol[GC_SHIELD][0]),
|
||||
G_KeyNumToName(gamecontrol[GC_SHIELD][1])));
|
||||
else if (gamecontrol[GC_SHIELD][0] != KEY_NULL)
|
||||
STRBUFCPY(keystr, G_KeyNumToName(gamecontrol[GC_SHIELD][0]));
|
||||
else //if (gamecontrol[GC_SHIELD][1] != KEY_NULL)
|
||||
STRBUFCPY(keystr, G_KeyNumToName(gamecontrol[GC_SHIELD][1]));
|
||||
|
||||
M_StartMessage(va("Shield Ability is assigned to\n'\x82""%s\x80""'."
|
||||
"\n\nYou can always reassign it\nin the Options menu later."
|
||||
"\n\n\nPress 'Enter' to continue\n",
|
||||
keystr), NULL, MM_NOTHING);
|
||||
MessageDef.x = 23; // Change the pop-up message's background position/width
|
||||
MessageDef.lastOn = (MessageDef.lastOn & ~0xFF) | 32;
|
||||
}
|
||||
}
|
||||
|
||||
static void M_HandleShieldPromptMenu(INT32 choice) // TODO: 2.3: Remove
|
||||
{
|
||||
switch (choice)
|
||||
{
|
||||
case KEY_ESCAPE:
|
||||
if (I_GetTime() <= shieldprompt_timer) // Don't mash past the pop-up by accident!
|
||||
break;
|
||||
|
||||
S_StartSound(NULL, sfx_menu1);
|
||||
noFurtherInput = true;
|
||||
shieldprompt_timer = 0;
|
||||
M_ShieldPromptUseDefaults();
|
||||
break;
|
||||
|
||||
case KEY_ENTER:
|
||||
if (I_GetTime() <= shieldprompt_timer) // Don't mash past the pop-up by accident!
|
||||
break;
|
||||
|
||||
S_StartSound(NULL, sfx_menu1);
|
||||
noFurtherInput = true;
|
||||
shieldprompt_timer = 0;
|
||||
|
||||
if (shieldprompt_currentchoice == 0)
|
||||
{
|
||||
OP_ChangeControlsDef.lastOn = 8; // Highlight Shield Ability in the controls menu
|
||||
M_Setup1PControlsMenu(0); // Set up P1's controls menu and call M_SetupNextMenu
|
||||
}
|
||||
else if (shieldprompt_currentchoice == 1) // Copy the Spin buttons to the Shield buttons
|
||||
{
|
||||
CV_SetValue(&cv_controlperkey, 2); // Make sure that Controls per Key is "Several"
|
||||
|
||||
gamecontrol [GC_SHIELD][0] = gamecontrol [GC_SPIN][0];
|
||||
gamecontrol [GC_SHIELD][1] = gamecontrol [GC_SPIN][1];
|
||||
gamecontrolbis[GC_SHIELD][0] = gamecontrolbis[GC_SPIN][0];
|
||||
gamecontrolbis[GC_SHIELD][1] = gamecontrolbis[GC_SPIN][1];
|
||||
CV_SetValue(&cv_shieldaxis, cv_spinaxis.value);
|
||||
CV_SetValue(&cv_shieldaxis2, cv_spinaxis2.value);
|
||||
|
||||
M_StartMessage(M_GetText("Spin and Shield Ability are now\nthe same button."
|
||||
"\n\nYou can always reassign them\nin the Options menu later."
|
||||
"\n\n\nPress 'Enter' to continue\n"),
|
||||
NULL, MM_NOTHING);
|
||||
MessageDef.x = 36; // Change the pop-up message's background position/width
|
||||
MessageDef.lastOn = (MessageDef.lastOn & ~0xFF) | 29;
|
||||
}
|
||||
else
|
||||
M_ShieldPromptUseDefaults();
|
||||
break;
|
||||
|
||||
case KEY_UPARROW:
|
||||
S_StartSound(NULL, sfx_menu1);
|
||||
shieldprompt_currentchoice = (shieldprompt_currentchoice+2)%3;
|
||||
break;
|
||||
|
||||
case KEY_DOWNARROW:
|
||||
S_StartSound(NULL, sfx_menu1);
|
||||
shieldprompt_currentchoice = (shieldprompt_currentchoice+1)%3;
|
||||
break;
|
||||
}
|
||||
|
||||
MessageDef.prevMenu = &MainDef;
|
||||
}
|
||||
|
||||
static void M_DrawShieldPromptMenu(void) // TODO: 2.3: Remove
|
||||
{
|
||||
INT16 cursorx = (BASEVIDWIDTH/2) - 24;
|
||||
|
||||
V_DrawFill(10-3, 68-3, 300+6, 40+6, 159);
|
||||
// V_DrawCenteredString doesn't centre newlines, so we have to draw each line separately
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, 68, V_ALLOWLOWERCASE, "Welcome back! Since you last played,");
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, 76, V_ALLOWLOWERCASE, "Spin has been split into separate");
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, 84, V_ALLOWLOWERCASE, "\"Spin\" and \"Shield Ability\" controls.");
|
||||
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, 98, V_ALLOWLOWERCASE, "Do you want to assign Shield Ability now?");
|
||||
|
||||
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, 164,
|
||||
(shieldprompt_currentchoice == 0) ? V_YELLOWMAP : 0, "Open Control Setup");
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, 172,
|
||||
(shieldprompt_currentchoice == 1) ? V_YELLOWMAP : 0, "Keep the old behaviour");
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, 180,
|
||||
(shieldprompt_currentchoice == 2) ? V_YELLOWMAP : 0, "Use default Shield Ability buttons");
|
||||
|
||||
switch (shieldprompt_currentchoice)
|
||||
{
|
||||
case 0: cursorx -= V_StringWidth("Open Control Setup", 0)/2; break;
|
||||
case 1: cursorx -= V_StringWidth("Keep the old behaviour", 0)/2; break;
|
||||
default: cursorx -= V_StringWidth("Use default Shield Ability buttons", 0)/2; break;
|
||||
}
|
||||
V_DrawScaledPatch(cursorx, 164 + (shieldprompt_currentchoice*8), 0, W_CachePatchName("M_CURSOR", PU_PATCH));
|
||||
}
|
||||
|
||||
static menuitem_t OP_ShieldPromptMenu[] = {{IT_KEYHANDLER | IT_NOTHING, NULL, "", M_HandleShieldPromptMenu, 0}}; // TODO: 2.3: Remove
|
||||
|
||||
menu_t OP_ShieldPromptDef = { // TODO: 2.3: Remove
|
||||
MN_SPECIAL,
|
||||
NULL,
|
||||
1,
|
||||
&MainDef,
|
||||
OP_ShieldPromptMenu,
|
||||
M_DrawShieldPromptMenu,
|
||||
0, 0, 0, NULL
|
||||
};
|
||||
|
||||
//
|
||||
// M_StartControlPanel
|
||||
//
|
||||
|
@ -3689,15 +3892,13 @@ void M_StartControlPanel(void)
|
|||
itemOn = singleplr;
|
||||
M_UpdateItemOn();
|
||||
|
||||
if (shieldbuttonprompt) // For old configs, show a pop-up about the new Shield button // TODO: 2.3: Remove
|
||||
if (shieldprompt_timer) // For old configs, show a pop-up about the new Shield button // TODO: 2.3: Remove
|
||||
{
|
||||
S_StartSound(NULL, sfx_menu1);
|
||||
shieldbuttonprompt = I_GetTime() + TICRATE; // Don't mash past the pop-up by accident!
|
||||
S_StartSound(NULL, sfx_strpst);
|
||||
noFurtherInput = true;
|
||||
shieldprompt_timer = I_GetTime() + TICRATE; // Don't mash past the pop-up by accident!
|
||||
|
||||
M_StartMessage(M_GetText("Welcome back! Since you last played,\nSpin has been split into separate\n\"Spin\" and \"Shield Ability\" controls."
|
||||
"\n\nDo you want to \x82""assign Shield Ability now\x80""?"
|
||||
"\n\n\nPress \x82""ENTER\x80"" or the \x83""A button\x80"" to accept\nPress \x82""ESC\x80"" or the \x85""B button\x80"" to skip\n"),
|
||||
M_ShieldButtonResponse, MM_YESNO);
|
||||
M_SetupNextMenu(&OP_ShieldPromptDef);
|
||||
}
|
||||
}
|
||||
else if (modeattacking)
|
||||
|
|
|
@ -176,7 +176,7 @@ typedef struct
|
|||
extern menupres_t menupres[NUMMENUTYPES];
|
||||
extern UINT32 prevMenuId;
|
||||
extern UINT32 activeMenuId;
|
||||
extern tic_t shieldbuttonprompt; // Show a prompt about the new Shield button for old configs // TODO: 2.3: Remove
|
||||
extern tic_t shieldprompt_timer; // Show a prompt about the new Shield button for old configs // TODO: 2.3: Remove
|
||||
|
||||
void M_InitMenuPresTables(void);
|
||||
UINT8 M_GetYoungestChildMenu(void);
|
||||
|
|
|
@ -563,7 +563,7 @@ void M_FirstLoadConfig(void)
|
|||
// For configs loaded at startup only, check for pre-Shield-button configs // TODO: 2.3: Remove
|
||||
if (GETMAJOREXECVERSION(cv_execversion.value) < 55 // Pre-v2.2.14 configs
|
||||
&& cv_execversion.value != 25) // Make sure that the config exists, too
|
||||
shieldbuttonprompt = 1;
|
||||
shieldprompt_timer = 1;
|
||||
|
||||
// don't filter anymore vars and don't let this convsvar be changed
|
||||
COM_BufInsertText(va("%s \"%d\"\n", cv_execversion.name, EXECVERSION));
|
||||
|
|
Loading…
Reference in a new issue