X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=fceu.git;a=blobdiff_plain;f=drivers%2Fgp2x%2Fthrottle.c;h=5a5f55efc4816f00c8b37c3a787e78722cd06ea4;hp=b6b628ce392f3099498dd58f54b31b3b25b750ec;hb=4a2a617ac879a95babe3b8a822188b71e9769ba4;hpb=b2b95d2e0d1fd5e52d03c2152605b09b024c1d0e diff --git a/drivers/gp2x/throttle.c b/drivers/gp2x/throttle.c index b6b628c..5a5f55e 100644 --- a/drivers/gp2x/throttle.c +++ b/drivers/gp2x/throttle.c @@ -1,77 +1,70 @@ #include +#include "../common/settings.h" #include "main.h" -#include "gp2x.h" +#include "minimal.h" #include "throttle.h" -#if 0 -static uint64 tfreq; -static uint64 desiredfps; -void RefreshThrottleFPS(void) -{ - uint64 f=FCEUI_GetDesiredFPS(); - // great, a bit faster than before - //f = (f*65) >> 6; - desiredfps=f>>8; - tfreq=1000000; - tfreq<<=16; /* Adjustment for fps returned from FCEUI_GetDesiredFPS(). */ -} +extern uint8 PAL; +extern int FSkip; +static int skip_count = 0; +static struct timeval tv_prev; -static uint64 GetCurTime(void) -{ - uint64 ret; - struct timeval tv; +#define tvdiff(tv1, tv2) \ + ((tv1.tv_sec - tv2.tv_sec) * 1000000 + tv1.tv_usec - tv2.tv_usec) - gettimeofday(&tv,0); - ret=(uint64)tv.tv_sec*1000000; - ret+=tv.tv_usec; - return(ret); +#define tvadd(tv, usec) { \ + tv.tv_usec += usec; \ + if (tv.tv_usec >= 1000000) { \ + tv.tv_sec += 1; \ + tv.tv_usec -= 1000000; \ + } \ } -INLINE void SpeedThrottle(void) -{ - static uint64 ttime,ltime; - - waiter: - - ttime=GetCurTime(); - - if( (ttime-ltime) < (tfreq/desiredfps) ) - { - goto waiter; - } - if( (ttime-ltime) >= (tfreq*4/desiredfps)) - ltime=ttime; - else - ltime+=tfreq/desiredfps; +#define tvsub(tv, usec) { \ + tv.tv_usec -= usec; \ + if (tv.tv_usec < 0) { \ + tv.tv_sec -= 1; \ + tv.tv_usec += 1000000; \ + } \ } -#else - -extern uint8 PAL; -extern int FSkip; -static int usec_aim = 0, usec_done = 0; -static int skip_count = 0; +void RefreshThrottleFPS(void) +{ + skip_count = 0; + if (Settings.perfect_vsync) + { + gp2x_video_wait_vsync(); + } + gettimeofday(&tv_prev, 0); + tvsub(tv_prev, PAL ? 19997 : 16639); +} -INLINE void SpeedThrottle(void) +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 frame_time = PAL ? 19997 : 16639; // ~50.007, 19.997 ms/frame : ~60.1, 16.639 ms/frame + int tdiff; + + tv_aim = tv_prev; + tvadd(tv_aim, frame_time); - 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) @@ -83,30 +76,46 @@ INLINE void SpeedThrottle(void) FSkip = 1; } } - else if (usec_done > usec_aim + 1024*4) + else if (tdiff >= frame_time) { /* auto frameskip */ - if (usec_done - usec_aim > 1024*32) - usec_done = usec_aim = 1; // too much behind, try to recover.. - else + if (/*tdiff < 36*1024 &&*/ skip_count < 6) { // limit frameskip FSkip = 1; - tv_prev = tv_now; + skip_count++; + } else + skip_count = 0; + + if (tdiff < 92*1024) + tv_prev = tv_aim; + else + tv_prev = tv_now; // something went wrong, try to recover return; } + else + skip_count = 0; #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; } -#endif