diff options
Diffstat (limited to 'asset.c')
-rw-r--r-- | asset.c | 117 |
1 files changed, 117 insertions, 0 deletions
@@ -0,0 +1,117 @@ +#include <stdio.h> + +#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]; +} |