From 89595e0d8f34b76f106d76bc634f36391aec4785 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 23 Mar 2020 07:58:24 -0700 Subject: [PATCH 1/2] UI: Translate HAT and left analog the same way. Before, we were resetting our HAT state for each axis we got, so we'd act like you pressed the arrow more times for each axis your device has. A similar thing was possible if you had multiple pads. --- ext/native/ui/root.cpp | 62 +++++++++++++++++++++---------------- ext/native/ui/ui_screen.cpp | 32 ++----------------- ext/native/ui/ui_screen.h | 10 +++--- 3 files changed, 42 insertions(+), 62 deletions(-) diff --git a/ext/native/ui/root.cpp b/ext/native/ui/root.cpp index 86b121f9c6..d093f3d514 100644 --- a/ext/native/ui/root.cpp +++ b/ext/native/ui/root.cpp @@ -247,29 +247,41 @@ bool TouchEvent(const TouchInput &touch, ViewGroup *root) { } bool AxisEvent(const AxisInput &axis, ViewGroup *root) { - enum { - DIR_POS = 1, - DIR_NEG = 2, + enum class DirState { + NONE = 0, + POS = 1, + NEG = 2, }; + struct PrevState { + DirState x = DirState::NONE; + DirState y = DirState::NONE; + }; + struct StateKey { + int deviceId; + int axisId; - static uint32_t x_state = 0; - static uint32_t y_state = 0; + bool operator <(const StateKey &other) const { + return std::tie(deviceId, axisId) < std::tie(other.deviceId, other.axisId); + } + }; + static std::map state; + StateKey stateKey{ axis.deviceId, axis.axisId }; const float THRESHOLD = 0.75; // Cannot use the remapper since this is for the menu, so we provide our own // axis->button emulation here. - auto GenerateKeyFromAxis = [&](uint32_t old, uint32_t cur, keycode_t neg_key, keycode_t pos_key) { + auto GenerateKeyFromAxis = [&](DirState old, DirState cur, keycode_t neg_key, keycode_t pos_key) { if (old == cur) return; - if (old == DIR_POS) { + if (old == DirState::POS) { KeyEvent(KeyInput{ DEVICE_ID_KEYBOARD, pos_key, KEY_UP }, root); - } else if (old == DIR_NEG) { + } else if (old == DirState::NEG) { KeyEvent(KeyInput{ DEVICE_ID_KEYBOARD, neg_key, KEY_UP }, root); } - if (cur == DIR_POS) { + if (cur == DirState::POS) { KeyEvent(KeyInput{ DEVICE_ID_KEYBOARD, pos_key, KEY_DOWN }, root); - } else if (cur == DIR_NEG) { + } else if (cur == DirState::NEG) { KeyEvent(KeyInput{ DEVICE_ID_KEYBOARD, neg_key, KEY_DOWN }, root); } }; @@ -284,29 +296,27 @@ bool AxisEvent(const AxisInput &axis, ViewGroup *root) { case DEVICE_ID_X360_2: case DEVICE_ID_X360_3: { - uint32_t dir = 0; - if (axis.axisId == JOYSTICK_AXIS_X) { - if (axis.value < -THRESHOLD) - dir = DIR_NEG; - else if (axis.value > THRESHOLD) - dir = DIR_POS; - GenerateKeyFromAxis(x_state, dir, NKCODE_DPAD_LEFT, NKCODE_DPAD_RIGHT); - x_state = dir; + PrevState &old = state[stateKey]; + DirState dir = DirState::NONE; + if (axis.value < -THRESHOLD) + dir = DirState::NEG; + else if (axis.value > THRESHOLD) + dir = DirState::POS; + + if (axis.axisId == JOYSTICK_AXIS_X || axis.axisId == JOYSTICK_AXIS_HAT_X) { + GenerateKeyFromAxis(old.x, dir, NKCODE_DPAD_LEFT, NKCODE_DPAD_RIGHT); + old.x = dir; } - if (axis.axisId == JOYSTICK_AXIS_Y) { - if (axis.value < -THRESHOLD) - dir = DIR_NEG; - else if (axis.value > THRESHOLD) - dir = DIR_POS; + if (axis.axisId == JOYSTICK_AXIS_Y || axis.axisId == JOYSTICK_AXIS_HAT_Y) { // We stupidly interpret the joystick Y axis backwards on Android instead of reversing // it early (see keymaps...). Too late to fix without invalidating a lot of config files, so we // reverse it here too. #if PPSSPP_PLATFORM(ANDROID) - GenerateKeyFromAxis(y_state, dir, NKCODE_DPAD_UP, NKCODE_DPAD_DOWN); + GenerateKeyFromAxis(old.y, dir, NKCODE_DPAD_UP, NKCODE_DPAD_DOWN); #else - GenerateKeyFromAxis(y_state, dir, NKCODE_DPAD_DOWN, NKCODE_DPAD_UP); + GenerateKeyFromAxis(old.y, dir, NKCODE_DPAD_DOWN, NKCODE_DPAD_UP); #endif - y_state = dir; + old.y = dir; } break; } diff --git a/ext/native/ui/ui_screen.cpp b/ext/native/ui/ui_screen.cpp index c69ec761a2..b0490bc762 100644 --- a/ext/native/ui/ui_screen.cpp +++ b/ext/native/ui/ui_screen.cpp @@ -14,7 +14,7 @@ static const bool ClickDebug = false; UIScreen::UIScreen() - : Screen(), root_(nullptr), translation_(0.0f), scale_(1.0f), recreateViews_(true), hatDown_(0) { + : Screen() { } UIScreen::~UIScreen() { @@ -182,39 +182,11 @@ void UIDialogScreen::sendMessage(const char *msg, const char *value) { } bool UIScreen::axis(const AxisInput &axis) { - // Simple translation of hat to keys for Shield and other modern pads. - // TODO: Use some variant of keymap? - int flags = 0; - if (axis.axisId == JOYSTICK_AXIS_HAT_X) { - if (axis.value < -0.7f) - flags |= PAD_BUTTON_LEFT; - if (axis.value > 0.7f) - flags |= PAD_BUTTON_RIGHT; - } - if (axis.axisId == JOYSTICK_AXIS_HAT_Y) { - if (axis.value < -0.7f) - flags |= PAD_BUTTON_UP; - if (axis.value > 0.7f) - flags |= PAD_BUTTON_DOWN; - } - - // Yeah yeah, this should be table driven.. - int pressed = flags & ~hatDown_; - int released = ~flags & hatDown_; - if (pressed & PAD_BUTTON_LEFT) key(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_DPAD_LEFT, KEY_DOWN)); - if (pressed & PAD_BUTTON_RIGHT) key(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_DPAD_RIGHT, KEY_DOWN)); - if (pressed & PAD_BUTTON_UP) key(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_DPAD_UP, KEY_DOWN)); - if (pressed & PAD_BUTTON_DOWN) key(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_DPAD_DOWN, KEY_DOWN)); - if (released & PAD_BUTTON_LEFT) key(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_DPAD_LEFT, KEY_UP)); - if (released & PAD_BUTTON_RIGHT) key(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_DPAD_RIGHT, KEY_UP)); - if (released & PAD_BUTTON_UP) key(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_DPAD_UP, KEY_UP)); - if (released & PAD_BUTTON_DOWN) key(KeyInput(DEVICE_ID_KEYBOARD, NKCODE_DPAD_DOWN, KEY_UP)); - hatDown_ = flags; if (root_) { UI::AxisEvent(axis, root_); return true; } - return (pressed & (PAD_BUTTON_LEFT | PAD_BUTTON_RIGHT | PAD_BUTTON_UP | PAD_BUTTON_DOWN)) != 0; + return false; } UI::EventReturn UIScreen::OnBack(UI::EventParams &e) { diff --git a/ext/native/ui/ui_screen.h b/ext/native/ui/ui_screen.h index 796bd78285..1f1c5b4317 100644 --- a/ext/native/ui/ui_screen.h +++ b/ext/native/ui/ui_screen.h @@ -44,17 +44,15 @@ protected: virtual void RecreateViews() override { recreateViews_ = true; } - UI::ViewGroup *root_; - Vec3 translation_; - Vec3 scale_; + UI::ViewGroup *root_ = nullptr; + Vec3 translation_ = Vec3(0.0f); + Vec3 scale_ = Vec3(1.0f); float alpha_ = 1.0f; private: void DoRecreateViews(); - bool recreateViews_; - - int hatDown_; + bool recreateViews_ = true; }; class UIDialogScreen : public UIScreen { From 3bc59b0ef776c61c17500d4ea0c127205296b34f Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 23 Mar 2020 08:14:36 -0700 Subject: [PATCH 2/2] Windows: Fix strange build error. --- ext/native/ui/root.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ext/native/ui/root.cpp b/ext/native/ui/root.cpp index d093f3d514..464283a909 100644 --- a/ext/native/ui/root.cpp +++ b/ext/native/ui/root.cpp @@ -253,8 +253,11 @@ bool AxisEvent(const AxisInput &axis, ViewGroup *root) { NEG = 2, }; struct PrevState { - DirState x = DirState::NONE; - DirState y = DirState::NONE; + PrevState() : x(DirState::NONE), y(DirState::NONE) { + } + + DirState x; + DirState y; }; struct StateKey { int deviceId;