mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-11-29 00:34:33 +01:00
Handle dummy streams in EA BNK files
This commit is contained in:
parent
e2160f4e09
commit
5b27c21a0b
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user