graphics settings

This commit is contained in:
Oleg Petruny 2025-01-12 23:49:42 +01:00
parent 509d2e9c98
commit 0176cc90de
29 changed files with 469 additions and 90 deletions

View File

@ -1,5 +1,4 @@
[/Script/Lost_Edge.CustomGameSettings] [/Script/Lost_Edge.CustomGameSettings]
bUseMotionBlur=False
bShowFps=False bShowFps=False
bMouseInverted=False bMouseInverted=False
fMouseSensetivity=1.000000 fMouseSensetivity=1.000000
@ -9,13 +8,13 @@ fEffectsVolume=1.000000
fVoicesVolume=1.000000 fVoicesVolume=1.000000
fMenuVolume=1.000000 fMenuVolume=1.000000
bUseVSync=False bUseVSync=False
bUseDynamicResolution=False bUseDynamicResolution=True
ResolutionSizeX=1920 ResolutionSizeX=1920
ResolutionSizeY=1080 ResolutionSizeY=1080
LastUserConfirmedResolutionSizeX=1920 LastUserConfirmedResolutionSizeX=1920
LastUserConfirmedResolutionSizeY=1080 LastUserConfirmedResolutionSizeY=1080
WindowPosX=-1 WindowPosX=0
WindowPosY=-1 WindowPosY=0
FullscreenMode=1 FullscreenMode=1
LastConfirmedFullscreenMode=1 LastConfirmedFullscreenMode=1
PreferredFullscreenMode=1 PreferredFullscreenMode=1
@ -23,10 +22,10 @@ Version=5
AudioQualityLevel=0 AudioQualityLevel=0
LastConfirmedAudioQualityLevel=0 LastConfirmedAudioQualityLevel=0
FrameRateLimit=0.000000 FrameRateLimit=0.000000
DesiredScreenWidth=1280 DesiredScreenWidth=1920
DesiredScreenHeight=720 DesiredScreenHeight=1080
LastUserConfirmedDesiredScreenWidth=1280 LastUserConfirmedDesiredScreenWidth=1920
LastUserConfirmedDesiredScreenHeight=720 LastUserConfirmedDesiredScreenHeight=1080
LastRecommendedScreenWidth=-1.000000 LastRecommendedScreenWidth=-1.000000
LastRecommendedScreenHeight=-1.000000 LastRecommendedScreenHeight=-1.000000
LastCPUBenchmarkResult=-1.000000 LastCPUBenchmarkResult=-1.000000

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -105,15 +105,33 @@ FWorldDilationChangedDelegate& UCommonFunctions::GetWorldDilationChangedDelegate
return SlowMotion::worldDilationChangedDelegate; return SlowMotion::worldDilationChangedDelegate;
} }
TArray<FString> UCommonFunctions::IntArrayToStringArray(const TArray<int32>& in)
{
TArray<FString> result;
result.Reserve(in.Num());
for(int32 i : in)
result.Add(FString::FromInt(i));
return MoveTemp(result);
}
TArray<int32> UCommonFunctions::StringArrayToIntArray(const TArray<FString>& in)
{
TArray<int32> result;
result.Reserve(in.Num());
for(auto& i : in)
result.Add(FCString::Atoi(*i));
return MoveTemp(result);
}
FString UCommonFunctions::IntPointToString(const FIntPoint& in) FString UCommonFunctions::IntPointToString(const FIntPoint& in)
{ {
FString result = FString::Printf(TEXT("%sx%s"), *FString::FromInt(in.X), *FString::FromInt(in.Y)); FString result = FString::Printf(TEXT("%dx%d"), in.X, in.Y);
return MoveTemp(result); return MoveTemp(result);
} }
FIntPoint UCommonFunctions::StringToIntPoint(const FString& in) FIntPoint UCommonFunctions::StringToIntPoint(const FString& in)
{ {
FIntPoint result; FIntPoint result{};
const FRegexPattern rgxP(FRegexPattern(TEXT("[0-9]+"))); const FRegexPattern rgxP(FRegexPattern(TEXT("[0-9]+")));
FRegexMatcher rgx = FRegexMatcher(rgxP, in); FRegexMatcher rgx = FRegexMatcher(rgxP, in);
@ -125,6 +143,41 @@ FIntPoint UCommonFunctions::StringToIntPoint(const FString& in)
return MoveTemp(result); return MoveTemp(result);
} }
TArray<FString> UCommonFunctions::IntPointArrayToStringArray(const TArray<FIntPoint>& in)
{
TArray<FString> result;
result.Reserve(in.Num());
for(auto& i : in)
result.Add(IntPointToString(i));
return MoveTemp(result);
}
TArray<FIntPoint> UCommonFunctions::StringArrayToIntPointArray(const TArray<FString>& in)
{
TArray<FIntPoint> result;
result.Reserve(in.Num());
for(auto& i : in)
result.Add(StringToIntPoint(i));
return MoveTemp(result);
}
int32 UCommonFunctions::GetLongestCharCount(TArray<FString>& in)
{
int32 result = 0;
for(auto& i : in)
if(i.Len() > result)
result = i.Len();
return result;
}
void UCommonFunctions::SortIntPointArray(TArray<FIntPoint>& in)
{
in.Sort([](const FIntPoint& a, const FIntPoint& b)
{
return a.X < b.X || a.Y < b.Y;
});
}
int32 UCommonFunctions::GreatestCommonDivisor(int32 a, int32 b) int32 UCommonFunctions::GreatestCommonDivisor(int32 a, int32 b)
{ {
int32 temp; int32 temp;

View File

@ -44,10 +44,26 @@ public:
UFUNCTION(BlueprintPure, Category = TypeCasts)
static TArray<FString> IntArrayToStringArray(const TArray<int32>& in);
UFUNCTION(BlueprintPure, Category = TypeCasts)
static TArray<int32> StringArrayToIntArray(const TArray<FString>& in);
UFUNCTION(BlueprintPure, Category = TypeCasts) UFUNCTION(BlueprintPure, Category = TypeCasts)
static FString IntPointToString(const FIntPoint& in); static FString IntPointToString(const FIntPoint& in);
UFUNCTION(BlueprintPure, Category = TypeCasts) UFUNCTION(BlueprintPure, Category = TypeCasts)
static FIntPoint StringToIntPoint(const FString& in); static FIntPoint StringToIntPoint(const FString& in);
UFUNCTION(BlueprintPure, Category = TypeCasts)
static TArray<FString> IntPointArrayToStringArray(const TArray<FIntPoint>& in);
UFUNCTION(BlueprintPure, Category = TypeCasts)
static TArray<FIntPoint> StringArrayToIntPointArray(const TArray<FString>& in);
UFUNCTION(BlueprintPure, Category = TypeCasts)
static void SortIntPointArray(UPARAM(ref) TArray<FIntPoint>& in);
UFUNCTION(BlueprintPure, Category = String)
static int32 GetLongestCharCount(UPARAM(ref) TArray<FString>& in);

View File

@ -0,0 +1,63 @@
// Oleg Petruny proprietary.
#include "CommonInspectors.h"
UEnum* UEnumInspector::GetEnumByName(const FString& name)
{
static TMap<FString, UEnum*> map;
if(map.Contains(name))
return map[name];
UEnum* enumPtr = FindObject<UEnum>((UPackage*)-1, *name, true);
map.Add(name, enumPtr);
return enumPtr;
}
TArray<FText> UEnumInspector::GetEnumDisplayNames(const UEnum* enumPtr)
{
if(!enumPtr)
return {};
auto enumPtrProxy = static_cast<const UDEPRECATED_EnumInspectorProxy*>(enumPtr);
TArray<FText> result;
for(int32 i = 0; i < enumPtrProxy->Names.Num() - 1; ++i) // last UEnum value is Num counter
result.Add(enumPtr->GetDisplayNameTextByIndex(enumPtrProxy->Names[i].Value));
return MoveTemp(result);
}
TArray<uint8> UEnumInspector::GetEnumValues(const UEnum* enumPtr)
{
if(!enumPtr)
return {};
auto enumPtrProxy = static_cast<const UDEPRECATED_EnumInspectorProxy*>(enumPtr);
TArray<uint8> result;
for(int32 i = 0; i < enumPtrProxy->Names.Num() - 1; ++i) // last UEnum value is Num counter
result.Add(enumPtrProxy->Names[i].Value);
return MoveTemp(result);
}
int32 UEnumInspector::GetEnumValueByValueId(const UEnum* enumPtr, const int32 id)
{
if(!enumPtr)
return 0;
auto enumPtrProxy = static_cast<const UDEPRECATED_EnumInspectorProxy*>(enumPtr);
if(id < enumPtrProxy->Names.Num())
return enumPtrProxy->Names[id].Value;
return -1;
}
int32 UEnumInspector::GetEnumValueIdByValue(const UEnum* enumPtr, const int32 value)
{
if(!enumPtr)
return 0;
auto enumPtrProxy = static_cast<const UDEPRECATED_EnumInspectorProxy*>(enumPtr);
for(int32 i = 0; i < enumPtrProxy->Names.Num(); ++i)
if(enumPtrProxy->Names[i].Value == value)
return i;
return int32();
}

View File

@ -0,0 +1,34 @@
// Oleg Petruny proprietary.
#pragma once
#include "CoreMinimal.h"
#include "CommonInspectors.generated.h"
UCLASS(Deprecated)
class UDEPRECATED_EnumInspectorProxy : public UEnum
{
GENERATED_BODY()
friend class UEnumInspector;
};
UCLASS()
class UEnumInspector : public UBlueprintFunctionLibrary
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintPure, Category = Enum)
static UEnum* GetEnumByName(const FString& name);
UFUNCTION(BlueprintPure, Category = Enum)
static TArray<FText> GetEnumDisplayNames(UPARAM(meta = (DisplayName = "enum")) const UEnum* enumPtr);
UFUNCTION(BlueprintPure, Category = Enum)
static TArray<uint8> GetEnumValues(UPARAM(meta = (DisplayName = "enum")) const UEnum* enumPtr);
UFUNCTION(BlueprintPure, Category = Enum)
static int32 GetEnumValueByValueId(UPARAM(meta = (DisplayName = "enum")) const UEnum* enumPtr, const int32 id);
UFUNCTION(BlueprintPure, Category = Enum)
static int32 GetEnumValueIdByValue(UPARAM(meta = (DisplayName = "enum")) const UEnum* enumPtr, const int32 value);
};

