123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467 |
- /*
- * 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
|