From 2dc481bfc0104d56fe55a275561c3378c84fc0c3 Mon Sep 17 00:00:00 2001 From: jacob Date: Fri, 23 May 2025 23:35:13 -0500 Subject: [PATCH] don't prefix resource names with res directory. check for resource existence after opening. --- res/shaders/grid.hlsl | 2 +- res/shaders/triangle.hlsl | 2 +- src/ase.c | 10 ++++- src/ase.h | 2 + src/font.c | 11 +++--- src/gpu_dx11.c | 48 +++++++++--------------- src/resource.c | 62 +++++++++++++++++------------- src/resource.h | 33 ++++++++++++---- src/sim_step.c | 22 +++++------ src/sound.c | 40 +++++++++----------- src/sprite.c | 26 +++++++++---- src/sys.h | 2 + src/sys_win32.c | 79 +++++++++++++++++++++------------------ src/user.c | 12 +++--- 14 files changed, 195 insertions(+), 156 deletions(-) diff --git a/res/shaders/grid.hlsl b/res/shaders/grid.hlsl index 8400fd0d..4b890314 100644 --- a/res/shaders/grid.hlsl +++ b/res/shaders/grid.hlsl @@ -1,4 +1,4 @@ -#include "res/shaders/common.hlsl" +#include "shaders/common.hlsl" struct vs_input { DECL(float4, pos); diff --git a/res/shaders/triangle.hlsl b/res/shaders/triangle.hlsl index 9241db53..c0096b73 100644 --- a/res/shaders/triangle.hlsl +++ b/res/shaders/triangle.hlsl @@ -1,4 +1,4 @@ -#include "res/shaders/common.hlsl" +#include "shaders/common.hlsl" struct { SamplerState sampler0; diff --git a/src/ase.c b/src/ase.c index f8e7cde4..f84a5c59 100644 --- a/src/ase.c +++ b/src/ase.c @@ -805,7 +805,11 @@ struct ase_decode_image_result ase_decode_image(struct arena *arena, struct stri /* ASSERT all data was read */ ASSERT(br_num_bytes_left(&br) == 0); - abort: +abort: + + if (res.errors.count <= 0) { + res.success = true; + } scratch_end(scratch); return res; @@ -978,5 +982,9 @@ struct ase_decode_sheet_result ase_decode_sheet(struct arena *arena, struct stri res.span_head = span_head; res.slice_key_head = slice_key_head; + if (res.errors.count <= 0) { + res.success = true; + } + return res; } diff --git a/src/ase.h b/src/ase.h index 48d89fce..cecbf898 100644 --- a/src/ase.h +++ b/src/ase.h @@ -49,6 +49,7 @@ struct ase_decode_image_result { struct image_rgba image; struct ase_error_list errors; b32 srgb; + b32 success; }; struct ase_decode_sheet_result { @@ -61,6 +62,7 @@ struct ase_decode_sheet_result { struct ase_span *span_head; struct ase_slice_key *slice_key_head; struct ase_error_list errors; + b32 success; }; struct ase_decode_image_result ase_decode_image(struct arena *arena, struct string encoded); diff --git a/src/font.c b/src/font.c index b8b27b3a..224c1519 100644 --- a/src/font.c +++ b/src/font.c @@ -105,17 +105,16 @@ INTERNAL WORK_TASK_FUNC_DEF(font_load_asset_task, vparams) i64 start_ns = sys_time_ns(); ASSERT(string_ends_with(path, LIT(".ttf"))); - if (!resource_exists(path)) { + ASSERT(ARRAY_COUNT(g_font_codes) < LOOKUP_TABLE_SIZE); + + /* Decode */ + struct resource res = resource_open(path); + if (!resource_exists(&res)) { /* FIME: Load baked font instead of panicking */ sys_panic(string_format(scratch.arena, LIT("Font \"%F\" not found"), FMT_STR(path))); } - - ASSERT(ARRAY_COUNT(g_font_codes) < LOOKUP_TABLE_SIZE); - - /* Decode */ - struct resource res = resource_open(path); struct ttf_decode_result result = ttf_decode(scratch.arena, resource_get_data(&res), point_size, g_font_codes, ARRAY_COUNT(g_font_codes)); resource_close(&res); diff --git a/src/gpu_dx11.c b/src/gpu_dx11.c index dcabafd7..4abf7c6b 100644 --- a/src/gpu_dx11.c +++ b/src/gpu_dx11.c @@ -43,8 +43,6 @@ #define DX11_SWAPCHAIN_FORMAT (DXGI_FORMAT_R8G8B8A8_UNORM) #define DX11_SWAPCHAIN_RTV_FORMAT (DXGI_FORMAT_R8G8B8A8_UNORM_SRGB) -#define SHADER_NAME_LEN 255 - struct dx11_shader { enum shader_kind kind; b32 valid; /* Is this shader allocated */ @@ -52,9 +50,6 @@ struct dx11_shader { ID3D11InputLayout *input_layout; ID3D11VertexShader *vs; ID3D11PixelShader *ps; - - struct string name; - u8 name_text[SHADER_NAME_LEN]; }; struct dx11_constant_buffer_data { @@ -461,7 +456,7 @@ INTERNAL void init_shader_table(void) /* Triangle shader layout */ G.shader_info[SHADER_TRIANGLE] = (struct dx11_shader_desc) { .kind = SHADER_TRIANGLE, - .name_cstr = "res/shaders/triangle.hlsl", + .name_cstr = "shaders/triangle.hlsl", .vertex_size = sizeof(struct triangle_shader_vertex), .input_layout_desc = { { "pos", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, @@ -473,7 +468,7 @@ INTERNAL void init_shader_table(void) /* Grid shader layout */ G.shader_info[SHADER_GRID] = (struct dx11_shader_desc) { .kind = SHADER_GRID, - .name_cstr = "res/shaders/grid.hlsl", + .name_cstr = "shaders/grid.hlsl", .vertex_size = sizeof(struct grid_shader_vertex), .input_layout_desc = { { "pos", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, @@ -584,11 +579,11 @@ INTERNAL HRESULT dx11_include_open(ID3DInclude *d3d_handler, D3D_INCLUDE_TYPE in sys_panic(LIT("D3d include handler somehow already has a resource open")); } - if (resource_exists(name)) { + struct resource res = resource_open(name); + if (resource_exists(&res)) { + handler->res = res; handler->has_open_resource = true; - struct resource *res = &handler->res; - *res = resource_open(name); - struct string data = resource_get_data(res); + struct string data = resource_get_data(&res); *data_out = data.text; *data_len_out = data.len; result = S_OK; @@ -644,17 +639,8 @@ INTERNAL struct string shader_alloc(struct arena *arena, struct dx11_shader *sha struct temp_arena scratch = scratch_begin(arena); struct string error_str = ZI; - struct string res_name = resource_get_name(src_res); - if (res_name.len > SHADER_NAME_LEN) { - sys_panic(string_format(scratch.arena, - LIT("Shader name \"%F\" too long (%F > %F)"), - FMT_STR(res_name), - FMT_UINT(res_name.len), - FMT_UINT(SHADER_NAME_LEN))); - } + struct string shader_name = string_from_cstr_no_limit(shader_desc->name_cstr); - MEMCPY(shader->name_text, res_name.text, res_name.len); - shader->name = STRING(res_name.len, shader->name_text); shader->kind = shader_desc->kind; shader->vertex_size = shader_desc->vertex_size; #if RESOURCE_RELOADING @@ -677,7 +663,7 @@ INTERNAL struct string shader_alloc(struct arena *arena, struct dx11_shader *sha b32 success = false; { struct string shader_src = resource_get_data(src_res); - logf_info("Compiling shader \"%F\"", FMT_STR(shader->name)); + logf_info("Compiling shader \"%F\"", FMT_STR(shader_name)); /* Compile shader */ /* TODO: pre-compile shaders w/ FXC? */ HRESULT hr = D3DCompile(shader_src.text, shader_src.len, NULL, NULL, (ID3DInclude *)&include_handler, "vs_main", "vs_5_0", flags, 0, &vs_blob, &error_blob); @@ -761,9 +747,9 @@ INTERNAL void reload_shader(struct dx11_shader *old_shader, struct dx11_shader_d { struct string name = string_from_cstr_no_limit(desc->name_cstr); struct string error_msg = ZI; - if (resource_exists(name)) { - struct resource src_res = resource_open(name); - { + struct resource src_res = resource_open(name); + { + if (resource_exists(&src_res)) { struct dx11_shader new_shader = ZI; struct string comp_error = shader_alloc(scratch.arena, &new_shader, desc, &src_res); if (comp_error.len == 0) { @@ -773,16 +759,16 @@ INTERNAL void reload_shader(struct dx11_shader *old_shader, struct dx11_shader_d *old_shader = new_shader; } else { error_msg = string_format(scratch.arena, - LIT("Failed to compile shader \"%F\":\n\n%F"), - FMT_STR(name), - FMT_STR(comp_error)); + LIT("Failed to compile shader \"%F\":\n\n%F"), + FMT_STR(name), + FMT_STR(comp_error)); shader_release(&new_shader); } + } else { + error_msg = string_format(scratch.arena, LIT("Could not find shader \"%F\""), FMT_STR(name)); } - resource_close(&src_res); - } else { - error_msg = string_format(scratch.arena, LIT("Could not find shader \"%F\""), FMT_STR(name)); } + resource_close(&src_res); if (error_msg.len != 0) { if (old_shader->valid) { /* If shader failed to load but a working shader already exists, just error rather than panicking */ diff --git a/src/resource.c b/src/resource.c index 761a6adc..76d27b41 100644 --- a/src/resource.c +++ b/src/resource.c @@ -59,11 +59,11 @@ struct resource_startup_receipt resource_startup(void) if (embedded_data.len <= 0) { sys_panic(LIT("No embedded resources found")); } - G.archive = tar_parse(&G.arena, embedded_data, LIT("res/")); + G.archive = tar_parse(&G.arena, embedded_data, LIT("")); #else /* Ensure we have the right working directory */ if (!sys_is_dir(LIT("res"))) { - sys_panic(LIT("Resource directory \"res\" not found")); + sys_panic(LIT("Resource directory \"res\" not found. Make sure the executable is being launched from the correct working directory.")); } #endif @@ -88,29 +88,54 @@ struct resource_startup_receipt resource_startup(void) * Open / close * ========================== */ -struct resource resource_open(struct string path) +struct resource resource_open(struct string name) { __prof; #if RESOURCES_EMBEDDED struct resource res = ZI; - struct tar_entry *entry = tar_get(&G.archive, path); + struct tar_entry *entry = tar_get(&G.archive, name); if (entry) { res._data = entry->data; - res._file_name = entry->file_name; + res._name = entry->file_name; + res._exists = true; } return res; #else struct resource res = ZI; - if (path.len < ARRAY_COUNT(res._file_name_text)) { - struct sys_file file = sys_file_open_read_wait(path); - struct sys_file_map file_map = sys_file_map_open_read(file); - struct string data = sys_file_map_data(file_map); + if (name.len < ARRAY_COUNT(res._name_text)) { + u8 path_text[RESOURCE_NAME_LEN_MAX + (sizeof("res/") - 1)]; + struct string path = ZI; + { + path_text[0] = 'r'; + path_text[1] = 'e'; + path_text[2] = 's'; + path_text[3] = '/'; + u64 path_text_len = 4; + MEMCPY(path_text + path_text_len, name.text, name.len); + path_text_len += name.len; + path = STRING(path_text_len, path_text); + } + struct sys_file file = sys_file_open_read_wait(path); + struct sys_file_map file_map = ZI; + struct string data = ZI; + if (file.valid) { + file_map = sys_file_map_open_read(file); + if (file_map.valid) { + data = sys_file_map_data(file_map); + } else { + sys_file_map_close(file_map); + } + } else { + sys_file_close(file); + } + + res._exists = file.valid && file_map.valid; res._data = data; res._file = file; res._file_map = file_map; - res._file_name_len = path.len; - MEMCPY(res._file_name_text, path.text, path.len); + res._name_len = name.len; + MEMCPY(res._name_text, name.text, name.len); } else { ASSERT(false); } @@ -126,21 +151,6 @@ void resource_close(struct resource *res_ptr) } #endif -/* ========================== * - * Util - * ========================== */ - -b32 resource_exists(struct string path) -{ - __prof; -#if RESOURCES_EMBEDDED - struct tar_entry *entry = tar_get(&G.archive, path); - return entry && !entry->is_dir; -#else - return sys_is_file(path); -#endif -} - /* ========================== * * Watch * ========================== */ diff --git a/src/resource.h b/src/resource.h index 9461d0bf..93f0342f 100644 --- a/src/resource.h +++ b/src/resource.h @@ -3,25 +3,36 @@ #include "sys.h" +#define RESOURCE_NAME_LEN_MAX 255 + /* A resource contains data that can be retrieved globally by name. * If enabled during compilation, resource data is embedded in the * executable. Otherwise each resource represents a file on disk. */ struct resource { struct string _data; + b32 _exists; #if RESOURCES_EMBEDDED - struct string _file_name; + struct string _name; #else struct sys_file _file; struct sys_file_map _file_map; - u8 _file_name_text[256]; - u8 _file_name_len; + u8 _name_text[RESOURCE_NAME_LEN_MAX]; + u8 _name_len; #endif }; +/* ========================== * + * Startup + * ========================== */ + struct resource_startup_receipt { i32 _; }; struct resource_startup_receipt resource_startup(void); -struct resource resource_open(struct string path); +/* ========================== * + * Open / close + * ========================== */ + +struct resource resource_open(struct string name); #if RESOURCES_EMBEDDED #define resource_close(res_ptr) @@ -29,16 +40,24 @@ struct resource resource_open(struct string path); void resource_close(struct resource *res_ptr); #endif -b32 resource_exists(struct string path); +/* ========================== * + * Data + * ========================== */ #define resource_get_data(res_ptr) (res_ptr)->_data +#define resource_exists(res_ptr) (res_ptr)->_exists + #if RESOURCES_EMBEDDED - #define resource_get_name(res_ptr) (res_ptr)->_file_name + #define resource_get_name(res_ptr) (res_ptr)->_name #else - #define resource_get_name(res_ptr) STRING((res_ptr)->_file_name_len, (res_ptr)->_file_name_text) + #define resource_get_name(res_ptr) STRING((res_ptr)->_name_len, (res_ptr)->_name_text) #endif +/* ========================== * + * Watch + * ========================== */ + #define RESOURCE_WATCH_CALLBACK_FUNC_DEF(func_name, arg_name) void func_name(struct string arg_name) typedef RESOURCE_WATCH_CALLBACK_FUNC_DEF(resource_watch_callback, name); diff --git a/src/sim_step.c b/src/sim_step.c index c02f3442..b1cc288d 100644 --- a/src/sim_step.c +++ b/src/sim_step.c @@ -54,7 +54,7 @@ void sim_accel_reset(struct sim_snapshot *ss, struct sim_accel *accel) INTERNAL struct sim_ent *test_spawn_smg(struct sim_ent *parent) { struct sim_ent *e = sim_ent_alloc_sync_src(parent); - e->sprite = sprite_tag_from_path(LIT("res/graphics/gun.ase")); + e->sprite = sprite_tag_from_path(LIT("graphics/gun.ase")); sim_ent_enable_prop(e, SEPROP_ATTACHED); e->attach_slice = LIT("attach.wep"); @@ -70,7 +70,7 @@ INTERNAL struct sim_ent *test_spawn_smg(struct sim_ent *parent) INTERNAL struct sim_ent *test_spawn_launcher(struct sim_ent *parent) { struct sim_ent *e = sim_ent_alloc_sync_src(parent); - e->sprite = sprite_tag_from_path(LIT("res/graphics/gun.ase")); + e->sprite = sprite_tag_from_path(LIT("graphics/gun.ase")); sim_ent_enable_prop(e, SEPROP_ATTACHED); e->attach_slice = LIT("attach.wep"); @@ -86,7 +86,7 @@ INTERNAL struct sim_ent *test_spawn_launcher(struct sim_ent *parent) INTERNAL struct sim_ent *test_spawn_chucker(struct sim_ent *parent) { struct sim_ent *chucker = sim_ent_alloc_sync_src(parent); - chucker->sprite = sprite_tag_from_path(LIT("res/graphics/gun.ase")); + chucker->sprite = sprite_tag_from_path(LIT("graphics/gun.ase")); sim_ent_enable_prop(chucker, SEPROP_ATTACHED); chucker->attach_slice = LIT("attach.wep"); @@ -137,12 +137,12 @@ INTERNAL struct sim_ent *test_spawn_employee(struct sim_ent *parent) { sim_ent_enable_prop(e, SEPROP_TEST); - e->sprite = sprite_tag_from_path(LIT("res/graphics/tim.ase")); + e->sprite = sprite_tag_from_path(LIT("graphics/tim.ase")); e->mass_unscaled = 10; e->inertia_unscaled = 5; } - //e->sprite = sprite_tag_from_path(LIT("res/graphics/box_rounded.ase")); + //e->sprite = sprite_tag_from_path(LIT("graphics/box_rounded.ase")); //e->sprite_span_name = LIT("idle.unarmed"); //e->sprite_span_name = LIT("idle.one_handed"); e->sprite_span_name = LIT("idle.two_handed"); @@ -259,7 +259,7 @@ INTERNAL void test_spawn_entities2(struct sim_ent *parent, struct v2 pos) struct xform xf = XFORM_TRS(.t = pos, .r = r, .s = size); sim_ent_set_xform(e, xf); - e->sprite = sprite_tag_from_path(LIT("res/graphics/box.ase")); + e->sprite = sprite_tag_from_path(LIT("graphics/box.ase")); e->layer = SIM_LAYER_SHOULDERS; e->sprite_tint = ALPHA_F(COLOR_BLUE, 0.75); @@ -288,7 +288,7 @@ INTERNAL void test_spawn_entities2(struct sim_ent *parent, struct v2 pos) struct xform xf = XFORM_TRS(.t = pos, .r = r, .s = size); sim_ent_set_xform(e, xf); - e->sprite = sprite_tag_from_path(LIT("res/graphics/bullet.ase")); + e->sprite = sprite_tag_from_path(LIT("graphics/bullet.ase")); e->sprite_collider_slice = LIT("shape"); e->layer = SIM_LAYER_SHOULDERS; @@ -316,7 +316,7 @@ INTERNAL void test_spawn_entities3(struct sim_ent *parent, struct v2 pos) struct xform xf = XFORM_TRS(.t = pos, .r = r, .s = size); sim_ent_set_xform(e, xf); - e->sprite = sprite_tag_from_path(LIT("res/graphics/box.ase")); + e->sprite = sprite_tag_from_path(LIT("graphics/box.ase")); e->layer = SIM_LAYER_SHOULDERS; e->sprite_tint = COLOR_RED; @@ -347,7 +347,7 @@ INTERNAL void test_spawn_tile(struct sim_snapshot *world, struct v2 world_pos) sim_ent_set_xform(e, xf); e->layer = SIM_LAYER_WALLS; - e->sprite = sprite_tag_from_path(LIT("res/graphics/tile.ase")); + e->sprite = sprite_tag_from_path(LIT("graphics/tile.ase")); e->sprite_tint = COLOR_RED; { @@ -719,7 +719,7 @@ INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, data, step_ctx) { struct xform xf = XFORM_TRS(.t = point, .r = rand_f64_from_state(&step_ctx->rand, 0, TAU)); struct sim_ent *decal = sim_ent_alloc_sync_src(root); - decal->sprite = sprite_tag_from_path(LIT("res/graphics/blood.ase")); + decal->sprite = sprite_tag_from_path(LIT("graphics/blood.ase")); decal->sprite_tint = RGBA_F(1, 1, 1, 0.25f); decal->layer = SIM_LAYER_FLOOR_DECALS; sim_ent_set_xform(decal, xf); @@ -1336,7 +1336,7 @@ void sim_step(struct sim_step_ctx *ctx) bullet->local_collider.points[0] = V2(0, 0); bullet->local_collider.count = 1; #else - bullet->sprite = sprite_tag_from_path(LIT("res/graphics/bullet.ase")); + bullet->sprite = sprite_tag_from_path(LIT("graphics/bullet.ase")); bullet->sprite_collider_slice = LIT("shape"); #endif } diff --git a/src/sound.c b/src/sound.c index 8505887d..103c6cd2 100644 --- a/src/sound.c +++ b/src/sound.c @@ -93,27 +93,30 @@ INTERNAL WORK_TASK_FUNC_DEF(sound_load_asset_task, vparams) logf_info("Loading sound \"%F\"", FMT_STR(path)); i64 start_ns = sys_time_ns(); - b32 success = true; struct string error_msg = LIT("Unknown error"); ASSERT(string_ends_with(path, LIT(".mp3"))); - if (resource_exists(path)) { - u64 decode_flags = 0; - if (flags & SOUND_FLAG_STEREO) { - decode_flags |= MP3_DECODE_FLAG_STEREO; - } - /* Decode */ + /* Decode */ + struct mp3_decode_result decoded = ZI; + { struct resource sound_rs = resource_open(path); - struct mp3_decode_result decoded = mp3_decode(scratch.arena, resource_get_data(&sound_rs), decode_flags); - resource_close(&sound_rs); - - if (!decoded.success) { - success = false; - error_msg = LIT("Failed to decode sound file"); - goto abort; + if (resource_exists(&sound_rs)) { + u64 decode_flags = 0; + if (flags & SOUND_FLAG_STEREO) { + decode_flags |= MP3_DECODE_FLAG_STEREO; + } + decoded = mp3_decode(scratch.arena, resource_get_data(&sound_rs), decode_flags); + if (!decoded.success) { + error_msg = LIT("Failed to decode sound file"); + } + } else { + error_msg = LIT("Resource not found"); } + resource_close(&sound_rs); + } + if (decoded.success) { /* Store */ struct sound *sound = NULL; i16 *samples = NULL; @@ -133,17 +136,8 @@ INTERNAL WORK_TASK_FUNC_DEF(sound_load_asset_task, vparams) f64 elapsed = SECONDS_FROM_NS(sys_time_ns() - start_ns); logf_info("Finished loading sound \"%F\" in %F seconds", FMT_STR(path), FMT_FLOAT(elapsed)); - asset_cache_mark_ready(asset, sound); } else { - success = false; - error_msg = LIT("Resource not found"); - goto abort; - } - - abort: - - if (!success) { logf_error("Error loading sound \"%F\": %F", FMT_STR(path), FMT_STR(error_msg)); /* Store */ diff --git a/src/sprite.c b/src/sprite.c index b596b507..5c2ad8ce 100644 --- a/src/sprite.c +++ b/src/sprite.c @@ -363,11 +363,17 @@ INTERNAL void cache_entry_load_texture(struct cache_ref ref, struct sprite_tag t { /* Decode */ struct ase_decode_image_result decoded = ZI; - if (resource_exists(path)) { + { struct resource texture_rs = resource_open(path); - decoded = ase_decode_image(scratch.arena, resource_get_data(&texture_rs)); + if (resource_exists(&texture_rs)) { + decoded = ase_decode_image(scratch.arena, resource_get_data(&texture_rs)); + } else { + logf_error("Sprite texture for \"%F\" not found", FMT_STR(path)); + } resource_close(&texture_rs); + } + if (decoded.success) { enum gpu_texture_format format = GPU_TEXTURE_FORMAT_R8G8B8A8_UNORM; if (decoded.srgb) { format = GPU_TEXTURE_FORMAT_R8G8B8A8_UNORM_SRGB; @@ -382,8 +388,6 @@ INTERNAL void cache_entry_load_texture(struct cache_ref ref, struct sprite_tag t e->texture->loaded = true; /* TODO: Query gpu for more accurate texture size in VRAM */ memory_size += (decoded.image.width * decoded.image.height) * sizeof(*decoded.image.pixels); - } else { - logf_error("Sprite [%F] \"%F\" not found", FMT_HEX(e->hash.v), FMT_STR(path)); } } arena_set_readonly(&e->arena); @@ -681,7 +685,17 @@ INTERNAL void cache_entry_load_sheet(struct cache_ref ref, struct sprite_tag tag { /* Decode */ struct ase_decode_sheet_result decoded = ZI; - if (resource_exists(path)) { + { + struct resource sheet_rs = resource_open(path); + if (resource_exists(&sheet_rs)) { + decoded = ase_decode_sheet(scratch.arena, resource_get_data(&sheet_rs)); + } else { + logf_error("Sprite sheet for \"%F\" not found", FMT_STR(path)); + } + resource_close(&sheet_rs); + } + + if (decoded.success) { struct resource sheet_rs = resource_open(path); decoded = ase_decode_sheet(scratch.arena, resource_get_data(&sheet_rs)); resource_close(&sheet_rs); @@ -691,8 +705,6 @@ INTERNAL void cache_entry_load_sheet(struct cache_ref ref, struct sprite_tag tag *e->sheet = init_sheet_from_ase_result(&e->arena, decoded); e->sheet->loaded = true; e->sheet->valid = true; - } else { - logf_error("Sprite \"%F\" not found", FMT_STR(path)); } } arena_set_readonly(&e->arena); diff --git a/src/sys.h b/src/sys.h index 6e9e69a7..5f2849fb 100644 --- a/src/sys.h +++ b/src/sys.h @@ -200,6 +200,7 @@ i64 sys_time_ns(void); struct sys_file { u64 handle; + b32 valid; }; struct sys_file_time { @@ -231,6 +232,7 @@ struct sys_file_time sys_file_get_time(struct sys_file file); struct sys_file_map { struct string mapped_memory; u64 handle; + b32 valid; }; struct sys_file_map sys_file_map_open_read(struct sys_file file); diff --git a/src/sys_win32.c b/src/sys_win32.c index 51d4332f..485ae03d 100644 --- a/src/sys_win32.c +++ b/src/sys_win32.c @@ -367,6 +367,7 @@ struct sys_file sys_file_open_read(struct string path) { __prof; struct temp_arena scratch = scratch_begin_no_conflict(); + struct sys_file file = ZI; wchar_t *path_wstr = wstr_from_string(scratch.arena, path); HANDLE handle = CreateFileW( @@ -378,9 +379,10 @@ struct sys_file sys_file_open_read(struct string path) FILE_ATTRIBUTE_NORMAL, NULL ); + file.handle = (u64)handle; + file.valid = handle != INVALID_HANDLE_VALUE; scratch_end(scratch); - struct sys_file file = { (u64)handle }; return file; } @@ -388,8 +390,9 @@ struct sys_file sys_file_open_read_wait(struct string path) { __prof; struct temp_arena scratch = scratch_begin_no_conflict(); - wchar_t *path_wstr = wstr_from_string(scratch.arena, path); + struct sys_file file = ZI; + wchar_t *path_wstr = wstr_from_string(scratch.arena, path); i32 delay_ms = 1; HANDLE handle; while ((handle = CreateFileW(path_wstr, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE) { @@ -403,18 +406,20 @@ struct sys_file sys_file_open_read_wait(struct string path) break; } } + file.handle = (u64)handle; + file.valid = handle != INVALID_HANDLE_VALUE; scratch_end(scratch); - return (struct sys_file) { (u64)handle }; + return file; } struct sys_file sys_file_open_write(struct string path) { __prof; struct temp_arena scratch = scratch_begin_no_conflict(); - wchar_t *path_wstr = wstr_from_string(scratch.arena, path); + struct sys_file file = ZI; - /* TODO: Handle errors / non-existing file (handle == INVALID_HANDLE_VALUE) */ + wchar_t *path_wstr = wstr_from_string(scratch.arena, path); HANDLE handle = CreateFileW( path_wstr, GENERIC_WRITE, @@ -424,17 +429,20 @@ struct sys_file sys_file_open_write(struct string path) FILE_ATTRIBUTE_NORMAL, NULL ); + file.handle = (u64)handle; + file.valid = handle != INVALID_HANDLE_VALUE; scratch_end(scratch); - return (struct sys_file) { (u64)handle }; + return file; } struct sys_file sys_file_open_append(struct string path) { __prof; struct temp_arena scratch = scratch_begin_no_conflict(); + struct sys_file file = ZI; + wchar_t *path_wstr = wstr_from_string(scratch.arena, path); - /* TODO: Handle errors / non-existing file (handle == INVALID_HANDLE_VALUE) */ HANDLE handle = CreateFileW( path_wstr, FILE_APPEND_DATA, @@ -444,15 +452,19 @@ struct sys_file sys_file_open_append(struct string path) FILE_ATTRIBUTE_NORMAL, NULL ); + file.handle = (u64)handle; + file.valid = handle != INVALID_HANDLE_VALUE; + scratch_end(scratch); - struct sys_file file = (struct sys_file) { (u64)handle }; return file; } void sys_file_close(struct sys_file file) { __prof; - CloseHandle((HANDLE)file.handle); + if (file.handle) { + CloseHandle((HANDLE)file.handle); + } } struct string sys_file_read_all(struct arena *arena, struct sys_file file) @@ -553,6 +565,7 @@ struct sys_file_time sys_file_get_time(struct sys_file file) struct sys_file_map sys_file_map_open_read(struct sys_file file) { __prof; + struct sys_file_map map = ZI; u64 size = sys_file_get_size(file); u8 *base_ptr = NULL; @@ -567,36 +580,30 @@ struct sys_file_map sys_file_map_open_read(struct sys_file file) 0, NULL ); - - if (!map_handle) { - ASSERT(false); - return (struct sys_file_map) { 0 }; + if (map_handle != INVALID_HANDLE_VALUE) { + base_ptr = MapViewOfFile( + map_handle, + FILE_MAP_READ, + 0, + 0, + 0 + ); + if (base_ptr == NULL) { + /* Failed to create view */ + CloseHandle(map_handle); + map_handle = INVALID_HANDLE_VALUE; + } } - - base_ptr = MapViewOfFile( - map_handle, - FILE_MAP_READ, - 0, - 0, - 0 - ); - - if (!base_ptr) { - /* Failed to create view */ - ASSERT(false); - CloseHandle(map_handle); - return (struct sys_file_map) { 0 }; - } - } else { - /* File is empty */ - ASSERT(false); - return (struct sys_file_map) { 0 }; } + if (map_handle == INVALID_HANDLE_VALUE) { + size = 0; + } + map.handle = (u64)map_handle; + map.mapped_memory = STRING(size, base_ptr); + map.valid = map_handle != INVALID_HANDLE_VALUE && base_ptr != NULL; - return (struct sys_file_map) { - .handle = (u64)map_handle, - .mapped_memory = STRING(size, base_ptr) - }; + + return map; } void sys_file_map_close(struct sys_file_map map) diff --git a/src/user.c b/src/user.c index 0a140c65..134283c4 100644 --- a/src/user.c +++ b/src/user.c @@ -1110,7 +1110,7 @@ INTERNAL void user_update(void) /* TODO: Something better */ if (sim_ent_has_prop(ent, SEPROP_TILE_CHUNK)) { struct v2i32 chunk_index = ent->tile_chunk_index; - struct sprite_tag tile_sprite = sprite_tag_from_path(LIT("res/graphics/tile.ase")); + struct sprite_tag tile_sprite = sprite_tag_from_path(LIT("graphics/tile.ase")); f32 tile_size = 1.f / SIM_TILES_PER_UNIT_SQRT; for (i32 tile_y = 0; tile_y < SIM_TILES_PER_CHUNK_SQRT; ++tile_y) { for (i32 tile_x = 0; tile_x < SIM_TILES_PER_CHUNK_SQRT; ++tile_x) { @@ -1307,7 +1307,7 @@ INTERNAL void user_update(void) #if 0 /* Draw contact info */ { - struct font *disp_font = font_load_async(LIT("res/fonts/fixedsys.ttf"), 12.0f); + struct font *disp_font = font_load_async(LIT("fonts/fixedsys.ttf"), 12.0f); if (disp_font) { f32 offset_px = 10; @@ -1424,7 +1424,7 @@ INTERNAL void user_update(void) #if 0 /* Test info */ { - struct font *disp_font = font_load_async(LIT("res/fonts/fixedsys.ttf"), 12.0f); + struct font *disp_font = font_load_async(LIT("fonts/fixedsys.ttf"), 12.0f); if (disp_font) { f32 offset_px = 10; struct string fmt = LIT( @@ -1567,7 +1567,7 @@ INTERNAL void user_update(void) struct v2 crosshair_pos = G.ui_cursor; u32 tint = RGBA_F(1, 1, 1, 1); - struct sprite_tag crosshair_tag = sprite_tag_from_path(LIT("res/graphics/crosshair.ase")); + struct sprite_tag crosshair_tag = sprite_tag_from_path(LIT("graphics/crosshair.ase")); struct sprite_texture *t = sprite_texture_from_tag_async(sprite_frame_scope, crosshair_tag); struct v2 size = V2(t->width, t->height); @@ -1760,7 +1760,7 @@ INTERNAL void user_update(void) struct sim_ent *ent = hovered_ent; struct v2 pos = v2_add(G.ui_cursor, V2(15, 15)); - struct font *font = font_load_async(LIT("res/fonts/fixedsys.ttf"), 12.0f); + struct font *font = font_load_async(LIT("fonts/fixedsys.ttf"), 12.0f); if (font) { struct temp_arena temp = arena_temp_begin(scratch.arena); @@ -1780,7 +1780,7 @@ INTERNAL void user_update(void) if (G.debug_draw) { f32 spacing = 20; struct v2 pos = V2(10, 8); - struct font *font = font_load_async(LIT("res/fonts/fixedsys.ttf"), 12.0f); + struct font *font = font_load_async(LIT("fonts/fixedsys.ttf"), 12.0f); if (font) { struct temp_arena temp = arena_temp_begin(scratch.arena);