1 /* OpenCP Module Player
2 * copyright (c) '94-'10 Niklas Beisert <nbeisert@physik.tu-muenchen.de>
3 * copyright (c) '04-'21 Stian Skjelstad <stian.skjelstad@gmail.com>
4 *
5 * Frames per second lock
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 *
21 * revision history: (please note changes here)
22 * -ss050118 Stian Skjelstad <stian@nixia.no>
23 * -first release
24 */
25
26 #include "config.h"
27 #include "types.h"
28 #include <sys/time.h>
29 #include <unistd.h>
30 #include "boot/plinkman.h"
31 #include "boot/psetting.h"
32 #include "filesel/pfilesel.h"
33 #include "stuff/err.h"
34 #include "framelock.h"
35 #ifdef DISABLE_SIGALRM
36 #include "timer.h"
37 #endif
38
39 static int Current = 0;
40 static int PendingPoll = 0;
41 int fsFPS=25;
42 int fsFPSCurrent=0;
43
44 static struct timeval target = {0, 0};
45 static struct timeval curr;
46
fpsInit(void)47 static void __attribute__((constructor))fpsInit(void)
48 {
49 fsFPS=cfGetProfileInt("screen", "fps", 20, 0);
50 if (fsFPS<=0)
51 fsFPS=20;
52 }
53
framelock(void)54 void framelock(void)
55 {
56 PendingPoll = 0;
57 rerun:
58 gettimeofday(&curr, 0);
59 if (curr.tv_sec!=target.tv_sec)
60 {
61 fsFPSCurrent=Current;
62 Current=1;
63 target.tv_sec=curr.tv_sec;
64 target.tv_usec=1000000/fsFPS;
65 return;
66 } else if (curr.tv_usec<target.tv_usec)
67 {
68 usleep(target.tv_usec-curr.tv_usec);
69 goto rerun;
70 }
71 target.tv_usec+=1000000/fsFPS;
72
73 #ifdef DISABLE_SIGALRM
74 tmTimerHandler();
75 #endif
76 Current++;
77 }
78
preemptive_framelock(void)79 void preemptive_framelock (void)
80 {
81 gettimeofday(&curr, 0);
82 if (curr.tv_sec!=target.tv_sec)
83 {
84 fsFPSCurrent=Current;
85 Current=1;
86 target.tv_sec=curr.tv_sec;
87 target.tv_usec=1000000/fsFPS;
88 PendingPoll = 1;
89 return;
90 } else if (curr.tv_usec<target.tv_usec)
91 {
92 return; /* we were suppose to sleep */
93 }
94 target.tv_usec+=1000000/fsFPS;
95
96 #ifdef DISABLE_SIGALRM
97 tmTimerHandler();
98 #endif
99 Current++;
100 PendingPoll = 1;
101 }
102
poll_framelock(void)103 int poll_framelock(void)
104 {
105 gettimeofday(&curr, 0);
106 if (curr.tv_sec!=target.tv_sec)
107 {
108 fsFPSCurrent=Current;
109 Current=1;
110 target.tv_sec=curr.tv_sec;
111 target.tv_usec=1000000/fsFPS;
112 PendingPoll = 0;
113 return 1;
114 } else if (curr.tv_usec<target.tv_usec)
115 {
116 if (PendingPoll)
117 {
118 PendingPoll = 0;
119 return 1;
120 }
121 return 0; /* we were suppose to sleep */
122 }
123 target.tv_usec+=1000000/fsFPS;
124
125 #ifdef DISABLE_SIGALRM
126 tmTimerHandler();
127 #endif
128 Current++;
129 PendingPoll = 0;
130 return 1;
131 }
132