Use SDL2 for better gamepad support and hotplug
This commit is contained in:
parent
cd7aa2c90c
commit
00cb6c2d48
@ -7,11 +7,14 @@ sudo: false
|
|||||||
language: cpp
|
language: cpp
|
||||||
os:
|
os:
|
||||||
- linux
|
- linux
|
||||||
|
# - osx
|
||||||
compiler:
|
compiler:
|
||||||
- gcc
|
- gcc
|
||||||
- clang
|
- clang
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
|
# include:
|
||||||
|
# - osx_image: xcode11.3
|
||||||
fast_finish: true
|
fast_finish: true
|
||||||
|
|
||||||
env:
|
env:
|
||||||
@ -36,6 +39,7 @@ addons:
|
|||||||
- libogg-dev
|
- libogg-dev
|
||||||
- libopenal-dev
|
- libopenal-dev
|
||||||
- libpng-dev
|
- libpng-dev
|
||||||
|
- libsdl2-dev
|
||||||
- libvorbis-dev
|
- libvorbis-dev
|
||||||
- libxrandr-dev
|
- libxrandr-dev
|
||||||
- mesa-common-dev
|
- mesa-common-dev
|
||||||
|
2
Brewfile
2
Brewfile
@ -4,8 +4,8 @@ brew "libvorbis"
|
|||||||
brew "openal-soft"
|
brew "openal-soft"
|
||||||
brew "freetype"
|
brew "freetype"
|
||||||
brew "curl"
|
brew "curl"
|
||||||
brew "nettle"
|
|
||||||
brew "fribidi"
|
brew "fribidi"
|
||||||
brew "glew"
|
brew "glew"
|
||||||
brew "harfbuzz"
|
brew "harfbuzz"
|
||||||
brew "libjpeg"
|
brew "libjpeg"
|
||||||
|
brew "sdl2"
|
||||||
|
@ -296,6 +296,19 @@ if(NOT SERVER_ONLY)
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (NOT SERVER_ONLY)
|
||||||
|
# SDL2
|
||||||
|
find_library(SDL2_LIBRARY NAMES SDL2 libSDL2)
|
||||||
|
find_path(SDL2_INCLUDEDIR NAMES SDL.h PATH_SUFFIXES SDL2 include/SDL2 include PATHS)
|
||||||
|
if (NOT SDL2_LIBRARY OR NOT SDL2_INCLUDEDIR)
|
||||||
|
message(FATAL_ERROR "SDL2 not found. "
|
||||||
|
"SDL2 is required to handle gamepad in SuperTuxKart.")
|
||||||
|
else()
|
||||||
|
include_directories("${SDL2_INCLUDEDIR}")
|
||||||
|
MESSAGE(STATUS "Use system SDL2: ${SDL2_LIBRARY}")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
# Build the irrlicht library
|
# Build the irrlicht library
|
||||||
add_subdirectory("${PROJECT_SOURCE_DIR}/lib/irrlicht")
|
add_subdirectory("${PROJECT_SOURCE_DIR}/lib/irrlicht")
|
||||||
include_directories("${PROJECT_SOURCE_DIR}/lib/irrlicht/include")
|
include_directories("${PROJECT_SOURCE_DIR}/lib/irrlicht/include")
|
||||||
@ -404,7 +417,6 @@ if (NOT SERVER_ONLY)
|
|||||||
include_directories("${RAQM_INCLUDEDIR}")
|
include_directories("${RAQM_INCLUDEDIR}")
|
||||||
MESSAGE(STATUS "Use system libraqm: ${RAQM_LIBRARY}")
|
MESSAGE(STATUS "Use system libraqm: ${RAQM_LIBRARY}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# OpenGL
|
# OpenGL
|
||||||
@ -656,6 +668,7 @@ if(NOT SERVER_ONLY)
|
|||||||
${FRIBIDI_LIBRARIES}
|
${FRIBIDI_LIBRARIES}
|
||||||
${FREETYPE_LIBRARIES}
|
${FREETYPE_LIBRARIES}
|
||||||
${HARFBUZZ_LIBRARY}
|
${HARFBUZZ_LIBRARY}
|
||||||
|
${SDL2_LIBRARY}
|
||||||
graphics_utils)
|
graphics_utils)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@ -713,7 +726,7 @@ if(MSVC OR MINGW)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(MINGW)
|
if(MINGW)
|
||||||
target_link_libraries(supertuxkart -ldxguid -ldinput8 -ldnsapi)
|
target_link_libraries(supertuxkart -ldxguid -ldnsapi)
|
||||||
if (NOT CMAKE_BUILD_TYPE MATCHES Debug)
|
if (NOT CMAKE_BUILD_TYPE MATCHES Debug)
|
||||||
target_link_libraries(supertuxkart -mwindows)
|
target_link_libraries(supertuxkart -mwindows)
|
||||||
endif()
|
endif()
|
||||||
|
@ -26,12 +26,13 @@ To build SuperTuxKart from source, you'll need to install the following packages
|
|||||||
* libpng (libpng-devel)
|
* libpng (libpng-devel)
|
||||||
* zlib (zlib-devel)
|
* zlib (zlib-devel)
|
||||||
* jpeg (libjpeg-turbo-devel)
|
* jpeg (libjpeg-turbo-devel)
|
||||||
|
* SDL2 (libsdl2-devel)
|
||||||
|
|
||||||
Fedora command:
|
Fedora command:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo dnf install @development-tools angelscript-devel \
|
sudo dnf install @development-tools angelscript-devel \
|
||||||
bluez-libs-devel cmake desktop-file-utils \
|
bluez-libs-devel cmake desktop-file-utils SDL2-devel \
|
||||||
freealut-devel freeglut-devel freetype-devel fribidi-devel \
|
freealut-devel freeglut-devel freetype-devel fribidi-devel \
|
||||||
gcc-c++ git-core libXrandr-devel libcurl-devel libjpeg-turbo-devel \
|
gcc-c++ git-core libXrandr-devel libcurl-devel libjpeg-turbo-devel \
|
||||||
libpng-devel libsquish-devel libtool libvorbis-devel mesa-libEGL-devel \
|
libpng-devel libsquish-devel libtool libvorbis-devel mesa-libEGL-devel \
|
||||||
@ -44,7 +45,7 @@ Mageia 6 command:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
su -c 'urpmi gcc-c++ cmake openssl-devel libcurl-devel freetype-devel harfbuzz-devel \
|
su -c 'urpmi gcc-c++ cmake openssl-devel libcurl-devel freetype-devel harfbuzz-devel \
|
||||||
fribidi-devel libjpeg-turbo-devel libogg-devel openal-soft-devel \
|
fribidi-devel libjpeg-turbo-devel libogg-devel openal-soft-devel SDL2-devel \
|
||||||
libpng-devel libvorbis-devel nettle-devel zlib-devel git subversion \
|
libpng-devel libvorbis-devel nettle-devel zlib-devel git subversion \
|
||||||
mesa-comon-devel libxrandr-devel libbluez-devel libfreetype6-devel'
|
mesa-comon-devel libxrandr-devel libbluez-devel libfreetype6-devel'
|
||||||
```
|
```
|
||||||
@ -52,7 +53,7 @@ mesa-comon-devel libxrandr-devel libbluez-devel libfreetype6-devel'
|
|||||||
openSUSE command:
|
openSUSE command:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo zypper install gcc-c++ cmake openssl-devel libcurl-devel \
|
sudo zypper install gcc-c++ cmake openssl-devel libcurl-devel libSDL2-devel \
|
||||||
freetype-devel harfbuzz-devel fribidi-devel libogg-devel openal-soft-devel libpng-devel \
|
freetype-devel harfbuzz-devel fribidi-devel libogg-devel openal-soft-devel libpng-devel \
|
||||||
libvorbis-devel libXrandr-devel pkgconf zlib-devel enet-devel glew-devel \
|
libvorbis-devel libXrandr-devel pkgconf zlib-devel enet-devel glew-devel \
|
||||||
libjpeg-devel bluez-devel freetype2-devel glu-devel
|
libjpeg-devel bluez-devel freetype2-devel glu-devel
|
||||||
@ -61,7 +62,7 @@ libjpeg-devel bluez-devel freetype2-devel glu-devel
|
|||||||
Ubuntu command:
|
Ubuntu command:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo apt-get install build-essential cmake libbluetooth-dev \
|
sudo apt-get install build-essential cmake libbluetooth-dev libsdl2-devel \
|
||||||
libcurl4-openssl-dev libenet-dev libfreetype6-dev libharfbuzz-dev libfribidi-dev \
|
libcurl4-openssl-dev libenet-dev libfreetype6-dev libharfbuzz-dev libfribidi-dev \
|
||||||
libgl1-mesa-dev libglew-dev libjpeg-dev libogg-dev libopenal-dev libpng-dev \
|
libgl1-mesa-dev libglew-dev libjpeg-dev libogg-dev libopenal-dev libpng-dev \
|
||||||
libssl-dev libvorbis-dev libxrandr-dev libx11-dev nettle-dev pkg-config zlib1g-dev
|
libssl-dev libvorbis-dev libxrandr-dev libx11-dev nettle-dev pkg-config zlib1g-dev
|
||||||
|
@ -487,10 +487,6 @@ struct SEvent
|
|||||||
NUMBER_OF_AXES = 32
|
NUMBER_OF_AXES = 32
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A bitmap of button states. You can use IsButtonPressed() to
|
|
||||||
( check the state of each button from 0 to (NUMBER_OF_BUTTONS - 1) */
|
|
||||||
u32 ButtonStates;
|
|
||||||
|
|
||||||
/** For AXIS_X, AXIS_Y, AXIS_Z, AXIS_R, AXIS_U and AXIS_V
|
/** For AXIS_X, AXIS_Y, AXIS_Z, AXIS_R, AXIS_U and AXIS_V
|
||||||
* Values are in the range -32768 to 32767, with 0 representing
|
* Values are in the range -32768 to 32767, with 0 representing
|
||||||
* the center position. You will receive the raw value from the
|
* the center position. You will receive the raw value from the
|
||||||
@ -501,17 +497,28 @@ struct SEvent
|
|||||||
*/
|
*/
|
||||||
s16 Axis[NUMBER_OF_AXES];
|
s16 Axis[NUMBER_OF_AXES];
|
||||||
|
|
||||||
/** The POV represents the angle of the POV hat in degrees * 100,
|
//! The ID of the joystick which generated this event.
|
||||||
* from 0 to 35,900. A value of 65535 indicates that the POV hat
|
/** This is an internal Irrlicht index; it does not map directly
|
||||||
* is centered (or not present).
|
* to any particular hardware joystick. */
|
||||||
* This value is only supported on Windows. On Linux, the POV hat
|
u32 AxisChanged;
|
||||||
* will be sent as 2 axes instead. */
|
|
||||||
u16 POV;
|
/** A bitmap of button states. You can use IsButtonPressed() to
|
||||||
|
( check the state of each button from 0 to (NUMBER_OF_BUTTONS - 1) */
|
||||||
|
u32 ButtonStates;
|
||||||
|
|
||||||
//! The ID of the joystick which generated this event.
|
//! The ID of the joystick which generated this event.
|
||||||
/** This is an internal Irrlicht index; it does not map directly
|
/** This is an internal Irrlicht index; it does not map directly
|
||||||
* to any particular hardware joystick. */
|
* to any particular hardware joystick. */
|
||||||
u8 Joystick;
|
u32 Joystick;
|
||||||
|
|
||||||
|
//! A helper function to check if a button is pressed.
|
||||||
|
bool IsAxisChanged(u32 axis) const
|
||||||
|
{
|
||||||
|
if(axis >= (u32)NUMBER_OF_AXES)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return (AxisChanged & (1 << axis)) ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
//! A helper function to check if a button is pressed.
|
//! A helper function to check if a button is pressed.
|
||||||
bool IsButtonPressed(u32 button) const
|
bool IsButtonPressed(u32 button) const
|
||||||
|
@ -129,11 +129,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
//! Define _IRR_COMPILE_WITH_JOYSTICK_SUPPORT_ if you want joystick events.
|
//! Define _IRR_COMPILE_WITH_JOYSTICK_SUPPORT_ if you want joystick events.
|
||||||
#define _IRR_COMPILE_WITH_JOYSTICK_EVENTS_
|
|
||||||
#ifdef NO_IRR_COMPILE_WITH_JOYSTICK_EVENTS_
|
|
||||||
#undef _IRR_COMPILE_WITH_JOYSTICK_EVENTS_
|
#undef _IRR_COMPILE_WITH_JOYSTICK_EVENTS_
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
//! Maximum number of texture an SMaterial can have, up to 8 are supported by Irrlicht.
|
//! Maximum number of texture an SMaterial can have, up to 8 are supported by Irrlicht.
|
||||||
#define _IRR_MATERIAL_MAX_TEXTURES_ 8
|
#define _IRR_MATERIAL_MAX_TEXTURES_ 8
|
||||||
|
@ -66,6 +66,8 @@ extern bool GLContextDebugBit;
|
|||||||
#define XRANDR_ROTATION_LEFT (1 << 1)
|
#define XRANDR_ROTATION_LEFT (1 << 1)
|
||||||
#define XRANDR_ROTATION_RIGHT (1 << 3)
|
#define XRANDR_ROTATION_RIGHT (1 << 3)
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
namespace irr
|
namespace irr
|
||||||
{
|
{
|
||||||
namespace video
|
namespace video
|
||||||
|
@ -352,11 +352,10 @@ struct SJoystickWin32Control
|
|||||||
|
|
||||||
void pollJoysticks()
|
void pollJoysticks()
|
||||||
{
|
{
|
||||||
if (0 == ActiveJoysticks.size())
|
|
||||||
return;
|
|
||||||
|
|
||||||
#if defined _IRR_COMPILE_WITH_JOYSTICK_EVENTS_
|
#if defined _IRR_COMPILE_WITH_JOYSTICK_EVENTS_
|
||||||
#ifdef _IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_
|
#ifdef _IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_
|
||||||
|
if (0 == ActiveJoysticks.size())
|
||||||
|
return;
|
||||||
|
|
||||||
u32 joystick;
|
u32 joystick;
|
||||||
DIJOYSTATE2 info;
|
DIJOYSTATE2 info;
|
||||||
|
@ -31,19 +31,6 @@
|
|||||||
#import <time.h>
|
#import <time.h>
|
||||||
#import "AppDelegate.h"
|
#import "AppDelegate.h"
|
||||||
|
|
||||||
#if defined _IRR_COMPILE_WITH_JOYSTICK_EVENTS_
|
|
||||||
|
|
||||||
#include <IOKit/IOKitLib.h>
|
|
||||||
#include <IOKit/IOCFPlugIn.h>
|
|
||||||
#ifdef MACOS_10_0_4
|
|
||||||
#include <IOKit/hidsystem/IOHIDUsageTables.h>
|
|
||||||
#else
|
|
||||||
/* The header was moved here in Mac OS X 10.1 */
|
|
||||||
#include <Kernel/IOKit/hidsystem/IOHIDUsageTables.h>
|
|
||||||
#endif
|
|
||||||
#include <IOKit/hid/IOHIDLib.h>
|
|
||||||
#include <IOKit/hid/IOHIDKeys.h>
|
|
||||||
|
|
||||||
// only OSX 10.5 seems to not need these defines...
|
// only OSX 10.5 seems to not need these defines...
|
||||||
#if !defined(__MAC_10_5) || defined(__MAC_10_6)
|
#if !defined(__MAC_10_5) || defined(__MAC_10_6)
|
||||||
// Contents from Events.h from Carbon/HIToolbox but we need it with Cocoa too
|
// Contents from Events.h from Carbon/HIToolbox but we need it with Cocoa too
|
||||||
@ -185,6 +172,19 @@ enum {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined _IRR_COMPILE_WITH_JOYSTICK_EVENTS_
|
||||||
|
|
||||||
|
#include <IOKit/IOKitLib.h>
|
||||||
|
#include <IOKit/IOCFPlugIn.h>
|
||||||
|
#ifdef MACOS_10_0_4
|
||||||
|
#include <IOKit/hidsystem/IOHIDUsageTables.h>
|
||||||
|
#else
|
||||||
|
/* The header was moved here in Mac OS X 10.1 */
|
||||||
|
#include <Kernel/IOKit/hidsystem/IOHIDUsageTables.h>
|
||||||
|
#endif
|
||||||
|
#include <IOKit/hid/IOHIDLib.h>
|
||||||
|
#include <IOKit/hid/IOHIDKeys.h>
|
||||||
|
|
||||||
struct JoystickComponent
|
struct JoystickComponent
|
||||||
{
|
{
|
||||||
IOHIDElementCookie cookie; // unique value which identifies element, will NOT change
|
IOHIDElementCookie cookie; // unique value which identifies element, will NOT change
|
||||||
|
@ -144,6 +144,14 @@ public:
|
|||||||
/** Returns if this config is sed by any devices. */
|
/** Returns if this config is sed by any devices. */
|
||||||
bool isPlugged() const { return m_plugged > 0; }
|
bool isPlugged() const { return m_plugged > 0; }
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
/** Decrease ref counter. */
|
||||||
|
void unPlugged()
|
||||||
|
{
|
||||||
|
m_plugged--;
|
||||||
|
assert(m_plugged >= 0);
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
/** Returns the number of devices using this configuration. */
|
/** Returns the number of devices using this configuration. */
|
||||||
int getNumberOfDevices() const { return m_plugged; }
|
int getNumberOfDevices() const { return m_plugged; }
|
||||||
|
@ -58,8 +58,6 @@ DeviceManager::~DeviceManager()
|
|||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
bool DeviceManager::initialize()
|
bool DeviceManager::initialize()
|
||||||
{
|
{
|
||||||
GamepadConfig *gamepadConfig = NULL;
|
|
||||||
GamePadDevice *gamepadDevice = NULL;
|
|
||||||
m_map_fire_to_select = false;
|
m_map_fire_to_select = false;
|
||||||
bool created = false;
|
bool created = false;
|
||||||
|
|
||||||
@ -110,65 +108,6 @@ bool DeviceManager::initialize()
|
|||||||
m_keyboards.push_back(new KeyboardDevice(m_keyboard_configs.get(n)));
|
m_keyboards.push_back(new KeyboardDevice(m_keyboard_configs.get(n)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(UserConfigParams::logMisc())
|
|
||||||
Log::info("Device manager","Initializing gamepad support.");
|
|
||||||
|
|
||||||
irr_driver->getDevice()->activateJoysticks(m_irrlicht_gamepads);
|
|
||||||
|
|
||||||
int num_gamepads = m_irrlicht_gamepads.size();
|
|
||||||
if(UserConfigParams::logMisc())
|
|
||||||
{
|
|
||||||
Log::info("Device manager","Irrlicht reports %d gamepads are attached to the system.",
|
|
||||||
num_gamepads);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create GamePadDevice for each physical gamepad and find a GamepadConfig to match
|
|
||||||
for (int id = 0; id < num_gamepads; id++)
|
|
||||||
{
|
|
||||||
core::stringc name = m_irrlicht_gamepads[id].Name;
|
|
||||||
|
|
||||||
// Some systems report a disk accelerometer as a gamepad, skip that
|
|
||||||
if (name.find("LIS3LV02DL") != -1) continue;
|
|
||||||
if (name == "applesmc") continue;
|
|
||||||
if (name.find("VirtualBox") == 0) continue;
|
|
||||||
|
|
||||||
if(m_irrlicht_gamepads[id].HasGenericName)
|
|
||||||
{
|
|
||||||
// On Windows all gamepads are given the same name ('microsoft
|
|
||||||
// pc-joystick driver'). Irrlicht now tries to get a better name
|
|
||||||
// from the registry, but in case this should fail we still have
|
|
||||||
// all gamepads with the same name shown in the GUI. This makes
|
|
||||||
// configuration totally useless, so append an ID to the name.
|
|
||||||
name = name + " " + StringUtils::toString(id).c_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (UserConfigParams::logMisc())
|
|
||||||
{
|
|
||||||
Log::info("Device manager","#%d: %s detected...", id, name.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns true if new configuration was created
|
|
||||||
if (getConfigForGamepad(id, name.c_str(), &gamepadConfig) == true)
|
|
||||||
{
|
|
||||||
if(UserConfigParams::logMisc())
|
|
||||||
Log::info("Device manager","creating new configuration.");
|
|
||||||
created = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(UserConfigParams::logMisc())
|
|
||||||
Log::info("Device manager","using existing configuration.");
|
|
||||||
}
|
|
||||||
|
|
||||||
gamepadConfig->setPlugged();
|
|
||||||
gamepadDevice = new GamePadDevice(id,
|
|
||||||
name.c_str(),
|
|
||||||
m_irrlicht_gamepads[id].Axes,
|
|
||||||
m_irrlicht_gamepads[id].Buttons,
|
|
||||||
gamepadConfig );
|
|
||||||
addGamepad(gamepadDevice);
|
|
||||||
} // end for
|
|
||||||
|
|
||||||
if ((UserConfigParams::m_multitouch_active == 1 &&
|
if ((UserConfigParams::m_multitouch_active == 1 &&
|
||||||
irr_driver->getDevice()->supportsTouchDevice()) ||
|
irr_driver->getDevice()->supportsTouchDevice()) ||
|
||||||
UserConfigParams::m_multitouch_active > 1)
|
UserConfigParams::m_multitouch_active > 1)
|
||||||
@ -268,20 +207,9 @@ bool DeviceManager::getConfigForGamepad(const int irr_id,
|
|||||||
// If we can't find an appropriate configuration then create one.
|
// If we can't find an appropriate configuration then create one.
|
||||||
if (!found)
|
if (!found)
|
||||||
{
|
{
|
||||||
if(irr_id < (int)(m_irrlicht_gamepads.size()))
|
// The Wiimote manager and SDL controller will set number of buttons and
|
||||||
{
|
// axes
|
||||||
*config = new GamepadConfig( name,
|
*config = new GamepadConfig(name.c_str());
|
||||||
m_irrlicht_gamepads[irr_id].Axes,
|
|
||||||
m_irrlicht_gamepads[irr_id].Buttons );
|
|
||||||
}
|
|
||||||
#ifdef ENABLE_WIIUSE
|
|
||||||
else // Wiimotes have a higher ID and do not refer to m_irrlicht_gamepads
|
|
||||||
{
|
|
||||||
// The Wiimote manager will set number of buttons and axis
|
|
||||||
*config = new GamepadConfig(name.c_str());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Add new config to list
|
// Add new config to list
|
||||||
m_gamepad_configs.push_back(*config);
|
m_gamepad_configs.push_back(*config);
|
||||||
configCreated = true;
|
configCreated = true;
|
||||||
|
@ -69,8 +69,6 @@ private:
|
|||||||
PtrVector<GamepadConfig, HOLD> m_gamepad_configs;
|
PtrVector<GamepadConfig, HOLD> m_gamepad_configs;
|
||||||
MultitouchDevice* m_multitouch_device;
|
MultitouchDevice* m_multitouch_device;
|
||||||
|
|
||||||
/** The list of all joysticks that were found and activated. */
|
|
||||||
core::array<SJoystickInfo> m_irrlicht_gamepads;
|
|
||||||
InputDevice* m_latest_used_device;
|
InputDevice* m_latest_used_device;
|
||||||
PlayerAssignMode m_assign_mode;
|
PlayerAssignMode m_assign_mode;
|
||||||
|
|
||||||
|
@ -40,20 +40,9 @@ GamePadDevice::GamePadDevice(const int irr_index, const std::string &name,
|
|||||||
config->setNumberOfButtons(button_count);
|
config->setNumberOfButtons(button_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
// HAT/POV buttons will be reported as additional axis with the values
|
m_prev_axis_directions.resize(axis_count);
|
||||||
// HAT_V_ID > HAT_H_ID. So increase the number of axis to be large
|
m_prev_axis_value.resize(axis_count);
|
||||||
// enough to handle HAT_V/H_ID as axis number.
|
m_axis_ok.resize(axis_count);
|
||||||
assert(Input::HAT_V_ID > Input::HAT_H_ID);
|
|
||||||
int adj_axis_count = axis_count > Input::HAT_V_ID ? axis_count
|
|
||||||
: Input::HAT_V_ID+1;
|
|
||||||
|
|
||||||
if(m_configuration->getNumberOfAxes()<adj_axis_count)
|
|
||||||
{
|
|
||||||
config->setNumberOfAxis(adj_axis_count);
|
|
||||||
}
|
|
||||||
m_prev_axis_directions.resize(adj_axis_count);
|
|
||||||
m_prev_axis_value.resize(adj_axis_count);
|
|
||||||
m_axis_ok.resize(adj_axis_count);
|
|
||||||
m_irr_index = irr_index;
|
m_irr_index = irr_index;
|
||||||
m_name = name;
|
m_name = name;
|
||||||
|
|
||||||
|
@ -73,6 +73,7 @@ public:
|
|||||||
int getIrrIndex() const { return m_irr_index; }
|
int getIrrIndex() const { return m_irr_index; }
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
void setIrrIndex(int i ) { m_irr_index = i; }
|
||||||
|
|
||||||
}; // class GamepadDevice
|
}; // class GamepadDevice
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
|
|
||||||
InputDevice::InputDevice()
|
InputDevice::InputDevice()
|
||||||
{
|
{
|
||||||
|
m_connected = true;
|
||||||
m_player = NULL;
|
m_player = NULL;
|
||||||
m_configuration = NULL;
|
m_configuration = NULL;
|
||||||
} // InputDevice
|
} // InputDevice
|
||||||
|
@ -47,6 +47,9 @@ enum DeviceType
|
|||||||
class InputDevice: public NoCopy
|
class InputDevice: public NoCopy
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
/** For SDL controller it's set false when it's unplugged. */
|
||||||
|
bool m_connected;
|
||||||
|
|
||||||
/** Device type (keyboard, gamepad). */
|
/** Device type (keyboard, gamepad). */
|
||||||
DeviceType m_type;
|
DeviceType m_type;
|
||||||
|
|
||||||
@ -107,6 +110,10 @@ public:
|
|||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
/** Returns the name of this device. */
|
/** Returns the name of this device. */
|
||||||
const std::string& getName() const { return m_name; }
|
const std::string& getName() const { return m_name; }
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
void setConnected(bool val) { m_connected = val; }
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
bool isConnected() const { return m_connected; }
|
||||||
}; // class InputDevice
|
}; // class InputDevice
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#include "input/input.hpp"
|
#include "input/input.hpp"
|
||||||
#include "input/keyboard_device.hpp"
|
#include "input/keyboard_device.hpp"
|
||||||
#include "input/multitouch_device.hpp"
|
#include "input/multitouch_device.hpp"
|
||||||
|
#include "input/sdl_controller.hpp"
|
||||||
#include "input/wiimote_manager.hpp"
|
#include "input/wiimote_manager.hpp"
|
||||||
#include "karts/controller/controller.hpp"
|
#include "karts/controller/controller.hpp"
|
||||||
#include "karts/abstract_kart.hpp"
|
#include "karts/abstract_kart.hpp"
|
||||||
@ -62,6 +63,9 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
#ifndef SERVER_ONLY
|
||||||
|
#include <SDL.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
InputManager *input_manager;
|
InputManager *input_manager;
|
||||||
|
|
||||||
@ -83,7 +87,14 @@ InputManager::InputManager() : m_mode(BOOTSTRAP),
|
|||||||
m_timer_in_use = false;
|
m_timer_in_use = false;
|
||||||
m_master_player_only = false;
|
m_master_player_only = false;
|
||||||
m_timer = 0;
|
m_timer = 0;
|
||||||
|
#ifndef SERVER_ONLY
|
||||||
|
SDL_SetHint(SDL_HINT_NO_SIGNAL_HANDLERS, "1");
|
||||||
|
if (SDL_Init(SDL_INIT_GAMECONTROLLER) != 0)
|
||||||
|
{
|
||||||
|
Log::error("InputManager", "Unable to initialize SDL: %s",
|
||||||
|
SDL_GetError());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
void InputManager::update(float dt)
|
void InputManager::update(float dt)
|
||||||
@ -93,6 +104,65 @@ void InputManager::update(float dt)
|
|||||||
wiimote_manager->update();
|
wiimote_manager->update();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef SERVER_ONLY
|
||||||
|
SDL_Event event;
|
||||||
|
while (SDL_PollEvent(&event))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
switch (event.type)
|
||||||
|
{
|
||||||
|
case SDL_QUIT:
|
||||||
|
{
|
||||||
|
exit(-1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SDL_JOYDEVICEADDED:
|
||||||
|
{
|
||||||
|
std::unique_ptr<SDLController> c(
|
||||||
|
new SDLController(event.jdevice.which));
|
||||||
|
SDL_JoystickID id = c->getInstanceID();
|
||||||
|
m_sdl_controller[id] = std::move(c);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SDL_JOYDEVICEREMOVED:
|
||||||
|
{
|
||||||
|
m_sdl_controller.erase(event.jdevice.which);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SDL_JOYAXISMOTION:
|
||||||
|
{
|
||||||
|
auto& controller = m_sdl_controller.at(event.jaxis.which);
|
||||||
|
if (controller->handleAxis(event))
|
||||||
|
input(controller->getEvent());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SDL_JOYHATMOTION:
|
||||||
|
{
|
||||||
|
auto& controller = m_sdl_controller.at(event.jhat.which);
|
||||||
|
if (controller->handleHat(event))
|
||||||
|
input(controller->getEvent());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SDL_JOYBUTTONUP:
|
||||||
|
case SDL_JOYBUTTONDOWN:
|
||||||
|
{
|
||||||
|
auto& controller = m_sdl_controller.at(event.jbutton.which);
|
||||||
|
if (controller->handleButton(event))
|
||||||
|
input(controller->getEvent());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (std::exception& e)
|
||||||
|
{
|
||||||
|
Log::error("SDLController", "%s", e.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if(m_timer_in_use)
|
if(m_timer_in_use)
|
||||||
{
|
{
|
||||||
m_timer -= dt;
|
m_timer -= dt;
|
||||||
@ -105,6 +175,11 @@ void InputManager::update(float dt)
|
|||||||
*/
|
*/
|
||||||
InputManager::~InputManager()
|
InputManager::~InputManager()
|
||||||
{
|
{
|
||||||
|
#ifndef SERVER_ONLY
|
||||||
|
m_sdl_controller.clear();
|
||||||
|
SDL_Quit();
|
||||||
|
#endif
|
||||||
|
|
||||||
delete m_device_manager;
|
delete m_device_manager;
|
||||||
} // ~InputManager
|
} // ~InputManager
|
||||||
|
|
||||||
@ -952,11 +1027,11 @@ EventPropagation InputManager::input(const SEvent& event)
|
|||||||
const float ORIENTATION_MULTIPLIER = 10.0f;
|
const float ORIENTATION_MULTIPLIER = 10.0f;
|
||||||
if (event.EventType == EET_JOYSTICK_INPUT_EVENT)
|
if (event.EventType == EET_JOYSTICK_INPUT_EVENT)
|
||||||
{
|
{
|
||||||
// Axes - FIXME, instead of checking all of them, ask the bindings
|
|
||||||
// which ones to poll
|
|
||||||
for (int axis_id=0; axis_id<SEvent::SJoystickEvent::NUMBER_OF_AXES ;
|
for (int axis_id=0; axis_id<SEvent::SJoystickEvent::NUMBER_OF_AXES ;
|
||||||
axis_id++)
|
axis_id++)
|
||||||
{
|
{
|
||||||
|
if (!event.JoystickEvent.IsAxisChanged(axis_id))
|
||||||
|
continue;
|
||||||
int value = event.JoystickEvent.Axis[axis_id];
|
int value = event.JoystickEvent.Axis[axis_id];
|
||||||
|
|
||||||
if (UserConfigParams::m_gamepad_debug)
|
if (UserConfigParams::m_gamepad_debug)
|
||||||
@ -970,26 +1045,6 @@ EventPropagation InputManager::input(const SEvent& event)
|
|||||||
axis_id, Input::AD_NEUTRAL, value);
|
axis_id, Input::AD_NEUTRAL, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.JoystickEvent.POV == 65535)
|
|
||||||
{
|
|
||||||
dispatchInput(Input::IT_STICKMOTION, event.JoystickEvent.Joystick,
|
|
||||||
Input::HAT_H_ID, Input::AD_NEUTRAL, 0);
|
|
||||||
dispatchInput(Input::IT_STICKMOTION, event.JoystickEvent.Joystick,
|
|
||||||
Input::HAT_V_ID, Input::AD_NEUTRAL, 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// *0.017453925f is to convert degrees to radians
|
|
||||||
dispatchInput(Input::IT_STICKMOTION, event.JoystickEvent.Joystick,
|
|
||||||
Input::HAT_H_ID, Input::AD_NEUTRAL,
|
|
||||||
(int)(cosf(event.JoystickEvent.POV*0.017453925f/100.0f)
|
|
||||||
*Input::MAX_VALUE));
|
|
||||||
dispatchInput(Input::IT_STICKMOTION, event.JoystickEvent.Joystick,
|
|
||||||
Input::HAT_V_ID, Input::AD_NEUTRAL,
|
|
||||||
(int)(sinf(event.JoystickEvent.POV*0.017453925f/100.0f)
|
|
||||||
*Input::MAX_VALUE));
|
|
||||||
}
|
|
||||||
|
|
||||||
GamePadDevice* gp =
|
GamePadDevice* gp =
|
||||||
getDeviceManager()->getGamePadFromIrrID(event.JoystickEvent.Joystick);
|
getDeviceManager()->getGamePadFromIrrID(event.JoystickEvent.Joystick);
|
||||||
|
|
||||||
|
@ -20,6 +20,8 @@
|
|||||||
#ifndef HEADER_INPUT_MANAGER_HPP
|
#ifndef HEADER_INPUT_MANAGER_HPP
|
||||||
#define HEADER_INPUT_MANAGER_HPP
|
#define HEADER_INPUT_MANAGER_HPP
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <set>
|
#include <set>
|
||||||
@ -29,6 +31,7 @@
|
|||||||
#include "utils/no_copy.hpp"
|
#include "utils/no_copy.hpp"
|
||||||
|
|
||||||
class DeviceManager;
|
class DeviceManager;
|
||||||
|
class SDLController;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Class to handle input.
|
* \brief Class to handle input.
|
||||||
@ -74,6 +77,11 @@ private:
|
|||||||
void handleStaticAction(int id0, int value);
|
void handleStaticAction(int id0, int value);
|
||||||
void inputSensing(Input::InputType type, int deviceID, int btnID,
|
void inputSensing(Input::InputType type, int deviceID, int btnID,
|
||||||
Input::AxisDirection axisDirection, int value);
|
Input::AxisDirection axisDirection, int value);
|
||||||
|
|
||||||
|
#ifndef SERVER_ONLY
|
||||||
|
std::map<int, std::unique_ptr<SDLController> > m_sdl_controller;
|
||||||
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
InputManager();
|
InputManager();
|
||||||
~InputManager();
|
~InputManager();
|
||||||
@ -101,6 +109,14 @@ public:
|
|||||||
/** Returns the ID of the player that plays with the keyboard,
|
/** Returns the ID of the player that plays with the keyboard,
|
||||||
* or -1 if none. */
|
* or -1 if none. */
|
||||||
int getPlayerKeyboardID() const;
|
int getPlayerKeyboardID() const;
|
||||||
|
#ifdef SERVER_ONLY
|
||||||
|
size_t getGamepadCount() const { return 0; }
|
||||||
|
#else
|
||||||
|
/** Returns number of active connected gamepad (with SDL), notice the
|
||||||
|
* disconnected gamepad will not be removed from device manager to allow
|
||||||
|
* re-plugging later with the same ID. */
|
||||||
|
size_t getGamepadCount() const { return m_sdl_controller.size(); }
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
extern InputManager *input_manager;
|
extern InputManager *input_manager;
|
||||||
|
180
src/input/sdl_controller.cpp
Normal file
180
src/input/sdl_controller.cpp
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
// SuperTuxKart - a fun racing game with go-kart
|
||||||
|
// Copyright (C) 2020 SuperTuxKart-Team
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
#ifndef SERVER_ONLY
|
||||||
|
|
||||||
|
#include "input/sdl_controller.hpp"
|
||||||
|
#include "input/device_config.hpp"
|
||||||
|
#include "input/device_manager.hpp"
|
||||||
|
#include "input/gamepad_device.hpp"
|
||||||
|
#include "input/input_manager.hpp"
|
||||||
|
#include "utils/log.hpp"
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
SDLController::SDLController(int device_id)
|
||||||
|
: m_gamepad(NULL)
|
||||||
|
{
|
||||||
|
m_irr_event = {};
|
||||||
|
m_irr_event.EventType = irr::EET_JOYSTICK_INPUT_EVENT;
|
||||||
|
m_game_controller = NULL;
|
||||||
|
m_joystick = NULL;
|
||||||
|
m_id = -1;
|
||||||
|
|
||||||
|
if (SDL_IsGameController(device_id))
|
||||||
|
{
|
||||||
|
m_game_controller = SDL_GameControllerOpen(device_id);
|
||||||
|
if (!m_game_controller)
|
||||||
|
throw std::runtime_error(SDL_GetError());
|
||||||
|
m_joystick = SDL_GameControllerGetJoystick(m_game_controller);
|
||||||
|
if (!m_joystick)
|
||||||
|
{
|
||||||
|
SDL_GameControllerClose(m_game_controller);
|
||||||
|
throw std::runtime_error(SDL_GetError());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_joystick = SDL_JoystickOpen(device_id);
|
||||||
|
if (!m_joystick)
|
||||||
|
throw std::runtime_error(SDL_GetError());
|
||||||
|
}
|
||||||
|
|
||||||
|
m_id = SDL_JoystickInstanceID(m_joystick);
|
||||||
|
if (m_id < 0)
|
||||||
|
{
|
||||||
|
if (m_game_controller)
|
||||||
|
SDL_GameControllerClose(m_game_controller);
|
||||||
|
else
|
||||||
|
SDL_JoystickClose(m_joystick);
|
||||||
|
throw std::runtime_error(SDL_GetError());
|
||||||
|
}
|
||||||
|
|
||||||
|
m_irr_event.JoystickEvent.Joystick = m_id;
|
||||||
|
const char* name_cstr = SDL_JoystickName(m_joystick);
|
||||||
|
if (name_cstr == NULL)
|
||||||
|
{
|
||||||
|
if (m_game_controller)
|
||||||
|
SDL_GameControllerClose(m_game_controller);
|
||||||
|
else
|
||||||
|
SDL_JoystickClose(m_joystick);
|
||||||
|
throw std::runtime_error("missing name for joystick");
|
||||||
|
}
|
||||||
|
std::string name = name_cstr;
|
||||||
|
|
||||||
|
m_buttons = SDL_JoystickNumButtons(m_joystick);
|
||||||
|
if (m_buttons < 0)
|
||||||
|
{
|
||||||
|
if (m_game_controller)
|
||||||
|
SDL_GameControllerClose(m_game_controller);
|
||||||
|
else
|
||||||
|
SDL_JoystickClose(m_joystick);
|
||||||
|
throw std::runtime_error(SDL_GetError());
|
||||||
|
}
|
||||||
|
|
||||||
|
m_axes = SDL_JoystickNumAxes(m_joystick);
|
||||||
|
if (m_axes < 0)
|
||||||
|
{
|
||||||
|
if (m_game_controller)
|
||||||
|
SDL_GameControllerClose(m_game_controller);
|
||||||
|
else
|
||||||
|
SDL_JoystickClose(m_joystick);
|
||||||
|
throw std::runtime_error(SDL_GetError());
|
||||||
|
}
|
||||||
|
|
||||||
|
m_hats = SDL_JoystickNumHats(m_joystick);
|
||||||
|
if (m_hats < 0)
|
||||||
|
{
|
||||||
|
if (m_game_controller)
|
||||||
|
SDL_GameControllerClose(m_game_controller);
|
||||||
|
else
|
||||||
|
SDL_JoystickClose(m_joystick);
|
||||||
|
throw std::runtime_error(SDL_GetError());
|
||||||
|
}
|
||||||
|
|
||||||
|
Log::info("SDLController",
|
||||||
|
"%s plugged in: buttons: %d, axes: %d, hats: %d.", name.c_str(),
|
||||||
|
m_buttons, m_axes, m_hats);
|
||||||
|
if (m_game_controller && SDL_GameControllerName(m_game_controller))
|
||||||
|
{
|
||||||
|
Log::info("SDLController", "%s uses game controller mapping %s.",
|
||||||
|
name.c_str(), SDL_GameControllerName(m_game_controller));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_buttons > irr::SEvent::SJoystickEvent::NUMBER_OF_BUTTONS)
|
||||||
|
m_buttons = irr::SEvent::SJoystickEvent::NUMBER_OF_BUTTONS;
|
||||||
|
if (m_axes > irr::SEvent::SJoystickEvent::NUMBER_OF_AXES)
|
||||||
|
m_axes = irr::SEvent::SJoystickEvent::NUMBER_OF_AXES;
|
||||||
|
// We store hats event with 4 buttons
|
||||||
|
int max_buttons_with_hats =
|
||||||
|
irr::SEvent::SJoystickEvent::NUMBER_OF_BUTTONS - (m_hats * 4);
|
||||||
|
if (m_buttons > max_buttons_with_hats)
|
||||||
|
m_hats = 0;
|
||||||
|
else
|
||||||
|
m_buttons += m_hats * 4;
|
||||||
|
|
||||||
|
DeviceManager* dm = input_manager->getDeviceManager();
|
||||||
|
GamepadConfig* cfg = NULL;
|
||||||
|
bool created = false;
|
||||||
|
|
||||||
|
if (dm->getConfigForGamepad(m_id, name, &cfg) == true)
|
||||||
|
{
|
||||||
|
Log::info("SDLController", "creating new configuration for %s.",
|
||||||
|
name.c_str());
|
||||||
|
created = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg->setNumberOfButtons(m_buttons);
|
||||||
|
cfg->setNumberOfAxis(m_axes);
|
||||||
|
cfg->setPlugged();
|
||||||
|
for (int i = 0; i < dm->getGamePadAmount(); i++)
|
||||||
|
{
|
||||||
|
GamePadDevice* d = dm->getGamePad(i);
|
||||||
|
if (d->getName() == name && !d->isConnected())
|
||||||
|
{
|
||||||
|
m_gamepad = d;
|
||||||
|
d->setConnected(true);
|
||||||
|
d->setIrrIndex(m_id);
|
||||||
|
d->setConfiguration(cfg);
|
||||||
|
if (created)
|
||||||
|
dm->save();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_gamepad = new GamePadDevice(m_id, name, m_axes, m_buttons, cfg);
|
||||||
|
dm->addGamepad(m_gamepad);
|
||||||
|
if (created)
|
||||||
|
dm->save();
|
||||||
|
} // SDLController
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
SDLController::~SDLController()
|
||||||
|
{
|
||||||
|
Log::info("SDLController", "%s unplugged.", SDL_JoystickName(m_joystick));
|
||||||
|
if (m_game_controller)
|
||||||
|
SDL_GameControllerClose(m_game_controller);
|
||||||
|
else
|
||||||
|
SDL_JoystickClose(m_joystick);
|
||||||
|
m_gamepad->getConfiguration()->unPlugged();
|
||||||
|
m_gamepad->setIrrIndex(-1);
|
||||||
|
m_gamepad->setConnected(false);
|
||||||
|
} // ~SDLController
|
||||||
|
|
||||||
|
#endif
|
131
src/input/sdl_controller.hpp
Normal file
131
src/input/sdl_controller.hpp
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
// SuperTuxKart - a fun racing game with go-kart
|
||||||
|
// Copyright (C) 2020 SuperTuxKart-Team
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
#ifndef HEADER_SDL_CONTROLLER_HPP
|
||||||
|
#define HEADER_SDL_CONTROLLER_HPP
|
||||||
|
|
||||||
|
#ifndef SERVER_ONLY
|
||||||
|
|
||||||
|
#include <SDL.h>
|
||||||
|
#include <IEventReceiver.h>
|
||||||
|
#include "utils/types.hpp"
|
||||||
|
|
||||||
|
class GamePadDevice;
|
||||||
|
|
||||||
|
class SDLController
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
SDL_GameController* m_game_controller;
|
||||||
|
|
||||||
|
SDL_Joystick* m_joystick;
|
||||||
|
|
||||||
|
GamePadDevice* m_gamepad;
|
||||||
|
|
||||||
|
int m_buttons;
|
||||||
|
|
||||||
|
int m_axes;
|
||||||
|
|
||||||
|
int m_hats;
|
||||||
|
|
||||||
|
SDL_JoystickID m_id;
|
||||||
|
|
||||||
|
irr::SEvent m_irr_event;
|
||||||
|
public:
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
SDLController(int device_id);
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
~SDLController();
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
const irr::SEvent& getEvent() const { return m_irr_event; }
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
SDL_JoystickID getInstanceID() const { return m_id; }
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
bool handleAxis(const SDL_Event& event)
|
||||||
|
{
|
||||||
|
if (event.jaxis.axis > m_axes)
|
||||||
|
return false;
|
||||||
|
m_irr_event.JoystickEvent.Axis[event.jaxis.axis] = event.jaxis.value;
|
||||||
|
uint32_t value = 1 << event.jaxis.axis;
|
||||||
|
m_irr_event.JoystickEvent.AxisChanged = value;
|
||||||
|
return true;
|
||||||
|
} // handleAxis
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
bool handleHat(const SDL_Event& event)
|
||||||
|
{
|
||||||
|
if (event.jhat.hat > m_hats)
|
||||||
|
return false;
|
||||||
|
uint32_t value = 0;
|
||||||
|
// Up, right, down and left (4 buttons)
|
||||||
|
switch (event.jhat.value)
|
||||||
|
{
|
||||||
|
case SDL_HAT_UP:
|
||||||
|
value = 1;
|
||||||
|
break;
|
||||||
|
case SDL_HAT_RIGHTUP:
|
||||||
|
value = 1 | (1 << 1);
|
||||||
|
break;
|
||||||
|
case SDL_HAT_RIGHT:
|
||||||
|
value = 1 << 1;
|
||||||
|
break;
|
||||||
|
case SDL_HAT_RIGHTDOWN:
|
||||||
|
value = (1 << 1) | (1 << 2);
|
||||||
|
break;
|
||||||
|
case SDL_HAT_DOWN:
|
||||||
|
value = 1 << 2;
|
||||||
|
break;
|
||||||
|
case SDL_HAT_LEFTDOWN:
|
||||||
|
value = (1 << 2) | (1 << 3);
|
||||||
|
break;
|
||||||
|
case SDL_HAT_LEFT:
|
||||||
|
value = 1 << 3;
|
||||||
|
break;
|
||||||
|
case SDL_HAT_LEFTUP:
|
||||||
|
value = (1 << 3) | 1;
|
||||||
|
break;
|
||||||
|
case SDL_HAT_CENTERED:
|
||||||
|
default:
|
||||||
|
value = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
int hat_start = m_buttons - (m_hats * 4);
|
||||||
|
unsigned hat_mask = (unsigned)((1 << hat_start) - 1);
|
||||||
|
m_irr_event.JoystickEvent.ButtonStates &= hat_mask;
|
||||||
|
value <<= hat_start;
|
||||||
|
value <<= (m_hats - 1) * 4;
|
||||||
|
m_irr_event.JoystickEvent.ButtonStates |= value;
|
||||||
|
m_irr_event.JoystickEvent.AxisChanged = 0;
|
||||||
|
return true;
|
||||||
|
} // handleHat
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
bool handleButton(const SDL_Event& event)
|
||||||
|
{
|
||||||
|
if (event.jbutton.button > m_buttons)
|
||||||
|
return false;
|
||||||
|
bool pressed = event.jbutton.state == SDL_PRESSED;
|
||||||
|
uint32_t value = 1 << event.jbutton.button;
|
||||||
|
if (pressed)
|
||||||
|
m_irr_event.JoystickEvent.ButtonStates |= value;
|
||||||
|
else
|
||||||
|
m_irr_event.JoystickEvent.ButtonStates &= (uint32_t)~value;
|
||||||
|
m_irr_event.JoystickEvent.AxisChanged = 0;
|
||||||
|
return true;
|
||||||
|
} // handleButton
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
@ -68,8 +68,8 @@ void Wiimote::resetIrrEvent()
|
|||||||
event.EventType = irr::EET_JOYSTICK_INPUT_EVENT;
|
event.EventType = irr::EET_JOYSTICK_INPUT_EVENT;
|
||||||
for(int i=0 ; i < irr::SEvent::SJoystickEvent::NUMBER_OF_AXES ; i++)
|
for(int i=0 ; i < irr::SEvent::SJoystickEvent::NUMBER_OF_AXES ; i++)
|
||||||
event.JoystickEvent.Axis[i] = 0;
|
event.JoystickEvent.Axis[i] = 0;
|
||||||
|
event.JoystickEvent.AxisChanged = 1;
|
||||||
event.JoystickEvent.Joystick = getIrrId();
|
event.JoystickEvent.Joystick = getIrrId();
|
||||||
event.JoystickEvent.POV = 65535;
|
|
||||||
event.JoystickEvent.ButtonStates = 0;
|
event.JoystickEvent.ButtonStates = 0;
|
||||||
} // resetIrrEvent
|
} // resetIrrEvent
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user