[GTK3] Add interference volume slider
This commit is contained in:
parent
50326f4058
commit
92cc8b6c6e
@ -172,7 +172,7 @@ void save_config(GtkWindow *main_window, GDateTime *saved_modification_date) {
|
||||
GError *error = NULL;
|
||||
|
||||
g_message("Trying to save config to %s", config_file_path);
|
||||
|
||||
|
||||
g_autoptr(GFile) file = g_file_new_for_path(config_file_path);
|
||||
g_autoptr(GFileInfo) file_info = g_file_query_info(file, "time::*", G_FILE_QUERY_INFO_NONE, NULL, NULL);
|
||||
|
||||
@ -429,7 +429,7 @@ const GB_rumble_mode_t config_get_rumble_mode(void) {
|
||||
}
|
||||
|
||||
// This should not happen
|
||||
g_warning("Unknown highpass mode: %s\nFalling back to “Never”", config.controls.rumble_mode);
|
||||
g_warning("Unknown rumble mode: %s\nFalling back to “Never”", config.controls.rumble_mode);
|
||||
default_value: return GB_RUMBLE_DISABLED;
|
||||
}
|
||||
|
||||
|
@ -47,11 +47,12 @@
|
||||
EXPAND_GROUP(audio, \
|
||||
EXPAND_GROUP_MEMBER(high_pass_filter_id, string, "emulate_hardware") \
|
||||
EXPAND_GROUP_MEMBER(sample_rate, integer, -1) \
|
||||
EXPAND_GROUP_MEMBER(interference_volume, integer, 0) \
|
||||
EXPAND_GROUP_MEMBER(muted, boolean, false) \
|
||||
) \
|
||||
EXPAND_GROUP(controls, \
|
||||
EXPAND_GROUP_MEMBER(analog_speed_controls, boolean, false) \
|
||||
EXPAND_GROUP_MEMBER(rumble_mode, string, "Never") \
|
||||
EXPAND_GROUP_MEMBER(rumble_mode, string, "never") \
|
||||
) \
|
||||
EXPAND_GROUP(window, \
|
||||
\
|
||||
|
47
gtk3/main.c
47
gtk3/main.c
@ -87,7 +87,7 @@ static const GActionEntry file_entries[] = {
|
||||
};
|
||||
|
||||
static const GActionEntry edit_entries[] = {
|
||||
|
||||
|
||||
};
|
||||
|
||||
static const GActionEntry emulation_entries[] = {
|
||||
@ -252,7 +252,7 @@ static gboolean init_controllers(void) {
|
||||
if (s->haptic == NULL) {
|
||||
g_warning("%s", SDL_GetError());
|
||||
}
|
||||
|
||||
|
||||
SDL_HapticClose(s->haptic);
|
||||
s->haptic = NULL;
|
||||
}
|
||||
@ -298,7 +298,7 @@ static gboolean init_audio(void) {
|
||||
|
||||
GB_audio_init(gui_data.sample_rate);
|
||||
GB_set_sample_rate(&gb, GB_audio_get_sample_rate());
|
||||
|
||||
|
||||
// restore playing state
|
||||
GB_audio_set_paused(!audio_playing);
|
||||
|
||||
@ -583,12 +583,12 @@ static void handle_events(GB_gameboy_t *gb) {
|
||||
gui_data.last_used_controller = s;
|
||||
controller_state |= BUTTON_MASK_A;
|
||||
}
|
||||
|
||||
|
||||
if (SDL_GameControllerGetButton(s->controller, SDL_CONTROLLER_BUTTON_B)) {
|
||||
gui_data.last_used_controller = s;
|
||||
controller_state |= BUTTON_MASK_B;
|
||||
}
|
||||
|
||||
|
||||
if (SDL_GameControllerGetButton(s->controller, SDL_CONTROLLER_BUTTON_BACK)) {
|
||||
gui_data.last_used_controller = s;
|
||||
controller_state |= BUTTON_MASK_SELECT;
|
||||
@ -698,9 +698,10 @@ static void init(void) {
|
||||
}
|
||||
|
||||
GB_apu_set_sample_callback(&gb, gb_audio_callback);
|
||||
|
||||
|
||||
GB_set_sample_rate(&gb, GB_audio_get_sample_rate());
|
||||
GB_set_highpass_filter_mode(&gb, config_get_highpass_mode());
|
||||
GB_set_interference_volume(&gb, (double) config.audio.interference_volume / 255.0);
|
||||
|
||||
GB_set_log_callback(&gb, wrapped_console_log);
|
||||
GB_set_input_callback(&gb, wrapped_console_get_sync_input);
|
||||
@ -837,7 +838,7 @@ static gpointer run_thread(gpointer null_ptr) {
|
||||
|
||||
char *path = g_file_get_path(gui_data.file);
|
||||
size_t path_length = strlen(path);
|
||||
|
||||
|
||||
/* At the worst case, size is strlen(path) + 4 bytes for .sav + NULL */
|
||||
char battery_save_path[path_length + 5];
|
||||
char cheats_save_path[path_length + 5];
|
||||
@ -915,14 +916,14 @@ static void create_action_groups(GApplication *app) {
|
||||
static gboolean on_key_press(GtkWidget *w, GdkEventKey *event, gpointer data) {
|
||||
uint8_t mask;
|
||||
|
||||
if (event->keyval == key_map[INPUT_UP]) mask = BUTTON_MASK_UP;
|
||||
if (event->keyval == key_map[INPUT_DOWN]) mask = BUTTON_MASK_DOWN;
|
||||
if (event->keyval == key_map[INPUT_LEFT]) mask = BUTTON_MASK_LEFT;
|
||||
if (event->keyval == key_map[INPUT_RIGHT]) mask = BUTTON_MASK_RIGHT;
|
||||
if (event->keyval == key_map[INPUT_START]) mask = BUTTON_MASK_START;
|
||||
if (event->keyval == key_map[INPUT_SELECT]) mask = BUTTON_MASK_SELECT;
|
||||
if (event->keyval == key_map[INPUT_A]) mask = BUTTON_MASK_A;
|
||||
if (event->keyval == key_map[INPUT_B]) mask = BUTTON_MASK_B;
|
||||
if (event->keyval == key_map[INPUT_UP]) mask = BUTTON_MASK_UP;
|
||||
if (event->keyval == key_map[INPUT_DOWN]) mask = BUTTON_MASK_DOWN;
|
||||
if (event->keyval == key_map[INPUT_LEFT]) mask = BUTTON_MASK_LEFT;
|
||||
if (event->keyval == key_map[INPUT_RIGHT]) mask = BUTTON_MASK_RIGHT;
|
||||
if (event->keyval == key_map[INPUT_START]) mask = BUTTON_MASK_START;
|
||||
if (event->keyval == key_map[INPUT_SELECT]) mask = BUTTON_MASK_SELECT;
|
||||
if (event->keyval == key_map[INPUT_A]) mask = BUTTON_MASK_A;
|
||||
if (event->keyval == key_map[INPUT_B]) mask = BUTTON_MASK_B;
|
||||
|
||||
if (event->keyval == key_map[INPUT_REWIND]) {
|
||||
gui_data.rewind_down = event->type == GDK_KEY_PRESS;
|
||||
@ -956,7 +957,7 @@ static gboolean on_key_press(GtkWidget *w, GdkEventKey *event, gpointer data) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (event->type == GDK_KEY_PRESS) {
|
||||
gui_data.pressed_buttons |= mask;
|
||||
}
|
||||
@ -1120,6 +1121,12 @@ void on_preferences_notify_sample_rate(PreferencesWindow *pref, const guint *sam
|
||||
init_audio();
|
||||
}
|
||||
|
||||
void on_preferences_notify_interference_volume(PreferencesWindow *pref, const guint *interference_volume) {
|
||||
if (GB_is_inited(&gb)) {
|
||||
GB_set_interference_volume(&gb, (double) *interference_volume / 255.0);
|
||||
}
|
||||
}
|
||||
|
||||
static void connect_signal_handlers(GApplication *app) {
|
||||
// Connect signal handlers
|
||||
gtk_widget_add_events(GTK_WIDGET(gui_data.main_window), GDK_KEY_PRESS_MASK);
|
||||
@ -1140,6 +1147,7 @@ static void connect_signal_handlers(GApplication *app) {
|
||||
g_signal_connect(gui_data.preferences, "pref-update::video-display-border-mode", G_CALLBACK(on_preferences_notify_border), NULL);
|
||||
g_signal_connect(gui_data.preferences, "pref-update::video-shader", G_CALLBACK(on_preferences_notify_shader), NULL);
|
||||
g_signal_connect(gui_data.preferences, "pref-update::audio-sample-rate", G_CALLBACK(on_preferences_notify_sample_rate), NULL);
|
||||
g_signal_connect(gui_data.preferences, "pref-update::audio-interference-volume", G_CALLBACK(on_preferences_notify_interference_volume), NULL);
|
||||
}
|
||||
|
||||
// This function gets called when the GApplication gets activated, i.e. it is ready to show widgets.
|
||||
@ -1167,7 +1175,7 @@ static void shutdown(GApplication *app, GFile **files, gint n_files, const gchar
|
||||
stop();
|
||||
SDL_Quit();
|
||||
GB_free(&gb);
|
||||
|
||||
|
||||
g_object_unref(gui_data.builder);
|
||||
}
|
||||
|
||||
@ -1193,7 +1201,6 @@ static void activate_about(GSimpleAction *action, GVariant *parameter, gpointer
|
||||
gtk_widget_hide(GTK_WIDGET(dialog));
|
||||
}
|
||||
|
||||
|
||||
// app.preferences GAction
|
||||
// Opens the preferences window
|
||||
static void activate_preferences(GSimpleAction *action, GVariant *parameter, gpointer app) {
|
||||
@ -1234,7 +1241,7 @@ static void activate_clear_console(GSimpleAction *action, GVariant *parameter, g
|
||||
static void close_rom(void) {
|
||||
stop();
|
||||
GB_free(&gb);
|
||||
|
||||
|
||||
gb_screen_clear(gui_data.screen);
|
||||
gb_screen_queue_render(gui_data.screen);
|
||||
|
||||
@ -1244,7 +1251,7 @@ static void close_rom(void) {
|
||||
// Update menu action states
|
||||
action_set_enabled(gui_data.main_application, "close", false);
|
||||
action_entries_set_enabled(emulation_entries, G_N_ELEMENTS(emulation_entries), false);
|
||||
|
||||
|
||||
// Try force the queued redraws
|
||||
while (g_main_context_pending(NULL)) {
|
||||
g_main_context_iteration(NULL, FALSE);
|
||||
|
@ -19,6 +19,7 @@ struct _PreferencesWindow {
|
||||
GtkCheckButton *aspect_ratio_toggle;
|
||||
GtkComboBoxText *highpass_filter_selector;
|
||||
GtkComboBoxText *sample_rate_selector;
|
||||
GtkScale *interference_volume_slider;
|
||||
GtkCheckButton *analog_speed_controls_toggle;
|
||||
GtkComboBoxText *rumble_mode_selector;
|
||||
GtkButton *configure_joypad_skip;
|
||||
@ -206,6 +207,18 @@ static void on_sample_rate_changed(GtkWidget *w, PreferencesWindow *self) {
|
||||
);
|
||||
}
|
||||
|
||||
static void on_interference_volume_changed(GtkWidget *w, PreferencesWindow *self) {
|
||||
GtkRange *range = GTK_RANGE(w);
|
||||
gdouble value = gtk_range_get_value(range);
|
||||
config.audio.interference_volume = (guint32) clamp_double(0, 255, value);
|
||||
|
||||
g_signal_emit(
|
||||
self,
|
||||
preferences_signals[PREF_UPDATE],
|
||||
g_quark_from_static_string("audio-interference-volume"),
|
||||
&config.audio.interference_volume
|
||||
);
|
||||
}
|
||||
|
||||
static void preferences_window_realize(GtkWidget *widget) {
|
||||
PreferencesWindow *self = (PreferencesWindow *)widget;
|
||||
@ -225,6 +238,7 @@ static void preferences_window_realize(GtkWidget *widget) {
|
||||
|
||||
gtk_combo_box_set_active_id(GTK_COMBO_BOX(self->highpass_filter_selector), config.audio.high_pass_filter_id);
|
||||
gtk_combo_box_set_active_id(GTK_COMBO_BOX(self->sample_rate_selector), g_strdup_printf("%i", config.audio.sample_rate));
|
||||
gtk_range_set_value(GTK_RANGE(self->interference_volume_slider), (double) config.audio.interference_volume);
|
||||
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(self->analog_speed_controls_toggle), config.controls.analog_speed_controls);
|
||||
gtk_combo_box_set_active_id(GTK_COMBO_BOX(self->rumble_mode_selector), config.controls.rumble_mode);
|
||||
@ -251,6 +265,7 @@ static void preferences_window_class_init(PreferencesWindowClass *class) {
|
||||
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PreferencesWindow, aspect_ratio_toggle);
|
||||
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PreferencesWindow, highpass_filter_selector);
|
||||
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PreferencesWindow, sample_rate_selector);
|
||||
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PreferencesWindow, interference_volume_slider);
|
||||
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PreferencesWindow, analog_speed_controls_toggle);
|
||||
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PreferencesWindow, rumble_mode_selector);
|
||||
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PreferencesWindow, configure_joypad_skip);
|
||||
@ -269,6 +284,7 @@ static void preferences_window_class_init(PreferencesWindowClass *class) {
|
||||
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_keep_aspect_ratio_changed);
|
||||
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_highpass_filter_changed);
|
||||
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_sample_rate_changed);
|
||||
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_interference_volume_changed);
|
||||
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_analog_speed_controls_changed);
|
||||
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_rumble_mode_changed);
|
||||
|
||||
|
@ -573,6 +573,8 @@ Author: Maximilian Mader
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBoxText" id="sample_rate_selector">
|
||||
<property name="margin_top">5</property>
|
||||
<property name="margin_bottom">10</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<items>
|
||||
@ -590,6 +592,35 @@ Author: Maximilian Mader
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Interference volume:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScale" id="interference_volume_slider">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="adjustment">byteAdjustment</property>
|
||||
<property name="round_digits">0</property>
|
||||
<property name="digits">0</property>
|
||||
<property name="value_pos">left</property>
|
||||
<signal name="value-changed" handler="on_interference_volume_changed" swapped="no"/>
|
||||
<signal name="format-value" handler="format_scale_value_pct" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">2</property>
|
||||
@ -976,4 +1007,10 @@ Author: Maximilian Mader
|
||||
</row>
|
||||
</data>
|
||||
</object>
|
||||
|
||||
<object class="GtkAdjustment" id="byteAdjustment">
|
||||
<property name="upper">255</property>
|
||||
<property name="step_increment">1</property>
|
||||
<property name="page_increment">8</property>
|
||||
</object>
|
||||
</interface>
|
||||
|
@ -37,7 +37,7 @@ Author: Maximilian Mader
|
||||
<property name="can_focus">False</property>
|
||||
<property name="type_hint">normal</property>
|
||||
<property name="program_name">SameBoy</property>
|
||||
<property name="copyright" translatable="yes">Copyright © 2015-2019 Lior Halphon</property>
|
||||
<property name="copyright" translatable="yes">Copyright © 2015-2021 Lior Halphon</property>
|
||||
<property name="website">https://sameboy.github.io</property>
|
||||
<property name="website_label" translatable="yes">sameboy.github.io</property>
|
||||
<property name="authors">Lior Halphon https://github.com/LIJI32
|
||||
|
11
gtk3/util.c
11
gtk3/util.c
@ -103,7 +103,7 @@ GB_model_t config_get_model_type(GuiData *gui_data) {
|
||||
GtkWidget *menubar_to_menu(GtkMenuBar *menubar) {
|
||||
GtkWidget *menu = gtk_menu_new();
|
||||
g_autoptr(GList) iter = gtk_container_get_children(GTK_CONTAINER(menubar));
|
||||
|
||||
|
||||
while (iter) {
|
||||
GtkWidget *item = GTK_WIDGET(iter->data);
|
||||
gtk_widget_reparent(item, menu);
|
||||
@ -157,3 +157,12 @@ gboolean scroll_to_bottom(GtkTextView *textview, GtkTextMark *mark) {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
gchar* format_scale_value_pct(GtkScale *scale, gdouble value) {
|
||||
GtkAdjustment *adj = gtk_range_get_adjustment(GTK_RANGE(scale));
|
||||
gdouble lower = gtk_adjustment_get_lower(adj);
|
||||
gdouble upper = gtk_adjustment_get_upper(adj);
|
||||
gdouble range = fabs(upper - lower);
|
||||
gdouble pct = (value / range) * 100.0;
|
||||
return g_strdup_printf ("%.1f%% ", pct);
|
||||
}
|
||||
|
@ -27,4 +27,6 @@ void set_combo_box_row_separator_func(GtkContainer *container);
|
||||
|
||||
gboolean scroll_to_bottom(GtkTextView *textview, GtkTextMark *mark);
|
||||
|
||||
gchar* format_scale_value_pct(GtkScale *scale, gdouble value);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user