rewrite frame limiter
authornotaz <notasas@gmail.com>
Sat, 15 Jan 2011 23:50:12 +0000 (01:50 +0200)
committernotaz <notasas@gmail.com>
Sat, 15 Jan 2011 23:51:08 +0000 (01:51 +0200)
the peops one is sometimes sleeping when not needed.

frontend/menu.c
frontend/menu.h
frontend/plugin_lib.c
frontend/plugin_lib.h

index e1a3cc0..f2a24fd 100644 (file)
@@ -68,7 +68,6 @@ int g_opts;
 // from softgpu plugin
 extern int iUseDither;
 extern int UseFrameSkip;
 // from softgpu plugin
 extern int iUseDither;
 extern int UseFrameSkip;
-extern int UseFrameLimit;
 extern uint32_t dwActFixes;
 extern float fFrameRateHz;
 extern int dwFrameRateTicks;
 extern uint32_t dwActFixes;
 extern float fFrameRateHz;
 extern int dwFrameRateTicks;
@@ -141,13 +140,13 @@ static int emu_save_load_game(int load, int sram)
 
 static void menu_set_defconfig(void)
 {
 
 static void menu_set_defconfig(void)
 {
+       g_opts = 0;
        scaling = SCALE_4_3;
 
        Config.Xa = Config.Cdda = Config.Sio =
        Config.SpuIrq = Config.RCntFix = Config.VSyncWA = 0;
 
        iUseDither = UseFrameSkip = 0;
        scaling = SCALE_4_3;
 
        Config.Xa = Config.Cdda = Config.Sio =
        Config.SpuIrq = Config.RCntFix = Config.VSyncWA = 0;
 
        iUseDither = UseFrameSkip = 0;
-       UseFrameLimit = 1;
        dwActFixes = 1<<7;
 
        iUseReverb = 2;
        dwActFixes = 1<<7;
 
        iUseReverb = 2;
@@ -200,7 +199,6 @@ static const struct {
        CE_INTVAL(g_opts),
        CE_INTVAL(iUseDither),
        CE_INTVAL(UseFrameSkip),
        CE_INTVAL(g_opts),
        CE_INTVAL(iUseDither),
        CE_INTVAL(UseFrameSkip),
-       CE_INTVAL(UseFrameLimit),
        CE_INTVAL(dwActFixes),
        CE_INTVAL(iUseReverb),
        CE_INTVAL(iUseInterpolation),
        CE_INTVAL(dwActFixes),
        CE_INTVAL(iUseReverb),
        CE_INTVAL(iUseInterpolation),
@@ -887,7 +885,7 @@ static const char h_cfg_nodrc[]  = "Disable dynamic recompiler and use interpret
 static menu_entry e_menu_adv_options[] =
 {
        mee_onoff_h   ("Show CPU load",          0, g_opts, OPT_SHOWCPU, h_cfg_cpul),
 static menu_entry e_menu_adv_options[] =
 {
        mee_onoff_h   ("Show CPU load",          0, g_opts, OPT_SHOWCPU, h_cfg_cpul),
-       mee_onoff_h   ("Frame Limiter",          0, UseFrameLimit, 1, h_cfg_fl),
+       mee_onoff_h   ("Disable Frame Limiter",  0, g_opts, OPT_NO_FRAMELIM, h_cfg_fl),
        mee_onoff_h   ("Disable XA Decoding",    0, Config.Xa, 1, h_cfg_xa),
        mee_onoff_h   ("Disable CD Audio",       0, Config.Cdda, 1, h_cfg_cdda),
        mee_onoff_h   ("SIO IRQ Always Enabled", 0, Config.Sio, 1, h_cfg_sio),
        mee_onoff_h   ("Disable XA Decoding",    0, Config.Xa, 1, h_cfg_xa),
        mee_onoff_h   ("Disable CD Audio",       0, Config.Cdda, 1, h_cfg_cdda),
        mee_onoff_h   ("SIO IRQ Always Enabled", 0, Config.Sio, 1, h_cfg_sio),
@@ -1393,11 +1391,7 @@ void menu_prepare_emu(void)
        if (Config.Cdda)
                CDR_stop();
 
        if (Config.Cdda)
                CDR_stop();
 
-       // HACK to set up the frame limiter if softgpu is not used..
-       if (gpu_plugsel != 0) {
-               fFrameRateHz = Config.PsxType ? 50.0f : 59.94f;
-               dwFrameRateTicks = (100000*100 / (unsigned long)(fFrameRateHz*100));
-       }
+       pl_frame_interval = Config.PsxType ? 20000 : 16667;
 
        if (GPU_open != NULL) {
                int ret = GPU_open(&gpuDisp, "PCSX", NULL);
 
        if (GPU_open != NULL) {
                int ret = GPU_open(&gpuDisp, "PCSX", NULL);
index 7fb85b3..d8aa892 100644 (file)
@@ -8,6 +8,7 @@ void menu_notify_mode_change(int w, int h, int bpp);
 enum opts {
        OPT_SHOWFPS = 1 << 0,
        OPT_SHOWCPU = 1 << 1,
 enum opts {
        OPT_SHOWFPS = 1 << 0,
        OPT_SHOWCPU = 1 << 1,
+       OPT_NO_FRAMELIM = 1 << 2,
 };
 
 extern int g_opts;
 };
 
 extern int g_opts;
index dfa2fae..688bb12 100644 (file)
 #include "../libpcsxcore/new_dynarec/new_dynarec.h"
 
 void *pl_fbdev_buf;
 #include "../libpcsxcore/new_dynarec/new_dynarec.h"
 
 void *pl_fbdev_buf;
+int pl_frame_interval;
 int keystate;
 static int pl_fbdev_w, pl_fbdev_h, pl_fbdev_bpp;
 int keystate;
 static int pl_fbdev_w, pl_fbdev_h, pl_fbdev_bpp;
-static int flip_cnt, flips_per_sec, tick_per_sec;
-extern float fps_cur; // XXX
+static int flip_cnt, vsync_cnt, flips_per_sec, tick_per_sec;
+static float vsps_cur;
 
 static int get_cpu_ticks(void)
 {
 
 static int get_cpu_ticks(void)
 {
@@ -53,7 +54,7 @@ static int get_cpu_ticks(void)
 static void print_fps(void)
 {
        if (pl_fbdev_bpp == 16)
 static void print_fps(void)
 {
        if (pl_fbdev_bpp == 16)
-               pl_text_out16(2, pl_fbdev_h - 10, "%2d %4.1f", flips_per_sec, fps_cur);
+               pl_text_out16(2, pl_fbdev_h - 10, "%2d %4.1f", flips_per_sec, vsps_cur);
 }
 
 static void print_cpu_usage(void)
 }
 
 static void print_cpu_usage(void)
@@ -128,36 +129,67 @@ static void update_input(void)
 #endif
 }
 
 #endif
 }
 
+#define MAX_LAG_FRAMES 3
+
+#define tvdiff(tv, tv_old) \
+       ((tv.tv_sec - tv_old.tv_sec) * 1000000 + tv.tv_usec - tv_old.tv_usec)
+// assumes us < 1000000
+#define tvadd(tv, us) { \
+       tv.tv_usec += us; \
+       if (tv.tv_usec >= 1000000) { \
+               tv.tv_usec -= 1000000; \
+               tv.tv_sec++; \
+       } \
+}
+
 /* called on every vsync */
 void pl_frame_limit(void)
 {
 /* called on every vsync */
 void pl_frame_limit(void)
 {
-       extern void CheckFrameRate(void);
-       static int oldsec;
-       struct timeval tv;
+       static struct timeval tv_old, tv_expect;
+       struct timeval now;
+       int diff;
+
+       vsync_cnt++;
 
        /* doing input here because the pad is polled
         * thousands of times per frame for some reason */
        update_input();
 
        pcnt_end(PCNT_ALL);
 
        /* doing input here because the pad is polled
         * thousands of times per frame for some reason */
        update_input();
 
        pcnt_end(PCNT_ALL);
-       gettimeofday(&tv, 0);
+       gettimeofday(&now, 0);
 
 
-       if (tv.tv_sec != oldsec) {
+       if (now.tv_sec != tv_old.tv_sec) {
+               diff = tvdiff(now, tv_old);
+               vsps_cur = 0.0f;
+               if (0 < diff && diff < 2000000)
+                       vsps_cur = 1000000.0f * vsync_cnt / diff;
                flips_per_sec = flip_cnt;
                flips_per_sec = flip_cnt;
-               flip_cnt = 0;
-               oldsec = tv.tv_sec;
+               vsync_cnt = flip_cnt = 0;
+               tv_old = now;
                if (g_opts & OPT_SHOWCPU)
                        tick_per_sec = get_cpu_ticks();
        }
 #ifdef PCNT
        static int ya_vsync_count;
        if (++ya_vsync_count == PCNT_FRAMES) {
                if (g_opts & OPT_SHOWCPU)
                        tick_per_sec = get_cpu_ticks();
        }
 #ifdef PCNT
        static int ya_vsync_count;
        if (++ya_vsync_count == PCNT_FRAMES) {
-               pcnt_print(fps_cur);
+               pcnt_print(vsps_cur);
                ya_vsync_count = 0;
        }
 #endif
 
                ya_vsync_count = 0;
        }
 #endif
 
-       CheckFrameRate();
+       if (!(g_opts & OPT_NO_FRAMELIM)) {
+               tvadd(tv_expect, pl_frame_interval);
+               diff = tvdiff(tv_expect, now);
+               if (diff > MAX_LAG_FRAMES * pl_frame_interval || diff < -MAX_LAG_FRAMES * pl_frame_interval) {
+                       //printf("pl_frame_limit reset, diff=%d, iv %d\n", diff, pl_frame_interval);
+                       tv_expect = now;
+               }
+               else if (diff > pl_frame_interval) {
+                       // yay for working usleep on pandora!
+                       //printf("usleep %d\n", diff - pl_frame_interval / 2);
+                       usleep(diff - pl_frame_interval / 2);
+               }
+       }
 
        pcnt_start(PCNT_ALL);
 }
 
        pcnt_start(PCNT_ALL);
 }
index 53389d2..22ab285 100644 (file)
@@ -39,6 +39,8 @@ struct rearmed_cbs {
 
 extern const struct rearmed_cbs pl_rearmed_cbs;
 
 
 extern const struct rearmed_cbs pl_rearmed_cbs;
 
+extern int pl_frame_interval;
+
 #ifndef ARRAY_SIZE
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
 #endif
 #ifndef ARRAY_SIZE
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
 #endif