Browse Source
Implemented real-time clock, allowing for precise timekeeping and framerate-independent game updates.
tess_experiment
Implemented real-time clock, allowing for precise timekeeping and framerate-independent game updates.
tess_experiment
4 changed files with 102 additions and 5 deletions
@ -1,19 +1,82 @@ |
|||||
#include "common.h" |
#include "common.h" |
||||
#include "time.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() |
void time_init() |
||||
{ |
{ |
||||
|
realTime = 0; |
||||
frameNumber = 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() |
void time_tick() |
||||
{ |
{ |
||||
++frameNumber; |
++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; |
return frameNumber; |
||||
} |
} |
||||
|
|
||||
|
u_long time_getFrameTime() |
||||
|
{ |
||||
|
return frameStartTime; |
||||
|
} |
||||
|
|
||||
|
u_short time_getDeltaTime() |
||||
|
{ |
||||
|
return frameDeltaTime; |
||||
|
} |
||||
|
|
||||
|
u_short time_getFrameRate() |
||||
|
{ |
||||
|
return avgFrameRate; |
||||
|
} |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue