3.6 KiB
Time System
Source: src/dusk/time/, platform layers in src/dusk<platform>/time/
Global state
extern dusktime_t TIME;
typedef struct {
float_t delta; // Fixed step size in seconds (DUSK_TIME_STEP)
float_t time; // Accumulated game time in seconds
// Only present when DUSK_TIME_DYNAMIC is defined:
float_t lastNonDynamic;
bool_t dynamicUpdate; // true on sub-step ticks
float_t dynamicDelta; // real elapsed seconds this frame
float_t dynamicTime; // accumulated real time
} dusktime_t;
Fixed vs dynamic timestep
Fixed timestep (default)
DUSK_TIME_STEP defaults to 16ms / 1000 = 0.016f seconds (62.5 Hz).
Every call to timeUpdate() advances TIME.time by exactly
DUSK_TIME_STEP and sets TIME.delta = DUSK_TIME_STEP. This is the
safe, deterministic mode for physics and game logic.
Dynamic timestep (DUSK_TIME_DYNAMIC)
When enabled, timeUpdate() calls the platform tick hook to measure
actual elapsed time. It fires a "non-dynamic" step (dynamicUpdate = false, delta = DUSK_TIME_STEP) once per fixed interval, and
"dynamic" sub-steps (dynamicUpdate = true) in between. Systems that
must run on the fixed interval (physics, networking) skip the dynamic
sub-steps by checking:
if(TIME.dynamicUpdate) return;
Platform hooks
Each platform provides three macros in its time/timeplatform.h:
| Macro | Purpose |
|---|---|
timeTickPlatform() |
Sample the hardware timer |
timeGetDeltaPlatform() |
Return seconds since last tick |
timeGetRealPlatform() |
Return epoch seconds since 1970 |
timeGetRealTimeZonePlatform() |
Return local timezone offset (seconds) |
timeTickPlatform and timeGetDeltaPlatform are only required when
DUSK_TIME_DYNAMIC is defined.
Platform implementations
| Platform | Tick source | Real time source |
|---|---|---|
| Linux | SDL_GetTicks64() (via SDL2) |
clock_gettime(CLOCK_REALTIME) |
| Knulli | SDL_GetTicks64() (via SDL2) |
clock_gettime(CLOCK_REALTIME) |
| PSP | SDL_GetTicks64() (via SDL2) |
sceRtcGetCurrentTick() (microseconds) |
| GameCube | none (fixed step only) | ticks_to_microsecs(__SYS_GetSystemTime()) + 2000->1970 offset |
| Wii | none (fixed step only) | same as GameCube |
GameCube / Wii note: the hardware timer returns ticks since 2000-01-01, so an offset of 946684800 seconds is added to convert to UNIX epoch. The timezone offset is always returned as 0.0 on Dolphin (timezone is not available without network time).
Epoch time (timeepoch.h)
typedef struct {
double_t time; // raw UTC seconds since 1970
double_t timeZone; // timezone offset in seconds
double_t offsetTime; // time + timeZone
} dusktimeepoch_t;
dusktimeepoch_t timeGetEpoch(void);
// Returns current time in local timezone.
Epoch helpers
int32_t timeEpochGetYear(epoch);
int32_t timeEpochGetMonth(epoch); // 1-12
int32_t timeEpochGetDayOfMonth(epoch); // 1-31
int32_t timeEpochGetHours(epoch); // 0-23
int32_t timeEpochGetMinutes(epoch); // 0-59
int32_t timeEpochGetSeconds(epoch); // 0-59
bool_t timeEpochIsLeapYear(year);
size_t timeEpochFormat(
dusktimeepoch_t epoch,
const char_t *format, // %Y %m %d %H %M %S
char_t *buffer,
size_t bufferSize
);
Adding a new platform time implementation
- Create
src/dusk<platform>/time/time<platform>.h/.c. - Implement
timeGetReal<Platform>()andtimeGetRealTimeZone<Platform>(). - If
DUSK_TIME_DYNAMIC: also implementtimeTick<Platform>()andtimeGetDelta<Platform>(). - Create
src/dusk<platform>/time/timeplatform.hwith the#definemacros pointing to your functions.