mirror of https://github.com/snes9xgit/snes9x.git
GTK+: Clean up speed throttling.
No more frameskip selection, only 4 options: * Timer throttling to Settings.FrameRate * Same, but skips frames when late * Wait on sound buffer * Don't throttle. Dynamic rate control is automatically disabled for option 3.
This commit is contained in:
parent
7dcf6a0ce4
commit
79b1ab0250
|
@ -204,7 +204,7 @@ else
|
|||
fi
|
||||
|
||||
PKG_CHECK_MODULES([GTK], ["$GTK_VERSION"])
|
||||
PKG_CHECK_MODULES([GLIB], [gthread-2.0 >= 2.6 gobject-2.0 >= 2.6])
|
||||
PKG_CHECK_MODULES([GLIB], [glib-2.0 > 2.28 gthread-2.0 >= 2.6 gobject-2.0 >= 2.6])
|
||||
PKG_CHECK_MODULES([LIBXML], [libxml-2.0 >= 2.0])
|
||||
PKG_CHECK_MODULES([XRANDR], [xrandr])
|
||||
|
||||
|
|
|
@ -413,7 +413,6 @@ Snes9xConfig::save_config_file (void)
|
|||
xml_out_int (xml, "sound_buffer_size", sound_buffer_size);
|
||||
xml_out_int (xml, "sound_driver", sound_driver);
|
||||
xml_out_int (xml, "sound_input_rate", sound_input_rate);
|
||||
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);
|
||||
|
@ -653,6 +652,8 @@ Snes9xConfig::set_option (const char *name, const char *value)
|
|||
else if (!strcasecmp (name, "frameskip"))
|
||||
{
|
||||
Settings.SkipFrames = atoi (value);
|
||||
if (Settings.SkipFrames == THROTTLE_SOUND_SYNC)
|
||||
Settings.SoundSync = 1;
|
||||
}
|
||||
else if (!strcasecmp (name, "sound_emulation"))
|
||||
{
|
||||
|
@ -918,10 +919,6 @@ Snes9xConfig::set_option (const char *name, const char *value)
|
|||
{
|
||||
Settings.UpAndDown = CLAMP (atoi (value), 0, 1);
|
||||
}
|
||||
else if (!strcasecmp (name, "sound_sync"))
|
||||
{
|
||||
Settings.SoundSync = atoi (value) ? 1 : 0;
|
||||
}
|
||||
else if (!strcasecmp (name, "rewind_buffer_size"))
|
||||
{
|
||||
rewind_buffer_size = CLAMP (atoi (value), 0, 2000);
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#ifndef __GTK_CONFIG_H
|
||||
#define __GTK_CONFIG_H
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <libxml/parser.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/Xrandr.h>
|
||||
|
@ -9,17 +8,30 @@
|
|||
#include "gtk_control.h"
|
||||
#include "snes_ntsc.h"
|
||||
|
||||
#define HWA_NONE 0
|
||||
#define HWA_OPENGL 1
|
||||
#define HWA_XV 2
|
||||
enum {
|
||||
HWA_NONE = 0,
|
||||
HWA_OPENGL = 1,
|
||||
HWA_XV = 2
|
||||
};
|
||||
|
||||
#define HIRES_MERGE 0
|
||||
#define HIRES_NORMAL 1
|
||||
#define HIRES_SCALE 2
|
||||
enum {
|
||||
HIRES_MERGE = 0,
|
||||
HIRES_NORMAL = 1,
|
||||
HIRES_SCALE = 2
|
||||
};
|
||||
|
||||
#define ESC_TOGGLE_MENUBAR 0
|
||||
#define ESC_EXIT_FULLSCREEN 1
|
||||
#define ESC_EXIT_SNES9X 2
|
||||
enum {
|
||||
ESC_TOGGLE_MENUBAR = 0,
|
||||
ESC_EXIT_FULLSCREEN = 1,
|
||||
ESC_EXIT_SNES9X = 2
|
||||
};
|
||||
|
||||
enum {
|
||||
THROTTLE_TIMER = 0,
|
||||
THROTTLE_TIMER_FRAMESKIP = 1,
|
||||
THROTTLE_SOUND_SYNC = 2,
|
||||
THROTTLE_NONE = 3
|
||||
};
|
||||
|
||||
class Snes9xConfig
|
||||
{
|
||||
|
@ -128,11 +140,11 @@ class Snes9xConfig
|
|||
unsigned char screensaver_needs_reset;
|
||||
int modal_dialogs;
|
||||
|
||||
int pointer_is_visible;
|
||||
struct timeval pointer_timestamp;
|
||||
|
||||
unsigned int rewind_granularity;
|
||||
unsigned int rewind_buffer_size;
|
||||
int pointer_is_visible;
|
||||
gint64 pointer_timestamp;
|
||||
|
||||
unsigned int rewind_granularity;
|
||||
unsigned int rewind_buffer_size;
|
||||
|
||||
XRRScreenResources *xrr_screen_resources;
|
||||
XRRCrtcInfo *xrr_crtc_info;
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
#include <gtk/gtk.h>
|
||||
#include <libxml/parser.h>
|
||||
#include <libxml/tree.h>
|
||||
#include <dlfcn.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
|
|
@ -361,6 +361,23 @@ event_hw_accel_changed (GtkComboBox *widget, gpointer data)
|
|||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
event_frameskip_combo_changed (GtkComboBox *widget, gpointer user_data)
|
||||
{
|
||||
Snes9xPreferences *window = (Snes9xPreferences *) user_data;
|
||||
|
||||
if (window->get_combo ("frameskip_combo") == THROTTLE_SOUND_SYNC)
|
||||
{
|
||||
window->set_check ("dynamic_rate_control", 0);
|
||||
window->enable_widget ("dynamic_rate_control", 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
window->enable_widget ("dynamic_rate_control", 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
event_scale_method_changed (GtkComboBox *widget, gpointer user_data)
|
||||
{
|
||||
|
@ -584,6 +601,7 @@ Snes9xPreferences::Snes9xPreferences (Snes9xConfig *config) :
|
|||
{ "game_data_clear", G_CALLBACK (event_game_data_clear) },
|
||||
{ "about_clicked", G_CALLBACK (event_about_clicked) },
|
||||
{ "auto_input_rate_toggled", G_CALLBACK (event_auto_input_rate_toggled) },
|
||||
{ "frameskip_combo_changed", G_CALLBACK (event_frameskip_combo_changed) },
|
||||
#ifdef USE_JOYSTICK
|
||||
{ "calibrate", G_CALLBACK (event_calibrate) },
|
||||
#endif
|
||||
|
@ -711,7 +729,8 @@ Snes9xPreferences::move_settings_to_dialog (void)
|
|||
config->auto_input_rate ? FALSE : TRUE);
|
||||
set_spin ("sound_buffer_size", config->sound_buffer_size);
|
||||
|
||||
set_check ("sync_sound", Settings.SoundSync);
|
||||
if (Settings.SkipFrames == THROTTLE_SOUND_SYNC)
|
||||
Settings.DynamicRateControl = 0;
|
||||
set_check ("dynamic_rate_control", Settings.DynamicRateControl);
|
||||
set_spin ("dynamic_rate_limit", Settings.DynamicRateLimit / 1000.0);
|
||||
set_spin ("rewind_buffer_size", config->rewind_buffer_size);
|
||||
|
@ -762,9 +781,8 @@ Snes9xPreferences::move_settings_to_dialog (void)
|
|||
set_combo ("ntsc_scanline_intensity", config->ntsc_scanline_intensity);
|
||||
set_combo ("scanline_filter_intensity", config->scanline_filter_intensity);
|
||||
|
||||
set_combo ("frameskip_combo",
|
||||
Settings.SkipFrames == AUTO_FRAMERATE ?
|
||||
0 : Settings.SkipFrames + 1);
|
||||
set_combo ("frameskip_combo", Settings.SkipFrames);
|
||||
enable_widget ("dynamic_rate_control", Settings.SkipFrames != THROTTLE_SOUND_SYNC);
|
||||
set_check ("bilinear_filter", Settings.BilinearFilter);
|
||||
|
||||
#ifdef USE_OPENGL
|
||||
|
@ -806,6 +824,11 @@ Snes9xPreferences::get_settings_from_dialog (void)
|
|||
{
|
||||
int sound_needs_restart = 0;
|
||||
int gfx_needs_restart = 0;
|
||||
int sound_sync = 0;
|
||||
|
||||
Settings.SkipFrames = get_combo ("frameskip_combo");
|
||||
if (Settings.SkipFrames == THROTTLE_SOUND_SYNC)
|
||||
sound_sync = 1;
|
||||
|
||||
if ((config->sound_driver != get_combo ("sound_driver")) ||
|
||||
(config->mute_sound != get_check ("mute_sound_check")) ||
|
||||
|
@ -814,7 +837,7 @@ Snes9xPreferences::get_settings_from_dialog (void)
|
|||
(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.SoundSync != sound_sync) ||
|
||||
(Settings.DynamicRateControl != get_check ("dynamic_rate_control")))
|
||||
{
|
||||
sound_needs_restart = 1;
|
||||
|
@ -858,7 +881,6 @@ Snes9xPreferences::get_settings_from_dialog (void)
|
|||
Settings.AutoSaveDelay = get_entry_value ("save_sram_after_sec");
|
||||
config->multithreading = get_check ("multithreading");
|
||||
config->pause_emulation_on_switch = get_check ("pause_emulation_on_switch");
|
||||
Settings.SkipFrames = get_combo ("frameskip_combo");
|
||||
Settings.BlockInvalidVRAMAccessMaster = get_check ("block_invalid_vram_access");
|
||||
Settings.UpAndDown = get_check ("upanddown");
|
||||
Settings.SuperFXClockMultiplier = get_spin ("superfx_multiplier");
|
||||
|
@ -868,7 +890,7 @@ Snes9xPreferences::get_settings_from_dialog (void)
|
|||
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");
|
||||
Settings.SoundSync = sound_sync;
|
||||
config->mute_sound = get_check ("mute_sound_check");
|
||||
config->mute_sound_turbo = get_check ("mute_sound_turbo_check");
|
||||
Settings.DynamicRateControl = get_check ("dynamic_rate_control");
|
||||
|
@ -988,11 +1010,6 @@ Snes9xPreferences::get_settings_from_dialog (void)
|
|||
strncpy (config->sram_directory, safety_sram_directory, PATH_MAX);
|
||||
}
|
||||
|
||||
if (Settings.SkipFrames == 0)
|
||||
Settings.SkipFrames = AUTO_FRAMERATE;
|
||||
else
|
||||
Settings.SkipFrames--;
|
||||
|
||||
memcpy (config->pad, pad, (sizeof (JoypadBinding)) * NUM_JOYPADS);
|
||||
memcpy (config->shortcut, shortcut, (sizeof (Binding)) * NUM_EMU_LINKS);
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
#include <signal.h>
|
||||
#include <gdk/gdk.h>
|
||||
#ifdef GDK_WINDOWING_X11
|
||||
|
@ -17,33 +16,26 @@
|
|||
#include "gtk_netplay.h"
|
||||
#endif
|
||||
|
||||
#define IDLE_FUNC_PRIORITY (G_PRIORITY_DEFAULT_IDLE)
|
||||
|
||||
void S9xPostRomInit (void);
|
||||
void S9xSyncSpeedFinish (void);
|
||||
static void S9xCheckPointerTimer (void);
|
||||
void S9xPostRomInit ();
|
||||
static void S9xThrottle ();
|
||||
static void S9xCheckPointerTimer ();
|
||||
static gboolean S9xIdleFunc (gpointer data);
|
||||
static gboolean S9xScreenSaverCheckFunc (gpointer data);
|
||||
|
||||
Snes9xWindow *top_level;
|
||||
Snes9xConfig *gui_config;
|
||||
StateManager stateMan;
|
||||
static struct timeval next_frame_time = { 0, 0 };
|
||||
static struct timeval now;
|
||||
static int needs_fullscreening = FALSE;
|
||||
int syncing;
|
||||
guint idle_func_id;
|
||||
Snes9xWindow *top_level;
|
||||
Snes9xConfig *gui_config;
|
||||
StateManager state_manager;
|
||||
static int needs_fullscreening = FALSE;
|
||||
guint idle_func_id;
|
||||
gint64 frame_clock = -1;
|
||||
gint64 pointer_timestamp = -1;
|
||||
|
||||
void
|
||||
S9xTerm (int signal)
|
||||
void S9xTerm (int signal)
|
||||
{
|
||||
S9xExit ();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
struct sigaction sig_callback;
|
||||
|
||||
|
@ -118,8 +110,7 @@ main (int argc, char *argv[])
|
|||
top_level->update_accels ();
|
||||
|
||||
Settings.Paused = TRUE;
|
||||
syncing = 0;
|
||||
idle_func_id = g_idle_add_full (IDLE_FUNC_PRIORITY,
|
||||
idle_func_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
|
||||
S9xIdleFunc,
|
||||
NULL,
|
||||
NULL);
|
||||
|
@ -160,8 +151,7 @@ main (int argc, char *argv[])
|
|||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
S9xOpenROM (const char *rom_filename)
|
||||
int S9xOpenROM (const char *rom_filename)
|
||||
{
|
||||
uint32 flags;
|
||||
bool8 loaded;
|
||||
|
@ -237,7 +227,7 @@ S9xOpenROM (const char *rom_filename)
|
|||
|
||||
CPU.Flags = flags;
|
||||
|
||||
if (stateMan.init (gui_config->rewind_buffer_size * 1024 * 1024))
|
||||
if (state_manager.init (gui_config->rewind_buffer_size * 1024 * 1024))
|
||||
{
|
||||
printf ("Using rewind buffer of %uMB\n", gui_config->rewind_buffer_size);
|
||||
}
|
||||
|
@ -247,8 +237,7 @@ S9xOpenROM (const char *rom_filename)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
S9xROMLoaded (void)
|
||||
void S9xROMLoaded ()
|
||||
{
|
||||
gui_config->rom_loaded = TRUE;
|
||||
top_level->configure_widgets ();
|
||||
|
@ -260,40 +249,18 @@ S9xROMLoaded (void)
|
|||
}
|
||||
|
||||
S9xSoundStart ();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
S9xNoROMLoaded (void)
|
||||
void S9xNoROMLoaded ()
|
||||
{
|
||||
S9xSoundStop ();
|
||||
gui_config->rom_loaded = FALSE;
|
||||
S9xDisplayRefresh (-1, -1);
|
||||
top_level->configure_widgets ();
|
||||
top_level->update_statusbar ();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
static inline void check_messages (void)
|
||||
{
|
||||
static unsigned int current_timeout = 0;
|
||||
|
||||
if (GFX.InfoStringTimeout > current_timeout)
|
||||
{
|
||||
top_level->show_status_message (GFX.InfoString);
|
||||
}
|
||||
|
||||
current_timeout = GFX.InfoStringTimeout;
|
||||
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
gboolean
|
||||
S9xPauseFunc (gpointer data)
|
||||
gboolean S9xPauseFunc (gpointer data)
|
||||
{
|
||||
S9xProcessEvents (TRUE);
|
||||
|
||||
|
@ -325,7 +292,7 @@ S9xPauseFunc (gpointer data)
|
|||
#endif
|
||||
|
||||
/* Resume high-performance callback */
|
||||
idle_func_id = g_idle_add_full (IDLE_FUNC_PRIORITY,
|
||||
idle_func_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
|
||||
S9xIdleFunc,
|
||||
NULL,
|
||||
NULL);
|
||||
|
@ -336,8 +303,7 @@ S9xPauseFunc (gpointer data)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
S9xIdleFunc (gpointer data)
|
||||
gboolean S9xIdleFunc (gpointer data)
|
||||
{
|
||||
if (needs_fullscreening)
|
||||
{
|
||||
|
@ -367,11 +333,8 @@ S9xIdleFunc (gpointer data)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if (syncing)
|
||||
S9xSyncSpeedFinish ();
|
||||
|
||||
S9xCheckPointerTimer ();
|
||||
|
||||
S9xThrottle ();
|
||||
S9xProcessEvents (TRUE);
|
||||
|
||||
#ifdef NETPLAY_SUPPORT
|
||||
|
@ -385,13 +348,13 @@ S9xIdleFunc (gpointer data)
|
|||
for (int i = 0; i < 8; i++)
|
||||
joypads[i] = MovieGetJoypad(i);
|
||||
|
||||
Settings.Rewinding = stateMan.pop();
|
||||
Settings.Rewinding = state_manager.pop();
|
||||
|
||||
for (int i = 0; i < 8; i++)
|
||||
MovieSetJoypad (i, joypads[i]);
|
||||
}
|
||||
else if(IPPU.TotalEmulatedFrames % gui_config->rewind_granularity == 0)
|
||||
stateMan.push();
|
||||
state_manager.push();
|
||||
|
||||
static int muted_from_turbo = FALSE;
|
||||
static int mute_saved_state = FALSE;
|
||||
|
@ -419,8 +382,7 @@ S9xIdleFunc (gpointer data)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
S9xScreenSaverCheckFunc (gpointer data)
|
||||
gboolean S9xScreenSaverCheckFunc (gpointer data)
|
||||
{
|
||||
|
||||
if (!Settings.Paused &&
|
||||
|
@ -432,18 +394,12 @@ S9xScreenSaverCheckFunc (gpointer data)
|
|||
}
|
||||
|
||||
/* Snes9x core hooks */
|
||||
void
|
||||
S9xMessage (int type, int number, const char *message)
|
||||
void S9xMessage (int type, int number, const char *message)
|
||||
{
|
||||
/*
|
||||
fprintf (stderr, "%s\n", message);
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
/* Varies from ParseArgs because this one is for the OS port to handle */
|
||||
void
|
||||
S9xParseArg (char **argv, int &i, int argc)
|
||||
void S9xParseArg (char **argv, int &i, int argc)
|
||||
{
|
||||
if (!strcasecmp (argv[i], "-filter"))
|
||||
{
|
||||
|
@ -511,106 +467,33 @@ S9xParseArg (char **argv, int &i, int argc)
|
|||
{
|
||||
gui_config->mute_sound = TRUE;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#undef TIMER_DIFF
|
||||
#define TIMER_DIFF(a, b) ((((a).tv_sec - (b).tv_sec) * 1000000) + (a).tv_usec - (b).tv_usec)
|
||||
/* Finishes syncing by using more accurate system sleep functions*/
|
||||
void
|
||||
S9xSyncSpeedFinish (void)
|
||||
static void S9xThrottle ()
|
||||
{
|
||||
if (!syncing)
|
||||
return;
|
||||
|
||||
gettimeofday (&now, NULL);
|
||||
|
||||
if (Settings.SoundSync && !Settings.DynamicRateControl)
|
||||
{
|
||||
while (!S9xSyncSound ())
|
||||
{
|
||||
usleep (100);
|
||||
|
||||
gettimeofday (&next_frame_time, NULL);
|
||||
|
||||
/* If we can't sync sound within a second, we're probably deadlocked */
|
||||
if (TIMER_DIFF (next_frame_time, now) > 1000000)
|
||||
{
|
||||
/* Flush out our sample buffer and give up. */
|
||||
S9xClearSamples ();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
next_frame_time = now;
|
||||
return;
|
||||
}
|
||||
|
||||
if (TIMER_DIFF (next_frame_time, now) < -500000)
|
||||
{
|
||||
next_frame_time = now;
|
||||
}
|
||||
|
||||
while (timercmp (&next_frame_time, &now, >))
|
||||
{
|
||||
int time_left = TIMER_DIFF (next_frame_time, now);
|
||||
|
||||
if (time_left > 500000)
|
||||
{
|
||||
next_frame_time = now;
|
||||
break;
|
||||
}
|
||||
|
||||
usleep (time_left);
|
||||
|
||||
gettimeofday (&now, NULL);
|
||||
}
|
||||
|
||||
next_frame_time.tv_usec += Settings.FrameTime;
|
||||
|
||||
if (next_frame_time.tv_usec >= 1000000)
|
||||
{
|
||||
next_frame_time.tv_sec += next_frame_time.tv_usec / 1000000;
|
||||
next_frame_time.tv_usec %= 1000000;
|
||||
}
|
||||
|
||||
syncing = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* SyncSpeed Handles delays between frames, similar to unix.cpp version,
|
||||
* cleaned up for clarity, adjusted for GUI event loop */
|
||||
void
|
||||
S9xSyncSpeed (void)
|
||||
{
|
||||
unsigned int limit;
|
||||
int lag;
|
||||
gint64 now;
|
||||
|
||||
#ifdef NETPLAY_SUPPORT
|
||||
if (S9xNetplaySyncSpeed ())
|
||||
return;
|
||||
#endif
|
||||
|
||||
now = g_get_monotonic_time ();
|
||||
|
||||
if (Settings.HighSpeedSeek > 0)
|
||||
{
|
||||
Settings.HighSpeedSeek--;
|
||||
IPPU.RenderThisFrame = FALSE;
|
||||
IPPU.SkippedFrames = 0;
|
||||
|
||||
gettimeofday (&now, NULL);
|
||||
next_frame_time = now;
|
||||
|
||||
syncing = 0;
|
||||
frame_clock = now;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
else if (Settings.TurboMode)
|
||||
if (Settings.TurboMode)
|
||||
{
|
||||
if ((++IPPU.FrameSkip >= Settings.TurboSkipFrames)
|
||||
IPPU.FrameSkip++;
|
||||
if ((IPPU.FrameSkip >= Settings.TurboSkipFrames)
|
||||
&& !Settings.HighSpeedSeek)
|
||||
{
|
||||
IPPU.FrameSkip = 0;
|
||||
|
@ -623,84 +506,93 @@ S9xSyncSpeed (void)
|
|||
IPPU.RenderThisFrame = FALSE;
|
||||
}
|
||||
|
||||
frame_clock = now;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
gettimeofday (&now, NULL);
|
||||
IPPU.RenderThisFrame = TRUE;
|
||||
|
||||
if (next_frame_time.tv_sec == 0)
|
||||
if (now - frame_clock > 500000)
|
||||
{
|
||||
next_frame_time = now;
|
||||
++next_frame_time.tv_usec;
|
||||
frame_clock = now;
|
||||
}
|
||||
|
||||
if (Settings.SkipFrames == AUTO_FRAMERATE && (!Settings.SoundSync || Settings.DynamicRateControl))
|
||||
if (Settings.SkipFrames == THROTTLE_SOUND_SYNC &&
|
||||
!Settings.DynamicRateControl)
|
||||
{
|
||||
lag = TIMER_DIFF (now, next_frame_time);
|
||||
|
||||
/* We compensate for the frame time by a frame in case it's just a CPU
|
||||
* discrepancy. We can recover lost time in the next frame anyway. */
|
||||
if (lag > (int) (Settings.FrameTime))
|
||||
while (!S9xSyncSound ())
|
||||
{
|
||||
if (lag > (int) Settings.FrameTime * 10)
|
||||
usleep (100);
|
||||
|
||||
/* If we can't sync sound within a half-second, we're probably deadlocked */
|
||||
if (g_get_monotonic_time () - now > 500000)
|
||||
{
|
||||
/* Running way too slowly */
|
||||
next_frame_time = now;
|
||||
IPPU.RenderThisFrame = 1;
|
||||
IPPU.SkippedFrames = 0;
|
||||
S9xClearSamples ();
|
||||
break;
|
||||
}
|
||||
else
|
||||
}
|
||||
|
||||
frame_clock = now;
|
||||
IPPU.SkippedFrames = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
else if (Settings.SkipFrames == THROTTLE_NONE)
|
||||
{
|
||||
frame_clock = now;
|
||||
}
|
||||
else // THROTTLE_TIMER or THROTTLE_TIMER_FRAMESKIP
|
||||
{
|
||||
if (Settings.SkipFrames == THROTTLE_TIMER_FRAMESKIP)
|
||||
{
|
||||
if (now - frame_clock > Settings.FrameTime)
|
||||
{
|
||||
IPPU.RenderThisFrame = 0;
|
||||
IPPU.SkippedFrames++;
|
||||
|
||||
if (IPPU.SkippedFrames < 8)
|
||||
{
|
||||
IPPU.RenderThisFrame = FALSE;
|
||||
frame_clock += Settings.FrameTime;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
frame_clock = now - Settings.FrameTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
while (now - frame_clock < Settings.FrameTime)
|
||||
{
|
||||
IPPU.RenderThisFrame = 1;
|
||||
IPPU.SkippedFrames = 0;
|
||||
usleep (100);
|
||||
now = g_get_monotonic_time ();
|
||||
}
|
||||
|
||||
frame_clock += Settings.FrameTime;
|
||||
IPPU.FrameSkip = 0;
|
||||
IPPU.SkippedFrames = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
limit = (Settings.SoundSync && !Settings.DynamicRateControl) ? 1 : Settings.SkipFrames + 1;
|
||||
|
||||
IPPU.SkippedFrames++;
|
||||
IPPU.RenderThisFrame = 0;
|
||||
|
||||
if (IPPU.SkippedFrames >= limit)
|
||||
{
|
||||
IPPU.RenderThisFrame = 1;
|
||||
IPPU.SkippedFrames = 0;
|
||||
}
|
||||
}
|
||||
|
||||
syncing = 1;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
S9xCheckPointerTimer (void)
|
||||
void S9xSyncSpeed ()
|
||||
{
|
||||
}
|
||||
|
||||
static void S9xCheckPointerTimer ()
|
||||
{
|
||||
if (!gui_config->pointer_is_visible)
|
||||
return;
|
||||
|
||||
gettimeofday (&now, NULL);
|
||||
|
||||
if (TIMER_DIFF (now, gui_config->pointer_timestamp) > 1000000)
|
||||
if (g_get_monotonic_time () - gui_config->pointer_timestamp > 1000000)
|
||||
{
|
||||
top_level->hide_mouse_cursor ();
|
||||
gui_config->pointer_is_visible = FALSE;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Final exit point, issues exit (0) */
|
||||
void
|
||||
S9xExit (void)
|
||||
void S9xExit ()
|
||||
{
|
||||
gui_config->save_config_file ();
|
||||
|
||||
|
@ -726,8 +618,6 @@ S9xExit (void)
|
|||
delete gui_config;
|
||||
|
||||
exit (0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -808,18 +698,14 @@ S9xPostRomInit (void)
|
|||
case 0x0A: break; //Barcode Battler
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const char *
|
||||
S9xStringInput(const char *message)
|
||||
const char *S9xStringInput(const char *message)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
S9xExtraUsage (void)
|
||||
void S9xExtraUsage ()
|
||||
{
|
||||
printf ("GTK port options:\n"
|
||||
"-filter [option] Use a filter to scale the image.\n"
|
||||
|
@ -827,5 +713,4 @@ S9xExtraUsage (void)
|
|||
" super2xsai hq2x hq3x hq4x 2xbrz 3xbrz 4xbrz epx ntsc\n"
|
||||
"\n"
|
||||
"-mutesound Disables sound output.\n");
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -30,8 +30,8 @@
|
|||
#define bind_textdomain_codeset(Domain,Codeset) (Codeset)
|
||||
#endif /* ENABLE_NLS */
|
||||
|
||||
#define SNES9X_GTK_AUTHORS "(c) 2007 - 2017 Brandon Wright (bearoso@gmail.com)"
|
||||
#define SNES9X_GTK_VERSION "85"
|
||||
#define SNES9X_GTK_AUTHORS "(c) 2007 - 2018 Brandon Wright (bearoso@gmail.com)"
|
||||
#define SNES9X_GTK_VERSION "86"
|
||||
|
||||
extern Snes9xWindow *top_level;
|
||||
extern Snes9xConfig *gui_config;
|
||||
|
@ -46,7 +46,7 @@ extern Snes9xConfig *gui_config;
|
|||
#endif
|
||||
|
||||
int S9xOpenROM (const char *filename);
|
||||
void S9xNoROMLoaded (void);
|
||||
void S9xROMLoaded (void);
|
||||
void S9xNoROMLoaded ();
|
||||
void S9xROMLoaded ();
|
||||
|
||||
#endif /* __GTK_S9X_H */
|
||||
|
|
|
@ -259,7 +259,7 @@ event_motion_notify (GtkWidget *widget,
|
|||
window->show_mouse_cursor ();
|
||||
}
|
||||
|
||||
gettimeofday (&(window->config->pointer_timestamp), NULL);
|
||||
window->config->pointer_timestamp = g_get_monotonic_time ();
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
@ -1052,37 +1052,16 @@
|
|||
</columns>
|
||||
<data>
|
||||
<row>
|
||||
<col id="0" translatable="yes">Automatic</col>
|
||||
<col id="0" translatable="yes">Timer-based</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">0</col>
|
||||
<col id="0" translatable="yes">Timer-based with automatic frame-skipping</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">1</col>
|
||||
<col id="0" translatable="yes">Sound buffer synchronization</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">2</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">3</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">4</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">5</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">6</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">7</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">8</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">9</col>
|
||||
<col id="0" translatable="yes">No throttling, but can use vsync to control speed</col>
|
||||
</row>
|
||||
</data>
|
||||
</object>
|
||||
|
@ -4135,21 +4114,6 @@
|
|||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="sync_sound">
|
||||
<property name="label" translatable="yes">Synchronize with sound</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="tooltip_text" translatable="yes">Base emulation speed on the rate sound is output</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<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>
|
||||
|
@ -4163,7 +4127,7 @@
|
|||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">2</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -4172,13 +4136,13 @@
|
|||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="tooltip_text" translatable="yes">Smoothes out slight hiccups in sound input rate</property>
|
||||
<property name="tooltip_text" translatable="yes">Smoothes out slight hiccups in sound input rate (can't be used with sound buffer synchronization)</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">3</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
|
@ -4195,7 +4159,7 @@
|
|||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">4</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -4211,7 +4175,7 @@
|
|||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">5</property>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -4227,7 +4191,7 @@
|
|||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">6</property>
|
||||
<property name="position">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -4447,7 +4411,7 @@
|
|||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">7</property>
|
||||
<property name="position">6</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
|
@ -4550,7 +4514,7 @@
|
|||
<object class="GtkLabel" id="label45">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Frameskip:</property>
|
||||
<property name="label" translatable="yes">Speed throttle:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
|
@ -4563,6 +4527,7 @@
|
|||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="model">liststore5</property>
|
||||
<signal name="changed" handler="frameskip_combo_changed" swapped="no"/>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="cellrenderertext5"/>
|
||||
<attributes>
|
||||
|
|
Loading…
Reference in New Issue