Skip to content

Commit 5cad7fc

Browse files
committed
Add gamepad support for L2 / R2 buttons (triggers)
1 parent 6716afb commit 5cad7fc

4 files changed

Lines changed: 138 additions & 72 deletions

File tree

platforms/shared/desktop/application.cpp

Lines changed: 93 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ static Uint64 frame_time_start = 0;
4444
static Uint64 frame_time_end = 0;
4545
static bool input_updated = false;
4646
static Uint16 input_last_state[GG_MAX_GAMEPADS] = { };
47+
static bool input_turbo_toggle_prev[GG_MAX_GAMEPADS][2] = { };
4748
static Uint32 mouse_last_motion_time = 0;
4849
static const Uint32 mouse_hide_timeout_ms = 1500;
4950

@@ -59,6 +60,7 @@ static void sdl_add_gamepads(void);
5960
static void sdl_remove_gamepad(SDL_JoystickID instance_id);
6061
static Uint16 input_build_state(int controller);
6162
static void input_apply_state(int controller, Uint16 before, Uint16 now);
63+
static bool input_get_button(SDL_GameController* controller, int mapping);
6264
static void handle_mouse_cursor(void);
6365
static void handle_menu(void);
6466
static void run_emulator(void);
@@ -599,67 +601,6 @@ static void sdl_events_app(const SDL_Event* event)
599601
sdl_remove_gamepad(event->cdevice.which);
600602
break;
601603
}
602-
case SDL_KEYDOWN:
603-
{
604-
if (event->key.repeat != 0)
605-
break;
606-
if (event->key.keysym.mod & KMOD_CTRL)
607-
break;
608-
if (event->key.keysym.mod & KMOD_SHIFT)
609-
break;
610-
611-
int key = event->key.keysym.scancode;
612-
613-
if (key == SDL_SCANCODE_ESCAPE)
614-
{
615-
config_emulator.fullscreen = false;
616-
application_trigger_fullscreen(false);
617-
break;
618-
}
619-
620-
for (int i = 0; i < GG_MAX_GAMEPADS; i++)
621-
{
622-
GG_Controllers controller = (GG_Controllers)i;
623-
624-
if (key == config_input_keyboard[i].key_toggle_turbo_I)
625-
{
626-
config_input.turbo_enabled[controller][0] = !config_input.turbo_enabled[controller][0];
627-
emu_set_turbo(controller, GG_KEY_I, config_input.turbo_enabled[controller][0]);
628-
}
629-
else if (key == config_input_keyboard[i].key_toggle_turbo_II)
630-
{
631-
config_input.turbo_enabled[controller][1] = !config_input.turbo_enabled[controller][1];
632-
emu_set_turbo(controller, GG_KEY_II, config_input.turbo_enabled[controller][1]);
633-
}
634-
}
635-
break;
636-
}
637-
case SDL_CONTROLLERBUTTONDOWN:
638-
{
639-
for (int i = 0; i < GG_MAX_GAMEPADS; i++)
640-
{
641-
if (!IsValidPointer(application_gamepad[i]))
642-
continue;
643-
644-
GG_Controllers controller = (GG_Controllers)i;
645-
SDL_JoystickID id = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(application_gamepad[i]));
646-
647-
if (event->cbutton.which != id)
648-
continue;
649-
650-
if (event->cbutton.button == config_input_gamepad[i].gamepad_toggle_turbo_I)
651-
{
652-
config_input.turbo_enabled[controller][0] = !config_input.turbo_enabled[controller][0];
653-
emu_set_turbo(controller, GG_KEY_I, config_input.turbo_enabled[controller][0]);
654-
}
655-
else if (event->cbutton.button == config_input_gamepad[i].gamepad_toggle_turbo_II)
656-
{
657-
config_input.turbo_enabled[controller][1] = !config_input.turbo_enabled[controller][1];
658-
emu_set_turbo(controller, GG_KEY_II, config_input.turbo_enabled[controller][1]);
659-
}
660-
}
661-
break;
662-
}
663604
}
664605
}
665606

@@ -672,50 +613,74 @@ static void sdl_events_shortcuts_gui(const SDL_Event* event)
672613
switch (key)
673614
{
674615
case SDL_SCANCODE_Q:
616+
if (event->key.repeat != 0)
617+
break;
675618
if (event->key.keysym.mod & KMOD_CTRL)
676619
application_trigger_quit();
677620
break;
678621
case SDL_SCANCODE_A:
622+
if (event->key.repeat != 0)
623+
break;
679624
if (event->key.keysym.mod & KMOD_CTRL)
680625
gui_shortcut(gui_ShortcutDebugSelectAll);
681626
break;
682627
case SDL_SCANCODE_C:
628+
if (event->key.repeat != 0)
629+
break;
683630
if (event->key.keysym.mod & KMOD_CTRL)
684631
gui_shortcut(gui_ShortcutDebugCopy);
685632
break;
686633
case SDL_SCANCODE_V:
634+
if (event->key.repeat != 0)
635+
break;
687636
if (event->key.keysym.mod & KMOD_CTRL)
688637
gui_shortcut(gui_ShortcutDebugPaste);
689638
break;
690639
case SDL_SCANCODE_O:
640+
if (event->key.repeat != 0)
641+
break;
691642
if (event->key.keysym.mod & KMOD_CTRL)
692643
gui_shortcut(gui_ShortcutOpenROM);
693644
break;
694645
case SDL_SCANCODE_R:
646+
if (event->key.repeat != 0)
647+
break;
695648
if (event->key.keysym.mod & KMOD_CTRL)
696649
gui_shortcut(gui_ShortcutReset);
697650
break;
698651
case SDL_SCANCODE_P:
652+
if (event->key.repeat != 0)
653+
break;
699654
if (event->key.keysym.mod & KMOD_CTRL)
700655
gui_shortcut(gui_ShortcutPause);
701656
break;
702657
case SDL_SCANCODE_F:
658+
if (event->key.repeat != 0)
659+
break;
703660
if (event->key.keysym.mod & KMOD_CTRL)
704661
gui_shortcut(gui_ShortcutFFWD);
705662
break;
706663
case SDL_SCANCODE_L:
664+
if (event->key.repeat != 0)
665+
break;
707666
if (event->key.keysym.mod & KMOD_CTRL)
708667
gui_shortcut(gui_ShortcutLoadState);
709668
break;
710669
case SDL_SCANCODE_S:
670+
if (event->key.repeat != 0)
671+
break;
711672
if (event->key.keysym.mod & KMOD_CTRL)
712673
gui_shortcut(gui_ShortcutSaveState);
713674
break;
714675
case SDL_SCANCODE_X:
676+
if (event->key.repeat != 0)
677+
break;
715678
if (event->key.keysym.mod & KMOD_CTRL)
716679
gui_shortcut(gui_ShortcutScreenshot);
717680
break;
718681
case SDL_SCANCODE_M:
682+
if (event->key.repeat != 0)
683+
break;
719684
if (event->key.keysym.mod & KMOD_CTRL)
720685
gui_shortcut(gui_ShortcutShowMainMenu);
721686
break;
@@ -732,6 +697,8 @@ static void sdl_events_shortcuts_gui(const SDL_Event* event)
732697
gui_shortcut(gui_ShortcutDebugRuntocursor);
733698
break;
734699
case SDL_SCANCODE_F9:
700+
if (event->key.repeat != 0)
701+
break;
735702
gui_shortcut(gui_ShortcutDebugBreakpoint);
736703
break;
737704
case SDL_SCANCODE_F10:
@@ -744,13 +711,24 @@ static void sdl_events_shortcuts_gui(const SDL_Event* event)
744711
gui_shortcut(gui_ShortcutDebugStepInto);
745712
break;
746713
case SDL_SCANCODE_F12:
714+
if (event->key.repeat != 0)
715+
break;
747716
config_emulator.fullscreen = !config_emulator.fullscreen;
748717
application_trigger_fullscreen(config_emulator.fullscreen);
749718
break;
750719
case SDL_SCANCODE_BACKSPACE:
751720
if (event->key.keysym.mod & KMOD_CTRL)
752721
gui_shortcut(gui_ShortcutDebugGoBack);
753722
break;
723+
case SDL_SCANCODE_ESCAPE:
724+
if (event->key.repeat != 0)
725+
break;
726+
if (config_emulator.fullscreen && !config_emulator.always_show_menu)
727+
{
728+
config_emulator.fullscreen = false;
729+
application_trigger_fullscreen(false);
730+
}
731+
break;
754732
}
755733
}
756734
}
@@ -763,7 +741,9 @@ static void sdl_events_emu(void)
763741

