Updated VGMStream to r1050-3802-g5c9d52d9

CQTexperiment
Christopher Snowhill 2021-07-09 01:14:16 -07:00
parent 0bac16c976
commit 1c7b4bfde9
11 changed files with 136 additions and 64 deletions

View File

@ -86,6 +86,7 @@
8313E3E71902021800B4B6F1 /* mpg123.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8313E3431901FBDD00B4B6F1 /* mpg123.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; 8313E3E71902021800B4B6F1 /* mpg123.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8313E3431901FBDD00B4B6F1 /* mpg123.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
8315958720FEC832007002F0 /* asf_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 8315958320FEC831007002F0 /* asf_decoder.c */; }; 8315958720FEC832007002F0 /* asf_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 8315958320FEC831007002F0 /* asf_decoder.c */; };
8315958920FEC83F007002F0 /* asf.c in Sources */ = {isa = PBXBuildFile; fileRef = 8315958820FEC83F007002F0 /* asf.c */; }; 8315958920FEC83F007002F0 /* asf.c in Sources */ = {isa = PBXBuildFile; fileRef = 8315958820FEC83F007002F0 /* asf.c */; };
8317C24C26982CC1007DD0B8 /* sspr.c in Sources */ = {isa = PBXBuildFile; fileRef = 8317C24826982CC1007DD0B8 /* sspr.c */; };
831BA6181EAC61A500CF89B0 /* adx.c in Sources */ = {isa = PBXBuildFile; fileRef = 831BA60E1EAC61A500CF89B0 /* adx.c */; }; 831BA6181EAC61A500CF89B0 /* adx.c in Sources */ = {isa = PBXBuildFile; fileRef = 831BA60E1EAC61A500CF89B0 /* adx.c */; };
831BA6191EAC61A500CF89B0 /* ogl.c in Sources */ = {isa = PBXBuildFile; fileRef = 831BA60F1EAC61A500CF89B0 /* ogl.c */; }; 831BA6191EAC61A500CF89B0 /* ogl.c in Sources */ = {isa = PBXBuildFile; fileRef = 831BA60F1EAC61A500CF89B0 /* ogl.c */; };
831BA61A1EAC61A500CF89B0 /* ps2_vds_vdm.c in Sources */ = {isa = PBXBuildFile; fileRef = 831BA6101EAC61A500CF89B0 /* ps2_vds_vdm.c */; }; 831BA61A1EAC61A500CF89B0 /* ps2_vds_vdm.c in Sources */ = {isa = PBXBuildFile; fileRef = 831BA6101EAC61A500CF89B0 /* ps2_vds_vdm.c */; };
@ -878,6 +879,7 @@
8313E33D1901FBDC00B4B6F1 /* mpg123.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = mpg123.xcodeproj; path = ../mpg123/mpg123.xcodeproj; sourceTree = "<group>"; }; 8313E33D1901FBDC00B4B6F1 /* mpg123.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = mpg123.xcodeproj; path = ../mpg123/mpg123.xcodeproj; sourceTree = "<group>"; };
8315958320FEC831007002F0 /* asf_decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = asf_decoder.c; sourceTree = "<group>"; }; 8315958320FEC831007002F0 /* asf_decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = asf_decoder.c; sourceTree = "<group>"; };
8315958820FEC83F007002F0 /* asf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = asf.c; sourceTree = "<group>"; }; 8315958820FEC83F007002F0 /* asf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = asf.c; sourceTree = "<group>"; };
8317C24826982CC1007DD0B8 /* sspr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sspr.c; sourceTree = "<group>"; };
831BA60E1EAC61A500CF89B0 /* adx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = adx.c; sourceTree = "<group>"; }; 831BA60E1EAC61A500CF89B0 /* adx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = adx.c; sourceTree = "<group>"; };
831BA60F1EAC61A500CF89B0 /* ogl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ogl.c; sourceTree = "<group>"; }; 831BA60F1EAC61A500CF89B0 /* ogl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ogl.c; sourceTree = "<group>"; };
831BA6101EAC61A500CF89B0 /* ps2_vds_vdm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ps2_vds_vdm.c; sourceTree = "<group>"; }; 831BA6101EAC61A500CF89B0 /* ps2_vds_vdm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ps2_vds_vdm.c; sourceTree = "<group>"; };
@ -2098,6 +2100,7 @@
836F6EF418BDC2190095E648 /* sqex_scd.c */, 836F6EF418BDC2190095E648 /* sqex_scd.c */,
837CEAF023487F2C00E62A4A /* sqex_sead_streamfile.h */, 837CEAF023487F2C00E62A4A /* sqex_sead_streamfile.h */,
83A21F84201D8981000F04B9 /* sqex_sead.c */, 83A21F84201D8981000F04B9 /* sqex_sead.c */,
8317C24826982CC1007DD0B8 /* sspr.c */,
8306B0C12098458C000302D4 /* sthd.c */, 8306B0C12098458C000302D4 /* sthd.c */,
83AA5D231F6E2F9C0020821C /* stm.c */, 83AA5D231F6E2F9C0020821C /* stm.c */,
836F6EF618BDC2190095E648 /* str_asr.c */, 836F6EF618BDC2190095E648 /* str_asr.c */,
@ -2932,6 +2935,7 @@
836F6F2518BDC2190095E648 /* g721_decoder.c in Sources */, 836F6F2518BDC2190095E648 /* g721_decoder.c in Sources */,
836F6FE818BDC2190095E648 /* ps2_mic.c in Sources */, 836F6FE818BDC2190095E648 /* ps2_mic.c in Sources */,
836F6F3C18BDC2190095E648 /* xa_decoder.c in Sources */, 836F6F3C18BDC2190095E648 /* xa_decoder.c in Sources */,
8317C24C26982CC1007DD0B8 /* sspr.c in Sources */,
832BF82521E0514B006F50F1 /* ogg_opus.c in Sources */, 832BF82521E0514B006F50F1 /* ogg_opus.c in Sources */,
83709E091ECBC1A4005C03D3 /* ta_aac.c in Sources */, 83709E091ECBC1A4005C03D3 /* ta_aac.c in Sources */,
836F6F9118BDC2190095E648 /* ios_psnd.c in Sources */, 836F6F9118BDC2190095E648 /* ios_psnd.c in Sources */,

