mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-11-24 23:10:10 +01:00
Fix EA SCHl BR and handle multilang better [Battlefield: Hardline (PS3)]
This commit is contained in:
parent
b4fff010dd
commit
0719c2cc61
@ -10,6 +10,10 @@ void block_update_ea_schl(off_t block_offset, VGMSTREAM * vgmstream) {
|
|||||||
size_t block_size, block_samples;
|
size_t block_size, block_samples;
|
||||||
int32_t (*read_32bit)(off_t,STREAMFILE*) = vgmstream->codec_endian ? read_32bitBE : read_32bitLE;
|
int32_t (*read_32bit)(off_t,STREAMFILE*) = vgmstream->codec_endian ? read_32bitBE : read_32bitLE;
|
||||||
|
|
||||||
|
uint32_t flag_lang = (vgmstream->codec_config >> 16) & 0xFFFF;
|
||||||
|
int flag_be = (vgmstream->codec_config & 0x02);
|
||||||
|
int flag_adpcm = (vgmstream->codec_config & 0x01);
|
||||||
|
|
||||||
|
|
||||||
/* EOF reads: signal we have nothing and let the layout fail */
|
/* EOF reads: signal we have nothing and let the layout fail */
|
||||||
if (block_offset >= get_streamfile_size(streamFile)) {
|
if (block_offset >= get_streamfile_size(streamFile)) {
|
||||||
@ -23,35 +27,21 @@ void block_update_ea_schl(off_t block_offset, VGMSTREAM * vgmstream) {
|
|||||||
{
|
{
|
||||||
uint32_t block_id = read_32bitBE(block_offset+0x00,streamFile);
|
uint32_t block_id = read_32bitBE(block_offset+0x00,streamFile);
|
||||||
|
|
||||||
if (vgmstream->codec_config & 0x02) /* size is always LE, except in early SS/MAC */
|
if (flag_be) /* size is always LE, except in early SS/MAC */
|
||||||
block_size = read_32bitBE(block_offset + 0x04,streamFile);
|
block_size = read_32bitBE(block_offset + 0x04,streamFile);
|
||||||
else
|
else
|
||||||
block_size = read_32bitLE(block_offset + 0x04,streamFile);
|
block_size = read_32bitLE(block_offset + 0x04,streamFile);
|
||||||
|
|
||||||
switch(block_id) {
|
if (block_id == 0x5343446C || block_id == (0x53440000 | flag_lang)) {
|
||||||
case 0x5343446C: /* "SCDl" */
|
/* "SCDl" or "SDxx" audio chunk */
|
||||||
case 0x5344454E: /* "SDEN" */
|
|
||||||
case 0x53444652: /* "SDFR" */
|
|
||||||
case 0x53444745: /* "SDGE" */
|
|
||||||
case 0x53444445: /* "SDDE" */
|
|
||||||
case 0x53444954: /* "SDIT" */
|
|
||||||
case 0x53445350: /* "SDSP" */
|
|
||||||
case 0x53444553: /* "SDES" */
|
|
||||||
case 0x53444D58: /* "SDMX" */
|
|
||||||
case 0x53445255: /* "SDRU" */
|
|
||||||
case 0x53444A41: /* "SDJA" */
|
|
||||||
case 0x53444A50: /* "SDJP" */
|
|
||||||
case 0x5344504C: /* "SDPL" */
|
|
||||||
/* audio chunk */
|
|
||||||
if (vgmstream->coding_type == coding_PSX)
|
if (vgmstream->coding_type == coding_PSX)
|
||||||
block_samples = ps_bytes_to_samples(block_size-0x10, vgmstream->channels);
|
block_samples = ps_bytes_to_samples(block_size-0x10, vgmstream->channels);
|
||||||
else
|
else
|
||||||
block_samples = read_32bit(block_offset+0x08,streamFile);
|
block_samples = read_32bit(block_offset+0x08,streamFile);
|
||||||
break;
|
}
|
||||||
default:
|
else {
|
||||||
/* ignore other chunks (audio "SCHl/SCCl/...", video "pIQT/MADk/...", etc) */
|
/* ignore other chunks (audio "SCHl/SCCl/...", non-target lang, video "pIQT/MADk/...", etc) */
|
||||||
block_samples = 0; /* layout ignores this */
|
block_samples = 0; /* layout ignores this */
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* "SCHl" start block (movie "SHxx" shouldn't use multi files) */
|
/* "SCHl" start block (movie "SHxx" shouldn't use multi files) */
|
||||||
@ -185,7 +175,7 @@ void block_update_ea_schl(off_t block_offset, VGMSTREAM * vgmstream) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* read ADPCM history before each channel if needed (not actually read in sx.exe) */
|
/* read ADPCM history before each channel if needed (not actually read in sx.exe) */
|
||||||
if (vgmstream->codec_config & 0x01) {
|
if (flag_adpcm) {
|
||||||
for (i = 0; i < vgmstream->channels; i++) {
|
for (i = 0; i < vgmstream->channels; i++) {
|
||||||
//vgmstream->ch[i].adpcm_history1_32 = read_16bit(vgmstream->ch[i].offset+0x00,streamFile);
|
//vgmstream->ch[i].adpcm_history1_32 = read_16bit(vgmstream->ch[i].offset+0x00,streamFile);
|
||||||
//vgmstream->ch[i].adpcm_history3_32 = read_16bit(vgmstream->ch[i].offset+0x02,streamFile);
|
//vgmstream->ch[i].adpcm_history3_32 = read_16bit(vgmstream->ch[i].offset+0x02,streamFile);
|
||||||
|
@ -74,6 +74,7 @@
|
|||||||
#define EA_BLOCKID_LOC_JA 0x00004A41 /* Japanese, older */
|
#define EA_BLOCKID_LOC_JA 0x00004A41 /* Japanese, older */
|
||||||
#define EA_BLOCKID_LOC_JP 0x00004A50 /* Japanese, newer */
|
#define EA_BLOCKID_LOC_JP 0x00004A50 /* Japanese, newer */
|
||||||
#define EA_BLOCKID_LOC_PL 0x0000504C /* Polish */
|
#define EA_BLOCKID_LOC_PL 0x0000504C /* Polish */
|
||||||
|
#define EA_BLOCKID_LOC_BR 0x00004252 /* Brazilian Portuguese */
|
||||||
|
|
||||||
#define EA_BNK_HEADER_LE 0x424E4B6C /* "BNKl" */
|
#define EA_BNK_HEADER_LE 0x424E4B6C /* "BNKl" */
|
||||||
#define EA_BNK_HEADER_BE 0x424E4B62 /* "BNKb" */
|
#define EA_BNK_HEADER_BE 0x424E4B62 /* "BNKb" */
|
||||||
@ -146,7 +147,8 @@ VGMSTREAM * init_vgmstream_ea_schl(STREAMFILE *streamFile) {
|
|||||||
read_32bitBE(0x00,streamFile) != (EA_BLOCKID_LOC_HEADER | EA_BLOCKID_LOC_RU) && /* "SHRU" */
|
read_32bitBE(0x00,streamFile) != (EA_BLOCKID_LOC_HEADER | EA_BLOCKID_LOC_RU) && /* "SHRU" */
|
||||||
read_32bitBE(0x00,streamFile) != (EA_BLOCKID_LOC_HEADER | EA_BLOCKID_LOC_JA) && /* "SHJA" */
|
read_32bitBE(0x00,streamFile) != (EA_BLOCKID_LOC_HEADER | EA_BLOCKID_LOC_JA) && /* "SHJA" */
|
||||||
read_32bitBE(0x00,streamFile) != (EA_BLOCKID_LOC_HEADER | EA_BLOCKID_LOC_JP) && /* "SHJP" */
|
read_32bitBE(0x00,streamFile) != (EA_BLOCKID_LOC_HEADER | EA_BLOCKID_LOC_JP) && /* "SHJP" */
|
||||||
read_32bitBE(0x00,streamFile) != (EA_BLOCKID_LOC_HEADER | EA_BLOCKID_LOC_PL)) /* "SHPL" */
|
read_32bitBE(0x00,streamFile) != (EA_BLOCKID_LOC_HEADER | EA_BLOCKID_LOC_PL) && /* "SHPL" */
|
||||||
|
read_32bitBE(0x00,streamFile) != (EA_BLOCKID_LOC_HEADER | EA_BLOCKID_LOC_BR)) /* "SHBR" */
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
/* Stream is divided into blocks/chunks: SCHl=audio header, SCCl=count of SCDl, SCDl=data xN, SCLl=loop end, SCEl=end.
|
/* Stream is divided into blocks/chunks: SCHl=audio header, SCCl=count of SCDl, SCDl=data xN, SCLl=loop end, SCEl=end.
|
||||||
@ -702,8 +704,16 @@ fail:
|
|||||||
static VGMSTREAM * parse_schl_block(STREAMFILE *streamFile, off_t offset, int standalone) {
|
static VGMSTREAM * parse_schl_block(STREAMFILE *streamFile, off_t offset, int standalone) {
|
||||||
off_t start_offset, header_offset;
|
off_t start_offset, header_offset;
|
||||||
size_t header_size;
|
size_t header_size;
|
||||||
|
uint32_t header_id;
|
||||||
ea_header ea = { 0 };
|
ea_header ea = { 0 };
|
||||||
|
|
||||||
|
/* use higher bits to store target localized block in case of multilang video,
|
||||||
|
* so only header sub-id will be read and other langs skipped */
|
||||||
|
header_id = read_32bitBE(offset + 0x00, streamFile);
|
||||||
|
if ((header_id & 0xFFFF0000) == EA_BLOCKID_LOC_HEADER) {
|
||||||
|
ea.codec_config |= (header_id & 0xFFFF) << 16;
|
||||||
|
}
|
||||||
|
|
||||||
if (guess_endianness32bit(offset + 0x04, streamFile)) { /* size is always LE, except in early SS/MAC */
|
if (guess_endianness32bit(offset + 0x04, streamFile)) { /* size is always LE, except in early SS/MAC */
|
||||||
header_size = read_32bitBE(offset + 0x04, streamFile);
|
header_size = read_32bitBE(offset + 0x04, streamFile);
|
||||||
ea.codec_config |= 0x02;
|
ea.codec_config |= 0x02;
|
||||||
@ -1497,6 +1507,7 @@ static off_t get_ea_stream_mpeg_start_offset(STREAMFILE* streamFile, off_t start
|
|||||||
size_t file_size = get_streamfile_size(streamFile);
|
size_t file_size = get_streamfile_size(streamFile);
|
||||||
off_t block_offset = start_offset;
|
off_t block_offset = start_offset;
|
||||||
int32_t (*read_32bit)(off_t,STREAMFILE*) = ea->big_endian ? read_32bitBE : read_32bitLE;
|
int32_t (*read_32bit)(off_t,STREAMFILE*) = ea->big_endian ? read_32bitBE : read_32bitLE;
|
||||||
|
uint32_t header_lang = (ea->codec_config >> 16) & 0xFFFF;
|
||||||
|
|
||||||
while (block_offset < file_size) {
|
while (block_offset < file_size) {
|
||||||
uint32_t block_id, block_size;
|
uint32_t block_id, block_size;
|
||||||
@ -1508,27 +1519,16 @@ static off_t get_ea_stream_mpeg_start_offset(STREAMFILE* streamFile, off_t start
|
|||||||
if (block_size > 0x00F00000) /* size is always LE, except in early SAT/MAC */
|
if (block_size > 0x00F00000) /* size is always LE, except in early SAT/MAC */
|
||||||
block_size = read_32bitBE(block_offset+0x04,streamFile);
|
block_size = read_32bitBE(block_offset+0x04,streamFile);
|
||||||
|
|
||||||
switch(block_id) {
|
if (block_id == EA_BLOCKID_DATA || block_id == ((EA_BLOCKID_LOC_DATA | header_lang))) {
|
||||||
case EA_BLOCKID_DATA: /* "SCDl" */
|
/* "SCDl" or target "SDxx" multilang blocks */
|
||||||
case EA_BLOCKID_LOC_DATA | EA_BLOCKID_LOC_EN: /* "SDEN" */
|
|
||||||
case EA_BLOCKID_LOC_DATA | EA_BLOCKID_LOC_FR: /* "SDFR" */
|
|
||||||
case EA_BLOCKID_LOC_DATA | EA_BLOCKID_LOC_GE: /* "SDGE" */
|
|
||||||
case EA_BLOCKID_LOC_DATA | EA_BLOCKID_LOC_DE: /* "SDDE" */
|
|
||||||
case EA_BLOCKID_LOC_DATA | EA_BLOCKID_LOC_IT: /* "SDIT" */
|
|
||||||
case EA_BLOCKID_LOC_DATA | EA_BLOCKID_LOC_SP: /* "SDSP" */
|
|
||||||
case EA_BLOCKID_LOC_DATA | EA_BLOCKID_LOC_ES: /* "SDES" */
|
|
||||||
case EA_BLOCKID_LOC_DATA | EA_BLOCKID_LOC_MX: /* "SDMX" */
|
|
||||||
case EA_BLOCKID_LOC_DATA | EA_BLOCKID_LOC_RU: /* "SDRU" */
|
|
||||||
case EA_BLOCKID_LOC_DATA | EA_BLOCKID_LOC_JA: /* "SDJA" */
|
|
||||||
case EA_BLOCKID_LOC_DATA | EA_BLOCKID_LOC_JP: /* "SDJP" */
|
|
||||||
case EA_BLOCKID_LOC_DATA | EA_BLOCKID_LOC_PL: /* "SDPL" */
|
|
||||||
offset = read_32bit(block_offset+0x0c,streamFile); /* first value seems ok, second is something else in EALayer3 */
|
offset = read_32bit(block_offset+0x0c,streamFile); /* first value seems ok, second is something else in EALayer3 */
|
||||||
return block_offset + 0x0c + ea->channels*0x04 + offset;
|
return block_offset + 0x0c + ea->channels*0x04 + offset;
|
||||||
case 0x00000000:
|
}
|
||||||
|
else if (block_id == 0x00000000) {
|
||||||
goto fail; /* just in case */
|
goto fail; /* just in case */
|
||||||
default:
|
}
|
||||||
|
else {
|
||||||
block_offset += block_size; /* size includes header */
|
block_offset += block_size; /* size includes header */
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user