Add stick and trigger input support
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
#include <pd/drivers/hid.hpp>
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
@@ -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
|
||||
@@ -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<u32, u32> pGamepad;
|
||||
std::unordered_map<u128, u128> pKeyboard;
|
||||
std::unordered_map<Event, u32> 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(); }
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user