Skip to content
Permalink
Browse files

Merge pull request #12755 from unknownbrackets/android-hat

UI: Translate HAT and left analog the same way
  • Loading branch information
hrydgard committed Mar 24, 2020
2 parents b0035db + 3bc59b0 commit cc0cfcd336ff75c6c2f84c50c86102bf5f398ba2
Showing with 45 additions and 62 deletions.
  1. +39 −26 ext/native/ui/root.cpp
  2. +2 −30 ext/native/ui/ui_screen.cpp
  3. +4 −6 ext/native/ui/ui_screen.h
@@ -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) {
}

DirState x;
DirState y;
};
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<StateKey, PrevState> 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;
}
@@ -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) {
@@ -44,17 +44,15 @@ class UIScreen : public Screen {

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 {

0 comments on commit cc0cfcd

Please sign in to comment.
You can’t perform that action at this time.