Merge branch 'settings_storage' into 'master'

Typed settings storage (#6876)

See merge request OpenMW/openmw!2651
pull/3232/head
psi29a 2 years ago
commit ad25e9b154

@ -4,3 +4,4 @@ endif()
add_subdirectory(detournavigator)
add_subdirectory(esm)
add_subdirectory(settings)

@ -0,0 +1,15 @@
openmw_add_executable(openmw_settings_access_benchmark access.cpp)
target_link_libraries(openmw_settings_access_benchmark benchmark::benchmark components)
if (UNIX AND NOT APPLE)
target_link_libraries(openmw_settings_access_benchmark ${CMAKE_THREAD_LIBS_INIT})
endif()
if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.16 AND MSVC)
target_precompile_headers(openmw_settings_access_benchmark PRIVATE <algorithm>)
endif()
if (BUILD_WITH_CODE_COVERAGE)
target_compile_options(openmw_settings_access_benchmark PRIVATE --coverage)
target_link_libraries(openmw_settings_access_benchmark gcov)
endif()

@ -0,0 +1,86 @@
#include <benchmark/benchmark.h>
#include <components/files/configurationmanager.hpp>
#include <components/settings/settings.hpp>
#include <components/settings/values.hpp>
#include <boost/program_options.hpp>
#include <algorithm>
#include <iostream>
namespace
{
namespace bpo = boost::program_options;
bpo::options_description makeOptionsDescription()
{
bpo::options_description result;
auto addOption = result.add_options();
addOption("help", "print help message");
Files::ConfigurationManager::addCommonOptions(result);
return result;
}
void settingsManager(benchmark::State& state)
{
for (auto _ : state)
{
benchmark::DoNotOptimize(Settings::Manager::getFloat("sky blending start", "Fog"));
}
}
void localStatic(benchmark::State& state)
{
for (auto _ : state)
{
static const float v = Settings::Manager::getFloat("sky blending start", "Fog");
benchmark::DoNotOptimize(v);
}
}
void settingsStorage(benchmark::State& state)
{
for (auto _ : state)
{
benchmark::DoNotOptimize(Settings::fog().mSkyBlendingStart.get());
}
}
}
BENCHMARK(settingsManager);
BENCHMARK(localStatic);
BENCHMARK(settingsStorage);
int main(int argc, char* argv[])
{
bpo::options_description desc = makeOptionsDescription();
bpo::parsed_options options = bpo::command_line_parser(argc, argv).options(desc).allow_unregistered().run();
bpo::variables_map variables;
bpo::store(options, variables);
bpo::notify(variables);
if (variables.find("help") != variables.end())
{
std::cout << desc << std::endl;
benchmark::Initialize(&argc, argv);
benchmark::Shutdown();
return 1;
}
Files::ConfigurationManager config;
bpo::variables_map composingVariables = Files::separateComposingVariables(variables, desc);
config.readConfiguration(variables, desc);
Files::mergeComposingVariables(variables, composingVariables, desc);
Settings::Manager::load(config);
benchmark::Initialize(&argc, argv);
benchmark::RunSpecifiedBenchmarks();
benchmark::Shutdown();
return 0;
}

