convert sys_timestamp_t to struct

This commit is contained in:
jacob 2025-01-29 10:22:00 -06:00
parent fef1d98c26
commit 4eef91dd63
11 changed files with 100 additions and 60 deletions

View File

@ -102,7 +102,7 @@ INTERNAL WORK_TASK_FUNC_DEF(font_load_asset_task, vparams)
struct asset *asset = params->asset;
logf_info("Loading font \"%F\" (point size %F)", FMT_STR(path), FMT_FLOAT((f64)point_size));
sys_timestamp_t start_ts = sys_timestamp();
struct sys_timestamp start_ts = sys_timestamp_prog();
ASSERT(string_ends_with(path, STR(".ttf")));
if (!resource_exists(path)) {
@ -157,7 +157,8 @@ INTERNAL WORK_TASK_FUNC_DEF(font_load_asset_task, vparams)
font_task_params_release(params);
logf_info("Finished loading font \"%F\" (point size %F) in %F seconds", FMT_STR(path), FMT_FLOAT((f64)point_size), FMT_FLOAT(sys_timestamp_seconds(sys_timestamp() - start_ts)));
f64 elapsed = sys_timestamp_to_seconds(sys_timestamp_sub(sys_timestamp_prog(), start_ts));
logf_info("Finished loading font \"%F\" (point size %F) in %F seconds", FMT_STR(path), FMT_FLOAT((f64)point_size), FMT_FLOAT(elapsed));
asset_cache_mark_ready(asset, font);
scratch_end(scratch);

View File

@ -504,7 +504,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
* ========================== */
++G.tick.tick_id;
G.tick.tick_ts = sys_timestamp();
G.tick.tick_ts = sys_timestamp_prog();
G.tick.dt = max_f64(0.0, (1.0 / GAME_FPS) * G.tick.timescale);
G.tick.time += G.tick.dt;
@ -1347,13 +1347,13 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(game_thread_entry_point, arg)
struct temp_arena scratch = scratch_begin_no_conflict();
(UNUSED)arg;
sys_timestamp_t last_frame_ts = 0;
struct sys_timestamp last_frame_ts = ZI;
f64 target_dt = GAME_FPS > (0) ? (1.0 / GAME_FPS) : 0;
while (!atomic_i32_eval(&G.game_thread_shutdown)) {
__profscope(game_update_w_sleep);
struct temp_arena temp = arena_temp_begin(scratch.arena);
sleep_frame(last_frame_ts, target_dt);
last_frame_ts = sys_timestamp();
last_frame_ts = sys_timestamp_prog();
{
struct game_cmd_array game_cmds = pop_cmds(temp.arena);
if (!G.paused) {

View File

@ -7,6 +7,10 @@ struct sprite_startup_receipt;
struct sound_startup_receipt;
struct phys_startup_receipt;
/* ========================== *
* Game cmd
* ========================== */
enum game_cmd_state {
GAME_CMD_STATE_STOP = -1,
GAME_CMD_STATE_NO_CHANGE = 0,
@ -30,16 +34,6 @@ enum game_cmd_kind {
GAME_CMD_KIND_COUNT
};
/* Absolute layers */
#define GAME_LAYER_FLOOR_DECALS -300
#define GAME_LAYER_BULLETS -200
#define GAME_LAYER_TRACERS -100
#define GAME_LAYER_SHOULDERS 0
/* Relative layers */
#define GAME_LAYER_RELATIVE_DEFAULT 0
#define GAME_LAYER_RELATIVE_WEAPON 1
struct game_cmd {
enum game_cmd_kind kind;
enum game_cmd_state state;
@ -61,6 +55,16 @@ struct game_cmd_array {
u64 count;
};
/* Absolute layers */
#define GAME_LAYER_FLOOR_DECALS -300
#define GAME_LAYER_BULLETS -200
#define GAME_LAYER_TRACERS -100
#define GAME_LAYER_SHOULDERS 0
/* Relative layers */
#define GAME_LAYER_RELATIVE_DEFAULT 0
#define GAME_LAYER_RELATIVE_WEAPON 1
struct game_startup_receipt { i32 _; };
struct game_startup_receipt game_startup(struct mixer_startup_receipt *mixer_sr,
struct sprite_startup_receipt *sheet_sr,

View File

@ -115,7 +115,7 @@ INLINE void ix_pause(void)
_mm_pause();
}
INLINE u64 ix_clock(void)
INLINE i64 ix_clock(void)
{
return __rdtsc();
}

View File

@ -91,7 +91,7 @@ INTERNAL WORK_TASK_FUNC_DEF(sound_load_asset_task, vparams)
u32 flags = params->flags;
logf_info("Loading sound \"%F\"", FMT_STR(path));
sys_timestamp_t start_ts = sys_timestamp();
struct sys_timestamp start_ts = sys_timestamp_prog();
b32 success = true;
struct string error_msg = STR("Unknown error");
@ -132,9 +132,8 @@ INTERNAL WORK_TASK_FUNC_DEF(sound_load_asset_task, vparams)
};
MEMCPY(sound->pcm.samples, decoded.pcm.samples, decoded.pcm.count * sizeof(*decoded.pcm.samples));
logf_info("Finished loading sound \"%F\" in %F seconds",
FMT_STR(path),
FMT_FLOAT(sys_timestamp_seconds(sys_timestamp() - start_ts)));
f64 elapsed = sys_timestamp_to_seconds(sys_timestamp_sub(sys_timestamp_prog(), start_ts));
logf_info("Finished loading sound \"%F\" in %F seconds", FMT_STR(path), FMT_FLOAT(elapsed));
asset_cache_mark_ready(asset, sound);
} else {

View File

@ -342,7 +342,7 @@ INTERNAL void cache_node_load_texture(struct cache_node *n, struct sprite_tag ta
struct string path = tag.path;
logf_info("Loading sprite texture \"%F\"", FMT_STR(path));
sys_timestamp_t start_ts = sys_timestamp();
struct sys_timestamp start_ts = sys_timestamp_prog();
ASSERT(string_ends_with(path, STR(".ase")));
ASSERT(n->kind == CACHE_NODE_KIND_TEXTURE);
@ -383,9 +383,10 @@ INTERNAL void cache_node_load_texture(struct cache_node *n, struct sprite_tag ta
n->memory_usage = n->arena.committed + memory_size;
atomic_u64_eval_add(&G.cache.memory_usage, n->memory_usage);
f64 elapsed = sys_timestamp_to_seconds(sys_timestamp_sub(sys_timestamp_prog(), start_ts));
logf_info("Finished loading sprite texture \"%F\" in %F seconds (cache size: %F bytes).",
FMT_STR(path),
FMT_FLOAT(sys_timestamp_seconds(sys_timestamp() - start_ts)),
FMT_FLOAT(elapsed),
FMT_UINT(n->memory_usage));
atomic_u32_eval_exchange(&n->state, CACHE_NODE_STATE_LOADED);
@ -647,7 +648,7 @@ INTERNAL void cache_node_load_sheet(struct cache_node *n, struct sprite_tag tag)
struct string path = tag.path;
logf_info("Loading sprite sheet \"%F\"", FMT_STR(path));
sys_timestamp_t start_ts = sys_timestamp();
struct sys_timestamp start_ts = sys_timestamp_prog();
//ASSERT(string_ends_with(path, STR(".ase")));
ASSERT(n->kind == CACHE_NODE_KIND_SHEET);
@ -682,9 +683,10 @@ INTERNAL void cache_node_load_sheet(struct cache_node *n, struct sprite_tag tag)
n->memory_usage = n->arena.committed;
atomic_u64_eval_add(&G.cache.memory_usage, n->memory_usage);
f64 elapsed = sys_timestamp_to_seconds(sys_timestamp_sub(sys_timestamp_prog(), start_ts));
logf_info("Finished loading sprite sheet \"%F\" in %F seconds (cache size: %F bytes).",
FMT_STR(path),
FMT_FLOAT(sys_timestamp_seconds(sys_timestamp() - start_ts)),
FMT_FLOAT(elapsed),
FMT_UINT(n->memory_usage));

View File

@ -174,25 +174,50 @@ void sys_memory_set_committed_readonly(void *address, u64 size);
void sys_memory_set_committed_readwrite(void *address, u64 size);
/* ========================== *
* Time
* Timestamp
* ========================== */
struct sys_timestamp {
u64 v;
};
/* Returns timestamp representing time since program start */
struct sys_timestamp sys_timestamp_prog(void);
/* NOTE: Conversion between timestamp & seconds should only happen with small
* timestamp values (like relative timestamps) to avoid precision loss */
struct sys_timestamp sys_timestamp_from_seconds(f64 s);
f64 sys_timestamp_to_seconds(struct sys_timestamp ts);
INLINE struct sys_timestamp sys_timestamp_add(struct sys_timestamp a, struct sys_timestamp b)
{
struct sys_timestamp res;
res.v = a.v + b.v;
return res;
}
INLINE struct sys_timestamp sys_timestamp_sub(struct sys_timestamp a, struct sys_timestamp b)
{
struct sys_timestamp res;
res.v = a.v - b.v;
return res;
}
/* ========================== *
* Datetime
* ========================== */
struct sys_datetime {
u32 year;
u32 month;
u32 day_of_week;
u32 day;
u32 hour;
u32 minute;
u32 second;
u32 milliseconds;
u32 year;
u32 month;
u32 day_of_week;
u32 day;
u32 hour;
u32 minute;
u32 second;
u32 milliseconds;
};
typedef u64 sys_timestamp_t;
sys_timestamp_t sys_timestamp(void);
f64 sys_timestamp_seconds(sys_timestamp_t ts);
struct sys_datetime sys_local_time(void);
/* ========================== *

View File

@ -244,16 +244,25 @@ INTERNAL i64 _win32_i64_muldiv(i64 value, i64 numer, i64 denom) {
return q * numer + r * numer / denom;
}
sys_timestamp_t sys_timestamp(void)
struct sys_timestamp sys_timestamp_prog(void)
{
struct sys_timestamp ts;
LARGE_INTEGER time;
QueryPerformanceCounter(&time);
return (u64)_win32_i64_muldiv(time.QuadPart - G.timer_start.QuadPart, 1000000000, G.timer_frequency.QuadPart);
ts.v = (u64)_win32_i64_muldiv(time.QuadPart - G.timer_start.QuadPart, 1000000000, G.timer_frequency.QuadPart);
return ts;
}
f64 sys_timestamp_seconds(sys_timestamp_t ts)
struct sys_timestamp sys_timestamp_from_seconds(f64 s)
{
return (f64)ts / 1000000000.0;
struct sys_timestamp ts;
ts.v = (u64)(s * 1000000000.0);
return ts;
}
f64 sys_timestamp_to_seconds(struct sys_timestamp ts)
{
return (f64)(ts.v) / 1000000000.0;
}
struct sys_datetime sys_local_time(void)

View File

@ -291,13 +291,13 @@ INTERNAL struct interp_ticks pull_ticks(f64 blend_time)
from_tick = oldest_tick;
to_tick = newest_tick;
for (struct blend_tick *bt = G.head_blend_tick; bt; bt = bt->next) {
f64 bt_time = sys_timestamp_seconds(bt->world.tick_ts);
f64 bt_time = sys_timestamp_to_seconds(bt->world.tick_ts);
if (bt_time < blend_time && bt_time > sys_timestamp_seconds(from_tick->tick_ts)) {
if (bt_time < blend_time && bt_time > sys_timestamp_to_seconds(from_tick->tick_ts)) {
from_tick = &bt->world;
}
if (bt_time > blend_time && bt_time < sys_timestamp_seconds(to_tick->tick_ts)) {
if (bt_time > blend_time && bt_time < sys_timestamp_to_seconds(to_tick->tick_ts)) {
to_tick = &bt->world;
}
}
@ -309,8 +309,8 @@ INTERNAL struct interp_ticks pull_ticks(f64 blend_time)
u64 bts_to_free_count = 0;
for (struct blend_tick *bt = G.head_blend_tick; bt; bt = bt->next) {
f64 bt_time = sys_timestamp_seconds(bt->world.tick_ts);
if (bt_time < sys_timestamp_seconds(from_tick->tick_ts)) {
f64 bt_time = sys_timestamp_to_seconds(bt->world.tick_ts);
if (bt_time < sys_timestamp_to_seconds(from_tick->tick_ts)) {
*arena_push(scratch.arena, struct blend_tick *) = bt;
++bts_to_free_count;
}
@ -490,7 +490,7 @@ INTERNAL void user_update(void)
* Begin frame
* ========================== */
f64 cur_time = sys_timestamp_seconds(sys_timestamp());
f64 cur_time = sys_timestamp_to_seconds(sys_timestamp_prog());
G.dt = max_f64(0.0, cur_time - G.time);
G.time += G.dt;
G.screen_size = sys_window_get_size(G.window);
@ -500,11 +500,11 @@ INTERNAL void user_update(void)
struct game_cmd_list cmd_list = ZI;
/* ========================== *
* Produce interpolated tick
* Interpolate between game ticks
* ========================== */
{
__profscope(produce_interpolated_tick);
__profscope(interpolate_ticks);
#if USER_INTERP_ENABLED
/* TODO: Use actual fps of game thread (will differ from GAME_FPS if game thread is lagging) to hide lag with slow-motion? */
@ -518,8 +518,8 @@ INTERNAL void user_update(void)
f32 tick_blend = 0;
{
f64 t0_time = sys_timestamp_seconds(t0->tick_ts);
f64 t1_time = sys_timestamp_seconds(t1->tick_ts);
f64 t0_time = sys_timestamp_to_seconds(t0->tick_ts);
f64 t1_time = sys_timestamp_to_seconds(t1->tick_ts);
if (t1_time > t0_time) {
tick_blend = (f32)((blend_time - t0_time) / (t1_time - t0_time));
}
@ -1717,13 +1717,13 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_thread_entry_point, arg)
{
(UNUSED)arg;
sys_timestamp_t last_frame_ts = 0;
struct sys_timestamp last_frame_ts = ZI;
f64 target_dt = USER_FRAME_LIMIT > (0) ? (1.0 / USER_FRAME_LIMIT) : 0;
while (!atomic_i32_eval(&G.user_thread_shutdown)) {
__profscope(user_update_w_sleep);
sleep_frame(last_frame_ts, target_dt);
last_frame_ts = sys_timestamp();
last_frame_ts = sys_timestamp_prog();
user_update();
}
}

View File

@ -239,11 +239,11 @@ INLINE void sync_flag_wait(struct sync_flag *sf)
* Sleep frame
* ========================== */
INLINE void sleep_frame(sys_timestamp_t last_frame_time, f64 target_dt)
INLINE void sleep_frame(struct sys_timestamp last_frame_time, f64 target_dt)
{
__prof;
if (last_frame_time != 0 && target_dt > 0) {
f64 last_frame_dt = sys_timestamp_seconds(sys_timestamp() - last_frame_time);
if (last_frame_time.v != 0 && target_dt > 0) {
f64 last_frame_dt = sys_timestamp_to_seconds(sys_timestamp_sub(sys_timestamp_prog(), last_frame_time));
f64 sleep_time = target_dt - last_frame_dt;
if (sleep_time > 0) {
sys_sleep_precise(sleep_time);

View File

@ -4,9 +4,9 @@
#include "entity.h"
struct world {
u64 continuity_gen; /* Starts at 1 */
u64 tick_id; /* Starts at 1 */
u64 tick_ts; /* When was this tick simulated in program time */
u64 continuity_gen; /* Starts at 1 */
u64 tick_id; /* Starts at 1 */
struct sys_timestamp tick_ts; /* When was this tick simulated in program time */
/* World time */
f64 timescale;