vgmstream/src/meta/ea_eaac_standard.c

83 lines
2.4 KiB
C
Raw Normal View History

2023-12-31 01:23:13 +01:00
#include "meta.h"
#include "../util/endianness.h"
2023-12-31 02:08:26 +01:00
#define EAAC_BLOCKID1_HEADER 0x48 /* 'H' */
2023-12-31 01:23:13 +01:00
/* .SNR+SNS - from EA latest games (~2005-2010), v0 header */
VGMSTREAM* init_vgmstream_ea_snr_sns(STREAMFILE* sf) {
eaac_meta_t info = {0};
/* checks */
if (!check_extensions(sf,"snr"))
return NULL;
info.sf_head = sf;
info.head_offset = 0x00;
info.body_offset = 0x00;
info.type = meta_EA_SNR_SNS;
info.standalone = true;
return load_vgmstream_ea_eaac(&info);
}
/* .SPS - from EA latest games (~2010~present), v1 header */
VGMSTREAM* init_vgmstream_ea_sps(STREAMFILE* sf) {
eaac_meta_t info = {0};
/* checks */
2023-12-31 02:08:26 +01:00
if (read_u8(0x00, sf) != EAAC_BLOCKID1_HEADER) /* validated later but fails faster */
return NULL;
2023-12-31 01:23:13 +01:00
if (!check_extensions(sf,"sps"))
return NULL;
info.sf_head = sf;
info.head_offset = 0x00;
info.type = meta_EA_SPS;
info.standalone = true;
return load_vgmstream_ea_eaac(&info);
}
/* .SNU - from EA Redwood Shores/Visceral games (Dead Space, Dante's Inferno, The Godfather 2), v0 header */
VGMSTREAM* init_vgmstream_ea_snu(STREAMFILE* sf) {
eaac_meta_t info = {0};
read_u32_t read_u32 = NULL;
/* checks */
if (!check_extensions(sf,"snu"))
return NULL;
/* EA SNU header (BE/LE depending on platform) */
/* 0x00(1): related to sample rate? (03=48000)
* 0x01(1): flags/count? (when set has extra block data before start_offset)
* 0x02(1): always 0?
* 0x03(1): channels? (usually matches but rarely may be 0)
* 0x04(4): some size, maybe >>2 ~= number of frames
* 0x08(4): start offset
* 0x0c(4): some sub-offset? (0x20, found when @0x01 is set) */
/* use start offset as endianness flag */
read_u32 = guess_read_u32(0x08,sf);
2023-12-31 02:08:26 +01:00
uint32_t body_offset = read_u32(0x08,sf);
uint8_t block_id = read_u8(body_offset, sf);
if (block_id == EAAC_BLOCKID1_HEADER) {
/* Dead Space 3 (PC) */
info.sf_head = sf;
info.head_offset = body_offset; /* header also at 0x10, but useless in SPS */
info.type = meta_EA_SNU;
info.is_sps = true;
}
else {
info.sf_head = sf;
info.sf_body = sf;
info.head_offset = 0x10; /* SNR header */
info.body_offset = body_offset; /* SNR body */
info.type = meta_EA_SNU;
}
2023-12-31 01:23:13 +01:00
return load_vgmstream_ea_eaac(&info);
}