summaryrefslogtreecommitdiff
path: root/asset.cpp
diff options
context:
space:
mode:
authorquou <quou@disroot.org>2024-12-22 22:19:36 +1100
committerquou <quou@disroot.org>2024-12-22 22:19:36 +1100
commit58245585cbe77e6c03ebe13f29e10393ff3c45b4 (patch)
tree6c3dcd8e9adcbc699318d4062bb2cf594116702e /asset.cpp
parent82767020e84ec8c1af2e3817fc7efede5497c82d (diff)
cute asset loading system
Diffstat (limited to 'asset.cpp')
-rw-r--r--asset.cpp101
1 files changed, 101 insertions, 0 deletions
diff --git a/asset.cpp b/asset.cpp
new file mode 100644
index 0000000..09260e0
--- /dev/null
+++ b/asset.cpp
@@ -0,0 +1,101 @@
+#include "asset.hpp"
+
+extern "C" {
+#include "memory.h"
+#include "pack.h"
+#include "plat.h"
+#include "str.h"
+}
+
+#define max_asset_types 32
+
+struct RLoader {
+ char magic[4];
+ Asset_Loader* loader;
+};
+
+struct Manager {
+ RLoader loaders[max_asset_types];
+
+ Manager() {
+ int i;
+ for (i = 0; i < max_asset_types; i++) {
+ loaders[i].loader = 0;
+ }
+ }
+
+ RLoader* find_loader(const char* magic) {
+ uint32_t hash = hash_string(magic);
+ int bucket = (int)(hash % max_asset_types);
+ int i;
+ for (i = 0; i < max_asset_types; i++) {
+ RLoader& e = loaders[bucket];
+ if (!e.loader || (
+ e.magic[0] == magic[0] &&
+ e.magic[1] == magic[1] &&
+ e.magic[2] == magic[2] &&
+ e.magic[3] == magic[3]
+ )) return &e;
+ bucket = (bucket + 1) % max_asset_types;
+ }
+ return 0;
+ }
+
+ Asset_Loader& get_loader(const char* magic) {
+ RLoader* r = find_loader(magic);
+ assert(r != 0 && r->loader != 0);
+ return *r->loader;
+ }
+
+ void set_loader(const char* magic, Asset_Loader* l) {
+ RLoader* r = find_loader(magic);
+ assert(r != 0 && r->loader == 0);
+ r->magic[0] = magic[0];
+ r->magic[1] = magic[1];
+ r->magic[2] = magic[2];
+ r->magic[3] = magic[3];
+ r->loader = l;
+ }
+} manager;
+
+void register_asset_loader(
+ const char* magic,
+ Asset_Loader* loader
+) {
+ manager.set_loader(magic, loader);
+}
+
+void Asset_Arena::init(Arena* arena, const char* pack_name) {
+ p = pack_open(pack_name, arena);
+ a = arena;
+ assets = 0;
+}
+
+void Asset_Arena::destroy() {
+ Asset* a;
+ for (a = assets; a; a = a->next) {
+ a->unload(a->loader);
+ }
+ pack_close(p);
+}
+
+void Asset_Arena::claim(Asset* a) {
+ if (assets) {
+ a->next = assets;
+ assets = a;
+ } else assets = a;
+}
+
+Asset* Asset_Arena::load(const char* name) {
+ char magic[4];
+ Pack_File* f = pack_open_file(p, name);
+ if (!f) return 0;
+ pack_read(f, magic, 4);
+ pack_seek(f, 0, seek_rel_start);
+ Asset_Loader& loader = manager.get_loader(magic);
+ Asset* asset = loader.load(a, f);
+ asset->loader = &loader;
+ pack_close_file(f);
+ claim(asset);
+ return asset;
+}