From 249e447920fa86da7d136b187d250db5489ddaf9 Mon Sep 17 00:00:00 2001 From: Nunuhara Cabbage Date: Sun, 9 Apr 2023 09:25:05 -0700 Subject: [PATCH] asset_manager: use built-in afa index The afa implementation from libsys4 now handles basename indexing, so we use that instead of creating a separate index. Also, afa v1 is now properly supported in libsys4, so there is no need for the id_indexed_afa hack. --- include/xsystem4.h | 2 - src/asset_manager.c | 131 +++++++++----------------------------------- src/hacks.c | 7 --- subprojects/libsys4 | 2 +- 4 files changed, 26 insertions(+), 116 deletions(-) diff --git a/include/xsystem4.h b/include/xsystem4.h index ac012cf..78f29ba 100644 --- a/include/xsystem4.h +++ b/include/xsystem4.h @@ -77,6 +77,4 @@ extern bool game_rance6_mg; extern bool game_rance7_mg; extern bool game_rance8; -extern bool id_indexed_afa; - #endif /* XSYSTEM4_H */ diff --git a/src/asset_manager.c b/src/asset_manager.c index f15dfb3..c1f7a59 100644 --- a/src/asset_manager.c +++ b/src/asset_manager.c @@ -74,7 +74,6 @@ struct asset_manager_ald { struct asset_manager_afa { struct asset_manager manager; struct afa_archive *archives[MAX_ARCHIVES]; - struct hash_table *index; }; static struct asset_manager *assets[ASSET_TYPE_MAX] = {0}; @@ -196,32 +195,9 @@ static bool afa_load_archive(struct asset_manager *_manager, const char *name) manager->archives[i] = manager->archives[i-1]; } manager->archives[0] = ar; - - // index needs to be rebuilt - if (manager->index) { - ht_free(manager->index); - manager->index = NULL; - } return true; } -static bool _afa_get_by_index(struct asset_manager *_manager, int id, - struct afa_archive **ar_out, int *no_out) -{ - struct asset_manager_afa *manager = (struct asset_manager_afa*)_manager; - uint32_t no = id - 1; - for (int i = 0; i < MAX_ARCHIVES && manager->archives[i]; i++) { - if (no < manager->archives[i]->nr_files) { - *ar_out = manager->archives[i]; - *no_out = no; - return true; - } - no -= manager->archives[i]->nr_files; - } - return false; -} - -// XXX: id-indexed afa static bool afa_exists_by_id(struct asset_manager *_manager, int id) { struct asset_manager_afa *manager = (struct asset_manager_afa*)_manager; @@ -232,15 +208,6 @@ static bool afa_exists_by_id(struct asset_manager *_manager, int id) return false; } -// XXX: string-indexed afa -static bool afa_exists_by_index(struct asset_manager *manager, int index) -{ - int no; - struct afa_archive *ar; - return _afa_get_by_index(manager, index, &ar, &no); -} - -// XXX: id-indexed afa static struct archive_data *afa_get_by_id(struct asset_manager *_manager, int id) { struct asset_manager_afa *manager = (struct asset_manager_afa*)_manager; @@ -252,76 +219,35 @@ static struct archive_data *afa_get_by_id(struct asset_manager *_manager, int id return NULL; } -// XXX: string-indexed afa -static struct archive_data *afa_get_by_index(struct asset_manager *manager, int index) -{ - int no; - struct afa_archive *ar; - if (!_afa_get_by_index(manager, index, &ar, &no)) - return NULL; - return archive_get(&ar->ar, no); -} - -static void afa_index_archive(struct hash_table *index, struct afa_archive *ar, unsigned base) -{ - for (unsigned i = 0; i < ar->nr_files; i++) { - // normalize case and remove file extension from file name - char *name = strdup(ar->files[i].name->text); - char *dot = strrchr(name, '.'); - if (dot) - *dot = '\0'; - sjis_toupper(name); - // add file to index - ht_put(index, name, (void*)((uintptr_t)base + i + 1)); - free(name); - } -} - -static bool _afa_get_by_name(struct asset_manager *_manager, const char *_name, - struct afa_archive **ar_out, int *no_out, int *id_out) +static struct archive_data *afa_get_by_name(struct asset_manager *_manager, const char *name, + int *id_out) { struct asset_manager_afa *manager = (struct asset_manager_afa*)_manager; - // initialize index lazily - if (!manager->index) { - manager->index = ht_create(4096); - unsigned base = 0; - for (unsigned i = 0; i < MAX_ARCHIVES && manager->archives[i]; i++) { - afa_index_archive(manager->index, manager->archives[i], base); - base += manager->archives[i]->nr_files; + + for (unsigned i = 0; i < MAX_ARCHIVES && manager->archives[i]; i++) { + struct archive_data *data; + data = archive_get_by_basename(&manager->archives[i]->ar, name); + if (data) { + if (id_out) + *id_out = data->no + 1; + return data; } } - - // normalize name and get id from index - char *name = strdup(_name); - sjis_toupper(name); - char *dot = strrchr(name, '.'); - if (dot) - *dot = '\0'; - uintptr_t id = (uintptr_t)ht_get(manager->index, name, NULL); - free(name); - - if (!id) - return false; - - if (id_out) - *id_out = id; - return _afa_get_by_index(_manager, id, ar_out, no_out); + return NULL; } -static bool afa_exists_by_name(struct asset_manager *manager, const char *name, int *id_out) +static bool afa_exists_by_name(struct asset_manager *_manager, const char *name, int *id_out) { - int no; - struct afa_archive *ar; - return _afa_get_by_name(manager, name, &ar, &no, id_out); -} + struct asset_manager_afa *manager = (struct asset_manager_afa*)_manager; -static struct archive_data *afa_get_by_name(struct asset_manager *manager, const char *name, int *id_out) -{ - int no; - struct afa_archive *ar; - if (!_afa_get_by_name(manager, name, &ar, &no, id_out)) - return NULL; - return archive_get(&ar->ar, no); + for (unsigned i = 0; i < MAX_ARCHIVES && manager->archives[i]; i++) { + if (archive_exists_by_basename(&manager->archives[i]->ar, name, id_out)) { + if (id_out) + *id_out += 1; + return true; + } + } + return false; } static void _ald_init(enum asset_type type, struct archive *ar) @@ -369,17 +295,10 @@ static void afa_init(enum asset_type type, char *file) struct asset_manager_afa *manager = xcalloc(1, sizeof(struct asset_manager_afa)); manager->manager.load_archive = afa_load_archive; - if (id_indexed_afa) { - manager->manager.exists_by_id = afa_exists_by_id; - manager->manager.get_by_id = afa_get_by_id; - manager->manager.exists_by_name = NULL; - manager->manager.get_by_name = NULL; - } else { - manager->manager.exists_by_name = afa_exists_by_name; - manager->manager.get_by_name = afa_get_by_name; - manager->manager.exists_by_id = afa_exists_by_index; - manager->manager.get_by_id = afa_get_by_index; - } + manager->manager.exists_by_id = afa_exists_by_id; + manager->manager.get_by_id = afa_get_by_id; + manager->manager.exists_by_name = afa_exists_by_name; + manager->manager.get_by_name = afa_get_by_name; manager->archives[0] = ar; assets[type] = &manager->manager; diff --git a/src/hacks.c b/src/hacks.c index 6a31a24..eff028d 100644 --- a/src/hacks.c +++ b/src/hacks.c @@ -37,8 +37,6 @@ bool game_rance6_mg = false; bool game_rance7_mg = false; bool game_rance8 = false; -bool id_indexed_afa = false; - static void write_instruction0(struct buffer *out, enum opcode op) { buffer_write_int16(out, op); @@ -168,12 +166,7 @@ void apply_game_specific_hacks(struct ain *ain) apply_rance6_hacks(ain); } else if (!strcmp(game_name, "Sengoku Rance")) { apply_rance7_hacks(ain); - } else if (!strcmp(game_name, "しゃーまんず・さんくちゅあり 巫女の聖域")) { - id_indexed_afa = true; - } else if (!strcmp(game_name, "大帝国")) { - id_indexed_afa = true; } else if (!strcmp(game_name, "ランス・クエスト") || !strcmp(game_name, "Rance Quest")) { - id_indexed_afa = true; game_rance8 = true; } free(game_name); diff --git a/subprojects/libsys4 b/subprojects/libsys4 index 17182d6..2fba500 160000 --- a/subprojects/libsys4 +++ b/subprojects/libsys4 @@ -1 +1 @@ -Subproject commit 17182d6c1217057c32474bba36049b29f94f7a65 +Subproject commit 2fba500382669ec1312225ba0e22ddf8d2b40043