Add some Ubi SB [G.R.A.W (X360), Splinter Cell D.A. Online (PC)]

This commit is contained in:
bnnm 2019-03-16 13:58:28 +01:00
parent 703c29775d
commit c1b9df6a5e
3 changed files with 83 additions and 4 deletions

View File

@ -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_ */

View File

@ -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);

View File

@ -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;