35868d35 |
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) |
86 | { |
87 | /* auto frameskip */ |
88 | if (usec_done - usec_aim > 150000) |
89 | usec_done = usec_aim = 0; // 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 | |