From cd709f0a55cbf5676ec723f993aaf6b767868cb2 Mon Sep 17 00:00:00 2001 From: "[ ]" <[ ]> Date: Fri, 30 May 2025 23:11:47 +0900 Subject: [PATCH] fix: Support per difficulty soundbanks > related to #1 --- hooks/sndbhook.cpp | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/hooks/sndbhook.cpp b/hooks/sndbhook.cpp index 1c60c6b..01431ec 100644 --- a/hooks/sndbhook.cpp +++ b/hooks/sndbhook.cpp @@ -233,10 +233,11 @@ constexpr size_t SNDPATHFMTMAX = sizeof(SNDPATHFMT) - 1; constexpr size_t MNTPATHMAX = sizeof("/sdAABBB/AABBB/AABBBC_pre.2dx"); constexpr size_t AVSPATHMAX = sizeof("/data/sound/AABBB/AABBBC_pre.2dx"); constexpr uint8_t CACHEMAX = 8; +constexpr int operator "" _i(long double x) { return static_cast(x); } typedef struct snd_bank snd_bank; typedef struct snd_s3p snd_s3p; typedef struct snd_2dx snd_2dx; -typedef void (*BmsbEnumValidSoundbanks_t)(void *, int32_t, int32_t); +typedef void *(*BmsbEnumValidSoundbanks_t)(void *, int32_t, int32_t); struct snd_2dx { @@ -447,7 +448,7 @@ public: static snd_bank *new_instance(int id); static void flush_cache(); static void pop_cache(); - static snd_bank *get_bank(int id); + static snd_bank *get_bank(int id, uint8_t suffix = 0); static uint8_t *read_bank_any(const char *avspath, const char *ext, size_t *sz); static bool has_format(const char *avspath, const char *ext); static avs::core::avs_file_t map_ifs(char *avspath); @@ -586,18 +587,20 @@ snd_bank::~snd_bank() avs::core::avs_fs_umount(mnt_); } } -snd_bank *snd_bank::get_bank(int id) +snd_bank *snd_bank::get_bank(int id, uint8_t suffix) { // Find in cache (latest=>oldest) + id = id + (suffix * 1e6_i); for (snd_bank *it = cache_; it; it = it->next_) if (it->id == id) return it; // Find in avs (has valid s3p/.2dx resource at data/sound/AABBB/AABBB.2dx) snd_bank *bank = new_instance(id); - snprintf(bank->avspath, AVSPATHMAX, "data/sound/%05d", id); + snprintf(bank->avspath, AVSPATHMAX, "data/sound/%05d", (id % 1e6_i)); if (has_format(bank->avspath, ".ifs")) bank->mnt_ = map_ifs(bank->avspath); - snprintf(bank->avspath + strlen(bank->avspath), 7, "/%05d", id); + snprintf(bank->avspath + strlen(bank->avspath), 7, "/%05d", (id % 1e6_i)); + if (suffix) snprintf(bank->avspath + strlen(bank->avspath), 2, "%d", suffix); if (!(has_format(bank->avspath, ".s3p") || has_format(bank->avspath, ".2dx"))) { pop_cache(); @@ -717,7 +720,7 @@ avs::core::avs_file_t on_avs_fs_mount(const char *mountpoint, const char *fsroot } return avs_fs_mount_(mountpoint, fsroot, fstype, data); } -void on_enum_valid_soundbanks(void *song, int32_t difficulty, int32_t unk2) +void *on_enum_valid_soundbanks(void *song, int32_t difficulty, int32_t unk2) { // Keysounds populated into CtrlSound::Bank[2][X] = [0:s3p][1:2dx][2:_pre.2dx], always uses lowest i databank for resource confirmed valid by this function // Struct memory layout 1:1 with data/info/(0/1)/music_*.bin @@ -725,14 +728,14 @@ void on_enum_valid_soundbanks(void *song, int32_t difficulty, int32_t unk2) const char *titlel = (const char *) song + offset_.DAT_song_titlel; const char *artistl = (const char *) song + offset_.DAT_song_artistl; const int32_t id = *(int32_t *) ((const char *) song + offset_.DAT_song_id); + const char suffix = *((const char *) song + offset_.DAT_song_id + 8 + difficulty); log_info("hooks::soundbank", "Processing s3p->2dx transcoding routine for [{}]({} - {})", id, artistl, titlel); - if (!(keysounds = snd_bank::get_bank(id))) + if (!(keysounds = snd_bank::get_bank(id, suffix - '0'))) { log_warning("hooks::soundbank", "soundbank::get_bank() was 0x0, this shouldn't happen.."); memcpy(reinterpret_cast(offset_.RD_05d_2dx), "%05d/%05d", SNDPATHFMTMAX); - BmsbEnumValidSoundbanks(song, difficulty, unk2); - return; + return BmsbEnumValidSoundbanks(song, difficulty, unk2); } else if (!snd_bank::has_format(keysounds->avspath, ".2dx")) { @@ -762,12 +765,15 @@ void on_enum_valid_soundbanks(void *song, int32_t difficulty, int32_t unk2) //_REV: symlink system/uid_.2dx -> /tmp/uid_.2dx } - // Resume execution + // Resume execution (force %05.2dx branch) const char *t = keysounds->sndpath(); memcpy(reinterpret_cast(offset_.RD_05d_2dx), t, SNDPATHFMTMAX); log_info("hooks::soundbank", "RD_05d_2dx set to '{}'", reinterpret_cast(offset_.RD_05d_2dx)); log_info("hooks::soundbank", "Processing completed"); - BmsbEnumValidSoundbanks(song, difficulty, unk2); + *((char *) song + offset_.DAT_song_id + 8 + difficulty) = '0'; + void *r = BmsbEnumValidSoundbanks(song, difficulty, unk2); + *((char *) song + offset_.DAT_song_id + 8 + difficulty) = suffix; + return r; } void run_tests() { @@ -853,7 +859,7 @@ void run_tests() // Caching and intermediate 2dx storage detection BmsbEnumValidSoundbanks_t t = BmsbEnumValidSoundbanks; - BmsbEnumValidSoundbanks = [](void *, int32_t, int32_t) { log_info("hooks::soundbank", "BmsbEnumValidSoundbanks(fallback)"); }; + BmsbEnumValidSoundbanks = [](void *, int32_t, int32_t) -> void * { return nullptr; }; char *tmp = (char *) malloc(0x3b0 + sizeof(int32_t)); int arr[6] = {25073, 24016, 26057, 25073, 26087, 29095}; strcpy(tmp, "SJISTITLE");