diff options
Diffstat (limited to 'Src/external_dependencies/openmpt-trunk/mptrack/Mptrack.h')
-rw-r--r-- | Src/external_dependencies/openmpt-trunk/mptrack/Mptrack.h | 467 |
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 |