release r2, update credits
[fceu.git] / drivers / gp2x / throttle.c
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