@ -42,7 +42,39 @@ add_component_dir (l10n
)
add_component_dir (settings
settings parser
categories
categories/camera
categories/cells
categories/fog
categories/game
categories/general
categories/groundcover
categories/gui
categories/hud
categories/input
categories/lua
categories/map
categories/models
categories/navigator
categories/physics
categories/postprocessing
categories/saves
categories/shaders
categories/shadows
categories/sound
categories/stereo
categories/stereoview
categories/terrain
categories/video
categories/water
categories/windows
parser
sanitizer
sanitizerimpl
settings
settingvalue
shadermanager
values
)
add_component_dir (bsa

@ -1,36 +1,29 @@
#include "settings.hpp"
#include <components/misc/constants.hpp>
#include <components/settings/settings.hpp>
#include <algorithm>
#include <components/settings/values.hpp>
namespace DetourNavigator
{
RecastSettings makeRecastSettingsFromSettingsManager()
{
constexpr float epsilon = std::numeric_limits<float>::epsilon();
RecastSettings result;
result.mBorderSize = std::max(0, ::Settings::Manager::getInt("border size", "Navigator"));
result.mCellHeight = std::max(epsilon, ::Settings::Manager::getFloat("cell height", "Navigator"));
result.mCellSize = std::max(epsilon, ::Settings::Manager::getFloat("cell size", "Navigator"));
result.mDetailSampleDist = std::max(0.0f, ::Settings::Manager::getFloat("detail sample dist", "Navigator"));
result.mDetailSampleMaxError
= std::max(0.0f, ::Settings::Manager::getFloat("detail sample max error", "Navigator"));
result.mBorderSize = ::Settings::navigator().mBorderSize;
result.mCellHeight = ::Settings::navigator().mCellHeight;
result.mCellSize = ::Settings::navigator().mCellSize;
result.mDetailSampleDist = ::Settings::navigator().mDetailSampleDist;
result.mDetailSampleMaxError = ::Settings::navigator().mDetailSampleMaxError;
result.mMaxClimb = Constants::sStepSizeUp;
result.mMaxSimplificationError
= std::max(0.0f, ::Settings::Manager::getFloat("max simplification error", "Navigator"));
result.mMaxSimplificationError = ::Settings::navigator().mMaxSimplificationError;
result.mMaxSlope = Constants::sMaxSlope;
result.mRecastScaleFactor
= std::max(epsilon, ::Settings::Manager::getFloat("recast scale factor", "Navigator"));
result.mRecastScaleFactor = ::Settings::navigator().mRecastScaleFactor;
result.mSwimHeightScale = 0;
result.mMaxEdgeLen = std::max(0, ::Settings::Manager::getInt("max edge len", "Navigator"));
result.mMaxVertsPerPoly = std::max(3, ::Settings::Manager::getInt("max verts per poly", "Navigator"));
result.mRegionMergeArea = std::max(0, ::Settings::Manager::getInt("region merge area", "Navigator"));
result.mRegionMinArea = std::max(0, ::Settings::Manager::getInt("region min area", "Navigator"));
result.mTileSize = std::max(1, ::Settings::Manager::getInt("tile size", "Navigator"));
result.mMaxEdgeLen = ::Settings::navigator().mMaxEdgeLen;
result.mMaxVertsPerPoly = ::Settings::navigator().mMaxVertsPerPoly;
result.mRegionMergeArea = ::Settings::navigator().mRegionMergeArea;
result.mRegionMinArea = ::Settings::navigator().mRegionMinArea;
result.mTileSize = ::Settings::navigator().mTileSize;
return result;
}
@ -39,12 +32,10 @@ namespace DetourNavigator
{
DetourSettings result;
result.mMaxNavMeshQueryNodes
= std::clamp(::Settings::Manager::getInt("max nav mesh query nodes", "Navigator"), 1, 65535);
result.mMaxPolys
= std::clamp(::Settings::Manager::getInt("max polygons per tile", "Navigator"), 1, (1 << 22) - 1);
result.mMaxPolygonPathSize = ::Settings::Manager::getSize("max polygon path size", "Navigator");
result.mMaxSmoothPathSize = ::Settings::Manager::getSize("max smooth path size", "Navigator");
result.mMaxNavMeshQueryNodes = ::Settings::navigator().mMaxNavMeshQueryNodes;
result.mMaxPolys = ::Settings::navigator().mMaxPolygonsPerTile;
result.mMaxPolygonPathSize = ::Settings::navigator().mMaxPolygonPathSize;
result.mMaxSmoothPathSize = ::Settings::navigator().mMaxSmoothPathSize;
return result;
}
@ -55,26 +46,20 @@ namespace DetourNavigator
result.mRecast = makeRecastSettingsFromSettingsManager();
result.mDetour = makeDetourSettingsFromSettingsManager();
result.mMaxTilesNumber = std::max(0, ::Settings::Manager::getInt("max tiles number", "Navigator"));
result.mWaitUntilMinDistanceToPlayer
= ::Settings::Manager::getInt("wait until min distance to player", "Navigator");
result.mAsyncNavMeshUpdaterThreads
= ::Settings::Manager::getSize("async nav mesh updater threads", "Navigator");
result.mMaxNavMeshTilesCacheSize = ::Settings::Manager::getSize("max nav mesh tiles cache size", "Navigator");
result.mEnableWriteRecastMeshToFile
= ::Settings::Manager::getBool("enable write recast mesh to file", "Navigator");
result.mEnableWriteNavMeshToFile = ::Settings::Manager::getBool("enable write nav mesh to file", "Navigator");
result.mRecastMeshPathPrefix = ::Settings::Manager::getString("recast mesh path prefix", "Navigator");
result.mNavMeshPathPrefix = ::Settings::Manager::getString("nav mesh path prefix", "Navigator");
result.mEnableRecastMeshFileNameRevision
= ::Settings::Manager::getBool("enable recast mesh file name revision", "Navigator");
result.mEnableNavMeshFileNameRevision
= ::Settings::Manager::getBool("enable nav mesh file name revision", "Navigator");
result.mMinUpdateInterval
= std::chrono::milliseconds(::Settings::Manager::getInt("min update interval ms", "Navigator"));
result.mEnableNavMeshDiskCache = ::Settings::Manager::getBool("enable nav mesh disk cache", "Navigator");
result.mWriteToNavMeshDb = ::Settings::Manager::getBool("write to navmeshdb", "Navigator");
result.mMaxDbFileSize = ::Settings::Manager::getUInt64("max navmeshdb file size", "Navigator");
result.mMaxTilesNumber = ::Settings::navigator().mMaxTilesNumber;
result.mWaitUntilMinDistanceToPlayer = ::Settings::navigator().mWaitUntilMinDistanceToPlayer;
result.mAsyncNavMeshUpdaterThreads = ::Settings::navigator().mAsyncNavMeshUpdaterThreads;
result.mMaxNavMeshTilesCacheSize = ::Settings::navigator().mMaxNavMeshTilesCacheSize;
result.mEnableWriteRecastMeshToFile = ::Settings::navigator().mEnableWriteRecastMeshToFile;
result.mEnableWriteNavMeshToFile = ::Settings::navigator().mEnableWriteNavMeshToFile;
result.mRecastMeshPathPrefix = ::Settings::navigator().mRecastMeshPathPrefix;
result.mNavMeshPathPrefix = ::Settings::navigator().mNavMeshPathPrefix;
result.mEnableRecastMeshFileNameRevision = ::Settings::navigator().mEnableRecastMeshFileNameRevision;
result.mEnableNavMeshFileNameRevision = ::Settings::navigator().mEnableNavMeshFileNameRevision;
result.mMinUpdateInterval = std::chrono::milliseconds(::Settings::navigator().mMinUpdateIntervalMs);
result.mEnableNavMeshDiskCache = ::Settings::navigator().mEnableNavMeshDiskCache;
result.mWriteToNavMeshDb = ::Settings::navigator().mWriteToNavmeshdb;
result.mMaxDbFileSize = ::Settings::navigator().mMaxNavmeshdbFileSize;
return result;
}

@ -0,0 +1,31 @@
#ifndef OPENMW_COMPONENTS_SETTINGS_CATEGORIES_CAMERA_H
#define OPENMW_COMPONENTS_SETTINGS_CATEGORIES_CAMERA_H
#include "components/settings/sanitizerimpl.hpp"
#include "components/settings/settingvalue.hpp"
#include <osg/Math>
#include <osg/Vec2f>
#include <osg/Vec3f>
#include <cstdint>
#include <string>
#include <string_view>
namespace Settings
{
struct CameraCategory
{
SettingValue<float> mNearClip{ "Camera", "near clip", makeMaxSanitizerFloat(0.005f) };
SettingValue<bool> mSmallFeatureCulling{ "Camera", "small feature culling" };
SettingValue<float> mSmallFeatureCullingPixelSize{ "Camera", "small feature culling pixel size",
makeMaxStrictSanitizerFloat(0) };
SettingValue<float> mViewingDistance{ "Camera", "viewing distance", makeMaxStrictSanitizerFloat(0) };
SettingValue<float> mFieldOfView{ "Camera", "field of view", makeClampSanitizerFloat(1, 179) };
SettingValue<float> mFirstPersonFieldOfView{ "Camera", "first person field of view",
makeClampSanitizerFloat(1, 179) };
SettingValue<bool> mReverseZ{ "Camera", "reverse z" };
};
}
#endif

@ -0,0 +1,36 @@
#ifndef OPENMW_COMPONENTS_SETTINGS_CATEGORIES_CELLS_H
#define OPENMW_COMPONENTS_SETTINGS_CATEGORIES_CELLS_H
#include "components/settings/sanitizerimpl.hpp"
#include "components/settings/settingvalue.hpp"
#include <osg/Math>
#include <osg/Vec2f>
#include <osg/Vec3f>
#include <cstdint>
#include <string>
#include <string_view>
namespace Settings
{
struct CellsCategory
{
SettingValue<bool> mPreloadEnabled{ "Cells", "preload enabled" };
SettingValue<int> mPreloadNumThreads{ "Cells", "preload num threads", makeMaxSanitizerInt(1) };
SettingValue<bool> mPreloadExteriorGrid{ "Cells", "preload exterior grid" };
SettingValue<bool> mPreloadFastTravel{ "Cells", "preload fast travel" };
SettingValue<bool> mPreloadDoors{ "Cells", "preload doors" };
SettingValue<float> mPreloadDistance{ "Cells", "preload distance", makeMaxStrictSanitizerFloat(0) };
SettingValue<bool> mPreloadInstances{ "Cells", "preload instances" };
SettingValue<int> mPreloadCellCacheMin{ "Cells", "preload cell cache min", makeMaxSanitizerInt(1) };
SettingValue<int> mPreloadCellCacheMax{ "Cells", "preload cell cache max", makeMaxSanitizerInt(1) };
SettingValue<float> mPreloadCellExpiryDelay{ "Cells", "preload cell expiry delay", makeMaxSanitizerFloat(0) };
SettingValue<float> mPredictionTime{ "Cells", "prediction time", makeMaxSanitizerFloat(0) };
SettingValue<float> mCacheExpiryDelay{ "Cells", "cache expiry delay", makeMaxSanitizerFloat(0) };
SettingValue<float> mTargetFramerate{ "Cells", "target framerate", makeMaxStrictSanitizerFloat(0) };
SettingValue<int> mPointersCacheSize{ "Cells", "pointers cache size", makeClampSanitizerInt(40, 1000) };
};
}
#endif

@ -0,0 +1,34 @@
#ifndef OPENMW_COMPONENTS_SETTINGS_CATEGORIES_FOG_H
#define OPENMW_COMPONENTS_SETTINGS_CATEGORIES_FOG_H
#include "components/settings/sanitizerimpl.hpp"
#include "components/settings/settingvalue.hpp"
#include <osg/Math>
#include <osg/Vec2f>
#include <osg/Vec3f>
#include <cstdint>
#include <string>
#include <string_view>
namespace Settings
{
struct FogCategory
{
SettingValue<bool> mUseDistantFog{ "Fog", "use distant fog" };
SettingValue<float> mDistantLandFogStart{ "Fog", "distant land fog start" };
SettingValue<float> mDistantLandFogEnd{ "Fog", "distant land fog end" };
SettingValue<float> mDistantUnderwaterFogStart{ "Fog", "distant underwater fog start" };
SettingValue<float> mDistantUnderwaterFogEnd{ "Fog", "distant underwater fog end" };
SettingValue<float> mDistantInteriorFogStart{ "Fog", "distant interior fog start" };
SettingValue<float> mDistantInteriorFogEnd{ "Fog", "distant interior fog end" };
SettingValue<bool> mRadialFog{ "Fog", "radial fog" };
SettingValue<bool> mExponentialFog{ "Fog", "exponential fog" };
SettingValue<bool> mSkyBlending{ "Fog", "sky blending" };
SettingValue<float> mSkyBlendingStart{ "Fog", "sky blending start", makeClampStrictMaxSanitizerFloat(0, 1) };
SettingValue<osg::Vec2f> mSkyRttResolution{ "Fog", "sky rtt resolution" };
};
}
#endif

@ -0,0 +1,71 @@
#ifndef OPENMW_COMPONENTS_SETTINGS_CATEGORIES_GAME_H
#define OPENMW_COMPONENTS_SETTINGS_CATEGORIES_GAME_H
#include "components/settings/sanitizerimpl.hpp"
#include "components/settings/settingvalue.hpp"
#include <osg/Math>
#include <osg/Vec2f>
#include <osg/Vec3f>
#include <cstdint>
#include <string>
#include <string_view>
namespace Settings
{
struct GameCategory
{
SettingValue<int> mShowOwned{ "Game", "show owned", makeEnumSanitizerInt({ 0, 1, 2, 3 }) };
SettingValue<bool> mShowProjectileDamage{ "Game", "show projectile damage" };
SettingValue<bool> mShowMeleeInfo{ "Game", "show melee info" };
SettingValue<bool> mShowEnchantChance{ "Game", "show enchant chance" };
SettingValue<bool> mBestAttack{ "Game", "best attack" };
SettingValue<int> mDifficulty{ "Game", "difficulty", makeClampSanitizerInt(-500, 500) };
SettingValue<int> mActorsProcessingRange{ "Game", "actors processing range",
makeClampSanitizerInt(3584, 7168) };
SettingValue<bool> mClassicReflectedAbsorbSpellsBehavior{ "Game", "classic reflected absorb spells behavior" };
SettingValue<bool> mClassicCalmSpellsBehavior{ "Game", "classic calm spells behavior" };
SettingValue<bool> mShowEffectDuration{ "Game", "show effect duration" };
SettingValue<bool> mPreventMerchantEquipping{ "Game", "prevent merchant equipping" };
SettingValue<bool> mEnchantedWeaponsAreMagical{ "Game", "enchanted weapons are magical" };
SettingValue<bool> mFollowersAttackOnSight{ "Game", "followers attack on sight" };
SettingValue<bool> mCanLootDuringDeathAnimation{ "Game", "can loot during death animation" };
SettingValue<bool> mRebalanceSoulGemValues{ "Game", "rebalance soul gem values" };
SettingValue<bool> mUseAdditionalAnimSources{ "Game", "use additional anim sources" };
SettingValue<bool> mBarterDispositionChangeIsPermanent{ "Game", "barter disposition change is permanent" };
SettingValue<int> mStrengthInfluencesHandToHand{ "Game", "strength influences hand to hand",
makeEnumSanitizerInt({ 0, 1, 2 }) };
SettingValue<bool> mWeaponSheathing{ "Game", "weapon sheathing" };
SettingValue<bool> mShieldSheathing{ "Game", "shield sheathing" };
SettingValue<bool> mOnlyAppropriateAmmunitionBypassesResistance{ "Game",
"only appropriate ammunition bypasses resistance" };
SettingValue<bool> mUseMagicItemAnimations{ "Game", "use magic item animations" };
SettingValue<bool> mNormaliseRaceSpeed{ "Game", "normalise race speed" };
SettingValue<float> mProjectilesEnchantMultiplier{ "Game", "projectiles enchant multiplier",
makeClampSanitizerFloat(0, 1) };
SettingValue<bool> mUncappedDamageFatigue{ "Game", "uncapped damage fatigue" };
SettingValue<bool> mTurnToMovementDirection{ "Game", "turn to movement direction" };
SettingValue<bool> mSmoothMovement{ "Game", "smooth movement" };
SettingValue<float> mSmoothMovementPlayerTurningDelay{ "Game", "smooth movement player turning delay",
makeMaxSanitizerFloat(0.01f) };
SettingValue<bool> mNPCsAvoidCollisions{ "Game", "NPCs avoid collisions" };
SettingValue<bool> mNPCsGiveWay{ "Game", "NPCs give way" };
SettingValue<bool> mSwimUpwardCorrection{ "Game", "swim upward correction" };
SettingValue<float> mSwimUpwardCoef{ "Game", "swim upward coef", makeClampSanitizerFloat(-1, 1) };
SettingValue<bool> mTrainersTrainingSkillsBasedOnBaseSkill{ "Game",
"trainers training skills based on base skill" };
SettingValue<bool> mAlwaysAllowStealingFromKnockedOutActors{ "Game",
"always allow stealing from knocked out actors" };
SettingValue<bool> mGraphicHerbalism{ "Game", "graphic herbalism" };
SettingValue<bool> mAllowActorsToFollowOverWaterSurface{ "Game", "allow actors to follow over water surface" };
SettingValue<osg::Vec3f> mDefaultActorPathfindHalfExtents{ "Game", "default actor pathfind half extents",
makeMaxStrictSanitizerVec3f(osg::Vec3f(0, 0, 0)) };
SettingValue<bool> mDayNightSwitches{ "Game", "day night switches" };
SettingValue<bool> mUnarmedCreatureAttacksDamageArmor{ "Game", "unarmed creature attacks damage armor" };
SettingValue<int> mActorCollisionShapeType{ "Game", "actor collision shape type",
makeEnumSanitizerInt({ 0, 1, 2 }) };
};
}
#endif

@ -0,0 +1,35 @@
#ifndef OPENMW_COMPONENTS_SETTINGS_CATEGORIES_GENERAL_H
#define OPENMW_COMPONENTS_SETTINGS_CATEGORIES_GENERAL_H
#include "components/settings/sanitizerimpl.hpp"
#include "components/settings/settingvalue.hpp"
#include <osg/Math>
#include <osg/Vec2f>
#include <osg/Vec3f>
#include <cstdint>
#include <string>
#include <string_view>
namespace Settings
{
struct GeneralCategory
{
SettingValue<int> mAnisotropy{ "General", "anisotropy", makeClampSanitizerInt(0, 16) };
SettingValue<std::string> mScreenshotFormat{ "General", "screenshot format",
makeEnumSanitizerString({ "jpg", "png", "tga" }) };
SettingValue<std::string> mTextureMagFilter{ "General", "texture mag filter",
makeEnumSanitizerString({ "nearest", "linear" }) };
SettingValue<std::string> mTextureMinFilter{ "General", "texture min filter",
makeEnumSanitizerString({ "nearest", "linear" }) };
SettingValue<std::string> mTextureMipmap{ "General", "texture mipmap",
makeEnumSanitizerString({ "none", "nearest", "linear" }) };
SettingValue<bool> mNotifyOnSavedScreenshot{ "General", "notify on saved screenshot" };
SettingValue<std::string> mPreferredLocales{ "General", "preferred locales" };
SettingValue<std::size_t> mLogBufferSize{ "General", "log buffer size" };
SettingValue<std::size_t> mConsoleHistoryBufferSize{ "General", "console history buffer size" };
};
}
#endif

@ -0,0 +1,27 @@
#ifndef OPENMW_COMPONENTS_SETTINGS_CATEGORIES_GROUNDCOVER_H
#define OPENMW_COMPONENTS_SETTINGS_CATEGORIES_GROUNDCOVER_H
#include "components/settings/sanitizerimpl.hpp"
#include "components/settings/settingvalue.hpp"
#include <osg/Math>
#include <osg/Vec2f>
#include <osg/Vec3f>
#include <cstdint>
#include <string>
#include <string_view>
namespace Settings
{
struct GroundcoverCategory
{
SettingValue<bool> mEnabled{ "Groundcover", "enabled" };
SettingValue<float> mDensity{ "Groundcover", "density", makeClampSanitizerFloat(0, 1) };
SettingValue<float> mRenderingDistance{ "Groundcover", "rendering distance", makeMaxSanitizerFloat(0) };
SettingValue<int> mStompMode{ "Groundcover", "stomp mode", makeEnumSanitizerInt({ 0, 1, 2 }) };
SettingValue<int> mStompIntensity{ "Groundcover", "stomp intensity", makeEnumSanitizerInt({ 0, 1, 2 }) };
};
}
#endif

@ -0,0 +1,36 @@
#ifndef OPENMW_COMPONENTS_SETTINGS_CATEGORIES_GUI_H
#define OPENMW_COMPONENTS_SETTINGS_CATEGORIES_GUI_H
#include "components/settings/sanitizerimpl.hpp"
#include "components/settings/settingvalue.hpp"
#include <osg/Math>
#include <osg/Vec2f>
#include <osg/Vec3f>
#include <cstdint>
#include <string>
#include <string_view>
namespace Settings
{
struct GUICategory
{
SettingValue<float> mScalingFactor{ "GUI", "scaling factor", makeClampSanitizerFloat(0.5f, 8) };
SettingValue<int> mFontSize{ "GUI", "font size", makeClampSanitizerInt(12, 18) };
SettingValue<float> mMenuTransparency{ "GUI", "menu transparency", makeClampSanitizerFloat(0, 1) };
SettingValue<float> mTooltipDelay{ "GUI", "tooltip delay", makeMaxSanitizerFloat(0) };
SettingValue<bool> mStretchMenuBackground{ "GUI", "stretch menu background" };
SettingValue<bool> mSubtitles{ "GUI", "subtitles" };
SettingValue<bool> mHitFader{ "GUI", "hit fader" };
SettingValue<bool> mWerewolfOverlay{ "GUI", "werewolf overlay" };
SettingValue<float> mColorBackgroundOwned{ "GUI", "color background owned", makeClampSanitizerFloat(0, 1) };
SettingValue<float> mColorCrosshairOwned{ "GUI", "color crosshair owned", makeClampSanitizerFloat(0, 1) };
SettingValue<bool> mKeyboardNavigation{ "GUI", "keyboard navigation" };
SettingValue<bool> mColorTopicEnable{ "GUI", "color topic enable" };
SettingValue<float> mColorTopicSpecific{ "GUI", "color topic specific", makeClampSanitizerFloat(0, 1) };
SettingValue<float> mColorTopicExhausted{ "GUI", "color topic exhausted", makeClampSanitizerFloat(0, 1) };
};
}
#endif

@ -0,0 +1,23 @@
#ifndef OPENMW_COMPONENTS_SETTINGS_CATEGORIES_HUD_H
#define OPENMW_COMPONENTS_SETTINGS_CATEGORIES_HUD_H
#include "components/settings/sanitizerimpl.hpp"
#include "components/settings/settingvalue.hpp"
#include <osg/Math>
#include <osg/Vec2f>
#include <osg/Vec3f>
#include <cstdint>
#include <string>
#include <string_view>
namespace Settings
{
struct HUDCategory
{
SettingValue<bool> mCrosshair{ "HUD", "crosshair" };
};
}
#endif

@ -0,0 +1,40 @@
#ifndef OPENMW_COMPONENTS_SETTINGS_CATEGORIES_INPUT_H
#define OPENMW_COMPONENTS_SETTINGS_CATEGORIES_INPUT_H
#include "components/settings/sanitizerimpl.hpp"
#include "components/settings/settingvalue.hpp"
#include <osg/Math>
#include <osg/Vec2f>
#include <osg/Vec3f>
#include <cstdint>
#include <string>
#include <string_view>
namespace Settings
{
struct InputCategory
{
SettingValue<bool> mGrabCursor{ "Input", "grab cursor" };
SettingValue<float> mCameraSensitivity{ "Input", "camera sensitivity", makeMaxStrictSanitizerFloat(0) };
SettingValue<float> mCameraYMultiplier{ "Input", "camera y multiplier", makeMaxStrictSanitizerFloat(0) };
SettingValue<bool> mInvertXAxis{ "Input", "invert x axis" };
SettingValue<bool> mInvertYAxis{ "Input", "invert y axis" };
SettingValue<bool> mEnableController{ "Input", "enable controller" };
SettingValue<float> mGamepadCursorSpeed{ "Input", "gamepad cursor speed", makeMaxStrictSanitizerFloat(0) };
SettingValue<float> mJoystickDeadZone{ "Input", "joystick dead zone", makeClampSanitizerFloat(0, 0.5f) };
SettingValue<bool> mEnableGyroscope{ "Input", "enable gyroscope" };
SettingValue<std::string> mGyroHorizontalAxis{ "Input", "gyro horizontal axis",
makeEnumSanitizerString({ "x", "y", "z", "-x", "-y", "-z" }) };
SettingValue<std::string> mGyroVerticalAxis{ "Input", "gyro vertical axis",
makeEnumSanitizerString({ "x", "y", "z", "-x", "-y", "-z" }) };
SettingValue<float> mGyroInputThreshold{ "Input", "gyro input threshold", makeMaxSanitizerFloat(0) };
SettingValue<float> mGyroHorizontalSensitivity{ "Input", "gyro horizontal sensitivity",
makeMaxStrictSanitizerFloat(0) };
SettingValue<float> mGyroVerticalSensitivity{ "Input", "gyro vertical sensitivity",
makeMaxStrictSanitizerFloat(0) };
};
}
#endif

@ -0,0 +1,31 @@
#ifndef OPENMW_COMPONENTS_SETTINGS_CATEGORIES_LUA_H
#define OPENMW_COMPONENTS_SETTINGS_CATEGORIES_LUA_H
#include "components/settings/sanitizerimpl.hpp"
#include "components/settings/settingvalue.hpp"
#include <osg/Math>
#include <osg/Vec2f>
#include <osg/Vec3f>
#include <cstdint>
#include <string>
#include <string_view>
namespace Settings
{
struct LuaCategory
{
SettingValue<bool> mLuaDebug{ "Lua", "lua debug" };
SettingValue<int> mLuaNumThreads{ "Lua", "lua num threads", makeEnumSanitizerInt({ 0, 1 }) };
SettingValue<bool> mLuaProfiler{ "Lua", "lua profiler" };
SettingValue<std::uint64_t> mSmallAllocMaxSize{ "Lua", "small alloc max size" };
SettingValue<std::uint64_t> mMemoryLimit{ "Lua", "memory limit" };
SettingValue<bool> mLogMemoryUsage{ "Lua", "log memory usage" };
SettingValue<std::uint64_t> mInstructionLimitPerCall{ "Lua", "instruction limit per call",
makeMaxSanitizerUInt64(1001) };
SettingValue<int> mGcStepsPerFrame{ "Lua", "gc steps per frame", makeMaxSanitizerInt(0) };
};
}
#endif

@ -0,0 +1,30 @@
#ifndef OPENMW_COMPONENTS_SETTINGS_CATEGORIES_MAP_H
#define OPENMW_COMPONENTS_SETTINGS_CATEGORIES_MAP_H
#include "components/settings/sanitizerimpl.hpp"
#include "components/settings/settingvalue.hpp"
#include <osg/Math>
#include <osg/Vec2f>
#include <osg/Vec3f>
#include <cstdint>
#include <string>
#include <string_view>
namespace Settings
{
struct MapCategory
{
SettingValue<int> mGlobalMapCellSize{ "Map", "global map cell size", makeMaxSanitizerInt(1) };
SettingValue<int> mLocalMapHudWidgetSize{ "Map", "local map hud widget size", makeMaxSanitizerInt(1) };
SettingValue<bool> mLocalMapHudFogOfWar{ "Map", "local map hud fog of war" };
SettingValue<int> mLocalMapResolution{ "Map", "local map resolution", makeMaxSanitizerInt(1) };
SettingValue<int> mLocalMapWidgetSize{ "Map", "local map widget size", makeMaxSanitizerInt(1) };
SettingValue<bool> mGlobal{ "Map", "global" };
SettingValue<bool> mAllowZooming{ "Map", "allow zooming" };
SettingValue<int> mMaxLocalViewingDistance{ "Map", "max local viewing distance", makeMaxSanitizerInt(1) };
};
}
#endif

@ -0,0 +1,47 @@
#ifndef OPENMW_COMPONENTS_SETTINGS_CATEGORIES_MODELS_H
#define OPENMW_COMPONENTS_SETTINGS_CATEGORIES_MODELS_H
#include "components/settings/sanitizerimpl.hpp"
#include "components/settings/settingvalue.hpp"
#include <osg/Math>
#include <osg/Vec2f>
#include <osg/Vec3f>
#include <cstdint>
#include <string>
#include <string_view>
namespace Settings
{
struct ModelsCategory
{
SettingValue<bool> mLoadUnsupportedNifFiles{ "Models", "load unsupported nif files" };
SettingValue<std::string> mXbaseanim{ "Models", "xbaseanim" };
SettingValue<std::string> mBaseanim{ "Models", "baseanim" };
SettingValue<std::string> mXbaseanim1st{ "Models", "xbaseanim1st" };
SettingValue<std::string> mBaseanimkna{ "Models", "baseanimkna" };
SettingValue<std::string> mBaseanimkna1st{ "Models", "baseanimkna1st" };
SettingValue<std::string> mXbaseanimfemale{ "Models", "xbaseanimfemale" };
SettingValue<std::string> mBaseanimfemale{ "Models", "baseanimfemale" };
SettingValue<std::string> mBaseanimfemale1st{ "Models", "baseanimfemale1st" };
SettingValue<std::string> mWolfskin{ "Models", "wolfskin" };
SettingValue<std::string> mWolfskin1st{ "Models", "wolfskin1st" };
SettingValue<std::string> mXargonianswimkna{ "Models", "xargonianswimkna" };
SettingValue<std::string> mXbaseanimkf{ "Models", "xbaseanimkf" };
SettingValue<std::string> mXbaseanim1stkf{ "Models", "xbaseanim1stkf" };
SettingValue<std::string> mXbaseanimfemalekf{ "Models", "xbaseanimfemalekf" };
SettingValue<std::string> mXargonianswimknakf{ "Models", "xargonianswimknakf" };
SettingValue<std::string> mSkyatmosphere{ "Models", "skyatmosphere" };
SettingValue<std::string> mSkyclouds{ "Models", "skyclouds" };
SettingValue<std::string> mSkynight01{ "Models", "skynight01" };
SettingValue<std::string> mSkynight02{ "Models", "skynight02" };
SettingValue<std::string> mWeatherashcloud{ "Models", "weatherashcloud" };
SettingValue<std::string> mWeatherblightcloud{ "Models", "weatherblightcloud" };
SettingValue<std::string> mWeathersnow{ "Models", "weathersnow" };
SettingValue<std::string> mWeatherblizzard{ "Models", "weatherblizzard" };
SettingValue<bool> mWriteNifDebugLog{ "Models", "write nif debug log" };
};
}
#endif

@ -0,0 +1,64 @@
#ifndef OPENMW_COMPONENTS_SETTINGS_CATEGORIES_NAVIGATOR_H
#define OPENMW_COMPONENTS_SETTINGS_CATEGORIES_NAVIGATOR_H
#include "components/settings/sanitizerimpl.hpp"
#include "components/settings/settingvalue.hpp"
#include <osg/Math>
#include <osg/Vec2f>
#include <osg/Vec3f>
#include <cstdint>
#include <string>
#include <string_view>
namespace Settings
{
struct NavigatorCategory
{
SettingValue<bool> mEnable{ "Navigator", "enable" };
SettingValue<float> mRecastScaleFactor{ "Navigator", "recast scale factor", makeMaxStrictSanitizerFloat(0) };
SettingValue<float> mCellHeight{ "Navigator", "cell height", makeMaxStrictSanitizerFloat(0) };
SettingValue<float> mCellSize{ "Navigator", "cell size", makeMaxStrictSanitizerFloat(0) };
SettingValue<float> mDetailSampleDist{ "Navigator", "detail sample dist",
makeEqualOrMaxSanitizerFloat(0, 0.9) };
SettingValue<float> mDetailSampleMaxError{ "Navigator", "detail sample max error", makeMaxSanitizerFloat(0) };
SettingValue<float> mMaxSimplificationError{ "Navigator", "max simplification error",
makeMaxSanitizerFloat(0) };
SettingValue<int> mTileSize{ "Navigator", "tile size", makeMaxSanitizerInt(1) };
SettingValue<int> mBorderSize{ "Navigator", "border size", makeMaxSanitizerInt(0) };
SettingValue<int> mMaxEdgeLen{ "Navigator", "max edge len", makeMaxSanitizerInt(0) };
SettingValue<int> mMaxNavMeshQueryNodes{ "Navigator", "max nav mesh query nodes",
makeClampSanitizerInt(1, 65535) };
SettingValue<int> mMaxPolygonsPerTile{ "Navigator", "max polygons per tile",
makeClampSanitizerInt(1, 1 << 21) };
SettingValue<int> mMaxVertsPerPoly{ "Navigator", "max verts per poly", makeMaxSanitizerInt(3) };
SettingValue<int> mRegionMergeArea{ "Navigator", "region merge area", makeMaxSanitizerInt(0) };
SettingValue<int> mRegionMinArea{ "Navigator", "region min area", makeMaxSanitizerInt(0) };
SettingValue<std::size_t> mAsyncNavMeshUpdaterThreads{ "Navigator", "async nav mesh updater threads",
makeMaxSanitizerSize(1) };
SettingValue<std::size_t> mMaxNavMeshTilesCacheSize{ "Navigator", "max nav mesh tiles cache size" };
SettingValue<std::size_t> mMaxPolygonPathSize{ "Navigator", "max polygon path size" };
SettingValue<std::size_t> mMaxSmoothPathSize{ "Navigator", "max smooth path size" };
SettingValue<bool> mEnableWriteRecastMeshToFile{ "Navigator", "enable write recast mesh to file" };
SettingValue<bool> mEnableWriteNavMeshToFile{ "Navigator", "enable write nav mesh to file" };
SettingValue<bool> mEnableRecastMeshFileNameRevision{ "Navigator", "enable recast mesh file name revision" };
SettingValue<bool> mEnableNavMeshFileNameRevision{ "Navigator", "enable nav mesh file name revision" };
SettingValue<std::string> mRecastMeshPathPrefix{ "Navigator", "recast mesh path prefix" };
SettingValue<std::string> mNavMeshPathPrefix{ "Navigator", "nav mesh path prefix" };
SettingValue<bool> mEnableNavMeshRender{ "Navigator", "enable nav mesh render" };
SettingValue<std::string> mNavMeshRenderMode{ "Navigator", "nav mesh render mode",
makeEnumSanitizerString({ "area type", "update frequency" }) };
SettingValue<bool> mEnableAgentsPathsRender{ "Navigator", "enable agents paths render" };
SettingValue<bool> mEnableRecastMeshRender{ "Navigator", "enable recast mesh render" };
SettingValue<int> mMaxTilesNumber{ "Navigator", "max tiles number", makeMaxSanitizerInt(0) };
SettingValue<int> mMinUpdateIntervalMs{ "Navigator", "min update interval ms", makeMaxSanitizerInt(0) };
SettingValue<int> mWaitUntilMinDistanceToPlayer{ "Navigator", "wait until min distance to player",
makeMaxSanitizerInt(0) };
SettingValue<bool> mEnableNavMeshDiskCache{ "Navigator", "enable nav mesh disk cache" };
SettingValue<bool> mWriteToNavmeshdb{ "Navigator", "write to navmeshdb" };
SettingValue<std::uint64_t> mMaxNavmeshdbFileSize{ "Navigator", "max navmeshdb file size" };
};
}
#endif

@ -0,0 +1,25 @@
#ifndef OPENMW_COMPONENTS_SETTINGS_CATEGORIES_PHYSICS_H
#define OPENMW_COMPONENTS_SETTINGS_CATEGORIES_PHYSICS_H
#include "components/settings/sanitizerimpl.hpp"
#include "components/settings/settingvalue.hpp"
#include <osg/Math>
#include <osg/Vec2f>
#include <osg/Vec3f>
#include <cstdint>
#include <string>
#include <string_view>
namespace Settings
{
struct PhysicsCategory
{
SettingValue<int> mAsyncNumThreads{ "Physics", "async num threads", makeMaxSanitizerInt(0) };
SettingValue<int> mLineofsightKeepInactiveCache{ "Physics", "lineofsight keep inactive cache",
makeMaxSanitizerInt(-1) };
};
}
#endif

@ -0,0 +1,27 @@
#ifndef OPENMW_COMPONENTS_SETTINGS_CATEGORIES_POSTPROCESSING_H
#define OPENMW_COMPONENTS_SETTINGS_CATEGORIES_POSTPROCESSING_H
#include "components/settings/sanitizerimpl.hpp"
#include "components/settings/settingvalue.hpp"
#include <osg/Math>
#include <osg/Vec2f>
#include <osg/Vec3f>
#include <cstdint>
#include <string>
#include <string_view>
namespace Settings
{
struct PostProcessingCategory
{
SettingValue<bool> mEnabled{ "Post Processing", "enabled" };
SettingValue<std::string> mChain{ "Post Processing", "chain" };
SettingValue<float> mAutoExposureSpeed{ "Post Processing", "auto exposure speed",
makeMaxStrictSanitizerFloat(0.0001f) };
SettingValue<bool> mTransparentPostpass{ "Post Processing", "transparent postpass" };
};
}
#endif

@ -0,0 +1,26 @@
#ifndef OPENMW_COMPONENTS_SETTINGS_CATEGORIES_SAVES_H
#define OPENMW_COMPONENTS_SETTINGS_CATEGORIES_SAVES_H
#include "components/settings/sanitizerimpl.hpp"
#include "components/settings/settingvalue.hpp"
#include <osg/Math>
#include <osg/Vec2f>
#include <osg/Vec3f>
#include <cstdint>
#include <string>
#include <string_view>
namespace Settings
{
struct SavesCategory
{
SettingValue<std::string> mCharacter{ "Saves", "character" };
SettingValue<bool> mAutosave{ "Saves", "autosave" };
SettingValue<bool> mTimeplayed{ "Saves", "timeplayed" };
SettingValue<int> mMaxQuicksaves{ "Saves", "max quicksaves", makeMaxSanitizerInt(1) };
};
}
#endif

@ -0,0 +1,49 @@
#ifndef OPENMW_COMPONENTS_SETTINGS_CATEGORIES_SHADERS_H
#define OPENMW_COMPONENTS_SETTINGS_CATEGORIES_SHADERS_H
#include "components/settings/sanitizerimpl.hpp"
#include "components/settings/settingvalue.hpp"
#include <osg/Math>
#include <osg/Vec2f>
#include <osg/Vec3f>
#include <cstdint>
#include <string>
#include <string_view>
namespace Settings
{
struct ShadersCategory
{
SettingValue<bool> mForceShaders{ "Shaders", "force shaders" };
SettingValue<bool> mForcePerPixelLighting{ "Shaders", "force per pixel lighting" };
SettingValue<bool> mClampLighting{ "Shaders", "clamp lighting" };
SettingValue<bool> mAutoUseObjectNormalMaps{ "Shaders", "auto use object normal maps" };
SettingValue<bool> mAutoUseObjectSpecularMaps{ "Shaders", "auto use object specular maps" };
SettingValue<bool> mAutoUseTerrainNormalMaps{ "Shaders", "auto use terrain normal maps" };
SettingValue<bool> mAutoUseTerrainSpecularMaps{ "Shaders", "auto use terrain specular maps" };
SettingValue<std::string> mNormalMapPattern{ "Shaders", "normal map pattern" };
SettingValue<std::string> mNormalHeightMapPattern{ "Shaders", "normal height map pattern" };
SettingValue<std::string> mSpecularMapPattern{ "Shaders", "specular map pattern" };
SettingValue<std::string> mTerrainSpecularMapPattern{ "Shaders", "terrain specular map pattern" };
SettingValue<bool> mApplyLightingToEnvironmentMaps{ "Shaders", "apply lighting to environment maps" };
SettingValue<std::string> mLightingMethod{ "Shaders", "lighting method",
makeEnumSanitizerString({ "legacy", "shaders compatibility", "shaders" }) };
SettingValue<float> mLightBoundsMultiplier{ "Shaders", "light bounds multiplier",
makeClampSanitizerFloat(0, 5) };
SettingValue<float> mMaximumLightDistance{ "Shaders", "maximum light distance" };
SettingValue<float> mLightFadeStart{ "Shaders", "light fade start", makeClampSanitizerFloat(0, 1) };
SettingValue<int> mMaxLights{ "Shaders", "max lights", makeClampSanitizerInt(2, 64) };
SettingValue<float> mMinimumInteriorBrightness{ "Shaders", "minimum interior brightness",
makeClampSanitizerFloat(0, 1) };
SettingValue<bool> mAntialiasAlphaTest{ "Shaders", "antialias alpha test" };
SettingValue<bool> mAdjustCoverageForAlphaTest{ "Shaders", "adjust coverage for alpha test" };
SettingValue<bool> mSoftParticles{ "Shaders", "soft particles" };
SettingValue<bool> mWeatherParticleOcclusion{ "Shaders", "weather particle occlusion" };
SettingValue<float> mWeatherParticleOcclusionSmallFeatureCullingPixelSize{ "Shaders",
"weather particle occlusion small feature culling pixel size" };
};
}
#endif

@ -0,0 +1,46 @@
#ifndef OPENMW_COMPONENTS_SETTINGS_CATEGORIES_SHADOWS_H
#define OPENMW_COMPONENTS_SETTINGS_CATEGORIES_SHADOWS_H
#include "components/settings/sanitizerimpl.hpp"
#include "components/settings/settingvalue.hpp"
#include <osg/Math>
#include <osg/Vec2f>
#include <osg/Vec3f>
#include <cstdint>
#include <string>
#include <string_view>
namespace Settings
{
struct ShadowsCategory
{
SettingValue<bool> mEnableShadows{ "Shadows", "enable shadows" };
SettingValue<int> mNumberOfShadowMaps{ "Shadows", "number of shadow maps", makeClampSanitizerInt(1, 8) };
SettingValue<float> mMaximumShadowMapDistance{ "Shadows", "maximum shadow map distance" };
SettingValue<float> mShadowFadeStart{ "Shadows", "shadow fade start", makeClampSanitizerFloat(0, 1) };
SettingValue<bool> mAllowShadowMapOverlap{ "Shadows", "allow shadow map overlap" };
SettingValue<float> mSplitPointUniformLogarithmicRatio{ "Shadows", "split point uniform logarithmic ratio",
makeClampSanitizerFloat(0, 1) };
SettingValue<float> mSplitPointBias{ "Shadows", "split point bias" };
SettingValue<bool> mEnableDebugHud{ "Shadows", "enable debug hud" };
SettingValue<bool> mEnableDebugOverlay{ "Shadows", "enable debug overlay" };
SettingValue<std::string> mComputeSceneBounds{ "Shadows", "compute scene bounds",
makeEnumSanitizerString({ "primitives", "bounds", "none" }) };
SettingValue<int> mShadowMapResolution{ "Shadows", "shadow map resolution" };
SettingValue<float> mMinimumLispsmNearFarRatio{ "Shadows", "minimum lispsm near far ratio",
makeMaxStrictSanitizerFloat(0) };
SettingValue<float> mPolygonOffsetFactor{ "Shadows", "polygon offset factor" };
SettingValue<float> mPolygonOffsetUnits{ "Shadows", "polygon offset units" };
SettingValue<float> mNormalOffsetDistance{ "Shadows", "normal offset distance" };
SettingValue<bool> mUseFrontFaceCulling{ "Shadows", "use front face culling" };
SettingValue<bool> mActorShadows{ "Shadows", "actor shadows" };
SettingValue<bool> mPlayerShadows{ "Shadows", "player shadows" };
SettingValue<bool> mTerrainShadows{ "Shadows", "terrain shadows" };
SettingValue<bool> mObjectShadows{ "Shadows", "object shadows" };
SettingValue<bool> mEnableIndoorShadows{ "Shadows", "enable indoor shadows" };
};
}
#endif

@ -0,0 +1,32 @@
#ifndef OPENMW_COMPONENTS_SETTINGS_CATEGORIES_SOUND_H
#define OPENMW_COMPONENTS_SETTINGS_CATEGORIES_SOUND_H
#include "components/settings/sanitizerimpl.hpp"
#include "components/settings/settingvalue.hpp"
#include <osg/Math>
#include <osg/Vec2f>
#include <osg/Vec3f>
#include <cstdint>
#include <string>
#include <string_view>
namespace Settings
{
struct SoundCategory
{
SettingValue<std::string> mDevice{ "Sound", "device" };
SettingValue<float> mMasterVolume{ "Sound", "master volume", makeClampSanitizerFloat(0, 1) };
SettingValue<float> mFootstepsVolume{ "Sound", "footsteps volume", makeClampSanitizerFloat(0, 1) };
SettingValue<float> mMusicVolume{ "Sound", "music volume", makeClampSanitizerFloat(0, 1) };
SettingValue<float> mSfxVolume{ "Sound", "sfx volume", makeClampSanitizerFloat(0, 1) };
SettingValue<float> mVoiceVolume{ "Sound", "voice volume", makeClampSanitizerFloat(0, 1) };
SettingValue<int> mBufferCacheMin{ "Sound", "buffer cache min", makeMaxSanitizerInt(1) };
SettingValue<int> mBufferCacheMax{ "Sound", "buffer cache max", makeMaxSanitizerInt(1) };
SettingValue<int> mHrtfEnable{ "Sound", "hrtf enable", makeEnumSanitizerInt({ -1, 0, 1 }) };
SettingValue<std::string> mHrtf{ "Sound", "hrtf" };
};
}
#endif

@ -0,0 +1,28 @@
#ifndef OPENMW_COMPONENTS_SETTINGS_CATEGORIES_STEREO_H
#define OPENMW_COMPONENTS_SETTINGS_CATEGORIES_STEREO_H
#include "components/settings/sanitizerimpl.hpp"
#include "components/settings/settingvalue.hpp"
#include <osg/Math>
#include <osg/Vec2f>
#include <osg/Vec3f>
#include <cstdint>
#include <string>
#include <string_view>
namespace Settings
{
struct StereoCategory
{
SettingValue<bool> mStereoEnabled{ "Stereo", "stereo enabled" };
SettingValue<bool> mMultiview{ "Stereo", "multiview" };
SettingValue<bool> mSharedShadowMaps{ "Stereo", "shared shadow maps" };
SettingValue<bool> mAllowDisplayListsForMultiview{ "Stereo", "allow display lists for multiview" };
SettingValue<bool> mUseCustomView{ "Stereo", "use custom view" };
SettingValue<bool> mUseCustomEyeResolution{ "Stereo", "use custom eye resolution" };
};
}
#endif

@ -0,0 +1,62 @@
#ifndef OPENMW_COMPONENTS_SETTINGS_CATEGORIES_STEREOVIEW_H
#define OPENMW_COMPONENTS_SETTINGS_CATEGORIES_STEREOVIEW_H
#include "components/settings/sanitizerimpl.hpp"
#include "components/settings/settingvalue.hpp"
#include <osg/Math>
#include <osg/Vec2f>
#include <osg/Vec3f>
#include <cstdint>
#include <string>
#include <string_view>
namespace Settings
{
struct StereoViewCategory
{
SettingValue<int> mEyeResolutionX{ "Stereo View", "eye resolution x", makeMaxSanitizerInt(1) };
SettingValue<int> mEyeResolutionY{ "Stereo View", "eye resolution y", makeMaxSanitizerInt(1) };
SettingValue<double> mLeftEyeOffsetX{ "Stereo View", "left eye offset x" };
SettingValue<double> mLeftEyeOffsetY{ "Stereo View", "left eye offset y" };
SettingValue<double> mLeftEyeOffsetZ{ "Stereo View", "left eye offset z" };
SettingValue<double> mLeftEyeOrientationX{ "Stereo View", "left eye orientation x",
makeClampSanitizerDouble(-1, 1) };
SettingValue<double> mLeftEyeOrientationY{ "Stereo View", "left eye orientation y",
makeClampSanitizerDouble(-1, 1) };
SettingValue<double> mLeftEyeOrientationZ{ "Stereo View", "left eye orientation z",
makeClampSanitizerDouble(-1, 1) };
SettingValue<double> mLeftEyeOrientationW{ "Stereo View", "left eye orientation w",
makeClampSanitizerDouble(-1, 1) };
SettingValue<double> mLeftEyeFovLeft{ "Stereo View", "left eye fov left",
makeClampSanitizerDouble(-osg::PI, osg::PI) };
SettingValue<double> mLeftEyeFovRight{ "Stereo View", "left eye fov right",
makeClampSanitizerDouble(-osg::PI, osg::PI) };
SettingValue<double> mLeftEyeFovUp{ "Stereo View", "left eye fov up",
makeClampSanitizerDouble(-osg::PI, osg::PI) };
SettingValue<double> mLeftEyeFovDown{ "Stereo View", "left eye fov down",
makeClampSanitizerDouble(-osg::PI, osg::PI) };
SettingValue<double> mRightEyeOffsetX{ "Stereo View", "right eye offset x" };
SettingValue<double> mRightEyeOffsetY{ "Stereo View", "right eye offset y" };
SettingValue<double> mRightEyeOffsetZ{ "Stereo View", "right eye offset z" };
SettingValue<double> mRightEyeOrientationX{ "Stereo View", "right eye orientation x",
makeClampSanitizerDouble(-1, 1) };
SettingValue<double> mRightEyeOrientationY{ "Stereo View", "right eye orientation y",
makeClampSanitizerDouble(-1, 1) };
SettingValue<double> mRightEyeOrientationZ{ "Stereo View", "right eye orientation z",
makeClampSanitizerDouble(-1, 1) };
SettingValue<double> mRightEyeOrientationW{ "Stereo View", "right eye orientation w",
makeClampSanitizerDouble(-1, 1) };
SettingValue<double> mRightEyeFovLeft{ "Stereo View", "right eye fov left",
makeClampSanitizerDouble(-osg::PI, osg::PI) };
SettingValue<double> mRightEyeFovRight{ "Stereo View", "right eye fov right",
makeClampSanitizerDouble(-osg::PI, osg::PI) };
SettingValue<double> mRightEyeFovUp{ "Stereo View", "right eye fov up",
makeClampSanitizerDouble(-osg::PI, osg::PI) };
SettingValue<double> mRightEyeFovDown{ "Stereo View", "right eye fov down",
makeClampSanitizerDouble(-osg::PI, osg::PI) };
};
}
#endif

@ -0,0 +1,39 @@
#ifndef OPENMW_COMPONENTS_SETTINGS_CATEGORIES_TERRAIN_H
#define OPENMW_COMPONENTS_SETTINGS_CATEGORIES_TERRAIN_H
#include "components/settings/sanitizerimpl.hpp"
#include "components/settings/settingvalue.hpp"
#include <osg/Math>
#include <osg/Vec2f>
#include <osg/Vec3f>
#include <cstdint>
#include <string>
#include <string_view>
namespace Settings
{
struct TerrainCategory
{
SettingValue<bool> mDistantTerrain{ "Terrain", "distant terrain" };
SettingValue<float> mLodFactor{ "Terrain", "lod factor", makeMaxStrictSanitizerFloat(0) };
SettingValue<int> mVertexLodMod{ "Terrain", "vertex lod mod" };
SettingValue<int> mCompositeMapLevel{ "Terrain", "composite map level", makeMaxSanitizerInt(-3) };
SettingValue<int> mCompositeMapResolution{ "Terrain", "composite map resolution", makeMaxSanitizerInt(1) };
SettingValue<float> mMaxCompositeGeometrySize{ "Terrain", "max composite geometry size",
makeMaxSanitizerFloat(1) };
SettingValue<bool> mDebugChunks{ "Terrain", "debug chunks" };
SettingValue<bool> mObjectPaging{ "Terrain", "object paging" };
SettingValue<bool> mObjectPagingActiveGrid{ "Terrain", "object paging active grid" };
SettingValue<float> mObjectPagingMergeFactor{ "Terrain", "object paging merge factor",
makeMaxStrictSanitizerFloat(0) };
SettingValue<float> mObjectPagingMinSize{ "Terrain", "object paging min size", makeMaxStrictSanitizerFloat(0) };
SettingValue<float> mObjectPagingMinSizeMergeFactor{ "Terrain", "object paging min size merge factor",
makeMaxStrictSanitizerFloat(0) };
SettingValue<float> mObjectPagingMinSizeCostMultiplier{ "Terrain", "object paging min size cost multiplier",
makeMaxStrictSanitizerFloat(0) };
};
}
#endif

@ -0,0 +1,34 @@
#ifndef OPENMW_COMPONENTS_SETTINGS_CATEGORIES_VIDEO_H
#define OPENMW_COMPONENTS_SETTINGS_CATEGORIES_VIDEO_H
#include "components/settings/sanitizerimpl.hpp"
#include "components/settings/settingvalue.hpp"
#include <osg/Math>
#include <osg/Vec2f>
#include <osg/Vec3f>
#include <cstdint>
#include <string>
#include <string_view>
namespace Settings
{
struct VideoCategory
{
SettingValue<int> mResolutionX{ "Video", "resolution x", makeMaxSanitizerInt(1) };
SettingValue<int> mResolutionY{ "Video", "resolution y", makeMaxSanitizerInt(1) };
SettingValue<int> mWindowMode{ "Video", "window mode", makeEnumSanitizerInt({ 0, 1, 2 }) };
SettingValue<int> mScreen{ "Video", "screen", makeMaxSanitizerInt(0) };
SettingValue<bool> mMinimizeOnFocusLoss{ "Video", "minimize on focus loss" };
SettingValue<bool> mWindowBorder{ "Video", "window border" };
SettingValue<int> mAntialiasing{ "Video", "antialiasing", makeEnumSanitizerInt({ 0, 2, 4, 8, 16 }) };
SettingValue<int> mVsyncMode{ "Video", "vsync mode", makeEnumSanitizerInt({ 0, 1, 2 }) };
SettingValue<float> mFramerateLimit{ "Video", "framerate limit", makeMaxSanitizerFloat(0) };
SettingValue<float> mContrast{ "Video", "contrast", makeMaxStrictSanitizerFloat(0) };
SettingValue<float> mGamma{ "Video", "gamma", makeMaxStrictSanitizerFloat(0) };
SettingValue<std::string> mScreenshotType{ "Video", "screenshot type" };
};
}
#endif

@ -0,0 +1,30 @@
#ifndef OPENMW_COMPONENTS_SETTINGS_CATEGORIES_WATER_H
#define OPENMW_COMPONENTS_SETTINGS_CATEGORIES_WATER_H
#include "components/settings/sanitizerimpl.hpp"
#include "components/settings/settingvalue.hpp"
#include <osg/Math>
#include <osg/Vec2f>
#include <osg/Vec3f>
#include <cstdint>
#include <string>
#include <string_view>
namespace Settings
{
struct WaterCategory
{
SettingValue<bool> mShader{ "Water", "shader" };
SettingValue<int> mRttSize{ "Water", "rtt size", makeMaxSanitizerInt(1) };
SettingValue<bool> mRefraction{ "Water", "refraction" };
SettingValue<int> mReflectionDetail{ "Water", "reflection detail", makeEnumSanitizerInt({ 0, 1, 2, 3, 4, 5 }) };
SettingValue<int> mRainRippleDetail{ "Water", "rain ripple detail", makeEnumSanitizerInt({ 0, 1, 2 }) };
SettingValue<float> mSmallFeatureCullingPixelSize{ "Water", "small feature culling pixel size",
makeMaxStrictSanitizerFloat(0) };
SettingValue<float> mRefractionScale{ "Water", "refraction scale", makeClampSanitizerFloat(0, 1) };
};
}
#endif

@ -0,0 +1,165 @@
#ifndef OPENMW_COMPONENTS_SETTINGS_CATEGORIES_WINDOWS_H
#define OPENMW_COMPONENTS_SETTINGS_CATEGORIES_WINDOWS_H
#include "components/settings/sanitizerimpl.hpp"
#include "components/settings/settingvalue.hpp"
#include <osg/Math>
#include <osg/Vec2f>
#include <osg/Vec3f>
#include <cstdint>
#include <string>
#include <string_view>
namespace Settings
{
struct WindowsCategory
{
SettingValue<float> mStatsX{ "Windows", "stats x" };
SettingValue<float> mStatsY{ "Windows", "stats y" };
SettingValue<float> mStatsW{ "Windows", "stats w" };
SettingValue<float> mStatsH{ "Windows", "stats h" };
SettingValue<float> mStatsMaximizedX{ "Windows", "stats maximized x" };
SettingValue<float> mStatsMaximizedY{ "Windows", "stats maximized y" };
SettingValue<float> mStatsMaximizedW{ "Windows", "stats maximized w" };
SettingValue<float> mStatsMaximizedH{ "Windows", "stats maximized h" };
SettingValue<bool> mStatsPin{ "Windows", "stats pin" };
SettingValue<bool> mStatsHidden{ "Windows", "stats hidden" };
SettingValue<bool> mStatsMaximized{ "Windows", "stats maximized" };
SettingValue<float> mSpellsX{ "Windows", "spells x" };
SettingValue<float> mSpellsY{ "Windows", "spells y" };
SettingValue<float> mSpellsW{ "Windows", "spells w" };
SettingValue<float> mSpellsH{ "Windows", "spells h" };
SettingValue<float> mSpellsMaximizedX{ "Windows", "spells maximized x" };
SettingValue<float> mSpellsMaximizedY{ "Windows", "spells maximized y" };
SettingValue<float> mSpellsMaximizedW{ "Windows", "spells maximized w" };
SettingValue<float> mSpellsMaximizedH{ "Windows", "spells maximized h" };
SettingValue<bool> mSpellsPin{ "Windows", "spells pin" };
SettingValue<bool> mSpellsHidden{ "Windows", "spells hidden" };
SettingValue<bool> mSpellsMaximized{ "Windows", "spells maximized" };
SettingValue<float> mMapX{ "Windows", "map x" };
SettingValue<float> mMapY{ "Windows", "map y" };
SettingValue<float> mMapW{ "Windows", "map w" };
SettingValue<float> mMapH{ "Windows", "map h" };
SettingValue<float> mMapMaximizedX{ "Windows", "map maximized x" };
SettingValue<float> mMapMaximizedY{ "Windows", "map maximized y" };
SettingValue<float> mMapMaximizedW{ "Windows", "map maximized w" };
SettingValue<float> mMapMaximizedH{ "Windows", "map maximized h" };
SettingValue<bool> mMapPin{ "Windows", "map pin" };
SettingValue<bool> mMapHidden{ "Windows", "map hidden" };
SettingValue<bool> mMapMaximized{ "Windows", "map maximized" };
SettingValue<float> mInventoryX{ "Windows", "inventory x" };
SettingValue<float> mInventoryY{ "Windows", "inventory y" };
SettingValue<float> mInventoryW{ "Windows", "inventory w" };
SettingValue<float> mInventoryH{ "Windows", "inventory h" };
SettingValue<float> mInventoryMaximizedX{ "Windows", "inventory maximized x" };
SettingValue<float> mInventoryMaximizedY{ "Windows", "inventory maximized y" };
SettingValue<float> mInventoryMaximizedW{ "Windows", "inventory maximized w" };
SettingValue<float> mInventoryMaximizedH{ "Windows", "inventory maximized h" };
SettingValue<bool> mInventoryPin{ "Windows", "inventory pin" };
SettingValue<bool> mInventoryHidden{ "Windows", "inventory hidden" };
SettingValue<bool> mInventoryMaximized{ "Windows", "inventory maximized" };
SettingValue<float> mInventoryContainerX{ "Windows", "inventory container x" };
SettingValue<float> mInventoryContainerY{ "Windows", "inventory container y" };
SettingValue<float> mInventoryContainerW{ "Windows", "inventory container w" };
SettingValue<float> mInventoryContainerH{ "Windows", "inventory container h" };
SettingValue<float> mInventoryContainerMaximizedX{ "Windows", "inventory container maximized x" };
SettingValue<float> mInventoryContainerMaximizedY{ "Windows", "inventory container maximized y" };
SettingValue<float> mInventoryContainerMaximizedW{ "Windows", "inventory container maximized w" };
SettingValue<float> mInventoryContainerMaximizedH{ "Windows", "inventory container maximized h" };
SettingValue<bool> mInventoryContainerMaximized{ "Windows", "inventory container maximized" };
SettingValue<float> mInventoryBarterX{ "Windows", "inventory barter x" };
SettingValue<float> mInventoryBarterY{ "Windows", "inventory barter y" };
SettingValue<float> mInventoryBarterW{ "Windows", "inventory barter w" };
SettingValue<float> mInventoryBarterH{ "Windows", "inventory barter h" };
SettingValue<float> mInventoryBarterMaximizedX{ "Windows", "inventory barter maximized x" };
SettingValue<float> mInventoryBarterMaximizedY{ "Windows", "inventory barter maximized y" };
SettingValue<float> mInventoryBarterMaximizedW{ "Windows", "inventory barter maximized w" };
SettingValue<float> mInventoryBarterMaximizedH{ "Windows", "inventory barter maximized h" };
SettingValue<bool> mInventoryBarterMaximized{ "Windows", "inventory barter maximized" };
SettingValue<float> mInventoryCompanionX{ "Windows", "inventory companion x" };
SettingValue<float> mInventoryCompanionY{ "Windows", "inventory companion y" };
SettingValue<float> mInventoryCompanionW{ "Windows", "inventory companion w" };
SettingValue<float> mInventoryCompanionH{ "Windows", "inventory companion h" };
SettingValue<float> mInventoryCompanionMaximizedX{ "Windows", "inventory companion maximized x" };
SettingValue<float> mInventoryCompanionMaximizedY{ "Windows", "inventory companion maximized y" };
SettingValue<float> mInventoryCompanionMaximizedW{ "Windows", "inventory companion maximized w" };
SettingValue<float> mInventoryCompanionMaximizedH{ "Windows", "inventory companion maximized h" };
SettingValue<bool> mInventoryCompanionMaximized{ "Windows", "inventory companion maximized" };
SettingValue<float> mDialogueX{ "Windows", "dialogue x" };
SettingValue<float> mDialogueY{ "Windows", "dialogue y" };
SettingValue<float> mDialogueW{ "Windows", "dialogue w" };
SettingValue<float> mDialogueH{ "Windows", "dialogue h" };
SettingValue<float> mDialogueMaximizedX{ "Windows", "dialogue maximized x" };
SettingValue<float> mDialogueMaximizedY{ "Windows", "dialogue maximized y" };
SettingValue<float> mDialogueMaximizedW{ "Windows", "dialogue maximized w" };
SettingValue<float> mDialogueMaximizedH{ "Windows", "dialogue maximized h" };
SettingValue<bool> mDialogueMaximized{ "Windows", "dialogue maximized" };
SettingValue<float> mAlchemyX{ "Windows", "alchemy x" };
SettingValue<float> mAlchemyY{ "Windows", "alchemy y" };
SettingValue<float> mAlchemyW{ "Windows", "alchemy w" };
SettingValue<float> mAlchemyH{ "Windows", "alchemy h" };
SettingValue<float> mAlchemyMaximizedX{ "Windows", "alchemy maximized x" };
SettingValue<float> mAlchemyMaximizedY{ "Windows", "alchemy maximized y" };
SettingValue<float> mAlchemyMaximizedW{ "Windows", "alchemy maximized w" };
SettingValue<float> mAlchemyMaximizedH{ "Windows", "alchemy maximized h" };
SettingValue<bool> mAlchemyMaximized{ "Windows", "alchemy maximized" };
SettingValue<float> mConsoleX{ "Windows", "console x" };
SettingValue<float> mConsoleY{ "Windows", "console y" };
SettingValue<float> mConsoleW{ "Windows", "console w" };
SettingValue<float> mConsoleH{ "Windows", "console h" };
SettingValue<float> mConsoleMaximizedX{ "Windows", "console maximized x" };
SettingValue<float> mConsoleMaximizedY{ "Windows", "console maximized y" };
SettingValue<float> mConsoleMaximizedW{ "Windows", "console maximized w" };
SettingValue<float> mConsoleMaximizedH{ "Windows", "console maximized h" };
SettingValue<bool> mConsoleMaximized{ "Windows", "console maximized" };
SettingValue<float> mContainerX{ "Windows", "container x" };
SettingValue<float> mContainerY{ "Windows", "container y" };
SettingValue<float> mContainerW{ "Windows", "container w" };
SettingValue<float> mContainerH{ "Windows", "container h" };
SettingValue<float> mContainerMaximizedX{ "Windows", "container maximized x" };
SettingValue<float> mContainerMaximizedY{ "Windows", "container maximized y" };
SettingValue<float> mContainerMaximizedW{ "Windows", "container maximized w" };
SettingValue<float> mContainerMaximizedH{ "Windows", "container maximized h" };
SettingValue<bool> mContainerMaximized{ "Windows", "container maximized" };
SettingValue<float> mBarterX{ "Windows", "barter x" };
SettingValue<float> mBarterY{ "Windows", "barter y" };
SettingValue<float> mBarterW{ "Windows", "barter w" };
SettingValue<float> mBarterH{ "Windows", "barter h" };
SettingValue<float> mBarterMaximizedX{ "Windows", "barter maximized x" };
SettingValue<float> mBarterMaximizedY{ "Windows", "barter maximized y" };
SettingValue<float> mBarterMaximizedW{ "Windows", "barter maximized w" };
SettingValue<float> mBarterMaximizedH{ "Windows", "barter maximized h" };
SettingValue<bool> mBarterMaximized{ "Windows", "barter maximized" };
SettingValue<float> mCompanionX{ "Windows", "companion x" };
SettingValue<float> mCompanionY{ "Windows", "companion y" };
SettingValue<float> mCompanionW{ "Windows", "companion w" };
SettingValue<float> mCompanionH{ "Windows", "companion h" };
SettingValue<float> mCompanionMaximizedX{ "Windows", "companion maximized x" };
SettingValue<float> mCompanionMaximizedY{ "Windows", "companion maximized y" };
SettingValue<float> mCompanionMaximizedW{ "Windows", "companion maximized w" };
SettingValue<float> mCompanionMaximizedH{ "Windows", "companion maximized h" };
SettingValue<bool> mCompanionMaximized{ "Windows", "companion maximized" };
SettingValue<float> mSettingsX{ "Windows", "settings x" };
SettingValue<float> mSettingsY{ "Windows", "settings y" };
SettingValue<float> mSettingsW{ "Windows", "settings w" };
SettingValue<float> mSettingsH{ "Windows", "settings h" };
SettingValue<float> mSettingsMaximizedX{ "Windows", "settings maximized x" };
SettingValue<float> mSettingsMaximizedY{ "Windows", "settings maximized y" };
SettingValue<float> mSettingsMaximizedW{ "Windows", "settings maximized w" };
SettingValue<float> mSettingsMaximizedH{ "Windows", "settings maximized h" };
SettingValue<bool> mSettingsMaximized{ "Windows", "settings maximized" };
SettingValue<float> mPostprocessorH{ "Windows", "postprocessor h" };
SettingValue<float> mPostprocessorW{ "Windows", "postprocessor w" };
SettingValue<float> mPostprocessorX{ "Windows", "postprocessor x" };
SettingValue<float> mPostprocessorY{ "Windows", "postprocessor y" };
SettingValue<float> mPostprocessorMaximizedX{ "Windows", "postprocessor maximized x" };
SettingValue<float> mPostprocessorMaximizedY{ "Windows", "postprocessor maximized y" };
SettingValue<float> mPostprocessorMaximizedW{ "Windows", "postprocessor maximized w" };
SettingValue<float> mPostprocessorMaximizedH{ "Windows", "postprocessor maximized h" };
SettingValue<bool> mPostprocessorMaximized{ "Windows", "postprocessor maximized" };
};
}
#endif

@ -0,0 +1,15 @@
#ifndef OPENMW_COMPONENTS_SETTINGS_SANITIZER_H
#define OPENMW_COMPONENTS_SETTINGS_SANITIZER_H
namespace Settings
{
template <class T>
struct Sanitizer
{
virtual ~Sanitizer() = default;
virtual T apply(const T& value) const = 0;
};
}
#endif

@ -0,0 +1,210 @@
#include "sanitizerimpl.hpp"
#include <osg/Vec3f>
#include <algorithm>
#include <cassert>
#include <cmath>
#include <limits>
#include <sstream>
#include <stdexcept>
#include <type_traits>
#include <utility>
#include <vector>
namespace Settings
{
namespace
{
template <class T>
struct Max final : Sanitizer<T>
{
T mMax;
explicit Max(const T& max)
: mMax(max)
{
}
T apply(const T& value) const override { return std::max(value, mMax); }
};
template <class T>
struct MaxStrict final : Sanitizer<T>
{
static_assert(std::is_floating_point_v<T>);
T mMax;
explicit MaxStrict(const T& max)
: mMax(std::nextafter(max, std::numeric_limits<T>::max()))
{
}
T apply(const T& value) const override { return std::max(value, mMax); }
};
template <>
struct MaxStrict<osg::Vec3f> final : Sanitizer<osg::Vec3f>
{
osg::Vec3f mMax;
explicit MaxStrict(const osg::Vec3f& max)
: mMax(std::nextafter(max.x(), std::numeric_limits<float>::max()),
std::nextafter(max.y(), std::numeric_limits<float>::max()),
std::nextafter(max.z(), std::numeric_limits<float>::max()))
{
}
osg::Vec3f apply(const osg::Vec3f& value) const override
{
return osg::Vec3f(
std::max(value.x(), mMax.x()), std::max(value.y(), mMax.y()), std::max(value.z(), mMax.z()));
}
};
template <class T>
struct Clamp final : Sanitizer<T>
{
T mMin;
T mMax;
explicit Clamp(const T& min, const T& max)
: mMin(min)
, mMax(max)
{
}
T apply(const T& value) const override { return std::clamp(value, mMin, mMax); }
};
template <class T>
auto getPrev(const T& value) -> std::enable_if_t<std::is_floating_point_v<T>, T>
{
assert(value > -std::numeric_limits<T>::max());
return std::nextafter(value, -std::numeric_limits<T>::max());
}
template <class T>
struct ClampStrictMax final : Sanitizer<T>
{
T mMin;
T mMax;
explicit ClampStrictMax(const T& min, const T& max)
: mMin(min)
, mMax(getPrev(max))
{
}
T apply(const T& value) const override { return std::clamp(value, mMin, mMax); }
};
template <class T>
struct Enum final : Sanitizer<T>
{
std::vector<T> mValues;
explicit Enum(std::initializer_list<T> value)
: mValues(std::make_move_iterator(value.begin()), std::make_move_iterator(value.end()))
{
}
T apply(const T& value) const override
{
if (std::find(mValues.begin(), mValues.end(), value) == mValues.end())
{
std::ostringstream message;
message << "Invalid enum value: " << value;
throw std::runtime_error(message.str());
}
return value;
}
};
template <class T>
struct EqualOrMax final : Sanitizer<T>
{
T mEqual;
T mMax;
explicit EqualOrMax(const T& equal, const T& max)
: mEqual(equal)
, mMax(max)
{
}
T apply(const T& value) const override
{
if (value == mEqual)
return value;
return std::max(value, mMax);
}
};
}
std::unique_ptr<Sanitizer<float>> makeMaxSanitizerFloat(float max)
{
return std::make_unique<Max<float>>(max);
}
std::unique_ptr<Sanitizer<int>> makeMaxSanitizerInt(int max)
{
return std::make_unique<Max<int>>(max);
}
std::unique_ptr<Sanitizer<std::size_t>> makeMaxSanitizerSize(std::size_t max)
{
return std::make_unique<Max<std::size_t>>(max);
}
std::unique_ptr<Sanitizer<std::uint64_t>> makeMaxSanitizerUInt64(std::uint64_t max)
{
return std::make_unique<Max<std::uint64_t>>(max);
}
std::unique_ptr<Sanitizer<float>> makeMaxStrictSanitizerFloat(float max)
{
return std::make_unique<MaxStrict<float>>(max);
}
std::unique_ptr<Sanitizer<osg::Vec3f>> makeMaxStrictSanitizerVec3f(const osg::Vec3f& max)
{
return std::make_unique<MaxStrict<osg::Vec3f>>(max);
}
std::unique_ptr<Sanitizer<float>> makeClampSanitizerFloat(float min, float max)
{
return std::make_unique<Clamp<float>>(min, max);
}
std::unique_ptr<Sanitizer<double>> makeClampSanitizerDouble(double min, double max)
{
return std::make_unique<Clamp<double>>(min, max);
}
std::unique_ptr<Sanitizer<int>> makeClampSanitizerInt(int min, int max)
{
return std::make_unique<Clamp<int>>(min, max);
}
std::unique_ptr<Sanitizer<float>> makeClampStrictMaxSanitizerFloat(float min, float max)
{
return std::make_unique<ClampStrictMax<float>>(min, max);
}
std::unique_ptr<Sanitizer<int>> makeEnumSanitizerInt(std::initializer_list<int> values)
{
return std::make_unique<Enum<int>>(values);
}
std::unique_ptr<Sanitizer<std::string>> makeEnumSanitizerString(std::initializer_list<std::string> values)
{
return std::make_unique<Enum<std::string>>(values);
}
std::unique_ptr<Sanitizer<float>> makeEqualOrMaxSanitizerFloat(float equal, float max)
{
return std::make_unique<EqualOrMax<float>>(equal, max);
}
}

@ -0,0 +1,42 @@
#ifndef OPENMW_COMPONENTS_SETTINGS_SANITIZERIMPL_H
#define OPENMW_COMPONENTS_SETTINGS_SANITIZERIMPL_H
#include "sanitizer.hpp"
#include <osg/Vec3f>
#include <initializer_list>
#include <memory>
#include <string>
#include <string_view>
namespace Settings
{
std::unique_ptr<Sanitizer<float>> makeMaxSanitizerFloat(float max);
std::unique_ptr<Sanitizer<int>> makeMaxSanitizerInt(int max);
std::unique_ptr<Sanitizer<std::size_t>> makeMaxSanitizerSize(std::size_t max);
std::unique_ptr<Sanitizer<std::uint64_t>> makeMaxSanitizerUInt64(std::uint64_t max);
std::unique_ptr<Sanitizer<float>> makeMaxStrictSanitizerFloat(float max);
std::unique_ptr<Sanitizer<osg::Vec3f>> makeMaxStrictSanitizerVec3f(const osg::Vec3f& max);
std::unique_ptr<Sanitizer<float>> makeClampSanitizerFloat(float min, float max);
std::unique_ptr<Sanitizer<double>> makeClampSanitizerDouble(double min, double max);
std::unique_ptr<Sanitizer<int>> makeClampSanitizerInt(int min, int max);
std::unique_ptr<Sanitizer<float>> makeClampStrictMaxSanitizerFloat(float min, float max);
std::unique_ptr<Sanitizer<int>> makeEnumSanitizerInt(std::initializer_list<int> values);
std::unique_ptr<Sanitizer<std::string>> makeEnumSanitizerString(std::initializer_list<std::string> values);
std::unique_ptr<Sanitizer<float>> makeEqualOrMaxSanitizerFloat(float equal, float max);
}
#endif

@ -1,5 +1,6 @@
#include "settings.hpp"
#include "parser.hpp"
#include "values.hpp"
#include <charconv>
#include <filesystem>
@ -79,11 +80,19 @@ namespace Settings
return doubleValue;
}
#endif
template <class T>
std::string serialize(const T& value)
{
std::ostringstream stream;
stream << value;
return stream.str();
}
}
CategorySettingValueMap Manager::mDefaultSettings = CategorySettingValueMap();
CategorySettingValueMap Manager::mUserSettings = CategorySettingValueMap();
CategorySettingVector Manager::mChangedSettings = CategorySettingVector();
std::set<std::pair<std::string_view, std::string_view>> Manager::sInitialized;
void Manager::clear()
{
@ -136,6 +145,12 @@ namespace Settings
if (std::filesystem::exists(settingspath))
parser.loadSettingsFile(settingspath, mUserSettings, false, false);
Settings::Values::init();
for (const auto& [key, value] : mDefaultSettings)
if (!sInitialized.contains(key))
throw std::runtime_error("Default setting [" + key.first + "] " + key.second + " is not initialized");
return settingspath;
}
@ -203,6 +218,21 @@ namespace Settings
return parseNumberFromSetting<size_t>(getString(setting, category), setting, category);
}
unsigned Manager::getUnsigned(std::string_view setting, std::string_view category)
{
return parseNumberFromSetting<unsigned>(getString(setting, category), setting, category);
}
unsigned long Manager::getUnsignedLong(std::string_view setting, std::string_view category)
{
return parseNumberFromSetting<unsigned long>(getString(setting, category), setting, category);
}
unsigned long long Manager::getUnsignedLongLong(std::string_view setting, std::string_view category)
{
return parseNumberFromSetting<unsigned long long>(getString(setting, category), setting, category);
}
bool Manager::getBool(std::string_view setting, std::string_view category)
{
const std::string& string = getString(setting, category);
@ -360,4 +390,59 @@ namespace Settings
}
}
void Manager::set(std::string_view setting, std::string_view category, int value)
{
setInt(setting, category, value);
}
void Manager::set(std::string_view setting, std::string_view category, unsigned value)
{
setString(setting, category, serialize(value));
}
void Manager::set(std::string_view setting, std::string_view category, unsigned long value)
{
setString(setting, category, serialize(value));
}
void Manager::set(std::string_view setting, std::string_view category, unsigned long long value)
{
setString(setting, category, serialize(value));
}
void Manager::set(std::string_view setting, std::string_view category, float value)
{
setFloat(setting, category, value);
}
void Manager::set(std::string_view setting, std::string_view category, double value)
{
setDouble(setting, category, value);
}
void Manager::set(std::string_view setting, std::string_view category, const std::string& value)
{
setString(setting, category, value);
}
void Manager::set(std::string_view setting, std::string_view category, bool value)
{
setBool(setting, category, value);
}
void Manager::set(std::string_view setting, std::string_view category, const osg::Vec2f& value)
{
setVector2(setting, category, value);
}
void Manager::set(std::string_view setting, std::string_view category, const osg::Vec3f& value)
{
setVector3(setting, category, value);
}
void Manager::recordInit(std::string_view setting, std::string_view category)
{
sInitialized.emplace(category, setting);
}
}

