diff options
author | Andrei Karas <akaras@inbox.ru> | 2013-11-05 20:56:20 +0300 |
---|---|---|
committer | Andrei Karas <akaras@inbox.ru> | 2013-11-05 20:56:20 +0300 |
commit | 102a7d4fe6e8874ad7dcdfe085a22b51de22999b (patch) | |
tree | 3dfdb542035ba1f6c871b6901461c81f11b1c6db /src/sdl2gfx/SDL2_framerate.c | |
parent | 0ca79840f3497375591a43b38d520ada03dfb2dd (diff) | |
download | mv-102a7d4fe6e8874ad7dcdfe085a22b51de22999b.tar.gz mv-102a7d4fe6e8874ad7dcdfe085a22b51de22999b.tar.bz2 mv-102a7d4fe6e8874ad7dcdfe085a22b51de22999b.tar.xz mv-102a7d4fe6e8874ad7dcdfe085a22b51de22999b.zip |
add configure option --without-internalsdlgfx for not use emdedded sdl2gfx.
Diffstat (limited to 'src/sdl2gfx/SDL2_framerate.c')
-rw-r--r-- | src/sdl2gfx/SDL2_framerate.c | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/src/sdl2gfx/SDL2_framerate.c b/src/sdl2gfx/SDL2_framerate.c new file mode 100644 index 000000000..b31b0feb2 --- /dev/null +++ b/src/sdl2gfx/SDL2_framerate.c @@ -0,0 +1,189 @@ +/* + +SDL_framerate.c: framerate manager + +Copyright (C) 2001-2012 Andreas Schiffler + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not +claim that you wrote the original software. If you use this software +in a product, an acknowledgment in the product documentation would be +appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and must not be +misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. + +Andreas Schiffler -- aschiffler at ferzkopp dot net + +Changed for ManaPlus (C) 2013 ManaPlus developers +*/ + +#include "SDL2_framerate.h" + +/*! +\brief Internal wrapper to SDL_GetTicks that ensures a non-zero return value. + +\return The tick count. +*/ +uint32_t _getTicks() +{ + const uint32_t ticks = SDL_GetTicks(); + + /* + * Since baseticks!=0 is used to track initialization + * we need to ensure that the tick count is always >0 + * since SDL_GetTicks may not have incremented yet and + * return 0 depending on the timing of the calls. + */ + if (ticks == 0) + return 1; + else + return ticks; +} + +/*! +\brief Initialize the framerate manager. + +Initialize the framerate manager, set default framerate of 30Hz and +reset delay interpolation. + +\param manager Pointer to the framerate manager. +*/ +void SDL_initFramerate(FPSmanager *const manager) +{ + /* + * Store some sane values + */ + manager->framecount = 0; + manager->rate = FPS_DEFAULT; + manager->rateticks = (1000.0f / (float) FPS_DEFAULT); + manager->baseticks = _getTicks(); + manager->lastticks = manager->baseticks; + +} + +/*! +\brief Set the framerate in Hz + +Sets a new framerate for the manager and reset delay interpolation. +Rate values must be between FPS_LOWER_LIMIT and FPS_UPPER_LIMIT inclusive to be accepted. + +\param manager Pointer to the framerate manager. +\param rate The new framerate in Hz (frames per second). + +\return 0 for sucess and -1 for error. +*/ +int SDL_setFramerate(FPSmanager *const manager, const uint32_t rate) +{ + if (rate >= FPS_LOWER_LIMIT && rate <= FPS_UPPER_LIMIT) + { + manager->framecount = 0; + manager->rate = rate; + manager->rateticks = (1000.0f / (float) rate); + return 0; + } + else + { + return -1; + } +} + +/*! +\brief Return the current target framerate in Hz + +Get the currently set framerate of the manager. + +\param manager Pointer to the framerate manager. + +\return Current framerate in Hz or -1 for error. +*/ +int SDL_getFramerate(FPSmanager *const manager) +{ + if (!manager) + return -1; + else + return (int)manager->rate; +} + +/*! +\brief Return the current framecount. + +Get the current framecount from the framerate manager. +A frame is counted each time SDL_framerateDelay is called. + +\param manager Pointer to the framerate manager. + +\return Current frame count or -1 for error. +*/ +int SDL_getFramecount(FPSmanager *const manager) +{ + if (!manager) + return -1; + else + return (int)manager->framecount; +} + +/*! +\brief Delay execution to maintain a constant framerate and calculate fps. + +Generate a delay to accomodate currently set framerate. Call once in the +graphics/rendering loop. If the computer cannot keep up with the rate (i.e. +drawing too slow), the delay is zero and the delay interpolation is reset. + +\param manager Pointer to the framerate manager. + +\return The time that passed since the last call to the function in ms. May return 0. +*/ +uint32_t SDL_framerateDelay(FPSmanager *const manager) +{ + uint32_t the_delay; + + /* + * No manager, no delay + */ + if (!manager) + return 0; + + /* + * Initialize uninitialized manager + */ + if (manager->baseticks == 0) + SDL_initFramerate(manager); + + /* + * Next frame + */ + manager->framecount ++; + + /* + * Get/calc ticks + */ + const uint32_t current_ticks = _getTicks(); + const uint32_t time_passed = current_ticks - manager->lastticks; + manager->lastticks = current_ticks; + const uint32_t target_ticks = manager->baseticks + (uint32_t)( + (float)(manager->framecount) * manager->rateticks); + + if (current_ticks <= target_ticks) + { + the_delay = target_ticks - current_ticks; + SDL_Delay(the_delay); + } + else + { + manager->framecount = 0; + manager->baseticks = _getTicks(); + } + + return time_passed; +} |