diff --git a/hooks/sndbhook.cpp b/hooks/sndbhook.cpp index 23af93a..6d095cc 100644 --- a/hooks/sndbhook.cpp +++ b/hooks/sndbhook.cpp @@ -23,12 +23,14 @@ enum pcm_resampler : int8_t }; typedef enum pcm_resampler pcm_resampler_t; typedef void (*BmswConfigInit_t)(const char *path); -typedef uint64_t (*BmswEnumValidSoundbanksAddr_t)(); typedef int (*BmswSymlink_t)(const char *srcwpath, const char *dstwpath, int canonic); +typedef uint64_t (*BmswTranscoderEnumValidSoundbanksAddr_t)(); +typedef pcm_resampler (*BmswTranscoderResampler_t)(); typedef int (*BmswTranscoderAsfToWav_t)(const uint8_t *srcasf, uint32_t srcsz, uint8_t **dstwav, uint32_t *dstsz, pcm_resampler_t resampler); static BmswConfigInit_t BmswConfigInit; -BmswEnumValidSoundbanksAddr_t BmswEnumValidSoundbanksAddr; static BmswSymlink_t BmswSymlink; +static BmswTranscoderEnumValidSoundbanksAddr_t BmswTranscoderEnumValidSoundbanksAddr; +static BmswTranscoderResampler_t BmswTranscoderResampler; static BmswTranscoderAsfToWav_t BmswTranscoderAsfToWav; static HMODULE bmsw_ = nullptr; bool init() @@ -41,10 +43,22 @@ bool init() if ((bmsw_ = libutils::try_library(MODULE_PATH / "bmsound-wine.dll"))) { BmswConfigInit = (BmswConfigInit_t) GetProcAddress(bmsw_, "BmswConfigInit"); - BmswEnumValidSoundbanksAddr = (BmswEnumValidSoundbanksAddr_t) GetProcAddress(bmsw_, "BmswEnumValidSoundbanksAddr"); BmswSymlink = (BmswSymlink_t) GetProcAddress(bmsw_, "BmswSymlink"); + BmswTranscoderEnumValidSoundbanksAddr = (BmswTranscoderEnumValidSoundbanksAddr_t) GetProcAddress(bmsw_, "BmswTranscoderEnumValidSoundbanksAddr"); + BmswTranscoderResampler = (BmswTranscoderResampler_t) GetProcAddress(bmsw_, "BmswTranscoderResampler"); BmswTranscoderAsfToWav = (BmswTranscoderAsfToWav_t) GetProcAddress(bmsw_, "BmswTranscoderAsfToWav"); + //_REM: 0.2.x support (old behaviour), remove on 0.3.0 + if (!BmswTranscoderEnumValidSoundbanksAddr || !BmswTranscoderResampler) + { + BmswTranscoderEnumValidSoundbanksAddr = (BmswTranscoderEnumValidSoundbanksAddr_t) GetProcAddress(bmsw_, "BmswEnumValidSoundbanksAddr"); + BmswTranscoderResampler = []() -> pcm_resampler + { + return bmswac_resampler_s16_ad; + }; + + } + // Load config BmswConfigInit("prop/linux.json"); return true; @@ -244,7 +258,7 @@ 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 *(*EnumValidSoundbanks_t)(void *, int32_t, int32_t); struct snd_2dx { @@ -693,7 +707,7 @@ static struct offset_t intptr_t RD_05d_c_s3p; // %05d/%05d%c.s3p intptr_t RD_05d_2dx; // %05d/%05d.2dx intptr_t RD_05d_c_2dx; // %05d/%05d%c.2dx - intptr_t TX_BmsbEnumValidSoundbanks; // enumerates above databank paths, simple exist check (lstat()/OPEN -> CLOSE_NOWRITE only) + intptr_t TX_EnumValidSoundbanks; // enumerates above databank paths, simple exist check (lstat()/OPEN -> CLOSE_NOWRITE only) intptr_t DAT_song_titlel; intptr_t DAT_song_artistl; intptr_t DAT_song_id; @@ -702,8 +716,8 @@ static struct offset_t } offset_; snd_bank *snd_bank::cache_ = nullptr; size_t snd_bank::cachesz_ = 0; -avcodec::pcm_resampler_t snd_bank::resampler_ = avcodec::bmswac_resampler_s16_ad; //_REM: Temporary (revert to bmswac_resampler_s16) -static BmsbEnumValidSoundbanks_t BmsbEnumValidSoundbanks; +avcodec::pcm_resampler_t snd_bank::resampler_ = avcodec::bmswac_resampler_s16; +static EnumValidSoundbanks_t EnumValidSoundbanks; 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 @@ -729,7 +743,7 @@ void *on_enum_valid_soundbanks(void *song, int32_t difficulty, int32_t unk2) { log_warning("hooks::soundbank", "soundbank::get_bank() was 0x0, this shouldn't happen.."); memcpy(reinterpret_cast(offset_.RD_05d_2dx), "%05d/%05d", SNDPATHFMTMAX); - return BmsbEnumValidSoundbanks(song, difficulty, unk2); + return EnumValidSoundbanks(song, difficulty, unk2); } else if (!snd_bank::has_format(keysounds->avspath, ".2dx")) { @@ -765,7 +779,7 @@ void *on_enum_valid_soundbanks(void *song, int32_t difficulty, int32_t unk2) log_info("hooks::soundbank", "RD_05d_2dx set to '{}'", reinterpret_cast(offset_.RD_05d_2dx)); log_info("hooks::soundbank", "Processing completed"); *((char *) song + offset_.DAT_song_id + 8 + difficulty) = '0'; - void *r = BmsbEnumValidSoundbanks(song, difficulty, unk2); + void *r = EnumValidSoundbanks(song, difficulty, unk2); *((char *) song + offset_.DAT_song_id + 8 + difficulty) = suffix; return r; } @@ -854,8 +868,8 @@ public: } // Caching and intermediate 2dx storage detection - BmsbEnumValidSoundbanks_t t = BmsbEnumValidSoundbanks; - BmsbEnumValidSoundbanks = [](void *, int32_t, int32_t) -> void * { return nullptr; }; + EnumValidSoundbanks_t t = EnumValidSoundbanks; + EnumValidSoundbanks = [](void *, int32_t, int32_t) -> void * { return nullptr; }; char *tmp = (char *) malloc(0x3b8 + strlen("00000000") + 1); int arr[6] = {25073, 24016, 26057, 25073, 26087, 29095}; strcpy(tmp, "SJISTITLE"); @@ -868,7 +882,7 @@ public: } free(tmp); - BmsbEnumValidSoundbanks = t; + EnumValidSoundbanks = t; snd_bank::flush_cache(); mf_broken::deinit(); } @@ -913,42 +927,44 @@ void init(HINSTANCE hmodule, const char *model, const char *ext) switch (to_hash(ext)) { case to_hash("2018091900"): - offset_.TX_BmsbEnumValidSoundbanks = (intptr_t) hmodule + 0x1170b0; + offset_.TX_EnumValidSoundbanks = (intptr_t) hmodule + 0x1170b0; break; case to_hash("2019090200"): case to_hash("2019100700"): - offset_.TX_BmsbEnumValidSoundbanks = (intptr_t) hmodule + 0x37a540; + offset_.TX_EnumValidSoundbanks = (intptr_t) hmodule + 0x37a540; break; case to_hash("2020092900"): - offset_.TX_BmsbEnumValidSoundbanks = (intptr_t) hmodule + 0x5ac460; + offset_.TX_EnumValidSoundbanks = (intptr_t) hmodule + 0x5ac460; break; case to_hash("2021083000"): - offset_.TX_BmsbEnumValidSoundbanks = (intptr_t) hmodule + 0x766bc0; + offset_.TX_EnumValidSoundbanks = (intptr_t) hmodule + 0x766bc0; break; case to_hash("2021091500"): - offset_.TX_BmsbEnumValidSoundbanks = (intptr_t) hmodule + 0x766c60; + offset_.TX_EnumValidSoundbanks = (intptr_t) hmodule + 0x766c60; break; case to_hash("2022082400"): - offset_.TX_BmsbEnumValidSoundbanks = (intptr_t) hmodule + 0x46e160; + offset_.TX_EnumValidSoundbanks = (intptr_t) hmodule + 0x46e160; break; case to_hash("2023090500"): - offset_.TX_BmsbEnumValidSoundbanks = (intptr_t) hmodule + 0xafd780; + offset_.TX_EnumValidSoundbanks = (intptr_t) hmodule + 0xafd780; break; case to_hash("2024082600"): - offset_.TX_BmsbEnumValidSoundbanks = (intptr_t) hmodule + 0x8eae40; + offset_.TX_EnumValidSoundbanks = (intptr_t) hmodule + 0x8eae40; break; case to_hash("2025082500"): - offset_.TX_BmsbEnumValidSoundbanks = (intptr_t) hmodule + 0x969fb0; + offset_.TX_EnumValidSoundbanks = (intptr_t) hmodule + 0x969fb0; break; default: - offset_.TX_BmsbEnumValidSoundbanks = (intptr_t) hmodule + (int64_t) avcodec::BmswEnumValidSoundbanksAddr(); - if (offset_.TX_BmsbEnumValidSoundbanks == (intptr_t) hmodule) - { - log_warning("hooks::soundbank", "Unsupported game version({}), skipping..", ext); - return; - } - log_info("hooks::soundbank", "Using user supplied offsets(0x{:x}), support may be limited..", offset_.TX_BmsbEnumValidSoundbanks); + break; } + snd_bank::resampler_ = avcodec::BmswTranscoderResampler() == avcodec::bmswac_resampler_none ? snd_bank::resampler_ : avcodec::BmswTranscoderResampler(); + offset_.TX_EnumValidSoundbanks = avcodec::BmswTranscoderEnumValidSoundbanksAddr() == 0x0 ? offset_.TX_EnumValidSoundbanks : (intptr_t) hmodule + (int64_t) avcodec::BmswTranscoderEnumValidSoundbanksAddr(); + if (offset_.TX_EnumValidSoundbanks == (intptr_t) hmodule) + { + log_warning("hooks::soundbank", "Unsupported game version({}), skipping..", ext); + return; + } + log_info("hooks::soundbank", "Hooking EnumValidSoundbanks(0x{:x})", offset_.TX_EnumValidSoundbanks); log_info("hooks::soundbank", "Supported game version({})", ext); // Override .rdata @@ -956,7 +972,7 @@ void init(HINSTANCE hmodule, const char *model, const char *ext) offset_.RD_05d_c_s3p = replace_pattern(hmodule, "253035642f2530356425632e73337000", "003035642f2530356425632e73337000", 0, 0); offset_.RD_05d_2dx = replace_pattern(hmodule, "253035642F253035642E32647800", "73797374656D2F30302E32647800", 0, 0); offset_.RD_05d_c_2dx = replace_pattern(hmodule, "253035642f2530356425632e32647800", "253035642f2530356425632e32647800", 0, 0); - if (!(offset_.TX_BmsbEnumValidSoundbanks && offset_.RD_05d_s3p && offset_.RD_05d_c_s3p && offset_.RD_05d_2dx && offset_.RD_05d_c_2dx)) + if (!(offset_.TX_EnumValidSoundbanks && offset_.RD_05d_s3p && offset_.RD_05d_c_s3p && offset_.RD_05d_2dx && offset_.RD_05d_c_2dx)) { log_warning("hooks::soundbank", "Could not find valid offsets, skipping.."); return; @@ -964,7 +980,7 @@ void init(HINSTANCE hmodule, const char *model, const char *ext) // Setup on_enum_valid_ksbd and optional tests offset_.guard = new memutils::VProtectGuard((void *) offset_.RD_05d_2dx, SNDPATHFMTMAX); - detour::trampoline(reinterpret_cast(offset_.TX_BmsbEnumValidSoundbanks), reinterpret_cast(on_enum_valid_soundbanks), reinterpret_cast(&BmsbEnumValidSoundbanks)); + detour::trampoline(reinterpret_cast(offset_.TX_EnumValidSoundbanks), reinterpret_cast(on_enum_valid_soundbanks), reinterpret_cast(&EnumValidSoundbanks)); hooks::devel::bind_routine(&tests_); log_info("hooks::soundbank", "Soundbank preprocessor ready");