| 1 | #include <sys/time.h> |
| 2 | #include "main.h" |
| 3 | #include "gp2x.h" |
| 4 | #include "minimal.h" |
| 5 | #include "throttle.h" |
| 6 | |
| 7 | |
| 8 | extern uint8 PAL; |
| 9 | extern int FSkip; |
| 10 | static int skip_count = 0; |
| 11 | static struct timeval tv_prev; |
| 12 | |
| 13 | void RefreshThrottleFPS(void) |
| 14 | { |
| 15 | skip_count = 0; |
| 16 | if (Settings.perfect_vsync) |
| 17 | { |
| 18 | gp2x_video_wait_vsync(); |
| 19 | } |
| 20 | gettimeofday(&tv_prev, 0); |
| 21 | } |
| 22 | |
| 23 | #define tvdiff(tv1, tv2) \ |
| 24 | ((tv1.tv_sec - tv2.tv_sec) * 1000000 + tv1.tv_usec - tv2.tv_usec) |
| 25 | |
| 26 | #define tvadd(tv, usec) { \ |
| 27 | tv.tv_usec += usec; \ |
| 28 | if (tv.tv_usec >= 1000000) { \ |
| 29 | tv.tv_sec += 1; \ |
| 30 | tv.tv_usec -= 1000000; \ |
| 31 | } \ |
| 32 | } |
| 33 | |
| 34 | #define tvsub(tv, usec) { \ |
| 35 | tv.tv_usec -= usec; \ |
| 36 | if (tv.tv_usec < 0) { \ |
| 37 | tv.tv_sec -= 1; \ |
| 38 | tv.tv_usec += 1000000; \ |
| 39 | } \ |
| 40 | } |
| 41 | |
| 42 | static void wait_to(struct timeval *tv_aim) |
| 43 | { |
| 44 | struct timeval tv_now; |
| 45 | int diff; |
| 46 | |
| 47 | do |
| 48 | { |
| 49 | gettimeofday(&tv_now, 0); |
| 50 | diff = tvdiff((*tv_aim), tv_now); |
| 51 | } |
| 52 | while (diff > 0); |
| 53 | } |
| 54 | |
| 55 | #include <stdio.h> |
| 56 | void SpeedThrottle(void) |
| 57 | { |
| 58 | struct timeval tv_now, tv_aim; |
| 59 | int tdiff; |
| 60 | |
| 61 | tv_aim = tv_prev; |
| 62 | tvadd(tv_aim, PAL ? 19997 : 16639); // ~50.007, 19.997 ms/frame : ~60.1, 16.639 ms/frame |
| 63 | |
| 64 | gettimeofday(&tv_now, 0); |
| 65 | tdiff = tvdiff(tv_now, tv_aim); |
| 66 | |
| 67 | #ifdef FRAMESKIP |
| 68 | if (Settings.frameskip >= 0) |
| 69 | { |
| 70 | if (skip_count >= Settings.frameskip) |
| 71 | skip_count = 0; |
| 72 | else { |
| 73 | skip_count++; |
| 74 | FSkip = 1; |
| 75 | } |
| 76 | } |
| 77 | else if (tdiff > 0) |
| 78 | { |
| 79 | /* auto frameskip */ |
| 80 | tv_prev = tv_now; |
| 81 | if (tdiff < 1024*16) // limit frameskip |
| 82 | { |
| 83 | FSkip = 1; |
| 84 | tvsub(tv_prev, tdiff); |
| 85 | } |
| 86 | return; |
| 87 | } |
| 88 | #endif |
| 89 | |
| 90 | /* throttle */ |
| 91 | if (tdiff < 0) |
| 92 | { |
| 93 | if (Settings.perfect_vsync) |
| 94 | { |
| 95 | if (tdiff <= (PAL ? 19997/2 : 16639/2)) |
| 96 | { |
| 97 | struct timeval tv_tmp = tv_aim; |
| 98 | tvsub(tv_tmp, 5000); |
| 99 | wait_to(&tv_tmp); |
| 100 | } |
| 101 | gp2x_video_wait_vsync(); |
| 102 | gettimeofday(&tv_prev, 0); |
| 103 | return; |
| 104 | } |
| 105 | else |
| 106 | { |
| 107 | wait_to(&tv_aim); |
| 108 | } |
| 109 | } |
| 110 | |
| 111 | tv_prev = tv_aim; |
| 112 | } |
| 113 | |