mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2024-11-10 07:12:07 +00:00
Merge pull request #827 from protocultor/sdlcontroller
Full transition to SDL_GameController for gamepad usage
This commit is contained in:
commit
12c7fddfaa
5 changed files with 793 additions and 428 deletions
|
@ -135,89 +135,59 @@ keyname_t keynames[] = {
|
||||||
{"MWHEELUP", K_MWHEELUP},
|
{"MWHEELUP", K_MWHEELUP},
|
||||||
{"MWHEELDOWN", K_MWHEELDOWN},
|
{"MWHEELDOWN", K_MWHEELDOWN},
|
||||||
|
|
||||||
{"JOY1", K_JOY1},
|
{"BTN_A", K_BTN_A},
|
||||||
{"JOY2", K_JOY2},
|
{"BTN_B", K_BTN_B},
|
||||||
{"JOY3", K_JOY3},
|
{"BTN_X", K_BTN_X},
|
||||||
{"JOY4", K_JOY4},
|
{"BTN_Y", K_BTN_Y},
|
||||||
{"JOY5", K_JOY5},
|
{"STICK_LEFT", K_STICK_LEFT},
|
||||||
{"JOY6", K_JOY6},
|
{"STICK_RIGHT", K_STICK_RIGHT},
|
||||||
{"JOY7", K_JOY7},
|
{"SHOULDR_LEFT", K_SHOULDER_LEFT},
|
||||||
{"JOY8", K_JOY8},
|
{"SHOULDR_RIGHT", K_SHOULDER_RIGHT},
|
||||||
{"JOY9", K_JOY9},
|
|
||||||
{"JOY10", K_JOY10},
|
|
||||||
{"JOY11", K_JOY11},
|
|
||||||
{"JOY12", K_JOY12},
|
|
||||||
{"JOY13", K_JOY13},
|
|
||||||
{"JOY14", K_JOY14},
|
|
||||||
{"JOY15", K_JOY15},
|
|
||||||
{"JOY16", K_JOY16},
|
|
||||||
{"JOY17", K_JOY17},
|
|
||||||
{"JOY18", K_JOY18},
|
|
||||||
{"JOY19", K_JOY19},
|
|
||||||
{"JOY20", K_JOY20},
|
|
||||||
{"JOY21", K_JOY21},
|
|
||||||
{"JOY22", K_JOY22},
|
|
||||||
{"JOY23", K_JOY23},
|
|
||||||
{"JOY24", K_JOY24},
|
|
||||||
{"JOY25", K_JOY25},
|
|
||||||
{"JOY26", K_JOY26},
|
|
||||||
{"JOY27", K_JOY27},
|
|
||||||
{"JOY28", K_JOY28},
|
|
||||||
{"JOY29", K_JOY29},
|
|
||||||
{"JOY30", K_JOY30},
|
|
||||||
{"JOY31", K_JOY31},
|
|
||||||
{"JOY32", K_JOY32},
|
|
||||||
|
|
||||||
{"HAT_UP", K_HAT_UP},
|
|
||||||
{"HAT_RIGHT", K_HAT_RIGHT},
|
|
||||||
{"HAT_DOWN", K_HAT_DOWN},
|
|
||||||
{"HAT_LEFT", K_HAT_LEFT},
|
|
||||||
|
|
||||||
{"TRIG_LEFT", K_TRIG_LEFT},
|
{"TRIG_LEFT", K_TRIG_LEFT},
|
||||||
{"TRIG_RIGHT", K_TRIG_RIGHT},
|
{"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
|
// virtual keys you get by pressing the corresponding normal joy key
|
||||||
// and the altselector key
|
// and the altselector key
|
||||||
{"JOY1_ALT", K_JOY1_ALT},
|
{"BTN_A_ALT", K_BTN_A_ALT},
|
||||||
{"JOY2_ALT", K_JOY2_ALT},
|
{"BTN_B_ALT", K_BTN_B_ALT},
|
||||||
{"JOY3_ALT", K_JOY3_ALT},
|
{"BTN_X_ALT", K_BTN_X_ALT},
|
||||||
{"JOY4_ALT", K_JOY4_ALT},
|
{"BTN_Y_ALT", K_BTN_Y_ALT},
|
||||||
{"JOY5_ALT", K_JOY5_ALT},
|
{"STICK_LEFT_ALT", K_STICK_LEFT_ALT},
|
||||||
{"JOY6_ALT", K_JOY6_ALT},
|
{"STICK_RIGHT_ALT", K_STICK_RIGHT_ALT},
|
||||||
{"JOY7_ALT", K_JOY7_ALT},
|
{"SHOULDR_LEFT_ALT", K_SHOULDER_LEFT_ALT},
|
||||||
{"JOY8_ALT", K_JOY8_ALT},
|
{"SHOULDR_RIGHT_ALT", K_SHOULDER_RIGHT_ALT},
|
||||||
{"JOY9_ALT", K_JOY9_ALT},
|
{"TRIG_LEFT_ALT", K_TRIG_LEFT_ALT},
|
||||||
{"JOY10_ALT", K_JOY10_ALT},
|
{"TRIG_RIGHT_ALT", K_TRIG_RIGHT_ALT},
|
||||||
{"JOY11_ALT", K_JOY11_ALT},
|
|
||||||
{"JOY12_ALT", K_JOY12_ALT},
|
|
||||||
{"JOY13_ALT", K_JOY13_ALT},
|
|
||||||
{"JOY14_ALT", K_JOY14_ALT},
|
|
||||||
{"JOY15_ALT", K_JOY15_ALT},
|
|
||||||
{"JOY16_ALT", K_JOY16_ALT},
|
|
||||||
{"JOY17_ALT", K_JOY17_ALT},
|
|
||||||
{"JOY18_ALT", K_JOY18_ALT},
|
|
||||||
{"JOY19_ALT", K_JOY19_ALT},
|
|
||||||
{"JOY20_ALT", K_JOY20_ALT},
|
|
||||||
{"JOY21_ALT", K_JOY21_ALT},
|
|
||||||
{"JOY22_ALT", K_JOY22_ALT},
|
|
||||||
{"JOY23_ALT", K_JOY23_ALT},
|
|
||||||
{"JOY24_ALT", K_JOY24_ALT},
|
|
||||||
{"JOY25_ALT", K_JOY25_ALT},
|
|
||||||
{"JOY26_ALT", K_JOY26_ALT},
|
|
||||||
{"JOY27_ALT", K_JOY27_ALT},
|
|
||||||
{"JOY28_ALT", K_JOY28_ALT},
|
|
||||||
{"JOY29_ALT", K_JOY29_ALT},
|
|
||||||
{"JOY30_ALT", K_JOY30_ALT},
|
|
||||||
{"JOY31_ALT", K_JOY31_ALT},
|
|
||||||
{"JOY32_ALT", K_JOY32_ALT},
|
|
||||||
|
|
||||||
{"HAT_UP_ALT", K_HAT_UP_ALT},
|
{"DP_UP_ALT", K_DPAD_UP_ALT},
|
||||||
{"HAT_RIGHT_ALT", K_HAT_RIGHT_ALT},
|
{"DP_DOWN_ALT", K_DPAD_DOWN_ALT},
|
||||||
{"HAT_DOWN_ALT", K_HAT_DOWN_ALT},
|
{"DP_LEFT_ALT", K_DPAD_LEFT_ALT},
|
||||||
{"HAT_LEFT_ALT", K_HAT_LEFT_ALT},
|
{"DP_RIGHT_ALT", K_DPAD_RIGHT_ALT},
|
||||||
|
|
||||||
{"TRIG_LEFT", K_TRIG_LEFT_ALT},
|
{"PADDLE_1_ALT", K_PADDLE_1_ALT},
|
||||||
{"TRIG_RIGHT", K_TRIG_RIGHT_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},
|
{"JOY_BACK", K_JOY_BACK},
|
||||||
|
|
||||||
|
@ -1194,13 +1164,13 @@ Key_Event(int key, qboolean down, qboolean special)
|
||||||
cvar_t *fullscreen;
|
cvar_t *fullscreen;
|
||||||
unsigned int time = Sys_Milliseconds();
|
unsigned int time = Sys_Milliseconds();
|
||||||
|
|
||||||
// evil hack for the joystick key altselector, which turns K_JOYx into K_JOYx_ALT
|
// evil hack for the joystick key altselector, which turns K_BTN_x into K_BTN_x_ALT
|
||||||
if(joy_altselector_pressed && key >= K_JOY1 && key <= K_JOY_LAST_REGULAR)
|
if(joy_altselector_pressed && key >= K_JOY_FIRST_REGULAR && key <= K_JOY_LAST_REGULAR)
|
||||||
{
|
{
|
||||||
// make sure key is not the altselector itself (which we won't turn into *_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)
|
if(keybindings[key] == NULL || strcmp(keybindings[key], "+joyaltselector") != 0)
|
||||||
{
|
{
|
||||||
int altkey = key + (K_JOY1_ALT - K_JOY1);
|
int altkey = key + (K_JOY_FIRST_REGULAR_ALT - K_JOY_FIRST_REGULAR);
|
||||||
// allow fallback to binding with non-alt key
|
// allow fallback to binding with non-alt key
|
||||||
if(keybindings[altkey] != NULL || keybindings[key] == NULL)
|
if(keybindings[altkey] != NULL || keybindings[key] == NULL)
|
||||||
key = altkey;
|
key = altkey;
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* the joystick altselector key is pressed
|
* the joystick altselector key is pressed
|
||||||
* => K_JOYx turns into K_JOYx_ALT
|
* => K_BTN_x turns into K_BTN_x_ALT
|
||||||
*/
|
*/
|
||||||
extern qboolean joy_altselector_pressed;
|
extern qboolean joy_altselector_pressed;
|
||||||
|
|
||||||
|
@ -125,98 +125,6 @@ enum QKEYS {
|
||||||
K_MWHEELDOWN,
|
K_MWHEELDOWN,
|
||||||
K_MWHEELUP,
|
K_MWHEELUP,
|
||||||
|
|
||||||
K_JOY1,
|
|
||||||
K_JOY2,
|
|
||||||
K_JOY3,
|
|
||||||
K_JOY4,
|
|
||||||
K_JOY5,
|
|
||||||
K_JOY6,
|
|
||||||
K_JOY7,
|
|
||||||
K_JOY8,
|
|
||||||
K_JOY9,
|
|
||||||
K_JOY10,
|
|
||||||
K_JOY11,
|
|
||||||
K_JOY12,
|
|
||||||
K_JOY13,
|
|
||||||
K_JOY14,
|
|
||||||
K_JOY15,
|
|
||||||
K_JOY16,
|
|
||||||
K_JOY17,
|
|
||||||
K_JOY18,
|
|
||||||
K_JOY19,
|
|
||||||
K_JOY20,
|
|
||||||
K_JOY21,
|
|
||||||
K_JOY22,
|
|
||||||
K_JOY23,
|
|
||||||
K_JOY24,
|
|
||||||
K_JOY25,
|
|
||||||
K_JOY26,
|
|
||||||
K_JOY27,
|
|
||||||
K_JOY28,
|
|
||||||
K_JOY29,
|
|
||||||
K_JOY30,
|
|
||||||
K_JOY31,
|
|
||||||
K_JOY32,
|
|
||||||
|
|
||||||
K_HAT_UP,
|
|
||||||
K_HAT_RIGHT,
|
|
||||||
K_HAT_DOWN,
|
|
||||||
K_HAT_LEFT,
|
|
||||||
|
|
||||||
K_TRIG_LEFT,
|
|
||||||
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,
|
|
||||||
|
|
||||||
/* Can't be mapped to any action (=> not regular) */
|
|
||||||
K_JOY_BACK,
|
|
||||||
|
|
||||||
K_JOY1_ALT,
|
|
||||||
K_JOY2_ALT,
|
|
||||||
K_JOY3_ALT,
|
|
||||||
K_JOY4_ALT,
|
|
||||||
K_JOY5_ALT,
|
|
||||||
K_JOY6_ALT,
|
|
||||||
K_JOY7_ALT,
|
|
||||||
K_JOY8_ALT,
|
|
||||||
K_JOY9_ALT,
|
|
||||||
K_JOY10_ALT,
|
|
||||||
K_JOY11_ALT,
|
|
||||||
K_JOY12_ALT,
|
|
||||||
K_JOY13_ALT,
|
|
||||||
K_JOY14_ALT,
|
|
||||||
K_JOY15_ALT,
|
|
||||||
K_JOY16_ALT,
|
|
||||||
K_JOY17_ALT,
|
|
||||||
K_JOY18_ALT,
|
|
||||||
K_JOY19_ALT,
|
|
||||||
K_JOY20_ALT,
|
|
||||||
K_JOY21_ALT,
|
|
||||||
K_JOY22_ALT,
|
|
||||||
K_JOY23_ALT,
|
|
||||||
K_JOY24_ALT,
|
|
||||||
K_JOY25_ALT,
|
|
||||||
K_JOY26_ALT,
|
|
||||||
K_JOY27_ALT,
|
|
||||||
K_JOY28_ALT,
|
|
||||||
K_JOY29_ALT,
|
|
||||||
K_JOY30_ALT,
|
|
||||||
K_JOY31_ALT,
|
|
||||||
K_JOY32_ALT,
|
|
||||||
|
|
||||||
K_HAT_UP_ALT,
|
|
||||||
K_HAT_RIGHT_ALT,
|
|
||||||
K_HAT_DOWN_ALT,
|
|
||||||
K_HAT_LEFT_ALT,
|
|
||||||
|
|
||||||
K_TRIG_LEFT_ALT,
|
|
||||||
K_TRIG_RIGHT_ALT,
|
|
||||||
|
|
||||||
// add other joystick/controller keys before this one and adjust it accordingly
|
|
||||||
K_JOY_LAST_REGULAR_ALT = K_TRIG_RIGHT_ALT,
|
|
||||||
|
|
||||||
K_SUPER, // TODO: what is this? SDL doesn't seem to know it..
|
K_SUPER, // TODO: what is this? SDL doesn't seem to know it..
|
||||||
K_COMPOSE,
|
K_COMPOSE,
|
||||||
K_MODE,
|
K_MODE,
|
||||||
|
@ -296,6 +204,67 @@ enum QKEYS {
|
||||||
// want to be able to type in the console) - the user can't bind this key.
|
// want to be able to type in the console) - the user can't bind this key.
|
||||||
K_CONSOLE,
|
K_CONSOLE,
|
||||||
|
|
||||||
|
// Keyboard keys / codes end here. Any new ones should go before this.
|
||||||
|
// 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_BACK,
|
||||||
|
K_BTN_GUIDE,
|
||||||
|
K_BTN_START,
|
||||||
|
K_STICK_LEFT,
|
||||||
|
K_STICK_RIGHT,
|
||||||
|
K_SHOULDER_LEFT,
|
||||||
|
K_SHOULDER_RIGHT,
|
||||||
|
K_TRIG_LEFT,
|
||||||
|
K_TRIG_RIGHT,
|
||||||
|
K_DPAD_UP,
|
||||||
|
K_DPAD_DOWN,
|
||||||
|
K_DPAD_LEFT,
|
||||||
|
K_DPAD_RIGHT,
|
||||||
|
K_BTN_MISC1,
|
||||||
|
K_PADDLE_1,
|
||||||
|
K_PADDLE_2,
|
||||||
|
K_PADDLE_3,
|
||||||
|
K_PADDLE_4,
|
||||||
|
K_TOUCHPAD,
|
||||||
|
|
||||||
|
// 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_TOUCHPAD,
|
||||||
|
|
||||||
|
/* 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_BACK_ALT,
|
||||||
|
K_BTN_GUIDE_ALT,
|
||||||
|
K_BTN_START_ALT,
|
||||||
|
K_STICK_LEFT_ALT,
|
||||||
|
K_STICK_RIGHT_ALT,
|
||||||
|
K_SHOULDER_LEFT_ALT,
|
||||||
|
K_SHOULDER_RIGHT_ALT,
|
||||||
|
K_TRIG_LEFT_ALT,
|
||||||
|
K_TRIG_RIGHT_ALT,
|
||||||
|
K_DPAD_UP_ALT,
|
||||||
|
K_DPAD_DOWN_ALT,
|
||||||
|
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_TOUCHPAD_ALT,
|
||||||
|
|
||||||
K_LAST
|
K_LAST
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,6 @@
|
||||||
// IN_Update() called at the beginning of a frame to the
|
// IN_Update() called at the beginning of a frame to the
|
||||||
// actual movement functions called at a later time.
|
// actual movement functions called at a later time.
|
||||||
static float mouse_x, mouse_y;
|
static float mouse_x, mouse_y;
|
||||||
static int back_button_id = -1;
|
|
||||||
static int sdl_back_button = SDL_CONTROLLER_BUTTON_BACK;
|
static int sdl_back_button = SDL_CONTROLLER_BUTTON_BACK;
|
||||||
static float joystick_yaw, joystick_pitch;
|
static float joystick_yaw, joystick_pitch;
|
||||||
static float joystick_forwardmove, joystick_sidemove;
|
static float joystick_forwardmove, joystick_sidemove;
|
||||||
|
@ -58,7 +57,7 @@ static qboolean mlooking;
|
||||||
// Used throughout the client.
|
// Used throughout the client.
|
||||||
int sys_frame_time;
|
int sys_frame_time;
|
||||||
|
|
||||||
// the joystick altselector that turns K_JOYX into K_JOYX_ALT
|
// the joystick altselector that turns K_BTN_X into K_BTN_X_ALT
|
||||||
// is pressed
|
// is pressed
|
||||||
qboolean joy_altselector_pressed = false;
|
qboolean joy_altselector_pressed = false;
|
||||||
|
|
||||||
|
@ -95,7 +94,6 @@ struct hapric_effects_cache {
|
||||||
qboolean show_haptic;
|
qboolean show_haptic;
|
||||||
|
|
||||||
static SDL_Haptic *joystick_haptic = NULL;
|
static SDL_Haptic *joystick_haptic = NULL;
|
||||||
static SDL_Joystick *joystick = NULL;
|
|
||||||
static SDL_GameController *controller = NULL;
|
static SDL_GameController *controller = NULL;
|
||||||
|
|
||||||
#define HAPTIC_EFFECT_LIST_SIZE 16
|
#define HAPTIC_EFFECT_LIST_SIZE 16
|
||||||
|
@ -132,6 +130,10 @@ static cvar_t *joy_axis_triggerright_threshold;
|
||||||
// Joystick haptic
|
// Joystick haptic
|
||||||
static cvar_t *joy_haptic_magnitude;
|
static cvar_t *joy_haptic_magnitude;
|
||||||
|
|
||||||
|
// Support for hot plugging of game controller
|
||||||
|
static qboolean first_init = true;
|
||||||
|
static int init_delay = 30;
|
||||||
|
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -421,6 +423,48 @@ IN_TranslateScancodeToQ2Key(SDL_Scancode sc)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
IN_TranslateGamepadBtnToQ2Key(int btn)
|
||||||
|
{
|
||||||
|
|
||||||
|
#define MY_BTN_CASE(X,Y) case SDL_CONTROLLER_BUTTON_ ## X : return K_ ## Y;
|
||||||
|
|
||||||
|
switch( btn )
|
||||||
|
{
|
||||||
|
// case SDL_CONTROLLER_BUTTON_A : return K_BTN_A;
|
||||||
|
MY_BTN_CASE(A,BTN_A)
|
||||||
|
MY_BTN_CASE(B,BTN_B)
|
||||||
|
MY_BTN_CASE(X,BTN_X)
|
||||||
|
MY_BTN_CASE(Y,BTN_Y)
|
||||||
|
MY_BTN_CASE(LEFTSHOULDER,SHOULDER_LEFT)
|
||||||
|
MY_BTN_CASE(RIGHTSHOULDER,SHOULDER_RIGHT)
|
||||||
|
MY_BTN_CASE(LEFTSTICK,STICK_LEFT)
|
||||||
|
MY_BTN_CASE(RIGHTSTICK,STICK_RIGHT)
|
||||||
|
MY_BTN_CASE(DPAD_UP,DPAD_UP)
|
||||||
|
MY_BTN_CASE(DPAD_DOWN,DPAD_DOWN)
|
||||||
|
MY_BTN_CASE(DPAD_LEFT,DPAD_LEFT)
|
||||||
|
MY_BTN_CASE(DPAD_RIGHT,DPAD_RIGHT)
|
||||||
|
#if SDL_VERSION_ATLEAST(2, 0, 14) // support for newer buttons
|
||||||
|
MY_BTN_CASE(PADDLE1,PADDLE_1)
|
||||||
|
MY_BTN_CASE(PADDLE2,PADDLE_2)
|
||||||
|
MY_BTN_CASE(PADDLE3,PADDLE_3)
|
||||||
|
MY_BTN_CASE(PADDLE4,PADDLE_4)
|
||||||
|
MY_BTN_CASE(MISC1,BTN_MISC1)
|
||||||
|
MY_BTN_CASE(TOUCHPAD,TOUCHPAD)
|
||||||
|
#endif
|
||||||
|
MY_BTN_CASE(BACK,BTN_BACK)
|
||||||
|
MY_BTN_CASE(GUIDE,BTN_GUIDE)
|
||||||
|
MY_BTN_CASE(START,BTN_START)
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef MY_BTN_CASE
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void IN_Controller_Init(qboolean notify_user);
|
||||||
|
static void IN_Controller_Shutdown(qboolean notify_user);
|
||||||
|
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -435,7 +479,6 @@ IN_Update(void)
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
unsigned int key;
|
unsigned int key;
|
||||||
|
|
||||||
static char last_hat = SDL_HAT_CENTERED;
|
|
||||||
static qboolean left_trigger = false;
|
static qboolean left_trigger = false;
|
||||||
static qboolean right_trigger = false;
|
static qboolean right_trigger = false;
|
||||||
|
|
||||||
|
@ -583,13 +626,21 @@ IN_Update(void)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDL_CONTROLLERBUTTONUP:
|
case SDL_CONTROLLERBUTTONUP:
|
||||||
case SDL_CONTROLLERBUTTONDOWN: /* Handle Controller Back button */
|
case SDL_CONTROLLERBUTTONDOWN:
|
||||||
{
|
{
|
||||||
qboolean down = (event.type == SDL_CONTROLLERBUTTONDOWN);
|
qboolean down = (event.type == SDL_CONTROLLERBUTTONDOWN);
|
||||||
|
|
||||||
|
// Handle Back Button first, to override its original key
|
||||||
if (event.cbutton.button == sdl_back_button)
|
if (event.cbutton.button == sdl_back_button)
|
||||||
{
|
{
|
||||||
Key_Event(K_JOY_BACK, down, true);
|
Key_Event(K_JOY_BACK, down, true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
key = IN_TranslateGamepadBtnToQ2Key(event.cbutton.button);
|
||||||
|
if(key != 0)
|
||||||
|
{
|
||||||
|
Key_Event(key, down, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -727,57 +778,24 @@ IN_Update(void)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Joystick can have more buttons than on general game controller
|
case SDL_CONTROLLERDEVICEREMOVED:
|
||||||
// so try to map not free buttons
|
if (!controller)
|
||||||
case SDL_JOYBUTTONUP:
|
|
||||||
case SDL_JOYBUTTONDOWN:
|
|
||||||
{
|
|
||||||
qboolean down = (event.type == SDL_JOYBUTTONDOWN);
|
|
||||||
|
|
||||||
// Ignore back button, we don't need event for such button
|
|
||||||
if (back_button_id == event.jbutton.button)
|
|
||||||
{
|
{
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
|
if (event.cdevice.which == SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(controller))) {
|
||||||
if (event.jbutton.button <= (K_JOY32 - K_JOY1))
|
IN_Controller_Shutdown(true);
|
||||||
{
|
IN_Controller_Init(false);
|
||||||
Key_Event(event.jbutton.button + K_JOY1, down, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
case SDL_JOYHATMOTION:
|
case SDL_JOYDEVICEADDED:
|
||||||
{
|
if (!controller)
|
||||||
if (last_hat != event.jhat.value)
|
|
||||||
{
|
{
|
||||||
char diff = last_hat ^event.jhat.value;
|
// This should be lower, but some controllers just don't want to get detected by the OS
|
||||||
int i;
|
init_delay = 100;
|
||||||
|
|
||||||
for (i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
if (diff & (1 << i))
|
|
||||||
{
|
|
||||||
// check that we have button up for some bit
|
|
||||||
if (last_hat & (1 << i))
|
|
||||||
{
|
|
||||||
Key_Event(i + K_HAT_UP, false, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check that we have button down for some bit */
|
|
||||||
if (event.jhat.value & (1 << i))
|
|
||||||
{
|
|
||||||
Key_Event(i + K_HAT_UP, true, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
last_hat = event.jhat.value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
case SDL_QUIT:
|
case SDL_QUIT:
|
||||||
Com_Quit();
|
Com_Quit();
|
||||||
|
@ -803,6 +821,26 @@ IN_Update(void)
|
||||||
// We need to save the frame time so other subsystems
|
// We need to save the frame time so other subsystems
|
||||||
// know the exact time of the last input events.
|
// know the exact time of the last input events.
|
||||||
sys_frame_time = Sys_Milliseconds();
|
sys_frame_time = Sys_Milliseconds();
|
||||||
|
|
||||||
|
// Hot plugging delay handling, to not be "overwhelmed" because some controllers
|
||||||
|
// present themselves as two different devices, triggering SDL_JOYDEVICEADDED
|
||||||
|
// too many times. They could trigger it even at game initialization.
|
||||||
|
if (init_delay)
|
||||||
|
{
|
||||||
|
init_delay--;
|
||||||
|
if (!init_delay)
|
||||||
|
{
|
||||||
|
if (!first_init)
|
||||||
|
{
|
||||||
|
IN_Controller_Shutdown(false);
|
||||||
|
IN_Controller_Init(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
first_init = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1021,7 +1059,7 @@ IN_Haptic_Effects_Info(void)
|
||||||
{
|
{
|
||||||
show_haptic = true;
|
show_haptic = true;
|
||||||
|
|
||||||
Com_Printf ("Joystic/Mouse haptic:\n");
|
Com_Printf ("Joystick/Mouse haptic:\n");
|
||||||
Com_Printf (" * %d effects\n", SDL_HapticNumEffects(joystick_haptic));
|
Com_Printf (" * %d effects\n", SDL_HapticNumEffects(joystick_haptic));
|
||||||
Com_Printf (" * %d effects in same time\n", SDL_HapticNumEffectsPlaying(joystick_haptic));
|
Com_Printf (" * %d effects in same time\n", SDL_HapticNumEffectsPlaying(joystick_haptic));
|
||||||
Com_Printf (" * %d haptic axis\n", SDL_HapticNumAxes(joystick_haptic));
|
Com_Printf (" * %d haptic axis\n", SDL_HapticNumAxes(joystick_haptic));
|
||||||
|
@ -1195,15 +1233,157 @@ Haptic_Feedback(char *name, int effect_volume, int effect_duration,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Game Controller
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
IN_Controller_Init(qboolean notify_user)
|
||||||
|
{
|
||||||
|
cvar_t *in_sdlbackbutton;
|
||||||
|
int nummappings;
|
||||||
|
char controllerdb[MAX_OSPATH] = {0};
|
||||||
|
SDL_Joystick *joystick = NULL;
|
||||||
|
SDL_bool is_controller = SDL_FALSE;
|
||||||
|
|
||||||
|
in_sdlbackbutton = Cvar_Get("in_sdlbackbutton", "0", CVAR_ARCHIVE);
|
||||||
|
if (in_sdlbackbutton)
|
||||||
|
{
|
||||||
|
switch ((int)in_sdlbackbutton->value)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
sdl_back_button = SDL_CONTROLLER_BUTTON_START;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
sdl_back_button = SDL_CONTROLLER_BUTTON_GUIDE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
sdl_back_button = SDL_CONTROLLER_BUTTON_BACK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (notify_user)
|
||||||
|
{
|
||||||
|
Com_Printf("- Game Controller init attempt -\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SDL_WasInit(SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC))
|
||||||
|
{
|
||||||
|
if (SDL_Init(SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC) == -1)
|
||||||
|
{
|
||||||
|
Com_Printf ("Couldn't init SDL joystick: %s.\n", SDL_GetError ());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Com_Printf ("%i joysticks were found.\n", SDL_NumJoysticks());
|
||||||
|
|
||||||
|
if (!SDL_NumJoysticks())
|
||||||
|
{
|
||||||
|
joystick_haptic = SDL_HapticOpenFromMouse();
|
||||||
|
|
||||||
|
if (joystick_haptic == NULL)
|
||||||
|
{
|
||||||
|
Com_Printf("Most likely mouse isn't haptic.\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IN_Haptic_Effects_Info();
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const char* rawPath = FS_GetNextRawPath(NULL); rawPath != NULL; rawPath = FS_GetNextRawPath(rawPath))
|
||||||
|
{
|
||||||
|
snprintf(controllerdb, MAX_OSPATH, "%s/gamecontrollerdb.txt", rawPath);
|
||||||
|
nummappings = SDL_GameControllerAddMappingsFromFile(controllerdb);
|
||||||
|
if (nummappings > 0)
|
||||||
|
Com_Printf ("%d mappings loaded from gamecontrollerdb.txt\n", nummappings);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < SDL_NumJoysticks(); i++)
|
||||||
|
{
|
||||||
|
joystick = SDL_JoystickOpen(i);
|
||||||
|
const char* joystick_name = SDL_JoystickName(joystick);
|
||||||
|
const int name_len = strlen(joystick_name);
|
||||||
|
|
||||||
|
Com_Printf ("The name of the joystick is '%s'\n", joystick_name);
|
||||||
|
|
||||||
|
// Ugly hack to detect IMU-only devices - works for Switch Pro Controller at least
|
||||||
|
if (name_len > 4 && !strncmp(joystick_name + name_len - 4, " IMU", 4))
|
||||||
|
{
|
||||||
|
Com_Printf ("Skipping IMU device.\n");
|
||||||
|
SDL_JoystickClose(joystick);
|
||||||
|
joystick = NULL;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Com_Printf ("Number of Axes: %d\n", SDL_JoystickNumAxes(joystick));
|
||||||
|
Com_Printf ("Number of Buttons: %d\n", SDL_JoystickNumButtons(joystick));
|
||||||
|
Com_Printf ("Number of Balls: %d\n", SDL_JoystickNumBalls(joystick));
|
||||||
|
Com_Printf ("Number of Hats: %d\n", SDL_JoystickNumHats(joystick));
|
||||||
|
|
||||||
|
is_controller = SDL_IsGameController(i);
|
||||||
|
if (!is_controller)
|
||||||
|
{
|
||||||
|
char joystick_guid[256] = {0};
|
||||||
|
|
||||||
|
SDL_JoystickGUID guid;
|
||||||
|
guid = SDL_JoystickGetDeviceGUID(i);
|
||||||
|
|
||||||
|
SDL_JoystickGetGUIDString(guid, joystick_guid, 255);
|
||||||
|
|
||||||
|
Com_Printf ("To use joystick as game controller please set SDL_GAMECONTROLLERCONFIG:\n");
|
||||||
|
Com_Printf ("e.g.: SDL_GAMECONTROLLERCONFIG='%s,%s,leftx:a0,lefty:a1,rightx:a2,righty:a3,back:b1,...\n", joystick_guid, joystick_name);
|
||||||
|
Com_Printf ("Or you can put 'gamecontrollerdb.txt' in your game directory.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_JoystickClose(joystick);
|
||||||
|
joystick = NULL;
|
||||||
|
|
||||||
|
if (is_controller)
|
||||||
|
{
|
||||||
|
controller = SDL_GameControllerOpen(i);
|
||||||
|
|
||||||
|
Com_Printf ("Controller settings: %s\n", SDL_GameControllerMapping(controller));
|
||||||
|
Com_Printf ("Controller axis: \n");
|
||||||
|
Com_Printf (" * leftx = %s\n", joy_axis_leftx->string);
|
||||||
|
Com_Printf (" * lefty = %s\n", joy_axis_lefty->string);
|
||||||
|
Com_Printf (" * rightx = %s\n", joy_axis_rightx->string);
|
||||||
|
Com_Printf (" * righty = %s\n", joy_axis_righty->string);
|
||||||
|
Com_Printf (" * triggerleft = %s\n", joy_axis_triggerleft->string);
|
||||||
|
Com_Printf (" * triggerright = %s\n", joy_axis_triggerright->string);
|
||||||
|
|
||||||
|
Com_Printf ("Controller thresholds: \n");
|
||||||
|
Com_Printf (" * leftx = %f\n", joy_axis_leftx_threshold->value);
|
||||||
|
Com_Printf (" * lefty = %f\n", joy_axis_lefty_threshold->value);
|
||||||
|
Com_Printf (" * rightx = %f\n", joy_axis_rightx_threshold->value);
|
||||||
|
Com_Printf (" * righty = %f\n", joy_axis_righty_threshold->value);
|
||||||
|
Com_Printf (" * triggerleft = %f\n", joy_axis_triggerleft_threshold->value);
|
||||||
|
Com_Printf (" * triggerright = %f\n", joy_axis_triggerright_threshold->value);
|
||||||
|
|
||||||
|
joystick_haptic = SDL_HapticOpenFromJoystick(SDL_GameControllerGetJoystick(controller));
|
||||||
|
|
||||||
|
if (joystick_haptic == NULL)
|
||||||
|
{
|
||||||
|
Com_Printf("Most likely controller isn't haptic.\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IN_Haptic_Effects_Info();
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initializes the backend
|
* Initializes the backend
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
IN_Init(void)
|
IN_Init(void)
|
||||||
{
|
{
|
||||||
cvar_t *in_sdlbackbutton;
|
|
||||||
int nummappings;
|
|
||||||
char controllerdb[MAX_OSPATH] = {0};
|
|
||||||
Com_Printf("------- input initialization -------\n");
|
Com_Printf("------- input initialization -------\n");
|
||||||
|
|
||||||
mouse_x = mouse_y = 0;
|
mouse_x = mouse_y = 0;
|
||||||
|
@ -1246,22 +1426,6 @@ IN_Init(void)
|
||||||
|
|
||||||
windowed_mouse = Cvar_Get("windowed_mouse", "1", CVAR_USERINFO | CVAR_ARCHIVE);
|
windowed_mouse = Cvar_Get("windowed_mouse", "1", CVAR_USERINFO | CVAR_ARCHIVE);
|
||||||
|
|
||||||
in_sdlbackbutton = Cvar_Get("in_sdlbackbutton", "0", CVAR_ARCHIVE);
|
|
||||||
if (in_sdlbackbutton)
|
|
||||||
{
|
|
||||||
switch ((int)in_sdlbackbutton->value)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
sdl_back_button = SDL_CONTROLLER_BUTTON_START;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
sdl_back_button = SDL_CONTROLLER_BUTTON_GUIDE;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
sdl_back_button = SDL_CONTROLLER_BUTTON_BACK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Cmd_AddCommand("+mlook", IN_MLookDown);
|
Cmd_AddCommand("+mlook", IN_MLookDown);
|
||||||
Cmd_AddCommand("-mlook", IN_MLookUp);
|
Cmd_AddCommand("-mlook", IN_MLookUp);
|
||||||
|
|
||||||
|
@ -1270,108 +1434,7 @@ IN_Init(void)
|
||||||
|
|
||||||
SDL_StartTextInput();
|
SDL_StartTextInput();
|
||||||
|
|
||||||
/* Joystick init */
|
IN_Controller_Init(false);
|
||||||
if (!SDL_WasInit(SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC))
|
|
||||||
{
|
|
||||||
if (SDL_Init(SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC) == -1)
|
|
||||||
{
|
|
||||||
Com_Printf ("Couldn't init SDL joystick: %s.\n", SDL_GetError ());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Com_Printf ("%i joysticks were found.\n", SDL_NumJoysticks());
|
|
||||||
|
|
||||||
if (SDL_NumJoysticks() > 0)
|
|
||||||
{
|
|
||||||
for (const char* rawPath = FS_GetNextRawPath(NULL); rawPath != NULL; rawPath = FS_GetNextRawPath(rawPath))
|
|
||||||
{
|
|
||||||
snprintf(controllerdb, MAX_OSPATH, "%s/gamecontrollerdb.txt", rawPath);
|
|
||||||
nummappings = SDL_GameControllerAddMappingsFromFile(controllerdb);
|
|
||||||
if (nummappings > 0)
|
|
||||||
Com_Printf ("%d mappings loaded from gamecontrollerdb.txt\n", nummappings);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < SDL_NumJoysticks(); i++) {
|
|
||||||
joystick = SDL_JoystickOpen(i);
|
|
||||||
|
|
||||||
Com_Printf ("The name of the joystick is '%s'\n", SDL_JoystickName(joystick));
|
|
||||||
Com_Printf ("Number of Axes: %d\n", SDL_JoystickNumAxes(joystick));
|
|
||||||
Com_Printf ("Number of Buttons: %d\n", SDL_JoystickNumButtons(joystick));
|
|
||||||
Com_Printf ("Number of Balls: %d\n", SDL_JoystickNumBalls(joystick));
|
|
||||||
Com_Printf ("Number of Hats: %d\n", SDL_JoystickNumHats(joystick));
|
|
||||||
|
|
||||||
joystick_haptic = SDL_HapticOpenFromJoystick(joystick);
|
|
||||||
|
|
||||||
if (joystick_haptic == NULL)
|
|
||||||
{
|
|
||||||
Com_Printf("Most likely joystick isn't haptic.\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
IN_Haptic_Effects_Info();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(SDL_IsGameController(i))
|
|
||||||
{
|
|
||||||
SDL_GameControllerButtonBind backBind;
|
|
||||||
controller = SDL_GameControllerOpen(i);
|
|
||||||
|
|
||||||
Com_Printf ("Controller settings: %s\n", SDL_GameControllerMapping(controller));
|
|
||||||
Com_Printf ("Controller axis: \n");
|
|
||||||
Com_Printf (" * leftx = %s\n", joy_axis_leftx->string);
|
|
||||||
Com_Printf (" * lefty = %s\n", joy_axis_lefty->string);
|
|
||||||
Com_Printf (" * rightx = %s\n", joy_axis_rightx->string);
|
|
||||||
Com_Printf (" * righty = %s\n", joy_axis_righty->string);
|
|
||||||
Com_Printf (" * triggerleft = %s\n", joy_axis_triggerleft->string);
|
|
||||||
Com_Printf (" * triggerright = %s\n", joy_axis_triggerright->string);
|
|
||||||
|
|
||||||
Com_Printf ("Controller thresholds: \n");
|
|
||||||
Com_Printf (" * leftx = %f\n", joy_axis_leftx_threshold->value);
|
|
||||||
Com_Printf (" * lefty = %f\n", joy_axis_lefty_threshold->value);
|
|
||||||
Com_Printf (" * rightx = %f\n", joy_axis_rightx_threshold->value);
|
|
||||||
Com_Printf (" * righty = %f\n", joy_axis_righty_threshold->value);
|
|
||||||
Com_Printf (" * triggerleft = %f\n", joy_axis_triggerleft_threshold->value);
|
|
||||||
Com_Printf (" * triggerright = %f\n", joy_axis_triggerright_threshold->value);
|
|
||||||
|
|
||||||
backBind = SDL_GameControllerGetBindForButton(controller, sdl_back_button);
|
|
||||||
|
|
||||||
if (backBind.bindType == SDL_CONTROLLER_BINDTYPE_BUTTON)
|
|
||||||
{
|
|
||||||
back_button_id = backBind.value.button;
|
|
||||||
Com_Printf ("\nBack button JOY%d will be unbindable.\n", back_button_id+1);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
char joystick_guid[256] = {0};
|
|
||||||
|
|
||||||
SDL_JoystickGUID guid;
|
|
||||||
guid = SDL_JoystickGetDeviceGUID(i);
|
|
||||||
|
|
||||||
SDL_JoystickGetGUIDString(guid, joystick_guid, 255);
|
|
||||||
|
|
||||||
Com_Printf ("To use joystick as game controller please set SDL_GAMECONTROLLERCONFIG:\n");
|
|
||||||
Com_Printf ("e.g.: SDL_GAMECONTROLLERCONFIG='%s,%s,leftx:a0,lefty:a1,rightx:a2,righty:a3,back:b1,...\n", joystick_guid, SDL_JoystickName(joystick));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
joystick_haptic = SDL_HapticOpenFromMouse();
|
|
||||||
|
|
||||||
if (joystick_haptic == NULL)
|
|
||||||
{
|
|
||||||
Com_Printf("Most likely mouse isn't haptic.\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
IN_Haptic_Effects_Info();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Com_Printf("------------------------------------\n\n");
|
Com_Printf("------------------------------------\n\n");
|
||||||
}
|
}
|
||||||
|
@ -1391,6 +1454,23 @@ IN_Haptic_Shutdown(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
IN_Controller_Shutdown(qboolean notify_user)
|
||||||
|
{
|
||||||
|
if (notify_user)
|
||||||
|
{
|
||||||
|
Com_Printf("- Game Controller disconnected -\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
IN_Haptic_Shutdown();
|
||||||
|
|
||||||
|
if (controller)
|
||||||
|
{
|
||||||
|
SDL_GameControllerClose(controller);
|
||||||
|
controller = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
IN_Shutdown(void)
|
IN_Shutdown(void)
|
||||||
{
|
{
|
||||||
|
@ -1400,20 +1480,7 @@ IN_Shutdown(void)
|
||||||
|
|
||||||
Com_Printf("Shutting down input.\n");
|
Com_Printf("Shutting down input.\n");
|
||||||
|
|
||||||
IN_Haptic_Shutdown();
|
IN_Controller_Shutdown(false);
|
||||||
|
|
||||||
if (controller)
|
|
||||||
{
|
|
||||||
back_button_id = -1;
|
|
||||||
SDL_GameControllerClose(controller);
|
|
||||||
controller = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (joystick)
|
|
||||||
{
|
|
||||||
SDL_JoystickClose(joystick);
|
|
||||||
joystick = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Uint32 subsystems = SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC;
|
const Uint32 subsystems = SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC;
|
||||||
if (SDL_WasInit(subsystems) == subsystems)
|
if (SDL_WasInit(subsystems) == subsystems)
|
||||||
|
|
|
@ -43,6 +43,13 @@
|
||||||
#define QMF_GRAYED 0x00000002
|
#define QMF_GRAYED 0x00000002
|
||||||
#define QMF_NUMBERSONLY 0x00000004
|
#define QMF_NUMBERSONLY 0x00000004
|
||||||
|
|
||||||
|
enum {
|
||||||
|
KEYS_ALL = 0,
|
||||||
|
KEYS_KEYBOARD_MOUSE,
|
||||||
|
KEYS_CONTROLLER,
|
||||||
|
KEYS_CONTROLLER_ALT
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct _tag_menuframework
|
typedef struct _tag_menuframework
|
||||||
{
|
{
|
||||||
int x, y;
|
int x, y;
|
||||||
|
|
|
@ -64,6 +64,8 @@ static void M_Menu_Video_f(void);
|
||||||
static void M_Menu_Options_f(void);
|
static void M_Menu_Options_f(void);
|
||||||
static void M_Menu_Keys_f(void);
|
static void M_Menu_Keys_f(void);
|
||||||
static void M_Menu_Joy_f(void);
|
static void M_Menu_Joy_f(void);
|
||||||
|
static void M_Menu_ControllerButtons_f(void);
|
||||||
|
static void M_Menu_ControllerAltButtons_f(void);
|
||||||
static void M_Menu_Quit_f(void);
|
static void M_Menu_Quit_f(void);
|
||||||
|
|
||||||
void M_Menu_Credits(void);
|
void M_Menu_Credits(void);
|
||||||
|
@ -229,25 +231,25 @@ Key_GetMenuKey(int key)
|
||||||
{
|
{
|
||||||
case K_KP_UPARROW:
|
case K_KP_UPARROW:
|
||||||
case K_UPARROW:
|
case K_UPARROW:
|
||||||
case K_HAT_UP:
|
case K_DPAD_UP:
|
||||||
return K_UPARROW;
|
return K_UPARROW;
|
||||||
|
|
||||||
case K_TAB:
|
case K_TAB:
|
||||||
case K_KP_DOWNARROW:
|
case K_KP_DOWNARROW:
|
||||||
case K_DOWNARROW:
|
case K_DOWNARROW:
|
||||||
case K_HAT_DOWN:
|
case K_DPAD_DOWN:
|
||||||
return K_DOWNARROW;
|
return K_DOWNARROW;
|
||||||
|
|
||||||
case K_KP_LEFTARROW:
|
case K_KP_LEFTARROW:
|
||||||
case K_LEFTARROW:
|
case K_LEFTARROW:
|
||||||
case K_HAT_LEFT:
|
case K_DPAD_LEFT:
|
||||||
case K_TRIG_LEFT:
|
case K_SHOULDER_LEFT:
|
||||||
return K_LEFTARROW;
|
return K_LEFTARROW;
|
||||||
|
|
||||||
case K_KP_RIGHTARROW:
|
case K_KP_RIGHTARROW:
|
||||||
case K_RIGHTARROW:
|
case K_RIGHTARROW:
|
||||||
case K_HAT_RIGHT:
|
case K_DPAD_RIGHT:
|
||||||
case K_TRIG_RIGHT:
|
case K_SHOULDER_RIGHT:
|
||||||
return K_RIGHTARROW;
|
return K_RIGHTARROW;
|
||||||
|
|
||||||
case K_MOUSE1:
|
case K_MOUSE1:
|
||||||
|
@ -256,45 +258,21 @@ Key_GetMenuKey(int key)
|
||||||
case K_MOUSE4:
|
case K_MOUSE4:
|
||||||
case K_MOUSE5:
|
case K_MOUSE5:
|
||||||
|
|
||||||
case K_JOY1:
|
|
||||||
case K_JOY2:
|
|
||||||
case K_JOY3:
|
|
||||||
case K_JOY4:
|
|
||||||
case K_JOY5:
|
|
||||||
case K_JOY6:
|
|
||||||
case K_JOY7:
|
|
||||||
case K_JOY8:
|
|
||||||
case K_JOY9:
|
|
||||||
case K_JOY10:
|
|
||||||
case K_JOY11:
|
|
||||||
case K_JOY12:
|
|
||||||
case K_JOY13:
|
|
||||||
case K_JOY14:
|
|
||||||
case K_JOY15:
|
|
||||||
case K_JOY16:
|
|
||||||
case K_JOY17:
|
|
||||||
case K_JOY18:
|
|
||||||
case K_JOY19:
|
|
||||||
case K_JOY20:
|
|
||||||
case K_JOY21:
|
|
||||||
case K_JOY22:
|
|
||||||
case K_JOY23:
|
|
||||||
case K_JOY24:
|
|
||||||
case K_JOY25:
|
|
||||||
case K_JOY26:
|
|
||||||
case K_JOY27:
|
|
||||||
case K_JOY28:
|
|
||||||
case K_JOY29:
|
|
||||||
case K_JOY30:
|
|
||||||
case K_JOY31:
|
|
||||||
|
|
||||||
case K_KP_ENTER:
|
case K_KP_ENTER:
|
||||||
case K_ENTER:
|
case K_ENTER:
|
||||||
|
case K_BTN_A:
|
||||||
return K_ENTER;
|
return K_ENTER;
|
||||||
|
|
||||||
case K_ESCAPE:
|
case K_ESCAPE:
|
||||||
case K_JOY_BACK:
|
case K_JOY_BACK:
|
||||||
|
case K_BTN_B:
|
||||||
return K_ESCAPE;
|
return K_ESCAPE;
|
||||||
|
|
||||||
|
case K_BACKSPACE:
|
||||||
|
case K_DEL:
|
||||||
|
case K_KP_DEL:
|
||||||
|
case K_BTN_Y:
|
||||||
|
return K_BACKSPACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return key;
|
return key;
|
||||||
|
@ -814,8 +792,7 @@ char *bindnames[][2] =
|
||||||
{"invdrop", "drop item"},
|
{"invdrop", "drop item"},
|
||||||
{"invprev", "prev item"},
|
{"invprev", "prev item"},
|
||||||
{"invnext", "next item"},
|
{"invnext", "next item"},
|
||||||
{"cmd help", "help computer"},
|
{"cmd help", "help computer"}
|
||||||
{"+joyaltselector", "enable alt joy keys"}
|
|
||||||
};
|
};
|
||||||
#define NUM_BINDNAMES (sizeof bindnames / sizeof bindnames[0])
|
#define NUM_BINDNAMES (sizeof bindnames / sizeof bindnames[0])
|
||||||
|
|
||||||
|
@ -827,14 +804,24 @@ static menuframework_s s_joy_menu;
|
||||||
static menuaction_s s_keys_actions[NUM_BINDNAMES];
|
static menuaction_s s_keys_actions[NUM_BINDNAMES];
|
||||||
|
|
||||||
static void
|
static void
|
||||||
M_UnbindCommand(char *command)
|
M_UnbindCommand(char *command, int scope)
|
||||||
{
|
{
|
||||||
int j;
|
int j;
|
||||||
int l;
|
int begin = 0, end = K_LAST;
|
||||||
|
switch (scope)
|
||||||
|
{
|
||||||
|
case KEYS_KEYBOARD_MOUSE:
|
||||||
|
end = K_JOY_FIRST_REGULAR;
|
||||||
|
break;
|
||||||
|
case KEYS_CONTROLLER:
|
||||||
|
begin = K_JOY_FIRST_REGULAR;
|
||||||
|
end = K_JOY_LAST_REGULAR + 1;
|
||||||
|
break;
|
||||||
|
case KEYS_CONTROLLER_ALT:
|
||||||
|
begin = K_JOY_FIRST_REGULAR_ALT;
|
||||||
|
}
|
||||||
|
|
||||||
l = strlen(command);
|
for (j = begin; j < end; j++)
|
||||||
|
|
||||||
for (j = 0; j < K_LAST; j++)
|
|
||||||
{
|
{
|
||||||
char *b;
|
char *b;
|
||||||
b = keybindings[j];
|
b = keybindings[j];
|
||||||
|
@ -844,7 +831,7 @@ M_UnbindCommand(char *command)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strncmp(b, command, l))
|
if (!strcmp(b, command))
|
||||||
{
|
{
|
||||||
Key_SetBinding(j, "");
|
Key_SetBinding(j, "");
|
||||||
}
|
}
|
||||||
|
@ -852,17 +839,28 @@ M_UnbindCommand(char *command)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
M_FindKeysForCommand(char *command, int *twokeys)
|
M_FindKeysForCommand(char *command, int *twokeys, int scope)
|
||||||
{
|
{
|
||||||
int count;
|
int count;
|
||||||
int j;
|
int j;
|
||||||
int l;
|
int begin = 0, end = K_LAST;
|
||||||
|
switch (scope)
|
||||||
|
{
|
||||||
|
case KEYS_KEYBOARD_MOUSE:
|
||||||
|
end = K_JOY_FIRST_REGULAR;
|
||||||
|
break;
|
||||||
|
case KEYS_CONTROLLER:
|
||||||
|
begin = K_JOY_FIRST_REGULAR;
|
||||||
|
end = K_JOY_LAST_REGULAR + 1;
|
||||||
|
break;
|
||||||
|
case KEYS_CONTROLLER_ALT:
|
||||||
|
begin = K_JOY_FIRST_REGULAR_ALT;
|
||||||
|
}
|
||||||
|
|
||||||
twokeys[0] = twokeys[1] = -1;
|
twokeys[0] = twokeys[1] = -1;
|
||||||
l = strlen(command);
|
|
||||||
count = 0;
|
count = 0;
|
||||||
|
|
||||||
for (j = 0; j < K_LAST; j++)
|
for (j = begin; j < end; j++)
|
||||||
{
|
{
|
||||||
char *b;
|
char *b;
|
||||||
b = keybindings[j];
|
b = keybindings[j];
|
||||||
|
@ -872,7 +870,7 @@ M_FindKeysForCommand(char *command, int *twokeys)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strncmp(b, command, l))
|
if (!strcmp(b, command))
|
||||||
{
|
{
|
||||||
twokeys[count] = j;
|
twokeys[count] = j;
|
||||||
count++;
|
count++;
|
||||||
|
@ -908,7 +906,7 @@ DrawKeyBindingFunc(void *self)
|
||||||
menuaction_s *a = (menuaction_s *)self;
|
menuaction_s *a = (menuaction_s *)self;
|
||||||
float scale = SCR_GetMenuScale();
|
float scale = SCR_GetMenuScale();
|
||||||
|
|
||||||
M_FindKeysForCommand(bindnames[a->generic.localdata[0]][0], keys);
|
M_FindKeysForCommand(bindnames[a->generic.localdata[0]][0], keys, KEYS_KEYBOARD_MOUSE);
|
||||||
|
|
||||||
if (keys[0] == -1)
|
if (keys[0] == -1)
|
||||||
{
|
{
|
||||||
|
@ -944,11 +942,11 @@ KeyBindingFunc(void *self)
|
||||||
menuaction_s *a = (menuaction_s *)self;
|
menuaction_s *a = (menuaction_s *)self;
|
||||||
int keys[2];
|
int keys[2];
|
||||||
|
|
||||||
M_FindKeysForCommand(bindnames[a->generic.localdata[0]][0], keys);
|
M_FindKeysForCommand(bindnames[a->generic.localdata[0]][0], keys, KEYS_KEYBOARD_MOUSE);
|
||||||
|
|
||||||
if (keys[1] != -1)
|
if (keys[1] != -1)
|
||||||
{
|
{
|
||||||
M_UnbindCommand(bindnames[a->generic.localdata[0]][0]);
|
M_UnbindCommand(bindnames[a->generic.localdata[0]][0], KEYS_KEYBOARD_MOUSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
menukeyitem_bind = true;
|
menukeyitem_bind = true;
|
||||||
|
@ -996,7 +994,8 @@ Keys_MenuKey(int key)
|
||||||
|
|
||||||
if (menukeyitem_bind)
|
if (menukeyitem_bind)
|
||||||
{
|
{
|
||||||
if ((key != K_ESCAPE) && (key != '`'))
|
// Any key/button except from the game controller and escape keys
|
||||||
|
if ((key != K_ESCAPE) && (key != '`') && (key < K_JOY_FIRST_REGULAR))
|
||||||
{
|
{
|
||||||
char cmd[1024];
|
char cmd[1024];
|
||||||
|
|
||||||
|
@ -1010,16 +1009,14 @@ Keys_MenuKey(int key)
|
||||||
return menu_out_sound;
|
return menu_out_sound;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
key = Key_GetMenuKey(key);
|
||||||
switch (key)
|
switch (key)
|
||||||
{
|
{
|
||||||
case K_KP_ENTER:
|
|
||||||
case K_ENTER:
|
case K_ENTER:
|
||||||
KeyBindingFunc(item);
|
KeyBindingFunc(item);
|
||||||
return menu_in_sound;
|
return menu_in_sound;
|
||||||
case K_BACKSPACE: /* delete bindings */
|
case K_BACKSPACE: /* delete bindings */
|
||||||
case K_DEL: /* delete bindings */
|
M_UnbindCommand(bindnames[item->generic.localdata[0]][0], KEYS_KEYBOARD_MOUSE);
|
||||||
case K_KP_DEL:
|
|
||||||
M_UnbindCommand(bindnames[item->generic.localdata[0]][0]);
|
|
||||||
return menu_out_sound;
|
return menu_out_sound;
|
||||||
default:
|
default:
|
||||||
return Default_MenuKey(&s_keys_menu, key);
|
return Default_MenuKey(&s_keys_menu, key);
|
||||||
|
@ -1059,7 +1056,7 @@ MultiplayerDrawKeyBindingFunc(void *self)
|
||||||
menuaction_s *a = (menuaction_s *)self;
|
menuaction_s *a = (menuaction_s *)self;
|
||||||
float scale = SCR_GetMenuScale();
|
float scale = SCR_GetMenuScale();
|
||||||
|
|
||||||
M_FindKeysForCommand(multiplayer_key_bindnames[a->generic.localdata[0]][0], keys);
|
M_FindKeysForCommand(multiplayer_key_bindnames[a->generic.localdata[0]][0], keys, KEYS_ALL);
|
||||||
|
|
||||||
if (keys[0] == -1)
|
if (keys[0] == -1)
|
||||||
{
|
{
|
||||||
|
@ -1095,11 +1092,11 @@ MultiplayerKeyBindingFunc(void *self)
|
||||||
menuaction_s *a = (menuaction_s *)self;
|
menuaction_s *a = (menuaction_s *)self;
|
||||||
int keys[2];
|
int keys[2];
|
||||||
|
|
||||||
M_FindKeysForCommand(multiplayer_key_bindnames[a->generic.localdata[0]][0], keys);
|
M_FindKeysForCommand(multiplayer_key_bindnames[a->generic.localdata[0]][0], keys, KEYS_ALL);
|
||||||
|
|
||||||
if (keys[1] != -1)
|
if (keys[1] != -1)
|
||||||
{
|
{
|
||||||
M_UnbindCommand(multiplayer_key_bindnames[a->generic.localdata[0]][0]);
|
M_UnbindCommand(multiplayer_key_bindnames[a->generic.localdata[0]][0], KEYS_ALL);
|
||||||
}
|
}
|
||||||
|
|
||||||
menukeyitem_bind = true;
|
menukeyitem_bind = true;
|
||||||
|
@ -1147,7 +1144,8 @@ MultiplayerKeys_MenuKey(int key)
|
||||||
|
|
||||||
if (menukeyitem_bind)
|
if (menukeyitem_bind)
|
||||||
{
|
{
|
||||||
if ((key != K_ESCAPE) && (key != '`'))
|
// Any key/button but the escape ones
|
||||||
|
if ((key != K_ESCAPE) && (key != '`') && (key != K_JOY_BACK))
|
||||||
{
|
{
|
||||||
char cmd[1024];
|
char cmd[1024];
|
||||||
|
|
||||||
|
@ -1161,16 +1159,14 @@ MultiplayerKeys_MenuKey(int key)
|
||||||
return menu_out_sound;
|
return menu_out_sound;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
key = Key_GetMenuKey(key);
|
||||||
switch (key)
|
switch (key)
|
||||||
{
|
{
|
||||||
case K_KP_ENTER:
|
|
||||||
case K_ENTER:
|
case K_ENTER:
|
||||||
MultiplayerKeyBindingFunc(item);
|
MultiplayerKeyBindingFunc(item);
|
||||||
return menu_in_sound;
|
return menu_in_sound;
|
||||||
case K_BACKSPACE: /* delete bindings */
|
case K_BACKSPACE: /* delete bindings */
|
||||||
case K_DEL: /* delete bindings */
|
M_UnbindCommand(multiplayer_key_bindnames[item->generic.localdata[0]][0], KEYS_ALL);
|
||||||
case K_KP_DEL:
|
|
||||||
M_UnbindCommand(multiplayer_key_bindnames[item->generic.localdata[0]][0]);
|
|
||||||
return menu_out_sound;
|
return menu_out_sound;
|
||||||
default:
|
default:
|
||||||
return Default_MenuKey(&s_multiplayer_keys_menu, key);
|
return Default_MenuKey(&s_multiplayer_keys_menu, key);
|
||||||
|
@ -1184,6 +1180,332 @@ M_Menu_Multiplayer_Keys_f(void)
|
||||||
M_PushMenu(MultiplayerKeys_MenuDraw, MultiplayerKeys_MenuKey);
|
M_PushMenu(MultiplayerKeys_MenuDraw, MultiplayerKeys_MenuKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GAME CONTROLLER ( GAMEPAD / JOYSTICK ) BUTTONS MENU
|
||||||
|
*/
|
||||||
|
|
||||||
|
char *controller_bindnames[][2] =
|
||||||
|
{
|
||||||
|
{"+attack", "attack"},
|
||||||
|
{"+moveup", "up / jump"},
|
||||||
|
{"+movedown", "down / crouch"},
|
||||||
|
{"weapnext", "next weapon"},
|
||||||
|
{"weapprev", "previous weapon"},
|
||||||
|
{"cycleweap weapon_chaingun weapon_machinegun weapon_blaster", "long range: quickswitch 1"},
|
||||||
|
{"cycleweap weapon_supershotgun weapon_shotgun", "close range: quickswitch 2"},
|
||||||
|
{"cycleweap weapon_rocketlauncher weapon_grenadelauncher ammo_grenades", "explosives: quickswitch 3"},
|
||||||
|
{"cycleweap weapon_bfg weapon_railgun weapon_hyperblaster", "special: quickswitch 4"},
|
||||||
|
{"prefweap weapon_railgun weapon_hyperblaster weapon_chaingun weapon_supershotgun weapon_machinegun weapon_shotgun weapon_blaster", "best safe weapon"},
|
||||||
|
{"prefweap weapon_bfg weapon_railgun weapon_rocketlauncher weapon_hyperblaster weapon_grenadelauncher weapon_chaingun ammo_grenades weapon_supershotgun", "best unsafe weapon"},
|
||||||
|
{"centerview", "center view"},
|
||||||
|
{"inven", "inventory"},
|
||||||
|
{"invuse", "use item"},
|
||||||
|
{"invdrop", "drop item"},
|
||||||
|
{"invprev", "prev item"},
|
||||||
|
{"invnext", "next item"},
|
||||||
|
{"cmd help", "help computer"},
|
||||||
|
{"+joyaltselector", "alt buttons modifier"}
|
||||||
|
};
|
||||||
|
#define NUM_CONTROLLER_BINDNAMES (sizeof controller_bindnames / sizeof controller_bindnames[0])
|
||||||
|
|
||||||
|
static menuframework_s s_controller_buttons_menu;
|
||||||
|
static menuaction_s s_controller_buttons_actions[NUM_CONTROLLER_BINDNAMES];
|
||||||
|
|
||||||
|
static void
|
||||||
|
DrawControllerButtonBindingFunc(void *self)
|
||||||
|
{
|
||||||
|
int keys[2];
|
||||||
|
menuaction_s *a = (menuaction_s *)self;
|
||||||
|
float scale = SCR_GetMenuScale();
|
||||||
|
|
||||||
|
M_FindKeysForCommand(controller_bindnames[a->generic.localdata[0]][0], keys, KEYS_CONTROLLER);
|
||||||
|
|
||||||
|
if (keys[0] == -1)
|
||||||
|
{
|
||||||
|
Menu_DrawString(a->generic.x + a->generic.parent->x + RCOLUMN_OFFSET * scale,
|
||||||
|
a->generic.y + a->generic.parent->y, "???");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
const char *name;
|
||||||
|
|
||||||
|
name = Key_KeynumToString(keys[0]);
|
||||||
|
|
||||||
|
Menu_DrawString(a->generic.x + a->generic.parent->x + RCOLUMN_OFFSET * scale,
|
||||||
|
a->generic.y + a->generic.parent->y, name);
|
||||||
|
|
||||||
|
x = strlen(name) * 8;
|
||||||
|
|
||||||
|
if (keys[1] != -1)
|
||||||
|
{
|
||||||
|
Menu_DrawString(a->generic.x + a->generic.parent->x + 24 * scale + (x * scale),
|
||||||
|
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]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ControllerButtonBindingFunc(void *self)
|
||||||
|
{
|
||||||
|
menuaction_s *a = (menuaction_s *)self;
|
||||||
|
int keys[2];
|
||||||
|
|
||||||
|
M_FindKeysForCommand(controller_bindnames[a->generic.localdata[0]][0], keys, KEYS_CONTROLLER);
|
||||||
|
|
||||||
|
if (keys[1] != -1)
|
||||||
|
{
|
||||||
|
M_UnbindCommand(controller_bindnames[a->generic.localdata[0]][0], KEYS_CONTROLLER);
|
||||||
|
}
|
||||||
|
|
||||||
|
menukeyitem_bind = true;
|
||||||
|
|
||||||
|
Menu_SetStatusBar(&s_controller_buttons_menu, "press a button for this action");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ControllerButtons_MenuInit(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
s_controller_buttons_menu.x = (int)(viddef.width * 0.50f);
|
||||||
|
s_controller_buttons_menu.nitems = 0;
|
||||||
|
s_controller_buttons_menu.cursordraw = KeyCursorDrawFunc;
|
||||||
|
|
||||||
|
for (i = 0; i < NUM_CONTROLLER_BINDNAMES; i++)
|
||||||
|
{
|
||||||
|
s_controller_buttons_actions[i].generic.type = MTYPE_ACTION;
|
||||||
|
s_controller_buttons_actions[i].generic.flags = QMF_GRAYED;
|
||||||
|
s_controller_buttons_actions[i].generic.x = 0;
|
||||||
|
s_controller_buttons_actions[i].generic.y = (i * 9);
|
||||||
|
s_controller_buttons_actions[i].generic.ownerdraw = DrawControllerButtonBindingFunc;
|
||||||
|
s_controller_buttons_actions[i].generic.localdata[0] = i;
|
||||||
|
s_controller_buttons_actions[i].generic.name = controller_bindnames[s_controller_buttons_actions[i].generic.localdata[0]][1];
|
||||||
|
|
||||||
|
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");
|
||||||
|
Menu_Center(&s_controller_buttons_menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ControllerButtons_MenuDraw(void)
|
||||||
|
{
|
||||||
|
Menu_AdjustCursor(&s_controller_buttons_menu, 1);
|
||||||
|
Menu_Draw(&s_controller_buttons_menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
ControllerButtons_MenuKey(int key)
|
||||||
|
{
|
||||||
|
menuaction_s *item = (menuaction_s *)Menu_ItemAtCursor(&s_controller_buttons_menu);
|
||||||
|
|
||||||
|
if (menukeyitem_bind)
|
||||||
|
{
|
||||||
|
// Only controller buttons allowed
|
||||||
|
if (key >= K_JOY_FIRST_REGULAR && key != K_JOY_BACK)
|
||||||
|
{
|
||||||
|
char cmd[1024];
|
||||||
|
|
||||||
|
Com_sprintf(cmd, sizeof(cmd), "bind \"%s\" \"%s\"\n",
|
||||||
|
Key_KeynumToString(key), controller_bindnames[item->generic.localdata[0]][0]);
|
||||||
|
Cbuf_InsertText(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
Menu_SetStatusBar(&s_controller_buttons_menu, "BTN_A assigns, BTN_Y clears, BTN_B exits");
|
||||||
|
menukeyitem_bind = false;
|
||||||
|
return menu_out_sound;
|
||||||
|
}
|
||||||
|
|
||||||
|
key = Key_GetMenuKey(key);
|
||||||
|
switch (key)
|
||||||
|
{
|
||||||
|
case K_ENTER:
|
||||||
|
ControllerButtonBindingFunc(item);
|
||||||
|
return menu_in_sound;
|
||||||
|
case K_BACKSPACE:
|
||||||
|
M_UnbindCommand(controller_bindnames[item->generic.localdata[0]][0], KEYS_CONTROLLER);
|
||||||
|
return menu_out_sound;
|
||||||
|
default:
|
||||||
|
return Default_MenuKey(&s_controller_buttons_menu, key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
M_Menu_ControllerButtons_f(void)
|
||||||
|
{
|
||||||
|
ControllerButtons_MenuInit();
|
||||||
|
M_PushMenu(ControllerButtons_MenuDraw, ControllerButtons_MenuKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GAME CONTROLLER ALTERNATE BUTTONS MENU
|
||||||
|
*/
|
||||||
|
|
||||||
|
char *controller_alt_bindnames[][2] =
|
||||||
|
{
|
||||||
|
{"weapnext", "next weapon"},
|
||||||
|
{"weapprev", "previous weapon"},
|
||||||
|
{"cycleweap weapon_chaingun weapon_machinegun weapon_blaster", "long range: quickswitch 1"},
|
||||||
|
{"cycleweap weapon_supershotgun weapon_shotgun", "close range: quickswitch 2"},
|
||||||
|
{"cycleweap weapon_rocketlauncher weapon_grenadelauncher ammo_grenades", "explosives: quickswitch 3"},
|
||||||
|
{"cycleweap weapon_bfg weapon_railgun weapon_hyperblaster", "special: quickswitch 4"},
|
||||||
|
{"prefweap weapon_railgun weapon_hyperblaster weapon_chaingun weapon_supershotgun weapon_machinegun weapon_shotgun weapon_blaster", "best safe weapon"},
|
||||||
|
{"prefweap weapon_bfg weapon_railgun weapon_rocketlauncher weapon_hyperblaster weapon_grenadelauncher weapon_chaingun ammo_grenades weapon_supershotgun", "best unsafe weapon"},
|
||||||
|
{"centerview", "center view"},
|
||||||
|
{"inven", "inventory"},
|
||||||
|
{"invuse", "use item"},
|
||||||
|
{"invdrop", "drop item"},
|
||||||
|
{"invprev", "prev item"},
|
||||||
|
{"invnext", "next item"},
|
||||||
|
{"use invulnerability", "use invulnerability"},
|
||||||
|
{"use rebreather", "use rebreather"},
|
||||||
|
{"use environment suit", "use environment suit"},
|
||||||
|
{"use power shield", "use power shield"},
|
||||||
|
{"use quad damage", "use quad damage"},
|
||||||
|
{"cmd help", "help computer"}
|
||||||
|
};
|
||||||
|
#define NUM_CONTROLLER_ALT_BINDNAMES (sizeof controller_alt_bindnames / sizeof controller_alt_bindnames[0])
|
||||||
|
|
||||||
|
static menuframework_s s_controller_alt_buttons_menu;
|
||||||
|
static menuaction_s s_controller_alt_buttons_actions[NUM_CONTROLLER_ALT_BINDNAMES];
|
||||||
|
|
||||||
|
static void
|
||||||
|
DrawControllerAltButtonBindingFunc(void *self)
|
||||||
|
{
|
||||||
|
int keys[2];
|
||||||
|
menuaction_s *a = (menuaction_s *)self;
|
||||||
|
float scale = SCR_GetMenuScale();
|
||||||
|
|
||||||
|
M_FindKeysForCommand(controller_alt_bindnames[a->generic.localdata[0]][0], keys, KEYS_CONTROLLER_ALT);
|
||||||
|
|
||||||
|
if (keys[0] == -1)
|
||||||
|
{
|
||||||
|
Menu_DrawString(a->generic.x + a->generic.parent->x + RCOLUMN_OFFSET * scale,
|
||||||
|
a->generic.y + a->generic.parent->y, "???");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
const char *name;
|
||||||
|
|
||||||
|
name = Key_KeynumToString(keys[0]);
|
||||||
|
|
||||||
|
Menu_DrawString(a->generic.x + a->generic.parent->x + RCOLUMN_OFFSET * scale,
|
||||||
|
a->generic.y + a->generic.parent->y, name);
|
||||||
|
|
||||||
|
x = strlen(name) * 8;
|
||||||
|
|
||||||
|
if (keys[1] != -1)
|
||||||
|
{
|
||||||
|
Menu_DrawString(a->generic.x + a->generic.parent->x + 24 * scale + (x * scale),
|
||||||
|
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]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ControllerAltButtonBindingFunc(void *self)
|
||||||
|
{
|
||||||
|
menuaction_s *a = (menuaction_s *)self;
|
||||||
|
int keys[2];
|
||||||
|
|
||||||
|
M_FindKeysForCommand(controller_alt_bindnames[a->generic.localdata[0]][0], keys, KEYS_CONTROLLER_ALT);
|
||||||
|
|
||||||
|
if (keys[1] != -1)
|
||||||
|
{
|
||||||
|
M_UnbindCommand(controller_alt_bindnames[a->generic.localdata[0]][0], KEYS_CONTROLLER_ALT);
|
||||||
|
}
|
||||||
|
|
||||||
|
menukeyitem_bind = true;
|
||||||
|
|
||||||
|
Menu_SetStatusBar(&s_controller_alt_buttons_menu, "press a button for this action");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ControllerAltButtons_MenuInit(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
s_controller_alt_buttons_menu.x = (int)(viddef.width * 0.50f);
|
||||||
|
s_controller_alt_buttons_menu.nitems = 0;
|
||||||
|
s_controller_alt_buttons_menu.cursordraw = KeyCursorDrawFunc;
|
||||||
|
|
||||||
|
for (i = 0; i < NUM_CONTROLLER_ALT_BINDNAMES; i++)
|
||||||
|
{
|
||||||
|
s_controller_alt_buttons_actions[i].generic.type = MTYPE_ACTION;
|
||||||
|
s_controller_alt_buttons_actions[i].generic.flags = QMF_GRAYED;
|
||||||
|
s_controller_alt_buttons_actions[i].generic.x = 0;
|
||||||
|
s_controller_alt_buttons_actions[i].generic.y = (i * 9);
|
||||||
|
s_controller_alt_buttons_actions[i].generic.ownerdraw = DrawControllerAltButtonBindingFunc;
|
||||||
|
s_controller_alt_buttons_actions[i].generic.localdata[0] = i;
|
||||||
|
s_controller_alt_buttons_actions[i].generic.name = controller_alt_bindnames[s_controller_alt_buttons_actions[i].generic.localdata[0]][1];
|
||||||
|
|
||||||
|
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");
|
||||||
|
Menu_Center(&s_controller_alt_buttons_menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ControllerAltButtons_MenuDraw(void)
|
||||||
|
{
|
||||||
|
Menu_AdjustCursor(&s_controller_alt_buttons_menu, 1);
|
||||||
|
Menu_Draw(&s_controller_alt_buttons_menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
ControllerAltButtons_MenuKey(int key)
|
||||||
|
{
|
||||||
|
menuaction_s *item = (menuaction_s *)Menu_ItemAtCursor(&s_controller_alt_buttons_menu);
|
||||||
|
|
||||||
|
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))
|
||||||
|
{
|
||||||
|
char cmd[1024];
|
||||||
|
key = key + (K_JOY_FIRST_REGULAR_ALT - K_JOY_FIRST_REGULAR); // 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");
|
||||||
|
menukeyitem_bind = false;
|
||||||
|
return menu_out_sound;
|
||||||
|
}
|
||||||
|
|
||||||
|
key = Key_GetMenuKey(key);
|
||||||
|
switch (key)
|
||||||
|
{
|
||||||
|
case K_ENTER:
|
||||||
|
ControllerAltButtonBindingFunc(item);
|
||||||
|
return menu_in_sound;
|
||||||
|
case K_BACKSPACE:
|
||||||
|
M_UnbindCommand(controller_alt_bindnames[item->generic.localdata[0]][0], KEYS_CONTROLLER_ALT);
|
||||||
|
return menu_out_sound;
|
||||||
|
default:
|
||||||
|
return Default_MenuKey(&s_controller_alt_buttons_menu, key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
M_Menu_ControllerAltButtons_f(void)
|
||||||
|
{
|
||||||
|
ControllerAltButtons_MenuInit();
|
||||||
|
M_PushMenu(ControllerAltButtons_MenuDraw, ControllerAltButtons_MenuKey);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* JOY MENU
|
* JOY MENU
|
||||||
*/
|
*/
|
||||||
|
@ -1194,6 +1516,20 @@ static menuslider_s s_joy_forwardsensitivity_slider;
|
||||||
static menuslider_s s_joy_sidesensitivity_slider;
|
static menuslider_s s_joy_sidesensitivity_slider;
|
||||||
static menuslider_s s_joy_upsensitivity_slider;
|
static menuslider_s s_joy_upsensitivity_slider;
|
||||||
static menuslider_s s_joy_haptic_slider;
|
static menuslider_s s_joy_haptic_slider;
|
||||||
|
static menuaction_s s_joy_customize_buttons_action;
|
||||||
|
static menuaction_s s_joy_customize_alt_buttons_action;
|
||||||
|
|
||||||
|
static void
|
||||||
|
CustomizeControllerButtonsFunc(void *unused)
|
||||||
|
{
|
||||||
|
M_Menu_ControllerButtons_f();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
CustomizeControllerAltButtonsFunc(void *unused)
|
||||||
|
{
|
||||||
|
M_Menu_ControllerAltButtons_f();
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
HapticMagnitudeFunc(void *unused)
|
HapticMagnitudeFunc(void *unused)
|
||||||
|
@ -1333,6 +1669,24 @@ Joy_MenuInit(void)
|
||||||
Menu_AddItem(&s_joy_menu, (void *)&s_joy_haptic_slider);
|
Menu_AddItem(&s_joy_menu, (void *)&s_joy_haptic_slider);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
y += 10;
|
||||||
|
|
||||||
|
s_joy_customize_buttons_action.generic.type = MTYPE_ACTION;
|
||||||
|
s_joy_customize_buttons_action.generic.x = 0;
|
||||||
|
s_joy_customize_buttons_action.generic.y = y;
|
||||||
|
y += 10;
|
||||||
|
s_joy_customize_buttons_action.generic.name = "customize buttons";
|
||||||
|
s_joy_customize_buttons_action.generic.callback = CustomizeControllerButtonsFunc;
|
||||||
|
Menu_AddItem(&s_joy_menu, (void *)&s_joy_customize_buttons_action);
|
||||||
|
|
||||||
|
s_joy_customize_alt_buttons_action.generic.type = MTYPE_ACTION;
|
||||||
|
s_joy_customize_alt_buttons_action.generic.x = 0;
|
||||||
|
s_joy_customize_alt_buttons_action.generic.y = y;
|
||||||
|
y += 10;
|
||||||
|
s_joy_customize_alt_buttons_action.generic.name = "customize alt buttons";
|
||||||
|
s_joy_customize_alt_buttons_action.generic.callback = CustomizeControllerAltButtonsFunc;
|
||||||
|
Menu_AddItem(&s_joy_menu, (void *)&s_joy_customize_alt_buttons_action);
|
||||||
|
|
||||||
Menu_Center(&s_joy_menu);
|
Menu_Center(&s_joy_menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1702,7 +2056,7 @@ Options_MenuInit(void)
|
||||||
s_options_customize_joy_action.generic.type = MTYPE_ACTION;
|
s_options_customize_joy_action.generic.type = MTYPE_ACTION;
|
||||||
s_options_customize_joy_action.generic.x = 0;
|
s_options_customize_joy_action.generic.x = 0;
|
||||||
s_options_customize_joy_action.generic.y = 130;
|
s_options_customize_joy_action.generic.y = 130;
|
||||||
s_options_customize_joy_action.generic.name = "customize joystick";
|
s_options_customize_joy_action.generic.name = "customize gamepad";
|
||||||
s_options_customize_joy_action.generic.callback = CustomizeJoyFunc;
|
s_options_customize_joy_action.generic.callback = CustomizeJoyFunc;
|
||||||
|
|
||||||
s_options_customize_options_action.generic.type = MTYPE_ACTION;
|
s_options_customize_options_action.generic.type = MTYPE_ACTION;
|
||||||
|
@ -2892,8 +3246,6 @@ LoadGame_MenuKey(int key)
|
||||||
return menu_move_sound;
|
return menu_move_sound;
|
||||||
|
|
||||||
case K_BACKSPACE:
|
case K_BACKSPACE:
|
||||||
case K_DEL:
|
|
||||||
case K_KP_DEL:
|
|
||||||
if ((item = Menu_ItemAtCursor(m)) != NULL)
|
if ((item = Menu_ItemAtCursor(m)) != NULL)
|
||||||
{
|
{
|
||||||
if (item->type == MTYPE_ACTION)
|
if (item->type == MTYPE_ACTION)
|
||||||
|
@ -3064,8 +3416,6 @@ SaveGame_MenuKey(int key)
|
||||||
return menu_move_sound;
|
return menu_move_sound;
|
||||||
|
|
||||||
case K_BACKSPACE:
|
case K_BACKSPACE:
|
||||||
case K_DEL:
|
|
||||||
case K_KP_DEL:
|
|
||||||
if ((item = Menu_ItemAtCursor(m)) != NULL)
|
if ((item = Menu_ItemAtCursor(m)) != NULL)
|
||||||
{
|
{
|
||||||
if (item->type == MTYPE_ACTION)
|
if (item->type == MTYPE_ACTION)
|
||||||
|
@ -5078,6 +5428,8 @@ M_Init(void)
|
||||||
Cmd_AddCommand("menu_options", M_Menu_Options_f);
|
Cmd_AddCommand("menu_options", M_Menu_Options_f);
|
||||||
Cmd_AddCommand("menu_keys", M_Menu_Keys_f);
|
Cmd_AddCommand("menu_keys", M_Menu_Keys_f);
|
||||||
Cmd_AddCommand("menu_joy", M_Menu_Joy_f);
|
Cmd_AddCommand("menu_joy", M_Menu_Joy_f);
|
||||||
|
Cmd_AddCommand("menu_buttons", M_Menu_ControllerButtons_f);
|
||||||
|
Cmd_AddCommand("menu_altbuttons", M_Menu_ControllerAltButtons_f);
|
||||||
Cmd_AddCommand("menu_quit", M_Menu_Quit_f);
|
Cmd_AddCommand("menu_quit", M_Menu_Quit_f);
|
||||||
|
|
||||||
/* initialize the server address book cvars (adr0, adr1, ...)
|
/* initialize the server address book cvars (adr0, adr1, ...)
|
||||||
|
|
Loading…
Reference in a new issue