From ce568fb6a3114c2a6b5f95e06ccbd6a8a3f55fed Mon Sep 17 00:00:00 2001 From: bnnm Date: Sat, 3 Mar 2018 02:03:53 +0100 Subject: [PATCH] Add .ATSL for PS4/Vita/PC [Warriors All-Stars (PC)] --- src/formats.c | 2 ++ src/meta/atsl3.c | 91 ++++++++++++++++++++++++++++++++++++++---------- src/meta/meta.h | 2 +- src/vgmstream.c | 2 +- 4 files changed, 76 insertions(+), 21 deletions(-) diff --git a/src/formats.c b/src/formats.c index 15649483..51e65490 100644 --- a/src/formats.c +++ b/src/formats.c @@ -43,7 +43,9 @@ static const char* extension_list[] = { "ast", "at3", "at9", + "atsl", "atsl3", + "atsl4", "atx", "aud", "aus", diff --git a/src/meta/atsl3.c b/src/meta/atsl3.c index 722c3f77..4bc0cd4c 100644 --- a/src/meta/atsl3.c +++ b/src/meta/atsl3.c @@ -1,45 +1,98 @@ #include "meta.h" #include "../coding/coding.h" -static STREAMFILE* setup_atsl3_streamfile(STREAMFILE *streamFile, off_t subfile_offset, size_t subfile_size); +static STREAMFILE* setup_atsl_streamfile(STREAMFILE *streamFile, off_t subfile_offset, size_t subfile_size, const char* fake_ext); +typedef enum { ATRAC3, ATRAC9, KOVS } atsl_codec; -/* .ATSL3 - Koei Tecmo container of multiple .AT3 [One Piece Pirate Warriors (PS3)] */ -VGMSTREAM * init_vgmstream_atsl3(STREAMFILE *streamFile) { +/* .ATSL - Koei Tecmo audio container [One Piece Pirate Warriors (PS3), Warriors All-Stars (PC)] */ +VGMSTREAM * init_vgmstream_atsl(STREAMFILE *streamFile) { VGMSTREAM *vgmstream = NULL; STREAMFILE *temp_streamFile = NULL; int total_subsongs, target_subsong = streamFile->stream_index; + int type, big_endian = 0; + atsl_codec codec; + const char* fake_ext; off_t subfile_offset; - size_t subfile_size, header_size, entry_size; + size_t subfile_size, header_size; + int32_t (*read_32bit)(off_t,STREAMFILE*) = NULL; - /* check extensions */ - if ( !check_extensions(streamFile,"atsl3")) + + /* check extensions + * .atsl: header id (for G1L extractions), .atsl3: PS3 games, .atsl4: PS4 games */ + if ( !check_extensions(streamFile,"atsl,atsl3,atsl4")) goto fail; if (read_32bitBE(0x00,streamFile) != 0x4154534C) /* "ATSL" */ goto fail; /* main header (LE) */ header_size = read_32bitLE(0x04,streamFile); - /* 0x08/0c: flags?, 0x10: some size? */ + /* 0x08/0c: flags?, 0x10: fixed? (0x03E8) */ total_subsongs = read_32bitLE(0x14,streamFile); - entry_size = read_32bitLE(0x18,streamFile); + /* 0x18: 0x28, or 0x30 (rarer) */ /* 0x1c: null, 0x20: subheader size, 0x24/28: null */ + //todo: sometimes entries are repeated/dummy and point to the first entry if (target_subsong == 0) target_subsong = 1; if (target_subsong > total_subsongs || total_subsongs <= 0) goto fail; - /* entry header (BE) */ - /* 0x00: id */ - subfile_offset = read_32bitBE(header_size + (target_subsong-1)*entry_size + 0x04,streamFile); - subfile_size = read_32bitBE(header_size + (target_subsong-1)*entry_size + 0x08,streamFile); - /* 0x08+: sample rate/num_samples/loop_start/etc, matching subfile header */ - /* some kind of seek/switch table follows */ - temp_streamFile = setup_atsl3_streamfile(streamFile, subfile_offset,subfile_size); + /* Type byte may be wrong (could need header id tests instead). + * Example flags at 0x08/0x0c: + * - 00010101 00020001 .atsl3 from One Piece Pirate Warriors (PS3)[ATRAC3] + * - 00000201 00020001 .atsl3 from Fist of North Star: Ken's Rage 2 (PS3)[ATRAC3] + * 00000301 00020101 (same) + * - 01040301 00060301 .atsl4 from Nobunaga's Ambition: Sphere of Influence (PS4)[ATRAC9] + * - 00060301 00040301 atsl in G1L from One Piece Pirate Warriors 3 (Vita)[ATRAC9] + * - 00060301 00010301 atsl in G1L from One Piece Pirate Warriors 3 (PC)[KOVS] + * - 000A0301 00010501 atsl in G1L from Warriors All-Stars (PC)[KOVS] + */ + type = read_8bit(0x0d, streamFile); + switch(type) { + case 0x01: + codec = KOVS; + fake_ext = "kvs"; + break; + case 0x02: + codec = ATRAC3; + fake_ext = "at3"; + big_endian = 1; + break; + case 0x04: + case 0x06: + codec = ATRAC9; + fake_ext = "at9"; + break; + default: + goto fail; + } + read_32bit = big_endian ? read_32bitBE : read_32bitLE; + + + /* entry header (machine endianness) */ + /* 0x00: id */ + subfile_offset = read_32bit(header_size + (target_subsong-1)*0x28 + 0x04,streamFile); + subfile_size = read_32bit(header_size + (target_subsong-1)*0x28 + 0x08,streamFile); + /* 0x08+: sample rate/num_samples/loop_start/etc, matching subfile header */ + /* some kind of seek/switch table follows (optional, found in .atsl3) */ + + temp_streamFile = setup_atsl_streamfile(streamFile, subfile_offset,subfile_size, fake_ext); if (!temp_streamFile) goto fail; /* init the VGMSTREAM */ - vgmstream = init_vgmstream_riff(temp_streamFile); - if (!vgmstream) goto fail; + switch(codec) { + case ATRAC3: + case ATRAC9: + vgmstream = init_vgmstream_riff(temp_streamFile); + if (!vgmstream) goto fail; + break; + case KOVS: + vgmstream = init_vgmstream_ogg_vorbis(temp_streamFile); + if (!vgmstream) goto fail; + break; + default: + goto fail; + } + vgmstream->num_streams = total_subsongs; close_streamfile(temp_streamFile); @@ -52,7 +105,7 @@ fail: } -static STREAMFILE* setup_atsl3_streamfile(STREAMFILE *streamFile, off_t subfile_offset, size_t subfile_size) { +static STREAMFILE* setup_atsl_streamfile(STREAMFILE *streamFile, off_t subfile_offset, size_t subfile_size, const char* fake_ext) { STREAMFILE *temp_streamFile = NULL, *new_streamFile = NULL; /* setup subfile */ @@ -64,7 +117,7 @@ static STREAMFILE* setup_atsl3_streamfile(STREAMFILE *streamFile, off_t subfile_ if (!new_streamFile) goto fail; temp_streamFile = new_streamFile; - new_streamFile = open_fakename_streamfile(temp_streamFile, NULL,"at3"); + new_streamFile = open_fakename_streamfile(temp_streamFile, NULL,fake_ext); if (!new_streamFile) goto fail; temp_streamFile = new_streamFile; diff --git a/src/meta/meta.h b/src/meta/meta.h index 80dc0622..b04e6dcd 100644 --- a/src/meta/meta.h +++ b/src/meta/meta.h @@ -697,7 +697,7 @@ VGMSTREAM * init_vgmstream_fsb_encrypted(STREAMFILE * streamFile); VGMSTREAM * init_vgmstream_xwc(STREAMFILE *streamFile); -VGMSTREAM * init_vgmstream_atsl3(STREAMFILE *streamFile); +VGMSTREAM * init_vgmstream_atsl(STREAMFILE *streamFile); VGMSTREAM * init_vgmstream_sps_n1(STREAMFILE *streamFile); diff --git a/src/vgmstream.c b/src/vgmstream.c index 463f1e09..72046001 100644 --- a/src/vgmstream.c +++ b/src/vgmstream.c @@ -375,7 +375,7 @@ VGMSTREAM * (*init_vgmstream_functions[])(STREAMFILE *streamFile) = { init_vgmstream_kma9, init_vgmstream_fsb_encrypted, init_vgmstream_xwc, - init_vgmstream_atsl3, + init_vgmstream_atsl, init_vgmstream_sps_n1, init_vgmstream_atx, init_vgmstream_sqex_sead,