don't prefix resource names with res directory. check for resource existence after opening.

This commit is contained in:
jacob 2025-05-23 23:35:13 -05:00
parent ad05469411
commit 2dc481bfc0
14 changed files with 195 additions and 156 deletions

View File

@ -1,4 +1,4 @@
#include "res/shaders/common.hlsl" #include "shaders/common.hlsl"
struct vs_input { struct vs_input {
DECL(float4, pos); DECL(float4, pos);

View File

@ -1,4 +1,4 @@
#include "res/shaders/common.hlsl" #include "shaders/common.hlsl"
struct { struct {
SamplerState sampler0; SamplerState sampler0;

View File

@ -805,7 +805,11 @@ struct ase_decode_image_result ase_decode_image(struct arena *arena, struct stri
/* ASSERT all data was read */ /* ASSERT all data was read */
ASSERT(br_num_bytes_left(&br) == 0); ASSERT(br_num_bytes_left(&br) == 0);
abort: abort:
if (res.errors.count <= 0) {
res.success = true;
}
scratch_end(scratch); scratch_end(scratch);
return res; 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.span_head = span_head;
res.slice_key_head = slice_key_head; res.slice_key_head = slice_key_head;
if (res.errors.count <= 0) {
res.success = true;
}
return res; return res;
} }

View File

@ -49,6 +49,7 @@ struct ase_decode_image_result {
struct image_rgba image; struct image_rgba image;
struct ase_error_list errors; struct ase_error_list errors;
b32 srgb; b32 srgb;
b32 success;
}; };
struct ase_decode_sheet_result { struct ase_decode_sheet_result {
@ -61,6 +62,7 @@ struct ase_decode_sheet_result {
struct ase_span *span_head; struct ase_span *span_head;
struct ase_slice_key *slice_key_head; struct ase_slice_key *slice_key_head;
struct ase_error_list errors; struct ase_error_list errors;
b32 success;
}; };
struct ase_decode_image_result ase_decode_image(struct arena *arena, struct string encoded); struct ase_decode_image_result ase_decode_image(struct arena *arena, struct string encoded);

View File

@ -105,17 +105,16 @@ INTERNAL WORK_TASK_FUNC_DEF(font_load_asset_task, vparams)
i64 start_ns = sys_time_ns(); i64 start_ns = sys_time_ns();
ASSERT(string_ends_with(path, LIT(".ttf"))); 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 */ /* FIME: Load baked font instead of panicking */
sys_panic(string_format(scratch.arena, sys_panic(string_format(scratch.arena,
LIT("Font \"%F\" not found"), LIT("Font \"%F\" not found"),
FMT_STR(path))); 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)); 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); resource_close(&res);

View File

@ -43,8 +43,6 @@
#define DX11_SWAPCHAIN_FORMAT (DXGI_FORMAT_R8G8B8A8_UNORM) #define DX11_SWAPCHAIN_FORMAT (DXGI_FORMAT_R8G8B8A8_UNORM)
#define DX11_SWAPCHAIN_RTV_FORMAT (DXGI_FORMAT_R8G8B8A8_UNORM_SRGB) #define DX11_SWAPCHAIN_RTV_FORMAT (DXGI_FORMAT_R8G8B8A8_UNORM_SRGB)
#define SHADER_NAME_LEN 255
struct dx11_shader { struct dx11_shader {
enum shader_kind kind; enum shader_kind kind;
b32 valid; /* Is this shader allocated */ b32 valid; /* Is this shader allocated */
@ -52,9 +50,6 @@ struct dx11_shader {
ID3D11InputLayout *input_layout; ID3D11InputLayout *input_layout;
ID3D11VertexShader *vs; ID3D11VertexShader *vs;
ID3D11PixelShader *ps; ID3D11PixelShader *ps;
struct string name;
u8 name_text[SHADER_NAME_LEN];
}; };
struct dx11_constant_buffer_data { struct dx11_constant_buffer_data {
@ -461,7 +456,7 @@ INTERNAL void init_shader_table(void)
/* Triangle shader layout */ /* Triangle shader layout */
G.shader_info[SHADER_TRIANGLE] = (struct dx11_shader_desc) { G.shader_info[SHADER_TRIANGLE] = (struct dx11_shader_desc) {
.kind = SHADER_TRIANGLE, .kind = SHADER_TRIANGLE,
.name_cstr = "res/shaders/triangle.hlsl", .name_cstr = "shaders/triangle.hlsl",
.vertex_size = sizeof(struct triangle_shader_vertex), .vertex_size = sizeof(struct triangle_shader_vertex),
.input_layout_desc = { .input_layout_desc = {
{ "pos", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "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 */ /* Grid shader layout */
G.shader_info[SHADER_GRID] = (struct dx11_shader_desc) { G.shader_info[SHADER_GRID] = (struct dx11_shader_desc) {
.kind = SHADER_GRID, .kind = SHADER_GRID,
.name_cstr = "res/shaders/grid.hlsl", .name_cstr = "shaders/grid.hlsl",
.vertex_size = sizeof(struct grid_shader_vertex), .vertex_size = sizeof(struct grid_shader_vertex),
.input_layout_desc = { .input_layout_desc = {
{ "pos", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "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")); 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; handler->has_open_resource = true;
struct resource *res = &handler->res; struct string data = resource_get_data(&res);
*res = resource_open(name);
struct string data = resource_get_data(res);
*data_out = data.text; *data_out = data.text;
*data_len_out = data.len; *data_len_out = data.len;
result = S_OK; 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 temp_arena scratch = scratch_begin(arena);
struct string error_str = ZI; struct string error_str = ZI;
struct string res_name = resource_get_name(src_res); struct string shader_name = string_from_cstr_no_limit(shader_desc->name_cstr);
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)));
}
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->kind = shader_desc->kind;
shader->vertex_size = shader_desc->vertex_size; shader->vertex_size = shader_desc->vertex_size;
#if RESOURCE_RELOADING #if RESOURCE_RELOADING
@ -677,7 +663,7 @@ INTERNAL struct string shader_alloc(struct arena *arena, struct dx11_shader *sha
b32 success = false; b32 success = false;
{ {
struct string shader_src = resource_get_data(src_res); 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 */ /* Compile shader */
/* TODO: pre-compile shaders w/ FXC? */ /* 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); 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 name = string_from_cstr_no_limit(desc->name_cstr);
struct string error_msg = ZI; 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 dx11_shader new_shader = ZI;
struct string comp_error = shader_alloc(scratch.arena, &new_shader, desc, &src_res); struct string comp_error = shader_alloc(scratch.arena, &new_shader, desc, &src_res);
if (comp_error.len == 0) { 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; *old_shader = new_shader;
} else { } else {
error_msg = string_format(scratch.arena, error_msg = string_format(scratch.arena,
LIT("Failed to compile shader \"%F\":\n\n%F"), LIT("Failed to compile shader \"%F\":\n\n%F"),
FMT_STR(name), FMT_STR(name),
FMT_STR(comp_error)); FMT_STR(comp_error));
shader_release(&new_shader); 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 (error_msg.len != 0) {
if (old_shader->valid) { if (old_shader->valid) {
/* If shader failed to load but a working shader already exists, just error rather than panicking */ /* If shader failed to load but a working shader already exists, just error rather than panicking */

View File

@ -59,11 +59,11 @@ struct resource_startup_receipt resource_startup(void)
if (embedded_data.len <= 0) { if (embedded_data.len <= 0) {
sys_panic(LIT("No embedded resources found")); 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 #else
/* Ensure we have the right working directory */ /* Ensure we have the right working directory */
if (!sys_is_dir(LIT("res"))) { 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 #endif
@ -88,29 +88,54 @@ struct resource_startup_receipt resource_startup(void)
* Open / close * Open / close
* ========================== */ * ========================== */
struct resource resource_open(struct string path) struct resource resource_open(struct string name)
{ {
__prof; __prof;
#if RESOURCES_EMBEDDED #if RESOURCES_EMBEDDED
struct resource res = ZI; struct resource res = ZI;
struct tar_entry *entry = tar_get(&G.archive, path); struct tar_entry *entry = tar_get(&G.archive, name);
if (entry) { if (entry) {
res._data = entry->data; res._data = entry->data;
res._file_name = entry->file_name; res._name = entry->file_name;
res._exists = true;
} }
return res; return res;
#else #else
struct resource res = ZI; struct resource res = ZI;
if (path.len < ARRAY_COUNT(res._file_name_text)) { if (name.len < ARRAY_COUNT(res._name_text)) {
struct sys_file file = sys_file_open_read_wait(path); u8 path_text[RESOURCE_NAME_LEN_MAX + (sizeof("res/") - 1)];
struct sys_file_map file_map = sys_file_map_open_read(file); struct string path = ZI;
struct string data = sys_file_map_data(file_map); {
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._data = data;
res._file = file; res._file = file;
res._file_map = file_map; res._file_map = file_map;
res._file_name_len = path.len; res._name_len = name.len;
MEMCPY(res._file_name_text, path.text, path.len); MEMCPY(res._name_text, name.text, name.len);
} else { } else {
ASSERT(false); ASSERT(false);
} }
@ -126,21 +151,6 @@ void resource_close(struct resource *res_ptr)
} }
#endif #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 * Watch
* ========================== */ * ========================== */

View File

@ -3,25 +3,36 @@
#include "sys.h" #include "sys.h"
#define RESOURCE_NAME_LEN_MAX 255
/* A resource contains data that can be retrieved globally by name. /* A resource contains data that can be retrieved globally by name.
* If enabled during compilation, resource data is embedded in the * If enabled during compilation, resource data is embedded in the
* executable. Otherwise each resource represents a file on disk. */ * executable. Otherwise each resource represents a file on disk. */
struct resource { struct resource {
struct string _data; struct string _data;
b32 _exists;
#if RESOURCES_EMBEDDED #if RESOURCES_EMBEDDED
struct string _file_name; struct string _name;
#else #else
struct sys_file _file; struct sys_file _file;
struct sys_file_map _file_map; struct sys_file_map _file_map;
u8 _file_name_text[256]; u8 _name_text[RESOURCE_NAME_LEN_MAX];
u8 _file_name_len; u8 _name_len;
#endif #endif
}; };
/* ========================== *
* Startup
* ========================== */
struct resource_startup_receipt { i32 _; }; struct resource_startup_receipt { i32 _; };
struct resource_startup_receipt resource_startup(void); 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 #if RESOURCES_EMBEDDED
#define resource_close(res_ptr) #define resource_close(res_ptr)
@ -29,16 +40,24 @@ struct resource resource_open(struct string path);
void resource_close(struct resource *res_ptr); void resource_close(struct resource *res_ptr);
#endif #endif
b32 resource_exists(struct string path); /* ========================== *
* Data
* ========================== */
#define resource_get_data(res_ptr) (res_ptr)->_data #define resource_get_data(res_ptr) (res_ptr)->_data
#define resource_exists(res_ptr) (res_ptr)->_exists
#if RESOURCES_EMBEDDED #if RESOURCES_EMBEDDED
#define resource_get_name(res_ptr) (res_ptr)->_file_name #define resource_get_name(res_ptr) (res_ptr)->_name
#else #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 #endif
/* ========================== *
* Watch
* ========================== */
#define RESOURCE_WATCH_CALLBACK_FUNC_DEF(func_name, arg_name) void func_name(struct string arg_name) #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); typedef RESOURCE_WATCH_CALLBACK_FUNC_DEF(resource_watch_callback, name);

View File

@ -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) INTERNAL struct sim_ent *test_spawn_smg(struct sim_ent *parent)
{ {
struct sim_ent *e = sim_ent_alloc_sync_src(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); sim_ent_enable_prop(e, SEPROP_ATTACHED);
e->attach_slice = LIT("attach.wep"); 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) INTERNAL struct sim_ent *test_spawn_launcher(struct sim_ent *parent)
{ {
struct sim_ent *e = sim_ent_alloc_sync_src(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); sim_ent_enable_prop(e, SEPROP_ATTACHED);
e->attach_slice = LIT("attach.wep"); 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) INTERNAL struct sim_ent *test_spawn_chucker(struct sim_ent *parent)
{ {
struct sim_ent *chucker = sim_ent_alloc_sync_src(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); sim_ent_enable_prop(chucker, SEPROP_ATTACHED);
chucker->attach_slice = LIT("attach.wep"); 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); 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->mass_unscaled = 10;
e->inertia_unscaled = 5; 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.unarmed");
//e->sprite_span_name = LIT("idle.one_handed"); //e->sprite_span_name = LIT("idle.one_handed");
e->sprite_span_name = LIT("idle.two_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); struct xform xf = XFORM_TRS(.t = pos, .r = r, .s = size);
sim_ent_set_xform(e, xf); 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->layer = SIM_LAYER_SHOULDERS;
e->sprite_tint = ALPHA_F(COLOR_BLUE, 0.75); 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); struct xform xf = XFORM_TRS(.t = pos, .r = r, .s = size);
sim_ent_set_xform(e, xf); 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->sprite_collider_slice = LIT("shape");
e->layer = SIM_LAYER_SHOULDERS; 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); struct xform xf = XFORM_TRS(.t = pos, .r = r, .s = size);
sim_ent_set_xform(e, xf); 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->layer = SIM_LAYER_SHOULDERS;
e->sprite_tint = COLOR_RED; 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); sim_ent_set_xform(e, xf);
e->layer = SIM_LAYER_WALLS; 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; 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 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); 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->sprite_tint = RGBA_F(1, 1, 1, 0.25f);
decal->layer = SIM_LAYER_FLOOR_DECALS; decal->layer = SIM_LAYER_FLOOR_DECALS;
sim_ent_set_xform(decal, xf); 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.points[0] = V2(0, 0);
bullet->local_collider.count = 1; bullet->local_collider.count = 1;
#else #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"); bullet->sprite_collider_slice = LIT("shape");
#endif #endif
} }

View File

@ -93,27 +93,30 @@ INTERNAL WORK_TASK_FUNC_DEF(sound_load_asset_task, vparams)
logf_info("Loading sound \"%F\"", FMT_STR(path)); logf_info("Loading sound \"%F\"", FMT_STR(path));
i64 start_ns = sys_time_ns(); i64 start_ns = sys_time_ns();
b32 success = true;
struct string error_msg = LIT("Unknown error"); struct string error_msg = LIT("Unknown error");
ASSERT(string_ends_with(path, LIT(".mp3"))); 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 resource sound_rs = resource_open(path);
struct mp3_decode_result decoded = mp3_decode(scratch.arena, resource_get_data(&sound_rs), decode_flags); if (resource_exists(&sound_rs)) {
resource_close(&sound_rs); u64 decode_flags = 0;
if (flags & SOUND_FLAG_STEREO) {
if (!decoded.success) { decode_flags |= MP3_DECODE_FLAG_STEREO;
success = false; }
error_msg = LIT("Failed to decode sound file"); decoded = mp3_decode(scratch.arena, resource_get_data(&sound_rs), decode_flags);
goto abort; 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 */ /* Store */
struct sound *sound = NULL; struct sound *sound = NULL;
i16 *samples = 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); 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)); logf_info("Finished loading sound \"%F\" in %F seconds", FMT_STR(path), FMT_FLOAT(elapsed));
asset_cache_mark_ready(asset, sound); asset_cache_mark_ready(asset, sound);
} else { } 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)); logf_error("Error loading sound \"%F\": %F", FMT_STR(path), FMT_STR(error_msg));
/* Store */ /* Store */

View File

@ -363,11 +363,17 @@ INTERNAL void cache_entry_load_texture(struct cache_ref ref, struct sprite_tag t
{ {
/* Decode */ /* Decode */
struct ase_decode_image_result decoded = ZI; struct ase_decode_image_result decoded = ZI;
if (resource_exists(path)) { {
struct resource texture_rs = resource_open(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); resource_close(&texture_rs);
}
if (decoded.success) {
enum gpu_texture_format format = GPU_TEXTURE_FORMAT_R8G8B8A8_UNORM; enum gpu_texture_format format = GPU_TEXTURE_FORMAT_R8G8B8A8_UNORM;
if (decoded.srgb) { if (decoded.srgb) {
format = GPU_TEXTURE_FORMAT_R8G8B8A8_UNORM_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; e->texture->loaded = true;
/* TODO: Query gpu for more accurate texture size in VRAM */ /* TODO: Query gpu for more accurate texture size in VRAM */
memory_size += (decoded.image.width * decoded.image.height) * sizeof(*decoded.image.pixels); 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); arena_set_readonly(&e->arena);
@ -681,7 +685,17 @@ INTERNAL void cache_entry_load_sheet(struct cache_ref ref, struct sprite_tag tag
{ {
/* Decode */ /* Decode */
struct ase_decode_sheet_result decoded = ZI; 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); struct resource sheet_rs = resource_open(path);
decoded = ase_decode_sheet(scratch.arena, resource_get_data(&sheet_rs)); decoded = ase_decode_sheet(scratch.arena, resource_get_data(&sheet_rs));
resource_close(&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 = init_sheet_from_ase_result(&e->arena, decoded);
e->sheet->loaded = true; e->sheet->loaded = true;
e->sheet->valid = true; e->sheet->valid = true;
} else {
logf_error("Sprite \"%F\" not found", FMT_STR(path));
} }
} }
arena_set_readonly(&e->arena); arena_set_readonly(&e->arena);

View File

@ -200,6 +200,7 @@ i64 sys_time_ns(void);
struct sys_file { struct sys_file {
u64 handle; u64 handle;
b32 valid;
}; };
struct sys_file_time { 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 sys_file_map {
struct string mapped_memory; struct string mapped_memory;
u64 handle; u64 handle;
b32 valid;
}; };
struct sys_file_map sys_file_map_open_read(struct sys_file file); struct sys_file_map sys_file_map_open_read(struct sys_file file);

View File

@ -367,6 +367,7 @@ struct sys_file sys_file_open_read(struct string path)
{ {
__prof; __prof;
struct temp_arena scratch = scratch_begin_no_conflict(); struct temp_arena scratch = scratch_begin_no_conflict();
struct sys_file file = ZI;
wchar_t *path_wstr = wstr_from_string(scratch.arena, path); wchar_t *path_wstr = wstr_from_string(scratch.arena, path);
HANDLE handle = CreateFileW( HANDLE handle = CreateFileW(
@ -378,9 +379,10 @@ struct sys_file sys_file_open_read(struct string path)
FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL,
NULL NULL
); );
file.handle = (u64)handle;
file.valid = handle != INVALID_HANDLE_VALUE;
scratch_end(scratch); scratch_end(scratch);
struct sys_file file = { (u64)handle };
return file; return file;
} }
@ -388,8 +390,9 @@ struct sys_file sys_file_open_read_wait(struct string path)
{ {
__prof; __prof;
struct temp_arena scratch = scratch_begin_no_conflict(); 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; i32 delay_ms = 1;
HANDLE handle; HANDLE handle;
while ((handle = CreateFileW(path_wstr, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE) { 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; break;
} }
} }
file.handle = (u64)handle;
file.valid = handle != INVALID_HANDLE_VALUE;
scratch_end(scratch); scratch_end(scratch);
return (struct sys_file) { (u64)handle }; return file;
} }
struct sys_file sys_file_open_write(struct string path) struct sys_file sys_file_open_write(struct string path)
{ {
__prof; __prof;
struct temp_arena scratch = scratch_begin_no_conflict(); 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( HANDLE handle = CreateFileW(
path_wstr, path_wstr,
GENERIC_WRITE, GENERIC_WRITE,
@ -424,17 +429,20 @@ struct sys_file sys_file_open_write(struct string path)
FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL,
NULL NULL
); );
file.handle = (u64)handle;
file.valid = handle != INVALID_HANDLE_VALUE;
scratch_end(scratch); scratch_end(scratch);
return (struct sys_file) { (u64)handle }; return file;
} }
struct sys_file sys_file_open_append(struct string path) struct sys_file sys_file_open_append(struct string path)
{ {
__prof; __prof;
struct temp_arena scratch = scratch_begin_no_conflict(); struct temp_arena scratch = scratch_begin_no_conflict();
struct sys_file file = ZI;
wchar_t *path_wstr = wstr_from_string(scratch.arena, path); wchar_t *path_wstr = wstr_from_string(scratch.arena, path);
/* TODO: Handle errors / non-existing file (handle == INVALID_HANDLE_VALUE) */
HANDLE handle = CreateFileW( HANDLE handle = CreateFileW(
path_wstr, path_wstr,
FILE_APPEND_DATA, FILE_APPEND_DATA,
@ -444,15 +452,19 @@ struct sys_file sys_file_open_append(struct string path)
FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL,
NULL NULL
); );
file.handle = (u64)handle;
file.valid = handle != INVALID_HANDLE_VALUE;
scratch_end(scratch); scratch_end(scratch);
struct sys_file file = (struct sys_file) { (u64)handle };
return file; return file;
} }
void sys_file_close(struct sys_file file) void sys_file_close(struct sys_file file)
{ {
__prof; __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) 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) struct sys_file_map sys_file_map_open_read(struct sys_file file)
{ {
__prof; __prof;
struct sys_file_map map = ZI;
u64 size = sys_file_get_size(file); u64 size = sys_file_get_size(file);
u8 *base_ptr = NULL; u8 *base_ptr = NULL;
@ -567,36 +580,30 @@ struct sys_file_map sys_file_map_open_read(struct sys_file file)
0, 0,
NULL NULL
); );
if (map_handle != INVALID_HANDLE_VALUE) {
if (!map_handle) { base_ptr = MapViewOfFile(
ASSERT(false); map_handle,
return (struct sys_file_map) { 0 }; 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, return map;
.mapped_memory = STRING(size, base_ptr)
};
} }
void sys_file_map_close(struct sys_file_map map) void sys_file_map_close(struct sys_file_map map)

View File

@ -1110,7 +1110,7 @@ INTERNAL void user_update(void)
/* TODO: Something better */ /* TODO: Something better */
if (sim_ent_has_prop(ent, SEPROP_TILE_CHUNK)) { if (sim_ent_has_prop(ent, SEPROP_TILE_CHUNK)) {
struct v2i32 chunk_index = ent->tile_chunk_index; 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; 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_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) { 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 #if 0
/* Draw contact info */ /* 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) { if (disp_font) {
f32 offset_px = 10; f32 offset_px = 10;
@ -1424,7 +1424,7 @@ INTERNAL void user_update(void)
#if 0 #if 0
/* Test info */ /* 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) { if (disp_font) {
f32 offset_px = 10; f32 offset_px = 10;
struct string fmt = LIT( struct string fmt = LIT(
@ -1567,7 +1567,7 @@ INTERNAL void user_update(void)
struct v2 crosshair_pos = G.ui_cursor; struct v2 crosshair_pos = G.ui_cursor;
u32 tint = RGBA_F(1, 1, 1, 1); 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 sprite_texture *t = sprite_texture_from_tag_async(sprite_frame_scope, crosshair_tag);
struct v2 size = V2(t->width, t->height); struct v2 size = V2(t->width, t->height);
@ -1760,7 +1760,7 @@ INTERNAL void user_update(void)
struct sim_ent *ent = hovered_ent; struct sim_ent *ent = hovered_ent;
struct v2 pos = v2_add(G.ui_cursor, V2(15, 15)); 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) { if (font) {
struct temp_arena temp = arena_temp_begin(scratch.arena); struct temp_arena temp = arena_temp_begin(scratch.arena);
@ -1780,7 +1780,7 @@ INTERNAL void user_update(void)
if (G.debug_draw) { if (G.debug_draw) {
f32 spacing = 20; f32 spacing = 20;
struct v2 pos = V2(10, 8); 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) { if (font) {
struct temp_arena temp = arena_temp_begin(scratch.arena); struct temp_arena temp = arena_temp_begin(scratch.arena);