I noticed on the
BP.org site a thread about controlling the frame rate of animated graphics. The Script BASIC
SDL_gfx extension module supports defining a frame rate and maintaining it.
The framerate functions are used to insert delays into the graphics loop to maintain a constant framerate.
The implementation is more sophisticated that the usual SDL_Delay(1000/FPS); call since these functions keep track of the desired game time per frame for a linearly interpolated sequence of future timing points of each frame. This is done to avoid rounding errors from the inherent instability in the delay generation and application - i.e. the 100th frame of a game running at 50Hz will be accurately 2.00sec after the 1st frame (if the machine can keep up with the drawing).
Interface
The functions return 0 or value for sucess and -1 for error. All functions use a pointer to a framerate-manager variable to operate.
void SDL_initFramerate(FPSmanager * manager);
Initialize the framerate manager, set default framerate of 30Hz and reset delay interpolation.
int SDL_setFramerate(FPSmanager * manager, int rate);
Set a new framerate for the manager and reset delay interpolation.
int SDL_getFramerate(FPSmanager * manager);
Get the currently set framerate of the manager.
void SDL_framerateDelay(FPSmanager * manager);
Generate a delay to accommodate 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.
' ScriptBasic GFX - Frame rate controlled circles
IMPORT gfx.inc
scrn = gfx::Window(640, 480, "ScriptBasic GFX - FPS Circles")
' Random Value Arrays
RANDOMIZE(gfx::Time())
FOR i = 0 TO 512
rx[i] = RND() % 640
ry[i] = 60 + RND() % 480 - 80
rz[i] = RND() % 64
rr[i] = RND() AND 255
rg[i] = RND() AND 255
rb[i] = RND() AND 255
af = rx[i] / 640
ra[i] = INT(255 * af)
NEXT
gfx::SDL_initFramerate
i = 0
REPEAT
gfx::filledCircleRGBA scrn, rx[i], ry[i], rz[i], rr[i], rg[i], rb[i], 255
i += 1
IF i > 512 THEN i = 0
gfx::Update
gfx::SDL_framerateDelay
gfx::stringColor scrn, 20, 15,"FPS: " & gfx::SDL_getFramerate() & CHR(0), 0xffffffff
UNTIL gfx::KeyName(0) = "+escape"
gfx::Close