Fix SNDS with CBD2 [Battle Tryst (Arcade)]

This commit is contained in:
bnnm 2020-12-01 23:25:13 +01:00
parent 2135fea36d
commit 54340f9bcd
2 changed files with 39 additions and 44 deletions

View File

@ -1,54 +1,39 @@
#include "layout.h"
#include "../vgmstream.h"
/* set up for the block at the given offset */
void block_update_str_snds(off_t block_offset, VGMSTREAM * vgmstream) {
off_t current_chunk;
size_t file_size;
void block_update_str_snds(off_t block_offset, VGMSTREAM* vgmstream) {
STREAMFILE* sf = vgmstream->ch[0].streamfile;
uint32_t block_type, block_subtype, block_size, block_current;
int i;
STREAMFILE *streamfile;
int FoundSSMP = 0;
off_t SSMP_offset = -1;
current_chunk = block_offset;
streamfile = vgmstream->ch[0].streamfile;
file_size = get_streamfile_size(streamfile);
/* EOF reads: signal we have nothing and let the layout fail */
if (block_offset >= get_streamfile_size(sf)) {
vgmstream->current_block_samples = -1;
return;
}
/* we may have to skip some chunks */
while (!FoundSSMP && current_chunk < file_size) {
if (current_chunk+read_32bitBE(current_chunk+4,streamfile)>=file_size)
break;
switch (read_32bitBE(current_chunk,streamfile)) {
case 0x534e4453: /* SNDS */
/* SSMP */
if (read_32bitBE(current_chunk+0x10,streamfile)==0x53534d50) {
FoundSSMP = 1;
SSMP_offset = current_chunk;
}
break;
case 0x46494c4c: /* FILL, the main culprit */
default:
break;
block_type = read_u32be(block_offset + 0x00,sf);
block_size = read_u32be(block_offset + 0x04,sf);
block_current = 0; /* ignore block by default (other chunks include MPVD + VHDR/FRAM and FILL) */
if (block_type == 0x534e4453) { /* SNDS */
block_subtype = read_u32be(block_offset + 0x10,sf); /* SNDS */
if (block_subtype == 0x53534d50) {
block_current = read_u32be(block_offset + 0x14, sf) / vgmstream->channels;
}
current_chunk += read_32bitBE(current_chunk+4,streamfile);
}
if (!FoundSSMP) {
/* if we couldn't find it all we can do is try playing the current
* block, which is going to suck */
vgmstream->current_block_offset = block_offset;
}
/* seen in Battle Tryst video frames */
if (block_size % 0x04)
block_size += 0x04 - (block_size % 0x04);
vgmstream->current_block_offset = SSMP_offset;
vgmstream->current_block_size = (read_32bitBE(
vgmstream->current_block_offset+4,
vgmstream->ch[0].streamfile) - 0x18) / vgmstream->channels;
vgmstream->next_block_offset = vgmstream->current_block_offset +
read_32bitBE(vgmstream->current_block_offset+4,
vgmstream->ch[0].streamfile);
vgmstream->current_block_offset = block_offset;
vgmstream->next_block_offset = block_offset + block_size;
vgmstream->current_block_size = block_current;
for (i = 0; i < vgmstream->channels; i++) {
vgmstream->ch[i].offset = vgmstream->current_block_offset + 0x18 + i * vgmstream->interleave_block_size;
vgmstream->ch[i].offset = block_offset + 0x18 + i * vgmstream->interleave_block_size;
}
}

View File

@ -13,10 +13,10 @@ VGMSTREAM* init_vgmstream_str_snds(STREAMFILE* sf) {
/* checks */
/* .str: standard
* .stream: Battle Tryst (Arcade) movies
* .3do: Aqua World - Umimi Monogatari (3DO) movies */
if (!check_extensions(sf, "str,3do"))
if (!check_extensions(sf, "str,stream,3do"))
goto fail;
if (read_u32be(0x00,sf) != 0x4354524c && /* "CTRL" */
read_u32be(0x00,sf) != 0x534e4453 && /* "SNDS" */
read_u32be(0x00,sf) != 0x53484452) /* "SHDR" */
@ -96,14 +96,24 @@ VGMSTREAM* init_vgmstream_str_snds(STREAMFILE* sf) {
vgmstream->num_samples /= vgmstream->channels;
switch (read_u32be(shdr_offset + 0x24,sf)) {
case 0x53445832: /* "SDX2" */
case 0x53445832: /* "SDX2" (common) */
if (channels > 1) {
vgmstream->coding_type = coding_SDX2_int;
vgmstream->interleave_block_size = 1;
vgmstream->interleave_block_size = 0x01;
} else {
vgmstream->coding_type = coding_SDX2;
}
break;
case 0x43424432: /* "CBD2" (rare, Battle Tryst) */
if (channels > 1) {
vgmstream->coding_type = coding_CBD2_int;
vgmstream->interleave_block_size = 0x01;
} else {
vgmstream->coding_type = coding_CBD2; /* assumed */
}
break;
default:
goto fail;
}