refactor: Add transcoding support for more styles
> some styles still won't work due to SOUND DATA CREATE ERROR > related to #1
This commit is contained in:
+2
-2
@@ -376,7 +376,7 @@ namespace games::iidx {
|
|||||||
cfgmgr32hook_init(avs::game::DLL_INSTANCE);
|
cfgmgr32hook_init(avs::game::DLL_INSTANCE);
|
||||||
|
|
||||||
// wine fixes
|
// wine fixes
|
||||||
hooks::bmsb::init(avs::game::DLL_INSTANCE);
|
hooks::bmsb::init(avs::game::DLL_INSTANCE, avs::game::EXT);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -414,7 +414,7 @@ namespace games::iidx {
|
|||||||
"!!! please do the following instead: !!!\n"
|
"!!! please do the following instead: !!!\n"
|
||||||
"!!! !!!\n"
|
"!!! !!!\n"
|
||||||
"!!! Revert your changes to XML file so it says !!!\n"
|
"!!! Revert your changes to XML file so it says !!!\n"
|
||||||
"!!! <model __type=\"str\">LDJ</model> !!!\n"
|
"!!! <model __type=\"str\">LDJ</model> !!!\n"
|
||||||
"!!! !!!\n"
|
"!!! !!!\n"
|
||||||
"!!! In SpiceCfg, enable 'IIDX TDJ Mode' or provide -iidxtdj flag !!!\n"
|
"!!! In SpiceCfg, enable 'IIDX TDJ Mode' or provide -iidxtdj flag !!!\n"
|
||||||
"!!! in command line !!!\n"
|
"!!! in command line !!!\n"
|
||||||
|
|||||||
+59
-20
@@ -15,7 +15,7 @@
|
|||||||
#include <shlwapi.h>
|
#include <shlwapi.h>
|
||||||
|
|
||||||
|
|
||||||
void dump(const char *path, const uint8_t *src, size_t sz)
|
void dump_(const char *path, const uint8_t *src, size_t sz)
|
||||||
{
|
{
|
||||||
FILE *fh = fopen(path, "wb");
|
FILE *fh = fopen(path, "wb");
|
||||||
fwrite(src, sz, 1, fh);
|
fwrite(src, sz, 1, fh);
|
||||||
@@ -526,7 +526,15 @@ static struct offset_t
|
|||||||
intptr_t RD_05d_2dx; // %05d/%05d.2dx
|
intptr_t RD_05d_2dx; // %05d/%05d.2dx
|
||||||
intptr_t RD_05d_c_2dx; // %05d/%05d%c.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_BmsbEnumValidSoundbanks; // 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;
|
||||||
memutils::VProtectGuard *guard;
|
memutils::VProtectGuard *guard;
|
||||||
|
|
||||||
|
static constexpr unsigned int by_ext(const char *ext, int h = 0)
|
||||||
|
{
|
||||||
|
return !ext[h] ? 5381 : (by_ext(ext, h + 1) * 33) ^ ext[h];
|
||||||
|
}
|
||||||
} offset_;
|
} offset_;
|
||||||
|
|
||||||
soundbank *soundbank::cache_ = nullptr;
|
soundbank *soundbank::cache_ = nullptr;
|
||||||
@@ -597,7 +605,7 @@ void soundbank::cache_bank_any(const uint8_t *sndbuf, size_t sz)
|
|||||||
char path[AVSPATHMAX];
|
char path[AVSPATHMAX];
|
||||||
snprintf(path, sizeof(path), "%s.2dx", this->avspath);
|
snprintf(path, sizeof(path), "%s.2dx", this->avspath);
|
||||||
log_info("hooks::bmsb", "Storing as intermediate soundbank at '{}'", (const char *) path);
|
log_info("hooks::bmsb", "Storing as intermediate soundbank at '{}'", (const char *) path);
|
||||||
dump(path, sndbuf, sz);
|
dump_(path, sndbuf, sz);
|
||||||
}
|
}
|
||||||
soundbank::soundbank() : id(0), avspath(""), uid_(UID_INVALID), mnt_(E_NOT_FOUND), next_(nullptr)
|
soundbank::soundbank() : id(0), avspath(""), uid_(UID_INVALID), mnt_(E_NOT_FOUND), next_(nullptr)
|
||||||
{
|
{
|
||||||
@@ -714,11 +722,11 @@ avs::core::avs_file_t soundbank::map_ifs(char *avspath)
|
|||||||
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/music_*.bin _BUG: therefore differs a bit between some styles
|
// Struct memory layout 1:1 with data/info/(0/1)/music_*.bin
|
||||||
soundbank *keysounds = nullptr;
|
soundbank *keysounds = nullptr;
|
||||||
const char *titlel = (const char *) song;
|
const char *titlel = (const char *) song + offset_.DAT_song_titlel;
|
||||||
const char *artistl = (const char *) song + 0xc0;
|
const char *artistl = (const char *) song + offset_.DAT_song_artistl;
|
||||||
const int32_t id = *(int32_t *) ((const char *) song + 0x3b0);
|
const int32_t id = *(int32_t *) ((const char *) song + offset_.DAT_song_id);
|
||||||
|
|
||||||
log_info("hooks::bmsb", "Processing s3p->2dx transcoding routine for [{}]({} - {})", id, artistl, titlel);
|
log_info("hooks::bmsb", "Processing s3p->2dx transcoding routine for [{}]({} - {})", id, artistl, titlel);
|
||||||
if (!(keysounds = soundbank::get_bank(id)))
|
if (!(keysounds = soundbank::get_bank(id)))
|
||||||
@@ -790,11 +798,11 @@ void run_tests()
|
|||||||
log_info("hooks:bmsb", "{}::Bank[S3P]::Voice[0]::Size {}", id, snds3p->voice_ptr(0)->sz);
|
log_info("hooks:bmsb", "{}::Bank[S3P]::Voice[0]::Size {}", id, snds3p->voice_ptr(0)->sz);
|
||||||
memcpy(sig, snds3p->voice(0)->sig, 4);
|
memcpy(sig, snds3p->voice(0)->sig, 4);
|
||||||
log_info("hooks:bmsb", "{}::Bank[S3P]::Voice[0]::Signature {}", id, sig);
|
log_info("hooks:bmsb", "{}::Bank[S3P]::Voice[0]::Signature {}", id, sig);
|
||||||
dump("raw_wma.wma", snds3p->voice(0)->asf(), snds3p->voice(0)->sz);
|
dump_("raw_wma.wma", snds3p->voice(0)->asf(), snds3p->voice(0)->sz);
|
||||||
|
|
||||||
// MF codec (tainted PCM data, bad)
|
// MF codec (tainted PCM data, bad)
|
||||||
mf_broken::asf_to_wav(snds3p->voice(0)->asf(), snds3p->voice(0)->sz, &wav, &wavsz);
|
mf_broken::asf_to_wav(snds3p->voice(0)->asf(), snds3p->voice(0)->sz, &wav, &wavsz);
|
||||||
dump("mf_wav.wav", wav, wavsz);
|
dump_("mf_wav.wav", wav, wavsz);
|
||||||
free(wav);
|
free(wav);
|
||||||
wav = nullptr;
|
wav = nullptr;
|
||||||
wavsz = 0;
|
wavsz = 0;
|
||||||
@@ -802,7 +810,7 @@ void run_tests()
|
|||||||
// AV codec (1:1 unmodified PCM data, other than resampling if enabled)
|
// AV codec (1:1 unmodified PCM data, other than resampling if enabled)
|
||||||
wav = (BYTE *) malloc(snd_2dx::assertsz_asf(snds3p->voice(0)->sz));
|
wav = (BYTE *) malloc(snd_2dx::assertsz_asf(snds3p->voice(0)->sz));
|
||||||
avcodec::BmswTranscoderAsfToWav(snds3p->voice(0)->asf(), snds3p->voice(0)->sz, &wav, &wavsz, avcodec::bmswac_resampler_s16);
|
avcodec::BmswTranscoderAsfToWav(snds3p->voice(0)->asf(), snds3p->voice(0)->sz, &wav, &wavsz, avcodec::bmswac_resampler_s16);
|
||||||
dump("ac_wav.wav", wav, wavsz);
|
dump_("ac_wav.wav", wav, wavsz);
|
||||||
free(wav);
|
free(wav);
|
||||||
wav = nullptr;
|
wav = nullptr;
|
||||||
wavsz = 0;
|
wavsz = 0;
|
||||||
@@ -825,9 +833,9 @@ void run_tests()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Valid 2DX (trim is not necessary)
|
// Valid 2DX (trim is not necessary)
|
||||||
log_info("hooks:bmsb", "25073::Bank[2DX]::dump()");
|
log_info("hooks:bmsb", "25073::Bank[2DX]::Dumping");
|
||||||
snd_2dx::bank *buf2dx = snd2dx->serialize(false);
|
snd_2dx::bank *buf2dx = snd2dx->serialize(false);
|
||||||
dump("ac_25073.2dx", reinterpret_cast<const uint8_t *>(buf2dx), buf2dx->sz());
|
dump_("ac_25073.2dx", reinterpret_cast<const uint8_t *>(buf2dx), buf2dx->sz());
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -849,10 +857,9 @@ 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:bmsb", "BmsbEnumValidSoundbanks(0x0)"); };
|
BmsbEnumValidSoundbanks = [](void *, int32_t, int32_t) { log_info("hooks::bmsb", "BmsbEnumValidSoundbanks(fallback)"); };
|
||||||
char *tmp = (char *) malloc(0x3b0 + sizeof(int32_t));
|
char *tmp = (char *) malloc(0x3b0 + sizeof(int32_t));
|
||||||
int arr[10] = {25073, 26020, 26094, 24016, 26057, 25073, 26069, 26070, 26059, 26087};
|
int arr[6] = {25073, 24016, 26057, 25073, 26087, 29095};
|
||||||
//int arr[10] = {25073, 24016, 26057, 25073, 26087};
|
|
||||||
strcpy(tmp, "SJISTITLE");
|
strcpy(tmp, "SJISTITLE");
|
||||||
strcpy(tmp + 0xc0, "SJISARTIST");
|
strcpy(tmp + 0xc0, "SJISARTIST");
|
||||||
for (int it: arr)
|
for (int it: arr)
|
||||||
@@ -866,26 +873,57 @@ void run_tests()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void init(HINSTANCE hmodule)
|
void init(HINSTANCE hmodule, const char *ext)
|
||||||
{
|
{
|
||||||
if (false && IsDebuggerPresent())
|
if (false && IsDebuggerPresent())
|
||||||
{
|
{
|
||||||
log_warning("hooks::bmsb", "Debugger detected, skipping..");
|
log_warning("hooks::bmsb", "Debugger detected, skipping..");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mf_broken::init())
|
if (!mf_broken::init())
|
||||||
{
|
{
|
||||||
log_warning("hooks::bmsb", "MF initialization failed, skipping..");
|
log_warning("hooks::bmsb", "MF initialization failed, skipping..");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!avcodec::init())
|
if (!avcodec::init())
|
||||||
{
|
{
|
||||||
log_warning("hooks::bmsb", "AVCodec initialization failed, skipping..");
|
log_warning("hooks::bmsb", "AVCodec initialization failed, skipping..");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Override .text
|
// Override .text .data per datacode _REV: prefer unique asm pattern offset lookup
|
||||||
offset_.TX_BmsbEnumValidSoundbanks = (intptr_t) hmodule + 0xafd780; //_TODO: Hardcoded for iidx30 for now, requires asm pattern lookup
|
offset_.DAT_song_titlel = 0x00;
|
||||||
|
offset_.DAT_song_artistl = 0xc0;
|
||||||
|
offset_.DAT_song_id = 0x3b0;
|
||||||
|
switch (offset_t::by_ext(ext))
|
||||||
|
{
|
||||||
|
case offset_t::by_ext("2018091900"):
|
||||||
|
offset_.TX_BmsbEnumValidSoundbanks = (intptr_t) hmodule + 0x1170b0;
|
||||||
|
offset_.DAT_song_id = 0x1C8;
|
||||||
|
break;
|
||||||
|
case offset_t::by_ext("2019090200"):
|
||||||
|
case offset_t::by_ext("2019100700"):
|
||||||
|
offset_.TX_BmsbEnumValidSoundbanks = (intptr_t) hmodule + 0x37a540;
|
||||||
|
offset_.DAT_song_id = 0x1C8;
|
||||||
|
break;
|
||||||
|
case offset_t::by_ext("2020092900"):
|
||||||
|
offset_.TX_BmsbEnumValidSoundbanks = (intptr_t) hmodule + 0x5ac460;
|
||||||
|
break;
|
||||||
|
case offset_t::by_ext("2021083000"):
|
||||||
|
offset_.TX_BmsbEnumValidSoundbanks = (intptr_t) hmodule + 0x766bc0;
|
||||||
|
break;
|
||||||
|
case offset_t::by_ext("2021091500"):
|
||||||
|
offset_.TX_BmsbEnumValidSoundbanks = (intptr_t) hmodule + 0x766c60;
|
||||||
|
break;
|
||||||
|
case offset_t::by_ext("2022082400"):
|
||||||
|
offset_.TX_BmsbEnumValidSoundbanks = (intptr_t) hmodule + 0x46e160;
|
||||||
|
break;
|
||||||
|
case offset_t::by_ext("2023090500"):
|
||||||
|
offset_.TX_BmsbEnumValidSoundbanks = (intptr_t) hmodule + 0xafd780;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
log_warning("hooks::bmsb", "Unsupported game version({}), skipping..", ext);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
log_info("hooks::bmsb", "Supported game version({})", ext);
|
||||||
|
|
||||||
// Override .rdata
|
// Override .rdata
|
||||||
offset_.RD_05d_s3p = replace_pattern(hmodule, "253035642f253035642e73337000", "003035642f253035642e73337000", 0, 0);
|
offset_.RD_05d_s3p = replace_pattern(hmodule, "253035642f253035642e73337000", "003035642f253035642e73337000", 0, 0);
|
||||||
@@ -907,7 +945,8 @@ void init(HINSTANCE hmodule)
|
|||||||
// Tests _REM: tests
|
// Tests _REM: tests
|
||||||
detour::trampoline(reinterpret_cast<void *>(avs::core::avs_fs_lstat), reinterpret_cast<void *>(on_avs_fs_lstat), reinterpret_cast<void **>(&avs_fs_lstat_));
|
detour::trampoline(reinterpret_cast<void *>(avs::core::avs_fs_lstat), reinterpret_cast<void *>(on_avs_fs_lstat), reinterpret_cast<void **>(&avs_fs_lstat_));
|
||||||
detour::trampoline(reinterpret_cast<void *>(avs::core::avs_fs_mount), reinterpret_cast<void *>(on_avs_fs_mount), reinterpret_cast<void **>(&avs_fs_mount_));
|
detour::trampoline(reinterpret_cast<void *>(avs::core::avs_fs_mount), reinterpret_cast<void *>(on_avs_fs_mount), reinterpret_cast<void **>(&avs_fs_mount_));
|
||||||
run_tests();
|
if (offset_t::by_ext(ext) == offset_t::by_ext("2023090500"))
|
||||||
|
run_tests();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -4,6 +4,6 @@
|
|||||||
|
|
||||||
namespace hooks::bmsb
|
namespace hooks::bmsb
|
||||||
{
|
{
|
||||||
void init(HINSTANCE hmodule);
|
void init(HINSTANCE hmodule, const char *ext);
|
||||||
void deinit(HINSTANCE hmodule);
|
void deinit(HINSTANCE hmodule);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user