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