mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-11-15 02:57:38 +01:00
Fix some ZSND .zsd [X-Men: The Official Game (Xbox), BMX XXX (Xbox)]
This commit is contained in:
parent
92c3a9ec94
commit
657202380b
@ -1234,7 +1234,7 @@ static const meta_info meta_info_list[] = {
|
|||||||
{meta_XPCM, "Circus XPCM header"},
|
{meta_XPCM, "Circus XPCM header"},
|
||||||
{meta_MSF_TAMASOFT, "Tama-Soft MSF header"},
|
{meta_MSF_TAMASOFT, "Tama-Soft MSF header"},
|
||||||
{meta_XPS_DAT, "From Software .XPS+DAT header"},
|
{meta_XPS_DAT, "From Software .XPS+DAT header"},
|
||||||
{meta_ZSND, "Vicarious Visions ZSND header"},
|
{meta_ZSND, "Z-Axis ZSND header"},
|
||||||
{meta_DSP_ADPY, "AQUASTYLE ADPY header"},
|
{meta_DSP_ADPY, "AQUASTYLE ADPY header"},
|
||||||
{meta_DSP_ADPX, "AQUASTYLE ADPX header"},
|
{meta_DSP_ADPX, "AQUASTYLE ADPX header"},
|
||||||
{meta_OGG_OPUS, "Ogg Opus header"},
|
{meta_OGG_OPUS, "Ogg Opus header"},
|
||||||
|
@ -3,13 +3,13 @@
|
|||||||
#include "zsnd_streamfile.h"
|
#include "zsnd_streamfile.h"
|
||||||
|
|
||||||
|
|
||||||
/* ZSND - Vicarious Visions games [X-Men Legends II (multi), Marvel Ultimate Alliance (multi)] */
|
/* ZSND - Z-Axis/Vicarious Visions games [X-Men Legends II (multi), Marvel Ultimate Alliance (multi)] */
|
||||||
VGMSTREAM * init_vgmstream_zsnd(STREAMFILE *streamFile) {
|
VGMSTREAM * init_vgmstream_zsnd(STREAMFILE *streamFile) {
|
||||||
VGMSTREAM * vgmstream = NULL;
|
VGMSTREAM * vgmstream = NULL;
|
||||||
STREAMFILE *temp_streamFile = NULL;
|
STREAMFILE *temp_streamFile = NULL;
|
||||||
off_t start_offset, name_offset;
|
off_t start_offset, name_offset;
|
||||||
size_t stream_size, name_size;
|
size_t stream_size, name_size;
|
||||||
int loop_flag, channel_count, sample_rate, layers;
|
int loop_flag, channel_count, sample_rate, layers, layers2 = 0;
|
||||||
uint32_t codec;
|
uint32_t codec;
|
||||||
int total_subsongs, target_subsong = streamFile->stream_index;
|
int total_subsongs, target_subsong = streamFile->stream_index;
|
||||||
int32_t (*read_32bit)(off_t,STREAMFILE*) = NULL;
|
int32_t (*read_32bit)(off_t,STREAMFILE*) = NULL;
|
||||||
@ -45,7 +45,7 @@ VGMSTREAM * init_vgmstream_zsnd(STREAMFILE *streamFile) {
|
|||||||
off_t header2_offset, header3_offset;
|
off_t header2_offset, header3_offset;
|
||||||
int table2_entries, table3_entries;
|
int table2_entries, table3_entries;
|
||||||
off_t table2_body, table3_body;
|
off_t table2_body, table3_body;
|
||||||
int is_compact, i;
|
int is_v1, i;
|
||||||
|
|
||||||
|
|
||||||
/* multiple config tables:
|
/* multiple config tables:
|
||||||
@ -68,11 +68,16 @@ VGMSTREAM * init_vgmstream_zsnd(STREAMFILE *streamFile) {
|
|||||||
* table1 may have more entries than table2/3, and sometimes isn't set
|
* table1 may have more entries than table2/3, and sometimes isn't set
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* 'compact' mode has no table heads, rare [Aggresive Inline (Xbox)]
|
/* V1 has no table heads, rare [Aggresive Inline (Xbox)]
|
||||||
* no apparent flag but we can test if table heads offsets appear */
|
* no apparent flag but we can test if table heads offsets appear */
|
||||||
is_compact = read_32bit(0x14,streamFile) > read_32bit(0x18,streamFile);
|
is_v1 = read_32bit(0x14,streamFile) <= read_32bit(0x1c,streamFile) &&
|
||||||
|
read_32bit(0x1c,streamFile) <= read_32bit(0x24,streamFile) &&
|
||||||
|
read_32bit(0x24,streamFile) <= read_32bit(0x2c,streamFile) &&
|
||||||
|
read_32bit(0x2c,streamFile) <= read_32bit(0x34,streamFile) &&
|
||||||
|
read_32bit(0x34,streamFile) <= read_32bit(0x3c,streamFile) &&
|
||||||
|
read_32bit(0x3c,streamFile) <= read_32bit(0x44,streamFile);
|
||||||
|
|
||||||
if (!is_compact) {
|
if (!is_v1) {
|
||||||
table2_entries = read_32bit(0x1c,streamFile);
|
table2_entries = read_32bit(0x1c,streamFile);
|
||||||
table2_body = read_32bit(0x24,streamFile);
|
table2_body = read_32bit(0x24,streamFile);
|
||||||
|
|
||||||
@ -108,7 +113,7 @@ VGMSTREAM * init_vgmstream_zsnd(STREAMFILE *streamFile) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x58424F58: { /* "XBOX" */
|
case 0x58424F58: { /* "XBOX" */
|
||||||
size_t entry2_size = is_compact ? 0x14 : 0x1c;
|
size_t entry2_size = is_v1 || check_extensions(streamFile, "zsd") ? 0x14 : 0x1c;
|
||||||
|
|
||||||
/* BMX has unordered stream headers, and not every stream has a header */
|
/* BMX has unordered stream headers, and not every stream has a header */
|
||||||
header2_offset = 0;
|
header2_offset = 0;
|
||||||
@ -129,30 +134,51 @@ VGMSTREAM * init_vgmstream_zsnd(STREAMFILE *streamFile) {
|
|||||||
sample_rate = read_32bit(header2_offset + 0x04,streamFile);
|
sample_rate = read_32bit(header2_offset + 0x04,streamFile);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* defaults to this in cutscene files in BMX with no heads at all,
|
layers = 0;
|
||||||
* but also needs mono for speech files in Aggresive Inline */
|
sample_rate = 0;
|
||||||
if (is_compact) {
|
|
||||||
layers = 0x00;
|
|
||||||
sample_rate = 16000;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
layers = 0x02;
|
|
||||||
sample_rate = 44100;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
layers = read_16bit(header2_offset + 0x02,streamFile);
|
layers = read_16bit(header2_offset + 0x02,streamFile);
|
||||||
sample_rate = read_32bit(header2_offset + 0x04,streamFile);
|
sample_rate = read_32bit(header2_offset + 0x04,streamFile);
|
||||||
|
if (entry2_size > 0x18) {
|
||||||
|
layers2 = read_32bit(header2_offset + 0x18,streamFile);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
header3_offset = table3_body + 0x54*(target_subsong-1);
|
header3_offset = table3_body + 0x54*(target_subsong-1);
|
||||||
start_offset = read_32bit(header3_offset + 0x00,streamFile);
|
start_offset = read_32bit(header3_offset + 0x00,streamFile);
|
||||||
stream_size = read_32bit(header3_offset + 0x04,streamFile);
|
stream_size = read_32bit(header3_offset + 0x04,streamFile);
|
||||||
|
/* 0x08: flags? related to looping? (not channels) */
|
||||||
//loop_end = read_32bit(header3_offset + 0x10,streamFile);
|
//loop_end = read_32bit(header3_offset + 0x10,streamFile);
|
||||||
name_offset = header3_offset + 0x14;
|
name_offset = header3_offset + 0x14;
|
||||||
name_size = 0x40;
|
name_size = 0x40;
|
||||||
|
|
||||||
|
/* early games sometimes don't seem to have info or headers, not sure how to detect better
|
||||||
|
* ex. Aggresive Inline speech (1ch) vs music (2ch), or BMX cutscenes (2ch) */
|
||||||
|
if (sample_rate == 0) {
|
||||||
|
int is_music = 0;
|
||||||
|
if (is_v1) {
|
||||||
|
char filename[PATH_LIMIT];
|
||||||
|
|
||||||
|
/* stream length isn't enough */
|
||||||
|
get_streamfile_filename(streamFile, filename, sizeof(filename));
|
||||||
|
is_music = strcmp(filename, "music.zsd") == 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
is_music = stream_size > 0x20000;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_music) {
|
||||||
|
layers = 0x02;
|
||||||
|
sample_rate = 44100;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
layers = 0x00;
|
||||||
|
sample_rate = is_v1 ? 16000 : 22050; /* some BMX need 16000 but can't detect? */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,6 +235,10 @@ VGMSTREAM * init_vgmstream_zsnd(STREAMFILE *streamFile) {
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (layers2) {
|
||||||
|
channel_count = channel_count * layers2;
|
||||||
|
}
|
||||||
|
|
||||||
loop_flag = 0;
|
loop_flag = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user