View File

@ -5,6 +5,8 @@
#include "Kismet/GameplayStatics.h" #include "Kismet/GameplayStatics.h"
#include "GraphicsSettingsHelper.h" #include "GraphicsSettingsHelper.h"
#include "MainGameModeBase.h"
#include "Widgets/WidgetsManager.h"
namespace namespace
{ {
@ -46,6 +48,25 @@ UCustomGameSettings* UCustomGameSettings::Get()
return Cast<UCustomGameSettings>(UGameUserSettings::GetGameUserSettings()); return Cast<UCustomGameSettings>(UGameUserSettings::GetGameUserSettings());
} }
void UCustomGameSettings::LoadSettings(bool bForceReload)
{
Super::LoadSettings(bForceReload);
UpdateResolutionQuality();
}
void UCustomGameSettings::ApplySettings(bool bCheckForCommandLineOverrides)
{
Super::ApplySettings(bCheckForCommandLineOverrides);
UGraphicsSettingsHelper::ApplySettings(this);
if(auto WM = AMainGameModeBase::GetWidgetsManager())
{
if(bShowFps)
WM->ShowFpsCount();
else
WM->HideFpsCount();
}
}
LOST_EDGE_API bool UCustomGameSettings::GetDefaultShowFps() const LOST_EDGE_API bool UCustomGameSettings::GetDefaultShowFps() const
{ {
return bDefaultShowFps; return bDefaultShowFps;

View File

@ -24,6 +24,9 @@ public:
UFUNCTION(BlueprintPure, Category = "Settings", meta = (DisplayName = "Get Custom Game Settings")) UFUNCTION(BlueprintPure, Category = "Settings", meta = (DisplayName = "Get Custom Game Settings"))
static UCustomGameSettings* Get(); static UCustomGameSettings* Get();
virtual void LoadSettings(bool bForceReload = false) override;
virtual void ApplySettings(bool bCheckForCommandLineOverrides) override;
/** Graphics */ /** Graphics */
@ -92,8 +95,9 @@ public:
protected: protected:
/** Graphics */
UPROPERTY(Config) UPROPERTY(Config)
float fMouseSensetivity; int32 eAntiAliasingMethod;
/** Audio */ /** Audio */
UPROPERTY(Config) UPROPERTY(Config)
@ -107,4 +111,7 @@ protected:
UPROPERTY(Config) UPROPERTY(Config)
float fMenuVolume; float fMenuVolume;
/** Game */
UPROPERTY(Config)
float fMouseSensetivity;
}; };

