diff --git a/UnrealProject/Lost_Edge/Content/UI/Blueprints/MainMenu/Pages/UI_MainMenu_Page_Options_Graphics.uasset b/UnrealProject/Lost_Edge/Content/UI/Blueprints/MainMenu/Pages/UI_MainMenu_Page_Options_Graphics.uasset index 59edf43..5951c6e 100644 --- a/UnrealProject/Lost_Edge/Content/UI/Blueprints/MainMenu/Pages/UI_MainMenu_Page_Options_Graphics.uasset +++ b/UnrealProject/Lost_Edge/Content/UI/Blueprints/MainMenu/Pages/UI_MainMenu_Page_Options_Graphics.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:31d5dd2e622a24b851d2c788ee3164050a17bd7d5c3a442b2a5e8ef28a652f34 -size 467247 +oid sha256:1370ea26a0c7ea1bbccf45fb4ac9a0a153717bfb0a179bf00489bed808003463 +size 504314 diff --git a/UnrealProject/Lost_Edge/Content/UI/Blueprints/Overlays/UI_Crosshair.uasset b/UnrealProject/Lost_Edge/Content/UI/Blueprints/Overlays/UI_Crosshair.uasset index 1e9e34e..0b0572d 100644 --- a/UnrealProject/Lost_Edge/Content/UI/Blueprints/Overlays/UI_Crosshair.uasset +++ b/UnrealProject/Lost_Edge/Content/UI/Blueprints/Overlays/UI_Crosshair.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b76ba0b71b0575036ef253825438018704801044c797a3126457c0a460f0774f -size 19560 +oid sha256:a7e352bf1da05d8f649d6dbb14b48e032dc24d1552750ecef59631323116b6fb +size 35727 diff --git a/UnrealProject/Lost_Edge/Content/UI/Blueprints/Overlays/UI_FpsCounter.uasset b/UnrealProject/Lost_Edge/Content/UI/Blueprints/Overlays/UI_FpsCounter.uasset index 4342a86..c7e38a9 100644 --- a/UnrealProject/Lost_Edge/Content/UI/Blueprints/Overlays/UI_FpsCounter.uasset +++ b/UnrealProject/Lost_Edge/Content/UI/Blueprints/Overlays/UI_FpsCounter.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c1d7d98d00913061d4729b0b1729a41168c7f1d45a4db8a80f38f8da8e1df9a6 -size 65918 +oid sha256:381abf297a22fb9eec4a60fc2608ded184bf3bb1c1d472b0889c58be3c618176 +size 75328 diff --git a/UnrealProject/Lost_Edge/Content/UI/Blueprints/UI_Journal.uasset b/UnrealProject/Lost_Edge/Content/UI/Blueprints/UI_Journal.uasset index 87d4172..340bf04 100644 --- a/UnrealProject/Lost_Edge/Content/UI/Blueprints/UI_Journal.uasset +++ b/UnrealProject/Lost_Edge/Content/UI/Blueprints/UI_Journal.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:40e75b054818801dce5da576f15396b6be2d27652f85a0f6eb3caafc73c492aa -size 40261 +oid sha256:0df779105a105e7f3a925f65f7e0295b8923617945cb44f3c84d25e490f115b4 +size 57000 diff --git a/UnrealProject/Lost_Edge/Content/UI/Components/UIC_ComboBox.uasset b/UnrealProject/Lost_Edge/Content/UI/Components/UIC_ComboBox.uasset index 4a8e116..c344965 100644 --- a/UnrealProject/Lost_Edge/Content/UI/Components/UIC_ComboBox.uasset +++ b/UnrealProject/Lost_Edge/Content/UI/Components/UIC_ComboBox.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:02a28e25e2216167070a987227c8cdd92cad3c4fa320d804a229f08f5b4cf832 -size 182229 +oid sha256:2b197def108a975d2b7ad81bfe618f246e50c1a9244aef38c5faace6223f6815 +size 203891 diff --git a/UnrealProject/Lost_Edge/Source/Lost_Edge/Private/CommonFunctions.h b/UnrealProject/Lost_Edge/Source/Lost_Edge/Private/CommonFunctions.h index 5d04150..431a51e 100644 --- a/UnrealProject/Lost_Edge/Source/Lost_Edge/Private/CommonFunctions.h +++ b/UnrealProject/Lost_Edge/Source/Lost_Edge/Private/CommonFunctions.h @@ -117,7 +117,9 @@ public: static TArray GetRandomIntArray(int32 size = 16, int32 min = 0, int32 max = 16); template - static TArray ArrayDiff(const TArray& a, const TArray& b); + static TArray ArraySymmetricDiff(const TArray& a, const TArray& b); + template + static TArray ArrayIntersection(const TArray& a, const TArray& b); template static void ArrayRemoveFirstFromEnd(TArray& array, T element); @@ -134,15 +136,15 @@ namespace SlowMotion } template -inline TArray UCommonFunctions::ArrayDiff(const TArray& a, const TArray& b) +inline TArray UCommonFunctions::ArraySymmetricDiff(const TArray& a, const TArray& b) { - TSet result; - if(a.Num() == 0) return b; else if(b.Num() == 0) return a; + TSet result; + for(auto& i : a) if(!b.Contains(i)) result.Add(i); @@ -154,6 +156,32 @@ inline TArray UCommonFunctions::ArrayDiff(const TArray& a, const TArray return result.Array(); } +template +inline TArray UCommonFunctions::ArrayIntersection(const TArray& a, const TArray& b) +{ + if(a.Num() == 0) + return {}; + else if(b.Num() == 0) + return {}; + + TSet result; + + if(a.Num() < b.Num()) + { + for(auto& i : a) + if(b.Contains(i)) + result.Add(i); + } + else + { + for(auto& i : b) + if(a.Contains(i)) + result.Add(i); + } + + return result.Array(); +} + template inline void UCommonFunctions::ArrayRemoveFirstFromEnd(TArray& array, T element) { diff --git a/UnrealProject/Lost_Edge/Source/Lost_Edge/Private/GraphicsSettingsHelper.cpp b/UnrealProject/Lost_Edge/Source/Lost_Edge/Private/GraphicsSettingsHelper.cpp index 082f62c..bc7223c 100644 --- a/UnrealProject/Lost_Edge/Source/Lost_Edge/Private/GraphicsSettingsHelper.cpp +++ b/UnrealProject/Lost_Edge/Source/Lost_Edge/Private/GraphicsSettingsHelper.cpp @@ -8,10 +8,14 @@ #include "CommonTexts.h" #include "CustomGameSettings.h" +#include #include namespace { + // some 16:9 resolutions (eg. 1366x768) are nonmathematical bullshit, therefore we try parse them with tolerance + constexpr float aspectRatioTolerance = 0.01f; + const FIntPoint ipDefaultWindowPosition = { 0, 0 }; std::optional ipPreviousWindowPosition; constexpr int32 iDefaultMonitorId = 0; @@ -19,7 +23,7 @@ namespace std::optional ipPreviousResolution; constexpr float fDefaultResolutionScale = 100.0f; constexpr int32 iDefaultFrameRateLimit = 120; - constexpr EDisplayMode eDefaultDisplayMode = EDisplayMode::Fullscreen; + constexpr EDisplayMode eDefaultDisplayMode = EDisplayMode::Borderless; std::optional ePreviousDisplayMode; constexpr bool bDefaultVSyncEnabled = false; constexpr int32 eDefaultAntiAliasingMethod = static_cast(ELostEdgeAntiAliasingMethod::FXAA); @@ -54,7 +58,7 @@ void UGraphicsSettingsHelper::SetDefaults(UCustomGameSettings* settings) settings->ResolutionSizeX = res.X; settings->ResolutionSizeY = res.Y; } - settings->bUseDynamicResolution = true; + settings->SetDynamicResolutionEnabled(true); settings->FrameRateLimit = GetDefaultFrameRateLimit(settings); settings->SetResolutionScaleValueEx(fDefaultResolutionScale); settings->FullscreenMode = DisplayToWindowMode(GetDefaultDisplayMode(settings)); @@ -66,6 +70,7 @@ void UGraphicsSettingsHelper::ApplySettings(UCustomGameSettings* settings) if(!settings) return; + CenterWindowPosition(settings); if(GEngine && GEngine->GameViewport) if(auto window = GEngine->GameViewport->GetWindow()) window->MoveWindowTo(settings->GetWindowPosition()); @@ -94,15 +99,41 @@ FIntPoint UGraphicsSettingsHelper::GetWindowPosition([[maybe_unused]] UCustomGam void UGraphicsSettingsHelper::SetWindowPosition(UCustomGameSettings* settings, const FIntPoint& pos) { - if(settings) - { - if(ipPreviousWindowPosition == pos) - ipPreviousWindowPosition.reset(); - else - ipPreviousWindowPosition = GetWindowPosition(settings); + if(!settings) + return; - settings->SetWindowPosition(pos.X, pos.Y); + if(ipPreviousWindowPosition == pos) + ipPreviousWindowPosition.reset(); + else + ipPreviousWindowPosition = GetWindowPosition(settings); + + settings->SetWindowPosition(std::max(0, pos.X), std::max(0, pos.Y)); +} + +void UGraphicsSettingsHelper::CenterWindowPosition(UCustomGameSettings* settings) +{ + if(!settings) + return; + + FIntPoint position; + if(GetDisplayMode(settings) == EDisplayMode::Fullscreen) + { + position = { 0, 0 }; } + else + { + auto monitors = GetAvailableMonitors(); + int32 monitorId = GetMonitorId(settings); + int32 offset = 0.0f; + for(int32 i = 0; i < monitorId; ++i) + offset += monitors[i].NativeWidth; + + FIntPoint monitor = GetNativeResolutionByMonitorId(monitorId); + FIntPoint window = GetResolution(settings); + position = { offset + (monitor.X - window.X) / 2, (monitor.Y - window.Y) / 2 }; + } + + SetWindowPosition(settings, position); } void UGraphicsSettingsHelper::RestoreWindowPosition(UCustomGameSettings* settings) @@ -278,6 +309,10 @@ TArray UGraphicsSettingsHelper::GetAllAvailableResolutions() TArray UGraphicsSettingsHelper::GetAvailableResolutionsByMonitorId(const int32 id) { + if(auto settings = UCustomGameSettings::Get()) + if(GetDisplayMode(settings) == EDisplayMode::Fullscreen) + return { GetNativeResolutionByMonitorId(GetMonitorId(settings)) }; + auto resolutions = GetAllAvailableResolutions(); FIntPoint nativeRes = GetNativeResolutionByMonitorId(id); TArray result; @@ -306,13 +341,37 @@ TArray UGraphicsSettingsHelper::FilterResolutionsViaAspectRatio(const { float resRatio = static_cast(i.X) / i.Y; float aspRatio = static_cast(aspectRatio.X) / aspectRatio.Y; - if(UCommonFunctions::FloatIsZero(resRatio - aspRatio)) + if(std::abs(resRatio - aspRatio) < aspectRatioTolerance) result.Add(i); } return MoveTemp(result); } +FIntPoint UGraphicsSettingsHelper::FilterClosestResolution(const TArray& resolutions, const FIntPoint& target) +{ + if(resolutions.IsEmpty() || target.X == 0) + return {}; + + int32 resultId = 0; + float coefficient = resolutions[resultId].X / (float)target.X; + if(UCommonFunctions::FloatIsZero(coefficient - 1)) + return resultId; + + for(int32 i = 1; i < resolutions.Num(); ++i) + { + float c = resolutions[i].X / (float)target.X; + if((coefficient > 1 && c < coefficient) + || (coefficient < 1 && c > coefficient && c < 1)) + { + coefficient = c; + resultId = i; + } + } + + return resolutions[resultId]; +} + void UGraphicsSettingsHelper::SetResolution(UCustomGameSettings* settings, const FIntPoint& resolution) { if(!settings) @@ -382,6 +441,9 @@ FIntPoint UGraphicsSettingsHelper::GetAspectRatio([[maybe_unused]] UCustomGameSe FIntPoint UGraphicsSettingsHelper::GetAspectRatioFromResolution(const FIntPoint& resolution) { + if(std::abs(resolution.X / (float)resolution.Y - 16 / 9.0f) < aspectRatioTolerance) + return { 16, 9 }; + int32 gcd = UCommonFunctions::GreatestCommonDivisor(resolution.X, resolution.Y); return { resolution.X / gcd, resolution.Y / gcd }; } @@ -393,6 +455,10 @@ FIntPoint UGraphicsSettingsHelper::GetAspectRatioOfMonitor(const int32 monitor) TArray UGraphicsSettingsHelper::GetAvailableAspectRatiousOfMonitor(const int32 monitor) { + if(auto settings = UCustomGameSettings::Get()) + if(GetMonitorId(settings) == monitor && GetDisplayMode(settings) == EDisplayMode::Fullscreen) + return { GetAspectRatioFromResolution(GetNativeResolutionByMonitorId(monitor)) }; + TArray resolutions = GetAvailableResolutionsByMonitorId(monitor); if(resolutions.Num() == 0) return { GetAspectRatio(nullptr) }; diff --git a/UnrealProject/Lost_Edge/Source/Lost_Edge/Private/GraphicsSettingsHelper.h b/UnrealProject/Lost_Edge/Source/Lost_Edge/Private/GraphicsSettingsHelper.h index 95fa48e..d4a5a8d 100644 --- a/UnrealProject/Lost_Edge/Source/Lost_Edge/Private/GraphicsSettingsHelper.h +++ b/UnrealProject/Lost_Edge/Source/Lost_Edge/Private/GraphicsSettingsHelper.h @@ -65,6 +65,8 @@ protected: // Window position setting is on the thin edge of user safeness, ther UFUNCTION(BlueprintCallable, Category = "Settings|Graphics|Window") static void SetWindowPosition(class UCustomGameSettings* settings, const FIntPoint& pos); UFUNCTION(BlueprintCallable, Category = "Settings|Graphics|Window") + static void CenterWindowPosition(class UCustomGameSettings* settings); + UFUNCTION(BlueprintCallable, Category = "Settings|Graphics|Window") static void RestoreWindowPosition(class UCustomGameSettings* settings); public: @@ -96,6 +98,8 @@ public: static TArray GetAvailableResolutionsByMonitorId(const int32 id); UFUNCTION(BlueprintPure, Category = "Settings|Graphics|Resolution") static TArray FilterResolutionsViaAspectRatio(const TArray& resolutions, const FIntPoint& aspectRatio); + UFUNCTION(BlueprintPure, Category = "Settings|Graphics|Resolution") + static FIntPoint FilterClosestResolution(const TArray& resolutions, const FIntPoint& target); UFUNCTION(BlueprintCallable, Category = "Settings|Graphics|Resolution") static void SetResolution(class UCustomGameSettings* settings, const FIntPoint& resolution); UFUNCTION(BlueprintCallable, Category = "Settings|Graphics|Resolution")