View File

@ -303,6 +303,7 @@ static int ps_find_loop_offsets_internal(STREAMFILE *sf, off_t start_offset, siz
&& buf[0] != 0x00 /* ignore blank frame */ && buf[0] != 0x00 /* ignore blank frame */
&& buf[0] != 0x0c /* ignore silent frame */ && buf[0] != 0x0c /* ignore silent frame */
&& buf[0] != 0x3c /* ignore some L-R tracks with different end flags */ && buf[0] != 0x3c /* ignore some L-R tracks with different end flags */
&& buf[0] != 0x1c /* ignore some L-R tracks with different end flags */
) { ) {
/* assume full loop with repeated frame header and null frame */ /* assume full loop with repeated frame header and null frame */
@ -351,11 +352,14 @@ int ps_find_loop_offsets_full(STREAMFILE *sf, off_t start_offset, size_t data_si
return ps_find_loop_offsets_internal(sf, start_offset, data_size, channels, interleave, p_loop_start, p_loop_end, 1); return ps_find_loop_offsets_internal(sf, start_offset, data_size, channels, interleave, p_loop_start, p_loop_end, 1);
} }
size_t ps_find_padding(STREAMFILE *streamFile, off_t start_offset, size_t data_size, int channels, size_t interleave, int discard_empty) { size_t ps_find_padding(STREAMFILE* sf, off_t start_offset, size_t data_size, int channels, size_t interleave, int discard_empty) {
off_t min_offset, offset; off_t min_offset, offset, read_offset = 0;
size_t frame_size = 0x10; size_t frame_size = 0x10;
size_t padding_size = 0; size_t padding_size = 0;
size_t interleave_consumed = 0; size_t interleave_consumed = 0;
uint8_t buf[0x8000];
int buf_pos = 0;
int bytes;
if (data_size == 0 || channels == 0 || (channels > 1 && interleave == 0)) if (data_size == 0 || channels == 0 || (channels > 1 && interleave == 0))
@ -374,12 +378,22 @@ size_t ps_find_padding(STREAMFILE *streamFile, off_t start_offset, size_t data_s
uint8_t flag; uint8_t flag;
int is_empty = 0; int is_empty = 0;
/* read in chunks to optimize (less SF rebuffering since we go in reverse) */
if (offset < read_offset || buf_pos <= 0) {
read_offset = offset - sizeof(buf);
if (read_offset < 0)
read_offset = 0; //?
bytes = read_streamfile(buf, read_offset, sizeof(buf), sf);
buf_pos = (bytes / frame_size * frame_size);
}
buf_pos -= frame_size;
offset -= frame_size; offset -= frame_size;
f1 = read_32bitBE(offset+0x00,streamFile); f1 = get_u32be(buf+buf_pos+0x00);
f2 = read_32bitBE(offset+0x04,streamFile); f2 = get_u32be(buf+buf_pos+0x04);
f3 = read_32bitBE(offset+0x08,streamFile); f3 = get_u32be(buf+buf_pos+0x08);
f4 = read_32bitBE(offset+0x0c,streamFile); f4 = get_u32be(buf+buf_pos+0x0c);
flag = (f1 >> 16) & 0xFF; flag = (f1 >> 16) & 0xFF;
if (f1 == 0 && f2 == 0 && f3 == 0 && f4 == 0) if (f1 == 0 && f2 == 0 && f3 == 0 && f4 == 0)
@ -406,9 +420,11 @@ size_t ps_find_padding(STREAMFILE *streamFile, off_t start_offset, size_t data_s
if (interleave_consumed == interleave) { if (interleave_consumed == interleave) {
interleave_consumed = 0; interleave_consumed = 0;
offset -= interleave * (channels - 1); offset -= interleave * (channels - 1);
buf_pos -= interleave * (channels - 1);
} }
} }
//;VGM_LOG("PSX PAD: total size %x\n", padding_size);
return padding_size; return padding_size;
} }
@ -424,14 +440,14 @@ size_t ps_cfg_bytes_to_samples(size_t bytes, size_t frame_size, int channels) {
} }
/* test PS-ADPCM frames for correctness */ /* test PS-ADPCM frames for correctness */
int ps_check_format(STREAMFILE *streamFile, off_t offset, size_t max) { int ps_check_format(STREAMFILE* sf, off_t offset, size_t max) {
off_t max_offset = offset + max; off_t max_offset = offset + max;
if (max_offset > get_streamfile_size(streamFile)) if (max_offset > get_streamfile_size(sf))
max_offset = get_streamfile_size(streamFile); max_offset = get_streamfile_size(sf);
while (offset < max_offset) { while (offset < max_offset) {
uint8_t predictor = (read_8bit(offset+0x00,streamFile) >> 4) & 0x0f; uint8_t predictor = (read_8bit(offset+0x00,sf) >> 4) & 0x0f;
uint8_t flags = read_8bit(offset+0x01,streamFile); uint8_t flags = read_8bit(offset+0x01,sf);
if (predictor > 5 || flags > 7) { if (predictor > 5 || flags > 7) {
return 0; return 0;

View File

@ -143,6 +143,7 @@ static const char* extension_list[] = {
"cwav", "cwav",
"cxs", "cxs",
"d2", //txth/reserved [Dodonpachi Dai-Ou-Jou (PS2)]
"da", "da",
//"dat", //common //"dat", //common
"data", "data",
@ -437,6 +438,7 @@ static const char* extension_list[] = {
"sb6", "sb6",
"sb7", "sb7",
"sbk", "sbk",
"sbin",
"sbr", "sbr",
"sbv", "sbv",
"sm0", "sm0",
@ -447,7 +449,6 @@ static const char* extension_list[] = {
"sm5", "sm5",
"sm6", "sm6",
"sm7", "sm7",
"sbin",
"sc", "sc",
"scd", "scd",
"sch", "sch",
@ -490,6 +491,7 @@ static const char* extension_list[] = {
"ss2", "ss2",
"ssd", //txth/reserved [Zack & Wiki (Wii)] "ssd", //txth/reserved [Zack & Wiki (Wii)]
"ssm", "ssm",
"sspr",
"sss", "sss",
"ster", "ster",
"sth", "sth",

View File

@ -407,6 +407,9 @@ static const hcakey_info hcakey_list[] = {
/* maimai DX Splash (AC) */ /* maimai DX Splash (AC) */
{9170825592834449000}, // 7F4551499DF55E68 {9170825592834449000}, // 7F4551499DF55E68
/* Dragon Quest Tact (Android) */
{3234477171400153310}, // 2CE32BD9B36A98DE
/* D4DJ Groovy Mix (Android) [base files] */ /* D4DJ Groovy Mix (Android) [base files] */
{393410674916959300}, // 0575ACECA945A444 {393410674916959300}, // 0575ACECA945A444
/* D4DJ Groovy Mix (Android) [music_* files, per-song later mixed with subkey] */ /* D4DJ Groovy Mix (Android) [music_* files, per-song later mixed with subkey] */

View File

@ -949,4 +949,6 @@ VGMSTREAM* init_vgmstream_tac(STREAMFILE* sf);
VGMSTREAM* init_vgmstream_ogv_3rdeye(STREAMFILE* sf); VGMSTREAM* init_vgmstream_ogv_3rdeye(STREAMFILE* sf);
VGMSTREAM* init_vgmstream_sspr(STREAMFILE* sf);
#endif /*_META_H*/ #endif /*_META_H*/

View File

@ -0,0 +1,55 @@
#include "meta.h"
#include "../coding/coding.h"
/* SSPR - Capcom container [Sengoku Basara 4 (PS3/PS4), Mega Man Zero ZX Legacy Collection (PS4)] */
VGMSTREAM* init_vgmstream_sspr(STREAMFILE* sf) {
VGMSTREAM* vgmstream = NULL;
STREAMFILE* temp_sf = NULL;
uint32_t name_offset, subfile_offset, subfile_size, name_size;
int big_endian;
int total_subsongs, target_subsong = sf->stream_index;
char* extension;
uint32_t (*read_u32)(off_t,STREAMFILE*) = NULL;
/* checks */
if (!check_extensions(sf,"sspr"))
goto fail;
if (!is_id32be(0x00,sf,"SSPR"))
goto fail;
/* Simple (audio only) container used some Capcom games (common engine?).
* Some files come with a .stqr with unknown data (cues?). */
big_endian = guess_endianness32bit(0x04, sf); /* 0x01 (version?) */
read_u32 = big_endian ? read_u32be : read_u32le;
total_subsongs = read_u32(0x08,sf);
if (target_subsong == 0) target_subsong = 1;
if (target_subsong < 0 || target_subsong > total_subsongs || total_subsongs < 1) goto fail;
/* 0x0c: null */
name_offset = read_u32(0x10 + (target_subsong-1) * 0x10 + 0x00,sf);
subfile_offset = read_u32(0x10 + (target_subsong-1) * 0x10 + 0x04,sf);
name_size = read_u32(0x10 + (target_subsong-1) * 0x10 + 0x08,sf);
subfile_size = read_u32(0x10 + (target_subsong-1) * 0x10 + 0x0c,sf);
extension = big_endian ? "at3" : "at9";
temp_sf = setup_subfile_streamfile(sf, subfile_offset, subfile_size, extension);
if (!temp_sf) goto fail;
vgmstream = init_vgmstream_riff(temp_sf);
if (!vgmstream) goto fail;
vgmstream->num_streams = total_subsongs;
read_string(vgmstream->stream_name,name_size+1, name_offset,sf);
close_streamfile(temp_sf);
return vgmstream;
fail:
close_streamfile(temp_sf);
close_vgmstream(vgmstream);
return NULL;
}

View File

@ -808,8 +808,7 @@ static int get_padding_size(txth_header* txth, int discard_empty);
/* Simple text parser of "key = value" lines. /* Simple text parser of "key = value" lines.
* The code is meh and error handling not exactly the best. */ * The code is meh and error handling not exactly the best. */
static int parse_txth(txth_header* txth) { static int parse_txth(txth_header* txth) {
off_t txt_offset = 0x00; off_t txt_offset, file_size;
off_t file_size = get_streamfile_size(txth->sf_text);
/* setup txth defaults */ /* setup txth defaults */
if (txth->sf_body) if (txth->sf_body)
@ -818,14 +817,8 @@ static int parse_txth(txth_header* txth) {
if (txth->target_subsong == 0) txth->target_subsong = 1; if (txth->target_subsong == 0) txth->target_subsong = 1;
/* skip BOM if needed */ txt_offset = read_bom(txth->sf_text);
if ((uint16_t)read_16bitLE(0x00, txth->sf_text) == 0xFFFE || file_size = get_streamfile_size(txth->sf_text);
(uint16_t)read_16bitLE(0x00, txth->sf_text) == 0xFEFF) {
txt_offset = 0x02;
}
else if (((uint32_t)read_32bitBE(0x00, txth->sf_text) & 0xFFFFFF00) == 0xEFBBBF00) {
txt_offset = 0x03;
}
/* read lines */ /* read lines */
{ {
@ -1533,7 +1526,7 @@ static int read_name_table_keyval(txth_header* txth, const char* line, char* key
/* try "(name): (val))" */ /* try "(name): (val))" */
ok = sscanf(line, " %[^\t#:] : %[^\t#\r\n] ", key, val); ok = sscanf(line, " %[^\t#:] : %[^\t#\r\n] ", key, val);
if (ok == 2) { if (ok == 2) {
;VGM_LOG("TXTH: name %s get\n", key); //;VGM_LOG("TXTH: name %s get\n", key);
return 1; return 1;
} }
@ -1541,14 +1534,14 @@ static int read_name_table_keyval(txth_header* txth, const char* line, char* key
key[0] = '\0'; key[0] = '\0';
ok = sscanf(line, " : %[^\t#\r\n] ", val); ok = sscanf(line, " : %[^\t#\r\n] ", val);
if (ok == 1) { if (ok == 1) {
;VGM_LOG("TXTH: default get\n"); //;VGM_LOG("TXTH: default get\n");
return 1; return 1;
} }
/* try "(name)#subsong: (val))" */ /* try "(name)#subsong: (val))" */
ok = sscanf(line, " %[^\t#:]#%i : %[^\t#\r\n] ", key, &subsong, val); ok = sscanf(line, " %[^\t#:]#%i : %[^\t#\r\n] ", key, &subsong, val);
if (ok == 3 && subsong == txth->target_subsong) { if (ok == 3 && subsong == txth->target_subsong) {
VGM_LOG("TXTH: name %s + subsong %i get\n", key, subsong); //;VGM_LOG("TXTH: name %s + subsong %i get\n", key, subsong);
return 1; return 1;
} }
@ -1556,7 +1549,7 @@ static int read_name_table_keyval(txth_header* txth, const char* line, char* key
key[0] = '\0'; key[0] = '\0';
ok = sscanf(line, " #%i: %[^\t#\r\n] ", &subsong, val); ok = sscanf(line, " #%i: %[^\t#\r\n] ", &subsong, val);
if (ok == 2 && subsong == txth->target_subsong) { if (ok == 2 && subsong == txth->target_subsong) {
VGM_LOG("TXTH: default + subsong %i get\n", subsong); //;VGM_LOG("TXTH: default + subsong %i get\n", subsong);
return 1; return 1;
} }
@ -1596,18 +1589,9 @@ static int parse_name_table(txth_header* txth, char* name_list) {
get_streamfile_basename(txth->sf_body, basename, sizeof(basename)); get_streamfile_basename(txth->sf_body, basename, sizeof(basename));
//;VGM_LOG("TXTH: names full=%s, file=%s, base=%s\n", fullname, filename, basename); //;VGM_LOG("TXTH: names full=%s, file=%s, base=%s\n", fullname, filename, basename);
txt_offset = 0x00; txt_offset = read_bom(sf_names);
file_size = get_streamfile_size(sf_names); file_size = get_streamfile_size(sf_names);
/* skip BOM if needed */
if ((uint16_t)read_16bitLE(0x00, sf_names) == 0xFFFE ||
(uint16_t)read_16bitLE(0x00, sf_names) == 0xFEFF) {
txt_offset = 0x02;
}
else if (((uint32_t)read_32bitBE(0x00, sf_names) & 0xFFFFFF00) == 0xEFBBBF00) {
txt_offset = 0x03;
}
/* in case of repeated name tables */ /* in case of repeated name tables */
memset(txth->name_values, 0, sizeof(txth->name_values)); memset(txth->name_values, 0, sizeof(txth->name_values));
txth->name_values_count = 0; txth->name_values_count = 0;

View File

@ -1887,8 +1887,7 @@ fail:
static txtp_header* parse_txtp(STREAMFILE* sf) { static txtp_header* parse_txtp(STREAMFILE* sf) {
txtp_header* txtp = NULL; txtp_header* txtp = NULL;
off_t txt_offset = 0x00; off_t txt_offset, file_size;
off_t file_size = get_streamfile_size(sf);
txtp = calloc(1,sizeof(txtp_header)); txtp = calloc(1,sizeof(txtp_header));
@ -1897,16 +1896,8 @@ static txtp_header* parse_txtp(STREAMFILE* sf) {
/* defaults */ /* defaults */
txtp->is_segmented = 1; txtp->is_segmented = 1;
txt_offset = read_bom(sf);
/* skip BOM if needed */ file_size = get_streamfile_size(sf);
if (file_size > 0 &&
(read_u16le(0x00, sf) == 0xFFFE || read_u16le(0x00, sf) == 0xFEFF)) {
txt_offset = 0x02;
}
else if ((read_u32be(0x00, sf) & 0xFFFFFF00) == 0xEFBBBF00) {
txt_offset = 0x03;
}
/* read and parse lines */ /* read and parse lines */
{ {

View File

@ -888,19 +888,25 @@ STREAMFILE* open_streamfile_by_ext(STREAMFILE* sf, const char* ext) {
STREAMFILE* open_streamfile_by_filename(STREAMFILE* sf, const char* filename) { STREAMFILE* open_streamfile_by_filename(STREAMFILE* sf, const char* filename) {
char fullname[PATH_LIMIT]; char fullname[PATH_LIMIT];
char partname[PATH_LIMIT]; char partname[PATH_LIMIT];
char *path, *name; char *path, *name, *otherpath;
if (!sf || !filename || !filename[0]) return NULL; if (!sf || !filename || !filename[0]) return NULL;
sf->get_name(sf, fullname, sizeof(fullname)); sf->get_name(sf, fullname, sizeof(fullname));
//todo normalize separators in a better way, safeops, improve copying //todo normalize separators in a better way, safeops, improve copying
path = strrchr(fullname,DIR_SEPARATOR);
/* check for non-normalized paths first (ex. txth) */
path = strrchr(fullname, '/');
otherpath = strrchr(fullname, '\\');
if (otherpath > path)
path = otherpath;
if (path) { if (path) {
path[1] = '\0'; /* remove name after separator */ path[1] = '\0'; /* remove name after separator */
strcpy(partname, filename); strcpy(partname, filename);
fix_dir_separators(partname); fix_dir_separators(partname); /* normalize to DIR_SEPARATOR */
/* normalize relative paths as don't work ok in some plugins */ /* normalize relative paths as don't work ok in some plugins */
if (partname[0] == '.' && partname[1] == DIR_SEPARATOR) { /* './name' */ if (partname[0] == '.' && partname[1] == DIR_SEPARATOR) { /* './name' */
@ -996,6 +1002,19 @@ size_t read_line(char* buf, int buf_size, off_t offset, STREAMFILE* sf, int* p_l
return i + extra_bytes; return i + extra_bytes;
} }
size_t read_bom(STREAMFILE* sf) {
if (read_u16le(0x00, sf) == 0xFFFE ||
read_u16le(0x00, sf) == 0xFEFF) {
return 0x02;
}
if ((read_u32be(0x00, sf) & 0xFFFFFF00) == 0xEFBBBF00) {
return 0x03;
}
return 0x00;
}
size_t read_string(char* buf, size_t buf_size, off_t offset, STREAMFILE* sf) { size_t read_string(char* buf, size_t buf_size, off_t offset, STREAMFILE* sf) {
size_t pos; size_t pos;
@ -1137,17 +1156,9 @@ STREAMFILE* read_filemap_file_pos(STREAMFILE* sf, int file_num, int* p_pos) {
get_streamfile_filename(sf, filename, sizeof(filename)); get_streamfile_filename(sf, filename, sizeof(filename));
txt_offset = 0x00; txt_offset = read_bom(sf_map);
file_size = get_streamfile_size(sf_map); file_size = get_streamfile_size(sf_map);
/* skip BOM if needed */
if (read_u16le(0x00, sf_map) == 0xFFFE ||
read_u16le(0x00, sf_map) == 0xFEFF) {
txt_offset = 0x02;
} else if ((read_u32be(0x00, sf_map) & 0xFFFFFF00) == 0xEFBBBF00) {
txt_offset = 0x03;
}
/* read lines and find target filename, format is (filename): value1, ... valueN */ /* read lines and find target filename, format is (filename): value1, ... valueN */
while (txt_offset < file_size) { while (txt_offset < file_size) {
char line[0x2000]; char line[0x2000];

View File

@ -355,6 +355,9 @@ static inline size_t align_size_to_block(size_t value, size_t block_align) {
* p_line_ok is set to 1 if the complete line was read; pass NULL to ignore. */ * p_line_ok is set to 1 if the complete line was read; pass NULL to ignore. */
size_t read_line(char* buf, int buf_size, off_t offset, STREAMFILE* sf, int* p_line_ok); size_t read_line(char* buf, int buf_size, off_t offset, STREAMFILE* sf, int* p_line_ok);
/* skip BOM if needed */
size_t read_bom(STREAMFILE* sf);
/* reads a c-string (ANSI only), up to bufsize or NULL, returning size. buf is optional (works as get_string_size). */ /* reads a c-string (ANSI only), up to bufsize or NULL, returning size. buf is optional (works as get_string_size). */
size_t read_string(char* buf, size_t buf_size, off_t offset, STREAMFILE* sf); size_t read_string(char* buf, size_t buf_size, off_t offset, STREAMFILE* sf);
/* reads a UTF16 string... but actually only as ANSI (discards the upper byte) */ /* reads a UTF16 string... but actually only as ANSI (discards the upper byte) */

View File

@ -524,6 +524,7 @@ VGMSTREAM* (*init_vgmstream_functions[])(STREAMFILE* sf) = {
init_vgmstream_idsp_tose, init_vgmstream_idsp_tose,
init_vgmstream_dsp_kwa, init_vgmstream_dsp_kwa,
init_vgmstream_ogv_3rdeye, init_vgmstream_ogv_3rdeye,
init_vgmstream_sspr,
/* lowest priority metas (should go after all metas, and TXTH should go before raw formats) */ /* lowest priority metas (should go after all metas, and TXTH should go before raw formats) */
init_vgmstream_txth, /* proper parsers should supersede TXTH, once added */ init_vgmstream_txth, /* proper parsers should supersede TXTH, once added */