cli: better FPS limiting
Simplify and make the fps limit behave better. From: Thomas Jones <thomas.jones@utoronto.ca> [rm: remove fps_limiter_frame_period now unused and fixup whitespace]
This commit is contained in:
parent
9d0c383e93
commit
18349689c8
|
@ -71,8 +71,7 @@ static float nds_screen_size_ratio = 1.0f;
|
||||||
#define NUM_FRAMES_TO_TIME 60
|
#define NUM_FRAMES_TO_TIME 60
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define FPS_LIMITER_FPS 60
|
||||||
#define FPS_LIMITER_FRAME_PERIOD 8
|
|
||||||
|
|
||||||
static SDL_Surface * surface;
|
static SDL_Surface * surface;
|
||||||
|
|
||||||
|
@ -129,7 +128,6 @@ class configured_features : public CommandLine
|
||||||
public:
|
public:
|
||||||
int auto_pause;
|
int auto_pause;
|
||||||
int frameskip;
|
int frameskip;
|
||||||
int fps_limiter_frame_period;
|
|
||||||
|
|
||||||
int engine_3d;
|
int engine_3d;
|
||||||
int savetype;
|
int savetype;
|
||||||
|
@ -147,7 +145,6 @@ init_config( class configured_features *config) {
|
||||||
|
|
||||||
config->auto_pause = 0;
|
config->auto_pause = 0;
|
||||||
config->frameskip = 0;
|
config->frameskip = 0;
|
||||||
config->fps_limiter_frame_period = FPS_LIMITER_FRAME_PERIOD;
|
|
||||||
|
|
||||||
config->engine_3d = 1;
|
config->engine_3d = 1;
|
||||||
config->savetype = 0;
|
config->savetype = 0;
|
||||||
|
@ -168,7 +165,6 @@ fill_config( class configured_features *config,
|
||||||
GOptionEntry options[] = {
|
GOptionEntry options[] = {
|
||||||
{ "auto-pause", 0, 0, G_OPTION_ARG_NONE, &config->auto_pause, "Pause emulation if focus is lost", NULL},
|
{ "auto-pause", 0, 0, G_OPTION_ARG_NONE, &config->auto_pause, "Pause emulation if focus is lost", NULL},
|
||||||
{ "frameskip", 0, 0, G_OPTION_ARG_INT, &config->frameskip, "Set frameskip", "FRAMESKIP"},
|
{ "frameskip", 0, 0, G_OPTION_ARG_INT, &config->frameskip, "Set frameskip", "FRAMESKIP"},
|
||||||
{ "limiter-period", 0, 0, G_OPTION_ARG_INT, &config->fps_limiter_frame_period, "Set frame period of the fps limiter", "LIMITER"},
|
|
||||||
{ "3d-engine", 0, 0, G_OPTION_ARG_INT, &config->engine_3d, "Select 3d rendering engine. Available engines:\n"
|
{ "3d-engine", 0, 0, G_OPTION_ARG_INT, &config->engine_3d, "Select 3d rendering engine. Available engines:\n"
|
||||||
"\t\t\t\t\t\t 0 = 3d disabled\n"
|
"\t\t\t\t\t\t 0 = 3d disabled\n"
|
||||||
"\t\t\t\t\t\t 1 = internal rasterizer (default)\n"
|
"\t\t\t\t\t\t 1 = internal rasterizer (default)\n"
|
||||||
|
@ -225,11 +221,6 @@ fill_config( class configured_features *config,
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config->fps_limiter_frame_period < 0 || config->fps_limiter_frame_period > 30) {
|
|
||||||
g_printerr("FPS limiter period must be >= 0 and <= 30.\n");
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config->nds_file == "") {
|
if (config->nds_file == "") {
|
||||||
g_printerr("Need to specify file to load.\n");
|
g_printerr("Need to specify file to load.\n");
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -275,30 +266,6 @@ joinThread_gdb( void *thread_handle) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A SDL timer callback function. Signals the supplied SDL semaphore
|
|
||||||
* if its value is small.
|
|
||||||
*
|
|
||||||
* @param interval The interval since the last call (in ms)
|
|
||||||
* @param param The pointer to the semaphore.
|
|
||||||
*
|
|
||||||
* @return The interval to the next call (required by SDL)
|
|
||||||
*/
|
|
||||||
static Uint32
|
|
||||||
fps_limiter_fn( Uint32 interval, void *param) {
|
|
||||||
SDL_sem *sdl_semaphore = (SDL_sem *)param;
|
|
||||||
|
|
||||||
/* signal the semaphore if it is getting low */
|
|
||||||
if ( SDL_SemValue( sdl_semaphore) < 4) {
|
|
||||||
SDL_SemPost( sdl_semaphore);
|
|
||||||
}
|
|
||||||
|
|
||||||
return interval;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef INCLUDE_OPENGL_2D
|
#ifdef INCLUDE_OPENGL_2D
|
||||||
/* initialization openGL function */
|
/* initialization openGL function */
|
||||||
static int
|
static int
|
||||||
|
@ -518,8 +485,7 @@ int main(int argc, char ** argv) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int limiter_frame_counter = 0;
|
int limiter_frame_counter = 0;
|
||||||
SDL_sem *fps_limiter_semaphore = NULL;
|
int limiter_tick0 = 0;
|
||||||
SDL_TimerID limiter_timer = NULL;
|
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
GKeyFile *keyfile;
|
GKeyFile *keyfile;
|
||||||
|
@ -726,27 +692,6 @@ int main(int argc, char ** argv) {
|
||||||
/* Since gtk has a different mapping the keys stop to work with the saved configuration :| */
|
/* Since gtk has a different mapping the keys stop to work with the saved configuration :| */
|
||||||
load_default_config(cli_kb_cfg);
|
load_default_config(cli_kb_cfg);
|
||||||
|
|
||||||
if ( !my_config.disable_limiter) {
|
|
||||||
/* create the semaphore used for fps limiting */
|
|
||||||
fps_limiter_semaphore = SDL_CreateSemaphore( 1);
|
|
||||||
|
|
||||||
/* start a SDL timer for every FPS_LIMITER_FRAME_PERIOD frames to keep us at 60 fps */
|
|
||||||
if ( fps_limiter_semaphore != NULL) {
|
|
||||||
limiter_timer = SDL_AddTimer( 16 * my_config.fps_limiter_frame_period,
|
|
||||||
fps_limiter_fn, fps_limiter_semaphore);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( limiter_timer == NULL) {
|
|
||||||
fprintf( stderr, "Error trying to start FPS limiter timer: %s\n",
|
|
||||||
SDL_GetError());
|
|
||||||
if ( fps_limiter_semaphore != NULL) {
|
|
||||||
SDL_DestroySemaphore( fps_limiter_semaphore);
|
|
||||||
fps_limiter_semaphore = NULL;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(my_config.load_slot != -1){
|
if(my_config.load_slot != -1){
|
||||||
loadstate_slot(my_config.load_slot);
|
loadstate_slot(my_config.load_slot);
|
||||||
}
|
}
|
||||||
|
@ -786,14 +731,17 @@ int main(int argc, char ** argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !my_config.disable_limiter && !ctrls_cfg.boost) {
|
if ( !my_config.disable_limiter && !ctrls_cfg.boost) {
|
||||||
limiter_frame_counter += 1 + my_config.frameskip;
|
int now = SDL_GetTicks();
|
||||||
if ( limiter_frame_counter >= my_config.fps_limiter_frame_period) {
|
int delay = (limiter_tick0 + limiter_frame_counter*1000/FPS_LIMITER_FPS) - now;
|
||||||
|
if (delay > 0) {
|
||||||
|
SDL_Delay(delay);
|
||||||
|
} else if (delay < -500) { // reset if we fall too far behind don't want to run super fast until we catch up
|
||||||
|
limiter_tick0 = now;
|
||||||
limiter_frame_counter = 0;
|
limiter_frame_counter = 0;
|
||||||
|
|
||||||
/* wait for the timer to expire */
|
|
||||||
SDL_SemWait( fps_limiter_semaphore);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// always count frames, we'll mess up if the limiter gets turned on later otherwise
|
||||||
|
limiter_frame_counter += 1 + my_config.frameskip;
|
||||||
|
|
||||||
#ifdef DISPLAY_FPS
|
#ifdef DISPLAY_FPS
|
||||||
fps_frame_counter += 1;
|
fps_frame_counter += 1;
|
||||||
|
@ -818,12 +766,6 @@ int main(int argc, char ** argv) {
|
||||||
/* Unload joystick */
|
/* Unload joystick */
|
||||||
uninit_joy();
|
uninit_joy();
|
||||||
|
|
||||||
if ( !my_config.disable_limiter) {
|
|
||||||
/* tidy up the FPS limiter timer and semaphore */
|
|
||||||
SDL_RemoveTimer( limiter_timer);
|
|
||||||
SDL_DestroySemaphore( fps_limiter_semaphore);
|
|
||||||
}
|
|
||||||
|
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
NDS_DeInit();
|
NDS_DeInit();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue