here is a code that can handle your fps, it's originally from SDL_gfx by ferzkopp
The file is SDL_framerate.c
Here is the include file
FPS_Manager.pbi :
Code: Select all
; From SDL_gfx by ferzkopp
; SDL_framerate.c
; http://www.ferzkopp.net/Software/SDL_gfx-2.0/
;-CONSTANTS
; Highest possible rate supported by framerate controller in Hz (1/s).
#FPS_UPPER_LIMIT = 200
; Lowest possible rate supported by framerate controller in Hz (1/s).
#FPS_LOWER_LIMIT = 1
; Default rate of framerate controller in Hz (1/s).
#FPS_DEFAULT = 30
;-METHOD
Interface FPSObject
FPS_setFramerate.i(__rate)
FPS_getFramerate.i()
FPS_getFramecount.i()
FPS_framerateDelay.i()
EndInterface
;-TEMPLATE
; Structure holding the state and timing information of the framerate controller.
Structure FPSmanager
*vTable
obj.FPSObject ; To be able to call class inside class
; Private
framecount.i
rateticks.f
baseticks.i
lastticks.i
rate.i
EndStructure
;-DECLARE
Declare.i FPS_initFramerate()
Declare.i CLASS_setFramerate(*manager.FPSmanager, __rate.i)
Declare.i CLASS_getFramerate(*manager.FPSmanager)
Declare.i CLASS_getFramecount(*manager.FPSmanager)
Declare.i CLASS_framerateDelay(*manager.FPSmanager)
;-VIRTUAL TABLES
DataSection
VTable_FPSClass:
Data.i @CLASS_setFramerate()
Data.i @CLASS_getFramerate()
Data.i @CLASS_getFramecount()
Data.i @CLASS_framerateDelay()
EndDataSection
;-INTERNAL PROCEDURE
Procedure.i getTicks()
Protected.i _ticks = ElapsedMilliseconds()
If _ticks = 0
ProcedureReturn 1
Else
ProcedureReturn _ticks
EndIf
EndProcedure
;-*************************************************************
;-Initialize framerate manager
; set Default framerate of 30Hz and reset delay interpolation.
; \param manager : Pointer to the framerate manager.
; \return : Pointer for sucess and 0 for error.
Procedure.i FPS_initFramerate()
Protected *manager.FPSManager
*manager = AllocateMemory(SizeOf(FPSmanager))
If *manager
;Need to initialize structure for the call of class inside another class
InitializeStructure(*manager, FPSmanager)
;Make sure the *vTable field points to our virtual table.
*manager\vTable = ?VTable_FPSClass
;now the call of class inside class can be done
*manager\obj = *manager
;Initialise the variables if any
*manager\framecount = 0
*manager\rate = #FPS_DEFAULT
*manager\rateticks = 1000.0 / #FPS_DEFAULT
*manager\baseticks = getTicks()
*manager\lastticks = *manager\baseticks
;Return a pointer to our new object.
ProcedureReturn *manager
Else
ProcedureReturn 0
EndIf
EndProcedure
;-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.
Procedure.i CLASS_setFramerate(*manager.FPSmanager, __rate.i)
If (__rate >= #FPS_LOWER_LIMIT) And (__rate <= #FPS_UPPER_LIMIT)
*manager\framecount = 0
*manager\rate = __rate
*manager\rateticks = 1000.0 / __rate
ProcedureReturn 0
Else
ProcedureReturn -1
EndIf
EndProcedure
;-Return current target framerate
; Get the currently set framerate of the manager in Hz.
; \param manager : Pointer To the framerate manager.
; \return : Current framerate in Hz or -1 for error.
Procedure.i CLASS_getFramerate(*manager.FPSmanager)
If *manager = #Null
ProcedureReturn -1
Else
ProcedureReturn *manager\rate
EndIf
EndProcedure
;-Return 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.
Procedure.i CLASS_getFramecount(*manager.FPSmanager)
If *manager = #Null
ProcedureReturn -1
Else
ProcedureReturn *manager\framecount
EndIf
EndProcedure
;-Delay execution
; 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.
Procedure.i CLASS_framerateDelay(*manager.FPSmanager)
Protected.i _current_ticks
Protected.i _target_ticks
Protected.i _the_delay
Protected.i _time_passed = 0
; No manager, no delay
If *manager = #Null : ProcedureReturn 0 : EndIf
; Initialize uninitialized manager
If *manager\baseticks = 0 : *manager = FPS_initFramerate() : EndIf
; Next frame
*manager\framecount + 1
; Get/calc ticks
_current_ticks = getTicks()
_time_passed = _current_ticks - *manager\lastticks
*manager\lastticks = _current_ticks
_target_ticks = *manager\baseticks + (*manager\framecount * *manager\rateticks)
If _current_ticks <= _target_ticks
_the_delay = _target_ticks - _current_ticks
Delay(_the_delay)
Else
*manager\framecount = 0
*manager\baseticks = getTicks()
EndIf
ProcedureReturn _time_passed
EndProcedure
Code: Select all
XIncludeFile "FPS_Manager.pbi"
; from the sample : TestFramerate.c of SDL_gfx
#scr_WIDTH = 640
#scr_HEIGHT = 480
i=0
x=#scr_WIDTH/2
y=#scr_HEIGHT/2
larg_circle = 60
dx=7
dy=5
time_passed = 0
message.s = ""
message2.s = ""
InitSprite():InitKeyboard()
If OpenWindow(0, 0, 0, #scr_WIDTH, #scr_HEIGHT, "FPS Example", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(0), 0, 0, #scr_WIDTH, #scr_HEIGHT, #True, 0, 0)
If CreateSprite(0, larg_circle, larg_circle) And StartDrawing(SpriteOutput(0))
For Radius = larg_circle/2 To 1 Step -5
Circle(larg_circle/2, larg_circle/2, Radius, RGB(Random(255), Random(255), Random(255)))
Next
StopDrawing()
EndIf
TransparentSpriteColor(0, 0)
; Set our FPS Manager, default:30
fpsm.FPSObject
fpsm = FPS_initFramerate()
rate = fpsm\FPS_getFramerate()
message = "Framerate set to "+Str(rate)+" Hz ..."
Repeat
Repeat
Event = WindowEvent()
Select Event
Case #PB_Event_Gadget
If EventGadget() = 0
quit = 1
EndIf
Case #PB_Event_CloseWindow
quit = 1
EndSelect
Until Event = 0
ExamineKeyboard()
If KeyboardPushed(#PB_Key_Escape) : quit = 1 : EndIf
i - 1
If i<0
; Set new rate
rate=5+5*(Random(100) % 10)
fpsm\FPS_setFramerate(rate)
message = "Framerate set to "+Str(rate)+" Hz ..."
; New timeout
i=2*rate
EndIf
ClearScreen(0)
StartDrawing(ScreenOutput())
DrawText(#scr_WIDTH/2-4*Len(message),#scr_HEIGHT-15,message)
If time_passed > 0
message2 = "Delay is "+Str(time_passed)+" ms / Measured framerate "+Str(1000/time_passed)+" Hz ..."
DrawText(#scr_WIDTH/2-4*Len(message2),#scr_HEIGHT-30,message2)
EndIf
StopDrawing()
; Move
x + dx
y + dy
; Reflect
If x<0 Or x>#scr_WIDTH-larg_circle : dx = -dx : EndIf
If y<0 Or y>#scr_HEIGHT-larg_circle : dy = -dy : EndIf
DisplayTransparentSprite(0, x, y)
FlipBuffers()
time_passed = fpsm\FPS_framerateDelay()
Until Quit = 1
EndIf