View File

@ -17,10 +17,12 @@ namespace
constexpr int32 iDefaultMonitorId = 0; constexpr int32 iDefaultMonitorId = 0;
const FIntPoint ipDefaultResolution = { 1920, 1080 }; const FIntPoint ipDefaultResolution = { 1920, 1080 };
std::optional<FIntPoint> ipPreviousResolution; std::optional<FIntPoint> ipPreviousResolution;
constexpr float fDefaultResolutionScale = 1.0f; constexpr float fDefaultResolutionScale = 100.0f;
constexpr int32 iDefaultFrameRateLimit = 120; constexpr int32 iDefaultFrameRateLimit = 120;
constexpr EDisplayMode eDefaultDisplayMode = EDisplayMode::Fullscreen; constexpr EDisplayMode eDefaultDisplayMode = EDisplayMode::Fullscreen;
std::optional<EDisplayMode> ePreviousDisplayMode; std::optional<EDisplayMode> ePreviousDisplayMode;
constexpr bool bDefaultVSyncEnabled = false;
constexpr int32 eDefaultAntiAliasingMethod = static_cast<int32>(ELostEdgeAntiAliasingMethod::FXAA);
} }
bool UGraphicsSettingsHelper::AreSettingsRestorable(UCustomGameSettings* settings) bool UGraphicsSettingsHelper::AreSettingsRestorable(UCustomGameSettings* settings)
@ -30,6 +32,16 @@ bool UGraphicsSettingsHelper::AreSettingsRestorable(UCustomGameSettings* setting
|| ePreviousDisplayMode.has_value(); || ePreviousDisplayMode.has_value();
} }
void UGraphicsSettingsHelper::RestoreGraphicsSettings(UCustomGameSettings* settings)
{
if(ipPreviousWindowPosition.has_value())
SetWindowPosition(settings, ipPreviousWindowPosition.value());
if(ipPreviousResolution.has_value())
SetResolution(settings, ipPreviousResolution.value());
if(ePreviousDisplayMode.has_value())
SetDisplayMode(settings, ePreviousDisplayMode.value());
}
void UGraphicsSettingsHelper::SetDefaults(UCustomGameSettings* settings) void UGraphicsSettingsHelper::SetDefaults(UCustomGameSettings* settings)
{ {
{ {
@ -42,7 +54,23 @@ void UGraphicsSettingsHelper::SetDefaults(UCustomGameSettings* settings)
settings->ResolutionSizeX = res.X; settings->ResolutionSizeX = res.X;
settings->ResolutionSizeY = res.Y; settings->ResolutionSizeY = res.Y;
} }
settings->bUseDynamicResolution = true;
settings->FrameRateLimit = GetDefaultFrameRateLimit(settings);
settings->SetResolutionScaleValueEx(fDefaultResolutionScale);
settings->FullscreenMode = DisplayToWindowMode(GetDefaultDisplayMode(settings)); settings->FullscreenMode = DisplayToWindowMode(GetDefaultDisplayMode(settings));
settings->eAntiAliasingMethod = eDefaultAntiAliasingMethod;
}
void UGraphicsSettingsHelper::ApplySettings(UCustomGameSettings* settings)
{
if(!settings)
return;
if(GEngine && GEngine->GameViewport)
if(auto window = GEngine->GameViewport->GetWindow())
window->MoveWindowTo(settings->GetWindowPosition());
GEngine->Exec(UCustomGameSettings::Get()->GetWorld(), *FString::Printf(TEXT("r.AntiAliasingMethod %d"), settings->eAntiAliasingMethod));
} }
FIntPoint UGraphicsSettingsHelper::GetDefaultWindowPosition([[maybe_unused]] UCustomGameSettings* settings) FIntPoint UGraphicsSettingsHelper::GetDefaultWindowPosition([[maybe_unused]] UCustomGameSettings* settings)
@ -66,20 +94,16 @@ FIntPoint UGraphicsSettingsHelper::GetWindowPosition([[maybe_unused]] UCustomGam
void UGraphicsSettingsHelper::SetWindowPosition(UCustomGameSettings* settings, const FIntPoint& pos) void UGraphicsSettingsHelper::SetWindowPosition(UCustomGameSettings* settings, const FIntPoint& pos)
{ {
if(settings && GEngine && GEngine->GameViewport) if(settings)
{
if(auto window = GEngine->GameViewport->GetWindow())
{ {
if(ipPreviousWindowPosition == pos) if(ipPreviousWindowPosition == pos)
ipPreviousWindowPosition.reset(); ipPreviousWindowPosition.reset();
else else
ipPreviousWindowPosition = GetWindowPosition(settings); ipPreviousWindowPosition = GetWindowPosition(settings);
window->MoveWindowTo(pos);
settings->SetWindowPosition(pos.X, pos.Y); settings->SetWindowPosition(pos.X, pos.Y);
} }
} }
}
void UGraphicsSettingsHelper::RestoreWindowPosition(UCustomGameSettings* settings) void UGraphicsSettingsHelper::RestoreWindowPosition(UCustomGameSettings* settings)
{ {
@ -126,10 +150,11 @@ int32 UGraphicsSettingsHelper::GetPrimaryMonitorId()
TArray<FString> UGraphicsSettingsHelper::GetAvailableMonitorsNames() TArray<FString> UGraphicsSettingsHelper::GetAvailableMonitorsNames()
{ {
TArray<FString> names;
auto monitors = GetAvailableMonitors(); auto monitors = GetAvailableMonitors();
for(auto& m : monitors) TArray<FString> names;
names.Add(m.ID); names.Reserve(monitors.Num());
for(int32 i = 0; i < monitors.Num(); ++i)
names.Add(FString::Printf(TEXT("%d - %s"), i + 1, *monitors[i].Name));
return MoveTemp(names); return MoveTemp(names);
} }
@ -195,11 +220,16 @@ TArray<FResolutionAndRefreshRates> UGraphicsSettingsHelper::GetAllAvailableResol
if(!RHIGetAvailableResolutions(buffer, false) || buffer.Num() == 0) if(!RHIGetAvailableResolutions(buffer, false) || buffer.Num() == 0)
return { {GetResolution(nullptr), {GetDefaultFrameRateLimit(nullptr)}} }; return { {GetResolution(nullptr), {GetDefaultFrameRateLimit(nullptr)}} };
TArray<FResolutionAndRefreshRates> result = {}; TArray<FResolutionAndRefreshRates> result;
int32 lastWidth = 0; int32 lastWidth = 0;
int32 lastHeight = 0; int32 lastHeight = 0;
FIntPoint currentResolution = GetResolution(nullptr);
bool currentInfoPresent = false;
for(auto& i : buffer) for(auto& i : buffer)
{ {
if(currentResolution.X == i.Width && currentResolution.Y == i.Height)
currentInfoPresent = true;
if(lastWidth != i.Width || lastHeight != i.Height) if(lastWidth != i.Width || lastHeight != i.Height)
{ {
result.Add({ {static_cast<int32>(i.Width), static_cast<int32>(i.Height)}, {static_cast<int32>(i.RefreshRate)} }); result.Add({ {static_cast<int32>(i.Width), static_cast<int32>(i.Height)}, {static_cast<int32>(i.RefreshRate)} });
@ -212,6 +242,10 @@ TArray<FResolutionAndRefreshRates> UGraphicsSettingsHelper::GetAllAvailableResol
} }
} }
if(!currentInfoPresent)
if(auto settings = UCustomGameSettings::Get())
result.Add({ currentResolution, { static_cast<int32>(settings->GetFrameRateLimit()) } });
return MoveTemp(result); return MoveTemp(result);
} }
@ -222,6 +256,7 @@ TArray<FIntPoint> UGraphicsSettingsHelper::GetAllAvailableResolutions()
return { {GetResolution(nullptr), {GetDefaultFrameRateLimit(nullptr)}} }; return { {GetResolution(nullptr), {GetDefaultFrameRateLimit(nullptr)}} };
TArray<FIntPoint> result; TArray<FIntPoint> result;
result.Reserve(buffer.Num() + 1);
int32 lastWidth = 0; int32 lastWidth = 0;
int32 lastHeight = 0; int32 lastHeight = 0;
for(auto& i : buffer) for(auto& i : buffer)
@ -233,20 +268,32 @@ TArray<FIntPoint> UGraphicsSettingsHelper::GetAllAvailableResolutions()
lastWidth = i.Width; lastWidth = i.Width;
} }
} }
FIntPoint currentResolution = GetResolution(nullptr);
if(!result.Contains(currentResolution))
result.Add(currentResolution);
return MoveTemp(result); return MoveTemp(result);
} }
TArray<FIntPoint> UGraphicsSettingsHelper::GetAvailableResolutionsByMonitorId(const int32 id) TArray<FIntPoint> UGraphicsSettingsHelper::GetAvailableResolutionsByMonitorId(const int32 id)
{ {
TArray<FIntPoint> result; auto resolutions = GetAllAvailableResolutions();
FIntPoint nativeRes = GetNativeResolutionByMonitorId(id); FIntPoint nativeRes = GetNativeResolutionByMonitorId(id);
for(auto& i : GetAllAvailableResolutions()) TArray<FIntPoint> result;
result.Reserve(resolutions.Num() + 1);
for(auto& i : resolutions)
{ {
if(i.X > nativeRes.X && i.Y > nativeRes.Y) if(i.X > nativeRes.X && i.Y > nativeRes.Y)
continue; continue;
result.Add(i); result.Add(i);
} }
if(id == GetMonitorId(nullptr))
{
FIntPoint currentResolution = GetResolution(nullptr);
if(!result.Contains(currentResolution))
result.Add(currentResolution);
}
return MoveTemp(result); return MoveTemp(result);
} }
@ -267,8 +314,6 @@ void UGraphicsSettingsHelper::SetResolution(UCustomGameSettings* settings, const
if(!settings) if(!settings)
return; return;
settings->bUseDynamicResolution = true;
if(ipPreviousResolution.has_value() && ipPreviousResolution == resolution) if(ipPreviousResolution.has_value() && ipPreviousResolution == resolution)
ipPreviousResolution.reset(); ipPreviousResolution.reset();
else else
@ -285,27 +330,11 @@ void UGraphicsSettingsHelper::RestoreResolution(UCustomGameSettings* settings)
SetResolution(settings, ipPreviousResolution.value()); SetResolution(settings, ipPreviousResolution.value());
} }
float UGraphicsSettingsHelper::GetDefaultResolutionScale([[maybe_unused]] UCustomGameSettings* settings) float UGraphicsSettingsHelper::GetDefaultResolutionScaleFast(UCustomGameSettings* settings)
{ {
return fDefaultResolutionScale; return fDefaultResolutionScale;
} }
float UGraphicsSettingsHelper::GetResolutionScale([[maybe_unused]] UCustomGameSettings* settings)
{
if(auto settings = UCustomGameSettings::Get())
return settings->GetResolutionScaleNormalized();
return 1.0f;
}
void UGraphicsSettingsHelper::SetResolutionScale(UCustomGameSettings* settings, const float resolutionScale)
{
if(!settings)
return;
settings->SetResolutionScaleNormalized(resolutionScale);
}
int32 UGraphicsSettingsHelper::GetDefaultFrameRateLimit([[maybe_unused]] UCustomGameSettings* settings) int32 UGraphicsSettingsHelper::GetDefaultFrameRateLimit([[maybe_unused]] UCustomGameSettings* settings)
{ {
return iDefaultFrameRateLimit; return iDefaultFrameRateLimit;
@ -315,8 +344,24 @@ TArray<int32> UGraphicsSettingsHelper::GetAvailableFrameRateLimitsForResolution(
{ {
auto resAndRates = GetAllAvailableResolutionsAndRefreshRates(); auto resAndRates = GetAllAvailableResolutionsAndRefreshRates();
for(auto& i : resAndRates) for(auto& i : resAndRates)
{
if(i.resolution == resolution) if(i.resolution == resolution)
{
if(resolution == GetResolution(nullptr))
if(auto settings = UCustomGameSettings::Get())
if(!i.refreshRates.Contains(settings->GetFrameRateLimit()))
i.refreshRates.Add(settings->GetFrameRateLimit());
if(!i.refreshRates.Contains(GetDefaultFrameRateLimit(nullptr)))
i.refreshRates.Add(GetDefaultFrameRateLimit(nullptr));
if(!i.refreshRates.Contains(0))
i.refreshRates.Add(0);
i.refreshRates.Sort();
return MoveTemp(i.refreshRates); return MoveTemp(i.refreshRates);
}
}
return { GetDefaultFrameRateLimit(nullptr) }; return { GetDefaultFrameRateLimit(nullptr) };
} }
@ -350,8 +395,15 @@ TArray<FIntPoint> UGraphicsSettingsHelper::GetAvailableAspectRatiousOfMonitor(co
TSet<FIntPoint> aspects; TSet<FIntPoint> aspects;
for(auto& i : resolutions) for(auto& i : resolutions)
{
aspects.Add(GetAspectRatioFromResolution(i)); aspects.Add(GetAspectRatioFromResolution(i));
return aspects.Array(); UE_LOG(LogTemp, Log, TEXT("%dx%d = %dx%d"), i.X, i.Y, GetAspectRatioFromResolution(i).X, GetAspectRatioFromResolution(i).Y);
}
aspects.Add(GetAspectRatioFromResolution(GetResolution(nullptr)));
TArray<FIntPoint> result = aspects.Array();
UCommonFunctions::SortIntPointArray(result);
return MoveTemp(result);
} }
EDisplayMode UGraphicsSettingsHelper::GetDefaultDisplayMode([[maybe_unused]] UCustomGameSettings* settings) EDisplayMode UGraphicsSettingsHelper::GetDefaultDisplayMode([[maybe_unused]] UCustomGameSettings* settings)
@ -406,6 +458,33 @@ void UGraphicsSettingsHelper::RestoreDisplayMode(UCustomGameSettings* settings)
SetDisplayMode(settings, ePreviousDisplayMode.value()); SetDisplayMode(settings, ePreviousDisplayMode.value());
} }
bool UGraphicsSettingsHelper::GetDefaultVSyncEnabled(UCustomGameSettings* settings)
{
return bDefaultVSyncEnabled;
}
int32 UGraphicsSettingsHelper::GetDefaultAntiAliasingMethod(UCustomGameSettings* settings)
{
return eDefaultAntiAliasingMethod;
}
int32 UGraphicsSettingsHelper::GetAntiAliasingMethod(UCustomGameSettings* settings)
{
static const auto cvar = IConsoleManager::Get().FindConsoleVariable(TEXT("r.AntiAliasingMethod"));
if(cvar)
return cvar->GetInt();
return -1;
}
void UGraphicsSettingsHelper::SetAntiAliasingMethod(UCustomGameSettings* settings, int32 method)
{
if(!settings)
return;
settings->eAntiAliasingMethod = FMath::Clamp(method, static_cast<int32>(ELostEdgeAntiAliasingMethod::None), static_cast<int32>(ELostEdgeAntiAliasingMethod::MSAA));
}
inline constexpr EDisplayMode UGraphicsSettingsHelper::WindowToDisplayMode(const EWindowMode::Type mode) inline constexpr EDisplayMode UGraphicsSettingsHelper::WindowToDisplayMode(const EWindowMode::Type mode)
{ {
switch(mode) switch(mode)
@ -433,6 +512,3 @@ inline constexpr EWindowMode::Type UGraphicsSettingsHelper::DisplayToWindowMode(
return EWindowMode::Type::Fullscreen; return EWindowMode::Type::Fullscreen;
} }
} }

