27 #if defined(HAVE_SDL) && !defined(USE_CONSOLE)
35 SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS,
"1");
37 if (SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC | SDL_INIT_EVENTS) != 0)
38 LogF(
"SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER): %s", SDL_GetError());
39 SDL_GameControllerEventState(SDL_ENABLE);
47 SDL_QuitSubSystem(SDL_INIT_GAMECONTROLLER | SDL_INIT_EVENTS);
52 #ifdef USE_SDL_MAINLOOP
56 while (SDL_PollEvent(&event))
60 case SDL_CONTROLLERAXISMOTION:
61 case SDL_CONTROLLERBUTTONDOWN:
62 case SDL_CONTROLLERBUTTONUP:
63 FeedEvent(event, FEED_BUTTONS);
65 case SDL_JOYDEVICEADDED:
66 case SDL_CONTROLLERDEVICEADDED:
67 case SDL_CONTROLLERDEVICEREMOVED:
76 const int deadZone = 16000;
81 inline int32_t abs_strength(int32_t strength)
83 return strength >= 0 ? strength : -(strength + 1);
87 void C4GamePadControl::FeedEvent(
const SDL_Event& event,
int feed)
91 case SDL_CONTROLLERAXISMOTION:
95 int32_t value = abs_strength(event.caxis.value);
96 uint8_t which =
event.caxis.which;
97 C4KeyCode keyCode =
event.caxis.value >= 0 ? maxCode : minCode;
103 event,
nullptr,
false, strength);
106 if (feed & FEED_BUTTONS)
109 if (PressedAxis.count(keyCode) && value <= deadZone)
111 PressedAxis.erase(keyCode);
114 else if (!PressedAxis.count(keyCode) && value > deadZone)
116 PressedAxis.insert(keyCode);
120 if (feed & FEED_MOVED)
123 AxisEvents[keyCode] = event;
127 case SDL_CONTROLLERBUTTONDOWN:
128 if (feed & FEED_BUTTONS)
133 case SDL_CONTROLLERBUTTONUP:
134 if (feed & FEED_BUTTONS)
142 void C4GamePadControl::CheckGamePad(
const SDL_Event& e)
146 case SDL_JOYDEVICEADDED:
148 if (!SDL_IsGameController(e.jdevice.which))
149 LogF(
"Gamepad %s isn't supported.", SDL_JoystickNameForIndex(e.jdevice.which));
151 case SDL_CONTROLLERDEVICEADDED:
153 auto device = std::make_shared<C4GamePadOpener>(e.cdevice.which);
154 Gamepads[device->GetID()] = device;
155 LogF(
"Gamepad #%d connected: %s", device->GetID(), SDL_JoystickNameForIndex(e.cdevice.which));
158 case SDL_CONTROLLERDEVICEREMOVED:
159 LogF(
"Gamepad #%d disconnected.", e.cdevice.which);
160 Gamepads.erase(e.cdevice.which);
167 for (
auto const &e : AxisEvents)
169 FeedEvent(e.second, FEED_MOVED);
178 for (
int i = 0; i < SDL_NumJoysticks(); i++)
179 if (SDL_IsGameController(i))
187 for (
const auto& p : Gamepads)
195 auto it = Gamepads.find(
id);
196 if (it != Gamepads.end())
203 for (
const auto& p : Gamepads)
204 if (p.second->GetPlayer() < 0)
212 for (
int i = 0; i < SDL_NumJoysticks(); i++)
213 if (SDL_IsGameController(i) && n-- == 0)
215 controller = SDL_GameControllerOpen(i);
216 if (!controller)
LogF(
"SDL: %s", SDL_GetError());
217 SDL_Joystick *joystick = SDL_GameControllerGetJoystick(controller);
218 haptic = SDL_HapticOpenFromJoystick(joystick);
219 if (haptic && SDL_HapticRumbleSupported(haptic))
220 SDL_HapticRumbleInit(haptic);
222 LogF(
"Gamepad #%d %s does not support rumbling.", SDL_JoystickInstanceID(joystick), SDL_JoystickName(joystick));
226 if (!controller)
LogF(
"Gamepad %d not available", iGamepad);
231 if (haptic) SDL_HapticClose(haptic);
232 if (controller) SDL_GameControllerClose(controller);
237 return SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(controller));
242 return !!SDL_GameControllerGetAttached(controller);
247 if (SDL_HapticRumbleSupported(haptic))
248 SDL_HapticRumblePlay(haptic, strength, length);
253 if (SDL_HapticRumbleSupported(haptic))
254 SDL_HapticRumbleStop(haptic);
C4Application Application
bool Log(const char *szMessage)
bool LogF(const char *strMessage,...)
bool DoKeyboardInput(C4KeyCode vk_code, C4KeyEventType event_type, bool alt, bool ctrl, bool shift, bool repeated, class C4GUI::Dialog *for_dialog=nullptr, bool fPlrCtrlOnly=false, int32_t strength=-1)
std::shared_ptr< C4GamePadOpener > GetGamePad(int gamepad)
std::shared_ptr< C4GamePadOpener > GetAvailableGamePad()
std::shared_ptr< C4GamePadOpener > GetGamePadByID(int32_t id)
C4GamePadOpener(int iGamePad)
void PlayRumble(float strength, uint32_t length)