diff --git a/src/libvgmstream.vcproj b/src/libvgmstream.vcproj index 1d03e4cd..1527776a 100644 --- a/src/libvgmstream.vcproj +++ b/src/libvgmstream.vcproj @@ -1,7 +1,7 @@  + + diff --git a/src/meta/meta.h b/src/meta/meta.h index 872fd1f3..96196e88 100644 --- a/src/meta/meta.h +++ b/src/meta/meta.h @@ -353,4 +353,6 @@ VGMSTREAM * init_vgmstream_ps2_vsf_tta(STREAMFILE *streamFile); VGMSTREAM * init_vgmstream_ads(STREAMFILE *streamFile); +VGMSTREAM * init_vgmstream_wii_str(STREAMFILE *streamFile); + #endif diff --git a/src/meta/ps2_kces.c b/src/meta/ps2_kces.c index 0d803939..fcecee14 100644 --- a/src/meta/ps2_kces.c +++ b/src/meta/ps2_kces.c @@ -19,7 +19,7 @@ VGMSTREAM * init_vgmstream_ps2_kces(STREAMFILE *streamFile) { if (read_32bitBE(0x00,streamFile) != 0x01006408) goto fail; - loop_flag = 0; /* (read_32bitLE(0x08,streamFile)!=0); */ + loop_flag = (read_32bitLE(0x14,streamFile)!=0); channel_count = read_32bitLE(0x1C,streamFile); /* build the VGMSTREAM */ @@ -33,7 +33,7 @@ VGMSTREAM * init_vgmstream_ps2_kces(STREAMFILE *streamFile) { vgmstream->coding_type = coding_PSX; vgmstream->num_samples = read_32bitLE(0x0C,streamFile)*28/16/channel_count; if (loop_flag) { - vgmstream->loop_start_sample = 0; + vgmstream->loop_start_sample = (read_32bitLE(0x0C,streamFile)-read_32bitLE(0x14,streamFile))*28/16/channel_count; vgmstream->loop_end_sample = read_32bitLE(0x0C,streamFile)*28/16/channel_count; } diff --git a/src/meta/ps2_str.c b/src/meta/ps2_str.c index 986797fd..b9e77029 100644 --- a/src/meta/ps2_str.c +++ b/src/meta/ps2_str.c @@ -34,6 +34,9 @@ VGMSTREAM * init_vgmstream_ps2_str(STREAMFILE *streamFile) { /* with others .STR file as it is a very common extension */ if (!infileSTH) goto fail; + if(read_32bitLE(0x2C,infileSTH)==0) + goto fail; + if((read_32bitLE(0x2C,infileSTH)==0x07) || (read_32bitLE(0x2C,infileSTH)==0x06)) channel_count=2; @@ -78,6 +81,7 @@ VGMSTREAM * init_vgmstream_ps2_str(STREAMFILE *streamFile) { vgmstream->ch[i].channel_start_offset= vgmstream->ch[i].offset+=(off_t)(vgmstream->interleave_block_size*i); + } } diff --git a/src/meta/wii_str.c b/src/meta/wii_str.c new file mode 100644 index 00000000..1555158a --- /dev/null +++ b/src/meta/wii_str.c @@ -0,0 +1,90 @@ +#include "meta.h" +#include "../util.h" + +VGMSTREAM * init_vgmstream_wii_str(STREAMFILE *streamFile) { + + VGMSTREAM * vgmstream = NULL; + STREAMFILE * infileSTH = NULL; + char filename[260]; + + char * filenameSTH = NULL; + + int i, j, channel_count, loop_flag; + + /* check extension, case insensitive */ + streamFile->get_name(streamFile,filename,sizeof(filename)); + if (strcasecmp("str",filename_extension(filename))) goto fail; + + /* check for .MIH file */ + filenameSTH=(char *)malloc(strlen(filename)+1); + + if (!filenameSTH) goto fail; + + strcpy(filenameSTH,filename); + strcpy(filenameSTH+strlen(filenameSTH)-3,"STH"); + + infileSTH = streamFile->open(streamFile,filenameSTH,STREAMFILE_DEFAULT_BUFFER_SIZE); + + /* STH File is necessary, so we can't confuse those file */ + /* with others .STR file as it is a very common extension */ + if (!infileSTH) goto fail; + + if(read_32bitLE(0x2C,infileSTH)!=0) + goto fail; + + channel_count = read_32bitBE(0x70,infileSTH); + + if(channel_count==1) + loop_flag = (read_32bitBE(0xD4,infileSTH)==0x00740000); + else + loop_flag = (read_32bitBE(0x124,infileSTH)==0x00740000); + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channel_count,loop_flag); + if (!vgmstream) goto fail; + + /* fill in the vital statistics */ + vgmstream->channels = channel_count; + vgmstream->sample_rate = read_32bitBE(0x38,infileSTH); + + vgmstream->interleave_block_size=0x8000; + vgmstream->num_samples=read_32bitBE(0x34,infileSTH); + + vgmstream->coding_type = coding_NGC_DSP; + vgmstream->layout_type = layout_interleave; + + vgmstream->meta_type = meta_WII_STR; + + if(loop_flag) { + vgmstream->loop_start_sample = 0; + vgmstream->loop_end_sample = vgmstream->num_samples; + } + + + /* open the file for reading by each channel */ + { + for (i=0;ich[i].streamfile = streamFile->open(streamFile,filename,vgmstream->interleave_block_size); + + if (!vgmstream->ch[i].streamfile) goto fail; + + vgmstream->ch[i].channel_start_offset= + vgmstream->ch[i].offset+=(off_t)(vgmstream->interleave_block_size*i); + + for(j=0; j<16; j++) { + vgmstream->ch[i].adpcm_coef[j]=read_16bitBE(0xAC+(j*2)+(i*0x50),infileSTH); + } + } + } + + close_streamfile(infileSTH); infileSTH=NULL; + + return vgmstream; + + /* clean up anything we may have opened */ +fail: + if (infileSTH) close_streamfile(infileSTH); + if (filenameSTH) {free(filenameSTH); filenameSTH=NULL;} + if (vgmstream) close_vgmstream(vgmstream); + return NULL; +} diff --git a/src/vgmstream.c b/src/vgmstream.c index b1d25cbf..2a409069 100644 --- a/src/vgmstream.c +++ b/src/vgmstream.c @@ -196,6 +196,7 @@ VGMSTREAM * (*init_vgmstream_fcns[])(STREAMFILE *streamFile) = { init_vgmstream_ps2_tk5, init_vgmstream_ps2_vsf_tta, init_vgmstream_ads, + init_vgmstream_wii_str, }; #define INIT_VGMSTREAM_FCNS (sizeof(init_vgmstream_fcns)/sizeof(init_vgmstream_fcns[0])) @@ -2099,6 +2100,9 @@ void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length) { case meta_ADS: snprintf(temp,TEMPSIZE,"dhSS Header"); break; + case meta_WII_STR: + snprintf(temp,TEMPSIZE,"HOTD Overkill - STR+STH WII Header"); + break; default: snprintf(temp,TEMPSIZE,"THEY SHOULD HAVE SENT A POET"); } diff --git a/src/vgmstream.h b/src/vgmstream.h index 85d58fa4..cf0289a5 100644 --- a/src/vgmstream.h +++ b/src/vgmstream.h @@ -375,7 +375,7 @@ typedef enum { meta_PS2_GBTS, /* Pop'n'Music 9 Audio File */ meta_NGC_IADP, /* Gamecube Interleave DSP */ meta_PS2_TK5, /* Tekken 5 Stream Files */ - + meta_WII_STR, /* House of The Dead Overkill STR+STH */ } meta_t; typedef struct {