mirror of
https://github.com/Shpoike/Quakespasm.git
synced 2024-11-10 07:21:58 +00:00
SDL2 Game Controller support
git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@1293 af15c1b1-3010-417e-b628-4374ebc0bcbd
This commit is contained in:
parent
9c9facfe7b
commit
dc2218b9c8
12 changed files with 501 additions and 26 deletions
|
@ -93,6 +93,14 @@ bind MOUSE1 +attack
|
|||
bind MOUSE2 +jump
|
||||
//bind MOUSE3 +mlook
|
||||
|
||||
//
|
||||
// game controller
|
||||
//
|
||||
bind LSHOULDER "impulse 12"
|
||||
bind RSHOULDER "impulse 10"
|
||||
bind LTRIGGER +jump
|
||||
bind RTRIGGER +attack
|
||||
|
||||
//
|
||||
// default cvars
|
||||
//
|
||||
|
|
|
@ -701,10 +701,10 @@ void GL_SetCanvas (canvastype newcanvas)
|
|||
glViewport (glx, gly, glwidth, glheight);
|
||||
break;
|
||||
case CANVAS_MENU:
|
||||
s = q_min((float)glwidth / 320.0, (float)glheight / 200.0);
|
||||
s = q_min((float)glwidth / 640.0, (float)glheight / 200.0); // ericw -- doubled width to 640 to accommodate long keybindings
|
||||
s = CLAMP (1.0, scr_menuscale.value, s);
|
||||
glOrtho (0, 320, 200, 0, -99999, 99999);
|
||||
glViewport (glx + (glwidth - 320*s) / 2, gly + (glheight - 200*s) / 2, 320*s, 200*s);
|
||||
glOrtho (0, 640, 200, 0, -99999, 99999);
|
||||
glViewport (glx + (glwidth - 320*s) / 2, gly + (glheight - 200*s) / 2, 640*s, 200*s);
|
||||
break;
|
||||
case CANVAS_SBAR:
|
||||
s = CLAMP (1.0, scr_sbarscale.value, (float)glwidth / 320.0);
|
||||
|
|
|
@ -924,6 +924,8 @@ int SCR_ModalMessage (const char *text, float timeout) //johnfitz -- timeout
|
|||
} while (lastchar != 'y' && lastchar != 'Y' &&
|
||||
lastchar != 'n' && lastchar != 'N' &&
|
||||
lastkey != K_ESCAPE &&
|
||||
lastkey != K_ABUTTON &&
|
||||
lastkey != K_BBUTTON &&
|
||||
time2 <= time1);
|
||||
Key_EndInputGrab ();
|
||||
|
||||
|
@ -934,7 +936,7 @@ int SCR_ModalMessage (const char *text, float timeout) //johnfitz -- timeout
|
|||
return false;
|
||||
//johnfitz
|
||||
|
||||
return (lastchar == 'y' || lastchar == 'Y');
|
||||
return (lastchar == 'y' || lastchar == 'Y' || lastkey == K_ABUTTON);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1951,6 +1951,7 @@ static void VID_MenuKey (int key)
|
|||
switch (key)
|
||||
{
|
||||
case K_ESCAPE:
|
||||
case K_BBUTTON:
|
||||
VID_SyncCvars (); //sync cvars before leaving menu. FIXME: there are other ways to leave menu
|
||||
S_LocalSound ("misc/menu1.wav");
|
||||
M_Menu_Options_f ();
|
||||
|
@ -2014,6 +2015,7 @@ static void VID_MenuKey (int key)
|
|||
|
||||
case K_ENTER:
|
||||
case K_KP_ENTER:
|
||||
case K_ABUTTON:
|
||||
m_entersound = true;
|
||||
switch (video_options_cursor)
|
||||
{
|
||||
|
|
423
Quake/in_sdl.c
423
Quake/in_sdl.c
|
@ -48,6 +48,21 @@ static cvar_t in_debugkeys = {"in_debugkeys", "0", CVAR_NONE};
|
|||
#include <IOKit/hidsystem/event_status_driver.h>
|
||||
#endif
|
||||
|
||||
// SDL2 Game Controller cvars
|
||||
cvar_t joy_deadzone = { "joy_deadzone", "0.2", CVAR_NONE };
|
||||
cvar_t joy_deadzone_trigger = { "joy_deadzone_trigger", "0.001", CVAR_NONE };
|
||||
cvar_t joy_sensitivity_yaw = { "joy_sensitivity_yaw", "300", CVAR_NONE };
|
||||
cvar_t joy_sensitivity_pitch = { "joy_sensitivity_pitch", "150", CVAR_NONE };
|
||||
cvar_t joy_invert = { "joy_invert", "0", CVAR_NONE };
|
||||
cvar_t joy_exponent = { "joy_exponent", "3", CVAR_NONE };
|
||||
cvar_t joy_swapmovelook = { "joy_swapmovelook", "0", CVAR_NONE };
|
||||
cvar_t joy_enable = { "joy_enable", "1", CVAR_NONE };
|
||||
|
||||
#if defined(USE_SDL2)
|
||||
static SDL_JoystickID joy_active_instaceid = -1;
|
||||
static SDL_GameController *joy_active_controller = NULL;
|
||||
#endif
|
||||
|
||||
static qboolean no_mouse = false;
|
||||
|
||||
static int buttonremap[] =
|
||||
|
@ -257,6 +272,63 @@ void IN_Deactivate (qboolean free_cursor)
|
|||
IN_BeginIgnoringMouseEvents();
|
||||
}
|
||||
|
||||
void IN_StartupJoystick (void)
|
||||
{
|
||||
#if defined(USE_SDL2)
|
||||
int i;
|
||||
int nummappings;
|
||||
char controllerdb[MAX_OSPATH];
|
||||
SDL_GameController *gamecontroller;
|
||||
|
||||
if (COM_CheckParm("-nojoy"))
|
||||
return;
|
||||
|
||||
// Load additional SDL2 controller definitions from gamecontrollerdb.txt
|
||||
q_snprintf (controllerdb, sizeof(controllerdb), "%s/gamecontrollerdb.txt", com_basedir);
|
||||
nummappings = SDL_GameControllerAddMappingsFromFile(controllerdb);
|
||||
if (nummappings)
|
||||
Con_Printf("%d mappings loaded from gamecontrollerdb.txt\n", nummappings);
|
||||
|
||||
// Also try host_parms->userdir
|
||||
if (host_parms->userdir != host_parms->basedir)
|
||||
{
|
||||
q_snprintf (controllerdb, sizeof(controllerdb), "%s/gamecontrollerdb.txt", host_parms->userdir);
|
||||
nummappings = SDL_GameControllerAddMappingsFromFile(controllerdb);
|
||||
if (nummappings)
|
||||
Con_Printf("%d mappings loaded from gamecontrollerdb.txt\n", nummappings);
|
||||
}
|
||||
|
||||
if (SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER) == -1 )
|
||||
{
|
||||
Con_Printf("WARNING: Could not initialize SDL Game Controller\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < SDL_NumJoysticks(); i++)
|
||||
{
|
||||
if ( SDL_IsGameController(i) )
|
||||
{
|
||||
gamecontroller = SDL_GameControllerOpen(i);
|
||||
if (gamecontroller)
|
||||
{
|
||||
Con_Printf("detected controller: %s\n", SDL_GameControllerNameForIndex(i));
|
||||
|
||||
joy_active_instaceid = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(gamecontroller));
|
||||
joy_active_controller = gamecontroller;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void IN_ShutdownJoystick (void)
|
||||
{
|
||||
#if defined(USE_SDL2)
|
||||
SDL_QuitSubSystem(SDL_INIT_GAMECONTROLLER);
|
||||
#endif
|
||||
}
|
||||
|
||||
void IN_Init (void)
|
||||
{
|
||||
textmode = Key_TextEntry();
|
||||
|
@ -282,31 +354,328 @@ void IN_Init (void)
|
|||
Cvar_RegisterVariable(&in_disablemacosxmouseaccel);
|
||||
#endif
|
||||
Cvar_RegisterVariable(&in_debugkeys);
|
||||
Cvar_RegisterVariable(&joy_sensitivity_yaw);
|
||||
Cvar_RegisterVariable(&joy_sensitivity_pitch);
|
||||
Cvar_RegisterVariable(&joy_deadzone);
|
||||
Cvar_RegisterVariable(&joy_deadzone_trigger);
|
||||
Cvar_RegisterVariable(&joy_invert);
|
||||
Cvar_RegisterVariable(&joy_exponent);
|
||||
Cvar_RegisterVariable(&joy_swapmovelook);
|
||||
Cvar_RegisterVariable(&joy_enable);
|
||||
|
||||
IN_Activate();
|
||||
IN_StartupJoystick();
|
||||
}
|
||||
|
||||
void IN_Shutdown (void)
|
||||
{
|
||||
IN_Deactivate(true);
|
||||
}
|
||||
|
||||
void IN_Commands (void)
|
||||
{
|
||||
/* TODO: implement this for joystick support */
|
||||
IN_ShutdownJoystick();
|
||||
}
|
||||
|
||||
extern cvar_t cl_maxpitch; /* johnfitz -- variable pitch clamping */
|
||||
extern cvar_t cl_minpitch; /* johnfitz -- variable pitch clamping */
|
||||
|
||||
|
||||
void IN_MouseMove(int dx, int dy)
|
||||
void IN_MouseMotion(int dx, int dy)
|
||||
{
|
||||
total_dx += dx;
|
||||
total_dy += dy;
|
||||
}
|
||||
|
||||
void IN_Move (usercmd_t *cmd)
|
||||
#if defined(USE_SDL2)
|
||||
typedef struct joyaxis_s
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
} joyaxis_t;
|
||||
|
||||
typedef struct joy_buttonstate_s
|
||||
{
|
||||
qboolean buttondown[SDL_CONTROLLER_BUTTON_MAX];
|
||||
} joybuttonstate_t;
|
||||
|
||||
typedef struct axisstate_s
|
||||
{
|
||||
float axisvalue[SDL_CONTROLLER_AXIS_MAX]; // normalized to +-1
|
||||
} joyaxisstate_t;
|
||||
|
||||
static joybuttonstate_t joy_buttonstate;
|
||||
static joyaxisstate_t joy_axisstate;
|
||||
|
||||
static double joy_buttontimer[SDL_CONTROLLER_BUTTON_MAX];
|
||||
static double joy_emulatedkeytimer[10];
|
||||
|
||||
/*
|
||||
================
|
||||
IN_ApplyEasing
|
||||
|
||||
assumes axis values are in [-1, 1]. Raises the axis values to the given exponent, keeping signs.
|
||||
================
|
||||
*/
|
||||
static joyaxis_t IN_ApplyEasing(joyaxis_t axis, float exponent)
|
||||
{
|
||||
joyaxis_t result = {0};
|
||||
float magnitude, eased_magnitude;
|
||||
|
||||
magnitude = sqrtf( (axis.x * axis.x) + (axis.y * axis.y) );
|
||||
|
||||
if (magnitude > 1)
|
||||
magnitude = 1;
|
||||
|
||||
if (magnitude == 0)
|
||||
return result;
|
||||
|
||||
eased_magnitude = powf(magnitude, exponent);
|
||||
|
||||
result.x = axis.x * (eased_magnitude / magnitude);
|
||||
result.y = axis.y * (eased_magnitude / magnitude);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
IN_ApplyMoveEasing
|
||||
|
||||
clamps coordinates to a square with coordinates +/- sqrt(2)/2, then scales them to +/- 1.
|
||||
This wastes a bit of stick range, but gives the diagonals coordinates of (+/-1,+/-1),
|
||||
so holding the stick on a diagonal gives the same speed boost as holding the forward and strafe keyboard keys.
|
||||
================
|
||||
*/
|
||||
static joyaxis_t IN_ApplyMoveEasing(joyaxis_t axis)
|
||||
{
|
||||
joyaxis_t result = {0};
|
||||
const float v = sqrtf(2.0f) / 2.0f;
|
||||
|
||||
result.x = q_max(-v, q_min(v, axis.x));
|
||||
result.y = q_max(-v, q_min(v, axis.y));
|
||||
|
||||
result.x /= v;
|
||||
result.y /= v;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
IN_ApplyDeadzone
|
||||
|
||||
from https://github.com/jeremiah-sypult/Quakespasm-Rift
|
||||
and adapted from http://www.third-helix.com/2013/04/12/doing-thumbstick-dead-zones-right.html
|
||||
================
|
||||
*/
|
||||
static joyaxis_t IN_ApplyDeadzone(joyaxis_t axis, float deadzone)
|
||||
{
|
||||
joyaxis_t result = {0};
|
||||
float magnitude = sqrtf( (axis.x * axis.x) + (axis.y * axis.y) );
|
||||
|
||||
if ( magnitude < deadzone ) {
|
||||
result.x = result.y = 0.0f;
|
||||
} else {
|
||||
joyaxis_t normalized;
|
||||
float gradient;
|
||||
|
||||
if ( magnitude > 1.0f ) {
|
||||
magnitude = 1.0f;
|
||||
}
|
||||
|
||||
normalized.x = axis.x / magnitude;
|
||||
normalized.y = axis.y / magnitude;
|
||||
gradient = ( (magnitude - deadzone) / (1.0f - deadzone) );
|
||||
result.x = normalized.x * gradient;
|
||||
result.y = normalized.y * gradient;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
IN_KeyForControllerButton
|
||||
================
|
||||
*/
|
||||
static int IN_KeyForControllerButton(SDL_GameControllerButton button)
|
||||
{
|
||||
switch (button)
|
||||
{
|
||||
case SDL_CONTROLLER_BUTTON_A: return K_ABUTTON;
|
||||
case SDL_CONTROLLER_BUTTON_B: return K_BBUTTON;
|
||||
case SDL_CONTROLLER_BUTTON_X: return K_XBUTTON;
|
||||
case SDL_CONTROLLER_BUTTON_Y: return K_YBUTTON;
|
||||
case SDL_CONTROLLER_BUTTON_BACK: return K_TAB;
|
||||
case SDL_CONTROLLER_BUTTON_START: return K_ESCAPE;
|
||||
case SDL_CONTROLLER_BUTTON_LEFTSTICK: return K_LTHUMB;
|
||||
case SDL_CONTROLLER_BUTTON_RIGHTSTICK: return K_RTHUMB;
|
||||
case SDL_CONTROLLER_BUTTON_LEFTSHOULDER: return K_LSHOULDER;
|
||||
case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER: return K_RSHOULDER;
|
||||
case SDL_CONTROLLER_BUTTON_DPAD_UP: return K_UPARROW;
|
||||
case SDL_CONTROLLER_BUTTON_DPAD_DOWN: return K_DOWNARROW;
|
||||
case SDL_CONTROLLER_BUTTON_DPAD_LEFT: return K_LEFTARROW;
|
||||
case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: return K_RIGHTARROW;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
IN_JoyKeyEvent
|
||||
|
||||
Sends a Key_Event if a unpressed -> pressed or pressed -> unpressed transition occurred,
|
||||
and generates key repeats if the button is held down.
|
||||
|
||||
Adapted from DarkPlaces by lordhavoc
|
||||
================
|
||||
*/
|
||||
static void IN_JoyKeyEvent(qboolean wasdown, qboolean isdown, int key, double *timer)
|
||||
{
|
||||
// we can't use `realtime` for key repeats because it is not monotomic
|
||||
const double currenttime = Sys_DoubleTime();
|
||||
|
||||
if (wasdown)
|
||||
{
|
||||
if (isdown)
|
||||
{
|
||||
if (currenttime >= *timer)
|
||||
{
|
||||
*timer = currenttime + 0.1;
|
||||
Key_Event(key, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*timer = 0;
|
||||
Key_Event(key, false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isdown)
|
||||
{
|
||||
*timer = currenttime + 0.5;
|
||||
Key_Event(key, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
================
|
||||
IN_Commands
|
||||
|
||||
Emit key events for game controller buttons, including emulated buttons for analog sticks/triggers
|
||||
================
|
||||
*/
|
||||
void IN_Commands (void)
|
||||
{
|
||||
#if defined(USE_SDL2)
|
||||
joyaxisstate_t newaxisstate;
|
||||
int i;
|
||||
const float stickthreshold = 0.9;
|
||||
const float triggerthreshold = joy_deadzone_trigger.value;
|
||||
|
||||
if (!joy_enable.value)
|
||||
return;
|
||||
|
||||
if (!joy_active_controller)
|
||||
return;
|
||||
|
||||
// emit key events for controller buttons
|
||||
for (i = 0; i < SDL_CONTROLLER_BUTTON_MAX; i++)
|
||||
{
|
||||
qboolean newstate = SDL_GameControllerGetButton(joy_active_controller, i);
|
||||
qboolean oldstate = joy_buttonstate.buttondown[i];
|
||||
|
||||
joy_buttonstate.buttondown[i] = newstate;
|
||||
|
||||
// NOTE: This can cause a reentrant call of IN_Commands, via SCR_ModalMessage when confirming a new game.
|
||||
IN_JoyKeyEvent(oldstate, newstate, IN_KeyForControllerButton(i), &joy_buttontimer[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < SDL_CONTROLLER_AXIS_MAX; i++)
|
||||
{
|
||||
newaxisstate.axisvalue[i] = SDL_GameControllerGetAxis(joy_active_controller, i) / 32768.0f;
|
||||
}
|
||||
|
||||
// emit emulated arrow keys so the analog sticks can be used in the menu
|
||||
if (key_dest != key_game)
|
||||
{
|
||||
IN_JoyKeyEvent(joy_axisstate.axisvalue[SDL_CONTROLLER_AXIS_LEFTX] < -stickthreshold, newaxisstate.axisvalue[SDL_CONTROLLER_AXIS_LEFTX] < -stickthreshold, K_LEFTARROW, &joy_emulatedkeytimer[0]);
|
||||
IN_JoyKeyEvent(joy_axisstate.axisvalue[SDL_CONTROLLER_AXIS_LEFTX] > stickthreshold, newaxisstate.axisvalue[SDL_CONTROLLER_AXIS_LEFTX] > stickthreshold, K_RIGHTARROW, &joy_emulatedkeytimer[1]);
|
||||
IN_JoyKeyEvent(joy_axisstate.axisvalue[SDL_CONTROLLER_AXIS_LEFTY] < -stickthreshold, newaxisstate.axisvalue[SDL_CONTROLLER_AXIS_LEFTY] < -stickthreshold, K_UPARROW, &joy_emulatedkeytimer[2]);
|
||||
IN_JoyKeyEvent(joy_axisstate.axisvalue[SDL_CONTROLLER_AXIS_LEFTY] > stickthreshold, newaxisstate.axisvalue[SDL_CONTROLLER_AXIS_LEFTY] > stickthreshold, K_DOWNARROW, &joy_emulatedkeytimer[3]);
|
||||
IN_JoyKeyEvent(joy_axisstate.axisvalue[SDL_CONTROLLER_AXIS_RIGHTX] < -stickthreshold,newaxisstate.axisvalue[SDL_CONTROLLER_AXIS_RIGHTX] < -stickthreshold, K_LEFTARROW, &joy_emulatedkeytimer[4]);
|
||||
IN_JoyKeyEvent(joy_axisstate.axisvalue[SDL_CONTROLLER_AXIS_RIGHTX] > stickthreshold, newaxisstate.axisvalue[SDL_CONTROLLER_AXIS_RIGHTX] > stickthreshold, K_RIGHTARROW, &joy_emulatedkeytimer[5]);
|
||||
IN_JoyKeyEvent(joy_axisstate.axisvalue[SDL_CONTROLLER_AXIS_RIGHTY] < -stickthreshold,newaxisstate.axisvalue[SDL_CONTROLLER_AXIS_RIGHTY] < -stickthreshold, K_UPARROW, &joy_emulatedkeytimer[6]);
|
||||
IN_JoyKeyEvent(joy_axisstate.axisvalue[SDL_CONTROLLER_AXIS_RIGHTY] > stickthreshold, newaxisstate.axisvalue[SDL_CONTROLLER_AXIS_RIGHTY] > stickthreshold, K_DOWNARROW, &joy_emulatedkeytimer[7]);
|
||||
}
|
||||
|
||||
// emit emulated keys for the analog triggers
|
||||
IN_JoyKeyEvent(joy_axisstate.axisvalue[SDL_CONTROLLER_AXIS_TRIGGERLEFT] > triggerthreshold, newaxisstate.axisvalue[SDL_CONTROLLER_AXIS_TRIGGERLEFT] > triggerthreshold, K_LTRIGGER, &joy_emulatedkeytimer[8]);
|
||||
IN_JoyKeyEvent(joy_axisstate.axisvalue[SDL_CONTROLLER_AXIS_TRIGGERRIGHT] > triggerthreshold, newaxisstate.axisvalue[SDL_CONTROLLER_AXIS_TRIGGERRIGHT] > triggerthreshold, K_RTRIGGER, &joy_emulatedkeytimer[9]);
|
||||
|
||||
joy_axisstate = newaxisstate;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
IN_JoyMove
|
||||
================
|
||||
*/
|
||||
void IN_JoyMove (usercmd_t *cmd)
|
||||
{
|
||||
#if defined(USE_SDL2)
|
||||
float speed;
|
||||
joyaxis_t moveAxis, lookAxis;
|
||||
|
||||
if (!joy_enable.value)
|
||||
return;
|
||||
|
||||
if (!joy_active_controller)
|
||||
return;
|
||||
|
||||
moveAxis.x = joy_axisstate.axisvalue[SDL_CONTROLLER_AXIS_LEFTX];
|
||||
moveAxis.y = joy_axisstate.axisvalue[SDL_CONTROLLER_AXIS_LEFTY];
|
||||
lookAxis.x = joy_axisstate.axisvalue[SDL_CONTROLLER_AXIS_RIGHTX];
|
||||
lookAxis.y = joy_axisstate.axisvalue[SDL_CONTROLLER_AXIS_RIGHTY];
|
||||
|
||||
if (joy_swapmovelook.value)
|
||||
{
|
||||
joyaxis_t temp = moveAxis;
|
||||
moveAxis = lookAxis;
|
||||
lookAxis = temp;
|
||||
}
|
||||
|
||||
moveAxis = IN_ApplyDeadzone(moveAxis, joy_deadzone.value);
|
||||
lookAxis = IN_ApplyDeadzone(lookAxis, joy_deadzone.value);
|
||||
|
||||
moveAxis = IN_ApplyMoveEasing(moveAxis);
|
||||
lookAxis = IN_ApplyEasing(lookAxis, joy_exponent.value);
|
||||
|
||||
if (in_speed.state & 1)
|
||||
speed = cl_movespeedkey.value;
|
||||
else
|
||||
speed = 1;
|
||||
|
||||
cmd->sidemove += (cl_sidespeed.value * speed * moveAxis.x);
|
||||
cmd->forwardmove -= (cl_forwardspeed.value * speed * moveAxis.y);
|
||||
|
||||
cl.viewangles[YAW] -= lookAxis.x * joy_sensitivity_yaw.value * host_frametime;
|
||||
cl.viewangles[PITCH] += lookAxis.y * joy_sensitivity_pitch.value * (joy_invert.value ? -1.0 : 1.0) * host_frametime;
|
||||
|
||||
if (lookAxis.x != 0 || lookAxis.y != 0)
|
||||
V_StopPitchDrift();
|
||||
|
||||
/* johnfitz -- variable pitch clamping */
|
||||
if (cl.viewangles[PITCH] > cl_maxpitch.value)
|
||||
cl.viewangles[PITCH] = cl_maxpitch.value;
|
||||
if (cl.viewangles[PITCH] < cl_minpitch.value)
|
||||
cl.viewangles[PITCH] = cl_minpitch.value;
|
||||
#endif
|
||||
}
|
||||
|
||||
void IN_MouseMove(usercmd_t *cmd)
|
||||
{
|
||||
int dmx, dmy;
|
||||
|
||||
|
@ -345,6 +714,12 @@ void IN_Move (usercmd_t *cmd)
|
|||
}
|
||||
}
|
||||
|
||||
void IN_Move(usercmd_t *cmd)
|
||||
{
|
||||
IN_JoyMove(cmd);
|
||||
IN_MouseMove(cmd);
|
||||
}
|
||||
|
||||
void IN_ClearStates (void)
|
||||
{
|
||||
}
|
||||
|
@ -682,9 +1057,41 @@ void IN_SendKeyEvents (void)
|
|||
#endif
|
||||
|
||||
case SDL_MOUSEMOTION:
|
||||
IN_MouseMove(event.motion.xrel, event.motion.yrel);
|
||||
IN_MouseMotion(event.motion.xrel, event.motion.yrel);
|
||||
break;
|
||||
|
||||
#if defined(USE_SDL2)
|
||||
case SDL_CONTROLLERDEVICEADDED:
|
||||
if (joy_active_instaceid == -1)
|
||||
{
|
||||
joy_active_controller = SDL_GameControllerOpen(event.cdevice.which);
|
||||
if (joy_active_controller == NULL)
|
||||
Con_DPrintf("Couldn't open game controller\n");
|
||||
else
|
||||
{
|
||||
SDL_Joystick *joy;
|
||||
joy = SDL_GameControllerGetJoystick(joy_active_controller);
|
||||
joy_active_instaceid = SDL_JoystickInstanceID(joy);
|
||||
}
|
||||
}
|
||||
else
|
||||
Con_DPrintf("Ignoring SDL_CONTROLLERDEVICEADDED\n");
|
||||
break;
|
||||
case SDL_CONTROLLERDEVICEREMOVED:
|
||||
if (joy_active_instaceid != -1 && event.cdevice.which == joy_active_instaceid)
|
||||
{
|
||||
SDL_GameControllerClose(joy_active_controller);
|
||||
joy_active_controller = NULL;
|
||||
joy_active_instaceid = -1;
|
||||
}
|
||||
else
|
||||
Con_DPrintf("Ignoring SDL_CONTROLLERDEVICEREMOVED\n");
|
||||
break;
|
||||
case SDL_CONTROLLERDEVICEREMAPPED:
|
||||
Con_DPrintf("Ignoring SDL_CONTROLLERDEVICEREMAPPED\n");
|
||||
break;
|
||||
#endif
|
||||
|
||||
case SDL_QUIT:
|
||||
CL_Disconnect ();
|
||||
Sys_Quit ();
|
||||
|
|
|
@ -32,7 +32,7 @@ void IN_Commands (void);
|
|||
// oportunity for devices to stick commands on the script buffer
|
||||
|
||||
// mouse moved by dx and dy pixels
|
||||
void IN_MouseMove(int dx, int dy);
|
||||
void IN_MouseMotion(int dx, int dy);
|
||||
|
||||
|
||||
void IN_SendKeyEvents (void);
|
||||
|
|
13
Quake/keys.c
13
Quake/keys.c
|
@ -40,8 +40,6 @@ int history_line = 0;
|
|||
|
||||
keydest_t key_dest;
|
||||
|
||||
#define MAX_KEYS 256
|
||||
|
||||
char *keybindings[MAX_KEYS];
|
||||
qboolean consolekeys[MAX_KEYS]; // if true, can't be rebound while in console
|
||||
qboolean menubound[MAX_KEYS]; // if true, can't be rebound while in menu
|
||||
|
@ -163,6 +161,17 @@ keyname_t keynames[] =
|
|||
{"BACKQUOTE", '`'}, // because a raw backquote may toggle the console
|
||||
{"TILDE", '~'}, // because a raw tilde may toggle the console
|
||||
|
||||
{"LTHUMB", K_LTHUMB},
|
||||
{"RTHUMB", K_RTHUMB},
|
||||
{"LSHOULDER", K_LSHOULDER},
|
||||
{"RSHOULDER", K_RSHOULDER},
|
||||
{"ABUTTON", K_ABUTTON},
|
||||
{"BBUTTON", K_BBUTTON},
|
||||
{"XBUTTON", K_XBUTTON},
|
||||
{"YBUTTON", K_YBUTTON},
|
||||
{"LTRIGGER", K_LTRIGGER},
|
||||
{"RTRIGGER", K_RTRIGGER},
|
||||
|
||||
{NULL, 0}
|
||||
};
|
||||
|
||||
|
|
15
Quake/keys.h
15
Quake/keys.h
|
@ -142,13 +142,26 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#define K_MOUSE4 241
|
||||
#define K_MOUSE5 242
|
||||
|
||||
// SDL2 game controller keys
|
||||
#define K_LTHUMB 243
|
||||
#define K_RTHUMB 244
|
||||
#define K_LSHOULDER 245
|
||||
#define K_RSHOULDER 246
|
||||
#define K_ABUTTON 247
|
||||
#define K_BBUTTON 248
|
||||
#define K_XBUTTON 249
|
||||
#define K_YBUTTON 250
|
||||
#define K_LTRIGGER 251
|
||||
#define K_RTRIGGER 252
|
||||
|
||||
#define MAX_KEYS 253
|
||||
|
||||
#define MAXCMDLINE 256
|
||||
|
||||
typedef enum {key_game, key_console, key_message, key_menu} keydest_t;
|
||||
|
||||
extern keydest_t key_dest;
|
||||
extern char *keybindings[256];
|
||||
extern char *keybindings[MAX_KEYS];
|
||||
|
||||
extern char key_lines[32][MAXCMDLINE];
|
||||
extern int edit_line;
|
||||
|
|
52
Quake/menu.c
52
Quake/menu.c
|
@ -276,6 +276,7 @@ void M_Main_Key (int key)
|
|||
switch (key)
|
||||
{
|
||||
case K_ESCAPE:
|
||||
case K_BBUTTON:
|
||||
IN_Activate();
|
||||
key_dest = key_game;
|
||||
m_state = m_none;
|
||||
|
@ -300,6 +301,7 @@ void M_Main_Key (int key)
|
|||
|
||||
case K_ENTER:
|
||||
case K_KP_ENTER:
|
||||
case K_ABUTTON:
|
||||
m_entersound = true;
|
||||
|
||||
switch (m_main_cursor)
|
||||
|
@ -364,6 +366,7 @@ void M_SinglePlayer_Key (int key)
|
|||
switch (key)
|
||||
{
|
||||
case K_ESCAPE:
|
||||
case K_BBUTTON:
|
||||
M_Menu_Main_f ();
|
||||
break;
|
||||
|
||||
|
@ -381,6 +384,7 @@ void M_SinglePlayer_Key (int key)
|
|||
|
||||
case K_ENTER:
|
||||
case K_KP_ENTER:
|
||||
case K_ABUTTON:
|
||||
m_entersound = true;
|
||||
|
||||
switch (m_singleplayer_cursor)
|
||||
|
@ -514,11 +518,13 @@ void M_Load_Key (int k)
|
|||
switch (k)
|
||||
{
|
||||
case K_ESCAPE:
|
||||
case K_BBUTTON:
|
||||
M_Menu_SinglePlayer_f ();
|
||||
break;
|
||||
|
||||
case K_ENTER:
|
||||
case K_KP_ENTER:
|
||||
case K_ABUTTON:
|
||||
S_LocalSound ("misc/menu2.wav");
|
||||
if (!loadable[load_cursor])
|
||||
return;
|
||||
|
@ -558,11 +564,13 @@ void M_Save_Key (int k)
|
|||
switch (k)
|
||||
{
|
||||
case K_ESCAPE:
|
||||
case K_BBUTTON:
|
||||
M_Menu_SinglePlayer_f ();
|
||||
break;
|
||||
|
||||
case K_ENTER:
|
||||
case K_KP_ENTER:
|
||||
case K_ABUTTON:
|
||||
m_state = m_none;
|
||||
IN_Activate();
|
||||
key_dest = key_game;
|
||||
|
@ -628,6 +636,7 @@ void M_MultiPlayer_Key (int key)
|
|||
switch (key)
|
||||
{
|
||||
case K_ESCAPE:
|
||||
case K_BBUTTON:
|
||||
M_Menu_Main_f ();
|
||||
break;
|
||||
|
||||
|
@ -645,6 +654,7 @@ void M_MultiPlayer_Key (int key)
|
|||
|
||||
case K_ENTER:
|
||||
case K_KP_ENTER:
|
||||
case K_ABUTTON:
|
||||
m_entersound = true;
|
||||
switch (m_multiplayer_cursor)
|
||||
{
|
||||
|
@ -735,6 +745,7 @@ void M_Setup_Key (int k)
|
|||
switch (k)
|
||||
{
|
||||
case K_ESCAPE:
|
||||
case K_BBUTTON:
|
||||
M_Menu_MultiPlayer_f ();
|
||||
break;
|
||||
|
||||
|
@ -774,6 +785,7 @@ forward:
|
|||
|
||||
case K_ENTER:
|
||||
case K_KP_ENTER:
|
||||
case K_ABUTTON:
|
||||
if (setup_cursor == 0 || setup_cursor == 1)
|
||||
return;
|
||||
|
||||
|
@ -926,6 +938,7 @@ again:
|
|||
switch (k)
|
||||
{
|
||||
case K_ESCAPE:
|
||||
case K_BBUTTON:
|
||||
M_Menu_MultiPlayer_f ();
|
||||
break;
|
||||
|
||||
|
@ -943,6 +956,7 @@ again:
|
|||
|
||||
case K_ENTER:
|
||||
case K_KP_ENTER:
|
||||
case K_ABUTTON:
|
||||
m_entersound = true;
|
||||
M_Menu_LanConfig_f ();
|
||||
break;
|
||||
|
@ -1221,11 +1235,13 @@ void M_Options_Key (int k)
|
|||
switch (k)
|
||||
{
|
||||
case K_ESCAPE:
|
||||
case K_BBUTTON:
|
||||
M_Menu_Main_f ();
|
||||
break;
|
||||
|
||||
case K_ENTER:
|
||||
case K_KP_ENTER:
|
||||
case K_ABUTTON:
|
||||
m_entersound = true;
|
||||
switch (options_cursor)
|
||||
{
|
||||
|
@ -1325,27 +1341,27 @@ void M_Menu_Keys_f (void)
|
|||
}
|
||||
|
||||
|
||||
void M_FindKeysForCommand (const char *command, int *twokeys)
|
||||
void M_FindKeysForCommand (const char *command, int *threekeys)
|
||||
{
|
||||
int count;
|
||||
int j;
|
||||
int l;
|
||||
char *b;
|
||||
|
||||
twokeys[0] = twokeys[1] = -1;
|
||||
threekeys[0] = threekeys[1] = threekeys[2] = -1;
|
||||
l = strlen(command);
|
||||
count = 0;
|
||||
|
||||
for (j = 0; j < 256; j++)
|
||||
for (j = 0; j < MAX_KEYS; j++)
|
||||
{
|
||||
b = keybindings[j];
|
||||
if (!b)
|
||||
continue;
|
||||
if (!strncmp (b, command, l) )
|
||||
{
|
||||
twokeys[count] = j;
|
||||
threekeys[count] = j;
|
||||
count++;
|
||||
if (count == 2)
|
||||
if (count == 3)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1359,7 +1375,7 @@ void M_UnbindCommand (const char *command)
|
|||
|
||||
l = strlen(command);
|
||||
|
||||
for (j = 0; j < 256; j++)
|
||||
for (j = 0; j < MAX_KEYS; j++)
|
||||
{
|
||||
b = keybindings[j];
|
||||
if (!b)
|
||||
|
@ -1374,7 +1390,7 @@ extern qpic_t *pic_up, *pic_down;
|
|||
void M_Keys_Draw (void)
|
||||
{
|
||||
int i, x, y;
|
||||
int keys[2];
|
||||
int keys[3];
|
||||
const char *name;
|
||||
qpic_t *p;
|
||||
|
||||
|
@ -1406,8 +1422,15 @@ void M_Keys_Draw (void)
|
|||
x = strlen(name) * 8;
|
||||
if (keys[1] != -1)
|
||||
{
|
||||
name = Key_KeynumToString (keys[1]);
|
||||
M_Print (140 + x + 8, y, "or");
|
||||
M_Print (140 + x + 32, y, Key_KeynumToString (keys[1]));
|
||||
M_Print (140 + x + 32, y, name);
|
||||
x = x + 32 + strlen(name) * 8;
|
||||
if (keys[2] != -1)
|
||||
{
|
||||
M_Print (140 + x + 8, y, "or");
|
||||
M_Print (140 + x + 32, y, Key_KeynumToString (keys[2]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1422,7 +1445,7 @@ void M_Keys_Draw (void)
|
|||
void M_Keys_Key (int k)
|
||||
{
|
||||
char cmd[80];
|
||||
int keys[2];
|
||||
int keys[3];
|
||||
|
||||
if (bind_grab)
|
||||
{ // defining a key
|
||||
|
@ -1441,6 +1464,7 @@ void M_Keys_Key (int k)
|
|||
switch (k)
|
||||
{
|
||||
case K_ESCAPE:
|
||||
case K_BBUTTON:
|
||||
M_Menu_Options_f ();
|
||||
break;
|
||||
|
||||
|
@ -1462,9 +1486,10 @@ void M_Keys_Key (int k)
|
|||
|
||||
case K_ENTER: // go into bind mode
|
||||
case K_KP_ENTER:
|
||||
case K_ABUTTON:
|
||||
M_FindKeysForCommand (bindnames[keys_cursor][0], keys);
|
||||
S_LocalSound ("misc/menu2.wav");
|
||||
if (keys[1] != -1)
|
||||
if (keys[2] != -1)
|
||||
M_UnbindCommand (bindnames[keys_cursor][0]);
|
||||
bind_grab = true;
|
||||
IN_Activate(); // activate to allow mouse key binding
|
||||
|
@ -1527,6 +1552,7 @@ void M_Help_Key (int key)
|
|||
switch (key)
|
||||
{
|
||||
case K_ESCAPE:
|
||||
case K_BBUTTON:
|
||||
M_Menu_Main_f ();
|
||||
break;
|
||||
|
||||
|
@ -1756,6 +1782,7 @@ void M_LanConfig_Key (int key)
|
|||
switch (key)
|
||||
{
|
||||
case K_ESCAPE:
|
||||
case K_BBUTTON:
|
||||
M_Menu_Net_f ();
|
||||
break;
|
||||
|
||||
|
@ -1775,6 +1802,7 @@ void M_LanConfig_Key (int key)
|
|||
|
||||
case K_ENTER:
|
||||
case K_KP_ENTER:
|
||||
case K_ABUTTON:
|
||||
if (lanConfig_cursor == 0)
|
||||
break;
|
||||
|
||||
|
@ -2266,6 +2294,7 @@ void M_GameOptions_Key (int key)
|
|||
switch (key)
|
||||
{
|
||||
case K_ESCAPE:
|
||||
case K_BBUTTON:
|
||||
M_Menu_Net_f ();
|
||||
break;
|
||||
|
||||
|
@ -2299,6 +2328,7 @@ void M_GameOptions_Key (int key)
|
|||
|
||||
case K_ENTER:
|
||||
case K_KP_ENTER:
|
||||
case K_ABUTTON:
|
||||
S_LocalSound ("misc/menu2.wav");
|
||||
if (gameoptions_cursor == 0)
|
||||
{
|
||||
|
@ -2430,6 +2460,7 @@ void M_ServerList_Key (int k)
|
|||
switch (k)
|
||||
{
|
||||
case K_ESCAPE:
|
||||
case K_BBUTTON:
|
||||
M_Menu_LanConfig_f ();
|
||||
break;
|
||||
|
||||
|
@ -2455,6 +2486,7 @@ void M_ServerList_Key (int k)
|
|||
|
||||
case K_ENTER:
|
||||
case K_KP_ENTER:
|
||||
case K_ABUTTON:
|
||||
S_LocalSound ("misc/menu2.wav");
|
||||
m_return_state = m_state;
|
||||
m_return_onerror = true;
|
||||
|
|
Binary file not shown.
|
@ -469,6 +469,7 @@ void Sys_Sleep (unsigned long msecs)
|
|||
|
||||
void Sys_SendKeyEvents (void)
|
||||
{
|
||||
IN_Commands(); //ericw -- allow joysticks to add keys so they can be used to confirm SCR_ModalMessage
|
||||
IN_SendKeyEvents();
|
||||
}
|
||||
|
||||
|
|
|
@ -436,6 +436,7 @@ void Sys_Sleep (unsigned long msecs)
|
|||
|
||||
void Sys_SendKeyEvents (void)
|
||||
{
|
||||
IN_Commands(); //ericw -- allow joysticks to add keys so they can be used to confirm SCR_ModalMessage
|
||||
IN_SendKeyEvents();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue