X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=fceu.git;a=blobdiff_plain;f=drivers%2Fgp2x%2Fthrottle.c;h=fdfc0eb15a3260a6edc935a2945763388bc09c18;hp=c52eb6857876df0f8562d81ed1a18d9cc0267372;hb=7b356ee3dc5d7e54d9dc06c413f84380d1044441;hpb=15d2d2584cc71389f06b969d7cd836332add97c6 diff --git a/drivers/gp2x/throttle.c b/drivers/gp2x/throttle.c index c52eb68..fdfc0eb 100644 --- a/drivers/gp2x/throttle.c +++ b/drivers/gp2x/throttle.c @@ -1,38 +1,68 @@ #include #include "main.h" #include "gp2x.h" +#include "minimal.h" #include "throttle.h" extern uint8 PAL; extern int FSkip; -static int usec_aim = 0, usec_done = 0; static int skip_count = 0; +static struct timeval tv_prev; void RefreshThrottleFPS(void) { - usec_aim = usec_done = skip_count = 0; + skip_count = 0; + if (Settings.perfect_vsync) + { + gp2x_video_wait_vsync(); + } + gettimeofday(&tv_prev, 0); } -void SpeedThrottle(void) +#define tvdiff(tv1, tv2) \ + ((tv1.tv_sec - tv2.tv_sec) * 1000000 + tv1.tv_usec - tv2.tv_usec) + +#define tvadd(tv, usec) { \ + tv.tv_usec += usec; \ + if (tv.tv_usec >= 1000000) { \ + tv.tv_sec += 1; \ + tv.tv_usec -= 1000000; \ + } \ +} + +#define tvsub(tv, usec) { \ + tv.tv_usec -= usec; \ + if (tv.tv_usec < 0) { \ + tv.tv_sec -= 1; \ + tv.tv_usec += 1000000; \ + } \ +} + +static void wait_to(struct timeval *tv_aim) { - static struct timeval tv_prev; struct timeval tv_now; - int delta_nom = PAL ? 19997 : 16639; // ~50.007, 19.997 ms/frame : ~60.1, 16.639 ms/frame + int diff; - - if (usec_done == 0) { // first time - usec_done = 1; - gettimeofday(&tv_prev, 0); - return; + do + { + gettimeofday(&tv_now, 0); + diff = tvdiff((*tv_aim), tv_now); } + while (diff > 0); +} - gettimeofday(&tv_now, 0); +#include +void SpeedThrottle(void) +{ + struct timeval tv_now, tv_aim; + int tdiff; + + tv_aim = tv_prev; + tvadd(tv_aim, PAL ? 19997 : 16639); // ~50.007, 19.997 ms/frame : ~60.1, 16.639 ms/frame - usec_aim += delta_nom; - if (tv_now.tv_sec != tv_prev.tv_sec) - usec_done += 1000000; - usec_done += tv_now.tv_usec - tv_prev.tv_usec; + gettimeofday(&tv_now, 0); + tdiff = tvdiff(tv_now, tv_aim); #ifdef FRAMESKIP if (Settings.frameskip >= 0) @@ -44,29 +74,40 @@ void SpeedThrottle(void) FSkip = 1; } } - else if (usec_done > usec_aim + 1024*4) + else if (tdiff > 0) { /* auto frameskip */ - if (usec_done - usec_aim > 1024*32) - usec_done = usec_aim = 1; // too much behind, try to recover.. - else - FSkip = 1; tv_prev = tv_now; + if (tdiff < 1024*16) // limit frameskip + { + FSkip = 1; + tvsub(tv_prev, tdiff); + } return; } #endif - tv_prev = tv_now; - while (usec_done < usec_aim) + /* throttle */ + if (tdiff < 0) { - gettimeofday(&tv_now, 0); - - if (tv_now.tv_sec != tv_prev.tv_sec) - usec_done += 1000000; - usec_done += tv_now.tv_usec - tv_prev.tv_usec; - tv_prev = tv_now; + if (Settings.perfect_vsync) + { + if (tdiff <= (PAL ? 19997/2 : 16639/2)) + { + struct timeval tv_tmp = tv_aim; + tvsub(tv_tmp, 5000); + wait_to(&tv_tmp); + } + gp2x_video_wait_vsync(); + gettimeofday(&tv_prev, 0); + return; + } + else + { + wait_to(&tv_aim); + } } - usec_done = usec_done - usec_aim + 1; // reset to prevent overflows - usec_aim = 0; + + tv_prev = tv_aim; }