diff --git a/client/gui/CGuiHandler.cpp b/client/gui/CGuiHandler.cpp index ebacdc1b4..6608ca44d 100644 --- a/client/gui/CGuiHandler.cpp +++ b/client/gui/CGuiHandler.cpp @@ -250,8 +250,8 @@ void CGuiHandler::setStatusbar(std::shared_ptr newStatusBar) void CGuiHandler::onScreenResize(bool resolutionChanged) { if(resolutionChanged) - { screenHandler().onScreenResize(); - } + windows().onScreenResize(); + CCS->curh->onScreenResize(); } diff --git a/client/gui/CursorHandler.cpp b/client/gui/CursorHandler.cpp index eaa8cfd98..fbc5922f8 100644 --- a/client/gui/CursorHandler.cpp +++ b/client/gui/CursorHandler.cpp @@ -312,3 +312,8 @@ void CursorHandler::changeCursor(Cursor::ShowType newShowType) break; } } + +void CursorHandler::onScreenResize() +{ + cursor->setImage(getCurrentImage(), getPivotOffset()); +} diff --git a/client/gui/CursorHandler.h b/client/gui/CursorHandler.h index 539c577bd..acaccaaa8 100644 --- a/client/gui/CursorHandler.h +++ b/client/gui/CursorHandler.h @@ -182,6 +182,7 @@ public: void hide(); void show(); + void onScreenResize(); /// change cursor's positions to (x, y) void cursorMove(const int & x, const int & y); diff --git a/client/render/IScreenHandler.h b/client/render/IScreenHandler.h index 32abf7711..f3b6d5eee 100644 --- a/client/render/IScreenHandler.h +++ b/client/render/IScreenHandler.h @@ -44,6 +44,8 @@ public: /// Dimensions of logical output. Can be different if scaling is used virtual Point getLogicalResolution() const = 0; + virtual int getInterfaceScalingPercentage() const = 0; + virtual int getScalingFactor() const = 0; /// Window has focus diff --git a/client/renderSDL/CursorHardware.cpp b/client/renderSDL/CursorHardware.cpp index cbcfaeac2..7c9daea4d 100644 --- a/client/renderSDL/CursorHardware.cpp +++ b/client/renderSDL/CursorHardware.cpp @@ -11,11 +11,14 @@ #include "StdInc.h" #include "CursorHardware.h" +#include "SDL_Extensions.h" + #include "../gui/CGuiHandler.h" #include "../render/IScreenHandler.h" #include "../render/Colors.h" #include "../render/IImage.h" -#include "SDL_Extensions.h" + +#include "../../lib/CConfigHandler.h" #include #include @@ -45,19 +48,28 @@ void CursorHardware::setVisible(bool on) void CursorHardware::setImage(std::shared_ptr image, const Point & pivotOffset) { - auto cursorSurface = CSDL_Ext::newSurface(image->dimensions() * GH.screenHandler().getScalingFactor()); + int videoScalingSettings = GH.screenHandler().getInterfaceScalingPercentage(); + float cursorScalingSettings = settings["video"]["cursorScalingFactor"].Float(); + int cursorScalingPercent = videoScalingSettings * cursorScalingSettings; + Point cursorDimensions = image->dimensions() * GH.screenHandler().getScalingFactor(); + Point cursorDimensionsScaled = image->dimensions() * cursorScalingPercent / 100; + Point pivotOffsetScaled = pivotOffset * cursorScalingPercent / 100 / GH.screenHandler().getScalingFactor(); + + auto cursorSurface = CSDL_Ext::newSurface(cursorDimensions); CSDL_Ext::fillSurface(cursorSurface, CSDL_Ext::toSDL(Colors::TRANSPARENCY)); image->draw(cursorSurface, Point(0,0)); + auto cursorSurfaceScaled = CSDL_Ext::scaleSurface(cursorSurface, cursorDimensionsScaled.x, cursorDimensionsScaled.y ); auto oldCursor = cursor; - cursor = SDL_CreateColorCursor(cursorSurface, pivotOffset.x, pivotOffset.y); + cursor = SDL_CreateColorCursor(cursorSurfaceScaled, pivotOffsetScaled.x, pivotOffsetScaled.y); if (!cursor) logGlobal->error("Failed to set cursor! SDL says %s", SDL_GetError()); SDL_FreeSurface(cursorSurface); + SDL_FreeSurface(cursorSurfaceScaled); GH.dispatchMainThread([this, oldCursor](){ SDL_SetCursor(cursor); diff --git a/client/renderSDL/ScreenHandler.cpp b/client/renderSDL/ScreenHandler.cpp index c8d99e6fa..7614335e8 100644 --- a/client/renderSDL/ScreenHandler.cpp +++ b/client/renderSDL/ScreenHandler.cpp @@ -84,19 +84,39 @@ Rect ScreenHandler::convertLogicalPointsToWindow(const Rect & input) const return result; } +int ScreenHandler::getInterfaceScalingPercentage() const +{ + auto [minimalScaling, maximalScaling] = getSupportedScalingRange(); + + int userScaling = settings["video"]["resolution"]["scaling"].Integer(); + + if (userScaling == 0) // autodetection + { +#ifdef VCMI_MOBILE + // for mobiles - stay at maximum scaling unless we have large screen + // might be better to check screen DPI / physical dimensions, but way more complex, and may result in different edge cases, e.g. chromebooks / tv's + int preferredMinimalScaling = 200; +#else + // for PC - avoid downscaling if possible + int preferredMinimalScaling = 100; +#endif + // prefer a little below maximum - to give space for extended UI + int preferredMaximalScaling = maximalScaling * 10 / 12; + userScaling = std::max(std::min(maximalScaling, preferredMinimalScaling), preferredMaximalScaling); + } + + int scaling = std::clamp(userScaling, minimalScaling, maximalScaling); + return scaling; +} + Point ScreenHandler::getPreferredLogicalResolution() const { Point renderResolution = getRenderResolution(); double reservedAreaWidth = settings["video"]["reservedWidth"].Float(); + + int scaling = getInterfaceScalingPercentage(); Point availableResolution = Point(renderResolution.x * (1 - reservedAreaWidth), renderResolution.y); - - auto [minimalScaling, maximalScaling] = getSupportedScalingRange(); - - int userScaling = settings["video"]["resolution"]["scaling"].Integer(); - int scaling = std::clamp(userScaling, minimalScaling, maximalScaling); - Point logicalResolution = availableResolution * 100.0 / scaling; - return logicalResolution; } @@ -335,25 +355,22 @@ EUpscalingFilter ScreenHandler::loadUpscalingFilter() const if (filter != EUpscalingFilter::AUTO) return filter; - // for now - always fallback to no filter - return EUpscalingFilter::NONE; - // else - autoselect -// Point outputResolution = getRenderResolution(); -// Point logicalResolution = getPreferredLogicalResolution(); -// -// float scaleX = static_cast(outputResolution.x) / logicalResolution.x; -// float scaleY = static_cast(outputResolution.x) / logicalResolution.x; -// float scaling = std::min(scaleX, scaleY); -// -// if (scaling <= 1.0f) -// return EUpscalingFilter::NONE; -// if (scaling <= 2.0f) -// return EUpscalingFilter::XBRZ_2; -// if (scaling <= 3.0f) -// return EUpscalingFilter::XBRZ_3; -// -// return EUpscalingFilter::XBRZ_4; + Point outputResolution = getRenderResolution(); + Point logicalResolution = getPreferredLogicalResolution(); + + float scaleX = static_cast(outputResolution.x) / logicalResolution.x; + float scaleY = static_cast(outputResolution.x) / logicalResolution.x; + float scaling = std::min(scaleX, scaleY); + + if (scaling <= 1.001f) + return EUpscalingFilter::NONE; // running at original resolution or even lower than that - no need for xbrz + if (scaling <= 2.001f) + return EUpscalingFilter::XBRZ_2; // resolutions below 1200p (including 1080p / FullHD) + if (scaling <= 3.001f) + return EUpscalingFilter::XBRZ_3; // resolutions below 2400p (including 1440p and 2160p / 4K) + + return EUpscalingFilter::XBRZ_4; // Only for massive displays, e.g. 8K } void ScreenHandler::selectUpscalingFilter() diff --git a/client/renderSDL/ScreenHandler.h b/client/renderSDL/ScreenHandler.h index e15958b55..6a9026d7b 100644 --- a/client/renderSDL/ScreenHandler.h +++ b/client/renderSDL/ScreenHandler.h @@ -112,6 +112,8 @@ public: int getScalingFactor() const final; + int getInterfaceScalingPercentage() const final; + std::vector getSupportedResolutions() const final; std::vector getSupportedResolutions(int displayIndex) const; std::tuple getSupportedScalingRange() const final; diff --git a/client/windows/settings/GeneralOptionsTab.cpp b/client/windows/settings/GeneralOptionsTab.cpp index d8ead20f8..6571a3422 100644 --- a/client/windows/settings/GeneralOptionsTab.cpp +++ b/client/windows/settings/GeneralOptionsTab.cpp @@ -194,10 +194,8 @@ GeneralOptionsTab::GeneralOptionsTab() build(config); - const auto & currentResolution = settings["video"]["resolution"]; - std::shared_ptr scalingLabel = widget("scalingLabel"); - scalingLabel->setText(scalingToLabelString(currentResolution["scaling"].Integer())); + scalingLabel->setText(scalingToLabelString(GH.screenHandler().getInterfaceScalingPercentage())); std::shared_ptr longTouchLabel = widget("longTouchLabel"); if (longTouchLabel) diff --git a/config/schemas/settings.json b/config/schemas/settings.json index 276903873..93ae2038f 100644 --- a/config/schemas/settings.json +++ b/config/schemas/settings.json @@ -184,6 +184,7 @@ "targetfps", "vsync", "fontsType", + "cursorScalingFactor", "fontScalingFactor", "upscalingFilter", "fontUpscalingFilter", @@ -195,22 +196,19 @@ "additionalProperties" : false, "required" : [ "width", "height", "scaling" ], "properties" : { - "width" : { "type" : "number" }, - "height" : { "type" : "number" }, - "scaling" : { "type" : "number" } - }, - "defaultIOS" : {"width" : 800, "height" : 600, "scaling" : 200 }, - "defaultAndroid" : {"width" : 800, "height" : 600, "scaling" : 200 }, - "default" : {"width" : 800, "height" : 600, "scaling" : 100 } + "width" : { "type" : "number", "default" : 1280 }, + "height" : { "type" : "number", "default" : 720 }, + "scaling" : { "type" : "number", "default" : 0 } + } }, "reservedWidth" : { "type" : "number", - "defaultIOS" : 0.1, // iOS camera cutout / notch is excluded from available area by SDL + "defaultIOS" : 0.1, // iOS camera cutout / notch is not excluded from available area by SDL, handle it this way "default" : 0 }, "fullscreen" : { "type" : "boolean", - "default" : false + "default" : true }, "realFullscreen" : { "type" : "boolean", @@ -256,6 +254,10 @@ "enum" : [ "auto", "original", "scalable" ], "default" : "auto" }, + "cursorScalingFactor" : { + "type" : "number", + "default" : 1 + }, "fontScalingFactor" : { "type" : "number", "default" : 1 diff --git a/launcher/settingsView/csettingsview_moc.cpp b/launcher/settingsView/csettingsview_moc.cpp index 91788e7b6..94ca8fc6c 100644 --- a/launcher/settingsView/csettingsview_moc.cpp +++ b/launcher/settingsView/csettingsview_moc.cpp @@ -127,7 +127,12 @@ void CSettingsView::loadSettings() #endif fillValidScalingRange(); - ui->spinBoxInterfaceScaling->setValue(settings["video"]["resolution"]["scaling"].Float()); + ui->buttonScalingAuto->setChecked(settings["video"]["resolution"]["scaling"].Integer() == 0); + if (settings["video"]["resolution"]["scaling"].Integer() == 0) + ui->spinBoxInterfaceScaling->setValue(100); + else + ui->spinBoxInterfaceScaling->setValue(settings["video"]["resolution"]["scaling"].Float()); + ui->spinBoxFramerateLimit->setValue(settings["video"]["targetfps"].Float()); ui->spinBoxFramerateLimit->setDisabled(settings["video"]["vsync"].Bool()); ui->sliderReservedArea->setValue(std::round(settings["video"]["reservedWidth"].Float() * 100)); @@ -174,6 +179,7 @@ void CSettingsView::loadSettings() ui->sliderControllerSticksAcceleration->setValue(settings["input"]["controllerAxisScale"].Float() * 100); ui->lineEditGameLobbyHost->setText(QString::fromStdString(settings["lobby"]["hostname"].String())); ui->spinBoxNetworkPortLobby->setValue(settings["lobby"]["port"].Integer()); + ui->buttonVSync->setChecked(settings["video"]["vsync"].Bool()); if (settings["video"]["fontsType"].String() == "auto") ui->buttonFontAuto->setChecked(true); @@ -195,7 +201,6 @@ void CSettingsView::loadSettings() void CSettingsView::loadToggleButtonSettings() { setCheckbuttonState(ui->buttonShowIntro, settings["video"]["showIntro"].Bool()); - setCheckbuttonState(ui->buttonVSync, settings["video"]["vsync"].Bool()); setCheckbuttonState(ui->buttonAutoCheck, settings["launcher"]["autoCheckRepositories"].Bool()); setCheckbuttonState(ui->buttonRepositoryDefault, settings["launcher"]["defaultRepositoryEnabled"].Bool()); @@ -212,10 +217,15 @@ void CSettingsView::loadToggleButtonSettings() std::string cursorType = settings["video"]["cursor"].String(); int cursorTypeIndex = vstd::find_pos(cursorTypesList, cursorType); setCheckbuttonState(ui->buttonCursorType, cursorTypeIndex); + ui->sliderScalingCursor->setDisabled(cursorType == "software"); // Not supported + ui->labelScalingCursorValue->setDisabled(cursorType == "software"); // Not supported int fontScalingPercentage = settings["video"]["fontScalingFactor"].Float() * 100; ui->sliderScalingFont->setValue(fontScalingPercentage / 5); + int cursorScalingPercentage = settings["video"]["cursorScalingFactor"].Float() * 100; + ui->sliderScalingCursor->setValue(cursorScalingPercentage / 5); + } void CSettingsView::fillValidResolutions() @@ -494,6 +504,8 @@ void CSettingsView::on_buttonCursorType_toggled(bool value) Settings node = settings.write["video"]["cursor"]; node->String() = cursorTypesList[value ? 1 : 0]; updateCheckbuttonText(ui->buttonCursorType); + ui->sliderScalingCursor->setDisabled(value == 1); // Not supported + ui->labelScalingCursorValue->setDisabled(value == 1); // Not supported } void CSettingsView::loadTranslation() @@ -627,7 +639,6 @@ void CSettingsView::on_buttonVSync_toggled(bool value) Settings node = settings.write["video"]["vsync"]; node->Bool() = value; ui->spinBoxFramerateLimit->setDisabled(settings["video"]["vsync"].Bool()); - updateCheckbuttonText(ui->buttonVSync); } void CSettingsView::on_comboBoxEnemyPlayerAI_currentTextChanged(const QString &arg1) @@ -816,3 +827,21 @@ void CSettingsView::on_buttonValidationFull_clicked(bool checked) Settings node = settings.write["mods"]["validation"]; node->String() = "full"; } + +void CSettingsView::on_sliderScalingCursor_valueChanged(int value) +{ + int actualValuePercentage = value * 5; + ui->labelScalingCursorValue->setText(QString("%1%").arg(actualValuePercentage)); + Settings node = settings.write["video"]["cursorScalingFactor"]; + node->Float() = actualValuePercentage / 100.0; +} + +void CSettingsView::on_buttonScalingAuto_toggled(bool checked) +{ + ui->spinBoxInterfaceScaling->setDisabled(checked); + ui->spinBoxInterfaceScaling->setValue(100); + + Settings node = settings.write["video"]["resolution"]["scaling"]; + node->Integer() = checked ? 0 : 100; +} + diff --git a/launcher/settingsView/csettingsview_moc.h b/launcher/settingsView/csettingsview_moc.h index 512762d0c..d05e7eb1e 100644 --- a/launcher/settingsView/csettingsview_moc.h +++ b/launcher/settingsView/csettingsview_moc.h @@ -97,6 +97,10 @@ private slots: void on_buttonValidationFull_clicked(bool checked); + void on_sliderScalingCursor_valueChanged(int value); + + void on_buttonScalingAuto_toggled(bool checked); + private: Ui::CSettingsView * ui; diff --git a/launcher/settingsView/csettingsview_moc.ui b/launcher/settingsView/csettingsview_moc.ui index c0082edd8..a974b5209 100644 --- a/launcher/settingsView/csettingsview_moc.ui +++ b/launcher/settingsView/csettingsview_moc.ui @@ -47,209 +47,119 @@ 0 - -800 + -126 729 - 1506 + 1503 - - + + + + + + 0 + 0 + + + + + + + true + + + + + + + Mods Validation + + + + + + + + Automatic + + + + + None + + + + + xBRZ x2 + + + + + xBRZ x3 + + + + + xBRZ x4 + + + + + + + + 500 + + + 2500 + + + 25 + + + 250 + + + 500 + + + Qt::Horizontal + + + QSlider::TicksAbove + + + 250 + + + + + + + Reset + + + + - - + + - 0 - - - 50 - - - 1 - - - 10 - - - 0 - - - Qt::Horizontal - - - QSlider::TicksAbove - - - 10 - - - - - - - Upscaling Filter - - - - - - - 100 - - 500 - - 10 - - - 100 - - - 100 - - - Qt::Horizontal - - - QSlider::TicksAbove - - - 50 - - - - - - - false - - - BattleAI - - - - BattleAI - - - - - StupidAI - - - - - - - - Additional repository - - - - - - - Ignore SSL errors - - - - - - - - Nearest - - - - - Linear - - - - - Automatic (Linear) - - - - - - - - VCMI Language - - - - - - - - 0 - 0 - - - - Automatic - - - true - - - true - - - buttonGroupFonts - - - - - - - - true - - - - Video - - - 5 - - - - - - - Show intro - - - - - - - Heroes III Translation - - - - - - - 0 - - 50 + 2000 - 1 + 250 - 10 - - - 0 + 250 Qt::Horizontal @@ -258,169 +168,11 @@ QSlider::TicksAbove - 10 + 250 - - - - - 0 - 0 - - - - Scalable - - - true - - - true - - - buttonGroupFonts - - - - - - - Touch Tap Tolerance - - - - - - - - - - - - - - 100 - - - Qt::Horizontal - - - QSlider::TicksAbove - - - 10 - - - - - - - - - - Renderer - - - - - - - - true - - - - Artificial Intelligence - - - 5 - - - - - - - Neutral AI in battles - - - - - - - VSync - - - - - - - Framerate Limit - - - - - - - empty = map name prefix - - - - - - - - true - - - - Input - Touchscreen - - - 5 - - - - - - - 0 - - - 50 - - - 1 - - - 10 - - - 0 - - - Qt::Horizontal - - - QSlider::TicksAbove - - - 10 - - - - - - - Relative Pointer Speed - - - - - - - + true @@ -442,8 +194,56 @@ - - + + + + Reserved screen area + + + + + + + + true + + + + General + + + 5 + + + + + + + Autosave + + + + + + + 100 + + + Qt::Horizontal + + + QSlider::TicksAbove + + + 10 + + + + + + + true + 0 @@ -456,26 +256,341 @@ true - - - - - - Long Touch Duration + + false - - - - - + + + + true + + + + 0 + 0 + + - Check on startup + Basic + + + true + + + false + + + buttonGroupValidation + + + + + + + Sound Volume - + + + + Haptic Feedback + + + + + + + Touch Tap Tolerance + + + + + + + + + + + + + 1024 + + + 65535 + + + 3030 + + + + + + + true + + + + 0 + 0 + + + + Full + + + true + + + false + + + buttonGroupValidation + + + + + + + + true + + + + Input - Controller + + + 5 + + + + + + + 10 + + + 30 + + + 1 + + + 2 + + + 20 + + + 20 + + + Qt::Horizontal + + + QSlider::TicksAbove + + + 2 + + + + + + + Software Cursor + + + + + + + VCAI + + + + VCAI + + + + + Nullkiller + + + + + + + + + + + true + + + + + + + VCAI + + + + VCAI + + + + + Nullkiller + + + + + + + + Heroes III Translation + + + + + + + + true + + + + Artificial Intelligence + + + 5 + + + + + + + Default repository + + + + + + + + + + % + + + 50 + + + 400 + + + 10 + + + + + + + Relative Pointer Speed + + + + + + + Downscaling Filter + + + + + + + true + + + + 0 + 0 + + + + + + + true + + + false + + + + + + + 1024 + + + 65535 + + + 3030 + + + + + + + Show intro + + + + + + + + 0 + 0 + + + + Automatic + + + true + + + true + + + buttonGroupFonts + + + + + + + 100 + + + Qt::Horizontal + + + QSlider::TicksAbove + + + 10 + + + + @@ -494,38 +609,28 @@ - - - - - true - - + + - Input - Controller - - - 5 + Refresh now - - - - - 0 - 0 - - + + - - - - true + Adventure Map Allies - + + + + Neutral AI in battles + + + + 10 @@ -556,14 +661,547 @@ - - + + - Downscaling Filter + - + + + + Display index + + + + + + + Use Relative Pointer Mode + + + + + + + + + + Autocombat AI in battles + + + + + + + true + + + + 0 + 0 + + + + Off + + + true + + + false + + + buttonGroupValidation + + + + + + + + true + + + + Input - Mouse + + + 5 + + + + + + + Network port + + + + + + + + 0 + 0 + + + + + + + true + + + + + + + + true + + + + Audio + + + 5 + + + + + + + Additional repository + + + + + + + + 0 + 0 + + + + VSync + + + true + + + + + + + Adventure Map Enemies + + + + + + + Framerate Limit + + + + + + + Use scalable fonts + + + + + + + Renderer + + + + + + + + true + + + + Input - Touchscreen + + + 5 + + + + + + + 25 + + + Qt::Horizontal + + + QSlider::TicksAbove + + + 5 + + + + + + + + + + + 0 + 0 + + + + + + + true + + + + + + + VCMI Language + + + + + + + Online Lobby address + + + + + + + Online Lobby port + + + + + + + Controller Click Tolerance + + + + + + + BattleAI + + + + BattleAI + + + + + StupidAI + + + + + + + + + Nearest + + + + + Linear + + + + + Automatic (Linear) + + + + + + + + Ignore SSL errors + + + + + + + + + + Show Tutorial again + + + + + + + Sticks Acceleration + + + + + + + + true + + + + Video + + + 5 + + + + + + + false + + + BattleAI + + + + BattleAI + + + + + StupidAI + + + + + + + + + + + + + + + Fullscreen + + + + + + + Mouse Click Tolerance + + + + + + + Enemy AI in battles + + + + + + + Autosave limit (0 = off) + + + + + + + 0 + + + 50 + + + 1 + + + 10 + + + 0 + + + Qt::Horizontal + + + QSlider::TicksAbove + + + 10 + + + + + + + Interface Scaling + + + + + + + Music Volume + + + + + + + false + + + BattleAI + + + + BattleAI + + + + + StupidAI + + + + + + + + + + + + + + + Cursor Scaling + + + + + + + + 0 + 0 + + + + + + + true + + + + + + + + 0 + 0 + + + + Scalable + + + true + + + true + + + buttonGroupFonts + + + + + + + + true + + + + Network + + + 5 + + + + + + + + true + + + + Miscellaneous + + + 5 + + + + + + + 100 + + + 500 + + + 10 + + + 100 + + + 100 + + + Qt::Horizontal + + + QSlider::TicksAbove + + + 50 + + + + Select display mode for game @@ -594,14 +1232,155 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use - - - - Use scalable fonts + + + + 20 + + + 1000 + + + 10 - + + + + Long Touch Duration + + + + + + + Check on startup + + + + + + + 0 + + + 50 + + + 1 + + + 10 + + + 0 + + + Qt::Horizontal + + + QSlider::TicksAbove + + + 10 + + + + + + + + 0 + 0 + + + + + + + true + + + + + + + 100 + + + 300 + + + Qt::Horizontal + + + QSlider::TicksAbove + + + 25 + + + + + + + Font Scaling (experimental) + + + + + + + + 0 + 0 + + + + + + + true + + + + + + + 0 + + + 50 + + + 1 + + + 10 + + + 0 + + + Qt::Horizontal + + + QSlider::TicksAbove + + + 10 + + + + + + + empty = map name prefix + + + + @@ -623,47 +1402,8 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use - - - - - - - - Automatic - - - - - None - - - - - xBRZ x2 - - - - - xBRZ x3 - - - - - xBRZ x4 - - - - - - - - Online Lobby port - - - - - + + 0 @@ -671,283 +1411,27 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use - + Automatic true - - - - VCAI - - - - VCAI - - - - - Nullkiller - - - - - - - - - true - - + + - Network - - - 5 + Sticks Sensitivity - - + + - Refresh now + Upscaling Filter - - - - 500 - - - 2500 - - - 25 - - - 250 - - - 500 - - - Qt::Horizontal - - - QSlider::TicksAbove - - - 250 - - - - - - - Display index - - - - - - - 500 - - - 2000 - - - 250 - - - 250 - - - Qt::Horizontal - - - QSlider::TicksAbove - - - 250 - - - - - - - false - - - BattleAI - - - - BattleAI - - - - - StupidAI - - - - - - - - Adventure Map Enemies - - - - - - - - - - true - - - - - - - Reset - - - - - - - Show Tutorial again - - - - - - - Fullscreen - - - - - - - Use Relative Pointer Mode - - - - - - - - - - - - - - Sticks Acceleration - - - - - - - Autosave limit (0 = off) - - - - - - - Mouse Click Tolerance - - - - - - - - true - - - - General - - - 5 - - - - - - - Online Lobby address - - - - - - - - 0 - 0 - - - - - - - true - - - - - - - Interface Scaling - - - - - - - Default repository - - - - - - - - 0 - 0 - - - - - - - true - - - - - - - Haptic Feedback - - - - - - @@ -955,449 +1439,15 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use - - - - - true - - - - Input - Mouse - - - 5 - - - - - - - 25 - - - Qt::Horizontal - - - QSlider::TicksAbove - - - 5 - - - - - - - 20 - - - 1000 - - - 10 - - - - - - - 1024 - - - 65535 - - - 3030 - - - - - - - 100 - - - 300 - - - Qt::Horizontal - - - QSlider::TicksAbove - - - 25 - - - - - - - Enemy AI in battles - - - - - - Reserved screen area - - - - - - - % - - - 50 - - - 400 - - - 10 - - - - - - - Music Volume - - - - - - - BattleAI - - - - BattleAI - - - - - StupidAI - - - - - - - - Autosave - - - - - - - 100 - - - Qt::Horizontal - - - QSlider::TicksAbove - - - 10 - - - - - - - Network port - - - - - - - true - - - - 0 - 0 - - - - - - - true - - - false - - - - Resolution - - - - - 0 - 0 - - - - - - - true - - - - - - - Sound Volume - - - - - - - Controller Click Tolerance - - - - - - - Adventure Map Allies - - - - - - - - true - - - - Miscellaneous - - - 5 - - - - - - - 1024 - - - 65535 - - - 3030 - - - - - - - VCAI - - - - VCAI - - - - - Nullkiller - - - - - - - - - true - - - - Audio - - - 5 - - - - - - - - 0 - 0 - - - - - - - true - - - - - - - Software Cursor - - - - - - - Autocombat AI in battles - - - - - - - - - - - - - - - - - true - - - - 0 - 0 - - - - - - - true - - - false - - - - - - - Font Scaling (experimental) - - - - - - - Sticks Sensitivity - - - - - - - Mods Validation - - - - - - - true - - - - 0 - 0 - - - - Off - - - true - - - false - - - buttonGroupValidation - - - - - - - true - - - - 0 - 0 - - - - Basic - - - true - - - false - - - buttonGroupValidation - - - - - - - true - - - - 0 - 0 - - - - Full - - - true - - - false - - - buttonGroupValidation - - + +