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