#include "asset.h" #include "memory.h" #include "plat.h" #include "standard.h" #include 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; }