Handle dummy streams in EA BNK files

This commit is contained in:
NicknineTheEagle 2018-07-17 23:57:08 +03:00
parent e2160f4e09
commit 5b27c21a0b

View File

@ -125,13 +125,13 @@ fail:
/* EA BNK with variable header - from EA games SFXs; also created by sx.exe */
VGMSTREAM * init_vgmstream_ea_bnk(STREAMFILE *streamFile) {
off_t start_offset, header_offset, offset, table_offset;
off_t start_offset, header_offset, test_offset, offset, table_offset;
size_t header_size;
ea_header ea = {0};
int32_t (*read_32bit)(off_t,STREAMFILE*) = NULL;
int16_t (*read_16bit)(off_t,STREAMFILE*) = NULL;
int i, bnk_version;
int total_streams, target_stream = streamFile->stream_index;
int total_streams, real_streams = 0, target_stream = streamFile->stream_index;
/* check extension */
@ -159,27 +159,19 @@ VGMSTREAM * init_vgmstream_ea_bnk(STREAMFILE *streamFile) {
bnk_version = read_8bit(offset + 0x04,streamFile);
total_streams = read_16bit(offset + 0x06,streamFile);
/* check multi-streams */
if (target_stream == 0) target_stream = 1;
if (target_stream < 0 || target_stream > total_streams || total_streams < 1) goto fail;
/* check multi-streams */
switch(bnk_version) {
case 0x02: /* early (Need For Speed PC, Fifa 98 SS) */
table_offset = 0x0c;
header_size = read_32bit(offset + 0x08,streamFile); /* full size */
header_offset = offset + table_offset + 0x04*(target_stream-1) + read_32bit(offset + table_offset + 0x04*(target_stream-1),streamFile);
break;
case 0x04: /* mid (last used in PSX banks) */
case 0x05: /* late (generated by sx.exe ~v2+) */
/* 0x08: header/file size, 0x0C: file size/null, 0x10: always null */
table_offset = 0x14;
if (read_32bit(offset + table_offset,streamFile) == 0x00)
table_offset += 0x4; /* MOH Heroes 2 PSP has an extra empty field, not sure why */
header_size = get_streamfile_size(streamFile); /* unknown (header is variable and may have be garbage until data) */
header_offset = offset + table_offset + 0x04*(target_stream-1) + read_32bit(offset + table_offset + 0x04*(target_stream-1),streamFile);
break;
default:
@ -187,6 +179,22 @@ VGMSTREAM * init_vgmstream_ea_bnk(STREAMFILE *streamFile) {
goto fail;
}
if (target_stream == 0) target_stream = 1;
for (i = 0; i < total_streams; i++) {
/* some of these are dummies with zero offset */
test_offset = read_32bit(offset + table_offset + 0x04 * i, streamFile);
if (test_offset != 0) {
real_streams++;
if (target_stream == real_streams)
header_offset = test_offset + offset + table_offset + 0x04 * i;
}
}
if (target_stream < 0 || target_stream > real_streams || real_streams < 1) goto fail;
if (!parse_variable_header(streamFile,&ea, header_offset, header_size - header_offset))
goto fail;
@ -208,7 +216,7 @@ VGMSTREAM * init_vgmstream_ea_bnk(STREAMFILE *streamFile) {
/* rest is common */
return init_vgmstream_ea_variable_header(streamFile, &ea, start_offset, bnk_version, total_streams);
return init_vgmstream_ea_variable_header(streamFile, &ea, start_offset, bnk_version, real_streams);
fail:
return NULL;