35868d35 |
1 | #include <sys/time.h> |
2 | #include "main.h" |
b2b95d2e |
3 | #include "gp2x.h" |
7b356ee3 |
4 | #include "minimal.h" |
35868d35 |
5 | #include "throttle.h" |
6 | |
35868d35 |
7 | |
8 | extern uint8 PAL; |
b2b95d2e |
9 | extern int FSkip; |
35868d35 |
10 | static int skip_count = 0; |
7b356ee3 |
11 | static struct timeval tv_prev; |
35868d35 |
12 | |
7b356ee3 |
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 | |
282becab |
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 | |
7b356ee3 |
43 | static void wait_to(struct timeval *tv_aim) |
35868d35 |
44 | { |
35868d35 |
45 | struct timeval tv_now; |
7b356ee3 |
46 | int diff; |
35868d35 |
47 | |
7b356ee3 |
48 | do |
49 | { |
50 | gettimeofday(&tv_now, 0); |
51 | diff = tvdiff((*tv_aim), tv_now); |
35868d35 |
52 | } |
7b356ee3 |
53 | while (diff > 0); |
54 | } |
35868d35 |
55 | |
7b356ee3 |
56 | #include <stdio.h> |
57 | void SpeedThrottle(void) |
58 | { |
59 | struct timeval tv_now, tv_aim; |
282becab |
60 | int frame_time = PAL ? 19997 : 16639; // ~50.007, 19.997 ms/frame : ~60.1, 16.639 ms/frame |
7b356ee3 |
61 | int tdiff; |
62 | |
63 | tv_aim = tv_prev; |
282becab |
64 | tvadd(tv_aim, frame_time); |
35868d35 |
65 | |
7b356ee3 |
66 | gettimeofday(&tv_now, 0); |
67 | tdiff = tvdiff(tv_now, tv_aim); |
35868d35 |
68 | |
69 | #ifdef FRAMESKIP |
b2b95d2e |
70 | if (Settings.frameskip >= 0) |
35868d35 |
71 | { |
b2b95d2e |
72 | if (skip_count >= Settings.frameskip) |
35868d35 |
73 | skip_count = 0; |
74 | else { |
75 | skip_count++; |
76 | FSkip = 1; |
77 | } |
78 | } |
282becab |
79 | else if (tdiff >= frame_time) |
35868d35 |
80 | { |
81 | /* auto frameskip */ |
282becab |
82 | if (/*tdiff < 36*1024 &&*/ skip_count < 6) { // limit frameskip |
7b356ee3 |
83 | FSkip = 1; |
282becab |
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 |
35868d35 |
92 | return; |
93 | } |
282becab |
94 | else |
95 | skip_count = 0; |
35868d35 |
96 | #endif |
97 | |
7b356ee3 |
98 | /* throttle */ |
99 | if (tdiff < 0) |
35868d35 |
100 | { |
7b356ee3 |
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 | } |
35868d35 |
117 | } |
7b356ee3 |
118 | |
119 | tv_prev = tv_aim; |
35868d35 |
120 | } |
35868d35 |
121 | |