Browse Source

Implemented real-time clock, allowing for precise timekeeping and framerate-independent game updates.

tess_experiment
Nico de Poel 3 years ago
parent
commit
a94ec5dc33
  1. 2
      display.c
  2. 3
      main.c
  3. 67
      time.c
  4. 35
      time.h

2
display.c

@ -55,7 +55,7 @@ void display_init()
// ISR subsystem to the kernel
ResetGraph(0);
SetVideoMode(MODE_NTSC);
//SetVideoMode(MODE_NTSC);
// Define display environments, first on top and second on bottom
SetDefDispEnv(&disp[0], 0, 0, SCREENWIDTH, SCREENHEIGHT);

3
main.c

@ -24,9 +24,9 @@ world_t world;
// Init function
void init(void)
{
time_init();
input_init();
display_init();
time_init();
//asset_loadTexture(tim_e1m1, NULL);
@ -49,6 +49,7 @@ int main(int argc, const char *argv[])
// Draw stuff
world_draw(&world);
FntPrint(-1, "Time: %d, ticks = %d, delta time = %d, fps = %d\n", time_getRealTime() >> 12, time_getFrameNumber(), time_getDeltaTime(), time_getFrameRate() >> 8);
FntPrint(-1, "Camera pos = (%d, %d, %d) rot = (%d, %d, %d)\n", cam_pos.vx, cam_pos.vy, cam_pos.vz, cam_rot.vx, cam_rot.vy, cam_rot.vz);
FntFlush(-1);

67
time.c

@ -1,19 +1,82 @@
#include "common.h"
#include "time.h"
static int frameNumber;
#include <hwregs_c.h>
static volatile u_long realTime; // Real time in 20,12 format (4096 ticks per second)
static u_long frameNumber; // Number of game ticks
static u_long frameStartTime; // Real time at which the current frame began
static u_short frameDeltaTime; // Real time since last game tick in 4,12 format
static u_short avgFrameRate; // Average framerate over the last 16 frames in 8,8 format
static u_long measureStartTime;
static void timer_callback()
{
realTime += 4;
}
void time_init()
{
realTime = 0;
frameNumber = 0;
frameStartTime = 0;
frameDeltaTime = 1; // Prevent division by zero for any code using this number on the first frame
avgFrameRate = 0;
measureStartTime = 0;
// Set the timer such that we get exactly 1024 interrupts per second on both PAL and NTSC (roughly once per millisecond)
// This allows the game speed to be completely framerate and video mode independent
const int counter = 4096;
EnterCriticalSection();
SetRCnt(RCntCNT2, counter, RCntMdINTR);
TIMER_CTRL(2) = 0x1E58;
InterruptCallback(6, timer_callback);
StartRCnt(RCntCNT2);
ChangeClearRCnt(2, 0);
ExitCriticalSection();
}
void time_tick()
{
++frameNumber;
u_long currTime = realTime;
if ((frameNumber & 0xF) == 0)
{
avgFrameRate = (u_short)((0x10 << 20) / (currTime - measureStartTime));
measureStartTime = currTime;
}
frameDeltaTime = (u_short)(currTime - frameStartTime);
// Start the next frame
frameStartTime = currTime;
}
int time_getFrameNumber()
u_long time_getRealTime()
{
return realTime;
}
u_long time_getFrameNumber()
{
return frameNumber;
}
u_long time_getFrameTime()
{
return frameStartTime;
}
u_short time_getDeltaTime()
{
return frameDeltaTime;
}
u_short time_getFrameRate()
{
return avgFrameRate;
}

35
time.h

@ -4,6 +4,39 @@
void time_init();
void time_tick();
int time_getFrameNumber();
/**
* @brief Get the real-time clock value.
* Note that this value will constantly update and change, so don't expect this value to remain consistent during a single frame.
* @return The real-time clock value in 20,12 format.
*/
u_long time_getRealTime();
/**
* @brief Get the current frame count.
* This is the number of frames that were counted, i.e. the number of main loop iterations since application start.
* @return The current frame's number in 32,0 format.
*/
u_long time_getFrameNumber();
/**
* @brief Get the current frame start time.
* The real-time value at which the current frame was started. Unlike time_getRealTime(), this value remains consistent for the entire frame.
* @return The current frame's start time in 20,12 format.
*/
u_long time_getFrameTime();
/**
* @brief Get the delta time between frames.
* The amount of real time passed between the last frame and the current frame. Use this for framerate-independent time stepping.
* @return The frame delta time in 4,12 format.
*/
u_short time_getDeltaTime();
/**
* @brief Get the average frame rate.
* The average framerate calculated over 16 frames. This gets updated periodically so isn't always entirely current.
* @return The average frame rate in 8,8 format.
*/
u_short time_getFrameRate();
#endif // __TIME_H__
Loading…
Cancel
Save