initial upstream import
[drnoksnes] / frame_skip.cpp
1 #include <unistd.h>
2 #include <sys/time.h>
3 #include <time.h>
4 #include <math.h>
5 #include "frame_skip.h"
6 #include "memmap.h"
7
8 #ifndef uclock_t
9 #define uclock_t unsigned int
10 #endif
11
12 #define TICKS_PER_SEC 1000000UL
13 //#define CPU_FPS 60
14 static int CPU_FPS=60;
15 static uclock_t F;
16
17 #define MAX_FRAMESKIP 10
18
19
20 static char init_frame_skip = 1;
21 char skip_next_frame = 0;
22 static struct timeval init_tv = { 0, 0 };
23
24
25 void reset_frame_skip(void)
26 {
27         //static Uint8 init=0;
28
29         init_tv.tv_usec = 0;
30         init_tv.tv_sec = 0;
31         skip_next_frame = 0;
32         init_frame_skip = 1;
33         CPU_FPS=Memory.ROMFramesPerSecond;
34
35         F = (uclock_t) ((double) TICKS_PER_SEC / CPU_FPS);
36 }
37
38 uclock_t get_ticks(void)
39 {
40         struct timeval tv;
41
42         gettimeofday(&tv, 0);
43         if (init_tv.tv_sec == 0)
44                 init_tv = tv;
45         return (tv.tv_sec - init_tv.tv_sec) * TICKS_PER_SEC + tv.tv_usec -
46                 init_tv.tv_usec;
47
48
49 }
50
51 int frame_skip(void)
52 {
53         static int f2skip;
54         static uclock_t sec = 0;
55         static uclock_t rfd;
56         static uclock_t target;
57         static int nbFrame = 0;
58         static int skpFrm = 0;
59
60         if (init_frame_skip) {
61                 init_frame_skip = 0;
62                 target = get_ticks();
63                 nbFrame = 0;
64                 //f2skip=0;
65                 //skpFrm=0;
66                 sec = 0;
67                 return 0;
68         }
69
70         target += F;
71         if (f2skip > 0) {
72                 f2skip--;
73                 skpFrm++;
74                 return 1;
75         } else
76                 skpFrm = 0;
77
78
79         rfd = get_ticks();
80
81         if (rfd < target && f2skip == 0) {
82                 while (get_ticks() < target);
83         } else {
84                 f2skip = (rfd - target) / (double) F;
85                 if (f2skip > MAX_FRAMESKIP) {
86                         f2skip = MAX_FRAMESKIP;
87                         reset_frame_skip();
88                 }
89                 // printf("Skip %d frame(s) %lu %lu\n",f2skip,target,rfd);
90         }
91         
92
93         nbFrame++;
94         if (get_ticks() - sec >= TICKS_PER_SEC) {
95                 nbFrame = 0;
96                 sec = get_ticks();
97         }
98         return 0;
99 }