add keyboard navigation support.
This commit is contained in:
@@ -267,6 +267,7 @@ public:
|
|||||||
PadState m_pad{};
|
PadState m_pad{};
|
||||||
TouchInfo m_touch_info{};
|
TouchInfo m_touch_info{};
|
||||||
Controller m_controller{};
|
Controller m_controller{};
|
||||||
|
KeyboardState m_keyboard{};
|
||||||
std::vector<ThemeMeta> m_theme_meta_entries;
|
std::vector<ThemeMeta> m_theme_meta_entries;
|
||||||
|
|
||||||
Vec2 m_scale{1, 1};
|
Vec2 m_scale{1, 1};
|
||||||
|
|||||||
@@ -366,6 +366,81 @@ struct Action final {
|
|||||||
std::string m_hint{};
|
std::string m_hint{};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct GenericHidState {
|
||||||
|
GenericHidState() {
|
||||||
|
Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Reset() {
|
||||||
|
buttons_cur = 0;
|
||||||
|
buttons_old = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 GetButtons() const {
|
||||||
|
return buttons_cur;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 GetButtonsDown() const {
|
||||||
|
return buttons_cur & ~buttons_old;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 GetButtonsUp() const {
|
||||||
|
return ~buttons_cur & buttons_old;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void Update() = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
u64 buttons_cur;
|
||||||
|
u64 buttons_old;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct KeyboardState final : GenericHidState {
|
||||||
|
struct MapEntry {
|
||||||
|
HidKeyboardKey key;
|
||||||
|
u64 button;
|
||||||
|
};
|
||||||
|
using Map = std::span<const MapEntry>;
|
||||||
|
|
||||||
|
void Init(Map map) {
|
||||||
|
m_map = map;
|
||||||
|
Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Update() override {
|
||||||
|
buttons_old = buttons_cur;
|
||||||
|
buttons_cur = 0;
|
||||||
|
|
||||||
|
if (!hidGetKeyboardStates(&m_state, 1)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto ctrl = m_state.modifiers & HidKeyboardModifier_Control;
|
||||||
|
const auto shift = m_state.modifiers & HidKeyboardModifier_Shift;
|
||||||
|
|
||||||
|
for (const auto& map : m_map) {
|
||||||
|
if (hidKeyboardStateGetKey(&m_state, map.key)) {
|
||||||
|
if (shift && map.button == static_cast<u64>(Button::L)) {
|
||||||
|
buttons_cur |= static_cast<u64>(Button::L2);
|
||||||
|
} else if (shift && map.button == static_cast<u64>(Button::R)) {
|
||||||
|
buttons_cur |= static_cast<u64>(Button::R2);
|
||||||
|
} else if (ctrl && map.button == static_cast<u64>(Button::L)) {
|
||||||
|
buttons_cur |= static_cast<u64>(Button::L3);
|
||||||
|
} else if (ctrl && map.button == static_cast<u64>(Button::R)) {
|
||||||
|
buttons_cur |= static_cast<u64>(Button::R3);
|
||||||
|
} else {
|
||||||
|
buttons_cur |= map.button;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Map m_map{};
|
||||||
|
HidKeyboardState m_state{};
|
||||||
|
};
|
||||||
|
|
||||||
struct Controller {
|
struct Controller {
|
||||||
u64 m_kdown{};
|
u64 m_kdown{};
|
||||||
u64 m_kheld{};
|
u64 m_kheld{};
|
||||||
|
|||||||
@@ -74,6 +74,37 @@ struct NszOption {
|
|||||||
const char* name;
|
const char* name;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
constexpr KeyboardState::MapEntry KEYBOARD_BUTTON_MAP[] = {
|
||||||
|
{HidKeyboardKey_UpArrow, static_cast<u64>(Button::DPAD_UP)},
|
||||||
|
{HidKeyboardKey_DownArrow, static_cast<u64>(Button::DPAD_DOWN)},
|
||||||
|
{HidKeyboardKey_LeftArrow, static_cast<u64>(Button::DPAD_LEFT)},
|
||||||
|
{HidKeyboardKey_RightArrow, static_cast<u64>(Button::DPAD_RIGHT)},
|
||||||
|
|
||||||
|
{HidKeyboardKey_W, static_cast<u64>(Button::DPAD_UP)},
|
||||||
|
{HidKeyboardKey_S, static_cast<u64>(Button::DPAD_DOWN)},
|
||||||
|
{HidKeyboardKey_A, static_cast<u64>(Button::DPAD_LEFT)},
|
||||||
|
{HidKeyboardKey_D, static_cast<u64>(Button::DPAD_RIGHT)},
|
||||||
|
|
||||||
|
// options (may swap).
|
||||||
|
{HidKeyboardKey_X, static_cast<u64>(Button::Y)},
|
||||||
|
{HidKeyboardKey_Z, static_cast<u64>(Button::X)},
|
||||||
|
|
||||||
|
// menus.
|
||||||
|
{HidKeyboardKey_Q, static_cast<u64>(Button::L)},
|
||||||
|
{HidKeyboardKey_E, static_cast<u64>(Button::R)},
|
||||||
|
|
||||||
|
// select and back.
|
||||||
|
{HidKeyboardKey_Return, static_cast<u64>(Button::A)},
|
||||||
|
{HidKeyboardKey_Space, static_cast<u64>(Button::A)},
|
||||||
|
{HidKeyboardKey_Backspace, static_cast<u64>(Button::B)},
|
||||||
|
|
||||||
|
// exit.
|
||||||
|
{HidKeyboardKey_Escape, static_cast<u64>(Button::START)},
|
||||||
|
|
||||||
|
// idk what this should map to.
|
||||||
|
{HidKeyboardKey_R, static_cast<u64>(Button::SELECT)},
|
||||||
|
};
|
||||||
|
|
||||||
constexpr NszOption NSZ_COMPRESS_LEVEL_OPTIONS[] = {
|
constexpr NszOption NSZ_COMPRESS_LEVEL_OPTIONS[] = {
|
||||||
{ .value = 0, .name = "Level 0 (no compression)" },
|
{ .value = 0, .name = "Level 0 (no compression)" },
|
||||||
{ .value = 1, .name = "Level 1" },
|
{ .value = 1, .name = "Level 1" },
|
||||||
@@ -1026,6 +1057,16 @@ void App::Poll() {
|
|||||||
hidGetTouchScreenStates(&state, 1);
|
hidGetTouchScreenStates(&state, 1);
|
||||||
m_touch_info.is_clicked = false;
|
m_touch_info.is_clicked = false;
|
||||||
|
|
||||||
|
// todo:
|
||||||
|
#if 0
|
||||||
|
HidMouseState mouse_state{};
|
||||||
|
hidGetMouseStates(&mouse_state, 1);
|
||||||
|
|
||||||
|
if (mouse_state.buttons) {
|
||||||
|
log_write("[MOUSE] buttons: 0x%X x: %d y: %d dx: %d dy: %d wx: %d wy: %d\n", mouse_state.buttons, mouse_state.x, mouse_state.y, mouse_state.delta_x, mouse_state.delta_y, mouse_state.wheel_delta_x, mouse_state.wheel_delta_y);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// todo: replace old touch code with gestures from below
|
// todo: replace old touch code with gestures from below
|
||||||
#if 0
|
#if 0
|
||||||
static HidGestureState prev_gestures[17]{};
|
static HidGestureState prev_gestures[17]{};
|
||||||
@@ -1071,6 +1112,7 @@ void App::Poll() {
|
|||||||
memcpy(prev_gestures, gestures, sizeof(gestures));
|
memcpy(prev_gestures, gestures, sizeof(gestures));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// todo: support mouse scroll / touch.
|
||||||
if (state.count == 1 && !m_touch_info.is_touching) {
|
if (state.count == 1 && !m_touch_info.is_touching) {
|
||||||
m_touch_info.initial = m_touch_info.cur = state.touches[0];
|
m_touch_info.initial = m_touch_info.cur = state.touches[0];
|
||||||
m_touch_info.is_touching = true;
|
m_touch_info.is_touching = true;
|
||||||
@@ -1094,14 +1136,29 @@ void App::Poll() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u64 kdown = 0;
|
||||||
|
u64 kup = 0;
|
||||||
|
u64 kheld = 0;
|
||||||
|
|
||||||
// todo: better implement this to match hos
|
// todo: better implement this to match hos
|
||||||
if (!m_touch_info.is_touching && !m_touch_info.is_clicked) {
|
if (!m_touch_info.is_touching && !m_touch_info.is_clicked) {
|
||||||
|
// controller.
|
||||||
padUpdate(&m_pad);
|
padUpdate(&m_pad);
|
||||||
m_controller.m_kdown = padGetButtonsDown(&m_pad);
|
kdown |= padGetButtonsDown(&m_pad);
|
||||||
m_controller.m_kheld = padGetButtons(&m_pad);
|
kheld |= padGetButtons(&m_pad);
|
||||||
m_controller.m_kup = padGetButtonsUp(&m_pad);
|
kup |= padGetButtonsUp(&m_pad);
|
||||||
m_controller.UpdateButtonHeld(static_cast<u64>(Button::ANY_DIRECTION), m_delta_time);
|
|
||||||
|
// keyboard.
|
||||||
|
m_keyboard.Update();
|
||||||
|
kdown |= m_keyboard.GetButtonsDown();
|
||||||
|
kheld |= m_keyboard.GetButtons();
|
||||||
|
kup |= m_keyboard.GetButtonsUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_controller.m_kdown = kdown;
|
||||||
|
m_controller.m_kheld = kheld;
|
||||||
|
m_controller.m_kup = kup;
|
||||||
|
m_controller.UpdateButtonHeld(static_cast<u64>(Button::ANY_DIRECTION), m_delta_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
void App::Update() {
|
void App::Update() {
|
||||||
@@ -1683,9 +1740,14 @@ App::App(const char* argv0) {
|
|||||||
SCOPED_TIMESTAMP("HID init");
|
SCOPED_TIMESTAMP("HID init");
|
||||||
hidInitializeTouchScreen();
|
hidInitializeTouchScreen();
|
||||||
hidInitializeGesture();
|
hidInitializeGesture();
|
||||||
|
hidInitializeKeyboard();
|
||||||
|
hidInitializeMouse();
|
||||||
|
|
||||||
padConfigureInput(8, HidNpadStyleSet_NpadStandard);
|
padConfigureInput(8, HidNpadStyleSet_NpadStandard);
|
||||||
// padInitializeDefault(&m_pad);
|
// padInitializeDefault(&m_pad);
|
||||||
padInitializeAny(&m_pad);
|
padInitializeAny(&m_pad);
|
||||||
|
|
||||||
|
m_keyboard.Init(KEYBOARD_BUTTON_MAP);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user