/* ADS in containers */ VGMSTREAM * init_vgmstream_ps2_ads_container(STREAMFILE *streamFile) { VGMSTREAM *vgmstream = NULL; STREAMFILE *temp_streamFile = NULL; off_t subfile_offset; size_t subfile_size; /* checks */ if (!check_extensions(streamFile, "ads")) goto fail; if (read_32bitBE(0x00,streamFile) == 0x41445343 && /* "ADSC" */ read_32bitBE(0x04,streamFile) == 0x01000000) { /* Kenka Bancho 2, Kamen Rider Hibiki/Kabuto, Shinjuku no Okami */ subfile_offset = 0x08; } else if (read_32bitBE(0x00,streamFile) == 0x63617669 && /* "cavi" */ read_32bitBE(0x04,streamFile) == 0x61207374 && /* "a st" */ read_32bitBE(0x08,streamFile) == 0x7265616D) { /* "ream" */ /* cavia games: Drakengard 1/2, Dragon Quest Yangus, GITS: Stand Alone Complex */ subfile_offset = 0x7d8; } else { goto fail; } subfile_size = get_streamfile_size(streamFile) - subfile_offset; temp_streamFile = setup_subfile_streamfile(streamFile, subfile_offset,subfile_size, NULL); if (!temp_streamFile) goto fail; vgmstream = init_vgmstream_ps2_ads(temp_streamFile); close_streamfile(temp_streamFile); return vgmstream; fail: close_streamfile(temp_streamFile); close_vgmstream(vgmstream); return NULL; }
/* .XPS - From Software games banks [Metal Wolf Chaos (Xbox), Otogi (Xbox)] */ VGMSTREAM * init_vgmstream_xps(STREAMFILE *streamFile) { VGMSTREAM * vgmstream = NULL; STREAMFILE * streamData = NULL; int i, entries; off_t entry_offset = 0x10; int total_subsongs, target_subsong = streamFile->stream_index; /* checks */ if (!check_extensions(streamFile, "xps")) goto fail; if (read_32bitLE(0x00,streamFile) != get_streamfile_size(streamFile)) goto fail; if (read_32bitBE(0x0c,streamFile) != 0x64696666) /* "diff" */ goto fail; /* handle .xps alone (stream .xps+data are done above) */ streamData = open_streamfile_by_ext(streamFile, "dat"); if (streamData) goto fail; /* main section + bank sections (usually same number but not always) */ entries = read_32bitLE(0x04,streamFile); total_subsongs = 0; if (target_subsong == 0) target_subsong = 1; if (target_subsong < 0 /*|| target_subsong > total_subsongs || total_subsongs < 1*/) goto fail; /* parse entries: skip (there is probably a stream/bank flag here) */ for (i = 0; i < entries; i++) { off_t entry_base = entry_offset; size_t entry_size = read_32bitLE(entry_base+0x00,streamFile); uint32_t entry_id = read_32bitBE(entry_base+0x04,streamFile); size_t entry_pad = read_32bitLE(entry_base+0x08,streamFile); /* 0x0c: always null, rest: entry (format varies) */ entry_offset += entry_size + entry_pad + 0x10; /* sound info entry */ if (entry_id == 0x73696400) { /* "sid\0" */ /* keep looking for sound banks */ continue; } /* sound bank entry, otherwise no good */ if (entry_id != 0x75647362) { /* "udsb" */ goto fail; } total_subsongs++; /* open internal RIFF */ if (target_subsong == total_subsongs && vgmstream == NULL) { STREAMFILE* temp_streamFile; off_t subsong_offset = entry_base+0x18; size_t subsong_size = read_32bitLE(entry_base+0x14,streamFile); temp_streamFile = setup_subfile_streamfile(streamFile, subsong_offset,subsong_size, "wav"); if (!temp_streamFile) goto fail; vgmstream = init_vgmstream_riff(temp_streamFile); close_streamfile(temp_streamFile); if (!vgmstream) goto fail; } } /* subsong not found */ if (!vgmstream) goto fail; vgmstream->num_streams = total_subsongs; return vgmstream; fail: close_streamfile(streamData); close_vgmstream(vgmstream); return NULL; }