Reinitialize gamepads command and fix EVDEV going bonkers on gamepad suddenly disconn...
[lsnes.git] / src / platform / macosx / joystick.cpp
blobd0ce3c5fa73271d8dee430c1714048a6874f50a2
1 #include "sdl-sysjoy-interface.h"
2 #include "core/keymapper.hpp"
3 #include "core/joystickapi.hpp"
4 #include "core/messages.hpp"
5 #include "core/misc.hpp"
6 #include "library/string.hpp"
7 #include <cstdlib>
9 namespace
11 volatile bool quit_signaled = false;
12 volatile bool quit_ack = false;
13 const unsigned POLL_WAIT = 20000;
14 std::map<uint8_t, SDL_Joystick*> joys;
15 std::map<uint8_t, unsigned> idx_to_jid;
17 void probe_joystick(int index)
19 SDL_Joystick* j = new SDL_Joystick;
20 memset(j, 0, sizeof(*j));
21 j->index = index;
22 if(SDL_SYS_JoystickOpen(j) < 0) {
23 delete j;
24 return;
26 uint64_t joyid = reinterpret_cast<size_t>(j);
27 joys[index] = j;
28 idx_to_jid[index] = lsnes_gamepads.add(j->name);
29 gamepad::pad& ngp = lsnes_gamepads[idx_to_jid[index]];
31 for(int i = 0; i < j->nbuttons; i++)
32 ngp.add_button(i, (stringfmt() << "Button #" << i).str());
33 for(int i = 0; i < j->naxes; i++)
34 ngp.add_axis(i, -32768, 32767, false, (stringfmt() << "Axis #" << i).str());
35 for(int i = 0; i < j->nhats; i++)
36 ngp.add_hat(i, (stringfmt() << "Hat #" << i).str());
39 struct _joystick_driver drv = {
40 .init = []() -> void {
41 quit_signaled = false;
42 quit_ack = false;
43 int jcnt = SDL_SYS_JoystickInit();
44 if(jcnt < 0)
45 return;
46 for(int i = 0; i < jcnt; i++)
47 probe_joystick(i);
48 quit_ack = quit_signaled = false;
50 .quit = []() -> void {
51 quit_signaled = true;
52 while(!quit_ack);
53 for(auto i : joys) {
54 SDL_SYS_JoystickClose(i.second);
55 delete i.second;
57 SDL_SYS_JoystickQuit();
59 .thread_fn = []() -> void {
60 while(!quit_signaled) {
61 for(auto i : joys)
62 SDL_SYS_JoystickUpdate(i.second);
63 usleep(POLL_WAIT);
65 quit_ack = true;
67 .signal = []() -> void {
68 quit_signaled = true;
69 while(!quit_ack);
71 .name = []() -> const char* { return "Mac OS X joystick plugin"; }
73 struct joystick_driver _drv(drv);
76 uint8_t SDL_numjoysticks;
79 int SDL_PrivateJoystickAxis(SDL_Joystick* j, uint8_t axis, int16_t value)
81 lsnes_gamepads[j->index].report_axis(axis, value);
82 j->axes[axis] = value;
83 return 0;
86 int SDL_PrivateJoystickBall(SDL_Joystick* j, uint8_t ball, int16_t dx, int16_t dy)
88 //We don't support balls.
89 return 0;
92 int SDL_PrivateJoystickHat(SDL_Joystick* j, uint8_t hat, uint8_t val)
94 int angle = -1;
95 if(val > 0)
96 angle = 4500 * (val - 1);
97 lsnes_gamepads[j->index].report_hat(hat, angle);
98 j->hats[hat] = val;
99 return 0;
102 int SDL_PrivateJoystickButton(SDL_Joystick* j, uint8_t button, uint8_t state)
104 lsnes_gamepads[j->index].report_button(button, state != 0);
105 j->buttons[button] = state;
106 return 0;
109 void SDL_SetError(const char* err)
111 messages << "Joystick driver error: " << err << std::endl;