File: sdltimer.c

package info (click to toggle)
tworld 1.3.0-5
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 6,620 kB
  • ctags: 1,407
  • sloc: ansic: 12,442; perl: 2,465; makefile: 191; sh: 16
file content (134 lines) | stat: -rw-r--r-- 2,896 bytes parent folder | download | duplicates (6)
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
132
133
134
/* sdltimer.c: Game timing functions.
 *
 * Copyright (C) 2001-2006 by Brian Raiter, under the GNU General Public
 * License. No warranty. See COPYING for details.
 */

#include	<stdlib.h>
#include	"SDL.h"
#include	"sdlgen.h"

/* By default, a second of game time lasts for 1000 milliseconds of
 * real time.
 */
static int	mspertick = 1000 / TICKS_PER_SECOND;

/* The tick counter.
 */
static int	utick = 0;

/* The time of the next tick.
 */
static int	nexttickat = 0;

/* A histogram of how many milliseconds the program spends sleeping
 * per tick.
 */
static int	showhistogram = FALSE;
static unsigned	hist[100];

/* Set the length (in real time) of a second of game time. A value of
 * zero selects the default length of one second.
 */
void settimersecond(int ms)
{
    mspertick = (ms ? ms : 1000) / TICKS_PER_SECOND;
}

/* Change the current timer setting. If action is positive, the timer
 * is started (or resumed). If action is negative, the timer is
 * stopped if it is running and the counter is reset to zero. If
 * action is zero, the timer is stopped if it is running, and the
 * counter remains at its current setting.
 */
void settimer(int action)
{
    if (action < 0) {
	nexttickat = 0;
	utick = 0;
    } else if (action > 0) {
	if (nexttickat < 0)
	    nexttickat = SDL_GetTicks() - nexttickat;
	else
	    nexttickat = SDL_GetTicks() + mspertick;
    } else {
	if (nexttickat > 0)
	    nexttickat = SDL_GetTicks() - nexttickat;
    }
}

/* Return the number of ticks since the timer was last reset.
 */
int gettickcount(void)
{
    return (int)utick;
}

/* Put the program to sleep until the next timer tick. If we've
 * already missed a timer tick, then wait for the next one.
 */
int waitfortick(void)
{
    int	ms;

    ms = nexttickat - SDL_GetTicks();
    if (showhistogram)
	if (ms < (int)(sizeof hist / sizeof *hist))
	    ++hist[ms >= 0 ? ms + 1 : 0];

    if (ms <= 0) {
	++utick;
	nexttickat += mspertick;
	return FALSE;
    }

    while (ms < 0)
	ms += mspertick;

    SDL_Delay(ms);

    ++utick;
    nexttickat += mspertick;
    return TRUE;
}

/* Move to the next timer tick without waiting.
 */
int advancetick(void)
{
    return ++utick;
}

/* At shutdown time, display the histogram data on stdout.
 */
static void shutdown(void)
{
    unsigned long	n;
    int			i;

    settimer(-1);

    if (showhistogram) {
	n = 0;
	for (i = 0 ; i < (int)(sizeof hist / sizeof *hist) ; ++i)
	    n += hist[i];
	if (n) {
	    printf("Histogram of idle time (ms/tick)\n");
	    if (hist[0])
		printf("NEG: %.1f%%\n", (hist[0] * 100.0) / n);
	    for (i = 1 ; i < (int)(sizeof hist / sizeof *hist) ; ++i)
		if (hist[i])
		    printf("%3d: %.1f%%\n", i - 1, (hist[i] * 100.0) / n);
	}
    }
}

/* Initialize and reset the timer.
 */
int _sdltimerinitialize(int _showhistogram)
{
    showhistogram = _showhistogram;
    atexit(shutdown);
    settimer(-1);
    return TRUE;
}