SDL: gamepad hot-plugging
This commit is contained in:
parent
8b5c2a3fac
commit
85b428c2e1
|
@ -137,7 +137,7 @@ unsigned int GamepadDevice::get_axis_range(u32 axis) {
|
||||||
|
|
||||||
std::string GamepadDevice::make_mapping_filename()
|
std::string GamepadDevice::make_mapping_filename()
|
||||||
{
|
{
|
||||||
std::string mapping_file = std::string(api_name()) + "_" + name();
|
std::string mapping_file = api_name() + "_" + name();
|
||||||
std::replace(mapping_file.begin(), mapping_file.end(), '/', '-');
|
std::replace(mapping_file.begin(), mapping_file.end(), '/', '-');
|
||||||
std::replace(mapping_file.begin(), mapping_file.end(), '\\', '-');
|
std::replace(mapping_file.begin(), mapping_file.end(), '\\', '-');
|
||||||
std::replace(mapping_file.begin(), mapping_file.end(), ':', '-');
|
std::replace(mapping_file.begin(), mapping_file.end(), ':', '-');
|
||||||
|
|
|
@ -26,8 +26,8 @@ class GamepadDevice
|
||||||
{
|
{
|
||||||
typedef void (*input_detected_cb)(u32 code);
|
typedef void (*input_detected_cb)(u32 code);
|
||||||
public:
|
public:
|
||||||
virtual const char* api_name() = 0;
|
const std::string& api_name() { return _api_name; }
|
||||||
virtual const char* name() = 0;
|
const std::string& name() { return _name; }
|
||||||
int maple_port() { return _maple_port; }
|
int maple_port() { return _maple_port; }
|
||||||
void set_maple_port(int port) { _maple_port = port; }
|
void set_maple_port(int port) { _maple_port = port; }
|
||||||
void gamepad_btn_input(u32 code, bool pressed);
|
void gamepad_btn_input(u32 code, bool pressed);
|
||||||
|
@ -64,7 +64,7 @@ public:
|
||||||
static GamepadDevice *GetGamepad(int index);
|
static GamepadDevice *GetGamepad(int index);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
GamepadDevice(int maple_port) : _maple_port(maple_port), input_mapper(NULL), _input_detected(NULL) {
|
GamepadDevice(int maple_port, const char *api_name) : _api_name(api_name), _maple_port(maple_port), input_mapper(NULL), _input_detected(NULL) {
|
||||||
_gamepads_mutex.lock();
|
_gamepads_mutex.lock();
|
||||||
_gamepads.push_back(this);
|
_gamepads.push_back(this);
|
||||||
_gamepads_mutex.unlock();
|
_gamepads_mutex.unlock();
|
||||||
|
@ -73,6 +73,7 @@ protected:
|
||||||
|
|
||||||
virtual void load_axis_min_max(u32 axis) {}
|
virtual void load_axis_min_max(u32 axis) {}
|
||||||
|
|
||||||
|
std::string _name;
|
||||||
InputMapping *input_mapper;
|
InputMapping *input_mapper;
|
||||||
std::map<u32, int> axis_min_values;
|
std::map<u32, int> axis_min_values;
|
||||||
std::map<u32, unsigned int> axis_ranges;
|
std::map<u32, unsigned int> axis_ranges;
|
||||||
|
@ -82,6 +83,7 @@ private:
|
||||||
unsigned int get_axis_range(u32 axis);
|
unsigned int get_axis_range(u32 axis);
|
||||||
std::string make_mapping_filename();
|
std::string make_mapping_filename();
|
||||||
|
|
||||||
|
std::string _api_name;
|
||||||
int _maple_port;
|
int _maple_port;
|
||||||
bool _detecting_button = false;
|
bool _detecting_button = false;
|
||||||
input_detected_cb _input_detected;
|
input_detected_cb _input_detected;
|
||||||
|
|
|
@ -616,9 +616,9 @@ static void gui_display_settings()
|
||||||
GamepadDevice *gamepad = GamepadDevice::GetGamepad(i);
|
GamepadDevice *gamepad = GamepadDevice::GetGamepad(i);
|
||||||
if (gamepad == NULL)
|
if (gamepad == NULL)
|
||||||
continue;
|
continue;
|
||||||
ImGui::Text("%s", gamepad->api_name());
|
ImGui::Text("%s", gamepad->api_name().c_str());
|
||||||
ImGui::NextColumn();
|
ImGui::NextColumn();
|
||||||
ImGui::Text("%s", gamepad->name());
|
ImGui::Text("%s", gamepad->name().c_str());
|
||||||
ImGui::NextColumn();
|
ImGui::NextColumn();
|
||||||
char port_name[32];
|
char port_name[32];
|
||||||
sprintf(port_name, "##mapleport%d", i);
|
sprintf(port_name, "##mapleport%d", i);
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "khronos/GL3/gl3w.h"
|
#include "khronos/GL3/gl3w.h"
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
#include "hw/maple/maple_devs.h"
|
||||||
#include "sdl_gamepad.h"
|
#include "sdl_gamepad.h"
|
||||||
#include "sdl_keyboard.h"
|
#include "sdl_keyboard.h"
|
||||||
|
|
||||||
|
@ -23,8 +24,6 @@ static SDL_GLContext glcontext;
|
||||||
#endif
|
#endif
|
||||||
#define WINDOW_HEIGHT 480
|
#define WINDOW_HEIGHT 480
|
||||||
|
|
||||||
static SDLGamepadDevice* sdl_gamepads[4] = { NULL };
|
|
||||||
static SDL_JoystickID joystick_ids[ARRAY_SIZE(sdl_gamepads)] = { 0 };
|
|
||||||
static SDLMouseGamepadDevice* sdl_mouse_gamepad = NULL;
|
static SDLMouseGamepadDevice* sdl_mouse_gamepad = NULL;
|
||||||
static SDLKbGamepadDevice* sdl_kb_gamepad = NULL;
|
static SDLKbGamepadDevice* sdl_kb_gamepad = NULL;
|
||||||
static SDLKeyboardDevice* sdl_keyboard = NULL;
|
static SDLKeyboardDevice* sdl_keyboard = NULL;
|
||||||
|
@ -44,6 +43,25 @@ extern s32 mo_y_abs;
|
||||||
|
|
||||||
extern int screen_width, screen_height;
|
extern int screen_width, screen_height;
|
||||||
|
|
||||||
|
static void sdl_open_joystick(int index)
|
||||||
|
{
|
||||||
|
SDL_Joystick *pJoystick = SDL_JoystickOpen(index);
|
||||||
|
|
||||||
|
if (pJoystick == NULL)
|
||||||
|
{
|
||||||
|
printf("SDL: Cannot open joystick %d\n", index + 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
new SDLGamepadDevice(index < MAPLE_PORTS ? index : -1, pJoystick); // TODO save/restore maple port
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sdl_close_joystick(SDL_JoystickID instance)
|
||||||
|
{
|
||||||
|
SDLGamepadDevice *device = SDLGamepadDevice::GetSDLGamepad(instance);
|
||||||
|
if (device != NULL)
|
||||||
|
delete device;
|
||||||
|
}
|
||||||
|
|
||||||
void input_sdl_init()
|
void input_sdl_init()
|
||||||
{
|
{
|
||||||
if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0)
|
if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0)
|
||||||
|
@ -53,25 +71,10 @@ void input_sdl_init()
|
||||||
die("error initializing SDL Joystick subsystem");
|
die("error initializing SDL Joystick subsystem");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Open joystick device
|
|
||||||
int numjoys = SDL_NumJoysticks();
|
|
||||||
printf("Number of Joysticks found = %i\n", numjoys);
|
|
||||||
for (int i = 0; i < numjoys && i < ARRAY_SIZE(sdl_gamepads); i++)
|
|
||||||
{
|
|
||||||
SDL_Joystick *pJoystick = SDL_JoystickOpen(i);
|
|
||||||
|
|
||||||
if (pJoystick == NULL)
|
|
||||||
{
|
|
||||||
printf("Cannot open joystick %d\n", i + 1);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
joystick_ids[i] = SDL_JoystickInstanceID(pJoystick);
|
|
||||||
|
|
||||||
sdl_gamepads[i] = new SDLGamepadDevice(i, pJoystick);
|
|
||||||
}
|
|
||||||
SDL_SetRelativeMouseMode(SDL_FALSE);
|
SDL_SetRelativeMouseMode(SDL_FALSE);
|
||||||
|
|
||||||
sdl_keyboard = new SDLKeyboardDevice(0); // FIXME ports!
|
sdl_keyboard = new SDLKeyboardDevice(0); // FIXME maple ports!
|
||||||
sdl_kb_gamepad = new SDLKbGamepadDevice(0);
|
sdl_kb_gamepad = new SDLKbGamepadDevice(0);
|
||||||
sdl_mouse_gamepad = new SDLMouseGamepadDevice(0);
|
sdl_mouse_gamepad = new SDLMouseGamepadDevice(0);
|
||||||
}
|
}
|
||||||
|
@ -113,20 +116,18 @@ void input_sdl_handle(u32 port)
|
||||||
break;
|
break;
|
||||||
case SDL_JOYBUTTONDOWN:
|
case SDL_JOYBUTTONDOWN:
|
||||||
case SDL_JOYBUTTONUP:
|
case SDL_JOYBUTTONUP:
|
||||||
for (int i = 0; i < ARRAY_SIZE(sdl_gamepads); i++)
|
{
|
||||||
if (joystick_ids[i] == event.jbutton.which)
|
SDLGamepadDevice *device = SDLGamepadDevice::GetSDLGamepad((SDL_JoystickID)event.jbutton.which);
|
||||||
{
|
if (device != NULL)
|
||||||
sdl_gamepads[i]->gamepad_btn_input(event.jbutton.button, event.type == SDL_JOYBUTTONDOWN);
|
device->gamepad_btn_input(event.jbutton.button, event.type == SDL_JOYBUTTONDOWN);
|
||||||
break;
|
}
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case SDL_JOYAXISMOTION:
|
case SDL_JOYAXISMOTION:
|
||||||
for (int i = 0; i < ARRAY_SIZE(sdl_gamepads); i++)
|
{
|
||||||
if (joystick_ids[i] == event.jaxis.which)
|
SDLGamepadDevice *device = SDLGamepadDevice::GetSDLGamepad((SDL_JoystickID)event.jaxis.which);
|
||||||
{
|
if (device != NULL)
|
||||||
sdl_gamepads[i]->gamepad_axis_input(event.jaxis.axis, event.jaxis.value);
|
device->gamepad_axis_input(event.jaxis.axis, event.jaxis.value);
|
||||||
break;
|
}
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDL_MOUSEMOTION:
|
case SDL_MOUSEMOTION:
|
||||||
|
@ -153,6 +154,14 @@ void input_sdl_handle(u32 port)
|
||||||
}
|
}
|
||||||
sdl_mouse_gamepad->gamepad_btn_input(event.button.button, event.button.state == SDL_PRESSED);
|
sdl_mouse_gamepad->gamepad_btn_input(event.button.button, event.button.state == SDL_PRESSED);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SDL_JOYDEVICEADDED:
|
||||||
|
sdl_open_joystick(event.jdevice.which);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SDL_JOYDEVICEREMOVED:
|
||||||
|
sdl_close_joystick((SDL_JoystickID)event.jdevice.which);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,29 +44,47 @@ public:
|
||||||
class SDLGamepadDevice : public GamepadDevice
|
class SDLGamepadDevice : public GamepadDevice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SDLGamepadDevice(int maple_port, SDL_Joystick* sdl_joystick) : GamepadDevice(maple_port), sdl_joystick(sdl_joystick)
|
SDLGamepadDevice(int maple_port, SDL_Joystick* sdl_joystick) : GamepadDevice(maple_port, "SDL"), sdl_joystick(sdl_joystick)
|
||||||
{
|
{
|
||||||
_name = SDL_JoystickName(sdl_joystick);
|
_name = SDL_JoystickName(sdl_joystick);
|
||||||
|
sdl_joystick_instance = SDL_JoystickInstanceID(sdl_joystick);
|
||||||
|
printf("SDL: Opened joystick on port %d: '%s' ", maple_port, _name.c_str());
|
||||||
if (!find_mapping())
|
if (!find_mapping())
|
||||||
{
|
{
|
||||||
if (_name == "Microsoft X-Box 360 pad")
|
if (_name == "Microsoft X-Box 360 pad")
|
||||||
{
|
{
|
||||||
input_mapper = new Xbox360InputMapping();
|
input_mapper = new Xbox360InputMapping();
|
||||||
printf("Using Xbox 360 mapping\n");
|
printf("using Xbox 360 mapping\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
input_mapper = new DefaultInputMapping();
|
input_mapper = new DefaultInputMapping();
|
||||||
printf("Using default mapping\n");
|
printf("using default mapping\n");
|
||||||
}
|
}
|
||||||
save_mapping();
|
save_mapping();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
printf("using custom mapping '%s'\n", input_mapper->name.c_str());
|
||||||
|
auto it = sdl_gamepads.find(sdl_joystick_instance);
|
||||||
|
if (it != sdl_gamepads.end())
|
||||||
|
delete it->second;
|
||||||
|
sdl_gamepads[sdl_joystick_instance] = this;
|
||||||
}
|
}
|
||||||
virtual const char* api_name() override { return "SDL"; }
|
|
||||||
virtual const char* name() override { return _name.c_str(); }
|
|
||||||
virtual ~SDLGamepadDevice() override
|
virtual ~SDLGamepadDevice() override
|
||||||
{
|
{
|
||||||
|
printf("SDL: Joystick '%s' on port %d disconnected\n", _name.c_str(), maple_port());
|
||||||
SDL_JoystickClose(sdl_joystick);
|
SDL_JoystickClose(sdl_joystick);
|
||||||
|
sdl_gamepads.erase(sdl_joystick_instance);
|
||||||
|
}
|
||||||
|
SDL_JoystickID sdl_instance() { return sdl_joystick_instance; }
|
||||||
|
|
||||||
|
static SDLGamepadDevice *GetSDLGamepad(SDL_JoystickID id)
|
||||||
|
{
|
||||||
|
auto it = sdl_gamepads.find(id);
|
||||||
|
if (it != sdl_gamepads.end())
|
||||||
|
return it->second;
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -77,10 +95,13 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string _name;
|
|
||||||
SDL_Joystick* sdl_joystick;
|
SDL_Joystick* sdl_joystick;
|
||||||
|
SDL_JoystickID sdl_joystick_instance;
|
||||||
|
static std::map<SDL_JoystickID, SDLGamepadDevice*> sdl_gamepads;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::map<SDL_JoystickID, SDLGamepadDevice*> SDLGamepadDevice::sdl_gamepads;
|
||||||
|
|
||||||
class KbInputMapping : public InputMapping
|
class KbInputMapping : public InputMapping
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -107,13 +128,12 @@ public:
|
||||||
class SDLKbGamepadDevice : public GamepadDevice
|
class SDLKbGamepadDevice : public GamepadDevice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SDLKbGamepadDevice(int maple_port) : GamepadDevice(maple_port)
|
SDLKbGamepadDevice(int maple_port) : GamepadDevice(maple_port, "SDL")
|
||||||
{
|
{
|
||||||
|
_name = "Keyboard";
|
||||||
if (!find_mapping())
|
if (!find_mapping())
|
||||||
input_mapper = new KbInputMapping();
|
input_mapper = new KbInputMapping();
|
||||||
}
|
}
|
||||||
virtual const char* api_name() override { return "SDL"; }
|
|
||||||
virtual const char* name() override { return "Keyboard"; }
|
|
||||||
virtual ~SDLKbGamepadDevice() {}
|
virtual ~SDLKbGamepadDevice() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -134,13 +154,12 @@ public:
|
||||||
class SDLMouseGamepadDevice : public GamepadDevice
|
class SDLMouseGamepadDevice : public GamepadDevice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SDLMouseGamepadDevice(int maple_port) : GamepadDevice(maple_port)
|
SDLMouseGamepadDevice(int maple_port) : GamepadDevice(maple_port, "SDL")
|
||||||
{
|
{
|
||||||
|
_name = "Mouse";
|
||||||
if (!find_mapping())
|
if (!find_mapping())
|
||||||
input_mapper = new MouseInputMapping();
|
input_mapper = new MouseInputMapping();
|
||||||
}
|
}
|
||||||
virtual const char* api_name() override { return "SDL"; }
|
|
||||||
virtual const char* name() override { return "Mouse"; }
|
|
||||||
virtual ~SDLMouseGamepadDevice() {}
|
virtual ~SDLMouseGamepadDevice() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue