mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-01-17 23:36:41 +01:00
Further work on the new ABK format
This commit is contained in:
parent
5ee34e32ff
commit
39284cf233
@ -7,7 +7,7 @@
|
||||
|
||||
static VGMSTREAM * init_vgmstream_eaaudiocore_header(STREAMFILE * streamHead, STREAMFILE * streamData, off_t header_offset, off_t start_offset, meta_t meta_type);
|
||||
static size_t get_snr_size(STREAMFILE *streamFile, off_t offset);
|
||||
static VGMSTREAM *parse_s10a_header(STREAMFILE *streamFile, off_t offset, uint16_t target_index);
|
||||
static VGMSTREAM *parse_s10a_header(STREAMFILE *streamFile, off_t offset, uint16_t target_index, off_t ast_offset);
|
||||
|
||||
/* .SNR+SNS - from EA latest games (~2008-2013), v0 header */
|
||||
VGMSTREAM * init_vgmstream_ea_snr_sns(STREAMFILE * streamFile) {
|
||||
@ -251,12 +251,14 @@ fail:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* EA ABK - ABK header seems to be same as in the old games but the sound table is different and it contains SNR/SNS sounds instead */
|
||||
VGMSTREAM * init_vgmstream_ea_abk_new(STREAMFILE *streamFile) {
|
||||
int is_dupe, total_sounds = 0, target_stream = streamFile->stream_index;
|
||||
off_t bnk_offset, header_table_offset, base_offset, value_offset, table_offset, entry_offset;
|
||||
off_t bnk_offset, header_table_offset, base_offset, unk_struct_offset, table_offset, snd_entry_offset, ast_offset;
|
||||
off_t num_entries_off, base_offset_off, entries_off, sound_table_offset_off;
|
||||
uint32_t i, j, k, version, num_sounds, total_sound_tables;
|
||||
uint16_t num_tables, bnk_index, bnk_target_index;
|
||||
uint8_t num_entries;
|
||||
uint8_t num_entries, extra_entries;
|
||||
off_t sound_table_offsets[0x2000];
|
||||
STREAMFILE *astData = NULL;
|
||||
VGMSTREAM *vgmstream;
|
||||
@ -293,13 +295,34 @@ VGMSTREAM * init_vgmstream_ea_abk_new(STREAMFILE *streamFile) {
|
||||
total_sound_tables = 0;
|
||||
bnk_target_index = 0xFFFF;
|
||||
|
||||
/* set up some common values */
|
||||
if (header_table_offset == 0x5C) {
|
||||
/* the usual variant */
|
||||
num_entries_off = 0x24;
|
||||
base_offset_off = 0x2C;
|
||||
entries_off = 0x3C;
|
||||
sound_table_offset_off = 0x04;
|
||||
}
|
||||
else if (header_table_offset == 0x78) {
|
||||
/* FIFA 08 has a bunch of extra zeroes all over the place, don't know what's up with that */
|
||||
num_entries_off = 0x40;
|
||||
base_offset_off = 0x54;
|
||||
entries_off = 0x68;
|
||||
sound_table_offset_off = 0x0C;
|
||||
}
|
||||
else {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_tables; i++) {
|
||||
num_entries = read_8bit(header_table_offset + 0x24, streamFile);
|
||||
base_offset = read_32bit(header_table_offset + 0x2C, streamFile);
|
||||
num_entries = read_8bit(header_table_offset + num_entries_off, streamFile);
|
||||
extra_entries = read_8bit(header_table_offset + num_entries_off + 0x03, streamFile);
|
||||
base_offset = read_32bit(header_table_offset + base_offset_off, streamFile);
|
||||
if (num_entries == 0xff) goto fail; /* EOF read */
|
||||
|
||||
for (j = 0; j < num_entries; j++) {
|
||||
value_offset = read_32bit(header_table_offset + 0x3C + 0x04 * j, streamFile);
|
||||
table_offset = read_32bit(base_offset + value_offset + 0x04, streamFile);
|
||||
unk_struct_offset = read_32bit(header_table_offset + entries_off + 0x04 * j, streamFile);
|
||||
table_offset = read_32bit(base_offset + unk_struct_offset + sound_table_offset_off, streamFile);
|
||||
|
||||
/* For some reason, there are duplicate entries pointing at the same sound tables */
|
||||
is_dupe = 0;
|
||||
@ -317,28 +340,35 @@ VGMSTREAM * init_vgmstream_ea_abk_new(STREAMFILE *streamFile) {
|
||||
|
||||
sound_table_offsets[total_sound_tables++] = table_offset;
|
||||
num_sounds = read_32bit(table_offset, streamFile);
|
||||
if (num_sounds == 0xffffffff) goto fail; /* EOF read */
|
||||
|
||||
for (k = 0; k < num_sounds; k++) {
|
||||
entry_offset = table_offset + 0x04 + 0x0C * k;
|
||||
bnk_index = read_16bit(entry_offset + 0x00, streamFile);
|
||||
/* 0x00: sound index */
|
||||
/* 0x02: ??? */
|
||||
/* 0x04: ??? */
|
||||
/* 0x08: streamed data offset */
|
||||
snd_entry_offset = table_offset + 0x04 + 0x0C * k;
|
||||
bnk_index = read_16bit(snd_entry_offset + 0x00, streamFile);
|
||||
|
||||
/* some of these are dummies */
|
||||
if (bnk_index == 0xFFFF)
|
||||
continue;
|
||||
|
||||
total_sounds++;
|
||||
if (target_stream == total_sounds)
|
||||
if (target_stream == total_sounds) {
|
||||
bnk_target_index = bnk_index;
|
||||
ast_offset = read_32bit(snd_entry_offset + 0x08, streamFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
header_table_offset += 0x3C + num_entries * 0x04;
|
||||
header_table_offset += entries_off + num_entries * 0x04 + extra_entries * 0x04;
|
||||
}
|
||||
|
||||
if (bnk_target_index == 0xFFFF)
|
||||
goto fail;
|
||||
|
||||
vgmstream = parse_s10a_header(streamFile, bnk_offset, bnk_target_index);
|
||||
vgmstream = parse_s10a_header(streamFile, bnk_offset, bnk_target_index, ast_offset);
|
||||
if (!vgmstream)
|
||||
goto fail;
|
||||
|
||||
@ -350,9 +380,11 @@ fail:
|
||||
}
|
||||
|
||||
/* EA S10A header - seen inside new ABK files. Putting it here in case it's encountered stand-alone. */
|
||||
static VGMSTREAM * parse_s10a_header(STREAMFILE *streamFile, off_t offset, uint16_t target_index) {
|
||||
static VGMSTREAM * parse_s10a_header(STREAMFILE *streamFile, off_t offset, uint16_t target_index, off_t ast_offset) {
|
||||
uint32_t header, num_sounds;
|
||||
off_t snr_offset, sns_offset;
|
||||
STREAMFILE *astFile = NULL;
|
||||
VGMSTREAM *vgmstream;
|
||||
|
||||
/* header is always big endian */
|
||||
/* 0x00 - header magic */
|
||||
@ -368,11 +400,35 @@ static VGMSTREAM * parse_s10a_header(STREAMFILE *streamFile, off_t offset, uint1
|
||||
goto fail;
|
||||
|
||||
snr_offset = offset + read_32bitBE(offset + 0x0C + 0x04 * target_index, streamFile);
|
||||
sns_offset = snr_offset + get_snr_size(streamFile, snr_offset);
|
||||
|
||||
return init_vgmstream_eaaudiocore_header(streamFile, streamFile, snr_offset, sns_offset, meta_EA_SNR_SNS);
|
||||
if (ast_offset == 0xFFFFFFFF) {
|
||||
/* RAM asset */
|
||||
sns_offset = snr_offset + get_snr_size(streamFile, snr_offset);
|
||||
vgmstream = init_vgmstream_eaaudiocore_header(streamFile, streamFile, snr_offset, sns_offset, meta_EA_SNR_SNS);
|
||||
if (!vgmstream)
|
||||
goto fail;
|
||||
}
|
||||
else {
|
||||
/* streamed asset */
|
||||
astFile = open_streamfile_by_ext(streamFile, "ast");
|
||||
if (!astFile)
|
||||
goto fail;
|
||||
|
||||
if (read_32bitBE(0x00, astFile) != 0x53313053) /* "S10S" */
|
||||
goto fail;
|
||||
|
||||
sns_offset = ast_offset;
|
||||
vgmstream = init_vgmstream_eaaudiocore_header(streamFile, astFile, snr_offset, sns_offset, meta_EA_SNR_SNS);
|
||||
if (!vgmstream)
|
||||
goto fail;
|
||||
|
||||
close_streamfile(astFile);
|
||||
}
|
||||
|
||||
return vgmstream;
|
||||
|
||||
fail:
|
||||
close_streamfile(astFile);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user