mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-01-29 19:37:30 +01:00
Add some Ubi SB [G.R.A.W (X360), Splinter Cell D.A. Online (PC)]
This commit is contained in:
parent
703c29775d
commit
c1b9df6a5e
@ -5,7 +5,7 @@
|
||||
#include "ubi_sb_streamfile.h"
|
||||
|
||||
static STREAMFILE* setup_ubi_bao_streamfile(STREAMFILE *streamFile, off_t stream_offset, size_t stream_size, int layer_number, int layer_count, int big_endian) {
|
||||
return setup_ubi_sb_streamfile(streamFile, stream_offset, stream_size, layer_number, layer_count, big_endian);
|
||||
return setup_ubi_sb_streamfile(streamFile, stream_offset, stream_size, layer_number, layer_count, big_endian, 0);
|
||||
}
|
||||
|
||||
#endif /* _UBI_BAO_STREAMFILE_H_ */
|
||||
|
@ -57,6 +57,7 @@ typedef struct {
|
||||
off_t layer_stream_type;
|
||||
off_t layer_num_samples;
|
||||
size_t layer_entry_size;
|
||||
size_t layer_hijack;
|
||||
|
||||
off_t silence_duration_int;
|
||||
off_t silence_duration_float;
|
||||
@ -555,6 +556,9 @@ static VGMSTREAM * init_vgmstream_ubi_sb_base(ubi_sb_header *sb, STREAMFILE *str
|
||||
/* get XMA header from extra section */
|
||||
chunk_size = 0x20;
|
||||
header_offset = sb->xma_header_offset;
|
||||
if (header_offset == 0)
|
||||
header_offset = sb->extra_offset;
|
||||
|
||||
bytes = ffmpeg_make_riff_xma_from_fmt_chunk(buf, 0x100, header_offset, chunk_size, sb->stream_size, streamHead, 1);
|
||||
|
||||
ffmpeg_data = init_ffmpeg_header_offset(streamData, buf, bytes, start_offset, sb->stream_size);
|
||||
@ -661,7 +665,7 @@ static VGMSTREAM * init_vgmstream_ubi_sb_layer(ubi_sb_header *sb, STREAMFILE *st
|
||||
/* open all layers and mix */
|
||||
for (i = 0; i < sb->layer_count; i++) {
|
||||
/* prepare streamfile from a single layer section */
|
||||
temp_streamFile = setup_ubi_sb_streamfile(streamData, sb->stream_offset, full_stream_size, i, sb->layer_count, sb->big_endian);
|
||||
temp_streamFile = setup_ubi_sb_streamfile(streamData, sb->stream_offset, full_stream_size, i, sb->layer_count, sb->big_endian, sb->cfg.layer_hijack);
|
||||
if (!temp_streamFile) goto fail;
|
||||
|
||||
sb->stream_size = get_streamfile_size(temp_streamFile);
|
||||
@ -1689,6 +1693,7 @@ static void config_sb_silence_f(ubi_sb_header * sb, off_t duration) {
|
||||
static int config_sb_version(ubi_sb_header * sb, STREAMFILE *streamFile) {
|
||||
int is_bia_ps2 = 0, is_biadd_psp = 0;
|
||||
int is_sc2_ps2_gc = 0;
|
||||
int is_sc4_pc_online = 0;
|
||||
|
||||
/* Most of the format varies with almost every game + platform (struct serialization?).
|
||||
* Support is configured case-by-case as offsets/order/fields only change slightly,
|
||||
@ -2347,6 +2352,22 @@ static int config_sb_version(ubi_sb_header * sb, STREAMFILE *streamFile) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Tom Clancy's Ghost Recon Advanced Warfighter (2006)(X360)-bank */
|
||||
if (sb->version == 0x00170001 && sb->platform == UBI_X360) {
|
||||
config_sb_entry(sb, 0x68, 0x70);
|
||||
|
||||
config_sb_audio_fs(sb, 0x2c, 0x30, 0x34);
|
||||
config_sb_audio_he(sb, 0x5c, 0x54, 0x40, 0x48, 0x64, 0x60);
|
||||
sb->cfg.audio_xma_offset = 0; /* header is in the extra table */
|
||||
|
||||
config_sb_sequence(sb, 0x2c, 0x14);
|
||||
|
||||
config_sb_layer_he(sb, 0x20, 0x38, 0x3c, 0x48);
|
||||
config_sb_layer_sh(sb, 0x30, 0x00, 0x08, 0x0c, 0x14);
|
||||
sb->cfg.layer_hijack = 1; /* WTF!!! layer format different from other layers using same id!!! */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Open Season (2006)(PC)-map 0x00180003 */
|
||||
if (sb->version == 0x00180003 && sb->platform == UBI_PC) {
|
||||
config_sb_entry(sb, 0x68, 0x78);
|
||||
@ -2395,8 +2416,18 @@ static int config_sb_version(ubi_sb_header * sb, STREAMFILE *streamFile) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Splinter Cell: Double Agent (2006)(PC)-map */
|
||||
|
||||
/* two configs with same id; use project file as identifier */
|
||||
if (sb->version == 0x00180006 && sb->platform == UBI_PC) {
|
||||
STREAMFILE * streamTest = open_streamfile_by_filename(streamFile, "Sc4_online_SoundProject.SP0");
|
||||
if (streamTest) {
|
||||
is_sc4_pc_online = 1;
|
||||
close_streamfile(streamTest);
|
||||
}
|
||||
}
|
||||
|
||||
/* Splinter Cell: Double Agent (2006)(PC)-map (offline) */
|
||||
if (sb->version == 0x00180006 && sb->platform == UBI_PC && !is_sc4_pc_online) {
|
||||
config_sb_entry(sb, 0x68, 0x7c);
|
||||
|
||||
config_sb_audio_fs(sb, 0x2c, 0x34, 0x30);
|
||||
@ -2407,6 +2438,18 @@ static int config_sb_version(ubi_sb_header * sb, STREAMFILE *streamFile) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Splinter Cell: Double Agent (2006)(PC)-map (online) */
|
||||
if (sb->version == 0x00180006 && sb->platform == UBI_PC && is_sc4_pc_online) {
|
||||
config_sb_entry(sb, 0x68, 0x78);
|
||||
|
||||
config_sb_audio_fs(sb, 0x2c, 0x34, 0x30);
|
||||
config_sb_audio_he(sb, 0x5c, 0x54, 0x40, 0x48, 0x64, 0x60);
|
||||
|
||||
config_sb_layer_he(sb, 0x20, 0x38, 0x3c, 0x44);
|
||||
config_sb_layer_sh(sb, 0x34, 0x00, 0x08, 0x0c, 0x14);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Splinter Cell: Double Agent (2006)(X360)-map */
|
||||
if (sb->version == 0x00180006 && sb->platform == UBI_X360) {
|
||||
config_sb_entry(sb, 0x68, 0x78);
|
||||
|
@ -11,6 +11,7 @@ typedef struct {
|
||||
int layer_count;
|
||||
int layer_max;
|
||||
int big_endian;
|
||||
int layer_hijack;
|
||||
|
||||
/* internal config */
|
||||
off_t header_next_start; /* offset to header field */
|
||||
@ -148,6 +149,11 @@ static int ubi_sb_io_init(STREAMFILE *streamfile, ubi_sb_io_data* data) {
|
||||
/* Layers have a main header, then headered blocks with data.
|
||||
* We configure stuff to unify parsing of all variations. */
|
||||
version = (uint32_t)read_32bit(offset+0x00, streamfile);
|
||||
|
||||
/* it was bound to happen... orz */
|
||||
if (data->layer_hijack == 1 && version == 0x000B0008)
|
||||
version = 0xFFFF0007;
|
||||
|
||||
switch(version) {
|
||||
case 0x00000002: /* Splinter Cell */
|
||||
/* - layer header
|
||||
@ -228,6 +234,35 @@ static int ubi_sb_io_init(STREAMFILE *streamfile, ubi_sb_io_data* data) {
|
||||
data->block_data_start = 0x0c + data->layer_max*0x04;
|
||||
break;
|
||||
|
||||
case 0xFFFF0007: /* Ghost Recon Advanced Warfighter (X360) */
|
||||
/* - layer header
|
||||
* 0x04: config?
|
||||
* 0x08: layer count
|
||||
* 0x0c: stream size
|
||||
* 0x10: block count
|
||||
* 0x14: block header size
|
||||
* 0x18: block size (fixed)
|
||||
* 0x1c+(04*11): min layer data? for 11 layers (-1 after layer count)
|
||||
* 0x48: size of header sizes
|
||||
* 0x4c+(04*N): header size per layer
|
||||
* 0xNN: header data per layer
|
||||
* - block header
|
||||
* 0x00: block number
|
||||
* 0x04: block offset
|
||||
* 0x08: always 0x03
|
||||
* 0x0c+(04*N): layer size per layer
|
||||
* 0xNN: layer data per layer */
|
||||
data->layer_max = read_32bit(offset+0x08, streamfile);
|
||||
|
||||
data->header_next_start = 0x18;
|
||||
data->header_sizes_start = 0x4c;
|
||||
data->header_data_start = 0x4c + data->layer_max*0x04;
|
||||
|
||||
data->block_next_start = 0;
|
||||
data->block_sizes_start = 0x0c;
|
||||
data->block_data_start = 0x0c + data->layer_max*0x04;
|
||||
break;
|
||||
|
||||
case 0x00040008: /* Assassin's Creed */
|
||||
case 0x000B0008: /* Open Season, Surf's Up, TMNT, Splinter Cell HD */
|
||||
case 0x000C0008: /* Splinter Cell: Double Agent */
|
||||
@ -326,7 +361,7 @@ fail:
|
||||
|
||||
|
||||
/* Handles deinterleaving of Ubisoft's headered+blocked 'multitrack' streams */
|
||||
static STREAMFILE* setup_ubi_sb_streamfile(STREAMFILE *streamFile, off_t stream_offset, size_t stream_size, int layer_number, int layer_count, int big_endian) {
|
||||
static STREAMFILE* setup_ubi_sb_streamfile(STREAMFILE *streamFile, off_t stream_offset, size_t stream_size, int layer_number, int layer_count, int big_endian, int layer_hijack) {
|
||||
STREAMFILE *temp_streamFile = NULL, *new_streamFile = NULL;
|
||||
ubi_sb_io_data io_data = {0};
|
||||
size_t io_data_size = sizeof(ubi_sb_io_data);
|
||||
@ -336,6 +371,7 @@ static STREAMFILE* setup_ubi_sb_streamfile(STREAMFILE *streamFile, off_t stream_
|
||||
io_data.layer_number = layer_number;
|
||||
io_data.layer_count = layer_count;
|
||||
io_data.big_endian = big_endian;
|
||||
io_data.layer_hijack = layer_hijack;
|
||||
|
||||
if (!ubi_sb_io_init(streamFile, &io_data))
|
||||
goto fail;
|
||||
|
Loading…
x
Reference in New Issue
Block a user