Update input handling in menus to use key bindings (port-ish of f17b9484)

G_GetControlForKey -> G_ControlBoundToKey, to make it usable everywhere
This commit is contained in:
GenericHeroGuy 2025-03-07 17:39:21 +01:00
parent 7740b0dccd
commit 84850ba8a3
9 changed files with 53 additions and 59 deletions

View file

@ -940,7 +940,7 @@ boolean CON_Responder(event_t *ev)
// let go keyup events, don't eat them // let go keyup events, don't eat them
if (ev->type != ev_keydown && ev->type != ev_console) if (ev->type != ev_keydown && ev->type != ev_console)
{ {
if (ev->data1 == gamecontrol[0][gc_console][0] || ev->data1 == gamecontrol[0][gc_console][1]) if (G_ControlBoundToKey(0, gc_console, ev->data1, false))
consdown = false; consdown = false;
return false; return false;
} }
@ -953,12 +953,12 @@ boolean CON_Responder(event_t *ev)
if (modeattacking || metalrecording || marathonmode) if (modeattacking || metalrecording || marathonmode)
return false; return false;
if (ev->data1 >= KEY_MOUSE1) // See also: HUD_Responder if (ev->data1 >= KEY_JOY1) // See also: HUD_Responder
{ {
INT32 i; INT32 i;
for (i = 0; i < num_gamecontrols; i++) for (i = 0; i < num_gamecontrols; i++)
{ {
if (gamecontrol[0][i][0] == ev->data1 || gamecontrol[0][i][1] == ev->data1) if (G_ControlBoundToKey(0, i, ev->data1, false))
break; break;
} }
@ -966,7 +966,7 @@ boolean CON_Responder(event_t *ev)
return false; return false;
} }
if (key == gamecontrol[0][gc_console][0] || key == gamecontrol[0][gc_console][1]) if (G_ControlBoundToKey(0, gc_console, key, false))
{ {
if (consdown) // ignore repeat if (consdown) // ignore repeat
return true; return true;

View file

@ -1504,7 +1504,7 @@ static void M_ConfirmConnect(event_t *ev)
{ {
if (ev->type == ev_keydown) if (ev->type == ev_keydown)
{ {
if (ev->data1 == ' ' || ev->data1 == 'y' || ev->data1 == KEY_ENTER || ev->data1 == gamecontrol[0][gc_accelerate][0] || ev->data1 == gamecontrol[0][gc_accelerate][1]) if (ev->data1 == ' ' || ev->data1 == 'y' || ev->data1 == KEY_ENTER || G_ControlBoundToKey(0, gc_accelerate, ev->data1, false))
{ {
if (totalfilesrequestednum > 0) if (totalfilesrequestednum > 0)
{ {
@ -1531,7 +1531,7 @@ static void M_ConfirmConnect(event_t *ev)
M_ClearMenus(true); M_ClearMenus(true);
} }
else if (ev->data1 == 'n' || ev->data1 == KEY_ESCAPE|| ev->data1 == gamecontrol[0][gc_brake][0] || ev->data1 == gamecontrol[0][gc_brake][1]) else if (ev->data1 == 'n' || ev->data1 == KEY_ESCAPE || G_ControlBoundToKey(0, gc_brake, ev->data1, false))
{ {
cl_mode = CL_ABORTED; cl_mode = CL_ABORTED;
M_ClearMenus(true); M_ClearMenus(true);
@ -1951,7 +1951,7 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic
G_MapEventsToControls(&events[eventtail]); G_MapEventsToControls(&events[eventtail]);
if (gamekeydown[0][KEY_ESCAPE] if (gamekeydown[0][KEY_ESCAPE]
|| gamekeydown[0][KEY_JOY1+1]) || G_PlayerInputDown(0, gc_brake, true))
cl_mode = CL_ABORTED; cl_mode = CL_ABORTED;
} }

View file

@ -4042,7 +4042,7 @@ boolean G_DemoTitleResponder(event_t *ev)
return true; return true;
} }
if (ch == KEY_ENTER || ch >= KEY_MOUSE1) if (ch == KEY_ENTER || ch >= KEY_JOY1)
{ {
demo.savemode = DSM_WILLSAVE; demo.savemode = DSM_WILLSAVE;
return true; return true;

View file

@ -763,30 +763,27 @@ INT16 G_SoftwareClipAimingPitch(INT32 *aiming)
return (INT16)((*aiming)>>16); return (INT16)((*aiming)>>16);
} }
// returns the first gamecontrol that matches the given key // check if the given key is bound to the given gamecontrol
// used by menu code (that boolean is kinda pointless...) // if menu is true, also check defaults if the gamecontrol has no binds
INT32 G_GetControlForKey(UINT8 p, INT32 key, boolean menu) boolean G_ControlBoundToKey(UINT8 p, INT32 gc, INT32 key, boolean menu)
{ {
INT32 i, gc; INT32 i;
for (gc = 0; gc < num_gamecontrols; gc++) INT32 (*map)[MAXINPUTMAPPING] = &gamecontrol[p][gc];
if (menu)
{ {
INT32 (*map)[][MAXINPUTMAPPING] = &gamecontrol[p];
// if this control isn't bound, switch to defaults
if (menu)
{
for (i = 0; i < MAXINPUTMAPPING; i++)
if ((*map)[gc][i])
goto bound;
map = &gamecontroldefault;
}
bound:
for (i = 0; i < MAXINPUTMAPPING; i++) for (i = 0; i < MAXINPUTMAPPING; i++)
if ((*map)[gc][i] == key) if ((*map)[i])
return gc; goto bound;
map = &gamecontroldefault[gc];
} }
return gc_null; bound:
for (i = 0; i < MAXINPUTMAPPING; i++)
if ((*map)[i] == key)
return true;
return false;
} }
static INT32 KeyValue(UINT8 p, INT32 key) static INT32 KeyValue(UINT8 p, INT32 key)
@ -1563,7 +1560,7 @@ boolean G_Responder(event_t *ev)
// allow spy mode changes even during the demo // allow spy mode changes even during the demo
if (gamestate == GS_LEVEL && ev->type == ev_keydown if (gamestate == GS_LEVEL && ev->type == ev_keydown
&& (ev->data1 == KEY_F12 || ev->data1 == gamecontrol[0][gc_viewpoint][0] || ev->data1 == gamecontrol[0][gc_viewpoint][1])) && (ev->data1 == KEY_F12 || G_ControlBoundToKey(0, gc_viewpoint, ev->data1, false)))
{ {
if (!demo.playback && (r_splitscreen)) if (!demo.playback && (r_splitscreen))
g_localplayers[0] = consoleplayer; g_localplayers[0] = consoleplayer;
@ -1581,17 +1578,17 @@ boolean G_Responder(event_t *ev)
if (gamestate == GS_LEVEL && ev->type == ev_keydown && multiplayer && demo.playback && !demo.freecam) if (gamestate == GS_LEVEL && ev->type == ev_keydown && multiplayer && demo.playback && !demo.freecam)
{ {
if (ev->data1 == gamecontrol[1][gc_viewpoint][0] || ev->data1 == gamecontrol[1][gc_viewpoint][1]) if (G_ControlBoundToKey(1, gc_viewpoint, ev->data1, false))
{ {
G_AdjustView(2, 1, true); G_AdjustView(2, 1, true);
return true; return true;
} }
else if (ev->data1 == gamecontrol[2][gc_viewpoint][0] || ev->data1 == gamecontrol[2][gc_viewpoint][1]) else if (G_ControlBoundToKey(2, gc_viewpoint, ev->data1, false))
{ {
G_AdjustView(3, 1, true); G_AdjustView(3, 1, true);
return true; return true;
} }
else if (ev->data1 == gamecontrol[3][gc_viewpoint][0] || ev->data1 == gamecontrol[3][gc_viewpoint][1]) else if (G_ControlBoundToKey(3, gc_viewpoint, ev->data1, false))
{ {
G_AdjustView(4, 1, true); G_AdjustView(4, 1, true);
return true; return true;
@ -1599,8 +1596,7 @@ boolean G_Responder(event_t *ev)
// Allow pausing // Allow pausing
if ( if (
ev->data1 == gamecontrol[0][gc_pause][0] G_ControlBoundToKey(0, gc_pause, ev->data1, false)
|| ev->data1 == gamecontrol[0][gc_pause][1]
|| ev->data1 == KEY_PAUSE || ev->data1 == KEY_PAUSE
) )
{ {
@ -1635,8 +1631,7 @@ boolean G_Responder(event_t *ev)
switch (ev->type) switch (ev->type)
{ {
case ev_keydown: case ev_keydown:
if (ev->data1 == gamecontrol[0][gc_pause][0] if (G_ControlBoundToKey(0, gc_pause, ev->data1, false)
|| ev->data1 == gamecontrol[0][gc_pause][1]
|| ev->data1 == KEY_PAUSE) || ev->data1 == KEY_PAUSE)
{ {
if (modeattacking && !demo.playback && (gamestate == GS_LEVEL)) if (modeattacking && !demo.playback && (gamestate == GS_LEVEL))
@ -1669,8 +1664,7 @@ boolean G_Responder(event_t *ev)
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++) for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
{ {
if (ev->data1 == gamecontrol[i][gc_camtoggle][0] if (G_ControlBoundToKey(i, gc_camtoggle, ev->data1, false))
|| ev->data1 == gamecontrol[i][gc_camtoggle][1])
{ {
if (!camtoggledelay[i]) if (!camtoggledelay[i])
{ {

View file

@ -122,7 +122,7 @@ extern INT32 localaiming[MAXSPLITSCREENPLAYERS]; // should be an angle_t but sig
INT32 G_PlayerInputAnalog(UINT8 p, INT32 gc, boolean menu); INT32 G_PlayerInputAnalog(UINT8 p, INT32 gc, boolean menu);
boolean G_PlayerInputDown(UINT8 p, INT32 gc, boolean menu); boolean G_PlayerInputDown(UINT8 p, INT32 gc, boolean menu);
INT32 G_GetControlForKey(UINT8 p, INT32 key, boolean menu); boolean G_ControlBoundToKey(UINT8 p, INT32 gc, INT32 key, boolean menu);
// //
// GAME // GAME

View file

@ -92,7 +92,7 @@ extern consvar_t cv_controlperkey, cv_turnsmooth;
// Or anything inbetween for analog values // Or anything inbetween for analog values
extern INT32 gamekeydown[MAXSPLITSCREENPLAYERS][NUMINPUTS]; extern INT32 gamekeydown[MAXSPLITSCREENPLAYERS][NUMINPUTS];
// two key codes (or virtual key) per game control // several key codes (or virtual key) per game control
extern INT32 gamecontrol[MAXSPLITSCREENPLAYERS][num_gamecontrols][MAXINPUTMAPPING]; extern INT32 gamecontrol[MAXSPLITSCREENPLAYERS][num_gamecontrols][MAXINPUTMAPPING];
extern INT32 gamecontroldefault[num_gamecontrols][MAXINPUTMAPPING]; // default control storage extern INT32 gamecontroldefault[num_gamecontrols][MAXINPUTMAPPING]; // default control storage

View file

@ -1233,12 +1233,12 @@ boolean HU_Responder(event_t *ev)
// (Unless if you're sharing a keyboard, since you probably establish when you start chatting that you have dibs on it...) // (Unless if you're sharing a keyboard, since you probably establish when you start chatting that you have dibs on it...)
// (Ahhh, the good ol days when I was a kid who couldn't afford an extra USB controller...) // (Ahhh, the good ol days when I was a kid who couldn't afford an extra USB controller...)
if (ev->data1 >= KEY_MOUSE1) if (ev->data1 >= KEY_JOY1)
{ {
INT32 i; INT32 i;
for (i = 0; i < num_gamecontrols; i++) for (i = 0; i < num_gamecontrols; i++)
{ {
if (gamecontrol[0][i][0] == ev->data1 || gamecontrol[0][i][1] == ev->data1) if (G_ControlBoundToKey(0, i, ev->data1, false))
break; break;
} }
@ -1249,7 +1249,7 @@ boolean HU_Responder(event_t *ev)
if (!chat_on) if (!chat_on)
{ {
// enter chat mode // enter chat mode
if ((ev->data1 == gamecontrol[0][gc_talkkey][0] || ev->data1 == gamecontrol[0][gc_talkkey][1]) if (G_ControlBoundToKey(0, gc_talkkey, ev->data1, false)
&& netgame && !OLD_MUTE) // check for old chat mute, still let the players open the chat incase they want to scroll otherwise. && netgame && !OLD_MUTE) // check for old chat mute, still let the players open the chat incase they want to scroll otherwise.
{ {
chat_on = true; chat_on = true;
@ -1259,7 +1259,7 @@ boolean HU_Responder(event_t *ev)
typelines = 1; typelines = 1;
return true; return true;
} }
if ((ev->data1 == gamecontrol[0][gc_teamkey][0] || ev->data1 == gamecontrol[0][gc_teamkey][1]) if (G_ControlBoundToKey(0, gc_teamkey, ev->data1, false)
&& netgame && !OLD_MUTE) && netgame && !OLD_MUTE)
{ {
chat_on = true; chat_on = true;
@ -1283,9 +1283,8 @@ boolean HU_Responder(event_t *ev)
return true; return true;
// Ignore non-keyboard keys, except when the talk key is bound // Ignore non-keyboard keys, except when the talk key is bound
if (ev->data1 >= KEY_MOUSE1 if (ev->data1 >= KEY_JOY1
&& (ev->data1 != gamecontrol[0][gc_talkkey][0] && !G_ControlBoundToKey(0, gc_talkkey, ev->data1, false))
&& ev->data1 != gamecontrol[0][gc_talkkey][1]))
return false; return false;
c = CON_ShiftChar(c); c = CON_ShiftChar(c);
@ -1325,9 +1324,9 @@ boolean HU_Responder(event_t *ev)
I_UpdateMouseGrab(); I_UpdateMouseGrab();
} }
else if (c == KEY_ESCAPE else if (c == KEY_ESCAPE
|| ((c == gamecontrol[0][gc_talkkey][0] || c == gamecontrol[0][gc_talkkey][1] || ((G_ControlBoundToKey(0, gc_talkkey, c, false)
|| c == gamecontrol[0][gc_teamkey][0] || c == gamecontrol[0][gc_teamkey][1]) || G_ControlBoundToKey(0, gc_teamkey, c, false))
&& c >= KEY_MOUSE1)) // If it's not a keyboard key, then the chat button is used as a toggle. && c >= KEY_JOY1)) // If it's not a keyboard key, then the chat button is used as a toggle.
{ {
chat_on = false; chat_on = false;
c_input = 0; // reset input cursor c_input = 0; // reset input cursor

View file

@ -2595,13 +2595,14 @@ boolean M_Responder(event_t *ev)
{ gc_accelerate, KEY_ENTER }, { gc_accelerate, KEY_ENTER },
}; };
INT32 gc = G_GetControlForKey(0, ch, true); for (size_t r = 0; r < sizeof(joyremap)/sizeof(*joyremap); r++)
if (gc != gc_null && !(gc == gc_brake && !menuactive)) // don't open the menu with brake!
{ {
for (size_t r = 0; r < sizeof(joyremap)/sizeof(*joyremap); r++) INT32 gc = joyremap[r][0];
if (gc == gc_brake && !menuactive)
continue; // don't open the menu with brake!
if (G_ControlBoundToKey(0, gc, ch, true))
{ {
if (gc != joyremap[r][0])
continue;
ch = joyremap[r][1]; ch = joyremap[r][1];
break; break;
} }
@ -9706,7 +9707,7 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
INT32 prev_setupm_fakeskin; INT32 prev_setupm_fakeskin;
boolean exitmenu = false; // exit to previous menu and send name change boolean exitmenu = false; // exit to previous menu and send name change
if ((choice == gamecontrol[0][gc_fire][0] || choice == gamecontrol[0][gc_fire][1]) && itemOn == 2) if (G_ControlBoundToKey(0, gc_fire, choice, false) && itemOn == 2)
choice = KEY_BACKSPACE; // Hack to allow resetting prefcolor on controllers choice = KEY_BACKSPACE; // Hack to allow resetting prefcolor on controllers
switch (choice) switch (choice)

View file

@ -1614,12 +1614,12 @@ boolean M_ScreenshotResponder(event_t *ev)
ch = ev->data1; ch = ev->data1;
if (ch >= KEY_MOUSE1 && menuactive) // If it's not a keyboard key, then don't allow it in the menus! if (ch >= KEY_JOY1 && menuactive) // If it's not a keyboard key, then don't allow it in the menus!
return false; return false;
if (ch == KEY_F8 || ch == gamecontrol[0][gc_screenshot][0] || ch == gamecontrol[0][gc_screenshot][1]) // remappable F8 if (ch == KEY_F8 || G_ControlBoundToKey(0, gc_screenshot, ch, false)) // remappable F8
M_ScreenShot(); M_ScreenShot();
else if (ch == KEY_F9 || ch == gamecontrol[0][gc_recordgif][0] || ch == gamecontrol[0][gc_recordgif][1]) // remappable F9 else if (ch == KEY_F9 || G_ControlBoundToKey(0, gc_recordgif, ch, false)) // remappable F9
((moviemode) ? M_StopMovie : M_StartMovie)(); ((moviemode) ? M_StopMovie : M_StartMovie)();
else else
return false; return false;