engine: drop raw SDL joystick API, always use GameController instead. Implement actually working rumble, ensure we're freeing up all resources related to gamepads
This commit is contained in:
parent
bff7299f9b
commit
b16037eabf
11 changed files with 313 additions and 418 deletions
|
@ -43,7 +43,6 @@ static struct joy_axis_s
|
||||||
short val;
|
short val;
|
||||||
short prevval;
|
short prevval;
|
||||||
} joyaxis[MAX_AXES] = { 0 };
|
} joyaxis[MAX_AXES] = { 0 };
|
||||||
static byte currentbinding; // add posibility to remap keys, to place it in joykeys[]
|
|
||||||
static qboolean joy_initialized;
|
static qboolean joy_initialized;
|
||||||
|
|
||||||
static CVAR_DEFINE_AUTO( joy_pitch, "100.0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "joystick pitch sensitivity" );
|
static CVAR_DEFINE_AUTO( joy_pitch, "100.0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "joystick pitch sensitivity" );
|
||||||
|
@ -60,8 +59,6 @@ static CVAR_DEFINE_AUTO( joy_pitch_deadzone, DEFAULT_JOY_DEADZONE, FCVAR_ARCHIVE
|
||||||
static CVAR_DEFINE_AUTO( joy_yaw_deadzone, DEFAULT_JOY_DEADZONE, FCVAR_ARCHIVE | FCVAR_FILTERABLE, "yaw axis deadzone. Value from 0 to 32767" );
|
static CVAR_DEFINE_AUTO( joy_yaw_deadzone, DEFAULT_JOY_DEADZONE, FCVAR_ARCHIVE | FCVAR_FILTERABLE, "yaw axis deadzone. Value from 0 to 32767" );
|
||||||
static CVAR_DEFINE_AUTO( joy_axis_binding, "sfpyrl", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "axis hardware id to engine inner axis binding, "
|
static CVAR_DEFINE_AUTO( joy_axis_binding, "sfpyrl", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "axis hardware id to engine inner axis binding, "
|
||||||
"s - side, f - forward, y - yaw, p - pitch, r - left trigger, l - right trigger" );
|
"s - side, f - forward, y - yaw, p - pitch, r - left trigger, l - right trigger" );
|
||||||
static CVAR_DEFINE_AUTO( joy_found, "0", FCVAR_READ_ONLY, "is joystick is connected" );
|
|
||||||
static CVAR_DEFINE_AUTO( joy_index, "0", FCVAR_READ_ONLY, "current active joystick" );
|
|
||||||
CVAR_DEFINE_AUTO( joy_enable, "1", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "enable joystick" );
|
CVAR_DEFINE_AUTO( joy_enable, "1", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "enable joystick" );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -71,7 +68,7 @@ Joy_IsActive
|
||||||
*/
|
*/
|
||||||
qboolean Joy_IsActive( void )
|
qboolean Joy_IsActive( void )
|
||||||
{
|
{
|
||||||
return joy_found.value && joy_enable.value;
|
return joy_enable.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -81,7 +78,7 @@ Joy_HatMotionEvent
|
||||||
DPad events
|
DPad events
|
||||||
============
|
============
|
||||||
*/
|
*/
|
||||||
void Joy_HatMotionEvent( byte hat, byte value )
|
static void Joy_HatMotionEvent( int value )
|
||||||
{
|
{
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
|
@ -96,9 +93,6 @@ void Joy_HatMotionEvent( byte hat, byte value )
|
||||||
};
|
};
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if( !joy_found.value )
|
|
||||||
return;
|
|
||||||
|
|
||||||
for( i = 0; i < ARRAYSIZE( keys ); i++ )
|
for( i = 0; i < ARRAYSIZE( keys ); i++ )
|
||||||
{
|
{
|
||||||
if( value & keys[i].mask )
|
if( value & keys[i].mask )
|
||||||
|
@ -225,7 +219,7 @@ static void Joy_ProcessStick( const engineAxis_t engineAxis, short value )
|
||||||
val |= Joy_GetHatValueForAxis( JOY_AXIS_SIDE );
|
val |= Joy_GetHatValueForAxis( JOY_AXIS_SIDE );
|
||||||
val |= Joy_GetHatValueForAxis( JOY_AXIS_FWD );
|
val |= Joy_GetHatValueForAxis( JOY_AXIS_FWD );
|
||||||
|
|
||||||
Joy_HatMotionEvent( 0, val );
|
Joy_HatMotionEvent( val );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,23 +230,9 @@ Joy_AxisMotionEvent
|
||||||
Axis events
|
Axis events
|
||||||
=============
|
=============
|
||||||
*/
|
*/
|
||||||
void Joy_AxisMotionEvent( byte axis, short value )
|
void Joy_AxisMotionEvent( engineAxis_t engineAxis, short value )
|
||||||
{
|
{
|
||||||
if( !joy_found.value )
|
if( engineAxis >= JOY_AXIS_NULL )
|
||||||
return;
|
|
||||||
|
|
||||||
if( axis >= MAX_AXES )
|
|
||||||
{
|
|
||||||
Con_Reportf( "Only 6 axes is supported\n" );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Joy_KnownAxisMotionEvent( joyaxesmap[axis], value );
|
|
||||||
}
|
|
||||||
|
|
||||||
void Joy_KnownAxisMotionEvent( engineAxis_t engineAxis, short value )
|
|
||||||
{
|
|
||||||
if( engineAxis == JOY_AXIS_NULL )
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if( value == joyaxis[engineAxis].val )
|
if( value == joyaxis[engineAxis].val )
|
||||||
|
@ -264,70 +244,6 @@ void Joy_KnownAxisMotionEvent( engineAxis_t engineAxis, short value )
|
||||||
Joy_ProcessStick( engineAxis, value );
|
Joy_ProcessStick( engineAxis, value );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
=============
|
|
||||||
Joy_BallMotionEvent
|
|
||||||
|
|
||||||
Trackball events. UNDONE
|
|
||||||
=============
|
|
||||||
*/
|
|
||||||
void Joy_BallMotionEvent( byte ball, short xrel, short yrel )
|
|
||||||
{
|
|
||||||
//if( !joy_found.value )
|
|
||||||
// return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
=============
|
|
||||||
Joy_ButtonEvent
|
|
||||||
|
|
||||||
Button events
|
|
||||||
=============
|
|
||||||
*/
|
|
||||||
void Joy_ButtonEvent( byte button, byte down )
|
|
||||||
{
|
|
||||||
if( !joy_found.value )
|
|
||||||
return;
|
|
||||||
|
|
||||||
// generic game button code.
|
|
||||||
if( button > 32 )
|
|
||||||
{
|
|
||||||
int origbutton = button;
|
|
||||||
button = ( button & 31 ) + K_AUX1;
|
|
||||||
|
|
||||||
Con_Reportf( "Only 32 joybuttons is supported, converting %i button ID to %s\n", origbutton, Key_KeynumToString( button ) );
|
|
||||||
}
|
|
||||||
else button += K_AUX1;
|
|
||||||
|
|
||||||
Key_Event( button, down );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
=============
|
|
||||||
Joy_RemoveEvent
|
|
||||||
|
|
||||||
Called when joystick is removed. For future expansion
|
|
||||||
=============
|
|
||||||
*/
|
|
||||||
void Joy_RemoveEvent( void )
|
|
||||||
{
|
|
||||||
if( joy_found.value )
|
|
||||||
Cvar_FullSet( "joy_found", "0", FCVAR_READ_ONLY );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
=============
|
|
||||||
Joy_RemoveEvent
|
|
||||||
|
|
||||||
Called when joystick is removed. For future expansion
|
|
||||||
=============
|
|
||||||
*/
|
|
||||||
void Joy_AddEvent( void )
|
|
||||||
{
|
|
||||||
if( joy_enable.value && !joy_found.value )
|
|
||||||
Cvar_FullSet( "joy_found", "1", FCVAR_READ_ONLY );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
=============
|
=============
|
||||||
Joy_FinalizeMove
|
Joy_FinalizeMove
|
||||||
|
@ -364,14 +280,8 @@ void Joy_FinalizeMove( float *fw, float *side, float *dpitch, float *dyaw )
|
||||||
|
|
||||||
*fw -= joy_forward.value * (float)joyaxis[JOY_AXIS_FWD ].val/(float)SHRT_MAX; // must be form -1.0 to 1.0
|
*fw -= joy_forward.value * (float)joyaxis[JOY_AXIS_FWD ].val/(float)SHRT_MAX; // must be form -1.0 to 1.0
|
||||||
*side += joy_side.value * (float)joyaxis[JOY_AXIS_SIDE].val/(float)SHRT_MAX;
|
*side += joy_side.value * (float)joyaxis[JOY_AXIS_SIDE].val/(float)SHRT_MAX;
|
||||||
#if !defined(XASH_SDL)
|
|
||||||
*dpitch += joy_pitch.value * (float)joyaxis[JOY_AXIS_PITCH].val/(float)SHRT_MAX * host.realframetime; // abs axis rotate is frametime related
|
|
||||||
*dyaw -= joy_yaw.value * (float)joyaxis[JOY_AXIS_YAW ].val/(float)SHRT_MAX * host.realframetime;
|
|
||||||
#else
|
|
||||||
// HACKHACK: SDL have inverted look axis.
|
|
||||||
*dpitch -= joy_pitch.value * (float)joyaxis[JOY_AXIS_PITCH].val/(float)SHRT_MAX * host.realframetime;
|
*dpitch -= joy_pitch.value * (float)joyaxis[JOY_AXIS_PITCH].val/(float)SHRT_MAX * host.realframetime;
|
||||||
*dyaw += joy_yaw.value * (float)joyaxis[JOY_AXIS_YAW ].val/(float)SHRT_MAX * host.realframetime;
|
*dyaw += joy_yaw.value * (float)joyaxis[JOY_AXIS_YAW ].val/(float)SHRT_MAX * host.realframetime;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -402,10 +312,6 @@ void Joy_Init( void )
|
||||||
Cvar_RegisterVariable( &joy_yaw_deadzone );
|
Cvar_RegisterVariable( &joy_yaw_deadzone );
|
||||||
|
|
||||||
Cvar_RegisterVariable( &joy_axis_binding );
|
Cvar_RegisterVariable( &joy_axis_binding );
|
||||||
Cvar_RegisterVariable( &joy_found );
|
|
||||||
// we doesn't loaded config.cfg yet, so this cvar is not archive.
|
|
||||||
// change by +set joy_index in cmdline
|
|
||||||
Cvar_RegisterVariable( &joy_index );
|
|
||||||
|
|
||||||
Cvar_RegisterVariable( &joy_enable );
|
Cvar_RegisterVariable( &joy_enable );
|
||||||
|
|
||||||
|
@ -417,7 +323,7 @@ void Joy_Init( void )
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Cvar_FullSet( "joy_found", va( "%d", Platform_JoyInit( joy_index.value )), FCVAR_READ_ONLY );
|
Platform_JoyInit();
|
||||||
|
|
||||||
joy_initialized = true;
|
joy_initialized = true;
|
||||||
}
|
}
|
||||||
|
@ -431,8 +337,5 @@ Shutdown joystick code
|
||||||
*/
|
*/
|
||||||
void Joy_Shutdown( void )
|
void Joy_Shutdown( void )
|
||||||
{
|
{
|
||||||
if( joy_initialized )
|
Platform_JoyShutdown();
|
||||||
{
|
|
||||||
Cvar_FullSet( "joy_found", 0, FCVAR_READ_ONLY );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,17 +105,9 @@ typedef enum engineAxis_e
|
||||||
} engineAxis_t;
|
} engineAxis_t;
|
||||||
|
|
||||||
qboolean Joy_IsActive( void );
|
qboolean Joy_IsActive( void );
|
||||||
void Joy_HatMotionEvent( byte hat, byte value );
|
void Joy_AxisMotionEvent( engineAxis_t engineAxis, short value );
|
||||||
void Joy_AxisMotionEvent( byte axis, short value );
|
|
||||||
void Joy_KnownAxisMotionEvent( engineAxis_t engineAxis, short value );
|
|
||||||
void Joy_BallMotionEvent( byte ball, short xrel, short yrel );
|
|
||||||
void Joy_ButtonEvent( byte button, byte down );
|
|
||||||
void Joy_AddEvent( void );
|
|
||||||
void Joy_RemoveEvent( void );
|
|
||||||
void Joy_FinalizeMove( float *fw, float *side, float *dpitch, float *dyaw );
|
void Joy_FinalizeMove( float *fw, float *side, float *dpitch, float *dyaw );
|
||||||
void Joy_Init( void );
|
void Joy_Init( void );
|
||||||
void Joy_Shutdown( void );
|
void Joy_Shutdown( void );
|
||||||
void Joy_EnableTextInput(qboolean enable, qboolean force);
|
|
||||||
|
|
||||||
|
|
||||||
#endif//INPUT_H
|
#endif//INPUT_H
|
||||||
|
|
|
@ -1107,7 +1107,7 @@ static qboolean OSK_KeyEvent( int key, int down )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
=============
|
=============
|
||||||
Joy_EnableTextInput
|
OSK_EnableTextInput
|
||||||
|
|
||||||
Enables built-in IME
|
Enables built-in IME
|
||||||
=============
|
=============
|
||||||
|
|
|
@ -201,7 +201,6 @@ static void Sys_PrintUsage( const char *exename )
|
||||||
O("-daemonize ", "run engine as a daemon")
|
O("-daemonize ", "run engine as a daemon")
|
||||||
#endif
|
#endif
|
||||||
#if XASH_SDL == 2
|
#if XASH_SDL == 2
|
||||||
O("-sdl_joy_old_api ","use SDL legacy joystick API")
|
|
||||||
O("-sdl_renderer <n> ","use alternative SDL_Renderer for software")
|
O("-sdl_renderer <n> ","use alternative SDL_Renderer for software")
|
||||||
#endif // XASH_SDL
|
#endif // XASH_SDL
|
||||||
#if XASH_ANDROID && !XASH_SDL
|
#if XASH_ANDROID && !XASH_SDL
|
||||||
|
|
|
@ -91,11 +91,16 @@ void GAME_EXPORT Platform_SetMousePos(int x, int y)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int Platform_JoyInit( int numjoy )
|
int Platform_JoyInit( void )
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Platform_JoyShutdown( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void Platform_EnableTextInput( qboolean enable )
|
void Platform_EnableTextInput( qboolean enable )
|
||||||
{
|
{
|
||||||
keystate.chars = enable;
|
keystate.chars = enable;
|
||||||
|
|
|
@ -285,9 +285,15 @@ void Platform_Vibrate(float life, char flags)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
int Platform_JoyInit( int numjoy )
|
|
||||||
|
int Platform_JoyInit( void )
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Platform_JoyShutdown( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -209,7 +209,8 @@ void Platform_Vibrate( float life, char flags );
|
||||||
==============================================================================
|
==============================================================================
|
||||||
*/
|
*/
|
||||||
// Gamepad support
|
// Gamepad support
|
||||||
int Platform_JoyInit( int numjoy ); // returns number of connected gamepads, negative if error
|
int Platform_JoyInit( void ); // returns number of connected gamepads, negative if error
|
||||||
|
void Platform_JoyShutdown( void );
|
||||||
// Text input
|
// Text input
|
||||||
void Platform_EnableTextInput( qboolean enable );
|
void Platform_EnableTextInput( qboolean enable );
|
||||||
key_modifier_t Platform_GetKeyModifiers( void );
|
key_modifier_t Platform_GetKeyModifiers( void );
|
||||||
|
|
|
@ -88,52 +88,8 @@ GNU General Public License for more details.
|
||||||
#define SDL_SCANCODE_PRINTSCREEN SDLK_PRINT
|
#define SDL_SCANCODE_PRINTSCREEN SDLK_PRINT
|
||||||
#define SDL_SCANCODE_UNKNOWN SDLK_UNKNOWN
|
#define SDL_SCANCODE_UNKNOWN SDLK_UNKNOWN
|
||||||
#define SDL_GetScancodeName( x ) "unknown"
|
#define SDL_GetScancodeName( x ) "unknown"
|
||||||
#define SDL_JoystickID Uint8
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int SDLash_GameControllerButtonMapping[] =
|
|
||||||
{
|
|
||||||
#if XASH_NSWITCH // devkitPro/SDL has inverted Nintendo layout for SDL_GameController
|
|
||||||
K_B_BUTTON, K_A_BUTTON, K_Y_BUTTON, K_X_BUTTON,
|
|
||||||
#else
|
|
||||||
K_A_BUTTON, K_B_BUTTON, K_X_BUTTON, K_Y_BUTTON,
|
|
||||||
#endif
|
|
||||||
K_BACK_BUTTON, K_MODE_BUTTON, K_START_BUTTON,
|
|
||||||
K_LSTICK, K_RSTICK,
|
|
||||||
K_L1_BUTTON, K_R1_BUTTON,
|
|
||||||
K_DPAD_UP, K_DPAD_DOWN, K_DPAD_LEFT, K_DPAD_RIGHT,
|
|
||||||
K_MISC_BUTTON,
|
|
||||||
K_PADDLE1_BUTTON, K_PADDLE2_BUTTON, K_PADDLE3_BUTTON, K_PADDLE4_BUTTON,
|
|
||||||
K_TOUCHPAD,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Swap axis to follow default axis binding:
|
|
||||||
// LeftX, LeftY, RightX, RightY, TriggerRight, TriggerLeft
|
|
||||||
static int SDLash_GameControllerAxisMapping[] =
|
|
||||||
{
|
|
||||||
JOY_AXIS_SIDE, // SDL_CONTROLLER_AXIS_LEFTX,
|
|
||||||
JOY_AXIS_FWD, // SDL_CONTROLLER_AXIS_LEFTY,
|
|
||||||
JOY_AXIS_PITCH, // SDL_CONTROLLER_AXIS_RIGHTX,
|
|
||||||
JOY_AXIS_YAW, // SDL_CONTROLLER_AXIS_RIGHTY,
|
|
||||||
JOY_AXIS_LT, // SDL_CONTROLLER_AXIS_TRIGGERLEFT,
|
|
||||||
JOY_AXIS_RT, // SDL_CONTROLLER_AXIS_TRIGGERRIGHT,
|
|
||||||
};
|
|
||||||
|
|
||||||
static qboolean SDLash_IsInstanceIDAGameController( SDL_JoystickID joyId )
|
|
||||||
{
|
|
||||||
#if !SDL_VERSION_ATLEAST( 2, 0, 4 )
|
|
||||||
// HACKHACK: if we're not initialized g_joy, then we're probably using gamecontroller api
|
|
||||||
// so return true
|
|
||||||
if( !g_joy )
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
#else
|
|
||||||
if( SDL_GameControllerFromInstanceID( joyId ) != NULL )
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
=============
|
=============
|
||||||
SDLash_KeyEvent
|
SDLash_KeyEvent
|
||||||
|
@ -408,50 +364,6 @@ static void SDLash_ActiveEvent( int gain )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
|
|
||||||
static size_t num_open_game_controllers = 0;
|
|
||||||
|
|
||||||
static void SDLash_GameController_Add( int index )
|
|
||||||
{
|
|
||||||
extern convar_t joy_enable; // private to input system
|
|
||||||
SDL_GameController *controller;
|
|
||||||
|
|
||||||
if( !joy_enable.value )
|
|
||||||
return;
|
|
||||||
|
|
||||||
controller = SDL_GameControllerOpen( index );
|
|
||||||
if( !controller )
|
|
||||||
{
|
|
||||||
Con_Reportf( "Failed to open SDL GameController %d: %s\n", index, SDL_GetError( ) );
|
|
||||||
SDL_ClearError( );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#if SDL_VERSION_ATLEAST( 2, 0, 6 )
|
|
||||||
Con_Reportf( "Added controller: %s (%i:%i:%i)\n",
|
|
||||||
SDL_GameControllerName( controller ),
|
|
||||||
SDL_GameControllerGetVendor( controller ),
|
|
||||||
SDL_GameControllerGetProduct( controller ),
|
|
||||||
SDL_GameControllerGetProductVersion( controller ));
|
|
||||||
#endif // SDL_VERSION_ATLEAST( 2, 0, 6 )
|
|
||||||
|
|
||||||
++num_open_game_controllers;
|
|
||||||
if( num_open_game_controllers == 1 )
|
|
||||||
Joy_AddEvent( );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void SDLash_GameController_Remove( SDL_JoystickID joystick_id )
|
|
||||||
{
|
|
||||||
Con_Reportf( "Removed controller %i\n", joystick_id );
|
|
||||||
|
|
||||||
// `Joy_RemoveEvent` sets `joy_found` to `0`.
|
|
||||||
// We only want to do this when all the game controllers have been removed.
|
|
||||||
--num_open_game_controllers;
|
|
||||||
if( num_open_game_controllers == 0 )
|
|
||||||
Joy_RemoveEvent( );
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
=============
|
=============
|
||||||
SDLash_EventFilter
|
SDLash_EventFilter
|
||||||
|
@ -479,28 +391,6 @@ static void SDLash_EventHandler( SDL_Event *event )
|
||||||
SDLash_KeyEvent( event->key );
|
SDLash_KeyEvent( event->key );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Joystick events */
|
|
||||||
case SDL_JOYAXISMOTION:
|
|
||||||
if ( !SDLash_IsInstanceIDAGameController( event->jaxis.which ))
|
|
||||||
Joy_AxisMotionEvent( event->jaxis.axis, event->jaxis.value );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SDL_JOYBALLMOTION:
|
|
||||||
if ( !SDLash_IsInstanceIDAGameController( event->jball.which ))
|
|
||||||
Joy_BallMotionEvent( event->jball.ball, event->jball.xrel, event->jball.yrel );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SDL_JOYHATMOTION:
|
|
||||||
if ( !SDLash_IsInstanceIDAGameController( event->jhat.which ))
|
|
||||||
Joy_HatMotionEvent( event->jhat.hat, event->jhat.value );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SDL_JOYBUTTONDOWN:
|
|
||||||
case SDL_JOYBUTTONUP:
|
|
||||||
if ( !SDLash_IsInstanceIDAGameController( event->jbutton.which ))
|
|
||||||
Joy_ButtonEvent( event->jbutton.button, event->jbutton.state );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SDL_QUIT:
|
case SDL_QUIT:
|
||||||
Sys_Quit( "caught SDL_QUIT" );
|
Sys_Quit( "caught SDL_QUIT" );
|
||||||
break;
|
break;
|
||||||
|
@ -568,46 +458,20 @@ static void SDLash_EventHandler( SDL_Event *event )
|
||||||
SDLash_InputEvent( event->text );
|
SDLash_InputEvent( event->text );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDL_JOYDEVICEADDED:
|
|
||||||
Joy_AddEvent();
|
|
||||||
break;
|
|
||||||
case SDL_JOYDEVICEREMOVED:
|
|
||||||
Joy_RemoveEvent();
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* GameController API */
|
/* GameController API */
|
||||||
case SDL_CONTROLLERAXISMOTION:
|
case SDL_CONTROLLERAXISMOTION:
|
||||||
{
|
|
||||||
if( !Joy_IsActive( ))
|
|
||||||
break;
|
|
||||||
|
|
||||||
if( event->caxis.axis >= 0 && event->caxis.axis < ARRAYSIZE( SDLash_GameControllerAxisMapping ))
|
|
||||||
{
|
|
||||||
Joy_KnownAxisMotionEvent( SDLash_GameControllerAxisMapping[event->caxis.axis], event->caxis.value );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case SDL_CONTROLLERBUTTONDOWN:
|
case SDL_CONTROLLERBUTTONDOWN:
|
||||||
case SDL_CONTROLLERBUTTONUP:
|
case SDL_CONTROLLERBUTTONUP:
|
||||||
{
|
|
||||||
if( !Joy_IsActive( ))
|
|
||||||
break;
|
|
||||||
|
|
||||||
// TODO: Use joyinput funcs, for future multiple gamepads support
|
|
||||||
if( event->cbutton.button >= 0 && event->cbutton.button < ARRAYSIZE( SDLash_GameControllerButtonMapping ))
|
|
||||||
{
|
|
||||||
Key_Event( SDLash_GameControllerButtonMapping[event->cbutton.button], event->cbutton.state );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case SDL_CONTROLLERDEVICEADDED:
|
case SDL_CONTROLLERDEVICEADDED:
|
||||||
SDLash_GameController_Add( event->cdevice.which );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SDL_CONTROLLERDEVICEREMOVED:
|
case SDL_CONTROLLERDEVICEREMOVED:
|
||||||
SDLash_GameController_Remove( event->cdevice.which );
|
case SDL_CONTROLLERDEVICEREMAPPED:
|
||||||
|
case SDL_CONTROLLERTOUCHPADDOWN:
|
||||||
|
case SDL_CONTROLLERTOUCHPADMOTION:
|
||||||
|
case SDL_CONTROLLERTOUCHPADUP:
|
||||||
|
case SDL_CONTROLLERSENSORUPDATE:
|
||||||
|
case SDL_CONTROLLERUPDATECOMPLETE_RESERVED_FOR_SDL3:
|
||||||
|
case SDL_CONTROLLERSTEAMHANDLEUPDATED:
|
||||||
|
SDLash_HandleGameControllerEvent( event );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDL_WINDOWEVENT:
|
case SDL_WINDOWEVENT:
|
||||||
|
|
|
@ -28,14 +28,16 @@ void GL_InitExtensions( void );
|
||||||
qboolean GL_DeleteContext( void );
|
qboolean GL_DeleteContext( void );
|
||||||
void VID_SaveWindowSize( int width, int height, qboolean maximized );
|
void VID_SaveWindowSize( int width, int height, qboolean maximized );
|
||||||
|
|
||||||
// joystick events
|
|
||||||
extern SDL_Joystick *g_joy;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// in_sdl.c
|
// in_sdl.c
|
||||||
//
|
//
|
||||||
void SDLash_InitCursors( void );
|
void SDLash_InitCursors( void );
|
||||||
void SDLash_FreeCursors( void );
|
void SDLash_FreeCursors( void );
|
||||||
|
|
||||||
|
//
|
||||||
|
// joy_sdl.c
|
||||||
|
//
|
||||||
|
void SDLash_HandleGameControllerEvent( SDL_Event *ev );
|
||||||
|
|
||||||
#endif // XASH_SDL
|
#endif // XASH_SDL
|
||||||
#endif // KEYWRAPPER_H
|
#endif // KEYWRAPPER_H
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
vid_sdl.c - SDL input component
|
in_sdl.c - SDL input component
|
||||||
Copyright (C) 2018 a1batross
|
Copyright (C) 2018-2025 a1batross
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -12,7 +12,6 @@ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
*/
|
*/
|
||||||
#if !XASH_DEDICATED
|
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
@ -24,7 +23,6 @@ GNU General Public License for more details.
|
||||||
#include "sound.h"
|
#include "sound.h"
|
||||||
#include "vid_common.h"
|
#include "vid_common.h"
|
||||||
|
|
||||||
SDL_Joystick *g_joy = NULL;
|
|
||||||
#if !SDL_VERSION_ATLEAST( 2, 0, 0 )
|
#if !SDL_VERSION_ATLEAST( 2, 0, 0 )
|
||||||
#define SDL_WarpMouseInWindow( win, x, y ) SDL_WarpMouse( ( x ), ( y ) )
|
#define SDL_WarpMouseInWindow( win, x, y ) SDL_WarpMouse( ( x ), ( y ) )
|
||||||
#else
|
#else
|
||||||
|
@ -126,20 +124,6 @@ void Platform_SetClipboardText( const char *buffer )
|
||||||
#endif // SDL_VERSION_ATLEAST( 2, 0, 0 )
|
#endif // SDL_VERSION_ATLEAST( 2, 0, 0 )
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
=============
|
|
||||||
Platform_Vibrate
|
|
||||||
|
|
||||||
=============
|
|
||||||
*/
|
|
||||||
void Platform_Vibrate( float time, char flags )
|
|
||||||
{
|
|
||||||
#if SDL_VERSION_ATLEAST( 2, 0, 9 )
|
|
||||||
if( g_joy )
|
|
||||||
SDL_JoystickRumble( g_joy, 0xFFFF, 0xFFFF, time * 1000.0f );
|
|
||||||
#endif // SDL_VERSION_ATLEAST( 2, 0, 9 )
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !XASH_PSVITA
|
#if !XASH_PSVITA
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -157,138 +141,6 @@ void Platform_EnableTextInput( qboolean enable )
|
||||||
|
|
||||||
#endif // !XASH_PSVITA
|
#endif // !XASH_PSVITA
|
||||||
|
|
||||||
/*
|
|
||||||
=============
|
|
||||||
SDLash_JoyInit_Old
|
|
||||||
|
|
||||||
=============
|
|
||||||
*/
|
|
||||||
static int SDLash_JoyInit_Old( int numjoy )
|
|
||||||
{
|
|
||||||
int num;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
Con_Reportf( "Joystick: SDL\n" );
|
|
||||||
|
|
||||||
if( SDL_WasInit( SDL_INIT_JOYSTICK ) != SDL_INIT_JOYSTICK &&
|
|
||||||
SDL_InitSubSystem( SDL_INIT_JOYSTICK ) )
|
|
||||||
{
|
|
||||||
Con_Reportf( "Failed to initialize SDL Joysitck: %s\n", SDL_GetError() );
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( g_joy )
|
|
||||||
{
|
|
||||||
SDL_JoystickClose( g_joy );
|
|
||||||
}
|
|
||||||
|
|
||||||
num = SDL_NumJoysticks();
|
|
||||||
|
|
||||||
if( num > 0 )
|
|
||||||
Con_Reportf( "%i joysticks found:\n", num );
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Con_Reportf( "No joystick found.\n" );
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
|
|
||||||
for( i = 0; i < num; i++ )
|
|
||||||
Con_Reportf( "%i\t: %s\n", i, SDL_JoystickNameForIndex( i ) );
|
|
||||||
#endif // SDL_VERSION_ATLEAST( 2, 0, 0 )
|
|
||||||
|
|
||||||
Con_Reportf( "Pass +set joy_index N to command line, where N is number, to select active joystick\n" );
|
|
||||||
|
|
||||||
g_joy = SDL_JoystickOpen( numjoy );
|
|
||||||
|
|
||||||
if( !g_joy )
|
|
||||||
{
|
|
||||||
Con_Reportf( "Failed to select joystick: %s\n", SDL_GetError( ) );
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
|
|
||||||
Con_Reportf( "Selected joystick: %s\n"
|
|
||||||
"\tAxes: %i\n"
|
|
||||||
"\tHats: %i\n"
|
|
||||||
"\tButtons: %i\n"
|
|
||||||
"\tBalls: %i\n",
|
|
||||||
SDL_JoystickName( g_joy ), SDL_JoystickNumAxes( g_joy ), SDL_JoystickNumHats( g_joy ),
|
|
||||||
SDL_JoystickNumButtons( g_joy ), SDL_JoystickNumBalls( g_joy ) );
|
|
||||||
|
|
||||||
SDL_GameControllerEventState( SDL_DISABLE );
|
|
||||||
#endif // SDL_VERSION_ATLEAST( 2, 0, 0 )
|
|
||||||
SDL_JoystickEventState( SDL_ENABLE );
|
|
||||||
|
|
||||||
return num;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
|
|
||||||
static void SDLash_GameControllerAddMappings( const char *name )
|
|
||||||
{
|
|
||||||
fs_offset_t len = 0;
|
|
||||||
byte *p = FS_LoadFile( name, &len, false );
|
|
||||||
|
|
||||||
if( !p )
|
|
||||||
return;
|
|
||||||
|
|
||||||
if( len > 0 && len < INT32_MAX ) // function accepts int, SDL3 fixes this
|
|
||||||
{
|
|
||||||
SDL_RWops *rwops = SDL_RWFromConstMem( p, len );
|
|
||||||
SDL_GameControllerAddMappingsFromRW( rwops, true );
|
|
||||||
}
|
|
||||||
|
|
||||||
Mem_Free( p );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
=============
|
|
||||||
SDLash_JoyInit_New
|
|
||||||
|
|
||||||
=============
|
|
||||||
*/
|
|
||||||
static int SDLash_JoyInit_New( int numjoy )
|
|
||||||
{
|
|
||||||
int count, numJoysticks, i;
|
|
||||||
|
|
||||||
Con_Reportf( "Joystick: SDL GameController API\n" );
|
|
||||||
if( SDL_WasInit( SDL_INIT_GAMECONTROLLER ) != SDL_INIT_GAMECONTROLLER &&
|
|
||||||
SDL_InitSubSystem( SDL_INIT_GAMECONTROLLER ) )
|
|
||||||
{
|
|
||||||
Con_Reportf( "Failed to initialize SDL GameController API: %s\n", SDL_GetError() );
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
SDLash_GameControllerAddMappings( "gamecontrollerdb.txt" ); // shipped in extras.pk3
|
|
||||||
SDLash_GameControllerAddMappings( "controllermappings.txt" );
|
|
||||||
|
|
||||||
count = 0;
|
|
||||||
numJoysticks = SDL_NumJoysticks();
|
|
||||||
for ( i = 0; i < numJoysticks; i++ )
|
|
||||||
if( SDL_IsGameController( i ) )
|
|
||||||
++count;
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
#endif // SDL_VERSION_ATLEAST( 2, 0, 0 )
|
|
||||||
|
|
||||||
/*
|
|
||||||
=============
|
|
||||||
Platform_JoyInit
|
|
||||||
|
|
||||||
=============
|
|
||||||
*/
|
|
||||||
int Platform_JoyInit( int numjoy )
|
|
||||||
{
|
|
||||||
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
|
|
||||||
// SDL_Joystick is now an old API
|
|
||||||
// SDL_GameController is preferred
|
|
||||||
if( !Sys_CheckParm( "-sdl_joy_old_api" ) )
|
|
||||||
return SDLash_JoyInit_New(numjoy);
|
|
||||||
#endif // SDL_VERSION_ATLEAST( 2, 0, 0 )
|
|
||||||
return SDLash_JoyInit_Old(numjoy);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
========================
|
========================
|
||||||
SDLash_InitCursors
|
SDLash_InitCursors
|
||||||
|
@ -436,5 +288,3 @@ key_modifier_t Platform_GetKeyModifiers( void )
|
||||||
return KeyModifier_None;
|
return KeyModifier_None;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // XASH_DEDICATED
|
|
||||||
|
|
273
engine/platform/sdl/joy_sdl.c
Normal file
273
engine/platform/sdl/joy_sdl.c
Normal file
|
@ -0,0 +1,273 @@
|
||||||
|
/*
|
||||||
|
joy_sdl.c - SDL gamepads
|
||||||
|
Copyright (C) 2018-2025 a1batross
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
*/
|
||||||
|
#include <SDL.h>
|
||||||
|
|
||||||
|
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
|
||||||
|
#include "common.h"
|
||||||
|
#include "keydefs.h"
|
||||||
|
#include "input.h"
|
||||||
|
#include "client.h"
|
||||||
|
#include "events.h"
|
||||||
|
|
||||||
|
static const int g_button_mapping[] =
|
||||||
|
{
|
||||||
|
#if XASH_NSWITCH // devkitPro/SDL has inverted Nintendo layout for SDL_GameController
|
||||||
|
K_B_BUTTON, K_A_BUTTON, K_Y_BUTTON, K_X_BUTTON,
|
||||||
|
#else
|
||||||
|
K_A_BUTTON, K_B_BUTTON, K_X_BUTTON, K_Y_BUTTON,
|
||||||
|
#endif
|
||||||
|
K_BACK_BUTTON, K_MODE_BUTTON, K_START_BUTTON,
|
||||||
|
K_LSTICK, K_RSTICK,
|
||||||
|
K_L1_BUTTON, K_R1_BUTTON,
|
||||||
|
K_DPAD_UP, K_DPAD_DOWN, K_DPAD_LEFT, K_DPAD_RIGHT,
|
||||||
|
K_MISC_BUTTON,
|
||||||
|
K_PADDLE1_BUTTON, K_PADDLE2_BUTTON, K_PADDLE3_BUTTON, K_PADDLE4_BUTTON,
|
||||||
|
K_TOUCHPAD,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Swap axis to follow default axis binding:
|
||||||
|
// LeftX, LeftY, RightX, RightY, TriggerRight, TriggerLeft
|
||||||
|
static const engineAxis_t g_axis_mapping[] =
|
||||||
|
{
|
||||||
|
JOY_AXIS_SIDE, // SDL_CONTROLLER_AXIS_LEFTX,
|
||||||
|
JOY_AXIS_FWD, // SDL_CONTROLLER_AXIS_LEFTY,
|
||||||
|
JOY_AXIS_PITCH, // SDL_CONTROLLER_AXIS_RIGHTX,
|
||||||
|
JOY_AXIS_YAW, // SDL_CONTROLLER_AXIS_RIGHTY,
|
||||||
|
JOY_AXIS_LT, // SDL_CONTROLLER_AXIS_TRIGGERLEFT,
|
||||||
|
JOY_AXIS_RT, // SDL_CONTROLLER_AXIS_TRIGGERRIGHT,
|
||||||
|
};
|
||||||
|
|
||||||
|
static SDL_JoystickID g_current_gamepad_id = -1; // used to send rumble to
|
||||||
|
static SDL_GameController *g_current_gamepad;
|
||||||
|
static SDL_GameController **g_gamepads;
|
||||||
|
static size_t g_num_gamepads;
|
||||||
|
|
||||||
|
static void SDLash_GameControllerAddMappings( const char *name )
|
||||||
|
{
|
||||||
|
fs_offset_t len = 0;
|
||||||
|
byte *p = FS_LoadFile( name, &len, false );
|
||||||
|
|
||||||
|
if( !p )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if( len > 0 && len < INT32_MAX ) // function accepts int, SDL3 fixes this
|
||||||
|
{
|
||||||
|
SDL_RWops *rwops = SDL_RWFromConstMem( p, (int)len );
|
||||||
|
SDL_GameControllerAddMappingsFromRW( rwops, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
Mem_Free( p );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SDLash_SetActiveGameController( SDL_JoystickID id )
|
||||||
|
{
|
||||||
|
g_current_gamepad_id = id;
|
||||||
|
g_current_gamepad = SDL_GameControllerFromInstanceID( id );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SDLash_GameControllerAdded( int device_index )
|
||||||
|
{
|
||||||
|
SDL_GameController *gc;
|
||||||
|
SDL_GameController **list;
|
||||||
|
|
||||||
|
gc = SDL_GameControllerOpen( device_index );
|
||||||
|
if( !gc )
|
||||||
|
{
|
||||||
|
Con_Printf( S_ERROR "SDL_GameControllerOpen: %s\n", SDL_GetError( ));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
list = Mem_Realloc( host.mempool, g_gamepads, sizeof( *list ) * ( g_num_gamepads + 1 ));
|
||||||
|
list[g_num_gamepads++] = gc;
|
||||||
|
|
||||||
|
g_gamepads = list;
|
||||||
|
|
||||||
|
// set as current device if none other set
|
||||||
|
if( g_current_gamepad_id < 0 )
|
||||||
|
{
|
||||||
|
SDL_Joystick *joy = SDL_GameControllerGetJoystick( gc );
|
||||||
|
|
||||||
|
if( joy )
|
||||||
|
SDLash_SetActiveGameController( SDL_JoystickInstanceID( joy ));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SDLash_GameControllerRemoved( SDL_JoystickID id )
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if( id == g_current_gamepad_id )
|
||||||
|
{
|
||||||
|
g_current_gamepad_id = -1;
|
||||||
|
g_current_gamepad = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// now close the device
|
||||||
|
for( i = 0; i < g_num_gamepads; i++ )
|
||||||
|
{
|
||||||
|
SDL_GameController *gc = g_gamepads[i];
|
||||||
|
SDL_Joystick *joy;
|
||||||
|
|
||||||
|
if( !gc )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
joy = SDL_GameControllerGetJoystick( gc );
|
||||||
|
|
||||||
|
if( !joy )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if( SDL_JoystickInstanceID( joy ) == id )
|
||||||
|
{
|
||||||
|
SDL_GameControllerClose( gc );
|
||||||
|
g_gamepads[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
=============
|
||||||
|
SDLash_JoyInit
|
||||||
|
|
||||||
|
=============
|
||||||
|
*/
|
||||||
|
static int SDLash_JoyInit( void )
|
||||||
|
{
|
||||||
|
int count, numJoysticks, i;
|
||||||
|
|
||||||
|
Con_Reportf( "Joystick: SDL GameController API\n" );
|
||||||
|
if( SDL_WasInit( SDL_INIT_GAMECONTROLLER ) != SDL_INIT_GAMECONTROLLER &&
|
||||||
|
SDL_InitSubSystem( SDL_INIT_GAMECONTROLLER ))
|
||||||
|
{
|
||||||
|
Con_Reportf( "Failed to initialize SDL GameController API: %s\n", SDL_GetError() );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDLash_GameControllerAddMappings( "gamecontrollerdb.txt" ); // shipped in extras.pk3
|
||||||
|
SDLash_GameControllerAddMappings( "controllermappings.txt" );
|
||||||
|
|
||||||
|
count = 0;
|
||||||
|
numJoysticks = SDL_NumJoysticks();
|
||||||
|
for ( i = 0; i < numJoysticks; i++ )
|
||||||
|
{
|
||||||
|
if( SDL_IsGameController( i ))
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SDLash_HandleGameControllerEvent( SDL_Event *ev )
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
|
||||||
|
switch( ev->type )
|
||||||
|
{
|
||||||
|
case SDL_CONTROLLERAXISMOTION:
|
||||||
|
SDLash_SetActiveGameController( ev->caxis.which );
|
||||||
|
x = ev->caxis.axis;
|
||||||
|
if( x >= 0 && x < ARRAYSIZE( g_axis_mapping ))
|
||||||
|
Joy_AxisMotionEvent( g_axis_mapping[x], ev->caxis.value );
|
||||||
|
break;
|
||||||
|
case SDL_CONTROLLERBUTTONDOWN:
|
||||||
|
case SDL_CONTROLLERBUTTONUP:
|
||||||
|
SDLash_SetActiveGameController( ev->cbutton.which );
|
||||||
|
x = ev->cbutton.button;
|
||||||
|
if( x >= 0 && x < ARRAYSIZE( g_button_mapping ))
|
||||||
|
Key_Event( g_button_mapping[x], ev->cbutton.state );
|
||||||
|
break;
|
||||||
|
case SDL_CONTROLLERDEVICEREMOVED:
|
||||||
|
SDLash_GameControllerRemoved( ev->cdevice.which );
|
||||||
|
break;
|
||||||
|
case SDL_CONTROLLERDEVICEADDED:
|
||||||
|
SDLash_GameControllerAdded( ev->cdevice.which );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
=============
|
||||||
|
Platform_Vibrate
|
||||||
|
|
||||||
|
=============
|
||||||
|
*/
|
||||||
|
void Platform_Vibrate( float time, char flags )
|
||||||
|
{
|
||||||
|
#if SDL_VERSION_ATLEAST( 2, 0, 9 )
|
||||||
|
SDL_GameController *gc = g_current_gamepad;
|
||||||
|
|
||||||
|
if( g_current_gamepad_id < 0 || !gc )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// a1ba: time is in milliseconds but might be not enough
|
||||||
|
// to spin up rumble
|
||||||
|
SDL_GameControllerRumble( gc, 0xFFFF, 0xFFFF, (int)floor( time ));
|
||||||
|
#endif // SDL_VERSION_ATLEAST( 2, 0, 9 )
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
=============
|
||||||
|
Platform_JoyInit
|
||||||
|
|
||||||
|
=============
|
||||||
|
*/
|
||||||
|
int Platform_JoyInit( void )
|
||||||
|
{
|
||||||
|
return SDLash_JoyInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
=============
|
||||||
|
Platform_JoyShutdown
|
||||||
|
|
||||||
|
=============
|
||||||
|
*/
|
||||||
|
void Platform_JoyShutdown( void )
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for( i = 0; i < g_num_gamepads; i++ )
|
||||||
|
{
|
||||||
|
if( !g_gamepads[i] )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
SDL_GameControllerClose( g_gamepads[i] );
|
||||||
|
g_gamepads[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Mem_Free( g_gamepads );
|
||||||
|
g_gamepads = NULL;
|
||||||
|
g_num_gamepads = 0;
|
||||||
|
|
||||||
|
g_current_gamepad = NULL;
|
||||||
|
g_current_gamepad_id = -1;
|
||||||
|
|
||||||
|
SDL_QuitSubSystem( SDL_INIT_GAMECONTROLLER );
|
||||||
|
}
|
||||||
|
#else // SDL_VERSION_ATLEAST( 2, 0, 0 )
|
||||||
|
void Platform_Vibrate( float time, char flags )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int Platform_JoyInit( void )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Platform_JoyShutdown( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
Loading…
Add table
Reference in a new issue