diff --git a/backends/include/pd_system/hid_glfw.hpp b/backends/include/pd_system/hid_glfw.hpp index d6f394c..d79dddc 100644 --- a/backends/include/pd_system/hid_glfw.hpp +++ b/backends/include/pd_system/hid_glfw.hpp @@ -3,6 +3,7 @@ #include typedef struct GLFWwindow GLFWwindow; +typedef struct GLFWgamepadstate GLFWgamepadstate; namespace PD { class HidGlfw : public HidDriver { @@ -13,6 +14,7 @@ class HidGlfw : public HidDriver { void Update() override; private: + void HandleAxisKey(GLFWgamepadstate s, int iK, int eA, bool negative); struct Impl; Impl* impl; }; diff --git a/backends/source/hid_glfw.cpp b/backends/source/hid_glfw.cpp index b72f001..23cf985 100644 --- a/backends/source/hid_glfw.cpp +++ b/backends/source/hid_glfw.cpp @@ -14,6 +14,19 @@ struct HidGlfw::Impl { bool InTextMode = false; }; +constexpr int KEY_BASE = GLFW_GAMEPAD_BUTTON_LAST; +constexpr int KEY_LSTICK_LEFT = KEY_BASE + 1; +constexpr int KEY_LSTICK_RIGHT = KEY_BASE + 2; +constexpr int KEY_LSTICK_UP = KEY_BASE + 3; +constexpr int KEY_LSTICK_DOWN = KEY_BASE + 4; +constexpr int KEY_RSTICK_LEFT = KEY_BASE + 5; +constexpr int KEY_RSTICK_RIGHT = KEY_BASE + 6; +constexpr int KEY_RSTICK_UP = KEY_BASE + 7; +constexpr int KEY_RSTICK_DOWN = KEY_BASE + 8; +constexpr int KEY_LEFT_TRIGGER = KEY_BASE + 9; +constexpr int KEY_RIGHT_TRIGGER = KEY_BASE + 10; +constexpr int KEY_LAST = KEY_RIGHT_TRIGGER; + HidGlfw::HidGlfw(GLFWwindow* win) : HidDriver("HidGlfw") { impl = new Impl; impl->Win = win; @@ -37,7 +50,17 @@ HidGlfw::HidGlfw(GLFWwindow* win) : HidDriver("HidGlfw") { 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++) { + pGamepad[KEY_LEFT_TRIGGER] = HidInternal::Gamepad::ZL; + pGamepad[KEY_RIGHT_TRIGGER] = HidInternal::Gamepad::ZR; + pGamepad[KEY_LSTICK_LEFT] = HidInternal::Gamepad::CPLeft; + pGamepad[KEY_LSTICK_RIGHT] = HidInternal::Gamepad::CPRight; + pGamepad[KEY_LSTICK_UP] = HidInternal::Gamepad::CPUp; + pGamepad[KEY_LSTICK_DOWN] = HidInternal::Gamepad::CPDown; + pGamepad[KEY_RSTICK_LEFT] = HidInternal::Gamepad::CSLeft; + pGamepad[KEY_RSTICK_RIGHT] = HidInternal::Gamepad::CSRight; + pGamepad[KEY_RSTICK_UP] = HidInternal::Gamepad::CSUp; + pGamepad[KEY_RSTICK_DOWN] = HidInternal::Gamepad::CSDown; + for (int i = 0; i <= KEY_LAST; i++) { impl->GPPrevStates[i] = 0; } } @@ -49,9 +72,25 @@ void HidGlfw::Update() { GLFWgamepadstate gpstate; int gps = glfwGetGamepadState(GLFW_JOYSTICK_1, &gpstate); if (gps == GLFW_TRUE) { + HandleAxisKey(gpstate, KEY_LEFT_TRIGGER, GLFW_GAMEPAD_AXIS_LEFT_TRIGGER, + false); + HandleAxisKey(gpstate, KEY_RIGHT_TRIGGER, GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER, + false); + HandleAxisKey(gpstate, KEY_LSTICK_LEFT, GLFW_GAMEPAD_AXIS_LEFT_X, true); + HandleAxisKey(gpstate, KEY_LSTICK_RIGHT, GLFW_GAMEPAD_AXIS_LEFT_X, false); + HandleAxisKey(gpstate, KEY_LSTICK_UP, GLFW_GAMEPAD_AXIS_LEFT_Y, true); + HandleAxisKey(gpstate, KEY_LSTICK_DOWN, GLFW_GAMEPAD_AXIS_LEFT_Y, false); + HandleAxisKey(gpstate, KEY_RSTICK_LEFT, GLFW_GAMEPAD_AXIS_RIGHT_X, true); + HandleAxisKey(gpstate, KEY_RSTICK_RIGHT, GLFW_GAMEPAD_AXIS_RIGHT_X, false); + HandleAxisKey(gpstate, KEY_RSTICK_UP, GLFW_GAMEPAD_AXIS_RIGHT_Y, true); + HandleAxisKey(gpstate, KEY_RSTICK_DOWN, GLFW_GAMEPAD_AXIS_RIGHT_Y, false); + pLStick[0].x = gpstate.axes[GLFW_GAMEPAD_AXIS_LEFT_X]; + pLStick[0].y = gpstate.axes[GLFW_GAMEPAD_AXIS_LEFT_Y]; + pRStick[0].x = gpstate.axes[GLFW_GAMEPAD_AXIS_RIGHT_X]; + pRStick[0].y = gpstate.axes[GLFW_GAMEPAD_AXIS_RIGHT_Y]; for (int i = 0; i <= GLFW_GAMEPAD_BUTTON_LAST; i++) { if (gpstate.buttons[i] == GLFW_PRESS) { - if (impl->PrevStates[i] == GLFW_RELEASE) { + if (impl->GPPrevStates[i] == GLFW_RELEASE) { pGamepadEvents[0][Event::Down] |= pGamepad[i]; } pGamepadEvents[0][Event::Held] |= pGamepad[i]; @@ -80,6 +119,25 @@ void HidGlfw::Update() { glfwGetCursorPos(impl->Win, &x, &y); pMouse[0] = fvec2(x, y); } + +void HidGlfw::HandleAxisKey(GLFWgamepadstate s, int iK, int eA, bool negative) { + if (s.axes[eA] <= 1.f && s.axes[eA] >= -1.f) { + if (s.axes[eA] > 0.05f && !negative) { + if (impl->GPPrevStates[iK] == GLFW_RELEASE) { + pGamepadEvents[0][Event::Down] |= pGamepad[iK]; + } + pGamepadEvents[0][Event::Held] |= pGamepad[iK]; + } + if (s.axes[eA] < -0.05f && negative) { + if (impl->GPPrevStates[iK] == GLFW_RELEASE) { + pGamepadEvents[0][Event::Down] |= pGamepad[iK]; + } + pGamepadEvents[0][Event::Held] |= pGamepad[iK]; + } + } + impl->GPPrevStates[iK] = (s.axes[eA] <= -0.05 && s.axes[eA] >= 0.05 && + s.axes[eA] >= -1.f && s.axes[eA] <= 1); +} } // namespace PD #else namespace PD { @@ -91,5 +149,6 @@ HidGlfw::~HidGlfw() {} void HidGlfw::Update() { HidDriver::Update(); // clear stats } +void HidGlfw::HandleAxisKey(GLFWgamepadstate s, int iK, int eA) {} } // namespace PD #endif \ No newline at end of file diff --git a/include/pd/drivers/hid.hpp b/include/pd/drivers/hid.hpp index 3bd451e..15b1751 100644 --- a/include/pd/drivers/hid.hpp +++ b/include/pd/drivers/hid.hpp @@ -127,6 +127,8 @@ class PD_API HidDriver : public DriverInterface { virtual void Update(); virtual bool IsEvent(Event e, HidInternal::GamepadKey keys); virtual bool IsEvent(Event e, HidInternal::Keyboard::Key keys); + virtual const fvec2& GetLeftStick() const { return pLStick[0]; } + virtual const fvec2& GetRightStick() const { return pRStick[0]; } PDHidBackendFlags GetFlags() const { return pFlags; } @@ -134,6 +136,8 @@ class PD_API HidDriver : public DriverInterface { void SwapTab(); PDHidBackendFlags pFlags = PDHidBackendFlags_None; fvec2 pMouse[2]; // Current And last pos + fvec2 pLStick[2]; + fvec2 pRStick[2]; std::unordered_map pGamepad; std::unordered_map pKeyboard; std::unordered_map pGamepadEvents[2]; @@ -168,6 +172,8 @@ class PD_API Hid { return driver->IsEvent(e, keys); } static PDHidBackendFlags GetFlags() { return driver->GetFlags(); } + static const fvec2& GetLeftStick() { return driver->GetLeftStick(); } + static const fvec2& GetRightStick() { return driver->GetRightStick(); } static const char* GetDriverName() { return driver->GetName(); } diff --git a/tests/gfx/source/main.cpp b/tests/gfx/source/main.cpp index 5164fd9..d98df53 100644 --- a/tests/gfx/source/main.cpp +++ b/tests/gfx/source/main.cpp @@ -57,6 +57,30 @@ std::string Key2String(PD::Hid::Gamepad gp) { if (gp & PD::Hid::Gamepad::DRight) { res += "DRight"; } + if (gp & PD::Hid::Gamepad::CPDown) { + res += "CPDown"; + } + if (gp & PD::Hid::Gamepad::CPUp) { + res += "CPUp"; + } + if (gp & PD::Hid::Gamepad::CPLeft) { + res += "CPLeft"; + } + if (gp & PD::Hid::Gamepad::CPRight) { + res += "CPRight"; + } + if (gp & PD::Hid::Gamepad::CSDown) { + res += "CSDown"; + } + if (gp & PD::Hid::Gamepad::CSUp) { + res += "CSUp"; + } + if (gp & PD::Hid::Gamepad::CSLeft) { + res += "CSLeft"; + } + if (gp & PD::Hid::Gamepad::CSRight) { + res += "CSRight"; + } if (gp & PD::Hid::Gamepad::L) { res += "L"; } @@ -133,6 +157,15 @@ class App { MainMenu main; }; +struct Cursor { + PD::fvec2 pPos = 0; + std::string name; + PD::Color pColor = 0xffff00ff; + void Render(PD::Li::Drawlist& l) { + l.DrawCircleFilled(pPos, 32.f, pColor, 15); + } +}; + int main(int argc, char** argv) { // PD::LogFilter(PD::LogLevel::Warning); Driver drv = Driver::OpenGL3; @@ -161,18 +194,39 @@ int main(int argc, char** argv) { font.LoadTTF(ResourcePath("default.ttf"), 64); pList.SetFont(&font); App app(font); + Cursor LeftStick; + Cursor RightStick; + RightStick.pColor = "#00ffff"; while (pOs->Mainloop()) { PD::Hid::Update(); pOs->ClearViewPort(); PD::Li::ResetPools(); // Move to other place (or refactor this) app.Update(pOs->GetViewport(), pList); + pList.SetFontscale(0.7); + if (PD::Hid::IsEvent(PD::Hid::Event::Down, PD::Hid::Gamepad::CPLeft | + PD::Hid::Gamepad::CPRight)) { + LeftStick.pPos.x += PD::Hid::GetLeftStick().x * 15; + } + if (PD::Hid::IsEvent(PD::Hid::Event::Down, + PD::Hid::Gamepad::CPUp | PD::Hid::Gamepad::CPDown)) { + LeftStick.pPos.y += PD::Hid::GetLeftStick().y * 15; + } + if (PD::Hid::IsEvent(PD::Hid::Event::Down, PD::Hid::Gamepad::CSLeft | + PD::Hid::Gamepad::CSRight)) { + RightStick.pPos.x += PD::Hid::GetRightStick().x * 15; + } + if (PD::Hid::IsEvent(PD::Hid::Event::Down, + PD::Hid::Gamepad::CSUp | PD::Hid::Gamepad::CSDown)) { + RightStick.pPos.y += PD::Hid::GetRightStick().y * 15; + } 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 {}\n {}\n {}\n {}\n " "{}\n {}\n " - "{}\n {}\n", + "{}\n {}\n LS: [{}]\n RS: [{}]\nLSP: {}", PD::Hid::GetDriverName(), bool(PD::Hid::GetFlags() & PDHidBackendFlags_HasGamepad), ComboGpOut(PD::Hid::Gamepad::Start), @@ -184,9 +238,20 @@ int main(int argc, char** argv) { 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)) + ComboGpOut(PD::Hid::Gamepad::ZL), ComboGpOut(PD::Hid::Gamepad::ZR), + ComboGpOut(PD::Hid::Gamepad::CPLeft), + ComboGpOut(PD::Hid::Gamepad::CPRight), + ComboGpOut(PD::Hid::Gamepad::CPUp), + ComboGpOut(PD::Hid::Gamepad::CPDown), + ComboGpOut(PD::Hid::Gamepad::CSLeft), + ComboGpOut(PD::Hid::Gamepad::CSRight), + ComboGpOut(PD::Hid::Gamepad::CSUp), + ComboGpOut(PD::Hid::Gamepad::CSDown), PD::Hid::GetLeftStick(), + PD::Hid::GetRightStick(), LeftStick.pPos) .c_str(), "#ffffff"); + LeftStick.Render(pList); + RightStick.Render(pList); PD::Gfx::Reset(); PD::Gfx::Draw(pList); pList.Clear();