From af5176721cdaf083cf8ec85445be85cdc2774071 Mon Sep 17 00:00:00 2001 From: bnnm Date: Sun, 15 Nov 2020 00:15:21 +0100 Subject: [PATCH] Fix some .nus3bank [Tekken Tag Tournament 2 (X360)] --- src/meta/nus3bank.c | 78 ++++++++++++++++++++++++++------------------- 1 file changed, 46 insertions(+), 32 deletions(-) diff --git a/src/meta/nus3bank.c b/src/meta/nus3bank.c index 81baf9fb..277cab41 100644 --- a/src/meta/nus3bank.c +++ b/src/meta/nus3bank.c @@ -3,28 +3,29 @@ #include "nus3bank_streamfile.h" -typedef enum { IDSP, IVAG, BNSF, RIFF, OPUS, RIFF_ENC, } nus3bank_codec; +typedef enum { IDSP, IVAG, BNSF, RIFF, RIFF_XMA2, OPUS, RIFF_ENC, } nus3bank_codec; -/* .nus3bank - Namco's newest audio container [Super Smash Bros (Wii U), idolmaster (PS4))] */ -VGMSTREAM * init_vgmstream_nus3bank(STREAMFILE *streamFile) { - VGMSTREAM *vgmstream = NULL; - STREAMFILE *temp_sf = NULL; +/* .nus3bank - Namco's newest audio container [Super Smash Bros (Wii U), THE iDOLM@STER 2 (PS3/X360)] */ +VGMSTREAM* init_vgmstream_nus3bank(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; + STREAMFILE* temp_sf = NULL; off_t tone_offset = 0, pack_offset = 0, name_offset = 0, subfile_offset = 0; size_t name_size = 0, subfile_size = 0; nus3bank_codec codec; const char* fake_ext; - int total_subsongs, target_subsong = streamFile->stream_index; + int total_subsongs, target_subsong = sf->stream_index; + /* checks */ /* .nub2: early [THE iDOLM@STER 2 (PS3/X360)] * .nus3bank: standard */ - if (!check_extensions(streamFile, "nub2,nus3bank")) + if (!check_extensions(sf, "nub2,nus3bank")) goto fail; - if (read_32bitBE(0x00,streamFile) != 0x4E555333) /* "NUS3" */ + if (read_u32be(0x00,sf) != 0x4E555333) /* "NUS3" */ goto fail; - if (read_32bitBE(0x08,streamFile) != 0x42414E4B) /* "BANK" */ + if (read_u32be(0x08,sf) != 0x42414E4B) /* "BANK" */ goto fail; - if (read_32bitBE(0x0c,streamFile) != 0x544F4320) /* "TOC\0" */ + if (read_u32be(0x0c,sf) != 0x544F4320) /* "TOC\0" */ goto fail; /* header is always LE, while contained files may use another endianness */ @@ -32,12 +33,12 @@ VGMSTREAM * init_vgmstream_nus3bank(STREAMFILE *streamFile) { /* parse TOC with all existing chunks and sizes (offsets must be derived) */ { int i; - off_t offset = 0x14 + read_32bitLE(0x10, streamFile); /* TOC size */ - size_t chunk_count = read_32bitLE(0x14, streamFile); /* rarely not 7 (ex. SMB U's snd_bgm_CRS12_Simple_Result_Final) */ + off_t offset = 0x14 + read_u32le(0x10, sf); /* TOC size */ + size_t chunk_count = read_u32le(0x14, sf); /* rarely not 7 (ex. SMB U's snd_bgm_CRS12_Simple_Result_Final) */ for (i = 0; i < chunk_count; i++) { - uint32_t chunk_id = (uint32_t)read_32bitBE(0x18+(i*0x08)+0x00, streamFile); - size_t chunk_size = (size_t)read_32bitLE(0x18+(i*0x08)+0x04, streamFile); + uint32_t chunk_id = read_u32be(0x18+(i*0x08)+0x00, sf); + size_t chunk_size = read_u32le(0x18+(i*0x08)+0x04, sf); switch(chunk_id) { case 0x544F4E45: /* "TONE": stream info */ @@ -71,7 +72,7 @@ VGMSTREAM * init_vgmstream_nus3bank(STREAMFILE *streamFile) { { int i; uint32_t codec_id = 0; - size_t entries = read_32bitLE(tone_offset+0x00, streamFile); + size_t entries = read_u32le(tone_offset+0x00, sf); /* get actual number of subsongs */ total_subsongs = 0; @@ -82,8 +83,8 @@ VGMSTREAM * init_vgmstream_nus3bank(STREAMFILE *streamFile) { size_t tone_header_size, stream_name_size, stream_size; uint8_t flags2; - tone_header_offset = read_32bitLE(tone_offset+0x04+(i*0x08)+0x00, streamFile); - tone_header_size = read_32bitLE(tone_offset+0x04+(i*0x08)+0x04, streamFile); + tone_header_offset = read_u32le(tone_offset+0x04+(i*0x08)+0x00, sf); + tone_header_size = read_u32le(tone_offset+0x04+(i*0x08)+0x04, sf); offset = tone_offset + tone_header_offset; //;VGM_LOG("NUS3BANK: tone at %lx, size %x\n", tone_offset + tone_header_offset, tone_header_size); @@ -96,7 +97,7 @@ VGMSTREAM * init_vgmstream_nus3bank(STREAMFILE *streamFile) { /* 0x00: type? normally 0x00 and rarely 0x09 */ /* 0x04: usually -1, found when tone is not a stream (most flags are off too) */ /* 0x06: flags1 */ - flags2 = read_8bit(offset + 0x07, streamFile); + flags2 = read_8bit(offset + 0x07, sf); offset += 0x08; /* flags3-6 (early .nub2 and some odd non-stream don't have them) */ @@ -104,18 +105,18 @@ VGMSTREAM * init_vgmstream_nus3bank(STREAMFILE *streamFile) { offset += 0x04; } - stream_name_size = read_8bit(offset + 0x00, streamFile); /* includes null */ + stream_name_size = read_8bit(offset + 0x00, sf); /* includes null */ stream_name_offset = offset + 0x01; offset += align_size_to_block(0x01 + stream_name_size, 0x04); /* padded if needed */ /* 0x00: subtype? should be 0 */ - if (read_32bitLE(offset + 0x04, streamFile) != 0x08) { /* flag? */ + if (read_u32le(offset + 0x04, sf) != 0x08) { /* flag? */ //;VGM_LOG("NUS3BANK: bad tone type at %lx, size %x\n", tone_offset + tone_header_offset, tone_header_size); continue; } - stream_offset = read_32bitLE(offset + 0x08, streamFile) + pack_offset; - stream_size = read_32bitLE(offset + 0x0c, streamFile); + stream_offset = read_u32le(offset + 0x08, sf) + pack_offset; + stream_size = read_u32le(offset + 0x0c, sf); //;VGM_LOG("NUS3BANK: so=%lx, ss=%x\n", stream_offset, stream_size); /* Beyond are a bunch of sub-chunks of unknown size with floats and stuff, that seemingly @@ -148,17 +149,25 @@ VGMSTREAM * init_vgmstream_nus3bank(STREAMFILE *streamFile) { } //todo improve, codec may be in one of the tone sub-chunks (or other chunk? one bank seems to use one codec) - codec_id = read_32bitBE(subfile_offset, streamFile); + codec_id = read_u32be(subfile_offset + 0x00, sf); switch(codec_id) { case 0x49445350: /* "IDSP" [Super Smash Bros. for 3DS (3DS)] */ codec = IDSP; fake_ext = "idsp"; break; - case 0x52494646: /* "RIFF" [THE iDOLM@STER 2 (PS3), Mario Kart Arcade GP DX (PC), idolm@ster: Platinum Stars (PS4)] */ - codec = RIFF; - fake_ext = "wav"; //TODO: works but should have better detection + case 0x52494646: { /* "RIFF" [THE iDOLM@STER 2 (PS3), Mario Kart Arcade GP DX (PC), idolm@ster: Platinum Stars (PS4)] */ + uint16_t format = read_u16le(subfile_offset + 0x14, sf); + if (format == 0x0166) { /* Tekken Tag Tournament 2 (X360) */ + codec = RIFF_XMA2; + fake_ext = "xma"; + } + else { + codec = RIFF; + fake_ext = "wav"; //TODO: works but should have better detection + } break; + } case 0x4F505553: /* "OPUS" [Taiko no Tatsujin (Switch)] */ codec = OPUS; @@ -186,9 +195,9 @@ VGMSTREAM * init_vgmstream_nus3bank(STREAMFILE *streamFile) { } } - //;VGM_LOG("NUS3BANK: subfile=%lx, size=%x\n", subfile_offset, subfile_size); + //;VGM_LOG("NUS3BANK: subfile=%lx, size=%x, %s\n", subfile_offset, subfile_size, fake_ext); - temp_sf = setup_subfile_streamfile(streamFile, subfile_offset, subfile_size, fake_ext); + temp_sf = setup_subfile_streamfile(sf, subfile_offset, subfile_size, fake_ext); if (!temp_sf) goto fail; /* init the VGMSTREAM */ @@ -218,6 +227,11 @@ VGMSTREAM * init_vgmstream_nus3bank(STREAMFILE *streamFile) { if (!vgmstream) goto fail; break; + case RIFF_XMA2: + vgmstream = init_vgmstream_xma(temp_sf); + if (!vgmstream) goto fail; + break; + case RIFF_ENC: vgmstream = init_vgmstream_nus3bank_encrypted(temp_sf); if (!vgmstream) goto fail; @@ -229,7 +243,7 @@ VGMSTREAM * init_vgmstream_nus3bank(STREAMFILE *streamFile) { vgmstream->num_streams = total_subsongs; if (name_offset) - read_string(vgmstream->stream_name,name_size, name_offset,streamFile); + read_string(vgmstream->stream_name, name_size, name_offset, sf); close_streamfile(temp_sf); @@ -242,9 +256,9 @@ fail: } /* encrypted RIFF from the above, in case kids try to extract and play single files */ -VGMSTREAM* init_vgmstream_nus3bank_encrypted(STREAMFILE *sf) { - VGMSTREAM *vgmstream = NULL; - STREAMFILE *temp_sf = NULL; +VGMSTREAM* init_vgmstream_nus3bank_encrypted(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; + STREAMFILE* temp_sf = NULL; /* checks */