mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-11-29 00:34:33 +01:00
Merge pull request #1290 from bnnm/gtd-misc
- Add PS3 .gtd [Knight's Contract (PS3)] - Add .fcb extension [Scribblenauts Unmasked (PC)] - Add KTSS .ktsl2asbin [Ultra Kaiju Monster Rancher (NS)] - Add FSB keys, cleanup - Add HCA keys
This commit is contained in:
commit
8424dcc5a8
@ -185,6 +185,7 @@ static const char* extension_list[] = {
|
|||||||
"ezw",
|
"ezw",
|
||||||
|
|
||||||
"fag",
|
"fag",
|
||||||
|
"fcb", //FFmpeg/not parsed (BINK AUDIO)
|
||||||
"fda",
|
"fda",
|
||||||
"ffw",
|
"ffw",
|
||||||
"filp",
|
"filp",
|
||||||
@ -1248,7 +1249,7 @@ static const meta_info meta_info_list[] = {
|
|||||||
{meta_SXD, "Sony SXD header"},
|
{meta_SXD, "Sony SXD header"},
|
||||||
{meta_OGL, "Shin'en OGL header"},
|
{meta_OGL, "Shin'en OGL header"},
|
||||||
{meta_MC3, "Paradigm MC3 header"},
|
{meta_MC3, "Paradigm MC3 header"},
|
||||||
{meta_GTD, "Hexadrive GHS/S_P_STH header"},
|
{meta_GHS, "Hexadrive GHS/S_P_STH header"},
|
||||||
{meta_AAC_TRIACE, "tri-Ace AAC header"},
|
{meta_AAC_TRIACE, "tri-Ace AAC header"},
|
||||||
{meta_MTA2, "Konami MTA2 header"},
|
{meta_MTA2, "Konami MTA2 header"},
|
||||||
{meta_NGC_ULW, "Criterion ULW raw header"},
|
{meta_NGC_ULW, "Criterion ULW raw header"},
|
||||||
|
@ -416,9 +416,9 @@
|
|||||||
<ClCompile Include="meta\gcsw.c" />
|
<ClCompile Include="meta\gcsw.c" />
|
||||||
<ClCompile Include="meta\gcub.c" />
|
<ClCompile Include="meta\gcub.c" />
|
||||||
<ClCompile Include="meta\genh.c" />
|
<ClCompile Include="meta\genh.c" />
|
||||||
|
<ClCompile Include="meta\ghs.c" />
|
||||||
<ClCompile Include="meta\gin.c" />
|
<ClCompile Include="meta\gin.c" />
|
||||||
<ClCompile Include="meta\gsp_gsb.c" />
|
<ClCompile Include="meta\gsp_gsb.c" />
|
||||||
<ClCompile Include="meta\gtd.c" />
|
|
||||||
<ClCompile Include="meta\h4m.c" />
|
<ClCompile Include="meta\h4m.c" />
|
||||||
<ClCompile Include="meta\halpst.c" />
|
<ClCompile Include="meta\halpst.c" />
|
||||||
<ClCompile Include="meta\hca.c" />
|
<ClCompile Include="meta\hca.c" />
|
||||||
|
@ -1069,15 +1069,15 @@
|
|||||||
<ClCompile Include="meta\genh.c">
|
<ClCompile Include="meta\genh.c">
|
||||||
<Filter>meta\Source Files</Filter>
|
<Filter>meta\Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="meta\ghs.c">
|
||||||
|
<Filter>meta\Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="meta\gin.c">
|
<ClCompile Include="meta\gin.c">
|
||||||
<Filter>meta\Source Files</Filter>
|
<Filter>meta\Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="meta\gsp_gsb.c">
|
<ClCompile Include="meta\gsp_gsb.c">
|
||||||
<Filter>meta\Source Files</Filter>
|
<Filter>meta\Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="meta\gtd.c">
|
|
||||||
<Filter>meta\Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="meta\h4m.c">
|
<ClCompile Include="meta\h4m.c">
|
||||||
<Filter>meta\Source Files</Filter>
|
<Filter>meta\Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
#include "fsb_encrypted_streamfile.h"
|
#include "fsb_encrypted_streamfile.h"
|
||||||
|
|
||||||
|
|
||||||
|
static VGMSTREAM* test_fsbkey(STREAMFILE* sf, const uint8_t* key, size_t key_size, uint8_t flags);
|
||||||
|
|
||||||
/* fully encrypted FSBs */
|
/* fully encrypted FSBs */
|
||||||
VGMSTREAM* init_vgmstream_fsb_encrypted(STREAMFILE* sf) {
|
VGMSTREAM* init_vgmstream_fsb_encrypted(STREAMFILE* sf) {
|
||||||
VGMSTREAM* vgmstream = NULL;
|
VGMSTREAM* vgmstream = NULL;
|
||||||
@ -18,58 +20,21 @@ VGMSTREAM* init_vgmstream_fsb_encrypted(STREAMFILE* sf) {
|
|||||||
if (!check_extensions(sf, "fsb,ps3,xen"))
|
if (!check_extensions(sf, "fsb,ps3,xen"))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
|
||||||
/* try fsbkey + all combinations of FSB4/5 and decryption algorithms */
|
/* try fsbkey + all combinations of FSB4/5 and decryption algorithms */
|
||||||
{
|
{
|
||||||
STREAMFILE* temp_sf = NULL;
|
|
||||||
uint8_t key[FSB_KEY_MAX];
|
uint8_t key[FSB_KEY_MAX];
|
||||||
size_t key_size = read_key_file(key, FSB_KEY_MAX, sf);
|
size_t key_size = read_key_file(key, FSB_KEY_MAX, sf);
|
||||||
|
|
||||||
if (key_size) {
|
test_fsbkey(sf, key, key_size, MODE_FSBS_ALL);
|
||||||
{
|
|
||||||
temp_sf = setup_fsb_streamfile(sf, key,key_size, 0);
|
|
||||||
if (!temp_sf) goto fail;
|
|
||||||
|
|
||||||
if (!vgmstream) vgmstream = init_vgmstream_fsb(temp_sf);
|
|
||||||
if (!vgmstream) vgmstream = init_vgmstream_fsb5(temp_sf);
|
|
||||||
|
|
||||||
close_streamfile(temp_sf);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!vgmstream) {
|
|
||||||
temp_sf = setup_fsb_streamfile(sf, key,key_size, 1);
|
|
||||||
if (!temp_sf) goto fail;
|
|
||||||
|
|
||||||
if (!vgmstream) vgmstream = init_vgmstream_fsb(temp_sf);
|
|
||||||
if (!vgmstream) vgmstream = init_vgmstream_fsb5(temp_sf);
|
|
||||||
|
|
||||||
close_streamfile(temp_sf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* try all keys until one works */
|
/* try all keys until one works */
|
||||||
if (!vgmstream) {
|
if (!vgmstream) {
|
||||||
int i;
|
for (int i = 0; i < fsbkey_list_count; i++) {
|
||||||
STREAMFILE* temp_sf = NULL;
|
|
||||||
|
|
||||||
for (i = 0; i < fsbkey_list_count; i++) {
|
|
||||||
fsbkey_info entry = fsbkey_list[i];
|
fsbkey_info entry = fsbkey_list[i];
|
||||||
//;VGM_LOG("fsbkey: size=%i, is_fsb5=%i, is_alt=%i\n", entry.fsbkey_size,entry.is_fsb5, entry.is_alt);
|
|
||||||
|
|
||||||
temp_sf = setup_fsb_streamfile(sf, entry.fsbkey, entry.fsbkey_size, entry.is_alt);
|
vgmstream = test_fsbkey(sf, (const uint8_t*)entry.key, entry.key_size, entry.flags);
|
||||||
if (!temp_sf) goto fail;
|
|
||||||
|
|
||||||
if (fsbkey_list[i].is_fsb5) {
|
|
||||||
vgmstream = init_vgmstream_fsb5(temp_sf);
|
|
||||||
} else {
|
|
||||||
vgmstream = init_vgmstream_fsb(temp_sf);
|
|
||||||
}
|
|
||||||
|
|
||||||
//;if (vgmstream) dump_streamfile(temp_sf, 0);
|
|
||||||
|
|
||||||
close_streamfile(temp_sf);
|
|
||||||
if (vgmstream) break;
|
if (vgmstream) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -83,3 +48,41 @@ fail:
|
|||||||
close_vgmstream(vgmstream);
|
close_vgmstream(vgmstream);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VGMSTREAM* test_fsbkey(STREAMFILE* sf, const uint8_t* key, size_t key_size, uint8_t flags) {
|
||||||
|
STREAMFILE* temp_sf = NULL;
|
||||||
|
VGMSTREAM* vc = NULL;
|
||||||
|
|
||||||
|
if (!key_size)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
int test_fsb4 = flags & FLAG_FSB4;
|
||||||
|
int test_fsb5 = flags & FLAG_FSB5;
|
||||||
|
int test_std = flags & FLAG_STD;
|
||||||
|
int test_alt = flags & FLAG_ALT;
|
||||||
|
|
||||||
|
|
||||||
|
if (!vc && test_std) {
|
||||||
|
temp_sf = setup_fsb_streamfile(sf, key, key_size, 0);
|
||||||
|
if (!temp_sf) return NULL;
|
||||||
|
|
||||||
|
if (!vc && test_fsb4) vc = init_vgmstream_fsb(temp_sf);
|
||||||
|
if (!vc && test_fsb5) vc = init_vgmstream_fsb5(temp_sf);
|
||||||
|
|
||||||
|
//;if (vgmstream) dump_streamfile(temp_sf, 0);
|
||||||
|
close_streamfile(temp_sf);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!vc && test_alt) {
|
||||||
|
temp_sf = setup_fsb_streamfile(sf, key, key_size, 1);
|
||||||
|
if (!temp_sf) return NULL;
|
||||||
|
|
||||||
|
if (!vc && test_fsb4) vc = init_vgmstream_fsb(temp_sf);
|
||||||
|
if (!vc && test_fsb5) vc = init_vgmstream_fsb5(temp_sf);
|
||||||
|
|
||||||
|
//;if (vgmstream) dump_streamfile(temp_sf, 0);
|
||||||
|
close_streamfile(temp_sf);
|
||||||
|
}
|
||||||
|
|
||||||
|
return vc;
|
||||||
|
}
|
||||||
|
@ -1,100 +1,11 @@
|
|||||||
#ifndef _FSB_KEYS_H_
|
#ifndef _FSB_KEYS_H_
|
||||||
#define _FSB_KEYS_H_
|
#define _FSB_KEYS_H_
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* List of known keys, found in aluigi's site (http://aluigi.altervista.org), forums, guessfsb.exe or manually.
|
* List of known keys, found in aluigi's site (http://aluigi.altervista.org), forums, guessfsb.exe or manually.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* DJ Hero 2 (X360) */ //"nos71RiT"
|
|
||||||
static const uint8_t key_dj2[] = { 0x6E,0x6F,0x73,0x37,0x31,0x52,0x69,0x54 };
|
|
||||||
|
|
||||||
/* Double Fine Productions: Brutal Legend, Massive Chalice, etc (multi) */ //"DFm3t4lFTW"
|
|
||||||
static const uint8_t key_dfp[] = { 0x44,0x46,0x6D,0x33,0x74,0x34,0x6C,0x46,0x54,0x57 };
|
|
||||||
|
|
||||||
/* N++ (PC?) */ //"H$#FJa%7gRZZOlxLiN50&g5Q"
|
|
||||||
static const uint8_t key_npp[] = { 0x48,0x24,0x23,0x46,0x4A,0x61,0x25,0x37,0x67,0x52,0x5A,0x5A,0x4F,0x6C,0x78,0x4C,0x69,0x4E,0x35,0x30,0x26,0x67,0x35,0x51 };
|
|
||||||
|
|
||||||
/* Slightly Mad Studios: Project CARS (PC?), World of Speed (PC) */ //"sTOoeJXI2LjK8jBMOk8h5IDRNZl3jq3I"
|
|
||||||
static const uint8_t key_sms[] = { 0x73,0x54,0x4F,0x6F,0x65,0x4A,0x58,0x49,0x32,0x4C,0x6A,0x4B,0x38,0x6A,0x42,0x4D,0x4F,0x6B,0x38,0x68,0x35,0x49,0x44,0x52,0x4E,0x5A,0x6C,0x33,0x6A,0x71,0x33,0x49 };
|
|
||||||
|
|
||||||
/* Ghost in the Shell: First Assault (PC) */ //"%lAn2{Pi*Lhw3T}@7*!kV=?qS$@iNlJ"
|
|
||||||
static const uint8_t key_gfs[] = { 0x25,0x6C,0x41,0x6E,0x32,0x7B,0x50,0x69,0x2A,0x4C,0x68,0x77,0x33,0x54,0x7D,0x40,0x37,0x2A,0x21,0x6B,0x56,0x3D,0x3F,0x71,0x53,0x24,0x40,0x69,0x4E,0x6C,0x4A };
|
|
||||||
|
|
||||||
/* RevHeadz Engine Sounds (Mobile) */ //"1^7%82#&5$~/8sz"
|
|
||||||
static const uint8_t key_rev[] = { 0x31,0x5E,0x37,0x25,0x38,0x32,0x23,0x26,0x35,0x24,0x7E,0x2F,0x38,0x73,0x7A };
|
|
||||||
|
|
||||||
/* Dark Souls 3 (PC) */ //"FDPrVuT4fAFvdHJYAgyMzRF4EcBAnKg"
|
|
||||||
static const uint8_t key_ds3[] = { 0x46,0x44,0x50,0x72,0x56,0x75,0x54,0x34,0x66,0x41,0x46,0x76,0x64,0x48,0x4A,0x59,0x41,0x67,0x79,0x4D,0x7A,0x52,0x46,0x34,0x45,0x63,0x42,0x41,0x6E,0x4B,0x67 };
|
|
||||||
|
|
||||||
/* Mortal Kombat X/XL (PC) */ //"996164B5FC0F402983F61F220BB51DC6"
|
|
||||||
static const uint8_t key_mkx[] = { 0x39,0x39,0x36,0x31,0x36,0x34,0x42,0x35,0x46,0x43,0x30,0x46,0x34,0x30,0x32,0x39,0x38,0x33,0x46,0x36,0x31,0x46,0x32,0x32,0x30,0x42,0x42,0x35,0x31,0x44,0x43,0x36 };
|
|
||||||
|
|
||||||
/* Xian Xia Chuan (PC) */ //"gat@tcqs2010"
|
|
||||||
static const uint8_t key_xxc[] = { 0x67,0x61,0x74,0x40,0x74,0x63,0x71,0x73,0x32,0x30,0x31,0x30 };
|
|
||||||
|
|
||||||
/* Mirror War: Reincarnation of Holiness (PC) */ //"logicsounddesignmwsdev"
|
|
||||||
static const uint8_t key_mwr[] = { 0x6C,0x6F,0x67,0x69,0x63,0x73,0x6F,0x75,0x6E,0x64,0x64,0x65,0x73,0x69,0x67,0x6E,0x6D,0x77,0x73,0x64,0x65,0x76 };
|
|
||||||
|
|
||||||
/* Need for Speed Shift 2 Unleashed (PC demo?) */ //"p&oACY^c4LK5C2v^x5nIO6kg5vNH$tlj"
|
|
||||||
static const uint8_t key_n2u[] = { 0x70,0x26,0x6F,0x41,0x43,0x59,0x5E,0x63,0x34,0x4C,0x4B,0x35,0x43,0x32,0x76,0x5E,0x78,0x35,0x6E,0x49,0x4F,0x36,0x6B,0x67,0x35,0x76,0x4E,0x48,0x24,0x74,0x6C,0x6A };
|
|
||||||
|
|
||||||
/* Critter Crunch (PC), Superbrothers: Sword & Sworcery (PC) */ //"j1$Mk0Libg3#apEr42mo"
|
|
||||||
static const uint8_t key_ccr[] = { 0x6A,0x31,0x24,0x4D,0x6B,0x30,0x4C,0x69,0x62,0x67,0x33,0x23,0x61,0x70,0x45,0x72,0x34,0x32,0x6D,0x6F };
|
|
||||||
|
|
||||||
/* Cyphers */ //"@kdj43nKDN^k*kj3ndf02hd95nsl(NJG"
|
|
||||||
static const uint8_t key_cyp[] = { 0x40,0x6B,0x64,0x6A,0x34,0x33,0x6E,0x4B,0x44,0x4E,0x5E,0x6B,0x2A,0x6B,0x6A,0x33,0x6E,0x64,0x66,0x30,0x32,0x68,0x64,0x39,0x35,0x6E,0x73,0x6C,0x28,0x4E,0x4A,0x47 };
|
|
||||||
|
|
||||||
/* Xuan Dou Zhi Wang / King of Combat */ //"Xiayuwu69252.Sonicli81223#$*@*0"
|
|
||||||
static const uint8_t key_xdz[] = { 0x58,0x69,0x61,0x79,0x75,0x77,0x75,0x36,0x39,0x32,0x35,0x32,0x2E,0x53,0x6F,0x6E,0x69,0x63,0x6C,0x69,0x38,0x31,0x32,0x32,0x33,0x23,0x24,0x2A,0x40,0x2A,0x30 };
|
|
||||||
|
|
||||||
/* Ji Feng Zhi Ren / Kritika Online */ //"kri_tika_5050_"
|
|
||||||
static const uint8_t key_jzz[] = { 0x6B,0x72,0x69,0x5F,0x74,0x69,0x6B,0x61,0x5F,0x35,0x30,0x35,0x30,0x5F };
|
|
||||||
|
|
||||||
/* Invisible Inc. (PC?) */ //"mint78run52"
|
|
||||||
static const uint8_t key_inv[] = { 0x6D,0x69,0x6E,0x74,0x37,0x38,0x72,0x75,0x6E,0x35,0x32 };
|
|
||||||
|
|
||||||
/* Guitar Hero 3 */ //"5atu6w4zaw"
|
|
||||||
static const uint8_t key_gh3[] = { 0x35,0x61,0x74,0x75,0x36,0x77,0x34,0x7A,0x61,0x77 };
|
|
||||||
|
|
||||||
/* Supreme Commander 2 */ //"B2A7BB00"
|
|
||||||
static const uint8_t key_sc2[] = { 0x42,0x32,0x41,0x37,0x42,0x42,0x30,0x30 };
|
|
||||||
|
|
||||||
/* Cookie Run: Ovenbreak */ //"ghfxhslrghfxhslr"
|
|
||||||
static const uint8_t key_cro[] = { 0x67,0x68,0x66,0x78,0x68,0x73,0x6C,0x72,0x67,0x68,0x66,0x78,0x68,0x73,0x6C,0x72 };
|
|
||||||
|
|
||||||
/* Monster Jam (PS2) */ //"truck/impact/carbody"
|
|
||||||
static const uint8_t key_mtj[] = { 0x74,0x72,0x75,0x63,0x6B,0x2F,0x69,0x6D,0x70,0x61,0x63,0x74,0x2F,0x63,0x61,0x72,0x62,0x6F,0x64,0x79 };
|
|
||||||
|
|
||||||
/* Guitar Hero 5 (X360) */
|
|
||||||
static const uint8_t key_gh5[] = { 0xFC,0xF9,0xE4,0xB3,0xF5,0x57,0x5C,0xA5,0xAC,0x13,0xEC,0x4A,0x43,0x19,0x58,0xEB,0x4E,0xF3,0x84,0x0B,0x8B,0x78,0xFA,0xFD,0xBB,0x18,0x46,0x7E,0x31,0xFB,0xD0 };
|
|
||||||
|
|
||||||
/* Sekiro: Shadows Die Twice (PC) */ //"G0KTrWjS9syqF7vVD6RaVXlFD91gMgkC"
|
|
||||||
static const uint8_t key_sek[] = { 0x47,0x30,0x4B,0x54,0x72,0x57,0x6A,0x53,0x39,0x73,0x79,0x71,0x46,0x37,0x76,0x56,0x44,0x36,0x52,0x61,0x56,0x58,0x6C,0x46,0x44,0x39,0x31,0x67,0x4D,0x67,0x6B,0x43 };
|
|
||||||
|
|
||||||
/* SCP: Unity (PC) */ //"BasicEncryptionKey"
|
|
||||||
static const uint8_t key_scp[] = { 0x42,0x61,0x73,0x69,0x63,0x45,0x6E,0x63,0x72,0x79,0x70,0x74,0x69,0x6F,0x6E,0x4B,0x65,0x79 };
|
|
||||||
|
|
||||||
/* Guitar Hero: Metallica (X360) */
|
|
||||||
static const uint8_t key_ghm[] = { 0x8C,0xFA,0xF3,0x14,0xB1,0x53,0xDA,0xAB,0x2B,0x82,0x6B,0xD5,0x55,0x16,0xCF,0x01,0x90,0x20,0x28,0x14,0xB1,0x53,0xD8 };
|
|
||||||
|
|
||||||
/* Worms Rumble Beta (PC) */ //"FXnTffGJ9LS855Gc"
|
|
||||||
static const uint8_t key_wrb[] = { 0x46,0x58,0x6E,0x54,0x66,0x66,0x47,0x4A,0x39,0x4C,0x53,0x38,0x35,0x35,0x47,0x63 };
|
|
||||||
|
|
||||||
/* Bubble Fighter (PC) */ //"qjvkeoqkrdhkdckd"
|
|
||||||
static const uint8_t key_bbf[] = { 0x71,0x6A,0x76,0x6B,0x65,0x6F,0x71,0x6B,0x72,0x64,0x68,0x6B,0x64,0x63,0x6B,0x64 };
|
|
||||||
|
|
||||||
/* Fall Guys (PC) update ~2021-11 */ //"p@4_ih*srN:UJk&8"
|
|
||||||
static const uint8_t key_fg1[] = { 0x70,0x40,0x34,0x5F,0x69,0x68,0x2A,0x73,0x72,0x4E,0x3A,0x55,0x4A,0x6B,0x26,0x38 };
|
|
||||||
|
|
||||||
/* Fall Guys (PC) update ~2022-07 */ //",&.XZ8]fLu%caPF+"
|
|
||||||
static const uint8_t key_fg2[] = { 0x2c,0x26,0x2e,0x58,0x5a,0x38,0x5d,0x66,0x4c,0x75,0x25,0x63,0x61,0x50,0x46,0x2b };
|
|
||||||
|
|
||||||
/* Achilles: Legends Untold (PC) */ //"Achilles_0_15_DpG"
|
|
||||||
static const uint8_t key_alu[] = { 0x41,0x63,0x68,0x69,0x6C,0x6C,0x65,0x73,0x5F,0x30,0x5F,0x31,0x35,0x5F,0x44,0x70,0x47 };
|
|
||||||
|
|
||||||
/* Cult of the Lamb Demo (PC) */ //"4FB8CC894515617939F4E1B7D50972D27213B8E6"
|
|
||||||
static const uint8_t key_col[] = { 0x34,0x46,0x42,0x38,0x43,0x43,0x38,0x39,0x34,0x35,0x31,0x35,0x36,0x31,0x37,0x39,0x33,0x39,0x46,0x34,0x45,0x31,0x42,0x37,0x44,0x35,0x30,0x39,0x37,0x32,0x44,0x32,0x37,0x32,0x31,0x33,0x42,0x38,0x45,0x36 };
|
|
||||||
|
|
||||||
// Unknown:
|
// Unknown:
|
||||||
// - Battle: Los Angeles
|
// - Battle: Los Angeles
|
||||||
// - Guitar Hero: Warriors of Rock, DJ hero FSB
|
// - Guitar Hero: Warriors of Rock, DJ hero FSB
|
||||||
@ -102,70 +13,62 @@ static const uint8_t key_col[] = { 0x34,0x46,0x42,0x38,0x43,0x43,0x38,0x39,0x34,
|
|||||||
// - Gas Guzzlers: Combat Carnage (PC?) "C5FA83EA64B34EC2BFE" hex or text? [FSB5]
|
// - Gas Guzzlers: Combat Carnage (PC?) "C5FA83EA64B34EC2BFE" hex or text? [FSB5]
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int is_fsb5; /* FSB5 or FSB4/3*/
|
uint8_t flags;
|
||||||
int is_alt; /* alt XOR mode (seemingly not tied to FSB version or anything) */
|
const char* key;
|
||||||
size_t fsbkey_size;
|
size_t key_size; /* precalc'd for speed */
|
||||||
const uint8_t* fsbkey;
|
|
||||||
} fsbkey_info;
|
} fsbkey_info;
|
||||||
|
|
||||||
|
#define FLAG_FSB4 (1 << 0) /* key is valid for FSB4/3 */
|
||||||
|
#define FLAG_FSB5 (1 << 1) /* key is valid for FSB5 */
|
||||||
|
#define FLAG_STD (1 << 2) /* regular XOR mode */
|
||||||
|
#define FLAG_ALT (1 << 3) /* alt XOR mode (seemingly not tied to FSB version or anything, maybe wrong key) */
|
||||||
|
|
||||||
|
#define MODE_FSB4_STD (FLAG_FSB4 | FLAG_STD)
|
||||||
|
#define MODE_FSB4_ALT (FLAG_FSB4 | FLAG_ALT)
|
||||||
|
#define MODE_FSB4_ALL (FLAG_FSB4 | FLAG_ALT)
|
||||||
|
#define MODE_FSB5_STD (FLAG_FSB5 | FLAG_STD)
|
||||||
|
#define MODE_FSB5_ALT (FLAG_FSB5 | FLAG_STD)
|
||||||
|
#define MODE_FSB5_ALL (FLAG_FSB5 | FLAG_STD | FLAG_ALT)
|
||||||
|
#define MODE_FSBS_STD (FLAG_FSB4 | FLAG_FSB5 | FLAG_STD)
|
||||||
|
#define MODE_FSBS_ALL (FLAG_FSB4 | FLAG_FSB5 | FLAG_STD | FLAG_ALT)
|
||||||
|
|
||||||
|
/* ugly macro for string + precomputed len (removing string's extra NULL)*/
|
||||||
|
#define FSBKEY_ADD(key) key, sizeof(key) - 1
|
||||||
|
|
||||||
static const fsbkey_info fsbkey_list[] = {
|
static const fsbkey_info fsbkey_list[] = {
|
||||||
{ 0,0, sizeof(key_dj2),key_dj2 },
|
{ MODE_FSBS_STD, FSBKEY_ADD("DFm3t4lFTW") }, // Double Fine Productions: Brutal Legend, Massive Chalice, etc (multi)
|
||||||
{ 0,0, sizeof(key_dfp),key_dfp },//FSB4
|
{ MODE_FSB4_STD, FSBKEY_ADD("nos71RiT") }, // DJ Hero 2 (X360)
|
||||||
{ 1,0, sizeof(key_dfp),key_dfp },//FSB5
|
{ MODE_FSB5_STD, FSBKEY_ADD("H$#FJa%7gRZZOlxLiN50&g5Q") }, // N++ (PC?)
|
||||||
{ 1,0, sizeof(key_npp),key_npp },//FSB5
|
{ MODE_FSB5_STD, FSBKEY_ADD("sTOoeJXI2LjK8jBMOk8h5IDRNZl3jq3I") }, // Slightly Mad Studios: Project CARS (PC?), World of Speed (PC)
|
||||||
{ 1,0, sizeof(key_sms),key_sms },//FSB5
|
{ MODE_FSB5_STD, FSBKEY_ADD("%lAn2{Pi*Lhw3T}@7*!kV=?qS$@iNlJ") }, // Ghost in the Shell: First Assault (PC)
|
||||||
{ 1,0, sizeof(key_gfs),key_gfs },//FSB5
|
{ MODE_FSB5_STD, FSBKEY_ADD("1^7%82#&5$~/8sz") }, // RevHeadz Engine Sounds (Mobile)
|
||||||
{ 1,0, sizeof(key_rev),key_rev },//FSB5
|
{ MODE_FSB5_ALL, FSBKEY_ADD("FDPrVuT4fAFvdHJYAgyMzRF4EcBAnKg") }, // Dark Souls 3 (PC) [untested]
|
||||||
{ 1,0, sizeof(key_ds3),key_ds3 },//untested
|
{ MODE_FSB4_ALL, FSBKEY_ADD("p&oACY^c4LK5C2v^x5nIO6kg5vNH$tlj") }, // Need for Speed Shift 2 Unleashed (PC demo?)[untested]
|
||||||
{ 1,1, sizeof(key_ds3),key_ds3 },
|
{ MODE_FSB5_STD, FSBKEY_ADD("996164B5FC0F402983F61F220BB51DC6") }, // Mortal Kombat X/XL (PC)
|
||||||
{ 1,0, sizeof(key_mkx),key_mkx },//FSB5
|
{ MODE_FSB5_STD, FSBKEY_ADD("logicsounddesignmwsdev") }, // Mirror War: Reincarnation of Holiness (PC)
|
||||||
{ 0,0, sizeof(key_xxc),key_xxc },//untested
|
{ MODE_FSBS_ALL, FSBKEY_ADD("gat@tcqs2010") }, // Xian Xia Chuan (PC) [untested]
|
||||||
{ 0,1, sizeof(key_xxc),key_xxc },//untested
|
{ MODE_FSBS_ALL, FSBKEY_ADD("j1$Mk0Libg3#apEr42mo") }, // Critter Crunch (PC), Superbrothers: Sword & Sworcery (PC) [untested]
|
||||||
{ 1,0, sizeof(key_xxc),key_xxc },//untested
|
{ MODE_FSBS_ALL, FSBKEY_ADD("@kdj43nKDN^k*kj3ndf02hd95nsl(NJG") }, // Cyphers [untested]
|
||||||
{ 1,1, sizeof(key_xxc),key_xxc },//untested
|
{ MODE_FSBS_ALL, FSBKEY_ADD("Xiayuwu69252.Sonicli81223#$*@*0") }, // Xuan Dou Zhi Wang / King of Combat [untested]
|
||||||
{ 1,0, sizeof(key_mwr),key_mwr },//FSB5
|
{ MODE_FSBS_ALL, FSBKEY_ADD("kri_tika_5050_") }, // Ji Feng Zhi Ren / Kritika Online [untested]
|
||||||
{ 0,0, sizeof(key_n2u),key_n2u },//untested
|
{ MODE_FSBS_ALL, FSBKEY_ADD("mint78run52") }, // Invisible Inc. (PC?) [untested]
|
||||||
{ 0,1, sizeof(key_n2u),key_n2u },//untested
|
{ MODE_FSBS_ALL, FSBKEY_ADD("5atu6w4zaw") }, // Guitar Hero 3 [untested]
|
||||||
{ 0,0, sizeof(key_ccr),key_ccr },//untested
|
{ MODE_FSBS_ALL, FSBKEY_ADD("B2A7BB00") }, // Supreme Commander 2 [untested]
|
||||||
{ 0,1, sizeof(key_ccr),key_ccr },//untested
|
{ MODE_FSB4_STD, FSBKEY_ADD("ghfxhslrghfxhslr") }, // Cookie Run: Ovenbreak
|
||||||
{ 1,0, sizeof(key_ccr),key_ccr },//untested
|
{ MODE_FSB4_ALT, FSBKEY_ADD("truck/impact/carbody") },// Monster Jam (PS2) [FSB3]
|
||||||
{ 1,1, sizeof(key_ccr),key_ccr },//untested
|
{ MODE_FSB4_ALT, FSBKEY_ADD("\xFC\xF9\xE4\xB3\xF5\x57\x5C\xA5\xAC\x13\xEC\x4A\x43\x19\x58\xEB\x4E\xF3\x84\x0B\x8B\x78\xFA\xFD\xBB\x18\x46\x7E\x31\xFB\xD0") },
|
||||||
{ 0,0, sizeof(key_cyp),key_cyp },//untested
|
{ MODE_FSB4_ALT, FSBKEY_ADD("\x8C\xFA\xF3\x14\xB1\x53\xDA\xAB\x2B\x82\x6B\xD5\x55\x16\xCF\x01\x90\x20\x28\x14\xB1\x53\xD8") },
|
||||||
{ 0,1, sizeof(key_cyp),key_cyp },//untested
|
{ MODE_FSB5_STD, FSBKEY_ADD("G0KTrWjS9syqF7vVD6RaVXlFD91gMgkC") }, // Sekiro: Shadows Die Twice (PC)
|
||||||
{ 1,0, sizeof(key_cyp),key_cyp },//untested
|
{ MODE_FSB5_STD, FSBKEY_ADD("BasicEncryptionKey") }, // SCP: Unity (PC)
|
||||||
{ 1,1, sizeof(key_cyp),key_cyp },//untested
|
{ MODE_FSB5_STD, FSBKEY_ADD("FXnTffGJ9LS855Gc") }, // Worms Rumble Beta (PC)
|
||||||
{ 0,0, sizeof(key_xdz),key_xdz },//untested
|
{ MODE_FSB4_STD, FSBKEY_ADD("qjvkeoqkrdhkdckd") }, // Bubble Fighter (PC)
|
||||||
{ 0,1, sizeof(key_xdz),key_xdz },//untested
|
{ MODE_FSB5_STD, FSBKEY_ADD("p@4_ih*srN:UJk&8") }, // Fall Guys (PC) update ~2021-11
|
||||||
{ 1,0, sizeof(key_xdz),key_xdz },//untested
|
{ MODE_FSB5_STD, FSBKEY_ADD(",&.XZ8]fLu%caPF+") }, // Fall Guys (PC) update ~2022-07
|
||||||
{ 1,1, sizeof(key_xdz),key_xdz },//untested
|
{ MODE_FSB5_STD, FSBKEY_ADD("Achilles_0_15_DpG") }, // Achilles: Legends Untold (PC)
|
||||||
{ 0,0, sizeof(key_jzz),key_jzz },//untested
|
{ MODE_FSB5_STD, FSBKEY_ADD("4FB8CC894515617939F4E1B7D50972D27213B8E6") }, // Cult of the Lamb Demo (PC)
|
||||||
{ 0,1, sizeof(key_jzz),key_jzz },//untested
|
{ MODE_FSB5_STD, FSBKEY_ADD("X3EK%Bbga-%Y9HZZ%gkc*C512*$$DhRxWTGgjUG@=rUD") }, // Signalis (PC)
|
||||||
{ 1,0, sizeof(key_jzz),key_jzz },//untested
|
{ MODE_FSB5_STD, FSBKEY_ADD("281ad163160cfc16f9a22c6755a64fad") }, // Ash Echoes beta (Android)
|
||||||
{ 1,1, sizeof(key_jzz),key_jzz },//untested
|
|
||||||
{ 0,0, sizeof(key_inv),key_inv },//untested
|
|
||||||
{ 0,1, sizeof(key_inv),key_inv },//untested
|
|
||||||
{ 1,0, sizeof(key_inv),key_inv },//untested
|
|
||||||
{ 1,1, sizeof(key_inv),key_inv },//untested
|
|
||||||
{ 0,0, sizeof(key_gh3),key_gh3 },//untested
|
|
||||||
{ 0,1, sizeof(key_gh3),key_gh3 },//untested
|
|
||||||
{ 1,0, sizeof(key_gh3),key_gh3 },//untested
|
|
||||||
{ 1,1, sizeof(key_gh3),key_gh3 },//untested
|
|
||||||
{ 0,0, sizeof(key_sc2),key_sc2 },//untested
|
|
||||||
{ 0,1, sizeof(key_sc2),key_sc2 },//untested
|
|
||||||
{ 1,0, sizeof(key_sc2),key_sc2 },//untested
|
|
||||||
{ 1,1, sizeof(key_sc2),key_sc2 },//untested
|
|
||||||
{ 1,0, sizeof(key_cro),key_cro },
|
|
||||||
{ 0,1, sizeof(key_mtj),key_mtj },// FSB3
|
|
||||||
{ 0,1, sizeof(key_gh5),key_gh5 },// FSB4
|
|
||||||
{ 1,0, sizeof(key_sek),key_sek },// FSB5
|
|
||||||
{ 1,0, sizeof(key_scp),key_scp },// FSB5
|
|
||||||
{ 0,1, sizeof(key_ghm),key_ghm },// FSB4
|
|
||||||
{ 1,0, sizeof(key_wrb),key_wrb },// FSB5
|
|
||||||
{ 0,0, sizeof(key_bbf),key_bbf },// FSB4
|
|
||||||
{ 1,0, sizeof(key_fg1),key_fg1 },// FSB5
|
|
||||||
{ 1,0, sizeof(key_fg2),key_fg2 },// FSB5
|
|
||||||
{ 1,0, sizeof(key_alu),key_alu },// FSB5
|
|
||||||
{ 1,0, sizeof(key_col),key_col },// FSB5
|
|
||||||
};
|
};
|
||||||
static const int fsbkey_list_count = sizeof(fsbkey_list) / sizeof(fsbkey_list[0]);
|
static const int fsbkey_list_count = sizeof(fsbkey_list) / sizeof(fsbkey_list[0]);
|
||||||
|
|
||||||
|
@ -2,9 +2,9 @@
|
|||||||
#include "../coding/coding.h"
|
#include "../coding/coding.h"
|
||||||
|
|
||||||
typedef enum { XMA2, ATRAC9 } gtd_codec;
|
typedef enum { XMA2, ATRAC9 } gtd_codec;
|
||||||
|
//TODO rename gtd to ghs
|
||||||
/* GTD - from Hexadrive's HexaEngine [Knights Contract (X360/PS3), Valhalla Knights 3 (Vita)] */
|
/* GHS - Hexadrive's HexaEngine games [Knights Contract (X360), Valhalla Knights 3 (Vita)] */
|
||||||
VGMSTREAM* init_vgmstream_gtd(STREAMFILE* sf) {
|
VGMSTREAM* init_vgmstream_ghs(STREAMFILE* sf) {
|
||||||
VGMSTREAM* vgmstream = NULL;
|
VGMSTREAM* vgmstream = NULL;
|
||||||
off_t start_offset, chunk_offset, stpr_offset, name_offset = 0, loop_start_offset, loop_end_offset;
|
off_t start_offset, chunk_offset, stpr_offset, name_offset = 0, loop_start_offset, loop_end_offset;
|
||||||
size_t data_size, chunk_size;
|
size_t data_size, chunk_size;
|
||||||
@ -36,7 +36,8 @@ VGMSTREAM* init_vgmstream_gtd(STREAMFILE* sf) {
|
|||||||
/* 0x34(18): null, 0x54(4): seek table offset, 0x58(4): seek table size, 0x5c(8): null, 0x64: seek table */
|
/* 0x34(18): null, 0x54(4): seek table offset, 0x58(4): seek table size, 0x5c(8): null, 0x64: seek table */
|
||||||
|
|
||||||
stpr_offset = read_32bitBE(chunk_offset+0x54,sf) + read_32bitBE(chunk_offset+0x58,sf);
|
stpr_offset = read_32bitBE(chunk_offset+0x54,sf) + read_32bitBE(chunk_offset+0x58,sf);
|
||||||
if (read_32bitBE(stpr_offset,sf) == 0x53545052) { /* "STPR" */
|
if (is_id32be(stpr_offset,sf, "STPR")) {
|
||||||
|
/* SRPR encases the original "S_P_STH" header (no data) */
|
||||||
name_offset = stpr_offset + 0xB8; /* there are offsets fields but seems to work */
|
name_offset = stpr_offset + 0xB8; /* there are offsets fields but seems to work */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,14 +56,14 @@ VGMSTREAM* init_vgmstream_gtd(STREAMFILE* sf) {
|
|||||||
/* 0x18-0x28: fixed/unknown values */
|
/* 0x18-0x28: fixed/unknown values */
|
||||||
|
|
||||||
stpr_offset = 0x2c;
|
stpr_offset = 0x2c;
|
||||||
if (read_32bitBE(stpr_offset,sf) == 0x53545052) { /* "STPR" */
|
if (is_id32be(stpr_offset,sf, "STPR")) {
|
||||||
|
/* STPR encases the original "S_P_STH" header (no data) */
|
||||||
name_offset = stpr_offset + 0xE8; /* there are offsets fields but seems to work */
|
name_offset = stpr_offset + 0xE8; /* there are offsets fields but seems to work */
|
||||||
}
|
}
|
||||||
|
|
||||||
codec = ATRAC9;
|
codec = ATRAC9;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* there is a PS3 variation with MSF inside */
|
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,7 +76,7 @@ VGMSTREAM* init_vgmstream_gtd(STREAMFILE* sf) {
|
|||||||
vgmstream->sample_rate = sample_rate;
|
vgmstream->sample_rate = sample_rate;
|
||||||
vgmstream->loop_start_sample = loop_start_sample;
|
vgmstream->loop_start_sample = loop_start_sample;
|
||||||
vgmstream->loop_end_sample = loop_end_sample;
|
vgmstream->loop_end_sample = loop_end_sample;
|
||||||
vgmstream->meta_type = meta_GTD;
|
vgmstream->meta_type = meta_GHS;
|
||||||
if (name_offset) //encoding is Shift-Jis in some PSV files
|
if (name_offset) //encoding is Shift-Jis in some PSV files
|
||||||
read_string(vgmstream->stream_name,STREAM_NAME_SIZE, name_offset,sf);
|
read_string(vgmstream->stream_name,STREAM_NAME_SIZE, name_offset,sf);
|
||||||
|
|
||||||
@ -125,3 +126,38 @@ fail:
|
|||||||
close_vgmstream(vgmstream);
|
close_vgmstream(vgmstream);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* S_P_STH - Hexadrive's HexaEngine games [Knights Contract (PS3)] */
|
||||||
|
VGMSTREAM* init_vgmstream_s_p_sth(STREAMFILE* sf) {
|
||||||
|
VGMSTREAM* vgmstream = NULL;
|
||||||
|
STREAMFILE* temp_sf = NULL;
|
||||||
|
uint32_t subfile_offset, subfile_size, name_offset;
|
||||||
|
|
||||||
|
|
||||||
|
/* checks */
|
||||||
|
if (!is_id64be(0x00,sf,"S_P_STH\x01"))
|
||||||
|
goto fail;
|
||||||
|
if (!check_extensions(sf,"gtd"))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
subfile_offset = read_u32be(0x08, sf);
|
||||||
|
subfile_size = get_streamfile_size(sf) - subfile_offset;
|
||||||
|
|
||||||
|
temp_sf = setup_subfile_streamfile(sf, subfile_offset, subfile_size, "msf");
|
||||||
|
if (!temp_sf) goto fail;
|
||||||
|
|
||||||
|
vgmstream = init_vgmstream_msf(temp_sf);
|
||||||
|
if (!vgmstream) goto fail;
|
||||||
|
|
||||||
|
vgmstream->meta_type = meta_GHS;
|
||||||
|
name_offset = 0xB0; /* there are offsets fields but seems to work */
|
||||||
|
read_string(vgmstream->stream_name, STREAM_NAME_SIZE, name_offset, sf);
|
||||||
|
|
||||||
|
close_streamfile(temp_sf);
|
||||||
|
return vgmstream;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
close_streamfile(temp_sf);
|
||||||
|
close_vgmstream(vgmstream);
|
||||||
|
return NULL;
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
#ifndef _HCA_KEYS_H_
|
#ifndef _HCA_KEYS_H_
|
||||||
#define _HCA_KEYS_H_
|
#define _HCA_KEYS_H_
|
||||||
|
#include <stdint.h>
|
||||||
#include "hca_keys_awb.h"
|
//#include "hca_keys_awb.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint64_t key; /* hca key or seed ('user') key */
|
uint64_t key; /* hca key or seed ('user') key */
|
||||||
@ -1100,6 +1100,9 @@ static const hcakey_info hcakey_list[] = {
|
|||||||
|
|
||||||
// Sin Chronicle (Android)
|
// Sin Chronicle (Android)
|
||||||
{4385672148314579020}, // 3CDD0995259D604C
|
{4385672148314579020}, // 3CDD0995259D604C
|
||||||
|
|
||||||
|
// The Eminence in Shadow: Master of Garden (Android)
|
||||||
|
{8115775984160473168}, // 70A1074224880050
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif/*_HCA_KEYS_H_*/
|
#endif/*_HCA_KEYS_H_*/
|
||||||
|
109
src/meta/ktsr.c
109
src/meta/ktsr.c
@ -2,7 +2,7 @@
|
|||||||
#include "../coding/coding.h"
|
#include "../coding/coding.h"
|
||||||
#include "../layout/layout.h"
|
#include "../layout/layout.h"
|
||||||
|
|
||||||
typedef enum { NONE, MSADPCM, DSP, GCADPCM, ATRAC9, RIFF_ATRAC9, KOVS, /*KNS*/ } ktsr_codec;
|
typedef enum { NONE, MSADPCM, DSP, GCADPCM, ATRAC9, RIFF_ATRAC9, KOVS, KTSS, } ktsr_codec;
|
||||||
|
|
||||||
#define MAX_CHANNELS 8
|
#define MAX_CHANNELS 8
|
||||||
|
|
||||||
@ -33,9 +33,9 @@ typedef struct {
|
|||||||
|
|
||||||
static int parse_ktsr(ktsr_header* ktsr, STREAMFILE* sf);
|
static int parse_ktsr(ktsr_header* ktsr, STREAMFILE* sf);
|
||||||
static layered_layout_data* build_layered_atrac9(ktsr_header* ktsr, STREAMFILE *sf, uint32_t config_data);
|
static layered_layout_data* build_layered_atrac9(ktsr_header* ktsr, STREAMFILE *sf, uint32_t config_data);
|
||||||
|
static VGMSTREAM* init_vgmstream_ktsr_sub(STREAMFILE* sf_b, ktsr_header* ktsr, VGMSTREAM* (*init_vgmstream)(STREAMFILE* sf), const char* ext);
|
||||||
|
|
||||||
|
/* KTSR - Koei Tecmo sound resource container */
|
||||||
/* KTSR - Koei Tecmo sound resource countainer */
|
|
||||||
VGMSTREAM* init_vgmstream_ktsr(STREAMFILE* sf) {
|
VGMSTREAM* init_vgmstream_ktsr(STREAMFILE* sf) {
|
||||||
VGMSTREAM* vgmstream = NULL;
|
VGMSTREAM* vgmstream = NULL;
|
||||||
STREAMFILE* sf_b = NULL;
|
STREAMFILE* sf_b = NULL;
|
||||||
@ -76,6 +76,26 @@ VGMSTREAM* init_vgmstream_ktsr(STREAMFILE* sf) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* subfiles */
|
||||||
|
{
|
||||||
|
VGMSTREAM* (*init_vgmstream)(STREAMFILE* sf) = NULL;
|
||||||
|
const char* ext;
|
||||||
|
switch(ktsr.codec) {
|
||||||
|
case RIFF_ATRAC9: init_vgmstream = init_vgmstream_riff; ext = "at9"; break;
|
||||||
|
case KOVS: init_vgmstream = init_vgmstream_ogg_vorbis; ext = "kvs"; break;
|
||||||
|
case KTSS: init_vgmstream = init_vgmstream_ktss; ext = "ktss"; break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (init_vgmstream) {
|
||||||
|
vgmstream = init_vgmstream_ktsr_sub(sf_b, &ktsr, init_vgmstream, ext);
|
||||||
|
if (!vgmstream) goto fail;
|
||||||
|
|
||||||
|
if (sf_b != sf) close_streamfile(sf_b);
|
||||||
|
return vgmstream;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* build the VGMSTREAM */
|
/* build the VGMSTREAM */
|
||||||
vgmstream = allocate_vgmstream(ktsr.channels, ktsr.loop_flag);
|
vgmstream = allocate_vgmstream(ktsr.channels, ktsr.loop_flag);
|
||||||
if (!vgmstream) goto fail;
|
if (!vgmstream) goto fail;
|
||||||
@ -125,49 +145,6 @@ VGMSTREAM* init_vgmstream_ktsr(STREAMFILE* sf) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
case RIFF_ATRAC9: {
|
|
||||||
VGMSTREAM* riff_vgmstream = NULL; //TODO: meh
|
|
||||||
STREAMFILE* temp_sf = setup_subfile_streamfile(sf_b, ktsr.stream_offsets[0], ktsr.stream_sizes[0], "at9");
|
|
||||||
if (!temp_sf) goto fail;
|
|
||||||
|
|
||||||
riff_vgmstream = init_vgmstream_riff(temp_sf);
|
|
||||||
close_streamfile(temp_sf);
|
|
||||||
if (!riff_vgmstream) goto fail;
|
|
||||||
|
|
||||||
riff_vgmstream->stream_size = vgmstream->stream_size;
|
|
||||||
riff_vgmstream->num_streams = vgmstream->num_streams;
|
|
||||||
riff_vgmstream->channel_layout = vgmstream->channel_layout;
|
|
||||||
|
|
||||||
strcpy(riff_vgmstream->stream_name, vgmstream->stream_name);
|
|
||||||
|
|
||||||
close_vgmstream(vgmstream);
|
|
||||||
if (sf_b != sf) close_streamfile(sf_b);
|
|
||||||
return riff_vgmstream;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef VGM_USE_VORBIS
|
|
||||||
case KOVS: {
|
|
||||||
VGMSTREAM* ogg_vgmstream = NULL; //TODO: meh
|
|
||||||
STREAMFILE* temp_sf = setup_subfile_streamfile(sf_b, ktsr.stream_offsets[0], ktsr.stream_sizes[0], "kvs");
|
|
||||||
if (!temp_sf) goto fail;
|
|
||||||
|
|
||||||
ogg_vgmstream = init_vgmstream_ogg_vorbis(temp_sf);
|
|
||||||
close_streamfile(temp_sf);
|
|
||||||
if (!ogg_vgmstream) goto fail;
|
|
||||||
|
|
||||||
ogg_vgmstream->stream_size = vgmstream->stream_size;
|
|
||||||
ogg_vgmstream->num_streams = vgmstream->num_streams;
|
|
||||||
ogg_vgmstream->channel_layout = vgmstream->channel_layout;
|
|
||||||
/* loops look shared */
|
|
||||||
strcpy(ogg_vgmstream->stream_name, vgmstream->stream_name);
|
|
||||||
|
|
||||||
close_vgmstream(vgmstream);
|
|
||||||
if (sf_b != sf) close_streamfile(sf_b);
|
|
||||||
return ogg_vgmstream;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
@ -193,6 +170,26 @@ fail:
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO improve, unity with other metas that do similar stuff
|
||||||
|
static VGMSTREAM* init_vgmstream_ktsr_sub(STREAMFILE* sf_b, ktsr_header* ktsr, VGMSTREAM* (*init_vgmstream)(STREAMFILE* sf), const char* ext) {
|
||||||
|
VGMSTREAM* sub_vgmstream = NULL;
|
||||||
|
STREAMFILE* temp_sf = setup_subfile_streamfile(sf_b, ktsr->stream_offsets[0], ktsr->stream_sizes[0], ext);
|
||||||
|
if (!temp_sf) return NULL;
|
||||||
|
|
||||||
|
sub_vgmstream = init_vgmstream(temp_sf);
|
||||||
|
close_streamfile(temp_sf);
|
||||||
|
if (!sub_vgmstream) return NULL;
|
||||||
|
|
||||||
|
sub_vgmstream->stream_size = ktsr->stream_sizes[0];
|
||||||
|
sub_vgmstream->num_streams = ktsr->total_subsongs;
|
||||||
|
sub_vgmstream->channel_layout = ktsr->channel_layout;
|
||||||
|
|
||||||
|
strcpy(sub_vgmstream->stream_name, ktsr->name);
|
||||||
|
|
||||||
|
return sub_vgmstream;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static layered_layout_data* build_layered_atrac9(ktsr_header* ktsr, STREAMFILE* sf, uint32_t config_data) {
|
static layered_layout_data* build_layered_atrac9(ktsr_header* ktsr, STREAMFILE* sf, uint32_t config_data) {
|
||||||
STREAMFILE* temp_sf = NULL;
|
STREAMFILE* temp_sf = NULL;
|
||||||
layered_layout_data* data = NULL;
|
layered_layout_data* data = NULL;
|
||||||
@ -256,12 +253,12 @@ static int parse_codec(ktsr_header* ktsr) {
|
|||||||
case 0x01: /* PC */
|
case 0x01: /* PC */
|
||||||
if (ktsr->is_external) {
|
if (ktsr->is_external) {
|
||||||
if (ktsr->format == 0x0005)
|
if (ktsr->format == 0x0005)
|
||||||
ktsr->codec = KOVS;
|
ktsr->codec = KOVS; // Atelier Ryza (PC)
|
||||||
else
|
else
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
else if (ktsr->format == 0x0000) {
|
else if (ktsr->format == 0x0000) {
|
||||||
ktsr->codec = MSADPCM;
|
ktsr->codec = MSADPCM; // Warrior Orochi 4 (PC)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
goto fail;
|
goto fail;
|
||||||
@ -271,21 +268,25 @@ static int parse_codec(ktsr_header* ktsr) {
|
|||||||
case 0x03: /* PS4/VITA */
|
case 0x03: /* PS4/VITA */
|
||||||
if (ktsr->is_external) {
|
if (ktsr->is_external) {
|
||||||
if (ktsr->format == 0x1001)
|
if (ktsr->format == 0x1001)
|
||||||
ktsr->codec = RIFF_ATRAC9;
|
ktsr->codec = RIFF_ATRAC9; // Nioh (PS4)
|
||||||
else
|
else
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
else if (ktsr->format == 0x0001)
|
else if (ktsr->format == 0x0001)
|
||||||
ktsr->codec = ATRAC9;
|
ktsr->codec = ATRAC9; // Attack on Titan: Wings of Freedom (Vita)
|
||||||
else
|
else
|
||||||
goto fail;
|
goto fail;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x04: /* Switch */
|
case 0x04: /* Switch */
|
||||||
if (ktsr->is_external)
|
if (ktsr->is_external) {
|
||||||
goto fail; /* KTSS? */
|
if (ktsr->format == 0x0005)
|
||||||
|
ktsr->codec = KTSS; // [Ultra Kaiju Monster Rancher (Switch)]
|
||||||
|
else
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
else if (ktsr->format == 0x0000)
|
else if (ktsr->format == 0x0000)
|
||||||
ktsr->codec = DSP;
|
ktsr->codec = DSP; // Fire Emblem: Three Houses (Switch)
|
||||||
else
|
else
|
||||||
goto fail;
|
goto fail;
|
||||||
break;
|
break;
|
||||||
@ -296,7 +297,7 @@ static int parse_codec(ktsr_header* ktsr) {
|
|||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
fail:
|
fail:
|
||||||
VGM_LOG("ktsr: unknown codec combo: ext=%x, fmt=%x, ptf=%x\n", ktsr->is_external, ktsr->format, ktsr->platform);
|
VGM_LOG("ktsr: unknown codec combo: external=%x, format=%x, platform=%x\n", ktsr->is_external, ktsr->format, ktsr->platform);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -596,7 +596,8 @@ VGMSTREAM * init_vgmstream_ogl(STREAMFILE *streamFile);
|
|||||||
|
|
||||||
VGMSTREAM * init_vgmstream_mc3(STREAMFILE *streamFile);
|
VGMSTREAM * init_vgmstream_mc3(STREAMFILE *streamFile);
|
||||||
|
|
||||||
VGMSTREAM * init_vgmstream_gtd(STREAMFILE *streamFile);
|
VGMSTREAM* init_vgmstream_ghs(STREAMFILE* sf);
|
||||||
|
VGMSTREAM* init_vgmstream_s_p_sth(STREAMFILE* sf);
|
||||||
|
|
||||||
VGMSTREAM* init_vgmstream_aac_triace(STREAMFILE* sf);
|
VGMSTREAM* init_vgmstream_aac_triace(STREAMFILE* sf);
|
||||||
|
|
||||||
|
@ -294,7 +294,7 @@ VGMSTREAM* (*init_vgmstream_functions[])(STREAMFILE* sf) = {
|
|||||||
init_vgmstream_sxd,
|
init_vgmstream_sxd,
|
||||||
init_vgmstream_ogl,
|
init_vgmstream_ogl,
|
||||||
init_vgmstream_mc3,
|
init_vgmstream_mc3,
|
||||||
init_vgmstream_gtd,
|
init_vgmstream_ghs,
|
||||||
init_vgmstream_aac_triace,
|
init_vgmstream_aac_triace,
|
||||||
init_vgmstream_va3,
|
init_vgmstream_va3,
|
||||||
init_vgmstream_mta2,
|
init_vgmstream_mta2,
|
||||||
@ -524,6 +524,7 @@ VGMSTREAM* (*init_vgmstream_functions[])(STREAMFILE* sf) = {
|
|||||||
init_vgmstream_vab,
|
init_vgmstream_vab,
|
||||||
init_vgmstream_bigrp,
|
init_vgmstream_bigrp,
|
||||||
init_vgmstream_sscf_encrypted,
|
init_vgmstream_sscf_encrypted,
|
||||||
|
init_vgmstream_s_p_sth,
|
||||||
|
|
||||||
/* lower priority metas (no clean header identity, somewhat ambiguous, or need extension/companion file to identify) */
|
/* lower priority metas (no clean header identity, somewhat ambiguous, or need extension/companion file to identify) */
|
||||||
init_vgmstream_scd_pcm,
|
init_vgmstream_scd_pcm,
|
||||||
|
@ -593,7 +593,7 @@ typedef enum {
|
|||||||
meta_SXD, /* Sony SXD (Gravity Rush, Freedom Wars PSV) */
|
meta_SXD, /* Sony SXD (Gravity Rush, Freedom Wars PSV) */
|
||||||
meta_OGL, /* Shin'en Wii/WiiU (Jett Rocket (Wii), FAST Racing NEO (WiiU)) */
|
meta_OGL, /* Shin'en Wii/WiiU (Jett Rocket (Wii), FAST Racing NEO (WiiU)) */
|
||||||
meta_MC3, /* Paradigm games (T3 PS2, MX Rider PS2, MI: Operation Surma PS2) */
|
meta_MC3, /* Paradigm games (T3 PS2, MX Rider PS2, MI: Operation Surma PS2) */
|
||||||
meta_GTD,
|
meta_GHS,
|
||||||
meta_AAC_TRIACE,
|
meta_AAC_TRIACE,
|
||||||
meta_MTA2,
|
meta_MTA2,
|
||||||
meta_NGC_ULW, /* Burnout 1 (GC only) */
|
meta_NGC_ULW, /* Burnout 1 (GC only) */
|
||||||
|
Loading…
Reference in New Issue
Block a user