764742
SDL_PumpEvents();
765743

766-
for (int controller = 0; controller < GG_MAX_GAMEPADS; controller++)
744+
int max_controller = config_input.turbo_tap ? GG_MAX_GAMEPADS : 1;
745+
746+
for (int controller = 0; controller < max_controller; controller++)
767747
{
768748
Uint16 now = input_build_state(controller);
769749
Uint16 before = input_last_state[controller];
@@ -924,27 +904,35 @@ static Uint16 input_build_state(int controller)
924904
if (keyboard_state[config_input_keyboard[controller].key_select])
925905
ret |= GG_KEY_SELECT;
926906

907+
bool kb_turbo_I = keyboard_state[config_input_keyboard[controller].key_toggle_turbo_I] != 0;
908+
bool kb_turbo_II = keyboard_state[config_input_keyboard[controller].key_toggle_turbo_II] != 0;
909+
bool gp_turbo_I = false;
910+
bool gp_turbo_II = false;
911+
927912
SDL_GameController* sdl_controller = application_gamepad[controller];
928913

929914
if (IsValidPointer(sdl_controller))
930915
{
931-
if (SDL_GameControllerGetButton(sdl_controller, (SDL_GameControllerButton)config_input_gamepad[controller].gamepad_I))
916+
if (input_get_button(sdl_controller, config_input_gamepad[controller].gamepad_I))
932917
ret |= GG_KEY_I;
933-
if (SDL_GameControllerGetButton(sdl_controller, (SDL_GameControllerButton)config_input_gamepad[controller].gamepad_II))
918+
if (input_get_button(sdl_controller, config_input_gamepad[controller].gamepad_II))
934919
ret |= GG_KEY_II;
935-
if (SDL_GameControllerGetButton(sdl_controller, (SDL_GameControllerButton)config_input_gamepad[controller].gamepad_III))
920+
if (input_get_button(sdl_controller, config_input_gamepad[controller].gamepad_III))
936921
ret |= GG_KEY_III;
937-
if (SDL_GameControllerGetButton(sdl_controller, (SDL_GameControllerButton)config_input_gamepad[controller].gamepad_IV))
922+
if (input_get_button(sdl_controller, config_input_gamepad[controller].gamepad_IV))
938923
ret |= GG_KEY_IV;
939-
if (SDL_GameControllerGetButton(sdl_controller, (SDL_GameControllerButton)config_input_gamepad[controller].gamepad_V))
924+
if (input_get_button(sdl_controller, config_input_gamepad[controller].gamepad_V))
940925
ret |= GG_KEY_V;
941-
if (SDL_GameControllerGetButton(sdl_controller, (SDL_GameControllerButton)config_input_gamepad[controller].gamepad_VI))
926+
if (input_get_button(sdl_controller, config_input_gamepad[controller].gamepad_VI))
942927
ret |= GG_KEY_VI;
943-
if (SDL_GameControllerGetButton(sdl_controller, (SDL_GameControllerButton)config_input_gamepad[controller].gamepad_run))
928+
if (input_get_button(sdl_controller, config_input_gamepad[controller].gamepad_run))
944929
ret |= GG_KEY_RUN;
945-
if (SDL_GameControllerGetButton(sdl_controller, (SDL_GameControllerButton)config_input_gamepad[controller].gamepad_select))
930+
if (input_get_button(sdl_controller, config_input_gamepad[controller].gamepad_select))
946931
ret |= GG_KEY_SELECT;
947932

933+
gp_turbo_I = input_get_button(sdl_controller, config_input_gamepad[controller].gamepad_toggle_turbo_I);
934+
gp_turbo_II = input_get_button(sdl_controller, config_input_gamepad[controller].gamepad_toggle_turbo_II);
935+
948936
// Use D-Pad
949937
if (config_input_gamepad[controller].gamepad_directional == 0)
950938
{
@@ -979,6 +967,23 @@ static Uint16 input_build_state(int controller)
979967
}
980968
}
981969

970+
bool pressed_turbo_I = kb_turbo_I || gp_turbo_I;
971+
bool pressed_turbo_II = kb_turbo_II || gp_turbo_II;
972+
973+
if (pressed_turbo_I && !input_turbo_toggle_prev[controller][0])
974+
{
975+
config_input.turbo_enabled[controller][0] = !config_input.turbo_enabled[controller][0];
976+
emu_set_turbo((GG_Controllers)controller, GG_KEY_I, config_input.turbo_enabled[controller][0]);
977+
}
978+
if (pressed_turbo_II && !input_turbo_toggle_prev[controller][1])
979+
{
980+
config_input.turbo_enabled[controller][1] = !config_input.turbo_enabled[controller][1];
981+
emu_set_turbo((GG_Controllers)controller, GG_KEY_II, config_input.turbo_enabled[controller][1]);
982+
}
983+
984+
input_turbo_toggle_prev[controller][0] = pressed_turbo_I;
985+
input_turbo_toggle_prev[controller][1] = pressed_turbo_II;
986+
982987
return ret;
983988
}
984989

