aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/sfx/time.cpp
blob: 0063b8ef6591e9e78f12c7b415dbd2410415ec74 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/***************************************************************************
 time.c  Copyright (C) 2003 Christoph Reichenbach


 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public Licence as
 published by the Free Software Foundaton; either version 2 of the
 Licence, or (at your option) any later version.

 It is distributed in the hope that it will be useful, but
 WITHOUT ANY WARRANTY; without even the implied warranty of
 merchantibility or fitness for a particular purpose. See the
 GNU General Public Licence for more details.

 You should have received a copy of the GNU General Public Licence
 along with this program; see the file COPYING. If not, write to
 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.


 Please contact the maintainer for any program-related bug reports or
 inquiries.

 Current Maintainer:

    Christoph Reichenbach (CR) <jameson@linuxgames.com>

***************************************************************************/

#include "sci/include/sfx_time.h"
#include "sci/include/resource.h"

sfx_timestamp_t
sfx_new_timestamp(long secs, long usecs, int frame_rate)
{
	sfx_timestamp_t r;
	r.secs = secs;
	r.usecs = usecs;
	r.frame_rate = frame_rate;
	r.frame_offset = 0;

	return r;
}


sfx_timestamp_t
sfx_timestamp_add(sfx_timestamp_t timestamp, int frames)
{
	timestamp.frame_offset += frames;

	if (timestamp.frame_offset < 0) {
		int secsub = 1 + (-timestamp.frame_offset / timestamp.frame_rate);

		timestamp.frame_offset += timestamp.frame_rate * secsub;
		timestamp.secs -= secsub;
	}

	timestamp.secs += (timestamp.frame_offset / timestamp.frame_rate);
	timestamp.frame_offset %= timestamp.frame_rate;

	return timestamp;
}

int
sfx_timestamp_frame_diff(sfx_timestamp_t a, sfx_timestamp_t b)
{
	long usecdelta = 0;

	if (a.frame_rate != b.frame_rate) {
		fprintf(stderr, "Fatal: The semantics of subtracting two timestamps with a different base from each other is not defined!\n");
		BREAKPOINT();
	}

	if (a.usecs != b.usecs) {
#if (SIZEOF_LONG >= 8)
		usecdelta = (a.usecs * a.frame_rate) / 1000000
			- (b.usecs * b.frame_rate) / 1000000;
#else
		usecdelta = ((a.usecs/1000) * a.frame_rate) / 1000
			- ((b.usecs/1000) * b.frame_rate) / 1000;
#endif
	}

	return usecdelta
		+ (a.secs - b.secs) * a.frame_rate
		+ a.frame_offset - b.frame_offset;
}

long
sfx_timestamp_usecs_diff(sfx_timestamp_t t1, sfx_timestamp_t t2)
{
	long secs1, secs2;
	long usecs1, usecs2;

	sfx_timestamp_gettime(&t1, &secs1, &usecs1);
	sfx_timestamp_gettime(&t2, &secs2, &usecs2);

	return (usecs1 - usecs2) + ((secs1 - secs2) * 1000000);
} 

sfx_timestamp_t
sfx_timestamp_renormalise(sfx_timestamp_t timestamp, int new_freq)
{
	sfx_timestamp_t r;
	sfx_timestamp_gettime(&timestamp, &r.secs, &r.usecs);
	r.frame_rate = new_freq;
	r.frame_offset = 0;

	return r;
}

void
sfx_timestamp_gettime(sfx_timestamp_t *timestamp, long *secs, long *usecs)
{
	long ust = timestamp->usecs;
	/* On 64 bit machines, we can do an accurate computation */
#if (SIZEOF_LONG >= 8)
	ust += (timestamp->frame_offset * 1000000l) / (timestamp->frame_rate);
#else
	ust += (timestamp->frame_offset * 1000l) / (timestamp->frame_rate / 1000l);
#endif

	if (ust > 1000000) {
		ust -= 1000000;
		*secs = timestamp->secs + 1;
	} else
		*secs = timestamp->secs;

	*usecs = ust;
}