diff --git a/Frameworks/vgmstream/vgmstream/src/meta/bkhd.c b/Frameworks/vgmstream/vgmstream/src/meta/bkhd.c index c2eb3723a..37f7dde74 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/bkhd.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/bkhd.c @@ -7,10 +7,9 @@ VGMSTREAM* init_vgmstream_bkhd(STREAMFILE* sf) { VGMSTREAM* vgmstream = NULL; STREAMFILE* temp_sf = NULL; - off_t subfile_offset, base_offset = 0; - size_t subfile_size; + uint32_t subfile_offset, subfile_size, base_offset = 0; uint32_t subfile_id; - int big_endian, version, is_riff = 0, is_dummy = 0, is_wmid = 0; + int big_endian, version, is_dummy = 0, is_wmid = 0; uint32_t (*read_u32)(off_t,STREAMFILE*); float (*read_f32)(off_t,STREAMFILE*); int total_subsongs, target_subsong = sf->stream_index; @@ -43,9 +42,11 @@ VGMSTREAM* init_vgmstream_bkhd(STREAMFILE* sf) { /* first chunk also follows standard chunk sizes unlike RIFF */ if (version <= 26) { - off_t data_offset, data_start, offset; - if (!find_chunk(sf, 0x44415441, base_offset, 0, &data_offset, NULL, big_endian, 0)) /* "DATA" */ + off_t data_offset_off; + uint32_t data_offset, data_start, offset; + if (!find_chunk(sf, 0x44415441, base_offset, 0, &data_offset_off, NULL, big_endian, 0)) /* "DATA" */ goto fail; + data_offset = data_offset_off; /* index: * 00: entries @@ -79,11 +80,11 @@ VGMSTREAM* init_vgmstream_bkhd(STREAMFILE* sf) { subfile_size = read_u32(offset + 0x14, sf); } else { - enum { + enum { CHUNK_DIDX = 0x44494458, /* "DIDX" */ CHUNK_DATA = 0x44415441, /* "DATA" */ }; - off_t didx_offset = 0, data_offset = 0, didx_size = 0, offset; + uint32_t didx_offset = 0, data_offset = 0, didx_size = 0, offset; chunk_t rc = {0}; rc.be_size = big_endian; @@ -120,25 +121,21 @@ VGMSTREAM* init_vgmstream_bkhd(STREAMFILE* sf) { subfile_offset = read_u32(offset + 0x04, sf) + data_offset; subfile_size = read_u32(offset + 0x08, sf); } - - //;VGM_LOG("BKHD: %lx, %x\n", subfile_offset, subfile_size); + + //;VGM_LOG("BKHD: %x, %x\n", subfile_offset, subfile_size); /* detect format */ if (subfile_offset <= 0 || subfile_size <= 0) { /* some indexes don't have data */ is_dummy = 1; } - else if (read_u32be(subfile_offset + 0x00, sf) == 0x52494646 || /* "RIFF" */ - read_u32be(subfile_offset + 0x00, sf) == 0x52494658) { /* "RIFX" */ - is_riff = 1; - } - else if (read_f32(subfile_offset + 0x02, sf) >= 30.0 && + else if (read_f32(subfile_offset + 0x02, sf) >= 30.0 && read_f32(subfile_offset + 0x02, sf) <= 250.0) { /* ignore Wwise's custom .wmid (similar to a regular midi but with simplified * chunks and custom fields: 0x00=MThd's division, 0x02: bpm (new), etc) */ is_wmid = 1; } - /* default is sfx */ + /* default is riff/sfx */ if (is_dummy || is_wmid) { @@ -151,7 +148,8 @@ VGMSTREAM* init_vgmstream_bkhd(STREAMFILE* sf) { temp_sf = setup_subfile_streamfile(sf, subfile_offset, subfile_size, NULL); if (!temp_sf) goto fail; - if (is_riff) { + /* read using temp_sf in case of >2GB .bnk */ + if (is_id32be(0x00, temp_sf, "RIFF") || is_id32be(0x00, temp_sf, "RIFX")) { vgmstream = init_vgmstream_wwise_bnk(temp_sf, &prefetch); if (!vgmstream) goto fail; } @@ -196,7 +194,7 @@ fail: /* BKHD mini format, for FX plugins [Borderlands 2 (X360), Warhammer 40000 (PC)] */ VGMSTREAM* init_vgmstream_bkhd_fx(STREAMFILE* sf) { VGMSTREAM* vgmstream = NULL; - off_t start_offset, data_size; + uint32_t start_offset, data_size; int big_endian, loop_flag, channels, sample_rate, entries; uint32_t (*read_u32)(off_t,STREAMFILE*); diff --git a/Frameworks/vgmstream/vgmstream/src/meta/hca_keys.h b/Frameworks/vgmstream/vgmstream/src/meta/hca_keys.h index 1582d0a6c..fb971f29f 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/hca_keys.h +++ b/Frameworks/vgmstream/vgmstream/src/meta/hca_keys.h @@ -885,6 +885,9 @@ static const hcakey_info hcakey_list[] = { // Heaven Burns Red (Android) {7355875239102698567}, // 6615518E8ECED447 + // Digimon ReArise (Android) + {34810080072368384}, // 007BAB9559510100 + }; #endif/*_HCA_KEYS_H_*/ diff --git a/Frameworks/vgmstream/vgmstream/src/meta/riff.c b/Frameworks/vgmstream/vgmstream/src/meta/riff.c index 23dc0aa7a..2220adaf4 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/riff.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/riff.c @@ -340,6 +340,7 @@ VGMSTREAM* init_vgmstream_riff(STREAMFILE* sf) { int mwv = 0; off_t mwv_pflt_offset = -1; off_t mwv_ctrl_offset = -1; + int ignore_riff_size = 0; /* checks*/ @@ -374,8 +375,9 @@ VGMSTREAM* init_vgmstream_riff(STREAMFILE* sf) { * .ima: Baja: Edge of Control (PS3/X360) * .nsa: Studio Ring games that uses NScripter [Hajimete no Otetsudai (PC)] * .pcm: Silent Hill Arcade (PC) + * .xvag: Uncharted Golden Abyss (Vita)[ATRAC9] */ - if ( check_extensions(sf, "wav,lwav,xwav,da,dax,cd,med,snd,adx,adp,xss,xsew,adpcm,adw,wd,,sbv,wvx,str,at3,rws,aud,at9,ckd,saf,ima,nsa,pcm") ) { + if ( check_extensions(sf, "wav,lwav,xwav,da,dax,cd,med,snd,adx,adp,xss,xsew,adpcm,adw,wd,,sbv,wvx,str,at3,rws,aud,at9,ckd,saf,ima,nsa,pcm,xvag") ) { ; } else if ( check_extensions(sf, "mwv") ) { @@ -445,10 +447,15 @@ VGMSTREAM* init_vgmstream_riff(STREAMFILE* sf) { else if (codec == 0x0002 && riff_size + 0x08 + 0x1c == file_size) riff_size += 0x1c; /* [Mega Man X Legacy Collection (PC)] (adds "ver /tIME/ver " chunks but RIFF size wasn't updated) */ + + else if (codec == 0x0001 && ( + riff_size + 0x08 + 0x08 == file_size || riff_size + 0x08 + 0x09 == file_size || + riff_size + 0x08 - 0x3E == file_size || riff_size + 0x08 - 0x02 == file_size)) + ignore_riff_size = 1; /* [Cross Gate (PC)] (last info LIST chunk has wrong size) */ } /* check for truncated RIFF */ - if (file_size != riff_size + 0x08) { + if (file_size != riff_size + 0x08 && !ignore_riff_size) { vgm_logi("RIFF: wrong expected size (report/re-rip?)\n"); VGM_LOG("riff: file_size = %x, riff_size+8 = %x\n", file_size, riff_size + 0x08); /* don't log to user */ goto fail; @@ -456,14 +463,17 @@ VGMSTREAM* init_vgmstream_riff(STREAMFILE* sf) { /* read through chunks to verify format and find metadata */ { - off_t current_chunk = 0x0c; /* start with first chunk */ + uint32_t current_chunk = 0x0c; /* start with first chunk */ while (current_chunk < file_size) { - uint32_t chunk_id = read_32bitBE(current_chunk + 0x00,sf); /* FOURCC */ - size_t chunk_size = read_32bitLE(current_chunk + 0x04,sf); + uint32_t chunk_id = read_u32be(current_chunk + 0x00,sf); /* FOURCC */ + uint32_t chunk_size = read_u32le(current_chunk + 0x04,sf); - if (current_chunk + 0x08 + chunk_size > file_size) - goto fail; + /* allow broken last chunk [Cross Gate (PC)] */ + if (current_chunk + 0x08 + chunk_size > file_size) { + VGM_LOG("RIFF: broken chunk at %x + 0x08 + %x > %x\n", current_chunk, chunk_size, file_size); + break; /* truncated */ + } switch(chunk_id) { case 0x666d7420: /* "fmt " */ @@ -490,7 +500,7 @@ VGMSTREAM* init_vgmstream_riff(STREAMFILE* sf) { switch (read_32bitBE(current_chunk+0x08, sf)) { case 0x6164746C: /* "adtl" */ /* yay, atdl is its own little world */ - parse_adtl(current_chunk + 8, chunk_size, + parse_adtl(current_chunk + 0x8, chunk_size, sf, &loop_start_ms,&loop_end_ms,&loop_flag); break; diff --git a/Frameworks/vgmstream/vgmstream/src/util/chunks.h b/Frameworks/vgmstream/vgmstream/src/util/chunks.h index 3d5ffe082..716367d29 100644 --- a/Frameworks/vgmstream/vgmstream/src/util/chunks.h +++ b/Frameworks/vgmstream/vgmstream/src/util/chunks.h @@ -7,8 +7,8 @@ typedef struct { uint32_t type; /* chunk id/fourcc */ uint32_t size; /* chunk size */ uint32_t offset; /* chunk offset (after type/size) */ - off_t current; /* start position, or next chunk after size (set to -1 to break) */ - off_t max; /* max offset, or filesize if not set */ + uint32_t current; /* start position, or next chunk after size (set to -1 to break) */ + uint32_t max; /* max offset, or filesize if not set */ int le_type; /* read type as LE instead of more common BE */ int be_size; /* read type as BE instead of more common LE */