mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-12-23 20:04:50 +01:00
98 lines
2.9 KiB
C
98 lines
2.9 KiB
C
|
#include "meta.h"
|
||
|
#include "../coding/coding.h"
|
||
|
|
||
|
|
||
|
/* .bsf - from Kuju games [Reign of Fire ((PS2/GC/Xbox)] */
|
||
|
VGMSTREAM* init_vgmstream_bsf(STREAMFILE* sf) {
|
||
|
VGMSTREAM* vgmstream = NULL;
|
||
|
STREAMFILE* temp_sf = NULL;
|
||
|
uint32_t subfile_type;
|
||
|
off_t subfile_name;
|
||
|
off_t subfile_offset;
|
||
|
size_t subfile_size;
|
||
|
int total_subsongs, target_subsong = sf->stream_index;
|
||
|
|
||
|
|
||
|
/* checks */
|
||
|
if (!check_extensions(sf,"bsf"))
|
||
|
goto fail;
|
||
|
if (read_u32le(0x00,sf) != 0x42534648) /* "BSFH" (notice chunks are LE even on GC) */
|
||
|
goto fail;
|
||
|
|
||
|
total_subsongs = read_u32le(0x08,sf);
|
||
|
if (target_subsong == 0) target_subsong = 1;
|
||
|
if (target_subsong < 0 || target_subsong > total_subsongs || total_subsongs < 1) goto fail;
|
||
|
|
||
|
/* dumb container of other formats */
|
||
|
{
|
||
|
int i;
|
||
|
off_t offset = 0x08 + read_u32le(0x04,sf); /* 0x04: chunk size */
|
||
|
|
||
|
subfile_type = 0;
|
||
|
for (i = 0; i < total_subsongs; i++) {
|
||
|
/* subsong header "xxxH" */
|
||
|
//uint32_t head_type = read_u32le(offset + 0x00,sf);
|
||
|
uint32_t head_size = read_u32le(offset + 0x04,sf);
|
||
|
/* 0x08: name
|
||
|
* 0x28: audio config? */
|
||
|
/* subsong data "xxxD" */
|
||
|
uint32_t data_type = read_u32le(offset + 0x08 + head_size + 0x00,sf);
|
||
|
uint32_t data_size = read_u32le(offset + 0x08 + head_size + 0x04,sf);
|
||
|
|
||
|
if (i + 1 == target_subsong) {
|
||
|
subfile_name = offset + 0x08;
|
||
|
subfile_type = data_type;
|
||
|
subfile_size = data_size;
|
||
|
subfile_offset = offset + 0x08 + head_size + 0x08;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
offset += 0x08 + head_size + 0x08 + data_size;
|
||
|
}
|
||
|
|
||
|
if (subfile_type == 0)
|
||
|
goto fail;
|
||
|
}
|
||
|
|
||
|
|
||
|
switch(subfile_type) {
|
||
|
case 0x44535044: /* "DSPD" */
|
||
|
temp_sf = setup_subfile_streamfile(sf, subfile_offset, subfile_size, "dsp");
|
||
|
if (!temp_sf) goto fail;
|
||
|
|
||
|
vgmstream = init_vgmstream_ngc_dsp_std(temp_sf);
|
||
|
if (!vgmstream) goto fail;
|
||
|
break;
|
||
|
|
||
|
case 0x56414744: /* "VAGD" */
|
||
|
temp_sf = setup_subfile_streamfile(sf, subfile_offset, subfile_size, "vag");
|
||
|
if (!temp_sf) goto fail;
|
||
|
|
||
|
vgmstream = init_vgmstream_vag(temp_sf);
|
||
|
if (!vgmstream) goto fail;
|
||
|
break;
|
||
|
|
||
|
case 0x57415644: /* "WAVD" */
|
||
|
temp_sf = setup_subfile_streamfile(sf, subfile_offset, subfile_size, "wav");
|
||
|
if (!temp_sf) goto fail;
|
||
|
|
||
|
vgmstream = init_vgmstream_riff(temp_sf);
|
||
|
if (!vgmstream) goto fail;
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
goto fail;
|
||
|
}
|
||
|
|
||
|
vgmstream->num_streams = total_subsongs;
|
||
|
read_string(vgmstream->stream_name, 0x20, subfile_name, sf);
|
||
|
|
||
|
close_streamfile(temp_sf);
|
||
|
return vgmstream;
|
||
|
|
||
|
fail:
|
||
|
close_streamfile(temp_sf);
|
||
|
close_vgmstream(vgmstream);
|
||
|
return NULL;
|
||
|
}
|