Updated VGMStream to r1640-104-gc92e4f85
parent
3aa2e3149f
commit
ac998301c6
|
@ -518,6 +518,8 @@
|
||||||
839933612591E8C1001855AF /* sbk.c in Sources */ = {isa = PBXBuildFile; fileRef = 8399335E2591E8C0001855AF /* sbk.c */; };
|
839933612591E8C1001855AF /* sbk.c in Sources */ = {isa = PBXBuildFile; fileRef = 8399335E2591E8C0001855AF /* sbk.c */; };
|
||||||
83997F5B22D9569E00633184 /* rad.c in Sources */ = {isa = PBXBuildFile; fileRef = 83997F5722D9569E00633184 /* rad.c */; };
|
83997F5B22D9569E00633184 /* rad.c in Sources */ = {isa = PBXBuildFile; fileRef = 83997F5722D9569E00633184 /* rad.c */; };
|
||||||
839B54521EEE1D9600048A2D /* ngc_ulw.c in Sources */ = {isa = PBXBuildFile; fileRef = 831BD11F1EEE1CF200198540 /* ngc_ulw.c */; };
|
839B54521EEE1D9600048A2D /* ngc_ulw.c in Sources */ = {isa = PBXBuildFile; fileRef = 831BD11F1EEE1CF200198540 /* ngc_ulw.c */; };
|
||||||
|
839C3D27270D49FF00E13653 /* lpcm_fb.c in Sources */ = {isa = PBXBuildFile; fileRef = 839C3D22270D49FF00E13653 /* lpcm_fb.c */; };
|
||||||
|
839C3D28270D49FF00E13653 /* lopu.c in Sources */ = {isa = PBXBuildFile; fileRef = 839C3D26270D49FF00E13653 /* lopu.c */; };
|
||||||
839E21E01F2EDAF100EE54D7 /* vorbis_custom_data_fsb.h in Headers */ = {isa = PBXBuildFile; fileRef = 839E21D61F2EDAF000EE54D7 /* vorbis_custom_data_fsb.h */; };
|
839E21E01F2EDAF100EE54D7 /* vorbis_custom_data_fsb.h in Headers */ = {isa = PBXBuildFile; fileRef = 839E21D61F2EDAF000EE54D7 /* vorbis_custom_data_fsb.h */; };
|
||||||
839E21E11F2EDAF100EE54D7 /* vorbis_custom_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 839E21D71F2EDAF000EE54D7 /* vorbis_custom_decoder.c */; };
|
839E21E11F2EDAF100EE54D7 /* vorbis_custom_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 839E21D71F2EDAF000EE54D7 /* vorbis_custom_decoder.c */; };
|
||||||
839E21E21F2EDAF100EE54D7 /* vorbis_custom_utils_wwise.c in Sources */ = {isa = PBXBuildFile; fileRef = 839E21D81F2EDAF000EE54D7 /* vorbis_custom_utils_wwise.c */; };
|
839E21E21F2EDAF100EE54D7 /* vorbis_custom_utils_wwise.c in Sources */ = {isa = PBXBuildFile; fileRef = 839E21D81F2EDAF000EE54D7 /* vorbis_custom_utils_wwise.c */; };
|
||||||
|
@ -1328,6 +1330,8 @@
|
||||||
8399335D2591E8C0001855AF /* ubi_sb_garbage_streamfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ubi_sb_garbage_streamfile.h; sourceTree = "<group>"; };
|
8399335D2591E8C0001855AF /* ubi_sb_garbage_streamfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ubi_sb_garbage_streamfile.h; sourceTree = "<group>"; };
|
||||||
8399335E2591E8C0001855AF /* sbk.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sbk.c; sourceTree = "<group>"; };
|
8399335E2591E8C0001855AF /* sbk.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sbk.c; sourceTree = "<group>"; };
|
||||||
83997F5722D9569E00633184 /* rad.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rad.c; sourceTree = "<group>"; };
|
83997F5722D9569E00633184 /* rad.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rad.c; sourceTree = "<group>"; };
|
||||||
|
839C3D22270D49FF00E13653 /* lpcm_fb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = lpcm_fb.c; sourceTree = "<group>"; };
|
||||||
|
839C3D26270D49FF00E13653 /* lopu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = lopu.c; sourceTree = "<group>"; };
|
||||||
839E21D61F2EDAF000EE54D7 /* vorbis_custom_data_fsb.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vorbis_custom_data_fsb.h; sourceTree = "<group>"; };
|
839E21D61F2EDAF000EE54D7 /* vorbis_custom_data_fsb.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vorbis_custom_data_fsb.h; sourceTree = "<group>"; };
|
||||||
839E21D71F2EDAF000EE54D7 /* vorbis_custom_decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vorbis_custom_decoder.c; sourceTree = "<group>"; };
|
839E21D71F2EDAF000EE54D7 /* vorbis_custom_decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vorbis_custom_decoder.c; sourceTree = "<group>"; };
|
||||||
839E21D81F2EDAF000EE54D7 /* vorbis_custom_utils_wwise.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vorbis_custom_utils_wwise.c; sourceTree = "<group>"; };
|
839E21D81F2EDAF000EE54D7 /* vorbis_custom_utils_wwise.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vorbis_custom_utils_wwise.c; sourceTree = "<group>"; };
|
||||||
|
@ -1945,6 +1949,8 @@
|
||||||
83D20074248DDB760048BD24 /* ktsr.c */,
|
83D20074248DDB760048BD24 /* ktsr.c */,
|
||||||
830EBE122004656E0023AA10 /* ktss.c */,
|
830EBE122004656E0023AA10 /* ktss.c */,
|
||||||
8373342423F60CDB00DE14DC /* kwb.c */,
|
8373342423F60CDB00DE14DC /* kwb.c */,
|
||||||
|
839C3D26270D49FF00E13653 /* lopu.c */,
|
||||||
|
839C3D22270D49FF00E13653 /* lpcm_fb.c */,
|
||||||
8373341F23F60CDB00DE14DC /* lrmd_streamfile.h */,
|
8373341F23F60CDB00DE14DC /* lrmd_streamfile.h */,
|
||||||
8373342223F60CDB00DE14DC /* lrmd.c */,
|
8373342223F60CDB00DE14DC /* lrmd.c */,
|
||||||
836F6E5A18BDC2180095E648 /* lsf.c */,
|
836F6E5A18BDC2180095E648 /* lsf.c */,
|
||||||
|
@ -2656,6 +2662,7 @@
|
||||||
834FE109215C79ED000A5D3D /* idsp_ie.c in Sources */,
|
834FE109215C79ED000A5D3D /* idsp_ie.c in Sources */,
|
||||||
83299FD01E7660C7003A3242 /* bik.c in Sources */,
|
83299FD01E7660C7003A3242 /* bik.c in Sources */,
|
||||||
8346D97C25BF838C00D1A8B0 /* mjb_mjh.c in Sources */,
|
8346D97C25BF838C00D1A8B0 /* mjb_mjh.c in Sources */,
|
||||||
|
839C3D27270D49FF00E13653 /* lpcm_fb.c in Sources */,
|
||||||
8373341823F60C7B00DE14DC /* tgcadpcm_decoder.c in Sources */,
|
8373341823F60C7B00DE14DC /* tgcadpcm_decoder.c in Sources */,
|
||||||
83FC417326D3304D009A2022 /* xsh_xsd_xss.c in Sources */,
|
83FC417326D3304D009A2022 /* xsh_xsd_xss.c in Sources */,
|
||||||
836F6F3318BDC2190095E648 /* ngc_dtk_decoder.c in Sources */,
|
836F6F3318BDC2190095E648 /* ngc_dtk_decoder.c in Sources */,
|
||||||
|
@ -2756,6 +2763,7 @@
|
||||||
83AA7F812519C042004C5298 /* silence.c in Sources */,
|
83AA7F812519C042004C5298 /* silence.c in Sources */,
|
||||||
834FE0B3215C798C000A5D3D /* acm_decoder_util.c in Sources */,
|
834FE0B3215C798C000A5D3D /* acm_decoder_util.c in Sources */,
|
||||||
837CEA7A23487E2500E62A4A /* ffmpeg_decoder_utils.c in Sources */,
|
837CEA7A23487E2500E62A4A /* ffmpeg_decoder_utils.c in Sources */,
|
||||||
|
839C3D28270D49FF00E13653 /* lopu.c in Sources */,
|
||||||
837CEAF823487F2C00E62A4A /* xmv_valve.c in Sources */,
|
837CEAF823487F2C00E62A4A /* xmv_valve.c in Sources */,
|
||||||
836F6F6718BDC2190095E648 /* acm.c in Sources */,
|
836F6F6718BDC2190095E648 /* acm.c in Sources */,
|
||||||
834FE0FD215C79ED000A5D3D /* vpk.c in Sources */,
|
834FE0FD215C79ED000A5D3D /* vpk.c in Sources */,
|
||||||
|
|
|
@ -404,9 +404,9 @@ ffmpeg_codec_data* init_ffmpeg_header_offset_subsong(STREAMFILE* sf, uint8_t* he
|
||||||
VGM_ASSERT(stream->codecpar->trailing_padding > 0, "FFMPEG: trailing_padding %i\n", (int)stream->codecpar->trailing_padding);
|
VGM_ASSERT(stream->codecpar->trailing_padding > 0, "FFMPEG: trailing_padding %i\n", (int)stream->codecpar->trailing_padding);
|
||||||
VGM_ASSERT(stream->codecpar->seek_preroll > 0, "FFMPEG: seek_preroll %i\n", (int)stream->codecpar->seek_preroll);//seek delay: OPUS
|
VGM_ASSERT(stream->codecpar->seek_preroll > 0, "FFMPEG: seek_preroll %i\n", (int)stream->codecpar->seek_preroll);//seek delay: OPUS
|
||||||
VGM_ASSERT(stream->start_time > 0, "FFMPEG: start_time %i\n", (int)stream->start_time); //delay
|
VGM_ASSERT(stream->start_time > 0, "FFMPEG: start_time %i\n", (int)stream->start_time); //delay
|
||||||
|
#if 0 //LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(58, 64, 100)
|
||||||
VGM_ASSERT(stream->first_discard_sample > 0, "FFMPEG: first_discard_sample %i\n", (int)stream->first_discard_sample); //padding: MP3
|
VGM_ASSERT(stream->first_discard_sample > 0, "FFMPEG: first_discard_sample %i\n", (int)stream->first_discard_sample); //padding: MP3
|
||||||
VGM_ASSERT(stream->last_discard_sample > 0, "FFMPEG: last_discard_sample %i\n", (int)stream->last_discard_sample); //padding: MP3
|
VGM_ASSERT(stream->last_discard_sample > 0, "FFMPEG: last_discard_sample %i\n", (int)stream->last_discard_sample); //padding: MP3
|
||||||
#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(58, 64, 100)
|
|
||||||
VGM_ASSERT(stream->skip_samples > 0, "FFMPEG: skip_samples %i\n", (int)stream->skip_samples); //delay: MP4
|
VGM_ASSERT(stream->skip_samples > 0, "FFMPEG: skip_samples %i\n", (int)stream->skip_samples); //delay: MP4
|
||||||
VGM_ASSERT(stream->start_skip_samples > 0, "FFMPEG: start_skip_samples %i\n", (int)stream->start_skip_samples); //delay: MP3
|
VGM_ASSERT(stream->start_skip_samples > 0, "FFMPEG: start_skip_samples %i\n", (int)stream->start_skip_samples); //delay: MP3
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -349,7 +349,7 @@ static STREAMFILE* setup_opus_streamfile(STREAMFILE* sf, opus_config* cfg, off_t
|
||||||
/* setup subfile */
|
/* setup subfile */
|
||||||
new_sf = open_wrap_streamfile(sf);
|
new_sf = open_wrap_streamfile(sf);
|
||||||
new_sf = open_io_streamfile_ex_f(new_sf, &io_data, sizeof(opus_io_data), opus_io_read, opus_io_size, opus_io_init, opus_io_close);
|
new_sf = open_io_streamfile_ex_f(new_sf, &io_data, sizeof(opus_io_data), opus_io_read, opus_io_size, opus_io_init, opus_io_close);
|
||||||
new_sf = open_buffer_streamfile_f(new_sf, 0);
|
//new_sf = open_buffer_streamfile_f(new_sf, 0); /* seems slightly slower on typical files */
|
||||||
return new_sf;
|
return new_sf;
|
||||||
fail:
|
fail:
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -266,6 +266,7 @@ static const char* extension_list[] = {
|
||||||
"l",
|
"l",
|
||||||
"l00", //txth/reserved [Disney's Dinosaur (PS2)]
|
"l00", //txth/reserved [Disney's Dinosaur (PS2)]
|
||||||
"laac", //fake extension for .aac (tri-Ace)
|
"laac", //fake extension for .aac (tri-Ace)
|
||||||
|
"ladpcm", //not fake
|
||||||
"laif", //fake extension for .aif (various)
|
"laif", //fake extension for .aif (various)
|
||||||
"laiff", //fake extension for .aiff
|
"laiff", //fake extension for .aiff
|
||||||
"laifc", //fake extension for .aifc
|
"laifc", //fake extension for .aifc
|
||||||
|
@ -289,7 +290,7 @@ static const char* extension_list[] = {
|
||||||
"lmp4", //fake extension for .mp4
|
"lmp4", //fake extension for .mp4
|
||||||
"lmpc", //fake extension for .mpc, FFmpeg/not parsed
|
"lmpc", //fake extension for .mpc, FFmpeg/not parsed
|
||||||
"logg", //fake extension for .ogg
|
"logg", //fake extension for .ogg
|
||||||
"lopus", //fake extension for .opus
|
"lopus", //fake extension for .opus, used by LOPU too
|
||||||
"lp",
|
"lp",
|
||||||
"lpcm",
|
"lpcm",
|
||||||
"lpk",
|
"lpk",
|
||||||
|
@ -1364,6 +1365,8 @@ static const meta_info meta_info_list[] = {
|
||||||
{meta_BNK_RELIC, "Relic BNK header"},
|
{meta_BNK_RELIC, "Relic BNK header"},
|
||||||
{meta_XSH_XSD_XSS, "Treyarch XSH+XSD/XSS header"},
|
{meta_XSH_XSD_XSS, "Treyarch XSH+XSD/XSS header"},
|
||||||
{meta_PSB, "M2 PSB header"},
|
{meta_PSB, "M2 PSB header"},
|
||||||
|
{meta_LOPU_FB, "French-Bread LOPU header"},
|
||||||
|
{meta_LPCM_FB, "French-Bread LPCM header"},
|
||||||
};
|
};
|
||||||
|
|
||||||
void get_vgmstream_coding_description(VGMSTREAM* vgmstream, char* out, size_t out_size) {
|
void get_vgmstream_coding_description(VGMSTREAM* vgmstream, char* out, size_t out_size) {
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#include "../coding/coding.h"
|
#include "../coding/coding.h"
|
||||||
#include "../coding/hca_decoder_clhca.h"
|
#include "../coding/hca_decoder_clhca.h"
|
||||||
|
|
||||||
//#define HCA_BRUTEFORCE
|
#define HCA_BRUTEFORCE
|
||||||
#ifdef HCA_BRUTEFORCE
|
#ifdef HCA_BRUTEFORCE
|
||||||
static void bruteforce_hca_key(STREAMFILE* sf, hca_codec_data* hca_data, unsigned long long* p_keycode, uint16_t subkey);
|
static void bruteforce_hca_key(STREAMFILE* sf, hca_codec_data* hca_data, unsigned long long* p_keycode, uint16_t subkey);
|
||||||
#endif
|
#endif
|
||||||
|
@ -22,12 +22,12 @@ VGMSTREAM* init_vgmstream_hca_subkey(STREAMFILE* sf, uint16_t subkey) {
|
||||||
|
|
||||||
|
|
||||||
/* checks */
|
/* checks */
|
||||||
|
if ((read_u32be(0x00,sf) & 0x7F7F7F7F) != get_id32be("HCA\0")) /* masked in encrypted files */
|
||||||
|
goto fail;
|
||||||
|
|
||||||
if (!check_extensions(sf, "hca"))
|
if (!check_extensions(sf, "hca"))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if ((read_u32be(0x00,sf) & 0x7F7F7F7F) != 0x48434100) /* "HCA\0", possibly masked */
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
/* init vgmstream and library's context, will validate the HCA */
|
/* init vgmstream and library's context, will validate the HCA */
|
||||||
hca_data = init_hca(sf);
|
hca_data = init_hca(sf);
|
||||||
if (!hca_data) {
|
if (!hca_data) {
|
||||||
|
@ -212,15 +212,15 @@ static void bruteforce_hca_key_bin_type(STREAMFILE* sf, hca_codec_data* hca_data
|
||||||
off_t keys_size, bytes;
|
off_t keys_size, bytes;
|
||||||
int pos;
|
int pos;
|
||||||
uint64_t old_key = 0;
|
uint64_t old_key = 0;
|
||||||
|
uint64_t key = 0;
|
||||||
|
|
||||||
|
|
||||||
VGM_LOG("HCA: test keys.bin (type %i)\n", type);
|
|
||||||
|
|
||||||
*p_keycode = 0;
|
|
||||||
|
|
||||||
/* load whole file in memory for performance (exes with keys shouldn't be too big) */
|
/* load whole file in memory for performance (exes with keys shouldn't be too big) */
|
||||||
sf_keys = open_streamfile_by_filename(sf, "keys.bin");
|
sf_keys = open_streamfile_by_filename(sf, "keys.bin");
|
||||||
if (!sf_keys) goto done;
|
if (!sf_keys) return;
|
||||||
|
|
||||||
|
VGM_LOG("HCA: test keys.bin (type %i)\n", type);
|
||||||
|
*p_keycode = 0;
|
||||||
|
|
||||||
keys_size = get_streamfile_size(sf_keys);
|
keys_size = get_streamfile_size(sf_keys);
|
||||||
|
|
||||||
|
@ -234,7 +234,6 @@ static void bruteforce_hca_key_bin_type(STREAMFILE* sf, hca_codec_data* hca_data
|
||||||
|
|
||||||
pos = 0;
|
pos = 0;
|
||||||
while (pos < keys_size - 4) {
|
while (pos < keys_size - 4) {
|
||||||
uint64_t key;
|
|
||||||
VGM_ASSERT(pos % 0x1000000 == 0, "HCA: pos %x...\n", pos);
|
VGM_ASSERT(pos % 0x1000000 == 0, "HCA: pos %x...\n", pos);
|
||||||
|
|
||||||
/* keys are usually u64le but other orders may exist */
|
/* keys are usually u64le but other orders may exist */
|
||||||
|
@ -256,8 +255,10 @@ static void bruteforce_hca_key_bin_type(STREAMFILE* sf, hca_codec_data* hca_data
|
||||||
|
|
||||||
cur_score = 0;
|
cur_score = 0;
|
||||||
test_key(hca_data, key, subkey, &cur_score, p_keycode);
|
test_key(hca_data, key, subkey, &cur_score, p_keycode);
|
||||||
if (cur_score == 1)
|
if (cur_score == 1) {
|
||||||
|
best_score = cur_score;
|
||||||
goto done;
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
if (cur_score > 0 && cur_score <= 500) {
|
if (cur_score > 0 && cur_score <= 500) {
|
||||||
VGM_LOG("HCA: possible key=%08x%08x (score=%i) at %x\n",
|
VGM_LOG("HCA: possible key=%08x%08x (score=%i) at %x\n",
|
||||||
|
@ -268,25 +269,32 @@ static void bruteforce_hca_key_bin_type(STREAMFILE* sf, hca_codec_data* hca_data
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
VGM_ASSERT(best_score > 0, "HCA: best key=%08x%08x (score=%i)\n",
|
if (best_score < 0 || best_score > 10000) {
|
||||||
(uint32_t)((*p_keycode >> 32) & 0xFFFFFFFF), (uint32_t)(*p_keycode & 0xFFFFFFFF), best_score);
|
|
||||||
VGM_ASSERT(best_score < 0, "HCA: key not found\n");
|
|
||||||
if (best_score < 0 || best_score > 10000)
|
|
||||||
*p_keycode = 0;
|
*p_keycode = 0;
|
||||||
|
VGM_LOG("HCA: good key not found\n");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* print key as p_keycode includes subkey */
|
||||||
|
VGM_LOG("HCA: best key=%08x%08x (score=%i)\n",
|
||||||
|
(uint32_t)((key >> 32) & 0xFFFFFFFF), (uint32_t)(key & 0xFFFFFFFF), best_score);
|
||||||
|
}
|
||||||
|
|
||||||
close_streamfile(sf_keys);
|
close_streamfile(sf_keys);
|
||||||
free(buf);
|
free(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bruteforce_hca_key_bin(STREAMFILE* sf, hca_codec_data* hca_data, unsigned long long* p_keycode, uint16_t subkey) {
|
static void bruteforce_hca_key_bin(STREAMFILE* sf, hca_codec_data* hca_data, unsigned long long* p_keycode, uint16_t subkey) {
|
||||||
bruteforce_hca_key_bin_type(sf, hca_data, p_keycode, subkey, HBF_TYPE_64LE_4);
|
|
||||||
bruteforce_hca_key_bin_type(sf, hca_data, p_keycode, subkey, HBF_TYPE_64BE_4);
|
|
||||||
bruteforce_hca_key_bin_type(sf, hca_data, p_keycode, subkey, HBF_TYPE_32LE_4);
|
|
||||||
bruteforce_hca_key_bin_type(sf, hca_data, p_keycode, subkey, HBF_TYPE_32BE_4);
|
|
||||||
bruteforce_hca_key_bin_type(sf, hca_data, p_keycode, subkey, HBF_TYPE_64LE_1);
|
bruteforce_hca_key_bin_type(sf, hca_data, p_keycode, subkey, HBF_TYPE_64LE_1);
|
||||||
bruteforce_hca_key_bin_type(sf, hca_data, p_keycode, subkey, HBF_TYPE_64BE_1);
|
/*
|
||||||
bruteforce_hca_key_bin_type(sf, hca_data, p_keycode, subkey, HBF_TYPE_32LE_1);
|
bruteforce_hca_key_bin_type(sf, hca_data, p_keycode, subkey, HBF_TYPE_32LE_1);
|
||||||
|
bruteforce_hca_key_bin_type(sf, hca_data, p_keycode, subkey, HBF_TYPE_64BE_1);
|
||||||
bruteforce_hca_key_bin_type(sf, hca_data, p_keycode, subkey, HBF_TYPE_32BE_1);
|
bruteforce_hca_key_bin_type(sf, hca_data, p_keycode, subkey, HBF_TYPE_32BE_1);
|
||||||
|
|
||||||
|
bruteforce_hca_key_bin_type(sf, hca_data, p_keycode, subkey, HBF_TYPE_64LE_4);
|
||||||
|
bruteforce_hca_key_bin_type(sf, hca_data, p_keycode, subkey, HBF_TYPE_32LE_4);
|
||||||
|
bruteforce_hca_key_bin_type(sf, hca_data, p_keycode, subkey, HBF_TYPE_64BE_4);
|
||||||
|
bruteforce_hca_key_bin_type(sf, hca_data, p_keycode, subkey, HBF_TYPE_32BE_4);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -303,13 +311,13 @@ static void bruteforce_hca_key_txt(STREAMFILE* sf, hca_codec_data* hca_data, uns
|
||||||
char line[1024];
|
char line[1024];
|
||||||
|
|
||||||
|
|
||||||
VGM_LOG("HCA: test keys.txt\n");
|
|
||||||
|
|
||||||
*p_keycode = 0;
|
|
||||||
|
|
||||||
/* load whole file in memory for performance (exes with keys shouldn't be too big) */
|
/* load whole file in memory for performance (exes with keys shouldn't be too big) */
|
||||||
sf_keys = open_streamfile_by_filename(sf, "keys.txt");
|
sf_keys = open_streamfile_by_filename(sf, "keys.txt");
|
||||||
if (!sf_keys) goto done;
|
if (!sf_keys) return;
|
||||||
|
|
||||||
|
VGM_LOG("HCA: test keys.txt\n");
|
||||||
|
*p_keycode = 0;
|
||||||
|
|
||||||
keys_size = get_streamfile_size(sf_keys);
|
keys_size = get_streamfile_size(sf_keys);
|
||||||
|
|
||||||
|
|
|
@ -758,9 +758,24 @@ static const hcakey_info hcakey_list[] = {
|
||||||
|
|
||||||
// m HOLD'EM (Android)
|
// m HOLD'EM (Android)
|
||||||
{369211553984367}, // 00014FCBC385AF6F
|
{369211553984367}, // 00014FCBC385AF6F
|
||||||
|
|
||||||
// Sonic Colors Ultimate (multi)
|
// Sonic Colors Ultimate (multi)
|
||||||
{1991062320101111}, // 000712DC5250B6F7
|
{1991062320101111}, // 000712DC5250B6F7
|
||||||
|
|
||||||
|
// ALTDEUS: Beyond Chronos (PC) [base-string 14238637353525924 + mods)]
|
||||||
|
{14238637353525934}, // 003295F7198AE2AE - bgm
|
||||||
|
{14238637353525954}, // 003295F7198AE2C2 - se
|
||||||
|
{14238637353525944}, // 003295F7198AE2B8 - voice
|
||||||
|
|
||||||
|
// SHOW BY ROCK!! Fes A Live (Android)
|
||||||
|
{54605542411982574}, // 00C1FF73963BD6EE
|
||||||
|
|
||||||
|
// Touhou Danmaku Kagura (Android)
|
||||||
|
{5654863921795627}, // 001417119B4FD22B
|
||||||
|
|
||||||
|
// Nogizaka 46 Fractal (Android)
|
||||||
|
{984635491346198130}, // 0DAA20C336EEAE72
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif/*_HCA_KEYS_H_*/
|
#endif/*_HCA_KEYS_H_*/
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
#include "meta.h"
|
||||||
|
#include "../coding/coding.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* LOPU - French-Bread's Opus [Melty Blood: Type Lumina (Switch)] */
|
||||||
|
VGMSTREAM* init_vgmstream_lopu_fb(STREAMFILE* sf) {
|
||||||
|
VGMSTREAM* vgmstream = NULL;
|
||||||
|
uint32_t start_offset, data_size;
|
||||||
|
int loop_flag, channels, sample_rate;
|
||||||
|
int32_t num_samples, loop_start, loop_end, skip;
|
||||||
|
|
||||||
|
/* checks */
|
||||||
|
if (!is_id32be(0x00, sf, "LOPU"))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
/* .lopus: real extension (honest) */
|
||||||
|
if (!check_extensions(sf, "lopus"))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
start_offset = read_u32le(0x04, sf);
|
||||||
|
sample_rate = read_s32le(0x08, sf);
|
||||||
|
channels = read_s16le(0x0c, sf);
|
||||||
|
/* 0x10: ? (1984) */
|
||||||
|
num_samples = read_s32le(0x14, sf);
|
||||||
|
loop_start = read_s32le(0x18, sf);
|
||||||
|
loop_end = read_s32le(0x1c, sf) + 1;
|
||||||
|
/* 0x20: frame size */
|
||||||
|
skip = read_s16le(0x24, sf);
|
||||||
|
data_size = read_u32le(0x28, sf);
|
||||||
|
/* rest: null */
|
||||||
|
|
||||||
|
loop_flag = (loop_end > 0); /* -1 if no loop */
|
||||||
|
num_samples -= skip;
|
||||||
|
|
||||||
|
|
||||||
|
/* build the VGMSTREAM */
|
||||||
|
vgmstream = allocate_vgmstream(channels, loop_flag);
|
||||||
|
if (!vgmstream) goto fail;
|
||||||
|
|
||||||
|
vgmstream->meta_type = meta_LOPU_FB;
|
||||||
|
vgmstream->sample_rate = sample_rate;
|
||||||
|
vgmstream->num_samples = num_samples;
|
||||||
|
vgmstream->loop_start_sample = loop_start;
|
||||||
|
vgmstream->loop_end_sample = loop_end;
|
||||||
|
|
||||||
|
#ifdef VGM_USE_FFMPEG
|
||||||
|
vgmstream->codec_data = init_ffmpeg_switch_opus(sf, start_offset, data_size, vgmstream->channels, skip, vgmstream->sample_rate);
|
||||||
|
if (!vgmstream->codec_data) goto fail;
|
||||||
|
vgmstream->coding_type = coding_FFmpeg;
|
||||||
|
vgmstream->layout_type = layout_none;
|
||||||
|
#else
|
||||||
|
goto fail;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!vgmstream_open_stream(vgmstream, sf, start_offset))
|
||||||
|
goto fail;
|
||||||
|
return vgmstream;
|
||||||
|
fail:
|
||||||
|
close_vgmstream(vgmstream);
|
||||||
|
return NULL;
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
#include "meta.h"
|
||||||
|
#include "../coding/coding.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* LPCM - French-Bread's DSP [Melty Blood: Type Lumina (Switch)] */
|
||||||
|
VGMSTREAM* init_vgmstream_lpcm_fb(STREAMFILE* sf) {
|
||||||
|
VGMSTREAM* vgmstream = NULL;
|
||||||
|
uint32_t start_offset;
|
||||||
|
int loop_flag, channels, sample_rate;
|
||||||
|
int32_t num_samples;
|
||||||
|
|
||||||
|
/* checks */
|
||||||
|
if (!is_id32be(0x00, sf, "LPCM"))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
/* .ladpcm: real extension (honest) */
|
||||||
|
if (!check_extensions(sf, "ladpcm"))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
/* 0x04: dsp offset (0x20) */
|
||||||
|
if (read_u32le(0x04, sf) != 0x20)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
num_samples = read_s32le(0x20, sf);
|
||||||
|
/* 0x24: nibbles? */
|
||||||
|
sample_rate = read_s32le(0x28, sf);
|
||||||
|
/* 0x2c: 0? */
|
||||||
|
/* 0x30: 2? */
|
||||||
|
/* 0x34: nibbles? */
|
||||||
|
/* 0x38: 2? */
|
||||||
|
if (read_u32le(0x38, sf) != 2)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
channels = 1;
|
||||||
|
loop_flag = 0;
|
||||||
|
|
||||||
|
start_offset = 0x78; /* could be 0x80 but this is closer to num_samples */
|
||||||
|
|
||||||
|
|
||||||
|
/* build the VGMSTREAM */
|
||||||
|
vgmstream = allocate_vgmstream(channels, loop_flag);
|
||||||
|
if (!vgmstream) goto fail;
|
||||||
|
|
||||||
|
vgmstream->meta_type = meta_LPCM_FB;
|
||||||
|
vgmstream->sample_rate = sample_rate;
|
||||||
|
vgmstream->num_samples = num_samples;
|
||||||
|
|
||||||
|
vgmstream->coding_type = coding_NGC_DSP;
|
||||||
|
vgmstream->layout_type = layout_none;
|
||||||
|
|
||||||
|
dsp_read_coefs_le(vgmstream, sf, 0x3c, 0);
|
||||||
|
/* 0x5c: hist? */
|
||||||
|
|
||||||
|
|
||||||
|
if (!vgmstream_open_stream(vgmstream, sf, start_offset))
|
||||||
|
goto fail;
|
||||||
|
return vgmstream;
|
||||||
|
fail:
|
||||||
|
close_vgmstream(vgmstream);
|
||||||
|
return NULL;
|
||||||
|
}
|
|
@ -964,4 +964,8 @@ VGMSTREAM* init_vgmstream_xsh_xsd_xss(STREAMFILE* sf);
|
||||||
|
|
||||||
VGMSTREAM* init_vgmstream_psb(STREAMFILE* sf);
|
VGMSTREAM* init_vgmstream_psb(STREAMFILE* sf);
|
||||||
|
|
||||||
|
VGMSTREAM* init_vgmstream_lopu_fb(STREAMFILE* sf);
|
||||||
|
|
||||||
|
VGMSTREAM* init_vgmstream_lpcm_fb(STREAMFILE* sf);
|
||||||
|
|
||||||
#endif /*_META_H*/
|
#endif /*_META_H*/
|
||||||
|
|
|
@ -25,16 +25,16 @@ VGMSTREAM* init_vgmstream_mp4_aac_ffmpeg(STREAMFILE* sf) {
|
||||||
|
|
||||||
|
|
||||||
/* checks */
|
/* checks */
|
||||||
/* .bin: Final Fantasy Dimensions (iOS), Final Fantasy V (iOS)
|
|
||||||
* .msd: UNO (iOS) */
|
|
||||||
if (!check_extensions(sf,"mp4,m4a,m4v,lmp4,bin,lbin,msd"))
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
if ((read_u32be(0x00,sf) & 0xFFFFFF00) != 0) /* first atom BE size (usually ~0x18) */
|
if ((read_u32be(0x00,sf) & 0xFFFFFF00) != 0) /* first atom BE size (usually ~0x18) */
|
||||||
goto fail;
|
goto fail;
|
||||||
if (!is_id32be(0x04,sf, "ftyp"))
|
if (!is_id32be(0x04,sf, "ftyp"))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
/* .bin: Final Fantasy Dimensions (iOS), Final Fantasy V (iOS)
|
||||||
|
* .msd: UNO (iOS) */
|
||||||
|
if (!check_extensions(sf,"mp4,m4a,m4v,lmp4,bin,lbin,msd"))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
file_size = get_streamfile_size(sf);
|
file_size = get_streamfile_size(sf);
|
||||||
|
|
||||||
ffmpeg_data = init_ffmpeg_offset(sf, start_offset, file_size);
|
ffmpeg_data = init_ffmpeg_offset(sf, start_offset, file_size);
|
||||||
|
@ -86,7 +86,7 @@ fail:
|
||||||
|
|
||||||
/* read useful MP4 chunks */
|
/* read useful MP4 chunks */
|
||||||
static void parse_mp4(STREAMFILE* sf, mp4_header* mp4) {
|
static void parse_mp4(STREAMFILE* sf, mp4_header* mp4) {
|
||||||
off_t offset, suboffset, max_offset, max_suboffset;
|
uint32_t offset, suboffset, max_offset, max_suboffset;
|
||||||
|
|
||||||
|
|
||||||
/* MOV format chunks, called "atoms", size goes first because Apple */
|
/* MOV format chunks, called "atoms", size goes first because Apple */
|
||||||
|
@ -117,12 +117,25 @@ static void parse_mp4(STREAMFILE* sf, mp4_header* mp4) {
|
||||||
mp4->loop_start = read_u32be(offset + 0x08 + 0x2c,sf);
|
mp4->loop_start = read_u32be(offset + 0x08 + 0x2c,sf);
|
||||||
mp4->loop_end = read_u32be(offset + 0x08 + 0x30,sf);
|
mp4->loop_end = read_u32be(offset + 0x08 + 0x30,sf);
|
||||||
}
|
}
|
||||||
/* could stop reading since FFmpeg will too */
|
max_offset = 0;
|
||||||
|
}
|
||||||
|
/* M2 emu's .m4a (codename zoom) */
|
||||||
|
else if (is_id32be(offset + 0x08 + 0x00,sf, "ZOOM")) {
|
||||||
|
/* 0x00: id */
|
||||||
|
mp4->encoder_delay = read_s32be(offset + 0x08 + 0x04,sf); /* Apple's 2112, also in iTunes tag */
|
||||||
|
/* 0x08: end padding */
|
||||||
|
mp4->num_samples = read_s32be(offset + 0x08 + 0x0c,sf);
|
||||||
|
mp4->loop_start = read_s32be(offset + 0x08 + 0x10,sf);
|
||||||
|
mp4->loop_end = read_s32be(offset + 0x08 + 0x14,sf);
|
||||||
|
mp4->loop_flag = (mp4->loop_end != 0);
|
||||||
|
if (mp4->loop_flag)
|
||||||
|
mp4->loop_end++; /* assumed, matches num_samples this way */
|
||||||
|
max_offset = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x6D6F6F76: { /* "moov" (header) */
|
case 0x6D6F6F76: { /* "moov" (header) */
|
||||||
suboffset = offset += 0x08;
|
suboffset = offset + 0x08;
|
||||||
max_suboffset = offset + size;
|
max_suboffset = offset + size;
|
||||||
while (suboffset < max_suboffset) {
|
while (suboffset < max_suboffset) {
|
||||||
uint32_t subsize = read_u32be(suboffset + 0x00,sf);
|
uint32_t subsize = read_u32be(suboffset + 0x00,sf);
|
||||||
|
@ -145,6 +158,7 @@ static void parse_mp4(STREAMFILE* sf, mp4_header* mp4) {
|
||||||
mp4->num_samples = read_s32be(criw_offset + 0x0c,sf);
|
mp4->num_samples = read_s32be(criw_offset + 0x0c,sf);
|
||||||
mp4->loop_flag = (mp4->loop_end > 0);
|
mp4->loop_flag = (mp4->loop_end > 0);
|
||||||
/* next 2 fields are null */
|
/* next 2 fields are null */
|
||||||
|
max_offset = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -200,9 +200,19 @@ static int get_loops_gameexe_ini(STREAMFILE* sf, int* p_loop_flag, int32_t* p_lo
|
||||||
length = ext-1-namebase;
|
length = ext-1-namebase;
|
||||||
file_size = get_streamfile_size(sf_loop);
|
file_size = get_streamfile_size(sf_loop);
|
||||||
|
|
||||||
/* format of line is:
|
/* According to the official documentation of RealLiveMax (the public version of RealLive), format of line is:
|
||||||
* #DSTRACK = 00000000 - eeeeeeee - ssssssss = "name" = "name2?"
|
* #DSTRACK = 00000000 - eeeeeeee - ssssssss = "filename" = "alias for game script"
|
||||||
* ^22 ^33 ^45 ^57
|
* ^22 ^33 ^45 ^57?
|
||||||
|
*
|
||||||
|
* Original text from the documentation (written in Japanese) is:
|
||||||
|
* ; ■BGMの登録:DirectSound
|
||||||
|
* ;(※必要ない場合は登録しないで下さい。)
|
||||||
|
* ; 終了位置の設定が 99999999 なら最後まで演奏します。
|
||||||
|
* ; ※設定値はサンプル数で指定して下さい。(旧システムではバイト指定でしたので注意してください。)
|
||||||
|
* ;=========================================================================================================
|
||||||
|
* ; 開始位置 - 終了位置 - リピート = ファイル名 = 登録名
|
||||||
|
* #DSTRACK = 00000000 - 01896330 - 00088270 = "b_manuke" = "b_manuke"
|
||||||
|
* #DSTRACK = 00000000 - 01918487 - 00132385 = "c_happy" = "c_happy"
|
||||||
*/
|
*/
|
||||||
|
|
||||||
for (found = 0, offset = 0; !found && offset<file_size; offset++) {
|
for (found = 0, offset = 0; !found && offset<file_size; offset++) {
|
||||||
|
|
|
@ -51,6 +51,7 @@ typedef struct {
|
||||||
int loop_flag;
|
int loop_flag;
|
||||||
int32_t loop_start;
|
int32_t loop_start;
|
||||||
int32_t loop_end;
|
int32_t loop_end;
|
||||||
|
int duration_test;
|
||||||
|
|
||||||
} psb_header_t;
|
} psb_header_t;
|
||||||
|
|
||||||
|
@ -153,6 +154,9 @@ VGMSTREAM* init_vgmstream_psb(STREAMFILE* sf) {
|
||||||
case 24: vgmstream->coding_type = coding_PCM24LE; break; /* Legend of Mana (PC) */
|
case 24: vgmstream->coding_type = coding_PCM24LE; break; /* Legend of Mana (PC) */
|
||||||
default: goto fail;
|
default: goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (psb.duration_test && psb.loop_start + psb.loop_end < vgmstream->num_samples)
|
||||||
|
vgmstream->loop_end_sample += psb.loop_start;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MSADPCM: /* [Senxin Aleste (AC)] */
|
case MSADPCM: /* [Senxin Aleste (AC)] */
|
||||||
|
@ -218,6 +222,8 @@ VGMSTREAM* init_vgmstream_psb(STREAMFILE* sf) {
|
||||||
}
|
}
|
||||||
|
|
||||||
vgmstream->num_samples = read_u32le(psb.stream_offset[0] + 0x00, sf);
|
vgmstream->num_samples = read_u32le(psb.stream_offset[0] + 0x00, sf);
|
||||||
|
if (psb.duration_test && psb.loop_start + psb.loop_end < vgmstream->num_samples)
|
||||||
|
vgmstream->loop_end_sample += psb.loop_start;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -592,7 +598,9 @@ static int parse_psb_channels(psb_header_t* psb, psb_node_t* nchans) {
|
||||||
psb->loop_start = psb_node_get_result(&nsub).num;
|
psb->loop_start = psb_node_get_result(&nsub).num;
|
||||||
|
|
||||||
psb_node_by_index(&node, 1, &nsub);
|
psb_node_by_index(&node, 1, &nsub);
|
||||||
psb->loop_end = psb_node_get_result(&nsub).num + psb->loop_start; /* duration */
|
psb->loop_end = psb_node_get_result(&nsub).num + 1; /* assumed, matches num_samples */
|
||||||
|
/* duration [LoM (PC), Namco Museum V1 (PC)] or standard [G-Darius (Sw)] (no apparent flags) */
|
||||||
|
psb->duration_test = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -527,6 +527,8 @@ VGMSTREAM* (*init_vgmstream_functions[])(STREAMFILE* sf) = {
|
||||||
init_vgmstream_bnk_relic,
|
init_vgmstream_bnk_relic,
|
||||||
init_vgmstream_xsh_xsd_xss,
|
init_vgmstream_xsh_xsd_xss,
|
||||||
init_vgmstream_psb,
|
init_vgmstream_psb,
|
||||||
|
init_vgmstream_lopu_fb,
|
||||||
|
init_vgmstream_lpcm_fb,
|
||||||
|
|
||||||
/* lowest priority metas (should go after all metas, and TXTH should go before raw formats) */
|
/* lowest priority metas (should go after all metas, and TXTH should go before raw formats) */
|
||||||
init_vgmstream_txth, /* proper parsers should supersede TXTH, once added */
|
init_vgmstream_txth, /* proper parsers should supersede TXTH, once added */
|
||||||
|
|
|
@ -756,6 +756,8 @@ typedef enum {
|
||||||
meta_BNK_RELIC,
|
meta_BNK_RELIC,
|
||||||
meta_XSH_XSD_XSS,
|
meta_XSH_XSD_XSS,
|
||||||
meta_PSB,
|
meta_PSB,
|
||||||
|
meta_LOPU_FB,
|
||||||
|
meta_LPCM_FB,
|
||||||
|
|
||||||
} meta_t;
|
} meta_t;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue