From ccbb4f5097a0d51ff3ed1033b13d733bf2cdd1e3 Mon Sep 17 00:00:00 2001 From: bnnm Date: Sun, 3 Jan 2021 16:00:08 +0100 Subject: [PATCH] Fix some .sts [Gacharoku 2 (PS2)] --- src/meta/ps2_exst.c | 65 ++++++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 30 deletions(-) diff --git a/src/meta/ps2_exst.c b/src/meta/ps2_exst.c index 68a3388e..5d9a7312 100644 --- a/src/meta/ps2_exst.c +++ b/src/meta/ps2_exst.c @@ -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; }