mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-02-20 20:41:08 +01:00
Fix some .mul [Tomb Raider 2013 (PS4)]
This commit is contained in:
parent
e5d89222ab
commit
86be2b74ad
@ -1,6 +1,7 @@
|
||||
#include "meta.h"
|
||||
#include "../layout/layout.h"
|
||||
#include "../coding/coding.h"
|
||||
#include "../util/endianness.h"
|
||||
#include "mul_streamfile.h"
|
||||
|
||||
typedef enum { PSX, DSP, IMA, XMA1, FSB4 } mul_codec;
|
||||
@ -16,15 +17,15 @@ VGMSTREAM* init_vgmstream_mul(STREAMFILE* sf) {
|
||||
int loop_flag, channel_count, sample_rate, num_samples, loop_start;
|
||||
int big_endian;
|
||||
mul_codec codec;
|
||||
uint32_t (*read_u32)(off_t,STREAMFILE*) = NULL;
|
||||
read_u32_t read_u32;
|
||||
read_f32_t read_f32;
|
||||
|
||||
|
||||
/* checks */
|
||||
/* .mul: found in the exe, used by the bigfile extractor (Gibbed.TombRaider)
|
||||
/* .mul: found in the exe/reversed names, used by the bigfile extractor (Gibbed.TombRaider)
|
||||
* (some files have companion .mus/sam files but seem to be sequences/control stuff)
|
||||
* .(extensionless): filenames as found in the bigfile
|
||||
* .emff: fake extension ('Eidos Music File Format') */
|
||||
if (!check_extensions(sf, "mul,,emff"))
|
||||
if (!check_extensions(sf, "mul,emff"))
|
||||
goto fail;
|
||||
if (read_u32be(0x10,sf) != 0 ||
|
||||
read_u32be(0x14,sf) != 0 ||
|
||||
@ -34,6 +35,7 @@ VGMSTREAM* init_vgmstream_mul(STREAMFILE* sf) {
|
||||
|
||||
big_endian = guess_endianness32bit(0x00, sf);
|
||||
read_u32 = big_endian ? read_u32be : read_u32le;
|
||||
read_f32 = big_endian ? read_f32be : read_f32le;
|
||||
|
||||
sample_rate = read_u32(0x00,sf);
|
||||
loop_start = read_u32(0x04,sf);
|
||||
@ -46,13 +48,15 @@ VGMSTREAM* init_vgmstream_mul(STREAMFILE* sf) {
|
||||
/* 0x28: loop offset within audio data (not file offset) */
|
||||
/* 0x2c: some value related to loop? */
|
||||
/* 0x34: id? */
|
||||
/* 0x38+: channel config until ~0x100? (multiple 0x3F800000 / 1.0f depending on the number of channels) */
|
||||
/* 0x38+: channel config until ~0x100? (multiple 1.0f depending on the number of channels) */
|
||||
|
||||
/* test known "version" (some float) later versions start from 0x24 instead of 0x20 */
|
||||
if (!(read_u32(0x38,sf) == 0x3F800000 || /* common */
|
||||
read_u32(0x38,sf) == 0x4530F000 || /* Avengers */
|
||||
read_u32(0x3c,sf) == 0x3F800000)) /* Tomb Raider Underworld */
|
||||
goto fail;
|
||||
/* extra tests just in case (1.0=common, varies but goes around ~2800.0) */
|
||||
{
|
||||
float check1 = read_f32(0x38,sf);
|
||||
float check2 = read_f32(0x3c,sf);
|
||||
if (!(check1 >= 1.0 && check1 <= 3000.0) && check2 != 1.0)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
loop_flag = (loop_start >= 0); /* 0xFFFFFFFF when not looping */
|
||||
|
||||
@ -115,13 +119,20 @@ fail:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* find first block with header info (probably hardcoded) */
|
||||
static off_t get_start_offset(STREAMFILE* sf) {
|
||||
uint32_t test1, test2;
|
||||
|
||||
/* find first block with header info */
|
||||
if (read_u32be(0x0800,sf) != 0 || read_u32be(0x0804,sf) != 0) /* earlier games */
|
||||
/* earlier games */
|
||||
test1 = read_u32be(0x0800,sf);
|
||||
test2 = read_u32be(0x0804,sf);
|
||||
if ((test1 != 0 && test1 != 0xFFFFFFFF) || (test2 != 0 && test2 != 0xFFFFFFFF))
|
||||
return 0x800;
|
||||
|
||||
if (read_u32be(0x2000,sf) != 0 || read_u32be(0x2004,sf) != 0) /* later games */
|
||||
/* later games */
|
||||
test1 = read_u32be(0x2000,sf);
|
||||
test2 = read_u32be(0x2004,sf);
|
||||
if ((test1 != 0 && test1 != 0xFFFFFFFF) || (test2 != 0 && test2 != 0xFFFFFFFF))
|
||||
return 0x2000;
|
||||
|
||||
return 0;
|
||||
@ -167,13 +178,16 @@ static int guess_codec(STREAMFILE* sf, off_t start_offset, int big_endian, int c
|
||||
uint32_t block_size = read_u32(offset+0x04, sf);
|
||||
uint32_t data_size = read_u32(offset+0x10, sf);
|
||||
|
||||
if (block_type == 0xFFFFFFFF || block_size == 0xFFFFFFFF || data_size == 0xFFFFFFFF)
|
||||
return 0;
|
||||
|
||||
if (block_type != 0x00) {
|
||||
offset += 0x10 + block_size;
|
||||
continue; /* not audio */
|
||||
}
|
||||
|
||||
/* test FSB4 header */
|
||||
if (read_u32be(offset + 0x10, sf) == 0x46534234 || read_u32be(offset + 0x20, sf) == 0x46534234) {
|
||||
if (is_id32be(offset + 0x10, sf, "FSB4") || is_id32be(offset + 0x20, sf, "FSB4")) {
|
||||
*p_codec = FSB4;
|
||||
return 1;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user