Files
dusk/.claude/time.md
T
2026-06-16 10:15:59 -05:00

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

  1. Create src/dusk<platform>/time/time<platform>.h/.c.
  2. Implement timeGetReal<Platform>() and timeGetRealTimeZone<Platform>().
  3. If DUSK_TIME_DYNAMIC: also implement timeTick<Platform>() and timeGetDelta<Platform>().
  4. Create src/dusk<platform>/time/timeplatform.h with the #define macros pointing to your functions.