Merge branch 'controller-crudules' into 'master'

Controller Crudules

Closes #479 and #476

See merge request KartKrew/Kart!1066
This commit is contained in:
AJ Martinez 2023-03-21 07:41:34 +00:00
commit 7868f21dd0
9 changed files with 144 additions and 76 deletions

View file

@ -1968,6 +1968,7 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic
{
for (; eventtail != eventhead; eventtail = (eventtail+1) & (MAXEVENTS-1))
{
HandleGamepadDeviceEvents(&events[eventtail]);
G_MapEventsToControls(&events[eventtail]);
}

View file

@ -203,7 +203,7 @@ static void HandleGamepadDeviceRemoved(event_t *ev)
}
/// Respond to added/removed device events, for bookkeeping available gamepads.
static void HandleGamepadDeviceEvents(event_t *ev)
void HandleGamepadDeviceEvents(event_t *ev)
{
I_Assert(ev != NULL);

View file

@ -26,6 +26,7 @@
#include "w_wad.h"
#include "z_zone.h"
#include "i_system.h"
#include "i_joy.h"
#include "i_threads.h"
#include "dehacked.h"
#include "g_input.h"
@ -480,40 +481,48 @@ boolean F_IntroResponder(event_t *event)
INT32 key = event->data1;
// remap virtual keys (mouse & joystick buttons)
switch (key)
if (event->type == ev_gamepad_axis && key >= JOYANALOGS
&& (abs(event->data2) > JOYAXISRANGE/2 || abs(event->data3) > JOYAXISRANGE/2))
{
case KEY_MOUSE1:
key = KEY_ENTER;
break;
case KEY_MOUSE1 + 1:
key = KEY_BACKSPACE;
break;
case KEY_JOY1:
case KEY_JOY1 + 2:
key = KEY_ENTER;
break;
case KEY_JOY1 + 3:
key = 'n';
break;
case KEY_JOY1 + 1:
key = KEY_BACKSPACE;
break;
case KEY_HAT1:
key = KEY_UPARROW;
break;
case KEY_HAT1 + 1:
key = KEY_DOWNARROW;
break;
case KEY_HAT1 + 2:
key = KEY_LEFTARROW;
break;
case KEY_HAT1 + 3:
key = KEY_RIGHTARROW;
break;
key = KEY_ENTER;
}
else
{
switch (key)
{
case KEY_MOUSE1:
key = KEY_ENTER;
break;
case KEY_MOUSE1 + 1:
key = KEY_BACKSPACE;
break;
case KEY_JOY1:
case KEY_JOY1 + 2:
key = KEY_ENTER;
break;
case KEY_JOY1 + 3:
key = 'n';
break;
case KEY_JOY1 + 1:
key = KEY_BACKSPACE;
break;
case KEY_HAT1:
key = KEY_UPARROW;
break;
case KEY_HAT1 + 1:
key = KEY_DOWNARROW;
break;
case KEY_HAT1 + 2:
key = KEY_LEFTARROW;
break;
case KEY_HAT1 + 3:
key = KEY_RIGHTARROW;
break;
}
if (event->type != ev_keydown && key != 301)
return false;
if (event->type != ev_keydown && key != 301)
return false;
}
if (key != 27 && key != KEY_ENTER && key != KEY_SPACE && key != KEY_BACKSPACE)
return false;

View file

@ -870,12 +870,12 @@ INT16 G_SoftwareClipAimingPitch(INT32 *aiming)
static INT32 G_GetValueFromControlTable(INT32 deviceID, INT32 deadzone, INT32 *controltable)
{
INT32 i;
INT32 i, failret = NO_BINDS_REACHABLE;
if (deviceID <= UNASSIGNED_DEVICE)
{
// An invalid device can't have any binds!
return 0;
return failret;
}
for (i = 0; i < MAXINPUTMAPPING; i++)
@ -895,10 +895,12 @@ static INT32 G_GetValueFromControlTable(INT32 deviceID, INT32 deadzone, INT32 *c
{
return value;
}
failret = 0;
}
// Not pressed.
return 0;
return failret;
}
INT32 G_PlayerInputAnalog(UINT8 p, INT32 gc, UINT8 menuPlayers)
@ -911,6 +913,7 @@ INT32 G_PlayerInputAnalog(UINT8 p, INT32 gc, UINT8 menuPlayers)
INT32 value = -1;
INT32 avail_gamepad_id = 0;
INT32 i;
boolean bind_was_reachable = false;
if (p >= MAXSPLITSCREENPLAYERS)
{
@ -952,6 +955,10 @@ INT32 G_PlayerInputAnalog(UINT8 p, INT32 gc, UINT8 menuPlayers)
{
return value;
}
if (value != NO_BINDS_REACHABLE)
{
bind_was_reachable = true;
}
// If you're on gamepad in 1P, and you didn't have a gamepad bind for this, then try your keyboard binds.
if (main_player == true && keyboard_player == -1 && deviceID > KEYBOARD_MOUSE_DEVICE)
@ -961,6 +968,10 @@ INT32 G_PlayerInputAnalog(UINT8 p, INT32 gc, UINT8 menuPlayers)
{
return value;
}
if (value != NO_BINDS_REACHABLE)
{
bind_was_reachable = true;
}
}
if (in_menu == true)
@ -997,15 +1008,22 @@ INT32 G_PlayerInputAnalog(UINT8 p, INT32 gc, UINT8 menuPlayers)
{
return value;
}
if (value != NO_BINDS_REACHABLE)
{
bind_was_reachable = true;
}
}
}
}
// Still nothing bound after everything. Try default gamepad controls.
value = G_GetValueFromControlTable(deviceID, deadzone, &(gamecontroldefault[gc][0]));
if (value > 0)
if (bind_was_reachable == false)
{
return value;
// Still nothing bound after everything. Try default gamepad controls.
value = G_GetValueFromControlTable(deviceID, deadzone, &(gamecontroldefault[gc][0]));
if (value > 0)
{
return value;
}
}
}
@ -1653,7 +1671,11 @@ boolean G_Responder(event_t *ev)
if (gameaction == ga_nothing && !demo.quitafterplaying &&
((demo.playback && !modeattacking && !demo.title && !multiplayer) || gamestate == GS_TITLESCREEN))
{
if (ev->type == ev_keydown)
if (ev->type == ev_keydown
|| (ev->type == ev_gamepad_axis && ev->data1 >= JOYANALOGS
&& ((abs(ev->data2) > JOYAXISRANGE/2
|| abs(ev->data3) > JOYAXISRANGE/2))
))
{
M_StartControlPanel();
return true;

View file

@ -362,6 +362,7 @@ static INT32 AssignDeviceToFirstUnassignedPlayer(INT32 device)
void G_MapEventsToControls(event_t *ev)
{
INT32 i;
INT32 *DeviceGameKeyDownArray;
if (ev->device >= 0)
{
@ -383,12 +384,17 @@ void G_MapEventsToControls(event_t *ev)
return;
}
DeviceGameKeyDownArray = G_GetDeviceGameKeyDownArray(ev->device);
if (!DeviceGameKeyDownArray)
return;
switch (ev->type)
{
case ev_keydown:
if (ev->data1 < NUMINPUTS)
{
G_GetDeviceGameKeyDownArray(ev->device)[ev->data1] = JOYAXISRANGE;
DeviceGameKeyDownArray[ev->data1] = JOYAXISRANGE;
if (AutomaticControllerReassignmentIsAllowed(ev->device))
{
@ -410,7 +416,7 @@ void G_MapEventsToControls(event_t *ev)
case ev_keyup:
if (ev->data1 < NUMINPUTS)
{
G_GetDeviceGameKeyDownArray(ev->device)[ev->data1] = 0;
DeviceGameKeyDownArray[ev->data1] = 0;
}
#ifdef PARANOIA
else
@ -425,28 +431,28 @@ void G_MapEventsToControls(event_t *ev)
if (ev->data2 < 0)
{
// Left
G_GetDeviceGameKeyDownArray(ev->device)[KEY_MOUSEMOVE + 2] = abs(ev->data2);
G_GetDeviceGameKeyDownArray(ev->device)[KEY_MOUSEMOVE + 3] = 0;
DeviceGameKeyDownArray[KEY_MOUSEMOVE + 2] = abs(ev->data2);
DeviceGameKeyDownArray[KEY_MOUSEMOVE + 3] = 0;
}
else
{
// Right
G_GetDeviceGameKeyDownArray(ev->device)[KEY_MOUSEMOVE + 2] = 0;
G_GetDeviceGameKeyDownArray(ev->device)[KEY_MOUSEMOVE + 3] = abs(ev->data2);
DeviceGameKeyDownArray[KEY_MOUSEMOVE + 2] = 0;
DeviceGameKeyDownArray[KEY_MOUSEMOVE + 3] = abs(ev->data2);
}
// Y axis
if (ev->data3 < 0)
{
// Up
G_GetDeviceGameKeyDownArray(ev->device)[KEY_MOUSEMOVE] = abs(ev->data3);
G_GetDeviceGameKeyDownArray(ev->device)[KEY_MOUSEMOVE + 1] = 0;
DeviceGameKeyDownArray[KEY_MOUSEMOVE] = abs(ev->data3);
DeviceGameKeyDownArray[KEY_MOUSEMOVE + 1] = 0;
}
else
{
// Down
G_GetDeviceGameKeyDownArray(ev->device)[KEY_MOUSEMOVE] = 0;
G_GetDeviceGameKeyDownArray(ev->device)[KEY_MOUSEMOVE + 1] = abs(ev->data3);
DeviceGameKeyDownArray[KEY_MOUSEMOVE] = 0;
DeviceGameKeyDownArray[KEY_MOUSEMOVE + 1] = abs(ev->data3);
}
break;
@ -466,14 +472,24 @@ void G_MapEventsToControls(event_t *ev)
// The trigger axes are handled specially.
i -= JOYANALOGS;
if (AutomaticControllerReassignmentIsAllowed(ev->device)
&& (abs(ev->data2) > JOYAXISRANGE/2 || abs(ev->data3) > JOYAXISRANGE/2))
{
INT32 assigned = AssignDeviceToFirstUnassignedPlayer(ev->device);
if (assigned >= 0)
{
CONS_Alert(CONS_NOTICE, "Player %d device was reassigned\n", assigned + 1);
}
}
if (ev->data2 != INT32_MAX)
{
G_GetDeviceGameKeyDownArray(ev->device)[KEY_AXIS1 + (JOYANALOGS * 4) + (i * 2)] = max(0, ev->data2);
DeviceGameKeyDownArray[KEY_AXIS1 + (JOYANALOGS * 4) + (i * 2)] = max(0, ev->data2);
}
if (ev->data3 != INT32_MAX)
{
G_GetDeviceGameKeyDownArray(ev->device)[KEY_AXIS1 + (JOYANALOGS * 4) + (i * 2) + 1] = max(0, ev->data3);
DeviceGameKeyDownArray[KEY_AXIS1 + (JOYANALOGS * 4) + (i * 2) + 1] = max(0, ev->data3);
}
}
else
@ -484,14 +500,14 @@ void G_MapEventsToControls(event_t *ev)
if (ev->data2 < 0)
{
// Left
G_GetDeviceGameKeyDownArray(ev->device)[KEY_AXIS1 + (i * 4)] = abs(ev->data2);
G_GetDeviceGameKeyDownArray(ev->device)[KEY_AXIS1 + (i * 4) + 1] = 0;
DeviceGameKeyDownArray[KEY_AXIS1 + (i * 4)] = abs(ev->data2);
DeviceGameKeyDownArray[KEY_AXIS1 + (i * 4) + 1] = 0;
}
else
{
// Right
G_GetDeviceGameKeyDownArray(ev->device)[KEY_AXIS1 + (i * 4)] = 0;
G_GetDeviceGameKeyDownArray(ev->device)[KEY_AXIS1 + (i * 4) + 1] = abs(ev->data2);
DeviceGameKeyDownArray[KEY_AXIS1 + (i * 4)] = 0;
DeviceGameKeyDownArray[KEY_AXIS1 + (i * 4) + 1] = abs(ev->data2);
}
}
@ -500,14 +516,14 @@ void G_MapEventsToControls(event_t *ev)
if (ev->data3 < 0)
{
// Up
G_GetDeviceGameKeyDownArray(ev->device)[KEY_AXIS1 + (i * 4) + 2] = abs(ev->data3);
G_GetDeviceGameKeyDownArray(ev->device)[KEY_AXIS1 + (i * 4) + 3] = 0;
DeviceGameKeyDownArray[KEY_AXIS1 + (i * 4) + 2] = abs(ev->data3);
DeviceGameKeyDownArray[KEY_AXIS1 + (i * 4) + 3] = 0;
}
else
{
// Down
G_GetDeviceGameKeyDownArray(ev->device)[KEY_AXIS1 + (i * 4) + 2] = 0;
G_GetDeviceGameKeyDownArray(ev->device)[KEY_AXIS1 + (i * 4) + 3] = abs(ev->data3);
DeviceGameKeyDownArray[KEY_AXIS1 + (i * 4) + 2] = 0;
DeviceGameKeyDownArray[KEY_AXIS1 + (i * 4) + 3] = abs(ev->data3);
}
}
}
@ -809,20 +825,20 @@ INT32 G_KeyStringtoNum(const char *keystr)
void G_DefineDefaultControls(void)
{
// These defaults are bad & temporary.
// These defaults are less bad than they used to be.
// Keyboard controls
gamecontroldefault[gc_up ][0] = KEY_UPARROW;
gamecontroldefault[gc_down ][0] = KEY_DOWNARROW;
gamecontroldefault[gc_left ][0] = KEY_LEFTARROW;
gamecontroldefault[gc_right ][0] = KEY_RIGHTARROW;
gamecontroldefault[gc_a ][0] = 'z';
gamecontroldefault[gc_b ][0] = 'x';
gamecontroldefault[gc_c ][0] = 'c';
gamecontroldefault[gc_x ][0] = 'a';
gamecontroldefault[gc_y ][0] = 's';
gamecontroldefault[gc_z ][0] = 'd';
gamecontroldefault[gc_l ][0] = 'q';
gamecontroldefault[gc_r ][0] = 'e';
gamecontroldefault[gc_a ][0] = 'f';
gamecontroldefault[gc_b ][0] = 'a';
gamecontroldefault[gc_c ][0] = 'v';
gamecontroldefault[gc_x ][0] = 's';
gamecontroldefault[gc_y ][0] = 'x';
gamecontroldefault[gc_z ][0] = 'c';
gamecontroldefault[gc_l ][0] = KEY_SPACE;
gamecontroldefault[gc_r ][0] = 'd';
gamecontroldefault[gc_start ][0] = KEY_ESCAPE;
gamecontroldefault[gc_rankings][0] = KEY_TAB;
@ -832,20 +848,24 @@ void G_DefineDefaultControls(void)
gamecontroldefault[gc_left ][1] = KEY_HAT1+2; // D-Pad Left
gamecontroldefault[gc_right][1] = KEY_HAT1+3; // D-Pad Right
gamecontroldefault[gc_a ][1] = KEY_JOY1+0; // A
gamecontroldefault[gc_b ][1] = KEY_JOY1+2; // X
gamecontroldefault[gc_b ][1] = KEY_JOY1+1; // B
gamecontroldefault[gc_c ][1] = KEY_JOY1+3; // Y
gamecontroldefault[gc_x ][1] = KEY_JOY1+1; // B
gamecontroldefault[gc_y ][1] = KEY_JOY1+6;
gamecontroldefault[gc_z ][1] = KEY_JOY1+8;
gamecontroldefault[gc_l ][1] = KEY_JOY1+4; // LB
gamecontroldefault[gc_r ][1] = KEY_JOY1+5; // RB
gamecontroldefault[gc_start][1] = KEY_JOY1+7; // Start
gamecontroldefault[gc_x ][1] = KEY_JOY1+2; // X
gamecontroldefault[gc_y ][1] = KEY_JOY1+9; // LB
gamecontroldefault[gc_z ][1] = KEY_JOY1+10; // RB
gamecontroldefault[gc_l ][1] = KEY_AXIS1+8; // LT
gamecontroldefault[gc_r ][1] = KEY_AXIS1+9; // RT
gamecontroldefault[gc_start][1] = KEY_JOY1+6; // Start
gamecontroldefault[gc_up ][2] = KEY_AXIS1+2; // Axis Y-
gamecontroldefault[gc_down ][2] = KEY_AXIS1+3; // Axis Y+
gamecontroldefault[gc_left ][2] = KEY_AXIS1+0; // Axis X-
gamecontroldefault[gc_right][2] = KEY_AXIS1+1; // Axis X+
#ifdef DEVELOP
gamecontroldefault[gc_console][0] = '`';
#endif
// Menu reserved controls
menucontrolreserved[gc_up ][0] = KEY_UPARROW;
menucontrolreserved[gc_down ][0] = KEY_DOWNARROW;

View file

@ -109,6 +109,7 @@ extern consvar_t cv_controlperkey;
#define MAXDEVICES (MAXGAMEPADS + 1) // Gamepads + keyboard & mouse
#define KEYBOARD_MOUSE_DEVICE (0)
#define UNASSIGNED_DEVICE (-1)
#define NO_BINDS_REACHABLE (-1)
extern INT32 gamekeydown[MAXDEVICES][NUMINPUTS];
// several key codes (or virtual key) per game control
@ -165,6 +166,8 @@ boolean G_IsDeviceResponding(INT32 device);
void G_SetDeviceResponding(INT32 device, boolean responding);
void G_ResetAllDeviceResponding(void);
void HandleGamepadDeviceEvents(event_t *ev);
// remaps the input event to a game control.
void G_MapEventsToControls(event_t *ev);

View file

@ -871,10 +871,15 @@ INT32 I_GetKey (void)
event_t *ev;
INT32 rc = 0;
G_ResetAllDeviceResponding();
// return the first keypress from the event queue
for (; eventtail != eventhead; eventtail = (eventtail+1)&(MAXEVENTS-1))
{
ev = &events[eventtail];
HandleGamepadDeviceEvents(ev);
if (ev->type == ev_keydown || ev->type == ev_console)
{
rc = ev->data1;

View file

@ -910,10 +910,15 @@ INT32 I_GetKey (void)
event_t *ev;
INT32 rc = 0;
G_ResetAllDeviceResponding();
// return the first keypress from the event queue
for (; eventtail != eventhead; eventtail = (eventtail+1)&(MAXEVENTS-1))
{
ev = &events[eventtail];
HandleGamepadDeviceEvents(ev);
if (ev->type == ev_keydown || ev->type == ev_console)
{
rc = ev->data1;

View file

@ -3067,9 +3067,12 @@ INT32 I_GetKey(void)
{
event_t *ev;
G_ResetAllDeviceResponding();
if (eventtail != eventhead)
{
ev = &events[eventtail];
HandleGamepadDeviceEvents(ev);
eventtail = (eventtail+1) & (MAXEVENTS-1);
if (ev->type == ev_keydown || ev->type == ev_console)
return ev->data1;