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