mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-02-21 04:48:21 +01:00
EA HDR: Fixed byte endianness detection
This commit is contained in:
parent
1194fbf618
commit
bf0bfec463
@ -374,12 +374,13 @@ fail:
|
||||
/* EA HDR/STH/DAT - seen in older 7th gen games, used for storing speech */
|
||||
VGMSTREAM * init_vgmstream_ea_hdr_sth_dat(STREAMFILE* sf) {
|
||||
int target_stream = sf->stream_index;
|
||||
uint32_t snr_offset, sns_offset, block_size;
|
||||
uint16_t sth_offset, sth_offset2;
|
||||
uint8_t userdata_size, total_sounds, block_id;
|
||||
off_t snr_offset, sns_offset, sth_offset, sth_offset2;
|
||||
size_t dat_size, block_size;
|
||||
STREAMFILE *datFile = NULL, *sthFile = NULL;
|
||||
size_t dat_size;
|
||||
STREAMFILE *sf_dat = NULL, *sf_sth = NULL;
|
||||
VGMSTREAM *vgmstream;
|
||||
int32_t(*read_32bit)(off_t, STREAMFILE*);
|
||||
uint32_t(*read_u32)(off_t, STREAMFILE*);
|
||||
|
||||
/* 0x00: ID */
|
||||
/* 0x02: parameters (userdata size, ...) */
|
||||
@ -387,46 +388,46 @@ VGMSTREAM * init_vgmstream_ea_hdr_sth_dat(STREAMFILE* sf) {
|
||||
/* 0x04: sub-ID (used for different police voices in NFS games) */
|
||||
/* 0x08: sample repeat (alt number of files?) */
|
||||
/* 0x09: block size (always zero?) */
|
||||
/* 0x0A: number of blocks (related to size?) */
|
||||
/* 0x0C: number of sub-banks (always zero?) */
|
||||
/* 0x0E: padding */
|
||||
/* 0x0a: number of blocks (related to size?) */
|
||||
/* 0x0c: number of sub-banks (always zero?) */
|
||||
/* 0x0e: padding */
|
||||
/* 0x10: table start */
|
||||
|
||||
if (!check_extensions(sf, "hdr"))
|
||||
goto fail;
|
||||
|
||||
if (read_8bit(0x09, sf) != 0)
|
||||
if (read_u8(0x09, sf) != 0)
|
||||
goto fail;
|
||||
|
||||
if (read_32bitBE(0x0c, sf) != 0)
|
||||
if (read_u32be(0x0c, sf) != 0)
|
||||
goto fail;
|
||||
|
||||
/* first offset is always zero */
|
||||
if (read_16bitBE(0x10, sf) != 0)
|
||||
if (read_u16be(0x10, sf) != 0)
|
||||
goto fail;
|
||||
|
||||
sthFile = open_streamfile_by_ext(sf, "sth");
|
||||
if (!sthFile)
|
||||
sf_sth = open_streamfile_by_ext(sf, "sth");
|
||||
if (!sf_sth)
|
||||
goto fail;
|
||||
|
||||
datFile = open_streamfile_by_ext(sf, "dat");
|
||||
if (!datFile)
|
||||
sf_dat = open_streamfile_by_ext(sf, "dat");
|
||||
if (!sf_dat)
|
||||
goto fail;
|
||||
|
||||
/* STH always starts with the first offset of zero */
|
||||
sns_offset = read_32bitBE(0x00, sthFile);
|
||||
sns_offset = read_u32be(0x00, sf_sth);
|
||||
if (sns_offset != 0)
|
||||
goto fail;
|
||||
|
||||
/* check if DAT starts with a correct SNS block */
|
||||
block_id = read_8bit(0x00, datFile);
|
||||
block_id = read_u8(0x00, sf_dat);
|
||||
if (block_id != EAAC_BLOCKID0_DATA && block_id != EAAC_BLOCKID0_END)
|
||||
goto fail;
|
||||
|
||||
userdata_size = read_8bit(0x02, sf);
|
||||
total_sounds = read_8bit(0x03, sf);
|
||||
userdata_size = read_u8(0x02, sf) & 0x0F;
|
||||
total_sounds = read_u8(0x03, sf);
|
||||
|
||||
if (read_8bit(0x08, sf) > total_sounds)
|
||||
if (read_u8(0x08, sf) > total_sounds)
|
||||
goto fail;
|
||||
|
||||
if (target_stream == 0) target_stream = 1;
|
||||
@ -434,14 +435,14 @@ VGMSTREAM * init_vgmstream_ea_hdr_sth_dat(STREAMFILE* sf) {
|
||||
goto fail;
|
||||
|
||||
/* offsets in HDR are always big endian */
|
||||
sth_offset = (uint16_t)read_16bitBE(0x10 + (0x02 + userdata_size) * (target_stream - 1), sf);
|
||||
sth_offset = read_u16be(0x10 + (0x02 + userdata_size) * (target_stream - 1), sf);
|
||||
|
||||
#if 0
|
||||
snr_offset = sth_offset + 0x04;
|
||||
sns_offset = read_32bit(sth_offset + 0x00, sthFile);
|
||||
sns_offset = read_u32(sth_offset + 0x00, sf_sth);
|
||||
#else
|
||||
/* we can't reliably detect byte endianness so we're going to find the sound the hacky way */
|
||||
dat_size = get_streamfile_size(datFile);
|
||||
/* overly intricate way to detect byte endianness because of the simplicity of HDR format */
|
||||
dat_size = get_streamfile_size(sf_dat);
|
||||
snr_offset = 0;
|
||||
sns_offset = 0;
|
||||
|
||||
@ -455,8 +456,8 @@ VGMSTREAM * init_vgmstream_ea_hdr_sth_dat(STREAMFILE* sf) {
|
||||
if (sns_offset >= dat_size)
|
||||
goto fail;
|
||||
|
||||
block_id = read_8bit(sns_offset, datFile);
|
||||
block_size = read_32bitBE(sns_offset, datFile) & 0x00FFFFFF;
|
||||
block_id = read_u8(sns_offset, sf_dat);
|
||||
block_size = read_u32be(sns_offset, sf_dat) & 0x00FFFFFF;
|
||||
if (block_size == 0)
|
||||
goto fail;
|
||||
|
||||
@ -469,36 +470,37 @@ VGMSTREAM * init_vgmstream_ea_hdr_sth_dat(STREAMFILE* sf) {
|
||||
break;
|
||||
}
|
||||
|
||||
sth_offset2 = (uint16_t)read_16bitBE(0x10 + (0x02 + userdata_size) * 1, sf);
|
||||
if (sns_offset == read_32bitBE(sth_offset2, sthFile)) {
|
||||
read_32bit = read_32bitBE;
|
||||
} else if (sns_offset == read_32bitLE(sth_offset2, sthFile)) {
|
||||
read_32bit = read_32bitLE;
|
||||
sns_offset = align_size_to_block(sns_offset, 0x40);
|
||||
sth_offset2 = read_u16be(0x10 + (0x02 + userdata_size) * 1, sf);
|
||||
if (sns_offset == read_u32be(sth_offset2, sf_sth)) {
|
||||
read_u32 = read_u32be;
|
||||
} else if (sns_offset == read_u32le(sth_offset2, sf_sth)) {
|
||||
read_u32 = read_u32le;
|
||||
} else {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
snr_offset = sth_offset + 0x04;
|
||||
sns_offset = read_32bit(sth_offset + 0x00, sthFile);
|
||||
sns_offset = read_u32(sth_offset + 0x00, sf_sth);
|
||||
}
|
||||
#endif
|
||||
|
||||
block_id = read_8bit(sns_offset, datFile);
|
||||
block_id = read_u8(sns_offset, sf_dat);
|
||||
if (block_id != EAAC_BLOCKID0_DATA && block_id != EAAC_BLOCKID0_END)
|
||||
goto fail;
|
||||
|
||||
vgmstream = init_vgmstream_eaaudiocore_header(sthFile, datFile, snr_offset, sns_offset, meta_EA_SNR_SNS, 0);
|
||||
vgmstream = init_vgmstream_eaaudiocore_header(sf_sth, sf_dat, snr_offset, sns_offset, meta_EA_SNR_SNS, 0);
|
||||
if (!vgmstream)
|
||||
goto fail;
|
||||
|
||||
vgmstream->num_streams = total_sounds;
|
||||
close_streamfile(sthFile);
|
||||
close_streamfile(datFile);
|
||||
close_streamfile(sf_sth);
|
||||
close_streamfile(sf_dat);
|
||||
return vgmstream;
|
||||
|
||||
fail:
|
||||
close_streamfile(sthFile);
|
||||
close_streamfile(datFile);
|
||||
close_streamfile(sf_sth);
|
||||
close_streamfile(sf_dat);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user