diff options
Diffstat (limited to 'asset.c')
-rw-r--r-- | asset.c | 152 |
1 files changed, 152 insertions, 0 deletions
@@ -0,0 +1,152 @@ +#include "asset.h" +#include "memory.h" +#include "plat.h" +#include "standard.h" +#include <stdlib.h> + +static const Asset_Meta asset_meta[] = { +#define x(id, type, path) { type, path }, + assets_xmacro() +#undef x +}; + +Asset* loaded_assets[asset_id_count]; + +static void init_mesh_asset(Asset* asset, void* raw, int size) { + Mesh* m = raw; + asset->payload = raw; + asset->payload_size = size; + m->p = (int*)&m[1]; + m->n = (int*)&m->p[m->pc * 3]; + m->t = (int*)&m->n[m->nc * 3]; + m->verts = (Mesh_Vert*)&m->t[m->tc * 2]; +} + +/* Loading assets isn't that efficient. Too bad. */ +static int get_asset_info( + File* pack, + int pack_count, + const char* name, + int* offset, + int* size +) { + int head_size = 8, i; + char buf[56]; + file_seek(pack, head_size, file_whence_begin); + for (i = 0; i < pack_count; i++) { + file_read(pack, size, 4); + file_read(pack, offset, 4); + file_read(pack, buf, sizeof buf); + if (string_equal(buf, name)) { + return 1; + } + } + return 0; +} + +Asset_Data* read_asset_data( + const char* name, + Arena* arena +) { + Asset_Data* r = 0; + File* pack; + int pack_count, offset, size; + pack = file_open("pack", file_flags_read); + if (!pack) { + print_err("Couldn't find 'pack'. Did you delete it?\n"); + pbreak(error_file_not_found); + return 0; + } + file_read(pack, &pack_count, 4); + if (get_asset_info(pack, pack_count, name, &offset, &size)) { + r = arena_alloc(arena, sizeof *r); + r->offset = offset; + r->size = size; + r->buffer = arena_alloc(arena, r->size); + file_seek(pack, offset, file_whence_begin); + file_read(pack, r->buffer, r->size); + } else { + print_err(\ + "%s doesn't exist in the pack. " + "Is the pack corrupt?\n", + name + ); + file_close(pack); + return 0; + } + file_close(pack); + return r; +} + +void preload_assets(Arena* mem) { + int offset, size, pack_count, id; + Asset* asset; + File* pack; + const Asset_Meta* meta; + const char* name; + Asset_Type type; + void* raw; + pack = file_open("pack", file_flags_read); + if (!pack) { + print_err("Couldn't find 'pack'. Did you delete it?\n"); + pbreak(error_file_not_found); + } + file_read(pack, &pack_count, 4); +#define gi(e_) \ + meta = get_asset_meta((Asset_ID)id); \ + name = meta->name; \ + type = meta->type; \ + if (get_asset_info( \ + pack, \ + pack_count, \ + name, \ + &offset, \ + &size \ + )) { \ + file_seek(pack, offset, file_whence_begin); \ + e_ \ + } else { \ + print_err( \ + "%s doesn't exist in the pack. " \ + "Is the pack corrupt?\n", \ + name \ + ); \ + pbreak(error_file_not_found); \ + } + for (id = 0; id < asset_id_count; id++) { + gi({ + asset = arena_alloc(mem, sizeof *asset); + asset->id = (Asset_ID)id; + asset->type = type; + raw = arena_alloc(mem, size); + file_seek(pack, offset, file_whence_begin); + file_read(pack, raw, size); + switch (type) { + case asset_type_mesh: + init_mesh_asset(asset, raw, size); + break; + default: + print_err("Invalid asset type.\n"); + pbreak(error_invalid_asset); + break; + } + loaded_assets[id] = asset; + }); + } +#undef gi + file_close(pack); +} + +const Asset* get_asset(Asset_ID id) { + return loaded_assets[id]; +} + +const Asset_Meta* get_asset_meta(Asset_ID id) { + return &asset_meta[id]; +} + +const struct Mesh* get_mesh(Asset_ID id) { + const Asset* a = get_asset(id); + return (struct Mesh*)a->payload; +} + |