aboutsummaryrefslogtreecommitdiff
path: root/Src/Plugins/SDK
diff options
context:
space:
mode:
authorJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
committerJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
commit20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/Plugins/SDK
parent537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff)
downloadwinamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz
Initial community commit
Diffstat (limited to 'Src/Plugins/SDK')
-rw-r--r--Src/Plugins/SDK/burner/BurnerCommon.cpp25
-rw-r--r--Src/Plugins/SDK/burner/BurnerCommon.h14
-rw-r--r--Src/Plugins/SDK/burner/DataBurner.cpp148
-rw-r--r--Src/Plugins/SDK/burner/DataBurner.h20
-rw-r--r--Src/Plugins/SDK/burner/ISOBurner.cpp67
-rw-r--r--Src/Plugins/SDK/burner/ISOBurner.h15
-rw-r--r--Src/Plugins/SDK/burner/ISOCreator.cpp139
-rw-r--r--Src/Plugins/SDK/burner/api.h5
-rw-r--r--Src/Plugins/SDK/burner/burner.rc114
-rw-r--r--Src/Plugins/SDK/burner/burner.vcxproj270
-rw-r--r--Src/Plugins/SDK/burner/burner.vcxproj.filters100
-rw-r--r--Src/Plugins/SDK/burner/factory_databurner.cpp71
-rw-r--r--Src/Plugins/SDK/burner/factory_databurner.h23
-rw-r--r--Src/Plugins/SDK/burner/factory_isoburner.cpp71
-rw-r--r--Src/Plugins/SDK/burner/factory_isoburner.h23
-rw-r--r--Src/Plugins/SDK/burner/factory_isocreator.cpp72
-rw-r--r--Src/Plugins/SDK/burner/factory_isocreator.h23
-rw-r--r--Src/Plugins/SDK/burner/ifc_burner_writecallback.h33
-rw-r--r--Src/Plugins/SDK/burner/isocreator.h20
-rw-r--r--Src/Plugins/SDK/burner/main.cpp55
-rw-r--r--Src/Plugins/SDK/burner/obj_databurner.h60
-rw-r--r--Src/Plugins/SDK/burner/obj_isoburner.h46
-rw-r--r--Src/Plugins/SDK/burner/obj_isocreator.h70
-rw-r--r--Src/Plugins/SDK/burner/resource.h14
-rw-r--r--Src/Plugins/SDK/coverdirectory/CoverDirectory.cpp314
-rw-r--r--Src/Plugins/SDK/coverdirectory/CoverDirectory.h36
-rw-r--r--Src/Plugins/SDK/coverdirectory/api.h23
-rw-r--r--Src/Plugins/SDK/coverdirectory/cover_directory.vcxproj235
-rw-r--r--Src/Plugins/SDK/coverdirectory/cover_directory.vcxproj.filters41
-rw-r--r--Src/Plugins/SDK/coverdirectory/coverdirectory.rc76
-rw-r--r--Src/Plugins/SDK/coverdirectory/coverdirectory.sln24
-rw-r--r--Src/Plugins/SDK/coverdirectory/main.cpp83
-rw-r--r--Src/Plugins/SDK/coverdirectory/resource.h14
-rw-r--r--Src/Plugins/SDK/coverdirectory/version.rc239
-rw-r--r--Src/Plugins/SDK/dsp_test/RESOURCE.H18
-rw-r--r--Src/Plugins/SDK/dsp_test/SCRIPT1.RC97
-rw-r--r--Src/Plugins/SDK/dsp_test/dsp_ns.txt23
-rw-r--r--Src/Plugins/SDK/dsp_test/dsp_test.c478
-rw-r--r--Src/Plugins/SDK/dsp_test/dsp_test.sln24
-rw-r--r--Src/Plugins/SDK/dsp_test/dsp_test.vcxproj227
-rw-r--r--Src/Plugins/SDK/dsp_test/dsp_test.vcxproj.filters32
-rw-r--r--Src/Plugins/SDK/gen_classicart/api.h24
-rw-r--r--Src/Plugins/SDK/gen_classicart/build_lng.cmd3
-rw-r--r--Src/Plugins/SDK/gen_classicart/gen_classicart.cpp935
-rw-r--r--Src/Plugins/SDK/gen_classicart/gen_classicart.nsi125
-rw-r--r--Src/Plugins/SDK/gen_classicart/gen_classicart.rc156
-rw-r--r--Src/Plugins/SDK/gen_classicart/gen_classicart.sln30
-rw-r--r--Src/Plugins/SDK/gen_classicart/gen_classicart.vcxproj449
-rw-r--r--Src/Plugins/SDK/gen_classicart/gen_classicart.vcxproj.filters42
-rw-r--r--Src/Plugins/SDK/gen_classicart/lng_generator.exebin0 -> 67072 bytes
-rw-r--r--Src/Plugins/SDK/gen_classicart/notfound.pngbin0 -> 3792 bytes
-rw-r--r--Src/Plugins/SDK/gen_classicart/resource.h33
-rw-r--r--Src/Plugins/SDK/in_tone/IN_TONE.sln24
-rw-r--r--Src/Plugins/SDK/in_tone/IN_TONE.vcxproj319
-rw-r--r--Src/Plugins/SDK/in_tone/IN_TONE.vcxproj.filters29
-rw-r--r--Src/Plugins/SDK/in_tone/MAIN.C240
-rw-r--r--Src/Plugins/SDK/in_tone/in_tone.rc109
-rw-r--r--Src/Plugins/SDK/in_tone/resource.h18
-rw-r--r--Src/Plugins/SDK/in_tone/version.rc239
-rw-r--r--Src/Plugins/SDK/irctell/api__irctell.h7
-rw-r--r--Src/Plugins/SDK/irctell/dde.cpp50
-rw-r--r--Src/Plugins/SDK/irctell/dde.h9
-rw-r--r--Src/Plugins/SDK/irctell/irctell.cpp122
-rw-r--r--Src/Plugins/SDK/irctell/irctell.h29
-rw-r--r--Src/Plugins/SDK/irctell/irctell.rc74
-rw-r--r--Src/Plugins/SDK/irctell/irctell.sln24
-rw-r--r--Src/Plugins/SDK/irctell/irctell.vcxproj243
-rw-r--r--Src/Plugins/SDK/irctell/irctell.vcxproj.filters44
-rw-r--r--Src/Plugins/SDK/irctell/resource.h17
-rw-r--r--Src/Plugins/SDK/irctell/version.rc239
-rw-r--r--Src/Plugins/SDK/ml_iso/ToISO.cpp366
-rw-r--r--Src/Plugins/SDK/ml_iso/api__ml_iso.h10
-rw-r--r--Src/Plugins/SDK/ml_iso/main.cpp150
-rw-r--r--Src/Plugins/SDK/ml_iso/main.h12
-rw-r--r--Src/Plugins/SDK/ml_iso/ml_iso.rc122
-rw-r--r--Src/Plugins/SDK/ml_iso/ml_iso.sln24
-rw-r--r--Src/Plugins/SDK/ml_iso/ml_iso.vcxproj246
-rw-r--r--Src/Plugins/SDK/ml_iso/ml_iso.vcxproj.filters41
-rw-r--r--Src/Plugins/SDK/ml_iso/resource.h26
-rw-r--r--Src/Plugins/SDK/ml_iso/version.rc239
-rw-r--r--Src/Plugins/SDK/ml_xmlex/api.h38
-rw-r--r--Src/Plugins/SDK/ml_xmlex/main.cpp69
-rw-r--r--Src/Plugins/SDK/ml_xmlex/main.h13
-rw-r--r--Src/Plugins/SDK/ml_xmlex/ml_xmlex.rc108
-rw-r--r--Src/Plugins/SDK/ml_xmlex/ml_xmlex.sln24
-rw-r--r--Src/Plugins/SDK/ml_xmlex/ml_xmlex.vcxproj241
-rw-r--r--Src/Plugins/SDK/ml_xmlex/ml_xmlex.vcxproj.filters41
-rw-r--r--Src/Plugins/SDK/ml_xmlex/readme.txt13
-rw-r--r--Src/Plugins/SDK/ml_xmlex/resource.h22
-rw-r--r--Src/Plugins/SDK/ml_xmlex/version.rc239
-rw-r--r--Src/Plugins/SDK/ml_xmlex/xmltest.xml8
-rw-r--r--Src/Plugins/SDK/ml_xmlex/xmltest2.xml7
-rw-r--r--Src/Plugins/SDK/ml_xmlex/xmlview.cpp301
-rw-r--r--Src/Plugins/SDK/out_null/Out_null.dsp108
-rw-r--r--Src/Plugins/SDK/out_null/Out_null.dsw29
-rw-r--r--Src/Plugins/SDK/out_null/Out_null.sln25
-rw-r--r--Src/Plugins/SDK/out_null/Out_null.vcxproj296
-rw-r--r--Src/Plugins/SDK/out_null/Out_null.vcxproj.filters32
-rw-r--r--Src/Plugins/SDK/out_null/main.c159
-rw-r--r--Src/Plugins/SDK/out_null/out_null.rc109
-rw-r--r--Src/Plugins/SDK/out_null/resource.h18
-rw-r--r--Src/Plugins/SDK/out_null/version.rc239
-rw-r--r--Src/Plugins/SDK/plLoadEx/ExComponent.cpp32
-rw-r--r--Src/Plugins/SDK/plLoadEx/ExComponent.h16
-rw-r--r--Src/Plugins/SDK/plLoadEx/SimpleHandler.cpp45
-rw-r--r--Src/Plugins/SDK/plLoadEx/SimpleHandler.h21
-rw-r--r--Src/Plugins/SDK/plLoadEx/SimpleHandlerFactory.cpp56
-rw-r--r--Src/Plugins/SDK/plLoadEx/SimpleHandlerFactory.h20
-rw-r--r--Src/Plugins/SDK/plLoadEx/SimpleLoader.cpp26
-rw-r--r--Src/Plugins/SDK/plLoadEx/SimpleLoader.h14
-rw-r--r--Src/Plugins/SDK/plLoadEx/example.simplebin0 -> 58 bytes
-rw-r--r--Src/Plugins/SDK/plLoadEx/plLoadEx.rc74
-rw-r--r--Src/Plugins/SDK/plLoadEx/plLoadEx.sln24
-rw-r--r--Src/Plugins/SDK/plLoadEx/plLoadEx.vcxproj229
-rw-r--r--Src/Plugins/SDK/plLoadEx/plLoadEx.vcxproj.filters56
-rw-r--r--Src/Plugins/SDK/plLoadEx/resource.h17
-rw-r--r--Src/Plugins/SDK/plLoadEx/version.rc239
-rw-r--r--Src/Plugins/SDK/plLoadEx/w5s.cpp9
118 files changed, 9968 insertions, 0 deletions
diff --git a/Src/Plugins/SDK/burner/BurnerCommon.cpp b/Src/Plugins/SDK/burner/BurnerCommon.cpp
new file mode 100644
index 00000000..933b8862
--- /dev/null
+++ b/Src/Plugins/SDK/burner/BurnerCommon.cpp
@@ -0,0 +1,25 @@
+#include "BurnerCommon.h"
+#include "api.h"
+#include <api/service/waservicefactory.h>
+
+BurnerCommon::BurnerCommon(obj_primo *_primo)
+{
+ primo = _primo;
+ triggerEvent=0;
+ triggerEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+}
+
+BurnerCommon::~BurnerCommon()
+{
+ if (triggerEvent)
+ CloseHandle(triggerEvent);
+
+ waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(obj_primo::getServiceGuid());
+ if (sf) sf->releaseInterface(primo);
+}
+
+void BurnerCommon::TriggerCallback()
+{
+ if (triggerEvent)
+ SetEvent(triggerEvent);
+} \ No newline at end of file
diff --git a/Src/Plugins/SDK/burner/BurnerCommon.h b/Src/Plugins/SDK/burner/BurnerCommon.h
new file mode 100644
index 00000000..48b0d1b8
--- /dev/null
+++ b/Src/Plugins/SDK/burner/BurnerCommon.h
@@ -0,0 +1,14 @@
+#pragma once
+#include <windows.h>
+#include "../primo/obj_primo.h"
+
+class BurnerCommon
+{
+public:
+ BurnerCommon(obj_primo *_primo);
+ ~BurnerCommon();
+ void TriggerCallback();
+protected:
+ obj_primo *primo;
+ HANDLE triggerEvent;
+};
diff --git a/Src/Plugins/SDK/burner/DataBurner.cpp b/Src/Plugins/SDK/burner/DataBurner.cpp
new file mode 100644
index 00000000..e5cd579d
--- /dev/null
+++ b/Src/Plugins/SDK/burner/DataBurner.cpp
@@ -0,0 +1,148 @@
+#include "DataBurner.h"
+#include "ifc_burner_writecallback.h"
+#include <malloc.h>
+#include <strsafe.h>
+
+DataBurner::DataBurner(obj_primo *_primo) : BurnerCommon(_primo)
+{
+ driveLetter=0;
+}
+
+DataBurner::~DataBurner()
+{
+ if (primo)
+ primo->CloseImage();
+}
+
+int DataBurner::Open(const wchar_t *volumeName, wchar_t driveLetter, int format)
+{
+ this->driveLetter = driveLetter;
+ if (!primo)
+ return 1;
+
+
+ DWORD units[] = {driveLetter, 0xFFFFFFFF};
+
+
+ // TODO: use PrimoSDK_DiscInfoEx to verify that a disc is available
+
+ // TODO: PrimoSDK_UnitVxBlock after we're done debugging
+ // TODO: PrimoSDK_UnitAIN
+ // TODO: PrimoSDK_UnitLock
+
+ DWORD ret = primo->NewImageWCS(units,
+ (PWORD)volumeName,
+ 0, // no track session # needed, I don't think
+ PRIMOSDK_ORIGDATE | format,
+ 0, // TODO
+ 0 // TODO
+ ); // TODO: validate format
+
+ return 0;
+}
+
+// TODO: check AddFolderWCS for return values
+static void createDirForFileW(obj_primo *primo, const wchar_t *str)
+{
+ const wchar_t *p = str;
+ if ((p[0] ==L'\\' || p[0] ==L'/') && (p[1] ==L'\\' || p[1] ==L'/'))
+ {
+ p += 2;
+ while (*p && *p !=L'\\' && *p !=L'/') p++;
+ if (!*p) return ;
+ p++;
+ while (*p && *p !=L'\\' && *p !=L'/') p++;
+ }
+ else
+ {
+ while (*p && *p !=L'\\' && *p !=L'/') p++;
+ }
+
+ while (*p)
+ {
+ while (*p !=L'\\' && *p !=L'/' && *p) p = CharNextW(p);
+ if (*p)
+ {
+ size_t copySize = (p-str+1)*sizeof(wchar_t);
+ wchar_t *copy = (wchar_t *)alloca(copySize);
+ StringCbCopy(copy, copySize, str);
+ primo->AddFolderWCS(copy);
+ p++;
+ }
+ }
+}
+
+int DataBurner::AddFile(const wchar_t *source, const wchar_t *destination)
+{
+ createDirForFileW(primo, destination);
+ DWORD ret = primo->AddFileWCS((PWORD)destination, (PWORD)source);
+
+ if (ret != PRIMOSDK_OK)
+ return 1;
+
+ return 0;
+}
+
+int DataBurner::AddFolder(const wchar_t *folder)
+{
+ createDirForFileW(primo, folder);
+ DWORD ret = primo->AddFolderWCS(folder); // add again in case they didn't terminate with a slash
+ if (ret != PRIMOSDK_OK)
+ return 1;
+
+ return 0;
+}
+
+int DataBurner::Write(int flags, unsigned int speed, ifc_burner_writecallback *callback)
+{
+ DWORD size=0;
+ DWORD ret = primo->WriteImage(flags, speed, &size);
+ if (ret != PRIMOSDK_OK)
+ return 1;
+
+ while (1)
+ {
+ DWORD cursec = 0, totsec = 0;
+ ret = primo->RunningStatus(PRIMOSDK_GETSTATUS, &cursec, &totsec);
+
+ if (ret == PRIMOSDK_RUNNING)
+ {
+ if (callback)
+ {
+ int abort = callback->OnStatus(cursec, totsec);
+ if (abort)
+ {
+ ret = primo->RunningStatus(PRIMOSDK_ABORT, 0, 0);
+ callback = 0; // cheap way to prevent making further callbacks
+ }
+ }
+ WaitForSingleObject(triggerEvent, 500);
+ }
+ else if (ret == PRIMOSDK_OK)
+ {
+ DWORD unit = driveLetter;
+ ret = primo->UnitStatus(&unit, NULL, NULL, NULL, NULL);
+
+ if (ret == PRIMOSDK_OK && callback)
+ callback->Finished();
+ break;
+ }
+ else
+ break;
+ }
+
+ if (ret != PRIMOSDK_OK)
+ return 1;
+
+ return 0;
+}
+
+#define CBCLASS DataBurner
+START_DISPATCH;
+CB(DATABURNER_OPEN, Open)
+CB(DATABURNER_ADDFILE, AddFile)
+CB(DATABURNER_ADDFOLDER, AddFolder)
+CB(DATABURNER_WRITE, Write)
+VCB(DATABURNER_FORCECALLBACK, ForceCallback)
+END_DISPATCH;
+#undef CBCLASS
diff --git a/Src/Plugins/SDK/burner/DataBurner.h b/Src/Plugins/SDK/burner/DataBurner.h
new file mode 100644
index 00000000..f30c1e7c
--- /dev/null
+++ b/Src/Plugins/SDK/burner/DataBurner.h
@@ -0,0 +1,20 @@
+#pragma once
+#include "obj_databurner.h"
+#include "BurnerCommon.h"
+
+class DataBurner : public obj_databurner, protected BurnerCommon
+{
+public:
+ DataBurner(obj_primo *primo);
+ ~DataBurner();
+ int Open(const wchar_t *volumeName, wchar_t driveLetter, int format);
+ int AddFile(const wchar_t *source, const wchar_t *destination);
+ int AddFolder(const wchar_t *folder);
+ int Write(int flags, unsigned int speed, ifc_burner_writecallback *callback);
+ inline void ForceCallback() { BurnerCommon::TriggerCallback(); }
+protected:
+ RECVS_DISPATCH;
+
+private:
+ wchar_t driveLetter;
+};
diff --git a/Src/Plugins/SDK/burner/ISOBurner.cpp b/Src/Plugins/SDK/burner/ISOBurner.cpp
new file mode 100644
index 00000000..84d45f62
--- /dev/null
+++ b/Src/Plugins/SDK/burner/ISOBurner.cpp
@@ -0,0 +1,67 @@
+#include "ISOBurner.h"
+#include "../nu/AutoChar.h"
+#include "ifc_burner_writecallback.h"
+
+ISOBurner::ISOBurner(obj_primo *_primo) : BurnerCommon(_primo)
+{
+}
+
+int ISOBurner::Open()
+{
+ if (!primo)
+ return 1;
+
+ return 0;
+}
+
+int ISOBurner::Write(wchar_t driveLetter, const wchar_t *isoFile, int flags, unsigned int speed, ifc_burner_writecallback *callback)
+{
+ DWORD unit[] = {driveLetter, 0xFFFFFFFF};
+ DWORD ret = primo->WriteOtherCDImage(unit, (PBYTE)(char *)AutoChar(isoFile), flags, speed);
+ if (ret != PRIMOSDK_OK)
+ return 1;
+
+ while (1)
+ {
+ DWORD cursec = 0, totsec = 0;
+ ret = primo->RunningStatus(PRIMOSDK_GETSTATUS, &cursec, &totsec);
+
+ if (ret == PRIMOSDK_RUNNING)
+ {
+ if (callback)
+ {
+ int abort = callback->OnStatus(cursec, totsec);
+ if (abort)
+ {
+ ret = primo->RunningStatus(PRIMOSDK_ABORT, 0, 0);
+ callback = 0; // cheap way to prevent making further callbacks
+ }
+ }
+ WaitForSingleObject(triggerEvent, 500);
+ }
+ else if (ret == PRIMOSDK_OK)
+ {
+ DWORD unit = driveLetter;
+ ret = primo->UnitStatus(&unit, NULL, NULL, NULL, NULL);
+
+ if (ret == PRIMOSDK_OK && callback)
+ callback->Finished();
+ break;
+ }
+ else
+ break;
+ }
+
+ if (ret != PRIMOSDK_OK)
+ return 1;
+
+ return 0;
+}
+
+#define CBCLASS ISOBurner
+START_DISPATCH;
+CB(ISOBURNER_OPEN, Open)
+CB(ISOBURNER_WRITE, Write)
+VCB(ISOBURNER_FORCECALLBACK, ForceCallback)
+END_DISPATCH;
+#undef CBCLASS
diff --git a/Src/Plugins/SDK/burner/ISOBurner.h b/Src/Plugins/SDK/burner/ISOBurner.h
new file mode 100644
index 00000000..ab331908
--- /dev/null
+++ b/Src/Plugins/SDK/burner/ISOBurner.h
@@ -0,0 +1,15 @@
+#pragma once
+
+#include "obj_isoburner.h"
+#include "BurnerCommon.h"
+
+class ISOBurner : public obj_isoburner, protected BurnerCommon
+{
+public:
+ ISOBurner(obj_primo *_primo);
+ int Open();
+ int Write(wchar_t driveLetter, const wchar_t *isoFile, int flags, unsigned int speed, ifc_burner_writecallback *callback);
+ inline void ForceCallback() { BurnerCommon::TriggerCallback(); }
+protected:
+ RECVS_DISPATCH;
+}; \ No newline at end of file
diff --git a/Src/Plugins/SDK/burner/ISOCreator.cpp b/Src/Plugins/SDK/burner/ISOCreator.cpp
new file mode 100644
index 00000000..bf8b83f3
--- /dev/null
+++ b/Src/Plugins/SDK/burner/ISOCreator.cpp
@@ -0,0 +1,139 @@
+#include "ISOCreator.h"
+#include <malloc.h>
+#include "../nu/AutoChar.h"
+#include "ifc_burner_writecallback.h"
+#include <strsafe.h>
+
+ISOCreator::ISOCreator(obj_primo *_primo) : BurnerCommon(_primo)
+{
+}
+
+ISOCreator::~ISOCreator()
+{
+ if (primo)
+ primo->CloseImage();
+}
+
+int ISOCreator::Open(const wchar_t *volumeName, int format, int media)
+{
+ if (!primo)
+ return 1;
+
+ DWORD units=0xFFFFFFFF;
+ DWORD ret = primo->NewImageWCS(
+ &units,
+ (PWORD)volumeName,
+ 0, // no track session # needed, I don't think
+ PRIMOSDK_ORIGDATE | format | media,
+ 0, // don't think we need a swap file for ISO
+ 0 // probably don't need a swap location either, we'll see ...
+ ); // TODO: validate format and media
+
+ if (ret != PRIMOSDK_OK)
+ return 1;
+
+ return 0;
+}
+
+// TODO: check AddFolderWCS for return values
+static void createDirForFileW(obj_primo *primo, const wchar_t *str)
+{
+ const wchar_t *p = str;
+ if ((p[0] ==L'\\' || p[0] ==L'/') && (p[1] ==L'\\' || p[1] ==L'/'))
+ {
+ p += 2;
+ while (*p && *p !=L'\\' && *p !=L'/') p++;
+ if (!*p) return ;
+ p++;
+ while (*p && *p !=L'\\' && *p !=L'/') p++;
+ }
+ else
+ {
+ while (*p && *p !=L'\\' && *p !=L'/') p++;
+ }
+
+ while (*p)
+ {
+ while (*p !=L'\\' && *p !=L'/' && *p) p = CharNextW(p);
+ if (*p)
+ {
+ size_t copySize = (p-str+1)*sizeof(wchar_t);
+ wchar_t *copy = (wchar_t *)alloca(copySize);
+ StringCbCopy(copy, copySize, str);
+ primo->AddFolderWCS(copy);
+ p++;
+ }
+ }
+}
+
+int ISOCreator::AddFile(const wchar_t *source, const wchar_t *destination)
+{
+ createDirForFileW(primo, destination);
+ DWORD ret = primo->AddFileWCS((PWORD)destination, (PWORD)source);
+
+ if (ret != PRIMOSDK_OK)
+ return 1;
+
+ return 0;
+}
+
+int ISOCreator::AddFolder(const wchar_t *folder)
+{
+ createDirForFileW(primo, folder);
+ DWORD ret = primo->AddFolderWCS(folder); // add again in case they didn't terminate with a slash
+ if (ret != PRIMOSDK_OK)
+ return 1;
+
+ return 0;
+}
+
+int ISOCreator::Write(const wchar_t *destination, ifc_burner_writecallback *callback)
+{
+ DWORD size=0;
+ DWORD ret = primo->SaveImage((PBYTE)(char *)AutoChar(destination), &size);
+ if (ret != PRIMOSDK_OK)
+ return 1;
+
+ while (1)
+ {
+ DWORD cursec = 0, totsec = 0;
+ ret = primo->RunningStatus(PRIMOSDK_GETSTATUS, &cursec, &totsec);
+
+ if (ret == PRIMOSDK_RUNNING)
+ {
+ if (callback)
+ {
+ int abort = callback->OnStatus(cursec, totsec);
+ if (abort)
+ {
+ ret = primo->RunningStatus(PRIMOSDK_ABORT, 0, 0);
+ callback = 0; // cheap way to prevent making further callbacks
+ }
+ }
+ WaitForSingleObject(triggerEvent, 500);
+ }
+ else if (ret == PRIMOSDK_OK)
+ {
+ if (callback)
+ callback->Finished();
+ break;
+ }
+ else
+ break;
+ }
+
+ if (ret != PRIMOSDK_OK)
+ return 1;
+
+ return 0;
+}
+
+#define CBCLASS ISOCreator
+START_DISPATCH;
+CB(ISOCREATOR_OPEN, Open)
+CB(ISOCREATOR_ADDFILE, AddFile)
+CB(ISOCREATOR_ADDFOLDER, AddFolder)
+CB(ISOCREATOR_WRITE, Write)
+VCB(ISOCREATOR_FORCECALLBACK, ForceCallback)
+END_DISPATCH;
+#undef CBCLASS
diff --git a/Src/Plugins/SDK/burner/api.h b/Src/Plugins/SDK/burner/api.h
new file mode 100644
index 00000000..6555c035
--- /dev/null
+++ b/Src/Plugins/SDK/burner/api.h
@@ -0,0 +1,5 @@
+#pragma once
+
+#include <api/service/api_service.h>
+extern api_service *serviceManager;
+#define WASABI_API_SVC serviceManager
diff --git a/Src/Plugins/SDK/burner/burner.rc b/Src/Plugins/SDK/burner/burner.rc
new file mode 100644
index 00000000..a78e00ea
--- /dev/null
+++ b/Src/Plugins/SDK/burner/burner.rc
@@ -0,0 +1,114 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 5,6,4,0
+ PRODUCTVERSION 5,6,4,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904e4"
+ BEGIN
+ VALUE "CompanyName", "Winamp SA"
+ VALUE "FileDescription", "Winamp 5.x System Component"
+ VALUE "FileVersion", "5, 6, 4, 0"
+ VALUE "InternalName", "burner.w5s"
+ VALUE "LegalCopyright", "Copyright © 2005-2014 Winamp SA"
+ VALUE "OriginalFilename", "burner.w5s"
+ VALUE "ProductName", "Winamp CD Rip & Burn Support Service"
+ VALUE "ProductVersion", "5, 6, 4, 0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1252
+ END
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.K.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // English (U.K.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/Src/Plugins/SDK/burner/burner.vcxproj b/Src/Plugins/SDK/burner/burner.vcxproj
new file mode 100644
index 00000000..3f9b5507
--- /dev/null
+++ b/Src/Plugins/SDK/burner/burner.vcxproj
@@ -0,0 +1,270 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>17.0</VCProjectVersion>
+ <ProjectGuid>{7872D4D3-7026-4F1C-9E8A-C469FFD743DF}</ProjectGuid>
+ <RootNamespace>burner</RootNamespace>
+ <Keyword>Win32Proj</Keyword>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>17.0.32708.82</_ProjectFileVersion>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ <LinkIncremental>false</LinkIncremental>
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ <LinkIncremental>false</LinkIncremental>
+ <GenerateManifest>true</GenerateManifest>
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <GenerateManifest>true</GenerateManifest>
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg">
+ <VcpkgEnabled>false</VcpkgEnabled>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <VcpkgConfiguration>Debug</VcpkgConfiguration>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..;..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;BURNER_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
+ <PrecompiledHeader />
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention />
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..;..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;BURNER_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MinSpace</Optimization>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..;..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;BURNER_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
+ <PrecompiledHeader />
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <IgnoreSpecificDefaultLibraries>msvcprt.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention />
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <Optimization>MinSpace</Optimization>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..;..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;BURNER_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <IgnoreSpecificDefaultLibraries>msvcprt.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="BurnerCommon.cpp" />
+ <ClCompile Include="DataBurner.cpp" />
+ <ClCompile Include="factory_databurner.cpp" />
+ <ClCompile Include="factory_isoburner.cpp" />
+ <ClCompile Include="factory_isocreator.cpp" />
+ <ClCompile Include="ISOBurner.cpp" />
+ <ClCompile Include="ISOCreator.cpp" />
+ <ClCompile Include="main.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="api.h" />
+ <ClInclude Include="BurnerCommon.h" />
+ <ClInclude Include="DataBurner.h" />
+ <ClInclude Include="factory_databurner.h" />
+ <ClInclude Include="factory_isoburner.h" />
+ <ClInclude Include="factory_isocreator.h" />
+ <ClInclude Include="ifc_burner_writecallback.h" />
+ <ClInclude Include="ISOBurner.h" />
+ <ClInclude Include="isocreator.h" />
+ <ClInclude Include="obj_databurner.h" />
+ <ClInclude Include="obj_isoburner.h" />
+ <ClInclude Include="obj_isocreator.h" />
+ <ClInclude Include="resource.h" />
+ <ClInclude Include="veritas.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="burner.rc" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/Src/Plugins/SDK/burner/burner.vcxproj.filters b/Src/Plugins/SDK/burner/burner.vcxproj.filters
new file mode 100644
index 00000000..819e2fc8
--- /dev/null
+++ b/Src/Plugins/SDK/burner/burner.vcxproj.filters
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Data Burner">
+ <UniqueIdentifier>{fc5aff02-d57c-487b-9237-e29174dac75f}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="ISO Burner">
+ <UniqueIdentifier>{f63ae2ba-ac00-4d5e-94fd-c4e25abadcb3}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="ISO Creator">
+ <UniqueIdentifier>{517c3c9f-3204-4b73-89d3-3ecfa2bbec82}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{65bb2e39-9fa9-4f92-ae7a-88829da14f0c}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="BurnerCommon.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="main.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="DataBurner.cpp">
+ <Filter>Data Burner</Filter>
+ </ClCompile>
+ <ClCompile Include="factory_databurner.cpp">
+ <Filter>Data Burner</Filter>
+ </ClCompile>
+ <ClCompile Include="factory_isoburner.cpp">
+ <Filter>ISO Burner</Filter>
+ </ClCompile>
+ <ClCompile Include="ISOBurner.cpp">
+ <Filter>ISO Burner</Filter>
+ </ClCompile>
+ <ClCompile Include="factory_isocreator.cpp">
+ <Filter>ISO Creator</Filter>
+ </ClCompile>
+ <ClCompile Include="ISOCreator.cpp">
+ <Filter>ISO Creator</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="BurnerCommon.h">
+ <Filter>Source Files</Filter>
+ </ClInclude>
+ <ClInclude Include="api.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="ifc_burner_writecallback.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="veritas.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="DataBurner.h">
+ <Filter>Data Burner</Filter>
+ </ClInclude>
+ <ClInclude Include="factory_databurner.h">
+ <Filter>Data Burner</Filter>
+ </ClInclude>
+ <ClInclude Include="obj_databurner.h">
+ <Filter>Data Burner</Filter>
+ </ClInclude>
+ <ClInclude Include="factory_isoburner.h">
+ <Filter>ISO Burner</Filter>
+ </ClInclude>
+ <ClInclude Include="ISOBurner.h">
+ <Filter>ISO Burner</Filter>
+ </ClInclude>
+ <ClInclude Include="obj_isoburner.h">
+ <Filter>ISO Burner</Filter>
+ </ClInclude>
+ <ClInclude Include="factory_isocreator.h">
+ <Filter>ISO Creator</Filter>
+ </ClInclude>
+ <ClInclude Include="isocreator.h">
+ <Filter>ISO Creator</Filter>
+ </ClInclude>
+ <ClInclude Include="obj_isocreator.h">
+ <Filter>ISO Creator</Filter>
+ </ClInclude>
+ <ClInclude Include="resource.h">
+ <Filter>Resource Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="burner.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/Src/Plugins/SDK/burner/factory_databurner.cpp b/Src/Plugins/SDK/burner/factory_databurner.cpp
new file mode 100644
index 00000000..349cdc44
--- /dev/null
+++ b/Src/Plugins/SDK/burner/factory_databurner.cpp
@@ -0,0 +1,71 @@
+#include "api.h"
+#include "factory_databurner.h"
+#include "DataBurner.h"
+
+static const char serviceName[] = "Data Burner";
+
+FOURCC DataBurnerFactory::GetServiceType()
+{
+ return WaSvc::OBJECT;
+}
+
+const char *DataBurnerFactory::GetServiceName()
+{
+ return serviceName;
+}
+
+GUID DataBurnerFactory::GetGUID()
+{
+ return obj_databurnerGUID;
+}
+
+void *DataBurnerFactory::GetInterface(int global_lock)
+{
+ obj_primo *primo=0;
+ waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(obj_primo::getServiceGuid());
+ if (sf) primo = reinterpret_cast<obj_primo *>(sf->getInterface());
+ if (!primo)
+ return 0;
+ DataBurner *creator = new DataBurner(primo);
+ obj_databurner *ifc= static_cast<obj_databurner *>(creator);
+// if (global_lock)
+// WASABI_API_SVC->service_lock(this, (void *)ifc);
+ return ifc;
+}
+
+int DataBurnerFactory::SupportNonLockingInterface()
+{
+ return 1;
+}
+
+int DataBurnerFactory::ReleaseInterface(void *ifc)
+{
+ //WASABI_API_SVC->service_unlock(ifc);
+ obj_databurner *creatorIFC = static_cast<obj_databurner *>(ifc);
+ DataBurner *creator = static_cast<DataBurner *>(creatorIFC);
+ delete creator;
+ return 1;
+}
+
+const char *DataBurnerFactory::GetTestString()
+{
+ return NULL;
+}
+
+int DataBurnerFactory::ServiceNotify(int msg, int param1, int param2)
+{
+ return 1;
+}
+
+#define CBCLASS DataBurnerFactory
+START_DISPATCH;
+CB(WASERVICEFACTORY_GETSERVICETYPE, GetServiceType)
+CB(WASERVICEFACTORY_GETSERVICENAME, GetServiceName)
+CB(WASERVICEFACTORY_GETGUID, GetGUID)
+CB(WASERVICEFACTORY_GETINTERFACE, GetInterface)
+CB(WASERVICEFACTORY_SUPPORTNONLOCKINGGETINTERFACE, SupportNonLockingInterface)
+CB(WASERVICEFACTORY_RELEASEINTERFACE, ReleaseInterface)
+CB(WASERVICEFACTORY_GETTESTSTRING, GetTestString)
+CB(WASERVICEFACTORY_SERVICENOTIFY, ServiceNotify)
+END_DISPATCH;
+#undef CBCLASS \ No newline at end of file
diff --git a/Src/Plugins/SDK/burner/factory_databurner.h b/Src/Plugins/SDK/burner/factory_databurner.h
new file mode 100644
index 00000000..14d2fd81
--- /dev/null
+++ b/Src/Plugins/SDK/burner/factory_databurner.h
@@ -0,0 +1,23 @@
+#ifndef NULLSOFT_BURNER_FACTORY_DATABURNER_H
+#define NULLSOFT_BURNER_FACTORY_DATABURNER_H
+
+#include <api/service/waservicefactory.h>
+#include <api/service/services.h>
+
+class DataBurnerFactory : public waServiceFactory
+{
+public:
+ FOURCC GetServiceType();
+ const char *GetServiceName();
+ GUID GetGUID();
+ void *GetInterface(int global_lock);
+ int SupportNonLockingInterface();
+ int ReleaseInterface(void *ifc);
+ const char *GetTestString();
+ int ServiceNotify(int msg, int param1, int param2);
+
+protected:
+ RECVS_DISPATCH;
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/SDK/burner/factory_isoburner.cpp b/Src/Plugins/SDK/burner/factory_isoburner.cpp
new file mode 100644
index 00000000..d98a786d
--- /dev/null
+++ b/Src/Plugins/SDK/burner/factory_isoburner.cpp
@@ -0,0 +1,71 @@
+#include "api.h"
+#include "factory_isoburner.h"
+#include "isoburner.h"
+
+static const char serviceName[] = "ISO Burner";
+
+FOURCC ISOBurnerFactory::GetServiceType()
+{
+ return WaSvc::OBJECT;
+}
+
+const char *ISOBurnerFactory::GetServiceName()
+{
+ return serviceName;
+}
+
+GUID ISOBurnerFactory::GetGUID()
+{
+ return obj_isoburnerGUID;
+}
+
+void *ISOBurnerFactory::GetInterface(int global_lock)
+{
+ obj_primo *primo=0;
+ waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(obj_primo::getServiceGuid());
+ if (sf) primo = reinterpret_cast<obj_primo *>(sf->getInterface());
+ if (!primo)
+ return 0;
+ ISOBurner *creator = new ISOBurner(primo);
+ obj_isoburner *ifc= static_cast<obj_isoburner *>(creator);
+ // if (global_lock)
+ // WASABI_API_SVC->service_lock(this, (void *)ifc);
+ return ifc;
+}
+
+int ISOBurnerFactory::SupportNonLockingInterface()
+{
+ return 1;
+}
+
+int ISOBurnerFactory::ReleaseInterface(void *ifc)
+{
+ //WASABI_API_SVC->service_unlock(ifc);
+ obj_isoburner *creatorIFC = static_cast<obj_isoburner *>(ifc);
+ ISOBurner *creator = static_cast<ISOBurner *>(creatorIFC);
+ delete creator;
+ return 1;
+}
+
+const char *ISOBurnerFactory::GetTestString()
+{
+ return NULL;
+}
+
+int ISOBurnerFactory::ServiceNotify(int msg, int param1, int param2)
+{
+ return 1;
+}
+
+#define CBCLASS ISOBurnerFactory
+START_DISPATCH;
+CB(WASERVICEFACTORY_GETSERVICETYPE, GetServiceType)
+CB(WASERVICEFACTORY_GETSERVICENAME, GetServiceName)
+CB(WASERVICEFACTORY_GETGUID, GetGUID)
+CB(WASERVICEFACTORY_GETINTERFACE, GetInterface)
+CB(WASERVICEFACTORY_SUPPORTNONLOCKINGGETINTERFACE, SupportNonLockingInterface)
+CB(WASERVICEFACTORY_RELEASEINTERFACE, ReleaseInterface)
+CB(WASERVICEFACTORY_GETTESTSTRING, GetTestString)
+CB(WASERVICEFACTORY_SERVICENOTIFY, ServiceNotify)
+END_DISPATCH;
+#undef CBCLASS \ No newline at end of file
diff --git a/Src/Plugins/SDK/burner/factory_isoburner.h b/Src/Plugins/SDK/burner/factory_isoburner.h
new file mode 100644
index 00000000..25bf87e6
--- /dev/null
+++ b/Src/Plugins/SDK/burner/factory_isoburner.h
@@ -0,0 +1,23 @@
+#ifndef NULLSOFT_BURNER_FACTORY_ISOBURNER_H
+#define NULLSOFT_BURNER_FACTORY_ISOBURNER_H
+
+#include <api/service/waservicefactory.h>
+#include <api/service/services.h>
+
+class ISOBurnerFactory : public waServiceFactory
+{
+public:
+ FOURCC GetServiceType();
+ const char *GetServiceName();
+ GUID GetGUID();
+ void *GetInterface(int global_lock);
+ int SupportNonLockingInterface();
+ int ReleaseInterface(void *ifc);
+ const char *GetTestString();
+ int ServiceNotify(int msg, int param1, int param2);
+
+protected:
+ RECVS_DISPATCH;
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/SDK/burner/factory_isocreator.cpp b/Src/Plugins/SDK/burner/factory_isocreator.cpp
new file mode 100644
index 00000000..c2584747
--- /dev/null
+++ b/Src/Plugins/SDK/burner/factory_isocreator.cpp
@@ -0,0 +1,72 @@
+#include "api.h"
+#include "factory_isocreator.h"
+#include "isocreator.h"
+
+static const char serviceName[] = "ISO Creator";
+
+FOURCC ISOCreatorFactory::GetServiceType()
+{
+ return WaSvc::OBJECT;
+}
+
+const char *ISOCreatorFactory::GetServiceName()
+{
+ return serviceName;
+}
+
+GUID ISOCreatorFactory::GetGUID()
+{
+ return obj_isocreatorGUID;
+}
+
+void *ISOCreatorFactory::GetInterface(int global_lock)
+{
+ obj_primo *primo=0;
+ waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(obj_primo::getServiceGuid());
+ if (sf) primo = reinterpret_cast<obj_primo *>(sf->getInterface());
+ if (!primo)
+ return 0;
+
+ ISOCreator *creator = new ISOCreator(primo);
+ obj_isocreator *ifc= static_cast<obj_isocreator *>(creator);
+// if (global_lock)
+// WASABI_API_SVC->service_lock(this, (void *)ifc);
+ return ifc;
+}
+
+int ISOCreatorFactory::SupportNonLockingInterface()
+{
+ return 1;
+}
+
+int ISOCreatorFactory::ReleaseInterface(void *ifc)
+{
+ //WASABI_API_SVC->service_unlock(ifc);
+ obj_isocreator *creatorIFC = static_cast<obj_isocreator *>(ifc);
+ ISOCreator *creator = static_cast<ISOCreator *>(creatorIFC);
+ delete creator;
+ return 1;
+}
+
+const char *ISOCreatorFactory::GetTestString()
+{
+ return NULL;
+}
+
+int ISOCreatorFactory::ServiceNotify(int msg, int param1, int param2)
+{
+ return 1;
+}
+
+#define CBCLASS ISOCreatorFactory
+START_DISPATCH;
+CB(WASERVICEFACTORY_GETSERVICETYPE, GetServiceType)
+CB(WASERVICEFACTORY_GETSERVICENAME, GetServiceName)
+CB(WASERVICEFACTORY_GETGUID, GetGUID)
+CB(WASERVICEFACTORY_GETINTERFACE, GetInterface)
+CB(WASERVICEFACTORY_SUPPORTNONLOCKINGGETINTERFACE, SupportNonLockingInterface)
+CB(WASERVICEFACTORY_RELEASEINTERFACE, ReleaseInterface)
+CB(WASERVICEFACTORY_GETTESTSTRING, GetTestString)
+CB(WASERVICEFACTORY_SERVICENOTIFY, ServiceNotify)
+END_DISPATCH;
+#undef CBCLASS \ No newline at end of file
diff --git a/Src/Plugins/SDK/burner/factory_isocreator.h b/Src/Plugins/SDK/burner/factory_isocreator.h
new file mode 100644
index 00000000..35849ce4
--- /dev/null
+++ b/Src/Plugins/SDK/burner/factory_isocreator.h
@@ -0,0 +1,23 @@
+#ifndef NULLSOFT_BURNER_FACTORY_ISOCREATOR_H
+#define NULLSOFT_BURNER_FACTORY_ISOCREATOR_H
+
+#include <api/service/waservicefactory.h>
+#include <api/service/services.h>
+
+class ISOCreatorFactory : public waServiceFactory
+{
+public:
+ FOURCC GetServiceType();
+ const char *GetServiceName();
+ GUID GetGUID();
+ void *GetInterface(int global_lock);
+ int SupportNonLockingInterface();
+ int ReleaseInterface(void *ifc);
+ const char *GetTestString();
+ int ServiceNotify(int msg, int param1, int param2);
+
+protected:
+ RECVS_DISPATCH;
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/SDK/burner/ifc_burner_writecallback.h b/Src/Plugins/SDK/burner/ifc_burner_writecallback.h
new file mode 100644
index 00000000..0eb3aa08
--- /dev/null
+++ b/Src/Plugins/SDK/burner/ifc_burner_writecallback.h
@@ -0,0 +1,33 @@
+#ifndef NULLSOFT_BURNER_IFC_BURNER_WRITECALLBACK_H
+#define NULLSOFT_BURNER_IFC_BURNER_WRITECALLBACK_H
+
+#include <bfc/dispatch.h>
+#include <bfc/platform/types.h>
+
+class ifc_burner_writecallback : public Dispatchable
+{
+protected:
+ ifc_burner_writecallback() {}
+ ~ifc_burner_writecallback() {}
+public:
+ int OnStatus(uint32_t sectorsWritten, uint32_t totalSectors); // return 1 to abort or 0 to continue
+ int Finished();
+ enum
+ {
+ BURNER_WRITECALLBACK_ONSTATUS = 0,
+ BURNER_WRITECALLBACK_FINISHED = 1,
+ };
+};
+
+
+inline int ifc_burner_writecallback::OnStatus(uint32_t sectorsWritten, uint32_t totalSectors)
+{
+ return _call(BURNER_WRITECALLBACK_ONSTATUS, (int)0, sectorsWritten, totalSectors);
+}
+
+inline int ifc_burner_writecallback::Finished()
+{
+ return _call(BURNER_WRITECALLBACK_FINISHED, (int)0);
+}
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/SDK/burner/isocreator.h b/Src/Plugins/SDK/burner/isocreator.h
new file mode 100644
index 00000000..4dd2aa42
--- /dev/null
+++ b/Src/Plugins/SDK/burner/isocreator.h
@@ -0,0 +1,20 @@
+#pragma once
+#include "obj_isocreator.h"
+#include "BurnerCommon.h"
+
+
+class ISOCreator : public obj_isocreator, protected BurnerCommon
+{
+public:
+ ISOCreator(obj_primo *_primo);
+ ~ISOCreator();
+ int Open(const wchar_t *volumeName, int format, int media);
+ int AddFile(const wchar_t *source, const wchar_t *destination);
+ int AddFolder(const wchar_t *folder);
+ int Write(const wchar_t *destination, ifc_burner_writecallback *callback);
+ inline void ForceCallback() { BurnerCommon::TriggerCallback(); }
+
+protected:
+ RECVS_DISPATCH;
+
+}; \ No newline at end of file
diff --git a/Src/Plugins/SDK/burner/main.cpp b/Src/Plugins/SDK/burner/main.cpp
new file mode 100644
index 00000000..6ff0fbe9
--- /dev/null
+++ b/Src/Plugins/SDK/burner/main.cpp
@@ -0,0 +1,55 @@
+#include "api.h"
+#include "../Agave/Component/ifc_wa5component.h"
+#include "factory_isocreator.h"
+#include "factory_isoburner.h"
+#include "factory_databurner.h"
+#include <bfc/platform/export.h>
+
+class WA5_Burner : public ifc_wa5component
+{
+public:
+ void RegisterServices(api_service *service);
+ int RegisterServicesSafeModeOk();
+ void DeregisterServices(api_service *service);
+protected:
+ RECVS_DISPATCH;
+};
+
+ISOCreatorFactory creatorFactory;
+ISOBurnerFactory isoBurnerFactory;
+DataBurnerFactory dataBurnerFactory;
+api_service *WASABI_API_SVC = 0;
+
+void WA5_Burner::RegisterServices(api_service *service)
+{
+ WASABI_API_SVC = service;
+ WASABI_API_SVC->service_register(&creatorFactory);
+ WASABI_API_SVC->service_register(&isoBurnerFactory);
+ WASABI_API_SVC->service_register(&dataBurnerFactory);
+}
+
+int WA5_Burner::RegisterServicesSafeModeOk()
+{
+ return 1;
+}
+
+void WA5_Burner::DeregisterServices(api_service *service)
+{
+ service->service_deregister(&creatorFactory);
+ service->service_deregister(&isoBurnerFactory);
+ service->service_deregister(&dataBurnerFactory);
+}
+
+static WA5_Burner wa5_burner;
+extern "C" DLLEXPORT ifc_wa5component *GetWinamp5SystemComponent()
+{
+ return &wa5_burner;
+}
+
+#define CBCLASS WA5_Burner
+START_DISPATCH;
+VCB(API_WA5COMPONENT_REGISTERSERVICES, RegisterServices)
+CB(15, RegisterServicesSafeModeOk)
+VCB(API_WA5COMPONENT_DEREEGISTERSERVICES, DeregisterServices)
+END_DISPATCH;
+#undef CBCLASS \ No newline at end of file
diff --git a/Src/Plugins/SDK/burner/obj_databurner.h b/Src/Plugins/SDK/burner/obj_databurner.h
new file mode 100644
index 00000000..2f78d5c0
--- /dev/null
+++ b/Src/Plugins/SDK/burner/obj_databurner.h
@@ -0,0 +1,60 @@
+#ifndef NULLSOFT_BURNER_OBJ_DATABURNER_H
+#define NULLSOFT_BURNER_OBJ_DATABURNER_H
+
+#include <bfc/dispatch.h>
+#include <bfc/platform/types.h>
+class ifc_burner_writecallback;
+
+class obj_databurner : public Dispatchable
+{
+protected:
+ obj_databurner() {}
+ ~obj_databurner() {}
+public:
+ int Open(const wchar_t *volumeName, wchar_t driveLetter, int format);
+ int AddFile(const wchar_t *source, const wchar_t *destination);
+ int AddFolder(const wchar_t *folder);
+ int Write(int flags, unsigned int speed, ifc_burner_writecallback *callback);
+ void ForceCallback(); // call this (from another thread) to force the Write() function to call your callback ASAP
+
+ DISPATCH_CODES
+ {
+ DATABURNER_OPEN = 0,
+ DATABURNER_ADDFILE = 1,
+ DATABURNER_ADDFOLDER = 2,
+ DATABURNER_WRITE = 3,
+ DATABURNER_FORCECALLBACK = 4,
+ };
+};
+
+inline int obj_databurner::Open(const wchar_t *volumeName, wchar_t driveLetter, int format)
+{
+ return _call(DATABURNER_OPEN, (int)1, volumeName, driveLetter, format);
+}
+
+inline int obj_databurner::AddFile(const wchar_t *source, const wchar_t *destination)
+{
+ return _call(DATABURNER_ADDFILE, (int)1, source, destination);
+}
+
+inline int obj_databurner::AddFolder(const wchar_t *folder)
+{
+ return _call(DATABURNER_ADDFOLDER, (int)1, folder);
+}
+
+inline int obj_databurner::Write(int flags, unsigned int speed, ifc_burner_writecallback *callback)
+{
+ return _call(DATABURNER_WRITE, (int)1, flags, speed, callback);
+}
+
+inline void obj_databurner::ForceCallback()
+{
+ _voidcall(DATABURNER_FORCECALLBACK);
+}
+
+// {0AF177FF-EC9E-4004-8886-B092879895BC}
+static const GUID obj_databurnerGUID =
+{ 0xaf177ff, 0xec9e, 0x4004, { 0x88, 0x86, 0xb0, 0x92, 0x87, 0x98, 0x95, 0xbc } };
+
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/SDK/burner/obj_isoburner.h b/Src/Plugins/SDK/burner/obj_isoburner.h
new file mode 100644
index 00000000..477f6671
--- /dev/null
+++ b/Src/Plugins/SDK/burner/obj_isoburner.h
@@ -0,0 +1,46 @@
+#ifndef NULLSOFT_BURNER_OBJ_ISOBURNER_H
+#define NULLSOFT_BURNER_OBJ_ISOBURNER_H
+
+#include <bfc/dispatch.h>
+
+class ifc_burner_writecallback;
+class obj_isoburner : public Dispatchable
+{
+protected:
+ obj_isoburner(){}
+ ~obj_isoburner(){}
+public:
+ int Open();
+ int Write(wchar_t driveLetter, const wchar_t *isoFile, int flags, unsigned int speed, ifc_burner_writecallback *callback);
+ void ForceCallback(); // call this (from another thread) to force the Write() function to call your callback ASAP
+
+ DISPATCH_CODES
+ {
+ ISOBURNER_OPEN = 0,
+ ISOBURNER_WRITE = 3,
+ ISOBURNER_FORCECALLBACK = 4,
+ };
+
+};
+
+inline int obj_isoburner::Open()
+{
+ return _call(ISOBURNER_OPEN, (int)1);
+}
+
+inline int obj_isoburner::Write(wchar_t driveLetter, const wchar_t *isoFile, int flags, unsigned int speed, ifc_burner_writecallback *callback)
+{
+ return _call(ISOBURNER_OPEN, (int)1, driveLetter, isoFile, flags, speed, callback);
+}
+
+inline void obj_isoburner::ForceCallback()
+{
+ _voidcall(ISOBURNER_FORCECALLBACK);
+}
+
+// {E3B85A59-E56F-4d2b-8ED2-F02BC4AF8BB5}
+static const GUID obj_isoburnerGUID =
+{ 0xe3b85a59, 0xe56f, 0x4d2b, { 0x8e, 0xd2, 0xf0, 0x2b, 0xc4, 0xaf, 0x8b, 0xb5 } };
+
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/SDK/burner/obj_isocreator.h b/Src/Plugins/SDK/burner/obj_isocreator.h
new file mode 100644
index 00000000..8d1014ca
--- /dev/null
+++ b/Src/Plugins/SDK/burner/obj_isocreator.h
@@ -0,0 +1,70 @@
+#pragma once
+#include <bfc/dispatch.h>
+#include <bfc/platform/types.h>
+class ifc_burner_writecallback;
+
+class obj_isocreator : public Dispatchable
+{
+protected:
+ obj_isocreator(){}
+ ~obj_isocreator(){}
+public:
+ int Open(const wchar_t *volumeName, int format, int media);
+ int AddFile(const wchar_t *source, const wchar_t *destination);
+ int AddFolder(const wchar_t *folder); // AddFile auto-creates the folders. Use AddFolder if you need to create an empty directory
+ int Write(const wchar_t *destination, ifc_burner_writecallback *callback);
+ void ForceCallback(); // call this (from another thread) to force the Write() function to call your callback ASAP
+
+ enum
+ {
+ FORMAT_ISOLEVEL1 = 0x00000100,
+ FORMAT_JOLIET = 0x00000200,
+ FORMAT_UDF = 0x00000400,
+ FORMAT_ISOLEVEL2 = 0x00200000,
+ FORMAT_ISOLEVEL3 = 0x00400000,
+ FORMAT_UDF201 = 0x00100000,
+
+ MEDIA_CD = 0x0,
+ MEDIA_DVD = 0x08000000,
+ };
+
+ enum
+ {
+ ISOCREATOR_OPEN = 0,
+ ISOCREATOR_ADDFILE = 1,
+ ISOCREATOR_ADDFOLDER = 2,
+ ISOCREATOR_WRITE = 3,
+ ISOCREATOR_FORCECALLBACK = 4,
+ };
+
+};
+
+inline int obj_isocreator::Open(const wchar_t *volumeName, int format, int media)
+{
+ return _call(ISOCREATOR_OPEN, (int)1, volumeName, format, media);
+}
+
+inline int obj_isocreator::AddFile(const wchar_t *source, const wchar_t *destination)
+{
+ return _call(ISOCREATOR_ADDFILE, (int)1, source, destination);
+}
+
+inline int obj_isocreator::AddFolder(const wchar_t *folder)
+{
+ return _call(ISOCREATOR_ADDFOLDER, (int)1, folder);
+}
+
+inline int obj_isocreator::Write(const wchar_t *destination, ifc_burner_writecallback *callback)
+{
+ return _call(ISOCREATOR_WRITE, (int)1, destination, callback);
+}
+
+inline void obj_isocreator::ForceCallback()
+{
+ _voidcall(ISOCREATOR_FORCECALLBACK);
+}
+
+// {4F0ED42C-A6C1-4c60-97D1-16D9BD02E461}
+static const GUID obj_isocreatorGUID =
+{ 0x4f0ed42c, 0xa6c1, 0x4c60, { 0x97, 0xd1, 0x16, 0xd9, 0xbd, 0x2, 0xe4, 0x61 } };
+
diff --git a/Src/Plugins/SDK/burner/resource.h b/Src/Plugins/SDK/burner/resource.h
new file mode 100644
index 00000000..9d1284b1
--- /dev/null
+++ b/Src/Plugins/SDK/burner/resource.h
@@ -0,0 +1,14 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by burner.rc
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 101
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1001
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/Src/Plugins/SDK/coverdirectory/CoverDirectory.cpp b/Src/Plugins/SDK/coverdirectory/CoverDirectory.cpp
new file mode 100644
index 00000000..f68be846
--- /dev/null
+++ b/Src/Plugins/SDK/coverdirectory/CoverDirectory.cpp
@@ -0,0 +1,314 @@
+#include "api.h"
+#include "CoverDirectory.h"
+#include <api/service/svcs/svc_imgload.h>
+#include <api/service/waservicefactory.h>
+#include <shlwapi.h>
+#include <strsafe.h>
+
+static void CleanNameForPath(wchar_t *name)
+{
+ while (name && *name)
+ {
+ switch(*name)
+ {
+ case L'?':
+ case L'*':
+ case L'|':
+ *name = L'_';
+ break;
+ case '/':
+ case L'\\':
+ case L':':
+ *name = L'-';
+ break;
+ case L'\"':
+ *name = L'\'';
+ break;
+ case L'<':
+ *name = L'(';
+ break;
+ case L'>': *name = L')';
+ break;
+ }
+ name++;
+ }
+}
+
+/* This is just hardcoded for now - Search the albumart in a cover library dir */
+static bool BuildCoverFilename(const wchar_t *filename, const wchar_t *type, wchar_t path[MAX_PATH], wchar_t mask[MAX_PATH])
+{
+ // TODO: use tagz for this.
+ wchar_t artistname[MAX_PATH]=L"", albumname[MAX_PATH]=L"";
+ // benski> we're abusing short-circuit evaluation in a big way here :)
+ if (((AGAVE_API_METADATA->GetExtendedFileInfo(filename, L"albumartist", artistname, MAX_PATH) && artistname[0])
+ || (AGAVE_API_METADATA->GetExtendedFileInfo(filename, L"artist", artistname, MAX_PATH) && artistname[0]))
+ && AGAVE_API_METADATA->GetExtendedFileInfo(filename, L"album", albumname, MAX_PATH) && albumname[0])
+ {
+ CleanNameForPath(artistname);
+ CleanNameForPath(albumname);
+ StringCchPrintf(mask, MAX_PATH, L"%s - %s.*",artistname, albumname);
+ PathCombine(path, WASABI_API_APP->path_getUserSettingsPath(), L"Cover Library");
+ return true;
+ }
+ return false;
+}
+
+static svc_imageLoader *FindImageLoader(const wchar_t *filespec, waServiceFactory **factory)
+{
+ FOURCC imgload = svc_imageLoader::getServiceType();
+ int n = WASABI_API_SVC->service_getNumServices(imgload);
+ for (int i=0; i<n; i++)
+ {
+ waServiceFactory *sf = WASABI_API_SVC->service_enumService(imgload,i);
+ if (sf)
+ {
+ svc_imageLoader * l = (svc_imageLoader*)sf->getInterface();
+ if (l)
+ {
+ if (l->isMine(filespec))
+ {
+ *factory = sf;
+ return l;
+ }
+ sf->releaseInterface(l);
+ }
+ }
+ }
+ return NULL;
+}
+
+static bool ImageExists(const wchar_t *path, const wchar_t *mask)
+{
+ wchar_t dirmask[MAX_PATH];
+ PathCombineW(dirmask, path, mask);
+ WIN32_FIND_DATAW find;
+ HANDLE hFind = FindFirstFileW(dirmask, &find);
+ if (hFind != INVALID_HANDLE_VALUE)
+ {
+ do
+ {
+ wchar_t fn[MAX_PATH];
+ PathCombine(fn, path, mask);
+ waServiceFactory *factory=0;
+ svc_imageLoader *loader = FindImageLoader(fn, &factory);
+ if (loader)
+ {
+ factory->releaseInterface(loader);
+ FindClose(hFind);
+ return true;
+ }
+
+ }
+ while (FindNextFileW(hFind, &find));
+ FindClose(hFind);
+ }
+ return false;
+}
+
+static bool LoadFile(const wchar_t *filename, void **bits, size_t *len)
+{
+ *len=0;
+ FILE * f = _wfopen(filename,L"rb");
+ if (!f)
+ return false;
+ fseek(f,0,2);
+ *len = ftell(f);
+ if (!*len)
+ {
+ fclose(f);
+ return false;
+ }
+ fseek(f,0,0);
+ void * data = WASABI_API_MEMMGR->sysMalloc(*len);
+ fread(data,*len,1,f);
+ fclose(f);
+ *bits = data;
+ return true;
+}
+
+static bool LoadImageData(const wchar_t *path, const wchar_t *mask, void **bits, size_t *len, wchar_t **mimeType)
+{
+ wchar_t dirmask[MAX_PATH];
+ PathCombineW(dirmask, path, mask);
+ WIN32_FIND_DATAW find;
+ HANDLE hFind = FindFirstFileW(dirmask, &find);
+ if (hFind != INVALID_HANDLE_VALUE)
+ {
+ do
+ {
+ wchar_t fn[MAX_PATH];
+ PathCombine(fn, path, find.cFileName);
+ waServiceFactory *factory=0;
+ svc_imageLoader *loader = FindImageLoader(fn, &factory);
+ if (loader)
+ {
+ factory->releaseInterface(loader);
+ if (LoadFile(fn, bits, len))
+ {
+ const wchar_t *ext = PathFindExtension(fn);
+ if (*ext)
+ {
+ ext++;
+ size_t len = wcslen(ext);
+ *mimeType = (wchar_t *)WASABI_API_MEMMGR->sysMalloc((len + 1) * sizeof(wchar_t));
+ StringCchCopy(*mimeType, len+1, ext);
+ CharLower(*mimeType);
+ }
+ else
+ {
+ *mimeType=0;
+ }
+
+ FindClose(hFind);
+ return true;
+ }
+ }
+
+ }
+ while (FindNextFileW(hFind, &find));
+ FindClose(hFind);
+ }
+ return false;
+}
+
+static bool DeleteImage(const wchar_t *path, const wchar_t *mask)
+{
+ wchar_t dirmask[MAX_PATH];
+ PathCombineW(dirmask, path, mask);
+ WIN32_FIND_DATAW find;
+ HANDLE hFind = FindFirstFileW(dirmask, &find);
+ if (hFind != INVALID_HANDLE_VALUE)
+ {
+ do
+ {
+ wchar_t fn[MAX_PATH];
+ PathCombine(fn, path, mask);
+ waServiceFactory *factory=0;
+ svc_imageLoader *loader = FindImageLoader(fn, &factory);
+ if (loader)
+ {
+ DeleteFile(fn);
+ factory->releaseInterface(loader);
+ }
+ }
+ while (FindNextFileW(hFind, &find));
+ FindClose(hFind);
+ }
+ return false;
+}
+
+bool CoverDirectory::IsMine(const wchar_t *filename)
+{
+ //wchar_t path[MAX_PATH], mask[MAX_PATH];
+ //if (BuildCoverFilename(filename, path, mask) && ImageExists(path, mask))
+ return true;
+ //else
+// return false;
+}
+
+int CoverDirectory::ProviderType()
+{
+ return ALBUMARTPROVIDER_TYPE_DATABASE;
+}
+
+// implementation note: use WASABI_API_MEMMGR to alloc bits and mimetype, so that the recipient can free through that
+int CoverDirectory::GetAlbumArtData(const wchar_t *filename, const wchar_t *type, void **bits, size_t *len, wchar_t **mimeType)
+{
+ wchar_t path[MAX_PATH], mask[MAX_PATH];
+ if (BuildCoverFilename(filename, type, path, mask))
+ {
+ if (LoadImageData(path, mask, bits, len, mimeType))
+ {
+ return ALBUMARTPROVIDER_SUCCESS;
+ }
+ }
+ return ALBUMARTPROVIDER_FAILURE;
+}
+
+int CoverDirectory::SetAlbumArtData(const wchar_t *filename, const wchar_t *type, void *bits, size_t len, const wchar_t *mimeType)
+{
+ // TODO:
+ return ALBUMARTPROVIDER_FAILURE;
+}
+
+int CoverDirectory::DeleteAlbumArt(const wchar_t *filename, const wchar_t *type)
+{
+ wchar_t path[MAX_PATH], mask[MAX_PATH];
+ if (BuildCoverFilename(filename, type, path, mask))
+ {
+ DeleteImage(path, mask);
+ return ALBUMARTPROVIDER_SUCCESS;
+ }
+ return ALBUMARTPROVIDER_FAILURE;
+}
+
+#define CBCLASS CoverDirectory
+START_DISPATCH;
+CB(SVC_ALBUMARTPROVIDER_PROVIDERTYPE, ProviderType);
+CB(SVC_ALBUMARTPROVIDER_GETALBUMARTDATA, GetAlbumArtData);
+CB(SVC_ALBUMARTPROVIDER_ISMINE, IsMine);
+CB(SVC_ALBUMARTPROVIDER_SETALBUMARTDATA, SetAlbumArtData);
+CB(SVC_ALBUMARTPROVIDER_DELETEALBUMART, DeleteAlbumArt);
+END_DISPATCH;
+#undef CBCLASS
+
+static CoverDirectory albumArtProvider;
+
+// {725084AC-DBAD-4f7b-98FA-478AE20B9517}
+static const GUID coverDirectoryGUID =
+{ 0x725084ac, 0xdbad, 0x4f7b, { 0x98, 0xfa, 0x47, 0x8a, 0xe2, 0xb, 0x95, 0x17 } };
+
+
+FOURCC AlbumArtFactory::GetServiceType()
+{
+ return svc_albumArtProvider::SERVICETYPE;
+}
+
+const char *AlbumArtFactory::GetServiceName()
+{
+ return "Cover Directory";
+}
+
+GUID AlbumArtFactory::GetGUID()
+{
+ return coverDirectoryGUID;
+}
+
+void *AlbumArtFactory::GetInterface(int global_lock)
+{
+ return &albumArtProvider;
+}
+
+int AlbumArtFactory::SupportNonLockingInterface()
+{
+ return 1;
+}
+
+int AlbumArtFactory::ReleaseInterface(void *ifc)
+{
+ //WASABI_API_SVC->service_unlock(ifc);
+ return 1;
+}
+
+const char *AlbumArtFactory::GetTestString()
+{
+ return 0;
+}
+
+int AlbumArtFactory::ServiceNotify(int msg, int param1, int param2)
+{
+ return 1;
+}
+
+#define CBCLASS AlbumArtFactory
+START_DISPATCH;
+CB(WASERVICEFACTORY_GETSERVICETYPE, GetServiceType)
+CB(WASERVICEFACTORY_GETSERVICENAME, GetServiceName)
+CB(WASERVICEFACTORY_GETGUID, GetGUID)
+CB(WASERVICEFACTORY_GETINTERFACE, GetInterface)
+CB(WASERVICEFACTORY_SUPPORTNONLOCKINGGETINTERFACE, SupportNonLockingInterface)
+CB(WASERVICEFACTORY_RELEASEINTERFACE, ReleaseInterface)
+CB(WASERVICEFACTORY_GETTESTSTRING, GetTestString)
+CB(WASERVICEFACTORY_SERVICENOTIFY, ServiceNotify)
+END_DISPATCH;
+#undef CBCLASS
diff --git a/Src/Plugins/SDK/coverdirectory/CoverDirectory.h b/Src/Plugins/SDK/coverdirectory/CoverDirectory.h
new file mode 100644
index 00000000..14a98759
--- /dev/null
+++ b/Src/Plugins/SDK/coverdirectory/CoverDirectory.h
@@ -0,0 +1,36 @@
+#ifndef NULLSOFT_COVERDIRECTORY_COVERDIRECTORY_H
+#define NULLSOFT_COVERDIRECTORY_COVERDIRECTORY_H
+
+#include "../Agave/AlbumArt/svc_albumArtProvider.h"
+#include <api/service/waservicefactory.h>
+
+class CoverDirectory : public svc_albumArtProvider
+{
+public:
+ bool IsMine(const wchar_t *filename);
+ int ProviderType();
+ // implementation note: use WASABI_API_MEMMGR to alloc bits and mimetype, so that the recipient can free through that
+ int GetAlbumArtData(const wchar_t *filename, const wchar_t *type, void **bits, size_t *len, wchar_t **mimeType);
+ int SetAlbumArtData(const wchar_t *filename, const wchar_t *type, void *bits, size_t len, const wchar_t *mimeType);
+ int DeleteAlbumArt(const wchar_t *filename, const wchar_t *type);
+protected:
+ RECVS_DISPATCH;
+};
+
+class AlbumArtFactory : public waServiceFactory
+{
+public:
+ FOURCC GetServiceType();
+ const char *GetServiceName();
+ GUID GetGUID();
+ void *GetInterface(int global_lock);
+ int SupportNonLockingInterface();
+ int ReleaseInterface(void *ifc);
+ const char *GetTestString();
+ int ServiceNotify(int msg, int param1, int param2);
+
+protected:
+ RECVS_DISPATCH;
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/SDK/coverdirectory/api.h b/Src/Plugins/SDK/coverdirectory/api.h
new file mode 100644
index 00000000..2e14ada9
--- /dev/null
+++ b/Src/Plugins/SDK/coverdirectory/api.h
@@ -0,0 +1,23 @@
+#ifndef NULLSOFT_COVERDIRECTORY_API_H
+#define NULLSOFT_COVERDIRECTORY_API_H
+
+#include <api/service/api_service.h>
+extern api_service *serviceManager;
+#define WASABI_API_SVC serviceManager
+
+#include <api/application/api_application.h>
+#define WASABI_API_APP applicationApi
+
+#include "../Agave/Config/api_config.h"
+extern api_config *config;
+#define AGAVE_API_CONFIG config
+
+#include <api/memmgr/api_memmgr.h>
+extern api_memmgr *memmgr;
+#define WASABI_API_MEMMGR memmgr
+
+#include "../Agave/Metadata/api_metadata.h"
+extern api_metadata *metadataApi;
+#define AGAVE_API_METADATA metadataApi
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/SDK/coverdirectory/cover_directory.vcxproj b/Src/Plugins/SDK/coverdirectory/cover_directory.vcxproj
new file mode 100644
index 00000000..df78ead4
--- /dev/null
+++ b/Src/Plugins/SDK/coverdirectory/cover_directory.vcxproj
@@ -0,0 +1,235 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectName>coverdirectory</ProjectName>
+ <ProjectGuid>{9B95B360-E6C8-4478-BFF7-A698FA57CFDA}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>16.0.32629.160</_ProjectFileVersion>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ <LinkIncremental>false</LinkIncremental>
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ <TargetExt>.w5s</TargetExt>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ <TargetExt>.w5s</TargetExt>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ <LinkIncremental>false</LinkIncremental>
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ <TargetExt>.w5s</TargetExt>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ <TargetExt>.w5s</TargetExt>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg">
+ <VcpkgEnabled>false</VcpkgEnabled>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <VcpkgConfiguration>Debug</VcpkgConfiguration>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..;..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;COVER_DIRECTORY_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader />
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..;..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;COVER_DIRECTORY_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MinSpace</Optimization>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..;..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;COVER_DIRECTORY_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
+ <PrecompiledHeader />
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <IgnoreSpecificDefaultLibraries>msvcprt.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <Optimization>MinSpace</Optimization>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..;..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;COVER_DIRECTORY_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <IgnoreSpecificDefaultLibraries>msvcprt.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="CoverDirectory.cpp" />
+ <ClCompile Include="main.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="api.h" />
+ <ClInclude Include="CoverDirectory.h" />
+ <ClInclude Include="resource.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="coverdirectory.rc" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/Src/Plugins/SDK/coverdirectory/cover_directory.vcxproj.filters b/Src/Plugins/SDK/coverdirectory/cover_directory.vcxproj.filters
new file mode 100644
index 00000000..226c3fa1
--- /dev/null
+++ b/Src/Plugins/SDK/coverdirectory/cover_directory.vcxproj.filters
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="CoverDirectory.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="main.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="api.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="CoverDirectory.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="resource.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="coverdirectory.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/Src/Plugins/SDK/coverdirectory/coverdirectory.rc b/Src/Plugins/SDK/coverdirectory/coverdirectory.rc
new file mode 100644
index 00000000..fcff7711
--- /dev/null
+++ b/Src/Plugins/SDK/coverdirectory/coverdirectory.rc
@@ -0,0 +1,76 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.K.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "#include ""version.rc2""\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // English (U.K.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#include "version.rc2"
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/Src/Plugins/SDK/coverdirectory/coverdirectory.sln b/Src/Plugins/SDK/coverdirectory/coverdirectory.sln
new file mode 100644
index 00000000..f12a106d
--- /dev/null
+++ b/Src/Plugins/SDK/coverdirectory/coverdirectory.sln
@@ -0,0 +1,24 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.32630.194
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "coverdirectory", "cover_directory.vcxproj", "{9B95B360-E6C8-4478-BFF7-A698FA57CFDA}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x86 = Debug|x86
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {9B95B360-E6C8-4478-BFF7-A698FA57CFDA}.Debug|x86.ActiveCfg = Debug|Win32
+ {9B95B360-E6C8-4478-BFF7-A698FA57CFDA}.Debug|x86.Build.0 = Debug|Win32
+ {9B95B360-E6C8-4478-BFF7-A698FA57CFDA}.Release|x86.ActiveCfg = Release|Win32
+ {9B95B360-E6C8-4478-BFF7-A698FA57CFDA}.Release|x86.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {B322BBBE-1422-476D-8065-34799153DD08}
+ EndGlobalSection
+EndGlobal
diff --git a/Src/Plugins/SDK/coverdirectory/main.cpp b/Src/Plugins/SDK/coverdirectory/main.cpp
new file mode 100644
index 00000000..87b65c3a
--- /dev/null
+++ b/Src/Plugins/SDK/coverdirectory/main.cpp
@@ -0,0 +1,83 @@
+#include "api.h"
+#include "../Agave/Component/ifc_wa5component.h"
+#include "CoverDirectory.h"
+
+class CoverDirectoryComponent : public ifc_wa5component
+{
+public:
+ void RegisterServices(api_service *service);
+ void DeregisterServices(api_service *service);
+protected:
+ RECVS_DISPATCH;
+};
+
+api_service *WASABI_API_SVC=0;
+api_application *WASABI_API_APP =0;
+api_config *AGAVE_API_CONFIG = 0;
+api_memmgr *WASABI_API_MEMMGR=0;
+api_metadata *AGAVE_API_METADATA = 0;
+static AlbumArtFactory albumArtFactory;
+
+template <class api_T>
+void ServiceBuild(api_T *&api_t, GUID factoryGUID_t)
+{
+ if (WASABI_API_SVC)
+ {
+ waServiceFactory *factory = WASABI_API_SVC->service_getServiceByGuid(factoryGUID_t);
+ if (factory)
+ api_t = (api_T *)factory->getInterface();
+ }
+}
+
+template <class api_T>
+void ServiceRelease(api_T *api_t, GUID factoryGUID_t)
+{
+ if (WASABI_API_SVC)
+ {
+ waServiceFactory *factory = WASABI_API_SVC->service_getServiceByGuid(factoryGUID_t);
+ if (factory)
+ factory->releaseInterface(api_t);
+ }
+ api_t = NULL;
+}
+
+void CoverDirectoryComponent::RegisterServices(api_service *service)
+{
+ WASABI_API_SVC = service;
+ ServiceBuild(WASABI_API_APP, applicationApiServiceGuid);
+ ServiceBuild(AGAVE_API_CONFIG, AgaveConfigGUID);
+ ServiceBuild(WASABI_API_MEMMGR, memMgrApiServiceGuid);
+ ServiceBuild(AGAVE_API_METADATA, api_metadataGUID);
+ WASABI_API_SVC->service_register(&albumArtFactory);
+ /* uncomment if we need it
+ WASABI_API_LNG = GetService<api_language>(languageApiGUID);
+ // need to have this initialised before we try to do anything with localisation features
+ WASABI_API_START_LANG(hModule,playlistLangGUID);
+ */
+}
+
+void CoverDirectoryComponent::DeregisterServices(api_service *service)
+{
+ ServiceRelease(WASABI_API_APP, applicationApiServiceGuid);
+ ServiceRelease(AGAVE_API_CONFIG, AgaveConfigGUID);
+ ServiceRelease(WASABI_API_MEMMGR, memMgrApiServiceGuid);
+ ServiceRelease(AGAVE_API_METADATA, api_metadataGUID);
+ WASABI_API_SVC->service_deregister(&albumArtFactory);
+ /* uncomment if we need it
+ ReleaseService(languageApiGUID, WASABI_API_LNG);
+ */
+}
+
+static CoverDirectoryComponent coverDirectoryComponent;
+
+extern "C" __declspec(dllexport) ifc_wa5component *GetWinamp5SystemComponent()
+{
+ return &coverDirectoryComponent;
+}
+
+#define CBCLASS CoverDirectoryComponent
+START_DISPATCH;
+VCB(API_WA5COMPONENT_REGISTERSERVICES, RegisterServices)
+VCB(API_WA5COMPONENT_DEREEGISTERSERVICES, DeregisterServices)
+END_DISPATCH;
+#undef CBCLASS
diff --git a/Src/Plugins/SDK/coverdirectory/resource.h b/Src/Plugins/SDK/coverdirectory/resource.h
new file mode 100644
index 00000000..f50760f2
--- /dev/null
+++ b/Src/Plugins/SDK/coverdirectory/resource.h
@@ -0,0 +1,14 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by coverdirectory.rc
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 101
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1001
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/Src/Plugins/SDK/coverdirectory/version.rc2 b/Src/Plugins/SDK/coverdirectory/version.rc2
new file mode 100644
index 00000000..fb8f143d
--- /dev/null
+++ b/Src/Plugins/SDK/coverdirectory/version.rc2
@@ -0,0 +1,39 @@
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+#include "..\..\..\Winamp\buildType.h"
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION WINAMP_PRODUCTVER
+ PRODUCTVERSION WINAMP_PRODUCTVER
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", "Winamp SA"
+ VALUE "FileDescription", "Winamp 5.x System Component"
+ VALUE "FileVersion", STR_WINAMP_PRODUCTVER
+ VALUE "InternalName", "coverdirectory.w5s"
+ VALUE "LegalCopyright", "Copyright © 2005-2023 Winamp SA"
+ VALUE "LegalTrademarks", "Nullsoft and Winamp are trademarks of Winamp SA"
+ VALUE "OriginalFilename", "coverdirectory.w5s"
+ VALUE "ProductName", "Winamp Cover Directory Service"
+ VALUE "ProductVersion", STR_WINAMP_PRODUCTVER
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/Src/Plugins/SDK/dsp_test/RESOURCE.H b/Src/Plugins/SDK/dsp_test/RESOURCE.H
new file mode 100644
index 00000000..a9f020ac
--- /dev/null
+++ b/Src/Plugins/SDK/dsp_test/RESOURCE.H
@@ -0,0 +1,18 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by Script1.rc
+//
+#define IDD_DIALOG1 101
+#define IDC_BOOGA 102
+#define IDC_SLIDER1 1000
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 104
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1001
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/Src/Plugins/SDK/dsp_test/SCRIPT1.RC b/Src/Plugins/SDK/dsp_test/SCRIPT1.RC
new file mode 100644
index 00000000..159d286a
--- /dev/null
+++ b/Src/Plugins/SDK/dsp_test/SCRIPT1.RC
@@ -0,0 +1,97 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_DIALOG1 DIALOGEX 0, 0, 28, 138
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION
+EXSTYLE WS_EX_TOOLWINDOW
+CAPTION "Tempo"
+FONT 8, "MS Sans Serif"
+BEGIN
+ CONTROL "Slider1",IDC_SLIDER1,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_VERT | WS_TABSTOP,3,0,20,128
+ LTEXT "100%",IDC_BOOGA,3,127,21,8
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE
+BEGIN
+ IDD_DIALOG1, DIALOG
+ BEGIN
+ RIGHTMARGIN, 21
+ BOTTOMMARGIN, 12
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/Src/Plugins/SDK/dsp_test/dsp_ns.txt b/Src/Plugins/SDK/dsp_test/dsp_ns.txt
new file mode 100644
index 00000000..b9a7332d
--- /dev/null
+++ b/Src/Plugins/SDK/dsp_test/dsp_ns.txt
@@ -0,0 +1,23 @@
+Nullsoft DSP Effects Plug-in 0.35 for Winamp
+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+
+This plug-in lets you use the following effects on
+your sound in Winamp:
+
+Echo: adds a simple echo effect to the music
+Voice Removal: only for Stereo sounds, this attempts
+ to remove the center channel. Sounds pretty good on
+ about 1% of music out there, the other 99% sounds
+ like crap :)
+Pitch/Tempo control: ownage :)
+
+Once you install this nugget, fire up Winamp, open
+up the preferences (CTRL+P), go to the Plugins/DSP&Effect
+section, and select 'Nullsoft DSP Effects' as
+the new DPS Plug-in. You can then select from the three
+above effects.
+
+Limitations:
+ This plug-in only effects audio that is 16 bit.
+ Note that this plug-in won't work with passive plug-ins
+ such as CD audio.
diff --git a/Src/Plugins/SDK/dsp_test/dsp_test.c b/Src/Plugins/SDK/dsp_test/dsp_test.c
new file mode 100644
index 00000000..1c9fa37f
--- /dev/null
+++ b/Src/Plugins/SDK/dsp_test/dsp_test.c
@@ -0,0 +1,478 @@
+// Winamp test dsp library 0.9 for Winamp 2
+// Copyright (C) 1997, Justin Frankel/Nullsoft
+// Feel free to base any plugins on this "framework"...
+
+#include <windows.h>
+#include <commctrl.h>
+#include <math.h>
+#include "../Winamp/dsp.h"
+#include "resource.h"
+
+// avoid stupid CRT silliness
+//BOOL WINAPI _DllMainCRTStartup(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
+//{
+// return TRUE;
+//}
+
+
+// pitch value
+int g_pitch=100;
+
+// pitch control window
+HWND pitch_control_hwnd;
+
+// auxilary pitch buffer (for resampling from)
+short *pitch_buffer=NULL;
+int pitch_buffer_len=0;
+int quit_pitch=0;
+
+// module getter.
+winampDSPModule *getModule(int which);
+
+void config(struct winampDSPModule *this_mod);
+int init(struct winampDSPModule *this_mod);
+int initpitch(struct winampDSPModule *this_mod);
+void quit(struct winampDSPModule *this_mod);
+void quitpitch(struct winampDSPModule *this_mod);
+int modify_samples1(struct winampDSPModule *this_mod, short int *samples, int numsamples, int bps, int nch, int srate);
+int modify_samples2(struct winampDSPModule *this_mod, short int *samples, int numsamples, int bps, int nch, int srate);
+int modify_samples3(struct winampDSPModule *this_mod, short int *samples, int numsamples, int bps, int nch, int srate);
+int modify_samples_lopass(struct winampDSPModule *this_mod, short int *samples, int numsamples, int bps, int nch, int srate);
+int modify_samples_hipass(struct winampDSPModule *this_mod, short int *samples, int numsamples, int bps, int nch, int srate);
+
+static INT_PTR CALLBACK pitchProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam);
+
+// Module header, includes version, description, and address of the module retriever function
+typedef struct {
+ int version; // DSP_HDRVER
+ char *description; // description of library
+ winampDSPModule* (*getModule)(int); // module retrieval function
+ int (*sf)(int);
+} winampDSPHeaderEx;
+
+int sf(int v)
+{
+ int res;
+ res = v * (unsigned long)1103515245;
+ res += (unsigned long)13293;
+ res &= (unsigned long)0x7FFFFFFF;
+ res ^= v;
+ return res;
+}
+
+winampDSPHeaderEx hdr = { DSP_HDRVER+1, "Nullsoft DSP v0.35 for Winamp 2ARG", getModule, sf };
+
+
+// first module
+winampDSPModule mod =
+{
+ "Nullsoft Echo v0.2",
+ NULL, // hwndParent
+ NULL, // hDllInstance
+ config,
+ init,
+ modify_samples1,
+ quit
+};
+
+
+// second module
+winampDSPModule mod2 =
+{
+ "Nullsoft Stereo Voice Removal v0.2",
+ NULL, // hwndParent
+ NULL, // hDllInstance
+ config,
+ init,
+ modify_samples2,
+ quit
+};
+
+winampDSPModule mod3 =
+{
+ "Nullsoft Pitch/Tempo Control v0.2",
+ NULL, // hwndParent
+ NULL, // hDllInstance
+ config,
+ initpitch,
+ modify_samples3,
+ quitpitch
+};
+
+winampDSPModule mod4 =
+{
+ "Nullsoft Lowpass Filter v1.0",
+ NULL, // hwndParent
+ NULL, // hDllInstance
+ config,
+ init,
+ modify_samples_lopass,
+ quit
+};
+winampDSPModule mod5 =
+{
+ "Nullsoft Highpass Filter v1.0",
+ NULL, // hwndParent
+ NULL, // hDllInstance
+ config,
+ init,
+ modify_samples_hipass,
+ quit
+};
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+// this is the only exported symbol. returns our main header.
+__declspec( dllexport ) winampDSPHeaderEx *winampDSPGetHeader2()
+{
+ return &hdr;
+}
+#ifdef __cplusplus
+}
+#endif
+
+// getmodule routine from the main header. Returns NULL if an invalid module was requested,
+// otherwise returns either mod1 or mod2 depending on 'which'.
+winampDSPModule *getModule(int which)
+{
+ switch (which)
+ {
+ case 0: return &mod;
+ case 1: return &mod2;
+ case 2: return &mod3;
+// case 3: return &mod4;
+// case 4: return &mod5;
+ default:return NULL;
+ }
+}
+
+// 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 winampDSPModule *this_mod)
+{
+ MessageBox(this_mod->hwndParent,"This module is Copyright(C) 1997-1999, Nullsoft\n"
+ "Notes:\n"
+ " * 8 bit samples aren't supported.\n"
+ " * Pitch control rules!\n"
+ " * Voice removal sucks (works about 10% of the time)!\n"
+ " * Echo isn't very good!\n"
+ "etc... this is really just a test of the new\n"
+ "DSP plug-in system. Nothing more.",
+ "Configuration",MB_OK);
+}
+
+int init(struct winampDSPModule *this_mod)
+{
+ return 0;
+}
+int initpitch(struct winampDSPModule *this_mod)
+{
+ pitch_buffer_len=0;
+ pitch_buffer=NULL;
+ quit_pitch=0;
+ ShowWindow((pitch_control_hwnd=CreateDialog(this_mod->hDllInstance,MAKEINTRESOURCE(IDD_DIALOG1),this_mod->hwndParent,pitchProc)),SW_SHOW);
+ return 0;
+}
+
+// cleanup (opposite of init()). Destroys the window, unregisters the window class
+void quit(struct winampDSPModule *this_mod)
+{
+}
+
+void quitpitch(struct winampDSPModule *this_mod)
+{
+ if (this_mod == &mod3)
+ {
+ if (pitch_buffer) GlobalFree(pitch_buffer);
+ pitch_buffer_len=0;
+ pitch_buffer=NULL;
+ quit_pitch=1;
+ if (pitch_control_hwnd)
+ {
+ DestroyWindow(pitch_control_hwnd);
+ pitch_control_hwnd=0;
+ }
+
+ }
+}
+
+short echo_buf[65536], echo_buf2[65536];
+
+int modify_samples1(struct winampDSPModule *this_mod, short int *samples, int numsamples, int bps, int nch, int srate)
+{
+ // echo doesn't support 8 bit right now cause I'm lazy.
+ if (bps==16)
+ {
+ int x,s;
+ s = numsamples*nch;
+
+ memcpy(echo_buf2, echo_buf, s*2);
+ memcpy(echo_buf, echo_buf+s, s*2);
+ memcpy(echo_buf+s, echo_buf+s*2, s*2);
+ memcpy(echo_buf+s*2,echo_buf+s*3, s*2);
+ memcpy(echo_buf+s*3,samples, s*2);
+
+ for (x = 0; x < s; x ++)
+ {
+ int s = samples[x]/2+echo_buf2[x]/2;
+ samples[x] = (s>32767?32767:s<-32768?-32768:s);
+ }
+ }
+ return numsamples;
+}
+
+int modify_samples3(struct winampDSPModule *this_mod, short int *samples, int numsamples, int bps, int nch, int srate)
+{
+ int pitch=g_pitch;
+ int rlen =numsamples*bps/8*nch;
+ int index=0, x;
+ int n;
+ int dindex;
+ if (quit_pitch || g_pitch==100) return numsamples;
+ if (g_pitch > 200) g_pitch=200;
+ if (g_pitch < 50) g_pitch=50;
+ pitch = 100000/pitch;
+ n=(numsamples*pitch)/1000;
+ dindex=(numsamples<<11)/n;
+ if (pitch_buffer_len < rlen)
+ {
+ pitch_buffer_len = rlen;
+ GlobalFree(pitch_buffer);
+ pitch_buffer=GlobalAlloc(GMEM_FIXED,rlen);
+ }
+ if (bps == 16 && nch == 2)
+ {
+ short *buf=pitch_buffer;
+ memcpy(buf,samples,rlen);
+ for (x = 0; x < n; x ++)
+ {
+ int p=(index>>11)<<1;
+ index+=dindex;
+ samples[0] = buf[p];
+ samples[1] = buf[p+1];
+ samples+=2;
+ }
+ return n;
+ }
+ else if (bps == 16 && nch == 1)
+ {
+ short *buf=pitch_buffer;
+ memcpy(buf,samples,rlen);
+ for (x = 0; x < n; x ++)
+ {
+ int p=(index>>11);
+ index+=dindex;
+ *samples++ = buf[p];
+ }
+ return n;
+ }
+ return numsamples;
+}
+
+
+int modify_samples2(struct winampDSPModule *this_mod, short int *samples, int numsamples, int bps, int nch, int srate)
+{
+ int x = numsamples;
+ if (bps == 16)
+ {
+ short *a = samples;
+ if (nch == 2) while (x--)
+ {
+ int l, r;
+ l = a[1]-a[0];
+ r = a[0]-a[1];
+ if (l < -32768) l = -32768;
+ if (l > 32767) l = 32767;
+ if (r < -32768) r = -32768;
+ if (r > 32767) r = 32767;
+ a[0] = l;
+ a[1] = r;
+ a+=2;
+ }
+ }
+ return numsamples;
+}
+
+/*
+int modify_samples_lopass(struct winampDSPModule *this_mod, short int *samples, int numsamples, int bps, int nch, int srate)
+{
+ if (bps==16)
+ {
+ static int lastspl=0,lastspl2=0;
+ int x;
+ x=numsamples;
+ if (nch==1) while (x--)
+ {
+ int thisspl=*samples;
+ *samples++=(lastspl+thisspl)/2;
+ lastspl=thisspl;
+ }
+ else if (nch == 2) while (x--)
+ {
+ int thisspl=*samples;
+ *samples++=(lastspl+thisspl)/2;
+ lastspl=thisspl;
+ thisspl=*samples;
+ *samples++=(lastspl2+thisspl)/2;
+ lastspl2=thisspl;
+ }
+ }
+ return numsamples;
+}
+*/
+
+
+enum FILTER_TYPE {
+ lowpass,highpass,bandpass
+};
+
+typedef struct
+{
+ float m_a0,m_a1;
+ float m_b0,m_b1,m_b2;
+ float m_d1,m_d2;
+ float m_k;
+} filter;
+
+float Filter(filter *f, const float x )
+{
+ float d0,y;
+
+ d0 = f->m_k*x - f->m_a1*f->m_d1 - f->m_a0*f->m_d2;
+ y = d0*f->m_b2 + f->m_d1*f->m_b1 + f->m_d2*f->m_b0;
+ f->m_d2 = f->m_d1;
+ f->m_d1 = d0;
+
+ return y;
+}
+
+
+void makefilter( filter *f, int t , float sample_rate , float cutoff , float dampening )
+{
+ float a2,c;
+
+ c = (float)( 1.f / tan( 3.14159265359*cutoff / sample_rate ) );
+ a2 = 1.f + c*(c+dampening);
+
+ f->m_a1 = 2.f * (1.f - c*c) / a2;
+ f->m_a0 = (1.f + c*(c-dampening)) / a2;
+ f->m_d1 = f->m_d2 = 0.f;
+
+ switch( t )
+ {
+ case lowpass:
+ f->m_k = 1.f / a2;
+ f->m_b1 = 2.f;
+ f->m_b0 = 1.f;
+ break;
+
+ case highpass:
+ f->m_k = c*c / a2;
+ f->m_b1 = -2.f;
+ f->m_b0 = 1.f;
+ break;
+
+ case bandpass:
+ f->m_k = c*dampening / a2;
+ f->m_b1 = 0.f;
+ f->m_b0 = -1.f;
+ break;
+ }
+ f->m_b2 = 1.f;
+}
+
+int modify_samples_lopass(struct winampDSPModule *this_mod, short int *samples, int numsamples, int bps, int nch, int srate)
+{
+ static int i;
+ static filter f1,f2;
+ if (!i)
+ {
+ i=1;
+ makefilter(&f1,bandpass,44100,1000.0,0.5);
+ makefilter(&f2,lowpass,44100,1.0,1.0);
+ }
+ if (bps==16)
+ {
+ int x;
+ x=numsamples;
+ if (nch == 2) while (x--)
+ {
+ int t=(int)Filter(&f1,*samples);
+ *samples++=min(max(t,-32768),32767);
+ t=(int)Filter(&f2,*samples);
+ *samples++=min(max(t,-32768),32767);
+ }
+ }
+ return numsamples;
+}
+
+#define mulspl(a,b) _mulspl((int)(a),(int)((b)*65536.0))
+
+int _mulspl(int a, int b)
+{
+ a *= b;
+ a >>= 16;
+ return a;
+}
+
+
+int modify_samples_hipass(struct winampDSPModule *this_mod, short int *samples, int numsamples, int bps, int nch, int srate)
+{
+ if (bps==16 && nch==2)
+ {
+ static short splbuf[32768+2];
+ short int *spls=splbuf+nch;
+ int x;
+ memcpy(spls,samples,numsamples*sizeof(short)*nch);
+ x=numsamples;
+ while (x--)
+ {
+ int ch;
+ for (ch = 0; ch < nch; ch ++)
+ {
+ int r=mulspl(spls[0],0.93) + mulspl(spls[-nch],-0.93) + mulspl(samples[-nch],0.86);
+ samples[0] = max(min(r,32767),-32768);
+ spls++;
+ samples++;
+ }
+ }
+ memcpy(splbuf,&splbuf[numsamples*nch],nch*sizeof(short));
+ }
+ return numsamples;
+}
+
+
+static BOOL CALLBACK pitchProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ if (uMsg == WM_INITDIALOG)
+ {
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMAX,0,50);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMIN,0,-50);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETPOS,1,1);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETPOS,1,0);
+ {
+ char str[123];
+ wsprintf(str,"%s%d%%",g_pitch>=100?"+":"",g_pitch-100);
+ SetDlgItemText(hwndDlg,IDC_BOOGA,str);
+ }
+ }
+ if (uMsg == WM_VSCROLL)
+ {
+ HWND swnd = (HWND) lParam;
+ if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER1))
+ {
+ g_pitch = -SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_GETPOS,0,0)+100;
+ {
+ char str[123];
+ wsprintf(str,"%s%d%%",g_pitch>=100?"+":"",g_pitch-100);
+ SetDlgItemText(hwndDlg,IDC_BOOGA,str);
+ }
+ }
+ }
+ return 0;
+}
+
+
diff --git a/Src/Plugins/SDK/dsp_test/dsp_test.sln b/Src/Plugins/SDK/dsp_test/dsp_test.sln
new file mode 100644
index 00000000..d502d889
--- /dev/null
+++ b/Src/Plugins/SDK/dsp_test/dsp_test.sln
@@ -0,0 +1,24 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.32802.440
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dsp_test", "dsp_test.vcxproj", "{91476D06-BDDF-4BD1-B855-AB2DC03A41C3}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x86 = Debug|x86
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {91476D06-BDDF-4BD1-B855-AB2DC03A41C3}.Debug|x86.ActiveCfg = Debug|Win32
+ {91476D06-BDDF-4BD1-B855-AB2DC03A41C3}.Debug|x86.Build.0 = Debug|Win32
+ {91476D06-BDDF-4BD1-B855-AB2DC03A41C3}.Release|x86.ActiveCfg = Release|Win32
+ {91476D06-BDDF-4BD1-B855-AB2DC03A41C3}.Release|x86.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {8AA64C58-B209-477B-8EDE-709FDFD0E5C5}
+ EndGlobalSection
+EndGlobal
diff --git a/Src/Plugins/SDK/dsp_test/dsp_test.vcxproj b/Src/Plugins/SDK/dsp_test/dsp_test.vcxproj
new file mode 100644
index 00000000..a3ecc7f1
--- /dev/null
+++ b/Src/Plugins/SDK/dsp_test/dsp_test.vcxproj
@@ -0,0 +1,227 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{91476D06-BDDF-4BD1-B855-AB2DC03A41C3}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>16.0.32629.160</_ProjectFileVersion>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ <LinkIncremental>false</LinkIncremental>
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ <LinkIncremental>false</LinkIncremental>
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg">
+ <VcpkgEnabled>false</VcpkgEnabled>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <VcpkgConfiguration>Debug</VcpkgConfiguration>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;DSP_TEST_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
+ <PrecompiledHeader />
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <AdditionalIncludeDirectories>..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;DSP_TEST_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <AdditionalIncludeDirectories>..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <OmitFramePointers>true</OmitFramePointers>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;DSP_TEST_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
+ <PrecompiledHeader />
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <AdditionalIncludeDirectories>..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <OmitFramePointers>true</OmitFramePointers>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;DSP_TEST_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <AdditionalIncludeDirectories>..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="dsp_test.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="RESOURCE.H" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="SCRIPT1.RC" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/Src/Plugins/SDK/dsp_test/dsp_test.vcxproj.filters b/Src/Plugins/SDK/dsp_test/dsp_test.vcxproj.filters
new file mode 100644
index 00000000..f1efa308
--- /dev/null
+++ b/Src/Plugins/SDK/dsp_test/dsp_test.vcxproj.filters
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="dsp_test.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="RESOURCE.H">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="SCRIPT1.RC">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/Src/Plugins/SDK/gen_classicart/api.h b/Src/Plugins/SDK/gen_classicart/api.h
new file mode 100644
index 00000000..993ee0cf
--- /dev/null
+++ b/Src/Plugins/SDK/gen_classicart/api.h
@@ -0,0 +1,24 @@
+#ifndef NULLSOFT_API_H
+#define NULLSOFT_API_H
+
+#include <api/service/api_service.h>
+extern api_service *serviceManager;
+#define WASABI_API_SVC serviceManager
+
+#include <api/service/waServiceFactory.h>
+
+#include <api/application/api_application.h>
+#define WASABI_API_APP applicationApi
+
+#include <api/memmgr/api_memmgr.h>
+extern api_memmgr *memmgrApi;
+#define WASABI_API_MEMMGR memmgrApi
+
+#include <api/service/svcs/svc_imgload.h>
+#include <api/service/svcs/svc_imgwrite.h>
+
+#include "../Agave/AlbumArt/api_albumart.h"
+
+#include "../Agave/Language/api_language.h"
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/SDK/gen_classicart/build_lng.cmd b/Src/Plugins/SDK/gen_classicart/build_lng.cmd
new file mode 100644
index 00000000..f4d9e656
--- /dev/null
+++ b/Src/Plugins/SDK/gen_classicart/build_lng.cmd
@@ -0,0 +1,3 @@
+@echo off
+lng_generator "x86_Release\gen_classicart.dll" /build
+pause
diff --git a/Src/Plugins/SDK/gen_classicart/gen_classicart.cpp b/Src/Plugins/SDK/gen_classicart/gen_classicart.cpp
new file mode 100644
index 00000000..98c988a6
--- /dev/null
+++ b/Src/Plugins/SDK/gen_classicart/gen_classicart.cpp
@@ -0,0 +1,935 @@
+/* gen_classicart
+ version 0.5, February 7th, 2010
+ version 0.4, February 4th, 2010
+ version 0.3, November 9th, 2009
+ version 0.2, February 27th, 2008
+
+ Copyright (C) 2008 Will Fisher
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Will Fisher will.fisher@gmail.com
+
+ ---------------------------------------------------------------------------
+
+ Changes from v0.2 by Darren Owen aka DrO
+
+ * Added Alt+A global shortcut to toggle the album art window
+ * Album art window is now included in Winamp's ctrl+tab feature (broken in some 5.5x builds)
+ * Double-click will now open the folder (like the native album art window does)
+ * Changing menu id to be dynamic rather than hard-coded to show use of IPC_REGISTER_LOWORD_COMMAND
+ * Made background colour match the media library album art views (override with waBkClr=1 in the plugin's ini section)
+ * Made compatible to deal with Winamp being minimised on startup so the window won't appear briefly
+ * Implemented winampUninstallPlugin(..) support
+
+ ---------------------------------------------------------------------------
+
+ Changes from v0.3 by Darren Owen aka DrO
+
+ * Added localisation support (with example en-us language file included in the installer)
+ * Adding an option to show the album art when clicking on an item in the playlist editor without having to play it
+ * Fixed the main menu item not working via the system menu
+ * Plugin will now only work on 5.53+ clients to ensure the Alt+A global shortcut will work (bug-fix for v0.3)
+ * Fixed issue with api.h not containing all of the required headers (only affects compiling source code)
+
+ ---------------------------------------------------------------------------
+
+ Changes from v0.4 by Darren Owen aka DrO
+
+ * Added detection of being used under a modern skin so the album art window and menu item can be automatically hidden (default: on)
+ * Added in ability for the tracking action to work via the keyboard actions along with button clicking
+ * Tweaked the menu item text so the items (at least with en-us translations) is better consistant with the rest of Winamp (if that's possible, heh)
+ * Added config menu into the Winamp preferences so it's possible to access the options when the album art window isn't shown
+
+*/
+
+#include <windows.h>
+#include <shlwapi.h>
+#include <strsafe.h>
+
+#include "../winamp/gen.h"
+#include "../winamp/wa_ipc.h"
+#include "../winamp/ipc_pe.h"
+#define WA_DLG_IMPLEMENT
+#include "../winamp/wa_dlg.h"
+
+#include "api.h"
+#include "resource.h"
+
+#define ID_PE_SCUP 40289
+#define ID_PE_SCDOWN 40290
+
+#define PLUGIN_NAME "Album Art Viewer"
+#define PLUGIN_VERSION "0.6"
+
+int init();
+void quit();
+void config();
+
+winampGeneralPurposePlugin plugin =
+{
+ GPPHDR_VER,
+ "nullsoft(gen_classicart.dll)",
+ init,
+ config,
+ quit,
+};
+
+// winampGeneralPurposePlugin plugin = {GPPHDR_VER,PLUGIN_NAME" v"PLUGIN_VERSION,init,config,quit};
+
+static api_memmgr* WASABI_API_MEMMGR;
+static api_service* WASABI_API_SVC;
+static api_albumart* AGAVE_API_ALBUMART;
+static api_application* WASABI_API_APP;
+static api_language* WASABI_API_LNG;
+HINSTANCE WASABI_API_LNG_HINST = 0,
+ WASABI_API_ORIG_HINST = 0;
+
+embedWindowState myWndState={0};
+HWND myWnd=NULL,
+ myWndChild=NULL;
+HMENU menu=NULL,
+ context_menu=NULL;
+WNDPROC oldWndProc=NULL,
+ oldPlaylistWndProc=NULL;
+BOOL no_uninstall=TRUE,
+ modernloaded=FALSE,
+ last_artwindow_open=FALSE;
+int artwindow_open=0,
+ lockAspect=1,
+ autoHide=0,
+ waBkClr=0,
+ on_click=0,
+ clickTrack=0,
+ hidemodern=1;
+UINT WINAMP_ARTVIEW_MENUID=0xa1ba;
+char* INI_FILE=NULL;
+RECT lastWnd={0};
+HDC cacheDC = NULL;
+COLORREF bgcolour = RGB(0,0,0);
+
+static INT_PTR CALLBACK art_dlgproc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+static LRESULT WINAPI SubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+static LRESULT WINAPI SubclassPlaylistProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+
+void viewArtWindow(BOOL show);
+void addAccelerators(HWND hwnd, ACCEL* accel, int accel_size, int translate_mode);
+
+// this is used to identify the skinned frame to allow for embedding/control by modern skins if needed
+// {8B9052B2-2782-4ac8-BA8E-E3DEDBF0BDB5}
+static const GUID ArtViewerGUID =
+{ 0x8b9052b2, 0x2782, 0x4ac8, { 0xba, 0x8e, 0xe3, 0xde, 0xdb, 0xf0, 0xbd, 0xb5 } };
+
+// this is used to identify the language dll to be used when this is running under a language pack
+// {EAD1E933-6D75-4c2c-B9C4-B4D7F06B7D8D}
+static const GUID GenClassicArtGUID =
+{ 0xead1e933, 0x6d75, 0x4c2c, { 0xb9, 0xc4, 0xb4, 0xd7, 0xf0, 0x6b, 0x7d, 0x8d } };
+
+BOOL ArtView_SetMinimised(BOOL fMinimized)
+{
+ if(fMinimized == TRUE)
+ {
+ return SetPropW(myWnd,L"AAMinMode",(HANDLE)TRUE);
+ }
+ RemovePropW(myWnd,L"AAMinMode");
+ return TRUE;
+}
+
+UINT ver = -1;
+UINT GetWinampVersion(HWND winamp)
+{
+ if(ver == -1)
+ {
+ return (ver = SendMessage(winamp,WM_WA_IPC,0,IPC_GETVERSION));
+ }
+ return ver;
+}
+
+template <class api_T>
+void ServiceBuild(api_T *&api_t, GUID factoryGUID_t){
+ if (WASABI_API_SVC){
+ waServiceFactory *factory = WASABI_API_SVC->service_getServiceByGuid(factoryGUID_t);
+ if (factory){
+ api_t = (api_T *)factory->getInterface();
+ }
+ }
+}
+
+BOOL DetectModernSkinLoaded(void)
+{
+ wchar_t skindir[MAX_PATH]={0};
+ SendMessage(plugin.hwndParent,WM_WA_IPC,(WPARAM)skindir,IPC_GETSKINW);
+ StringCchCat(skindir,MAX_PATH,L"\\skin.xml");
+ return PathFileExists(skindir);
+}
+
+void InsertItemIntoMainMenu(void){
+ MENUITEMINFO i = {sizeof(i), MIIM_ID | MIIM_STATE | MIIM_TYPE, MFT_STRING, MFS_UNCHECKED, WINAMP_ARTVIEW_MENUID};
+ i.dwTypeData = WASABI_API_LNGSTRINGW(IDS_ALBUM_ART_MENU);
+ InsertMenuItem(menu, 10 + (int)SendMessage(plugin.hwndParent,WM_WA_IPC,(WPARAM)0,IPC_ADJUST_OPTIONSMENUPOS), TRUE, &i);
+ SendMessage(plugin.hwndParent,WM_WA_IPC,(WPARAM)1,IPC_ADJUST_OPTIONSMENUPOS);
+}
+
+int init()
+{
+ if(GetWinampVersion(plugin.hwndParent) < 0x5053)
+ {
+ // this is due to the api_application dependancy to allow for registering a hotkey correctly
+ MessageBoxA(plugin.hwndParent,"This plug-in requires Winamp v5.9 and up for it to work.\t\n"
+ "Please upgrade your Winamp client to be able to use this.",
+ plugin.description,MB_OK|MB_ICONINFORMATION);
+ return GEN_INIT_FAILURE;
+ }
+ else
+ {
+ WASABI_API_SVC = (api_service*)SendMessage(plugin.hwndParent, WM_WA_IPC, 0, IPC_GET_API_SERVICE);
+ if(WASABI_API_SVC != NULL)
+ {
+ INI_FILE = (char*)SendMessage(plugin.hwndParent,WM_WA_IPC,0,IPC_GETINIFILE);
+
+ ServiceBuild(WASABI_API_MEMMGR,memMgrApiServiceGuid);
+ if(WASABI_API_MEMMGR == NULL) return 1;
+
+ ServiceBuild(AGAVE_API_ALBUMART,albumArtGUID);
+ if(AGAVE_API_ALBUMART == NULL) return 1;
+
+ ServiceBuild(WASABI_API_APP,applicationApiServiceGuid);
+ if(WASABI_API_APP == NULL) return 1;
+
+ ServiceBuild(WASABI_API_LNG,languageApiGUID);
+ if(WASABI_API_LNG == NULL) return 1;
+
+ WASABI_API_START_LANG(plugin.hDllInstance,GenClassicArtGUID);
+
+ static char pluginTitle[MAX_PATH] = {0};
+ StringCchPrintfA(pluginTitle, MAX_PATH, WASABI_API_LNGSTRING(IDS_PLUGIN_NAME), PLUGIN_VERSION);
+ plugin.description = pluginTitle;
+
+ WADlg_init(plugin.hwndParent);
+
+ // subclass main window
+ oldWndProc = (WNDPROC)SetWindowLongPtrW(plugin.hwndParent, GWLP_WNDPROC, (LONG_PTR)SubclassProc);
+ oldPlaylistWndProc = (WNDPROC)SetWindowLongPtrW((HWND)SendMessage(plugin.hwndParent,WM_WA_IPC,IPC_GETWND_PE,IPC_GETWND),
+ GWLP_WNDPROC, (LONG_PTR)SubclassPlaylistProc);
+
+ // do this dynamically (if on an older client then we'd need to check for a return of 1 and set an arbitrary default)
+ WINAMP_ARTVIEW_MENUID = SendMessage(plugin.hwndParent,WM_WA_IPC,0,IPC_REGISTER_LOWORD_COMMAND);
+
+ // add our menu option
+ menu = (HMENU)SendMessage(plugin.hwndParent,WM_WA_IPC,(WPARAM)0,IPC_GET_HMENU);
+ if(hidemodern){
+ if(!DetectModernSkinLoaded())
+ {
+ InsertItemIntoMainMenu();
+ }
+ else
+ {
+ modernloaded=TRUE;
+ }
+ }
+ else
+ {
+ InsertItemIntoMainMenu();
+ }
+
+ // load values from ini file
+ lockAspect = GetPrivateProfileIntA("gen_classicart","wnd_lock_aspect",lockAspect,INI_FILE);
+ myWndState.r.top = GetPrivateProfileIntA("gen_classicart","wnd_top",0,INI_FILE);
+ myWndState.r.bottom = GetPrivateProfileIntA("gen_classicart","wnd_bottom",0,INI_FILE);
+ myWndState.r.left = GetPrivateProfileIntA("gen_classicart","wnd_left",0,INI_FILE);
+ myWndState.r.right = GetPrivateProfileIntA("gen_classicart","wnd_right",0,INI_FILE);
+ artwindow_open = GetPrivateProfileIntA("gen_classicart","wnd_open",artwindow_open,INI_FILE);
+ autoHide = GetPrivateProfileIntA("gen_classicart","wnd_auto_hide",autoHide,INI_FILE);
+ waBkClr = GetPrivateProfileIntA("gen_classicart","waBkClr",waBkClr,INI_FILE);
+ clickTrack = GetPrivateProfileIntA("gen_classicart","clickTrack",clickTrack,INI_FILE);
+ hidemodern = GetPrivateProfileIntA("gen_classicart","hidemodern",hidemodern,INI_FILE);
+ last_artwindow_open = GetPrivateProfileIntA("gen_classicart","wnd_open_last",last_artwindow_open,INI_FILE);
+
+ // create window
+ myWndState.flags = EMBED_FLAGS_NOWINDOWMENU;
+ myWnd = (HWND)SendMessage(plugin.hwndParent,WM_WA_IPC,(WPARAM)&myWndState,IPC_GET_EMBEDIF);
+ WASABI_API_APP->app_registerGlobalWindow(myWnd);
+ myWndChild = WASABI_API_CREATEDIALOGW(IDD_DIALOG,myWnd,art_dlgproc);
+
+ SET_EMBED_GUID((&myWndState),ArtViewerGUID);
+ SetWindowText(myWnd,WASABI_API_LNGSTRINGW(IDS_ALBUM_ART));
+
+ if(SendMessage(plugin.hwndParent,WM_WA_IPC,0,IPC_INITIAL_SHOW_STATE) == SW_SHOWMINIMIZED && artwindow_open)
+ {
+ // we are starting minimised so process as needed (keep our window hidden)
+ MENUITEMINFO i = {sizeof(i), MIIM_STATE , MFT_STRING, MFS_UNCHECKED, WINAMP_ARTVIEW_MENUID};
+ SetMenuItemInfo(menu, WINAMP_ARTVIEW_MENUID, FALSE, &i);
+ ArtView_SetMinimised(TRUE);
+ }
+ else
+ {
+ if(artwindow_open) viewArtWindow(TRUE);
+ }
+
+ // not working correctly at the moment
+ ACCEL accel = {FVIRTKEY|FALT,'A',WINAMP_ARTVIEW_MENUID};
+ addAccelerators(myWndChild,&accel,1,TRANSLATE_MODE_GLOBAL);
+
+ context_menu = WASABI_API_LOADMENUW(IDR_MENU1);
+ return GEN_INIT_SUCCESS;
+ }
+ }
+ return GEN_INIT_FAILURE;
+}
+
+void quit()
+{
+ if(no_uninstall)
+ {
+ // save window state
+ #define WritePrivateProfileInt(key, val) \
+ { \
+ char zzval[10] = {0}; \
+ StringCchPrintfA(zzval,10,"%d",val); \
+ WritePrivateProfileStringA("gen_classicart",key,zzval,INI_FILE); \
+ }
+
+ GetWindowRect(myWnd,&myWndState.r);
+ WritePrivateProfileInt("wnd_top",myWndState.r.top);
+ WritePrivateProfileInt("wnd_bottom",myWndState.r.bottom);
+ WritePrivateProfileInt("wnd_left",myWndState.r.left);
+ WritePrivateProfileInt("wnd_right",myWndState.r.right);
+ WritePrivateProfileInt("wnd_open",artwindow_open);
+ WritePrivateProfileInt("wnd_lock_aspect",lockAspect);
+ WritePrivateProfileInt("wnd_auto_hide",autoHide);
+ WritePrivateProfileInt("clickTrack",clickTrack);
+ WritePrivateProfileInt("hidemodern",hidemodern);
+ // reset the state so if we're using a classic skin then it'll work if the window is disabled
+ if(modernloaded==FALSE) last_artwindow_open = artwindow_open;
+ WritePrivateProfileInt("wnd_open_last",last_artwindow_open);
+ }
+
+ WASABI_API_APP->app_unregisterGlobalWindow(myWnd);
+ ArtView_SetMinimised(FALSE);
+ DestroyWindow(myWnd);
+ WADlg_close();
+
+ // restores the original winamp window proc now that we are closing and if the window was subclassed
+ if(GetWindowLongPtr(plugin.hwndParent,GWLP_WNDPROC) == (LONG_PTR)SubclassProc){
+ SetWindowLongPtr(plugin.hwndParent,GWLP_WNDPROC,(LONG_PTR)oldWndProc);
+ }
+
+ // restores the original playlist window proc now that we are closing and if the window was subclassed
+ HWND pe_wnd = (HWND)SendMessage(plugin.hwndParent,WM_WA_IPC,IPC_GETWND_PE,IPC_GETWND);
+ if(GetWindowLongPtr(pe_wnd,GWLP_WNDPROC) == (LONG_PTR)SubclassPlaylistProc){
+ SetWindowLongPtr(pe_wnd,GWLP_WNDPROC,(LONG_PTR)oldPlaylistWndProc);
+ }
+}
+
+int config_open = 0;
+void config()
+{
+ /*if(!config_open){
+ char message[256]={0}, tmp[128]={0};
+ config_open = 1;
+ StringCchPrintfA(message,256,WASABI_API_LNGSTRING(IDS_ABOUT_STRING),WASABI_API_LNGSTRING_BUF(IDS_ALBUM_ART,tmp,128));
+ MessageBoxA(0,message,plugin.description,0);
+ config_open = 0;
+ }
+ else{
+ SetActiveWindow(FindWindowA("#32770",plugin.description));
+ }*/
+
+HWND list = FindWindowEx(GetParent(GetFocus()),0,L"ListBox",0);
+HMENU popup = GetSubMenu(WASABI_API_LOADMENUW(IDR_MENU1),0);
+RECT r = {0};
+wchar_t temp[MAX_PATH] = {0};
+
+ DeleteMenu(popup,ID_CONTEXTMENU_GETALBUMART,MF_BYCOMMAND);
+ DeleteMenu(popup,ID_CONTEXTMENU_REFRESH,MF_BYCOMMAND);
+ DeleteMenu(popup,ID_CONTEXTMENU_OPENFOLDER,MF_BYCOMMAND);
+
+ MENUITEMINFO i = {sizeof(i),MIIM_ID|MIIM_STATE|MIIM_TYPE,MFT_STRING,MFS_UNCHECKED|MFS_DISABLED,1};
+ StringCchPrintf(temp,MAX_PATH,WASABI_API_LNGSTRINGW(IDS_PLUGIN_NAME),TEXT(PLUGIN_VERSION));
+ i.dwTypeData = temp;
+ InsertMenuItem(popup, 0, TRUE, &i);
+
+ i.wID=2;
+ i.fState=0;
+ i.fType=MFT_SEPARATOR;
+ InsertMenuItem(popup, -1, TRUE, &i);
+
+ i.dwTypeData = WASABI_API_LNGSTRINGW(IDS_ABOUT);
+ i.wID=4;
+ i.fType=MFT_STRING;
+ InsertMenuItem(popup, -1, TRUE, &i);
+
+ SendMessage(list,LB_GETITEMRECT,SendMessage(list,LB_GETCURSEL,1,0),(LPARAM)&r);
+ ClientToScreen(list,(LPPOINT)&r);
+
+ CheckMenuItem(popup,ID_CONTEXTMENU_LOCKASPECTRATIO,(lockAspect?MF_CHECKED:MF_UNCHECKED)|MF_BYCOMMAND);
+ CheckMenuItem(popup,ID_CONTEXTMENU_AUTOHIDE,(autoHide?MF_CHECKED:MF_UNCHECKED)|MF_BYCOMMAND);
+ CheckMenuItem(popup,ID_CONTEXTMENU_CLICKTRACK,(clickTrack?MF_CHECKED:MF_UNCHECKED)|MF_BYCOMMAND);
+ CheckMenuItem(popup,ID_CONTEXTMENU_AUTO_HIDE_MODERN,(hidemodern?MF_CHECKED:MF_UNCHECKED)|MF_BYCOMMAND);
+
+ switch(TrackPopupMenu(popup,TPM_RETURNCMD|TPM_LEFTBUTTON,r.left,r.top,0,list,NULL)){
+ case 4:
+ {
+ char message[256]={0}, tmp[128]={0};
+ StringCchPrintfA(message,256,WASABI_API_LNGSTRING(IDS_ABOUT_STRING),WASABI_API_LNGSTRING_BUF(IDS_ALBUM_ART,tmp,128));
+ MessageBoxA(list,message,plugin.description,0);
+ }
+ break;
+ case ID_CONTEXTMENU_LOCKASPECTRATIO:
+ lockAspect = (!lockAspect);
+ if(cacheDC) DeleteDC(cacheDC); cacheDC = NULL;
+ InvalidateRect(myWndChild,NULL,TRUE);
+ break;
+ case ID_CONTEXTMENU_AUTOHIDE:
+ autoHide = (!autoHide);
+ break;
+ case ID_CONTEXTMENU_CLICKTRACK:
+ clickTrack = (!clickTrack);
+ break;
+ case ID_CONTEXTMENU_AUTO_HIDE_MODERN:
+ hidemodern = (!hidemodern);
+ break;
+ }
+
+ // clean up as we're sharing this menu
+ DestroyMenu(popup);
+}
+
+static LRESULT WINAPI SubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ // handles the item being selected through the main window menu
+ // including via the windows taskbar menu as it'll fail otherwise
+ if((msg == WM_COMMAND || msg == WM_SYSCOMMAND) && LOWORD(wParam) == WINAMP_ARTVIEW_MENUID)
+ {
+ if(artwindow_open) PostMessage(myWndChild,WM_CLOSE,0,0);
+ else PostMessage(myWndChild,WM_USER+1,0,0);
+ }
+
+ else if(msg == WM_WA_IPC)
+ {
+ if(lParam == IPC_CB_MISC && (wParam == IPC_CB_MISC_TITLE || wParam == IPC_CB_MISC_TITLE_RATING))
+ {
+ // art change
+ PostMessage(myWndChild,WM_USER,0,0);
+ }
+ else if(lParam == IPC_SKIN_CHANGED && hidemodern)
+ {
+ // need to check this when doing classic->modern as it causes the pledit to be hidden
+ if(DetectModernSkinLoaded()){
+ if(modernloaded==FALSE){
+ last_artwindow_open = artwindow_open;
+ if(last_artwindow_open==TRUE){
+ PostMessage(myWndChild,WM_CLOSE,0,0);
+ }
+ DeleteMenu(menu,WINAMP_ARTVIEW_MENUID,MF_BYCOMMAND);
+ SendMessage(plugin.hwndParent,WM_WA_IPC,(WPARAM)-1,IPC_ADJUST_OPTIONSMENUPOS);
+ }
+ modernloaded=TRUE;
+ }
+ else{
+ if(modernloaded==TRUE)
+ {
+ InsertItemIntoMainMenu();
+ if(last_artwindow_open==TRUE)
+ {
+ PostMessage(myWndChild,WM_USER+1,0,0);
+ }
+ }
+ modernloaded=FALSE;
+ }
+ }
+ }
+
+ // the purpose of this is show our gen frame window if we started in a minimised state
+ // as showing then hiding will otherwise cause a window to flash briefly on screen
+ else if(msg == WM_SIZE)
+ {
+ if (wParam == SIZE_RESTORED)
+ {
+ if(GetPropW(myWnd,L"AAMinMode"))
+ {
+ ShowWindow(myWnd,SW_SHOWNA);
+ ArtView_SetMinimised(FALSE);
+ }
+ }
+ }
+
+ return CallWindowProc(oldWndProc, hwnd, msg, wParam, lParam);
+}
+
+int IsInPlaylistArea(HWND playlist_wnd, int mode)
+{
+POINT pt = {0};
+RECT rc = {0};
+
+ GetCursorPos(&pt);
+ GetClientRect(playlist_wnd,&rc);
+
+ ScreenToClient(playlist_wnd,&pt);
+ // this corrects so the selection works correctly on the selection boundary
+ pt.y -= 2;
+
+ if(!mode)
+ {
+ // corrects for the window area so it only happens if a selection happens
+ rc.top += 18;
+ rc.left += 12;
+ rc.right -= 19;
+ rc.bottom -= 40;
+ return PtInRect(&rc,pt);
+ }
+ else
+ {
+ rc.bottom -= 13;
+ rc.top = rc.bottom - 19;
+ rc.left += 14;
+
+ for(int i = 0; i < 4; i++)
+ {
+ rc.right = rc.left + 22;
+ if(PtInRect(&rc,pt))
+ {
+ return 1;
+ }
+ else{
+ rc.left = rc.right + 7;
+ }
+ }
+ return 0;
+ }
+}
+
+static LRESULT WINAPI SubclassPlaylistProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ LRESULT ret=0;
+
+ // this will detect false clicks such as when the menus are shown in the classic playlist editor
+ if(msg == WM_LBUTTONDOWN)
+ {
+ if(IsInPlaylistArea(hwnd,1))
+ {
+ on_click = 1;
+ }
+ }
+
+ ret = CallWindowProc(oldPlaylistWndProc, hwnd, msg, wParam, lParam);
+
+ // this will then handle the detection of a proper click in the playlist editor so
+ // if enabled then we can get and show the album art for the selected playlist item
+ if(msg == WM_LBUTTONDOWN && !(GetKeyState(VK_MENU)&0x1000) &&
+ !(GetKeyState(VK_SHIFT)&0x1000) &&
+ !(GetKeyState(VK_CONTROL)&0x1000))
+ {
+ if(!on_click && clickTrack)
+ {
+ POINT pt = {0};
+ INT index = 0;
+ GetCursorPos(&pt);
+ ScreenToClient(hwnd,&pt);
+ // this corrects so the selection works correctly on the selection boundary
+ pt.y -= 2;
+ index = SendMessage(hwnd,WM_WA_IPC,IPC_PE_GETIDXFROMPOINT,(LPARAM)&pt);
+ if(IsInPlaylistArea(hwnd,0))
+ {
+ // bounds check things
+ if(index < SendMessage(hwnd,WM_WA_IPC,IPC_PE_GETINDEXTOTAL,0))
+ {
+ // art change to show the selected item in the playlist editor
+ PostMessage(myWndChild,WM_USER,0,(LPARAM)SendMessage(plugin.hwndParent,WM_WA_IPC,index,IPC_GETPLAYLISTFILEW));
+ }
+ }
+ }
+ else
+ {
+ // needs to do an increment for the next click will be a false
+ if(on_click == 1)
+ {
+ on_click = 2;
+ }
+ else{
+ on_click = 0;
+ }
+ }
+ }
+
+ else if(msg == WM_COMMAND)
+ {
+ // this is used for tracking the selection of items in the playlist editor
+ // so we can update the album art when doing a single up/down selection
+ if((LOWORD(wParam) == ID_PE_SCUP || LOWORD(wParam) == ID_PE_SCDOWN) && clickTrack)
+ {
+ // only do on up/down without any other keyboard accelerators pressed
+ if(!(GetKeyState(VK_MENU)&0x1000) &&
+ !(GetKeyState(VK_SHIFT)&0x1000) &&
+ !(GetKeyState(VK_CONTROL)&0x1000))
+ {
+ if(SendMessage(plugin.hwndParent,WM_WA_IPC,0,IPC_PLAYLIST_GET_SELECTED_COUNT))
+ {
+ int sel = SendMessage(plugin.hwndParent,WM_WA_IPC,-1,IPC_PLAYLIST_GET_NEXT_SELECTED);
+ if(sel != -1)
+ {
+ // art change to show the selected item in the playlist editor
+ PostMessage(myWndChild,WM_USER,0,(LPARAM)SendMessage(plugin.hwndParent,WM_WA_IPC,sel,IPC_GETPLAYLISTFILEW));
+ }
+ }
+ }
+ }
+ }
+
+ return ret;
+}
+
+ARGB32 * loadImg(const void * data, int len, int *w, int *h, bool ldata=false)
+{
+ FOURCC imgload = svc_imageLoader::getServiceType();
+ int n = WASABI_API_SVC->service_getNumServices(imgload);
+ for(int i=0; i<n; i++)
+ {
+ waServiceFactory *sf = WASABI_API_SVC->service_enumService(imgload,i);
+ if(sf)
+ {
+ svc_imageLoader * l = (svc_imageLoader*)sf->getInterface();
+ if(l)
+ {
+ if(l->testData(data,len))
+ {
+ ARGB32* ret;
+ if(ldata) ret = l->loadImageData(data,len,w,h);
+ else ret = l->loadImage(data,len,w,h);
+ sf->releaseInterface(l);
+ return ret;
+ }
+ sf->releaseInterface(l);
+ }
+ }
+ }
+ return NULL;
+}
+
+ARGB32 * loadRrc(int id, wchar_t * sec, int *w, int *h, bool data=false)
+{
+ DWORD size=0;
+ HGLOBAL resourceHandle = WASABI_API_LOADRESFROMFILEW(sec,MAKEINTRESOURCE(id),&size);
+ if(resourceHandle)
+ {
+ ARGB32* ret = loadImg(resourceHandle,size,w,h,data);
+ UnlockResource(resourceHandle);
+ return ret;
+ }
+ return NULL;
+}
+
+void adjustbmp(ARGB32 * p, int len, COLORREF fg)
+{
+ ARGB32 * end = p+len;
+ while (p < end)
+ {
+ int a = (*p>>24)&0xff ;
+ int b = a*((*p&0xff) * (fg&0xff)) / (0xff*0xff);
+ int g = a*(((*p>>8)&0xff) * ((fg>>8)&0xff)) / (0xff*0xff);
+ int r = a*(((*p>>16)&0xff) * ((fg>>16)&0xff)) / (0xff*0xff);
+ *p = (a<<24) | (r&0xff) | ((g&0xff)<<8) | ((b&0xff)<<16);
+ p++;
+ }
+}
+
+void DrawArt(HDC dc, HWND hwndDlg, ARGB32 * cur_image, int cur_w, int cur_h)
+{
+ RECT dst, wnd;
+ GetWindowRect(hwndDlg,&wnd);
+ wnd.right = wnd.right - wnd.left;
+ wnd.left = 0;
+ wnd.bottom = wnd.bottom - wnd.top;
+ wnd.top = 0;
+
+ if(!memcmp(&lastWnd,&wnd,sizeof(RECT)) && cacheDC)
+ {
+ BitBlt(dc,0,0,wnd.right,wnd.bottom,cacheDC,0,0,SRCCOPY);
+ return;
+ }
+
+ // create cacheDC
+ if(cacheDC) DeleteDC(cacheDC);
+ cacheDC = CreateCompatibleDC(dc);
+ HBITMAP hbm = CreateCompatibleBitmap(dc,wnd.right,wnd.bottom);
+ SelectObject(cacheDC,hbm);
+ DeleteObject(hbm);
+ lastWnd = wnd;
+
+ if(!lockAspect) dst = wnd;
+ else
+ {
+ // maintain 'square' stretching, fill in dst
+ double aspX = (double)(wnd.right)/(double)cur_w;
+ double aspY = (double)(wnd.bottom)/(double)cur_h;
+ double asp = min(aspX, aspY);
+ int newW = (int)(cur_w*asp);
+ int newH = (int)(cur_h*asp);
+ dst.left = (wnd.right - newW)/2;
+ dst.top = (wnd.bottom - newH)/2;
+ dst.right = dst.left + newW;
+ dst.bottom = dst.top + newH;
+ }
+
+ // fill the background to black
+ HBRUSH brush = CreateSolidBrush(bgcolour);
+ FillRect(cacheDC,&wnd,brush);
+ DeleteObject(brush);
+
+ //SkinBitmap(cur_image, cur_w, cur_h).stretchToRect(&DCCanvas(cacheDC), &dst);
+ HDC srcDC = CreateCompatibleDC(dc);
+ BITMAPINFO bmi = {0};
+ bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bmi.bmiHeader.biWidth = cur_w;
+ bmi.bmiHeader.biHeight = -cur_h;
+ bmi.bmiHeader.biPlanes = 1;
+ bmi.bmiHeader.biBitCount = 32;
+ bmi.bmiHeader.biCompression = BI_RGB;
+ void *bits = 0;
+ HBITMAP srcBMP = CreateDIBSection(srcDC, &bmi, DIB_RGB_COLORS, &bits, NULL, 0);
+ memcpy(bits, cur_image, cur_w*cur_h*4);
+
+ HBITMAP oldSrcBM = (HBITMAP)SelectObject(srcDC,srcBMP);
+ BLENDFUNCTION blendFn;
+ blendFn.BlendOp = AC_SRC_OVER;
+ blendFn.BlendFlags = 0;
+ blendFn.SourceConstantAlpha = 255;
+ blendFn.AlphaFormat = AC_SRC_ALPHA;
+
+ AlphaBlend(cacheDC,
+ dst.left, dst.top,
+ dst.right-dst.left, dst.bottom-dst.top,
+ srcDC,
+ 0, 0,
+ cur_w, cur_h,
+ blendFn);
+
+ BitBlt(dc,0,0,wnd.right,wnd.bottom,cacheDC,0,0,SRCCOPY);
+ SelectObject(srcDC,oldSrcBM);
+ DeleteObject(srcBMP);
+ DeleteDC(srcDC);
+}
+
+static INT_PTR CALLBACK art_dlgproc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ static ARGB32 * cur_image;
+ static int cur_w, cur_h;
+ static bool closed;
+ switch(msg)
+ {
+ case WM_INITDIALOG:
+ closed = 0;
+ cur_image = 0;
+ bgcolour = WADlg_getColor(WADLG_ITEMBG);
+ PostMessage(hwndDlg,WM_USER,0,0);
+ break;
+ case WM_USER+1:
+ viewArtWindow(TRUE);
+ closed=0;
+ break;
+ case WM_DISPLAYCHANGE:
+ WADlg_init(plugin.hwndParent);
+ bgcolour = WADlg_getColor(WADLG_ITEMBG);
+ case WM_USER:
+ {
+ wchar_t *filename = (!lParam?(wchar_t *)SendMessage(plugin.hwndParent,WM_WA_IPC,0,IPC_GET_PLAYING_FILENAME):(wchar_t*)lParam);
+ if(cur_image) WASABI_API_MEMMGR->sysFree(cur_image); cur_image = 0;
+ if (AGAVE_API_ALBUMART->GetAlbumArt(filename, L"cover", &cur_w, &cur_h, &cur_image) != ALBUMART_SUCCESS)
+ {/*
+ SkinBitmap b(L"winamp.cover.notfound");
+ if(!b.isInvalid())
+ {
+ cur_w = b.getWidth();
+ cur_h = b.getHeight();
+ cur_image = (ARGB32*)WASABI_API_MEMMGR->sysMalloc(cur_w * cur_h * sizeof(ARGB32));
+ memcpy(cur_image,b.getBits(),cur_w * cur_h * sizeof(ARGB32));
+ }
+ else*/
+ {
+ cur_image = loadRrc(IDR_IMAGE_NOTFOUND,L"PNG",&cur_w, &cur_h,true);
+ if(cur_image) adjustbmp(cur_image, cur_w*cur_h, WADlg_getColor(WADLG_ITEMFG));
+ }
+
+ if(!waBkClr) bgcolour = WADlg_getColor(WADLG_ITEMBG);
+ if(autoHide && !closed && msg != WM_DISPLAYCHANGE)
+ viewArtWindow(FALSE);
+ }
+ else
+ {
+ if(waBkClr) bgcolour = RGB(0,0,0);
+ if(autoHide && !closed && msg != WM_DISPLAYCHANGE)
+ viewArtWindow(TRUE);
+ }
+ if(cacheDC) DeleteDC(cacheDC); cacheDC = NULL;
+ InvalidateRect(hwndDlg,NULL,TRUE);
+ }
+ break;
+ case WM_DESTROY:
+ if(cur_image) WASABI_API_MEMMGR->sysFree(cur_image); cur_image = 0;
+ if(cacheDC) DeleteDC(cacheDC); cacheDC = NULL;
+ break;
+ case WM_PAINT:
+ {
+ if (cur_image)
+ {
+ PAINTSTRUCT psPaint={0};
+ HDC dc = BeginPaint(hwndDlg, &psPaint);
+ DrawArt(dc,hwndDlg,cur_image,cur_w,cur_h);
+ EndPaint(hwndDlg, &psPaint);
+ }
+ }
+ break;
+ case WM_ERASEBKGND:
+ {
+ if (cur_image)
+ {
+ HDC dc = (HDC)wParam;
+ DrawArt(dc,hwndDlg,cur_image,cur_w,cur_h);
+ return 1;
+ }
+ }
+ break;
+ case WM_SIZE:
+ if(cacheDC) DeleteDC(cacheDC); cacheDC = NULL;
+ InvalidateRect(hwndDlg,NULL,TRUE);
+ break;
+ case WM_CLOSE:
+ closed=1;
+ viewArtWindow(FALSE);
+ break;
+ case WM_LBUTTONDBLCLK:
+ PostMessage(hwndDlg,WM_COMMAND,MAKEWPARAM(ID_CONTEXTMENU_OPENFOLDER,0),0);
+ break;
+ case WM_RBUTTONDOWN:
+ {
+ HMENU menu = GetSubMenu(context_menu,0);
+ POINT p;
+ GetCursorPos(&p);
+ CheckMenuItem(menu,ID_CONTEXTMENU_LOCKASPECTRATIO,(lockAspect?MF_CHECKED:MF_UNCHECKED)|MF_BYCOMMAND);
+ CheckMenuItem(menu,ID_CONTEXTMENU_AUTOHIDE,(autoHide?MF_CHECKED:MF_UNCHECKED)|MF_BYCOMMAND);
+ CheckMenuItem(menu,ID_CONTEXTMENU_CLICKTRACK,(clickTrack?MF_CHECKED:MF_UNCHECKED)|MF_BYCOMMAND);
+ CheckMenuItem(menu,ID_CONTEXTMENU_AUTO_HIDE_MODERN,(hidemodern?MF_CHECKED:MF_UNCHECKED)|MF_BYCOMMAND);
+ TrackPopupMenu(menu,TPM_RIGHTBUTTON|TPM_LEFTBUTTON|TPM_NONOTIFY,p.x,p.y,0,hwndDlg,NULL);
+ }
+ break;
+ case WM_COMMAND:
+ // this is used when 'Alt+A' is pressed by the user as part of the registered global shortcut
+ if(LOWORD(wParam) == WINAMP_ARTVIEW_MENUID)
+ {
+ if(artwindow_open) PostMessage(myWndChild,WM_CLOSE,0,0);
+ else PostMessage(myWndChild,WM_USER+1,0,0);
+ }
+
+ switch(LOWORD(wParam))
+ {
+ case ID_CONTEXTMENU_GETALBUMART:
+ {
+ wchar_t *filename = (wchar_t *)SendMessage(plugin.hwndParent,WM_WA_IPC,0,IPC_GET_PLAYING_FILENAME);
+ if(filename && *filename)
+ {
+ wchar_t artist[1024],album[1024];
+ extendedFileInfoStructW a = {filename,L"artist",artist,1024};
+ SendMessage(plugin.hwndParent,WM_WA_IPC,(LPARAM)&a,IPC_GET_EXTENDED_FILE_INFOW);
+ a.metadata = L"album";
+ a.ret = album;
+ SendMessage(plugin.hwndParent,WM_WA_IPC,(LPARAM)&a,IPC_GET_EXTENDED_FILE_INFOW);
+ artFetchData d = {sizeof(d),hwndDlg,artist,album,0};
+ int r = (int)SendMessage(plugin.hwndParent,WM_WA_IPC,(LPARAM)&d,IPC_FETCH_ALBUMART);
+ if(r == 0 && d.imgData && d.imgDataLen) // success, save art in correct location
+ {
+ AGAVE_API_ALBUMART->SetAlbumArt(filename,L"cover",0,0,d.imgData,d.imgDataLen,d.type);
+ WASABI_API_MEMMGR->sysFree(d.imgData);
+ SendMessage(hwndDlg,WM_USER,0,0);
+ }
+ }
+ }
+ break;
+ case ID_CONTEXTMENU_LOCKASPECTRATIO:
+ lockAspect = (!lockAspect);
+ if(cacheDC) DeleteDC(cacheDC); cacheDC = NULL;
+ InvalidateRect(hwndDlg,NULL,TRUE);
+ break;
+ case ID_CONTEXTMENU_REFRESH:
+ SendMessage(hwndDlg,WM_USER,0,0);
+ break;
+ case ID_CONTEXTMENU_OPENFOLDER:
+ {
+ wchar_t *filename = (wchar_t *)SendMessage(plugin.hwndParent,WM_WA_IPC,0,IPC_GET_PLAYING_FILENAME);
+ if(filename && *filename)
+ {
+ wchar_t fn[MAX_PATH];
+ lstrcpynW(fn,filename,MAX_PATH);
+ PathRemoveFileSpecW(fn);
+ ShellExecuteW(NULL,L"open",fn,NULL,NULL,SW_SHOW);
+ }
+ }
+ break;
+ case ID_CONTEXTMENU_AUTOHIDE:
+ autoHide = (!autoHide);
+ break;
+ case ID_CONTEXTMENU_CLICKTRACK:
+ clickTrack = (!clickTrack);
+ break;
+ case ID_CONTEXTMENU_AUTO_HIDE_MODERN:
+ hidemodern = (!hidemodern);
+ break;
+ }
+ break;
+ }
+ return 0;
+}
+
+void viewArtWindow(BOOL show)
+{
+ artwindow_open=show;
+ MENUITEMINFO i = {sizeof(i), MIIM_STATE , MFT_STRING, (artwindow_open?MFS_CHECKED:MFS_UNCHECKED), WINAMP_ARTVIEW_MENUID};
+ SetMenuItemInfo(menu, WINAMP_ARTVIEW_MENUID, FALSE, &i);
+ ShowWindow(myWnd,(artwindow_open?SW_SHOW:SW_HIDE));
+}
+
+void addAccelerators(HWND hwnd, ACCEL* accel, int accel_size, int translate_mode)
+{
+ HACCEL hAccel = CreateAcceleratorTable(accel,accel_size);
+ if (hAccel) WASABI_API_APP->app_addAccelerators(hwnd, &hAccel, accel_size, translate_mode);
+}
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ __declspec( dllexport ) winampGeneralPurposePlugin * winampGetGeneralPurposePlugin()
+ {
+ return &plugin;
+ }
+
+ __declspec(dllexport) int winampUninstallPlugin(HINSTANCE hDllInst, HWND hwndDlg, int param)
+ {
+ // prompt to remove our settings with default as no (just incase)
+ if(MessageBoxA(hwndDlg,WASABI_API_LNGSTRING(IDS_DO_YOU_ALSO_WANT_TO_REMOVE_SETTINGS),
+ plugin.description,MB_YESNO|MB_DEFBUTTON2) == IDYES)
+ {
+ WritePrivateProfileStringA("gen_classicart",0,0,INI_FILE);
+ no_uninstall = FALSE;
+ }
+
+ // as we're doing too much in subclasses, etc we cannot allow for on-the-fly removal so need to do a normal reboot
+ return GEN_PLUGIN_UNINSTALL_REBOOT;
+ }
+
+#ifdef __cplusplus
+}
+#endif \ No newline at end of file
diff --git a/Src/Plugins/SDK/gen_classicart/gen_classicart.nsi b/Src/Plugins/SDK/gen_classicart/gen_classicart.nsi
new file mode 100644
index 00000000..c1dc70c1
--- /dev/null
+++ b/Src/Plugins/SDK/gen_classicart/gen_classicart.nsi
@@ -0,0 +1,125 @@
+; waplugin.nsi
+;
+; This script will generate an installer that installs a Winamp 2 plug-in.
+;
+; This installer will automatically alert the user that installation was
+; successful, and ask them whether or not they would like to make the
+; plug-in the default and run Winamp.
+
+;--------------------------------
+
+;Header Files
+
+!include "Sections.nsh"
+!include "WinMessages.nsh"
+
+; common defines for a generic dro installer :o)
+!define VERSION "0.6"
+!define ALT_VER "0_6"
+!define PLUG "Album Art Viewer"
+!define PLUG_ALT "Album_Art_Viewer"
+!define PLUG_FILE "gen_classicart"
+
+; use leet compression
+SetCompressor lzma
+
+; adds xp style support
+XPStyle on
+
+; The name of the installer
+Name "${PLUG} v${VERSION}"
+
+; The file to write
+OutFile "${PLUG_ALT}_v${ALT_VER}.exe"
+
+InstType "Plugin only"
+InstType "Plugin + language file"
+InstType /NOCUSTOM
+InstType /COMPONENTSONLYONCUSTOM
+
+; The default installation directory
+InstallDir $PROGRAMFILES\Winamp
+InstProgressFlags smooth
+
+; detect winamp path from uninstall string if available
+InstallDirRegKey HKLM \
+ "Software\Microsoft\Windows\CurrentVersion\Uninstall\Winamp" \
+ "UninstallString"
+
+; The text to prompt the user to enter a directory
+DirText "Please select your Winamp path below (you will be able to proceed when Winamp is detected):"
+# currently doesn't work - DirShow hide
+
+; automatically close the installer when done.
+AutoCloseWindow true
+
+; hide the "show details" box
+ShowInstDetails show
+
+;--------------------------------
+
+;Pages
+
+PageEx directory
+Caption " "
+PageExEnd
+Page components
+Page instfiles
+
+;--------------------------------
+
+
+; The stuff to install
+Section ""
+ SetOverwrite on
+ SetOutPath "$INSTDIR\Plugins"
+ ; File to extract
+ File "x86_Release\${PLUG_FILE}.dll"
+ SetOverwrite off
+SectionEnd
+
+Section "Example language file"
+; SectionSetFlags 0 SF_BOLD
+ SectionIn 2
+
+ SetOverwrite on
+ SetOutPath "$INSTDIR\Plugins\${PLUG_FILE}"
+ ; File to extract
+ File "x86_Release\LangFiles\${PLUG_FILE}.lng"
+ SetOverwrite off
+SectionEnd
+
+;--------------------------------
+
+Function .onInit
+ ;Detect running Winamp instances and close them
+ !define WINAMP_FILE_EXIT 40001
+
+ FindWindow $R0 "Winamp v1.x"
+ IntCmp $R0 0 ok
+ MessageBox MB_YESNO|MB_ICONEXCLAMATION "Please close all instances of Winamp before installing$\n\
+ ${PLUG} v${VERSION}. Attempt to close Winamp now?" IDYES checkagain IDNO no
+ checkagain:
+ FindWindow $R0 "Winamp v1.x"
+ IntCmp $R0 0 ok
+ SendMessage $R0 ${WM_COMMAND} ${WINAMP_FILE_EXIT} 0
+ Goto checkagain
+ no:
+ Abort
+ ok:
+FunctionEnd
+
+Function .onInstSuccess
+ MessageBox MB_YESNO \
+ '${PLUG} was installed. Do you want to run Winamp now?' \
+ IDNO end
+ ExecShell open "$INSTDIR\Winamp.exe"
+ end:
+FunctionEnd
+
+Function .onVerifyInstDir
+ ;Check for Winamp installation
+ IfFileExists $INSTDIR\Winamp.exe Good
+ Abort
+ Good:
+FunctionEnd \ No newline at end of file
diff --git a/Src/Plugins/SDK/gen_classicart/gen_classicart.rc b/Src/Plugins/SDK/gen_classicart/gen_classicart.rc
new file mode 100644
index 00000000..8aa7b28a
--- /dev/null
+++ b/Src/Plugins/SDK/gen_classicart/gen_classicart.rc
@@ -0,0 +1,156 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.K.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_DIALOG DIALOGEX 0, 0, 187, 95
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN
+EXSTYLE WS_EX_WINDOWEDGE
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_DIALOG, DIALOG
+ BEGIN
+ RIGHTMARGIN, 186
+ BOTTOMMARGIN, 94
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+IDR_MENU1 MENU
+BEGIN
+ POPUP "ContextMenu"
+ BEGIN
+ MENUITEM "Get album art", ID_CONTEXTMENU_GETALBUMART
+ MENUITEM "Refresh album art", ID_CONTEXTMENU_REFRESH
+ MENUITEM "Open folder", ID_CONTEXTMENU_OPENFOLDER
+ MENUITEM SEPARATOR
+ MENUITEM "Lock aspect ratio", ID_CONTEXTMENU_LOCKASPECTRATIO
+ MENUITEM "Auto-hide", ID_CONTEXTMENU_AUTOHIDE
+ MENUITEM "Auto-hide window with modern skins", ID_CONTEXTMENU_AUTO_HIDE_MODERN
+ MENUITEM SEPARATOR
+ MENUITEM "Show album art for selected playlist item", ID_CONTEXTMENU_CLICKTRACK
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// PNG
+//
+
+IDR_IMAGE_NOTFOUND PNG "notfound.png"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE
+BEGIN
+ IDS_PLUGIN_NAME "Album Art v%s"
+ IDS_ALBUM_ART_MENU "Album Art\tAlt+A"
+ IDS_ALBUM_ART "Album Art"
+ IDS_DO_YOU_ALSO_WANT_TO_REMOVE_SETTINGS
+ "Do you also want to remove the saved settings for this plugin?"
+ IDS_ABOUT_STRING "%s\nby Will Fisher, (C) 2008\n\nUpdates by DrO, (C) 2009-2010"
+ IDS_ABOUT "About..."
+END
+
+STRINGTABLE
+BEGIN
+ 65535 "{EAD1E933-6D75-4c2c-B9C4-B4D7F06B7D8D}"
+END
+
+#endif // English (U.K.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/Src/Plugins/SDK/gen_classicart/gen_classicart.sln b/Src/Plugins/SDK/gen_classicart/gen_classicart.sln
new file mode 100644
index 00000000..c4f8e2a4
--- /dev/null
+++ b/Src/Plugins/SDK/gen_classicart/gen_classicart.sln
@@ -0,0 +1,30 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.32630.194
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gen_classicart", "gen_classicart.vcxproj", "{DD15E699-90D2-4301-921A-7C2C48B25766}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x86 = Debug|x86
+ Profiling|x86 = Profiling|x86
+ Release Static|x86 = Release Static|x86
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {DD15E699-90D2-4301-921A-7C2C48B25766}.Debug|x86.ActiveCfg = Debug|Win32
+ {DD15E699-90D2-4301-921A-7C2C48B25766}.Debug|x86.Build.0 = Debug|Win32
+ {DD15E699-90D2-4301-921A-7C2C48B25766}.Profiling|x86.ActiveCfg = Profiling|Win32
+ {DD15E699-90D2-4301-921A-7C2C48B25766}.Profiling|x86.Build.0 = Profiling|Win32
+ {DD15E699-90D2-4301-921A-7C2C48B25766}.Release Static|x86.ActiveCfg = Release|Win32
+ {DD15E699-90D2-4301-921A-7C2C48B25766}.Release Static|x86.Build.0 = Release|Win32
+ {DD15E699-90D2-4301-921A-7C2C48B25766}.Release|x86.ActiveCfg = Release|Win32
+ {DD15E699-90D2-4301-921A-7C2C48B25766}.Release|x86.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {66E16789-5B4D-4040-B006-59B99C861563}
+ EndGlobalSection
+EndGlobal
diff --git a/Src/Plugins/SDK/gen_classicart/gen_classicart.vcxproj b/Src/Plugins/SDK/gen_classicart/gen_classicart.vcxproj
new file mode 100644
index 00000000..ae03d0ca
--- /dev/null
+++ b/Src/Plugins/SDK/gen_classicart/gen_classicart.vcxproj
@@ -0,0 +1,449 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Profiling|Win32">
+ <Configuration>Profiling</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Profiling|x64">
+ <Configuration>Profiling</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectName>gen_classicart</ProjectName>
+ <ProjectGuid>{C3E347A7-B0D5-423B-A124-02936516B2EA}</ProjectGuid>
+ <RootNamespace>gen_classicart</RootNamespace>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profiling|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profiling|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Profiling|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Profiling|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>16.0.32629.160</_ProjectFileVersion>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ <LinkIncremental>false</LinkIncremental>
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ <LinkIncremental>false</LinkIncremental>
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profiling|Win32'">
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ <LinkIncremental>false</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profiling|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg">
+ <VcpkgEnabled>false</VcpkgEnabled>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <VcpkgConfiguration>Debug</VcpkgConfiguration>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..\Wasabi;..\..;..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;_WIN32_WINNT=0x500;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader />
+ <PrecompiledHeaderOutputFile>$(IntDir)$(TagetName).pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>shlwapi.lib;msimg32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ <SubSystem>Windows</SubSystem>
+ </Link>
+ <Midl>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ <TypeLibraryName>$(IntDir)$(TargetName).tlb</TypeLibraryName>
+ <HeaderFileName />
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..\Wasabi;..\..;..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;_WIN32_WINNT=0x500;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <PrecompiledHeaderOutputFile>$(IntDir)$(TagetName).pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(IntDir)$(TagetName).pdb</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>shlwapi.lib;msimg32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TagetName).pdb</ProgramDatabaseFile>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ <SubSystem>Windows</SubSystem>
+ </Link>
+ <Midl>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TypeLibraryName>$(IntDir)$(TargetName).tlb</TypeLibraryName>
+ <HeaderFileName>
+ </HeaderFileName>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MinSpace</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..\Wasabi;..\..;..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;TATAKI_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling />
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
+ <PrecompiledHeader />
+ <PrecompiledHeaderOutputFile>$(IntDir)$(TagetName).pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>shlwapi.lib;msimg32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <BaseAddress>0x12500000</BaseAddress>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ </Link>
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ <TypeLibraryName>$(IntDir)$(TargetName).tlb</TypeLibraryName>
+ <HeaderFileName />
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <Optimization>MinSpace</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..\Wasabi;..\..;..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;TATAKI_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <PrecompiledHeaderOutputFile>$(IntDir)$(TagetName).pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(IntDir)$(TagetName).pdb</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>shlwapi.lib;msimg32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <BaseAddress>0x12500000</BaseAddress>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ <ProgramDatabaseFile>$(IntDir)$(TagetName).pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ </Link>
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TypeLibraryName>$(IntDir)$(TargetName).tlb</TypeLibraryName>
+ <HeaderFileName>
+ </HeaderFileName>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Profiling|Win32'">
+ <ClCompile>
+ <Optimization>MinSpace</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..\Wasabi;..\..;..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling />
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader />
+ <PrecompiledHeaderOutputFile>$(IntDir)$(TagetName).pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(IntDir)$(TagetName).pdb</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>shlwapi.lib;msimg32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <EntryPointSymbol>_DllMainCRTStartup</EntryPointSymbol>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ <ProgramDatabaseFile>$(IntDir)$(TagetName).pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ </Link>
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ <TypeLibraryName>$(IntDir)$(TargetName).tlb</TypeLibraryName>
+ <HeaderFileName />
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Profiling|x64'">
+ <ClCompile>
+ <Optimization>MinSpace</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..\Wasabi;..\..;..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <PrecompiledHeaderOutputFile>$(IntDir)$(TagetName).pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(IntDir)$(TagetName).pdb</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>shlwapi.lib;msimg32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <EntryPointSymbol>_DllMainCRTStartup</EntryPointSymbol>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ <ProgramDatabaseFile>$(IntDir)$(TagetName).pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ </Link>
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TypeLibraryName>$(IntDir)$(TargetName).tlb</TypeLibraryName>
+ <HeaderFileName>
+ </HeaderFileName>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="gen_classicart.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="gen_classicart.rc" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="api.h" />
+ <ClInclude Include="resource.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="notfound.png" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/Src/Plugins/SDK/gen_classicart/gen_classicart.vcxproj.filters b/Src/Plugins/SDK/gen_classicart/gen_classicart.vcxproj.filters
new file mode 100644
index 00000000..f7cf8108
--- /dev/null
+++ b/Src/Plugins/SDK/gen_classicart/gen_classicart.vcxproj.filters
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{dc60e336-beb5-4726-9c94-0b8e309bb18b}</UniqueIdentifier>
+ <Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{e70551dc-3601-4d7a-b048-646279a130b6}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl</Extensions>
+ </Filter>
+ <Filter Include="Image Files">
+ <UniqueIdentifier>{aba55931-1b82-424a-a1e3-18bd09bbc930}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{c89321cb-8ede-44a9-98b1-1e79cb278b95}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="gen_classicart.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="api.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="resource.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="notfound.png">
+ <Filter>Image Files</Filter>
+ </None>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="gen_classicart.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/Src/Plugins/SDK/gen_classicart/lng_generator.exe b/Src/Plugins/SDK/gen_classicart/lng_generator.exe
new file mode 100644
index 00000000..5dcd1227
--- /dev/null
+++ b/Src/Plugins/SDK/gen_classicart/lng_generator.exe
Binary files differ
diff --git a/Src/Plugins/SDK/gen_classicart/notfound.png b/Src/Plugins/SDK/gen_classicart/notfound.png
new file mode 100644
index 00000000..2a6cc8f1
--- /dev/null
+++ b/Src/Plugins/SDK/gen_classicart/notfound.png
Binary files differ
diff --git a/Src/Plugins/SDK/gen_classicart/resource.h b/Src/Plugins/SDK/gen_classicart/resource.h
new file mode 100644
index 00000000..d95d06e4
--- /dev/null
+++ b/Src/Plugins/SDK/gen_classicart/resource.h
@@ -0,0 +1,33 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by gen_classicart.rc
+//
+#define IDS_PLUGIN_NAME 1
+#define IDS_ALBUM_ART_MENU 2
+#define IDS_ALBUM_ART 3
+#define IDS_DO_YOU_ALSO_WANT_TO_REMOVE_SETTINGS 4
+#define IDS_ABOUT_STRING 5
+#define IDS_STRING6 6
+#define IDS_ABOUT 6
+#define IDD_DIALOG 101
+#define IDR_MENU1 102
+#define IDR_IMAGE_NOTFOUND 103
+#define ID_CONTEXTMENU_REFRESH 40001
+#define ID_CONTEXTMENU_LOCKASPECTRATIO 40002
+#define ID_CONTEXTMENU_GETALBUMART 40003
+#define ID_CONTEXTMENU_OPENFOLDER 40004
+#define ID_CONTEXTMENU_AUTOHIDE 40005
+#define ID_CONTEXTMENU_CLICKTRACK 40006
+#define ID_CONTEXTMENU_AUTO 40007
+#define ID_CONTEXTMENU_AUTO_HIDE_MODERN 40008
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 104
+#define _APS_NEXT_COMMAND_VALUE 40009
+#define _APS_NEXT_CONTROL_VALUE 1003
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/Src/Plugins/SDK/in_tone/IN_TONE.sln b/Src/Plugins/SDK/in_tone/IN_TONE.sln
new file mode 100644
index 00000000..d6f93055
--- /dev/null
+++ b/Src/Plugins/SDK/in_tone/IN_TONE.sln
@@ -0,0 +1,24 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.32802.440
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "in_tone", "IN_TONE.vcxproj", "{CE007A38-412F-4758-B17D-489398D1DD50}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x86 = Debug|x86
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {CE007A38-412F-4758-B17D-489398D1DD50}.Debug|x86.ActiveCfg = Debug|Win32
+ {CE007A38-412F-4758-B17D-489398D1DD50}.Debug|x86.Build.0 = Debug|Win32
+ {CE007A38-412F-4758-B17D-489398D1DD50}.Release|x86.ActiveCfg = Release|Win32
+ {CE007A38-412F-4758-B17D-489398D1DD50}.Release|x86.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {AAF99C25-33D3-4ECC-BF56-FF3FF981E2E8}
+ EndGlobalSection
+EndGlobal
diff --git a/Src/Plugins/SDK/in_tone/IN_TONE.vcxproj b/Src/Plugins/SDK/in_tone/IN_TONE.vcxproj
new file mode 100644
index 00000000..d7242f25
--- /dev/null
+++ b/Src/Plugins/SDK/in_tone/IN_TONE.vcxproj
@@ -0,0 +1,319 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectName>in_tone</ProjectName>
+ <ProjectGuid>{CE007A38-412F-4758-B17D-489398D1DD50}</ProjectGuid>
+ <SccProjectName />
+ <SccLocalPath />
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>16.0.32629.160</_ProjectFileVersion>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ <LinkIncremental>false</LinkIncremental>
+ <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules />
+ <CodeAnalysisRuleAssemblies />
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules />
+ <CodeAnalysisRuleAssemblies />
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ <LinkIncremental>false</LinkIncremental>
+ <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules />
+ <CodeAnalysisRuleAssemblies />
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules />
+ <CodeAnalysisRuleAssemblies />
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg">
+ <VcpkgEnabled>false</VcpkgEnabled>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <VcpkgConfiguration>Debug</VcpkgConfiguration>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
+ <PrecompiledHeader />
+ <PrecompiledHeaderOutputFile>$(IntDir)$(TargetName).pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <AdditionalIncludeDirectories>..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ <AdditionalDependencies>msvcmrt.lib;vcruntime.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ <Midl>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ <TypeLibraryName>.\Debug/IN_TONE.tlb</TypeLibraryName>
+ <HeaderFileName />
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <PrecompiledHeaderOutputFile>$(IntDir)$(TargetName).pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <AdditionalIncludeDirectories>..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ <AdditionalDependencies>msvcmrt.lib;vcruntime.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ <Midl>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TypeLibraryName>.\Debug/IN_TONE.tlb</TypeLibraryName>
+ <HeaderFileName>
+ </HeaderFileName>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MinSpace</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <OmitFramePointers>true</OmitFramePointers>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FunctionLevelLinking>
+ </FunctionLevelLinking>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
+ <PrecompiledHeader />
+ <PrecompiledHeaderOutputFile>$(IntDir)$(TargetName).pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ <AdditionalIncludeDirectories>..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ <AdditionalDependencies>msvcmrt.lib;vcruntime.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ <TypeLibraryName>.\Release/IN_TONE.tlb</TypeLibraryName>
+ <HeaderFileName />
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <Optimization>MinSpace</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <OmitFramePointers>true</OmitFramePointers>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <PrecompiledHeaderOutputFile>$(IntDir)$(TargetName).pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ <AdditionalIncludeDirectories>..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ <AdditionalDependencies>msvcmrt.lib;vcruntime.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TypeLibraryName>.\Release/IN_TONE.tlb</TypeLibraryName>
+ <HeaderFileName>
+ </HeaderFileName>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="Main.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="resource.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="in_tone.rc" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/Src/Plugins/SDK/in_tone/IN_TONE.vcxproj.filters b/Src/Plugins/SDK/in_tone/IN_TONE.vcxproj.filters
new file mode 100644
index 00000000..ffd0a02d
--- /dev/null
+++ b/Src/Plugins/SDK/in_tone/IN_TONE.vcxproj.filters
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{fe3315d9-7104-47fb-a190-5606b0a79c2c}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{a324aabb-8e08-4409-b564-68f296e5712f}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{e5a6e5a8-3ea2-46a9-9e02-9b9880fc1f6d}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="in_tone.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="resource.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="Main.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/Src/Plugins/SDK/in_tone/MAIN.C b/Src/Plugins/SDK/in_tone/MAIN.C
new file mode 100644
index 00000000..1ab7ccce
--- /dev/null
+++ b/Src/Plugins/SDK/in_tone/MAIN.C
@@ -0,0 +1,240 @@
+/*
+** Example Winamp input plug-in
+** Copyright (c) 1998, Justin Frankel/Nullsoft Inc.
+*/
+
+#include <windows.h>
+#include <mmreg.h>
+#include <msacm.h>
+#include <math.h>
+#include <stdio.h>
+
+#include "../Winamp/in2.h"
+
+#define WM_WA_MPEG_EOF WM_USER+2
+
+
+extern In_Module mod;
+char lastfn[MAX_PATH];
+short sample_buffer[576*2];
+
+/*
+// avoid CRT. Evil. Big. Bloated.
+BOOL WINAPI _DllMainCRTStartup(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
+{
+ return TRUE;
+}
+*/
+int paused;
+DWORD WINAPI __stdcall PlayThread(void *b);
+
+int gen_freq=2600;
+
+int killDecodeThread=0;
+HANDLE thread_handle=INVALID_HANDLE_VALUE;
+
+void config(HWND hwndParent)
+{
+ MessageBoxA(hwndParent,"To use, open 'tone://2600' (for 2600hz).","Configuration",MB_OK); // Must stay in ANSI
+}
+void about(HWND hwndParent)
+{
+ MessageBoxA(hwndParent,"Nullsoft Tone Generator, by Justin Frankel","About Nullsoft Tone Generator",MB_OK); // Must stay in ANSI
+}
+
+int init()
+{
+ return 0;
+}
+
+void quit() { }
+
+int isourfile(const char *fn)
+{
+ char buf[8];
+ memcpy(buf,fn,7);
+ buf[7]=0;
+ return lstrcmpA(buf,"tone://")?0:1; // Must stay in ANSI
+}
+
+int play(const char *fn) {
+ int maxlatency;
+ int tmp;
+ strcpy(lastfn,fn);
+ // simple atoi() inline so that we don't have to use libc (for a nice 4k dll)
+ {
+ const char *s=fn+7;
+ int n=0;
+ while (*s >= '0' && *s <= '9')
+ {
+ n*=10;
+ n += *s++ -'0';
+ }
+ gen_freq=n;
+ }
+ paused=0;
+ memset(sample_buffer,0,sizeof(sample_buffer));
+
+ maxlatency = mod.outMod->Open(44100,1,16, -1,-1);
+ if (maxlatency < 0)
+ {
+ return 1;
+ }
+ mod.SetInfo(0,44,1,1);
+ mod.SAVSAInit(maxlatency,44100);
+ mod.VSASetInfo(44100,1);
+ mod.outMod->SetVolume(-666);
+
+ killDecodeThread=0;
+ thread_handle = (HANDLE) CreateThread(NULL,0,(LPTHREAD_START_ROUTINE) PlayThread,(void *) &killDecodeThread,0,&tmp);
+
+ return 0;
+}
+
+void pause() { paused=1; mod.outMod->Pause(1); }
+void unpause() { paused=0; mod.outMod->Pause(0); }
+int ispaused() { return paused; }
+
+void stop() {
+ if (thread_handle != INVALID_HANDLE_VALUE)
+ {
+ killDecodeThread=1;
+ if (WaitForSingleObject(thread_handle,INFINITE) == WAIT_TIMEOUT)
+ {
+ MessageBoxA(mod.hMainWindow,"error asking thread to die!\n","error killing decode thread",0); // Must stay in ANSI
+ TerminateThread(thread_handle,0);
+ }
+ CloseHandle(thread_handle);
+ thread_handle = INVALID_HANDLE_VALUE;
+ }
+
+ mod.outMod->Close();
+ mod.SAVSADeInit();
+}
+
+int getlength() { return -1000; }
+int getoutputtime() { return mod.outMod->GetOutputTime(); }
+void setoutputtime(int time_in_ms) { }
+
+void setvolume(int volume) { mod.outMod->SetVolume(volume); }
+void setpan(int pan) { mod.outMod->SetPan(pan); }
+
+int infoDlg(const char *fn, HWND hwnd)
+{
+ return 0;
+}
+
+void getfileinfo(const char *filename, char *title, int *length_in_ms)
+{
+ if (!filename || !*filename) filename=lastfn;
+ if (title)
+ {
+ const char *s=filename+7;
+ int n=0;
+ while (*s >= '0' && *s <= '9')
+ {
+ n*=10;
+ n += *s++ -'0';
+ }
+ sprintf(title,"%dhz Tone",n);
+ }
+ if (length_in_ms) *length_in_ms=-1000;
+}
+
+void eq_set(int on, char data[10], int preamp)
+{
+}
+
+
+In_Module mod =
+{
+ IN_VER,
+ L"Nullsoft Tone Generator v0.2 "
+/* #ifdef __alpha
+ "(AXP)"
+#else
+ "(x86)"
+#endif */
+ ,
+ 0, // hMainWindow
+ 0, // hDllInstance
+ "\0"
+ ,
+ 0, // is_seekable
+ 1, // uses output
+ config,
+ about,
+ init,
+ quit,
+ getfileinfo,
+ infoDlg,
+ isourfile,
+ play,
+ pause,
+ unpause,
+ ispaused,
+ stop,
+
+ getlength,
+ getoutputtime,
+ setoutputtime,
+
+ setvolume,
+ setpan,
+
+ 0,0,0,0,0,0,0,0,0, // vis stuff
+
+
+ 0,0, // dsp
+
+ eq_set,
+
+ NULL, // setinfo
+
+ 0 // out_mod
+
+};
+
+__declspec( dllexport ) In_Module * winampGetInModule2()
+{
+ return &mod;
+}
+
+int _fltused=0;
+
+DWORD WINAPI __stdcall PlayThread(void *b)
+{
+ double angle=0.0,dangle=3.14159*2.0*(double)gen_freq/(double)44100.0;
+ while (! *((int *)b) )
+ {
+ if (mod.outMod->CanWrite() >= ((sizeof(sample_buffer)/2)<<(mod.dsp_isactive()?1:0)))
+ {
+ int l=sizeof(sample_buffer)/2,x=l/2;
+ short *s=sample_buffer;
+ while (x--)
+ {
+ int i;
+ double d = sin(angle)*32766.5;
+#ifndef __alpha
+ __asm {
+ fld d
+ fistp i
+ }
+#else
+ i = (int) d;
+#endif
+ *s++=i;
+ angle += dangle;
+ }
+ {
+ int t=mod.outMod->GetWrittenTime();
+ mod.SAAddPCMData((char *)sample_buffer,1,16,t);
+ mod.VSAAddPCMData((char *)sample_buffer,1,16,t);
+ }
+ l=mod.dsp_dosamples(sample_buffer,l/2,16,1,44100)*2;
+ mod.outMod->Write((char *)sample_buffer,l);
+ }
+ else Sleep(50);
+ }
+ return 0;
+} \ No newline at end of file
diff --git a/Src/Plugins/SDK/in_tone/in_tone.rc b/Src/Plugins/SDK/in_tone/in_tone.rc
new file mode 100644
index 00000000..9616e11d
--- /dev/null
+++ b/Src/Plugins/SDK/in_tone/in_tone.rc
@@ -0,0 +1,109 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Polish resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_PLK)
+#ifdef _WIN32
+LANGUAGE LANG_POLISH, SUBLANG_DEFAULT
+#pragma code_page(1250)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "#include ""version.rc2""\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Polish resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.K.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE
+BEGIN
+ IDS_NULLSOFT_IN_TONE "Nullsoft Tone Input v%s"
+ 65535 "{1A710E67-5180-49ac-8102-105856ED0A2F}"
+END
+
+#endif // English (U.K.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#include "version.rc2"
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/Src/Plugins/SDK/in_tone/resource.h b/Src/Plugins/SDK/in_tone/resource.h
new file mode 100644
index 00000000..8af67da5
--- /dev/null
+++ b/Src/Plugins/SDK/in_tone/resource.h
@@ -0,0 +1,18 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by in_tone.rc
+//
+#define IDS_NULLSOFT_IN_TONE_OLD 0
+
+#define IDS_NULLSOFT_IN_TONE 65534
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 108
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1037
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/Src/Plugins/SDK/in_tone/version.rc2 b/Src/Plugins/SDK/in_tone/version.rc2
new file mode 100644
index 00000000..b3a65977
--- /dev/null
+++ b/Src/Plugins/SDK/in_tone/version.rc2
@@ -0,0 +1,39 @@
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+#include "..\..\..\Winamp\buildType.h"
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 0,2,0,1
+ PRODUCTVERSION WINAMP_PRODUCTVER
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", "Winamp SA"
+ VALUE "FileDescription", "Winamp Tone Input Plug-in"
+ VALUE "FileVersion", "0,2,0,1"
+ VALUE "InternalName", "Nullsoft Tone Input"
+ VALUE "LegalCopyright", "Copyright © 2005-2023 Winamp SA"
+ VALUE "LegalTrademarks", "Nullsoft and Winamp are trademarks of Winamp SA"
+ VALUE "OriginalFilename", "in_tone.dll"
+ VALUE "ProductName", "Winamp"
+ VALUE "ProductVersion", STR_WINAMP_PRODUCTVER
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/Src/Plugins/SDK/irctell/api__irctell.h b/Src/Plugins/SDK/irctell/api__irctell.h
new file mode 100644
index 00000000..c28bfc1a
--- /dev/null
+++ b/Src/Plugins/SDK/irctell/api__irctell.h
@@ -0,0 +1,7 @@
+/* copyright 2006 Ben Allison */
+#ifndef NULLSOFT_APIH
+#define NULLSOFT_APIH
+
+#include <api/service/api_service.h>
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/SDK/irctell/dde.cpp b/Src/Plugins/SDK/irctell/dde.cpp
new file mode 100644
index 00000000..790ffa09
--- /dev/null
+++ b/Src/Plugins/SDK/irctell/dde.cpp
@@ -0,0 +1,50 @@
+#include <windows.h>
+#include "dde.h"
+#include <strsafe.h>
+
+HDDEDATA CALLBACK DdeGenericCallback(UINT uType, UINT uFmt,HCONV hconv, HSZ hsz1,
+ HSZ hsz2, HDDEDATA hdata, DWORD dwData1,
+ DWORD dwData2)
+{
+ return ((HDDEDATA)0);
+}
+
+void DdeCom::sendCommand(wchar_t *application, wchar_t *command, DWORD minInterval)
+{
+ static DWORD lastCmd=0, now;
+ HSZ string1,string2,string3;
+ wchar_t line[512];
+ HCONV ddeConv;
+ DWORD result;
+
+ now = GetTickCount();
+ if (now < lastCmd + minInterval)
+ return;
+
+ StringCchCopy(line, 512, command);
+
+ DWORD DDE=0;
+
+ if (DdeInitialize(&DDE, DdeGenericCallback, CBF_SKIP_ALLNOTIFICATIONS+ST_CLIENT,0) != DMLERR_NO_ERROR)
+ {
+ MessageBox(NULL,L"DDE INITIALIZE", L"Error", MB_OK);
+
+ return;
+ }
+
+ string1 = DdeCreateStringHandle(DDE, application, CP_WINANSI);
+ string2 = DdeCreateStringHandle(DDE, L"COMMAND", CP_WINANSI);
+
+ if ((ddeConv = DdeConnect(DDE, string1, string2, 0)) != 0)
+ {
+ string3 = DdeCreateStringHandle(DDE, L"None", CP_WINANSI);
+ DdeClientTransaction((LPBYTE)line, (wcslen(line)+1)*sizeof(line[0]), ddeConv, string3, CF_UNICODETEXT, XTYP_POKE, 1000, &result);
+ DdeFreeStringHandle(DDE, string3);
+ DdeDisconnect(ddeConv);
+ lastCmd = now;
+ }
+
+ DdeFreeStringHandle(DDE, string1);
+ DdeFreeStringHandle(DDE, string2);
+ DdeUninitialize(DDE);
+}
diff --git a/Src/Plugins/SDK/irctell/dde.h b/Src/Plugins/SDK/irctell/dde.h
new file mode 100644
index 00000000..3f14eb3e
--- /dev/null
+++ b/Src/Plugins/SDK/irctell/dde.h
@@ -0,0 +1,9 @@
+#ifndef __DDECOM_H
+#define __DDECOM_H
+
+class DdeCom {
+public:
+ static void sendCommand(wchar_t *application, wchar_t *command, DWORD minInterval);
+};
+
+#endif
diff --git a/Src/Plugins/SDK/irctell/irctell.cpp b/Src/Plugins/SDK/irctell/irctell.cpp
new file mode 100644
index 00000000..92f333b8
--- /dev/null
+++ b/Src/Plugins/SDK/irctell/irctell.cpp
@@ -0,0 +1,122 @@
+#include <windows.h>
+#include "irctell.h"
+#include <api/syscb/api_syscb.h>
+#include <api/core/api_core.h>
+#include "api__irctell.h"
+#include <api/service/waservicefactory.h>
+#include "dde.h"
+#include <strsafe.h>
+
+static WACIrctell Irctell;
+extern "C" __declspec(dllexport) ifc_wa5component *GetWinamp5SystemComponent()
+{
+ return &Irctell;
+}
+
+bool dotell=true;
+api_syscb *sysCallbackApi=0;
+api_core *core=0;
+api_service *WASABI_API_SVC = 0;
+
+void WACIrctell::RegisterServices(api_service *service)
+{
+ WASABI_API_SVC = service;
+ waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(syscbApiServiceGuid);
+ if (sf) sysCallbackApi = reinterpret_cast<api_syscb *>(sf->getInterface());
+
+ sysCallbackApi->syscb_registerCallback(static_cast<SysCallback *>(this));
+ sf = WASABI_API_SVC->service_getServiceByGuid(coreApiServiceGuid);
+ if (sf) core = reinterpret_cast<api_core *>(sf->getInterface());
+
+ if (core)
+ core->core_addCallback(0, this);
+}
+
+void WACIrctell::DeregisterServices(api_service *service)
+{
+ // be sure to delete all your windows etc HERE, not in the destructor
+ // because the API pointer might be invalid in the destructor
+// if (core)
+ // core->core_delCallback(0, this);
+}
+
+/*
+void WACIrctell::onRegisterServices() {
+dotell.setName("Enabled");
+dotell=0;
+registerAttribute(&dotell);
+
+appstr.setName("DDE Target");
+appstr="mIRC";
+registerAttribute(&appstr);
+
+cmdstr.setName("DDE Command");
+cmdstr="/me is listening to %s";
+registerAttribute(&cmdstr);
+}
+*/
+
+int WACIrctell::ccb_notify(int msg, int param1, int param2)
+{
+ if (msg==TITLECHANGE && dotell)
+ {
+ const wchar_t *title = (const wchar_t *)param1;
+ const wchar_t *cur=core->core_getCurrent(0);
+
+ wchar_t msg[256];
+ StringCchPrintfW(msg, 256, L"/describe #winamp is now listening to \"%s\"", title);
+ DdeCom::sendCommand(L"mIRC", msg, 1000);
+ }
+ return 0;
+}
+
+FOURCC WACIrctell::getEventType()
+{
+ return SysCallback::SERVICE;
+}
+
+int WACIrctell::notify(int msg, int param1, int param2)
+{
+ switch(msg)
+ {
+ case SvcCallback::ONREGISTER:
+ {
+ waServiceFactory *sf = (waServiceFactory *)param2;
+ if (sf->getGuid() == coreApiServiceGuid)
+ {
+ core = reinterpret_cast<api_core *>(sf->getInterface());
+ core->core_addCallback(0, this);
+ }
+ }
+ break;
+
+ case SvcNotify::ONDEREGISTERED:
+ {
+ waServiceFactory *sf = (waServiceFactory *)param2;
+ if (sf->getGuid() == coreApiServiceGuid)
+ {
+ if (core)
+ core->core_delCallback(0, this);
+ core = 0;
+ }
+ }
+ break;
+
+ }
+ return 0;
+
+}
+
+#define CBCLASS WACIrctell
+START_MULTIPATCH;
+START_PATCH(patch_wa5)
+M_VCB(patch_wa5, ifc_wa5component, API_WA5COMPONENT_REGISTERSERVICES, RegisterServices);
+M_VCB(patch_wa5, ifc_wa5component, API_WA5COMPONENT_DEREEGISTERSERVICES, DeregisterServices);
+NEXT_PATCH(patch_core)
+M_CB(patch_core, CoreCallback, CCB_NOTIFY, ccb_notify);
+NEXT_PATCH(patch_svc)
+M_CB(patch_svc, SysCallback, SYSCALLBACK_GETEVENTTYPE, getEventType);
+M_CB(patch_svc, SysCallback, SYSCALLBACK_NOTIFY, notify);
+END_PATCH
+END_MULTIPATCH;
+#undef CBCLASS
diff --git a/Src/Plugins/SDK/irctell/irctell.h b/Src/Plugins/SDK/irctell/irctell.h
new file mode 100644
index 00000000..3054aec1
--- /dev/null
+++ b/Src/Plugins/SDK/irctell/irctell.h
@@ -0,0 +1,29 @@
+#ifndef _GENERIC_H
+#define _GENERIC_H
+
+
+#include <api/syscb/callbacks/corecb.h>
+#include <api/syscb/callbacks/svccb.h>
+#include "../Agave/Component/ifc_wa5component.h"
+#include <bfc/multipatch.h>
+
+enum { patch_wa5, patch_core, patch_svc};
+class WACIrctell :public MultiPatch<patch_wa5, ifc_wa5component>,
+ public MultiPatch<patch_core, CoreCallback>,
+ public MultiPatch<patch_svc, SysCallback>
+{
+
+public:
+ void RegisterServices(api_service *service);
+ void DeregisterServices(api_service *service);
+
+ int ccb_notify(int msg, int param1=0, int param2=0);
+
+ FOURCC getEventType();
+ int notify(int msg, int param1 = 0, int param2 = 0);
+
+protected:
+ RECVS_MULTIPATCH;
+};
+
+#endif
diff --git a/Src/Plugins/SDK/irctell/irctell.rc b/Src/Plugins/SDK/irctell/irctell.rc
new file mode 100644
index 00000000..15455697
--- /dev/null
+++ b/Src/Plugins/SDK/irctell/irctell.rc
@@ -0,0 +1,74 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "#include ""version.rc2""\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE
+BEGIN
+ 65535 "{9E398E5F-EDEC-4dd8-A40D-E29B385A88C0}"
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#include "version.rc2"
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/Src/Plugins/SDK/irctell/irctell.sln b/Src/Plugins/SDK/irctell/irctell.sln
new file mode 100644
index 00000000..0e2e720f
--- /dev/null
+++ b/Src/Plugins/SDK/irctell/irctell.sln
@@ -0,0 +1,24 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.32802.440
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "irctell", "irctell.vcxproj", "{8F034E55-D388-416D-8575-5D765255CFF6}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x86 = Debug|x86
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {8F034E55-D388-416D-8575-5D765255CFF6}.Debug|x86.ActiveCfg = Debug|Win32
+ {8F034E55-D388-416D-8575-5D765255CFF6}.Debug|x86.Build.0 = Debug|Win32
+ {8F034E55-D388-416D-8575-5D765255CFF6}.Release|x86.ActiveCfg = Release|Win32
+ {8F034E55-D388-416D-8575-5D765255CFF6}.Release|x86.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {23036EDD-9085-419F-AF16-2AC1EE49B96D}
+ EndGlobalSection
+EndGlobal
diff --git a/Src/Plugins/SDK/irctell/irctell.vcxproj b/Src/Plugins/SDK/irctell/irctell.vcxproj
new file mode 100644
index 00000000..02b68c80
--- /dev/null
+++ b/Src/Plugins/SDK/irctell/irctell.vcxproj
@@ -0,0 +1,243 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{8F034E55-D388-416D-8575-5D765255CFF6}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>16.0.32629.160</_ProjectFileVersion>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ <LinkIncremental>false</LinkIncremental>
+ <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules />
+ <CodeAnalysisRuleAssemblies />
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ <TargetExt>.w5s</TargetExt>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules />
+ <CodeAnalysisRuleAssemblies />
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ <TargetExt>.w5s</TargetExt>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ <LinkIncremental>false</LinkIncremental>
+ <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules />
+ <CodeAnalysisRuleAssemblies />
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ <TargetExt>.w5s</TargetExt>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules />
+ <CodeAnalysisRuleAssemblies />
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ <TargetExt>.w5s</TargetExt>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg">
+ <VcpkgEnabled>false</VcpkgEnabled>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <VcpkgConfiguration>Debug</VcpkgConfiguration>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..;..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;IRCTELL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader />
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..;..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;IRCTELL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MinSpace</Optimization>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..;..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;IRCTELL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
+ <PrecompiledHeader />
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <IgnoreSpecificDefaultLibraries>msvcprt.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <Optimization>MinSpace</Optimization>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..;..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;IRCTELL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <IgnoreSpecificDefaultLibraries>msvcprt.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="dde.cpp" />
+ <ClCompile Include="irctell.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="api__irctell.h" />
+ <ClInclude Include="dde.h" />
+ <ClInclude Include="irctell.h" />
+ <ClInclude Include="resource.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="irctell.rc" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/Src/Plugins/SDK/irctell/irctell.vcxproj.filters b/Src/Plugins/SDK/irctell/irctell.vcxproj.filters
new file mode 100644
index 00000000..90d52bb5
--- /dev/null
+++ b/Src/Plugins/SDK/irctell/irctell.vcxproj.filters
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="dde.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="irctell.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="api__irctell.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="dde.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="irctell.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="resource.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="irctell.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/Src/Plugins/SDK/irctell/resource.h b/Src/Plugins/SDK/irctell/resource.h
new file mode 100644
index 00000000..f5925f2f
--- /dev/null
+++ b/Src/Plugins/SDK/irctell/resource.h
@@ -0,0 +1,17 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by irctell.rc
+//
+#define IDS_STRING0 1
+#define IDC_BUTTON1 1001
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 103
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1002
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/Src/Plugins/SDK/irctell/version.rc2 b/Src/Plugins/SDK/irctell/version.rc2
new file mode 100644
index 00000000..ed40cd10
--- /dev/null
+++ b/Src/Plugins/SDK/irctell/version.rc2
@@ -0,0 +1,39 @@
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+#include "..\..\..\Winamp\buildType.h"
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION WINAMP_PRODUCTVER
+ PRODUCTVERSION WINAMP_PRODUCTVER
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", "Winamp SA"
+ VALUE "FileDescription", "Winamp 5.x System Component"
+ VALUE "FileVersion", STR_WINAMP_PRODUCTVER
+ VALUE "InternalName", "irctell.w5s"
+ VALUE "LegalCopyright", "Copyright © 2005-2023 Winamp SA"
+ VALUE "LegalTrademarks", "Nullsoft and Winamp are trademarks of Winamp SA"
+ VALUE "OriginalFilename", "irctell.w5s"
+ VALUE "ProductName", "Winamp IRC Notifier Service"
+ VALUE "ProductVersion", STR_WINAMP_PRODUCTVER
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/Src/Plugins/SDK/ml_iso/ToISO.cpp b/Src/Plugins/SDK/ml_iso/ToISO.cpp
new file mode 100644
index 00000000..1a5e132f
--- /dev/null
+++ b/Src/Plugins/SDK/ml_iso/ToISO.cpp
@@ -0,0 +1,366 @@
+#include "main.h"
+#include "api__ml_iso.h"
+#include <api/service/waservicefactory.h>
+#include "../burner/obj_isocreator.h"
+#include "../playlist/ifc_playlistloadercallback.h"
+#include <shlwapi.h>
+#include <strsafe.h>
+
+/**
+** Playlist Loader callback class
+** Used when this plugin loads a playlist file
+** the playlist loader will call the OnFile() function
+** for each playlist item
+*/
+class ISOPlaylistLoader : public ifc_playlistloadercallback
+{
+public:
+ ISOPlaylistLoader(obj_isocreator *_creator);
+
+protected:
+ RECVS_DISPATCH;
+
+private:
+ void OnFile(const wchar_t *filename, const wchar_t *title, int lengthInMS, ifc_plentryinfo *info);
+ obj_isocreator *creator;
+};
+
+/**
+** helper function
+** for getting a filename location
+** of where to save the ISO file
+**/
+static bool PromptForFilename(wchar_t *filename, size_t filenameCch)
+{
+ wchar_t oldCurPath[MAX_PATH], newCurPath[MAX_PATH];
+ OPENFILENAMEW openfilename;
+
+ // null terminate the string or else we'll get a garbage filename as the 'default' filename
+ filename[0]=0;
+
+ // GetSaveFileName changes Window's working directory
+ // which locks that folder from being deleted until Winamp closes
+ // so we save the old working directory name
+ // and restore it on complete
+ // Winamp maintains its own concept of a working directory
+ // to help us avoid this problem
+ GetCurrentDirectoryW(MAX_PATH, oldCurPath);
+
+
+ // initialize the open file name struct
+ openfilename.lStructSize = sizeof(openfilename);
+ openfilename.hwndOwner = plugin.hwndLibraryParent;
+ openfilename.hInstance = plugin.hDllInstance;
+ openfilename.lpstrFilter = L"ISO Files\0*.iso\0";
+ openfilename.lpstrCustomFilter = 0;
+ openfilename.nMaxCustFilter = 0;
+ openfilename.nFilterIndex = 0;
+ openfilename.lpstrFile = filename;
+ openfilename.nMaxFile = filenameCch;
+ openfilename.lpstrFileTitle = 0;
+ openfilename.nMaxFileTitle = 0;
+ // we set the initial directory based on winamp's working path
+ openfilename.lpstrInitialDir = WASABI_API_APP->path_getWorkingPath();
+ openfilename.lpstrTitle = 0;
+ // despite the big note about working directory
+ // we don't want to use OFN_NOCHANGEDIR
+ // because we're going to manually sync Winamp's working path
+ openfilename.Flags = OFN_ENABLESIZING | OFN_EXPLORER | OFN_LONGNAMES;
+ openfilename.nFileOffset = 0;
+ openfilename.nFileExtension = 0;
+ openfilename.lpstrDefExt = L".iso";
+ openfilename.lCustData = 0;
+ openfilename.lpfnHook = 0;
+ openfilename.lpTemplateName = 0;
+
+ if (GetSaveFileNameW(&openfilename))
+ {
+ // let's re-synch Winamp's working directory
+ GetCurrentDirectoryW(MAX_PATH, newCurPath);
+ WASABI_API_APP->path_setWorkingPath(newCurPath);
+
+ // set the old path back
+ SetCurrentDirectoryW(oldCurPath);
+ return true; // success!
+ }
+ else
+ {
+ // set the old path back
+ SetCurrentDirectoryW(oldCurPath);
+ return false; // user hit cancel or something else happened
+ }
+
+}
+
+/**
+** helper functions
+** for creating and deleting
+** an iso creator object
+** through the wasabi service manager
+**/
+static obj_isocreator *CreateISOCreator()
+{
+ waServiceFactory *factory = WASABI_API_SVC->service_getServiceByGuid(obj_isocreatorGUID);
+ if (factory)
+ return (obj_isocreator *)factory->getInterface();
+ else
+ return 0;
+}
+
+static void ReleaseISOCreator(obj_isocreator *creator)
+{
+ if (creator)
+ {
+ waServiceFactory *factory = WASABI_API_SVC->service_getServiceByGuid(obj_isocreatorGUID);
+ if (factory)
+ factory->releaseInterface(creator);
+ }
+}
+
+void ConvertItemRecordListToISO(const itemRecordList *list)
+{
+ obj_isocreator *isocreator = CreateISOCreator();
+ if (isocreator)
+ {
+ wchar_t destination[MAX_PATH];
+
+ if (PromptForFilename(destination, MAX_PATH))
+ {
+ // these values are hardcoded for this example.
+ isocreator->Open(L"WinampISO", obj_isocreator::FORMAT_JOLIET, obj_isocreator::MEDIA_CD);
+
+ char destinationPath[MAX_PATH];
+
+ // loop through the files and add them
+ for (int i=0;i<list->Size;i++)
+ {
+ itemRecord &item = list->Items[i];
+
+ // since we have metadata, we're going to auto-generate folders based on the album name
+ const char *album = item.album;
+ if (!album || !*album)
+ album = "Unknown Album";
+
+ // isocreator requires a preceding backslash
+ StringCbPrintfA(destinationPath, sizeof(destinationPath), "\\%s\\%s", album, PathFindFileNameA(item.filename));
+
+ // convert to unicode since that's what obj_isocreator requires
+ wchar_t unicodeSource[MAX_PATH];
+ wchar_t unicodeDest[MAX_PATH];
+ MultiByteToWideChar(CP_ACP, 0, item.filename, -1, unicodeSource, MAX_PATH);
+ MultiByteToWideChar(CP_ACP, 0, destinationPath, -1, unicodeDest, MAX_PATH);
+ isocreator->AddFile(unicodeSource, unicodeDest);
+ }
+
+ isocreator->Write(destination, 0);
+ }
+ ReleaseISOCreator(isocreator);
+ }
+}
+
+void ConvertFilenamesToISO(const char *filenames)
+{
+ obj_isocreator *isocreator = CreateISOCreator();
+ if (isocreator)
+ {
+ wchar_t destination[MAX_PATH];
+
+ if (PromptForFilename(destination, MAX_PATH))
+ {
+ // these values are hardcoded for this example.
+ isocreator->Open(L"WinampISO", obj_isocreator::FORMAT_JOLIET, obj_isocreator::MEDIA_CD);
+
+ wchar_t destinationPath[MAX_PATH];
+
+ // loop through the files and add them
+ while (*filenames)
+ {
+ /**
+ ** both playlist loader and iso creator want unicode filenames
+ ** so we'll convert it first
+ */
+ wchar_t unicodeFilename[MAX_PATH];
+ MultiByteToWideChar(CP_ACP, 0, filenames, -1, unicodeFilename, MAX_PATH);
+
+ /**
+ ** see if this file is a playlist file
+ ** we'll do that by trying to load it
+ ** the Load() function will fail gracefully if it's not a playlist file
+ ** if it succeeds, it will call loader.OnFile() which adds it to the iso file
+ **/
+ ISOPlaylistLoader loader(isocreator); // make a callback object for playlist loading
+ if (AGAVE_API_PLAYLISTMANAGER->Load(unicodeFilename, &loader) == PLAYLISTMANAGER_LOAD_NO_LOADER)
+ {
+ // not a playlist file, so load it normally
+
+ // isocreator requires a preceding backslash
+ StringCbPrintfW(destinationPath, sizeof(destinationPath), L"\\%s", PathFindFileNameW(unicodeFilename));
+
+ isocreator->AddFile(unicodeFilename, destinationPath);
+ }
+ filenames+=strlen(filenames)+1;
+ }
+ isocreator->Write(destination, 0);
+ }
+ ReleaseISOCreator(isocreator);
+ }
+}
+
+
+/**
+** Load Playlist and write it to the ISO file
+** this function is a bit complex, since we have to load the playlist
+** through api_playlistmanager. This involves creating an playlist loader callback
+** (ifc_playlistloadercallback) which gets called for each playlist item
+**/
+void ConvertPlaylistToISO(const mlPlaylist *playlist)
+{
+ obj_isocreator *isocreator = CreateISOCreator();
+ if (isocreator)
+ {
+ wchar_t destination[MAX_PATH];
+
+ if (PromptForFilename(destination, MAX_PATH))
+ {
+ // these values are hardcoded for this example.
+ const wchar_t *title=L"WinampISO";
+ if (playlist->title) // if there's a playlist title, use it as the volume name
+ title = playlist->title;
+
+ isocreator->Open(title, obj_isocreator::FORMAT_JOLIET, obj_isocreator::MEDIA_CD);
+
+ ISOPlaylistLoader loader(isocreator); // make a callback object for playlist loading
+ AGAVE_API_PLAYLISTMANAGER->Load(playlist->filename, &loader);
+
+ isocreator->Write(destination, 0);
+ }
+ ReleaseISOCreator(isocreator);
+ }
+}
+
+/** Load all playlists and write them to the ISO file
+** this function is a bit complex, since we have to load the playlist
+** through api_playlistmanager. This involves creating an playlist loader callback
+** (ifc_playlistloadercallback) which gets called for each playlist item
+**/
+void ConvertPlaylistsToISO(const mlPlaylist **playlists)
+{
+ obj_isocreator *isocreator = CreateISOCreator();
+ if (isocreator)
+ {
+ wchar_t destination[MAX_PATH];
+
+ if (PromptForFilename(destination, MAX_PATH))
+ {
+ // these values are hardcoded for this example.
+ isocreator->Open(L"WinampISO", obj_isocreator::FORMAT_JOLIET, obj_isocreator::MEDIA_CD);
+ while (*playlists)
+ {
+ const mlPlaylist *playlist = *playlists;
+ ISOPlaylistLoader loader(isocreator); // make a callback object for playlist loading
+ AGAVE_API_PLAYLISTMANAGER->Load(playlist->filename, &loader);
+ playlists++;
+ }
+ isocreator->Write(destination, 0);
+ }
+ ReleaseISOCreator(isocreator);
+ }
+}
+
+void ConvertUnicodeItemRecordListToISO(const itemRecordListW *list)
+{
+ obj_isocreator *isocreator = CreateISOCreator();
+ if (isocreator)
+ {
+ wchar_t destination[MAX_PATH];
+
+ if (PromptForFilename(destination, MAX_PATH))
+ {
+ // these values are hardcoded for this example.
+ isocreator->Open(L"WinampISO", obj_isocreator::FORMAT_JOLIET, obj_isocreator::MEDIA_CD);
+
+ wchar_t destinationPath[MAX_PATH];
+
+ // loop through the files and add them
+ for (int i=0;i<list->Size;i++)
+ {
+ itemRecordW &item = list->Items[i];
+
+ // since we have metadata, we're going to auto-generate folders based on the album name
+ const wchar_t *album = item.album;
+ if (!album || !*album)
+ album = L"Unknown Album";
+
+ // isocreator requires a preceding backslash
+ StringCbPrintfW(destinationPath, sizeof(destinationPath), L"\\%s\\%s", album, PathFindFileNameW(item.filename));
+
+ isocreator->AddFile(item.filename, destinationPath);
+ }
+ isocreator->Write(destination, 0);
+ }
+ ReleaseISOCreator(isocreator);
+ }
+}
+
+void ConvertUnicodeFilenamesToISO(const wchar_t *filenames)
+{
+ obj_isocreator *isocreator = CreateISOCreator();
+ if (isocreator)
+ {
+ wchar_t destination[MAX_PATH];
+
+ if (PromptForFilename(destination, MAX_PATH))
+ {
+ // these values are hardcoded for this example.
+ isocreator->Open(L"WinampISO", obj_isocreator::FORMAT_JOLIET, obj_isocreator::MEDIA_CD);
+
+ wchar_t destinationPath[MAX_PATH];
+
+ // loop through the files and add them
+ while (*filenames)
+ {
+ /**
+ ** see if this file is a playlist file
+ ** we'll do that by trying to load it
+ ** the Load() function will fail gracefully if it's not a playlist file
+ ** if it succeeds, it will call loader.OnFile() which adds it to the iso file
+ **/
+ ISOPlaylistLoader loader(isocreator); // make a callback object for playlist loading
+ if (AGAVE_API_PLAYLISTMANAGER->Load(filenames, &loader) == PLAYLISTMANAGER_LOAD_NO_LOADER)
+ {
+ // not a playlist file, so load it normally
+
+ // isocreator requires a preceding backslash
+ StringCbPrintfW(destinationPath, sizeof(destinationPath), L"\\%s", PathFindFileNameW(filenames));
+
+ isocreator->AddFile(filenames, destinationPath);
+ }
+ filenames+=wcslen(filenames)+1;
+ }
+
+ isocreator->Write(destination, 0);
+ }
+ ReleaseISOCreator(isocreator);
+ }
+}
+
+/* --- Playlist Loader definition --- */
+ISOPlaylistLoader::ISOPlaylistLoader(obj_isocreator *_creator)
+{
+ creator=_creator;
+}
+
+void ISOPlaylistLoader::OnFile(const wchar_t *filename, const wchar_t *title, int lengthInMS, ifc_plentryinfo *info)
+{
+ // isocreator requires a preceding backslash
+ wchar_t destinationPath[MAX_PATH];
+ StringCbPrintfW(destinationPath, sizeof(destinationPath), L"\\%s", PathFindFileNameW(filename));
+ // add file to .iso image
+ creator->AddFile(filename, destinationPath);
+}
+
+#define CBCLASS ISOPlaylistLoader
+START_DISPATCH;
+VCB(IFC_PLAYLISTLOADERCALLBACK_ONFILE, OnFile)
+//VCB(IFC_PLAYLISTLOADERCALLBACK_ONPLAYLISTINFO, OnPlaylistInfo)
+END_DISPATCH;
diff --git a/Src/Plugins/SDK/ml_iso/api__ml_iso.h b/Src/Plugins/SDK/ml_iso/api__ml_iso.h
new file mode 100644
index 00000000..f95dc35f
--- /dev/null
+++ b/Src/Plugins/SDK/ml_iso/api__ml_iso.h
@@ -0,0 +1,10 @@
+#pragma once
+
+#include <api/service/api_service.h>
+
+#include <api/application/api_application.h>
+#define WASABI_API_APP applicationApi
+
+#include "../playlist/api_playlistmanager.h"
+extern api_playlistmanager *playlistManagerApi;
+#define AGAVE_API_PLAYLISTMANAGER playlistManagerApi
diff --git a/Src/Plugins/SDK/ml_iso/main.cpp b/Src/Plugins/SDK/ml_iso/main.cpp
new file mode 100644
index 00000000..764e25e6
--- /dev/null
+++ b/Src/Plugins/SDK/ml_iso/main.cpp
@@ -0,0 +1,150 @@
+#include "main.h"
+#include "../Winamp/wa_ipc.h"
+#include "api__ml_iso.h"
+#include <api/service/waservicefactory.h>
+
+
+/* wasabi services we'll be using */
+api_service *WASABI_API_SVC = 0;
+api_application *WASABI_API_APP = 0;
+api_playlistmanager *AGAVE_API_PLAYLISTMANAGER = 0;
+
+/* gen_ml calls this function when it loads your plugin. return non-zero to abort loading your plugin */
+int Init()
+{
+ // this plugin requires an interface only present on 5.54 and up, so we'll just refuse to load on older versions
+ if (SendMessage(plugin.hwndWinampParent, WM_WA_IPC, 0, IPC_GETVERSION) < 0x5054)
+ return 1;
+
+ // go ahead and grab the wasabi service manager. we'll need it later when we get an ISO Creator object
+ WASABI_API_SVC = (api_service *)SendMessage(plugin.hwndWinampParent, WM_WA_IPC, 0, IPC_GET_API_SERVICE);
+
+ // get the application API
+ // we need this to get/set Winamp's current working directory
+ waServiceFactory *factory = WASABI_API_SVC->service_getServiceByGuid(applicationApiServiceGuid);
+ if (factory)
+ WASABI_API_APP = (api_application *)factory->getInterface();
+
+ // get the playlist manager API
+ // we'll need this for loading playlists
+ factory = WASABI_API_SVC->service_getServiceByGuid(api_playlistmanagerGUID);
+ if (factory)
+ AGAVE_API_PLAYLISTMANAGER = (api_playlistmanager *)factory->getInterface();
+
+ // this media library plugin doesn't add a node to the treeview, so we don't really do anything in here besides
+ // grabbing the service manager
+ // all of the action will come via Send-To which is handled in MessageProc
+
+ return 0;
+}
+
+void Quit()
+{
+
+}
+
+INT_PTR MessageProc(int message_type, INT_PTR param1, INT_PTR param2, INT_PTR param3)
+{
+ switch(message_type)
+ {
+ // this gets sent when Winamp wants to build the send-to menu. If we want to be in the send-to
+ // we make some API calls during this function
+ case ML_MSG_ONSENDTOBUILD:
+ {
+ INT_PTR source_type = param1; // param 1 is the source type
+ INT_PTR context = param2; // param 2 is just some context value that we have to use when we call back into the API
+
+ // we only accept certain types of sources, so we'll explicitly check
+ // if we were to handle ALL types, checking against the known types
+ // is good practice in case new Winamp versions add additional source types
+ switch(source_type)
+ {
+ case ML_TYPE_ITEMRECORDLIST: // Item Record List. Used by the local media library
+ case ML_TYPE_FILENAMES: // raw list of filenames
+ case ML_TYPE_PLAYLIST: // a playlist. we'll use the playlist loading API to crack it open
+ case ML_TYPE_PLAYLISTS: // a list of playlists. we'll use the playlist loading API to crack each one open
+ case ML_TYPE_ITEMRECORDLISTW: // unicode version of an Item Record List
+ case ML_TYPE_FILENAMESW: // raw list of unicode filenames
+ {
+ // add ourselves to the send-to menu!
+ mlAddToSendToStructW s;
+ s.context = context; // pass in the context value passed to this function.
+ s.desc = L"Create new ISO image";
+ s.user32 = (INT_PTR)MessageProc; // this value has to be some unique value that you can identify later
+ // by convention, use the pointer to this function, since it's obviously unique
+
+ SendMessage(plugin.hwndLibraryParent, WM_ML_IPC, (WPARAM)&s, ML_IPC_ADDTOSENDTOW);
+ }
+ // returning 0 tells the media library to continue building the send-to menu
+ // it doesn't mean we added or didn't add items to the send-to menu
+ return 0;
+ case ML_TYPE_STREAMNAMES: // doesn't make sense to burn a stream to an ISO file so we won't even popup on the send-to menu when it's streams
+ case ML_TYPE_CDTRACKS: // we'll avoid CD tracks. in theory we could use the ripping API but let's not complicate this example
+ case ML_TYPE_QUERYSTRING: // media library query. not sure that this is even used anywhere. either way we're not going to handle it
+ case ML_TYPE_STREAMNAMESW: // don't cross the streams
+ case ML_TYPE_TREEITEM: // not even sure this is used
+ // break out of here because it's not supported. returning 0 just tells the send-to menu to continue building,
+ // it doesn't mean we added or didn't add items to the send-to menu
+ return 0;
+ }
+ // shouldn't get here
+ return 0;
+ }
+
+// this gets sent when a send-to menu item got selected
+ // it might be ours. it might not.
+ case ML_MSG_ONSENDTOSELECT:
+ {
+ // let's see if it's ours. We check 'user32' against the function pointer for this function
+ INT_PTR unique = param3;
+ if (unique != (INT_PTR)MessageProc) // not ours? let's bail
+ return 0; // remember to always return 0 or else other media library plugins won't get the notification
+
+ INT_PTR type = param1; // what type of data got sent
+ INT_PTR data = param2; // pointer to the data. depends on the type
+
+ switch(type)
+ {
+ case ML_TYPE_ITEMRECORDLIST: // Item Record List. Used by the local media library
+ ConvertItemRecordListToISO((const itemRecordList *)data);
+ return 1; // return 1 to say we handled it
+ case ML_TYPE_FILENAMES: // raw list of filenames
+ ConvertFilenamesToISO((const char *)data);
+ return 1; // return 1 to say we handled it
+ case ML_TYPE_PLAYLIST: // a playlist. we'll use the playlist loading API to crack it open
+ ConvertPlaylistToISO((const mlPlaylist *)data);
+ return 1; // return 1 to say we handled it
+ case ML_TYPE_PLAYLISTS: // a list of playlists. we'll use the playlist loading API to crack each one open
+ ConvertPlaylistsToISO((const mlPlaylist **)data);
+ return 1; // return 1 to say we handled it
+ case ML_TYPE_ITEMRECORDLISTW: // unicode version of an Item Record List
+ ConvertUnicodeItemRecordListToISO((const itemRecordListW *)data);
+ return 1; // return 1 to say we handled it
+ case ML_TYPE_FILENAMESW: // raw list of unicode filenames
+ ConvertUnicodeFilenamesToISO((const wchar_t *)data);
+ return 1; // return 1 to say we handled it
+
+ default: // something we didn't support
+ return 0;
+ }
+ }
+ }
+ return 0;
+}
+
+winampMediaLibraryPlugin plugin =
+{
+ MLHDR_VER,
+ "ISO Creator",
+ Init,
+ Quit,
+ MessageProc,
+ 0,
+ 0,
+ 0,
+};
+
+extern "C" __declspec(dllexport) winampMediaLibraryPlugin *winampGetMediaLibraryPlugin()
+ {
+ return &plugin;
+ }
diff --git a/Src/Plugins/SDK/ml_iso/main.h b/Src/Plugins/SDK/ml_iso/main.h
new file mode 100644
index 00000000..f9b04b6e
--- /dev/null
+++ b/Src/Plugins/SDK/ml_iso/main.h
@@ -0,0 +1,12 @@
+#pragma once
+#include "..\..\General\gen_ml\ml.h"
+
+extern winampMediaLibraryPlugin plugin;
+
+void ConvertItemRecordListToISO(const itemRecordList *list);
+void ConvertFilenamesToISO(const char *filenames);
+void ConvertPlaylistToISO(const mlPlaylist *playlist);
+void ConvertPlaylistsToISO(const mlPlaylist **playlist);
+void ConvertUnicodeItemRecordListToISO(const itemRecordListW *list);
+void ConvertUnicodeFilenamesToISO(const wchar_t *filenames);
+
diff --git a/Src/Plugins/SDK/ml_iso/ml_iso.rc b/Src/Plugins/SDK/ml_iso/ml_iso.rc
new file mode 100644
index 00000000..07c90471
--- /dev/null
+++ b/Src/Plugins/SDK/ml_iso/ml_iso.rc
@@ -0,0 +1,122 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "#include ""version.rc2""\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Bitmap
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Accelerator
+//
+
+IDR_VIEW_BM_ACCELERATORS ACCELERATORS
+BEGIN
+
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE
+BEGIN
+ IDS_NULLSOFT_ISO "Nullsoft ISO Example Media Library Plug-in v%s"
+ 65535 "{A3A1E7C0-761B-4391-A08A-F0D7AF38931C}"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_ISO "ISO"
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#include "version.rc2"
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/Src/Plugins/SDK/ml_iso/ml_iso.sln b/Src/Plugins/SDK/ml_iso/ml_iso.sln
new file mode 100644
index 00000000..cc6aefdf
--- /dev/null
+++ b/Src/Plugins/SDK/ml_iso/ml_iso.sln
@@ -0,0 +1,24 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.32802.440
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ml_iso", "ml_iso.vcxproj", "{229EE189-137B-4E20-804D-CA1F71810332}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x86 = Debug|x86
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {229EE189-137B-4E20-804D-CA1F71810332}.Debug|x86.ActiveCfg = Debug|Win32
+ {229EE189-137B-4E20-804D-CA1F71810332}.Debug|x86.Build.0 = Debug|Win32
+ {229EE189-137B-4E20-804D-CA1F71810332}.Release|x86.ActiveCfg = Release|Win32
+ {229EE189-137B-4E20-804D-CA1F71810332}.Release|x86.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {85243140-49BA-42D9-AC20-4B3F643E9127}
+ EndGlobalSection
+EndGlobal
diff --git a/Src/Plugins/SDK/ml_iso/ml_iso.vcxproj b/Src/Plugins/SDK/ml_iso/ml_iso.vcxproj
new file mode 100644
index 00000000..97c12b70
--- /dev/null
+++ b/Src/Plugins/SDK/ml_iso/ml_iso.vcxproj
@@ -0,0 +1,246 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{229EE189-137B-4E20-804D-CA1F71810332}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>16.0.32629.160</_ProjectFileVersion>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ <LinkIncremental>false</LinkIncremental>
+ <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules />
+ <CodeAnalysisRuleAssemblies />
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules />
+ <CodeAnalysisRuleAssemblies />
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ <LinkIncremental>false</LinkIncremental>
+ <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules />
+ <CodeAnalysisRuleAssemblies />
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules />
+ <CodeAnalysisRuleAssemblies />
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg">
+ <VcpkgEnabled>false</VcpkgEnabled>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <VcpkgConfiguration>Debug</VcpkgConfiguration>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..;..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;ML_ISO_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
+ <PrecompiledHeader />
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..;..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;ML_ISO_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MinSpace</Optimization>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..;..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;ML_ISO_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
+ <PrecompiledHeader />
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <IgnoreSpecificDefaultLibraries>msvcprt.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <Optimization>MinSpace</Optimization>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..;..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;ML_ISO_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <IgnoreSpecificDefaultLibraries>msvcprt.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="main.cpp" />
+ <ClCompile Include="ToISO.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="api__ml_iso.h" />
+ <ClInclude Include="main.h" />
+ <ClInclude Include="resource.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="ml_iso.rc" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/Src/Plugins/SDK/ml_iso/ml_iso.vcxproj.filters b/Src/Plugins/SDK/ml_iso/ml_iso.vcxproj.filters
new file mode 100644
index 00000000..2e8c4e3d
--- /dev/null
+++ b/Src/Plugins/SDK/ml_iso/ml_iso.vcxproj.filters
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="main.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="ToISO.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="main.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="api__ml_iso.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="resource.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="ml_iso.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/Src/Plugins/SDK/ml_iso/resource.h b/Src/Plugins/SDK/ml_iso/resource.h
new file mode 100644
index 00000000..d24b69a0
--- /dev/null
+++ b/Src/Plugins/SDK/ml_iso/resource.h
@@ -0,0 +1,26 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by ml_iso.rc
+//
+#define IDS_ISO 1
+#define IDR_MENU1 101
+#define IDC_CURSOR1 105
+#define IDB_BITMAP1 106
+#define IDR_VIEW_BM_ACCELERATORS 111
+#define IDC_BUTTON_CUSTOM 1000
+#define IDC_LIST 1001
+#define ID_Menu 40001
+#define ID_ISO_HELP 40002
+#define ID_ISO_SENDTO 40003
+#define IDS_NULLSOFT_ISO 65534
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 112
+#define _APS_NEXT_COMMAND_VALUE 40004
+#define _APS_NEXT_CONTROL_VALUE 1002
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/Src/Plugins/SDK/ml_iso/version.rc2 b/Src/Plugins/SDK/ml_iso/version.rc2
new file mode 100644
index 00000000..7298f068
--- /dev/null
+++ b/Src/Plugins/SDK/ml_iso/version.rc2
@@ -0,0 +1,39 @@
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+#include "..\..\..\Winamp\buildType.h"
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,1
+ PRODUCTVERSION WINAMP_PRODUCTVER
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", "Winamp SA"
+ VALUE "FileDescription", "Winamp Media Library Plug-in"
+ VALUE "FileVersion", "1,0,0,1"
+ VALUE "InternalName", "Nullsoft ISO"
+ VALUE "LegalCopyright", "Copyright © 2003-2023 Winamp SA"
+ VALUE "LegalTrademarks", "Nullsoft and Winamp are trademarks of Winamp SA"
+ VALUE "OriginalFilename", "ml_iso.dll"
+ VALUE "ProductName", "Winamp"
+ VALUE "ProductVersion", STR_WINAMP_PRODUCTVER
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/Src/Plugins/SDK/ml_xmlex/api.h b/Src/Plugins/SDK/ml_xmlex/api.h
new file mode 100644
index 00000000..28cf5548
--- /dev/null
+++ b/Src/Plugins/SDK/ml_xmlex/api.h
@@ -0,0 +1,38 @@
+#ifndef NULLSOFT_API_H
+#define NULLSOFT_API_H
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once
+#endif
+
+#include <wtypes.h>
+
+#include <api/service/api_service.h>
+extern api_service *serviceManager;
+#define WASABI_API_SVC serviceManager
+
+#include <api/application/api_application.h>
+#define WASABI_API_APP applicationApi
+
+#include <api/service/waServiceFactory.h>
+
+#include "../Agave/Config/api_config.h"
+extern api_config *configApi;
+#define AGAVE_API_CONFIG configApi
+
+#include "../Agave/Language/api_language.h"
+
+#include "../Winamp/api_stats.h"
+extern api_stats *statsApi;
+#define AGAVE_API_STATS statsApi
+
+#include "../playlist/api_playlistmanager.h"
+extern api_playlistmanager *playlistManagerApi;
+#define AGAVE_API_PLAYLISTMANAGER playlistManagerApi
+
+HRESULT WasabiApi_Initialize(HINSTANCE hInstance, api_service *serviceApi);
+HRESULT WasabiApi_LoadDefaults();
+ULONG WasabiApi_AddRef(void);
+ULONG WasabiApi_Release(void);
+
+#endif
diff --git a/Src/Plugins/SDK/ml_xmlex/main.cpp b/Src/Plugins/SDK/ml_xmlex/main.cpp
new file mode 100644
index 00000000..bc0f69e4
--- /dev/null
+++ b/Src/Plugins/SDK/ml_xmlex/main.cpp
@@ -0,0 +1,69 @@
+#include "main.h"
+#include "../Winamp/wa_ipc.h"
+#include "resource.h"
+#include "api.h"
+#include "../nu/AutoWide.h"
+#include "../nu/AutoChar.h"
+#include <strsafe.h>
+#include "..\..\General\gen_ml\menu.h"
+#include "..\..\General\gen_ml\ml_ipc_0313.h"
+
+#define PLUGIN_VERSION L"1.1"
+
+int Init();
+void Quit();
+UINT_PTR xmlex_treeItem = 0;
+api_service *serviceManager = 0;
+
+EXTERN_C winampMediaLibraryPlugin plugin =
+{
+ MLHDR_VER,
+ "Nullsoft XML Reader",
+ Init,
+ Quit,
+ xmlex_pluginMessageProc,
+ 0,
+ 0,
+ 0,
+};
+
+int Init()
+{
+ //starting point for wasabi, where services are shared
+ WASABI_API_SVC = (api_service *)SendMessage(plugin.hwndWinampParent, WM_WA_IPC, 0, IPC_GET_API_SERVICE);
+
+ // waServiceFactory *sf = plugin.service->service_getServiceByGuid(languageApiGUID);
+ // if (sf) WASABI_API_LNG = reinterpret_cast<api_language*>(sf->getInterface());
+
+ // wasabi based services for localisation support
+ // api_language* WASABI_API_LNG = 0;
+ // HINSTANCE WASABI_API_LNG_HINST = 0, WASABI_API_ORIG_HINST = 0;
+
+ // need to have this initialised before we try to do anything with localisation features
+ // WASABI_API_START_LANG(plugin.hDllInstance,MlImpexLangGUID);
+
+ // static wchar_t szDescription[256];
+ // StringCchPrintf(szDescription, ARRAYSIZE(szDescription),
+ // WASABI_API_LNGSTRINGW(IDS_NULLSOFT_XMLEX), PLUGIN_VERSION);
+ // plugin.description = (char*)szDescription;
+
+ //set up tree item, gen_ml will call xmlex_pluginMessageProc if/when the treeview item gets selected
+ MLTREEITEMW newTree;
+ newTree.size = sizeof(MLTREEITEMW);
+ newTree.parentId = 0;
+ newTree.title = L"XML Example";
+ newTree.hasChildren = 0;
+ newTree.id = 0;
+ SendMessage(plugin.hwndLibraryParent, WM_ML_IPC, (WPARAM) &newTree, ML_IPC_TREEITEM_ADDW);
+ xmlex_treeItem = newTree.id;
+ return 0; // 0 for success. returning non-zero will cause gen_ml to abort loading your plugin
+}
+
+void Quit()
+{
+}
+
+extern "C" __declspec(dllexport) winampMediaLibraryPlugin *winampGetMediaLibraryPlugin()
+{
+ return &plugin;
+} \ No newline at end of file
diff --git a/Src/Plugins/SDK/ml_xmlex/main.h b/Src/Plugins/SDK/ml_xmlex/main.h
new file mode 100644
index 00000000..d0b8b435
--- /dev/null
+++ b/Src/Plugins/SDK/ml_xmlex/main.h
@@ -0,0 +1,13 @@
+#ifndef _XMLEX_MAIN_H_
+#define _XMLEX_MAIN_H_
+#include <windows.h>
+#include <windowsx.h>
+#include "../nu/MediaLibraryInterface.h"
+#include "..\..\General\gen_ml\ml.h"
+#include "..\..\General\gen_ml\config.h"
+
+extern winampMediaLibraryPlugin plugin;
+INT_PTR xmlex_pluginMessageProc(int message_type, INT_PTR param1, INT_PTR param2, INT_PTR param3);
+extern UINT_PTR xmlex_treeItem;
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/SDK/ml_xmlex/ml_xmlex.rc b/Src/Plugins/SDK/ml_xmlex/ml_xmlex.rc
new file mode 100644
index 00000000..6c22ba12
--- /dev/null
+++ b/Src/Plugins/SDK/ml_xmlex/ml_xmlex.rc
@@ -0,0 +1,108 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "#include ""version.rc2""\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_VIEW_XMLEX DIALOGEX 0, 0, 215, 120
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_CLIPSIBLINGS |
+ WS_CLIPCHILDREN
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ CONTROL "",IDC_LIST,"SysListView32",LVS_REPORT |
+ LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_TABSTOP,0,0,
+ 214,103
+ CONTROL "Load XML File",IDC_LOAD,"Button",BS_OWNERDRAW |
+ WS_TABSTOP,0,106,50,11
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_VIEW_XMLEX, DIALOG
+ BEGIN
+ RIGHTMARGIN, 214
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE
+BEGIN
+ IDS_NULLSOFT_XMLEX "Nullsoft XML Reader"
+ 65535 "{1A710E67-5180-49ac-8102-105856ED0A2F}"
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#include "version.rc2"
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/Src/Plugins/SDK/ml_xmlex/ml_xmlex.sln b/Src/Plugins/SDK/ml_xmlex/ml_xmlex.sln
new file mode 100644
index 00000000..e63e5ba8
--- /dev/null
+++ b/Src/Plugins/SDK/ml_xmlex/ml_xmlex.sln
@@ -0,0 +1,24 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.32802.440
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ml_xmlex", "ml_xmlex.vcxproj", "{BB556FAF-21F5-418E-9BDE-1F9EFF4AA042}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x86 = Debug|x86
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {BB556FAF-21F5-418E-9BDE-1F9EFF4AA042}.Debug|x86.ActiveCfg = Debug|Win32
+ {BB556FAF-21F5-418E-9BDE-1F9EFF4AA042}.Debug|x86.Build.0 = Debug|Win32
+ {BB556FAF-21F5-418E-9BDE-1F9EFF4AA042}.Release|x86.ActiveCfg = Release|Win32
+ {BB556FAF-21F5-418E-9BDE-1F9EFF4AA042}.Release|x86.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {BE4BA4B4-72CA-4EA3-A44E-C3B01B5DE34F}
+ EndGlobalSection
+EndGlobal
diff --git a/Src/Plugins/SDK/ml_xmlex/ml_xmlex.vcxproj b/Src/Plugins/SDK/ml_xmlex/ml_xmlex.vcxproj
new file mode 100644
index 00000000..6550896b
--- /dev/null
+++ b/Src/Plugins/SDK/ml_xmlex/ml_xmlex.vcxproj
@@ -0,0 +1,241 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{BB556FAF-21F5-418E-9BDE-1F9EFF4AA042}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>16.0.32629.160</_ProjectFileVersion>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ <LinkIncremental>false</LinkIncremental>
+ <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules />
+ <CodeAnalysisRuleAssemblies />
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules />
+ <CodeAnalysisRuleAssemblies />
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ <LinkIncremental>false</LinkIncremental>
+ <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules />
+ <CodeAnalysisRuleAssemblies />
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules />
+ <CodeAnalysisRuleAssemblies />
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg">
+ <VcpkgEnabled>false</VcpkgEnabled>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <VcpkgConfiguration>Debug</VcpkgConfiguration>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..;..\..\..\wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader />
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..;..\..\..\wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MinSpace</Optimization>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..;..\..\..\wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
+ <PrecompiledHeader />
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <Optimization>MinSpace</Optimization>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..;..\..\..\wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="main.cpp" />
+ <ClCompile Include="xmlview.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="main.h" />
+ <ClInclude Include="resource.h" />
+ <ClInclude Include="api.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="ml_xmlex.rc" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\..\Wasabi\Wasabi.vcxproj">
+ <Project>{3e0bfa8a-b86a-42e9-a33f-ec294f823f7f}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/Src/Plugins/SDK/ml_xmlex/ml_xmlex.vcxproj.filters b/Src/Plugins/SDK/ml_xmlex/ml_xmlex.vcxproj.filters
new file mode 100644
index 00000000..dc42c30b
--- /dev/null
+++ b/Src/Plugins/SDK/ml_xmlex/ml_xmlex.vcxproj.filters
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="main.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="xmlview.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="main.h">
+ <Filter>Source Files</Filter>
+ </ClInclude>
+ <ClInclude Include="api.h">
+ <Filter>Source Files</Filter>
+ </ClInclude>
+ <ClInclude Include="resource.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="ml_xmlex.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/Src/Plugins/SDK/ml_xmlex/readme.txt b/Src/Plugins/SDK/ml_xmlex/readme.txt
new file mode 100644
index 00000000..26c78641
--- /dev/null
+++ b/Src/Plugins/SDK/ml_xmlex/readme.txt
@@ -0,0 +1,13 @@
+ml_xmlex.dll - Readme
+
+This is an example of implementation of Winamp's built in XML parser. Please make note that Winamp's XML service will parse all syntactically correct xml.
+
+XML file form for this plugin is exemplified in xmltest.xml, which is provided with the source for this plugin.
+XML files should be in the format of
+
+ <Library>
+ <Song Filename="" Artist="" Title="" /> (or)
+ <Song Filename="" Artist"" Title=""></Song>
+ </Library>
+
+with the extension .xml for this plugin to read it correctly. \ No newline at end of file
diff --git a/Src/Plugins/SDK/ml_xmlex/resource.h b/Src/Plugins/SDK/ml_xmlex/resource.h
new file mode 100644
index 00000000..8a39fb64
--- /dev/null
+++ b/Src/Plugins/SDK/ml_xmlex/resource.h
@@ -0,0 +1,22 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by ml_xmlex.rc
+//
+
+#define IDS_NULLSOFT_XMLEX_OLD 0
+#define IDD_VIEW_XMLEX 101
+#define IDC_LIST 1001
+#define IDC_BUTTON1 1002
+#define IDC_LOAD 1003
+#define IDS_NULLSOFT_XMLEX 65534
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 102
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1004
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/Src/Plugins/SDK/ml_xmlex/version.rc2 b/Src/Plugins/SDK/ml_xmlex/version.rc2
new file mode 100644
index 00000000..6e4abc80
--- /dev/null
+++ b/Src/Plugins/SDK/ml_xmlex/version.rc2
@@ -0,0 +1,39 @@
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+#include "..\..\..\Winamp\buildType.h"
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,1
+ PRODUCTVERSION WINAMP_PRODUCTVER
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", "Winamp SA"
+ VALUE "FileDescription", "Winamp Media Library Plug-in"
+ VALUE "FileVersion", "1,0,0,1"
+ VALUE "InternalName", "Nullsoft XML Playlist Loader"
+ VALUE "LegalCopyright", "Copyright © 2003-2023 Winamp SA"
+ VALUE "LegalTrademarks", "Nullsoft and Winamp are trademarks of Winamp SA"
+ VALUE "OriginalFilename", "ml_xmlex.dll"
+ VALUE "ProductName", "Winamp"
+ VALUE "ProductVersion", STR_WINAMP_PRODUCTVER
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/Src/Plugins/SDK/ml_xmlex/xmltest.xml b/Src/Plugins/SDK/ml_xmlex/xmltest.xml
new file mode 100644
index 00000000..719208fc
--- /dev/null
+++ b/Src/Plugins/SDK/ml_xmlex/xmltest.xml
@@ -0,0 +1,8 @@
+<!-- all valid versions of this in xml will work, however, filename, artist, and title must all be attributes of Song -->
+<Library>
+<Song Filename="C:\Music\artist - title.mp3" Artist="artist1" Title="title1"/>
+<Song Filename="C:\Music\artist2 - title2.wma" Artist="artist2" Title="title2"></Song>
+<Song Title="title3" Filename="C:\Music\artist3 - title3.mp3" Artist="artist3"/>
+<Song Filename="C:\Music\artist4 - title4.ogg" Title="title4" Artist="artist4"/>
+<Song Filename="C:\Music\artist5 - title5.aac" Artist="artist5" Title="title5"/>
+</Library> \ No newline at end of file
diff --git a/Src/Plugins/SDK/ml_xmlex/xmltest2.xml b/Src/Plugins/SDK/ml_xmlex/xmltest2.xml
new file mode 100644
index 00000000..b325ef57
--- /dev/null
+++ b/Src/Plugins/SDK/ml_xmlex/xmltest2.xml
@@ -0,0 +1,7 @@
+<Library>
+<Song Filename="C:\Music\artist1 - title1.mp3" Artist="artist" Title="title"/>
+<Song Filename="C:\Music\artist2 - title2.wma" Artist="artist2" Title="title2"/>
+<Song Filename="C:\Music\artist3 - title3.mp3" Artist="artist3" Title="title3"/>
+<Song Filename="C:\Music\artist4 - title4.ogg" Artist="artist4" Title="title4"/>
+<Song Filename="C:\Music\artist5 - title5.aac" Artist="artist5" Title="title5"/>
+</Library> \ No newline at end of file
diff --git a/Src/Plugins/SDK/ml_xmlex/xmlview.cpp b/Src/Plugins/SDK/ml_xmlex/xmlview.cpp
new file mode 100644
index 00000000..463df934
--- /dev/null
+++ b/Src/Plugins/SDK/ml_xmlex/xmlview.cpp
@@ -0,0 +1,301 @@
+#include "main.h"
+#include <bfc/dispatch.h>
+#include <windowsx.h>
+#include "shlobj.h"
+#include "..\..\General\gen_ml\ml_ipc_0313.h"
+#include "..\..\General\gen_ml\childwnd.h"
+#include "../Winamp/wa_dlg.h"
+#include "../xml/ifc_xmlreadercallback.h"
+#include "../xml/obj_xml.h"
+#include <api/service/waServiceFactory.h>
+#include "resource.h"
+#include "api.h"
+
+typedef void (*ChildResizeFunc)(HWND, ChildWndResizeItem*, int);
+static ChildResizeFunc ml_childresize_init=0, ml_childresize_resize=0;
+
+typedef int (*HookDialogFunc)(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
+static HookDialogFunc ml_hook_dialog_msg = 0;
+
+typedef void (*DrawFunc)(HWND hwndDlg, int *tab, int tabsize);
+static DrawFunc ml_draw = 0;
+
+LRESULT CALLBACK view_xmlexDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam);
+static HWND m_hwnd;
+
+static ChildWndResizeItem xmlwnd_rlist[]={
+ {IDC_LIST,0x0011},
+ {IDC_LOAD,0x0101},
+};
+
+//--------------------------
+
+class ListXMLLoader : public ifc_xmlreadercallback
+{
+public:
+ ListXMLLoader(HWND _hwndList) : hwndList(_hwndList), index(0) {}
+ void loadSongFromXml(const wchar_t* filename, const wchar_t* artist, const wchar_t* title)
+ {
+ LVITEM lvi = {0, };
+ lvi.mask = LVIF_TEXT;
+ lvi.iItem = index;
+ lvi.pszText = (LPTSTR)filename;
+ lvi.cchTextMax = lstrlenW(filename);
+ SendMessage(hwndList, LVM_INSERTITEMW, 0, (LPARAM)&lvi);
+
+ lvi.iSubItem = 1;
+ lvi.pszText = (LPTSTR)artist;
+ lvi.cchTextMax = lstrlenW(artist);
+ SendMessageW(hwndList, LVM_SETITEMW, 0, (LPARAM)&lvi);
+
+ lvi.iSubItem = 2;
+ lvi.pszText = (LPTSTR)title;
+ lvi.cchTextMax = lstrlenW(title);
+ SendMessageW(hwndList, LVM_SETITEMW, 0, (LPARAM)&lvi);
+
+ index++;
+ }
+ void reset()
+ {
+ ListView_DeleteAllItems(hwndList);
+ index = 0;
+ }
+ void loadXML(wchar_t []);
+
+ /* XML loader callback */
+ void StartTag(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params)
+ {
+ //read subtags of LIBRARY
+ if(!wcsicmp(xmlpath, L"LIBRARY\fSONG"))
+ {
+ //getItemValue() will return the value for an attribute
+ loadSongFromXml(params->getItemValue(L"FILENAME"), params->getItemValue(L"ARTIST"),params->getItemValue(L"TITLE"));
+ }
+ }
+
+private:
+ HWND hwndList;
+ int index;
+
+protected: // this is a Wasabi object, so we need to declare a dispatch table
+ RECVS_DISPATCH;
+};
+
+/* Dispatch table for a Wasabi object */
+#define CBCLASS ListXMLLoader
+START_DISPATCH;
+VCB(ONSTARTELEMENT, StartTag)
+END_DISPATCH;
+#undef CBCLASS
+
+/* helper function for ListXMLLoader::loadXML */
+static bool LoadFile(obj_xml *parser, const wchar_t *filename)
+{
+ HANDLE file = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL);
+
+ if (file == INVALID_HANDLE_VALUE)
+ return false;
+
+ char data[1024];
+
+ DWORD bytesRead;
+ while (true)
+ {
+ if (ReadFile(file, data, 1024, &bytesRead, NULL) && bytesRead)
+ {
+ parser->xmlreader_feed(data, bytesRead);
+ }
+ else
+ break;
+ }
+
+ CloseHandle(file);
+ parser->xmlreader_feed(0, 0);
+
+ return true;
+}
+
+void ListXMLLoader::loadXML(wchar_t xmlfile[MAX_PATH] = L"xmltest.xml")
+{
+ // reset the listview state
+ reset();
+
+ // get an XML parser object from the service manager
+ obj_xml *parser=0;
+ waServiceFactory *parserFactory = WASABI_API_SVC->service_getServiceByGuid(obj_xmlGUID);
+ if (parserFactory)
+ parser = (obj_xml *)parserFactory->getInterface();
+
+ if (parser)
+ {
+ //set up a tag that we can read
+ //within StartTag(), we can read all subtags of this tag
+ parser->xmlreader_registerCallback(L"LIBRARY\f*", this);
+ parser->xmlreader_open();
+
+ LoadFile(parser, xmlfile);
+
+ parser->xmlreader_unregisterCallback(this);
+ parser->xmlreader_close();
+ parserFactory->releaseInterface(parser);
+ }
+}
+//--------------------------
+
+/* This function gets called directly from gen_ml when it wants our plugin to do something
+ we're only handling dialog creation, but there are lots of other messages a full-featured
+ plugin would deal with */
+
+INT_PTR xmlex_pluginMessageProc(int message_type, INT_PTR param1, INT_PTR param2, INT_PTR param3)
+{
+ if (message_type == ML_MSG_TREE_ONCREATEVIEW && param1 == xmlex_treeItem)
+ {
+ return (INT_PTR)CreateDialog(plugin.hDllInstance, MAKEINTRESOURCE(IDD_VIEW_XMLEX), (HWND)(LONG_PTR)param2, (DLGPROC)view_xmlexDialogProc);
+ }
+ return 0;
+}
+
+static BOOL xmlex_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam)
+{
+ /* gen_ml has some helper functions to deal with skinned dialogs,
+ we're going to grab their function pointers.
+ for definition of magic numbers, see gen_ml/ml.h */
+ if (!ml_childresize_init)
+ {
+ /* skinning helper functions */
+ ml_hook_dialog_msg = (HookDialogFunc)SendMessage(plugin.hwndLibraryParent, WM_ML_IPC, (WPARAM)2, ML_IPC_SKIN_WADLG_GETFUNC);
+ ml_draw = (DrawFunc)SendMessage(plugin.hwndLibraryParent, WM_ML_IPC, (WPARAM)3, ML_IPC_SKIN_WADLG_GETFUNC);
+
+ /* resizing helper functions */
+ ml_childresize_init = (ChildResizeFunc)SendMessage(plugin.hwndLibraryParent, WM_ML_IPC, (WPARAM)32, ML_IPC_SKIN_WADLG_GETFUNC);
+ ml_childresize_resize = (ChildResizeFunc)SendMessage(plugin.hwndLibraryParent, WM_ML_IPC, (WPARAM)33, ML_IPC_SKIN_WADLG_GETFUNC);
+ }
+
+ m_hwnd=hwnd;
+ HWND listWnd = GetDlgItem(hwnd,IDC_LIST);
+
+ /* add listview columns */
+ LVCOLUMN lvc = {0, };
+ lvc.mask = LVCF_TEXT | LVCF_WIDTH;
+ lvc.pszText = (LPTSTR)L"Filename";
+ lvc.cx = 250;
+ SendMessageW(listWnd, LVM_INSERTCOLUMNW, (WPARAM)0, (LPARAM)&lvc);
+
+ lvc.pszText = (LPTSTR)L"Artist";
+ lvc.cx = 150;
+ SendMessageW(listWnd, LVM_INSERTCOLUMNW, (WPARAM)1, (LPARAM)&lvc);
+
+ lvc.pszText = (LPTSTR)L"Title";
+ lvc.cx = 150;
+ SendMessageW(listWnd, LVM_INSERTCOLUMNW, (WPARAM)2, (LPARAM)&lvc);
+
+ /* skin dialog */
+ MLSKINWINDOW sw;
+ sw.skinType = SKINNEDWND_TYPE_DIALOG;
+ sw.style = SWS_USESKINCOLORS | SWS_USESKINCURSORS | SWS_USESKINFONT;
+ sw.hwndToSkin = hwnd;
+ MLSkinWindow(plugin.hwndLibraryParent, &sw);
+
+ /* skin listview */
+ sw.hwndToSkin = listWnd;
+ sw.skinType = SKINNEDWND_TYPE_LISTVIEW;
+ sw.style = SWLVS_FULLROWSELECT | SWLVS_DOUBLEBUFFER | SWS_USESKINFONT | SWS_USESKINCOLORS | SWS_USESKINCURSORS;
+ MLSkinWindow(plugin.hwndLibraryParent, &sw);
+
+ /* skin button */
+ sw.skinType = SKINNEDWND_TYPE_BUTTON;
+ sw.style = SWS_USESKINCOLORS | SWS_USESKINCURSORS | SWS_USESKINFONT;
+ sw.hwndToSkin = GetDlgItem(hwnd, IDC_LOAD);
+ MLSkinWindow(plugin.hwndLibraryParent, &sw);
+
+ ml_childresize_init(hwnd, xmlwnd_rlist, sizeof(xmlwnd_rlist) / sizeof(xmlwnd_rlist[0]));
+
+ //all other initialization is done. lets wait 20ms before we actually do anything with this plugin
+ //this way other (more important) things finish before this does
+ SetTimer(hwnd,101,20,NULL);
+
+ return FALSE;
+}
+
+static BOOL xmlex_OnSize(HWND hwnd, UINT state, int cx, int cy)
+{
+ if (state != SIZE_MINIMIZED)
+ ml_childresize_resize(hwnd, xmlwnd_rlist, sizeof(xmlwnd_rlist) / sizeof(xmlwnd_rlist[0]));
+ return FALSE;
+}
+
+static BOOL xmlex_OnDestroy(HWND hwnd)
+{
+ m_hwnd=0;
+ return FALSE;
+}
+static void xmlex_OnTimer(HWND hwnd, UINT id)
+{
+ if (id == 101)
+ {
+ KillTimer(hwnd,101);
+ // populate list with default local file, no pre-loaded xml file if not in working dir (really will only pre-load something in debug mode)
+ ListXMLLoader loader(GetDlgItem(hwnd, IDC_LIST));
+ loader.loadXML();
+ }
+}
+static BOOL xmlex_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
+{
+ switch(id) {
+ case IDC_LOAD:
+ {
+ wchar_t filename[256] = L"";
+ //browse box supported in windows 2000+
+ //if this doesnt work for you (old versions of windows) just know that the file name is set in ofn.lpstrFile which is then moved to filename variable
+ OPENFILENAME ofn = {0};
+ ofn.lStructSize = sizeof (OPENFILENAME);
+ ofn.hwndOwner=hwnd;
+ ofn.lpstrFilter=L"XML Files (*.xml)\0*.XML\0\0";
+ ofn.lpstrCustomFilter=NULL;
+ ofn.nFilterIndex=1;
+ ofn.lpstrFile=filename; //contains file name after user has selected it
+ ofn.nMaxFile=MAX_PATH;
+ ofn.lpstrFileTitle=NULL;
+ ofn.lpstrInitialDir=NULL;
+ ofn.Flags=OFN_PATHMUSTEXIST;
+ GetOpenFileName(&ofn);
+ if(*filename) //do not load on browse -> cancel
+ {
+ ListXMLLoader loader(GetDlgItem(hwnd, IDC_LIST));
+ loader.loadXML(filename);
+ }
+ }
+ break;
+ }
+ return 0;
+}
+
+LRESULT CALLBACK view_xmlexDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ /* first, ask the dialog skinning system if it wants to do anything with the message
+ the function pointer gets set during WM_INITDIALOG so might be NULL for the first few messages
+ in theory we could grab it right here if we don't have it, but it's not necessary
+ and I wanted to put all the function pointer gathering code in the same place for this example */
+ if (ml_hook_dialog_msg)
+ {
+ INT_PTR a = ml_hook_dialog_msg(hwndDlg, uMsg, wParam, lParam);
+ if (a)
+ return a;
+ }
+
+ switch(uMsg) {
+ HANDLE_MSG(hwndDlg, WM_INITDIALOG, xmlex_OnInitDialog);
+ HANDLE_MSG(hwndDlg, WM_TIMER, xmlex_OnTimer);
+ HANDLE_MSG(hwndDlg, WM_COMMAND, xmlex_OnCommand);
+ HANDLE_MSG(hwndDlg, WM_SIZE, xmlex_OnSize);
+ case WM_PAINT:
+ {
+ int tab[] = { IDC_LIST|DCW_SUNKENBORDER};
+ ml_draw(hwndDlg, tab, sizeof(tab) / sizeof(tab[0]));
+ }
+ return 0;
+ HANDLE_MSG(hwndDlg, WM_DESTROY, xmlex_OnDestroy);
+
+ }
+ return FALSE;
+}
diff --git a/Src/Plugins/SDK/out_null/Out_null.dsp b/Src/Plugins/SDK/out_null/Out_null.dsp
new file mode 100644
index 00000000..7ec8730f
--- /dev/null
+++ b/Src/Plugins/SDK/out_null/Out_null.dsp
@@ -0,0 +1,108 @@
+# Microsoft Developer Studio Project File - Name="out_null" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=out_null - Win32 Release
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "Out_null.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "Out_null.mak" CFG="out_null - Win32 Release"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "out_null - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "out_null - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""$/out_null", KIBAAAAA"
+# PROP Scc_LocalPath "."
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "out_null - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir ".\Release"
+# PROP BASE Intermediate_Dir ".\Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir ".\Release"
+# PROP Intermediate_Dir ".\Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
+# ADD CPP /nologo /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE MTL /nologo /D "NDEBUG" /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /machine:I386 /nodefaultlib /out:"c:\program files\winamp\plugins\out_null.dll"
+
+!ELSEIF "$(CFG)" == "out_null - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir ".\Debug"
+# PROP BASE Intermediate_Dir ".\Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir ".\Debug"
+# PROP Intermediate_Dir ".\Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /debug /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:"c:\program files\winamp\plugins\out_null.dll"
+
+!ENDIF
+
+# Begin Target
+
+# Name "out_null - Win32 Release"
+# Name "out_null - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90"
+# Begin Source File
+
+SOURCE=.\main.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/Src/Plugins/SDK/out_null/Out_null.dsw b/Src/Plugins/SDK/out_null/Out_null.dsw
new file mode 100644
index 00000000..9082bebf
--- /dev/null
+++ b/Src/Plugins/SDK/out_null/Out_null.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "out_null"=.\Out_null.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/Src/Plugins/SDK/out_null/Out_null.sln b/Src/Plugins/SDK/out_null/Out_null.sln
new file mode 100644
index 00000000..36e98e3b
--- /dev/null
+++ b/Src/Plugins/SDK/out_null/Out_null.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.32630.194
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "out_null", "Out_null.vcxproj", "{B8D54893-D578-41CF-B0EF-24C1B340F536}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x86 = Debug|x86
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {B8D54893-D578-41CF-B0EF-24C1B340F536}.Debug|x86.ActiveCfg = Debug|Win32
+ {B8D54893-D578-41CF-B0EF-24C1B340F536}.Debug|x86.Build.0 = Debug|Win32
+ {B8D54893-D578-41CF-B0EF-24C1B340F536}.Release|x86.ActiveCfg = Release|Win32
+ {B8D54893-D578-41CF-B0EF-24C1B340F536}.Release|x86.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {82A636E0-35BE-4DB3-B1AE-3CA392E3BA95}
+ EndGlobalSection
+EndGlobal
diff --git a/Src/Plugins/SDK/out_null/Out_null.vcxproj b/Src/Plugins/SDK/out_null/Out_null.vcxproj
new file mode 100644
index 00000000..eace4a73
--- /dev/null
+++ b/Src/Plugins/SDK/out_null/Out_null.vcxproj
@@ -0,0 +1,296 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectName>out_null</ProjectName>
+ <SccProjectName>"$/out_null", KIBAAAAA</SccProjectName>
+ <SccLocalPath>.</SccLocalPath>
+ <ProjectGuid>{B8D54893-D578-41CF-B0EF-24C1B340F536}</ProjectGuid>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ <LinkIncremental>false</LinkIncremental>
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ <LinkIncremental>false</LinkIncremental>
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg">
+ <VcpkgEnabled>false</VcpkgEnabled>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <VcpkgConfiguration>Debug</VcpkgConfiguration>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+ <FunctionLevelLinking>false</FunctionLevelLinking>
+ <Optimization>Disabled</Optimization>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <WarningLevel>Level3</WarningLevel>
+ <MinimalRebuild>false</MinimalRebuild>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <PrecompiledHeaderOutputFile>.\Debug\Out_null.pch</PrecompiledHeaderOutputFile>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <AdditionalIncludeDirectories>..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Midl>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <TypeLibraryName>.\Debug\Out_null.tlb</TypeLibraryName>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ </Midl>
+ <ResourceCompile>
+ <Culture>0x0409</Culture>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Bscmake>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <OutputFile>.\Debug\Out_null.bsc</OutputFile>
+ </Bscmake>
+ <Link>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <LinkDLL>true</LinkDLL>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+ <FunctionLevelLinking>false</FunctionLevelLinking>
+ <Optimization>Disabled</Optimization>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <PrecompiledHeaderOutputFile>.\Debug\Out_null.pch</PrecompiledHeaderOutputFile>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <AdditionalIncludeDirectories>..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Midl>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <TypeLibraryName>.\Debug\Out_null.tlb</TypeLibraryName>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ </Midl>
+ <ResourceCompile>
+ <Culture>0x0409</Culture>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Bscmake>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <OutputFile>.\Debug\Out_null.bsc</OutputFile>
+ </Bscmake>
+ <Link>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <LinkDLL>true</LinkDLL>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+ <StringPooling>true</StringPooling>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <Optimization>MaxSpeed</Optimization>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <WarningLevel>Level3</WarningLevel>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <PrecompiledHeaderOutputFile>.\Release\Out_null.pch</PrecompiledHeaderOutputFile>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ <AdditionalIncludeDirectories>..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Midl>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <TypeLibraryName>.\Release\Out_null.tlb</TypeLibraryName>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ </Midl>
+ <ResourceCompile>
+ <Culture>0x0409</Culture>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Bscmake>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <OutputFile>.\Release\Out_null.bsc</OutputFile>
+ </Bscmake>
+ <Link>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <LinkDLL>true</LinkDLL>
+ <SubSystem>Windows</SubSystem>
+ <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+ <StringPooling>true</StringPooling>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <Optimization>MaxSpeed</Optimization>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <WarningLevel>Level3</WarningLevel>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <PrecompiledHeaderOutputFile>.\Release\Out_null.pch</PrecompiledHeaderOutputFile>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ <AdditionalIncludeDirectories>..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Midl>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <TypeLibraryName>.\Release\Out_null.tlb</TypeLibraryName>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ </Midl>
+ <ResourceCompile>
+ <Culture>0x0409</Culture>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Bscmake>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <OutputFile>.\Release\Out_null.bsc</OutputFile>
+ </Bscmake>
+ <Link>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <LinkDLL>true</LinkDLL>
+ <SubSystem>Windows</SubSystem>
+ <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="main.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="resource.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="out_null.rc" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/Src/Plugins/SDK/out_null/Out_null.vcxproj.filters b/Src/Plugins/SDK/out_null/Out_null.vcxproj.filters
new file mode 100644
index 00000000..472c4d7e
--- /dev/null
+++ b/Src/Plugins/SDK/out_null/Out_null.vcxproj.filters
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{e21794e3-c3bb-45ec-9813-6351aaff4a82}</UniqueIdentifier>
+ <Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{568df85e-3172-4193-826c-888576340f16}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;fi;fd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{92396768-2921-46da-8d9d-ec606b43d772}</UniqueIdentifier>
+ <Extensions>ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="main.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="resource.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="out_null.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/Src/Plugins/SDK/out_null/main.c b/Src/Plugins/SDK/out_null/main.c
new file mode 100644
index 00000000..55eb9906
--- /dev/null
+++ b/Src/Plugins/SDK/out_null/main.c
@@ -0,0 +1,159 @@
+#include <windows.h>
+#include <shlobj.h>
+#include "../winamp/out.h"
+
+#define PI_VER2 "v1.2"
+
+/* #ifdef __alpha
+#define PI_VER PI_VER2 " (AXP)"
+#else
+#define PI_VER PI_VER2 " (x86)"
+#endif */
+
+int getwrittentime();
+int getoutputtime();
+
+int srate, numchan, bps, active;
+volatile int writtentime, w_offset;
+
+
+BOOL WINAPI _DllMainCRTStartup(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
+{
+ return TRUE;
+}
+
+Out_Module out;
+
+static int last_pause=0;
+
+void config(HWND hwnd)
+{
+}
+
+void about(HWND hwnd)
+{
+}
+
+void init()
+{
+}
+
+void quit()
+{
+}
+
+int start_t;
+
+int open(int samplerate, int numchannels, int bitspersamp, int bufferlenms, int prebufferms)
+{
+ start_t=GetTickCount();
+ w_offset = writtentime = 0;
+ active=1;
+ numchan = numchannels;
+ srate = samplerate;
+ bps = bitspersamp;
+ return 1;
+}
+
+void close()
+{
+}
+
+int write(char *buf, int len)
+{
+ writtentime += len;
+ return 0;
+}
+
+int canwrite()
+{
+ if (last_pause) return 0;
+ if (getwrittentime() < getoutputtime()+MulDiv(65536,1000,srate*bps*numchan/8)) return 65536;
+ return 0;
+}
+
+int isplaying()
+{
+ return 0;
+}
+
+int pause(int pause)
+{
+ int t=last_pause;
+ if (!last_pause && pause) { w_offset+=GetTickCount()-start_t; writtentime=0; }
+ if (last_pause && !pause) { start_t=GetTickCount(); }
+ last_pause=pause;
+ return t;
+}
+
+void setvolume(int volume)
+{
+}
+
+void setpan(int pan)
+{
+}
+
+void flush(int t)
+{
+ w_offset=t;
+ start_t=GetTickCount();
+ writtentime=0;
+}
+
+int getoutputtime()
+{
+ if (last_pause)
+ return w_offset;
+ return GetTickCount()-start_t + w_offset;
+}
+
+int getwrittentime()
+{
+ int t=srate*numchan,l;
+ int ms=writtentime;
+
+ if (t)
+ {
+ l=ms%t;
+ ms /= t;
+ ms *= 1000;
+ ms += (l*1000)/t;
+
+ ms/=(bps/8);
+
+ return ms + w_offset;
+ }
+ else
+ return ms;
+}
+
+Out_Module out = {
+ OUT_VER,
+ "Nullsoft NULL Output " PI_VER2
+
+ ,
+ 65,
+ 0, // hmainwindow
+ 0, // hdllinstance
+ config,
+ about,
+ init,
+ quit,
+ open,
+ close,
+ write,
+ canwrite,
+ isplaying,
+ pause,
+ setvolume,
+ setpan,
+ flush,
+ getoutputtime,
+ getwrittentime
+};
+
+__declspec( dllexport ) Out_Module * winampGetOutModule()
+{
+ return &out;
+}
diff --git a/Src/Plugins/SDK/out_null/out_null.rc b/Src/Plugins/SDK/out_null/out_null.rc
new file mode 100644
index 00000000..b8f200a1
--- /dev/null
+++ b/Src/Plugins/SDK/out_null/out_null.rc
@@ -0,0 +1,109 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Polish resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_PLK)
+#ifdef _WIN32
+LANGUAGE LANG_POLISH, SUBLANG_DEFAULT
+#pragma code_page(1250)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "#include ""version.rc2""\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Polish resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.K.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE
+BEGIN
+ IDS_NULLSOFT_NULL_OUTPUT "Nullsoft Null Output v%s"
+ 65535 "{1A710E67-5180-49ac-8102-105856ED0A2F}"
+END
+
+#endif // English (U.K.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#include "version.rc2"
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/Src/Plugins/SDK/out_null/resource.h b/Src/Plugins/SDK/out_null/resource.h
new file mode 100644
index 00000000..8c4033e0
--- /dev/null
+++ b/Src/Plugins/SDK/out_null/resource.h
@@ -0,0 +1,18 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by out_null.rc
+//
+#define IDS_NULLSOFT_NULL_OUTPUT_OLD 0
+
+#define IDS_NULLSOFT_NULL_OUTPUT 65534
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 108
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1037
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/Src/Plugins/SDK/out_null/version.rc2 b/Src/Plugins/SDK/out_null/version.rc2
new file mode 100644
index 00000000..43fce05d
--- /dev/null
+++ b/Src/Plugins/SDK/out_null/version.rc2
@@ -0,0 +1,39 @@
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+#include "..\..\..\Winamp\buildType.h"
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,2,0,1
+ PRODUCTVERSION WINAMP_PRODUCTVER
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", "Winamp SA"
+ VALUE "FileDescription", "Winamp Null Output Plug-in"
+ VALUE "FileVersion", "1,2,0,1"
+ VALUE "InternalName", "Nullsoft Null Output"
+ VALUE "LegalCopyright", "Copyright © 2005-2023 Winamp SA"
+ VALUE "LegalTrademarks", "Nullsoft and Winamp are trademarks of Winamp SA"
+ VALUE "OriginalFilename", "out_null.dll"
+ VALUE "ProductName", "Winamp"
+ VALUE "ProductVersion", STR_WINAMP_PRODUCTVER
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/Src/Plugins/SDK/plLoadEx/ExComponent.cpp b/Src/Plugins/SDK/plLoadEx/ExComponent.cpp
new file mode 100644
index 00000000..a9283fe6
--- /dev/null
+++ b/Src/Plugins/SDK/plLoadEx/ExComponent.cpp
@@ -0,0 +1,32 @@
+#include "ExComponent.h"
+#include "api/service/api_service.h" // Service Manager is central to Wasabi
+#include "SimpleHandlerFactory.h" // the Service Factory we're going to regsister
+
+// the service factory we're going to register
+static SimpleHandlerFactory simpleHandlerFactory;
+
+void ExComponent::RegisterServices(api_service *service)
+{
+ // If we need any services, we can retrieve them here
+ // however, you have no guarantee that a service you want will be active yet
+ // so it's best to "lazy load" and get it the first time you need it
+
+ // Register any services we provide here
+ service->service_register(&simpleHandlerFactory);
+}
+
+void ExComponent::DeregisterServices(api_service *service)
+{
+ // Unregister our services
+ service->service_deregister(&simpleHandlerFactory);
+
+ // And release any services we retrieved
+}
+
+// Define the dispatch table
+#define CBCLASS ExComponent
+START_DISPATCH;
+VCB(API_WA5COMPONENT_REGISTERSERVICES, RegisterServices)
+VCB(API_WA5COMPONENT_DEREEGISTERSERVICES, DeregisterServices)
+END_DISPATCH;
+#undef CBCLASS
diff --git a/Src/Plugins/SDK/plLoadEx/ExComponent.h b/Src/Plugins/SDK/plLoadEx/ExComponent.h
new file mode 100644
index 00000000..fc9e338b
--- /dev/null
+++ b/Src/Plugins/SDK/plLoadEx/ExComponent.h
@@ -0,0 +1,16 @@
+#ifndef NULLSOFT_PLLOADEX_EXCOMPONENT_H
+#define NULLSOFT_PLLOADEX_EXCOMPONENT_H
+
+#include "../Agave/Component/ifc_wa5component.h"
+
+class ExComponent : public ifc_wa5component
+{
+public:
+ void RegisterServices(api_service *service);
+ void DeregisterServices(api_service *service);
+
+protected:
+ RECVS_DISPATCH; // all Wasabi objects implementing a Dispatchable interface require this
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/SDK/plLoadEx/SimpleHandler.cpp b/Src/Plugins/SDK/plLoadEx/SimpleHandler.cpp
new file mode 100644
index 00000000..d541f7f4
--- /dev/null
+++ b/Src/Plugins/SDK/plLoadEx/SimpleHandler.cpp
@@ -0,0 +1,45 @@
+#include "SimpleHandler.h"
+#include "SimpleLoader.h"
+const wchar_t *Cef_Handler::EnumerateExtensions(size_t n)
+{
+ if (n == 0)
+ return L"simple";
+ else
+ return 0;
+}
+
+const wchar_t *Cef_Handler::GetName()
+{
+ return L"Simple Playlist Loader";
+}
+
+int Cef_Handler::SupportedFilename(const wchar_t *filename)
+{
+ size_t filenameLength = wcslen(filename);
+ size_t extensionLength = wcslen(L".simple");
+ if (filenameLength < extensionLength) return SVC_PLAYLISTHANDLER_FAILED; // too short
+ if (!wcsicmp(filename + filenameLength - extensionLength, L".simple"))
+ return SVC_PLAYLISTHANDLER_SUCCESS;
+ else
+ return SVC_PLAYLISTHANDLER_FAILED;
+}
+
+ifc_playlistloader *Cef_Handler::CreateLoader(const wchar_t *filename)
+{
+ return new SimpleLoader();
+}
+
+void Cef_Handler::ReleaseLoader(ifc_playlistloader *loader)
+{
+ delete (SimpleLoader *)loader;
+}
+
+// Define the dispatch table
+#define CBCLASS Cef_Handler
+START_DISPATCH;
+CB(SVC_PLAYLISTHANDLER_ENUMEXTENSIONS, EnumerateExtensions)
+CB(SVC_PLAYLISTHANDLER_SUPPORTFILENAME, SupportedFilename)
+CB(SVC_PLAYLISTHANDLER_CREATELOADER, CreateLoader)
+VCB(SVC_PLAYLISTHANDLER_RELEASELOADER, ReleaseLoader)
+CB(SVC_PLAYLISTHANDLER_GETNAME, GetName)
+END_DISPATCH; \ No newline at end of file
diff --git a/Src/Plugins/SDK/plLoadEx/SimpleHandler.h b/Src/Plugins/SDK/plLoadEx/SimpleHandler.h
new file mode 100644
index 00000000..c0eeeb2d
--- /dev/null
+++ b/Src/Plugins/SDK/plLoadEx/SimpleHandler.h
@@ -0,0 +1,21 @@
+#ifndef NULLSOFT_PLLOADEX_SIMPLEHANDLER_H
+#define NULLSOFT_PLLOADEX_SIMPLEHANDLER_H
+
+#include "../playlist/svc_playlisthandler.h"
+
+class Cef_Handler : public svc_playlisthandler
+{
+public:
+ const wchar_t *EnumerateExtensions(size_t n); // returns 0 when it's done
+ const wchar_t *GetName(); // returns a name suitable for display to user of this playlist form (e.g. PLS Playlist)
+ int SupportedFilename(const wchar_t *filename); // returns SUCCESS and FAILED, so be careful ...
+ ifc_playlistloader *CreateLoader(const wchar_t *filename);
+ void ReleaseLoader(ifc_playlistloader *loader);
+ // there are a few more functions, but we're not going to implement them because we don't need to do, and the Dispatchable interface
+ // provides smart default return values
+
+protected:
+ RECVS_DISPATCH; // all Wasabi objects implementing a Dispatchable interface require this
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/SDK/plLoadEx/SimpleHandlerFactory.cpp b/Src/Plugins/SDK/plLoadEx/SimpleHandlerFactory.cpp
new file mode 100644
index 00000000..4f3ab316
--- /dev/null
+++ b/Src/Plugins/SDK/plLoadEx/SimpleHandlerFactory.cpp
@@ -0,0 +1,56 @@
+#include "SimpleHandlerFactory.h"
+#include "SimpleHandler.h"
+/*
+ This is the GUID for our service factory
+ don't re-use this.
+ make your own guid with guidgen.exe
+ lives somewhere like C:\Program Files\Microsoft Visual Studio\2019\Professional\Common7\Tools
+*/
+
+// {1CCF6445-A452-45e8-BE72-846991CBCAF6}
+static const GUID SimpleHandlerGUID =
+{ 0x1ccf6445, 0xa452, 0x45e8, { 0xbe, 0x72, 0x84, 0x69, 0x91, 0xcb, 0xca, 0xf6 } };
+
+
+// our playlist handler.
+static Cef_Handler simpleHandler;
+
+FOURCC SimpleHandlerFactory::GetServiceType()
+{
+ return svc_playlisthandler::getServiceType();
+}
+
+const char *SimpleHandlerFactory::GetServiceName()
+{
+ return "Simple Playlist Loader";
+}
+
+GUID SimpleHandlerFactory::GetGuid()
+{
+ return SimpleHandlerGUID;
+}
+
+void *SimpleHandlerFactory::GetInterface(int global_lock)
+{
+// simpleHandler is a singleton object, so we can just return a pointer to it
+ // depending on what kind of service you are making, you might have to
+ // 'new' an object and return that instead (and then free it in ReleaseInterface)
+ return &simpleHandler;
+}
+
+int SimpleHandlerFactory::ReleaseInterface(void *ifc)
+{
+ // no-op because we returned a singleton (see above)
+ return 1;
+}
+
+// Define the dispatch table
+#define CBCLASS SimpleHandlerFactory
+START_DISPATCH;
+CB(WASERVICEFACTORY_GETSERVICETYPE, GetServiceType)
+CB(WASERVICEFACTORY_GETSERVICENAME, GetServiceName)
+CB(WASERVICEFACTORY_GETGUID, GetGuid)
+CB(WASERVICEFACTORY_GETINTERFACE, GetInterface)
+CB(WASERVICEFACTORY_RELEASEINTERFACE, ReleaseInterface)
+END_DISPATCH;
+#undef CBCLASS \ No newline at end of file
diff --git a/Src/Plugins/SDK/plLoadEx/SimpleHandlerFactory.h b/Src/Plugins/SDK/plLoadEx/SimpleHandlerFactory.h
new file mode 100644
index 00000000..c4f6c82b
--- /dev/null
+++ b/Src/Plugins/SDK/plLoadEx/SimpleHandlerFactory.h
@@ -0,0 +1,20 @@
+#ifndef NULLSOFT_PLLOADEX_SIMPLEHANDLERFACTORY_H
+#define NULLSOFT_PLLOADEX_SIMPLEHANDLERFACTORY_H
+
+#include "api/service/waservicefactory.h"
+
+class SimpleHandlerFactory : public waServiceFactory
+{
+public:
+ FOURCC GetServiceType();
+ const char *GetServiceName();
+ GUID GetGuid();
+ void *GetInterface(int global_lock = TRUE);
+ int ReleaseInterface(void *ifc);
+
+protected:
+ RECVS_DISPATCH; // all Wasabi objects implementing a Dispatchable interface require this
+
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/SDK/plLoadEx/SimpleLoader.cpp b/Src/Plugins/SDK/plLoadEx/SimpleLoader.cpp
new file mode 100644
index 00000000..ef82e18e
--- /dev/null
+++ b/Src/Plugins/SDK/plLoadEx/SimpleLoader.cpp
@@ -0,0 +1,26 @@
+#include "SimpleLoader.h"
+#include <stdio.h>
+int SimpleLoader::Load(const wchar_t *filename, ifc_playlistloadercallback *playlist)
+{
+ FILE *simpleFile = _wfopen(filename, L"rt");
+ if (simpleFile)
+ {
+ wchar_t nextFile[1024];
+ while (!feof(simpleFile))
+ {
+ if (fgetws(nextFile, 1024, simpleFile))
+ playlist->OnFile(nextFile, 0, -1, 0);
+ }
+ return IFC_PLAYLISTLOADER_SUCCESS;
+ }
+
+ return IFC_PLAYLISTLOADER_FAILED;
+
+}
+
+// Define the dispatch table
+#define CBCLASS SimpleLoader
+START_DISPATCH;
+CB(IFC_PLAYLISTLOADER_LOAD, Load)
+END_DISPATCH;
+#undef CBCLASS \ No newline at end of file
diff --git a/Src/Plugins/SDK/plLoadEx/SimpleLoader.h b/Src/Plugins/SDK/plLoadEx/SimpleLoader.h
new file mode 100644
index 00000000..15d4dbf3
--- /dev/null
+++ b/Src/Plugins/SDK/plLoadEx/SimpleLoader.h
@@ -0,0 +1,14 @@
+#ifndef NULLSOFT_PLLOADEX_SIMPLELOADER_H
+#define NULLSOFT_PLLOADEX_SIMPLELOADER_H
+
+#include "../playlist/ifc_playlistloader.h"
+
+class SimpleLoader : public ifc_playlistloader
+{
+public:
+ int Load(const wchar_t *filename, ifc_playlistloadercallback *playlist);
+protected:
+ RECVS_DISPATCH; // all Wasabi objects implementing a Dispatchable interface require this
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/SDK/plLoadEx/example.simple b/Src/Plugins/SDK/plLoadEx/example.simple
new file mode 100644
index 00000000..4c98c54c
--- /dev/null
+++ b/Src/Plugins/SDK/plLoadEx/example.simple
Binary files differ
diff --git a/Src/Plugins/SDK/plLoadEx/plLoadEx.rc b/Src/Plugins/SDK/plLoadEx/plLoadEx.rc
new file mode 100644
index 00000000..15455697
--- /dev/null
+++ b/Src/Plugins/SDK/plLoadEx/plLoadEx.rc
@@ -0,0 +1,74 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "#include ""version.rc2""\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE
+BEGIN
+ 65535 "{9E398E5F-EDEC-4dd8-A40D-E29B385A88C0}"
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#include "version.rc2"
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/Src/Plugins/SDK/plLoadEx/plLoadEx.sln b/Src/Plugins/SDK/plLoadEx/plLoadEx.sln
new file mode 100644
index 00000000..e0b1ce92
--- /dev/null
+++ b/Src/Plugins/SDK/plLoadEx/plLoadEx.sln
@@ -0,0 +1,24 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.32802.440
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "plLoadEx", "plLoadEx.vcxproj", "{28C5A01B-EA4D-48BF-BCBD-D32515FBA99F}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x86 = Debug|x86
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {28C5A01B-EA4D-48BF-BCBD-D32515FBA99F}.Debug|x86.ActiveCfg = Debug|Win32
+ {28C5A01B-EA4D-48BF-BCBD-D32515FBA99F}.Debug|x86.Build.0 = Debug|Win32
+ {28C5A01B-EA4D-48BF-BCBD-D32515FBA99F}.Release|x86.ActiveCfg = Release|Win32
+ {28C5A01B-EA4D-48BF-BCBD-D32515FBA99F}.Release|x86.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {80A18643-B5B2-4FF2-A66D-8F83807C6D0B}
+ EndGlobalSection
+EndGlobal
diff --git a/Src/Plugins/SDK/plLoadEx/plLoadEx.vcxproj b/Src/Plugins/SDK/plLoadEx/plLoadEx.vcxproj
new file mode 100644
index 00000000..d9936ed4
--- /dev/null
+++ b/Src/Plugins/SDK/plLoadEx/plLoadEx.vcxproj
@@ -0,0 +1,229 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{28C5A01B-EA4D-48BF-BCBD-D32515FBA99F}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>16.0.32629.160</_ProjectFileVersion>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ <LinkIncremental>false</LinkIncremental>
+ <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules />
+ <CodeAnalysisRuleAssemblies />
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ <TargetExt>.w5s</TargetExt>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules />
+ <CodeAnalysisRuleAssemblies />
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ <TargetExt>.w5s</TargetExt>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ <LinkIncremental>false</LinkIncremental>
+ <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules />
+ <CodeAnalysisRuleAssemblies />
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ <TargetExt>.w5s</TargetExt>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules />
+ <CodeAnalysisRuleAssemblies />
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ <TargetExt>.w5s</TargetExt>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg">
+ <VcpkgEnabled>false</VcpkgEnabled>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <VcpkgConfiguration>Debug</VcpkgConfiguration>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..;..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;PLLOADEX_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader />
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..;..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;PLLOADEX_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\..;..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;PLLOADEX_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <PrecompiledHeader />
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\..;..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;PLLOADEX_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="ExComponent.cpp" />
+ <ClCompile Include="SimpleHandler.cpp" />
+ <ClCompile Include="SimpleHandlerFactory.cpp" />
+ <ClCompile Include="SimpleLoader.cpp" />
+ <ClCompile Include="w5s.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="ExComponent.h" />
+ <ClInclude Include="resource.h" />
+ <ClInclude Include="SimpleHandler.h" />
+ <ClInclude Include="SimpleHandlerFactory.h" />
+ <ClInclude Include="SimpleLoader.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="plLoadEx.rc" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/Src/Plugins/SDK/plLoadEx/plLoadEx.vcxproj.filters b/Src/Plugins/SDK/plLoadEx/plLoadEx.vcxproj.filters
new file mode 100644
index 00000000..626ce31a
--- /dev/null
+++ b/Src/Plugins/SDK/plLoadEx/plLoadEx.vcxproj.filters
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="ExComponent.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="SimpleHandler.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="SimpleHandlerFactory.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="SimpleLoader.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="w5s.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="ExComponent.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="SimpleHandler.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="SimpleHandlerFactory.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="SimpleLoader.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="resource.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="plLoadEx.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/Src/Plugins/SDK/plLoadEx/resource.h b/Src/Plugins/SDK/plLoadEx/resource.h
new file mode 100644
index 00000000..d5542519
--- /dev/null
+++ b/Src/Plugins/SDK/plLoadEx/resource.h
@@ -0,0 +1,17 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by plLoadEx.rc
+//
+#define IDS_STRING0 1
+#define IDC_BUTTON1 1001
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 103
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1002
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/Src/Plugins/SDK/plLoadEx/version.rc2 b/Src/Plugins/SDK/plLoadEx/version.rc2
new file mode 100644
index 00000000..6e3a4f55
--- /dev/null
+++ b/Src/Plugins/SDK/plLoadEx/version.rc2
@@ -0,0 +1,39 @@
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+#include "..\..\..\Winamp\buildType.h"
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION WINAMP_PRODUCTVER
+ PRODUCTVERSION WINAMP_PRODUCTVER
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", "Winamp SA"
+ VALUE "FileDescription", "Winamp 5.x System Component"
+ VALUE "FileVersion", STR_WINAMP_PRODUCTVER
+ VALUE "InternalName", "plLoadEx.w5s"
+ VALUE "LegalCopyright", "Copyright © 2005-2023 Winamp SA"
+ VALUE "LegalTrademarks", "Nullsoft and Winamp are trademarks of Winamp SA"
+ VALUE "OriginalFilename", "plLoadEx.w5s"
+ VALUE "ProductName", "Winamp Example Service"
+ VALUE "ProductVersion", STR_WINAMP_PRODUCTVER
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/Src/Plugins/SDK/plLoadEx/w5s.cpp b/Src/Plugins/SDK/plLoadEx/w5s.cpp
new file mode 100644
index 00000000..4d94aa5a
--- /dev/null
+++ b/Src/Plugins/SDK/plLoadEx/w5s.cpp
@@ -0,0 +1,9 @@
+#include "ExComponent.h" // the component we're registering is defined here
+
+ExComponent exComponent; // our component
+
+// Winamp GetProcAddress()'s this after loading your w5s file
+extern "C" __declspec(dllexport) ifc_wa5component *GetWinamp5SystemComponent()
+{
+ return &exComponent;
+}