/* * TrackerSettings.h * ----------------- * Purpose: Header file for application setting handling. * Notes : (currently none) * Authors: Olivier Lapicque * 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 "mpt/uuid/uuid.hpp" #include "../common/Logging.h" #include "../common/version.h" #include "openmpt/soundbase/SampleFormat.hpp" #include "../soundlib/MixerSettings.h" #include "../soundlib/Resampler.h" #include "../sounddsp/EQ.h" #include "../sounddsp/DSP.h" #include "../sounddsp/Reverb.h" #include "openmpt/sounddevice/SoundDevice.hpp" #include "StreamEncoderSettings.h" #include "Settings.h" #include <array> #include <bitset> OPENMPT_NAMESPACE_BEGIN namespace SoundDevice { class Manager; } // namespace SoundDevice namespace Tuning { class CTuningCollection; } // namespace Tuning using CTuningCollection = Tuning::CTuningCollection; // User-defined colors enum ModColor : uint8 { MODCOLOR_BACKNORMAL = 0, MODCOLOR_TEXTNORMAL, MODCOLOR_BACKCURROW, MODCOLOR_TEXTCURROW, MODCOLOR_BACKSELECTED, MODCOLOR_TEXTSELECTED, MODCOLOR_SAMPLE, MODCOLOR_BACKPLAYCURSOR, MODCOLOR_TEXTPLAYCURSOR, MODCOLOR_BACKHILIGHT, MODCOLOR_NOTE, MODCOLOR_INSTRUMENT, MODCOLOR_VOLUME, MODCOLOR_PANNING, MODCOLOR_PITCH, MODCOLOR_GLOBALS, MODCOLOR_ENVELOPES, MODCOLOR_VUMETER_LO, MODCOLOR_VUMETER_MED, MODCOLOR_VUMETER_HI, MODCOLOR_SEPSHADOW, MODCOLOR_SEPFACE, MODCOLOR_SEPHILITE, MODCOLOR_BLENDCOLOR, MODCOLOR_DODGY_COMMANDS, MODCOLOR_BACKSAMPLE, MODCOLOR_SAMPLESELECTED, MODCOLOR_BACKENV, MODCOLOR_VUMETER_LO_VST, MODCOLOR_VUMETER_MED_VST, MODCOLOR_VUMETER_HI_VST, MODCOLOR_ENVELOPE_RELEASE, MODCOLOR_SAMPLE_LOOPMARKER, MODCOLOR_SAMPLE_SUSTAINMARKER, MODCOLOR_SAMPLE_CUEPOINT, MAX_MODCOLORS, // Internal color codes (not saved to color preset files) MODCOLOR_2NDHIGHLIGHT, MODCOLOR_DEFAULTVOLUME, MODCOLOR_DUMMYCOMMAND, MAX_MODPALETTECOLORS }; // Pattern Setup (contains also non-pattern related settings) // Feel free to replace the deprecated flags by new flags, but be sure to // update TrackerSettings::TrackerSettings() as well. #define PATTERN_PLAYNEWNOTE 0x01 // play new notes while recording #define PATTERN_SMOOTHSCROLL 0x02 // scroll tick by tick, not row by row #define PATTERN_STDHIGHLIGHT 0x04 // enable primary highlight (measures) #define PATTERN_NOFOLLOWONCLICK 0x08 // disable song follow when clicking into pattern #define PATTERN_CENTERROW 0x10 // always center active row #define PATTERN_WRAP 0x20 // wrap around cursor in editor #define PATTERN_EFFECTHILIGHT 0x40 // effect syntax highlighting #define PATTERN_HEXDISPLAY 0x80 // display row number in hex #define PATTERN_FLATBUTTONS 0x100 // flat toolbar buttons #define PATTERN_PLAYNAVIGATEROW 0x200 // play whole row when navigating #define PATTERN_SINGLEEXPAND 0x400 // single click to expand tree #define PATTERN_PLAYEDITROW 0x800 // play all notes on the current row while entering notes #define PATTERN_NOEXTRALOUD 0x1000 // no loud samples in sample editor #define PATTERN_DRAGNDROPEDIT 0x2000 // enable drag and drop editing #define PATTERN_2NDHIGHLIGHT 0x4000 // activate secondary highlight (beats) #define PATTERN_MUTECHNMODE 0x8000 // ignore muted channels #define PATTERN_SHOWPREVIOUS 0x10000 // show prev/next patterns #define PATTERN_CONTSCROLL 0x20000 // continous pattern scrolling #define PATTERN_KBDNOTEOFF 0x40000 // Record note-off events #define PATTERN_FOLLOWSONGOFF 0x80000 // follow song off by default #define PATTERN_PLAYTRANSPOSE 0x100000 // Preview note transposition #define PATTERN_NOCLOSEDIALOG 0x200000 // Don't use OpenMPT's custom close dialog with a list of saved files when closing the main window #define PATTERN_DBLCLICKSELECT 0x400000 // Double-clicking pattern selects whole channel #define PATTERN_OLDCTXMENUSTYLE 0x800000 // Hide pattern context menu entries instead of greying them out. #define PATTERN_SYNCMUTE 0x1000000 // maintain sample sync on mute #define PATTERN_AUTODELAY 0x2000000 // automatically insert delay commands in pattern when entering notes #define PATTERN_NOTEFADE 0x4000000 // alt. note fade behaviour when entering notes #define PATTERN_OVERFLOWPASTE 0x8000000 // continue paste in the next pattern instead of cutting off #define PATTERN_SHOWDEFAULTVOLUME 0x10000000 // if there is no volume command next to note+instr, display the sample's default volume. #define PATTERN_RESETCHANNELS 0x20000000 // reset channels when looping #define PATTERN_LIVEUPDATETREE 0x40000000 // update active sample / instr icons in treeview #define PATTERN_SYNCSAMPLEPOS 0x80000000 // sync sample positions when seeking #define PATTERNFONT_SMALL UL_("@1") #define PATTERNFONT_LARGE UL_("@2") // MIDI Setup #define MIDISETUP_RECORDVELOCITY 0x01 // Record MIDI velocity #define MIDISETUP_TRANSPOSEKEYBOARD 0x02 // Apply transpose value to MIDI Notes #define MIDISETUP_MIDITOPLUG 0x04 // Pass MIDI messages to plugins #define MIDISETUP_MIDIVOL_TO_NOTEVOL 0x08 // Combine MIDI volume to note velocity #define MIDISETUP_RECORDNOTEOFF 0x10 // Record MIDI Note Off to pattern #define MIDISETUP_RESPONDTOPLAYCONTROLMSGS 0x20 // Respond to Restart/Continue/Stop MIDI commands #define MIDISETUP_MIDIMACROCONTROL 0x80 // Record MIDI controller changes a MIDI macro changes in pattern #define MIDISETUP_PLAYPATTERNONMIDIIN 0x100 // Play pattern if MIDI Note is received and playback is paused #define MIDISETUP_ENABLE_RECORD_DEFAULT 0x200 // Enable MIDI recording by default #define MIDISETUP_MIDIMACROPITCHBEND 0x400 // Record MIDI pitch bend messages a MIDI macro changes in pattern #ifndef NO_EQ // EQ struct EQPresetPacked { char szName[12]; // locale encoding uint32le Gains[MAX_EQ_BANDS]; uint32le Freqs[MAX_EQ_BANDS]; }; MPT_BINARY_STRUCT(EQPresetPacked, 60) struct EQPreset { char szName[12]; // locale encoding uint32 Gains[MAX_EQ_BANDS]; uint32 Freqs[MAX_EQ_BANDS]; }; template<> inline SettingValue ToSettingValue(const EQPreset &val) { EQPresetPacked valpacked; std::memcpy(valpacked.szName, val.szName, std::size(valpacked.szName)); std::copy(val.Gains, val.Gains + MAX_EQ_BANDS, valpacked.Gains); std::copy(val.Freqs, val.Freqs + MAX_EQ_BANDS, valpacked.Freqs); return SettingValue(EncodeBinarySetting<EQPresetPacked>(valpacked), "EQPreset"); } template<> inline EQPreset FromSettingValue(const SettingValue &val) { ASSERT(val.GetTypeTag() == "EQPreset"); EQPresetPacked valpacked = DecodeBinarySetting<EQPresetPacked>(val.as<std::vector<std::byte> >()); EQPreset valresult; std::memcpy(valresult.szName, valpacked.szName, std::size(valresult.szName)); std::copy(valpacked.Gains, valpacked.Gains + MAX_EQ_BANDS, valresult.Gains); std::copy(valpacked.Freqs, valpacked.Freqs + MAX_EQ_BANDS, valresult.Freqs); return valresult; } #endif // !NO_EQ template<> inline SettingValue ToSettingValue(const mpt::UUID &val) { return SettingValue(val.ToUString()); } template<> inline mpt::UUID FromSettingValue(const SettingValue &val) { return mpt::UUID::FromString(val.as<mpt::ustring>()); } // Chords struct MPTChord { enum { notesPerChord = 4, relativeMode = 0x3F, noNote = int8_min, }; using NoteType = int8; uint8 key; // Base note std::array<NoteType, notesPerChord - 1> notes; // Additional chord notes }; using MPTChords = std::array<MPTChord, 3 * 12>; // 3 octaves // MIDI recording enum RecordAftertouchOptions { atDoNotRecord = 0, atRecordAsVolume, atRecordAsMacro, }; // New file action enum NewFileAction { nfDefaultFormat = 0, nfSameAsCurrent, nfDefaultTemplate }; // Sample editor preview behaviour enum SampleEditorKeyBehaviour { seNoteOffOnNewKey = 0, seNoteOffOnKeyUp, seNoteOffOnKeyRestrike, }; enum SampleEditorDefaultFormat { dfFLAC, dfWAV, dfRAW, dfS3I, }; enum class TimelineFormat { Seconds = 0, Samples, SamplesPow2, }; enum class DefaultChannelColors { NoColors = 0, Rainbow, Random, }; class SampleUndoBufferSize { protected: size_t sizeByte; int32 sizePercent; void CalculateSize(); public: enum { defaultSize = 10, // In percent }; SampleUndoBufferSize(int32 percent = defaultSize) : sizePercent(percent) { CalculateSize(); } void Set(int32 percent) { sizePercent = percent; CalculateSize(); } int32 GetSizeInPercent() const { return sizePercent; } size_t GetSizeInBytes() const { return sizeByte; } }; template<> inline SettingValue ToSettingValue(const SampleUndoBufferSize &val) { return SettingValue(val.GetSizeInPercent()); } template<> inline SampleUndoBufferSize FromSettingValue(const SettingValue &val) { return SampleUndoBufferSize(val.as<int32>()); } mpt::ustring IgnoredCCsToString(const std::bitset<128> &midiIgnoreCCs); std::bitset<128> StringToIgnoredCCs(const mpt::ustring &in); mpt::ustring SettingsModTypeToString(MODTYPE modtype); MODTYPE SettingsStringToModType(const mpt::ustring &str); template<> inline SettingValue ToSettingValue(const RecordAftertouchOptions &val) { return SettingValue(int32(val)); } template<> inline RecordAftertouchOptions FromSettingValue(const SettingValue &val) { return RecordAftertouchOptions(val.as<int32>()); } template<> inline SettingValue ToSettingValue(const SampleEditorKeyBehaviour &val) { return SettingValue(int32(val)); } template<> inline SampleEditorKeyBehaviour FromSettingValue(const SettingValue &val) { return SampleEditorKeyBehaviour(val.as<int32>()); } template<> inline SettingValue ToSettingValue(const TimelineFormat &val) { return SettingValue(int32(val)); } template<> inline TimelineFormat FromSettingValue(const SettingValue &val) { return TimelineFormat(val.as<int32>()); } template<> inline SettingValue ToSettingValue(const DefaultChannelColors & val) { return SettingValue(int32(val)); } template<> inline DefaultChannelColors FromSettingValue(const SettingValue& val) { return DefaultChannelColors(val.as<int32>()); } template<> inline SettingValue ToSettingValue(const MODTYPE &val) { return SettingValue(SettingsModTypeToString(val), "MODTYPE"); } template<> inline MODTYPE FromSettingValue(const SettingValue &val) { ASSERT(val.GetTypeTag() == "MODTYPE"); return SettingsStringToModType(val.as<mpt::ustring>()); } template<> inline SettingValue ToSettingValue(const PlugVolumeHandling &val) { return SettingValue(int32(val), "PlugVolumeHandling"); } template<> inline PlugVolumeHandling FromSettingValue(const SettingValue &val) { ASSERT(val.GetTypeTag() == "PlugVolumeHandling"); if((uint32)val.as<int32>() > PLUGIN_VOLUMEHANDLING_MAX) { return PLUGIN_VOLUMEHANDLING_IGNORE; } return static_cast<PlugVolumeHandling>(val.as<int32>()); } template<> inline SettingValue ToSettingValue(const std::vector<uint32> &val) { return mpt::String::Combine(val, U_(",")); } template<> inline std::vector<uint32> FromSettingValue(const SettingValue &val) { return mpt::String::Split<uint32>(val, U_(",")); } template<> inline SettingValue ToSettingValue(const std::vector<mpt::ustring> &val) { return mpt::String::Combine(val, U_(";")); } template<> inline std::vector<mpt::ustring> FromSettingValue(const SettingValue &val) { return mpt::String::Split<mpt::ustring>(val, U_(";")); } template<> inline SettingValue ToSettingValue(const SampleFormat &val) { return SettingValue(val.AsInt()); } template<> inline SampleFormat FromSettingValue(const SettingValue &val) { return SampleFormat::FromInt(val.as<int32>()); } template<> inline SettingValue ToSettingValue(const SoundDevice::ChannelMapping &val) { return SettingValue(val.ToUString(), "ChannelMapping"); } template<> inline SoundDevice::ChannelMapping FromSettingValue(const SettingValue &val) { ASSERT(val.GetTypeTag() == "ChannelMapping"); return SoundDevice::ChannelMapping::FromString(val.as<mpt::ustring>()); } template<> inline SettingValue ToSettingValue(const ResamplingMode &val) { return SettingValue(int32(val)); } template<> inline ResamplingMode FromSettingValue(const SettingValue &val) { return ResamplingMode(val.as<int32>()); } template<> inline SettingValue ToSettingValue(const Resampling::AmigaFilter &val) { return SettingValue(int32(val)); } template<> inline Resampling::AmigaFilter FromSettingValue(const SettingValue &val) { return static_cast<Resampling::AmigaFilter>(val.as<int32>()); } template<> inline SettingValue ToSettingValue(const NewFileAction &val) { return SettingValue(int32(val)); } template<> inline NewFileAction FromSettingValue(const SettingValue &val) { return NewFileAction(val.as<int32>()); } template<> inline SettingValue ToSettingValue(const std::bitset<128> &val) { return SettingValue(IgnoredCCsToString(val), "IgnoredCCs"); } template<> inline std::bitset<128> FromSettingValue(const SettingValue &val) { ASSERT(val.GetTypeTag() == "IgnoredCCs"); return StringToIgnoredCCs(val.as<mpt::ustring>()); } template<> inline SettingValue ToSettingValue(const SampleEditorDefaultFormat &val) { mpt::ustring format; switch(val) { case dfWAV: format = U_("wav"); break; case dfFLAC: default: format = U_("flac"); break; case dfRAW: format = U_("raw"); break; case dfS3I: format = U_("s3i"); break; } return SettingValue(format); } template<> inline SampleEditorDefaultFormat FromSettingValue(const SettingValue &val) { mpt::ustring format = mpt::ToLowerCase(val.as<mpt::ustring>()); if(format == U_("wav")) return dfWAV; if(format == U_("raw")) return dfRAW; if(format == U_("s3i")) return dfS3I; else // if(format == U_("flac")) return dfFLAC; } enum SoundDeviceStopMode { SoundDeviceStopModeClosed = 0, SoundDeviceStopModeStopped = 1, SoundDeviceStopModePlaying = 2, }; template<> inline SettingValue ToSettingValue(const SoundDeviceStopMode &val) { return SettingValue(static_cast<int32>(val)); } template<> inline SoundDeviceStopMode FromSettingValue(const SettingValue &val) { return static_cast<SoundDeviceStopMode>(static_cast<int32>(val)); } enum ProcessPriorityClass { ProcessPriorityClassIDLE = IDLE_PRIORITY_CLASS, ProcessPriorityClassBELOW = BELOW_NORMAL_PRIORITY_CLASS, ProcessPriorityClassNORMAL = NORMAL_PRIORITY_CLASS, ProcessPriorityClassABOVE = ABOVE_NORMAL_PRIORITY_CLASS, ProcessPriorityClassHIGH = HIGH_PRIORITY_CLASS, ProcessPriorityClassREALTIME = REALTIME_PRIORITY_CLASS }; template<> inline SettingValue ToSettingValue(const ProcessPriorityClass &val) { mpt::ustring s; switch(val) { case ProcessPriorityClassIDLE: s = U_("idle"); break; case ProcessPriorityClassBELOW: s = U_("below"); break; case ProcessPriorityClassNORMAL: s = U_("normal"); break; case ProcessPriorityClassABOVE: s = U_("above"); break; case ProcessPriorityClassHIGH: s = U_("high"); break; case ProcessPriorityClassREALTIME: s = U_("realtime"); break; default: s = U_("normal"); break; } return SettingValue(s); } template<> inline ProcessPriorityClass FromSettingValue(const SettingValue &val) { ProcessPriorityClass result = ProcessPriorityClassNORMAL; mpt::ustring s = val.as<mpt::ustring>(); if(s.empty()) { result = ProcessPriorityClassNORMAL; } else if(s == U_("idle")) { result = ProcessPriorityClassIDLE; } else if(s == U_("below")) { result = ProcessPriorityClassBELOW; } else if(s == U_("normal")) { result = ProcessPriorityClassNORMAL; } else if(s == U_("above")) { result = ProcessPriorityClassABOVE; } else if(s == U_("high")) { result = ProcessPriorityClassHIGH; } else if(s == U_("realtime")) { result = ProcessPriorityClassREALTIME; } else { result = ProcessPriorityClassNORMAL; } return result; } template<> inline SettingValue ToSettingValue(const mpt::Date::Unix &val) { time_t t = val; const tm* lastUpdate = gmtime(&t); CString outDate; if(lastUpdate) { outDate.Format(_T("%04d-%02d-%02d %02d:%02d"), lastUpdate->tm_year + 1900, lastUpdate->tm_mon + 1, lastUpdate->tm_mday, lastUpdate->tm_hour, lastUpdate->tm_min); } return SettingValue(mpt::ToUnicode(outDate), "UTC"); } template<> inline mpt::Date::Unix FromSettingValue(const SettingValue &val) { MPT_ASSERT(val.GetTypeTag() == "UTC"); std::string s = mpt::ToCharset(mpt::Charset::Locale, val.as<mpt::ustring>()); tm lastUpdate; MemsetZero(lastUpdate); if(sscanf(s.c_str(), "%04d-%02d-%02d %02d:%02d", &lastUpdate.tm_year, &lastUpdate.tm_mon, &lastUpdate.tm_mday, &lastUpdate.tm_hour, &lastUpdate.tm_min) == 5) { lastUpdate.tm_year -= 1900; lastUpdate.tm_mon--; } time_t outTime = mpt::Date::Unix::FromUTC(lastUpdate); if(outTime < 0) { outTime = 0; } return mpt::Date::Unix(outTime); } struct FontSetting { enum FontFlags { None = 0, Bold = 1, Italic = 2, }; mpt::ustring name; int32 size; FlagSet<FontFlags> flags; FontSetting(const mpt::ustring &name = U_(""), int32 size = 120, FontFlags flags = None) : name(name), size(size), flags(flags) { } bool operator== (const FontSetting &other) const { return name == other.name && size == other.size && flags == other.flags; } bool operator!= (const FontSetting &other) const { return !(*this == other); } }; MPT_DECLARE_ENUM(FontSetting::FontFlags) template<> inline SettingValue ToSettingValue(const FontSetting &val) { return SettingValue(mpt::ToUnicode(val.name) + U_(",") + mpt::ufmt::val(val.size) + U_("|") + mpt::ufmt::val(val.flags.GetRaw())); } template<> inline FontSetting FromSettingValue(const SettingValue &val) { FontSetting setting(val.as<mpt::ustring>()); std::size_t sizeStart = setting.name.rfind(UC_(',')); if(sizeStart != std::string::npos) { const std::vector<mpt::ustring> fields = mpt::String::Split<mpt::ustring>(setting.name.substr(sizeStart + 1), U_("|")); if(fields.size() >= 1) { setting.size = ConvertStrTo<int32>(fields[0]); } if(fields.size() >= 2) { setting.flags = static_cast<FontSetting::FontFlags>(ConvertStrTo<int32>(fields[1])); } setting.name.resize(sizeStart); } return setting; } class DefaultAndWorkingDirectory { protected: mpt::PathString m_Default; mpt::PathString m_Working; public: DefaultAndWorkingDirectory(); DefaultAndWorkingDirectory(const mpt::PathString &def); ~DefaultAndWorkingDirectory(); public: void SetDefaultDir(const mpt::PathString &filenameFrom, bool stripFilename = false); void SetWorkingDir(const mpt::PathString &filenameFrom, bool stripFilename = false); mpt::PathString GetDefaultDir() const; mpt::PathString GetWorkingDir() const; private: bool InternalSet(mpt::PathString &dest, const mpt::PathString &filenameFrom, bool stripFilename); }; class ConfigurableDirectory : public DefaultAndWorkingDirectory { protected: SettingsContainer &conf; Setting<mpt::PathString> m_Setting; public: ConfigurableDirectory(SettingsContainer &conf, const AnyStringLocale §ion, const AnyStringLocale &key, const mpt::PathString &def); ~ConfigurableDirectory(); }; class DebugSettings { private: SettingsContainer &conf; private: // Debug #if !defined(MPT_LOG_IS_DISABLED) Setting<int> DebugLogLevel; Setting<std::string> DebugLogFacilitySolo; Setting<std::string> DebugLogFacilityBlocked; Setting<bool> DebugLogFileEnable; Setting<bool> DebugLogDebuggerEnable; Setting<bool> DebugLogConsoleEnable; #endif Setting<bool> DebugTraceEnable; Setting<uint32> DebugTraceSize; Setting<bool> DebugTraceAlwaysDump; Setting<bool> DebugStopSoundDeviceOnCrash; Setting<bool> DebugStopSoundDeviceBeforeDump; Setting<bool> DebugDelegateToWindowsHandler; public: DebugSettings(SettingsContainer &conf); ~DebugSettings(); }; namespace SoundDevice { namespace Legacy { typedef uint16 ID; inline constexpr SoundDevice::Legacy::ID MaskType = 0xff00; inline constexpr SoundDevice::Legacy::ID MaskIndex = 0x00ff; inline constexpr int ShiftType = 8; inline constexpr int ShiftIndex = 0; inline constexpr SoundDevice::Legacy::ID TypeWAVEOUT = 0; inline constexpr SoundDevice::Legacy::ID TypeDSOUND = 1; inline constexpr SoundDevice::Legacy::ID TypeASIO = 2; inline constexpr SoundDevice::Legacy::ID TypePORTAUDIO_WASAPI = 3; inline constexpr SoundDevice::Legacy::ID TypePORTAUDIO_WDMKS = 4; inline constexpr SoundDevice::Legacy::ID TypePORTAUDIO_WMME = 5; inline constexpr SoundDevice::Legacy::ID TypePORTAUDIO_DS = 6; } // namespace Legacy } // namespace SoundDevice class TrackerSettings { private: SettingsContainer &conf; public: // Version Setting<mpt::ustring> IniVersion; const bool FirstRun; const Version PreviousSettingsVersion; Setting<mpt::UUID> VersionInstallGUID; // Display Setting<bool> m_ShowSplashScreen; Setting<bool> gbMdiMaximize; Setting<bool> highResUI; Setting<LONG> glTreeSplitRatio; Setting<LONG> glTreeWindowWidth; Setting<LONG> glGeneralWindowHeight; Setting<LONG> glPatternWindowHeight; Setting<LONG> glSampleWindowHeight; Setting<LONG> glInstrumentWindowHeight; Setting<LONG> glCommentsWindowHeight; Setting<LONG> glGraphWindowHeight; Setting<int32> gnPlugWindowX; Setting<int32> gnPlugWindowY; Setting<int32> gnPlugWindowWidth; Setting<int32> gnPlugWindowHeight; Setting<int32> gnPlugWindowLast; // Last selected plugin ID Setting<uint32> gnMsgBoxVisiblityFlags; Setting<uint32> GUIUpdateInterval; CachedSetting<uint32> FSUpdateInterval; CachedSetting<uint32> VuMeterUpdateInterval; CachedSetting<float> VuMeterDecaySpeedDecibelPerSecond; CachedSetting<bool> accidentalFlats; Setting<bool> rememberSongWindows; Setting<bool> showDirsInSampleBrowser; Setting<DefaultChannelColors> defaultRainbowChannelColors; Setting<FontSetting> commentsFont; // Misc Setting<MODTYPE> defaultModType; Setting<NewFileAction> defaultNewFileAction; Setting<PlugVolumeHandling> DefaultPlugVolumeHandling; Setting<bool> autoApplySmoothFT2Ramping; CachedSetting<uint32> MiscITCompressionStereo; // Mask: bit0: IT, bit1: Compat IT, bit2: MPTM CachedSetting<uint32> MiscITCompressionMono; // Mask: bit0: IT, bit1: Compat IT, bit2: MPTM CachedSetting<bool> MiscSaveChannelMuteStatus; CachedSetting<bool> MiscAllowMultipleCommandsPerKey; CachedSetting<bool> MiscDistinguishModifiers; Setting<ProcessPriorityClass> MiscProcessPriorityClass; CachedSetting<bool> MiscFlushFileBuffersOnSave; CachedSetting<bool> MiscCacheCompleteFileBeforeLoading; Setting<bool> MiscUseSingleInstance; // Sound Settings bool m_SoundShowRecordingSettings; Setting<bool> m_SoundShowDeprecatedDevices; Setting<bool> m_SoundDeprecatedDeviceWarningShown; Setting<std::vector<uint32> > m_SoundSampleRates; Setting<bool> m_SoundSettingsOpenDeviceAtStartup; Setting<SoundDeviceStopMode> m_SoundSettingsStopMode; bool m_SoundDeviceSettingsUseOldDefaults; SoundDevice::Legacy::ID m_SoundDeviceID_DEPRECATED; SoundDevice::Settings m_SoundDeviceSettingsDefaults; SoundDevice::Settings GetSoundDeviceSettingsDefaults() const; #if defined(MPT_WITH_DIRECTSOUND) bool m_SoundDeviceDirectSoundOldDefaultIdentifier; #endif // MPT_WITH_DIRECTSOUND Setting<SoundDevice::Identifier> m_SoundDeviceIdentifier; SoundDevice::Identifier GetSoundDeviceIdentifier() const; void SetSoundDeviceIdentifier(const SoundDevice::Identifier &identifier); SoundDevice::Settings GetSoundDeviceSettings(const SoundDevice::Identifier &device) const; void SetSoundDeviceSettings(const SoundDevice::Identifier &device, const SoundDevice::Settings &settings); Setting<uint32> MixerMaxChannels; Setting<uint32> MixerDSPMask; Setting<uint32> MixerFlags; Setting<uint32> MixerSamplerate; Setting<uint32> MixerOutputChannels; Setting<uint32> MixerPreAmp; Setting<uint32> MixerStereoSeparation; Setting<uint32> MixerVolumeRampUpMicroseconds; Setting<uint32> MixerVolumeRampDownMicroseconds; Setting<uint32> MixerNumInputChannels; MixerSettings GetMixerSettings() const; void SetMixerSettings(const MixerSettings &settings); Setting<ResamplingMode> ResamplerMode; Setting<uint8> ResamplerSubMode; Setting<int32> ResamplerCutoffPercent; Setting<Resampling::AmigaFilter> ResamplerEmulateAmiga; CResamplerSettings GetResamplerSettings() const; void SetResamplerSettings(const CResamplerSettings &settings); Setting<int> SoundBoostedThreadPriority; Setting<mpt::ustring> SoundBoostedThreadMMCSSClass; Setting<bool> SoundBoostedThreadRealtimePosix; Setting<int> SoundBoostedThreadNicenessPosix; Setting<int> SoundBoostedThreadRtprioPosix; Setting<bool> SoundMaskDriverCrashes; Setting<bool> SoundAllowDeferredProcessing; // MIDI Settings Setting<UINT> m_nMidiDevice; Setting<CString> midiDeviceName; // FIXME: MIDI recording is currently done in its own callback/thread and // accesses settings framework from in there. Work-around the ASSERTs for // now by using cached settings. CachedSetting<uint32> m_dwMidiSetup; CachedSetting<RecordAftertouchOptions> aftertouchBehaviour; CachedSetting<uint16> midiVelocityAmp; CachedSetting<std::bitset<128> > midiIgnoreCCs; Setting<uint32> midiImportPatternLen; Setting<uint32> midiImportQuantize; Setting<uint8> midiImportTicks; // Pattern Editor CachedSetting<bool> gbLoopSong; CachedSetting<UINT> gnPatternSpacing; CachedSetting<bool> gbPatternVUMeters; CachedSetting<bool> gbPatternPluginNames; CachedSetting<bool> gbPatternRecord; CachedSetting<bool> patternNoEditPopup; CachedSetting<bool> patternStepCommands; CachedSetting<uint32> m_dwPatternSetup; CachedSetting<uint32> m_nRowHighlightMeasures; // primary (measures) and secondary (beats) highlight CachedSetting<uint32> m_nRowHighlightBeats; // primary (measures) and secondary (beats) highlight CachedSetting<ROWINDEX> recordQuantizeRows; CachedSetting<UINT> gnAutoChordWaitTime; CachedSetting<int32> orderlistMargins; CachedSetting<int32> rowDisplayOffset; Setting<FontSetting> patternFont; Setting<mpt::ustring> patternFontDot; Setting<int32> effectVisWidth; Setting<int32> effectVisHeight; Setting<int32> effectVisX; Setting<int32> effectVisY; Setting<CString> patternAccessibilityFormat; CachedSetting<bool> patternAlwaysDrawWholePatternOnScrollSlow; CachedSetting<bool> orderListOldDropBehaviour; // Sample Editor Setting<SampleUndoBufferSize> m_SampleUndoBufferSize; Setting<SampleEditorKeyBehaviour> sampleEditorKeyBehaviour; Setting<SampleEditorDefaultFormat> m_defaultSampleFormat; Setting<TimelineFormat> sampleEditorTimelineFormat; Setting<ResamplingMode> sampleEditorDefaultResampler; Setting<int32> m_nFinetuneStep; // Increment finetune by x cents when using spin control. Setting<int32> m_FLACCompressionLevel; // FLAC compression level for saving (0...8) Setting<bool> compressITI; Setting<bool> m_MayNormalizeSamplesOnLoad; Setting<bool> previewInFileDialogs; CachedSetting<bool> cursorPositionInHex; // Export Setting<bool> ExportDefaultToSoundcardSamplerate; StreamEncoderSettingsConf ExportStreamEncoderSettings; // Components Setting<bool> ComponentsLoadOnStartup; Setting<bool> ComponentsKeepLoaded; bool IsComponentBlocked(const std::string &name); // Effects #ifndef NO_REVERB CReverbSettings m_ReverbSettings; #endif #ifndef NO_DSP CSurroundSettings m_SurroundSettings; #endif #ifndef NO_DSP CMegaBassSettings m_MegaBassSettings; #endif #ifndef NO_EQ EQPreset m_EqSettings; EQPreset m_EqUserPresets[4]; #endif #ifndef NO_DSP BitCrushSettings m_BitCrushSettings; #endif // Display (Colors) std::array<COLORREF, MAX_MODCOLORS> rgbCustomColors; // AutoSave CachedSetting<bool> CreateBackupFiles; CachedSetting<bool> AutosaveEnabled; CachedSetting<uint32> AutosaveIntervalMinutes; CachedSetting<uint32> AutosaveHistoryDepth; CachedSetting<bool> AutosaveUseOriginalPath; ConfigurableDirectory AutosavePath; // Paths ConfigurableDirectory PathSongs; ConfigurableDirectory PathSamples; ConfigurableDirectory PathInstruments; ConfigurableDirectory PathPlugins; ConfigurableDirectory PathPluginPresets; ConfigurableDirectory PathExport; DefaultAndWorkingDirectory PathTunings; DefaultAndWorkingDirectory PathUserTemplates; mpt::PathString m_szKbdFile; // Default template Setting<mpt::PathString> defaultTemplateFile; Setting<mpt::ustring> defaultArtist; Setting<uint32> mruListLength; std::vector<mpt::PathString> mruFiles; // Chords MPTChords Chords; // Tunings std::unique_ptr<CTuningCollection> oldLocalTunings; // Plugins Setting<bool> bridgeAllPlugins; Setting<bool> enableAutoSuspend; CachedSetting<bool> midiMappingInPluginEditor; Setting<mpt::ustring> pluginProjectPath; CachedSetting<mpt::lstring> vstHostProductString; CachedSetting<mpt::lstring> vstHostVendorString; CachedSetting<int32> vstHostVendorVersion; // Broken Plugins Workarounds Setting<bool> BrokenPluginsWorkaroundVSTMaskAllCrashes; Setting<bool> BrokenPluginsWorkaroundVSTNeverUnloadAnyPlugin; #if defined(MPT_ENABLE_UPDATE) // Update Setting<bool> UpdateEnabled; Setting<bool> UpdateInstallAutomatically; Setting<mpt::Date::Unix> UpdateLastUpdateCheck; Setting<int32> UpdateUpdateCheckPeriod_DEPRECATED; Setting<int32> UpdateIntervalDays; Setting<uint32> UpdateChannel; Setting<mpt::ustring> UpdateUpdateURL_DEPRECATED; Setting<mpt::ustring> UpdateAPIURL; Setting<bool> UpdateStatisticsConsentAsked; Setting<bool> UpdateStatistics; Setting<bool> UpdateSendGUID_DEPRECATED; Setting<bool> UpdateShowUpdateHint; Setting<CString> UpdateIgnoreVersion; Setting<bool> UpdateSkipSignatureVerificationUNSECURE; Setting<std::vector<mpt::ustring>> UpdateSigningKeysRootAnchors; #endif // MPT_ENABLE_UPDATE // Wine support Setting<bool> WineSupportEnabled; Setting<bool> WineSupportAlwaysRecompile; Setting<bool> WineSupportAskCompile; Setting<int32> WineSupportCompileVerbosity; Setting<bool> WineSupportForeignOpenMPT; Setting<bool> WineSupportAllowUnknownHost; Setting<int32> WineSupportEnablePulseAudio; // 0==off 1==auto 2==on Setting<int32> WineSupportEnablePortAudio; // 0==off 1==auto 2==on Setting<int32> WineSupportEnableRtAudio; // 0==off 1==auto 2==on public: TrackerSettings(SettingsContainer &conf); ~TrackerSettings(); void MigrateOldSoundDeviceSettings(SoundDevice::Manager &manager); private: void MigrateTunings(const Version storedVersion); std::unique_ptr<CTuningCollection> LoadLocalTunings(); public: void SaveSettings(); static void GetDefaultColourScheme(std::array<COLORREF, MAX_MODCOLORS> &colours); std::vector<uint32> GetSampleRates() const; static MPTChords &GetChords() { return Instance().Chords; } // Get settings object singleton static TrackerSettings &Instance(); void SetMIDIDevice(UINT id); UINT GetCurrentMIDIDevice(); protected: static std::vector<uint32> GetDefaultSampleRates(); #ifndef NO_EQ void FixupEQ(EQPreset &eqSettings); #endif // !NO_EQ void LoadChords(MPTChords &chords); void SaveChords(MPTChords &chords); }; OPENMPT_NAMESPACE_END