From f76dc31146f13a61976ca1b4c9f5898fcfb77d2a Mon Sep 17 00:00:00 2001 From: bnnm Date: Sun, 31 Dec 2023 02:08:26 +0100 Subject: [PATCH] Fix some .snu [Dead Space 3 (PC)] --- src/meta/ea_eaac.c | 9 +++++---- src/meta/ea_eaac_standard.c | 29 ++++++++++++++++++++++++----- src/meta/meta.h | 1 + 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/meta/ea_eaac.c b/src/meta/ea_eaac.c index c1f667c5..b2681aaa 100644 --- a/src/meta/ea_eaac.c +++ b/src/meta/ea_eaac.c @@ -40,10 +40,11 @@ #define EAAC_BLOCKID1_DATA 0x44 /* 'D' */ #define EAAC_BLOCKID1_END 0x45 /* 'E' */ -static VGMSTREAM* init_vgmstream_eaaudiocore_header(STREAMFILE* sf_head, STREAMFILE* sf_data, off_t header_offset, off_t start_offset, meta_t meta_type, bool standalone); +static VGMSTREAM* init_vgmstream_eaaudiocore_header(STREAMFILE* sf_head, STREAMFILE* sf_data, off_t header_offset, off_t start_offset, meta_t meta_type, bool standalone, bool is_sps); VGMSTREAM* load_vgmstream_ea_eaac(eaac_meta_t* info) { - return init_vgmstream_eaaudiocore_header(info->sf_head, info->sf_body, info->head_offset, info->body_offset, info->type, info->standalone); + info->is_sps = info->is_sps || info->type == meta_EA_SPS; + return init_vgmstream_eaaudiocore_header(info->sf_head, info->sf_body, info->head_offset, info->body_offset, info->type, info->standalone, info->is_sps); } @@ -77,12 +78,12 @@ static VGMSTREAM* init_vgmstream_eaaudiocore_main(eaac_header_t* eaac, STREAMFIL * Audio "assets" come in separate RAM headers (.SNR/SPH) and raw blocked streams (.SNS/SPS), * or together in pseudoformats (.SNU, .SBR+.SBS banks, .AEMS, .MUS, etc). * Some .SNR include stream data, while .SPS have headers so .SPH is optional. */ -static VGMSTREAM* init_vgmstream_eaaudiocore_header(STREAMFILE* sf_head, STREAMFILE* sf_data, off_t header_offset, off_t start_offset, meta_t meta_type, bool standalone) { +static VGMSTREAM* init_vgmstream_eaaudiocore_header(STREAMFILE* sf_head, STREAMFILE* sf_data, off_t header_offset, off_t start_offset, meta_t meta_type, bool standalone, bool is_sps) { eaac_header_t eaac = {0}; /* SPS put the header in the first block */ uint32_t header_block_size = 0; - if (meta_type == meta_EA_SPS) { + if (is_sps) { uint32_t header_block_info = read_u32be(header_offset, sf_head); uint8_t header_block_id; diff --git a/src/meta/ea_eaac_standard.c b/src/meta/ea_eaac_standard.c index 9cc83aec..292a83a4 100644 --- a/src/meta/ea_eaac_standard.c +++ b/src/meta/ea_eaac_standard.c @@ -2,6 +2,9 @@ #include "../util/endianness.h" +#define EAAC_BLOCKID1_HEADER 0x48 /* 'H' */ + + /* .SNR+SNS - from EA latest games (~2005-2010), v0 header */ VGMSTREAM* init_vgmstream_ea_snr_sns(STREAMFILE* sf) { eaac_meta_t info = {0}; @@ -23,6 +26,8 @@ VGMSTREAM* init_vgmstream_ea_sps(STREAMFILE* sf) { eaac_meta_t info = {0}; /* checks */ + if (read_u8(0x00, sf) != EAAC_BLOCKID1_HEADER) /* validated later but fails faster */ + return NULL; if (!check_extensions(sf,"sps")) return NULL; @@ -54,10 +59,24 @@ VGMSTREAM* init_vgmstream_ea_snu(STREAMFILE* sf) { /* use start offset as endianness flag */ read_u32 = guess_read_u32(0x08,sf); - info.sf_head = sf; - info.sf_body = sf; - info.head_offset = 0x10; /* SNR header */ - info.body_offset = read_u32(0x08,sf); /* SNS blocks */ - info.type = meta_EA_SNU; + 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; + } + return load_vgmstream_ea_eaac(&info); } diff --git a/src/meta/meta.h b/src/meta/meta.h index e487637a..f6e311f1 100644 --- a/src/meta/meta.h +++ b/src/meta/meta.h @@ -657,6 +657,7 @@ typedef struct { uint32_t body_offset; meta_t type; bool standalone; + bool is_sps; } eaac_meta_t; VGMSTREAM* load_vgmstream_ea_eaac(eaac_meta_t* info);