mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-11-28 00:20:47 +01:00
263 lines
7.9 KiB
C
263 lines
7.9 KiB
C
#include "xmp_vgmstream.h"
|
|
|
|
/* with <v3.8.5.62, any more than ~1000 will crash XMplay's file list screen. */
|
|
#define EXTENSION_LIST_SIZE_OLD 1000
|
|
#define EXTENSION_LIST_SIZE_OLD_VERSION 0x0308053d /* less than v3.8.5.62 */
|
|
|
|
|
|
/* Adds ext to XMPlay's extension list. */
|
|
static int add_extension(int length, char * dst, const char * ext) {
|
|
int ext_len;
|
|
int i;
|
|
|
|
if (length <= 1)
|
|
return 0;
|
|
|
|
ext_len = strlen(ext);
|
|
|
|
/* check if end reached or not enough room to add */
|
|
if (ext_len+2 > length-2) {
|
|
dst[0]='\0';
|
|
return 0;
|
|
}
|
|
|
|
/* copy new extension + null terminate */
|
|
for (i=0; i < ext_len; i++)
|
|
dst[i] = ext[i];
|
|
dst[i]='/';
|
|
dst[i+1]='\0';
|
|
return i+1;
|
|
}
|
|
|
|
/* Creates XMPlay's extension list, a single string with 2 nulls.
|
|
* Extensions must be in this format: "Description\0extension1/.../extensionN" */
|
|
void build_extension_list(char* extension_list, int list_size, DWORD version) {
|
|
const char ** ext_list;
|
|
size_t ext_list_len;
|
|
int i, written;
|
|
|
|
int limit_old = EXTENSION_LIST_SIZE_OLD;
|
|
int limit = list_size;
|
|
if (limit > limit_old && version <= EXTENSION_LIST_SIZE_OLD_VERSION)
|
|
limit = limit_old;
|
|
|
|
written = sprintf(extension_list, "%s%c", "vgmstream files",'\0');
|
|
|
|
ext_list = vgmstream_get_formats(&ext_list_len);
|
|
|
|
for (i=0; i < ext_list_len; i++) {
|
|
written += add_extension(limit-written, extension_list + written, ext_list[i]);
|
|
}
|
|
extension_list[written-1] = '\0'; /* remove last "/" */
|
|
}
|
|
|
|
|
|
/* Get tags as an array of "key\0value\0", NULL-terminated.
|
|
* Processes tags from the path alone (expects folders to be named in a particular way),
|
|
* so of limited usefulness. */
|
|
char* get_tags_from_filepath_info(VGMSTREAM* infostream, XMPFUNC_MISC* xmpf_misc, const char* filepath) {
|
|
char* tags;
|
|
int pos = 0;
|
|
|
|
tags = xmpf_misc->Alloc(1024);
|
|
memset(tags, 0x00, 1024);
|
|
|
|
if (strlen(infostream->stream_name) > 0) {
|
|
memcpy(tags + pos, "title", 5);
|
|
pos += 6;
|
|
memcpy(tags + pos, infostream->stream_name, strlen(infostream->stream_name));
|
|
pos += strlen(infostream->stream_name) + 1;
|
|
}
|
|
|
|
const char* end;
|
|
const char* start = NULL;
|
|
int j = 2;
|
|
for (const char* i = filepath + strlen(filepath); i > filepath; i--)
|
|
{
|
|
if ((*i == '\\') && (j == 1))
|
|
{
|
|
start = i + 1;
|
|
j--;
|
|
break;
|
|
}
|
|
if ((*i == '\\') && (j == 2))
|
|
{
|
|
end = i;
|
|
j--;
|
|
}
|
|
}
|
|
|
|
//run some sanity checks
|
|
|
|
int brace_curly = 0, brace_square = 0;
|
|
char check_ok = 0;
|
|
for (const char* i = filepath; *i != 0; i++)
|
|
{
|
|
if (*i == '(')
|
|
brace_curly++;
|
|
if (*i == ')')
|
|
brace_curly--;
|
|
if (*i == '[')
|
|
brace_square++;
|
|
if (*i == ']')
|
|
brace_square--;
|
|
if (brace_curly > 1 || brace_curly < -1 || brace_square > 1 || brace_square < -1)
|
|
break;
|
|
}
|
|
|
|
if (brace_square == 0 && brace_curly == 0)
|
|
check_ok = 1;
|
|
|
|
if (start != NULL && strstr(filepath, "\\VGMPP\\") != NULL && check_ok == 1 && strchr(start, '(') != NULL)
|
|
{
|
|
char tagline[1024];
|
|
memset(tagline, 0x00, sizeof(tagline));
|
|
strncpy(tagline, start, end - start);
|
|
|
|
char* alttitle_st;
|
|
char* alttitle_ed;
|
|
char* album_st;
|
|
char* album_ed;
|
|
char* company_st;
|
|
char* company_ed;
|
|
char* company2_st;
|
|
char* company2_ed;
|
|
char* date_st;
|
|
char* date_ed;
|
|
char* platform_st;
|
|
char* platform_ed;
|
|
|
|
if (strchr(tagline, '[') != NULL) //either alternative title or platform usually
|
|
{
|
|
alttitle_st = strchr(tagline, '[') + 1;
|
|
alttitle_ed = strchr(alttitle_st, ']');
|
|
if (strchr(alttitle_st, '[') != NULL && strchr(alttitle_st, '[') > strchr(alttitle_st, '(')) //both might be present actually
|
|
{
|
|
platform_st = strchr(alttitle_st, '[') + 1;
|
|
platform_ed = strchr(alttitle_ed + 1, ']');
|
|
}
|
|
else
|
|
{
|
|
platform_st = NULL;
|
|
platform_ed = NULL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
platform_st = NULL;
|
|
platform_ed = NULL;
|
|
alttitle_st = NULL;
|
|
alttitle_ed = NULL;
|
|
}
|
|
|
|
album_st = tagline;
|
|
|
|
if (strchr(tagline, '(') < alttitle_st && alttitle_st != NULL) //square braces after curly braces -- platform
|
|
{
|
|
platform_st = alttitle_st;
|
|
platform_ed = alttitle_ed;
|
|
alttitle_st = NULL;
|
|
alttitle_ed = NULL;
|
|
album_ed = strchr(tagline, '('); //get normal title for now
|
|
}
|
|
else if (alttitle_st != NULL)
|
|
album_ed = strchr(tagline, '[');
|
|
else
|
|
album_ed = strchr(tagline, '(');
|
|
|
|
date_st = strchr(album_ed, '(') + 1; //first string in curly braces is usualy release date, I have one package with platform name there
|
|
if (date_st == NULL)
|
|
date_ed = NULL;
|
|
if (date_st[0] >= 0x30 && date_st[0] <= 0x39 && date_st[1] >= 0x30 && date_st[1] <= 0x39) //check if it contains 2 digits
|
|
{
|
|
date_ed = strchr(date_st, ')');
|
|
}
|
|
else //platform?
|
|
{
|
|
platform_st = date_st;
|
|
platform_ed = strchr(date_st, ')');
|
|
date_st = strchr(platform_ed, '(') + 1;
|
|
date_ed = strchr(date_st, ')');
|
|
}
|
|
|
|
company_st = strchr(date_ed, '(') + 1; //company name follows date
|
|
if (company_st != NULL)
|
|
{
|
|
company_ed = strchr(company_st, ')');
|
|
if (strchr(company_ed, '(') != NULL)
|
|
{
|
|
company2_st = strchr(company_ed, '(') + 1;
|
|
company2_ed = strchr(company2_st, ')');
|
|
}
|
|
else
|
|
{
|
|
company2_st = NULL;
|
|
company2_ed = NULL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
company_st = NULL;
|
|
company_ed = NULL;
|
|
company2_st = NULL;
|
|
company2_ed = NULL;
|
|
}
|
|
|
|
if (alttitle_st != NULL) //prefer alternative title, which is usually japanese
|
|
{
|
|
memcpy(tags + pos, "album", 5);
|
|
pos += 6;
|
|
memcpy(tags + pos, alttitle_st, alttitle_ed - alttitle_st);
|
|
pos += alttitle_ed - alttitle_st + 1;
|
|
}
|
|
else
|
|
{
|
|
memcpy(tags + pos, "album", 5);
|
|
pos += 6;
|
|
memcpy(tags + pos, album_st, album_ed - album_st);
|
|
pos += album_ed - album_st + 1;
|
|
}
|
|
|
|
if (date_st != NULL)
|
|
{
|
|
memcpy(tags + pos, "date", 4);
|
|
pos += 5;
|
|
memcpy(tags + pos, date_st, date_ed - date_st);
|
|
pos += date_ed - date_st + 1;
|
|
}
|
|
|
|
if (date_st != NULL)
|
|
{
|
|
memcpy(tags + pos, "genre", 5);
|
|
pos += 6;
|
|
memcpy(tags + pos, platform_st, platform_ed - platform_st);
|
|
pos += platform_ed - platform_st + 1;
|
|
}
|
|
|
|
if (company_st != NULL)
|
|
{
|
|
char combuf[256];
|
|
memset(combuf, 0x00, sizeof(combuf));
|
|
char tmp[128];
|
|
memset(tmp, 0x00, sizeof(tmp));
|
|
memcpy(tmp, company_st, company_ed - company_st);
|
|
if (company2_st != NULL)
|
|
{
|
|
char tmp2[128];
|
|
memset(tmp2, 0x00, sizeof(tmp2));
|
|
memcpy(tmp2, company2_st, company2_ed - company2_st);
|
|
sprintf(combuf, "\r\n\r\nDeveloper\t%s\r\nPublisher\t%s", tmp, tmp2);
|
|
}
|
|
else
|
|
sprintf(combuf, "\r\n\r\nDeveloper\t%s", tmp);
|
|
|
|
memcpy(tags + pos, "comment", 7);
|
|
pos += 8;
|
|
memcpy(tags + pos, combuf, strlen(combuf));
|
|
pos += strlen(combuf) + 1;
|
|
}
|
|
}
|
|
|
|
return tags; /* assuming XMPlay free()s this, since it Alloc()s it */
|
|
}
|