diff --git a/cli/vgmstream_cli.c b/cli/vgmstream_cli.c index effa93f1..7d1ce90a 100644 --- a/cli/vgmstream_cli.c +++ b/cli/vgmstream_cli.c @@ -380,6 +380,21 @@ int main(int argc, char ** argv) { res = validate_config(&cfg); if (!res) goto fail; +#if 0 + /* CLI has no need to check */ + { + int valid; + vgmstream_ctx_valid_cfg cfg2 = {0}; + + cfg2.skip_standard = 1; + cfg2.reject_extensionless = 0; + cfg2.accept_unknown = 0; + cfg2.accept_common = 1; + + valid = vgmstream_ctx_is_valid(cfg.infilename, &cfg2); + if (!valid) goto fail; + } +#endif /* open streamfile and pass subsong */ { diff --git a/fb2k/foo_input_vgmstream.rc b/fb2k/foo_input_vgmstream.rc index 1fef7288..d389ca37 100755 --- a/fb2k/foo_input_vgmstream.rc +++ b/fb2k/foo_input_vgmstream.rc @@ -52,6 +52,11 @@ BEGIN CONTROL "Disable tagfile",IDC_TAGFILE_DISABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,131,87,10 CONTROL "Override title",IDC_OVERRIDE_TITLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,147,97,10 + + CONTROL "Enable unknown exts",IDC_EXTS_UNKNOWN_ON,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,163,87,10 + + CONTROL "Enable common exts",IDC_EXTS_COMMON_ON,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,179,87,10 + END diff --git a/fb2k/foo_prefs.cpp b/fb2k/foo_prefs.cpp index a70ca2e3..8bf6f79b 100755 --- a/fb2k/foo_prefs.cpp +++ b/fb2k/foo_prefs.cpp @@ -14,29 +14,20 @@ extern "C" { #include "foo_vgmstream.h" -static const GUID guid_cfg_LoopForever = { 0xa19e36eb, 0x72a0, 0x4077, { 0x91, 0x43, 0x38, 0xb4, 0x5, 0xfc, 0x91, 0xc5 } }; -static const GUID guid_cfg_IgnoreLoop = { 0xddda7ab6, 0x7bb6, 0x4abe, { 0xb9, 0x66, 0x2d, 0xb7, 0x8f, 0xe4, 0xcc, 0xab } }; -static const GUID guid_cfg_LoopCount = { 0xfc8dfd72, 0xfae8, 0x44cc, { 0xbe, 0x99, 0x1c, 0x7b, 0x27, 0x7a, 0xb6, 0xb9 } }; -static const GUID guid_cfg_FadeLength = { 0x61da7ef1, 0x56a5, 0x4368, { 0xae, 0x6, 0xec, 0x6f, 0xd7, 0xe6, 0x15, 0x5d } }; -static const GUID guid_cfg_FadeDelay = { 0x73907787, 0xaf49, 0x4659, { 0x96, 0x8e, 0x9f, 0x70, 0xa1, 0x62, 0x49, 0xc4 } }; -static const GUID guid_cfg_DisableSubsongs = { 0xa8cdd664, 0xb32b, 0x4a36, { 0x83, 0x07, 0xa0, 0x4c, 0xcd, 0x52, 0xa3, 0x7c } }; -static const GUID guid_cfg_DownmixChannels = { 0x5a0e65dd, 0xeb37, 0x4c67, { 0x9a, 0xb1, 0x3f, 0xb0, 0xc9, 0x7e, 0xb0, 0xe0 } }; -static const GUID guid_cfg_TagfileDisable = { 0xc1971eb7, 0xa930, 0x4bae, { 0x9e, 0x7f, 0xa9, 0x50, 0x36, 0x32, 0x41, 0xb3 } }; -static const GUID guid_cfg_OverrideTitle = { 0xe794831f, 0xd067, 0x4337, { 0x97, 0x85, 0x10, 0x57, 0x39, 0x4b, 0x1b, 0x97 } }; - -static cfg_bool cfg_LoopForever(guid_cfg_LoopForever, DEFAULT_LOOP_FOREVER); -static cfg_bool cfg_IgnoreLoop(guid_cfg_IgnoreLoop, DEFAULT_IGNORE_LOOP); -static cfg_string cfg_LoopCount(guid_cfg_LoopCount, DEFAULT_LOOP_COUNT); -static cfg_string cfg_FadeLength(guid_cfg_FadeLength, DEFAULT_FADE_SECONDS); -static cfg_string cfg_FadeDelay(guid_cfg_FadeDelay, DEFAULT_FADE_DELAY_SECONDS); -static cfg_bool cfg_DisableSubsongs(guid_cfg_DisableSubsongs, DEFAULT_DISABLE_SUBSONGS); -static cfg_string cfg_DownmixChannels(guid_cfg_DownmixChannels, DEFAULT_DOWNMIX_CHANNELS); -static cfg_bool cfg_TagfileDisable(guid_cfg_TagfileDisable, DEFAULT_TAGFILE_DISABLE); -static cfg_bool cfg_OverrideTitle(guid_cfg_OverrideTitle, DEFAULT_OVERRIDE_TITLE); +static cfg_bool cfg_LoopForever ({0xa19e36eb,0x72a0,0x4077,{0x91,0x43,0x38,0xb4,0x05,0xfc,0x91,0xc5}}, DEFAULT_LOOP_FOREVER); +static cfg_bool cfg_IgnoreLoop ({0xddda7ab6,0x7bb6,0x4abe,{0xb9,0x66,0x2d,0xb7,0x8f,0xe4,0xcc,0xab}}, DEFAULT_IGNORE_LOOP); +static cfg_string cfg_LoopCount ({0xfc8dfd72,0xfae8,0x44cc,{0xbe,0x99,0x1c,0x7b,0x27,0x7a,0xb6,0xb9}}, DEFAULT_LOOP_COUNT); +static cfg_string cfg_FadeLength ({0x61da7ef1,0x56a5,0x4368,{0xae,0x06,0xec,0x6f,0xd7,0xe6,0x15,0x5d}}, DEFAULT_FADE_SECONDS); +static cfg_string cfg_FadeDelay ({0x73907787,0xaf49,0x4659,{0x96,0x8e,0x9f,0x70,0xa1,0x62,0x49,0xc4}}, DEFAULT_FADE_DELAY_SECONDS); +static cfg_bool cfg_DisableSubsongs ({0xa8cdd664,0xb32b,0x4a36,{0x83,0x07,0xa0,0x4c,0xcd,0x52,0xa3,0x7c}}, DEFAULT_DISABLE_SUBSONGS); +static cfg_string cfg_DownmixChannels ({0x5a0e65dd,0xeb37,0x4c67,{0x9a,0xb1,0x3f,0xb0,0xc9,0x7e,0xb0,0xe0}}, DEFAULT_DOWNMIX_CHANNELS); +static cfg_bool cfg_TagfileDisable ({0xc1971eb7,0xa930,0x4bae,{0x9e,0x7f,0xa9,0x50,0x36,0x32,0x41,0xb3}}, DEFAULT_TAGFILE_DISABLE); +static cfg_bool cfg_OverrideTitle ({0xe794831f,0xd067,0x4337,{0x97,0x85,0x10,0x57,0x39,0x4b,0x1b,0x97}}, DEFAULT_OVERRIDE_TITLE); +static cfg_bool cfg_ExtsUnknownOn ({0xd92dc6a2,0x9683,0x422d,{0x8e,0xd1,0x59,0x46,0xd5,0xbf,0x01,0x6f}}, DEFAULT_EXTS_UNKNOWN_ON); +static cfg_bool cfg_ExtsCommonOn ({0x405af423,0x5037,0x4eae,{0xa6,0xe3,0x72,0xd0,0x12,0x7d,0x84,0x6c}}, DEFAULT_EXTS_COMMON_ON); // Needs to be here in rder to access the static config -void input_vgmstream::load_settings() -{ +void input_vgmstream::load_settings() { // no verification needed here, as it is done below sscanf(cfg_FadeLength.get_ptr(),"%lf",&fade_seconds); sscanf(cfg_LoopCount.get_ptr(),"%lf",&loop_count); @@ -47,28 +38,28 @@ void input_vgmstream::load_settings() sscanf(cfg_DownmixChannels.get_ptr(),"%d",&downmix_channels); tagfile_disable = cfg_TagfileDisable; override_title = cfg_OverrideTitle; + //exts_unknown_on = cfg_ExtsUnknownOn; + //exts_common_on = cfg_ExtsCommonOn; +} +void input_vgmstream::g_load_cfg(int *accept_unknown, int *accept_common) { + //todo improve + *accept_unknown = cfg_ExtsUnknownOn ? 1 : 0; + *accept_common = cfg_ExtsCommonOn ? 1 : 0; } -const char * vgmstream_prefs::get_name() -{ +const char * vgmstream_prefs::get_name() { return input_vgmstream::g_get_name(); } - -GUID vgmstream_prefs::get_guid() -{ +GUID vgmstream_prefs::get_guid() { return input_vgmstream::g_get_preferences_guid(); } - -GUID vgmstream_prefs::get_parent_guid() -{ +GUID vgmstream_prefs::get_parent_guid() { return guid_input; } - -BOOL vgmstreamPreferences::OnInitDialog(CWindow, LPARAM) -{ +BOOL vgmstreamPreferences::OnInitDialog(CWindow, LPARAM) { CheckDlgButton(IDC_LOOP_FOREVER, cfg_LoopForever?BST_CHECKED:BST_UNCHECKED); CheckDlgButton(IDC_IGNORE_LOOP, cfg_IgnoreLoop?BST_CHECKED:BST_UNCHECKED); CheckDlgButton(IDC_LOOP_NORMALLY, (!cfg_IgnoreLoop && !cfg_LoopForever)?BST_CHECKED:BST_UNCHECKED); @@ -83,21 +74,19 @@ BOOL vgmstreamPreferences::OnInitDialog(CWindow, LPARAM) CheckDlgButton(IDC_TAGFILE_DISABLE, cfg_TagfileDisable?BST_CHECKED:BST_UNCHECKED); CheckDlgButton(IDC_OVERRIDE_TITLE, cfg_OverrideTitle?BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(IDC_EXTS_UNKNOWN_ON, cfg_ExtsUnknownOn?BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(IDC_EXTS_COMMON_ON, cfg_ExtsCommonOn?BST_CHECKED:BST_UNCHECKED); return TRUE; } - -t_uint32 vgmstreamPreferences::get_state() -{ +t_uint32 vgmstreamPreferences::get_state() { t_uint32 state = preferences_state::resettable; if (HasChanged()) state |= preferences_state::changed; return state; } - -void vgmstreamPreferences::reset() -{ +void vgmstreamPreferences::reset() { CheckDlgButton(IDC_LOOP_FOREVER, DEFAULT_LOOP_FOREVER?BST_CHECKED:BST_UNCHECKED); CheckDlgButton(IDC_IGNORE_LOOP, DEFAULT_IGNORE_LOOP?BST_CHECKED:BST_UNCHECKED); CheckDlgButton(IDC_LOOP_NORMALLY, (!DEFAULT_IGNORE_LOOP && !DEFAULT_LOOP_FOREVER)?BST_CHECKED:BST_UNCHECKED); @@ -112,17 +101,19 @@ void vgmstreamPreferences::reset() CheckDlgButton(IDC_TAGFILE_DISABLE, DEFAULT_TAGFILE_DISABLE?BST_CHECKED:BST_UNCHECKED); CheckDlgButton(IDC_OVERRIDE_TITLE, DEFAULT_OVERRIDE_TITLE?BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(IDC_EXTS_UNKNOWN_ON, DEFAULT_EXTS_UNKNOWN_ON?BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(IDC_EXTS_COMMON_ON, DEFAULT_EXTS_COMMON_ON?BST_CHECKED:BST_UNCHECKED); } - -void vgmstreamPreferences::apply() -{ +void vgmstreamPreferences::apply() { cfg_LoopForever = IsDlgButtonChecked(IDC_LOOP_FOREVER)?true:false; cfg_IgnoreLoop = IsDlgButtonChecked(IDC_IGNORE_LOOP)?true:false; cfg_DisableSubsongs = IsDlgButtonChecked(IDC_DISABLE_SUBSONGS)?true:false; cfg_TagfileDisable = IsDlgButtonChecked(IDC_TAGFILE_DISABLE)?true:false; cfg_OverrideTitle = IsDlgButtonChecked(IDC_OVERRIDE_TITLE)?true:false; + cfg_ExtsUnknownOn = IsDlgButtonChecked(IDC_EXTS_UNKNOWN_ON)?true:false; + cfg_ExtsCommonOn = IsDlgButtonChecked(IDC_EXTS_COMMON_ON)?true:false; double temp_fade_seconds; double temp_fade_delay_seconds; @@ -178,8 +169,8 @@ void vgmstreamPreferences::apply() } -bool vgmstreamPreferences::HasChanged() -{ +bool vgmstreamPreferences::HasChanged() { + if(IsDlgButtonChecked(IDC_LOOP_FOREVER)) if(cfg_LoopForever != true) return true; @@ -189,14 +180,22 @@ bool vgmstreamPreferences::HasChanged() if(IsDlgButtonChecked(IDC_LOOP_NORMALLY)) if(cfg_IgnoreLoop != false || cfg_LoopForever != false) return true; - bool current_cfg_DisableSubsongs = IsDlgButtonChecked(IDC_DISABLE_SUBSONGS)?true:false; - if(cfg_DisableSubsongs != current_cfg_DisableSubsongs) return true; + bool current; - bool current_cfg_TagfileDisable = IsDlgButtonChecked(IDC_TAGFILE_DISABLE)?true:false; - if(cfg_TagfileDisable != current_cfg_TagfileDisable) return true; + current = IsDlgButtonChecked(IDC_DISABLE_SUBSONGS)?true:false; + if(cfg_DisableSubsongs != current) return true; - bool current_cfg_OverrideTitle = IsDlgButtonChecked(IDC_OVERRIDE_TITLE)?true:false; - if(cfg_OverrideTitle != current_cfg_OverrideTitle) return true; + current = IsDlgButtonChecked(IDC_TAGFILE_DISABLE)?true:false; + if(cfg_TagfileDisable != current) return true; + + current = IsDlgButtonChecked(IDC_OVERRIDE_TITLE)?true:false; + if(cfg_OverrideTitle != current) return true; + + current = IsDlgButtonChecked(IDC_EXTS_UNKNOWN_ON)?true:false; + if(cfg_ExtsUnknownOn != current) return true; + + current = IsDlgButtonChecked(IDC_EXTS_COMMON_ON)?true:false; + if(cfg_ExtsCommonOn != current) return true; pfc::string FadeLength(cfg_FadeLength); pfc::string FadeDelay(cfg_FadeDelay); @@ -213,8 +212,7 @@ bool vgmstreamPreferences::HasChanged() } -void vgmstreamPreferences::OnEditChange(UINT, int, CWindow) -{ +void vgmstreamPreferences::OnEditChange(UINT, int, CWindow) { m_callback->on_state_changed(); } diff --git a/fb2k/foo_prefs.h b/fb2k/foo_prefs.h index ac2108ea..37ec2d7d 100755 --- a/fb2k/foo_prefs.h +++ b/fb2k/foo_prefs.h @@ -18,14 +18,18 @@ #define DEFAULT_DOWNMIX_CHANNELS "8" #define DEFAULT_TAGFILE_DISABLE false #define DEFAULT_OVERRIDE_TITLE false +#define DEFAULT_EXTS_UNKNOWN_ON false +#define DEFAULT_EXTS_COMMON_ON false class vgmstreamPreferences : public CDialogImpl, public preferences_page_instance { public: - //Constructor - invoked by preferences_page_impl helpers - don't do Create() in here, preferences_page_impl does this for us + //Constructor - invoked by preferences_page_impl helpers - + //don't do Create() in here, preferences_page_impl does this for us vgmstreamPreferences(preferences_page_callback::ptr callback) : m_callback(callback) {} //Note that we don't bother doing anything regarding destruction of our class. - //The host ensures that our dialog is destroyed first, then the last reference to our preferences_page_instance object is released, causing our object to be deleted. + //The host ensures that our dialog is destroyed first, then the last reference to our + //preferences_page_instance object is released, causing our object to be deleted. //dialog resource ID @@ -48,6 +52,8 @@ public: COMMAND_HANDLER_EX(IDC_DOWNMIX_CHANNELS, EN_CHANGE, OnEditChange) COMMAND_HANDLER_EX(IDC_TAGFILE_DISABLE, BN_CLICKED, OnEditChange) COMMAND_HANDLER_EX(IDC_OVERRIDE_TITLE, BN_CLICKED, OnEditChange) + COMMAND_HANDLER_EX(IDC_EXTS_UNKNOWN_ON, BN_CLICKED, OnEditChange) + COMMAND_HANDLER_EX(IDC_EXTS_COMMON_ON, BN_CLICKED, OnEditChange) END_MSG_MAP() private: BOOL OnInitDialog(CWindow, LPARAM); @@ -60,8 +66,7 @@ private: -class vgmstream_prefs : public preferences_page_impl -{ +class vgmstream_prefs : public preferences_page_impl { public: const char * get_name(); diff --git a/fb2k/foo_vgmstream.cpp b/fb2k/foo_vgmstream.cpp index 565ba02a..0006f8bf 100644 --- a/fb2k/foo_vgmstream.cpp +++ b/fb2k/foo_vgmstream.cpp @@ -384,24 +384,12 @@ void input_vgmstream::retag_commit(abort_callback & p_abort) { /*throw exception bool input_vgmstream::g_is_our_content_type(const char * p_content_type) {return false;} // called to check if file can be processed by the plugin -bool input_vgmstream::g_is_our_path(const char * p_path,const char * p_extension) { - const char ** ext_list; - size_t ext_list_len; - int i; +bool input_vgmstream::g_is_our_path(const char * p_path, const char * p_extension) { + vgmstream_ctx_valid_cfg cfg = {0}; - ext_list = vgmstream_get_formats(&ext_list_len); - - for (i=0; i < ext_list_len; i++) { - if (!stricmp_utf8(p_extension, ext_list[i])) - return 1; - } - - /* some extensionless files can be handled by vgmstream, try to play */ - if (strlen(p_extension) <= 0) { - return 1; - } - - return 0; + cfg.is_extension = 1; + input_vgmstream::g_load_cfg(&cfg.accept_unknown, &cfg.accept_common); + return vgmstream_ctx_is_valid(p_extension, &cfg) > 0 ? true : false; } // internal util to create a VGMSTREAM diff --git a/fb2k/foo_vgmstream.h b/fb2k/foo_vgmstream.h index e1e06906..82a2714b 100644 --- a/fb2k/foo_vgmstream.h +++ b/fb2k/foo_vgmstream.h @@ -78,6 +78,8 @@ class input_vgmstream : public input_stubs { bool tagfile_disable; pfc::string8 tagfile_name; bool override_title; + //bool exts_common_on; + //bool exts_unknown_on; /* song config */ foobar_song_config config; @@ -90,6 +92,8 @@ class input_vgmstream : public input_stubs { bool get_description_tag(pfc::string_base & temp, pfc::string_base const& description, const char *tag, char delimiter = '\n'); void set_config_defaults(foobar_song_config *current); void apply_config(VGMSTREAM * vgmstream, foobar_song_config *current); + + static void g_load_cfg(int *accept_unknown, int *accept_common); }; /* foo_streamfile.cpp */ diff --git a/fb2k/resource.h b/fb2k/resource.h index 07e5dbaf..8f7a2921 100755 --- a/fb2k/resource.h +++ b/fb2k/resource.h @@ -17,6 +17,8 @@ #define IDC_DOWNMIX_CHANNELS 1010 #define IDC_TAGFILE_DISABLE 1011 #define IDC_OVERRIDE_TITLE 1012 +#define IDC_EXTS_UNKNOWN_ON 1015 +#define IDC_EXTS_COMMON_ON 1016 // Next default values for new objects // diff --git a/src/formats.c b/src/formats.c index e0591aaf..4f55ac7e 100644 --- a/src/formats.c +++ b/src/formats.c @@ -94,7 +94,7 @@ static const char* extension_list[] = { "bik", "bika", "bik2", - //"bin", //common + //"bin", //common "bk2", "bmdx", "bms", @@ -552,7 +552,7 @@ static const char* extension_list[] = { "xss", "xvag", "xvas", - "xwav",//fake extension for .wav (renamed, to be removed) + "xwav", //fake extension for .wav (renamed, to be removed) "xwb", "xmd", "xopus", @@ -576,12 +576,36 @@ static const char* extension_list[] = { //, NULL //end mark }; +static const char* common_extension_list[] = { + "aac", //common + "ac3", //common, FFmpeg/not parsed (AC3) + "aif", //common + "aiff", //common + "bin", //common + "flac", //common + "gsf", //conflicts with GBA gsf plugins? + "mp2", //common + "mp3", //common + "mp4", //common + "mpc", //common + "ogg", //common + "opus", //common + "stm", //common + "wav", //common +}; + + /* List supported formats and return elements in the list, for plugins that need to know. */ const char ** vgmstream_get_formats(size_t * size) { *size = sizeof(extension_list) / sizeof(char*); return extension_list; } +const char ** vgmstream_get_common_formats(size_t * size) { + *size = sizeof(common_extension_list) / sizeof(char*); + return common_extension_list; +} + /* internal description info */ diff --git a/src/plugins.c b/src/plugins.c index 2ea896a9..52413263 100644 --- a/src/plugins.c +++ b/src/plugins.c @@ -2,6 +2,71 @@ #include "plugins.h" #include "mixing.h" + +/* ****************************************** */ +/* CONTEXT: simplifies plugin code */ +/* ****************************************** */ + +int vgmstream_ctx_is_valid(const char* filename, vgmstream_ctx_valid_cfg *cfg) { + const char ** extension_list; + size_t extension_list_len; + const char *extension; + int i; + + + if (cfg->is_extension) { + extension = filename; + } else { + extension = filename_extension(filename); + } + + /* some metas accept extensionless files */ + if (strlen(extension) <= 0) { + return !cfg->reject_extensionless; + } + + /* try in default list */ + if (!cfg->skip_standard) { + extension_list = vgmstream_get_formats(&extension_list_len); + for (i = 0; i < extension_list_len; i++) { + if (strcasecmp(extension, extension_list[i]) == 0) { + return 1; + } + } + } + + /* try in common extensions */ + if (cfg->accept_common) { + extension_list = vgmstream_get_common_formats(&extension_list_len); + for (i = 0; i < extension_list_len; i++) { + if (strcasecmp(extension, extension_list[i]) == 0) + return 1; + } + } + + /* allow anything not in the normal list but not in common extensions */ + if (cfg->accept_unknown) { + int is_common = 0; + + extension_list = vgmstream_get_common_formats(&extension_list_len); + for (i = 0; i < extension_list_len; i++) { + if (strcasecmp(extension, extension_list[i]) == 0) { + is_common = 1; + break; + } + } + + if (!is_common) + return 1; + } + + return 0; +} + +/* ****************************************** */ +/* TAGS: loads key=val tags from a file */ +/* ****************************************** */ + #define VGMSTREAM_TAGS_LINE_MAX 2048 /* opaque tag state */ @@ -253,6 +318,10 @@ void vgmstream_tags_reset(VGMSTREAM_TAGS* tags, const char* target_filename) { tags->targetname_len = strlen(tags->targetname); } +/* ****************************************** */ +/* MIXING: modifies vgmstream output */ +/* ****************************************** */ + void vgmstream_mixing_enable(VGMSTREAM* vgmstream, int32_t max_sample_count, int *input_channels, int *output_channels) { mixing_setup(vgmstream, max_sample_count); mixing_info(vgmstream, input_channels, output_channels); diff --git a/src/plugins.h b/src/plugins.h index 63021423..94b8d69a 100644 --- a/src/plugins.h +++ b/src/plugins.h @@ -6,46 +6,57 @@ #include "streamfile.h" +/* ****************************************** */ +/* CONTEXT: simplifies plugin code */ +/* ****************************************** */ + +typedef struct { + int is_extension; /* set if filename is already an extension */ + int skip_standard; /* set if shouldn't check standard formats */ + int reject_extensionless; /* set if player can't play extensionless files */ + int accept_unknown; /* set to allow any extension (for txth) */ + int accept_common; /* set to allow known-but-common extension (when player has plugin priority) */ +} vgmstream_ctx_valid_cfg; + +/* returns if vgmstream can parse file by extension */ +int vgmstream_ctx_is_valid(const char* filename, vgmstream_ctx_valid_cfg *cfg); #if 0 -/* ****************************************** */ -/* PLAYER: simplifies plugin code */ -/* ****************************************** */ /* opaque player state */ -typedef struct VGMSTREAM_PLAYER VGMSTREAM_PLAYER; +typedef struct VGMSTREAM_CTX VGMSTREAM_CTX; typedef struct { //... -} VGMSTREAM_PLAYER_INFO; +} VGMSTREAM_CTX_INFO; -VGMSTREAM_PLAYER* vgmstream_player_init(...); +VGMSTREAM_CTX* vgmstream_ctx_init(...); -VGMSTREAM_PLAYER* vgmstream_player_format_check(...); -VGMSTREAM_PLAYER* vgmstream_player_set_format_whilelist(...); -VGMSTREAM_PLAYER* vgmstream_player_set_format_blacklist(...); +VGMSTREAM_CTX* vgmstream_ctx_format_check(...); +VGMSTREAM_CTX* vgmstream_ctx_set_format_whilelist(...); +VGMSTREAM_CTX* vgmstream_ctx_set_format_blacklist(...); -VGMSTREAM_PLAYER* vgmstream_player_set_file(...); +VGMSTREAM_CTX* vgmstream_ctx_set_file(...); -VGMSTREAM_PLAYER* vgmstream_player_get_config(...); +VGMSTREAM_CTX* vgmstream_ctx_get_config(...); -VGMSTREAM_PLAYER* vgmstream_player_set_config(...); +VGMSTREAM_CTX* vgmstream_ctx_set_config(...); -VGMSTREAM_PLAYER* vgmstream_player_get_buffer(...); +VGMSTREAM_CTX* vgmstream_ctx_get_buffer(...); -VGMSTREAM_PLAYER* vgmstream_player_get_info(...); +VGMSTREAM_CTX* vgmstream_ctx_get_info(...); -VGMSTREAM_PLAYER* vgmstream_player_describe(...); +VGMSTREAM_CTX* vgmstream_ctx_describe(...); -VGMSTREAM_PLAYER* vgmstream_player_get_title(...); +VGMSTREAM_CTX* vgmstream_ctx_get_title(...); -VGMSTREAM_PLAYER* vgmstream_player_get_tagfile(...); +VGMSTREAM_CTX* vgmstream_ctx_get_tagfile(...); -VGMSTREAM_PLAYER* vgmstream_player_play(...); +VGMSTREAM_CTX* vgmstream_ctx_play(...); -VGMSTREAM_PLAYER* vgmstream_player_seek(...); +VGMSTREAM_CTX* vgmstream_ctx_seek(...); -VGMSTREAM_PLAYER* vgmstream_player_close(...); +VGMSTREAM_CTX* vgmstream_ctx_close(...); #endif diff --git a/src/vgmstream.h b/src/vgmstream.h index 2b9de067..45e5c7e2 100644 --- a/src/vgmstream.h +++ b/src/vgmstream.h @@ -1329,6 +1329,9 @@ int get_vgmstream_average_bitrate(VGMSTREAM * vgmstream); * The list disables some common formats that may conflict (.wav, .ogg, etc). */ const char ** vgmstream_get_formats(size_t * size); +/* same, but for common-but-disabled formats in the above list. */ +const char ** vgmstream_get_common_formats(size_t * size); + /* Force enable/disable internal looping. Should be done before playing anything (or after reset), * and not all codecs support arbitrary loop values ATM. */ void vgmstream_force_loop(VGMSTREAM* vgmstream, int loop_flag, int loop_start_sample, int loop_end_sample); diff --git a/winamp/in_vgmstream.c b/winamp/in_vgmstream.c index 517ed43f..3862eeca 100644 --- a/winamp/in_vgmstream.c +++ b/winamp/in_vgmstream.c @@ -69,6 +69,8 @@ typedef struct { int disable_subsongs; int downmix_channels; int tagfile_disable; + int exts_unknown_on; + int exts_common_on; ReplayGainType gain_type; ReplayGainType clip_type; } winamp_settings; @@ -384,6 +386,8 @@ static void cfg_char_to_wchar(TCHAR *wdst, size_t wdstsize, const char *src) { #define DEFAULT_DISABLE_SUBSONGS 0 #define DEFAULT_DOWNMIX_CHANNELS 0 #define DEFAULT_TAGFILE_DISABLE 0 +#define DEFAULT_EXTS_UNKNOWN_ON 0 +#define DEFAULT_EXTS_COMMON_ON 0 #define DEFAULT_GAIN_TYPE 1 #define DEFAULT_CLIP_TYPE 2 @@ -396,6 +400,8 @@ static void cfg_char_to_wchar(TCHAR *wdst, size_t wdstsize, const char *src) { #define INI_ENTRY_DISABLE_SUBSONGS TEXT("disable_subsongs") #define INI_ENTRY_DOWNMIX_CHANNELS TEXT("downmix_channels") #define INI_ENTRY_TAGFILE_DISABLE TEXT("tagfile_disable") +#define INI_ENTRY_EXTS_UNKNOWN_ON TEXT("exts_unknown_on") +#define INI_ENTRY_EXTS_COMMON_ON TEXT("exts_common_on") #define INI_ENTRY_GAIN_TYPE TEXT("gain_type") #define INI_ENTRY_CLIP_TYPE TEXT("clip_type") @@ -517,6 +523,8 @@ static void load_config() { } settings.tagfile_disable = GetPrivateProfileInt(CONFIG_APP_NAME,INI_ENTRY_TAGFILE_DISABLE,DEFAULT_TAGFILE_DISABLE,iniFile); + settings.exts_unknown_on = GetPrivateProfileInt(CONFIG_APP_NAME,INI_ENTRY_EXTS_UNKNOWN_ON,DEFAULT_EXTS_UNKNOWN_ON,iniFile); + settings.exts_common_on = GetPrivateProfileInt(CONFIG_APP_NAME,INI_ENTRY_EXTS_COMMON_ON,DEFAULT_EXTS_COMMON_ON,iniFile); settings.gain_type = GetPrivateProfileInt(CONFIG_APP_NAME, INI_ENTRY_GAIN_TYPE, DEFAULT_GAIN_TYPE, iniFile); settings.clip_type = GetPrivateProfileInt(CONFIG_APP_NAME, INI_ENTRY_CLIP_TYPE, DEFAULT_CLIP_TYPE, iniFile); @@ -584,6 +592,10 @@ INT_PTR CALLBACK configDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lPara if (settings.tagfile_disable) CheckDlgButton(hDlg,IDC_TAGFILE_DISABLE,BST_CHECKED); + if (settings.exts_unknown_on) + CheckDlgButton(hDlg,IDC_EXTS_UNKNOWN_ON,BST_CHECKED); + if (settings.exts_common_on) + CheckDlgButton(hDlg,IDC_EXTS_COMMON_ON,BST_CHECKED); break; @@ -680,6 +692,14 @@ INT_PTR CALLBACK configDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lPara cfg_sprintf(buf, TEXT("%d"),settings.tagfile_disable); WritePrivateProfileString(CONFIG_APP_NAME,INI_ENTRY_TAGFILE_DISABLE,buf,iniFile); + settings.exts_unknown_on = (IsDlgButtonChecked(hDlg,IDC_EXTS_UNKNOWN_ON) == BST_CHECKED); + cfg_sprintf(buf, TEXT("%d"),settings.exts_unknown_on); + WritePrivateProfileString(CONFIG_APP_NAME,INI_ENTRY_EXTS_UNKNOWN_ON,buf,iniFile); + + settings.exts_common_on = (IsDlgButtonChecked(hDlg,IDC_EXTS_COMMON_ON) == BST_CHECKED); + cfg_sprintf(buf, TEXT("%d"),settings.exts_common_on); + WritePrivateProfileString(CONFIG_APP_NAME,INI_ENTRY_EXTS_COMMON_ON,buf,iniFile); + hReplayGain = GetDlgItem(hDlg, IDC_REPLAYGAIN); settings.gain_type = SendMessage(hReplayGain, CB_GETCURSEL, 0, 0); cfg_sprintf(buf, TEXT("%d"), settings.gain_type); @@ -725,6 +745,8 @@ INT_PTR CALLBACK configDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lPara CheckDlgButton(hDlg,IDC_DISABLE_SUBSONGS,BST_UNCHECKED); SetDlgItemText(hDlg,IDC_DOWNMIX_CHANNELS,DEFAULT_DOWNMIX_CHANNELS); CheckDlgButton(hDlg,IDC_TAGFILE_DISABLE,BST_UNCHECKED); + CheckDlgButton(hDlg,IDC_EXTS_UNKNOWN_ON,BST_UNCHECKED); + CheckDlgButton(hDlg,IDC_EXTS_COMMON_ON,BST_UNCHECKED); break; default: @@ -1079,34 +1101,16 @@ void winamp_Quit() { /* called before extension checks, to allow detection of mms://, etc */ int winamp_IsOurFile(const in_char *fn) { - const in_char *filename; - const in_char *extension; + vgmstream_ctx_valid_cfg cfg = {0}; + char filename_utf8[PATH_LIMIT]; - /* favor strrchr (optimized/aligned) rather than homemade loops */ - - /* find possible separator first to avoid misdetecting folders with dots + extensionless files - * (allow both slashes as plugin could pass normalized '/') */ - filename = wa_strrchr(fn, wa_L('\\')); - if (filename != NULL) - filename++; /* skip separator */ - else { - filename = wa_strrchr(fn, wa_L('/')); - if (filename != NULL) - filename++; /* skip separator */ - else - filename = fn; /* pathname has no separators (single filename) */ - } - - extension = wa_strrchr(filename,'.'); - if (extension != NULL) - extension++; /* skip dot */ - else - return 1; /* extensionless, try to play it */ + wa_ichar_to_char(filename_utf8, PATH_LIMIT, fn); + cfg.skip_standard = 1; /* validated by Winamp */ + cfg.accept_unknown = settings.exts_unknown_on; + cfg.accept_common = settings.exts_common_on; /* 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; + return vgmstream_ctx_is_valid(filename_utf8, &cfg); } diff --git a/winamp/resource.h b/winamp/resource.h index 753f5185..38d17852 100644 --- a/winamp/resource.h +++ b/winamp/resource.h @@ -13,3 +13,5 @@ #define IDC_TAGFILE_DISABLE 1012 #define IDC_REPLAYGAIN 1013 #define IDC_CLIPPROTECT 1014 +#define IDC_EXTS_UNKNOWN_ON 1015 +#define IDC_EXTS_COMMON_ON 1016 diff --git a/winamp/resource.rc b/winamp/resource.rc index 222ea030..fd09736f 100644 --- a/winamp/resource.rc +++ b/winamp/resource.rc @@ -4,7 +4,7 @@ #define IDC_STATIC -1 //elements: text, id, x, y, width, height [, style [, extended-style]] -IDD_CONFIG DIALOGEX 0, 0, 187, 164 +IDD_CONFIG DIALOGEX 0, 0, 187, 196 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "in_vgmstream configuration" FONT 8, "MS Sans Serif", 0, 0, 0x0 @@ -45,4 +45,11 @@ BEGIN EDITTEXT IDC_DOWNMIX_CHANNELS,52,112,37,14,ES_AUTOHSCROLL CONTROL "Disable tagfile",IDC_TAGFILE_DISABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,131,87,10 + + //CONTROL "Override title",IDC_OVERRIDE_TITLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,147,97,10 + + CONTROL "Enable unknown exts",IDC_EXTS_UNKNOWN_ON,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,163,87,10 + + CONTROL "Enable common exts",IDC_EXTS_COMMON_ON,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,179,87,10 + END