@ -3,6 +3,7 @@
#include "categories.hpp"
#include <set>
#include <string>
#include <string_view>
#include <vector>
@ -61,6 +62,9 @@ namespace Settings
static int getInt(std::string_view setting, std::string_view category);
static std::uint64_t getUInt64(std::string_view setting, std::string_view category);
static std::size_t getSize(std::string_view setting, std::string_view category);
static unsigned getUnsigned(std::string_view setting, std::string_view category);
static unsigned long getUnsignedLong(std::string_view setting, std::string_view category);
static unsigned long long getUnsignedLongLong(std::string_view setting, std::string_view category);
static float getFloat(std::string_view setting, std::string_view category);
static double getDouble(std::string_view setting, std::string_view category);
static const std::string& getString(std::string_view setting, std::string_view category);
@ -69,6 +73,13 @@ namespace Settings
static osg::Vec2f getVector2(std::string_view setting, std::string_view category);
static osg::Vec3f getVector3(std::string_view setting, std::string_view category);
template <class T>
static T get(std::string_view setting, std::string_view category)
{
recordInit(setting, category);
return getImpl<T>(setting, category);
}
static void setInt(std::string_view setting, std::string_view category, int value);
static void setUInt64(std::string_view setting, std::string_view category, std::uint64_t value);
static void setFloat(std::string_view setting, std::string_view category, float value);
@ -79,8 +90,86 @@ namespace Settings
static void setBool(std::string_view setting, std::string_view category, bool value);
static void setVector2(std::string_view setting, std::string_view category, osg::Vec2f value);
static void setVector3(std::string_view setting, std::string_view category, osg::Vec3f value);
static void set(std::string_view setting, std::string_view category, int value);
static void set(std::string_view setting, std::string_view category, unsigned value);
static void set(std::string_view setting, std::string_view category, unsigned long value);
static void set(std::string_view setting, std::string_view category, unsigned long long value);
static void set(std::string_view setting, std::string_view category, float value);
static void set(std::string_view setting, std::string_view category, double value);
static void set(std::string_view setting, std::string_view category, const std::string& value);
static void set(std::string_view setting, std::string_view category, bool value);
static void set(std::string_view setting, std::string_view category, const osg::Vec2f& value);
static void set(std::string_view setting, std::string_view category, const osg::Vec3f& value);
private:
static std::set<std::pair<std::string_view, std::string_view>> sInitialized;
template <class T>
static T getImpl(std::string_view setting, std::string_view category);
static void recordInit(std::string_view setting, std::string_view category);
};
template <>
inline int Manager::getImpl<int>(std::string_view setting, std::string_view category)
{
return getInt(setting, category);
}
template <>
inline unsigned Manager::getImpl<unsigned>(std::string_view setting, std::string_view category)
{
return getUnsigned(setting, category);
}
template <>
inline unsigned long Manager::getImpl<unsigned long>(std::string_view setting, std::string_view category)
{
return getUnsignedLong(setting, category);
}
template <>
inline unsigned long long Manager::getImpl<unsigned long long>(std::string_view setting, std::string_view category)
{
return getUnsignedLongLong(setting, category);
}
template <>
inline float Manager::getImpl<float>(std::string_view setting, std::string_view category)
{
return getFloat(setting, category);
}
template <>
inline double Manager::getImpl<double>(std::string_view setting, std::string_view category)
{
return getDouble(setting, category);
}
template <>
inline std::string Manager::getImpl<std::string>(std::string_view setting, std::string_view category)
{
return getString(setting, category);
}
template <>
inline bool Manager::getImpl<bool>(std::string_view setting, std::string_view category)
{
return getBool(setting, category);
}
template <>
inline osg::Vec2f Manager::getImpl<osg::Vec2f>(std::string_view setting, std::string_view category)
{
return getVector2(setting, category);
}
template <>
inline osg::Vec3f Manager::getImpl<osg::Vec3f>(std::string_view setting, std::string_view category)
{
return getVector3(setting, category);
}
}
#endif // COMPONENTS_SETTINGS_H

