Add stick and trigger input support

This commit is contained in:
2026-04-09 21:51:38 +02:00
parent ff3b241dd2
commit 6dbf5a4812
4 changed files with 136 additions and 4 deletions
+2
View File
@@ -3,6 +3,7 @@
#include <pd/drivers/hid.hpp> #include <pd/drivers/hid.hpp>
typedef struct GLFWwindow GLFWwindow; typedef struct GLFWwindow GLFWwindow;
typedef struct GLFWgamepadstate GLFWgamepadstate;
namespace PD { namespace PD {
class HidGlfw : public HidDriver { class HidGlfw : public HidDriver {
@@ -13,6 +14,7 @@ class HidGlfw : public HidDriver {
void Update() override; void Update() override;
private: private:
void HandleAxisKey(GLFWgamepadstate s, int iK, int eA, bool negative);
struct Impl; struct Impl;
Impl* impl; Impl* impl;
}; };
+61 -2
View File
@@ -14,6 +14,19 @@ struct HidGlfw::Impl {
bool InTextMode = false; 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") { HidGlfw::HidGlfw(GLFWwindow* win) : HidDriver("HidGlfw") {
impl = new Impl; impl = new Impl;
impl->Win = win; 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_RIGHT_BUMPER] = HidInternal::Gamepad::R;
pGamepad[GLFW_GAMEPAD_BUTTON_LEFT_THUMB] = HidInternal::Gamepad::LStick; pGamepad[GLFW_GAMEPAD_BUTTON_LEFT_THUMB] = HidInternal::Gamepad::LStick;
pGamepad[GLFW_GAMEPAD_BUTTON_RIGHT_THUMB] = HidInternal::Gamepad::RStick; 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; impl->GPPrevStates[i] = 0;
} }
} }
@@ -49,9 +72,25 @@ void HidGlfw::Update() {
GLFWgamepadstate gpstate; GLFWgamepadstate gpstate;
int gps = glfwGetGamepadState(GLFW_JOYSTICK_1, &gpstate); int gps = glfwGetGamepadState(GLFW_JOYSTICK_1, &gpstate);
if (gps == GLFW_TRUE) { 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++) { for (int i = 0; i <= GLFW_GAMEPAD_BUTTON_LAST; i++) {
if (gpstate.buttons[i] == GLFW_PRESS) { 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::Down] |= pGamepad[i];
} }
pGamepadEvents[0][Event::Held] |= pGamepad[i]; pGamepadEvents[0][Event::Held] |= pGamepad[i];
@@ -80,6 +119,25 @@ void HidGlfw::Update() {
glfwGetCursorPos(impl->Win, &x, &y); glfwGetCursorPos(impl->Win, &x, &y);
pMouse[0] = fvec2(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 } // namespace PD
#else #else
namespace PD { namespace PD {
@@ -91,5 +149,6 @@ HidGlfw::~HidGlfw() {}
void HidGlfw::Update() { void HidGlfw::Update() {
HidDriver::Update(); // clear stats HidDriver::Update(); // clear stats
} }
void HidGlfw::HandleAxisKey(GLFWgamepadstate s, int iK, int eA) {}
} // namespace PD } // namespace PD
#endif #endif
+6
View File
@@ -127,6 +127,8 @@ class PD_API HidDriver : public DriverInterface {
virtual void Update(); virtual void Update();
virtual bool IsEvent(Event e, HidInternal::GamepadKey keys); virtual bool IsEvent(Event e, HidInternal::GamepadKey keys);
virtual bool IsEvent(Event e, HidInternal::Keyboard::Key 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; } PDHidBackendFlags GetFlags() const { return pFlags; }
@@ -134,6 +136,8 @@ class PD_API HidDriver : public DriverInterface {
void SwapTab(); void SwapTab();
PDHidBackendFlags pFlags = PDHidBackendFlags_None; PDHidBackendFlags pFlags = PDHidBackendFlags_None;
fvec2 pMouse[2]; // Current And last pos fvec2 pMouse[2]; // Current And last pos
fvec2 pLStick[2];
fvec2 pRStick[2];
std::unordered_map<u32, u32> pGamepad; std::unordered_map<u32, u32> pGamepad;
std::unordered_map<u128, u128> pKeyboard; std::unordered_map<u128, u128> pKeyboard;
std::unordered_map<Event, u32> pGamepadEvents[2]; std::unordered_map<Event, u32> pGamepadEvents[2];
@@ -168,6 +172,8 @@ class PD_API Hid {
return driver->IsEvent(e, keys); return driver->IsEvent(e, keys);
} }
static PDHidBackendFlags GetFlags() { return driver->GetFlags(); } 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(); } static const char* GetDriverName() { return driver->GetName(); }
+67 -2
View File
@@ -57,6 +57,30 @@ std::string Key2String(PD::Hid::Gamepad gp) {
if (gp & PD::Hid::Gamepad::DRight) { if (gp & PD::Hid::Gamepad::DRight) {
res += "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) { if (gp & PD::Hid::Gamepad::L) {
res += "L"; res += "L";
} }
@@ -133,6 +157,15 @@ class App {
MainMenu main; 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) { int main(int argc, char** argv) {
// PD::LogFilter(PD::LogLevel::Warning); // PD::LogFilter(PD::LogLevel::Warning);
Driver drv = Driver::OpenGL3; Driver drv = Driver::OpenGL3;
@@ -161,18 +194,39 @@ int main(int argc, char** argv) {
font.LoadTTF(ResourcePath("default.ttf"), 64); font.LoadTTF(ResourcePath("default.ttf"), 64);
pList.SetFont(&font); pList.SetFont(&font);
App app(font); App app(font);
Cursor LeftStick;
Cursor RightStick;
RightStick.pColor = "#00ffff";
while (pOs->Mainloop()) { while (pOs->Mainloop()) {
PD::Hid::Update(); PD::Hid::Update();
pOs->ClearViewPort(); pOs->ClearViewPort();
PD::Li::ResetPools(); // Move to other place (or refactor this) PD::Li::ResetPools(); // Move to other place (or refactor this)
app.Update(pOs->GetViewport(), pList); 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( pList.DrawText(
PD::fvec2(5, 37), PD::fvec2(5, 37),
std::format( std::format(
"Input:\n Driver: {}\n Gamepad: {}\n {}\n {}\n " "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 {}\n {}\n "
"{}\n {}\n " "{}\n {}\n "
"{}\n {}\n", "{}\n {}\n LS: [{}]\n RS: [{}]\nLSP: {}",
PD::Hid::GetDriverName(), PD::Hid::GetDriverName(),
bool(PD::Hid::GetFlags() & PDHidBackendFlags_HasGamepad), bool(PD::Hid::GetFlags() & PDHidBackendFlags_HasGamepad),
ComboGpOut(PD::Hid::Gamepad::Start), ComboGpOut(PD::Hid::Gamepad::Start),
@@ -184,9 +238,20 @@ int main(int argc, char** argv) {
ComboGpOut(PD::Hid::Gamepad::DLeft), ComboGpOut(PD::Hid::Gamepad::DLeft),
ComboGpOut(PD::Hid::Gamepad::DRight), ComboGpOut(PD::Hid::Gamepad::DRight),
ComboGpOut(PD::Hid::Gamepad::L), ComboGpOut(PD::Hid::Gamepad::R), 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(), .c_str(),
"#ffffff"); "#ffffff");
LeftStick.Render(pList);
RightStick.Render(pList);
PD::Gfx::Reset(); PD::Gfx::Reset();
PD::Gfx::Draw(pList); PD::Gfx::Draw(pList);
pList.Clear(); pList.Clear();