aboutsummaryrefslogtreecommitdiff
path: root/Src/Plugins/Input/in_mod-openmpt
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/Input/in_mod-openmpt
parent537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff)
downloadwinamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz
Initial community commit
Diffstat (limited to 'Src/Plugins/Input/in_mod-openmpt')
-rw-r--r--Src/Plugins/Input/in_mod-openmpt/ExtendedInfo.cpp90
-rw-r--r--Src/Plugins/Input/in_mod-openmpt/ExtendedRead.cpp139
-rw-r--r--Src/Plugins/Input/in_mod-openmpt/MODPlayer.h44
-rw-r--r--Src/Plugins/Input/in_mod-openmpt/MODThread.cpp166
-rw-r--r--Src/Plugins/Input/in_mod-openmpt/api__in_mod.h8
-rw-r--r--Src/Plugins/Input/in_mod-openmpt/in_mod-openmpt.rc81
-rw-r--r--Src/Plugins/Input/in_mod-openmpt/in_mod-openmpt.sln182
-rw-r--r--Src/Plugins/Input/in_mod-openmpt/in_mod-openmpt.vcxproj271
-rw-r--r--Src/Plugins/Input/in_mod-openmpt/in_mod-openmpt.vcxproj.filters53
-rw-r--r--Src/Plugins/Input/in_mod-openmpt/main.cpp258
-rw-r--r--Src/Plugins/Input/in_mod-openmpt/nxfile-callbacks.cpp87
-rw-r--r--Src/Plugins/Input/in_mod-openmpt/resource.h18
-rw-r--r--Src/Plugins/Input/in_mod-openmpt/version.rc239
13 files changed, 1436 insertions, 0 deletions
diff --git a/Src/Plugins/Input/in_mod-openmpt/ExtendedInfo.cpp b/Src/Plugins/Input/in_mod-openmpt/ExtendedInfo.cpp
new file mode 100644
index 00000000..93f2fa4c
--- /dev/null
+++ b/Src/Plugins/Input/in_mod-openmpt/ExtendedInfo.cpp
@@ -0,0 +1,90 @@
+#include <bfc/platform/types.h>
+#include <windows.h>
+#include <strsafe.h>
+#include "api__in_mod.h"
+#include "resource.h"
+#include <libopenmpt/libopenmpt.h>
+#include "../nu/AutoChar.h"
+#include "../nu/ns_wc.h"
+#include <libopenmpt/libopenmpt_stream_callbacks_file.h>
+
+static wchar_t *open_filename = 0;
+static openmpt_module *info_mod = 0;
+openmpt_module *OpenMod(const wchar_t *filename);
+
+extern "C" __declspec(dllexport)
+ int winampGetExtendedFileInfoW(const wchar_t *fn, const char *data, wchar_t *dest, size_t destlen)
+{
+ if (!_stricmp(data, "type"))
+ {
+ dest[0]='0';
+ dest[1]=0;
+ return 1;
+ }
+ else if (!_stricmp(data, "family"))
+ {
+ size_t len;
+ const wchar_t *p;
+ if (!fn || !fn[0]) {
+ return 0;
+ }
+ len = wcslen(fn);
+ if (len < 4 || L'.' != fn[len - 4]) {
+ return 0;
+ }
+ p = &fn[len - 3];
+ const char *tracker = openmpt_get_tracker_name(AutoChar(p));
+ if (tracker && *tracker) {
+ *dest = 0;
+ MultiByteToWideCharSZ(CP_UTF8, 0, tracker, -1, dest, (int)destlen);
+ openmpt_free_string(tracker);
+ return 1;
+ }
+ openmpt_free_string(tracker);
+ return 0;
+ } else {
+ if (!open_filename || _wcsicmp(open_filename,fn)) {
+ free(open_filename);
+ open_filename = _wcsdup(fn);
+ openmpt_module_destroy(info_mod);
+ info_mod = 0;
+ info_mod = OpenMod(fn);
+ }
+ int retval = 0;
+
+ if (!_stricmp(data, "length")) {
+ double seconds = openmpt_module_get_duration_seconds(info_mod);
+ StringCchPrintf(dest, destlen, L"%.0f", seconds*1000.0);
+ retval = 1;
+ } else if (!_stricmp(data, "artist")) {
+ const char *value = openmpt_module_get_metadata(info_mod, "artist");
+ MultiByteToWideCharSZ(CP_UTF8, 0, value, -1, dest, (int)destlen);
+ openmpt_free_string(value);
+ retval = 1;
+ } else if (!_stricmp(data, "tool")) {
+ const char *value = openmpt_module_get_metadata(info_mod, "tracker");
+ MultiByteToWideCharSZ(CP_UTF8, 0, value, -1, dest, (int)destlen);
+ openmpt_free_string(value);
+ retval = 1;
+ } else if (!_stricmp(data, "title")) {
+ const char *value = openmpt_module_get_metadata(info_mod, "title");
+ MultiByteToWideCharSZ(CP_UTF8, 0, value, -1, dest, (int)destlen);
+ openmpt_free_string(value);
+ retval = 1;
+ } else if (!_stricmp(data, "year")) {
+ const char *value = openmpt_module_get_metadata(info_mod, "date");
+ MultiByteToWideCharSZ(CP_UTF8, 0, value, -1, dest, (int)destlen);
+ openmpt_free_string(value);
+ retval = 1;
+ } else if (!_stricmp(data, "comment")) {
+ const char *value = openmpt_module_get_metadata(info_mod, "message");
+ MultiByteToWideCharSZ(CP_UTF8, 0, value, -1, dest, (int)destlen);
+ openmpt_free_string(value);
+ retval = 1;
+ }
+
+ return retval;
+ }
+
+ return 0;
+} \ No newline at end of file
diff --git a/Src/Plugins/Input/in_mod-openmpt/ExtendedRead.cpp b/Src/Plugins/Input/in_mod-openmpt/ExtendedRead.cpp
new file mode 100644
index 00000000..646b3807
--- /dev/null
+++ b/Src/Plugins/Input/in_mod-openmpt/ExtendedRead.cpp
@@ -0,0 +1,139 @@
+#include "api__in_mod.h"
+#include <libopenmpt/libopenmpt.h>
+#include "../nsutil/pcm.h"
+
+static const size_t kModBufferSize = 512;
+static const unsigned int kModSampleRate = 44100; // TODO(benski) configurable!
+
+openmpt_module *OpenMod(const wchar_t *filename);
+
+class PlayParams
+{
+public:
+ PlayParams();
+ ~PlayParams();
+ openmpt_module *mod;
+ float *buffer;
+ int bps;
+ int channels;
+ int sample_rate;
+ bool use_float;
+ size_t (*openmpt_read)(openmpt_module * mod, int32_t samplerate, size_t count, float *interleaved_stereo);
+};
+
+PlayParams::PlayParams()
+{
+ mod = 0;
+ buffer = 0;
+}
+
+PlayParams::~PlayParams()
+{
+ openmpt_module_destroy(mod);
+ free(buffer);
+
+}
+
+static PlayParams *ExtendedOpen(const wchar_t *fn, int *size, int *bps, int *nch, int *srate, bool use_float)
+{
+ float *float_buffer = 0;
+ size_t (*openmpt_read)(openmpt_module * mod, int32_t samplerate, size_t count, float *interleaved_stereo)=openmpt_module_read_interleaved_float_stereo;
+
+ openmpt_module *mod = OpenMod(fn);
+ if (!mod) {
+ return 0;
+ }
+
+ int requested_channels = *nch;
+ int requested_bits = *bps;
+ int requested_srate = *srate;
+
+ if (!requested_channels) {
+ requested_channels=2;
+ }
+
+ if (!requested_bits) {
+ if (use_float) {
+ requested_bits=32;
+ } else {
+ requested_bits=16;
+ }
+ }
+
+ if (!requested_srate) {
+ requested_srate = kModSampleRate;
+ }
+
+ if (requested_channels == 1) {
+ openmpt_read = openmpt_module_read_float_mono;
+ } else if (requested_channels < 4) {
+ requested_channels = 2;
+ openmpt_read = openmpt_module_read_interleaved_float_stereo;
+ } else if (requested_channels) {
+ requested_channels = 4;
+ openmpt_read = openmpt_module_read_interleaved_float_quad;
+ }
+
+ if (!use_float) {
+ float_buffer = (float *)malloc(sizeof(float) * kModBufferSize * requested_channels);
+ if (!float_buffer) {
+ openmpt_module_destroy(mod);
+ return 0;
+ }
+ }
+
+ PlayParams *play_params = new PlayParams;
+ if (!play_params) {
+ openmpt_module_destroy(mod);
+ free(float_buffer);
+ return 0;
+ }
+
+ play_params->mod = mod;
+ play_params->buffer = float_buffer;
+ play_params->bps = requested_bits;
+ play_params->channels = requested_channels;
+ play_params->use_float = use_float;
+ play_params->openmpt_read = openmpt_read;
+ play_params->sample_rate = requested_srate;
+
+ *nch = requested_channels;
+ *srate = requested_srate;
+ *bps = requested_bits;
+
+ *size = (int)(openmpt_module_get_duration_seconds(mod) * (double)requested_bits * (double)requested_srate * (double)requested_channels / 8.0);
+
+ return play_params;
+}
+extern "C" __declspec(dllexport) intptr_t winampGetExtendedRead_openW_float(const wchar_t *fn, int *size, int *bps, int *nch, int *srate)
+{
+ return (intptr_t)ExtendedOpen(fn, size, bps, nch, srate, true);
+}
+
+extern "C" __declspec(dllexport) intptr_t winampGetExtendedRead_openW(const wchar_t *fn, int *size, int *bps, int *nch, int *srate)
+{
+ return (intptr_t)ExtendedOpen(fn, size, bps, nch, srate, false);
+}
+
+extern "C" __declspec(dllexport) size_t winampGetExtendedRead_getData(intptr_t handle, char *dest, size_t len, int *killswitch)
+{
+ PlayParams *play_params = (PlayParams *)handle;
+ size_t requested_samples = len / (play_params->channels * play_params->bps/8);
+
+ if (play_params->use_float) {
+ return play_params->openmpt_read(play_params->mod, play_params->sample_rate, requested_samples, (float *)dest) * sizeof(float) * play_params->channels;
+ } else {
+ if (requested_samples > kModBufferSize) {
+ requested_samples = kModBufferSize;
+ }
+ size_t count = play_params->openmpt_read(play_params->mod, play_params->sample_rate, requested_samples, play_params->buffer);
+ nsutil_pcm_FloatToInt_Interleaved(dest, play_params->buffer, play_params->bps, play_params->channels*count);
+ return count * play_params->bps * play_params->channels / 8;
+ }
+}
+
+extern "C" __declspec(dllexport) void winampGetExtendedRead_close(intptr_t handle)
+{
+ PlayParams *play_params = (PlayParams *)handle;
+ delete play_params;
+} \ No newline at end of file
diff --git a/Src/Plugins/Input/in_mod-openmpt/MODPlayer.h b/Src/Plugins/Input/in_mod-openmpt/MODPlayer.h
new file mode 100644
index 00000000..be8fca01
--- /dev/null
+++ b/Src/Plugins/Input/in_mod-openmpt/MODPlayer.h
@@ -0,0 +1,44 @@
+#pragma once
+#include <bfc/platform/types.h>
+#include <libopenmpt/libopenmpt.h>
+#include "../nu/AudioOutput.h"
+
+class MODPlayer
+{
+public:
+ MODPlayer(const wchar_t *_filename);
+ ~MODPlayer();
+ DWORD CALLBACK ThreadFunction();
+
+ void Kill();
+ void Seek(int seek_pos);
+ int GetOutputTime() const;
+private:
+ enum
+ {
+ // values that you can return from OnXXXX()
+ MOD_CONTINUE = 0, // continue processing
+ MOD_ABORT = 1, // abort parsing gracefully (maybe 'stop' was pressed)
+ MOD_STOP = 2, // stop parsing completely - usually returned when mkv version is too new or codecs not supported
+
+ // values returned from errors within the Step() function itself
+ MOD_EOF = 3, // end of file
+ MOD_ERROR = 4, // parsing error
+ };
+
+ HANDLE killswitch, seek_event;
+ wchar_t *filename;
+ volatile int m_needseek;
+
+ /* AudioOutput implementation */
+ class MODWait
+ {
+ public:
+ void Wait_SetEvents(HANDLE killswitch, HANDLE seek_event);
+ protected:
+ int WaitOrAbort(int time_in_ms);
+ private:
+ HANDLE handles[2];
+ };
+ nu::AudioOutput<MODWait> audio_output;
+}; \ No newline at end of file
diff --git a/Src/Plugins/Input/in_mod-openmpt/MODThread.cpp b/Src/Plugins/Input/in_mod-openmpt/MODThread.cpp
new file mode 100644
index 00000000..40c67082
--- /dev/null
+++ b/Src/Plugins/Input/in_mod-openmpt/MODThread.cpp
@@ -0,0 +1,166 @@
+#include "api__in_mod.h"
+#include "../Winamp/wa_ipc.h"
+#include "MODPlayer.h"
+#include <libopenmpt/libopenmpt_stream_callbacks_file.h>
+#include <nx/nxuri.h>
+#include <nx/nxstring.h>
+#include <nx/nxfile.h>
+#include "../nsutil/pcm.h"
+
+openmpt_module *OpenMod(const wchar_t *filename);
+
+extern int g_duration;
+extern In_Module plugin;
+// {B6CB4A7C-A8D0-4c55-8E60-9F7A7A23DA0F}
+static const GUID playbackConfigGroupGUID =
+{
+ 0xb6cb4a7c, 0xa8d0, 0x4c55, { 0x8e, 0x60, 0x9f, 0x7a, 0x7a, 0x23, 0xda, 0xf }
+};
+
+static const size_t kModBufferSize = 512;
+static const unsigned int kModSampleRate = 44100; // TODO(benski) configurable!
+
+void MODPlayer::MODWait::Wait_SetEvents(HANDLE killswitch, HANDLE seek_event)
+{
+ handles[0]=killswitch;
+ handles[1]=seek_event;
+}
+
+int MODPlayer::MODWait::WaitOrAbort(int time_in_ms)
+{
+ switch(WaitForMultipleObjects(2, handles, FALSE, time_in_ms))
+ {
+ case WAIT_TIMEOUT: // all good, wait successful
+ return 0;
+ case WAIT_OBJECT_0: // killswitch
+ return MODPlayer::MOD_STOP;
+ case WAIT_OBJECT_0+1: // seek event
+ return MODPlayer::MOD_ABORT;
+ default: // some OS error?
+ return MODPlayer::MOD_ERROR;
+ }
+}
+
+MODPlayer::MODPlayer(const wchar_t *_filename) : audio_output(&plugin)
+{
+ filename = _wcsdup(_filename);
+ m_needseek = -1;
+
+ killswitch = CreateEvent(NULL, TRUE, FALSE, NULL);
+ seek_event = CreateEvent(NULL, TRUE, FALSE, NULL);
+
+ audio_output.Wait_SetEvents(killswitch, seek_event);
+}
+
+MODPlayer::~MODPlayer()
+{
+ CloseHandle(killswitch);
+ CloseHandle(seek_event);
+ free(filename);
+}
+
+void MODPlayer::Kill()
+{
+ SetEvent(killswitch);
+}
+
+void MODPlayer::Seek(int seek_pos)
+{
+ m_needseek = seek_pos;
+ SetEvent(seek_event);
+}
+
+int MODPlayer::GetOutputTime() const
+{
+ if (m_needseek != -1)
+ return m_needseek;
+ else
+ return plugin.outMod->GetOutputTime();
+}
+
+DWORD CALLBACK MODThread(LPVOID param)
+{
+ MODPlayer *player = (MODPlayer *)param;
+ DWORD ret = player->ThreadFunction();
+ return ret;
+}
+
+DWORD CALLBACK MODPlayer::ThreadFunction()
+{
+ float *float_buffer = 0;
+ void *int_buffer = 0;
+
+ HANDLE handles[] = {killswitch, seek_event};
+ size_t count = 0;
+ size_t (*openmpt_read)(openmpt_module * mod, int32_t samplerate, size_t count, float *interleaved_stereo)=openmpt_module_read_interleaved_float_stereo;
+
+ int channels = 2;
+ bool force_mono = AGAVE_API_CONFIG->GetBool(playbackConfigGroupGUID, L"mono", false);
+ bool surround = AGAVE_API_CONFIG->GetBool(playbackConfigGroupGUID, L"surround", true);
+ int bits = (int)AGAVE_API_CONFIG->GetUnsigned(playbackConfigGroupGUID, L"bits", 16);
+ if (force_mono) {
+ channels = 1;
+ openmpt_read = openmpt_module_read_float_mono;
+ } else if (surround) {
+ channels = 4;
+ openmpt_read = openmpt_module_read_interleaved_float_quad;
+ }
+
+ // ===== tell audio output helper object about the output plugin =====
+ audio_output.Init(plugin.outMod);
+
+ openmpt_module * mod = OpenMod(filename);
+ if (!mod) {
+ goto btfo;
+ }
+ openmpt_module_ctl_set(mod, "seek.sync_sample", "1");
+ g_duration = (int)(openmpt_module_get_duration_seconds(mod) * 1000);
+ audio_output.Open(0, channels, kModSampleRate, bits);
+
+ float_buffer = (float *)malloc(sizeof(float) * kModBufferSize * channels);
+ int_buffer = malloc(kModBufferSize * channels * bits/8);
+
+ while (WaitForMultipleObjects(2, handles, FALSE, 0) != WAIT_OBJECT_0) {
+ count = openmpt_read(mod, kModSampleRate, kModBufferSize, float_buffer);
+ if (count == 0) {
+ break;
+ }
+ nsutil_pcm_FloatToInt_Interleaved(int_buffer, float_buffer, bits, channels*count);
+ int ret = audio_output.Write((char *)int_buffer, channels*count*bits/8);
+
+ if (ret == MOD_STOP) {
+ break;
+ } else if (ret == MOD_ABORT) {
+ ResetEvent(seek_event);
+ openmpt_module_set_position_seconds(mod, m_needseek/1000.0);
+ audio_output.Flush(m_needseek);
+ m_needseek = -1;
+ } else if (ret != MOD_CONTINUE) {
+ ret = ret;
+ }
+ }
+
+ if (WaitForSingleObject(killswitch, 0) != WAIT_OBJECT_0) {
+ audio_output.Write(0,0);
+ audio_output.WaitWhilePlaying();
+
+ if (WaitForSingleObject(killswitch, 0) != WAIT_OBJECT_0) {
+ PostMessage(plugin.hMainWindow, WM_WA_MPEG_EOF, 0, 0);
+ }
+ }
+ audio_output.Close();
+ openmpt_module_destroy(mod);
+ free(float_buffer);
+ free(int_buffer);
+ return 0;
+
+btfo: // bail the fuck out
+ if (WaitForSingleObject(killswitch, 0) != WAIT_OBJECT_0) {
+ PostMessage(plugin.hMainWindow, WM_WA_MPEG_EOF, 0, 0);
+ }
+ audio_output.Close();
+ openmpt_module_destroy(mod);
+ free(float_buffer);
+ free(int_buffer);
+ return 1;
+} \ No newline at end of file
diff --git a/Src/Plugins/Input/in_mod-openmpt/api__in_mod.h b/Src/Plugins/Input/in_mod-openmpt/api__in_mod.h
new file mode 100644
index 00000000..fdd31ee5
--- /dev/null
+++ b/Src/Plugins/Input/in_mod-openmpt/api__in_mod.h
@@ -0,0 +1,8 @@
+#pragma once
+
+#include "../Agave/Config/api_config.h"
+
+#include "api/application/api_application.h"
+#define WASABI_API_APP applicationApi
+
+#include "../Agave/Language/api_language.h"
diff --git a/Src/Plugins/Input/in_mod-openmpt/in_mod-openmpt.rc b/Src/Plugins/Input/in_mod-openmpt/in_mod-openmpt.rc
new file mode 100644
index 00000000..77c1b8ac
--- /dev/null
+++ b/Src/Plugins/Input/in_mod-openmpt/in_mod-openmpt.rc
@@ -0,0 +1,81 @@
+// 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
+ IDS_NULLSOFT_MOD "Nullsoft Module Decoder v%s"
+ 65535 "{B5691276-95DB-4b5c-BA73-B904A38EFFBF}"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_NULLSOFT_MOD_OLD "Nullsoft Module Decoder"
+ IDS_ABOUT_TEXT "%s\nWritten by Ben Allison\n© 2015-2023 Ben Allison\nBuild date: %s\n\nUses libopenmpt v%S\n\n%S"
+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/Input/in_mod-openmpt/in_mod-openmpt.sln b/Src/Plugins/Input/in_mod-openmpt/in_mod-openmpt.sln
new file mode 100644
index 00000000..06db8a5e
--- /dev/null
+++ b/Src/Plugins/Input/in_mod-openmpt/in_mod-openmpt.sln
@@ -0,0 +1,182 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.29709.97
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "in_mod-openmpt", "in_mod-openmpt.vcxproj", "{C4CF3B23-75B1-410D-83B9-0C74C02BE13F}"
+ ProjectSection(ProjectDependencies) = postProject
+ {57C90706-B25D-4ACA-9B33-95CDB2427C27} = {57C90706-B25D-4ACA-9B33-95CDB2427C27}
+ {DABE6307-F8DD-416D-9DAC-673E2DECB73F} = {DABE6307-F8DD-416D-9DAC-673E2DECB73F}
+ {1654FB18-FDE6-406F-9D84-BA12BFBD67B2} = {1654FB18-FDE6-406F-9D84-BA12BFBD67B2}
+ {D8D5E11C-F959-49EF-B741-B3F6DE52DED8} = {D8D5E11C-F959-49EF-B741-B3F6DE52DED8}
+ {F1397660-35F6-4734-837E-88DCE80E4837} = {F1397660-35F6-4734-837E-88DCE80E4837}
+ {F1F5CD60-0D5B-4CEA-9EEB-2F87FF9AA915} = {F1F5CD60-0D5B-4CEA-9EEB-2F87FF9AA915}
+ {189B867F-FF4B-45A1-B741-A97492EE69AF} = {189B867F-FF4B-45A1-B741-A97492EE69AF}
+ {627CF18A-C8CA-451E-AFD0-8679CADFDA6B} = {627CF18A-C8CA-451E-AFD0-8679CADFDA6B}
+ {E105A0A2-7391-47C5-86AC-718003524C3D} = {E105A0A2-7391-47C5-86AC-718003524C3D}
+ {B544DCB7-16E5-41BC-B51B-7EAD8CFDFA05} = {B544DCB7-16E5-41BC-B51B-7EAD8CFDFA05}
+ {7ADFAFB9-0A83-4D35-9891-FB24FDF30B53} = {7ADFAFB9-0A83-4D35-9891-FB24FDF30B53}
+ {0F9730E4-45DA-4BD2-A50A-403A4BC9751A} = {0F9730E4-45DA-4BD2-A50A-403A4BC9751A}
+ {9C5101EF-3E20-4558-809B-277FDD50E878} = {9C5101EF-3E20-4558-809B-277FDD50E878}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nsutil", "..\nsutil\nsutil.vcxproj", "{DABE6307-F8DD-416D-9DAC-673E2DECB73F}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nx", "..\replicant\nx\nx.vcxproj", "{57C90706-B25D-4ACA-9B33-95CDB2427C27}"
+ ProjectSection(ProjectDependencies) = postProject
+ {0F9730E4-45DA-4BD2-A50A-403A4BC9751A} = {0F9730E4-45DA-4BD2-A50A-403A4BC9751A}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nu", "..\replicant\nu\nu.vcxproj", "{F1F5CD60-0D5B-4CEA-9EEB-2F87FF9AA915}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jnetlib", "..\replicant\jnetlib\jnetlib.vcxproj", "{E105A0A2-7391-47C5-86AC-718003524C3D}"
+ ProjectSection(ProjectDependencies) = postProject
+ {0F9730E4-45DA-4BD2-A50A-403A4BC9751A} = {0F9730E4-45DA-4BD2-A50A-403A4BC9751A}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "..\replicant\zlib\zlib.vcxproj", "{0F9730E4-45DA-4BD2-A50A-403A4BC9751A}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libopenmpt", "..\libopenmpt\libopenmpt.vcxproj", "{9C5101EF-3E20-4558-809B-277FDD50E878}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libopenmpt_modplug", "..\libopenmpt\libopenmpt_modplug.vcxproj", "{F1397660-35F6-4734-837E-88DCE80E4837}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "openmpt-mpg123", "..\libopenmpt\openmpt-mpg123.vcxproj", "{7ADFAFB9-0A83-4D35-9891-FB24FDF30B53}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "openmpt-ogg", "..\libopenmpt\openmpt-ogg.vcxproj", "{D8D5E11C-F959-49EF-B741-B3F6DE52DED8}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "openmpt-portaudio", "..\libopenmpt\openmpt-portaudio.vcxproj", "{189B867F-FF4B-45A1-B741-A97492EE69AF}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "openmpt-portaudiocpp", "..\libopenmpt\openmpt-portaudiocpp.vcxproj", "{627CF18A-C8CA-451E-AFD0-8679CADFDA6B}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "openmpt-vorbis", "..\libopenmpt\openmpt-vorbis.vcxproj", "{B544DCB7-16E5-41BC-B51B-7EAD8CFDFA05}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "openmpt-zlib", "..\libopenmpt\openmpt-zlib.vcxproj", "{1654FB18-FDE6-406F-9D84-BA12BFBD67B2}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Debug|x64 = Debug|x64
+ Release|Win32 = Release|Win32
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {C4CF3B23-75B1-410D-83B9-0C74C02BE13F}.Debug|Win32.ActiveCfg = Debug|Win32
+ {C4CF3B23-75B1-410D-83B9-0C74C02BE13F}.Debug|Win32.Build.0 = Debug|Win32
+ {C4CF3B23-75B1-410D-83B9-0C74C02BE13F}.Debug|x64.ActiveCfg = Debug|x64
+ {C4CF3B23-75B1-410D-83B9-0C74C02BE13F}.Debug|x64.Build.0 = Debug|x64
+ {C4CF3B23-75B1-410D-83B9-0C74C02BE13F}.Release|Win32.ActiveCfg = Release|Win32
+ {C4CF3B23-75B1-410D-83B9-0C74C02BE13F}.Release|Win32.Build.0 = Release|Win32
+ {C4CF3B23-75B1-410D-83B9-0C74C02BE13F}.Release|x64.ActiveCfg = Release|x64
+ {C4CF3B23-75B1-410D-83B9-0C74C02BE13F}.Release|x64.Build.0 = Release|x64
+ {DABE6307-F8DD-416D-9DAC-673E2DECB73F}.Debug|Win32.ActiveCfg = Debug|Win32
+ {DABE6307-F8DD-416D-9DAC-673E2DECB73F}.Debug|Win32.Build.0 = Debug|Win32
+ {DABE6307-F8DD-416D-9DAC-673E2DECB73F}.Debug|x64.ActiveCfg = Debug|x64
+ {DABE6307-F8DD-416D-9DAC-673E2DECB73F}.Debug|x64.Build.0 = Debug|x64
+ {DABE6307-F8DD-416D-9DAC-673E2DECB73F}.Release|Win32.ActiveCfg = Release|Win32
+ {DABE6307-F8DD-416D-9DAC-673E2DECB73F}.Release|Win32.Build.0 = Release|Win32
+ {DABE6307-F8DD-416D-9DAC-673E2DECB73F}.Release|x64.ActiveCfg = Release|x64
+ {DABE6307-F8DD-416D-9DAC-673E2DECB73F}.Release|x64.Build.0 = Release|x64
+ {57C90706-B25D-4ACA-9B33-95CDB2427C27}.Debug|Win32.ActiveCfg = Debug|Win32
+ {57C90706-B25D-4ACA-9B33-95CDB2427C27}.Debug|Win32.Build.0 = Debug|Win32
+ {57C90706-B25D-4ACA-9B33-95CDB2427C27}.Debug|x64.ActiveCfg = Debug|x64
+ {57C90706-B25D-4ACA-9B33-95CDB2427C27}.Debug|x64.Build.0 = Debug|x64
+ {57C90706-B25D-4ACA-9B33-95CDB2427C27}.Release|Win32.ActiveCfg = Release|Win32
+ {57C90706-B25D-4ACA-9B33-95CDB2427C27}.Release|Win32.Build.0 = Release|Win32
+ {57C90706-B25D-4ACA-9B33-95CDB2427C27}.Release|x64.ActiveCfg = Release|x64
+ {57C90706-B25D-4ACA-9B33-95CDB2427C27}.Release|x64.Build.0 = Release|x64
+ {F1F5CD60-0D5B-4CEA-9EEB-2F87FF9AA915}.Debug|Win32.ActiveCfg = Debug|Win32
+ {F1F5CD60-0D5B-4CEA-9EEB-2F87FF9AA915}.Debug|Win32.Build.0 = Debug|Win32
+ {F1F5CD60-0D5B-4CEA-9EEB-2F87FF9AA915}.Debug|x64.ActiveCfg = Debug|x64
+ {F1F5CD60-0D5B-4CEA-9EEB-2F87FF9AA915}.Debug|x64.Build.0 = Debug|x64
+ {F1F5CD60-0D5B-4CEA-9EEB-2F87FF9AA915}.Release|Win32.ActiveCfg = Release|Win32
+ {F1F5CD60-0D5B-4CEA-9EEB-2F87FF9AA915}.Release|Win32.Build.0 = Release|Win32
+ {F1F5CD60-0D5B-4CEA-9EEB-2F87FF9AA915}.Release|x64.ActiveCfg = Release|x64
+ {F1F5CD60-0D5B-4CEA-9EEB-2F87FF9AA915}.Release|x64.Build.0 = Release|x64
+ {E105A0A2-7391-47C5-86AC-718003524C3D}.Debug|Win32.ActiveCfg = Debug|Win32
+ {E105A0A2-7391-47C5-86AC-718003524C3D}.Debug|Win32.Build.0 = Debug|Win32
+ {E105A0A2-7391-47C5-86AC-718003524C3D}.Debug|x64.ActiveCfg = Debug|x64
+ {E105A0A2-7391-47C5-86AC-718003524C3D}.Debug|x64.Build.0 = Debug|x64
+ {E105A0A2-7391-47C5-86AC-718003524C3D}.Release|Win32.ActiveCfg = Release|Win32
+ {E105A0A2-7391-47C5-86AC-718003524C3D}.Release|Win32.Build.0 = Release|Win32
+ {E105A0A2-7391-47C5-86AC-718003524C3D}.Release|x64.ActiveCfg = Release|x64
+ {E105A0A2-7391-47C5-86AC-718003524C3D}.Release|x64.Build.0 = Release|x64
+ {0F9730E4-45DA-4BD2-A50A-403A4BC9751A}.Debug|Win32.ActiveCfg = Debug|Win32
+ {0F9730E4-45DA-4BD2-A50A-403A4BC9751A}.Debug|Win32.Build.0 = Debug|Win32
+ {0F9730E4-45DA-4BD2-A50A-403A4BC9751A}.Debug|x64.ActiveCfg = Debug|x64
+ {0F9730E4-45DA-4BD2-A50A-403A4BC9751A}.Debug|x64.Build.0 = Debug|x64
+ {0F9730E4-45DA-4BD2-A50A-403A4BC9751A}.Release|Win32.ActiveCfg = Release|Win32
+ {0F9730E4-45DA-4BD2-A50A-403A4BC9751A}.Release|Win32.Build.0 = Release|Win32
+ {0F9730E4-45DA-4BD2-A50A-403A4BC9751A}.Release|x64.ActiveCfg = Release|x64
+ {0F9730E4-45DA-4BD2-A50A-403A4BC9751A}.Release|x64.Build.0 = Release|x64
+ {9C5101EF-3E20-4558-809B-277FDD50E878}.Debug|Win32.ActiveCfg = Debug|Win32
+ {9C5101EF-3E20-4558-809B-277FDD50E878}.Debug|Win32.Build.0 = Debug|Win32
+ {9C5101EF-3E20-4558-809B-277FDD50E878}.Debug|x64.ActiveCfg = Debug|x64
+ {9C5101EF-3E20-4558-809B-277FDD50E878}.Debug|x64.Build.0 = Debug|x64
+ {9C5101EF-3E20-4558-809B-277FDD50E878}.Release|Win32.ActiveCfg = Release|Win32
+ {9C5101EF-3E20-4558-809B-277FDD50E878}.Release|Win32.Build.0 = Release|Win32
+ {9C5101EF-3E20-4558-809B-277FDD50E878}.Release|x64.ActiveCfg = Release|x64
+ {9C5101EF-3E20-4558-809B-277FDD50E878}.Release|x64.Build.0 = Release|x64
+ {F1397660-35F6-4734-837E-88DCE80E4837}.Debug|Win32.ActiveCfg = Debug|Win32
+ {F1397660-35F6-4734-837E-88DCE80E4837}.Debug|Win32.Build.0 = Debug|Win32
+ {F1397660-35F6-4734-837E-88DCE80E4837}.Debug|x64.ActiveCfg = Debug|x64
+ {F1397660-35F6-4734-837E-88DCE80E4837}.Debug|x64.Build.0 = Debug|x64
+ {F1397660-35F6-4734-837E-88DCE80E4837}.Release|Win32.ActiveCfg = Release|Win32
+ {F1397660-35F6-4734-837E-88DCE80E4837}.Release|Win32.Build.0 = Release|Win32
+ {F1397660-35F6-4734-837E-88DCE80E4837}.Release|x64.ActiveCfg = Release|x64
+ {F1397660-35F6-4734-837E-88DCE80E4837}.Release|x64.Build.0 = Release|x64
+ {7ADFAFB9-0A83-4D35-9891-FB24FDF30B53}.Debug|Win32.ActiveCfg = Debug|Win32
+ {7ADFAFB9-0A83-4D35-9891-FB24FDF30B53}.Debug|Win32.Build.0 = Debug|Win32
+ {7ADFAFB9-0A83-4D35-9891-FB24FDF30B53}.Debug|x64.ActiveCfg = Debug|x64
+ {7ADFAFB9-0A83-4D35-9891-FB24FDF30B53}.Debug|x64.Build.0 = Debug|x64
+ {7ADFAFB9-0A83-4D35-9891-FB24FDF30B53}.Release|Win32.ActiveCfg = Release|Win32
+ {7ADFAFB9-0A83-4D35-9891-FB24FDF30B53}.Release|Win32.Build.0 = Release|Win32
+ {7ADFAFB9-0A83-4D35-9891-FB24FDF30B53}.Release|x64.ActiveCfg = Release|x64
+ {7ADFAFB9-0A83-4D35-9891-FB24FDF30B53}.Release|x64.Build.0 = Release|x64
+ {D8D5E11C-F959-49EF-B741-B3F6DE52DED8}.Debug|Win32.ActiveCfg = Debug|Win32
+ {D8D5E11C-F959-49EF-B741-B3F6DE52DED8}.Debug|Win32.Build.0 = Debug|Win32
+ {D8D5E11C-F959-49EF-B741-B3F6DE52DED8}.Debug|x64.ActiveCfg = Debug|x64
+ {D8D5E11C-F959-49EF-B741-B3F6DE52DED8}.Debug|x64.Build.0 = Debug|x64
+ {D8D5E11C-F959-49EF-B741-B3F6DE52DED8}.Release|Win32.ActiveCfg = Release|Win32
+ {D8D5E11C-F959-49EF-B741-B3F6DE52DED8}.Release|Win32.Build.0 = Release|Win32
+ {D8D5E11C-F959-49EF-B741-B3F6DE52DED8}.Release|x64.ActiveCfg = Release|x64
+ {D8D5E11C-F959-49EF-B741-B3F6DE52DED8}.Release|x64.Build.0 = Release|x64
+ {189B867F-FF4B-45A1-B741-A97492EE69AF}.Debug|Win32.ActiveCfg = Debug|Win32
+ {189B867F-FF4B-45A1-B741-A97492EE69AF}.Debug|Win32.Build.0 = Debug|Win32
+ {189B867F-FF4B-45A1-B741-A97492EE69AF}.Debug|x64.ActiveCfg = Debug|x64
+ {189B867F-FF4B-45A1-B741-A97492EE69AF}.Debug|x64.Build.0 = Debug|x64
+ {189B867F-FF4B-45A1-B741-A97492EE69AF}.Release|Win32.ActiveCfg = Release|Win32
+ {189B867F-FF4B-45A1-B741-A97492EE69AF}.Release|Win32.Build.0 = Release|Win32
+ {189B867F-FF4B-45A1-B741-A97492EE69AF}.Release|x64.ActiveCfg = Release|x64
+ {189B867F-FF4B-45A1-B741-A97492EE69AF}.Release|x64.Build.0 = Release|x64
+ {627CF18A-C8CA-451E-AFD0-8679CADFDA6B}.Debug|Win32.ActiveCfg = Debug|Win32
+ {627CF18A-C8CA-451E-AFD0-8679CADFDA6B}.Debug|Win32.Build.0 = Debug|Win32
+ {627CF18A-C8CA-451E-AFD0-8679CADFDA6B}.Debug|x64.ActiveCfg = Debug|x64
+ {627CF18A-C8CA-451E-AFD0-8679CADFDA6B}.Debug|x64.Build.0 = Debug|x64
+ {627CF18A-C8CA-451E-AFD0-8679CADFDA6B}.Release|Win32.ActiveCfg = Release|Win32
+ {627CF18A-C8CA-451E-AFD0-8679CADFDA6B}.Release|Win32.Build.0 = Release|Win32
+ {627CF18A-C8CA-451E-AFD0-8679CADFDA6B}.Release|x64.ActiveCfg = Release|x64
+ {627CF18A-C8CA-451E-AFD0-8679CADFDA6B}.Release|x64.Build.0 = Release|x64
+ {B544DCB7-16E5-41BC-B51B-7EAD8CFDFA05}.Debug|Win32.ActiveCfg = Debug|Win32
+ {B544DCB7-16E5-41BC-B51B-7EAD8CFDFA05}.Debug|Win32.Build.0 = Debug|Win32
+ {B544DCB7-16E5-41BC-B51B-7EAD8CFDFA05}.Debug|x64.ActiveCfg = Debug|x64
+ {B544DCB7-16E5-41BC-B51B-7EAD8CFDFA05}.Debug|x64.Build.0 = Debug|x64
+ {B544DCB7-16E5-41BC-B51B-7EAD8CFDFA05}.Release|Win32.ActiveCfg = Release|Win32
+ {B544DCB7-16E5-41BC-B51B-7EAD8CFDFA05}.Release|Win32.Build.0 = Release|Win32
+ {B544DCB7-16E5-41BC-B51B-7EAD8CFDFA05}.Release|x64.ActiveCfg = Release|x64
+ {B544DCB7-16E5-41BC-B51B-7EAD8CFDFA05}.Release|x64.Build.0 = Release|x64
+ {1654FB18-FDE6-406F-9D84-BA12BFBD67B2}.Debug|Win32.ActiveCfg = Debug|Win32
+ {1654FB18-FDE6-406F-9D84-BA12BFBD67B2}.Debug|Win32.Build.0 = Debug|Win32
+ {1654FB18-FDE6-406F-9D84-BA12BFBD67B2}.Debug|x64.ActiveCfg = Debug|x64
+ {1654FB18-FDE6-406F-9D84-BA12BFBD67B2}.Debug|x64.Build.0 = Debug|x64
+ {1654FB18-FDE6-406F-9D84-BA12BFBD67B2}.Release|Win32.ActiveCfg = Release|Win32
+ {1654FB18-FDE6-406F-9D84-BA12BFBD67B2}.Release|Win32.Build.0 = Release|Win32
+ {1654FB18-FDE6-406F-9D84-BA12BFBD67B2}.Release|x64.ActiveCfg = Release|x64
+ {1654FB18-FDE6-406F-9D84-BA12BFBD67B2}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {B33DB141-83E8-409F-A02B-22328B6EAD6E}
+ EndGlobalSection
+EndGlobal
diff --git a/Src/Plugins/Input/in_mod-openmpt/in_mod-openmpt.vcxproj b/Src/Plugins/Input/in_mod-openmpt/in_mod-openmpt.vcxproj
new file mode 100644
index 00000000..608eac69
--- /dev/null
+++ b/Src/Plugins/Input/in_mod-openmpt/in_mod-openmpt.vcxproj
@@ -0,0 +1,271 @@
+<?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>{C4CF3B23-75B1-410D-83B9-0C74C02BE13F}</ProjectGuid>
+ <RootNamespace>in_modopenmpt</RootNamespace>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ <TargetName>in_mod</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ <TargetName>in_mod</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ <TargetName>in_mod</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ <TargetName>in_mod</TargetName>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </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)'=='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)'=='Debug|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|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 Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ <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'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ <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 Label="Vcpkg">
+ <VcpkgEnableManifest>false</VcpkgEnableManifest>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <VcpkgInstalledDir>
+ </VcpkgInstalledDir>
+ <VcpkgUseStatic>false</VcpkgUseStatic>
+ <VcpkgConfiguration>Debug</VcpkgConfiguration>
+ <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <VcpkgInstalledDir>
+ </VcpkgInstalledDir>
+ <VcpkgUseStatic>false</VcpkgUseStatic>
+ <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <VcpkgInstalledDir>
+ </VcpkgInstalledDir>
+ <VcpkgUseStatic>false</VcpkgUseStatic>
+ <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
+ <VcpkgConfiguration>Debug</VcpkgConfiguration>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <VcpkgInstalledDir>
+ </VcpkgInstalledDir>
+ <VcpkgUseStatic>false</VcpkgUseStatic>
+ <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..\replicant;..\..\..\Wasabi;..\..\..\external_dependencies\openmpt-trunk;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;IN_MODOPENMPT_EXPORTS;UNICODE_INPUT_PLUGIN;WIN32_LEAN_AND_MEAN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>nsutil.lib;nx.lib;libopenmpt.lib;openmpt-vorbis.lib;openmpt-ogg.lib;openmpt-mpg123.lib;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>
+ <AdditionalLibraryDirectories>..\..\..\external_dependencies\openmpt-trunk\build\lib\$(PlatformShortName)_$(Configuration);..\..\..\replicant\nx\$(PlatformShortName)_$(Configuration);..\..\..\nsutil\$(PlatformShortName)_$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ </Link>
+ <PostBuildEvent>
+ <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\
+xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
+ <Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..\replicant;..\..\..\Wasabi;..\..\..\external_dependencies\openmpt-trunk;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN64;_DEBUG;_WINDOWS;_USRDLL;IN_MODOPENMPT_EXPORTS;UNICODE_INPUT_PLUGIN;WIN32_LEAN_AND_MEAN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>nsutil.lib;nx.lib;libopenmpt.lib;openmpt-vorbis.lib;openmpt-ogg.lib;openmpt-mpg123.lib;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>
+ <AdditionalLibraryDirectories>..\..\..\external_dependencies\openmpt-trunk\build\lib\$(PlatformShortName)_$(Configuration);..\..\..\replicant\nx\$(PlatformShortName)_$(Configuration);..\..\..\nsutil\$(PlatformShortName)_$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ </Link>
+ <PostBuildEvent>
+ <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\
+xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
+ <Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <AdditionalIncludeDirectories>..\..\..\replicant;..\..\..\Wasabi;..\..\..\external_dependencies\openmpt-trunk;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;IN_MODOPENMPT_EXPORTS;WIN32_LEAN_AND_MEAN;UNICODE_INPUT_PLUGIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>nsutil.lib;nx.lib;libopenmpt.lib;openmpt-vorbis.lib;openmpt-ogg.lib;openmpt-mpg123.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ <AdditionalLibraryDirectories>..\..\..\external_dependencies\openmpt-trunk\build\lib\$(PlatformShortName)_$(Configuration);..\..\..\replicant\nx\$(PlatformShortName)_$(Configuration);..\..\..\nsutil\$(PlatformShortName)_$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ </Link>
+ <PostBuildEvent>
+ <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
+ <Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <AdditionalIncludeDirectories>..\..\..\replicant;..\..\..\Wasabi;..\..\..\external_dependencies\openmpt-trunk;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN64;NDEBUG;_WINDOWS;_USRDLL;IN_MODOPENMPT_EXPORTS;WIN32_LEAN_AND_MEAN;UNICODE_INPUT_PLUGIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ <DisableSpecificWarnings>4244;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>nsutil.lib;nx.lib;libopenmpt.lib;openmpt-vorbis.lib;openmpt-ogg.lib;openmpt-mpg123.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <AdditionalLibraryDirectories>..\..\..\external_dependencies\openmpt-trunk\build\lib\$(PlatformShortName)_$(Configuration);..\..\..\replicant\nx\$(PlatformShortName)_$(Configuration);..\..\..\nsutil\$(PlatformShortName)_$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ </Link>
+ <PostBuildEvent>
+ <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
+ <Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\nu\SpillBuffer.cpp" />
+ <ClCompile Include="ExtendedInfo.cpp" />
+ <ClCompile Include="ExtendedRead.cpp" />
+ <ClCompile Include="main.cpp" />
+ <ClCompile Include="MODThread.cpp" />
+ <ClCompile Include="nxfile-callbacks.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\nu\SpillBuffer.h" />
+ <ClInclude Include="api__in_mod.h" />
+ <ClInclude Include="MODPlayer.h" />
+ <ClInclude Include="resource.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="in_mod-openmpt.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/Input/in_mod-openmpt/in_mod-openmpt.vcxproj.filters b/Src/Plugins/Input/in_mod-openmpt/in_mod-openmpt.vcxproj.filters
new file mode 100644
index 00000000..91ec5abd
--- /dev/null
+++ b/Src/Plugins/Input/in_mod-openmpt/in_mod-openmpt.vcxproj.filters
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <ClCompile Include="nxfile-callbacks.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="MODThread.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="main.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="ExtendedRead.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="ExtendedInfo.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\nu\SpillBuffer.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="api__in_mod.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="resource.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="MODPlayer.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\nu\SpillBuffer.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{cc05d482-8e29-4ae1-abbf-739eacb1be71}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Ressource Files">
+ <UniqueIdentifier>{908a3b0b-d02c-47ab-a57c-3c2777135350}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{b548883b-d979-442d-b28f-b5e52a90d483}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="in_mod-openmpt.rc">
+ <Filter>Ressource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/Src/Plugins/Input/in_mod-openmpt/main.cpp b/Src/Plugins/Input/in_mod-openmpt/main.cpp
new file mode 100644
index 00000000..c719d2b6
--- /dev/null
+++ b/Src/Plugins/Input/in_mod-openmpt/main.cpp
@@ -0,0 +1,258 @@
+#include "../Winamp/IN2.h"
+#include "api__in_mod.h"
+#include "../nu/ServiceBuilder.h"
+#include "resource.h"
+#include <strsafe.h>
+#include "MODPlayer.h"
+#include "../nu/AutoWide.h"
+#include <libopenmpt/libopenmpt.h>
+
+static MODPlayer *player;
+DWORD CALLBACK MODThread(LPVOID param);
+extern In_Module plugin;
+
+HINSTANCE WASABI_API_LNG_HINST = 0, WASABI_API_ORIG_HINST = 0;
+int g_duration=0;
+int paused = 0;
+static HANDLE play_thread = 0;
+
+static const wchar_t *MOD_PLUGIN_VERSION = L"3.05";
+
+// {B6CB4A7C-A8D0-4c55-8E60-9F7A7A23DA0F}
+static const GUID playbackConfigGroupGUID =
+{
+ 0xb6cb4a7c, 0xa8d0, 0x4c55, { 0x8e, 0x60, 0x9f, 0x7a, 0x7a, 0x23, 0xda, 0xf }
+};
+
+static wchar_t plugin_name[256];
+
+/* Wasabi services */
+api_application *WASABI_API_APP=0;
+api_config *AGAVE_API_CONFIG=0;
+api_language *WASABI_API_LNG = 0;
+
+static int Init()
+{
+ if (!IsWindow(plugin.hMainWindow)) {
+ return IN_INIT_FAILURE;
+ }
+
+ ServiceBuild(plugin.service, AGAVE_API_CONFIG, AgaveConfigGUID);
+ ServiceBuild(plugin.service, WASABI_API_APP, applicationApiServiceGuid);
+ ServiceBuild(plugin.service, WASABI_API_LNG, languageApiGUID);
+
+ // need to have this initialised before we try to do anything with localisation features
+ WASABI_API_START_LANG(plugin.hDllInstance, InModMPTLangGUID);
+ StringCbPrintfW(plugin_name,sizeof(plugin_name),WASABI_API_LNGSTRINGW(IDS_NULLSOFT_MOD), MOD_PLUGIN_VERSION);
+ plugin.description = (char *)plugin_name;
+
+
+ static char fileExtensionsString[2048] = "";
+ char* end = fileExtensionsString;
+ size_t remaining=sizeof(fileExtensionsString);
+ const char *extensions = openmpt_get_supported_extensions();
+ char *next_token;
+ for (const char *extension = strtok_s((char *)extensions, ";", &next_token); extension; extension = strtok_s(NULL, ";", &next_token)) {
+ StringCbCopyExA(end, remaining, extension, &end, &remaining, 0);
+ const char *tracker = openmpt_get_tracker_name(extension);
+ StringCbCopyExA(end+1, remaining-1, tracker, &end, &remaining, 0);
+ openmpt_free_string(tracker);
+ end++; remaining--;
+
+ }
+ plugin.FileExtensions = fileExtensionsString;
+ *end = 0;
+
+ openmpt_free_string(extensions);
+ return IN_INIT_SUCCESS;
+}
+
+static void Quit()
+{
+ ServiceRelease(plugin.service, AGAVE_API_CONFIG, AgaveConfigGUID);
+ ServiceRelease(plugin.service, WASABI_API_APP, applicationApiServiceGuid);
+ ServiceRelease(plugin.service, WASABI_API_LNG, languageApiGUID);
+}
+
+static int InfoBox(const wchar_t *file, HWND hwndParent)
+{
+ return INFOBOX_UNCHANGED;
+}
+
+static int IsOurFile(const wchar_t *file)
+{
+ return 0;
+}
+
+static void GetFileInfo(const wchar_t *file, wchar_t *title, int *length_in_ms)
+{
+}
+
+
+
+static int Play(const wchar_t *file)
+{
+ g_duration=-1000;
+ player = new MODPlayer(file);
+ play_thread = CreateThread(0, 0, MODThread, player, 0, 0);
+ SetThreadPriority(play_thread, (int)AGAVE_API_CONFIG->GetInt(playbackConfigGroupGUID, L"priority", THREAD_PRIORITY_HIGHEST));
+ return 0; // success
+}
+
+static void Pause()
+{
+ paused = 1;
+ plugin.outMod->Pause(1);
+}
+
+static void UnPause()
+{
+ paused = 0;
+ plugin.outMod->Pause(0);
+}
+
+static int IsPaused()
+{
+ return paused;
+}
+
+static void Stop()
+{
+ if (player) {
+ player->Kill();
+ if (play_thread) {
+ WaitForSingleObject(play_thread, INFINITE);
+ }
+ play_thread = 0;
+ delete player;
+ player=0;
+ }
+}
+
+static int GetLength()
+{
+ return g_duration;
+}
+
+static int GetOutputTime()
+{
+ if (plugin.outMod && player) {
+ return player->GetOutputTime();
+ } else {
+ return 0;
+ }
+}
+
+static void SetOutputTime(int time_in_ms)
+{
+ if (player) {
+ player->Seek(time_in_ms);
+ }
+}
+
+static void SetVolume(int _volume)
+{
+ plugin.outMod->SetVolume(_volume);
+}
+
+static void SetPan(int _pan)
+{
+ plugin.outMod->SetPan(_pan);
+}
+
+static void EQSet(int on, char data[10], int preamp)
+{
+}
+
+static int DoAboutMessageBox(HWND parent, wchar_t* title, wchar_t* message)
+{
+ MSGBOXPARAMS msgbx = {sizeof(MSGBOXPARAMS),0};
+ msgbx.lpszText = message;
+ msgbx.lpszCaption = title;
+ msgbx.lpszIcon = MAKEINTRESOURCE(102);
+ msgbx.hInstance = GetModuleHandle(0);
+ msgbx.dwStyle = MB_USERICON;
+ msgbx.hwndOwner = parent;
+ return MessageBoxIndirect(&msgbx);
+}
+
+static void About(HWND hwndParent)
+{
+ wchar_t message[1024], text[1024];
+ char license_trim[1024];
+ WASABI_API_LNGSTRINGW_BUF(IDS_NULLSOFT_MOD_OLD,text,1024);
+ const char *library_version = openmpt_get_string("library_version");
+ const char *license = openmpt_get_string("license");
+
+ // trim the license string
+ StringCbCopyA(license_trim, sizeof(license_trim), license);
+ char * trim = license_trim;
+ for (int i=0;i<4;i++) {
+ trim = strchr(trim, '\n');
+ if (trim) {
+ trim++;
+ }
+ }
+ *trim=0;
+
+ StringCchPrintfW(message, 1024,
+ WASABI_API_LNGSTRINGW(IDS_ABOUT_TEXT),
+ plugin.description,
+ TEXT(__DATE__),
+ library_version,
+ license_trim
+ );
+
+
+ DoAboutMessageBox(hwndParent,text,message);
+}
+
+
+extern In_Module plugin =
+{
+ IN_VER_RET, // defined in IN2.H
+ "nullsoft(in_mod.dll)",
+ 0, // hMainWindow (filled in by winamp)
+ 0, // hDllInstance (filled in by winamp)
+ "S3M\0Scream Tracker\0", // this is a double-null limited list. "EXT\0Description\0EXT\0Description\0" etc.
+ 1, // is_seekable
+ 1, // uses output plug-in system
+ About, // TODO(benski) config
+ About,
+ Init,
+ Quit,
+ GetFileInfo,
+ InfoBox,
+ IsOurFile,
+ Play,
+ Pause,
+ UnPause,
+ IsPaused,
+ Stop,
+
+ GetLength,
+ GetOutputTime,
+ SetOutputTime,
+
+ SetVolume,
+ SetPan,
+
+ 0,0,0,0,0,0,0,0,0, // visualization calls filled in by winamp
+
+ 0,0, // dsp calls filled in by winamp
+
+ EQSet,
+
+ NULL, // setinfo call filled in by winamp
+
+ 0, // out_mod filled in by winamp
+};
+
+// exported symbol. Returns output module.
+extern "C"
+{
+ __declspec(dllexport) In_Module * winampGetInModule2()
+ {
+ return &plugin;
+ }
+} \ No newline at end of file
diff --git a/Src/Plugins/Input/in_mod-openmpt/nxfile-callbacks.cpp b/Src/Plugins/Input/in_mod-openmpt/nxfile-callbacks.cpp
new file mode 100644
index 00000000..571207ba
--- /dev/null
+++ b/Src/Plugins/Input/in_mod-openmpt/nxfile-callbacks.cpp
@@ -0,0 +1,87 @@
+#include <nx/nxfile.h>
+#include <libopenmpt/libopenmpt.h>
+#include <assert.h>
+
+static size_t openmpt_nxfile_read(void *stream, void *dst, size_t bytes)
+{
+ nx_file_t f = (nx_file_t)stream;
+ size_t bytes_read;
+ ns_error_t err = NXFileRead(f, dst, bytes, &bytes_read);
+ if (err != NErr_Success) {
+ return 0;
+ }
+ return bytes_read;
+}
+
+static int openmpt_nxfile_seek(void *stream, int64_t offset, int whence)
+{
+ nx_file_t f = (nx_file_t)stream;
+ uint64_t position;
+ if (whence == OPENMPT_STREAM_SEEK_SET) {
+ position = offset;
+ } else if (whence == OPENMPT_STREAM_SEEK_CUR) {
+ ns_error_t err = NXFileTell(f, &position);
+ if (err != NErr_Success) {
+ return -1;
+ }
+ position += offset;
+ } else if (whence == OPENMPT_STREAM_SEEK_END) {
+ assert(0);
+ } else {
+ return -1;
+ }
+ ns_error_t err = NXFileSeek(f, position);
+ if (err = NErr_Success) {
+ return 0;
+ } else {
+ return -1;
+ }
+}
+
+static int64_t openmpt_nxfile_tell(void *stream)
+{
+ nx_file_t f = (nx_file_t)stream;
+ uint64_t position;
+ if (NXFileTell(f, &position) == NErr_Success) {
+ return (int64_t)position;
+ } else {
+ return -1;
+ }
+}
+
+openmpt_stream_callbacks openmpt_stream_get_nxfile_callbacks(void)
+{
+ openmpt_stream_callbacks retval;
+ memset( &retval, 0, sizeof( openmpt_stream_callbacks ) );
+ retval.read = openmpt_nxfile_read;
+ retval.seek = openmpt_nxfile_seek;
+ retval.tell = openmpt_nxfile_tell;
+ return retval;
+}
+
+openmpt_module *OpenMod(const wchar_t *filename)
+{
+ openmpt_module * mod = 0;
+
+ nx_string_t nx_filename=0;
+ nx_uri_t nx_uri=0;
+ NXStringCreateWithUTF16(&nx_filename, filename);
+ NXURICreateWithNXString(&nx_uri, nx_filename);
+ NXStringRelease(nx_filename);
+
+ nx_file_t f=0;
+ ns_error_t nserr;
+
+ nserr = NXFileOpenZip(&f, nx_uri, NULL);
+ if (nserr != NErr_Success) {
+ nserr = NXFileOpenFile(&f, nx_uri, nx_file_FILE_read_binary);
+ }
+ NXURIRelease(nx_uri);
+ if (nserr != NErr_Success) {
+ return 0;
+ }
+
+ mod = openmpt_module_create(openmpt_stream_get_nxfile_callbacks(), f, NULL, NULL, NULL);
+ NXFileRelease(f);
+ return mod;
+} \ No newline at end of file
diff --git a/Src/Plugins/Input/in_mod-openmpt/resource.h b/Src/Plugins/Input/in_mod-openmpt/resource.h
new file mode 100644
index 00000000..2dc4d87b
--- /dev/null
+++ b/Src/Plugins/Input/in_mod-openmpt/resource.h
@@ -0,0 +1,18 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by in_mod-openmpt.rc
+//
+#define IDS_NULLSOFT_MOD_OLD 0
+#define IDS_ABOUT_TEXT 2
+#define IDS_NULLSOFT_MOD 65534
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 3
+#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/Input/in_mod-openmpt/version.rc2 b/Src/Plugins/Input/in_mod-openmpt/version.rc2
new file mode 100644
index 00000000..fa5af207
--- /dev/null
+++ b/Src/Plugins/Input/in_mod-openmpt/version.rc2
@@ -0,0 +1,39 @@
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+#include "../../../Winamp/buildType.h"
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 3,05,0,0
+ 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 Input Plug-in"
+ VALUE "FileVersion", "3,05,0,0"
+ VALUE "InternalName", "Nullsoft Module Decoder"
+ VALUE "LegalCopyright", "Copyright © 2015-2023 Ben Allison, Winamp SA"
+ VALUE "LegalTrademarks", "Nullsoft and Winamp are trademarks of Winamp SA"
+ VALUE "OriginalFilename", "in_mod.dll"
+ VALUE "ProductName", "Winamp"
+ VALUE "ProductVersion", STR_WINAMP_PRODUCTVER
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END