VGMSTREAM * init_vgmstream_pos(STREAMFILE *streamFile) { VGMSTREAM * vgmstream = NULL; STREAMFILE * streamFileWAV = NULL; char filename[1024]; char filenameWAV[1024]; int i; /* check extension, case insensitive */ streamFile->get_name(streamFile,filename,sizeof(filename)); if (strcasecmp("pos",filename_extension(filename))) goto fail; /* check for .WAV file */ strcpy(filenameWAV,filename); strcpy(filenameWAV+strlen(filenameWAV)-3,"wav"); streamFileWAV = streamFile->open(streamFile,filenameWAV,STREAMFILE_DEFAULT_BUFFER_SIZE); if (!streamFileWAV) { /* try again, ucase */ for (i=strlen(filenameWAV);i>=0&&filenameWAV[i]!=DIRSEP;i--) filenameWAV[i]=toupper(filenameWAV[i]); streamFileWAV = streamFile->open(streamFile,filenameWAV,STREAMFILE_DEFAULT_BUFFER_SIZE); if (!streamFileWAV) goto fail; } /* let the real initer do the parsing */ vgmstream = init_vgmstream_riff(streamFileWAV); if (!vgmstream) goto fail; close_streamfile(streamFileWAV); streamFileWAV = NULL; /* install loops */ if (!vgmstream->loop_flag) { vgmstream->loop_flag = 1; vgmstream->loop_ch = calloc(vgmstream->channels, sizeof(VGMSTREAMCHANNEL)); if (!vgmstream->loop_ch) goto fail; } vgmstream->loop_start_sample = read_32bitLE(0,streamFile); vgmstream->loop_end_sample = read_32bitLE(4,streamFile); vgmstream->meta_type = meta_RIFF_WAVE_POS; return vgmstream; /* clean up anything we may have opened */ fail: if (streamFileWAV) close_streamfile(streamFileWAV); if (vgmstream) 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; }