frontend: new sync code
authornotaz <notasas@gmail.com>
Fri, 30 Aug 2013 00:54:48 +0000 (03:54 +0300)
committernotaz <notasas@gmail.com>
Fri, 30 Aug 2013 21:58:10 +0000 (00:58 +0300)
should fix video drift/desync on pandora

platform/common/config_file.c
platform/common/emu.c
platform/common/emu.h
platform/common/main.c
platform/common/menu_pico.c

index f058fbd..f8f7fdf 100644 (file)
@@ -308,11 +308,6 @@ static int custom_read(menu_entry *me, const char *var, const char *val)
                                return 0;
                        return 1;
 
-               case MA_OPT2_GAMMA:
-                       if (strcasecmp(var, "Gamma correction") != 0) return 0;
-                       currentConfig.gamma = (int) (atof(val) * 100.0);
-                       return 1;
-
                case MA_CDOPT_READAHEAD:
                        if (strcasecmp(var, "ReadAhead buffer") != 0) return 0;
                        PicoCDBuffers = atoi(val) / 2;
index ee216fe..8bc83af 100644 (file)
@@ -43,7 +43,7 @@ void *g_screen_ptr;
 int g_screen_width  = 320;\r
 int g_screen_height = 240;\r
 \r
-char *PicoConfigFile = "config.cfg";\r
+const char *PicoConfigFile = "config2.cfg";\r
 currentConfig_t currentConfig, defaultConfig;\r
 int state_slot = 0;\r
 int config_slot = 0, config_slot_current = 0;\r
@@ -1276,31 +1276,26 @@ static void emu_loop_prep(void)
                filter_old = currentConfig.filter;\r
        }\r
 \r
+printf("-- gamma %d\n", currentConfig.gamma);\r
        plat_target_gamma_set(currentConfig.gamma, 0);\r
 \r
        pemu_loop_prep();\r
 }\r
 \r