@ -0,0 +1,70 @@
#ifndef OPENMW_COMPONENTS_SETTINGS_SETTINGVALUE_H
#define OPENMW_COMPONENTS_SETTINGS_SETTINGVALUE_H
#include "sanitizer.hpp"
#include "settings.hpp"
#include "components/debug/debuglog.hpp"
#include <osg/io_utils>
#include <memory>
#include <stdexcept>
#include <string_view>
namespace Settings
{
template <class T>
class SettingValue
{
public:
explicit SettingValue(
std::string_view category, std::string_view name, std::unique_ptr<const Sanitizer<T>>&& sanitizer = nullptr)
: mCategory(category)
, mName(name)
, mSanitizer(std::move(sanitizer))
, mValue(sanitize(Settings::Manager::get<T>(name, category)))
{
}
const T& get() const { return mValue; }
operator const T&() const { return mValue; }
void set(const T& value)
{
if (mValue == value)
return;
mValue = sanitize(value);
Settings::Manager::set(mName, mCategory, mValue);
}
private:
const std::string_view mCategory;
const std::string_view mName;
const std::unique_ptr<const Sanitizer<T>> mSanitizer;
T mValue{};
T sanitize(const T& value) const
{
if (mSanitizer == nullptr)
return value;
try
{
T sanitizedValue = mSanitizer->apply(value);
if (sanitizedValue != value)
Log(Debug::Warning) << "Setting [" << mCategory << "] " << mName
<< " value is out of allowed values set: " << value << ", sanitized to "
<< sanitizedValue;
return sanitizedValue;
}
catch (const std::exception& e)
{
throw std::runtime_error("Invalid setting [" + std::string(mCategory) + "] " + std::string(mName)
+ " value: " + std::string(e.what()));
}
}
};
}
#endif

