From 564c31aa30bd5035f1aa8775217dfc155e292ed6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Ziad=C3=A9?= Date: Tue, 27 May 2025 18:43:00 +0300 Subject: [PATCH] Add support for vim-style hjkl D-pad keys --- Cocoa/GBView.m | 151 +++++++++++++++++++++++++++++++++++++++++++++++++ SDL/main.c | 22 +++++++ 2 files changed, 173 insertions(+) diff --git a/Cocoa/GBView.m b/Cocoa/GBView.m index 103ec78..0227883 100644 --- a/Cocoa/GBView.m +++ b/Cocoa/GBView.m @@ -454,6 +454,87 @@ static const uint8_t workboy_vk_to_key[] = { } } + // Add support for vim-style hjkl D-pad keys alongside arrow keys + if (!handled) { + unsigned short keyCode = theEvent.keyCode; + if (keyCode == kVK_ANSI_H) { // h = left + handled = true; + for (unsigned player = 0; player < player_count; player++) { + if (self.document.partner) { + if (player == 0) { + GB_set_key_state_for_player(_gb, GB_KEY_LEFT, 0, true); + GB_set_use_faux_analog_inputs(_gb, 0, false); + } + else { + GB_set_key_state_for_player(self.document.partner.gb, GB_KEY_LEFT, 0, true); + GB_set_use_faux_analog_inputs(self.document.partner.gb, 0, false); + } + } + else { + GB_set_key_state_for_player(_gb, GB_KEY_LEFT, player, true); + GB_set_use_faux_analog_inputs(_gb, player, false); + } + } + } + else if (keyCode == kVK_ANSI_J) { // j = down + handled = true; + for (unsigned player = 0; player < player_count; player++) { + if (self.document.partner) { + if (player == 0) { + GB_set_key_state_for_player(_gb, GB_KEY_DOWN, 0, true); + GB_set_use_faux_analog_inputs(_gb, 0, false); + } + else { + GB_set_key_state_for_player(self.document.partner.gb, GB_KEY_DOWN, 0, true); + GB_set_use_faux_analog_inputs(self.document.partner.gb, 0, false); + } + } + else { + GB_set_key_state_for_player(_gb, GB_KEY_DOWN, player, true); + GB_set_use_faux_analog_inputs(_gb, player, false); + } + } + } + else if (keyCode == kVK_ANSI_K) { // k = up + handled = true; + for (unsigned player = 0; player < player_count; player++) { + if (self.document.partner) { + if (player == 0) { + GB_set_key_state_for_player(_gb, GB_KEY_UP, 0, true); + GB_set_use_faux_analog_inputs(_gb, 0, false); + } + else { + GB_set_key_state_for_player(self.document.partner.gb, GB_KEY_UP, 0, true); + GB_set_use_faux_analog_inputs(self.document.partner.gb, 0, false); + } + } + else { + GB_set_key_state_for_player(_gb, GB_KEY_UP, player, true); + GB_set_use_faux_analog_inputs(_gb, player, false); + } + } + } + else if (keyCode == kVK_ANSI_L) { // l = right + handled = true; + for (unsigned player = 0; player < player_count; player++) { + if (self.document.partner) { + if (player == 0) { + GB_set_key_state_for_player(_gb, GB_KEY_RIGHT, 0, true); + GB_set_use_faux_analog_inputs(_gb, 0, false); + } + else { + GB_set_key_state_for_player(self.document.partner.gb, GB_KEY_RIGHT, 0, true); + GB_set_use_faux_analog_inputs(self.document.partner.gb, 0, false); + } + } + else { + GB_set_key_state_for_player(_gb, GB_KEY_RIGHT, player, true); + GB_set_use_faux_analog_inputs(_gb, player, false); + } + } + } + } + if (!handled && [theEvent type] != NSEventTypeFlagsChanged) { [super keyDown:theEvent]; } @@ -533,6 +614,76 @@ static const uint8_t workboy_vk_to_key[] = { } } } + + // Add support for vim-style hjkl D-pad keys alongside arrow keys + if (!handled) { + unsigned short keyCode = theEvent.keyCode; + if (keyCode == kVK_ANSI_H) { // h = left + handled = true; + for (unsigned player = 0; player < player_count; player++) { + if (self.document.partner) { + if (player == 0) { + GB_set_key_state_for_player(_gb, GB_KEY_LEFT, 0, false); + } + else { + GB_set_key_state_for_player(self.document.partner.gb, GB_KEY_LEFT, 0, false); + } + } + else { + GB_set_key_state_for_player(_gb, GB_KEY_LEFT, player, false); + } + } + } + else if (keyCode == kVK_ANSI_J) { // j = down + handled = true; + for (unsigned player = 0; player < player_count; player++) { + if (self.document.partner) { + if (player == 0) { + GB_set_key_state_for_player(_gb, GB_KEY_DOWN, 0, false); + } + else { + GB_set_key_state_for_player(self.document.partner.gb, GB_KEY_DOWN, 0, false); + } + } + else { + GB_set_key_state_for_player(_gb, GB_KEY_DOWN, player, false); + } + } + } + else if (keyCode == kVK_ANSI_K) { // k = up + handled = true; + for (unsigned player = 0; player < player_count; player++) { + if (self.document.partner) { + if (player == 0) { + GB_set_key_state_for_player(_gb, GB_KEY_UP, 0, false); + } + else { + GB_set_key_state_for_player(self.document.partner.gb, GB_KEY_UP, 0, false); + } + } + else { + GB_set_key_state_for_player(_gb, GB_KEY_UP, player, false); + } + } + } + else if (keyCode == kVK_ANSI_L) { // l = right + handled = true; + for (unsigned player = 0; player < player_count; player++) { + if (self.document.partner) { + if (player == 0) { + GB_set_key_state_for_player(_gb, GB_KEY_RIGHT, 0, false); + } + else { + GB_set_key_state_for_player(self.document.partner.gb, GB_KEY_RIGHT, 0, false); + } + } + else { + GB_set_key_state_for_player(_gb, GB_KEY_RIGHT, player, false); + } + } + } + } + if (!handled && [theEvent type] != NSEventTypeFlagsChanged) { [super keyUp:theEvent]; } diff --git a/SDL/main.c b/SDL/main.c index ebd888c..caf149a 100644 --- a/SDL/main.c +++ b/SDL/main.c @@ -632,12 +632,34 @@ static void handle_events(GB_gameboy_t *gb) GB_set_key_state(gb, GB_KEY_B, event.type == SDL_KEYDOWN); } else { + bool key_handled = false; for (unsigned i = 0; i < GB_KEY_MAX; i++) { if (event.key.keysym.scancode == configuration.keys[i]) { if (i <= GB_KEY_DOWN) { GB_set_use_faux_analog_inputs(gb, 0, false); } GB_set_key_state(gb, i, event.type == SDL_KEYDOWN); + key_handled = true; + } + } + + // Add support for vim-style hjkl D-pad keys alongside arrow keys (only if not already mapped) + if (!key_handled) { + if (event.key.keysym.scancode == SDL_SCANCODE_H) { + GB_set_use_faux_analog_inputs(gb, 0, false); + GB_set_key_state(gb, GB_KEY_LEFT, event.type == SDL_KEYDOWN); + } + else if (event.key.keysym.scancode == SDL_SCANCODE_J) { + GB_set_use_faux_analog_inputs(gb, 0, false); + GB_set_key_state(gb, GB_KEY_DOWN, event.type == SDL_KEYDOWN); + } + else if (event.key.keysym.scancode == SDL_SCANCODE_K) { + GB_set_use_faux_analog_inputs(gb, 0, false); + GB_set_key_state(gb, GB_KEY_UP, event.type == SDL_KEYDOWN); + } + else if (event.key.keysym.scancode == SDL_SCANCODE_L) { + GB_set_use_faux_analog_inputs(gb, 0, false); + GB_set_key_state(gb, GB_KEY_RIGHT, event.type == SDL_KEYDOWN); } } }