mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2025-04-03 00:41:34 +00:00
Merge pull request #1183 from protocultor/sdl3_buttons
Consistent binding between multiple gamepad types + labels by style
This commit is contained in:
commit
4fe0d0be6b
8 changed files with 681 additions and 223 deletions
|
@ -581,18 +581,33 @@ it's `+set busywait 0` (setting the `busywait` cvar) and `-portable`
|
|||
* **sw_colorlight**: enable experimental color lighting.
|
||||
|
||||
|
||||
## Game Controller
|
||||
## Gamepad
|
||||
|
||||
* **in_initjoy**: Toggles initialization of game controller. Default is
|
||||
`1`, which enables gamepad usage; `0` disables its detection at
|
||||
startup. Can only be set from command line.
|
||||
|
||||
* **in_sdlbackbutton**: Defines which button is used in the gamepad as
|
||||
* **joy_escbutton**: Defines which button is used in the gamepad as
|
||||
the `Esc` key, to pull the main menu and 'cancel' / 'go back' on its
|
||||
options. Valid values are `0` = Back / Select / Minus, `1` = Start /
|
||||
Menu / Plus (default), or `2` = Guide / Home / PS. Requires a game
|
||||
options. Valid values are `0` = Start / Menu / Plus (default), `1` =
|
||||
Back / Select / Minus, or `2` = Guide / Home / PS. Requires a game
|
||||
restart, or gamepad replug, when changed.
|
||||
|
||||
* **joy_labels**: Defines style of button labels in binding menus. Note
|
||||
that binding through console only uses the SDL nomenclature (`0`).
|
||||
Default is `-1`, which requires at least SDL 2.0.12 to work.
|
||||
- `-1`: *Autodetect*, sets to `0` if gamepad type isn't detected
|
||||
- `0`: *SDL*, face buttons appear as cardinal points
|
||||
- `1`: *Xbox*, with One / Series X / S labels
|
||||
- `2`: *Playstation*, 4 & 5 format
|
||||
- `3`: *Switch*, traditional Nintendo button format
|
||||
|
||||
* **joy_confirm**: Style of *confirm* and *cancel* buttons in menus. As
|
||||
with the previous one, SDL 2.0.12 is required for `-1` to work.
|
||||
- `-1`: *Autodetect*, sets to `1` if Nintendo, `0` otherwise
|
||||
- `0`: SOUTH to confirm, EAST to cancel (standard style)
|
||||
- `1`: EAST to confirm, SOUTH to cancel (Japanese style)
|
||||
|
||||
* **joy_layout**: Allows to select the stick layout of the gamepad.
|
||||
- `0`: *Default*, left stick moves, right aims
|
||||
- `1`: *Southpaw*, same as previous one with inverted sticks
|
||||
|
|
|
@ -139,62 +139,6 @@ keyname_t keynames[] = {
|
|||
{"MWHEELUP", K_MWHEELUP},
|
||||
{"MWHEELDOWN", K_MWHEELDOWN},
|
||||
|
||||
{"BTN_A", K_BTN_A},
|
||||
{"BTN_B", K_BTN_B},
|
||||
{"BTN_X", K_BTN_X},
|
||||
{"BTN_Y", K_BTN_Y},
|
||||
{"STICK_LEFT", K_STICK_LEFT},
|
||||
{"STICK_RIGHT", K_STICK_RIGHT},
|
||||
{"SHOULDR_LEFT", K_SHOULDER_LEFT},
|
||||
{"SHOULDR_RIGHT", K_SHOULDER_RIGHT},
|
||||
{"TRIG_LEFT", K_TRIG_LEFT},
|
||||
{"TRIG_RIGHT", K_TRIG_RIGHT},
|
||||
|
||||
{"DP_UP", K_DPAD_UP},
|
||||
{"DP_DOWN", K_DPAD_DOWN},
|
||||
{"DP_LEFT", K_DPAD_LEFT},
|
||||
{"DP_RIGHT", K_DPAD_RIGHT},
|
||||
|
||||
{"PADDLE_1", K_PADDLE_1},
|
||||
{"PADDLE_2", K_PADDLE_2},
|
||||
{"PADDLE_3", K_PADDLE_3},
|
||||
{"PADDLE_4", K_PADDLE_4},
|
||||
{"BTN_MISC1", K_BTN_MISC1},
|
||||
{"TOUCHPAD", K_TOUCHPAD},
|
||||
{"BTN_BACK", K_BTN_BACK},
|
||||
{"BTN_GUIDE", K_BTN_GUIDE},
|
||||
{"BTN_START", K_BTN_START},
|
||||
|
||||
// virtual keys you get by pressing the corresponding normal joy key
|
||||
// and the altselector key
|
||||
{"BTN_A_ALT", K_BTN_A_ALT},
|
||||
{"BTN_B_ALT", K_BTN_B_ALT},
|
||||
{"BTN_X_ALT", K_BTN_X_ALT},
|
||||
{"BTN_Y_ALT", K_BTN_Y_ALT},
|
||||
{"STICK_LEFT_ALT", K_STICK_LEFT_ALT},
|
||||
{"STICK_RIGHT_ALT", K_STICK_RIGHT_ALT},
|
||||
{"SHOULDR_LEFT_ALT", K_SHOULDER_LEFT_ALT},
|
||||
{"SHOULDR_RIGHT_ALT", K_SHOULDER_RIGHT_ALT},
|
||||
{"TRIG_LEFT_ALT", K_TRIG_LEFT_ALT},
|
||||
{"TRIG_RIGHT_ALT", K_TRIG_RIGHT_ALT},
|
||||
|
||||
{"DP_UP_ALT", K_DPAD_UP_ALT},
|
||||
{"DP_DOWN_ALT", K_DPAD_DOWN_ALT},
|
||||
{"DP_LEFT_ALT", K_DPAD_LEFT_ALT},
|
||||
{"DP_RIGHT_ALT", K_DPAD_RIGHT_ALT},
|
||||
|
||||
{"PADDLE_1_ALT", K_PADDLE_1_ALT},
|
||||
{"PADDLE_2_ALT", K_PADDLE_2_ALT},
|
||||
{"PADDLE_3_ALT", K_PADDLE_3_ALT},
|
||||
{"PADDLE_4_ALT", K_PADDLE_4_ALT},
|
||||
{"BTN_MISC1_ALT", K_BTN_MISC1_ALT},
|
||||
{"TOUCHPAD_ALT", K_TOUCHPAD_ALT},
|
||||
{"BTN_BACK_ALT", K_BTN_BACK_ALT},
|
||||
{"BTN_GUIDE_ALT", K_BTN_GUIDE_ALT},
|
||||
{"BTN_START_ALT", K_BTN_START_ALT},
|
||||
|
||||
{"JOY_BACK", K_JOY_BACK},
|
||||
|
||||
{"SUPER", K_SUPER},
|
||||
{"COMPOSE", K_COMPOSE},
|
||||
{"MODE", K_MODE},
|
||||
|
@ -267,6 +211,147 @@ keyname_t keynames[] = {
|
|||
{NULL, 0}
|
||||
};
|
||||
|
||||
static char *gamepadbtns[] =
|
||||
{
|
||||
// It is imperative that this list of buttons follow EXACTLY the order they
|
||||
// appear in QKEYS enum in keyboard.h, which in turn is the same order as
|
||||
// they appear in SDL_GamepadButton / SDL_GameControllerButton enum.
|
||||
"BTN_SOUTH",
|
||||
"BTN_EAST",
|
||||
"BTN_WEST",
|
||||
"BTN_NORTH",
|
||||
"BTN_BACK",
|
||||
"BTN_GUIDE",
|
||||
"BTN_START",
|
||||
"STICK_LEFT",
|
||||
"STICK_RIGHT",
|
||||
"SHOULDR_LEFT",
|
||||
"SHOULDR_RIGHT",
|
||||
"DP_UP",
|
||||
"DP_DOWN",
|
||||
"DP_LEFT",
|
||||
"DP_RIGHT",
|
||||
"BTN_MISC1",
|
||||
"PADDL_RIGHT1",
|
||||
"PADDL_LEFT1",
|
||||
"PADDL_RIGHT2",
|
||||
"PADDL_LEFT2",
|
||||
"TOUCHPAD",
|
||||
"BTN_MISC2",
|
||||
"BTN_MISC3",
|
||||
"BTN_MISC4",
|
||||
"BTN_MISC5",
|
||||
"BTN_MISC6",
|
||||
"TRIG_LEFT",
|
||||
"TRIG_RIGHT",
|
||||
// Same with _ALT buttons ( button + 'alt modifier' pressed )
|
||||
"BTN_SOUTH_ALT",
|
||||
"BTN_EAST_ALT",
|
||||
"BTN_WEST_ALT",
|
||||
"BTN_NORTH_ALT",
|
||||
"BTN_BACK_ALT",
|
||||
"BTN_GUIDE_ALT",
|
||||
"BTN_START_ALT",
|
||||
"STICK_LEFT_ALT",
|
||||
"STICK_RIGHT_ALT",
|
||||
"SHOULDR_LEFT_ALT",
|
||||
"SHOULDR_RIGHT_ALT",
|
||||
"DP_UP_ALT",
|
||||
"DP_DOWN_ALT",
|
||||
"DP_LEFT_ALT",
|
||||
"DP_RIGHT_ALT",
|
||||
"BTN_MISC1_ALT",
|
||||
"PADDL_RIGHT1_ALT",
|
||||
"PADDL_LEFT1_ALT",
|
||||
"PADDL_RIGHT2_ALT",
|
||||
"PADDL_LEFT2_ALT",
|
||||
"TOUCHPAD_ALT",
|
||||
"BTN_MISC2_ALT",
|
||||
"BTN_MISC3_ALT",
|
||||
"BTN_MISC4_ALT",
|
||||
"BTN_MISC5_ALT",
|
||||
"BTN_MISC6_ALT",
|
||||
"TRIG_LEFT_ALT",
|
||||
"TRIG_RIGHT_ALT"
|
||||
};
|
||||
|
||||
#define NUM_GAMEPAD_BTNS (sizeof gamepadbtns / sizeof gamepadbtns[0])
|
||||
|
||||
static char *gpbtns_face[] =
|
||||
{
|
||||
// Xbox
|
||||
"A",
|
||||
"B",
|
||||
"X",
|
||||
"Y",
|
||||
"VIEW",
|
||||
"XBOX",
|
||||
"MENU",
|
||||
"LS",
|
||||
"RS",
|
||||
"LB",
|
||||
"RB",
|
||||
// Playstation
|
||||
"CROSS",
|
||||
"CIRCLE",
|
||||
"SQUARE",
|
||||
"TRIANGLE",
|
||||
"CREATE",
|
||||
"PS",
|
||||
"OPTIONS",
|
||||
"L3",
|
||||
"R3",
|
||||
"L1",
|
||||
"R1",
|
||||
// Nintendo Switch
|
||||
"B",
|
||||
"A",
|
||||
"Y",
|
||||
"X",
|
||||
"-",
|
||||
"HOME",
|
||||
"+",
|
||||
"L stick",
|
||||
"R stick",
|
||||
"L btn",
|
||||
"R btn",
|
||||
};
|
||||
|
||||
static char *gpbtns_paddles[] =
|
||||
{
|
||||
// Xbox
|
||||
"SHARE",
|
||||
"P1",
|
||||
"P3",
|
||||
"P2",
|
||||
"P4",
|
||||
// Playstation
|
||||
"MIC",
|
||||
"RB",
|
||||
"LB",
|
||||
"Right Fn",
|
||||
"Left Fn",
|
||||
// Switch
|
||||
"CAPTURE",
|
||||
"Right SR",
|
||||
"Left SL",
|
||||
"Right SL",
|
||||
"Left SR" // JoyCon btn positions suck
|
||||
};
|
||||
|
||||
static char *gpbtns_triggers[] =
|
||||
{
|
||||
// Xbox
|
||||
"LT",
|
||||
"RT",
|
||||
// Playstation
|
||||
"L2",
|
||||
"R2",
|
||||
// Switch
|
||||
"ZL",
|
||||
"ZR"
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
static void
|
||||
|
@ -739,6 +824,7 @@ static int
|
|||
Key_StringToKeynum(char *str)
|
||||
{
|
||||
keyname_t *kn;
|
||||
int i;
|
||||
|
||||
if (!str || !str[0])
|
||||
{
|
||||
|
@ -758,6 +844,14 @@ Key_StringToKeynum(char *str)
|
|||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < NUM_GAMEPAD_BTNS; i++)
|
||||
{
|
||||
if (!Q_stricmp(str, gamepadbtns[i]))
|
||||
{
|
||||
return K_JOY_FIRST_BTN + i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -785,6 +879,11 @@ Key_KeynumToString(int keynum)
|
|||
return tinystr;
|
||||
}
|
||||
|
||||
if (keynum >= K_JOY_FIRST_BTN) // gamepad button
|
||||
{
|
||||
return gamepadbtns[keynum - K_JOY_FIRST_BTN];
|
||||
}
|
||||
|
||||
for (kn = keynames; kn->name; kn++)
|
||||
{
|
||||
if (keynum == kn->keynum)
|
||||
|
@ -796,6 +895,49 @@ Key_KeynumToString(int keynum)
|
|||
return "<UNKNOWN KEYNUM>";
|
||||
}
|
||||
|
||||
/*
|
||||
* Same as Key_KeynumToString(), but for joystick/gamepad buttons.
|
||||
*/
|
||||
char *
|
||||
Key_KeynumToString_Joy(int key)
|
||||
{
|
||||
extern gamepad_labels_t joy_current_lbls;
|
||||
const int lbl_style = (int)joy_current_lbls - 1;
|
||||
|
||||
if (key < K_JOY_FIRST_BTN)
|
||||
{
|
||||
return Key_KeynumToString(key);
|
||||
}
|
||||
|
||||
// Don't print the _ALT buttons (buttons with the alt modifier pressed)
|
||||
if (key >= K_JOY_FIRST_BTN_ALT)
|
||||
{
|
||||
key -= K_JOY_FIRST_BTN_ALT - K_JOY_FIRST_BTN;
|
||||
}
|
||||
|
||||
if (lbl_style < 0) // was SDL
|
||||
{
|
||||
goto exit_sdl;
|
||||
}
|
||||
|
||||
// Alter this logic if new gamepad buttons are added in SDL
|
||||
if (key < K_DPAD_UP) // face & shoulder buttons
|
||||
{
|
||||
return gpbtns_face[lbl_style * (K_DPAD_UP - K_BTN_SOUTH) + key - K_BTN_SOUTH];
|
||||
}
|
||||
else if (key >= K_TRIG_LEFT) // triggers
|
||||
{
|
||||
return gpbtns_triggers[lbl_style * (K_JOY_FIRST_BTN_ALT - K_TRIG_LEFT) + key - K_TRIG_LEFT];
|
||||
}
|
||||
else if (key > K_DPAD_RIGHT && key < K_TOUCHPAD) // paddles & misc1
|
||||
{
|
||||
return gpbtns_paddles[lbl_style * (K_TOUCHPAD - K_BTN_MISC1) + key - K_BTN_MISC1];
|
||||
}
|
||||
|
||||
exit_sdl:
|
||||
return gamepadbtns[key - K_JOY_FIRST_BTN];
|
||||
}
|
||||
|
||||
void
|
||||
Key_SetBinding(int keynum, char *binding)
|
||||
{
|
||||
|
@ -885,7 +1027,7 @@ Key_Bind_f(void)
|
|||
}
|
||||
|
||||
/* don't allow binding escape or the special console keys */
|
||||
if(b == K_ESCAPE || b == '^' || b == '`' || b == '~' || b == K_JOY_BACK)
|
||||
if(b == K_ESCAPE || b == '^' || b == '`' || b == '~')
|
||||
{
|
||||
if(doneWithDefaultCfg)
|
||||
{
|
||||
|
@ -1203,12 +1345,12 @@ Key_Event(int key, qboolean down, qboolean special)
|
|||
unsigned int time = Sys_Milliseconds();
|
||||
|
||||
// evil hack for the joystick key altselector, which turns K_BTN_x into K_BTN_x_ALT
|
||||
if(joy_altselector_pressed && key >= K_JOY_FIRST_REGULAR && key <= K_JOY_LAST_REGULAR)
|
||||
if(joy_altselector_pressed && key >= K_JOY_FIRST_BTN && key < K_JOY_FIRST_BTN_ALT)
|
||||
{
|
||||
// make sure key is not the altselector itself (which we won't turn into *_ALT)
|
||||
if(keybindings[key] == NULL || strcmp(keybindings[key], "+joyaltselector") != 0)
|
||||
{
|
||||
int altkey = key + (K_JOY_FIRST_REGULAR_ALT - K_JOY_FIRST_REGULAR);
|
||||
int altkey = key + (K_JOY_FIRST_BTN_ALT - K_JOY_FIRST_BTN);
|
||||
// allow fallback to binding with non-alt key
|
||||
if(keybindings[altkey] != NULL || keybindings[key] == NULL)
|
||||
key = altkey;
|
||||
|
@ -1275,7 +1417,7 @@ Key_Event(int key, qboolean down, qboolean special)
|
|||
}
|
||||
|
||||
/* Key is unbound */
|
||||
if ((key >= K_MOUSE1 && key != K_JOY_BACK) && !keybindings[key] && (cls.key_dest != key_console) &&
|
||||
if ((key >= K_MOUSE1) && !keybindings[key] && (cls.key_dest != key_console) &&
|
||||
(cls.state == ca_active))
|
||||
{
|
||||
Com_Printf("%s (%d) is unbound, hit F4 to set.\n", Key_KeynumToString(key), key);
|
||||
|
@ -1296,47 +1438,43 @@ Key_Event(int key, qboolean down, qboolean special)
|
|||
- moves one menu level up
|
||||
- closes the menu
|
||||
- closes the help computer
|
||||
- closes the chat window
|
||||
Fully same logic for K_JOY_BACK */
|
||||
if (!cls.disable_screen)
|
||||
- closes the chat window */
|
||||
if (key == K_ESCAPE && !cls.disable_screen)
|
||||
{
|
||||
if (key == K_ESCAPE || key == K_JOY_BACK)
|
||||
if (!down)
|
||||
{
|
||||
if (!down)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Close the help computer */
|
||||
if (cl.frame.playerstate.stats[STAT_LAYOUTS] &&
|
||||
(cls.key_dest == key_game))
|
||||
{
|
||||
Cbuf_AddText("cmd putaway\n");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (cls.key_dest)
|
||||
{
|
||||
/* Close chat window */
|
||||
case key_message:
|
||||
Key_Message(key);
|
||||
break;
|
||||
|
||||
/* Close menu or one layer up */
|
||||
case key_menu:
|
||||
M_Keydown(key);
|
||||
break;
|
||||
|
||||
/* Pause game and / or leave console,
|
||||
break into the menu. */
|
||||
case key_game:
|
||||
case key_console:
|
||||
M_Menu_Main_f();
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Close the help computer */
|
||||
if (cl.frame.playerstate.stats[STAT_LAYOUTS] &&
|
||||
(cls.key_dest == key_game))
|
||||
{
|
||||
Cbuf_AddText("cmd putaway\n");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (cls.key_dest)
|
||||
{
|
||||
/* Close chat window */
|
||||
case key_message:
|
||||
Key_Message(key);
|
||||
break;
|
||||
|
||||
/* Close menu or one layer up */
|
||||
case key_menu:
|
||||
M_Keydown(key);
|
||||
break;
|
||||
|
||||
/* Pause game and / or leave console,
|
||||
break into the menu. */
|
||||
case key_game:
|
||||
case key_console:
|
||||
M_Menu_Main_f();
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* This is one of the most ugly constructs I've
|
||||
|
|
|
@ -486,8 +486,18 @@ void CL_BaseMove (usercmd_t *cmd);
|
|||
|
||||
void IN_CenterView (void);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LBL_SDL = 0,
|
||||
LBL_XBOX,
|
||||
LBL_PLAYSTATION,
|
||||
LBL_SWITCH,
|
||||
LBL_MAX_COUNT
|
||||
} gamepad_labels_t;
|
||||
|
||||
float CL_KeyState (kbutton_t *key);
|
||||
char *Key_KeynumToString (int keynum);
|
||||
char *Key_KeynumToString_Joy (int key);
|
||||
|
||||
void CL_WriteDemoMessage (void);
|
||||
void CL_Stop_f (void);
|
||||
|
|
|
@ -208,11 +208,11 @@ enum QKEYS {
|
|||
// From here on, only gamepad controls must be allowed.
|
||||
// Otherwise, separate bindings (keyboard / controller) menu options will not work.
|
||||
|
||||
K_BTN_A,
|
||||
K_JOY_FIRST_REGULAR = K_BTN_A,
|
||||
K_BTN_B,
|
||||
K_BTN_X,
|
||||
K_BTN_Y,
|
||||
K_BTN_SOUTH,
|
||||
K_JOY_FIRST_BTN = K_BTN_SOUTH,
|
||||
K_BTN_EAST,
|
||||
K_BTN_WEST,
|
||||
K_BTN_NORTH,
|
||||
K_BTN_BACK,
|
||||
K_BTN_GUIDE,
|
||||
K_BTN_START,
|
||||
|
@ -225,26 +225,28 @@ enum QKEYS {
|
|||
K_DPAD_LEFT,
|
||||
K_DPAD_RIGHT,
|
||||
K_BTN_MISC1,
|
||||
K_PADDLE_1,
|
||||
K_PADDLE_2,
|
||||
K_PADDLE_3,
|
||||
K_PADDLE_4,
|
||||
K_TOUCHPAD, // SDL_CONTROLLER_BUTTON_MAX - 1
|
||||
K_PADDLE_RIGHT_1,
|
||||
K_PADDLE_LEFT_1,
|
||||
K_PADDLE_RIGHT_2,
|
||||
K_PADDLE_LEFT_2,
|
||||
K_TOUCHPAD, // SDL_CONTROLLER_BUTTON_MAX - 1, SDL2 limit
|
||||
K_BTN_MISC2,
|
||||
K_BTN_MISC3,
|
||||
K_BTN_MISC4,
|
||||
K_BTN_MISC5,
|
||||
K_BTN_MISC6, // SDL_GAMEPAD_BUTTON_COUNT - 1, current SDL3 count
|
||||
K_TRIG_LEFT, // buttons for triggers (axes)
|
||||
K_TRIG_RIGHT,
|
||||
|
||||
// add other joystick/controller keys before this one
|
||||
// and adjust it accordingly, also remember to add corresponding _ALT key below!
|
||||
K_JOY_LAST_REGULAR = K_TRIG_RIGHT,
|
||||
// Add other gamepad keys before this one, adjust from SDL 2/3 definitions, and
|
||||
// add the corresponding _ALT key below! Respect the order, must be the same as above.
|
||||
// Also, verify if cl_keyboard.c needs a refactor on its arrays.
|
||||
|
||||
/* Can't be mapped to any action (=> not regular) */
|
||||
K_JOY_BACK,
|
||||
|
||||
K_BTN_A_ALT,
|
||||
K_JOY_FIRST_REGULAR_ALT = K_BTN_A_ALT,
|
||||
K_BTN_B_ALT,
|
||||
K_BTN_X_ALT,
|
||||
K_BTN_Y_ALT,
|
||||
K_BTN_SOUTH_ALT,
|
||||
K_JOY_FIRST_BTN_ALT = K_BTN_SOUTH_ALT,
|
||||
K_BTN_EAST_ALT,
|
||||
K_BTN_WEST_ALT,
|
||||
K_BTN_NORTH_ALT,
|
||||
K_BTN_BACK_ALT,
|
||||
K_BTN_GUIDE_ALT,
|
||||
K_BTN_START_ALT,
|
||||
|
@ -257,11 +259,16 @@ enum QKEYS {
|
|||
K_DPAD_LEFT_ALT,
|
||||
K_DPAD_RIGHT_ALT,
|
||||
K_BTN_MISC1_ALT,
|
||||
K_PADDLE_1_ALT,
|
||||
K_PADDLE_2_ALT,
|
||||
K_PADDLE_3_ALT,
|
||||
K_PADDLE_4_ALT,
|
||||
K_PADDLE_RIGHT_1_ALT,
|
||||
K_PADDLE_LEFT_1_ALT,
|
||||
K_PADDLE_RIGHT_2_ALT,
|
||||
K_PADDLE_LEFT_2_ALT,
|
||||
K_TOUCHPAD_ALT,
|
||||
K_BTN_MISC2_ALT,
|
||||
K_BTN_MISC3_ALT,
|
||||
K_BTN_MISC4_ALT,
|
||||
K_BTN_MISC5_ALT,
|
||||
K_BTN_MISC6_ALT,
|
||||
K_TRIG_LEFT_ALT,
|
||||
K_TRIG_RIGHT_ALT,
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ typedef enum
|
|||
// IN_Update() called at the beginning of a frame to the
|
||||
// actual movement functions called at a later time.
|
||||
static float mouse_x, mouse_y;
|
||||
static unsigned char sdl_back_button = SDL_CONTROLLER_BUTTON_START;
|
||||
static unsigned char joy_escbutton = SDL_CONTROLLER_BUTTON_START;
|
||||
static int joystick_left_x, joystick_left_y, joystick_right_x, joystick_right_y;
|
||||
static float gyro_yaw, gyro_pitch;
|
||||
static qboolean mlooking;
|
||||
|
@ -91,6 +91,12 @@ int sys_frame_time;
|
|||
// is pressed
|
||||
qboolean joy_altselector_pressed = false;
|
||||
|
||||
// Gamepad labels' style (Xbox, Playstation, etc.) in use, normally set after detection
|
||||
gamepad_labels_t joy_current_lbls = LBL_SDL;
|
||||
|
||||
// Using japanese style for confirm & cancel buttons on gamepad
|
||||
qboolean japanese_confirm = false;
|
||||
|
||||
// Console Variables
|
||||
cvar_t *freelook;
|
||||
cvar_t *lookstrafe;
|
||||
|
@ -134,6 +140,12 @@ static int last_haptic_effect_size = HAPTIC_EFFECT_LIST_SIZE;
|
|||
static int last_haptic_effect_pos = 0;
|
||||
static haptic_effects_cache_t last_haptic_effect[HAPTIC_EFFECT_LIST_SIZE];
|
||||
|
||||
// Gamepad labels' style (Xbox, Playstation, etc.) requested by user
|
||||
static cvar_t *joy_labels;
|
||||
|
||||
// Gamepad style for confirm and cancel buttons (traditional or japanese)
|
||||
static cvar_t *joy_confirm;
|
||||
|
||||
// Joystick sensitivity
|
||||
static cvar_t *joy_yawsensitivity;
|
||||
static cvar_t *joy_pitchsensitivity;
|
||||
|
@ -506,6 +518,110 @@ IN_TranslateScancodeToQ2Key(SDL_Scancode sc)
|
|||
static void IN_Controller_Init(qboolean notify_user);
|
||||
static void IN_Controller_Shutdown(qboolean notify_user);
|
||||
|
||||
/*
|
||||
* Sets the gamepad buttons' style of labels (SDL, Xbox, PS, Switch).
|
||||
* They are only visible in the gamepad binding options.
|
||||
* Traditional binding uses SDL style, no matter the gamepad.
|
||||
*/
|
||||
static void
|
||||
IN_GamepadLabels_Changed(void)
|
||||
{
|
||||
const int requested = (int)joy_labels->value;
|
||||
joy_labels->modified = false;
|
||||
joy_current_lbls = LBL_SDL;
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 12)
|
||||
if (requested < 0 && controller) // try to autodetect...
|
||||
{
|
||||
switch (SDL_GameControllerGetType(controller))
|
||||
{
|
||||
case SDL_CONTROLLER_TYPE_XBOX360:
|
||||
case SDL_CONTROLLER_TYPE_XBOXONE:
|
||||
joy_current_lbls = LBL_XBOX;
|
||||
return;
|
||||
|
||||
case SDL_CONTROLLER_TYPE_PS3:
|
||||
case SDL_CONTROLLER_TYPE_PS4:
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 14)
|
||||
case SDL_CONTROLLER_TYPE_PS5:
|
||||
#endif // SDL_VERSION_ATLEAST(2, 0, 14)
|
||||
joy_current_lbls = LBL_PLAYSTATION;
|
||||
return;
|
||||
|
||||
case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO:
|
||||
#if SDL_VERSION_ATLEAST(2, 24, 0)
|
||||
case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_PAIR:
|
||||
#endif // SDL_VERSION_ATLEAST(2, 24, 0)
|
||||
joy_current_lbls = LBL_SWITCH;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif // SDL_VERSION_ATLEAST(2, 0, 12)
|
||||
if (requested >= LBL_SDL && requested < LBL_MAX_COUNT)
|
||||
{
|
||||
joy_current_lbls = (gamepad_labels_t)requested;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets which gamepad button works as "confirm", and which
|
||||
* works as "cancel", in menus.
|
||||
*/
|
||||
static void
|
||||
IN_GamepadConfirm_Changed(void)
|
||||
{
|
||||
const int requested = (int)joy_confirm->value;
|
||||
japanese_confirm = false;
|
||||
joy_confirm->modified = false;
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 12)
|
||||
if (requested < 0 && controller) // try to autodetect...
|
||||
{
|
||||
switch (SDL_GameControllerGetType(controller))
|
||||
{
|
||||
case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO:
|
||||
#if SDL_VERSION_ATLEAST(2, 24, 0)
|
||||
case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_PAIR:
|
||||
#endif // SDL_VERSION_ATLEAST(2, 24, 0)
|
||||
japanese_confirm = true;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif // SDL_VERSION_ATLEAST(2, 0, 12)
|
||||
if (requested == 1)
|
||||
{
|
||||
japanese_confirm = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
IN_GyroMode_Changed(void)
|
||||
{
|
||||
if (gyro_mode->value < 2)
|
||||
{
|
||||
gyro_active = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
gyro_active = true;
|
||||
}
|
||||
gyro_mode->modified = false;
|
||||
}
|
||||
|
||||
static void
|
||||
IN_VirtualKeyEvent(int keynum, qboolean *state_store, qboolean new_state)
|
||||
{
|
||||
if (new_state != *state_store)
|
||||
{
|
||||
*state_store = new_state;
|
||||
Key_Event(keynum, *state_store, true);
|
||||
}
|
||||
}
|
||||
|
||||
qboolean IN_NumpadIsOn()
|
||||
{
|
||||
SDL_Keymod mod = SDL_GetModState();
|
||||
|
@ -534,6 +650,7 @@ IN_Update(void)
|
|||
|
||||
static qboolean left_trigger = false;
|
||||
static qboolean right_trigger = false;
|
||||
static qboolean left_stick[4] = {false, false, false, false}; // left, right, up, down virtual keys
|
||||
|
||||
static int consoleKeyCode = 0;
|
||||
|
||||
|
@ -734,8 +851,8 @@ IN_Update(void)
|
|||
qboolean down = (event.type == SDL_CONTROLLERBUTTONDOWN);
|
||||
unsigned char btn = event.cbutton.button;
|
||||
|
||||
// Handle Back Button, to override its original key
|
||||
Key_Event( (btn == sdl_back_button)? K_JOY_BACK : K_BTN_A + btn,
|
||||
// Handle Esc button first, to override its original key
|
||||
Key_Event( (btn == joy_escbutton)? K_ESCAPE : K_JOY_FIRST_BTN + btn,
|
||||
down, true );
|
||||
break;
|
||||
}
|
||||
|
@ -747,26 +864,12 @@ IN_Update(void)
|
|||
switch (event.caxis.axis)
|
||||
{
|
||||
case SDL_CONTROLLER_AXIS_TRIGGERLEFT:
|
||||
{
|
||||
qboolean new_left_trigger = axis_value > 8192;
|
||||
if (new_left_trigger != left_trigger)
|
||||
{
|
||||
left_trigger = new_left_trigger;
|
||||
Key_Event(K_TRIG_LEFT, left_trigger, true);
|
||||
}
|
||||
IN_VirtualKeyEvent(K_TRIG_LEFT, &left_trigger, axis_value > 8192);
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_CONTROLLER_AXIS_TRIGGERRIGHT:
|
||||
{
|
||||
qboolean new_right_trigger = axis_value > 8192;
|
||||
if (new_right_trigger != right_trigger)
|
||||
{
|
||||
right_trigger = new_right_trigger;
|
||||
Key_Event(K_TRIG_RIGHT, right_trigger, true);
|
||||
}
|
||||
IN_VirtualKeyEvent(K_TRIG_RIGHT, &right_trigger, axis_value > 8192);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!cl_paused->value && cls.key_dest == key_game)
|
||||
|
@ -786,6 +889,24 @@ IN_Update(void)
|
|||
joystick_right_y = axis_value;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Virtual keys to navigate menus with left stick
|
||||
if (cls.key_dest == key_menu)
|
||||
{
|
||||
switch (event.caxis.axis)
|
||||
{
|
||||
case SDL_CONTROLLER_AXIS_LEFTX:
|
||||
IN_VirtualKeyEvent(K_LEFTARROW, &left_stick[0], axis_value < -16896);
|
||||
IN_VirtualKeyEvent(K_RIGHTARROW, &left_stick[1], axis_value > 16896);
|
||||
break;
|
||||
|
||||
case SDL_CONTROLLER_AXIS_LEFTY:
|
||||
IN_VirtualKeyEvent(K_UPARROW, &left_stick[2], axis_value < -16896);
|
||||
IN_VirtualKeyEvent(K_DOWNARROW, &left_stick[3], axis_value > 16896);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -834,8 +955,7 @@ IN_Update(void)
|
|||
|
||||
#endif // !NO_SDL_GYRO
|
||||
|
||||
if (gyro_active && gyro_mode->value &&
|
||||
!cl_paused->value && cls.key_dest == key_game)
|
||||
if (gyro_active && !cl_paused->value && cls.key_dest == key_game)
|
||||
{
|
||||
#ifndef NO_SDL_GYRO
|
||||
if (!gyro_turning_axis->value)
|
||||
|
@ -986,6 +1106,19 @@ IN_Update(void)
|
|||
countdown_reason = REASON_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
if (joy_labels->modified)
|
||||
{
|
||||
IN_GamepadLabels_Changed();
|
||||
}
|
||||
if (joy_confirm->modified)
|
||||
{
|
||||
IN_GamepadConfirm_Changed();
|
||||
}
|
||||
if (gyro_mode->modified)
|
||||
{
|
||||
IN_GyroMode_Changed();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2070,19 +2203,19 @@ IN_Controller_Init(qboolean notify_user)
|
|||
SDL_Joystick *joystick = NULL;
|
||||
SDL_bool is_controller = SDL_FALSE;
|
||||
|
||||
cvar = Cvar_Get("in_sdlbackbutton", "1", CVAR_ARCHIVE);
|
||||
cvar = Cvar_Get("joy_escbutton", "0", CVAR_ARCHIVE);
|
||||
if (cvar)
|
||||
{
|
||||
switch ((int)cvar->value)
|
||||
{
|
||||
case 0:
|
||||
sdl_back_button = SDL_CONTROLLER_BUTTON_BACK;
|
||||
case 1:
|
||||
joy_escbutton = SDL_CONTROLLER_BUTTON_BACK;
|
||||
break;
|
||||
case 2:
|
||||
sdl_back_button = SDL_CONTROLLER_BUTTON_GUIDE;
|
||||
joy_escbutton = SDL_CONTROLLER_BUTTON_GUIDE;
|
||||
break;
|
||||
default:
|
||||
sdl_back_button = SDL_CONTROLLER_BUTTON_START;
|
||||
joy_escbutton = SDL_CONTROLLER_BUTTON_START;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2106,6 +2239,9 @@ IN_Controller_Init(qboolean notify_user)
|
|||
#ifdef SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE
|
||||
SDL_SetHint( SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE, "1" );
|
||||
#endif
|
||||
#ifdef SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS // use button positions instead of labels, like SDL3
|
||||
SDL_SetHint( SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS, "0" );
|
||||
#endif
|
||||
|
||||
if (SDL_Init(SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC) == -1)
|
||||
{
|
||||
|
@ -2291,6 +2427,10 @@ IN_Controller_Init(qboolean notify_user)
|
|||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
IN_GamepadLabels_Changed();
|
||||
IN_GamepadConfirm_Changed();
|
||||
IN_GyroMode_Changed();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2326,6 +2466,8 @@ IN_Init(void)
|
|||
joy_forwardsensitivity = Cvar_Get("joy_forwardsensitivity", "1.0", CVAR_ARCHIVE);
|
||||
joy_sidesensitivity = Cvar_Get("joy_sidesensitivity", "1.0", CVAR_ARCHIVE);
|
||||
|
||||
joy_labels = Cvar_Get("joy_labels", "-1", CVAR_ARCHIVE);
|
||||
joy_confirm = Cvar_Get("joy_confirm", "-1", CVAR_ARCHIVE);
|
||||
joy_layout = Cvar_Get("joy_layout", "0", CVAR_ARCHIVE);
|
||||
joy_left_expo = Cvar_Get("joy_left_expo", "2.0", CVAR_ARCHIVE);
|
||||
joy_left_snapaxis = Cvar_Get("joy_left_snapaxis", "0.15", CVAR_ARCHIVE);
|
||||
|
@ -2340,16 +2482,11 @@ IN_Init(void)
|
|||
gyro_calibration_y = Cvar_Get("gyro_calibration_y", "0.0", CVAR_ARCHIVE);
|
||||
gyro_calibration_z = Cvar_Get("gyro_calibration_z", "0.0", CVAR_ARCHIVE);
|
||||
|
||||
gyro_yawsensitivity = Cvar_Get("gyro_yawsensitivity", "1.0", CVAR_ARCHIVE);
|
||||
gyro_pitchsensitivity = Cvar_Get("gyro_pitchsensitivity", "1.0", CVAR_ARCHIVE);
|
||||
gyro_yawsensitivity = Cvar_Get("gyro_yawsensitivity", "2.5", CVAR_ARCHIVE);
|
||||
gyro_pitchsensitivity = Cvar_Get("gyro_pitchsensitivity", "2.5", CVAR_ARCHIVE);
|
||||
gyro_tightening = Cvar_Get("gyro_tightening", "3.5", CVAR_ARCHIVE);
|
||||
gyro_turning_axis = Cvar_Get("gyro_turning_axis", "0", CVAR_ARCHIVE);
|
||||
|
||||
gyro_mode = Cvar_Get("gyro_mode", "2", CVAR_ARCHIVE);
|
||||
if ((int)gyro_mode->value == 2)
|
||||
{
|
||||
gyro_active = true;
|
||||
}
|
||||
|
||||
windowed_pauseonfocuslost = Cvar_Get("vid_pauseonfocuslost", "0", CVAR_USERINFO | CVAR_ARCHIVE);
|
||||
windowed_mouse = Cvar_Get("windowed_mouse", "1", CVAR_USERINFO | CVAR_ARCHIVE);
|
||||
|
|
|
@ -81,7 +81,7 @@ typedef enum
|
|||
// IN_Update() called at the beginning of a frame to the
|
||||
// actual movement functions called at a later time.
|
||||
static float mouse_x, mouse_y;
|
||||
static unsigned char sdl_back_button = SDL_GAMEPAD_BUTTON_START;
|
||||
static unsigned char joy_escbutton = SDL_GAMEPAD_BUTTON_START;
|
||||
static int joystick_left_x, joystick_left_y, joystick_right_x, joystick_right_y;
|
||||
static float gyro_yaw, gyro_pitch;
|
||||
static qboolean mlooking;
|
||||
|
@ -94,6 +94,12 @@ int sys_frame_time;
|
|||
// is pressed
|
||||
qboolean joy_altselector_pressed = false;
|
||||
|
||||
// Gamepad labels' style (Xbox, Playstation, etc.) in use, normally set after detection
|
||||
gamepad_labels_t joy_current_lbls = LBL_SDL;
|
||||
|
||||
// Using japanese style for confirm & cancel buttons on gamepad
|
||||
qboolean japanese_confirm = false;
|
||||
|
||||
// Console Variables
|
||||
cvar_t *freelook;
|
||||
cvar_t *lookstrafe;
|
||||
|
@ -137,6 +143,12 @@ static int last_haptic_effect_size = HAPTIC_EFFECT_LIST_SIZE;
|
|||
static int last_haptic_effect_pos = 0;
|
||||
static haptic_effects_cache_t last_haptic_effect[HAPTIC_EFFECT_LIST_SIZE];
|
||||
|
||||
// Gamepad labels' style (Xbox, Playstation, etc.) requested by user
|
||||
static cvar_t *joy_labels;
|
||||
|
||||
// Gamepad style for confirm and cancel buttons (traditional or japanese)
|
||||
static cvar_t *joy_confirm;
|
||||
|
||||
// Joystick sensitivity
|
||||
static cvar_t *joy_yawsensitivity;
|
||||
static cvar_t *joy_pitchsensitivity;
|
||||
|
@ -504,6 +516,98 @@ IN_TranslateScancodeToQ2Key(SDL_Scancode sc)
|
|||
static void IN_Controller_Init(qboolean notify_user);
|
||||
static void IN_Controller_Shutdown(qboolean notify_user);
|
||||
|
||||
/*
|
||||
* Sets the gamepad buttons' style of labels (SDL, Xbox, PS, Switch).
|
||||
* They are only visible in the gamepad binding options.
|
||||
* Traditional binding uses SDL style, no matter the gamepad.
|
||||
*/
|
||||
static void
|
||||
IN_GamepadLabels_Changed(void)
|
||||
{
|
||||
const int requested = (int)joy_labels->value;
|
||||
joy_labels->modified = false;
|
||||
joy_current_lbls = LBL_SDL;
|
||||
|
||||
if (requested < 0 && controller) // try to autodetect...
|
||||
{
|
||||
switch (SDL_GetGamepadType(controller))
|
||||
{
|
||||
case SDL_GAMEPAD_TYPE_XBOX360:
|
||||
case SDL_GAMEPAD_TYPE_XBOXONE:
|
||||
joy_current_lbls = LBL_XBOX;
|
||||
return;
|
||||
|
||||
case SDL_GAMEPAD_TYPE_PS3:
|
||||
case SDL_GAMEPAD_TYPE_PS4:
|
||||
case SDL_GAMEPAD_TYPE_PS5:
|
||||
joy_current_lbls = LBL_PLAYSTATION;
|
||||
return;
|
||||
|
||||
case SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_PRO:
|
||||
case SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_PAIR:
|
||||
joy_current_lbls = LBL_SWITCH;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (requested >= LBL_SDL && requested < LBL_MAX_COUNT)
|
||||
{
|
||||
joy_current_lbls = (gamepad_labels_t)requested;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets which gamepad button works as "confirm", and which
|
||||
* works as "cancel", in menus.
|
||||
*/
|
||||
static void
|
||||
IN_GamepadConfirm_Changed(void)
|
||||
{
|
||||
const int requested = (int)joy_confirm->value;
|
||||
japanese_confirm = false;
|
||||
joy_confirm->modified = false;
|
||||
|
||||
if (requested < 0 && controller) // try to autodetect...
|
||||
{
|
||||
switch (SDL_GetGamepadType(controller))
|
||||
{
|
||||
case SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_PRO:
|
||||
case SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_PAIR:
|
||||
japanese_confirm = true;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (requested == 1)
|
||||
{
|
||||
japanese_confirm = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
IN_GyroMode_Changed(void)
|
||||
{
|
||||
if (gyro_mode->value < 2)
|
||||
{
|
||||
gyro_active = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
gyro_active = true;
|
||||
}
|
||||
gyro_mode->modified = false;
|
||||
}
|
||||
|
||||
static void
|
||||
IN_VirtualKeyEvent(int keynum, qboolean *state_store, qboolean new_state)
|
||||
{
|
||||
if (new_state != *state_store)
|
||||
{
|
||||
*state_store = new_state;
|
||||
Key_Event(keynum, *state_store, true);
|
||||
}
|
||||
}
|
||||
|
||||
qboolean IN_NumpadIsOn()
|
||||
{
|
||||
SDL_Keymod mod = SDL_GetModState();
|
||||
|
@ -532,6 +636,7 @@ IN_Update(void)
|
|||
|
||||
static qboolean left_trigger = false;
|
||||
static qboolean right_trigger = false;
|
||||
static qboolean left_stick[4] = {false, false, false, false}; // left, right, up, down virtual keys
|
||||
|
||||
static int consoleKeyCode = 0;
|
||||
|
||||
|
@ -733,8 +838,8 @@ IN_Update(void)
|
|||
qboolean down = (event.type == SDL_EVENT_GAMEPAD_BUTTON_DOWN);
|
||||
unsigned char btn = event.gbutton.button;
|
||||
|
||||
// Handle Back Button, to override its original key
|
||||
Key_Event( (btn == sdl_back_button)? K_JOY_BACK : K_BTN_A + btn,
|
||||
// Handle Esc button first, to override its original key
|
||||
Key_Event( (btn == joy_escbutton)? K_ESCAPE : K_JOY_FIRST_BTN + btn,
|
||||
down, true );
|
||||
break;
|
||||
}
|
||||
|
@ -746,26 +851,12 @@ IN_Update(void)
|
|||
switch (event.gaxis.axis)
|
||||
{
|
||||
case SDL_GAMEPAD_AXIS_LEFT_TRIGGER :
|
||||
{
|
||||
qboolean new_left_trigger = axis_value > 8192;
|
||||
if (new_left_trigger != left_trigger)
|
||||
{
|
||||
left_trigger = new_left_trigger;
|
||||
Key_Event(K_TRIG_LEFT, left_trigger, true);
|
||||
}
|
||||
IN_VirtualKeyEvent(K_TRIG_LEFT, &left_trigger, axis_value > 8192);
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_GAMEPAD_AXIS_RIGHT_TRIGGER :
|
||||
{
|
||||
qboolean new_right_trigger = axis_value > 8192;
|
||||
if (new_right_trigger != right_trigger)
|
||||
{
|
||||
right_trigger = new_right_trigger;
|
||||
Key_Event(K_TRIG_RIGHT, right_trigger, true);
|
||||
}
|
||||
IN_VirtualKeyEvent(K_TRIG_RIGHT, &right_trigger, axis_value > 8192);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!cl_paused->value && cls.key_dest == key_game)
|
||||
|
@ -785,6 +876,24 @@ IN_Update(void)
|
|||
joystick_right_y = axis_value;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Virtual keys to navigate menus with left stick
|
||||
if (cls.key_dest == key_menu)
|
||||
{
|
||||
switch (event.gaxis.axis)
|
||||
{
|
||||
case SDL_GAMEPAD_AXIS_LEFTX :
|
||||
IN_VirtualKeyEvent(K_LEFTARROW, &left_stick[0], axis_value < -16896);
|
||||
IN_VirtualKeyEvent(K_RIGHTARROW, &left_stick[1], axis_value > 16896);
|
||||
break;
|
||||
|
||||
case SDL_GAMEPAD_AXIS_LEFTY :
|
||||
IN_VirtualKeyEvent(K_UPARROW, &left_stick[2], axis_value < -16896);
|
||||
IN_VirtualKeyEvent(K_DOWNARROW, &left_stick[3], axis_value > 16896);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -833,8 +942,7 @@ IN_Update(void)
|
|||
|
||||
#endif // !NO_SDL_GYRO
|
||||
|
||||
if (gyro_active && gyro_mode->value &&
|
||||
!cl_paused->value && cls.key_dest == key_game)
|
||||
if (gyro_active && !cl_paused->value && cls.key_dest == key_game)
|
||||
{
|
||||
#ifndef NO_SDL_GYRO
|
||||
if (!gyro_turning_axis->value)
|
||||
|
@ -983,6 +1091,20 @@ IN_Update(void)
|
|||
countdown_reason = REASON_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
// Gamepad labels' type and "confirm & cancel style" change handling
|
||||
if (joy_labels->modified)
|
||||
{
|
||||
IN_GamepadLabels_Changed();
|
||||
}
|
||||
if (joy_confirm->modified)
|
||||
{
|
||||
IN_GamepadConfirm_Changed();
|
||||
}
|
||||
if (gyro_mode->modified)
|
||||
{
|
||||
IN_GyroMode_Changed();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2068,19 +2190,19 @@ IN_Controller_Init(qboolean notify_user)
|
|||
SDL_Joystick *joystick = NULL;
|
||||
bool is_controller = false;
|
||||
|
||||
cvar = Cvar_Get("in_sdlbackbutton", "1", CVAR_ARCHIVE);
|
||||
cvar = Cvar_Get("joy_escbutton", "0", CVAR_ARCHIVE);
|
||||
if (cvar)
|
||||
{
|
||||
switch ((int)cvar->value)
|
||||
{
|
||||
case 0:
|
||||
sdl_back_button = SDL_GAMEPAD_BUTTON_BACK;
|
||||
case 1:
|
||||
joy_escbutton = SDL_GAMEPAD_BUTTON_BACK;
|
||||
break;
|
||||
case 2:
|
||||
sdl_back_button = SDL_GAMEPAD_BUTTON_GUIDE;
|
||||
joy_escbutton = SDL_GAMEPAD_BUTTON_GUIDE;
|
||||
break;
|
||||
default:
|
||||
sdl_back_button = SDL_GAMEPAD_BUTTON_START;
|
||||
joy_escbutton = SDL_GAMEPAD_BUTTON_START;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2280,6 +2402,9 @@ IN_Controller_Init(qboolean notify_user)
|
|||
}
|
||||
|
||||
SDL_free((void *)joysticks);
|
||||
IN_GamepadLabels_Changed();
|
||||
IN_GamepadConfirm_Changed();
|
||||
IN_GyroMode_Changed();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2315,6 +2440,8 @@ IN_Init(void)
|
|||
joy_forwardsensitivity = Cvar_Get("joy_forwardsensitivity", "1.0", CVAR_ARCHIVE);
|
||||
joy_sidesensitivity = Cvar_Get("joy_sidesensitivity", "1.0", CVAR_ARCHIVE);
|
||||
|
||||
joy_labels = Cvar_Get("joy_labels", "-1", CVAR_ARCHIVE);
|
||||
joy_confirm = Cvar_Get("joy_confirm", "-1", CVAR_ARCHIVE);
|
||||
joy_layout = Cvar_Get("joy_layout", "0", CVAR_ARCHIVE);
|
||||
joy_left_expo = Cvar_Get("joy_left_expo", "2.0", CVAR_ARCHIVE);
|
||||
joy_left_snapaxis = Cvar_Get("joy_left_snapaxis", "0.15", CVAR_ARCHIVE);
|
||||
|
@ -2329,16 +2456,11 @@ IN_Init(void)
|
|||
gyro_calibration_y = Cvar_Get("gyro_calibration_y", "0.0", CVAR_ARCHIVE);
|
||||
gyro_calibration_z = Cvar_Get("gyro_calibration_z", "0.0", CVAR_ARCHIVE);
|
||||
|
||||
gyro_yawsensitivity = Cvar_Get("gyro_yawsensitivity", "1.0", CVAR_ARCHIVE);
|
||||
gyro_pitchsensitivity = Cvar_Get("gyro_pitchsensitivity", "1.0", CVAR_ARCHIVE);
|
||||
gyro_yawsensitivity = Cvar_Get("gyro_yawsensitivity", "2.5", CVAR_ARCHIVE);
|
||||
gyro_pitchsensitivity = Cvar_Get("gyro_pitchsensitivity", "2.5", CVAR_ARCHIVE);
|
||||
gyro_tightening = Cvar_Get("gyro_tightening", "3.5", CVAR_ARCHIVE);
|
||||
gyro_turning_axis = Cvar_Get("gyro_turning_axis", "0", CVAR_ARCHIVE);
|
||||
|
||||
gyro_mode = Cvar_Get("gyro_mode", "2", CVAR_ARCHIVE);
|
||||
if ((int)gyro_mode->value == 2)
|
||||
{
|
||||
gyro_active = true;
|
||||
}
|
||||
|
||||
windowed_pauseonfocuslost = Cvar_Get("vid_pauseonfocuslost", "0", CVAR_USERINFO | CVAR_ARCHIVE);
|
||||
windowed_mouse = Cvar_Get("windowed_mouse", "1", CVAR_USERINFO | CVAR_ARCHIVE);
|
||||
|
|
|
@ -240,6 +240,8 @@ M_PushMenu(menuframework_s* menu)
|
|||
cls.key_dest = key_menu;
|
||||
}
|
||||
|
||||
extern qboolean japanese_confirm;
|
||||
|
||||
int
|
||||
Key_GetMenuKey(int key)
|
||||
{
|
||||
|
@ -280,24 +282,27 @@ Key_GetMenuKey(int key)
|
|||
|
||||
case K_KP_ENTER:
|
||||
case K_ENTER:
|
||||
case K_BTN_A:
|
||||
return K_ENTER;
|
||||
|
||||
case K_ESCAPE:
|
||||
case K_JOY_BACK:
|
||||
case K_BTN_B:
|
||||
return K_ESCAPE;
|
||||
|
||||
case K_BACKSPACE:
|
||||
case K_DEL:
|
||||
case K_KP_DEL:
|
||||
if (IN_NumpadIsOn() == true) { break; }
|
||||
case K_BTN_Y:
|
||||
case K_BACKSPACE:
|
||||
case K_DEL:
|
||||
case K_BTN_NORTH:
|
||||
return K_BACKSPACE;
|
||||
|
||||
case K_KP_INS:
|
||||
if (IN_NumpadIsOn() == true) { break; }
|
||||
case K_INS:
|
||||
return K_INS;
|
||||
|
||||
case K_BTN_SOUTH:
|
||||
if (japanese_confirm) return K_ESCAPE;
|
||||
else return K_ENTER;
|
||||
|
||||
case K_BTN_EAST:
|
||||
if (japanese_confirm) return K_ENTER;
|
||||
else return K_ESCAPE;
|
||||
}
|
||||
|
||||
return key;
|
||||
|
@ -940,14 +945,14 @@ M_UnbindCommand(char *command, int scope)
|
|||
switch (scope)
|
||||
{
|
||||
case KEYS_KEYBOARD_MOUSE:
|
||||
end = K_JOY_FIRST_REGULAR;
|
||||
end = K_JOY_FIRST_BTN;
|
||||
break;
|
||||
case KEYS_CONTROLLER:
|
||||
begin = K_JOY_FIRST_REGULAR;
|
||||
end = K_JOY_LAST_REGULAR + 1;
|
||||
begin = K_JOY_FIRST_BTN;
|
||||
end = K_JOY_FIRST_BTN_ALT;
|
||||
break;
|
||||
case KEYS_CONTROLLER_ALT:
|
||||
begin = K_JOY_FIRST_REGULAR_ALT;
|
||||
begin = K_JOY_FIRST_BTN_ALT;
|
||||
}
|
||||
|
||||
for (j = begin; j < end; j++)
|
||||
|
@ -976,14 +981,14 @@ M_FindKeysForCommand(char *command, int *twokeys, int scope)
|
|||
switch (scope)
|
||||
{
|
||||
case KEYS_KEYBOARD_MOUSE:
|
||||
end = K_JOY_FIRST_REGULAR;
|
||||
end = K_JOY_FIRST_BTN;
|
||||
break;
|
||||
case KEYS_CONTROLLER:
|
||||
begin = K_JOY_FIRST_REGULAR;
|
||||
end = K_JOY_LAST_REGULAR + 1;
|
||||
begin = K_JOY_FIRST_BTN;
|
||||
end = K_JOY_FIRST_BTN_ALT;
|
||||
break;
|
||||
case KEYS_CONTROLLER_ALT:
|
||||
begin = K_JOY_FIRST_REGULAR_ALT;
|
||||
begin = K_JOY_FIRST_BTN_ALT;
|
||||
}
|
||||
|
||||
twokeys[0] = twokeys[1] = -1;
|
||||
|
@ -1124,7 +1129,7 @@ Keys_MenuKey(int key)
|
|||
if (menukeyitem_bind)
|
||||
{
|
||||
// Any key/button except from the game controller and escape keys
|
||||
if ((key != K_ESCAPE) && (key != '`') && (key < K_JOY_FIRST_REGULAR))
|
||||
if ((key != K_ESCAPE) && (key != '`') && (key < K_JOY_FIRST_BTN))
|
||||
{
|
||||
char cmd[1024];
|
||||
|
||||
|
@ -1277,7 +1282,7 @@ MultiplayerKeys_MenuKey(int key)
|
|||
if (menukeyitem_bind)
|
||||
{
|
||||
// Any key/button but the escape ones
|
||||
if ((key != K_ESCAPE) && (key != '`') && (key != K_JOY_BACK))
|
||||
if ((key != K_ESCAPE) && (key != '`'))
|
||||
{
|
||||
char cmd[1024];
|
||||
|
||||
|
@ -1319,6 +1324,30 @@ M_Menu_Multiplayer_Keys_f(void)
|
|||
* GAME CONTROLLER ( GAMEPAD / JOYSTICK ) BUTTONS MENU
|
||||
*/
|
||||
|
||||
static void
|
||||
GamepadMenu_StatusPrompt(menuframework_s *m)
|
||||
{
|
||||
static char m_gamepadbind_statusbar[64];
|
||||
int btn_confirm, btn_cancel;
|
||||
|
||||
if (japanese_confirm)
|
||||
{
|
||||
btn_confirm = K_BTN_EAST;
|
||||
btn_cancel = K_BTN_SOUTH;
|
||||
}
|
||||
else
|
||||
{
|
||||
btn_confirm = K_BTN_SOUTH;
|
||||
btn_cancel = K_BTN_EAST;
|
||||
}
|
||||
|
||||
snprintf(m_gamepadbind_statusbar, 64, "%s assigns, %s clears, %s exits",
|
||||
Key_KeynumToString_Joy(btn_confirm), Key_KeynumToString_Joy(K_BTN_NORTH),
|
||||
Key_KeynumToString_Joy(btn_cancel));
|
||||
|
||||
Menu_SetStatusBar(m, m_gamepadbind_statusbar);
|
||||
}
|
||||
|
||||
char *controller_bindnames[][2] =
|
||||
{
|
||||
{"+attack", "attack"},
|
||||
|
@ -1374,7 +1403,7 @@ DrawControllerButtonBindingFunc(void *self)
|
|||
int x;
|
||||
const char *name;
|
||||
|
||||
name = Key_KeynumToString(keys[0]);
|
||||
name = Key_KeynumToString_Joy(keys[0]);
|
||||
|
||||
Menu_DrawString(a->generic.x + a->generic.parent->x + RCOLUMN_OFFSET * scale,
|
||||
a->generic.y + a->generic.parent->y, name);
|
||||
|
@ -1387,7 +1416,7 @@ DrawControllerButtonBindingFunc(void *self)
|
|||
a->generic.y + a->generic.parent->y, "or");
|
||||
Menu_DrawString(a->generic.x + a->generic.parent->x + 48 * scale + (x * scale),
|
||||
a->generic.y + a->generic.parent->y,
|
||||
Key_KeynumToString(keys[1]));
|
||||
Key_KeynumToString_Joy(keys[1]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1432,7 +1461,7 @@ ControllerButtons_MenuInit(void)
|
|||
Menu_AddItem(&s_controller_buttons_menu, (void *)&s_controller_buttons_actions[i]);
|
||||
}
|
||||
|
||||
Menu_SetStatusBar(&s_controller_buttons_menu, "BTN_A assigns, BTN_Y clears, BTN_B exits");
|
||||
GamepadMenu_StatusPrompt(&s_controller_buttons_menu);
|
||||
Menu_Center(&s_controller_buttons_menu);
|
||||
}
|
||||
|
||||
|
@ -1451,7 +1480,7 @@ ControllerButtons_MenuKey(int key)
|
|||
if (menukeyitem_bind)
|
||||
{
|
||||
// Only controller buttons allowed
|
||||
if (key >= K_JOY_FIRST_REGULAR && key != K_JOY_BACK)
|
||||
if (key >= K_JOY_FIRST_BTN)
|
||||
{
|
||||
char cmd[1024];
|
||||
|
||||
|
@ -1460,7 +1489,7 @@ ControllerButtons_MenuKey(int key)
|
|||
Cbuf_InsertText(cmd);
|
||||
}
|
||||
|
||||
Menu_SetStatusBar(&s_controller_buttons_menu, "BTN_A assigns, BTN_Y clears, BTN_B exits");
|
||||
GamepadMenu_StatusPrompt(&s_controller_buttons_menu);
|
||||
menukeyitem_bind = false;
|
||||
return menu_out_sound;
|
||||
}
|
||||
|
@ -1548,7 +1577,7 @@ DrawControllerAltButtonBindingFunc(void *self)
|
|||
size_t x;
|
||||
const char *name;
|
||||
|
||||
name = Key_KeynumToString(keys[0]);
|
||||
name = Key_KeynumToString_Joy(keys[0]);
|
||||
|
||||
Menu_DrawString(a->generic.x + a->generic.parent->x + RCOLUMN_OFFSET * scale,
|
||||
a->generic.y + a->generic.parent->y, name);
|
||||
|
@ -1561,7 +1590,7 @@ DrawControllerAltButtonBindingFunc(void *self)
|
|||
a->generic.y + a->generic.parent->y, "or");
|
||||
Menu_DrawString(a->generic.x + a->generic.parent->x + 48 * scale + (x * scale),
|
||||
a->generic.y + a->generic.parent->y,
|
||||
Key_KeynumToString(keys[1]));
|
||||
Key_KeynumToString_Joy(keys[1]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1606,7 +1635,7 @@ ControllerAltButtons_MenuInit(void)
|
|||
Menu_AddItem(&s_controller_alt_buttons_menu, (void *)&s_controller_alt_buttons_actions[i]);
|
||||
}
|
||||
|
||||
Menu_SetStatusBar(&s_controller_alt_buttons_menu, "BTN_A assigns, BTN_Y clears, BTN_B exits");
|
||||
GamepadMenu_StatusPrompt(&s_controller_alt_buttons_menu);
|
||||
Menu_Center(&s_controller_alt_buttons_menu);
|
||||
}
|
||||
|
||||
|
@ -1625,17 +1654,17 @@ ControllerAltButtons_MenuKey(int key)
|
|||
if (menukeyitem_bind)
|
||||
{
|
||||
// Only controller buttons allowed, different from the alt buttons modifier
|
||||
if (key >= K_JOY_FIRST_REGULAR && key != K_JOY_BACK && (keybindings[key] == NULL || strcmp(keybindings[key], "+joyaltselector") != 0))
|
||||
if (key >= K_JOY_FIRST_BTN && (keybindings[key] == NULL || strcmp(keybindings[key], "+joyaltselector") != 0))
|
||||
{
|
||||
char cmd[1024];
|
||||
key = key + (K_JOY_FIRST_REGULAR_ALT - K_JOY_FIRST_REGULAR); // change input to its ALT mode
|
||||
key = key + (K_JOY_FIRST_BTN_ALT - K_JOY_FIRST_BTN); // change input to its ALT mode
|
||||
|
||||
Com_sprintf(cmd, sizeof(cmd), "bind \"%s\" \"%s\"\n",
|
||||
Key_KeynumToString(key), controller_alt_bindnames[item->generic.localdata[0]][0]);
|
||||
Cbuf_InsertText(cmd);
|
||||
}
|
||||
|
||||
Menu_SetStatusBar(&s_controller_alt_buttons_menu, "BTN_A assigns, BTN_Y clears, BTN_B exits");
|
||||
GamepadMenu_StatusPrompt(&s_controller_alt_buttons_menu);
|
||||
menukeyitem_bind = false;
|
||||
return menu_out_sound;
|
||||
}
|
||||
|
|
|
@ -268,7 +268,7 @@ int RI_InitContext(void* win)
|
|||
#ifdef YQ2_GL1_GLES
|
||||
|
||||
// Load GL pointers through GLAD and check context.
|
||||
if( !gladLoadGLES1Loader(SDL_GL_GetProcAddress))
|
||||
if( !gladLoadGLES1Loader( (void * (*)(const char *)) SDL_GL_GetProcAddress ) )
|
||||
{
|
||||
R_Printf(PRINT_ALL, "RI_InitContext(): ERROR: loading OpenGL ES function pointers failed!\n");
|
||||
return false;
|
||||
|
|
Loading…
Reference in a new issue