diff --git a/backends/source/hid_glfw.cpp b/backends/source/hid_glfw.cpp index 05292c4..286ae21 100644 --- a/backends/source/hid_glfw.cpp +++ b/backends/source/hid_glfw.cpp @@ -8,6 +8,7 @@ struct HidGlfw::Impl { GLFWwindow* Win; int PrevState; std::unordered_map PrevStates; + std::unordered_map GPPrevStates; GLFWcharfun OldTextCB; std::string* Text; bool InTextMode = false; @@ -16,15 +17,51 @@ struct HidGlfw::Impl { HidGlfw::HidGlfw(GLFWwindow* win) : HidDriver("HidGlfw") { impl = new Impl; impl->Win = win; + pFlags |= PDHidBackendFlags_HasMouse; pFlags |= PDHidBackendFlags_HasKeyboard; - pGamepad[GLFW_MOUSE_BUTTON_LEFT] = HidInternal::Touch; + if (glfwJoystickPresent(GLFW_JOYSTICK_1)) { + pFlags |= PDHidBackendFlags_HasGamepad; + } + pGamepad[GLFW_GAMEPAD_BUTTON_A] = HidInternal::Gamepad::A; + pGamepad[GLFW_GAMEPAD_BUTTON_B] = HidInternal::Gamepad::B; + pGamepad[GLFW_GAMEPAD_BUTTON_X] = HidInternal::Gamepad::X; + pGamepad[GLFW_GAMEPAD_BUTTON_Y] = HidInternal::Gamepad::Y; + pGamepad[GLFW_GAMEPAD_BUTTON_START] = HidInternal::Gamepad::Start; + pGamepad[GLFW_GAMEPAD_BUTTON_BACK] = HidInternal::Gamepad::Select; + pGamepad[GLFW_GAMEPAD_BUTTON_DPAD_LEFT] = HidInternal::Gamepad::DLeft; + pGamepad[GLFW_GAMEPAD_BUTTON_DPAD_RIGHT] = HidInternal::Gamepad::DRight; + pGamepad[GLFW_GAMEPAD_BUTTON_DPAD_UP] = HidInternal::Gamepad::DUp; + pGamepad[GLFW_GAMEPAD_BUTTON_DPAD_DOWN] = HidInternal::Gamepad::DDown; + pGamepad[GLFW_GAMEPAD_BUTTON_LEFT_BUMPER] = HidInternal::Gamepad::L; + pGamepad[GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER] = HidInternal::Gamepad::R; + pGamepad[GLFW_GAMEPAD_BUTTON_LEFT_THUMB] = HidInternal::Gamepad::LStick; + pGamepad[GLFW_GAMEPAD_BUTTON_RIGHT_THUMB] = HidInternal::Gamepad::RStick; + for (int i = 0; i <= GLFW_GAMEPAD_BUTTON_LAST; i++) { + impl->GPPrevStates[i] = 0; + } } HidGlfw::~HidGlfw() {} void HidGlfw::Update() { HidDriver::Update(); // clear stats + GLFWgamepadstate gpstate; + int gps = glfwGetGamepadState(GLFW_JOYSTICK_1, &gpstate); + if (gps == GLFW_TRUE) { + for (int i = 0; i <= GLFW_GAMEPAD_BUTTON_LAST; i++) { + if (gpstate.buttons[i] == GLFW_PRESS) { + if (impl->PrevStates[i] == GLFW_RELEASE) { + pGamepadEvents[0][Event::Down] |= pGamepad[i]; + } + pGamepadEvents[0][Event::Held] |= pGamepad[i]; + } else if (gpstate.buttons[i] == GLFW_RELEASE && + impl->GPPrevStates[i] == GLFW_PRESS) { + pGamepadEvents[0][Event::Up] |= pGamepad[i]; + } + impl->GPPrevStates[i] = gpstate.buttons[i]; + } + } int state = glfwGetMouseButton(impl->Win, GLFW_MOUSE_BUTTON_LEFT); if (state == GLFW_PRESS) { if (impl->PrevState == GLFW_RELEASE) { diff --git a/include/pd/drivers/hid.hpp b/include/pd/drivers/hid.hpp index 20c20eb..3bd451e 100644 --- a/include/pd/drivers/hid.hpp +++ b/include/pd/drivers/hid.hpp @@ -98,6 +98,8 @@ enum Gamepad : GamepadKey { ZL = 1 << 20, ///< ZL ZR = 1 << 21, ///< ZR Touch = 1 << 22, ///< Touch + LStick = 1 << 23, ///< Left Stick + RStick = 1 << 24, ///< Right Stick Up = DUp | CPUp, ///< DPad or CPad Up Down = DDown | CPDown, ///< DPad or CPad Down Left = DLeft | CPLeft, ///< DPad or CPad Left diff --git a/tests/gfx/source/main.cpp b/tests/gfx/source/main.cpp index 6fca03b..5164fd9 100644 --- a/tests/gfx/source/main.cpp +++ b/tests/gfx/source/main.cpp @@ -25,6 +25,65 @@ const char* ResourcePath(const char* in) { #endif } +std::string Key2String(PD::Hid::Gamepad gp) { + std::string res; + if (gp & PD::Hid::Gamepad::A) { + res += "A"; + } + if (gp & PD::Hid::Gamepad::B) { + res += "B"; + } + if (gp & PD::Hid::Gamepad::X) { + res += "X"; + } + if (gp & PD::Hid::Gamepad::Y) { + res += "Y"; + } + if (gp & PD::Hid::Gamepad::Start) { + res += "Start"; + } + if (gp & PD::Hid::Gamepad::Select) { + res += "Select"; + } + if (gp & PD::Hid::Gamepad::DDown) { + res += "DDown"; + } + if (gp & PD::Hid::Gamepad::DUp) { + res += "DUp"; + } + if (gp & PD::Hid::Gamepad::DLeft) { + res += "DLeft"; + } + if (gp & PD::Hid::Gamepad::DRight) { + res += "DRight"; + } + if (gp & PD::Hid::Gamepad::L) { + res += "L"; + } + if (gp & PD::Hid::Gamepad::R) { + res += "R"; + } + if (gp & PD::Hid::Gamepad::ZL) { + res += "ZL"; + } + if (gp & PD::Hid::Gamepad::ZR) { + res += "ZR"; + } + return res; +} + +std::string ComboGpOut(PD::Hid::Gamepad gp) { + std::string res = Key2String(gp); + if (PD::Hid::IsEvent(PD::Hid::Event::Down, gp)) { + res += ": 1"; + } else if (PD::Hid::IsEvent(PD::Hid::Event::Held, gp)) { + res += ": 2"; + } else if (PD::Hid::IsEvent(PD::Hid::Event::Up, gp)) { + res += ": 3"; + } + return res; +} + class MainMenu : public PD::Ultra::Layout { public: MainMenu(PD::Li::Font& font) { @@ -32,8 +91,7 @@ class MainMenu : public PD::Ultra::Layout { SetBaseViewport(PD::ivec2(1280, 720)); pBackground.SetSize(800, 450); pBackground.SetColor("#ffffffff"); - pBackground.SetAlignment(UltraAlignment_CenterHorizontal | - UltraAlignment_CenterVertical); + pBackground.SetAlignment(UltraAlignment_Center); Push(pBackground); pText.SetColor("#ffffff"); pText.SetText("MousePos: "); @@ -108,6 +166,27 @@ int main(int argc, char** argv) { pOs->ClearViewPort(); PD::Li::ResetPools(); // Move to other place (or refactor this) app.Update(pOs->GetViewport(), pList); + pList.DrawText( + PD::fvec2(5, 37), + std::format( + "Input:\n Driver: {}\n Gamepad: {}\n {}\n {}\n " + "{}\n {}\n {}\n {}\n {}\n {}\n {}\n {}\n " + "{}\n {}\n " + "{}\n {}\n", + PD::Hid::GetDriverName(), + bool(PD::Hid::GetFlags() & PDHidBackendFlags_HasGamepad), + ComboGpOut(PD::Hid::Gamepad::Start), + ComboGpOut(PD::Hid::Gamepad::Select), + ComboGpOut(PD::Hid::Gamepad::A), ComboGpOut(PD::Hid::Gamepad::B), + ComboGpOut(PD::Hid::Gamepad::X), ComboGpOut(PD::Hid::Gamepad::Y), + ComboGpOut(PD::Hid::Gamepad::DDown), + ComboGpOut(PD::Hid::Gamepad::DUp), + ComboGpOut(PD::Hid::Gamepad::DLeft), + ComboGpOut(PD::Hid::Gamepad::DRight), + ComboGpOut(PD::Hid::Gamepad::L), ComboGpOut(PD::Hid::Gamepad::R), + ComboGpOut(PD::Hid::Gamepad::ZL), ComboGpOut(PD::Hid::Gamepad::ZR)) + .c_str(), + "#ffffff"); PD::Gfx::Reset(); PD::Gfx::Draw(pList); pList.Clear();