-static void skip_frame(int do_audio)\r
-{\r
-       PicoSkipFrame = do_audio ? 1 : 2;\r
-       PicoFrame();\r
-       PicoSkipFrame = 0;\r
-}\r
-\r
 /* our tick here is 1 us right now */\r
 #define ms_to_ticks(x) (unsigned int)(x * 1000)\r
 #define get_ticks() plat_get_ticks_us()\r
 \r
 void emu_loop(void)\r
 {\r
-       int pframes_done;               /* "period" frames, used for sync */\r
        int frames_done, frames_shown;  /* actual frames for fps counter */\r
-       int target_fps, target_frametime;\r
-       unsigned int timestamp_base = 0, timestamp_fps;\r
+       int target_frametime_x3;\r
+       unsigned int timestamp_x3 = 0;\r
+       unsigned int timestamp_aim_x3 = 0;\r
+       unsigned int timestamp_fps_x3 = 0;\r
        char *notice_msg = NULL;\r
        char fpsbuff[24];\r
-       int i;\r
+       int fskip_cnt = 0;\r
 \r
        fpsbuff[0] = 0;\r
 \r
@@ -1315,45 +1310,47 @@ void emu_loop(void)
        pemu_sound_start();\r
 \r
        /* number of ticks per frame */\r
-       if (Pico.m.pal) {\r
-               target_fps = 50;\r
-               target_frametime = ms_to_ticks(1000) / 50;\r
-       } else {\r
-               target_fps = 60;\r
-               target_frametime = ms_to_ticks(1000) / 60 + 1;\r
-       }\r
+       if (Pico.m.pal)\r
+               target_frametime_x3 = 3 * ms_to_ticks(1000) / 50;\r
+       else\r
+               target_frametime_x3 = 3 * ms_to_ticks(1000) / 60;\r
 \r
-       timestamp_fps = get_ticks();\r
        reset_timing = 1;\r
-\r
-       frames_done = frames_shown = pframes_done = 0;\r
-\r
-       plat_video_wait_vsync();\r
+       frames_done = frames_shown = 0;\r
 \r
        /* loop with resync every 1 sec. */\r
        while (engineState == PGS_Running)\r
        {\r
-               unsigned int timestamp;\r
-               int diff, diff_lim;\r
+               int skip = 0;\r
+               int diff;\r
 \r
                pprof_start(main);\r
 \r
-               timestamp = get_ticks();\r
                if (reset_timing) {\r
                        reset_timing = 0;\r
-                       timestamp_base = timestamp;\r
-                       pframes_done = 0;\r
+                       plat_video_wait_vsync();\r
+                       timestamp_aim_x3 = get_ticks() * 3;\r
+                       timestamp_fps_x3 = timestamp_aim_x3;\r
+                       fskip_cnt = 0;\r
+               }\r
+               else if (currentConfig.EmuOpt & EOPT_NO_FRMLIMIT) {\r
+                       timestamp_aim_x3 = get_ticks() * 3;\r
                }\r
 \r
+               timestamp_x3 = get_ticks() * 3;\r
+\r
                // show notice_msg message?\r
                if (notice_msg_time != 0)\r
                {\r
                        static int noticeMsgSum;\r
-                       if (timestamp - ms_to_ticks(notice_msg_time) > ms_to_ticks(STATUS_MSG_TIMEOUT)) {\r
+                       if (timestamp_x3 - ms_to_ticks(notice_msg_time) * 3\r
+                            > ms_to_ticks(STATUS_MSG_TIMEOUT) * 3)\r
+                       {\r
                                notice_msg_time = 0;\r
                                plat_status_msg_clear();\r
                                notice_msg = NULL;\r
-                       } else {\r
+                       }\r
+                       else {\r
                                int sum = noticeMsg[0] + noticeMsg[1] + noticeMsg[2];\r
                                if (sum != noticeMsgSum) {\r
                                        plat_status_msg_clear();\r
@@ -1364,7 +1361,7 @@ void emu_loop(void)
                }\r
 \r
                // second changed?\r
-               if (timestamp - timestamp_fps >= ms_to_ticks(1000))\r
+               if (timestamp_x3 - timestamp_fps_x3 >= ms_to_ticks(1000) * 3)\r
                {\r
 #ifdef BENCHMARK\r
                        static int bench = 0, bench_fps = 0, bench_fps_s = 0, bfp = 0, bf[4];\r
@@ -1382,86 +1379,79 @@ void emu_loop(void)
                                sprintf(fpsbuff, "%02i/%02i  ", frames_shown, frames_done);\r
 #endif\r
                        frames_shown = frames_done = 0;\r
-                       timestamp_fps += ms_to_ticks(1000);\r
+                       timestamp_fps_x3 += ms_to_ticks(1000) * 3;\r
                }\r
 #ifdef PFRAMES\r
                sprintf(fpsbuff, "%i", Pico.m.frame_count);\r
 #endif\r
 \r
-               if (timestamp - timestamp_base >= ms_to_ticks(1000))\r
-               {\r
-                       if ((currentConfig.EmuOpt & EOPT_NO_FRMLIMIT) && currentConfig.Frameskip >= 0)\r
-                               pframes_done = 0;\r
-                       else\r
-                               pframes_done -= target_fps;\r
-                       if (pframes_done < -2) {\r
-                               /* don't drag more than 2 frames behind */\r
-                               pframes_done = -2;\r
-                               timestamp_base = timestamp - 2 * target_frametime;\r
-                       }\r
-                       else\r
-                               timestamp_base += ms_to_ticks(1000);\r
-               }\r
-\r
-               diff = timestamp - timestamp_base;\r
-               diff_lim = (pframes_done + 1) * target_frametime;\r
+               diff = timestamp_aim_x3 - timestamp_x3;\r
 \r
-               if (currentConfig.Frameskip >= 0) // frameskip enabled\r
+               if (currentConfig.Frameskip >= 0) // frameskip enabled (or 0)\r
                {\r
-                       for (i = 0; i < currentConfig.Frameskip; i++) {\r
-                               emu_update_input();\r
-                               skip_frame(1);\r
-                               pframes_done++; frames_done++;\r
-                               diff_lim += target_frametime;\r
-\r
-                               if (!(currentConfig.EmuOpt & (EOPT_NO_FRMLIMIT|EOPT_EXT_FRMLIMIT))) {\r
-                                       timestamp = get_ticks();\r
-                                       diff = timestamp - timestamp_base;\r
-                                       if (!reset_timing && diff < diff_lim) // we are too fast\r
-                                               plat_wait_till_us(timestamp_base + diff_lim);\r
-                               }\r
+                       if (fskip_cnt < currentConfig.Frameskip) {\r
+                               fskip_cnt++;\r
+                               skip = 1;\r
+                       }\r
+                       else {\r
+                               fskip_cnt = 0;\r
                        }\r
                }\r
-               else if (diff > diff_lim)\r
+               else if (diff < -target_frametime_x3)\r
                {\r
                        /* no time left for this frame - skip */\r
                        /* limit auto frameskip to 8 */\r
-                       if (frames_done / 8 <= frames_shown) {\r
-                               emu_update_input();\r
-                               skip_frame(diff < diff_lim + target_frametime * 16);\r
-                               pframes_done++; frames_done++;\r
-                               continue;\r
-                       }\r
+                       if (frames_done / 8 <= frames_shown)\r
+                               skip = 1;\r
+               }\r
+\r
+               // don't go in debt too much\r
+               while (diff < -target_frametime_x3 * 3) {\r
+                       timestamp_aim_x3 += target_frametime_x3;\r
+                       diff = timestamp_aim_x3 - timestamp_x3;\r
                }\r
 \r
                emu_update_input();\r
-               PicoFrame();\r
-               pemu_finalize_frame(fpsbuff, notice_msg);\r
+               if (skip) {\r
+                       int do_audio = diff > -target_frametime_x3 * 2;\r
+                       PicoSkipFrame = do_audio ? 1 : 2;\r
+                       PicoFrame();\r
+                       PicoSkipFrame = 0;\r
+               }\r
+               else {\r
+                       PicoFrame();\r
+                       pemu_finalize_frame(fpsbuff, notice_msg);\r
+                       frames_shown++;\r
+               }\r
+               frames_done++;\r
+               timestamp_aim_x3 += target_frametime_x3;\r
 \r
-               if (!flip_after_sync)\r
+               if (!skip && !flip_after_sync)\r
                        plat_video_flip();\r
 \r
                /* frame limiter */\r
-               if (!reset_timing && !(currentConfig.EmuOpt & (EOPT_NO_FRMLIMIT|EOPT_EXT_FRMLIMIT)))\r
+               if (!skip && !reset_timing\r
+                   && !(currentConfig.EmuOpt & (EOPT_NO_FRMLIMIT|EOPT_EXT_FRMLIMIT)))\r
                {\r
-                       timestamp = get_ticks();\r
-                       diff = timestamp - timestamp_base;\r
+                       unsigned int timestamp = get_ticks();\r
+                       diff = timestamp_aim_x3 - timestamp * 3;\r
 \r
                        // sleep or vsync if we are still too fast\r
-                       if (diff < diff_lim)\r
-                       {\r
+                       if (diff > target_frametime_x3 && (currentConfig.EmuOpt & EOPT_VSYNC)) {\r
                                // we are too fast\r
-                               plat_wait_till_us(timestamp_base + diff_lim - target_frametime / 4);\r
-                               if (currentConfig.EmuOpt & EOPT_VSYNC)\r
-                                       plat_video_wait_vsync();\r
+                               plat_video_wait_vsync();\r
+                               timestamp = get_ticks();\r
+                               diff = timestamp * 3 - timestamp_aim_x3;\r
+                       }\r
+                       if (diff > target_frametime_x3) {\r
+                               // still too fast\r
+                               plat_wait_till_us(timestamp + (diff - target_frametime_x3) / 3);\r
                        }\r
                }\r
 \r
-               if (flip_after_sync)\r
+               if (!skip && flip_after_sync)\r
                        plat_video_flip();\r
 \r
-               pframes_done++; frames_done++; frames_shown++;\r
-\r
                pprof_end(main);\r
        }\r
 \r
index 4a4b439..93787c7 100644 (file)
@@ -77,7 +77,7 @@ typedef struct _currentConfig_t {
 } currentConfig_t;
 
 extern currentConfig_t currentConfig, defaultConfig;
-extern char *PicoConfigFile;
+extern const char *PicoConfigFile;
 extern int state_slot;
 extern int config_slot, config_slot_current;
 extern unsigned char *movie_data;
index e8f92b9..5267667 100644 (file)
@@ -19,7 +19,6 @@
 #include <cpu/debug.h>\r
 \r
 \r
-extern char *PicoConfigFile;\r
 static int load_state_slot = -1;\r
 char **g_argv;\r
 \r
index 1427490..8e723ff 100644 (file)
@@ -927,7 +927,7 @@ static void debug_menu_loop(void)
 // ------------ main menu ------------
 
 static const char credits[] =
-       "PicoDrive v" VERSION " (c) notaz, 2006-2011\n\n\n"
+       "PicoDrive v" VERSION " (c) notaz, 2006-2013\n\n\n"
        "Credits:\n"
        "fDave: Cyclone 68000 core,\n"
        "      base code of PicoDrive\n"
@@ -935,7 +935,6 @@ static const char credits[] =
        "MAME devs: YM2612 and SN76496 cores\n"
        "Inder, ketchupgun: graphics\n"
 #ifdef __GP2X__
-       "rlyeh and others: minimal SDK\n"
        "Squidge: mmuhack\n"
        "Dzz: ARM940 sample\n"
 #endif
@@ -944,7 +943,7 @@ static const char credits[] =
        " Charles MacDonald, Haze,\n"
        " Stephane Dallongeville,\n"
        " Lordus, Exophase, Rokas,\n"
-       " Nemesis, Tasco Deluxe";
+       " Eke, Nemesis, Tasco Deluxe";
 
 static void menu_main_draw_status(void)
 {