#include #include "asset.h" #include "error.h" #include "platform.h" #include "standard.h" static const char* const asset_vpaths[] = { /* asset_id_usr */ "data/usr.img" }; static struct { FILE* pack; int pack_count; unsigned char memory[asset_memory]; int memory_ptr; Bitmap bitmaps[bitmap_asset_count]; int bitmap_count; } asset_manager; void* asset_mgr_alloc(int size) { void* a; a = &asset_manager.memory[asset_manager.memory_ptr]; asset_manager.memory_ptr += size; #ifdef DEBUG if (asset_manager.memory_ptr > asset_memory) { platform_err("Out of asset memory.\n"); platform_abort(error_out_of_memory); } #endif return a; } /* Loading assets isn't that efficient. Too bad. */ int get_asset_info(const char* name, int* offset, int* size) { int head_size = 8, i; char buf[56]; fseek(asset_manager.pack, head_size, SEEK_SET); for (i = 0; i < asset_manager.pack_count; i++) { fread(size, 4, 1, asset_manager.pack); fread(offset, 4, 1, asset_manager.pack); fread(buf, 1, sizeof buf, asset_manager.pack); if (string_equal(buf, name)) { return 1; } } return 0; } void load_assets() { int i, offset, size; const char* name; Bitmap* bmp; FILE* pack; char magic[4]; asset_manager.bitmap_count = 0; pack = fopen("pack", "rb"); if (!pack) { platform_err("Failed to open 'pack'. Did you delete it?"); platform_abort(error_file_not_found); } asset_manager.pack = pack; fread(&asset_manager.pack_count, 4, 1, pack); #define gi(e_) \ name = asset_vpaths[i]; \ if (get_asset_info(name, &offset, &size)) { \ fseek(pack, offset, SEEK_SET); \ e_ \ } else { \ platform_err( \ "%s doesn't exist in the pack. " \ "Is the pack corrupt?\n", \ name \ ); \ platform_abort(error_file_not_found); \ } for (i = 0; i < bitmap_asset_count; i++) { gi({ bmp = &asset_manager.bitmaps[asset_manager.bitmap_count++]; fread(magic, 4, 1, pack); if (!string_equal(magic, "IMAG")) { platform_err("Invalid asset\n"); platform_abort(error_invalid_asset); } fread(&bmp->w, 4, 1, pack); fread(&bmp->h, 4, 1, pack); size = bmp->w * bmp->h * sizeof *bmp->pixels; bmp->pixels = asset_mgr_alloc(size); fread(bmp->pixels, 1, size, pack); }); } #undef gi fclose(pack); } const Bitmap* get_bitmap(Asset_ID id) { return &asset_manager.bitmaps[id]; }