diff options
author | Kae <80987908+Novaenia@users.noreply.github.com> | 2023-06-28 22:52:09 +1000 |
---|---|---|
committer | Kae <80987908+Novaenia@users.noreply.github.com> | 2023-06-28 22:52:09 +1000 |
commit | 0b7ddd05d19fa320b25ad0f5c968852dc416583d (patch) | |
tree | 82dcdaa98157a22c453af124091957dbf162f56c /source/application/StarMainApplication_sdl.cpp | |
parent | 0886098242be9e41f351519f8a5958995e8ed9ab (diff) |
Add extremely basic controller support (only movement)
Diffstat (limited to 'source/application/StarMainApplication_sdl.cpp')
-rw-r--r-- | source/application/StarMainApplication_sdl.cpp | 158 |
1 files changed, 102 insertions, 56 deletions
diff --git a/source/application/StarMainApplication_sdl.cpp b/source/application/StarMainApplication_sdl.cpp index d03e141..818cada 100644 --- a/source/application/StarMainApplication_sdl.cpp +++ b/source/application/StarMainApplication_sdl.cpp @@ -151,45 +151,56 @@ Maybe<Key> keyFromSdlKeyCode(SDL_Keycode sym) { } KeyMod keyModsFromSdlKeyMods(uint16_t mod) { - KeyMod keyMod = KeyMod::NoMod; - - if (mod & KMOD_LSHIFT) - keyMod |= KeyMod::LShift; - if (mod & KMOD_RSHIFT) - keyMod |= KeyMod::RShift; - if (mod & KMOD_LCTRL) - keyMod |= KeyMod::LCtrl; - if (mod & KMOD_RCTRL) - keyMod |= KeyMod::RCtrl; - if (mod & KMOD_LALT) - keyMod |= KeyMod::LAlt; - if (mod & KMOD_RALT) - keyMod |= KeyMod::RAlt; - if (mod & KMOD_LGUI) - keyMod |= KeyMod::LGui; - if (mod & KMOD_RGUI) - keyMod |= KeyMod::RGui; - if (mod & KMOD_NUM) - keyMod |= KeyMod::Num; - if (mod & KMOD_CAPS) - keyMod |= KeyMod::Caps; - if (mod & KMOD_MODE) - keyMod |= KeyMod::AltGr; - - return keyMod; + return static_cast<KeyMod>(mod); } MouseButton mouseButtonFromSdlMouseButton(uint8_t button) { - if (button == SDL_BUTTON_LEFT) - return MouseButton::Left; - else if (button == SDL_BUTTON_MIDDLE) - return MouseButton::Middle; - else if (button == SDL_BUTTON_RIGHT) - return MouseButton::Right; - else if (button == SDL_BUTTON_X1) - return MouseButton::FourthButton; - else - return MouseButton::FifthButton; + switch (button) { + case SDL_BUTTON_LEFT: return MouseButton::Left; + case SDL_BUTTON_MIDDLE: return MouseButton::Middle; + case SDL_BUTTON_RIGHT: return MouseButton::Right; + case SDL_BUTTON_X1: return MouseButton::FourthButton; + default: return MouseButton::FifthButton; + } +} + +ControllerAxis controllerAxisFromSdlControllerAxis(uint8_t axis) { + switch (axis) { + case SDL_CONTROLLER_AXIS_LEFTX: return ControllerAxis::LeftX; + case SDL_CONTROLLER_AXIS_LEFTY: return ControllerAxis::LeftY; + case SDL_CONTROLLER_AXIS_RIGHTX: return ControllerAxis::RightX; + case SDL_CONTROLLER_AXIS_RIGHTY: return ControllerAxis::RightY; + case SDL_CONTROLLER_AXIS_TRIGGERLEFT: return ControllerAxis::TriggerLeft; + case SDL_CONTROLLER_AXIS_TRIGGERRIGHT: return ControllerAxis::TriggerRight; + default: return ControllerAxis::Invalid; + } +} + +ControllerButton controllerButtonFromSdlControllerButton(uint8_t button) { + switch (button) { + case SDL_CONTROLLER_BUTTON_A: return ControllerButton::A; + case SDL_CONTROLLER_BUTTON_B: return ControllerButton::B; + case SDL_CONTROLLER_BUTTON_X: return ControllerButton::X; + case SDL_CONTROLLER_BUTTON_Y: return ControllerButton::Y; + case SDL_CONTROLLER_BUTTON_BACK: return ControllerButton::Back; + case SDL_CONTROLLER_BUTTON_GUIDE: return ControllerButton::Guide; + case SDL_CONTROLLER_BUTTON_START: return ControllerButton::Start; + case SDL_CONTROLLER_BUTTON_LEFTSTICK: return ControllerButton::LeftStick; + case SDL_CONTROLLER_BUTTON_RIGHTSTICK: return ControllerButton::RightStick; + case SDL_CONTROLLER_BUTTON_LEFTSHOULDER: return ControllerButton::LeftShoulder; + case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER: return ControllerButton::RightShoulder; + case SDL_CONTROLLER_BUTTON_DPAD_UP: return ControllerButton::DPadUp; + case SDL_CONTROLLER_BUTTON_DPAD_DOWN: return ControllerButton::DPadDown; + case SDL_CONTROLLER_BUTTON_DPAD_LEFT: return ControllerButton::DPadLeft; + case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: return ControllerButton::DPadRight; + case SDL_CONTROLLER_BUTTON_MISC1: return ControllerButton::Misc1; + case SDL_CONTROLLER_BUTTON_PADDLE1: return ControllerButton::Paddle1; + case SDL_CONTROLLER_BUTTON_PADDLE2: return ControllerButton::Paddle2; + case SDL_CONTROLLER_BUTTON_PADDLE3: return ControllerButton::Paddle3; + case SDL_CONTROLLER_BUTTON_PADDLE4: return ControllerButton::Paddle4; + case SDL_CONTROLLER_BUTTON_TOUCHPAD: return ControllerButton::Touchpad; + default: return ControllerButton::Invalid; + } } class SdlPlatform { @@ -233,9 +244,9 @@ public: if (SDL_InitSubSystem(SDL_INIT_VIDEO)) throw ApplicationException(strf("Couldn't initialize SDL Video: {}", SDL_GetError())); - Logger::info("Application: Initializing SDL Joystick"); - if (SDL_InitSubSystem(SDL_INIT_JOYSTICK)) - throw ApplicationException(strf("Couldn't initialize SDL Joystick: {}", SDL_GetError())); + Logger::info("Application: Initializing SDL Controller"); + if (SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER)) + throw ApplicationException(strf("Couldn't initialize SDL Controller: {}", SDL_GetError())); Logger::info("Application: Initializing SDL Sound"); if (SDL_InitSubSystem(SDL_INIT_AUDIO)) @@ -585,7 +596,8 @@ private: SDL_Event event; while (SDL_PollEvent(&event)) { Maybe<InputEvent> starEvent; - if (event.type == SDL_WINDOWEVENT) { + switch (event.type) { + case SDL_WINDOWEVENT: if (event.window.event == SDL_WINDOWEVENT_MAXIMIZED || event.window.event == SDL_WINDOWEVENT_RESTORED) { auto windowFlags = SDL_GetWindowFlags(m_sdlWindow); @@ -605,40 +617,71 @@ private: m_renderer->setScreenSize(m_windowSize); m_application->windowChanged(m_windowMode, m_windowSize); } - - } else if (event.type == SDL_KEYDOWN) { + break; + case SDL_KEYDOWN: if (!event.key.repeat) { if (auto key = keyFromSdlKeyCode(event.key.keysym.sym)) starEvent.set(KeyDownEvent{*key, keyModsFromSdlKeyMods(event.key.keysym.mod)}); } - - } else if (event.type == SDL_KEYUP) { + break; + case SDL_KEYUP: if (auto key = keyFromSdlKeyCode(event.key.keysym.sym)) starEvent.set(KeyUpEvent{*key}); - - } else if (event.type == SDL_TEXTINPUT) { + break; + case SDL_TEXTINPUT: starEvent.set(TextInputEvent{String(event.text.text)}); - - } else if (event.type == SDL_MOUSEMOTION) { + break; + case SDL_MOUSEMOTION: starEvent.set(MouseMoveEvent{ {event.motion.xrel, -event.motion.yrel}, {event.motion.x, (int)m_windowSize[1] - event.motion.y}}); - - } else if (event.type == SDL_MOUSEBUTTONDOWN) { + break; + case SDL_MOUSEBUTTONDOWN: starEvent.set(MouseButtonDownEvent{mouseButtonFromSdlMouseButton(event.button.button), {event.button.x, (int)m_windowSize[1] - event.button.y}}); - - } else if (event.type == SDL_MOUSEBUTTONUP) { + break; + case SDL_MOUSEBUTTONUP: starEvent.set(MouseButtonUpEvent{mouseButtonFromSdlMouseButton(event.button.button), {event.button.x, (int)m_windowSize[1] - event.button.y}}); - - } else if (event.type == SDL_MOUSEWHEEL) { + break; + case SDL_MOUSEWHEEL: int x, y; SDL_GetMouseState(&x, &y); starEvent.set(MouseWheelEvent{event.wheel.y < 0 ? MouseWheel::Down : MouseWheel::Up, {x, (int)m_windowSize[1] - y}}); - - } else if (event.type == SDL_QUIT) { + break; + case SDL_CONTROLLERAXISMOTION: + starEvent.set(ControllerAxisEvent{ + (ControllerId)event.caxis.which, + controllerAxisFromSdlControllerAxis(event.caxis.axis), + (float)event.caxis.value / 32768.0f + }); + break; + case SDL_CONTROLLERBUTTONDOWN: + starEvent.set(ControllerButtonDownEvent{ (ControllerId)event.cbutton.which, controllerButtonFromSdlControllerButton(event.cbutton.button) }); + break; + case SDL_CONTROLLERBUTTONUP: + starEvent.set(ControllerButtonUpEvent{ (ControllerId)event.cbutton.which, controllerButtonFromSdlControllerButton(event.cbutton.button) }); + break; + case SDL_CONTROLLERDEVICEADDED: + { + auto insertion = m_SdlControllers.insert_or_assign(event.cdevice.which, SDLGameControllerUPtr(SDL_GameControllerOpen(event.cdevice.which), SDL_GameControllerClose)); + if (SDL_GameController* controller = insertion.first->second.get()) + Logger::info("Controller device '{}' added", SDL_GameControllerName(controller)); + } + break; + case SDL_CONTROLLERDEVICEREMOVED: + { + auto find = m_SdlControllers.find(event.cdevice.which); + if (find != m_SdlControllers.end()) { + if (SDL_GameController* controller = find->second.get()) + Logger::info("Controller device '{}' removed", SDL_GameControllerName(controller)); + m_SdlControllers.erase(event.cdevice.which); + } + } + break; + case SDL_QUIT: m_quitRequested = true; starEvent.reset(); + break; } if (starEvent) @@ -744,6 +787,9 @@ private: SDL_GLContext m_sdlGlContext = nullptr; SDL_AudioDeviceID m_sdlAudioDevice = 0; + typedef std::unique_ptr<SDL_GameController, decltype(&SDL_GameControllerClose)> SDLGameControllerUPtr; + StableHashMap<int, SDLGameControllerUPtr> m_SdlControllers; + typedef std::unique_ptr<SDL_Surface, decltype(&SDL_FreeSurface)> SDLSurfaceUPtr; typedef std::unique_ptr<SDL_Cursor, decltype(&SDL_FreeCursor)> SDLCursorUPtr; struct CursorEntry { |