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 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(), ':', '-');
|
||||
|
|
|
@ -26,8 +26,8 @@ class GamepadDevice
|
|||
{
|
||||
typedef void (*input_detected_cb)(u32 code);
|
||||
public:
|
||||
virtual const char* api_name() = 0;
|
||||
virtual const char* name() = 0;
|
||||
const std::string& api_name() { return _api_name; }
|
||||
const std::string& name() { return _name; }
|
||||
int maple_port() { return _maple_port; }
|
||||
void set_maple_port(int port) { _maple_port = port; }
|
||||
void gamepad_btn_input(u32 code, bool pressed);
|
||||
|
@ -64,7 +64,7 @@ public:
|
|||
static GamepadDevice *GetGamepad(int index);
|
||||
|
||||
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.push_back(this);
|
||||
_gamepads_mutex.unlock();
|
||||
|
@ -73,6 +73,7 @@ protected:
|
|||
|
||||
virtual void load_axis_min_max(u32 axis) {}
|
||||
|
||||
std::string _name;
|
||||
InputMapping *input_mapper;
|
||||
std::map<u32, int> axis_min_values;
|
||||
std::map<u32, unsigned int> axis_ranges;
|
||||
|
@ -82,6 +83,7 @@ private:
|
|||
unsigned int get_axis_range(u32 axis);
|
||||
std::string make_mapping_filename();
|
||||
|
||||
std::string _api_name;
|
||||
int _maple_port;
|
||||
bool _detecting_button = false;
|
||||
input_detected_cb _input_detected;
|
||||
|
|
|
@ -616,9 +616,9 @@ static void gui_display_settings()
|
|||
GamepadDevice *gamepad = GamepadDevice::GetGamepad(i);
|
||||
if (gamepad == NULL)
|
||||
continue;
|
||||
ImGui::Text("%s", gamepad->api_name());
|
||||
ImGui::Text("%s", gamepad->api_name().c_str());
|
||||
ImGui::NextColumn();
|
||||
ImGui::Text("%s", gamepad->name());
|
||||
ImGui::Text("%s", gamepad->name().c_str());
|
||||
ImGui::NextColumn();
|
||||
char port_name[32];
|
||||
sprintf(port_name, "##mapleport%d", i);
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "khronos/GL3/gl3w.h"
|
||||
#endif
|
||||
#endif
|
||||
#include "hw/maple/maple_devs.h"
|
||||
#include "sdl_gamepad.h"
|
||||
#include "sdl_keyboard.h"
|
||||
|
||||
|
@ -23,8 +24,6 @@ static SDL_GLContext glcontext;
|
|||
#endif
|
||||
#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 SDLKbGamepadDevice* sdl_kb_gamepad = NULL;
|
||||
static SDLKeyboardDevice* sdl_keyboard = NULL;
|
||||
|
@ -44,6 +43,25 @@ extern s32 mo_y_abs;
|
|||
|
||||
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()
|
||||
{
|
||||
if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0)
|
||||
|
@ -53,25 +71,10 @@ void input_sdl_init()
|
|||
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_keyboard = new SDLKeyboardDevice(0); // FIXME ports!
|
||||
sdl_keyboard = new SDLKeyboardDevice(0); // FIXME maple ports!
|
||||
sdl_kb_gamepad = new SDLKbGamepadDevice(0);
|
||||
sdl_mouse_gamepad = new SDLMouseGamepadDevice(0);
|
||||
}
|
||||
|
@ -113,19 +116,17 @@ void input_sdl_handle(u32 port)
|
|||
break;
|
||||
case SDL_JOYBUTTONDOWN:
|
||||
case SDL_JOYBUTTONUP:
|
||||
for (int i = 0; i < ARRAY_SIZE(sdl_gamepads); i++)
|
||||
if (joystick_ids[i] == event.jbutton.which)
|
||||
{
|
||||
sdl_gamepads[i]->gamepad_btn_input(event.jbutton.button, event.type == SDL_JOYBUTTONDOWN);
|
||||
break;
|
||||
SDLGamepadDevice *device = SDLGamepadDevice::GetSDLGamepad((SDL_JoystickID)event.jbutton.which);
|
||||
if (device != NULL)
|
||||
device->gamepad_btn_input(event.jbutton.button, event.type == SDL_JOYBUTTONDOWN);
|
||||
}
|
||||
break;
|
||||
case SDL_JOYAXISMOTION:
|
||||
for (int i = 0; i < ARRAY_SIZE(sdl_gamepads); i++)
|
||||
if (joystick_ids[i] == event.jaxis.which)
|
||||
{
|
||||
sdl_gamepads[i]->gamepad_axis_input(event.jaxis.axis, event.jaxis.value);
|
||||
break;
|
||||
SDLGamepadDevice *device = SDLGamepadDevice::GetSDLGamepad((SDL_JoystickID)event.jaxis.which);
|
||||
if (device != NULL)
|
||||
device->gamepad_axis_input(event.jaxis.axis, event.jaxis.value);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -153,6 +154,14 @@ void input_sdl_handle(u32 port)
|
|||
}
|
||||
sdl_mouse_gamepad->gamepad_btn_input(event.button.button, event.button.state == SDL_PRESSED);
|
||||
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
|
||||
{
|
||||
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);
|
||||
sdl_joystick_instance = SDL_JoystickInstanceID(sdl_joystick);
|
||||
printf("SDL: Opened joystick on port %d: '%s' ", maple_port, _name.c_str());
|
||||
if (!find_mapping())
|
||||
{
|
||||
if (_name == "Microsoft X-Box 360 pad")
|
||||
{
|
||||
input_mapper = new Xbox360InputMapping();
|
||||
printf("Using Xbox 360 mapping\n");
|
||||
printf("using Xbox 360 mapping\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
input_mapper = new DefaultInputMapping();
|
||||
printf("Using default mapping\n");
|
||||
printf("using default mapping\n");
|
||||
}
|
||||
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
|
||||
{
|
||||
printf("SDL: Joystick '%s' on port %d disconnected\n", _name.c_str(), maple_port());
|
||||
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:
|
||||
|
@ -77,10 +95,13 @@ protected:
|
|||
}
|
||||
|
||||
private:
|
||||
std::string _name;
|
||||
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
|
||||
{
|
||||
public:
|
||||
|
@ -107,13 +128,12 @@ public:
|
|||
class SDLKbGamepadDevice : public GamepadDevice
|
||||
{
|
||||
public:
|
||||
SDLKbGamepadDevice(int maple_port) : GamepadDevice(maple_port)
|
||||
SDLKbGamepadDevice(int maple_port) : GamepadDevice(maple_port, "SDL")
|
||||
{
|
||||
_name = "Keyboard";
|
||||
if (!find_mapping())
|
||||
input_mapper = new KbInputMapping();
|
||||
}
|
||||
virtual const char* api_name() override { return "SDL"; }
|
||||
virtual const char* name() override { return "Keyboard"; }
|
||||
virtual ~SDLKbGamepadDevice() {}
|
||||
};
|
||||
|
||||
|
@ -134,13 +154,12 @@ public:
|
|||
class SDLMouseGamepadDevice : public GamepadDevice
|
||||
{
|
||||
public:
|
||||
SDLMouseGamepadDevice(int maple_port) : GamepadDevice(maple_port)
|
||||
SDLMouseGamepadDevice(int maple_port) : GamepadDevice(maple_port, "SDL")
|
||||
{
|
||||
_name = "Mouse";
|
||||
if (!find_mapping())
|
||||
input_mapper = new MouseInputMapping();
|
||||
}
|
||||
virtual const char* api_name() override { return "SDL"; }
|
||||
virtual const char* name() override { return "Mouse"; }
|
||||
virtual ~SDLMouseGamepadDevice() {}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue