From 78542225f56f68d0ca80407bfee34fcf9bd481dc Mon Sep 17 00:00:00 2001 From: bnnm Date: Sat, 30 Jun 2018 17:35:07 +0200 Subject: [PATCH] Allow extensionless files in Winamp [Baten Kaitos 2 (GC)] --- src/formats.c | 11 +++++++---- src/util.c | 28 ++++++++++++++++++++-------- winamp/in_vgmstream.c | 32 +++++++++++++++++++++++++++++--- 3 files changed, 56 insertions(+), 15 deletions(-) diff --git a/src/formats.c b/src/formats.c index 7f2ead2d..3f815bfa 100644 --- a/src/formats.c +++ b/src/formats.c @@ -1,13 +1,16 @@ #include "vgmstream.h" -//#define VGM_REGISTER_TYPE(extension) ... -//#define VGM_REGISTER_TYPE_COMMON(extension) ... /* for common extensions like aiff */ +/* defines the list of accepted extensions. vgmstream doesn't use it internally so it's here + * to inform plugins that need it. Common extensions are commented out to avoid stealing them. */ -/* some extensions could be #ifdef but no really needed */ +/* some extensions require external libraries and could be #ifdef, no really needed */ /* some formats marked as "not parsed" mean they'll go through FFmpeg, the header/extension is not parsed */ + static const char* extension_list[] = { + //"", /* vgmstream can plays extensionless files too, but plugins must accept them manually */ + "04sw", "2dx9", "2pfs", @@ -437,7 +440,7 @@ static const char* extension_list[] = { "zsd", "zwdsp", - "vgmstream" + "vgmstream" /* fake extension, catch-all for FFmpeg/txth/etc */ //, NULL //end mark }; diff --git a/src/util.c b/src/util.c index badb2c97..2895c62a 100644 --- a/src/util.c +++ b/src/util.c @@ -2,16 +2,28 @@ #include "util.h" #include "streamtypes.h" -const char * filename_extension(const char * filename) { - const char * ext; +const char * filename_extension(const char * pathname) { + const char * filename; + const char * extension; - /* You know what would be nice? strrchrnul(). - * Instead I have to do it myself. */ - ext = strrchr(filename,'.'); - if (ext==NULL) ext=filename+strlen(filename); /* point to null, i.e. an empty string for the extension */ - else ext=ext+1; /* skip the dot */ + /* get basename + extension */ + filename = pathname; +#if 0 + //must detect empty extensions in folders with . in the name; not too important and DIR_SEPARATOR could improved + filename = strrchr(pathname, DIR_SEPARATOR); + if (filename == NULL) + filename = pathname; /* pathname has no separators (single filename) */ + else + filename++; /* skip the separator */ +#endif - return ext; + extension = strrchr(filename,'.'); + if (extension==NULL) + extension = filename+strlen(filename); /* point to null, i.e. an empty string for the extension */ + else + extension++; /* skip the dot */ + + return extension; } /* unused */ diff --git a/winamp/in_vgmstream.c b/winamp/in_vgmstream.c index c639f41a..1114ed1c 100644 --- a/winamp/in_vgmstream.c +++ b/winamp/in_vgmstream.c @@ -43,7 +43,7 @@ In_Module input_module; DWORD WINAPI __stdcall decode(void *arg); -/* Winamp Play extension list, needed to accept/play and associate extensions in Windows */ +/* Winamp Play extension list, to accept and associate extensions in Windows */ #define EXTENSION_LIST_SIZE (0x2000 * 6) #define EXT_BUFFER_SIZE 200 char working_extension_list[EXTENSION_LIST_SIZE] = {0}; @@ -88,6 +88,7 @@ in_char lastfn[PATH_LIMIT] = {0}; /* name of the currently playing file */ #define wa_strchr wcschr #define wa_sscanf swscanf #define wa_snprintf _snwprintf +#define wa_strrchr wcsrchr #define wa_fileinfo fileinfoW #define wa_IPC_PE_INSERTFILENAME IPC_PE_INSERTFILENAMEW #define wa_L(x) L ##x @@ -99,6 +100,7 @@ in_char lastfn[PATH_LIMIT] = {0}; /* name of the currently playing file */ #define wa_strchr strchr #define wa_sscanf sscanf #define wa_snprintf snprintf +#define wa_strrchr strrchr #define wa_fileinfo fileinfo #define wa_IPC_PE_INSERTFILENAME IPC_PE_INSERTFILENAME #define wa_L(x) x @@ -777,7 +779,9 @@ static void add_extension(int length, char * dst, const char * ext) { } /* Creates Winamp's extension list, a single string that ends with \0\0. - * Each extension must be in this format: "extension\0Description\0" */ + * Each extension must be in this format: "extension\0Description\0" + * The list is used to accept extensions by default when IsOurFile returns 0, and to register file types. + * It could be ignored/empty and just detect in IsOurFile instead. */ static void build_extension_list() { const char ** ext_list; size_t ext_list_len; @@ -871,7 +875,29 @@ void winamp_Quit() { /* called before extension checks, to allow detection of mms://, etc */ int winamp_IsOurFile(const in_char *fn) { - return 0; /* we don't recognize protocols */ + const in_char *filename; + const in_char *extension; + + /* get basename + extension */ + filename = fn; +#if 0 + //must detect empty extensions in folders with . in the name; doesn't work ok? + filename = wa_strrchr(fn, wa_L('\\')); + if (filename == NULL) + filename = fn; + else + filename++; +#endif + extension = wa_strrchr(filename, wa_L('.')); + if (extension == NULL) + return 1; /* extensionless, try to play it */ + else + extension++; + + /* returning 0 here means it only accepts the extensions in working_extension_list */ + /* it's possible to ignore the list and manually accept extensions, like foobar's g_is_our_path */ + + return 0; } /* request to start playing a file */