#include "common.h" #include "time.h" #include 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; } 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; }