mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-01-29 19:37:30 +01:00
Add SCHl .hab/gsf/abk and custom mpf+mus pairs, remove trj/trm map pair
This commit is contained in:
parent
7211e0e0ec
commit
49628d6198
@ -156,10 +156,12 @@ static const char* extension_list[] = {
|
|||||||
"genh",
|
"genh",
|
||||||
"gms",
|
"gms",
|
||||||
"gsb",
|
"gsb",
|
||||||
|
//"gsf", //conflicts with GBA gsf plugins?
|
||||||
"gtd",
|
"gtd",
|
||||||
"gwm",
|
"gwm",
|
||||||
|
|
||||||
"h4m",
|
"h4m",
|
||||||
|
"hab",
|
||||||
"hca",
|
"hca",
|
||||||
"hdr",
|
"hdr",
|
||||||
"hgc1",
|
"hgc1",
|
||||||
@ -417,8 +419,6 @@ static const char* extension_list[] = {
|
|||||||
"thp",
|
"thp",
|
||||||
"tk5",
|
"tk5",
|
||||||
"tra",
|
"tra",
|
||||||
"trj",
|
|
||||||
"trm",
|
|
||||||
"tun",
|
"tun",
|
||||||
"txth",
|
"txth",
|
||||||
"txtp",
|
"txtp",
|
||||||
|
@ -5,24 +5,24 @@
|
|||||||
|
|
||||||
/* header version */
|
/* header version */
|
||||||
#define EA_VERSION_NONE -1
|
#define EA_VERSION_NONE -1
|
||||||
#define EA_VERSION_V0 0x00 // ~early PC (when codec1 was used)
|
#define EA_VERSION_V0 0x00 /* ~early PC (when codec1 was used) */
|
||||||
#define EA_VERSION_V1 0x01 // ~PC
|
#define EA_VERSION_V1 0x01 /* ~PC */
|
||||||
#define EA_VERSION_V2 0x02 // ~PS era
|
#define EA_VERSION_V2 0x02 /* ~PS1 */
|
||||||
#define EA_VERSION_V3 0x03 // ~PS2 era
|
#define EA_VERSION_V3 0x03 /* ~PS2 */
|
||||||
|
|
||||||
/* platform constants (unasigned values seem internal only) */
|
/* platform constants (unassigned values seem internal only) */
|
||||||
#define EA_PLATFORM_GENERIC -1 // typically Wii/X360/PS3/videos
|
#define EA_PLATFORM_GENERIC -1 /* typically Wii/X360/PS3/videos */
|
||||||
#define EA_PLATFORM_PC 0x00
|
#define EA_PLATFORM_PC 0x00
|
||||||
#define EA_PLATFORM_PSX 0x01
|
#define EA_PLATFORM_PSX 0x01
|
||||||
#define EA_PLATFORM_N64 0x02
|
#define EA_PLATFORM_N64 0x02
|
||||||
#define EA_PLATFORM_MAC 0x03
|
#define EA_PLATFORM_MAC 0x03
|
||||||
#define EA_PLATFORM_SAT 0x04
|
#define EA_PLATFORM_SAT 0x04
|
||||||
#define EA_PLATFORM_PS2 0x05
|
#define EA_PLATFORM_PS2 0x05
|
||||||
#define EA_PLATFORM_GC_WII 0x06 // reused later for Wii
|
#define EA_PLATFORM_GC_WII 0x06
|
||||||
#define EA_PLATFORM_XBOX 0x07
|
#define EA_PLATFORM_XBOX 0x07
|
||||||
#define EA_PLATFORM_X360 0x09 // also "Xenon"
|
#define EA_PLATFORM_X360 0x09
|
||||||
#define EA_PLATFORM_PSP 0x0A
|
#define EA_PLATFORM_PSP 0x0A
|
||||||
#define EA_PLATFORM_PS3 0x0E // very rare [Need for Speed: Carbon (PS3)]
|
#define EA_PLATFORM_PS3 0x0E /* very rare [Need for Speed: Carbon (PS3)] */
|
||||||
#define EA_PLATFORM_3DS 0x14
|
#define EA_PLATFORM_3DS 0x14
|
||||||
|
|
||||||
/* codec constants (undefined are probably reserved, ie.- sx.exe encodes PCM24/DVI but no platform decodes them) */
|
/* codec constants (undefined are probably reserved, ie.- sx.exe encodes PCM24/DVI but no platform decodes them) */
|
||||||
@ -112,9 +112,24 @@ static void update_ea_stream_size_and_samples(STREAMFILE* streamFile, off_t star
|
|||||||
|
|
||||||
/* EA SCHl with variable header - from EA games (roughly 1997~2010); generated by EA Canada's sx.exe/Sound eXchange */
|
/* 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 *streamFile) {
|
VGMSTREAM * init_vgmstream_ea_schl(STREAMFILE *streamFile) {
|
||||||
/* check extension; exts don't seem enforced by EA's tools, but usually:
|
|
||||||
* STR/ASF/MUS ~early, EAM ~mid, SNG/AUD ~late, rest uncommon/one game (ex. STRM: MySims Kingdom Wii) */
|
/* check extension */
|
||||||
if (!check_extensions(streamFile,"str,asf,mus,eam,sng,aud,sx,strm,xa,xsf,exa,stm,trj,trm"))
|
/* they don't seem enforced by EA's tools but usually:
|
||||||
|
* .asf: ~early [ex. Need for Speed (PC)]
|
||||||
|
* .str: ~early [ex. FIFA 2002 (PS1)]
|
||||||
|
* .eam: ~mid (fake?)
|
||||||
|
* .exa: ~mid [ex. 007 - From Russia with Love]
|
||||||
|
* .sng: ~late (fake?)
|
||||||
|
* .aud: ~late [ex. FIFA 14 (3DS)]
|
||||||
|
* .strm: MySims Kingdom (Wii)
|
||||||
|
* .stm: FIFA 12 (3DS)
|
||||||
|
* .sx/xa: fake?
|
||||||
|
* .hab: GoldenEye - Rogue Agent (inside .big)
|
||||||
|
* .xsf: 007 - Agent Under Fire (Xbox)
|
||||||
|
* .gsf: 007 - Everything or Nothing (GC)
|
||||||
|
* .mus: map/mpf+mus only?
|
||||||
|
* (extensionless): SSX (PS2) (inside .big) */
|
||||||
|
if (!check_extensions(streamFile,"asf,str,eam,exa,sng,aud,sx,xa,strm,stm,hab,xsf,gsf,mus,"))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
/* check header */
|
/* check header */
|
||||||
@ -147,8 +162,12 @@ VGMSTREAM * init_vgmstream_ea_bnk(STREAMFILE *streamFile) {
|
|||||||
off_t offset;
|
off_t offset;
|
||||||
|
|
||||||
/* check extension */
|
/* check extension */
|
||||||
/* .bnk: sfx, .sdt: speech, .mus: streams/jingles (rare) */
|
/* .bnk: common
|
||||||
if (!check_extensions(streamFile,"bnk,sdt,mus"))
|
* .sdt: Harry Potter games
|
||||||
|
* .mus: streams/jingles (rare)
|
||||||
|
* .abk: GoldenEye - Rogue Agent
|
||||||
|
* .ast: FIFA 2004 (inside .big) */
|
||||||
|
if (!check_extensions(streamFile,"bnk,sdt,mus,abk,ast"))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
/* check header (doesn't use EA blocks, otherwise very similar to SCHl) */
|
/* check header (doesn't use EA blocks, otherwise very similar to SCHl) */
|
||||||
@ -363,7 +382,59 @@ fail:
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EA MAP/MUS combo - used in some old games for interactive music info */
|
|
||||||
|
/* open map/mpf+mus pairs that aren't exact pairs, since EA's games can load any combo */
|
||||||
|
static STREAMFILE * open_mapfile_pair(STREAMFILE *streamFile) {
|
||||||
|
static const char *const mapfile_pairs[][2] = {
|
||||||
|
/* standard cases, replace map part with mus part (from the end to preserve prefixes) */
|
||||||
|
{"MUS_CTRL.MPF","MUS_STR.MUS"}, /* GoldenEye - Rogue Agent (PS2) */
|
||||||
|
{"mus_ctrl.mpf","mus_str.mus"}, /* GoldenEye - Rogue Agent (others) */
|
||||||
|
{".mpf","_main.mus"}, /* 007 - Everything or Nothing (GC) */
|
||||||
|
/* hack when when multiple maps point to the same mus, uses name before "+"
|
||||||
|
* ex. ZZZTR00A.TRJ+ZTR00PGR.MAP or ZZZTR00A.TRJ+ZTR00R0A.MAP both point to ZZZTR00A.TRJ */
|
||||||
|
{"+",""}, /* Need for Speed III (PS1) */
|
||||||
|
};
|
||||||
|
STREAMFILE *musFile = NULL;
|
||||||
|
char file_name[PATH_LIMIT];
|
||||||
|
int pair_count = (sizeof(mapfile_pairs)/sizeof(mapfile_pairs[0]));
|
||||||
|
int i;
|
||||||
|
size_t file_len, map_len;
|
||||||
|
|
||||||
|
get_streamfile_filename(streamFile, file_name, PATH_LIMIT);
|
||||||
|
file_len = strlen(file_name);
|
||||||
|
|
||||||
|
for (i = 0; i < pair_count; i++) {
|
||||||
|
const char *map_name = mapfile_pairs[i][0];
|
||||||
|
const char *mus_name = mapfile_pairs[i][1];
|
||||||
|
map_len = strlen(map_name);
|
||||||
|
|
||||||
|
if (map_name[0] == '+') {
|
||||||
|
/* use name before "+" */
|
||||||
|
char *mod_name = strchr(file_name, '+');
|
||||||
|
if (mod_name == NULL)
|
||||||
|
continue;
|
||||||
|
mod_name[0] = '\0';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* replace map_name with expected mus_name */
|
||||||
|
if (file_len < map_len)
|
||||||
|
continue;
|
||||||
|
if (strncmp(file_name+(file_len - map_len), map_name, map_len) != 0)
|
||||||
|
continue;
|
||||||
|
file_name[file_len - map_len] = '\0';
|
||||||
|
strcat(file_name, mus_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
musFile = open_streamfile_by_filename(streamFile, file_name);
|
||||||
|
if (musFile) return musFile;
|
||||||
|
|
||||||
|
get_streamfile_filename(streamFile, file_name, PATH_LIMIT); /* reset for next loop */
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* EA MAP/MUS combo - used in older games for interactive music (for EA's PathFinder tool) */
|
||||||
VGMSTREAM * init_vgmstream_ea_map_mus(STREAMFILE *streamFile) {
|
VGMSTREAM * init_vgmstream_ea_map_mus(STREAMFILE *streamFile) {
|
||||||
uint8_t version, num_sounds, num_userdata, userdata_size;
|
uint8_t version, num_sounds, num_userdata, userdata_size;
|
||||||
off_t section_offset, schl_offset;
|
off_t section_offset, schl_offset;
|
||||||
@ -383,7 +454,10 @@ VGMSTREAM * init_vgmstream_ea_map_mus(STREAMFILE *streamFile) {
|
|||||||
if (version > 1) goto fail;
|
if (version > 1) goto fail;
|
||||||
|
|
||||||
musFile = open_streamfile_by_ext(streamFile, "mus");
|
musFile = open_streamfile_by_ext(streamFile, "mus");
|
||||||
if (!musFile) goto fail;
|
if (!musFile) {
|
||||||
|
musFile = open_mapfile_pair(streamFile);
|
||||||
|
if (!musFile) goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 0x04: ???
|
* 0x04: ???
|
||||||
@ -427,7 +501,7 @@ fail:
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EA MPF/MUS combo - used in newer 6th gen games for storing music */
|
/* EA MPF/MUS combo - used in newer 6th gen games for interactive music (for EA's PathFinder tool) */
|
||||||
VGMSTREAM * init_vgmstream_ea_mpf_mus(STREAMFILE *streamFile) {
|
VGMSTREAM * init_vgmstream_ea_mpf_mus(STREAMFILE *streamFile) {
|
||||||
off_t section_offset, entry_offset, subentry_num, eof_offset, off_mult, schl_offset;
|
off_t section_offset, entry_offset, subentry_num, eof_offset, off_mult, schl_offset;
|
||||||
size_t sec2_size;
|
size_t sec2_size;
|
||||||
@ -463,12 +537,15 @@ VGMSTREAM * init_vgmstream_ea_mpf_mus(STREAMFILE *streamFile) {
|
|||||||
if (version == 5 && sub_version > 2) goto fail; /* newer version using SNR/SNS */
|
if (version == 5 && sub_version > 2) goto fail; /* newer version using SNR/SNS */
|
||||||
|
|
||||||
musFile = open_streamfile_by_ext(streamFile, "mus");
|
musFile = open_streamfile_by_ext(streamFile, "mus");
|
||||||
if (!musFile) goto fail;
|
if (!musFile) {
|
||||||
|
musFile = open_mapfile_pair(streamFile);
|
||||||
|
if (!musFile) goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
/* HACK: number of sub-entries is stored in bitstreams that are different in LE and BE */
|
/* HACK: number of sub-entries is stored in bitstreams that are different in LE and BE */
|
||||||
/* I can't figure it out, so let's just use a workaround for now */
|
/* I can't figure it out, so let's just use a workaround for now */
|
||||||
|
|
||||||
if (version == 3 && sub_version == 1) { /* SSX Tricky /*
|
if (version == 3 && sub_version == 1) { /* SSX Tricky */
|
||||||
/* we need to go through the first two sections to find sound table */
|
/* we need to go through the first two sections to find sound table */
|
||||||
sec1_num = read_16bit(0x12, streamFile);
|
sec1_num = read_16bit(0x12, streamFile);
|
||||||
sec2_size = read_8bit(0x0e, streamFile);
|
sec2_size = read_8bit(0x0e, streamFile);
|
||||||
@ -517,7 +594,7 @@ VGMSTREAM * init_vgmstream_ea_mpf_mus(STREAMFILE *streamFile) {
|
|||||||
eof_offset = read_32bit(entry_offset + 0x04, streamFile) * 0x04;
|
eof_offset = read_32bit(entry_offset + 0x04, streamFile) * 0x04;
|
||||||
total_streams = (eof_offset - section_offset) / 0x08;
|
total_streams = (eof_offset - section_offset) / 0x08;
|
||||||
off_mult = 0x04;
|
off_mult = 0x04;
|
||||||
} else if (version == 4) { /* SSX 3, Need for Speed: Underground 2 /*
|
} else if (version == 4) { /* SSX 3, Need for Speed: Underground 2 */
|
||||||
/* we need to go through the first two sections to find sound table */
|
/* we need to go through the first two sections to find sound table */
|
||||||
sec1_num = read_16bit(0x12, streamFile);
|
sec1_num = read_16bit(0x12, streamFile);
|
||||||
sec2_num = read_8bit(0x0f, streamFile);
|
sec2_num = read_8bit(0x0f, streamFile);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user