lyra_game_ue/Source/LyraGame/Settings/LyraSettingsShared.cpp
Goran Lazarevski 3bcab085f8 Initial commit
2025-03-20 11:06:26 +01:00

264 lines
7.9 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "LyraSettingsShared.h"
#include "Framework/Application/SlateApplication.h"
#include "Internationalization/Culture.h"
#include "Kismet/GameplayStatics.h"
#include "Misc/App.h"
#include "Misc/ConfigCacheIni.h"
#include "Player/LyraLocalPlayer.h"
#include "Rendering/SlateRenderer.h"
#include "SubtitleDisplaySubsystem.h"
#include "EnhancedInputSubsystems.h"
#include "UserSettings/EnhancedInputUserSettings.h"
#include UE_INLINE_GENERATED_CPP_BY_NAME(LyraSettingsShared)
static FString SHARED_SETTINGS_SLOT_NAME = TEXT("SharedGameSettings");
namespace LyraSettingsSharedCVars
{
static float DefaultGamepadLeftStickInnerDeadZone = 0.25f;
static FAutoConsoleVariableRef CVarGamepadLeftStickInnerDeadZone(
TEXT("gpad.DefaultLeftStickInnerDeadZone"),
DefaultGamepadLeftStickInnerDeadZone,
TEXT("Gamepad left stick inner deadzone")
);
static float DefaultGamepadRightStickInnerDeadZone = 0.25f;
static FAutoConsoleVariableRef CVarGamepadRightStickInnerDeadZone(
TEXT("gpad.DefaultRightStickInnerDeadZone"),
DefaultGamepadRightStickInnerDeadZone,
TEXT("Gamepad right stick inner deadzone")
);
}
ULyraSettingsShared::ULyraSettingsShared()
{
FInternationalization::Get().OnCultureChanged().AddUObject(this, &ThisClass::OnCultureChanged);
GamepadMoveStickDeadZone = LyraSettingsSharedCVars::DefaultGamepadLeftStickInnerDeadZone;
GamepadLookStickDeadZone = LyraSettingsSharedCVars::DefaultGamepadRightStickInnerDeadZone;
}
int32 ULyraSettingsShared::GetLatestDataVersion() const
{
// 0 = before subclassing ULocalPlayerSaveGame
// 1 = first proper version
return 1;
}
ULyraSettingsShared* ULyraSettingsShared::CreateTemporarySettings(const ULyraLocalPlayer* LocalPlayer)
{
// This is not loaded from disk but should be set up to save
ULyraSettingsShared* SharedSettings = Cast<ULyraSettingsShared>(CreateNewSaveGameForLocalPlayer(ULyraSettingsShared::StaticClass(), LocalPlayer, SHARED_SETTINGS_SLOT_NAME));
SharedSettings->ApplySettings();
return SharedSettings;
}
ULyraSettingsShared* ULyraSettingsShared::LoadOrCreateSettings(const ULyraLocalPlayer* LocalPlayer)
{
// This will stall the main thread while it loads
ULyraSettingsShared* SharedSettings = Cast<ULyraSettingsShared>(LoadOrCreateSaveGameForLocalPlayer(ULyraSettingsShared::StaticClass(), LocalPlayer, SHARED_SETTINGS_SLOT_NAME));
SharedSettings->ApplySettings();
return SharedSettings;
}
bool ULyraSettingsShared::AsyncLoadOrCreateSettings(const ULyraLocalPlayer* LocalPlayer, FOnSettingsLoadedEvent Delegate)
{
FOnLocalPlayerSaveGameLoadedNative Lambda = FOnLocalPlayerSaveGameLoadedNative::CreateLambda([Delegate]
(ULocalPlayerSaveGame* LoadedSave)
{
ULyraSettingsShared* LoadedSettings = CastChecked<ULyraSettingsShared>(LoadedSave);
LoadedSettings->ApplySettings();
Delegate.ExecuteIfBound(LoadedSettings);
});
return ULocalPlayerSaveGame::AsyncLoadOrCreateSaveGameForLocalPlayer(ULyraSettingsShared::StaticClass(), LocalPlayer, SHARED_SETTINGS_SLOT_NAME, Lambda);
}
void ULyraSettingsShared::SaveSettings()
{
// Schedule an async save because it's okay if it fails
AsyncSaveGameToSlotForLocalPlayer();
// TODO_BH: Move this to the serialize function instead with a bumped version number
if (UEnhancedInputLocalPlayerSubsystem* System = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(OwningPlayer))
{
if (UEnhancedInputUserSettings* InputSettings = System->GetUserSettings())
{
InputSettings->AsyncSaveSettings();
}
}
}
void ULyraSettingsShared::ApplySettings()
{
ApplySubtitleOptions();
ApplyBackgroundAudioSettings();
ApplyCultureSettings();
if (UEnhancedInputLocalPlayerSubsystem* System = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(OwningPlayer))
{
if (UEnhancedInputUserSettings* InputSettings = System->GetUserSettings())
{
InputSettings->ApplySettings();
}
}
}
void ULyraSettingsShared::SetColorBlindStrength(int32 InColorBlindStrength)
{
InColorBlindStrength = FMath::Clamp(InColorBlindStrength, 0, 10);
if (ColorBlindStrength != InColorBlindStrength)
{
ColorBlindStrength = InColorBlindStrength;
FSlateApplication::Get().GetRenderer()->SetColorVisionDeficiencyType(
(EColorVisionDeficiency)(int32)ColorBlindMode, (int32)ColorBlindStrength, true, false);
}
}
int32 ULyraSettingsShared::GetColorBlindStrength() const
{
return ColorBlindStrength;
}
void ULyraSettingsShared::SetColorBlindMode(EColorBlindMode InMode)
{
if (ColorBlindMode != InMode)
{
ColorBlindMode = InMode;
FSlateApplication::Get().GetRenderer()->SetColorVisionDeficiencyType(
(EColorVisionDeficiency)(int32)ColorBlindMode, (int32)ColorBlindStrength, true, false);
}
}
EColorBlindMode ULyraSettingsShared::GetColorBlindMode() const
{
return ColorBlindMode;
}
void ULyraSettingsShared::ApplySubtitleOptions()
{
if (USubtitleDisplaySubsystem* SubtitleSystem = USubtitleDisplaySubsystem::Get(OwningPlayer))
{
FSubtitleFormat SubtitleFormat;
SubtitleFormat.SubtitleTextSize = SubtitleTextSize;
SubtitleFormat.SubtitleTextColor = SubtitleTextColor;
SubtitleFormat.SubtitleTextBorder = SubtitleTextBorder;
SubtitleFormat.SubtitleBackgroundOpacity = SubtitleBackgroundOpacity;
SubtitleSystem->SetSubtitleDisplayOptions(SubtitleFormat);
}
}
//////////////////////////////////////////////////////////////////////
void ULyraSettingsShared::SetAllowAudioInBackgroundSetting(ELyraAllowBackgroundAudioSetting NewValue)
{
if (ChangeValueAndDirty(AllowAudioInBackground, NewValue))
{
ApplyBackgroundAudioSettings();
}
}
void ULyraSettingsShared::ApplyBackgroundAudioSettings()
{
if (OwningPlayer && OwningPlayer->IsPrimaryPlayer())
{
FApp::SetUnfocusedVolumeMultiplier((AllowAudioInBackground != ELyraAllowBackgroundAudioSetting::Off) ? 1.0f : 0.0f);
}
}
//////////////////////////////////////////////////////////////////////
void ULyraSettingsShared::ApplyCultureSettings()
{
if (bResetToDefaultCulture)
{
const FCulturePtr SystemDefaultCulture = FInternationalization::Get().GetDefaultCulture();
check(SystemDefaultCulture.IsValid());
const FString CultureToApply = SystemDefaultCulture->GetName();
if (FInternationalization::Get().SetCurrentCulture(CultureToApply))
{
// Clear this string
GConfig->RemoveKey(TEXT("Internationalization"), TEXT("Culture"), GGameUserSettingsIni);
GConfig->Flush(false, GGameUserSettingsIni);
}
bResetToDefaultCulture = false;
}
else if (!PendingCulture.IsEmpty())
{
// SetCurrentCulture may trigger PendingCulture to be cleared (if a culture change is broadcast) so we take a copy of it to work with
const FString CultureToApply = PendingCulture;
if (FInternationalization::Get().SetCurrentCulture(CultureToApply))
{
// Note: This is intentionally saved to the users config
// We need to localize text before the player logs in and very early in the loading screen
GConfig->SetString(TEXT("Internationalization"), TEXT("Culture"), *CultureToApply, GGameUserSettingsIni);
GConfig->Flush(false, GGameUserSettingsIni);
}
ClearPendingCulture();
}
}
void ULyraSettingsShared::ResetCultureToCurrentSettings()
{
ClearPendingCulture();
bResetToDefaultCulture = false;
}
const FString& ULyraSettingsShared::GetPendingCulture() const
{
return PendingCulture;
}
void ULyraSettingsShared::SetPendingCulture(const FString& NewCulture)
{
PendingCulture = NewCulture;
bResetToDefaultCulture = false;
bIsDirty = true;
}
void ULyraSettingsShared::OnCultureChanged()
{
ClearPendingCulture();
bResetToDefaultCulture = false;
}
void ULyraSettingsShared::ClearPendingCulture()
{
PendingCulture.Reset();
}
bool ULyraSettingsShared::IsUsingDefaultCulture() const
{
FString Culture;
GConfig->GetString(TEXT("Internationalization"), TEXT("Culture"), Culture, GGameUserSettingsIni);
return Culture.IsEmpty();
}
void ULyraSettingsShared::ResetToDefaultCulture()
{
ClearPendingCulture();
bResetToDefaultCulture = true;
bIsDirty = true;
}
//////////////////////////////////////////////////////////////////////
void ULyraSettingsShared::ApplyInputSensitivity()
{
}