aboutsummaryrefslogtreecommitdiff
path: root/Src/Plugins/Visualization/vis_milk2/vis.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Plugins/Visualization/vis_milk2/vis.cpp')
-rw-r--r--Src/Plugins/Visualization/vis_milk2/vis.cpp275
1 files changed, 275 insertions, 0 deletions
diff --git a/Src/Plugins/Visualization/vis_milk2/vis.cpp b/Src/Plugins/Visualization/vis_milk2/vis.cpp
new file mode 100644
index 00000000..afc80edd
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/vis.cpp
@@ -0,0 +1,275 @@
+/*
+ LICENSE
+ -------
+Copyright 2005-2013 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "api__vis_milk2.h"
+#include <windows.h>
+#include "vis.h"
+#include "plugin.h"
+#include "defines.h"
+#include "resource.h"
+#include "utility.h"
+
+CPlugin g_plugin;
+_locale_t g_use_C_locale = 0;
+char keyMappings[8];
+bool g_bFullyExited = true;
+
+// wasabi based services for localisation support
+api_service *WASABI_API_SVC = 0;
+api_language *WASABI_API_LNG = 0;
+api_application *WASABI_API_APP = 0;
+api_syscb *WASABI_API_SYSCB = 0;
+HINSTANCE WASABI_API_LNG_HINST = 0, WASABI_API_ORIG_HINST = 0;
+
+void config(struct winampVisModule *this_mod); // configuration dialog
+int init(struct winampVisModule *this_mod); // initialization for module
+int render1(struct winampVisModule *this_mod); // rendering for module 1
+void quit(struct winampVisModule *this_mod); // deinitialization for module
+
+// our only plugin module in this plugin:
+winampVisModule mod1 =
+{
+ MODULEDESC,
+ NULL, // hwndParent
+ NULL, // hDllInstance
+ 0, // sRate
+ 0, // nCh
+ 0, // latencyMS - tells winamp how much in advance you want the audio data,
+ // in ms.
+ 10, // delayMS - if winamp tells the plugin to render a frame and it takes
+ // less than this # of milliseconds, winamp will sleep (go idle)
+ // for the remainder. In effect, this limits the framerate of
+ // the plugin. A value of 10 would cause a fps limit of ~100.
+ // Derivation: (1000 ms/sec) / (10 ms/frame) = 100 fps.
+ 0, // spectrumNch
+ 2, // waveformNch
+ { 0, }, // spectrumData
+ { 0, }, // waveformData
+ config,
+ init,
+ render1,
+ quit
+};
+
+// getmodule routine from the main header. Returns NULL if an invalid module was requested,
+// otherwise returns either mod1, mod2 or mod3 depending on 'which'.
+winampVisModule *getModule(int which)
+{
+ switch (which)
+ {
+ case 0: return &mod1;
+ //case 1: return &mod2;
+ //case 2: return &mod3;
+ default: return NULL;
+ }
+}
+
+// Module header, includes version, description, and address of the module retriever function
+winampVisHeader hdr = { VIS_HDRVER, DLLDESC, getModule };
+
+// use this to get our own HINSTANCE since overriding DllMain(..) causes instant crashes (should see why)
+static HINSTANCE GetMyInstance()
+{
+ MEMORY_BASIC_INFORMATION mbi = {0};
+ if(VirtualQuery(GetMyInstance, &mbi, sizeof(mbi)))
+ return (HINSTANCE)mbi.AllocationBase;
+ return NULL;
+}
+
+// this is the only exported symbol. returns our main header.
+// if you are compiling C++, the extern "C" { is necessary, so we just #ifdef it
+#ifdef __cplusplus
+extern "C" {
+#endif
+ __declspec( dllexport ) winampVisHeader *winampVisGetHeader(HWND hwndParent)
+ {
+ if(!WASABI_API_LNG_HINST)
+ {
+ // loader so that we can get the localisation service api for use
+ WASABI_API_SVC = (api_service*)SendMessage(hwndParent, WM_WA_IPC, 0, IPC_GET_API_SERVICE);
+ if (WASABI_API_SVC == (api_service*)1) WASABI_API_SVC = NULL;
+
+ waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(languageApiGUID);
+ if (sf) WASABI_API_LNG = reinterpret_cast<api_language*>(sf->getInterface());
+
+ sf = WASABI_API_SVC->service_getServiceByGuid(applicationApiServiceGuid);
+ if (sf) WASABI_API_APP = reinterpret_cast<api_application*>(sf->getInterface());
+
+ sf = WASABI_API_SVC->service_getServiceByGuid(syscbApiServiceGuid);
+ if (sf) WASABI_API_SYSCB = reinterpret_cast<api_syscb*>(sf->getInterface());
+
+ // need to have this initialised before we try to do anything with localisation features
+ WASABI_API_START_LANG(GetMyInstance(),VisMilkdropLangGUID);
+
+ /* added for v2.25 as a quick work around to allow partial
+ /* keyboard mappings (mainly coming from de-de requirements)
+ ** [yY][Y][yY][zZ]
+ ** 1 2 3 4
+ **
+ ** 1 - does yes for the 3 different prompt types
+ ** 2 - does Ctrl+Y for stopping display of custom message of song title
+ ** 3 - something for preset editing (not 100% sure what)
+ ** 4 - used for the previous track sent to Winamp
+ */
+ WASABI_API_LNGSTRING_BUF(IDS_KEY_MAPPINGS, keyMappings, 8);
+
+ // as we're under a different thread we need to set the locale
+ //WASABI_API_LNG->UseUserNumericLocale();
+ g_use_C_locale = WASABI_API_LNG->Get_C_NumericLocale();
+ }
+
+ return &hdr;
+ }
+#ifdef __cplusplus
+}
+#endif
+
+bool WaitUntilPluginFinished(HWND hWndWinamp)
+{
+ int slept = 0;
+ while (!g_bFullyExited && slept < 1000)
+ {
+ Sleep(50);
+ slept += 50;
+ }
+
+ if (!g_bFullyExited)
+ {
+ wchar_t title[64];
+ MessageBoxW(hWndWinamp, WASABI_API_LNGSTRINGW(IDS_ERROR_THE_PLUGIN_IS_ALREADY_RUNNING),
+ WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR, title, 64),
+ MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
+ return false;
+ }
+
+ return true;
+}
+
+HWND GetDialogBoxParent(HWND winamp)
+{
+ HWND parent = (HWND)SendMessage(winamp, WM_WA_IPC, 0, IPC_GETDIALOGBOXPARENT);
+ if (!parent || parent == (HWND)1)
+ return winamp;
+ return parent;
+}
+
+// configuration. Passed this_mod, as a "this" parameter. Allows you to make one configuration
+// function that shares code for all your modules (you don't HAVE to use it though, you can make
+// config1(), config2(), etc...)
+void config(struct winampVisModule *this_mod)
+{
+ if (!g_bFullyExited)
+ {
+ g_plugin.OnAltK();
+ return;
+ }
+
+ g_bFullyExited = false;
+ g_plugin.PluginPreInitialize(this_mod->hwndParent, this_mod->hDllInstance);
+ WASABI_API_DIALOGBOXPARAMW(IDD_CONFIG, GetDialogBoxParent(this_mod->hwndParent), g_plugin.ConfigDialogProc, (LPARAM)&g_plugin);
+ g_bFullyExited = true;
+}
+
+int (*warand)(void) = 0;
+
+int fallback_rand_fn(void) {
+ return rand();
+}
+
+// initialization. Registers our window class, creates our window, etc. Again, this one works for
+// both modules, but you could make init1() and init2()...
+// returns 0 on success, 1 on failure.
+int init(struct winampVisModule *this_mod)
+{
+ DWORD version = GetWinampVersion(mod1.hwndParent);
+
+ if (!warand)
+ {
+ warand = (int (*)(void))SendMessage(this_mod->hwndParent, WM_WA_IPC, 0, IPC_GET_RANDFUNC);
+ if ((size_t)warand <= 1)
+ {
+ warand = fallback_rand_fn;
+ }
+ }
+
+ if (!WaitUntilPluginFinished(this_mod->hwndParent))
+ {
+ return 1;
+ }
+
+ if (GetWinampVersion(mod1.hwndParent) < 0x4000)
+ {
+ // query winamp for its playback state
+ LRESULT ret = SendMessage(this_mod->hwndParent, WM_USER, 0, 104);
+ // ret=1: playing, ret=3: paused, other: stopped
+
+ if (ret != 1)
+ {
+ wchar_t title[64];
+ MessageBoxW(this_mod->hwndParent, WASABI_API_LNGSTRINGW(IDS_THIS_PLUGIN_NEEDS_MUSIC_TO_RUN),
+ WASABI_API_LNGSTRINGW_BUF(IDS_NO_MUSIC_PLAYING, title, 64),
+ MB_OK|MB_SETFOREGROUND|MB_TOPMOST|MB_TASKMODAL );
+ return 1; // failure
+ }
+ }
+
+ g_bFullyExited = false;
+
+ if (!g_plugin.PluginPreInitialize(this_mod->hwndParent, this_mod->hDllInstance))
+ {
+ g_plugin.PluginQuit();
+ g_bFullyExited = true;
+ return 1;
+ }
+
+ if (!g_plugin.PluginInitialize())
+ {
+ g_plugin.PluginQuit();
+ g_bFullyExited = true;
+ return 1;
+ }
+
+ return 0; // success
+}
+
+// render function for oscilliscope. Returns 0 if successful, 1 if visualization should end.
+int render1(struct winampVisModule *this_mod)
+{
+ if (g_plugin.PluginRender(this_mod->waveformData[0], this_mod->waveformData[1]))
+ return 0; // ok
+ else
+ return 1; // failed
+}
+
+// cleanup (opposite of init()). Should destroy the window, unregister the window class, etc.
+void quit(struct winampVisModule *this_mod)
+{
+ g_plugin.PluginQuit();
+ g_bFullyExited = true;
+} \ No newline at end of file