From 116ea7d0d756df2485a19c3d0d93027a8bd708a2 Mon Sep 17 00:00:00 2001 From: Maximilian Mader Date: Mon, 11 May 2020 00:05:59 +0200 Subject: [PATCH] [GTK3] Improve analog speed controls a bit --- gtk3/main.c | 60 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 22 deletions(-) diff --git a/gtk3/main.c b/gtk3/main.c index 3fb05d9..2ad51cb 100644 --- a/gtk3/main.c +++ b/gtk3/main.c @@ -122,6 +122,7 @@ typedef struct GuiData { bool turbo_down; double clock_mutliplier; double analog_clock_multiplier; + bool analog_clock_multiplier_valid; // Input uint8_t pressed_buttons; @@ -164,6 +165,7 @@ static GuiData gui_data = { .rewind_paused = false, .turbo_down = false, .clock_mutliplier = 1.0, + .analog_clock_multiplier = 1.0, }; GB_gameboy_t gb; @@ -269,6 +271,22 @@ static void replace_extension(const char *src, size_t length, char *dest, const strcat(dest, ext); } +static double clamp_double(double min, double max, double value) { + if (value < min) return min; + if (value > max) return max; + return value; +} + +static double max_double(double a, double b) { + if (a > b) return a; + return b; +} + +static double min_double(double a, double b) { + if (a < b) return a; + return b; +} + static uint32_t rgb_encode(GB_gameboy_t *gb, uint8_t r, uint8_t g, uint8_t b) { return 0xFF000000 | (r << 16) | (g << 8) | b; } @@ -1189,17 +1207,26 @@ static void vblank(GB_gameboy_t *gb) { GB_set_pixels_output(gb, get_pixels()); - if (config.analog_speed_controls && gui_data.analog_clock_multiplier != 0.0) { - GB_set_clock_multiplier(gb, gui_data.analog_clock_multiplier); - } - else if (gui_data.underclock_down && gui_data.clock_mutliplier > 0.5) { - gui_data.clock_mutliplier -= 1.0/16; + // Handle the speed modifiers: + // The binary slowdown is limited to half speed. + // The analog multiplier can go down to a third and up to three times full speed. + if (gui_data.underclock_down && gui_data.clock_mutliplier > 0.5) { + gui_data.clock_mutliplier -= 1.0 / 16; + //gui_data.clock_mutliplier = clamp_double(0.5, 1.0, gui_data.clock_mutliplier - 1.0 / 16); GB_set_clock_multiplier(gb, gui_data.clock_mutliplier); } else if (!gui_data.underclock_down && gui_data.clock_mutliplier < 1.0) { - gui_data.clock_mutliplier += 1.0/16; + gui_data.clock_mutliplier += 1.0 / 16; + //gui_data.clock_mutliplier = clamp_double(0.5, 1.0, gui_data.clock_mutliplier + 1.0 / 16); GB_set_clock_multiplier(gb, gui_data.clock_mutliplier); } + else if (config.analog_speed_controls && gui_data.analog_clock_multiplier_valid) { + GB_set_clock_multiplier(gb, gui_data.analog_clock_multiplier); + + if (gui_data.analog_clock_multiplier == 1.0) { + gui_data.analog_clock_multiplier_valid = false; + } + } if (g_strcmp0("vram_viewer_tileset", gui_data.vram_viewer_active_tab) == 0) { const gchar *palette_id = gtk_combo_box_get_active_id(builder_get(GTK_COMBO_BOX, "vram_viewer_tileset_palette_selector")); @@ -1265,22 +1292,6 @@ static void vblank(GB_gameboy_t *gb) { g_idle_add((GSourceFunc) on_vblank, NULL); } -static double clamp_double(double min, double max, double value) { - if (value < min) return min; - if (value > max) return max; - return value; -} - -static double max_double(double a, double b) { - if (a > b) return a; - return b; -} - -static double min_double(double a, double b) { - if (a < b) return a; - return b; -} - static void handle_events(GB_gameboy_t *gb) { SDL_GameControllerUpdate(); @@ -1302,9 +1313,11 @@ static void handle_events(GB_gameboy_t *gb) { if (left_trigger > 0.0) { analog_clock_multiplier = min_double(analog_clock_multiplier, clamp_double(1.0 / 3, 1.0, 1 - left_trigger + 0.2)); + gui_data.analog_clock_multiplier_valid = true; } else if (right_trigger > 0.0) { analog_clock_multiplier = max_double(analog_clock_multiplier, clamp_double(1.0, 3.0, right_trigger * 3 + 0.8)); + gui_data.analog_clock_multiplier_valid = true; } } @@ -1673,12 +1686,15 @@ static gboolean on_key_press(GtkWidget *w, GdkEventKey *event, gpointer data) { if (event->keyval == key_map[INPUT_TURBO]) { gui_data.turbo_down = event->type == GDK_KEY_PRESS; + gui_data.analog_clock_multiplier_valid = false; + GB_audio_clear_queue(); GB_set_turbo_mode(&gb, gui_data.turbo_down, gui_data.turbo_down && gui_data.rewind_down); } if (event->keyval == key_map[INPUT_SLOWDOWN]) { gui_data.underclock_down = event->type == GDK_KEY_PRESS; + gui_data.analog_clock_multiplier_valid = false; } if (event->keyval == key_map[INPUT_FULLSCREEN]) {