@ -0,0 +1,12 @@
#include "values.hpp"
namespace Settings
{
Values* Values::sValues = nullptr;
void Values::init()
{
static Values values;
Values::sValues = &values;
}
}

@ -0,0 +1,201 @@
#ifndef OPENMW_COMPONENTS_SETTINGS_VALUES_H
#define OPENMW_COMPONENTS_SETTINGS_VALUES_H
#include "categories/camera.hpp"
#include "categories/cells.hpp"
#include "categories/fog.hpp"
#include "categories/game.hpp"
#include "categories/general.hpp"
#include "categories/groundcover.hpp"
#include "categories/gui.hpp"
#include "categories/hud.hpp"
#include "categories/input.hpp"
#include "categories/lua.hpp"
#include "categories/map.hpp"
#include "categories/models.hpp"
#include "categories/navigator.hpp"
#include "categories/physics.hpp"
#include "categories/postprocessing.hpp"
#include "categories/saves.hpp"
#include "categories/shaders.hpp"
#include "categories/shadows.hpp"
#include "categories/sound.hpp"
#include "categories/stereo.hpp"
#include "categories/stereoview.hpp"
#include "categories/terrain.hpp"
#include "categories/video.hpp"
#include "categories/water.hpp"
#include "categories/windows.hpp"
namespace Settings
{
class Values
{
public:
CameraCategory mCamera;
CellsCategory mCells;
TerrainCategory mTerrain;
FogCategory mFog;
MapCategory mMap;
GUICategory mGUI;
HUDCategory mHUD;
GameCategory mGame;
GeneralCategory mGeneral;
ShadersCategory mShaders;
InputCategory mInput;
SavesCategory mSaves;
SoundCategory mSound;
VideoCategory mVideo;
WaterCategory mWater;
WindowsCategory mWindows;
NavigatorCategory mNavigator;
ShadowsCategory mShadows;
PhysicsCategory mPhysics;
ModelsCategory mModels;
GroundcoverCategory mGroundcover;
LuaCategory mLua;
StereoCategory mStereo;
StereoViewCategory mStereoView;
PostProcessingCategory mPostProcessing;
static void init();
private:
static Values* sValues;
friend Values& values();
};
inline Values& values()
{
return *Values::sValues;
}
inline CameraCategory& camera()
{
return values().mCamera;
}
inline CellsCategory& cells()
{
return values().mCells;
}
inline TerrainCategory& terrain()
{
return values().mTerrain;
}
inline FogCategory& fog()
{
return values().mFog;
}
inline MapCategory& map()
{
return values().mMap;
}
inline GUICategory& gui()
{
return values().mGUI;
}
inline HUDCategory& hud()
{
return values().mHUD;
}
inline GameCategory& game()
{
return values().mGame;
}
inline GeneralCategory& general()
{
return values().mGeneral;
}
inline ShadersCategory& shaders()
{
return values().mShaders;
}
inline InputCategory& input()
{
return values().mInput;
}
inline SavesCategory& saves()
{
return values().mSaves;
}
inline SoundCategory& sound()
{
return values().mSound;
}
inline VideoCategory& video()
{
return values().mVideo;
}
inline WaterCategory& water()
{
return values().mWater;
}
inline WindowsCategory& windows()
{
return values().mWindows;
}
inline NavigatorCategory& navigator()
{
return values().mNavigator;
}
inline ShadowsCategory& shadows()
{
return values().mShadows;
}
inline PhysicsCategory& physics()
{
return values().mPhysics;
}
inline ModelsCategory& models()
{
return values().mModels;
}
inline GroundcoverCategory& groundcover()
{
return values().mGroundcover;
}
inline LuaCategory& lua()
{
return values().mLua;
}
inline StereoCategory& stereo()
{
return values().mStereo;
}
inline StereoViewCategory& stereoView()
{
return values().mStereoView;
}
inline PostProcessingCategory& postProcessing()
{
return values().mPostProcessing;
}
}
#endif
Loading…
Cancel
Save