mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-02-20 20:41:08 +01:00
Added TXTM format for specifying companion files
This commit is contained in:
parent
6ad66fdeb8
commit
ac389b1af3
@ -178,6 +178,9 @@ static void load_awb_name(STREAMFILE* sf, STREAMFILE* sf_acb, VGMSTREAM* vgmstre
|
||||
char filename[PATH_LIMIT];
|
||||
int len_name, len_cmp;
|
||||
|
||||
/* try parsing TXTM if present */
|
||||
sf_acb = read_filemap_file(sf_acb, 0);
|
||||
if (sf_acb) return sf_acb;
|
||||
|
||||
/* try (name).awb + (name).awb */
|
||||
sf_acb = open_streamfile_by_ext(sf, "acb");
|
||||
|
@ -526,16 +526,20 @@ static STREAMFILE *open_mapfile_pair(STREAMFILE* sf, int track, int num_tracks)
|
||||
"trick_alps0.mus,"
|
||||
"trick_lhotse0.mus"}
|
||||
};
|
||||
STREAMFILE *musFile = NULL;
|
||||
STREAMFILE *sf_mus = NULL;
|
||||
char file_name[PATH_LIMIT];
|
||||
int pair_count = (sizeof(mapfile_pairs) / sizeof(mapfile_pairs[0]));
|
||||
int i, j;
|
||||
size_t file_len, map_len;
|
||||
|
||||
/* try parsing TXTM if present */
|
||||
sf_mus = read_filemap_file(sf, track);
|
||||
if (sf_mus) return sf_mus;
|
||||
|
||||
/* if loading the first track, try opening MUS with the same name first (most common scenario) */
|
||||
if (track == 0) {
|
||||
musFile = open_streamfile_by_ext(sf, "mus");
|
||||
if (musFile) return musFile;
|
||||
sf_mus = open_streamfile_by_ext(sf, "mus");
|
||||
if (sf_mus) return sf_mus;
|
||||
}
|
||||
|
||||
get_streamfile_filename(sf, file_name, PATH_LIMIT);
|
||||
@ -579,8 +583,8 @@ static STREAMFILE *open_mapfile_pair(STREAMFILE* sf, int track, int num_tracks)
|
||||
strncpy(file_name, pch, PATH_LIMIT - 1);
|
||||
}
|
||||
|
||||
musFile = open_streamfile_by_filename(sf, file_name);
|
||||
if (musFile) return musFile;
|
||||
sf_mus = open_streamfile_by_filename(sf, file_name);
|
||||
if (sf_mus) return sf_mus;
|
||||
|
||||
get_streamfile_filename(sf, file_name, PATH_LIMIT); /* reset for next loop */
|
||||
}
|
||||
@ -591,8 +595,8 @@ static STREAMFILE *open_mapfile_pair(STREAMFILE* sf, int track, int num_tracks)
|
||||
char *mod_name = strchr(file_name, '+');
|
||||
if (mod_name) {
|
||||
mod_name[0] = '\0';
|
||||
musFile = open_streamfile_by_filename(sf, file_name);
|
||||
if (musFile) return musFile;
|
||||
sf_mus = open_streamfile_by_filename(sf, file_name);
|
||||
if (sf_mus) return sf_mus;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -636,11 +636,6 @@ static STREAMFILE* open_mapfile_pair(STREAMFILE* sf, int track, int num_tracks)
|
||||
{"SSX4FE.mpf", "TrackFE.mus"}, /* SSX On Tour */
|
||||
{"SSX4Path.mpf", "Track.mus"}, /* SSX On Tour */
|
||||
{"SSX4.mpf", "moments0.mus,main.mus,load_loop0.mus"}, /* SSX Blur */
|
||||
{"willow.mpf", "willow.mus,willow_o.mus"}, /* Harry Potter and the Chamber of Secrets */
|
||||
{"exterior.mpf", "exterior.mus,ext_o.mus"}, /* Harry Potter and the Chamber of Secrets */
|
||||
{"Peak1Amb.mpf", "Peak1_Strm.mus,Peak1_Ovr0.mus"}, /* SSX 3 */
|
||||
{"Peak2Amb.mpf", "Peak2_Strm.mus,Peak2_Ovr0.mus"},
|
||||
{"Peak3Amb.mpf", "Peak3_Strm.mus,Peak3_Ovr0.mus"},
|
||||
{"*.mpf", "*_main.mus"}, /* 007 - Everything or Nothing */
|
||||
/* TODO: need better wildcard support
|
||||
* NSF2:
|
||||
@ -663,6 +658,10 @@ static STREAMFILE* open_mapfile_pair(STREAMFILE* sf, int track, int num_tracks)
|
||||
int i, j;
|
||||
size_t file_len, map_len;
|
||||
|
||||
/* try parsing TXTM if present */
|
||||
sf_mus = read_filemap_file(sf, track);
|
||||
if (sf_mus) return sf_mus;
|
||||
|
||||
/* if loading the first track, try opening MUS with the same name first (most common scenario) */
|
||||
if (track == 0) {
|
||||
sf_mus = open_streamfile_by_ext(sf, "mus");
|
||||
|
@ -905,6 +905,10 @@ static STREAMFILE * open_xsb_filename_pair(STREAMFILE *streamXwb) {
|
||||
char temp_filename[PATH_LIMIT];
|
||||
int target_len;
|
||||
|
||||
/* try parsing TXTM if present */
|
||||
streamXsb = read_filemap_file(streamXwb, 0);
|
||||
if (streamXsb) return streamXsb;
|
||||
|
||||
/* try names in external .xsb, using a bunch of possible name pairs */
|
||||
get_streamfile_filename(streamXwb,target_filename,PATH_LIMIT);
|
||||
target_len = strlen(target_filename);
|
||||
|
@ -1122,6 +1122,76 @@ fail:
|
||||
return 0;
|
||||
}
|
||||
|
||||
STREAMFILE *read_filemap_file(STREAMFILE *sf, int file_num) {
|
||||
char filename[PATH_LIMIT];
|
||||
off_t txt_offset, file_size;
|
||||
STREAMFILE *sf_map = NULL;
|
||||
|
||||
sf_map = open_streamfile_by_filename(sf, ".txtm");
|
||||
if (!sf_map) goto fail;
|
||||
|
||||
get_streamfile_filename(sf, filename, sizeof(filename));
|
||||
|
||||
txt_offset = 0x00;
|
||||
file_size = get_streamfile_size(sf_map);
|
||||
|
||||
/* skip BOM if needed */
|
||||
if ((uint16_t)read_16bitLE(0x00, sf_map) == 0xFFFE ||
|
||||
(uint16_t)read_16bitLE(0x00, sf_map) == 0xFEFF) {
|
||||
txt_offset = 0x02;
|
||||
} else if (((uint32_t)read_32bitBE(0x00, sf_map) & 0xFFFFFF00) == 0xEFBBBF00) {
|
||||
txt_offset = 0x03;
|
||||
}
|
||||
|
||||
/* read lines and find target filename, format is (filename): value1, ... valueN */
|
||||
while (txt_offset < file_size) {
|
||||
char line[0x2000];
|
||||
char key[PATH_LIMIT] = { 0 }, val[0x2000] = { 0 };
|
||||
int ok, bytes_read, line_ok;
|
||||
|
||||
bytes_read = read_line(line, sizeof(line), txt_offset, sf_map, &line_ok);
|
||||
if (!line_ok) goto fail;
|
||||
|
||||
txt_offset += bytes_read;
|
||||
|
||||
/* get key/val (ignores lead spaces, stops at space/comment/separator) */
|
||||
ok = sscanf(line, " %[^ \t#:] : %[^\t#\r\n] ", key, val);
|
||||
if (ok != 2) { /* ignore line if no key=val (comment or garbage) */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmp(key, filename) == 0) {
|
||||
int n;
|
||||
char subval[PATH_LIMIT];
|
||||
const char *current = val;
|
||||
int i;
|
||||
|
||||
for (i = 0; i <= file_num; i++) {
|
||||
if (current[0] == '\0')
|
||||
goto fail;
|
||||
|
||||
ok = sscanf(current, " %[^\t#\r\n,]%n ", subval, &n);
|
||||
if (ok != 1)
|
||||
goto fail;
|
||||
|
||||
if (i == file_num)
|
||||
{
|
||||
close_streamfile(sf_map);
|
||||
return open_streamfile_by_filename(sf, subval);
|
||||
}
|
||||
|
||||
current += n;
|
||||
if (current[0] == ',')
|
||||
current++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fail:
|
||||
close_streamfile(sf_map);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void fix_dir_separators(char * filename) {
|
||||
char c;
|
||||
int i = 0;
|
||||
|
@ -345,6 +345,10 @@ size_t read_string_utf16be(char* buf, size_t buf_size, off_t offset, STREAMFILE*
|
||||
* returns size of key if found and copied */
|
||||
size_t read_key_file(uint8_t* buf, size_t buf_size, STREAMFILE* sf);
|
||||
|
||||
/* Opens .txtm file containing file:companion file(-s) mappings and tries to see if there's a match
|
||||
* then loads the associated companion file if one is found */
|
||||
STREAMFILE *read_filemap_file(STREAMFILE *sf, int file_num);
|
||||
|
||||
/* hack to allow relative paths in various OSs */
|
||||
void fix_dir_separators(char* filename);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user