fix: Support per difficulty soundbanks

> related to #1
This commit is contained in:
[ ]
2025-05-30 23:11:47 +09:00
parent 07249ebb1c
commit cd709f0a55
+18 -12
View File
@@ -233,10 +233,11 @@ constexpr size_t SNDPATHFMTMAX = sizeof(SNDPATHFMT) - 1;
constexpr size_t MNTPATHMAX = sizeof("/sdAABBB/AABBB/AABBBC_pre.2dx"); constexpr size_t MNTPATHMAX = sizeof("/sdAABBB/AABBB/AABBBC_pre.2dx");
constexpr size_t AVSPATHMAX = sizeof("/data/sound/AABBB/AABBBC_pre.2dx"); constexpr size_t AVSPATHMAX = sizeof("/data/sound/AABBB/AABBBC_pre.2dx");
constexpr uint8_t CACHEMAX = 8; constexpr uint8_t CACHEMAX = 8;
constexpr int operator "" _i(long double x) { return static_cast<int>(x); }
typedef struct snd_bank snd_bank; typedef struct snd_bank snd_bank;
typedef struct snd_s3p snd_s3p; typedef struct snd_s3p snd_s3p;
typedef struct snd_2dx snd_2dx; 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 struct snd_2dx
{ {
@@ -447,7 +448,7 @@ public:
static snd_bank *new_instance(int id); static snd_bank *new_instance(int id);
static void flush_cache(); static void flush_cache();
static void pop_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 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 bool has_format(const char *avspath, const char *ext);
static avs::core::avs_file_t map_ifs(char *avspath); static avs::core::avs_file_t map_ifs(char *avspath);
@@ -586,18 +587,20 @@ snd_bank::~snd_bank()
avs::core::avs_fs_umount(mnt_); 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) // Find in cache (latest=>oldest)
id = id + (suffix * 1e6_i);
for (snd_bank *it = cache_; it; it = it->next_) for (snd_bank *it = cache_; it; it = it->next_)
if (it->id == id) return it; if (it->id == id) return it;
// Find in avs (has valid s3p/.2dx resource at data/sound/AABBB/AABBB.2dx) // Find in avs (has valid s3p/.2dx resource at data/sound/AABBB/AABBB.2dx)
snd_bank *bank = new_instance(id); 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")) if (has_format(bank->avspath, ".ifs"))
bank->mnt_ = map_ifs(bank->avspath); 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"))) if (!(has_format(bank->avspath, ".s3p") || has_format(bank->avspath, ".2dx")))
{ {
pop_cache(); 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); 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 // 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 // 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 *titlel = (const char *) song + offset_.DAT_song_titlel;
const char *artistl = (const char *) song + offset_.DAT_song_artistl; const char *artistl = (const char *) song + offset_.DAT_song_artistl;
const int32_t id = *(int32_t *) ((const char *) song + offset_.DAT_song_id); 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); 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.."); log_warning("hooks::soundbank", "soundbank::get_bank() was 0x0, this shouldn't happen..");
memcpy(reinterpret_cast<void *>(offset_.RD_05d_2dx), "%05d/%05d", SNDPATHFMTMAX); memcpy(reinterpret_cast<void *>(offset_.RD_05d_2dx), "%05d/%05d", SNDPATHFMTMAX);
BmsbEnumValidSoundbanks(song, difficulty, unk2); return BmsbEnumValidSoundbanks(song, difficulty, unk2);
return;
} }
else if (!snd_bank::has_format(keysounds->avspath, ".2dx")) 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 //_REV: symlink system/uid_.2dx -> /tmp/uid_.2dx
} }
// Resume execution // Resume execution (force %05.2dx branch)
const char *t = keysounds->sndpath(); const char *t = keysounds->sndpath();
memcpy(reinterpret_cast<void *>(offset_.RD_05d_2dx), t, SNDPATHFMTMAX); memcpy(reinterpret_cast<void *>(offset_.RD_05d_2dx), t, SNDPATHFMTMAX);
log_info("hooks::soundbank", "RD_05d_2dx set to '{}'", reinterpret_cast<const char *>(offset_.RD_05d_2dx)); log_info("hooks::soundbank", "RD_05d_2dx set to '{}'", reinterpret_cast<const char *>(offset_.RD_05d_2dx));
log_info("hooks::soundbank", "Processing completed"); 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() void run_tests()
{ {
@@ -853,7 +859,7 @@ void run_tests()
// Caching and intermediate 2dx storage detection // Caching and intermediate 2dx storage detection
BmsbEnumValidSoundbanks_t t = BmsbEnumValidSoundbanks; 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)); char *tmp = (char *) malloc(0x3b0 + sizeof(int32_t));
int arr[6] = {25073, 24016, 26057, 25073, 26087, 29095}; int arr[6] = {25073, 24016, 26057, 25073, 26087, 29095};
strcpy(tmp, "SJISTITLE"); strcpy(tmp, "SJISTITLE");