c52eb6857876df0f8562d81ed1a18d9cc0267372
[fceu.git] / drivers / gp2x / throttle.c
1 #include <sys/time.h>
2 #include "main.h"
3 #include "gp2x.h"
4 #include "throttle.h"
5
6
7 extern uint8 PAL;
8 extern int FSkip;
9 static int usec_aim = 0, usec_done = 0;
10 static int skip_count = 0;
11
12 void RefreshThrottleFPS(void)
13 {
14         usec_aim = usec_done = skip_count = 0;
15 }
16
17 void SpeedThrottle(void)
18 {
19         static struct timeval tv_prev;
20         struct timeval tv_now;
21         int delta_nom = PAL ? 19997 : 16639; // ~50.007, 19.997 ms/frame : ~60.1, 16.639 ms/frame
22
23
24         if (usec_done == 0) { // first time
25                 usec_done = 1;
26                 gettimeofday(&tv_prev, 0);
27                 return;
28         }
29
30         gettimeofday(&tv_now, 0);
31
32         usec_aim += delta_nom;
33         if (tv_now.tv_sec != tv_prev.tv_sec)
34                 usec_done += 1000000;
35         usec_done += tv_now.tv_usec - tv_prev.tv_usec;
36
37 #ifdef FRAMESKIP
38         if (Settings.frameskip >= 0)
39         {
40                 if (skip_count >= Settings.frameskip)
41                         skip_count = 0;
42                 else {
43                         skip_count++;
44                         FSkip = 1;
45                 }
46         }
47         else if (usec_done > usec_aim + 1024*4)
48         {
49                 /* auto frameskip */
50                 if (usec_done - usec_aim > 1024*32)
51                         usec_done = usec_aim = 1; // too much behind, try to recover..
52                 else
53                         FSkip = 1;
54                 tv_prev = tv_now;
55                 return;
56         }
57 #endif
58
59         tv_prev = tv_now;
60         while (usec_done < usec_aim)
61         {
62                 gettimeofday(&tv_now, 0);
63
64                 if (tv_now.tv_sec != tv_prev.tv_sec)
65                         usec_done += 1000000;
66                 usec_done += tv_now.tv_usec - tv_prev.tv_usec;
67                 tv_prev = tv_now;
68         }
69         usec_done = usec_done - usec_aim + 1; // reset to prevent overflows
70         usec_aim = 0;
71 }
72