@@ -1004,6 +1009,24 @@ static void input_apply_state(int controller, Uint16 before, Uint16 now)
10041009
}
10051010
}
10061011

1012+
static bool input_get_button(SDL_GameController* controller, int mapping)
1013+
{
1014+
if (!IsValidPointer(controller))
1015+
return false;
1016+
1017+
if (mapping >= 0 && mapping < SDL_CONTROLLER_BUTTON_MAX)
1018+
return SDL_GameControllerGetButton(controller, (SDL_GameControllerButton)mapping) != 0;
1019+
1020+
if (mapping >= GAMEPAD_VBTN_AXIS_BASE)
1021+
{
1022+
int axis = mapping - GAMEPAD_VBTN_AXIS_BASE;
1023+
Sint16 value = SDL_GameControllerGetAxis(controller, (SDL_GameControllerAxis)axis);
1024+
return value > GAMEPAD_VBTN_AXIS_THRESHOLD;
1025+
}
1026+
1027+
return false;
1028+
}
1029+
10071030
static void run_emulator(void)
10081031
{
10091032
config_emulator.paused = emu_is_paused();

platforms/shared/desktop/application.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@
2929
#define EXTERN extern
3030
#endif
3131

32+
#define GAMEPAD_VBTN_AXIS_BASE 1000
33+
#define GAMEPAD_VBTN_AXIS_THRESHOLD 3000
34+
#define GAMEPAD_VBTN_L2 (GAMEPAD_VBTN_AXIS_BASE + SDL_CONTROLLER_AXIS_TRIGGERLEFT)
35+
#define GAMEPAD_VBTN_R2 (GAMEPAD_VBTN_AXIS_BASE + SDL_CONTROLLER_AXIS_TRIGGERRIGHT)
36+
3237
EXTERN SDL_Window* application_sdl_window;
3338
EXTERN SDL_GameController* application_gamepad[GG_MAX_GAMEPADS];
3439
EXTERN int application_added_gamepad_mappings;

platforms/shared/desktop/gui_menus.cpp

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -786,6 +786,8 @@ static void menu_input(void)
786786

787787
if (ImGui::BeginMenu(keyboard_name))
788788
{
789+
ImGui::TextDisabled("Keyboard %s", keyboard_name);
790+
ImGui::Separator();
789791
keyboard_configuration_item("Left:", &config_input_keyboard[i].key_left, i);
790792
keyboard_configuration_item("Right:", &config_input_keyboard[i].key_right, i);
791793
keyboard_configuration_item("Up:", &config_input_keyboard[i].key_up, i);
@@ -859,6 +861,8 @@ static void menu_input(void)
859861

860862
if (ImGui::BeginMenu("Button Configuration"))
861863
{
864+
ImGui::TextDisabled("Gamepad %s", gamepad_name);
865+
ImGui::Separator();
862866
gamepad_configuration_item("Select:", &config_input_gamepad[i].gamepad_select, i);
863867
gamepad_configuration_item("Run:", &config_input_gamepad[i].gamepad_run, i);
864868
gamepad_configuration_item("I:", &config_input_gamepad[i].gamepad_I, i);
@@ -1249,8 +1253,27 @@ static void gamepad_configuration_item(const char* text, int* button, int player
12491253
ImGui::Text("%s", text);
12501254
ImGui::SameLine(120);
12511255

1252-
static const char* gamepad_names[16] = {"A", "B", "X" ,"Y", "BACK", "GUIDE", "START", "L3", "R3", "L1", "R1", "UP", "DOWN", "LEFT", "RIGHT", "15"};
1253-
const char* button_name = (*button >= 0 && *button < 16) ? gamepad_names[*button] : "";
1256+
const char* button_name = "";
1257+
1258+
if (*button == SDL_CONTROLLER_BUTTON_INVALID)
1259+
{
1260+
button_name = "";
1261+
}
1262+
else if (*button >= 0 && *button < SDL_CONTROLLER_BUTTON_MAX)
1263+
{
1264+
static const char* gamepad_names[21] = {"A", "B", "X" ,"Y", "BACK", "GUIDE", "START", "L3", "R3", "L1", "R1", "UP", "DOWN", "LEFT", "RIGHT", "MISC", "PAD1", "PAD2", "PAD3", "PAD4", "TOUCH"};
1265+
button_name = gamepad_names[*button];
1266+
}
1267+
else if (*button >= GAMEPAD_VBTN_AXIS_BASE)
1268+
{
1269+
int axis = *button - GAMEPAD_VBTN_AXIS_BASE;
1270+
if (axis == SDL_CONTROLLER_AXIS_TRIGGERLEFT)
1271+
button_name = "L2";
1272+
else if (axis == SDL_CONTROLLER_AXIS_TRIGGERRIGHT)
1273+
button_name = "R2";
1274+
else
1275+
button_name = "??";
1276+
}
12541277

12551278
char button_label[256];
12561279
snprintf(button_label, 256, "%s##%s%d", button_name, text, player);

platforms/shared/desktop/gui_popups.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,21 @@ void gui_popup_modal_gamepad(int pad)
8484
}
8585
}
8686

87+
for (int a = SDL_CONTROLLER_AXIS_LEFTX; a < SDL_CONTROLLER_AXIS_MAX; a++)
88+
{
89+
if (a != SDL_CONTROLLER_AXIS_TRIGGERLEFT && a != SDL_CONTROLLER_AXIS_TRIGGERRIGHT)
90+
continue;
91+
92+
Sint16 value = SDL_GameControllerGetAxis(application_gamepad[pad], (SDL_GameControllerAxis)a);
93+
94+
if (value > GAMEPAD_VBTN_AXIS_THRESHOLD)
95+
{
96+
*gui_configured_button = GAMEPAD_VBTN_AXIS_BASE + a;
97+
ImGui::CloseCurrentPopup();
98+
break;
99+
}
100+
}
101+
87102
if (ImGui::Button("Cancel", ImVec2(120, 0)))
88103
{
89104
ImGui::CloseCurrentPopup();

0 commit comments

Comments
 (0)