diff --git a/ext/native/ui/root.cpp b/ext/native/ui/root.cpp index 86b121f9c6..464283a909 100644 --- a/ext/native/ui/root.cpp +++ b/ext/native/ui/root.cpp @@ -247,29 +247,44 @@ 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 { + PrevState() : x(DirState::NONE), y(DirState::NONE) { + } - static uint32_t x_state = 0; - static uint32_t y_state = 0; + DirState x; + DirState y; + }; + struct StateKey { + int deviceId; + int axisId; + + 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 +299,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 {