winamp/Src/Plugins/Input/in_mod-openmpt/main.cpp
2024-09-24 14:54:57 +02:00

258 lines
5.5 KiB
C++

#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;
}
}