2010-04-20 20:26:10 +00:00
|
|
|
#include "layout.h"
|
2018-04-14 02:36:28 +02:00
|
|
|
#include "../coding/coding.h"
|
2010-04-20 20:26:10 +00:00
|
|
|
|
2018-04-14 02:36:28 +02:00
|
|
|
/* EA-style blocks */
|
2018-02-17 21:15:21 +01:00
|
|
|
void block_update_ea_swvr(off_t block_offset, VGMSTREAM * vgmstream) {
|
|
|
|
STREAMFILE* streamFile = vgmstream->ch[0].streamfile;
|
2010-04-20 20:26:10 +00:00
|
|
|
int i;
|
2018-04-14 02:36:28 +02:00
|
|
|
size_t block_size, header_size = 0, channel_size = 0, interleave = 0;
|
|
|
|
uint32_t block_id;
|
2018-02-17 21:15:21 +01:00
|
|
|
int32_t (*read_32bit)(off_t,STREAMFILE*) = vgmstream->codec_endian ? read_32bitBE : read_32bitLE;
|
2018-04-14 02:36:28 +02:00
|
|
|
int16_t (*read_16bit)(off_t,STREAMFILE*) = vgmstream->codec_endian ? read_16bitBE : read_16bitLE;
|
2010-04-20 20:26:10 +00:00
|
|
|
|
2018-04-14 02:36:28 +02:00
|
|
|
block_id = read_32bit(block_offset+0x00, streamFile);
|
|
|
|
block_size = read_32bit(block_offset+0x04, streamFile);
|
|
|
|
|
|
|
|
/* parse blocks (Freekstyle uses multiblocks) */
|
|
|
|
switch(block_id) {
|
|
|
|
case 0x5641474D: /* "VAGM" */
|
|
|
|
if (read_16bit(block_offset+0x1a, streamFile) == 0x0024) {
|
|
|
|
header_size = 0x40;
|
|
|
|
channel_size = (block_size - header_size) / vgmstream->channels;
|
|
|
|
|
|
|
|
/* ignore blocks of other subsongs */
|
|
|
|
{
|
|
|
|
int target_subsong = vgmstream->stream_index ? vgmstream->stream_index : 1;
|
|
|
|
if (read_32bit(block_offset+0x0c, streamFile)+1 != target_subsong) {
|
|
|
|
channel_size = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
header_size = 0x1c;
|
|
|
|
channel_size = (block_size - header_size) / vgmstream->channels;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 0x56414742: /* "VAGB" */
|
|
|
|
if (read_16bit(block_offset+0x1a, streamFile) == 0x6400) {
|
|
|
|
header_size = 0x40;
|
|
|
|
} else {
|
|
|
|
header_size = 0x18;
|
|
|
|
}
|
|
|
|
channel_size = (block_size - header_size) / vgmstream->channels;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0x4453504D: /* "DSPM" */
|
|
|
|
header_size = 0x60;
|
|
|
|
channel_size = (block_size - header_size) / vgmstream->channels;
|
|
|
|
|
|
|
|
/* ignore blocks of other subsongs */
|
|
|
|
{
|
|
|
|
int target_subsong = vgmstream->stream_index ? vgmstream->stream_index : 1;
|
|
|
|
if (read_32bit(block_offset+0x0c, streamFile)+1 != target_subsong) {
|
|
|
|
channel_size = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
dsp_read_coefs_be(vgmstream, streamFile, block_offset+0x1a, 0x22);
|
|
|
|
//todo adpcm history?
|
|
|
|
break;
|
|
|
|
case 0x44535042: /* "DSPB" */
|
|
|
|
header_size = 0x40;
|
|
|
|
channel_size = (block_size - header_size) / vgmstream->channels;
|
|
|
|
dsp_read_coefs_be(vgmstream, streamFile, block_offset+0x18, 0x00);
|
|
|
|
//todo adpcm history?
|
|
|
|
break;
|
|
|
|
//todo unknown ADPCM (PC)
|
|
|
|
#if 0
|
|
|
|
case 0x4D534943: /* "MSIC" */
|
|
|
|
header_size = 0x1c;
|
|
|
|
channel_size = (block_size - header_size) / vgmstream->channels;
|
|
|
|
//todo adpcm history?
|
|
|
|
break;
|
|
|
|
case 0x53484F43: /* "SHOC" (a generic block but hopefully has PC sounds) */
|
|
|
|
header_size = 0x18;
|
|
|
|
channel_size = (block_size - header_size) / vgmstream->channels;
|
|
|
|
//todo adpcm history?
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
case 0x46494C4C: /* "FILL" (FILLs do that up to 0x6000, but at 0x5FFC don't actually have size) */
|
|
|
|
if ((block_offset + 0x04) % 0x6000 == 0)
|
|
|
|
block_size = 0x04;
|
|
|
|
header_size = 0x08;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0xFFFFFFFF:
|
|
|
|
channel_size = -1; /* signal bad block */
|
|
|
|
break;
|
|
|
|
|
|
|
|
default: /* ignore, 0 samples */
|
|
|
|
VGM_LOG("EA SWVR: ignored 0x%08x at 0x%lx\n", block_id, block_offset);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
vgmstream->current_block_size = channel_size;
|
2018-02-17 21:15:21 +01:00
|
|
|
vgmstream->current_block_offset = block_offset;
|
2018-04-14 02:36:28 +02:00
|
|
|
vgmstream->next_block_offset = block_offset + block_size;
|
2010-04-20 20:26:10 +00:00
|
|
|
|
2018-04-14 02:36:28 +02:00
|
|
|
interleave = /*vgmstream->coding_type == coding_IMA ? 0 :*/ channel_size;
|
|
|
|
for (i = 0; i < vgmstream->channels; i++) {
|
|
|
|
vgmstream->ch[i].offset = block_offset + header_size + interleave*i;
|
2010-04-20 20:26:10 +00:00
|
|
|
}
|
|
|
|
}
|