Add a simple auto frameskip to the gtk frontend

Add a simple auto frameskip method based on effective fps
ratio (fps / 60). If the ratio is too low add more frameskip,
if the ratio is too high or we are skipping too much do
the opposite. The proposed patch that led to this one is
available in bug #2862131.
While at it shorten the number of frameskip values
available since they skip too much to be playable.
This commit is contained in:
riccardom 2009-12-28 11:15:37 +00:00
parent 559039dc38
commit ed6fd31c38
1 changed files with 36 additions and 20 deletions

View File

@ -202,16 +202,11 @@ static const char *ui_description =
" <menuitem action='micnoise'/>" " <menuitem action='micnoise'/>"
#endif #endif
" <menu action='FrameskipMenu'>" " <menu action='FrameskipMenu'>"
" <menuitem action='frameskipA'/>"
" <menuitem action='frameskip0'/>" " <menuitem action='frameskip0'/>"
" <menuitem action='frameskip1'/>" " <menuitem action='frameskip1'/>"
" <menuitem action='frameskip2'/>" " <menuitem action='frameskip2'/>"
" <menuitem action='frameskip3'/>" " <menuitem action='frameskip3'/>"
" <menuitem action='frameskip4'/>"
" <menuitem action='frameskip5'/>"
" <menuitem action='frameskip6'/>"
" <menuitem action='frameskip7'/>"
" <menuitem action='frameskip8'/>"
" <menuitem action='frameskip9'/>"
" </menu>" " </menu>"
" <menu action='LayersMenu'>" " <menu action='LayersMenu'>"
" <menuitem action='layermainbg0'/>" " <menuitem action='layermainbg0'/>"
@ -339,17 +334,20 @@ static const GtkRadioActionEntry interpolation_entries[] = {
{ "interp_bilinear", NULL, "_Bilinear", NULL, NULL, 1}, { "interp_bilinear", NULL, "_Bilinear", NULL, NULL, 1},
}; };
enum frameskip_enum {
FRAMESKIP_0 = 0,
FRAMESKIP_1 = 1,
FRAMESKIP_2 = 2,
FRAMESKIP_3 = 3,
FRAMESKIP_AUTO
};
static const GtkRadioActionEntry frameskip_entries[] = { static const GtkRadioActionEntry frameskip_entries[] = {
{ "frameskip0", NULL, "_0", NULL, NULL, 0}, { "frameskipA", NULL, "_Auto", NULL, NULL, FRAMESKIP_AUTO},
{ "frameskip1", NULL, "_1", NULL, NULL, 1}, { "frameskip0", NULL, "_0", NULL, NULL, FRAMESKIP_0},
{ "frameskip2", NULL, "_2", NULL, NULL, 2}, { "frameskip1", NULL, "_1", NULL, NULL, FRAMESKIP_1},
{ "frameskip3", NULL, "_3", NULL, NULL, 3}, { "frameskip2", NULL, "_2", NULL, NULL, FRAMESKIP_2},
{ "frameskip4", NULL, "_4", NULL, NULL, 4}, { "frameskip3", NULL, "_3", NULL, NULL, FRAMESKIP_3},
{ "frameskip5", NULL, "_5", NULL, NULL, 5},
{ "frameskip6", NULL, "_6", NULL, NULL, 6},
{ "frameskip7", NULL, "_7", NULL, NULL, 7},
{ "frameskip8", NULL, "_8", NULL, NULL, 8},
{ "frameskip9", NULL, "_9", NULL, NULL, 9},
}; };
static const GtkRadioActionEntry savet_entries[] = { static const GtkRadioActionEntry savet_entries[] = {
@ -546,6 +544,7 @@ joinThread_gdb( void *thread_handle) {
/************************ GTK *******************************/ /************************ GTK *******************************/
uint Frameskip = 0; uint Frameskip = 0;
bool autoframeskip = false;
GdkInterpType Interpolation = GDK_INTERP_BILINEAR; GdkInterpType Interpolation = GDK_INTERP_BILINEAR;
static GtkWidget *pWindow; static GtkWidget *pWindow;
@ -1564,6 +1563,7 @@ static void Modify_Interpolation(GtkAction *action, GtkRadioAction *current)
static void Modify_Frameskip(GtkAction *action, GtkRadioAction *current) static void Modify_Frameskip(GtkAction *action, GtkRadioAction *current)
{ {
Frameskip = gtk_radio_action_get_current_value(current) ; Frameskip = gtk_radio_action_get_current_value(current) ;
autoframeskip = Frameskip == FRAMESKIP_AUTO;
} }
/////////////////////////////// TOOLS MANAGEMENT /////////////////////////////// /////////////////////////////// TOOLS MANAGEMENT ///////////////////////////////
@ -1607,7 +1607,7 @@ static inline void _updateDTools()
gboolean EmuLoop(gpointer data) gboolean EmuLoop(gpointer data)
{ {
static Uint32 fps_SecStart, fps_FrameCount; static Uint32 fps_SecStart, next_fps_SecStart, fps_FrameCount, skipped_frames;
static int limiter_frame_counter; static int limiter_frame_counter;
unsigned int i; unsigned int i;
gchar Title[20]; gchar Title[20];
@ -1618,22 +1618,38 @@ gboolean EmuLoop(gpointer data)
} }
/* If desmume is currently running */ /* If desmume is currently running */
fps_FrameCount += Frameskip + 1;
if (!fps_SecStart) if (!fps_SecStart)
fps_SecStart = SDL_GetTicks(); fps_SecStart = SDL_GetTicks();
if (SDL_GetTicks() - fps_SecStart >= 1000) { /* don't count autoframeskip as real frameskip */
fps_SecStart = SDL_GetTicks(); if (Frameskip == FRAMESKIP_AUTO)
Frameskip = 0;
fps_FrameCount += Frameskip + 1;
next_fps_SecStart = SDL_GetTicks();
if ((next_fps_SecStart - fps_SecStart) >= 1000) {
fps_SecStart = next_fps_SecStart;
snprintf(Title, sizeof(Title), "Desmume - %dfps", fps_FrameCount); snprintf(Title, sizeof(Title), "Desmume - %dfps", fps_FrameCount);
gtk_window_set_title(GTK_WINDOW(pWindow), Title); gtk_window_set_title(GTK_WINDOW(pWindow), Title);
float emu_ratio = fps_FrameCount / 60.0;
if (autoframeskip) {
if (emu_ratio < 1 && (fps_FrameCount - skipped_frames) > skipped_frames)
Frameskip = MIN(Frameskip+1, FRAMESKIP_AUTO-1);
if (emu_ratio > 1 || skipped_frames >= fps_FrameCount-Frameskip)
Frameskip = Frameskip ? Frameskip-1 : 0;
}
LOG("auto: %d fps: %u skipped: %u emu_ratio: %f Frameskip: %u\n", autoframeskip, fps_FrameCount, skipped_frames, emu_ratio, Frameskip);
fps_FrameCount = 0; fps_FrameCount = 0;
skipped_frames = 0;
} }
desmume_cycle(); /* Emule ! */ desmume_cycle(); /* Emule ! */
for (i = 0; i < Frameskip; i++) { for (i = 0; i < Frameskip; i++) {
NDS_SkipNextFrame(); NDS_SkipNextFrame();
desmume_cycle(); desmume_cycle();
skipped_frames++;
} }
_updateDTools(); _updateDTools();