From 729047d4495a3e232b5359fd87a2cb127a566a6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 22 Oct 2026 15:34:47 +0200 Subject: [PATCH] Config: Make the setting tables constexpr SETTING now takes offsets with offsetof and passes them along with the setting's type, instead of the block and member pointers, and the ConfigSetting constructors are constexpr. So the tables are built at compile time, and later per-setting metadata can be checked by the compiler too. Defaults that weren't constants had to change: - AutoFrameSkip called IsVREnabled() during static initialization, before VR is set up. It's now a default callback, evaluated when the config is loaded or reset, which can turn it on by default on VR devices. - DisplayRefreshRate read g_Config's own initial value, which is 60. Path defaults now share the string member of the default union. Co-Authored-By: Claude Opus 5.5 (1M context) --- Core/Config.cpp | 66 ++++++++------ Core/ConfigSettings.cpp | 6 +- Core/ConfigSettings.h | 193 +++++++++++++++------------------------- 3 files changed, 115 insertions(+), 150 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index 799f77c726..d78ef38082 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -16,10 +16,12 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include +#include #include #include #include #include +#include #include #include @@ -249,11 +251,19 @@ static int DefaultScreenRotation() { #endif } -#define SETTING(a, x) &a, &a.x -#define SETTING_IDX(a, x, i) &a, &a.x[i] +#if defined(__GNUC__) || defined(__clang__) +// offsetof on classes with virtual functions (like ConfigBlock) is conditionally supported, and our compilers do support it. +#pragma GCC diagnostic ignored "-Winvalid-offsetof" +#endif + +// The type of the block a setting lives in, from an expression like g_Config or g_Config.gestureControls[0]. +#define CONFIG_BLOCK_TYPE(a) std::remove_reference_t +// Offsets are taken with offsetof, so the tables can be constexpr. +#define SETTING(a, x) ConfigSettingOffset{ (uint32_t)offsetof(CONFIG_BLOCK_TYPE(a), x) } +#define SETTING_IDX(a, x, i) ConfigSettingOffset>{ (uint32_t)(offsetof(CONFIG_BLOCK_TYPE(a), x) + (i) * sizeof(std::remove_extent_t)) } // All relative to g_Config. -static const ConfigSetting generalSettings[] = { +static constexpr ConfigSetting generalSettings[] = { ConfigSetting("FirstRun", SETTING(g_Config, bFirstRun), true, CfgFlag::DEFAULT), ConfigSetting("RunCount", SETTING(g_Config, iRunCount), 0, CfgFlag::DEFAULT), ConfigSetting("Enable Logging", SETTING(g_Config, bEnableLogging), true, CfgFlag::PER_GAME), @@ -405,7 +415,7 @@ static bool DefaultSasThread() { return cpu_info.num_cores > 1; } -static const ConfigSetting achievementSettings[] = { +static constexpr ConfigSetting achievementSettings[] = { // Core settings ConfigSetting("AchievementsEnable", SETTING(g_Config, bAchievementsEnable), false, CfgFlag::PER_GAME), ConfigSetting("AchievementsEnableRAIntegration", SETTING(g_Config, bAchievementsEnableRAIntegration), false, CfgFlag::DEFAULT), @@ -435,7 +445,7 @@ static const ConfigSetting achievementSettings[] = { ConfigSetting("AchievementsUnlockedPos", SETTING(g_Config, iAchievementsUnlockedPos), (int)ScreenEdgePosition::TOP_CENTER, CfgFlag::PER_GAME | CfgFlag::DEFAULT), }; -static const ConfigSetting cpuSettings[] = { +static constexpr ConfigSetting cpuSettings[] = { ConfigSetting("CPUCore", SETTING(g_Config, iCpuCore), &DefaultCpuCore, CfgFlag::PER_GAME | CfgFlag::REPORT), ConfigSetting("SeparateSASThread", SETTING(g_Config, bSeparateSASThread), &DefaultSasThread, CfgFlag::PER_GAME | CfgFlag::REPORT), ConfigSetting("IOTimingMethod", SETTING(g_Config, iIOTimingMethod), IOTIMING_FAST, CfgFlag::PER_GAME | CfgFlag::REPORT), @@ -676,7 +686,7 @@ bool DisplayLayoutConfig::ResetToDefault(std::string_view blockName) { // These were previously part of Graphics. // It's instantiated into g_Config.displayLayoutLandscape and g_Config.displayLayoutPortrait. // Defaults are set directly on the struct declaration (and adjusted per instance in ResetToDefault above). -static const ConfigSetting displayLayoutSettings[] = { +static constexpr ConfigSetting displayLayoutSettings[] = { ConfigSetting("BufferFiltering", SETTING(g_Config.displayLayoutLandscape, iDisplayFilter), CfgFlag::PER_GAME), ConfigSetting("DisplayStretch", SETTING(g_Config.displayLayoutLandscape, bDisplayStretch), CfgFlag::PER_GAME), ConfigSetting("DisplayOffsetX", SETTING(g_Config.displayLayoutLandscape, fDisplayOffsetX), CfgFlag::PER_GAME), @@ -702,7 +712,7 @@ bool GestureControlConfig::ResetToDefault(std::string_view blockName) { } // These were previously mostly part of General (which was wrong). -static const ConfigSetting gestureControlSettings[] = { +static constexpr ConfigSetting gestureControlSettings[] = { ConfigSetting("SwipeUp", SETTING(g_Config.gestureControls[0], iSwipeUp), 0, CfgFlag::PER_GAME), ConfigSetting("SwipeDown", SETTING(g_Config.gestureControls[0], iSwipeDown), 0, CfgFlag::PER_GAME), ConfigSetting("SwipeLeft", SETTING(g_Config.gestureControls[0], iSwipeLeft), 0, CfgFlag::PER_GAME), @@ -732,7 +742,7 @@ static int DefaultAnalogAltSpeedPercent() { return LegacyFpsLimitToPercent(g_Config.iLegacyAnalogFpsLimit); } -static const ConfigSetting graphicsSettings[] = { +static constexpr ConfigSetting graphicsSettings[] = { ConfigSetting("iShowStatusFlags", SETTING(g_Config, iShowStatusFlags), 0, CfgFlag::PER_GAME), ConfigSetting("GraphicsBackend", SETTING(g_Config, iGPUBackend), &DefaultGPUBackend, &GPUBackendTranslator::To, &GPUBackendTranslator::From, CfgFlag::DEFAULT | CfgFlag::REPORT), #if PPSSPP_PLATFORM(ANDROID) && PPSSPP_ARCH(ARM64) @@ -758,7 +768,7 @@ static const ConfigSetting graphicsSettings[] = { ConfigSetting("AndroidHwScale", SETTING(g_Config, iAndroidHwScale), 0, CfgFlag::DEFAULT), ConfigSetting("HighQualityDepth", SETTING(g_Config, bHighQualityDepth), true, CfgFlag::PER_GAME | CfgFlag::REPORT), ConfigSetting("FrameSkip", SETTING(g_Config, iFrameSkip), 0, CfgFlag::PER_GAME | CfgFlag::REPORT), - ConfigSetting("AutoFrameSkip", SETTING(g_Config, bAutoFrameSkip), IsVREnabled(), CfgFlag::PER_GAME | CfgFlag::REPORT), + ConfigSetting("AutoFrameSkip", SETTING(g_Config, bAutoFrameSkip), &IsVREnabled, CfgFlag::PER_GAME | CfgFlag::REPORT), ConfigSetting("StereoRendering", SETTING(g_Config, bStereoRendering), false, CfgFlag::PER_GAME), ConfigSetting("StereoToMonoShader", SETTING(g_Config, sStereoToMonoShader), "RedBlue", CfgFlag::PER_GAME), // Read before the new settings, which use them as defaults. @@ -823,7 +833,7 @@ static const ConfigSetting graphicsSettings[] = { ConfigSetting("UberShaderVertex", SETTING(g_Config, bUberShaderVertex), true, CfgFlag::DEFAULT), - ConfigSetting("DisplayRefreshRate", SETTING(g_Config, iDisplayRefreshRate), g_Config.iDisplayRefreshRate, CfgFlag::PER_GAME), + ConfigSetting("DisplayRefreshRate", SETTING(g_Config, iDisplayRefreshRate), 60, CfgFlag::PER_GAME), }; static int LegacyVolumeToNewVolume(int legacy, int max) { @@ -864,7 +874,7 @@ bool DefaultAudioMixWithOthers() { #endif } -static const ConfigSetting soundSettings[] = { +static constexpr ConfigSetting soundSettings[] = { ConfigSetting("Enable", SETTING(g_Config, bEnableSound), true, CfgFlag::PER_GAME), ConfigSetting("ExtraAudioBuffering", SETTING(g_Config, bExtraAudioBuffering), false, CfgFlag::DEFAULT), ConfigSetting("AudioBufferSize", SETTING(g_Config, iSDLAudioBufferSize), 256, CfgFlag::DEFAULT), @@ -904,9 +914,9 @@ static bool DefaultShowTouchControls() { } } -static const float defaultControlScale = 1.15f; -static const ConfigTouchPos defaultTouchPosShow = { -1.0f, -1.0f, defaultControlScale, true }; -static const ConfigTouchPos defaultTouchPosHide = { -1.0f, -1.0f, defaultControlScale, false }; +static constexpr float defaultControlScale = 1.15f; +static constexpr ConfigTouchPos defaultTouchPosShow = { -1.0f, -1.0f, defaultControlScale, true }; +static constexpr ConfigTouchPos defaultTouchPosHide = { -1.0f, -1.0f, defaultControlScale, false }; void TouchControlConfig::ResetLayout() { // reset puts the settings in a state so they'll then get properly reinitialized in InitPadLayout. @@ -954,7 +964,7 @@ bool TouchControlConfig::ResetToDefault(std::string_view blockName) { return true; } -static const ConfigSetting touchControlSettings[] = { +static constexpr ConfigSetting touchControlSettings[] = { ConfigSetting("ShowTouchCross", SETTING(g_Config.touchControlsLandscape, bShowTouchCross), true, CfgFlag::PER_GAME), ConfigSetting("ShowTouchCircle", SETTING(g_Config.touchControlsLandscape, bShowTouchCircle), true, CfgFlag::PER_GAME), ConfigSetting("ShowTouchSquare", SETTING(g_Config.touchControlsLandscape, bShowTouchSquare), true, CfgFlag::PER_GAME), @@ -1003,7 +1013,7 @@ static const ConfigSetting touchControlSettings[] = { ConfigSetting("HideStickBackground", SETTING(g_Config.touchControlsLandscape, bHideStickBackground), CfgFlag::PER_GAME), }; -static const ConfigSetting controlSettings[] = { +static constexpr ConfigSetting controlSettings[] = { ConfigSetting("HapticFeedback", SETTING(g_Config, bHapticFeedback), false, CfgFlag::PER_GAME), #if PPSSPP_PLATFORM(WINDOWS) @@ -1094,7 +1104,7 @@ static const ConfigSetting controlSettings[] = { static const std::vector emptyList; -static const ConfigSetting networkSettings[] = { +static constexpr ConfigSetting networkSettings[] = { ConfigSetting("EnableWlan", SETTING(g_Config, bEnableWlan), false, CfgFlag::PER_GAME), ConfigSetting("EnableAdhocServer", SETTING(g_Config, bEnableAdhocServer), false, CfgFlag::PER_GAME), ConfigSetting("proAdhocServer", SETTING(g_Config, sProAdhocServer), &DefaultProAdhocServer, CfgFlag::PER_GAME), @@ -1121,14 +1131,14 @@ static const ConfigSetting networkSettings[] = { ConfigSetting("ChatScreenPosition", SETTING(g_Config, iChatScreenPosition), (int)ScreenEdgePosition::BOTTOM_LEFT, CfgFlag::PER_GAME), ConfigSetting("ChatTimestamps", SETTING(g_Config, bChatTimestamps), true, CfgFlag::PER_GAME), ConfigSetting("EnableQuickChat", SETTING(g_Config, bEnableQuickChat), true, CfgFlag::PER_GAME), - ConfigSetting("QuickChat1", SETTING(g_Config, sQuickChat[0]), "Quick Chat 1", CfgFlag::PER_GAME), - ConfigSetting("QuickChat2", SETTING(g_Config, sQuickChat[1]), "Quick Chat 2", CfgFlag::PER_GAME), - ConfigSetting("QuickChat3", SETTING(g_Config, sQuickChat[2]), "Quick Chat 3", CfgFlag::PER_GAME), - ConfigSetting("QuickChat4", SETTING(g_Config, sQuickChat[3]), "Quick Chat 4", CfgFlag::PER_GAME), - ConfigSetting("QuickChat5", SETTING(g_Config, sQuickChat[4]), "Quick Chat 5", CfgFlag::PER_GAME), + ConfigSetting("QuickChat1", SETTING_IDX(g_Config, sQuickChat, 0), "Quick Chat 1", CfgFlag::PER_GAME), + ConfigSetting("QuickChat2", SETTING_IDX(g_Config, sQuickChat, 1), "Quick Chat 2", CfgFlag::PER_GAME), + ConfigSetting("QuickChat3", SETTING_IDX(g_Config, sQuickChat, 2), "Quick Chat 3", CfgFlag::PER_GAME), + ConfigSetting("QuickChat4", SETTING_IDX(g_Config, sQuickChat, 3), "Quick Chat 4", CfgFlag::PER_GAME), + ConfigSetting("QuickChat5", SETTING_IDX(g_Config, sQuickChat, 4), "Quick Chat 5", CfgFlag::PER_GAME), }; -static const ConfigSetting systemParamSettings[] = { +static constexpr ConfigSetting systemParamSettings[] = { ConfigSetting("PSPModel", SETTING(g_Config, iPSPModel), PSP_MODEL_SLIM, CfgFlag::PER_GAME | CfgFlag::REPORT), ConfigSetting("PSPFirmwareVersion", SETTING(g_Config, iFirmwareVersion), PSP_DEFAULT_FIRMWARE, CfgFlag::PER_GAME | CfgFlag::REPORT), ConfigSetting("NickName", SETTING(g_Config, sNickName), "PPSSPP", CfgFlag::PER_GAME), @@ -1149,7 +1159,7 @@ static const ConfigSetting systemParamSettings[] = { ConfigSetting("FuseID", SETTING(g_Config, sFuseID), "", CfgFlag::DEFAULT), }; -static const ConfigSetting debuggerSettings[] = { +static constexpr ConfigSetting debuggerSettings[] = { ConfigSetting("DisasmWindowX", SETTING(g_Config, iDisasmWindowX), -1, CfgFlag::DEFAULT), ConfigSetting("DisasmWindowY", SETTING(g_Config, iDisasmWindowY), -1, CfgFlag::DEFAULT), ConfigSetting("DisasmWindowW", SETTING(g_Config, iDisasmWindowW), -1, CfgFlag::DEFAULT), @@ -1174,21 +1184,21 @@ static const ConfigSetting debuggerSettings[] = { ConfigSetting("AutoSaveLoadSymbols", SETTING(g_Config, bAutoSaveLoadSymbols), false, CfgFlag::DEFAULT), }; -static const ConfigSetting jitSettings[] = { +static constexpr ConfigSetting jitSettings[] = { ConfigSetting("DiscardRegsOnJRRA", SETTING(g_Config, bDiscardRegsOnJRRA), false, CfgFlag::DONT_SAVE | CfgFlag::REPORT), }; -static const ConfigSetting upgradeSettings[] = { +static constexpr ConfigSetting upgradeSettings[] = { ConfigSetting("UpgradeMessage", SETTING(g_Config, sUpgradeMessage), "", CfgFlag::DEFAULT), ConfigSetting("UpgradeVersion", SETTING(g_Config, sUpgradeVersion), "", CfgFlag::DEFAULT), ConfigSetting("DismissedVersion", SETTING(g_Config, sDismissedVersion), "", CfgFlag::DEFAULT), }; -static const ConfigSetting themeSettings[] = { +static constexpr ConfigSetting themeSettings[] = { ConfigSetting("ThemeName", SETTING(g_Config, sThemeName), "Default", CfgFlag::DEFAULT), }; -static const ConfigSetting vrSettings[] = { +static constexpr ConfigSetting vrSettings[] = { ConfigSetting("VREnable", SETTING(g_Config, bEnableVR), true, CfgFlag::PER_GAME), ConfigSetting("VREnable6DoF", SETTING(g_Config, bEnable6DoF), false, CfgFlag::PER_GAME), ConfigSetting("VREnableStereo", SETTING(g_Config, bEnableStereo), false, CfgFlag::PER_GAME), diff --git a/Core/ConfigSettings.cpp b/Core/ConfigSettings.cpp index 9a866b1ea7..a4a4e1062e 100644 --- a/Core/ConfigSettings.cpp +++ b/Core/ConfigSettings.cpp @@ -139,7 +139,7 @@ bool ConfigSetting::ReadFromIniSection(ConfigBlock *configBlock, const Section * if (defaultCallback_.p) { *target = defaultCallback_.p(); } else { - *target = Path(default_.p); + *target = Path(default_.s); } } return false; @@ -351,8 +351,8 @@ bool ConfigSetting::RestoreToDefault(ConfigBlock *configBlock, bool log) const { if (defaultCallback_.p) { *ptr_path = defaultCallback_.p(); break; - } else if (default_.p) { - *ptr_path = Path(default_.p); + } else if (default_.s) { + *ptr_path = Path(default_.s); } else { ptr_path->clear(); } diff --git a/Core/ConfigSettings.h b/Core/ConfigSettings.h index 81d311f42d..5951608003 100644 --- a/Core/ConfigSettings.h +++ b/Core/ConfigSettings.h @@ -1,7 +1,10 @@ #pragma once #include +#include +#include #include +#include #include "Core/ConfigValues.h" @@ -19,6 +22,12 @@ ENUM_CLASS_BITOPS(CfgFlag); struct ConfigBlock; +// Where a setting is within its ConfigBlock, along with its type. Made by the SETTING macro in Config.cpp. +template +struct ConfigSettingOffset { + uint32_t offset; +}; + struct ConfigSetting { enum class Type { TYPE_TERMINATOR, @@ -34,13 +43,23 @@ struct ConfigSetting { TYPE_CUSTOM_BUTTON }; union DefaultValue { + constexpr DefaultValue() : i(0) {} + constexpr DefaultValue(bool v) : b(v) {} + constexpr DefaultValue(int v) : i(v) {} + constexpr DefaultValue(uint32_t v) : u(v) {} + constexpr DefaultValue(uint64_t v) : lu(v) {} + constexpr DefaultValue(float v) : f(v) {} + constexpr DefaultValue(const char *v) : s(v) {} // Strings and paths. + constexpr DefaultValue(const std::vector *v) : v(v) {} + constexpr DefaultValue(ConfigTouchPos v) : touchPos(v) {} + constexpr DefaultValue(ConfigCustomButton v) : customButton(v) {} + bool b; int i; uint32_t u; uint64_t lu; float f; const char *s; - const char *p; // not sure how much point.. const std::vector *v; ConfigTouchPos touchPos; ConfigCustomButton customButton; @@ -57,6 +76,17 @@ struct ConfigSetting { typedef ConfigCustomButton (*CustomButtonDefaultCallback)(); union DefaultCallback { + constexpr DefaultCallback() : b(nullptr) {} + constexpr DefaultCallback(BoolDefaultCallback cb) : b(cb) {} + constexpr DefaultCallback(IntDefaultCallback cb) : i(cb) {} + constexpr DefaultCallback(Uint32DefaultCallback cb) : u(cb) {} + constexpr DefaultCallback(Uint64DefaultCallback cb) : lu(cb) {} + constexpr DefaultCallback(FloatDefaultCallback cb) : f(cb) {} + constexpr DefaultCallback(StringDefaultCallback cb) : s(cb) {} + constexpr DefaultCallback(PathDefaultCallback cb) : p(cb) {} + constexpr DefaultCallback(TouchPosDefaultCallback cb) : touchPos(cb) {} + constexpr DefaultCallback(CustomButtonDefaultCallback cb) : customButton(cb) {} + BoolDefaultCallback b; IntDefaultCallback i; Uint32DefaultCallback u; @@ -68,125 +98,50 @@ struct ConfigSetting { CustomButtonDefaultCallback customButton; }; - // The configBlock you pass in here is just to be able to calculate the offset of the setting within the block so it can be - // applied to other blocks. - ConfigSetting(std::string_view ini, ConfigBlock *configBlock, bool *v, bool def, CfgFlag flags) noexcept - : iniKey_(ini), type_(Type::TYPE_BOOL), flags_(flags), offset_((const char *)v - (const char *)configBlock) { - defaultCallback_.b = nullptr; - default_.b = def; - } + // The offset says where the setting is within its ConfigBlock, so it can be applied to any block of that type. + constexpr ConfigSetting(std::string_view ini, ConfigSettingOffset v, bool def, CfgFlag flags) noexcept + : type_(Type::TYPE_BOOL), iniKey_(ini), flags_(flags), default_(def), offset_(v.offset) {} + constexpr ConfigSetting(std::string_view ini, ConfigSettingOffset v, CfgFlag flags) noexcept + : type_(Type::TYPE_BOOL), iniKey_(ini), flags_(flags), default_(false), offset_(v.offset) {} // The default is unused with this constructor. + constexpr ConfigSetting(std::string_view ini, ConfigSettingOffset v, int def, CfgFlag flags) noexcept + : type_(Type::TYPE_INT), iniKey_(ini), flags_(flags), default_(def), offset_(v.offset) {} + constexpr ConfigSetting(std::string_view ini, ConfigSettingOffset v, CfgFlag flags) noexcept + : type_(Type::TYPE_INT), iniKey_(ini), flags_(flags), default_(0), offset_(v.offset) {} // The default is unused with this constructor. + constexpr ConfigSetting(std::string_view ini, ConfigSettingOffset v, int def, std::string (*transTo)(int), int (*transFrom)(const std::string &), CfgFlag flags) noexcept + : type_(Type::TYPE_INT), iniKey_(ini), flags_(flags), default_(def), offset_(v.offset), translateTo_(transTo), translateFrom_(transFrom) {} + constexpr ConfigSetting(std::string_view ini, ConfigSettingOffset v, uint32_t def, CfgFlag flags) noexcept + : type_(Type::TYPE_UINT32), iniKey_(ini), flags_(flags), default_(def), offset_(v.offset) {} + constexpr ConfigSetting(std::string_view ini, ConfigSettingOffset v, uint64_t def, CfgFlag flags) noexcept + : type_(Type::TYPE_UINT64), iniKey_(ini), flags_(flags), default_(def), offset_(v.offset) {} + constexpr ConfigSetting(std::string_view ini, ConfigSettingOffset v, float def, CfgFlag flags) noexcept + : type_(Type::TYPE_FLOAT), iniKey_(ini), flags_(flags), default_(def), offset_(v.offset) {} + constexpr ConfigSetting(std::string_view ini, ConfigSettingOffset v, CfgFlag flags) noexcept + : type_(Type::TYPE_FLOAT), iniKey_(ini), flags_(flags), default_(0.0f), offset_(v.offset) {} + constexpr ConfigSetting(std::string_view ini, ConfigSettingOffset v, const char *def, CfgFlag flags) noexcept + : type_(Type::TYPE_STRING), iniKey_(ini), flags_(flags), default_(def), offset_(v.offset) {} + constexpr ConfigSetting(std::string_view ini, ConfigSettingOffset> v, const std::vector *def, CfgFlag flags) noexcept + : type_(Type::TYPE_STRING_VECTOR), iniKey_(ini), flags_(flags), default_(def), offset_(v.offset) {} + constexpr ConfigSetting(std::string_view ini, ConfigSettingOffset v, const char *def, CfgFlag flags) noexcept + : type_(Type::TYPE_PATH), iniKey_(ini), flags_(flags), default_(def), offset_(v.offset) {} + constexpr ConfigSetting(const char *iniX, const char *iniY, const char *iniScale, const char *iniShow, ConfigSettingOffset v, ConfigTouchPos def, CfgFlag flags) noexcept + : ini2_(iniY), ini3_(iniScale), ini4_(iniShow), type_(Type::TYPE_TOUCH_POS), iniKey_(iniX), flags_(flags), default_(def), offset_(v.offset) {} + constexpr ConfigSetting(const char *iniKey, const char *iniImage, const char *iniShape, const char *iniToggle, const char *iniRepeat, ConfigSettingOffset v, ConfigCustomButton def, CfgFlag flags) noexcept + : ini2_(iniImage), ini3_(iniShape), ini4_(iniToggle), ini5_(iniRepeat), type_(Type::TYPE_CUSTOM_BUTTON), iniKey_(iniKey), flags_(flags), default_(def), offset_(v.offset) {} - ConfigSetting(std::string_view ini, ConfigBlock *configBlock, bool *v, CfgFlag flags) noexcept - : iniKey_(ini), type_(Type::TYPE_BOOL), flags_(flags), offset_((const char *)v - (const char *)configBlock) { - defaultCallback_.b = nullptr; - default_.b = false; // unused with this constructor - } - - ConfigSetting(std::string_view ini, ConfigBlock *configBlock, int *v, int def, CfgFlag flags) noexcept - : iniKey_(ini), type_(Type::TYPE_INT), flags_(flags), offset_((const char *)v - (const char *)configBlock) { - defaultCallback_.i = nullptr; - default_.i = def; - } - - ConfigSetting(std::string_view ini, ConfigBlock *configBlock, int *v, CfgFlag flags) noexcept - : iniKey_(ini), type_(Type::TYPE_INT), flags_(flags), offset_((const char *)v - (const char *)configBlock) { - defaultCallback_.i = nullptr; - default_.i = 0; // unused with this constructor - } - - ConfigSetting(std::string_view ini, ConfigBlock *configBlock, int *v, int def, std::string (*transTo)(int), int (*transFrom)(const std::string &), CfgFlag flags) noexcept - : iniKey_(ini), type_(Type::TYPE_INT), flags_(flags), translateTo_(transTo), translateFrom_(transFrom), offset_((const char *)v - (const char *)configBlock) { - defaultCallback_.i = nullptr; - default_.i = def; - } - - ConfigSetting(std::string_view ini, ConfigBlock *configBlock, uint32_t *v, uint32_t def, CfgFlag flags) noexcept - : iniKey_(ini), type_(Type::TYPE_UINT32), flags_(flags), offset_((const char *)v - (const char *)configBlock) { - defaultCallback_.u = nullptr; - default_.u = def; - } - - ConfigSetting(std::string_view ini, ConfigBlock *configBlock, uint64_t *v, uint64_t def, CfgFlag flags) noexcept - : iniKey_(ini), type_(Type::TYPE_UINT64), flags_(flags), offset_((const char *)v - (const char *)configBlock) { - defaultCallback_.lu = nullptr; - default_.lu = def; - } - - ConfigSetting(std::string_view ini, ConfigBlock *configBlock, float *v, float def, CfgFlag flags) noexcept - : iniKey_(ini), type_(Type::TYPE_FLOAT), flags_(flags), offset_((const char *)v - (const char *)configBlock) { - defaultCallback_.f = nullptr; - default_.f = def; - } - - ConfigSetting(std::string_view ini, ConfigBlock *configBlock, float *v, CfgFlag flags) noexcept - : iniKey_(ini), type_(Type::TYPE_FLOAT), flags_(flags), offset_((const char *)v - (const char *)configBlock) { - defaultCallback_.f = nullptr; - default_.f = 0.0f; - } - - ConfigSetting(std::string_view ini, ConfigBlock *configBlock, std::string *v, const char *def, CfgFlag flags) noexcept - : iniKey_(ini), type_(Type::TYPE_STRING), flags_(flags), offset_((const char *)v - (const char *)configBlock) { - defaultCallback_.s = nullptr; - default_.s = def; - } - - ConfigSetting(std::string_view ini, ConfigBlock *configBlock, std::vector *v, const std::vector *def, CfgFlag flags) noexcept - : iniKey_(ini), type_(Type::TYPE_STRING_VECTOR), flags_(flags), offset_((const char *)v - (const char *)configBlock) { - default_.v = def; - } - - ConfigSetting(std::string_view ini, ConfigBlock *configBlock, Path *v, const char *def, CfgFlag flags) noexcept - : iniKey_(ini), type_(Type::TYPE_PATH), flags_(flags), offset_((const char *)v - (const char *)configBlock) { - defaultCallback_.p = nullptr; - default_.p = def; - } - - ConfigSetting(const char *iniX, const char *iniY, const char *iniScale, const char *iniShow, ConfigBlock *configBlock, ConfigTouchPos *v, ConfigTouchPos def, CfgFlag flags) noexcept - : iniKey_(iniX), ini2_(iniY), ini3_(iniScale), ini4_(iniShow), type_(Type::TYPE_TOUCH_POS), flags_(flags), offset_((const char *)v - (const char *)configBlock) { - defaultCallback_.touchPos = nullptr; - default_.touchPos = def; - } - - ConfigSetting(const char *iniKey, const char *iniImage, const char *iniShape, const char *iniToggle, const char *iniRepeat, ConfigBlock *configBlock, ConfigCustomButton *v, ConfigCustomButton def, CfgFlag flags) noexcept - : iniKey_(iniKey), ini2_(iniImage), ini3_(iniShape), ini4_(iniToggle), ini5_(iniRepeat), type_(Type::TYPE_CUSTOM_BUTTON), flags_(flags), offset_((const char *)v - (const char *)configBlock) { - defaultCallback_.customButton = nullptr; - default_.customButton = def; - } - - ConfigSetting(std::string_view ini, ConfigBlock *configBlock, bool *v, BoolDefaultCallback def, CfgFlag flags) noexcept - : iniKey_(ini), type_(Type::TYPE_BOOL), flags_(flags), offset_((const char *)v - (const char *)configBlock) { - defaultCallback_.b = def; - } - - ConfigSetting(std::string_view ini, ConfigBlock *configBlock, int *v, IntDefaultCallback def, CfgFlag flags) noexcept - : iniKey_(ini), type_(Type::TYPE_INT), flags_(flags), offset_((const char *)v - (const char *)configBlock) { - defaultCallback_.i = def; - } - - ConfigSetting(std::string_view ini, ConfigBlock *configBlock, int *v, IntDefaultCallback def, std::string(*transTo)(int), int(*transFrom)(const std::string &), CfgFlag flags) noexcept - : iniKey_(ini), type_(Type::TYPE_INT), flags_(flags), offset_((const char *)v - (const char *)configBlock), translateTo_(transTo), translateFrom_(transFrom) { - defaultCallback_.i = def; - } - - ConfigSetting(std::string_view ini, ConfigBlock *configBlock, uint32_t *v, Uint32DefaultCallback def, CfgFlag flags) noexcept - : iniKey_(ini), type_(Type::TYPE_UINT32), flags_(flags), offset_((const char *)v - (const char *)configBlock) { - defaultCallback_.u = def; - } - - ConfigSetting(std::string_view ini, ConfigBlock *configBlock, float *v, FloatDefaultCallback def, CfgFlag flags) noexcept - : iniKey_(ini), type_(Type::TYPE_FLOAT), flags_(flags), offset_((const char *)v - (const char *)configBlock) { - defaultCallback_.f = def; - } - - ConfigSetting(std::string_view ini, ConfigBlock *configBlock, std::string *v, StringDefaultCallback def, CfgFlag flags) noexcept - : iniKey_(ini), type_(Type::TYPE_STRING), flags_(flags), offset_((const char *)v - (const char *)configBlock) { - defaultCallback_.s = def; - } - - ConfigSetting(std::string_view iniX, const char *iniY, const char *iniScale, const char *iniShow, ConfigBlock *configBlock, ConfigTouchPos *v, TouchPosDefaultCallback def, CfgFlag flags) noexcept - : iniKey_(iniX), ini2_(iniY), ini3_(iniScale), ini4_(iniShow), type_(Type::TYPE_TOUCH_POS), flags_(flags), offset_((const char *)v - (const char *)configBlock) { - defaultCallback_.touchPos = def; - } + constexpr ConfigSetting(std::string_view ini, ConfigSettingOffset v, BoolDefaultCallback def, CfgFlag flags) noexcept + : type_(Type::TYPE_BOOL), iniKey_(ini), flags_(flags), defaultCallback_(def), offset_(v.offset) {} + constexpr ConfigSetting(std::string_view ini, ConfigSettingOffset v, IntDefaultCallback def, CfgFlag flags) noexcept + : type_(Type::TYPE_INT), iniKey_(ini), flags_(flags), defaultCallback_(def), offset_(v.offset) {} + constexpr ConfigSetting(std::string_view ini, ConfigSettingOffset v, IntDefaultCallback def, std::string(*transTo)(int), int(*transFrom)(const std::string &), CfgFlag flags) noexcept + : type_(Type::TYPE_INT), iniKey_(ini), flags_(flags), defaultCallback_(def), offset_(v.offset), translateTo_(transTo), translateFrom_(transFrom) {} + constexpr ConfigSetting(std::string_view ini, ConfigSettingOffset v, Uint32DefaultCallback def, CfgFlag flags) noexcept + : type_(Type::TYPE_UINT32), iniKey_(ini), flags_(flags), defaultCallback_(def), offset_(v.offset) {} + constexpr ConfigSetting(std::string_view ini, ConfigSettingOffset v, FloatDefaultCallback def, CfgFlag flags) noexcept + : type_(Type::TYPE_FLOAT), iniKey_(ini), flags_(flags), defaultCallback_(def), offset_(v.offset) {} + constexpr ConfigSetting(std::string_view ini, ConfigSettingOffset v, StringDefaultCallback def, CfgFlag flags) noexcept + : type_(Type::TYPE_STRING), iniKey_(ini), flags_(flags), defaultCallback_(def), offset_(v.offset) {} + constexpr ConfigSetting(std::string_view iniX, const char *iniY, const char *iniScale, const char *iniShow, ConfigSettingOffset v, TouchPosDefaultCallback def, CfgFlag flags) noexcept + : ini2_(iniY), ini3_(iniScale), ini4_(iniShow), type_(Type::TYPE_TOUCH_POS), iniKey_(iniX), flags_(flags), defaultCallback_(def), offset_(v.offset) {} bool ReadFromIniSection(ConfigBlock *configBlock, const Section *section, bool applyDefaultIfMissing) const;