From f47b79b0b0fa2a2bc81f9d0e2b3c26b4ce300c22 Mon Sep 17 00:00:00 2001 From: bnnm Date: Sun, 24 Jan 2021 21:02:27 +0100 Subject: [PATCH] Add MJB+MJH [Star Wars: Bounty Hunter (PS2)] --- src/formats.c | 2 + src/libvgmstream.vcproj | 4 ++ src/libvgmstream.vcxproj | 1 + src/libvgmstream.vcxproj.filters | 3 ++ src/meta/meta.h | 2 + src/meta/mjb_mjh.c | 83 ++++++++++++++++++++++++++++++++ src/vgmstream.c | 1 + src/vgmstream.h | 1 + 8 files changed, 97 insertions(+) create mode 100644 src/meta/mjb_mjh.c diff --git a/src/formats.c b/src/formats.c index f098ac6c..25fb3af8 100644 --- a/src/formats.c +++ b/src/formats.c @@ -305,6 +305,7 @@ static const char* extension_list[] = { "mds", "mdsp", "med", + "mjb", "mi4", "mib", "mic", @@ -1334,6 +1335,7 @@ static const meta_info meta_info_list[] = { {meta_DSP_CWAC, "CRI CWAC header"}, {meta_COMPRESSWAVE, "CompressWave .cwav header"}, {meta_KTAC, "Koei Tecmo KTAC header"}, + {meta_MJB_MJH, "Sony MultiStream MJH+MJB header"}, }; void get_vgmstream_coding_description(VGMSTREAM* vgmstream, char* out, size_t out_size) { diff --git a/src/libvgmstream.vcproj b/src/libvgmstream.vcproj index 75c08dea..5325200d 100644 --- a/src/libvgmstream.vcproj +++ b/src/libvgmstream.vcproj @@ -931,6 +931,10 @@ + + + diff --git a/src/libvgmstream.vcxproj.filters b/src/libvgmstream.vcxproj.filters index 5a3bd5e1..013f1718 100644 --- a/src/libvgmstream.vcxproj.filters +++ b/src/libvgmstream.vcxproj.filters @@ -1675,6 +1675,9 @@ meta\Source Files + + meta\Source Files + meta\Source Files diff --git a/src/meta/meta.h b/src/meta/meta.h index 71076b79..ecbe94c0 100644 --- a/src/meta/meta.h +++ b/src/meta/meta.h @@ -940,4 +940,6 @@ VGMSTREAM* init_vgmstream_compresswave(STREAMFILE* sf); VGMSTREAM* init_vgmstream_ktac(STREAMFILE* sf); +VGMSTREAM* init_vgmstream_mjb_mjh(STREAMFILE* sf); + #endif /*_META_H*/ diff --git a/src/meta/mjb_mjh.c b/src/meta/mjb_mjh.c new file mode 100644 index 00000000..f80b7f7b --- /dev/null +++ b/src/meta/mjb_mjh.c @@ -0,0 +1,83 @@ +#include "meta.h" +#include "../coding/coding.h" + +/* MJB+MJH - SCEE MultiStream? bank of MIB+MIH [Star Wars: Bounty Hunter (PS2)] */ +VGMSTREAM* init_vgmstream_mjb_mjh(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; + STREAMFILE* sh = NULL; + off_t start_offset = 0, header_offset = 0; + size_t data_size, frame_size, frame_count; + int channels, loop_flag, sample_rate; + int total_subsongs, target_subsong = sf->stream_index; + + + /* checks */ + if (!check_extensions(sf, "mjb")) + goto fail; + + sh = open_streamfile_by_ext(sf, "mjh"); + if (!sh) goto fail; + + /* parse entries */ + { + int i; + off_t subsong_offset = 0; + + total_subsongs = read_s32le(0x00,sh); + if (target_subsong == 0) target_subsong = 1; + if (target_subsong < 0 || target_subsong > total_subsongs || total_subsongs < 1) goto fail; + + for (i = 0; i < total_subsongs; i++) { + off_t offset = 0x40 + 0x40 * i; + size_t subsong_size = read_u32le(offset + 0x08,sh) * read_u32le(offset + 0x10,sh) * read_u32le(offset + 0x14,sh); + + if (i + 1== target_subsong) { + header_offset = offset; + start_offset = subsong_offset; + } + subsong_offset += subsong_size; + } + + if (!header_offset) + goto fail; + } + + VGM_LOG("3: %lx\n", start_offset); + + /* also see MIB+MIH (same thing but this excludes padding stuff) */ + if (read_u32le(header_offset + 0x00,sh) != 0x40) + goto fail; + channels = read_u32le(header_offset + 0x08,sh); + sample_rate = read_u32le(header_offset + 0x0c,sh); + frame_size = read_u32le(header_offset + 0x10,sh); + frame_count = read_u32le(header_offset + 0x14,sh); + + data_size = frame_count * frame_size * channels; + loop_flag = 0; + + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channels, loop_flag); + if (!vgmstream) goto fail; + + vgmstream->meta_type = meta_MJB_MJH; + vgmstream->sample_rate = sample_rate; + vgmstream->num_samples = ps_bytes_to_samples(data_size, channels); + + vgmstream->num_streams = total_subsongs; + vgmstream->stream_size = data_size; + + vgmstream->coding_type = coding_PSX; + vgmstream->layout_type = layout_interleave; + vgmstream->interleave_block_size = frame_size; + + if (!vgmstream_open_stream(vgmstream, sf, start_offset)) + goto fail; + close_streamfile(sh); + return vgmstream; + +fail: + close_streamfile(sh); + close_vgmstream(vgmstream); + return NULL; +} diff --git a/src/vgmstream.c b/src/vgmstream.c index c7ba0976..031a4945 100644 --- a/src/vgmstream.c +++ b/src/vgmstream.c @@ -519,6 +519,7 @@ VGMSTREAM* (*init_vgmstream_functions[])(STREAMFILE* sf) = { init_vgmstream_acx, init_vgmstream_compresswave, init_vgmstream_ktac, + init_vgmstream_mjb_mjh, /* lowest priority metas (should go after all metas, and TXTH should go before raw formats) */ init_vgmstream_txth, /* proper parsers should supersede TXTH, once added */ diff --git a/src/vgmstream.h b/src/vgmstream.h index dfa5bfb7..9e401296 100644 --- a/src/vgmstream.h +++ b/src/vgmstream.h @@ -752,6 +752,7 @@ typedef enum { meta_DSP_CWAC, meta_COMPRESSWAVE, meta_KTAC, + meta_MJB_MJH, } meta_t; /* standard WAVEFORMATEXTENSIBLE speaker positions */