Function to calculate FPS with another FPS
#1
In another post I asked for help in how to determine slower frame rates within a master frame rate for a Pac-Man clone I'm working on. DSMan decoded some of the original Ms. Pac-Man assembly code to reveal how it was being accomplished.

I took that idea and created a function that will determine any frame rate within a master frame rate up to 60 FPS. The function and demo code created to show the function in action are below. With this function you can change the frame rate of a game at any time and still maintain any object's desired slower frame rate.

There is an anomaly in the slope that you'll see as it is drawn. I'm not really sure what to make of this? Any ideas?

Code: (Select All)
' Getting slower frame rates within a master frame rate

DIM F(60) AS INTEGER '           frame counters
DIM FramesPerSecond AS INTEGER ' game's frames per second
DIM Dummy AS INTEGER '           used to set intital data
DIM Frame AS INTEGER '           frame counter
DIM Wipe AS INTEGER '            trigger a clearing of frame counters
DIM x AS INTEGER '               cycle through 1 to FramesPerSecond

'+--------------+
'+ Example code |
'+--------------+

Frame = 0 '                                                         reset frame counter
FramesPerSecond = 60 '                                              set game FPS
SCREEN _NEWIMAGE(640, 480, 32) '                                    create graphics screen
DO '                                                                begin various FPS loop
    Dummy = FPS(-1, FramesPerSecond) '                              create frame data set
    DO '                                                            begin demo loop
        _LIMIT FramesPerSecond '                                    limit loop to game's frame rate
        CLS '                                                       clear the screen
        LOCATE 2, 2: PRINT "Counting down from 60 FPS to 1 FPS" '   inform user of progress
        LOCATE 3, 2: PRINT "Frames per second ="; FramesPerSecond
        LOCATE 4, 1: PRINT INT(Frame / FramesPerSecond) + 1; "of 5 seconds elapsed"
        Frame = Frame + 1 '                                         increment game frame counter
        Wipe = 0 '                                                  reset frame counter wipe trigger
        IF Frame = FramesPerSecond * 5 THEN Frame = 0: Wipe = -1 '  when 5 seconds has elapsed reset frame counter and trigger a wipe
        FOR x = 1 TO FramesPerSecond '                              cycle through all available frame rates
            IF Wipe THEN F(x) = 0 '                                 clear frame counter if wipe triggered
            IF FPS(x, Frame) THEN F(x) = F(x) + 1 '                 is this frame rate's frame active during this frame in the game?
            LINE (10, 200 - x * 2)-(10 + F(x), 200 - x * 2) '       yes, draw a line showing progress of frames counted
        NEXT x
        _DISPLAY '                                                  update the screen with changes
    LOOP UNTIL Wipe OR _KEYDOWN(27) '                               leave when user presses the ESC key or a wipe triggered
    FramesPerSecond = FramesPerSecond - 1 '                         decrease the game's frames per second
    IF FramesPerSecond < 1 THEN FramesPerSecond = 60 '              reset the game's frame rate when needed
LOOP UNTIL _KEYDOWN(27) '                                           leave when user presses the ESC key
SYSTEM '                                                            return to the operating system

'--------------------------------------------------------------------------------------------------------------------------------------------+-----+
FUNCTION FPS (TargetFPS AS INTEGER, Frame AS INTEGER) STATIC '                                                                               | FPS |
    '+---------------------------------------------------------------------------------------------------------------------------------------+-----+
    '| Returns frame rates embedded in a master frame rate                                                                                         |
    '|                                                                                                                                             |
    '| Usage:   dummy   = FPS(-1, 60)           When the target FPS is less than 1 a new data set is created for the requested frame rate          |
    '|          MoveNow = FPS(24, InputFrame)   Will return -1 (TRUE) if input frame is on during the target frame rate                            |
    '|                                                                                                                                             |
    '| Example: IF FPS(Object.FPS, GameFrame) then Move(Object)  Move the object if the object's frame is on within the game's current frame count |
    '+---------------------------------------------------------------------------------------------------------------------------------------------+

    DIM f AS INTEGER '                                  frame counter/value
    DIM b AS SINGLE '                                   bit counter/step rate
    DIM FramesCreated AS INTEGER '                      numer of frames calculated

    IF TargetFPS < 1 THEN '                             calculate frame counters?
        REDIM FPSnum(Frame) AS _UNSIGNED _INTEGER64 '   yes, resize 64bit value array
        REDIM Bit(Frame) AS _UNSIGNED _INTEGER64 '      resize bit value array
        FOR b = 1 TO Frame '                            cycle through bit values
            Bit(b) = 2 ^ (b - 1) '                      calculate value of each bit
        NEXT b
        FOR f = 1 TO Frame '                            cycle through requested frames
            FOR b = 1 TO Frame STEP (Frame / f) '       cycle through bits at current frames per second
                FPSnum(f) = FPSnum(f) + Bit(b) '        calculate which bits are turned on
            NEXT b
        NEXT f
        FramesCreated = Frame '                         remember number of frames created
        EXIT FUNCTION '                                 leave function
    END IF
    IF FramesCreated = 0 THEN EXIT FUNCTION '           no data created yet, leave
    f = Frame '                                         don't modify input value
    IF f < 1 THEN EXIT FUNCTION '                       invalid frame number requested, leave
    IF f > FramesCreated THEN f = f MOD FramesCreated ' keep frame number within range
    IF FPSnum(TargetFPS) AND Bit(f) THEN FPS = -1 '     report if bit is on for current frame in requested FPS

END FUNCTION
'---------------------------------------------------------------------------------------------------------------------------------------------------
Reply




Users browsing this thread: 2 Guest(s)