diff --git a/src/meta/ea_eaac.c b/src/meta/ea_eaac.c index 5c433220..99c834b3 100644 --- a/src/meta/ea_eaac.c +++ b/src/meta/ea_eaac.c @@ -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; }