refresh rate: comments
[fceu.git] / drivers / gp2x / throttle.c
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