b6b628ce392f3099498dd58f54b31b3b25b750ec
[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 #if 0
7 static uint64 tfreq;
8 static uint64 desiredfps;
9
10 void RefreshThrottleFPS(void)
11 {
12  uint64 f=FCEUI_GetDesiredFPS();
13  // great, a bit faster than before
14  //f = (f*65) >> 6;
15  desiredfps=f>>8;
16  tfreq=1000000;
17  tfreq<<=16;    /* Adjustment for fps returned from FCEUI_GetDesiredFPS(). */
18 }
19
20 static uint64 GetCurTime(void)
21 {
22  uint64 ret;
23  struct timeval tv;
24
25  gettimeofday(&tv,0);
26  ret=(uint64)tv.tv_sec*1000000;
27  ret+=tv.tv_usec;
28  return(ret);
29 }
30
31 INLINE void SpeedThrottle(void)
32 {
33  static uint64 ttime,ltime;
34
35  waiter:
36
37  ttime=GetCurTime();
38
39  if( (ttime-ltime) < (tfreq/desiredfps) )
40  {
41   goto waiter;
42  }
43  if( (ttime-ltime) >= (tfreq*4/desiredfps))
44   ltime=ttime;
45  else
46   ltime+=tfreq/desiredfps;
47 }
48
49 #else
50
51 extern uint8 PAL;
52 extern int FSkip;
53 static int usec_aim = 0, usec_done = 0;
54 static int skip_count = 0;
55
56 INLINE void SpeedThrottle(void)
57 {
58         static struct timeval tv_prev;
59         struct timeval tv_now;
60         int delta_nom = PAL ? 19997 : 16639; // ~50.007, 19.997 ms/frame : ~60.1, 16.639 ms/frame
61
62
63         if (usec_done == 0) { // first time
64                 usec_done = 1;
65                 gettimeofday(&tv_prev, 0);
66                 return;
67         }
68
69         gettimeofday(&tv_now, 0);
70
71         usec_aim += delta_nom;
72         if (tv_now.tv_sec != tv_prev.tv_sec)
73                 usec_done += 1000000;
74         usec_done += tv_now.tv_usec - tv_prev.tv_usec;
75
76 #ifdef FRAMESKIP
77         if (Settings.frameskip >= 0)
78         {
79                 if (skip_count >= Settings.frameskip)
80                         skip_count = 0;
81                 else {
82                         skip_count++;
83                         FSkip = 1;
84                 }
85         }
86         else if (usec_done > usec_aim + 1024*4)
87         {
88                 /* auto frameskip */
89                 if (usec_done - usec_aim > 1024*32)
90                         usec_done = usec_aim = 1; // too much behind, try to recover..
91                 else
92                         FSkip = 1;
93                 tv_prev = tv_now;
94                 return;
95         }
96 #endif
97
98         tv_prev = tv_now;
99         while (usec_done < usec_aim)
100         {
101                 gettimeofday(&tv_now, 0);
102
103                 if (tv_now.tv_sec != tv_prev.tv_sec)
104                         usec_done += 1000000;
105                 usec_done += tv_now.tv_usec - tv_prev.tv_usec;
106                 tv_prev = tv_now;
107         }
108         usec_done = usec_done - usec_aim + 1; // reset to prevent overflows
109         usec_aim = 0;
110 }
111 #endif
112