EA ABK: Redwood Shores AMB/AMX variant

This commit is contained in:
EdnessP 2024-07-03 13:00:13 +03:00
parent 272fd2eac6
commit 8db6820f65
5 changed files with 164 additions and 6 deletions

View File

@ -62,7 +62,9 @@ static const char* extension_list[] = {
"akb",
"al", //txth/raw [Dominions 3 - The Awakening (PC)]
"al2", //txth/raw [Conquest of Elysium 3 (PC)]
"amb",
"ams", //txth/reserved [Super Dragon Ball Z (PS2) ELF names]
"amx",
"an2",
"ao",
"ap",

View File

@ -1,11 +1,66 @@
#include "meta.h"
#include "../util/endianness.h"
static VGMSTREAM* init_vgmstream_ea_abk_eaac_main(STREAMFILE* sf);
static VGMSTREAM* parse_s10a_header(STREAMFILE* sf, off_t offset, uint16_t target_index, off_t ast_offset);
/* .ABK - standard */
VGMSTREAM* init_vgmstream_ea_abk_eaac(STREAMFILE* sf) {
if (!check_extensions(sf, "abk"))
return NULL;
return init_vgmstream_ea_abk_eaac_main(sf);
}
/* .AMB/AMX - EA Redwood Shores variant [The Godfather (PS3/X360), The Simpsons Game (PS3/360)] */
VGMSTREAM* init_vgmstream_ea_amb_eaac(STREAMFILE* sf) {
/* container with .ABK ("ABKC") and .CSI ("MOIR") data */
VGMSTREAM* vgmstream = NULL;
STREAMFILE* sf_abk = NULL;
off_t abk_offset;
size_t abk_size;
read_u32_t read_u32;
if (!check_extensions(sf, "amb,amx"))
return NULL;
read_u32 = guess_read_u32(0x00, sf);
if (read_u32(0x00, sf) != 0x09) /* version? */
return NULL;
abk_offset = 0x40;
/* 0x04: MOIR offset (+ abk_offset)
* 0x08: MOIR size
* 0x0C: unk offset (same as MOIR)
* 0x10: unk size (always 0?)
* 0x14: unk (some hash?)
* 0x18: always 1.0f?
* 0x1C: always 2.0f?
* 0x20: always 100.0f?
* 0x24: unk (some bitfield? sometimes 0x10000)
*/
abk_size = read_u32(0x04, sf);
if (read_u32(0x0C, sf) != abk_size)
goto fail;
sf_abk = open_wrap_streamfile(sf);
sf_abk = open_clamp_streamfile(sf_abk, abk_offset, abk_size);
if (!sf_abk) goto fail;
vgmstream = init_vgmstream_ea_abk_eaac_main(sf_abk);
if (!vgmstream) goto fail;
close_streamfile(sf_abk);
return vgmstream;
fail:
close_vgmstream(vgmstream);
close_streamfile(sf_abk);
return NULL;
}
/* EA ABK - ABK header seems to be same as in the old games but the sound table is different and it contains SNR/SNS sounds instead */
VGMSTREAM* init_vgmstream_ea_abk_eaac(STREAMFILE* sf) {
static VGMSTREAM* init_vgmstream_ea_abk_eaac_main(STREAMFILE* sf) {
VGMSTREAM* vgmstream;
int is_dupe, total_sounds = 0, target_stream = sf->stream_index;
off_t bnk_offset, modules_table, module_data, player_offset, samples_table, entry_offset, ast_offset;
@ -21,8 +76,6 @@ VGMSTREAM* init_vgmstream_ea_abk_eaac(STREAMFILE* sf) {
/* checks */
if (!is_id32be(0x00, sf, "ABKC"))
return NULL;
if (!check_extensions(sf, "abk"))
return NULL;
/* use table offset to check endianness */
if (guess_endian32(0x1C, sf)) {

View File

@ -7,10 +7,111 @@
#define EA_BNK_HEADER_LE 0x424E4B6C /* "BNKl" */
#define EA_BNK_HEADER_BE 0x424E4B62 /* "BNKb" */
static VGMSTREAM* init_vgmstream_ea_abk_schl_main(STREAMFILE* sf);
/* .ABK - standard */
VGMSTREAM* init_vgmstream_ea_abk_schl(STREAMFILE* sf) {
if (!check_extensions(sf, "abk"))
return NULL;
return init_vgmstream_ea_abk_schl_main(sf);
}
/* .AMB/AMX - EA Redwood Shores variant [007: From Russia with Love, The Godfather (PC/PS2/Wii)] */
VGMSTREAM* init_vgmstream_ea_amb_schl(STREAMFILE* sf) {
/* container with .ABK ("ABKC") and .CSI ("MOIR") data */
VGMSTREAM* vgmstream = NULL;
STREAMFILE* sf_abk = NULL;
off_t abk_offset, header_offset = 0x00;
size_t abk_size;
uint32_t version;
read_u32_t read_u32;
if (!check_extensions(sf, "amb,amx"))
return NULL;
/* 0x08 covers both v4-v8 and v9 */
read_u32 = guess_read_u32(0x08, sf);
if (read_u64le(0x00, sf) == 0) {
header_offset = read_u32(0x08, sf);
if (header_offset > 0x40) /* 0x20 (v4), 0x30/0x40 (v8) */
return NULL;
version = read_u32(header_offset, sf);
if (version != 0x04 && version != 0x08)
return NULL;
}
else if (read_u32(0x00, sf) != 0x09)
return NULL;
version = read_u32(header_offset + 0x00, sf);
abk_offset = header_offset + (version > 0x04 ? 0x40 : 0x20);
/* Version 0x04: [007: From Russia with Love (Demo)]
* 0x04: MOIR offset (+ abk offset)
* 0x08: unk (always 0?)
* 0x0C: unk (some hash?)
* 0x10: always 2.0f?
* 0x14: always 2.0f?
* 0x18: always 100.0f?
* 0x1C: unk (some bools? 0x0101)
* 0x20: ABKC data
*/
/* Version 0x08: [007: From Russia with Love]
* 0x04: MOIR offset (+ abk offset)
* 0x08: unk offset (same as MOIR)
* 0x0C: unk (always 0?)
* 0x10: unk (some hash?)
* 0x14: usually 2.0f? sometimes 1.0f or 5.0f
* 0x18: always 2.0f?
* 0x1C: usually 75.0f? sometimes 100.0f or 1000.0f
* 0x20: unk (some bools? 0x0101)
* 0x40: ABKC data
*/
/* Version 0x09: [The Godfather]
* 0x04: MOIR offset (+ abk_offset)
* 0x08: MOIR size
* 0x0C: unk offset (same as MOIR, usually)
* 0x10: unk size (always 0?)
* 0x14: unk (some hash?)
* 0x18: always 1.0f?
* 0x1C: always 2.0f?
* 0x20: always 100.0f?
* 0x24: unk (some bools? sometimes 0x010000)
* 0x40: ABKC data
*/
abk_size = read_u32(header_offset + 0x04, sf);
if (abk_size > get_streamfile_size(sf))
goto fail;
/* in case stricter checks are needed: */
//if (!is_id32be(abk_offset + abk_size, sf, "MOIR"))
// goto fail;
/* (v9) rarely some other bad(?) value [The Godfather (PS2)] */
//if (read_u32(0x0C, sf) != abk_size) goto fail;
sf_abk = open_wrap_streamfile(sf);
sf_abk = open_clamp_streamfile(sf_abk, abk_offset, abk_size);
if (!sf_abk) goto fail;
vgmstream = init_vgmstream_ea_abk_schl_main(sf_abk);
if (!vgmstream) goto fail;
close_streamfile(sf_abk);
return vgmstream;
fail:
close_vgmstream(vgmstream);
close_streamfile(sf_abk);
return NULL;
}
/* EA ABK - common soundbank format in 6th-gen games, can reference RAM and streamed assets */
/* RAM assets are stored in embedded BNK file */
/* streamed assets are stored externally in AST file (mostly seen in earlier 6th-gen games) */
VGMSTREAM* init_vgmstream_ea_abk_schl(STREAMFILE* sf) {
static VGMSTREAM* init_vgmstream_ea_abk_schl_main(STREAMFILE* sf) {
int bnk_target_stream, is_dupe, total_sounds = 0, target_stream = sf->stream_index;
off_t bnk_offset, modules_table, module_data, player_offset, samples_table, entry_offset, target_entry_offset, schl_offset, schl_loop_offset;
uint32_t i, j, k, num_sounds, num_sample_tables;
@ -26,8 +127,6 @@ VGMSTREAM* init_vgmstream_ea_abk_schl(STREAMFILE* sf) {
/* check extension */
if (!is_id32be(0x00, sf, "ABKC"))
return NULL;
if (!check_extensions(sf, "abk"))
return NULL;
/* use table offset to check endianness */
if (guess_endian32(0x1C, sf)) {

View File

@ -604,6 +604,7 @@ VGMSTREAM * init_vgmstream_ea_schl(STREAMFILE *streamFile);
VGMSTREAM * init_vgmstream_ea_schl_video(STREAMFILE *streamFile);
VGMSTREAM * init_vgmstream_ea_bnk(STREAMFILE * streamFile);
VGMSTREAM * init_vgmstream_ea_abk_schl(STREAMFILE * streamFile);
VGMSTREAM * init_vgmstream_ea_amb_schl(STREAMFILE * streamFile);
VGMSTREAM * init_vgmstream_ea_hdr_dat(STREAMFILE * streamFile);
VGMSTREAM * init_vgmstream_ea_hdr_dat_v2(STREAMFILE * streamFile);
VGMSTREAM * init_vgmstream_ea_map_mus(STREAMFILE * streamFile);
@ -653,6 +654,7 @@ VGMSTREAM * init_vgmstream_ea_snu(STREAMFILE * streamFile);
VGMSTREAM * init_vgmstream_ea_snr_sns(STREAMFILE * streamFile);
VGMSTREAM * init_vgmstream_ea_sps(STREAMFILE * streamFile);
VGMSTREAM * init_vgmstream_ea_abk_eaac(STREAMFILE * streamFile);
VGMSTREAM * init_vgmstream_ea_amb_eaac(STREAMFILE * streamFile);
VGMSTREAM * init_vgmstream_ea_hdr_sth_dat(STREAMFILE * streamFile);
VGMSTREAM * init_vgmstream_ea_mpf_mus_eaac(STREAMFILE * streamFile);
VGMSTREAM * init_vgmstream_ea_msb_mus_eaac(STREAMFILE * streamFile);

View File

@ -291,6 +291,7 @@ init_vgmstream_t init_vgmstream_functions[] = {
init_vgmstream_xa_04sw,
init_vgmstream_ea_bnk,
init_vgmstream_ea_abk_schl,
init_vgmstream_ea_amb_schl,
init_vgmstream_ea_hdr_dat,
init_vgmstream_ea_hdr_dat_v2,
init_vgmstream_ea_map_mus,
@ -321,6 +322,7 @@ init_vgmstream_t init_vgmstream_functions[] = {
init_vgmstream_ea_snr_sns,
init_vgmstream_ea_sps,
init_vgmstream_ea_abk_eaac,
init_vgmstream_ea_amb_eaac,
init_vgmstream_ea_hdr_sth_dat,
init_vgmstream_ea_mpf_mus_eaac,
init_vgmstream_ea_msb_mus_eaac,