~ubuntu-branches/ubuntu/trusty/manaplus/trusty

« back to all changes in this revision

Viewing changes to src/sdl2gfx/SDL2_framerate.c

  • Committer: Package Import Robot
  • Author(s): Patrick Matthäi
  • Date: 2013-11-18 15:19:44 UTC
  • mfrom: (1.1.14)
  • Revision ID: package-import@ubuntu.com-20131118151944-iyd93ut2rmxzp8gg
Tags: 1.3.11.10-1
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 
 
3
SDL_framerate.c: framerate manager
 
4
 
 
5
Copyright (C) 2001-2012  Andreas Schiffler
 
6
 
 
7
This software is provided 'as-is', without any express or implied
 
8
warranty. In no event will the authors be held liable for any damages
 
9
arising from the use of this software.
 
10
 
 
11
Permission is granted to anyone to use this software for any purpose,
 
12
including commercial applications, and to alter it and redistribute it
 
13
freely, subject to the following restrictions:
 
14
 
 
15
1. The origin of this software must not be misrepresented; you must not
 
16
claim that you wrote the original software. If you use this software
 
17
in a product, an acknowledgment in the product documentation would be
 
18
appreciated but is not required.
 
19
 
 
20
2. Altered source versions must be plainly marked as such, and must not be
 
21
misrepresented as being the original software.
 
22
 
 
23
3. This notice may not be removed or altered from any source
 
24
distribution.
 
25
 
 
26
Andreas Schiffler -- aschiffler at ferzkopp dot net
 
27
 
 
28
Changed for ManaPlus (C) 2013  ManaPlus developers
 
29
*/
 
30
 
 
31
#include "SDL2_framerate.h"
 
32
 
 
33
/*!
 
34
\brief Internal wrapper to SDL_GetTicks that ensures a non-zero return value.
 
35
 
 
36
\return The tick count.
 
37
*/
 
38
uint32_t _getTicks()
 
39
{
 
40
    const uint32_t ticks = SDL_GetTicks();
 
41
 
 
42
    /* 
 
43
    * Since baseticks!=0 is used to track initialization
 
44
    * we need to ensure that the tick count is always >0 
 
45
    * since SDL_GetTicks may not have incremented yet and
 
46
    * return 0 depending on the timing of the calls.
 
47
    */
 
48
    if (ticks == 0)
 
49
        return 1;
 
50
    else
 
51
        return ticks;
 
52
}
 
53
 
 
54
/*!
 
55
\brief Initialize the framerate manager.
 
56
 
 
57
Initialize the framerate manager, set default framerate of 30Hz and
 
58
reset delay interpolation.
 
59
 
 
60
\param manager Pointer to the framerate manager.
 
61
*/
 
62
void SDL_initFramerate(FPSmanager *const manager)
 
63
{
 
64
    /*
 
65
    * Store some sane values 
 
66
    */
 
67
    manager->framecount = 0;
 
68
    manager->rate = FPS_DEFAULT;
 
69
    manager->rateticks = (1000.0f / (float) FPS_DEFAULT);
 
70
    manager->baseticks = _getTicks();
 
71
    manager->lastticks = manager->baseticks;
 
72
 
 
73
}
 
74
 
 
75
/*!
 
76
\brief Set the framerate in Hz 
 
77
 
 
78
Sets a new framerate for the manager and reset delay interpolation.
 
79
Rate values must be between FPS_LOWER_LIMIT and FPS_UPPER_LIMIT inclusive to be accepted.
 
80
 
 
81
\param manager Pointer to the framerate manager.
 
82
\param rate The new framerate in Hz (frames per second).
 
83
 
 
84
\return 0 for sucess and -1 for error.
 
85
*/
 
86
int SDL_setFramerate(FPSmanager *const manager, const uint32_t rate)
 
87
{
 
88
    if (rate >= FPS_LOWER_LIMIT && rate <= FPS_UPPER_LIMIT)
 
89
    {
 
90
        manager->framecount = 0;
 
91
        manager->rate = rate;
 
92
        manager->rateticks = (1000.0f / (float) rate);
 
93
        return 0;
 
94
    }
 
95
    else
 
96
    {
 
97
        return -1;
 
98
    }
 
99
}
 
100
 
 
101
/*!
 
102
\brief Return the current target framerate in Hz 
 
103
 
 
104
Get the currently set framerate of the manager.
 
105
 
 
106
\param manager Pointer to the framerate manager.
 
107
 
 
108
\return Current framerate in Hz or -1 for error.
 
109
*/
 
110
int SDL_getFramerate(FPSmanager *const manager)
 
111
{
 
112
    if (!manager)
 
113
        return -1;
 
114
    else
 
115
        return (int)manager->rate;
 
116
}
 
117
 
 
118
/*!
 
119
\brief Return the current framecount.
 
120
 
 
121
Get the current framecount from the framerate manager. 
 
122
A frame is counted each time SDL_framerateDelay is called.
 
123
 
 
124
\param manager Pointer to the framerate manager.
 
125
 
 
126
\return Current frame count or -1 for error.
 
127
*/
 
128
int SDL_getFramecount(FPSmanager *const manager)
 
129
{
 
130
    if (!manager)
 
131
        return -1;
 
132
    else
 
133
        return (int)manager->framecount;
 
134
}
 
135
 
 
136
/*!
 
137
\brief Delay execution to maintain a constant framerate and calculate fps.
 
138
 
 
139
Generate a delay to accomodate currently set framerate. Call once in the
 
140
graphics/rendering loop. If the computer cannot keep up with the rate (i.e.
 
141
drawing too slow), the delay is zero and the delay interpolation is reset.
 
142
 
 
143
\param manager Pointer to the framerate manager.
 
144
 
 
145
\return The time that passed since the last call to the function in ms. May return 0.
 
146
*/
 
147
uint32_t SDL_framerateDelay(FPSmanager *const manager)
 
148
{
 
149
    uint32_t the_delay;
 
150
 
 
151
    /*
 
152
    * No manager, no delay
 
153
    */
 
154
    if (!manager)
 
155
        return 0;
 
156
 
 
157
    /*
 
158
    * Initialize uninitialized manager 
 
159
    */
 
160
    if (manager->baseticks == 0)
 
161
        SDL_initFramerate(manager);
 
162
 
 
163
    /*
 
164
    * Next frame 
 
165
    */
 
166
    manager->framecount ++;
 
167
 
 
168
    /*
 
169
    * Get/calc ticks 
 
170
    */
 
171
    const uint32_t current_ticks = _getTicks();
 
172
    const uint32_t time_passed = current_ticks - manager->lastticks;
 
173
    manager->lastticks = current_ticks;
 
174
    const uint32_t target_ticks = manager->baseticks + (uint32_t)(
 
175
        (float)(manager->framecount) * manager->rateticks);
 
176
 
 
177
    if (current_ticks <= target_ticks)
 
178
    {
 
179
        the_delay = target_ticks - current_ticks;
 
180
        SDL_Delay(the_delay);
 
181
    }
 
182
    else
 
183
    {
 
184
        manager->framecount = 0;
 
185
        manager->baseticks = _getTicks();
 
186
    }
 
187
 
 
188
    return time_passed;
 
189
}