From 3061d465d1cf1ffab63598491856331903804000 Mon Sep 17 00:00:00 2001 From: jacob Date: Tue, 25 Jun 2024 18:35:53 -0500 Subject: [PATCH] minor tweaks & fixes --- build.c | 24 +++++++++++------------ res/graphics/tim.ase | 4 ++-- src/config.h | 2 +- src/game.c | 21 ++++++-------------- src/game.h | 3 +++ src/sprite.c | 33 +++++++++++++------------------ src/sys.h | 2 +- src/sys_win32.c | 13 +++++++++++-- src/user.c | 46 ++++++++++++-------------------------------- src/util.h | 15 +++++++++------ src/work.c | 5 +---- 11 files changed, 71 insertions(+), 97 deletions(-) diff --git a/build.c b/build.c index 8668786c..563142fb 100644 --- a/build.c +++ b/build.c @@ -640,10 +640,12 @@ void OnBuild(StringList cli_args) D_AddDependency(&store, pch_c_file, pch_c_src_gen_obj_file); if (IsDirty(pch_c_file)) { D_ClearWrite(pch_c_src_gen_file, Lit("")); - BuildStepSimpleCommandArg *bs_arg = ArenaPush(&arena, BuildStepSimpleCommandArg); + BuildStepMsvcCompileCommandArg *bs_arg = ArenaPush(&arena, BuildStepMsvcCompileCommandArg); bs_arg->cmd = StringF(&arena, pch_c_compile_args_fmt, FmtStr(pch_header_file.full_path), FmtStr(pch_c_src_gen_file.full_path)); + bs_arg->depfile_dependent = pch_header_file; + bs_arg->output_depfile = dep_file; String step_name = StringF(&arena, Lit("%F -> %F"), FmtStr(D_GetName(pch_header_file)), FmtStr(D_GetName(pch_c_file))); - AddStep(step_name, &BuildStepSimpleCommand, bs_arg); + AddStep(step_name, &BuildStepMsvcCompileCommand, bs_arg); } /* Cpp */ @@ -651,10 +653,12 @@ void OnBuild(StringList cli_args) D_AddDependency(&store, pch_cpp_file, pch_cpp_src_gen_obj_file); if (IsDirty(pch_cpp_file)) { D_ClearWrite(pch_cpp_src_gen_file, Lit("")); - BuildStepSimpleCommandArg *bs_arg = ArenaPush(&arena, BuildStepSimpleCommandArg); + BuildStepMsvcCompileCommandArg *bs_arg = ArenaPush(&arena, BuildStepMsvcCompileCommandArg); bs_arg->cmd = StringF(&arena, pch_cpp_compile_args_fmt, FmtStr(pch_header_file.full_path), FmtStr(pch_cpp_src_gen_file.full_path)); + bs_arg->depfile_dependent = pch_header_file; + bs_arg->output_depfile = dep_file; String step_name = StringF(&arena, Lit("%F -> %F"), FmtStr(D_GetName(pch_header_file)), FmtStr(D_GetName(pch_cpp_file))); - AddStep(step_name, &BuildStepSimpleCommand, bs_arg); + AddStep(step_name, &BuildStepMsvcCompileCommand, bs_arg); } } else { StringListAppend(&arena, &c_compile_args, StringF(&arena, Lit("-include-pch %F"), FmtStr(pch_c_file.full_path))); @@ -665,22 +669,18 @@ void OnBuild(StringList cli_args) /* C */ if (IsDirty(pch_c_file)) { - BuildStepMsvcCompileCommandArg *bs_arg = ArenaPush(&arena, BuildStepMsvcCompileCommandArg); + BuildStepSimpleCommandArg *bs_arg = ArenaPush(&arena, BuildStepSimpleCommandArg); bs_arg->cmd = StringF(&arena, pch_c_compile_args_fmt, FmtStr(pch_header_file.full_path), FmtStr(pch_c_file.full_path)); - bs_arg->depfile_dependent = pch_header_file; - bs_arg->output_depfile = dep_file; String step_name = StringF(&arena, Lit("%F -> %F"), FmtStr(D_GetName(pch_header_file)), FmtStr(D_GetName(pch_c_file))); - AddStep(step_name, &BuildStepMsvcCompileCommand, bs_arg); + AddStep(step_name, &BuildStepSimpleCommand, bs_arg); } /* Cpp */ if (IsDirty(pch_cpp_file)) { - BuildStepMsvcCompileCommandArg *bs_arg = ArenaPush(&arena, BuildStepMsvcCompileCommandArg); + BuildStepSimpleCommandArg *bs_arg = ArenaPush(&arena, BuildStepSimpleCommandArg); bs_arg->cmd = StringF(&arena, pch_cpp_compile_args_fmt, FmtStr(pch_header_file.full_path), FmtStr(pch_cpp_file.full_path)); - bs_arg->depfile_dependent = pch_header_file; - bs_arg->output_depfile = dep_file; String step_name = StringF(&arena, Lit("%F -> %F"), FmtStr(D_GetName(pch_header_file)), FmtStr(D_GetName(pch_cpp_file))); - AddStep(step_name, &BuildStepMsvcCompileCommand, bs_arg); + AddStep(step_name, &BuildStepSimpleCommand, bs_arg); } } } diff --git a/res/graphics/tim.ase b/res/graphics/tim.ase index 70d39afb..d28b0a57 100644 --- a/res/graphics/tim.ase +++ b/res/graphics/tim.ase @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2089ee4280aefb07b9f249f30bcdf7d8a3d3be4a04f5c7f41384657ed00ca2e0 -size 890 +oid sha256:70f7f9f3cd307b97da03c233bb38f30c71d5766cee011e95049f3493cb3f9bd6 +size 1453 diff --git a/src/config.h b/src/config.h index 2998cccf..9ce0703f 100644 --- a/src/config.h +++ b/src/config.h @@ -34,7 +34,7 @@ /* How many ticks back in time should the user blend between? * = * - * E.g: At 1.5, the user thread will render 49.5ms back in time (if game thread runs at 30FPS) + * E.g: At 1.5, the user thread will render 75ms back in time (if game thread runs at 50FPS) */ #define USER_INTERP_OFFSET_TICK_RATIO 1.1 #define USER_INTERP_ENABLED 1 diff --git a/src/game.c b/src/game.c index 8e2cc5e5..feef130c 100644 --- a/src/game.c +++ b/src/game.c @@ -196,6 +196,9 @@ INTERNAL void game_update(void) e->valid = true; e->rel_xform = XFORM_TRS(.t = pos, .r = r, .s = size); + e->sprite = sprite_tag_from_path(STR("res/graphics/tim.ase"));; + e->sprite_span_name = STR("idle.unarmed"); + struct v2 sprite_pos = V2(0, 0); f32 sprite_rot = 0; struct v2 sprite_size = V2(0.5f, 0.5f); @@ -213,9 +216,6 @@ INTERNAL void game_update(void) sprite_xf = xform_translate(sprite_xf, v2_neg(sprite_pivot)); sprite_xf = xform_scale(sprite_xf, sprite_size); e->sprite_quad_xform = sprite_xf; - - e->sprite = sprite_tag_from_path(STR("res/graphics/tim.ase"));; - e->sprite_span_name = STR("UNARMED"); e->sprite_tint = COLOR_WHITE; entity_enable_prop(e, ENTITY_PROP_PLAYER_CONTROLLED); @@ -265,6 +265,9 @@ INTERNAL void game_update(void) /* Movement */ case GAME_CMD_KIND_PLAYER_MOVE: { G.world.player_move_dir = cmd.move_dir; + } break; + + case GAME_CMD_KIND_PLAYER_AIM: { G.world.player_aim = cmd.aim; } break; @@ -439,17 +442,6 @@ INTERNAL void game_update(void) struct entity *follow = entity_from_handle(&G.world.entity_store, ent->camera_follow); if (entity_has_prop(follow, ENTITY_PROP_PLAYER_CONTROLLED)) { -#if 0 - /* Regular style camera */ - f32 target_dist_x = 0.5; - //f32 target_dist_y = target_dist_x * (16.0f / 9.0f); - f32 target_dist_y = target_dist_x; - struct v2 target_dir = v2_mul_v2(v2_norm(follow->player_aim), V2(target_dist_x, target_dist_y)); - struct v2 target_pos = v2_add(ent->camera_rel_xform_target.og, target_dir); - ent->camera_rel_xform_target = ent->rel_xform; - ent->camera_rel_xform_target.og = target_pos; -#else - /* "Look" style camera */ f32 aspect_ratio = 1.0; { struct xform quad_xf = xform_mul(ent->world_xform, ent->camera_quad_xform); @@ -464,7 +456,6 @@ INTERNAL void game_update(void) struct v2 camera_focus_pos = v2_add(follow->world_xform.og, camera_focus_dir); ent->camera_rel_xform_target = ent->rel_xform; ent->camera_rel_xform_target.og = camera_focus_pos; -#endif } /* Lerp camera */ diff --git a/src/game.h b/src/game.h index a4cf04cd..cbb8186f 100644 --- a/src/game.h +++ b/src/game.h @@ -10,6 +10,7 @@ enum game_cmd_kind { GAME_CMD_KIND_NONE, GAME_CMD_KIND_PLAYER_MOVE, + GAME_CMD_KIND_PLAYER_AIM, /* Testing */ GAME_CMD_KIND_CLEAR_ALL, @@ -22,6 +23,8 @@ struct game_cmd { /* GAME_CMD_KIND_PLAYER_MOVE */ struct v2 move_dir; + + /* GAME_CMD_KIND_PLAYER_AIM */ struct v2 aim; }; diff --git a/src/sprite.c b/src/sprite.c index a01f5a54..8b5a8c59 100644 --- a/src/sprite.c +++ b/src/sprite.c @@ -801,23 +801,13 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(sprite_evictor_thread_entry_point, arg) { (UNUSED)arg; - b32 abort = false; - while (!abort) { - struct temp_arena scratch = scratch_begin_no_conflict(); - struct evict_node *head_consider = NULL; - struct evict_node *head_consider_lru = NULL; - struct evict_node *head_evicted = NULL; - - sys_mutex_lock(&G.evictor_mutex); - { - /* Thread shutdown */ - if (G.evictor_shutdown) { - abort = true; - } else { - /* Wait */ - sys_condition_variable_wait_time(&G.evictor_cv, &G.evictor_mutex, EVICTOR_CYCLE_INTERVAL); - } - + sys_mutex_lock(&G.evictor_mutex); + { + while (!G.evictor_shutdown) { + struct temp_arena scratch = scratch_begin_no_conflict(); + struct evict_node *head_consider = NULL; + struct evict_node *head_consider_lru = NULL; + struct evict_node *head_evicted = NULL; if (!G.evictor_shutdown) { u32 cur_cycle = *atomic_u32_raw(&G.evictor_cycle); @@ -866,7 +856,7 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(sprite_evictor_thread_entry_point, arg) /* Check usage time */ #if RESOURCE_RELOADING /* Only check conditional if RESOURCE_RELOADING is enabled, - * since over-budget is assumed to be * true otherwise */ + * since over-budget is assumed to be * true otherwise */ if (cache_over_budget) #endif { @@ -981,8 +971,11 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(sprite_evictor_thread_entry_point, arg) } } atomic_u32_inc_eval(&G.evictor_cycle); + scratch_end(scratch); + + /* Wait */ + sys_condition_variable_wait_time(&G.evictor_cv, &G.evictor_mutex, EVICTOR_CYCLE_INTERVAL); } - sys_mutex_unlock(&G.evictor_mutex); - scratch_end(scratch); } + sys_mutex_unlock(&G.evictor_mutex); } diff --git a/src/sys.h b/src/sys.h index 11003e86..47b19fdc 100644 --- a/src/sys.h +++ b/src/sys.h @@ -393,7 +393,7 @@ struct sys_condition_variable sys_condition_variable_alloc(void); void sys_condition_variable_release(struct sys_condition_variable *cv); void sys_condition_variable_wait(struct sys_condition_variable *cv, struct sys_mutex *mutex); void sys_condition_variable_wait_time(struct sys_condition_variable *cv, struct sys_mutex *mutex, f64 seconds); -void sys_condition_variable_signal(struct sys_condition_variable *cv); +void sys_condition_variable_signal(struct sys_condition_variable *cv, u32 count); void sys_condition_variable_broadcast(struct sys_condition_variable *cv); /* ========================== * diff --git a/src/sys_win32.c b/src/sys_win32.c index 88929f6a..1a05b76a 100644 --- a/src/sys_win32.c +++ b/src/sys_win32.c @@ -1542,11 +1542,20 @@ void sys_condition_variable_wait_time(struct sys_condition_variable *cv, struct #endif } -void sys_condition_variable_signal(struct sys_condition_variable *cv) +void sys_condition_variable_signal(struct sys_condition_variable *cv, u32 count) { __prof; struct win32_condition_variable *w32cv = (struct win32_condition_variable *)cv->handle; - WakeConditionVariable(&w32cv->condition_variable); + /* Windows will wake all waiters if many single-wakes occur anyway, so we + * might as well wake all ourselves. + * https://devblogs.microsoft.com/oldnewthing/20180201-00/?p=97946 */ + if (count <= 24) { + for (u32 i = 0; i < count; ++i) { + WakeConditionVariable(&w32cv->condition_variable); + } + } else { + WakeAllConditionVariable(&w32cv->condition_variable); + } } void sys_condition_variable_broadcast(struct sys_condition_variable *cv) diff --git a/src/user.c b/src/user.c index e9300563..c8d135b3 100644 --- a/src/user.c +++ b/src/user.c @@ -761,8 +761,6 @@ INTERNAL void user_update(void) if (!sprite_tag_is_nil(ent->sprite)) { /* Draw texture */ struct sprite_tag sprite = ent->sprite; - /* TODO: Remove this once renderer is rewritten to work with tags */ - struct sprite_texture *texture = sprite_texture_from_tag_async(sprite_frame_scope, sprite); struct xform xf = xform_mul(ent->world_xform, ent->sprite_quad_xform); struct quad quad = quad_mul_xform(QUAD_UNIT_SQUARE_CENTERED, xf); @@ -791,33 +789,11 @@ INTERNAL void user_update(void) struct draw_sprite_params params = DRAW_SPRITE_PARAMS(.sprite = sprite, .tint = tint, .clip = frame.clip); - /* TODO: Check for texture loading as well */ + /* TODO: Fade in a placeholder or something instead of drawing nothing. */ + struct sprite_texture *texture = sprite_texture_from_tag_async(sprite_frame_scope, sprite); if (sheet->loaded && texture->loaded) { - /* TODO: Fade in a placeholder or something instead of drawing nothing. */ draw_sprite_quad(G.world_canvas, params, quad); } - -#if 0 - if (G.debug_draw && !skip_debug_draw) { - /* Debug draw sprite quad */ - { - f32 thickness = 2.f; - u32 color = RGBA_32_F(1, 1, 0, 0.25); - draw_solid_quad_line(G.world_canvas, quad, (thickness / PIXELS_PER_UNIT / G.world_view.zoom), color); - } - - /* Debug draw sprite transform */ - { - debug_draw_xform(xf); - } - - /* Debug draw sprite pivot */ - { - u32 color = RGBA_32_F(1, 0, 0, 1); - draw_solid_circle(G.world_canvas, ent->world_xform.og, 0.02, color, 20); - } - } -#endif } /* Debug draw info */ @@ -970,19 +946,21 @@ INTERNAL void user_update(void) input_move_dir = v2_norm(input_move_dir); } - /* Aim */ - struct v2 input_aim = player->player_aim; - if (!G.debug_camera) { - input_aim = v2_sub(G.world_cursor, player->world_xform.og); - } - - /* Queue cmd */ + /* Queue move cmd */ queue_game_cmd(&cmd_list, (struct game_cmd) { .kind = GAME_CMD_KIND_PLAYER_MOVE, .move_dir = input_move_dir, - .aim = input_aim }); + /* Queue aim cmd */ + if (!G.debug_camera) { + struct v2 input_aim = v2_sub(G.world_cursor, player->world_xform.og); + queue_game_cmd(&cmd_list, (struct game_cmd) { + .kind = GAME_CMD_KIND_PLAYER_AIM, + .aim = input_aim, + }); + } + /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ diff --git a/src/util.h b/src/util.h index 9c2afcff..7789e683 100644 --- a/src/util.h +++ b/src/util.h @@ -129,7 +129,7 @@ struct sync_flag { /* TODO: Make this a rw mutex? */ struct sys_mutex mutex; struct sys_condition_variable cv; - struct atomic_i32 flag; + b32 flag; }; INLINE struct sync_flag sync_flag_alloc(void) @@ -149,21 +149,24 @@ INLINE void sync_flag_release(struct sync_flag *sf) INLINE void sync_flag_set(struct sync_flag *sf) { __prof; - if (atomic_i32_eval_compare_exchange(&sf->flag, 0, 1) == 0) { + sys_mutex_lock(&sf->mutex); + { + sf->flag = 1; sys_condition_variable_broadcast(&sf->cv); } + sys_mutex_unlock(&sf->mutex); } INLINE void sync_flag_wait(struct sync_flag *sf) { __prof; - while (atomic_i32_eval(&sf->flag) == 0) { - sys_mutex_lock(&sf->mutex); - { + sys_mutex_lock(&sf->mutex); + { + while (sf->flag == 0) { sys_condition_variable_wait(&sf->cv, &sf->mutex); } - sys_mutex_unlock(&sf->mutex); } + sys_mutex_unlock(&sf->mutex); } /* ========================== * diff --git a/src/work.c b/src/work.c index c8d9c3ec..50760903 100644 --- a/src/work.c +++ b/src/work.c @@ -272,10 +272,7 @@ INTERNAL void work_schedule_assume_locked(struct work *work) G.scheduled_work_priority_tails[priority] = work; - WRITE_BARRIER(); - for (u64 i = 0; i < work->tasks_incomplete; ++i) { - sys_condition_variable_signal(&G.cv); - } + sys_condition_variable_signal(&G.cv, work->tasks_incomplete); } INTERNAL void work_unschedule_assume_locked(struct work *work)