diff --git a/Cocoa/Preferences.xib b/Cocoa/Preferences.xib index 149f71e..aa4a87d 100644 --- a/Cocoa/Preferences.xib +++ b/Cocoa/Preferences.xib @@ -603,13 +603,13 @@ - + - - + + diff --git a/SDL/gui.c b/SDL/gui.c index 5650d9b..81a9e42 100644 --- a/SDL/gui.c +++ b/SDL/gui.c @@ -108,10 +108,11 @@ configuration_t configuration = .rewind_length = 60 * 2, .model = MODEL_CGB, .volume = 100, + .rumble_mode = GB_RUMBLE_ALL_GAMES, }; -static const char *help[] ={ +static const char *help[] = { "Drop a ROM to play.\n" "\n" "Keyboard Shortcuts:\n" @@ -763,6 +764,7 @@ static void enter_controls_menu(unsigned index) static unsigned joypad_index = 0; static SDL_Joystick *joystick = NULL; static SDL_GameController *controller = NULL; +SDL_Haptic *haptic = NULL; const char *current_joypad_name(unsigned index) { @@ -792,6 +794,12 @@ static void cycle_joypads(unsigned index) if (joypad_index >= SDL_NumJoysticks()) { joypad_index = 0; } + + if (haptic) { + SDL_HapticClose(haptic); + haptic = NULL; + } + if (controller) { SDL_GameControllerClose(controller); controller = NULL; @@ -806,14 +814,22 @@ static void cycle_joypads(unsigned index) else { joystick = SDL_JoystickOpen(joypad_index); } -} + if (joystick) { + haptic = SDL_HapticOpenFromJoystick(joystick); + }} static void cycle_joypads_backwards(unsigned index) { - joypad_index++; + joypad_index--; if (joypad_index >= SDL_NumJoysticks()) { joypad_index = SDL_NumJoysticks() - 1; } + + if (haptic) { + SDL_HapticClose(haptic); + haptic = NULL; + } + if (controller) { SDL_GameControllerClose(controller); controller = NULL; @@ -828,7 +844,9 @@ static void cycle_joypads_backwards(unsigned index) else { joystick = SDL_JoystickOpen(joypad_index); } -} + if (joystick) { + haptic = SDL_HapticOpenFromJoystick(joystick); + }} static void detect_joypad_layout(unsigned index) { @@ -837,9 +855,36 @@ static void detect_joypad_layout(unsigned index) joypad_axis_temp = -1; } +static void cycle_rumble_mode(unsigned index) +{ + if (configuration.rumble_mode == GB_RUMBLE_ALL_GAMES) { + configuration.rumble_mode = GB_RUMBLE_DISABLED; + } + else { + configuration.rumble_mode++; + } +} + +static void cycle_rumble_mode_backwards(unsigned index) +{ + if (configuration.rumble_mode == GB_RUMBLE_DISABLED) { + configuration.rumble_mode = GB_RUMBLE_ALL_GAMES; + } + else { + configuration.rumble_mode--; + } +} + +const char *current_rumble_mode(unsigned index) +{ + return (const char *[]){"Disabled", "Rumble Game Paks Only", "All Games"} + [configuration.rumble_mode]; +} + static const struct menu_item joypad_menu[] = { {"Joypad:", cycle_joypads, current_joypad_name, cycle_joypads_backwards}, {"Configure layout", detect_joypad_layout}, + {"Rumble Mode:", cycle_rumble_mode, current_rumble_mode, cycle_rumble_mode_backwards}, {"Back", return_to_root_menu}, {NULL,} }; @@ -893,6 +938,9 @@ void connect_joypad(void) joystick = SDL_JoystickOpen(0); } } + if (joystick) { + haptic = SDL_HapticOpenFromJoystick(joystick); + } } void run_gui(bool is_running) diff --git a/SDL/gui.h b/SDL/gui.h index 4a3b55f..af7543b 100644 --- a/SDL/gui.h +++ b/SDL/gui.h @@ -21,6 +21,7 @@ extern SDL_Window *window; extern SDL_Renderer *renderer; extern SDL_Texture *texture; extern SDL_PixelFormat *pixel_format; +extern SDL_Haptic *haptic; extern shader_t shader; enum scaling_mode { @@ -105,6 +106,7 @@ typedef struct { uint8_t dmg_palette; GB_border_mode_t border_mode; uint8_t volume; + GB_rumble_mode_t rumble_mode; } configuration_t; extern configuration_t configuration; diff --git a/SDL/main.c b/SDL/main.c index c4a4d0f..f75e3aa 100644 --- a/SDL/main.c +++ b/SDL/main.c @@ -367,6 +367,11 @@ static uint32_t rgb_encode(GB_gameboy_t *gb, uint8_t r, uint8_t g, uint8_t b) return SDL_MapRGB(pixel_format, r, g, b); } +static void rumble(GB_gameboy_t *gb, double amp) +{ + SDL_HapticRumblePlay(haptic, amp, 250); +} + static void debugger_interrupt(int ignore) { if (!GB_is_inited(&gb)) return; @@ -488,6 +493,8 @@ restart: GB_set_vblank_callback(&gb, (GB_vblank_callback_t) vblank); GB_set_pixels_output(&gb, active_pixel_buffer); GB_set_rgb_encode_callback(&gb, rgb_encode); + GB_set_rumble_callback(&gb, rumble); + GB_set_rumble_mode(&gb, configuration.rumble_mode); GB_set_sample_rate(&gb, GB_audio_get_frequency()); GB_set_color_correction_mode(&gb, configuration.color_correction_mode); update_palette();