aboutsummaryrefslogtreecommitdiff
path: root/Src/external_dependencies/openmpt-trunk/mptrack/Mptrack.h
diff options
context:
space:
mode:
Diffstat (limited to 'Src/external_dependencies/openmpt-trunk/mptrack/Mptrack.h')
-rw-r--r--Src/external_dependencies/openmpt-trunk/mptrack/Mptrack.h467
1 files changed, 467 insertions, 0 deletions
diff --git a/Src/external_dependencies/openmpt-trunk/mptrack/Mptrack.h b/Src/external_dependencies/openmpt-trunk/mptrack/Mptrack.h
new file mode 100644
index 00000000..07eb9287
--- /dev/null
+++ b/Src/external_dependencies/openmpt-trunk/mptrack/Mptrack.h
@@ -0,0 +1,467 @@
+/*
+ * MPTrack.h
+ * ---------
+ * Purpose: OpenMPT core application class.
+ * Notes : (currently none)
+ * Authors: OpenMPT Devs
+ * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
+ */
+
+
+#pragma once
+
+#include "openmpt/all/BuildSettings.hpp"
+
+#include "resource.h" // main symbols
+#include "Settings.h"
+#include "MPTrackUtil.h"
+#include "Reporting.h"
+#include "../soundlib/MIDIMacros.h"
+#include "../soundlib/modcommand.h"
+#include "../common/ComponentManager.h"
+#include "../misc/mptMutex.h"
+#include "../common/mptRandom.h"
+
+#include <future>
+
+OPENMPT_NAMESPACE_BEGIN
+
+class CModDoc;
+class CModDocTemplate;
+class CVstPluginManager;
+namespace SoundDevice
+{
+class Manager;
+} // namespace SoundDevice
+struct AllSoundDeviceComponents;
+class CDLSBank;
+class DebugSettings;
+class TrackerSettings;
+class ComponentManagerSettings;
+namespace mpt
+{
+namespace Wine
+{
+class VersionContext;
+class Context;
+} // namespace Wine
+} // namespace mpt
+class GdiplusRAII;
+
+
+/////////////////////////////////////////////////////////////////////////////
+// 16-colors DIB
+struct MODPLUGDIB
+{
+ BITMAPINFOHEADER bmiHeader;
+ RGBQUAD bmiColors[16];
+ LPBYTE lpDibBits;
+};
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Midi Library
+
+using MidiLibrary = std::array<mpt::PathString, 128 * 2>; // 128 instruments + 128 percussions
+
+
+//////////////////////////////////////////////////////////////////////////
+// Dragon Droppings
+
+enum DragonDropType
+{
+ DRAGONDROP_NOTHING = 0, // |------< Drop Type >-------------|---< dropItem >----|---< dropParam >---|
+ DRAGONDROP_DLS, // | Instrument from a DLS bank | DLS Bank # | DLS Instrument |
+ DRAGONDROP_SAMPLE, // | Sample from a song | Sample # | NULL |
+ DRAGONDROP_INSTRUMENT, // | Instrument from a song | Instrument # | NULL |
+ DRAGONDROP_SOUNDFILE, // | File from instrument library | ? | File Name |
+ DRAGONDROP_MIDIINSTR, // | File from midi library | Midi Program/Perc | File Name |
+ DRAGONDROP_PATTERN, // | Pattern from a song | Pattern # | NULL |
+ DRAGONDROP_ORDER, // | Pattern index in a song | Order # | NULL |
+ DRAGONDROP_SONG, // | Song file (mod/s3m/xm/it) | 0 | File Name |
+ DRAGONDROP_SEQUENCE // | Sequence (a set of orders) | Sequence # | NULL |
+};
+
+struct DRAGONDROP
+{
+ const CSoundFile *sndFile = nullptr;
+ DragonDropType dropType = DRAGONDROP_NOTHING;
+ uint32 dropItem = 0;
+ LPARAM dropParam = 0;
+
+ mpt::PathString GetPath() const
+ {
+ const mpt::PathString *const path = reinterpret_cast<const mpt::PathString *>(dropParam);
+ MPT_ASSERT(path);
+ return path ? *path : mpt::PathString();
+ }
+};
+
+
+/////////////////////////////////////////////////////////////////////////////
+// CTrackApp:
+// See mptrack.cpp for the implementation of this class
+//
+
+class CMPTCommandLineInfo;
+
+class CTrackApp : public CWinApp
+{
+ friend class CMainFrame;
+ // static data
+protected:
+ static MODTYPE m_nDefaultDocType;
+ static MidiLibrary midiLibrary;
+
+public:
+ static std::vector<std::unique_ptr<CDLSBank>> gpDLSBanks;
+
+protected:
+ mpt::recursive_mutex_with_lock_count m_GlobalMutex;
+
+ DWORD m_GuiThreadId = 0;
+
+ std::future<std::vector<std::unique_ptr<CDLSBank>>> m_scannedDlsBanks;
+ std::atomic<bool> m_scannedDlsBanksAvailable = false;
+
+ std::unique_ptr<mpt::random_device> m_RD;
+ std::unique_ptr<mpt::thread_safe_prng<mpt::default_prng>> m_PRNG;
+
+ std::unique_ptr<GdiplusRAII> m_Gdiplus;
+
+ std::shared_ptr<mpt::OS::Wine::VersionContext> m_WineVersion;
+
+ IniFileSettingsBackend *m_pSettingsIniFile;
+ SettingsContainer *m_pSettings = nullptr;
+ DebugSettings *m_pDebugSettings = nullptr;
+ TrackerSettings *m_pTrackerSettings = nullptr;
+ IniFileSettingsBackend *m_pSongSettingsIniFile = nullptr;
+ SettingsContainer *m_pSongSettings = nullptr;
+ ComponentManagerSettings *m_pComponentManagerSettings = nullptr;
+ IniFileSettingsContainer *m_pPluginCache = nullptr;
+ CModDocTemplate *m_pModTemplate = nullptr;
+ CVstPluginManager *m_pPluginManager = nullptr;
+ mpt::log::GlobalLogger m_GlobalLogger{};
+ std::unique_ptr<AllSoundDeviceComponents> m_pAllSoundDeviceComponents;
+ std::unique_ptr<SoundDevice::Manager> m_pSoundDevicesManager;
+
+ mpt::PathString m_InstallPath; // i.e. "C:\Program Files\OpenMPT\" (installer mode) or "G:\OpenMPT\" (portable mode)
+ mpt::PathString m_InstallBinPath; // i.e. "C:\Program Files\OpenMPT\bin\" (multi-arch mode) or InstallPath (legacy mode)
+ mpt::PathString m_InstallBinArchPath; // i.e. "C:\Program Files\OpenMPT\bin\amd64\" (multi-arch mode) or InstallPath (legacy mode)
+ mpt::PathString m_InstallPkgPath; // i.e. "C:\Program Files\OpenMPT\" (installer mode) or "G:\OpenMPT\" (portable mode)
+
+ mpt::PathString m_ConfigPath; // InstallPath (portable mode) or "%AppData%\OpenMPT\"
+
+ mpt::PathString m_szConfigFileName;
+ mpt::PathString m_szPluginCacheFileName;
+
+ std::shared_ptr<mpt::Wine::Context> m_Wine;
+ mpt::PathString m_WineWrapperDllName;
+ // Default macro configuration
+ MIDIMacroConfig m_MidiCfg;
+ DWORD m_dwLastPluginIdleCall = 0;
+ bool m_bInstallerMode = false;
+ bool m_bPortableMode = false;
+ bool m_bSourceTreeMode = false;
+
+public:
+ CTrackApp();
+
+ CDataRecoveryHandler *GetDataRecoveryHandler() override;
+ void AddToRecentFileList(LPCTSTR lpszPathName) override;
+ void AddToRecentFileList(const mpt::PathString &path);
+ /// Removes item from MRU-list; most recent item has index zero.
+ void RemoveMruItem(const size_t item);
+ void RemoveMruItem(const mpt::PathString &path);
+
+public:
+ bool IsMultiArchInstall() const { return m_InstallPath == m_InstallBinArchPath; }
+ mpt::PathString GetInstallPath() const { return m_InstallPath; } // i.e. "C:\Program Files\OpenMPT\" (installer mode) or "G:\OpenMPT\" (portable mode)
+ mpt::PathString GetInstallBinPath() const { return m_InstallBinPath; } // i.e. "C:\Program Files\OpenMPT\bin\" (multi-arch mode) or InstallPath (legacy mode)
+ mpt::PathString GetInstallBinArchPath() const { return m_InstallBinArchPath; } // i.e. "C:\Program Files\OpenMPT\bin\amd64\" (multi-arch mode) or InstallPath (legacy mode)
+ mpt::PathString GetInstallPkgPath() const { return m_InstallPkgPath; } // i.e. "C:\Program Files\OpenMPT\" (installer mode) or "G:\OpenMPT\" (portable mode)
+
+ static MODTYPE GetDefaultDocType() { return m_nDefaultDocType; }
+ static void SetDefaultDocType(MODTYPE n) { m_nDefaultDocType = n; }
+ static MidiLibrary &GetMidiLibrary() { return midiLibrary; }
+ static void ImportMidiConfig(const mpt::PathString &filename, bool hideWarning = false);
+ static void ExportMidiConfig(const mpt::PathString &filename);
+ static void ImportMidiConfig(SettingsContainer &file, const mpt::PathString &path, bool forgetSettings = false);
+ static void ExportMidiConfig(SettingsContainer &file);
+ static std::future<std::vector<std::unique_ptr<CDLSBank>>> LoadDefaultDLSBanks();
+ static void SaveDefaultDLSBanks();
+ static void RemoveDLSBank(UINT nBank);
+ static bool AddDLSBank(const mpt::PathString &filename);
+ static bool OpenURL(const char *url); // UTF8
+ static bool OpenURL(const std::string &url); // UTF8
+ static bool OpenURL(const CString &url);
+ static bool OpenURL(const mpt::ustring &url);
+ static bool OpenURL(const mpt::PathString &lpszURL);
+ static bool OpenFile(const mpt::PathString &file) { return OpenURL(file); };
+ static bool OpenDirectory(const mpt::PathString &directory) { return OpenURL(directory); };
+
+ // Retrieve the user-supplied MIDI port name for a MIDI input or output port.
+ mpt::ustring GetFriendlyMIDIPortName(const mpt::ustring &deviceName, bool isInputPort, bool addDeviceName = true);
+ CString GetFriendlyMIDIPortName(const CString &deviceName, bool isInputPort, bool addDeviceName = true);
+
+ int GetOpenDocumentCount() const;
+ std::vector<CModDoc *> GetOpenDocuments() const;
+
+public:
+ inline mpt::recursive_mutex_with_lock_count &GetGlobalMutexRef() { return m_GlobalMutex; }
+ bool InGuiThread() const { return GetCurrentThreadId() == m_GuiThreadId; }
+ mpt::random_device &RandomDevice() { return *m_RD; }
+ mpt::thread_safe_prng<mpt::default_prng> &PRNG() { return *m_PRNG; }
+ CModDocTemplate *GetModDocTemplate() const { return m_pModTemplate; }
+ CVstPluginManager *GetPluginManager() const { return m_pPluginManager; }
+ SoundDevice::Manager *GetSoundDevicesManager() const { return m_pSoundDevicesManager.get(); }
+ void GetDefaultMidiMacro(MIDIMacroConfig &cfg) const { cfg = m_MidiCfg; }
+ void SetDefaultMidiMacro(const MIDIMacroConfig &cfg) { m_MidiCfg = cfg; }
+ mpt::PathString GetConfigFileName() const { return m_szConfigFileName; }
+ SettingsContainer *GetpSettings()
+ {
+ return m_pSettings;
+ }
+ SettingsContainer &GetSettings()
+ {
+ ASSERT(m_pSettings);
+ return *m_pSettings;
+ }
+ TrackerSettings &GetTrackerSettings()
+ {
+ ASSERT(m_pTrackerSettings);
+ return *m_pTrackerSettings;
+ }
+ bool IsInstallerMode() const
+ {
+ return m_bInstallerMode;
+ }
+ bool IsPortableMode() const
+ {
+ return m_bPortableMode;
+ }
+ bool IsSourceTreeMode() const
+ {
+ return m_bSourceTreeMode;
+ }
+
+ SettingsContainer &GetPluginCache()
+ {
+ ASSERT(m_pPluginCache);
+ return *m_pPluginCache;
+ }
+
+ SettingsContainer &GetSongSettings()
+ {
+ ASSERT(m_pSongSettings);
+ return *m_pSongSettings;
+ }
+ const mpt::PathString &GetSongSettingsFilename() const
+ {
+ return m_pSongSettingsIniFile->GetFilename();
+ }
+
+ void SetWineVersion(std::shared_ptr<mpt::OS::Wine::VersionContext> wineVersion)
+ {
+ MPT_ASSERT_ALWAYS(mpt::OS::Windows::IsWine());
+ m_WineVersion = wineVersion;
+ }
+ std::shared_ptr<mpt::OS::Wine::VersionContext> GetWineVersion() const
+ {
+ MPT_ASSERT_ALWAYS(mpt::OS::Windows::IsWine());
+ MPT_ASSERT_ALWAYS(m_WineVersion); // Verify initialization order. We should not should reach this until after Wine is detected.
+ return m_WineVersion;
+ }
+
+ void SetWine(std::shared_ptr<mpt::Wine::Context> wine)
+ {
+ m_Wine = wine;
+ }
+ std::shared_ptr<mpt::Wine::Context> GetWine() const
+ {
+ return m_Wine;
+ }
+
+ void SetWineWrapperDllFilename(mpt::PathString filename)
+ {
+ m_WineWrapperDllName = filename;
+ }
+ mpt::PathString GetWineWrapperDllFilename() const
+ {
+ return m_WineWrapperDllName;
+ }
+
+ /// Returns path to config folder including trailing '\'.
+ mpt::PathString GetConfigPath() const { return m_ConfigPath; }
+ void SetupPaths(bool overridePortable);
+ void CreatePaths();
+
+#if !defined(MPT_BUILD_RETRO)
+ bool CheckSystemSupport();
+#endif // !MPT_BUILD_RETRO
+
+ // Relative / absolute paths conversion
+ mpt::PathString PathAbsoluteToInstallRelative(const mpt::PathString &path) { return path.AbsolutePathToRelative(GetInstallPath()); }
+ mpt::PathString PathInstallRelativeToAbsolute(const mpt::PathString &path) { return path.RelativePathToAbsolute(GetInstallPath()); }
+ mpt::PathString PathAbsoluteToInstallBinArchRelative(const mpt::PathString &path) { return path.AbsolutePathToRelative(GetInstallBinArchPath()); }
+ mpt::PathString PathInstallBinArchRelativeToAbsolute(const mpt::PathString &path) { return path.RelativePathToAbsolute(GetInstallBinArchPath()); }
+
+ static void OpenModulesDialog(std::vector<mpt::PathString> &files, const mpt::PathString &overridePath = mpt::PathString());
+
+public:
+ // Get name of resampling mode. addTaps = true also adds the number of taps the filter uses.
+ static CString GetResamplingModeName(ResamplingMode mode, int length, bool addTaps);
+
+ // Overrides
+public:
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CTrackApp)
+public:
+ BOOL InitInstance() override;
+ BOOL InitInstanceEarly(CMPTCommandLineInfo &cmdInfo);
+ BOOL InitInstanceLate(CMPTCommandLineInfo &cmdInfo);
+ BOOL InitInstanceImpl(CMPTCommandLineInfo &cmdInfo);
+ int Run() override;
+ LRESULT ProcessWndProcException(CException *e, const MSG *pMsg) override;
+ int ExitInstance() override;
+ int ExitInstanceImpl();
+ BOOL OnIdle(LONG lCount) override;
+ //}}AFX_VIRTUAL
+
+ // Implementation
+
+ //{{AFX_MSG(CTrackApp)
+ CModDoc *NewDocument(MODTYPE newType = MOD_TYPE_NONE);
+
+ afx_msg void OnFileNew() { NewDocument(); }
+ afx_msg void OnFileNewMOD() { NewDocument(MOD_TYPE_MOD); }
+ afx_msg void OnFileNewS3M() { NewDocument(MOD_TYPE_S3M); }
+ afx_msg void OnFileNewXM() { NewDocument(MOD_TYPE_XM); }
+ afx_msg void OnFileNewIT() { NewDocument(MOD_TYPE_IT); }
+ afx_msg void OnFileNewMPT() { NewDocument(MOD_TYPE_MPT); }
+
+ afx_msg void OnFileOpen();
+ afx_msg void OnAppAbout();
+
+ afx_msg void OnFileCloseAll();
+ afx_msg void OnUpdateAnyDocsOpen(CCmdUI *cmd);
+
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+
+protected:
+ size_t AddScannedDLSBanks();
+
+ void InitializeDXPlugins();
+ void UninitializeDXPlugins();
+
+ bool MoveConfigFile(const mpt::PathString &fileName, mpt::PathString subDir = {}, mpt::PathString newFileName = {});
+};
+
+
+extern CTrackApp theApp;
+
+
+//////////////////////////////////////////////////////////////////
+// More Bitmap Helpers
+
+class CFastBitmap
+{
+protected:
+ static constexpr uint8 BLEND_OFFSET = 0x80;
+
+ struct MODPLUGFASTDIB
+ {
+ BITMAPINFOHEADER bmiHeader;
+ RGBQUAD bmiColors[256];
+ std::vector<uint8> DibBits;
+ };
+
+ MODPLUGFASTDIB m_Dib;
+ UINT m_nTextColor, m_nBkColor;
+ MODPLUGDIB *m_pTextDib;
+ uint8 m_nBlendOffset;
+ uint8 m_n4BitPalette[16];
+ uint8 m_nXShiftFactor;
+
+public:
+ CFastBitmap() {}
+
+public:
+ void Init(MODPLUGDIB *lpTextDib = nullptr);
+ void Blit(HDC hdc, int x, int y, int cx, int cy);
+ void Blit(HDC hdc, LPCRECT lprc) { Blit(hdc, lprc->left, lprc->top, lprc->right - lprc->left, lprc->bottom - lprc->top); }
+ void SetTextColor(int nText, int nBk = -1)
+ {
+ m_nTextColor = nText;
+ if(nBk >= 0)
+ m_nBkColor = nBk;
+ }
+ void SetTextBkColor(UINT nBk) { m_nBkColor = nBk; }
+ void SetColor(UINT nIndex, COLORREF cr);
+ void SetAllColors(UINT nBaseIndex, UINT nColors, COLORREF *pcr);
+ void TextBlt(int x, int y, int cx, int cy, int srcx, int srcy, MODPLUGDIB *lpdib = nullptr);
+ void SetBlendMode(bool enable) { m_nBlendOffset = enable ? BLEND_OFFSET : 0; }
+ bool GetBlendMode() const { return m_nBlendOffset != 0; }
+ void SetBlendColor(COLORREF cr);
+ void SetSize(int x, int y);
+ int GetWidth() const { return m_Dib.bmiHeader.biWidth; }
+};
+
+
+///////////////////////////////////////////////////
+// 4-bit DIB Drawing functions
+void DibBlt(HDC hdc, int x, int y, int sizex, int sizey, int srcx, int srcy, MODPLUGDIB *lpdib);
+MODPLUGDIB *LoadDib(LPCTSTR lpszName);
+RGBQUAD rgb2quad(COLORREF c);
+
+// Other bitmap functions
+int DrawTextT(HDC hdc, const wchar_t *lpchText, int cchText, LPRECT lprc, UINT format);
+int DrawTextT(HDC hdc, const char *lpchText, int cchText, LPRECT lprc, UINT format);
+void DrawButtonRect(HDC hdc, const RECT *lpRect, LPCSTR lpszText = nullptr, BOOL bDisabled = FALSE, BOOL bPushed = FALSE, DWORD dwFlags = (DT_CENTER | DT_VCENTER), uint32 topMargin = 0);
+void DrawButtonRect(HDC hdc, const RECT *lpRect, LPCWSTR lpszText = nullptr, BOOL bDisabled = FALSE, BOOL bPushed = FALSE, DWORD dwFlags = (DT_CENTER | DT_VCENTER), uint32 topMargin = 0);
+
+// Misc functions
+void ErrorBox(UINT nStringID, CWnd *p = nullptr);
+
+// Helper function declarations.
+struct SNDMIXPLUGIN;
+class IMixPlugin;
+void AddPluginNamesToCombobox(CComboBox &CBox, const SNDMIXPLUGIN *plugarray, const bool libraryName = false, const PLUGINDEX updatePlug = PLUGINDEX_INVALID);
+void AddPluginParameternamesToCombobox(CComboBox &CBox, SNDMIXPLUGIN &plugarray);
+void AddPluginParameternamesToCombobox(CComboBox &CBox, IMixPlugin &plug);
+
+// Append note names in range [noteStart, noteEnd] to given combobox. Index starts from 0.
+void AppendNotesToControl(CComboBox &combobox, ModCommand::NOTE noteStart, ModCommand::NOTE noteEnd);
+
+// Append note names to combo box.
+// If nInstr is given, instrument-specific note names are used instead of default note names.
+// A custom note range may also be specified using the noteStart and noteEnd parameters.
+// If they are left out, only notes that are available in the module type, plus any supported "special notes" are added.
+void AppendNotesToControlEx(CComboBox &combobox, const CSoundFile &sndFile, INSTRUMENTINDEX nInstr = MAX_INSTRUMENTS, ModCommand::NOTE noteStart = 0, ModCommand::NOTE noteEnd = 0);
+
+// Get window text (e.g. edit box content) as a CString
+CString GetWindowTextString(const CWnd &wnd);
+
+// Get window text (e.g. edit box content) as a unicode string
+mpt::ustring GetWindowTextUnicode(const CWnd &wnd);
+
+///////////////////////////////////////////////////
+// Tables
+
+extern const TCHAR *szSpecialNoteNamesMPT[];
+extern const TCHAR *szSpecialNoteShortDesc[];
+extern const char *szHexChar;
+
+// Defined in load_mid.cpp
+extern const char *szMidiProgramNames[128];
+extern const char *szMidiPercussionNames[61]; // notes 25..85
+extern const char *szMidiGroupNames[17]; // 16 groups + Percussions
+
+/////////////////////////////////////////////////////////////////////////////
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
+
+
+OPENMPT_NAMESPACE_END