Added TXTM format for specifying companion files

This commit is contained in:
NicknineTheEagle 2020-11-08 22:42:57 +03:00
parent 6ad66fdeb8
commit ac389b1af3
6 changed files with 96 additions and 12 deletions

View File

@ -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");

View File

@ -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;
}
}

View File

@ -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");

View File

@ -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);

View File

@ -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;

View File

@ -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);