vgmstream/src/meta/ppst.c

61 lines
2.0 KiB
C
Raw Normal View History

#include "meta.h"
#include "../coding/coding.h"
#include "ppst_streamfile.h"
/* PPST - ParaPpa STream (maybe), extracted from .img bigfile [Parappa the Rapper (PSP)] */
VGMSTREAM * init_vgmstream_ppst(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
int total_subsongs, target_subsong = streamFile->stream_index;
/* checks */
if (!check_extensions(streamFile, "sng"))
goto fail;
if (read_32bitBE(0x00,streamFile) != 0x50505354) /* "PPST" */
goto fail;
/* header has some control and comment fields then interleaved RIFF .at3 */
/* count subsongs (mainly 4, rarely 1) */
{
off_t offset = 0xa0;
total_subsongs = 0;
while (offset < 0x800) {
if (read_32bitLE(offset + 0x04, streamFile) == 0) /* subsong size */
break;
total_subsongs++;
offset += 0x08;
}
VGM_LOG("st=%lx\n", total_subsongs);
if (target_subsong == 0) target_subsong = 1;
if (target_subsong < 0 || target_subsong > total_subsongs || total_subsongs < 1) goto fail;
}
{
off_t start_offset = 0x800;
size_t interleave_size = 0x4000;
size_t stride_size = 0x4000*total_subsongs;
/* subsong header at 0xa0, 0x00(1): id, 0x01(3): blocks of interleave */
size_t stream_size = read_32bitLE(0xA0+0x08*(target_subsong-1)+0x04, streamFile);
STREAMFILE* temp_streamFile = setup_ppst_streamfile(streamFile, start_offset+interleave_size*(target_subsong-1), interleave_size, stride_size, stream_size);
if (!temp_streamFile) goto fail;
vgmstream = init_vgmstream_riff(temp_streamFile);
close_streamfile(temp_streamFile);
if (!vgmstream) goto fail;
vgmstream->num_streams = total_subsongs;
vgmstream->stream_size = stream_size;
vgmstream->meta_type = meta_PPST;
}
return vgmstream;
fail:
close_vgmstream(vgmstream);
return NULL;
}