summaryrefslogtreecommitdiff
path: root/asset.c
diff options
context:
space:
mode:
Diffstat (limited to 'asset.c')
-rw-r--r--asset.c152
1 files changed, 152 insertions, 0 deletions
diff --git a/asset.c b/asset.c
new file mode 100644
index 0000000..0eca404
--- /dev/null
+++ b/asset.c
@@ -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;
+}
+