If you have an issue with any of our projects. feel free to register.

Commit 2a52dd83 authored by Christopher Snowhill's avatar Christopher Snowhill

Updated VGMStream to r1050-3548-g64ffe5ea

parent d070dffd
......@@ -622,6 +622,7 @@
83F1EE2D245D4FB20076E182 /* imuse_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 83F1EE28245D4FB10076E182 /* imuse_decoder.c */; };
83F1EE2E245D4FB20076E182 /* vadpcm_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 83F1EE2C245D4FB20076E182 /* vadpcm_decoder.c */; };
83F1EE30245D4FC10076E182 /* imuse.c in Sources */ = {isa = PBXBuildFile; fileRef = 83F1EE2F245D4FC10076E182 /* imuse.c */; };
83F2CCE525A5B41600F46FA8 /* acx.c in Sources */ = {isa = PBXBuildFile; fileRef = 83F2CCE125A5B41600F46FA8 /* acx.c */; };
83F5F8831908D0A400C8E65F /* fsb5.c in Sources */ = {isa = PBXBuildFile; fileRef = 83F5F8821908D0A400C8E65F /* fsb5.c */; };
83FBD506235D31F800D35BCD /* riff_ogg_streamfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 83FBD502235D31F700D35BCD /* riff_ogg_streamfile.h */; };
83FC176D23AC58D100E1025F /* xma_ue3.c in Sources */ = {isa = PBXBuildFile; fileRef = 83FC176A23AC58D100E1025F /* xma_ue3.c */; };
......@@ -1363,6 +1364,7 @@
83F1EE28245D4FB10076E182 /* imuse_decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = imuse_decoder.c; sourceTree = "<group>"; };
83F1EE2C245D4FB20076E182 /* vadpcm_decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vadpcm_decoder.c; sourceTree = "<group>"; };
83F1EE2F245D4FC10076E182 /* imuse.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = imuse.c; sourceTree = "<group>"; };
83F2CCE125A5B41600F46FA8 /* acx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = acx.c; sourceTree = "<group>"; };
83F412871E932F9A002E37D0 /* Vorbis.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Vorbis.xcodeproj; path = ../Vorbis/macosx/Vorbis.xcodeproj; sourceTree = "<group>"; };
83F5F8821908D0A400C8E65F /* fsb5.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = fsb5.c; sourceTree = "<group>"; };
83FBD502235D31F700D35BCD /* riff_ogg_streamfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = riff_ogg_streamfile.h; sourceTree = "<group>"; };
......@@ -1685,6 +1687,7 @@
836F6E2A18BDC2180095E648 /* aax.c */,
837CEAD623487E8300E62A4A /* acb.c */,
836F6E2B18BDC2180095E648 /* acm.c */,
83F2CCE125A5B41600F46FA8 /* acx.c */,
83AA7F7A2519C042004C5298 /* adp_konami.c */,
834FE0CF215C79E8000A5D3D /* adpcm_capcom.c */,
836F6E2C18BDC2180095E648 /* ads.c */,
......@@ -2674,6 +2677,7 @@
836F6F9918BDC2190095E648 /* maxis_xa.c in Sources */,
836F702118BDC2190095E648 /* rs03.c in Sources */,
836F6F8818BDC2190095E648 /* fsb.c in Sources */,
83F2CCE525A5B41600F46FA8 /* acx.c in Sources */,
83FC176D23AC58D100E1025F /* xma_ue3.c in Sources */,
836F6FE518BDC2190095E648 /* ps2_lpcm.c in Sources */,
8375737321F9507D00F01AF5 /* oki_decoder.c in Sources */,
......
......@@ -39,6 +39,7 @@ static const char* extension_list[] = {
//"ac3", //common, FFmpeg/not parsed (AC3)
"acb",
"acm",
"acx",
"ad", //txth/reserved [Xenosaga Freaks (PS2)]
"adc", //txth/reserved [Tomb Raider The Last Revelation (DC), Tomb Raider Chronicles (DC)]
"adm",
......
#include "meta.h"
#include "../coding/coding.h"
/* .acx - CRI container [Baroque (SAT), Persona 3 (PS2), THE iDOLM@STER: Live For You (X360)] */
VGMSTREAM* init_vgmstream_acx(STREAMFILE* sf) {
VGMSTREAM* vgmstream = NULL;
STREAMFILE* temp_sf = NULL;
off_t subfile_offset;
size_t subfile_size;
int total_subsongs, target_subsong = sf->stream_index;
/* checks */
if (!check_extensions(sf,"acx"))
goto fail;
if (read_u32be(0x00,sf) != 0x00000000)
goto fail;
/* simple container for sfx and rarely music [Burning Rangers (SAT)],
* mainly used until .csb was introduced */
total_subsongs = read_u32be(0x04,sf);
if (target_subsong == 0) target_subsong = 1;
if (target_subsong < 0 || target_subsong > total_subsongs || total_subsongs < 1) goto fail;
subfile_offset = read_u32be(0x08 + (target_subsong-1) * 0x08 + 0x00,sf);
subfile_size = read_u32be(0x08 + (target_subsong-1) * 0x08 + 0x04,sf);
temp_sf = setup_subfile_streamfile(sf, subfile_offset, subfile_size, "adx");
if (!temp_sf) goto fail;
vgmstream = init_vgmstream_adx(temp_sf);
if (!vgmstream) goto fail;
vgmstream->num_streams = total_subsongs;
close_streamfile(temp_sf);
return vgmstream;
fail:
close_streamfile(temp_sf);
close_vgmstream(vgmstream);
return NULL;
}
......@@ -20,7 +20,7 @@ static const adxkey_info adxkey8_list[] = {
{0x49e1,0x4a57,0x553d, "karaage",0},
/* Blood+ (PS2) [Grasshopper Manufacture] */
{0x5f5d,0x58bd,0x55ed, NULL,0}, // keystring not in ELF?
{0x5f5d,0x58bd,0x55ed, "LOVELOVE",0}, // obfuscated keystring is "KNUDKNUD", adds +1 to chars to get final key
/* Killer7 (PS2) [Grasshopper Manufacture] */
{0x50fb,0x5803,0x5701, "GHM",0},
......@@ -34,14 +34,14 @@ static const adxkey_info adxkey8_list[] = {
/* Phantasy Star Universe (PC), Phantasy Star Universe: Ambition of the Illuminus (PS2) [Sonic Team] */
{0x5deb,0x5f27,0x673f, "3x5k62bg9ptbwy",0},
/* Senko no Ronde [G.rev] */
/* Senko no Ronde Rev.X (X360) [G.rev] */
{0x46d3,0x5ced,0x474d, "ranatus",0},
/* NiGHTS: Journey of Dreams (Wii) [Sonic Team] */
{0x440b,0x6539,0x5723, "sakakit4649",0},
/* unknown source */
{0x586d,0x5d65,0x63eb, NULL,0}, // from guessadx (unique?)
/* The iDOLM@STER: Live For You (X360) [Bandai Namco] (.aix) */
{0x586d,0x5d65,0x63eb, "75_501NO_003B",0},
/* Shuffle! On the Stage (PS2) [Navel] */
{0x4969,0x5deb,0x467f, "SHUF",0},
......@@ -64,8 +64,8 @@ static const adxkey_info adxkey8_list[] = {
/* Soulcalibur IV (PS3) [Namco] */
{0x59ed,0x4679,0x46c9, "SC4Test",0},
/* Senko no Ronde DUO (X360) [G.rev] */
{0x6157,0x6809,0x4045, NULL,0}, // from guessadx
/* Senko no Ronde DUO (X360/AC) [G.rev] */
{0x6157,0x6809,0x4045, "yomesokushitsu",0},
/* Nogizaka Haruka no Himitsu: Cosplay Hajimemashita (PS2) [Vridge] */
{0x45af,0x5f27,0x52b1, "SKFHSIA",0},
......@@ -100,16 +100,16 @@ static const adxkey_info adxkey8_list[] = {
/* Soshite Kono Uchuu ni Kirameku Kimi no Shi XXX (PS2) [Datam Polystar] */
{0x5f5d,0x552b,0x5507, "DATAM-KK2",0},
/* Sakura Taisen: Atsuki Chishio Ni (PS2) [Sega] */
{0x645d,0x6011,0x5c29, NULL,0}, // confirmed unique with guessadx
/* Sakura Taisen: Atsuki Chishio ni (PS2) [Sega] */
{0x645d,0x6011,0x5c29, NULL,0}, // possible key: "[Seq][ADX] illegal cri or libsd status."
/* Sakura Taisen 3 ~Paris wa Moeteiru ka~ (PS2) [Sega] */
{0x62ad,0x4b13,0x5957, NULL,0}, // confirmed unique with guessadx
/* Sakura Taisen Monogatari: Mysterious Paris (PS2) [Sega] */
{0x62ad,0x4b13,0x5957, "inoue4126",0},
/* Sotsugyou 2nd Generation (PS2) [Jinx] */
{0x6305,0x509f,0x4c01, NULL,0}, // First guess from guessadx, other was {0x6307,0x509f,0x2ac5}
/* La Corda d'Oro (PSP) [Koei] */
/* Kin'iro no Corda -La Corda d'Oro- (PSP) [Koei] */
{0x55b7,0x67e5,0x5387, NULL,0}, // keystring not in ELF?
/* Nanatsuiro * Drops Pure!! (PS2) [Media Works] */
......@@ -127,7 +127,7 @@ static const adxkey_info adxkey8_list[] = {
/* Sora no Otoshimono: DokiDoki Summer Vacation (PSP) [Kadokawa Shoten] */
{0x5e75,0x4a89,0x4c61, "funen-gomi",0},
/* Boku wa Koukuu Kanseikan: Airport Hero Naha (PSP) [Sonic Powered] */
/* Boku wa Koukuu Kanseikan: Airport Hero Naha/Narita/Shinchitose/Haneda/Kankuu (PSP) [Sonic Powered] */
{0x64ab,0x5297,0x632f, "sonic",0},
/* Lucky Star: Net Idol Meister (PSP) [Vridge, Kadokawa Shoten] */
......
......@@ -162,7 +162,7 @@ VGMSTREAM* init_vgmstream_awc(STREAMFILE* sf) {
vgmstream->layout_data = build_layered_awc(sf, &awc);
if (!vgmstream->layout_data) goto fail;
vgmstream->layout_type = layout_layered;
vgmstream->coding_type = coding_FFmpeg;
vgmstream->coding_type = coding_VORBIS_custom;
}
else {
vorbis_custom_config cfg = {0};
......
......@@ -4,22 +4,22 @@
/* CSB (Cue Sheet Binary?) - CRI container of memory audio, often together with a .cpk wave bank */
VGMSTREAM * init_vgmstream_csb(STREAMFILE *streamFile) {
VGMSTREAM *vgmstream = NULL;
STREAMFILE *temp_sf = NULL;
VGMSTREAM* init_vgmstream_csb(STREAMFILE* sf) {
VGMSTREAM* vgmstream = NULL;
STREAMFILE* temp_sf = NULL;
off_t subfile_offset;
size_t subfile_size;
utf_context *utf = NULL;
utf_context *utf_sdl = NULL;
int total_subsongs, target_subsong = streamFile->stream_index;
int total_subsongs, target_subsong = sf->stream_index;
uint8_t fmt = 0;
const char *stream_name;
const char* stream_name;
/* checks */
if (!check_extensions(streamFile, "csb"))
if (!check_extensions(sf, "csb"))
goto fail;
if (read_32bitBE(0x00,streamFile) != 0x40555446) /* "@UTF" */
if (!is_id32be(0x00,sf, "@UTF"))
goto fail;
/* .csb is an early, simpler version of .acb+awk (see acb.c) used until ~2013?
......@@ -35,32 +35,41 @@ VGMSTREAM * init_vgmstream_csb(STREAMFILE *streamFile) {
int found = 0;
utf = utf_open(streamFile, table_offset, &rows, &name);
utf = utf_open(sf, table_offset, &rows, &name);
if (!utf) goto fail;
if (strcmp(name, "TBLCSB") != 0)
goto fail;
/* each TBLCSB row has a name and subtable with actual things:
* - INFO (TBL_INFO): table type/version
* - INFO (TBL_INFO): table type/version, rarely ommited [Nights: Journey of Dreams (Wii)-some csb]
* - CUE (TBLCUE): base cues
* - SYNTH (TBLSYN): cue configs
* - SOUND_ELEMENT (TBLSDL): audio info/data (usually AAX)
* - ISAAC (TBLISC): 3D config
* - VOICE_LIMIT_GROUP (TBLVLG): system info?
* Subtable can be empty but must still appear (0 rows).
* Subtable can be empty but still appear (0 rows).
*/
sdl_row = 3; /* should use fixed order */
/* get SOUND_ELEMENT and table */
if (!utf_query_string(utf, sdl_row, "name", &row_name) || strcmp(row_name, "SOUND_ELEMENT") != 0)
sdl_row = -1;
for (i = 0; i < rows; i++) {
if (!utf_query_string(utf, i, "name", &row_name))
goto fail;
if (strcmp(row_name, "SOUND_ELEMENT") == 0) {
sdl_row = i; /* usually 2 or 3 */
break;
}
}
if (sdl_row < 0)
goto fail;
/* read SOUND_ELEMENT table */
if (!utf_query_u8(utf, sdl_row, "ttype", &ttype) || ttype != 4)
goto fail;
if (!utf_query_data(utf, sdl_row, "utf", &sdl_offset, &sdl_size))
goto fail;
utf_sdl = utf_open(streamFile, sdl_offset, &sdl_rows, &sdl_name);
utf_sdl = utf_open(sf, sdl_offset, &sdl_rows, &sdl_name);
if (!utf_sdl) goto fail;
if (strcmp(sdl_name, "TBLSDL") != 0)
......@@ -109,7 +118,7 @@ VGMSTREAM * init_vgmstream_csb(STREAMFILE *streamFile) {
//;VGM_LOG("CSB: subfile offset=%lx + %x\n", subfile_offset, subfile_size);
temp_sf = setup_subfile_streamfile(streamFile, subfile_offset, subfile_size, "aax");
temp_sf = setup_subfile_streamfile(sf, subfile_offset, subfile_size, "aax");
if (!temp_sf) goto fail;
switch(fmt) {
......
......@@ -80,6 +80,9 @@ static const uint8_t key_ghm[] = { 0x8C,0xFA,0xF3,0x14,0xB1,0x53,0xDA,0xAB,0x2B,
/* 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 };
// Unknown:
// - Battle: Los Angeles
// - Guitar Hero: Warriors of Rock, DJ hero FSB
......@@ -90,7 +93,7 @@ typedef struct {
int is_fsb5; /* FSB5 or FSB4/3*/
int is_alt; /* alt XOR mode (seemingly not tied to FSB version or anything) */
size_t fsbkey_size;
const uint8_t *fsbkey;
const uint8_t* fsbkey;
} fsbkey_info;
static const fsbkey_info fsbkey_list[] = {
......@@ -153,6 +156,7 @@ static const fsbkey_info fsbkey_list[] = {
{ 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
};
static const int fsbkey_list_count = sizeof(fsbkey_list) / sizeof(fsbkey_list[0]);
......
......@@ -934,4 +934,6 @@ VGMSTREAM *init_vgmstream_sbk(STREAMFILE *sf);
VGMSTREAM* init_vgmstream_ifs(STREAMFILE* sf);
VGMSTREAM* init_vgmstream_acx(STREAMFILE* sf);
#endif /*_META_H*/
......@@ -660,6 +660,8 @@ VGMSTREAM* init_vgmstream_sadb(STREAMFILE* sf) {
dspm.start_offset = read_32bitBE(0x48,sf);
dspm.interleave = 0x10;
dspm.ignore_loop_ps = 1; /* does something strange with offsets/etc, ignore */
dspm.meta_type = meta_DSP_SADB;
return init_vgmstream_dsp_common(sf, &dspm);
fail:
......
......@@ -3,66 +3,71 @@
/* EXST - from Sony games [Shadow of the Colossus (PS2), Gacha Mecha Stadium Saru Battle (PS2)] */
VGMSTREAM * init_vgmstream_ps2_exst(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
STREAMFILE * streamBody = NULL;
VGMSTREAM* init_vgmstream_ps2_exst(STREAMFILE* sf) {
VGMSTREAM* vgmstream = NULL;
STREAMFILE* sf_body = NULL;
off_t start_offset;
int loop_flag, channel_count;
int loop_flag, channels, sample_rate;
size_t block_size, num_blocks, loop_start_block;
/* checks */
/* .sts+int: main [Shadow of the Colossus (PS2)] (some .sts have manually joined header+body)
/* .sts+int: standard [Shadow of the Colossus (PS2)] (some fake .sts have manually joined header+body)
* .x: header+body [Ape Escape 3 (PS2)] */
if (!check_extensions(streamFile, "sts,x"))
if (!check_extensions(sf, "sts,x"))
goto fail;
if (read_32bitBE(0x00,streamFile) != 0x45585354) /* "EXST" */
if (!is_id32be(0x00,sf, "EXST"))
goto fail;
streamBody = open_streamfile_by_ext(streamFile,"int");
if (!streamBody) {
/* data+body joined */
start_offset = 0x78;
if (get_streamfile_size(streamFile) < start_offset)
goto fail;
}
else {
/* body is separate */
sf_body = open_streamfile_by_ext(sf,"int");
if (sf_body) {
/* separate header+body (header is 0x78) */
start_offset = 0x00;
}
else {
/* joint header+body */
start_offset = 0x78;
/* Gacharoku 2 has header+data but padded header (ELF has pointers + size to SOUND.PCK, and
* treats them as single files, no extension but there are Sg2ExStAdpcm* calls in the ELF) */
if ((get_streamfile_size(sf) % 0x10) == 0)
start_offset = 0x80;
if (get_streamfile_size(sf) < start_offset)
goto fail;
}
channel_count = read_16bitLE(0x06,streamFile);
loop_flag = read_32bitLE(0x0C,streamFile) == 1;
loop_start_block = read_32bitLE(0x10,streamFile);
num_blocks = read_32bitLE(0x14,streamFile);
channels = read_u16le(0x06,sf);
sample_rate = read_u32le(0x08,sf);
loop_flag = read_u32le(0x0C,sf) == 1;
loop_start_block = read_u32le(0x10,sf);
num_blocks = read_u32le(0x14,sf);
/* 0x18: 0x24 config per channel? (volume+panning+etc?) */
/* rest is padding up to 0x78 */
/* build the VGMSTREAM */
vgmstream = allocate_vgmstream(channel_count,loop_flag);
vgmstream = allocate_vgmstream(channels, loop_flag);
if (!vgmstream) goto fail;
vgmstream->sample_rate = read_32bitLE(0x08,streamFile);
vgmstream->meta_type = meta_PS2_EXST;
vgmstream->sample_rate = sample_rate;
vgmstream->coding_type = coding_PSX;
vgmstream->layout_type = layout_interleave;
vgmstream->interleave_block_size = 0x400;
block_size = vgmstream->interleave_block_size * vgmstream->channels;
vgmstream->num_samples = ps_bytes_to_samples(num_blocks*block_size, channel_count);
if (vgmstream->loop_flag) {
vgmstream->loop_start_sample = ps_bytes_to_samples(loop_start_block*block_size, channel_count);;
vgmstream->loop_end_sample = vgmstream->num_samples;
}
vgmstream->num_samples = ps_bytes_to_samples(num_blocks * block_size, channels);
vgmstream->loop_start_sample = ps_bytes_to_samples(loop_start_block * block_size, channels);
vgmstream->loop_end_sample = vgmstream->num_samples;
if (!vgmstream_open_stream(vgmstream,streamBody ? streamBody : streamFile,start_offset))
if (!vgmstream_open_stream(vgmstream, sf_body ? sf_body : sf, start_offset))
goto fail;
close_streamfile(streamBody);
close_streamfile(sf_body);
return vgmstream;
fail:
close_streamfile(streamBody);
close_streamfile(sf_body);
close_vgmstream(vgmstream);
return NULL;
}
......@@ -9,7 +9,7 @@
typedef enum { CODEC_NONE = 0, UBI_IMA, RAW_PCM, RAW_PSX, RAW_XMA1, RAW_XMA2_OLD, RAW_XMA2_NEW, RAW_AT3, RAW_AT3_105, FMT_AT3, RAW_DSP, FMT_OGG } ubi_bao_codec;
typedef enum { TYPE_NONE = 0, UBI_AUDIO, UBI_LAYER, UBI_SEQUENCE, UBI_SILENCE } ubi_bao_type;
typedef enum { FILE_NONE = 0, UBI_FORGE, UBI_FORGE_b } ubi_bao_file;
typedef enum { FILE_NONE = 0, UBI_FORGE, UBI_FORGE_b, UBI_FAT } ubi_bao_file;
typedef struct {
size_t bao_class;
......@@ -1403,6 +1403,13 @@ static STREAMFILE* open_atomic_bao(ubi_bao_file file_type, uint32_t file_id, int
goto fail;
case UBI_FAT:
snprintf(buf,buf_size, "%08x.bao", file_id);
sf_bao = open_streamfile_by_filename(sf, buf);
if (sf_bao) return sf_bao;
goto fail;
default:
goto fail;
}
......@@ -1747,6 +1754,30 @@ static int config_bao_version(ubi_bao_header* bao, STREAMFILE* sf) {
bao->cfg.file_type = UBI_FORGE;
return 1;
case 0x001B0200: /* Beowulf (PS3/X360)-atomic-bin+fat */
config_bao_entry(bao, 0xA0, 0x24);
config_bao_audio_b(bao, 0x08, 0x1c, 0x28, 0x34, 1, 1); /* 0x2c: prefetch flag? */
config_bao_audio_m(bao, 0x44, 0x48, 0x50, 0x58, 0x64, 0x74);
bao->cfg.audio_interleave = 0x10;
bao->cfg.audio_fix_psx_samples = 1;
config_bao_sequence(bao, 0x2c, 0x20, 0x1c, 0x14);
config_bao_layer_m(bao, 0x4c, 0x20, 0x2c, 0x44, 0x00, 0x50, 0x00, 0x00, 1); /* stream size: 0x48? */
config_bao_layer_e(bao, 0x30, 0x00, 0x04, 0x08, 0x10);
config_bao_silence_f(bao, 0x1c);
bao->cfg.codec_map[0x00] = RAW_XMA1;
bao->cfg.codec_map[0x02] = RAW_PSX;
bao->cfg.codec_map[0x03] = UBI_IMA;
bao->cfg.codec_map[0x04] = FMT_OGG;
bao->cfg.codec_map[0x07] = RAW_AT3_105;
bao->cfg.file_type = UBI_FAT;
return 1;
case 0x001F0008: /* Rayman Raving Rabbids: TV Party (Wii)-package */
case 0x001F0010: /* Prince of Persia 2008 (PC/PS3/X360)-atomic-forge, Far Cry 2 (PS3)-atomic-dunia? */
case 0x001F0011: /* Naruto: The Broken Bond (X360)-package */
......@@ -1879,9 +1910,6 @@ static int config_bao_version(ubi_bao_header* bao, STREAMFILE* sf) {
bao->cfg.file_type = UBI_FORGE_b;
return 1;
case 0x001B0200: /* Beowulf (PS3)-atomic-bin+fat */
/* same as 0x001B0100 except:
* - base 0xA0, skip 0x24, name style %08x (.bao/sbao?) */
case 0x001C0000: /* Lost: Via Domus (PS3)-atomic-gear */
/* same as 0x001B0100 except:
* - base 0xA0, skip 0x24, name style %08x.bao (not .sbao?) */
......
......@@ -3988,9 +3988,11 @@ static int config_sb_version(ubi_sb_header* sb, STREAMFILE* sf) {
return 1;
}
/* Naruto: Rise of a Ninja (2007)(X360)-bank */
/* Rainbow Six Vegas 2 (2008)(PS3)-bank */
/* Rainbow Six Vegas 2 (2008)(X360)-bank */
if ((sb->version == 0x001C0000 && sb->platform == UBI_PS3) ||
if ((sb->version == 0x001B0001 && sb->platform == UBI_X360) ||
(sb->version == 0x001C0000 && sb->platform == UBI_PS3) ||
(sb->version == 0x001C0000 && sb->platform == UBI_X360)) {
config_sb_entry(sb, 0x64, 0x7c);
......
......@@ -96,7 +96,8 @@ VGMSTREAM* init_vgmstream_wwise(STREAMFILE* sf) {
switch(ww.codec) {
case PCM: /* common */
/* normally riff.c has priority but it's needed when .wem is used */
if (ww.fmt_size != 0x10 && ww.fmt_size != 0x18 && ww.fmt_size != 0x28) goto fail; /* old, new/Limbo (PC) */
/* old=0x10, 0x12=Army of Two: the 40th Day (PS3), new/Limbo (PC) */
if (ww.fmt_size != 0x10 && ww.fmt_size != 0x12 && ww.fmt_size != 0x18 && ww.fmt_size != 0x28) goto fail;
if (ww.bits_per_sample != 16) goto fail;
vgmstream->coding_type = (ww.big_endian ? coding_PCM16BE : coding_PCM16LE);
......
......@@ -12,13 +12,14 @@ VGMSTREAM* init_vgmstream_xnb(STREAMFILE* sf) {
int big_endian, flags, codec, sample_rate, block_align, bps;
size_t data_size;
char platform;
int is_ogg = 0, is_at9 = 0;
int is_sound = 0, is_ogg = 0, is_at9 = 0, is_song = 0;
char song_name[255+1];
/* checks */
if (!check_extensions(sf,"xnb"))
goto fail;
if ((read_32bitBE(0x00, sf) & 0xFFFFFF00) != 0x584E4200) /* "XNB" */
if ((read_u32be(0x00, sf) & 0xFFFFFF00) != get_id32be("XNB\0"))
goto fail;
/* XNA Studio platforms: 'w' = Windows, 'm' = Windows Phone 7, 'x' = X360
......@@ -32,9 +33,9 @@ VGMSTREAM* init_vgmstream_xnb(STREAMFILE* sf) {
flags = read_u8(0x05, sf);
//if (flags & 0x01) goto fail; /* "HiDef profile" content (no actual difference) */
/* full size */
if (read_32bitLE(0x06, sf) != get_streamfile_size(sf)) {
if (read_u32le(0x06, sf) != get_streamfile_size(sf)) {
goto fail;
}
......@@ -59,49 +60,73 @@ VGMSTREAM* init_vgmstream_xnb(STREAMFILE* sf) {
/* XNB contains "type reader" class references to parse "shared resource" data (can be any implemented filetype) */
{
char reader_name[255+1];
size_t reader_string_len;
uint32_t fmt_chunk_size;
const char* type_sound = "Microsoft.Xna.Framework.Content.SoundEffectReader"; /* partial "fmt" chunk or XMA */
const char* type_ogg = "SoundEffectFromOggReader"; /* has extra text info after base part */
//const char* type_song = "Microsoft.Xna.Framework.Content.SongReader"; /* references a companion .wma */
size_t string_len;
uint8_t type_count;
const static char* type_sound = "Microsoft.Xna.Framework.Content.SoundEffectReader"; /* partial "fmt" chunk or XMA */
const static char* type_ogg = "SoundEffectFromOggReader"; /* has extra text info after base part */
const static char* type_song = "Microsoft.Xna.Framework.Content.SongReader"; /* references a companion .wma */
const static char* type_int32 = "Microsoft.Xna.Framework.Content.Int32Reader"; /* extra crap */
type_count = read_u8(offset++, sf_h);
/* check type reader string */
string_len = read_u8(offset++, sf_h); /* doesn't count null */
if (read_string(reader_name, string_len+1, offset, sf_h) != string_len)
goto fail;
/* type reader count, accept only one for now */
if (read_u8(offset++, sf_h) != 1)
if (strcmp(reader_name, type_sound) == 0) {
if (type_count != 1) goto fail;
is_sound = 1;
}
else if (strncmp(reader_name, type_ogg, strlen(type_ogg)) == 0) { /* has extra info after base string */
if (type_count != 1) goto fail;
is_ogg = 1;
}
else if (strcmp(reader_name, type_song) == 0) {
if (type_count != 2) goto fail;
is_song = 1;
}
else {
goto fail;
}
reader_string_len = read_u8(offset++, sf_h); /* doesn't count null */
if (reader_string_len > 255) goto fail;
offset += string_len + 1;
/* check SoundEffect type string */
if (read_string(reader_name, reader_string_len+1, offset, sf_h) != reader_string_len)
goto fail;
if (strcmp(reader_name, type_sound) != 0) {
is_ogg = strncmp(reader_name, type_ogg, strlen(type_ogg)) == 0;
if (!is_ogg)
if (is_song) {
offset += 3;
string_len = read_u8(offset++, sf_h);
if (read_string(reader_name, string_len+1, offset, sf_h) != string_len)
goto fail;
if (strcmp(reader_name, type_int32) != 0)
goto fail;
offset += string_len + 1;
}
offset += reader_string_len + 1;
offset += 0x04; /* reader version, 0 */