View File

@ -27,6 +27,15 @@ enum class EDisplayMode : uint8
Windowed = 2 UMETA(DisplayName = "Windowed") Windowed = 2 UMETA(DisplayName = "Windowed")
}; };
UENUM(BlueprintType)
enum class ELostEdgeAntiAliasingMethod : uint8
{
None = AAM_None UMETA(DisplayName = "None"),
FXAA = AAM_FXAA UMETA(DisplayName = "FXAA"),
TAA = AAM_TemporalAA UMETA(DisplayName = "TAA"),
MSAA = AAM_MSAA UMETA(DisplayName = "MSAA")
};
/** /**
* Helper for trivial and complex graphic settings. * Helper for trivial and complex graphic settings.
* Most of functions work without settings pointer. It is there just for Blueprint call convinience. * Most of functions work without settings pointer. It is there just for Blueprint call convinience.
@ -41,8 +50,12 @@ class UGraphicsSettingsHelper : public UBlueprintFunctionLibrary
public: public:
UFUNCTION(BlueprintPure, Category = "Settings|Graphics", meta = (DisplayName = "Are Graphics Settings Restorable")) UFUNCTION(BlueprintPure, Category = "Settings|Graphics", meta = (DisplayName = "Are Graphics Settings Restorable"))
static bool AreSettingsRestorable(class UCustomGameSettings* settings); static bool AreSettingsRestorable(class UCustomGameSettings* settings);
UFUNCTION(BlueprintCallable, Category = "Settings|Graphics")
static void RestoreGraphicsSettings(class UCustomGameSettings* settings);
UFUNCTION(BlueprintCallable, Category = "Settings|Graphics", meta = (DisplayName = "Set Graphics Defaults")) UFUNCTION(BlueprintCallable, Category = "Settings|Graphics", meta = (DisplayName = "Set Graphics Defaults"))
static void SetDefaults(class UCustomGameSettings* settings); static void SetDefaults(class UCustomGameSettings* settings);
UFUNCTION(BlueprintCallable, Category = "Settings|Graphics", meta = (DisplayName = "Apply Graphics Settings"))
static void ApplySettings(class UCustomGameSettings* settings);
protected: // Window position setting is on the thin edge of user safeness, therefore protected. Please use SetMonitor(). protected: // Window position setting is on the thin edge of user safeness, therefore protected. Please use SetMonitor().
UFUNCTION(BlueprintPure, Category = "Settings|Graphics|Window") UFUNCTION(BlueprintPure, Category = "Settings|Graphics|Window")
@ -89,11 +102,7 @@ public:
static void RestoreResolution(class UCustomGameSettings* settings); static void RestoreResolution(class UCustomGameSettings* settings);
UFUNCTION(BlueprintPure, Category = "Settings|Graphics|Resolution Scale") UFUNCTION(BlueprintPure, Category = "Settings|Graphics|Resolution Scale")
static float GetDefaultResolutionScale(class UCustomGameSettings* settings); static float GetDefaultResolutionScaleFast(class UCustomGameSettings* settings);
UFUNCTION(BlueprintPure, Category = "Settings|Graphics|Resolution Scale")
static float GetResolutionScale(class UCustomGameSettings* settings);
UFUNCTION(BlueprintCallable, Category = "Settings|Graphics|Resolution Scale")
static void SetResolutionScale(class UCustomGameSettings* settings, const float resolutionScale);
UFUNCTION(BlueprintPure, Category = "Settings|Graphics|Frame Rate Limit") UFUNCTION(BlueprintPure, Category = "Settings|Graphics|Frame Rate Limit")
static int32 GetDefaultFrameRateLimit(class UCustomGameSettings* settings); static int32 GetDefaultFrameRateLimit(class UCustomGameSettings* settings);
@ -124,6 +133,16 @@ public:
UFUNCTION(BlueprintCallable, Category = "Settings|Graphics|Display Mode") UFUNCTION(BlueprintCallable, Category = "Settings|Graphics|Display Mode")
static void RestoreDisplayMode(class UCustomGameSettings* settings); static void RestoreDisplayMode(class UCustomGameSettings* settings);
UFUNCTION(BlueprintPure, Category = "Settings|Graphics|VSync")
static bool GetDefaultVSyncEnabled(class UCustomGameSettings* settings);
UFUNCTION(BlueprintPure, Category = "Settings|Graphics|Anti Aliasing")
static int32 GetDefaultAntiAliasingMethod(class UCustomGameSettings* settings);
UFUNCTION(BlueprintPure, Category = "Settings|Graphics|Anti Aliasing")
static int32 GetAntiAliasingMethod(class UCustomGameSettings* settings);
UFUNCTION(BlueprintCallable, Category = "Settings|Graphics|Anti Aliasing")
static void SetAntiAliasingMethod(class UCustomGameSettings* settings, int32 method);
private: private:
inline constexpr static EDisplayMode WindowToDisplayMode(const EWindowMode::Type mode); inline constexpr static EDisplayMode WindowToDisplayMode(const EWindowMode::Type mode);
inline constexpr static EWindowMode::Type DisplayToWindowMode(const EDisplayMode mode); inline constexpr static EWindowMode::Type DisplayToWindowMode(const EDisplayMode mode);

View File

@ -6,15 +6,57 @@ void UComboBoxText::PostInitProperties()
{ {
Super::PostInitProperties(); Super::PostInitProperties();
SetOptions(_DefaultOptions); SetOptionsAsText(_DefaultOptions);
_DefaultOptions.Empty(); _DefaultOptions.Empty();
OnSelectionChanged.AddDynamic(this, &UComboBoxText::UpdateButtonPadding);
auto& style = GetWidgetStyle();
buttonNormalLeftPadding = style.ComboButtonStyle.ButtonStyle.NormalPadding.Left;
buttonPressedLeftPadding = style.ComboButtonStyle.ButtonStyle.PressedPadding.Left;
} }
void UComboBoxText::SetOptions(const TArray<FText>& options) void UComboBoxText::SetOptionsAsText(const TArray<FText>& options)
{ {
ClearSelection(); ClearSelection();
Options.Empty(); Options.Empty(options.Num());
for(auto& o : options) for(auto& o : options)
Options.Add(MakeShareable(new FString(o.ToString()))); Options.Add(MakeShareable(new FString(o.ToString())));
RefreshOptions(); RefreshOptions();
PostOptionsSet();
}
void UComboBoxText::SetOptionsAsString(const TArray<FString>& options)
{
ClearSelection();
Options.Empty(options.Num());
for(auto& o : options)
Options.Add(MakeShareable(new FString(o)));
RefreshOptions();
PostOptionsSet();
}
TArray<FString> UComboBoxText::GetOptions()
{
TArray<FString> result;
result.Reserve(Options.Num());
for(auto& o : Options)
result.Add(*o);
return MoveTemp(result);
}
void UComboBoxText::PostOptionsSet()
{
longestCharCount = 0;
for(auto& o : Options)
if(o->Len() > longestCharCount)
longestCharCount = o->Len();
}
void UComboBoxText::UpdateButtonPadding(FString SelectedItem, ESelectInfo::Type SelectionType)
{
const int32 len = longestCharCount - SelectedItem.Len();
auto style = GetWidgetStyle();
float padding = GetFont().Size * (static_cast<float>(len));
style.ComboButtonStyle.ButtonStyle.NormalPadding.Left = padding + buttonNormalLeftPadding;
style.ComboButtonStyle.ButtonStyle.PressedPadding.Left = padding + buttonPressedLeftPadding;
SetWidgetStyle(style);
} }

View File

@ -15,9 +15,22 @@ public:
virtual void PostInitProperties() override; virtual void PostInitProperties() override;
UFUNCTION(BlueprintCallable) UFUNCTION(BlueprintCallable)
void SetOptions(const TArray<FText>& options); void SetOptionsAsText(const TArray<FText>& options);
UFUNCTION(BlueprintCallable)
void SetOptionsAsString(const TArray<FString>& options);
UFUNCTION(BlueprintPure)
TArray<FString> GetOptions();
protected: protected:
void PostOptionsSet();
UFUNCTION()
void UpdateButtonPadding(FString SelectedItem, ESelectInfo::Type SelectionType);
UPROPERTY(EditAnywhere, Category = ComboBoxTextDefault) UPROPERTY(EditAnywhere, Category = ComboBoxTextDefault)
TArray<FText> _DefaultOptions; TArray<FText> _DefaultOptions;
int32 longestCharCount;
float buttonNormalLeftPadding, buttonPressedLeftPadding;
}; };

View File

@ -3,6 +3,7 @@
#include "ResolutionResponsiveWidget.h" #include "ResolutionResponsiveWidget.h"
#include "Components/PanelSlot.h" #include "Components/PanelSlot.h"
#include "GraphicsSettingsHelper.h"
#include "UnrealClient.h" #include "UnrealClient.h"
bool UResolutionResponsiveWidget::Initialize() bool UResolutionResponsiveWidget::Initialize()

View File

@ -10,6 +10,7 @@
#include "UObject/ScriptInterface.h" #include "UObject/ScriptInterface.h"
#include "CustomGameInstance.h" #include "CustomGameInstance.h"
#include "CustomGameSettings.h"
#include "Interactable/Interactable.h" #include "Interactable/Interactable.h"
#include "Interactable/Modificators/InteractableModificator.h" #include "Interactable/Modificators/InteractableModificator.h"
#include "Interactable/Modificators/InventoryInteractableModificator.h" #include "Interactable/Modificators/InventoryInteractableModificator.h"
@ -98,6 +99,12 @@ void UWidgetsManager::Init()
journalWidget->SetVisibility(ESlateVisibility::Hidden); journalWidget->SetVisibility(ESlateVisibility::Hidden);
journalWidget->AddToViewport(); journalWidget->AddToViewport();
} }
if(auto settings = UCustomGameSettings::Get())
{
if(settings->bShowFps)
ShowFpsCount();
}
} }
} }
@ -156,6 +163,27 @@ void UWidgetsManager::HideMainMenu()
void UWidgetsManager::ShowFpsCount()
{
if(fpsCountWidget)
return;
if(auto PC = UGameplayStatics::GetPlayerController(GetWorld(), 0))
fpsCountWidget = CreateWidget<UUserWidget>(PC, fpsCountWidgetClass);
fpsCountWidget->AddToViewport();
}
void UWidgetsManager::HideFpsCount()
{
if(!fpsCountWidget)
return;
fpsCountWidget->RemoveFromViewport();
fpsCountWidget = nullptr;
}
void UWidgetsManager::ShowInteractionHints(const UInteractableModificator* modificator) void UWidgetsManager::ShowInteractionHints(const UInteractableModificator* modificator)
{ {
if(interactableHintWidgetManager) if(interactableHintWidgetManager)

View File

@ -30,6 +30,9 @@ public:
void ShowMainMenu(bool pause = true); void ShowMainMenu(bool pause = true);
void HideMainMenu(); void HideMainMenu();
void ShowFpsCount();
void HideFpsCount();
UFUNCTION(BlueprintCallable, Category = WidgetsManager) UFUNCTION(BlueprintCallable, Category = WidgetsManager)
void ShowInteractionHints(const class UInteractableModificator* modificator = nullptr); void ShowInteractionHints(const class UInteractableModificator* modificator = nullptr);
UFUNCTION(BlueprintCallable, Category = WidgetsManager) UFUNCTION(BlueprintCallable, Category = WidgetsManager)
@ -70,6 +73,10 @@ protected:
TSubclassOf<class UMainMenuWidget> mainMenuWidgetClass; TSubclassOf<class UMainMenuWidget> mainMenuWidgetClass;
class UMainMenuWidget* mainMenuWidget = nullptr; class UMainMenuWidget* mainMenuWidget = nullptr;
UPROPERTY(EditDefaultsOnly)
TSubclassOf<class UUserWidget> fpsCountWidgetClass;
class UUserWidget* fpsCountWidget = nullptr;
UPROPERTY(EditDefaultsOnly) UPROPERTY(EditDefaultsOnly)
TSubclassOf<class UInteractableHintWidgetManager> interactableHintWidgetManagerClass; // hidden in cutscene TSubclassOf<class UInteractableHintWidgetManager> interactableHintWidgetManagerClass; // hidden in cutscene
class UInteractableHintWidgetManager* interactableHintWidgetManager = nullptr; class UInteractableHintWidgetManager* interactableHintWidgetManager = nullptr;