mirror of
https://github.com/libretro/snes9x.git
synced 2024-12-02 14:26:38 +00:00
Add automatic input rate checkbox. Use as default.
This commit is contained in:
parent
d726c6a8dd
commit
5874559a3e
@ -403,6 +403,7 @@ Snes9xConfig::save_config_file (void)
|
||||
xml_out_int (xml, "sound_sync", Settings.SoundSync);
|
||||
xml_out_int (xml, "dynamic_rate_control", Settings.DynamicRateControl);
|
||||
xml_out_int (xml, "dynamic_rate_limit", Settings.DynamicRateLimit);
|
||||
xml_out_int (xml, "auto_input_rate", auto_input_rate);
|
||||
|
||||
/* Snes9X core-stored variables */
|
||||
xml_out_int (xml, "transparency", Settings.Transparency);
|
||||
@ -667,6 +668,10 @@ Snes9xConfig::set_option (const char *name, const char *value)
|
||||
Settings.DynamicRateLimit = atoi (value);
|
||||
Settings.DynamicRateLimit = CLAMP (Settings.DynamicRateLimit, 1, 1000);
|
||||
}
|
||||
else if (!strcasecmp (name, "auto_input_rate"))
|
||||
{
|
||||
auto_input_rate = atoi (value);
|
||||
}
|
||||
else if (!strcasecmp (name, "gaussian_interpolation"))
|
||||
{
|
||||
}
|
||||
|
@ -465,66 +465,22 @@ event_input_rate_changed (GtkRange *range, gpointer data)
|
||||
return;
|
||||
}
|
||||
|
||||
static double XRRGetExactRefreshRate (Display *dpy, Window window)
|
||||
{
|
||||
XRRScreenResources *resources = NULL;
|
||||
XRROutputInfo *output_info = NULL;
|
||||
XRRCrtcInfo *crtc_info = NULL;
|
||||
RROutput output;
|
||||
int event_base;
|
||||
int error_base;
|
||||
int version_major;
|
||||
int version_minor;
|
||||
double refresh_rate = 0.0;
|
||||
int i;
|
||||
|
||||
if (!XRRQueryExtension (dpy, &event_base, &error_base) ||
|
||||
!XRRQueryVersion (dpy, &version_major, &version_minor))
|
||||
{
|
||||
return refresh_rate;
|
||||
}
|
||||
|
||||
resources = XRRGetScreenResources (dpy, window);
|
||||
output = XRRGetOutputPrimary (dpy, window);
|
||||
output_info = XRRGetOutputInfo (dpy, resources, output);
|
||||
crtc_info = XRRGetCrtcInfo (dpy, resources, output_info->crtc);
|
||||
|
||||
for (i = 0; i < resources->nmode; i++)
|
||||
{
|
||||
if (resources->modes[i].id == crtc_info->mode)
|
||||
{
|
||||
XRRModeInfo *m = &resources->modes[i];
|
||||
|
||||
refresh_rate = (double) m->dotClock / m->hTotal / m->vTotal;
|
||||
refresh_rate /= m->modeFlags & RR_DoubleScan ? 2 : 1;
|
||||
refresh_rate /= m->modeFlags & RR_ClockDivideBy2 ? 2 : 1;
|
||||
refresh_rate *= m->modeFlags & RR_DoubleClock ? 2 : 1;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
XRRFreeCrtcInfo (crtc_info);
|
||||
XRRFreeOutputInfo (output_info);
|
||||
XRRFreeScreenResources (resources);
|
||||
|
||||
return refresh_rate;
|
||||
}
|
||||
|
||||
static void
|
||||
event_set_input_rate (GtkButton *widget, gpointer data)
|
||||
void
|
||||
event_auto_input_rate_toggled (GtkToggleButton *togglebutton, gpointer data)
|
||||
{
|
||||
Snes9xPreferences *preferences = (Snes9xPreferences *) data;
|
||||
GdkWindow *gdk_window = gtk_widget_get_window (GTK_WIDGET(top_level->get_window()));
|
||||
Display *dpy = GDK_DISPLAY_XDISPLAY (gdk_window_get_display (gdk_window));
|
||||
Window window = GDK_COMPAT_WINDOW_XID (gdk_window);
|
||||
double rate = XRRGetExactRefreshRate(dpy, window);
|
||||
|
||||
if (rate != 0.0)
|
||||
preferences->set_slider("sound_input_rate", (int) (rate * 32040 / 60.09881389744051 + 0.5));
|
||||
if (gtk_toggle_button_get_active (togglebutton))
|
||||
{
|
||||
preferences->set_slider("sound_input_rate", top_level->get_auto_input_rate ());
|
||||
gtk_widget_set_sensitive (preferences->get_widget("sound_input_rate"), FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_widget_set_sensitive (preferences->get_widget("sound_input_rate"), TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
event_about_clicked (GtkButton *widget, gpointer data)
|
||||
{
|
||||
@ -620,7 +576,7 @@ Snes9xPreferences::Snes9xPreferences (Snes9xConfig *config) :
|
||||
{ "game_data_browse", G_CALLBACK (event_game_data_browse) },
|
||||
{ "game_data_clear", G_CALLBACK (event_game_data_clear) },
|
||||
{ "about_clicked", G_CALLBACK (event_about_clicked) },
|
||||
{ "set_input_rate", G_CALLBACK (event_set_input_rate) },
|
||||
{ "auto_input_rate_toggled", G_CALLBACK (event_auto_input_rate_toggled) },
|
||||
#ifdef USE_JOYSTICK
|
||||
{ "calibrate", G_CALLBACK (event_calibrate) },
|
||||
#endif
|
||||
@ -737,6 +693,9 @@ Snes9xPreferences::move_settings_to_dialog (void)
|
||||
set_spin ("num_threads", config->num_threads);
|
||||
set_check ("mute_sound_check", config->mute_sound);
|
||||
set_check ("mute_sound_turbo_check", config->mute_sound_turbo);
|
||||
set_check ("auto_input_rate", config->auto_input_rate);
|
||||
gtk_widget_set_sensitive (get_widget("sound_input_rate"),
|
||||
config->auto_input_rate ? FALSE : TRUE);
|
||||
set_spin ("sound_buffer_size", config->sound_buffer_size);
|
||||
set_slider ("sound_input_rate", config->sound_input_rate);
|
||||
set_check ("sync_sound", Settings.SoundSync);
|
||||
@ -826,16 +785,15 @@ Snes9xPreferences::get_settings_from_dialog (void)
|
||||
int sound_needs_restart = 0;
|
||||
int gfx_needs_restart = 0;
|
||||
|
||||
if ((config->sound_driver != get_combo ("sound_driver")) ||
|
||||
(config->mute_sound != get_check ("mute_sound_check")) ||
|
||||
(config->sound_buffer_size != (int) get_spin ("sound_buffer_size"))||
|
||||
(Settings.Stereo != get_check ("stereo_check")) ||
|
||||
(config->sound_playback_rate !=
|
||||
(7 - (get_combo ("playback_combo")))) ||
|
||||
(config->sound_input_rate != get_slider ("sound_input_rate")) ||
|
||||
(Settings.SoundSync != get_check ("sync_sound")) ||
|
||||
(Settings.DynamicRateControl != get_check ("dynamic_rate_control"))
|
||||
)
|
||||
if ((config->sound_driver != get_combo ("sound_driver")) ||
|
||||
(config->mute_sound != get_check ("mute_sound_check")) ||
|
||||
(config->sound_buffer_size != (int) get_spin ("sound_buffer_size")) ||
|
||||
(Settings.Stereo != get_check ("stereo_check")) ||
|
||||
(config->sound_playback_rate != (7 - (get_combo ("playback_combo")))) ||
|
||||
(config->sound_input_rate != get_slider ("sound_input_rate")) ||
|
||||
(config->auto_input_rate != get_check ("auto_input_rate")) ||
|
||||
(Settings.SoundSync != get_check ("sync_sound")) ||
|
||||
(Settings.DynamicRateControl != get_check ("dynamic_rate_control")))
|
||||
{
|
||||
sound_needs_restart = 1;
|
||||
}
|
||||
@ -889,6 +847,7 @@ Snes9xPreferences::get_settings_from_dialog (void)
|
||||
config->sound_playback_rate = 7 - (get_combo ("playback_combo"));
|
||||
config->sound_buffer_size = get_spin ("sound_buffer_size");
|
||||
config->sound_input_rate = get_slider ("sound_input_rate");
|
||||
config->auto_input_rate = get_check ("auto_input_rate");
|
||||
Settings.SoundSync = get_check ("sync_sound");
|
||||
config->mute_sound = get_check ("mute_sound_check");
|
||||
config->mute_sound_turbo = get_check ("mute_sound_turbo_check");
|
||||
|
@ -1529,6 +1529,74 @@ Snes9xWindow::toggle_fullscreen_mode (void)
|
||||
enter_fullscreen_mode ();
|
||||
}
|
||||
|
||||
static double XRRGetExactRefreshRate (Display *dpy, Window window)
|
||||
{
|
||||
XRRScreenResources *resources = NULL;
|
||||
XRROutputInfo *output_info = NULL;
|
||||
XRRCrtcInfo *crtc_info = NULL;
|
||||
RROutput output;
|
||||
int event_base;
|
||||
int error_base;
|
||||
int version_major;
|
||||
int version_minor;
|
||||
double refresh_rate = 0.0;
|
||||
int i;
|
||||
|
||||
if (!XRRQueryExtension (dpy, &event_base, &error_base) ||
|
||||
!XRRQueryVersion (dpy, &version_major, &version_minor))
|
||||
{
|
||||
return refresh_rate;
|
||||
}
|
||||
|
||||
resources = XRRGetScreenResources (dpy, window);
|
||||
output = XRRGetOutputPrimary (dpy, window);
|
||||
output_info = XRRGetOutputInfo (dpy, resources, output);
|
||||
crtc_info = XRRGetCrtcInfo (dpy, resources, output_info->crtc);
|
||||
|
||||
for (i = 0; i < resources->nmode; i++)
|
||||
{
|
||||
if (resources->modes[i].id == crtc_info->mode)
|
||||
{
|
||||
XRRModeInfo *m = &resources->modes[i];
|
||||
|
||||
refresh_rate = (double) m->dotClock / m->hTotal / m->vTotal;
|
||||
refresh_rate /= m->modeFlags & RR_DoubleScan ? 2 : 1;
|
||||
refresh_rate /= m->modeFlags & RR_ClockDivideBy2 ? 2 : 1;
|
||||
refresh_rate *= m->modeFlags & RR_DoubleClock ? 2 : 1;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
XRRFreeCrtcInfo (crtc_info);
|
||||
XRRFreeOutputInfo (output_info);
|
||||
XRRFreeScreenResources (resources);
|
||||
|
||||
return refresh_rate;
|
||||
}
|
||||
|
||||
double
|
||||
Snes9xWindow::get_refresh_rate (void)
|
||||
{
|
||||
Window xid = gdk_x11_window_get_xid(gtk_widget_get_window (window));
|
||||
Display *dpy = gdk_x11_display_get_xdisplay(gtk_widget_get_display (window));
|
||||
double refresh_rate = XRRGetExactRefreshRate (dpy, xid);
|
||||
|
||||
if (refresh_rate < 10.0)
|
||||
{
|
||||
printf ("Warning: Couldn't read refresh rate.\n");
|
||||
refresh_rate = 60.0;
|
||||
}
|
||||
|
||||
return refresh_rate;
|
||||
}
|
||||
|
||||
int
|
||||
Snes9xWindow::get_auto_input_rate (void)
|
||||
{
|
||||
return (int) (get_refresh_rate () * 32040.0 / 60.09881389744051 + 0.5);
|
||||
}
|
||||
|
||||
static void set_bypass_compositor (Display *dpy, Window window, unsigned char bypass)
|
||||
{
|
||||
Atom net_wm_bypass_compositor = XInternAtom (dpy, "_NET_WM_BYPASS_COMPOSITOR", False);
|
||||
@ -1569,6 +1637,12 @@ Snes9xWindow::enter_fullscreen_mode (void)
|
||||
{
|
||||
config->change_display_resolution = 0;
|
||||
}
|
||||
|
||||
if (gui_config->auto_input_rate)
|
||||
{
|
||||
Settings.SoundInputRate = top_level->get_auto_input_rate ();
|
||||
S9xUpdateDynamicRate (1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Make sure everything is done synchronously */
|
||||
@ -1623,6 +1697,12 @@ Snes9xWindow::leave_fullscreen_mode (void)
|
||||
config->xrr_crtc_info->rotation,
|
||||
&config->xrr_output,
|
||||
1);
|
||||
|
||||
if (gui_config->auto_input_rate)
|
||||
{
|
||||
Settings.SoundInputRate = top_level->get_auto_input_rate ();
|
||||
S9xUpdateDynamicRate (1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
gtk_window_unfullscreen (GTK_WINDOW (window));
|
||||
|
@ -61,6 +61,8 @@ class Snes9xWindow : public GtkBuilderWindow
|
||||
void resize_to_multiple (int factor);
|
||||
void resize_viewport (int width, int height);
|
||||
void expose (void);
|
||||
double get_refresh_rate (void);
|
||||
int get_auto_input_rate (void);
|
||||
|
||||
cairo_t *get_cairo (void);
|
||||
void release_cairo (void);
|
||||
|
@ -127,7 +127,14 @@ S9xPortSoundInit (void)
|
||||
{
|
||||
driver->init ();
|
||||
|
||||
Settings.SoundInputRate = CLAMP (gui_config->sound_input_rate, 8000, 48000);
|
||||
if (gui_config->auto_input_rate)
|
||||
{
|
||||
Settings.SoundInputRate = top_level->get_auto_input_rate ();
|
||||
}
|
||||
else
|
||||
{
|
||||
Settings.SoundInputRate = CLAMP (gui_config->sound_input_rate, 8000, 48000);
|
||||
}
|
||||
|
||||
Settings.SoundPlaybackRate = playback_rates[gui_config->sound_playback_rate];
|
||||
|
||||
|
@ -4047,7 +4047,22 @@
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="auto_input_rate">
|
||||
<property name="label" translatable="yes">Automatically adjust input rate to display</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="tooltip_text" translatable="yes">Sets the correct input rate based on the display's refresh rate</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="auto_input_rate_toggled" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="dynamic_rate_control">
|
||||
<property name="label" translatable="yes">Dynamic rate control</property>
|
||||
@ -4060,7 +4075,7 @@
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">2</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
@ -4077,7 +4092,7 @@
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">3</property>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
@ -4093,7 +4108,7 @@
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">4</property>
|
||||
<property name="position">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
@ -4109,7 +4124,7 @@
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">5</property>
|
||||
<property name="position">6</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
@ -4171,8 +4186,8 @@
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">4</property>
|
||||
<property name="bottom_attach">5</property>
|
||||
<property name="top_attach">3</property>
|
||||
<property name="bottom_attach">4</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options">GTK_FILL</property>
|
||||
</packing>
|
||||
@ -4185,8 +4200,8 @@
|
||||
<property name="label" translatable="yes">Buffer size:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">4</property>
|
||||
<property name="bottom_attach">5</property>
|
||||
<property name="top_attach">3</property>
|
||||
<property name="bottom_attach">4</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options">GTK_FILL</property>
|
||||
</packing>
|
||||
@ -4199,8 +4214,8 @@
|
||||
<property name="label" translatable="yes">Dynamic rate limit:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">5</property>
|
||||
<property name="bottom_attach">6</property>
|
||||
<property name="top_attach">4</property>
|
||||
<property name="bottom_attach">5</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options">GTK_FILL</property>
|
||||
</packing>
|
||||
@ -4229,8 +4244,8 @@
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">5</property>
|
||||
<property name="bottom_attach">6</property>
|
||||
<property name="top_attach">4</property>
|
||||
<property name="bottom_attach">5</property>
|
||||
<property name="y_options">GTK_FILL</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
</packing>
|
||||
@ -4243,8 +4258,8 @@
|
||||
<property name="label" translatable="yes">Input rate:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options">GTK_FILL</property>
|
||||
</packing>
|
||||
@ -4262,8 +4277,8 @@
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
<property name="y_options">GTK_FILL</property>
|
||||
</packing>
|
||||
</child>
|
||||
@ -4297,23 +4312,6 @@
|
||||
<property name="y_options">GTK_FILL</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="set_input_rate_button">
|
||||
<property name="label" translatable="yes">Automatically Set Input Rate</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<signal name="clicked" handler="set_input_rate" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options">GTK_FILL</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label139">
|
||||
<property name="visible">True</property>
|
||||
@ -4322,8 +4320,8 @@
|
||||
<property name="label" translatable="yes">Video rate:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">3</property>
|
||||
<property name="bottom_attach">4</property>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options">GTK_FILL</property>
|
||||
</packing>
|
||||
@ -4337,8 +4335,8 @@
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">3</property>
|
||||
<property name="bottom_attach">4</property>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
<property name="y_options">GTK_FILL</property>
|
||||
</packing>
|
||||
</child>
|
||||
@ -4346,7 +4344,7 @@
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">6</property>
|
||||
<property name="position">7</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
|
Loading…
Reference in New Issue
Block a user