From 09155bef1ece7c1efe361b82ca59bb36a168444a Mon Sep 17 00:00:00 2001 From: EdnessP <55930127+EdnessP@users.noreply.github.com> Date: Thu, 9 May 2024 03:12:13 +0300 Subject: [PATCH 1/6] EA SBK: sbnk+sdat/BNKx --- 3 | 0 src/formats.c | 1 + src/libvgmstream.vcxproj | 1 + src/libvgmstream.vcxproj.filters | 15 +++--- src/meta/ea_sbk.c | 82 ++++++++++++++++++++++++++++++++ src/meta/ea_schl.c | 4 ++ src/meta/meta.h | 3 ++ src/vgmstream.c | 1 + src/vgmstream_types.h | 1 + 9 files changed, 102 insertions(+), 6 deletions(-) delete mode 100644 3 create mode 100644 src/meta/ea_sbk.c diff --git a/3 b/3 deleted file mode 100644 index e69de29b..00000000 diff --git a/src/formats.c b/src/formats.c index 9cf4ee55..e6b7a579 100644 --- a/src/formats.c +++ b/src/formats.c @@ -1433,6 +1433,7 @@ static const meta_info meta_info_list[] = { {meta_GWB_GWD, "Ubisoft GWB+GWD header"}, {meta_CBX, "Traveller's Tales CBX header"}, {meta_VAS_ROCKSTAR, "Rockstar .VAS header"}, + {meta_EA_SBK, "Electronic Arts SBK header"}, }; void get_vgmstream_coding_description(VGMSTREAM* vgmstream, char* out, size_t out_size) { diff --git a/src/libvgmstream.vcxproj b/src/libvgmstream.vcxproj index 726f87e0..0421dc0c 100644 --- a/src/libvgmstream.vcxproj +++ b/src/libvgmstream.vcxproj @@ -430,6 +430,7 @@ + diff --git a/src/libvgmstream.vcxproj.filters b/src/libvgmstream.vcxproj.filters index 217f50ba..aa0a2b19 100644 --- a/src/libvgmstream.vcxproj.filters +++ b/src/libvgmstream.vcxproj.filters @@ -167,9 +167,6 @@ coding\Header Files - - coding\libs\Header Files - layout\Header Files @@ -416,6 +413,9 @@ util\Header Files + + Header Files + @@ -700,9 +700,6 @@ coding\Source Files - - coding\libs\Source Files - layout\Source Files @@ -1111,6 +1108,9 @@ meta\Source Files + + meta\Source Files + meta\Source Files @@ -2143,5 +2143,8 @@ util\Source Files + + Source Files + \ No newline at end of file diff --git a/src/meta/ea_sbk.c b/src/meta/ea_sbk.c new file mode 100644 index 00000000..1a78d203 --- /dev/null +++ b/src/meta/ea_sbk.c @@ -0,0 +1,82 @@ +#include "meta.h" +#include "../util/endianness.h" + + +/* .SBK - EA Redwood Shores soundbank (Simpsons Game, Godfather) */ +VGMSTREAM* init_vgmstream_ea_sbk(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; + int target_stream = sf->stream_index; + off_t chunk_offset; + size_t chunk_size; + + /* checks */ + if (!is_id32be(0x00, sf, "sbnk") && /* sbnk */ + !is_id32le(0x00, sf, "sbnk")) /* knbs */ + return NULL; + + if (!check_extensions(sf, "sbk")) + return NULL; + + + read_u32_t read_u32 = is_id32be(0x00, sf, "sbnk") ? read_u32le : read_u32be; + + chunk_offset = read_u32(0x10, sf); + chunk_size = read_u32(0x14, sf); + + if (chunk_offset + chunk_size != get_streamfile_size(sf)) + goto fail; + + + if (!target_stream) target_stream = 1; + target_stream -= 1; + + if (is_id32be(chunk_offset, sf, "BNKl") || + is_id32be(chunk_offset, sf, "BNKb")) { + /* The Godfather */ + + vgmstream = load_vgmstream_ea_bnk(sf, chunk_offset, target_stream, 0); /* unsure about is_embedded */ + if (!vgmstream) goto fail; + + vgmstream->meta_type = meta_EA_SBK; + } + else if (is_id32be(chunk_offset, sf, "sdat") || /* sdat */ + is_id32le(chunk_offset, sf, "sdat")) { /* tads */ + /* The Simpsons Game */ + + int total_subsongs; + off_t entry_offset, stream_offset; + + eaac_meta_t info = {0}; + + total_subsongs = read_u32(chunk_offset + 0x04, sf); + entry_offset = chunk_offset + 0x8 + target_stream * 0x10; + + /* For each entry: + * 0x00: stream index + * 0x04: 0x0313BABE (?) + * 0x08: stream offset + * 0x0C: 0xFEEDFEED (?) + */ + + if (read_u32(entry_offset + 0x00, sf) != target_stream) + goto fail; + + stream_offset = chunk_offset + read_u32(entry_offset + 0x08, sf); + + info.sf_head = sf; + info.sf_body = sf; + info.head_offset = stream_offset; + info.type = meta_EA_SBK; + + vgmstream = load_vgmstream_ea_eaac(&info); + if (!vgmstream) goto fail; + + vgmstream->num_streams = total_subsongs; + } + + return vgmstream; + +fail: + close_vgmstream(vgmstream); + return NULL; +} diff --git a/src/meta/ea_schl.c b/src/meta/ea_schl.c index ae4ce262..a536e813 100644 --- a/src/meta/ea_schl.c +++ b/src/meta/ea_schl.c @@ -142,6 +142,10 @@ static off_t get_ea_stream_mpeg_start_offset(STREAMFILE* sf, off_t start_offset, static VGMSTREAM* init_vgmstream_ea_variable_header(STREAMFILE* sf, ea_header* ea, off_t start_offset, int is_bnk); static void update_ea_stream_size(STREAMFILE* sf, off_t start_offset, VGMSTREAM* vgmstream); +VGMSTREAM* load_vgmstream_ea_bnk(STREAMFILE* sf, off_t offset, int target_stream, int is_embedded) { + return parse_bnk_header(sf, offset, target_stream, is_embedded); +} + /* EA SCHl with variable header - from EA games (roughly 1997~2010); generated by EA Canada's sx.exe/Sound eXchange */ VGMSTREAM* init_vgmstream_ea_schl(STREAMFILE* sf) { diff --git a/src/meta/meta.h b/src/meta/meta.h index 72cdb10d..e93036b5 100644 --- a/src/meta/meta.h +++ b/src/meta/meta.h @@ -1004,4 +1004,7 @@ VGMSTREAM* init_vgmstream_cbx(STREAMFILE* sf); VGMSTREAM* init_vgmstream_vas_rockstar(STREAMFILE* sf); +VGMSTREAM* load_vgmstream_ea_bnk(STREAMFILE* sf, off_t offset, int target_stream, int is_embedded); +VGMSTREAM* init_vgmstream_ea_sbk(STREAMFILE* sf); + #endif /*_META_H*/ diff --git a/src/vgmstream.c b/src/vgmstream.c index c0706d1d..24049d62 100644 --- a/src/vgmstream.c +++ b/src/vgmstream.c @@ -523,6 +523,7 @@ init_vgmstream_t init_vgmstream_functions[] = { init_vgmstream_s_pack, init_vgmstream_cbx, init_vgmstream_vas_rockstar, + init_vgmstream_ea_sbk, /* lower priority metas (no clean header identity, somewhat ambiguous, or need extension/companion file to identify) */ init_vgmstream_agsc, diff --git a/src/vgmstream_types.h b/src/vgmstream_types.h index bee11bf2..a236cc1a 100644 --- a/src/vgmstream_types.h +++ b/src/vgmstream_types.h @@ -707,6 +707,7 @@ typedef enum { meta_GWB_GWD, meta_CBX, meta_VAS_ROCKSTAR, + meta_EA_SBK, } meta_t; From 627b397daabd6d890744b579ce2f4c7864c3058b Mon Sep 17 00:00:00 2001 From: EdnessP <55930127+EdnessP@users.noreply.github.com> Date: Thu, 9 May 2024 03:20:39 +0300 Subject: [PATCH 2/6] visual studio doing random things... --- src/libvgmstream.vcxproj.filters | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libvgmstream.vcxproj.filters b/src/libvgmstream.vcxproj.filters index aa0a2b19..a9e47374 100644 --- a/src/libvgmstream.vcxproj.filters +++ b/src/libvgmstream.vcxproj.filters @@ -167,6 +167,9 @@ coding\Header Files + + coding\libs\Header Files + layout\Header Files @@ -413,9 +416,6 @@ util\Header Files - - Header Files - @@ -700,6 +700,9 @@ coding\Source Files + + coding\libs\Source Files + layout\Source Files @@ -2143,8 +2146,5 @@ util\Source Files - - Source Files - \ No newline at end of file From e699c53cf3421fbd111b785b2ea829f4d28cbf83 Mon Sep 17 00:00:00 2001 From: EdnessP <55930127+EdnessP@users.noreply.github.com> Date: Thu, 9 May 2024 03:50:32 +0300 Subject: [PATCH 3/6] EA SBK: Remove unnecessary comment --- src/meta/ea_sbk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/meta/ea_sbk.c b/src/meta/ea_sbk.c index 1a78d203..21fb8d61 100644 --- a/src/meta/ea_sbk.c +++ b/src/meta/ea_sbk.c @@ -34,7 +34,7 @@ VGMSTREAM* init_vgmstream_ea_sbk(STREAMFILE* sf) { is_id32be(chunk_offset, sf, "BNKb")) { /* The Godfather */ - vgmstream = load_vgmstream_ea_bnk(sf, chunk_offset, target_stream, 0); /* unsure about is_embedded */ + vgmstream = load_vgmstream_ea_bnk(sf, chunk_offset, target_stream, 0); if (!vgmstream) goto fail; vgmstream->meta_type = meta_EA_SBK; From 3fdbe757ae41c22830ce7ada9f9394b34862348e Mon Sep 17 00:00:00 2001 From: EdnessP <55930127+EdnessP@users.noreply.github.com> Date: Thu, 9 May 2024 05:31:44 +0300 Subject: [PATCH 4/6] EA SBK: Safety checks --- src/meta/ea_sbk.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/meta/ea_sbk.c b/src/meta/ea_sbk.c index 21fb8d61..5496db6a 100644 --- a/src/meta/ea_sbk.c +++ b/src/meta/ea_sbk.c @@ -27,7 +27,8 @@ VGMSTREAM* init_vgmstream_ea_sbk(STREAMFILE* sf) { goto fail; - if (!target_stream) target_stream = 1; + if (target_stream < 0) goto fail; + if (target_stream == 0) target_stream = 1; target_stream -= 1; if (is_id32be(chunk_offset, sf, "BNKl") || @@ -43,12 +44,16 @@ VGMSTREAM* init_vgmstream_ea_sbk(STREAMFILE* sf) { is_id32le(chunk_offset, sf, "sdat")) { /* tads */ /* The Simpsons Game */ - int total_subsongs; + int total_streams; off_t entry_offset, stream_offset; eaac_meta_t info = {0}; - total_subsongs = read_u32(chunk_offset + 0x04, sf); + + total_streams = read_u32(chunk_offset + 0x04, sf); + if (total_streams < 1 || target_stream + 1 > total_streams) + goto fail; + entry_offset = chunk_offset + 0x8 + target_stream * 0x10; /* For each entry: @@ -57,7 +62,6 @@ VGMSTREAM* init_vgmstream_ea_sbk(STREAMFILE* sf) { * 0x08: stream offset * 0x0C: 0xFEEDFEED (?) */ - if (read_u32(entry_offset + 0x00, sf) != target_stream) goto fail; @@ -66,12 +70,17 @@ VGMSTREAM* init_vgmstream_ea_sbk(STREAMFILE* sf) { info.sf_head = sf; info.sf_body = sf; info.head_offset = stream_offset; + //info.body_offset info.type = meta_EA_SBK; vgmstream = load_vgmstream_ea_eaac(&info); if (!vgmstream) goto fail; - vgmstream->num_streams = total_subsongs; + vgmstream->num_streams = total_streams; + } + else { + VGM_LOG("EA SBK: unsupported sound data block\n"); + goto fail; } return vgmstream; From 70272bf73bf1553396031160ce8c3c7958c5ad8c Mon Sep 17 00:00:00 2001 From: EdnessP <55930127+EdnessP@users.noreply.github.com> Date: Thu, 9 May 2024 13:19:14 +0300 Subject: [PATCH 5/6] EA SBK: misc changes --- src/meta/ea_sbk.c | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/src/meta/ea_sbk.c b/src/meta/ea_sbk.c index 5496db6a..34fd5e50 100644 --- a/src/meta/ea_sbk.c +++ b/src/meta/ea_sbk.c @@ -6,8 +6,9 @@ VGMSTREAM* init_vgmstream_ea_sbk(STREAMFILE* sf) { VGMSTREAM* vgmstream = NULL; int target_stream = sf->stream_index; - off_t chunk_offset; - size_t chunk_size; + off_t sdat_offset; + size_t sdat_size; + read_u32_t read_u32; /* checks */ if (!is_id32be(0x00, sf, "sbnk") && /* sbnk */ @@ -18,12 +19,14 @@ VGMSTREAM* init_vgmstream_ea_sbk(STREAMFILE* sf) { return NULL; - read_u32_t read_u32 = is_id32be(0x00, sf, "sbnk") ? read_u32le : read_u32be; + read_u32 = is_id32be(0x00, sf, "sbnk") ? read_u32le : read_u32be; - chunk_offset = read_u32(0x10, sf); - chunk_size = read_u32(0x14, sf); + sdat_offset = read_u32(0x10, sf); + sdat_size = read_u32(0x14, sf); - if (chunk_offset + chunk_size != get_streamfile_size(sf)) + /* lots of other unk data between here and the sdat chunk */ + + if (sdat_offset + sdat_size != get_streamfile_size(sf)) goto fail; @@ -31,17 +34,17 @@ VGMSTREAM* init_vgmstream_ea_sbk(STREAMFILE* sf) { if (target_stream == 0) target_stream = 1; target_stream -= 1; - if (is_id32be(chunk_offset, sf, "BNKl") || - is_id32be(chunk_offset, sf, "BNKb")) { + if (is_id32be(sdat_offset, sf, "BNKl") || + is_id32be(sdat_offset, sf, "BNKb")) { /* The Godfather */ - vgmstream = load_vgmstream_ea_bnk(sf, chunk_offset, target_stream, 0); + vgmstream = load_vgmstream_ea_bnk(sf, sdat_offset, target_stream, 0); if (!vgmstream) goto fail; vgmstream->meta_type = meta_EA_SBK; } - else if (is_id32be(chunk_offset, sf, "sdat") || /* sdat */ - is_id32le(chunk_offset, sf, "sdat")) { /* tads */ + else if (is_id32be(sdat_offset, sf, "sdat") || /* sdat */ + is_id32le(sdat_offset, sf, "sdat")) { /* tads */ /* The Simpsons Game */ int total_streams; @@ -50,22 +53,20 @@ VGMSTREAM* init_vgmstream_ea_sbk(STREAMFILE* sf) { eaac_meta_t info = {0}; - total_streams = read_u32(chunk_offset + 0x04, sf); + total_streams = read_u32(sdat_offset + 0x04, sf); if (total_streams < 1 || target_stream + 1 > total_streams) goto fail; - entry_offset = chunk_offset + 0x8 + target_stream * 0x10; - /* For each entry: * 0x00: stream index * 0x04: 0x0313BABE (?) * 0x08: stream offset * 0x0C: 0xFEEDFEED (?) */ - if (read_u32(entry_offset + 0x00, sf) != target_stream) - goto fail; + entry_offset = sdat_offset + 0x08 + target_stream * 0x10; - stream_offset = chunk_offset + read_u32(entry_offset + 0x08, sf); + if (read_u32(entry_offset + 0x00, sf) != target_stream) goto fail; + stream_offset = sdat_offset + read_u32(entry_offset + 0x08, sf); info.sf_head = sf; info.sf_body = sf; @@ -79,7 +80,7 @@ VGMSTREAM* init_vgmstream_ea_sbk(STREAMFILE* sf) { vgmstream->num_streams = total_streams; } else { - VGM_LOG("EA SBK: unsupported sound data block\n"); + VGM_LOG("EA SBK: unsupported sound data chunk\n"); goto fail; } From 17fe0be8773005d524b89c086575d810cfb96665 Mon Sep 17 00:00:00 2001 From: EdnessP <55930127+EdnessP@users.noreply.github.com> Date: Thu, 9 May 2024 19:48:08 +0300 Subject: [PATCH 6/6] EA SBK: Confirm LE sdat chunks exist (Godfather II) --- src/meta/ea_sbk.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/meta/ea_sbk.c b/src/meta/ea_sbk.c index 34fd5e50..f880f5f4 100644 --- a/src/meta/ea_sbk.c +++ b/src/meta/ea_sbk.c @@ -21,11 +21,14 @@ VGMSTREAM* init_vgmstream_ea_sbk(STREAMFILE* sf) { read_u32 = is_id32be(0x00, sf, "sbnk") ? read_u32le : read_u32be; + /* sdat_size is stored at 0x0C too? */ sdat_offset = read_u32(0x10, sf); sdat_size = read_u32(0x14, sf); /* lots of other unk data between here and the sdat chunk */ + if (read_u32(0x0C, sf) != sdat_size) + goto fail; if (sdat_offset + sdat_size != get_streamfile_size(sf)) goto fail; @@ -45,7 +48,7 @@ VGMSTREAM* init_vgmstream_ea_sbk(STREAMFILE* sf) { } else if (is_id32be(sdat_offset, sf, "sdat") || /* sdat */ is_id32le(sdat_offset, sf, "sdat")) { /* tads */ - /* The Simpsons Game */ + /* The Simpsons Game, The Godfather II */ int total_streams; off_t entry_offset, stream_offset;