482 lines
15 KiB
C++
482 lines
15 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#pragma once
|
|
|
|
#include "CommonInputBaseTypes.h"
|
|
#include "Containers/Array.h"
|
|
#include "Containers/Map.h"
|
|
#include "Containers/UnrealString.h"
|
|
#include "Delegates/Delegate.h"
|
|
#include "GameFramework/GameUserSettings.h"
|
|
#include "Input/LyraMappableConfigPair.h"
|
|
#include "InputCoreTypes.h"
|
|
#include "Performance/LyraPerformanceStatTypes.h"
|
|
#include "Scalability.h"
|
|
#include "UObject/NameTypes.h"
|
|
#include "UObject/UObjectGlobals.h"
|
|
|
|
#include "LyraSettingsLocal.generated.h"
|
|
|
|
class ULyraLocalPlayer;
|
|
class UObject;
|
|
class UPlayerMappableInputConfig;
|
|
class USoundControlBus;
|
|
class USoundControlBusMix;
|
|
struct FFrame;
|
|
|
|
USTRUCT()
|
|
struct FLyraScalabilitySnapshot
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
FLyraScalabilitySnapshot();
|
|
|
|
Scalability::FQualityLevels Qualities;
|
|
bool bActive = false;
|
|
bool bHasOverrides = false;
|
|
};
|
|
|
|
/**
|
|
* ULyraSettingsLocal
|
|
*/
|
|
UCLASS()
|
|
class ULyraSettingsLocal : public UGameUserSettings
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
public:
|
|
|
|
ULyraSettingsLocal();
|
|
|
|
static ULyraSettingsLocal* Get();
|
|
|
|
//~UObject interface
|
|
virtual void BeginDestroy() override;
|
|
//~End of UObject interface
|
|
|
|
//~UGameUserSettings interface
|
|
virtual void SetToDefaults() override;
|
|
virtual void LoadSettings(bool bForceReload) override;
|
|
virtual void ConfirmVideoMode() override;
|
|
virtual float GetEffectiveFrameRateLimit() override;
|
|
virtual void ResetToCurrentSettings() override;
|
|
virtual void ApplyNonResolutionSettings() override;
|
|
virtual int32 GetOverallScalabilityLevel() const override;
|
|
virtual void SetOverallScalabilityLevel(int32 Value) override;
|
|
//~End of UGameUserSettings interface
|
|
|
|
void OnExperienceLoaded();
|
|
void OnHotfixDeviceProfileApplied();
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// Frontend state
|
|
|
|
public:
|
|
void SetShouldUseFrontendPerformanceSettings(bool bInFrontEnd);
|
|
protected:
|
|
bool ShouldUseFrontendPerformanceSettings() const;
|
|
private:
|
|
bool bInFrontEndForPerformancePurposes = false;
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// Performance stats
|
|
public:
|
|
/** Returns the display mode for the specified performance stat */
|
|
ELyraStatDisplayMode GetPerfStatDisplayState(ELyraDisplayablePerformanceStat Stat) const;
|
|
|
|
/** Sets the display mode for the specified performance stat */
|
|
void SetPerfStatDisplayState(ELyraDisplayablePerformanceStat Stat, ELyraStatDisplayMode DisplayMode);
|
|
|
|
/** Fired when the display state for a performance stat has changed, or the settings are applied */
|
|
DECLARE_EVENT(ULyraSettingsLocal, FPerfStatSettingsChanged);
|
|
FPerfStatSettingsChanged& OnPerfStatDisplayStateChanged() { return PerfStatSettingsChangedEvent; }
|
|
|
|
private:
|
|
// List of stats to display in the HUD
|
|
UPROPERTY(Config)
|
|
TMap<ELyraDisplayablePerformanceStat, ELyraStatDisplayMode> DisplayStatList;
|
|
|
|
// Event for display stat widget containers to bind to
|
|
FPerfStatSettingsChanged PerfStatSettingsChangedEvent;
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// Brightness/Gamma
|
|
public:
|
|
UFUNCTION()
|
|
float GetDisplayGamma() const;
|
|
UFUNCTION()
|
|
void SetDisplayGamma(float InGamma);
|
|
|
|
private:
|
|
void ApplyDisplayGamma();
|
|
|
|
UPROPERTY(Config)
|
|
float DisplayGamma = 2.2;
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// Display
|
|
public:
|
|
UFUNCTION()
|
|
float GetFrameRateLimit_OnBattery() const;
|
|
UFUNCTION()
|
|
void SetFrameRateLimit_OnBattery(float NewLimitFPS);
|
|
|
|
UFUNCTION()
|
|
float GetFrameRateLimit_InMenu() const;
|
|
UFUNCTION()
|
|
void SetFrameRateLimit_InMenu(float NewLimitFPS);
|
|
|
|
UFUNCTION()
|
|
float GetFrameRateLimit_WhenBackgrounded() const;
|
|
UFUNCTION()
|
|
void SetFrameRateLimit_WhenBackgrounded(float NewLimitFPS);
|
|
|
|
UFUNCTION()
|
|
float GetFrameRateLimit_Always() const;
|
|
UFUNCTION()
|
|
void SetFrameRateLimit_Always(float NewLimitFPS);
|
|
|
|
protected:
|
|
void UpdateEffectiveFrameRateLimit();
|
|
|
|
private:
|
|
UPROPERTY(Config)
|
|
float FrameRateLimit_OnBattery;
|
|
UPROPERTY(Config)
|
|
float FrameRateLimit_InMenu;
|
|
UPROPERTY(Config)
|
|
float FrameRateLimit_WhenBackgrounded;
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// Display - Mobile quality settings
|
|
public:
|
|
|
|
static int32 GetDefaultMobileFrameRate();
|
|
static int32 GetMaxMobileFrameRate();
|
|
|
|
static bool IsSupportedMobileFramePace(int32 TestFPS);
|
|
|
|
// Returns the first frame rate at which overall quality is restricted/limited by the current device profile
|
|
int32 GetFirstFrameRateWithQualityLimit() const;
|
|
|
|
// Returns the lowest quality at which there's a limit on the overall frame rate (or -1 if there is no limit)
|
|
int32 GetLowestQualityWithFrameRateLimit() const;
|
|
|
|
void ResetToMobileDeviceDefaults();
|
|
|
|
int32 GetMaxSupportedOverallQualityLevel() const;
|
|
|
|
private:
|
|
void SetMobileFPSMode(int32 NewLimitFPS);
|
|
|
|
void ClampMobileResolutionQuality(int32 TargetFPS);
|
|
void RemapMobileResolutionQuality(int32 FromFPS, int32 ToFPS);
|
|
|
|
void ClampMobileFPSQualityLevels(bool bWriteBack);
|
|
void ClampMobileQuality();
|
|
|
|
int32 GetHighestLevelOfAnyScalabilityChannel() const;
|
|
|
|
/* Modifies the input levels based on the active mode's overrides */
|
|
void OverrideQualityLevelsToScalabilityMode(const FLyraScalabilitySnapshot& InMode, Scalability::FQualityLevels& InOutLevels);
|
|
|
|
/* Clamps the input levels based on the active device profile's default allowed levels */
|
|
void ClampQualityLevelsToDeviceProfile(const Scalability::FQualityLevels& ClampLevels, Scalability::FQualityLevels& InOutLevels);
|
|
|
|
public:
|
|
int32 GetDesiredMobileFrameRateLimit() const { return DesiredMobileFrameRateLimit; }
|
|
|
|
void SetDesiredMobileFrameRateLimit(int32 NewLimitFPS);
|
|
|
|
private:
|
|
UPROPERTY(Config)
|
|
int32 MobileFrameRateLimit = 30;
|
|
|
|
FLyraScalabilitySnapshot DeviceDefaultScalabilitySettings;
|
|
|
|
bool bSettingOverallQualityGuard = false;
|
|
|
|
int32 DesiredMobileFrameRateLimit = 0;
|
|
|
|
private:
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// Display - Console quality presets
|
|
public:
|
|
UFUNCTION()
|
|
FString GetDesiredDeviceProfileQualitySuffix() const;
|
|
UFUNCTION()
|
|
void SetDesiredDeviceProfileQualitySuffix(const FString& InDesiredSuffix);
|
|
|
|
protected:
|
|
/** Updates device profiles, FPS mode etc for the current game mode */
|
|
void UpdateGameModeDeviceProfileAndFps();
|
|
|
|
void UpdateConsoleFramePacing();
|
|
void UpdateDesktopFramePacing();
|
|
void UpdateMobileFramePacing();
|
|
|
|
void UpdateDynamicResFrameTime(float TargetFPS);
|
|
|
|
private:
|
|
UPROPERTY(Transient)
|
|
FString DesiredUserChosenDeviceProfileSuffix;
|
|
|
|
UPROPERTY(Transient)
|
|
FString CurrentAppliedDeviceProfileOverrideSuffix;
|
|
|
|
UPROPERTY(config)
|
|
FString UserChosenDeviceProfileSuffix;
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// Audio - Volume
|
|
public:
|
|
DECLARE_EVENT_OneParam(ULyraSettingsLocal, FAudioDeviceChanged, const FString& /*DeviceId*/);
|
|
FAudioDeviceChanged OnAudioOutputDeviceChanged;
|
|
|
|
public:
|
|
/** Returns if we're using headphone mode (HRTF) **/
|
|
UFUNCTION()
|
|
bool IsHeadphoneModeEnabled() const;
|
|
|
|
/** Enables or disables headphone mode (HRTF) - NOTE this setting will be overruled if au.DisableBinauralSpatialization is set */
|
|
UFUNCTION()
|
|
void SetHeadphoneModeEnabled(bool bEnabled);
|
|
|
|
/** Returns if we can enable/disable headphone mode (i.e., if it's not forced on or off by the platform) */
|
|
UFUNCTION()
|
|
bool CanModifyHeadphoneModeEnabled() const;
|
|
|
|
public:
|
|
/** Whether we *want* to use headphone mode (HRTF); may or may not actually be applied **/
|
|
UPROPERTY(Transient)
|
|
bool bDesiredHeadphoneMode;
|
|
|
|
private:
|
|
/** Whether to use headphone mode (HRTF) **/
|
|
UPROPERTY(config)
|
|
bool bUseHeadphoneMode;
|
|
|
|
public:
|
|
/** Returns if we're using High Dynamic Range Audio mode (HDR Audio) **/
|
|
UFUNCTION()
|
|
bool IsHDRAudioModeEnabled() const;
|
|
|
|
/** Enables or disables High Dynamic Range Audio mode (HDR Audio) */
|
|
UFUNCTION()
|
|
void SetHDRAudioModeEnabled(bool bEnabled);
|
|
|
|
/** Whether to use High Dynamic Range Audio mode (HDR Audio) **/
|
|
UPROPERTY(config)
|
|
bool bUseHDRAudioMode;
|
|
|
|
public:
|
|
/** Returns true if this platform can run the auto benchmark */
|
|
UFUNCTION(BlueprintCallable, Category = Settings)
|
|
bool CanRunAutoBenchmark() const;
|
|
|
|
/** Returns true if this user should run the auto benchmark as it has never been run */
|
|
UFUNCTION(BlueprintCallable, Category = Settings)
|
|
bool ShouldRunAutoBenchmarkAtStartup() const;
|
|
|
|
/** Run the auto benchmark, optionally saving right away */
|
|
UFUNCTION(BlueprintCallable, Category = Settings)
|
|
void RunAutoBenchmark(bool bSaveImmediately);
|
|
|
|
/** Apply just the quality scalability settings */
|
|
void ApplyScalabilitySettings();
|
|
|
|
UFUNCTION()
|
|
float GetOverallVolume() const;
|
|
UFUNCTION()
|
|
void SetOverallVolume(float InVolume);
|
|
|
|
UFUNCTION()
|
|
float GetMusicVolume() const;
|
|
UFUNCTION()
|
|
void SetMusicVolume(float InVolume);
|
|
|
|
UFUNCTION()
|
|
float GetSoundFXVolume() const;
|
|
UFUNCTION()
|
|
void SetSoundFXVolume(float InVolume);
|
|
|
|
UFUNCTION()
|
|
float GetDialogueVolume() const;
|
|
UFUNCTION()
|
|
void SetDialogueVolume(float InVolume);
|
|
|
|
UFUNCTION()
|
|
float GetVoiceChatVolume() const;
|
|
UFUNCTION()
|
|
void SetVoiceChatVolume(float InVolume);
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// Audio - Sound
|
|
public:
|
|
/** Returns the user's audio device id */
|
|
UFUNCTION()
|
|
FString GetAudioOutputDeviceId() const { return AudioOutputDeviceId; }
|
|
|
|
/** Sets the user's audio device by id */
|
|
UFUNCTION()
|
|
void SetAudioOutputDeviceId(const FString& InAudioOutputDeviceId);
|
|
|
|
private:
|
|
UPROPERTY(Config)
|
|
FString AudioOutputDeviceId;
|
|
|
|
void SetVolumeForSoundClass(FName ChannelName, float InVolume);
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// Safezone
|
|
public:
|
|
UFUNCTION()
|
|
bool IsSafeZoneSet() const { return SafeZoneScale != -1; }
|
|
UFUNCTION()
|
|
float GetSafeZone() const { return SafeZoneScale >= 0 ? SafeZoneScale : 0; }
|
|
UFUNCTION()
|
|
void SetSafeZone(float Value) { SafeZoneScale = Value; ApplySafeZoneScale(); }
|
|
|
|
void ApplySafeZoneScale();
|
|
private:
|
|
void SetVolumeForControlBus(USoundControlBus* InSoundControlBus, float InVolume);
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// Keybindings
|
|
public:
|
|
|
|
|
|
// Sets the controller representation to use, a single platform might support multiple kinds of controllers. For
|
|
// example, Win64 games could be played with both an XBox or Playstation controller.
|
|
UFUNCTION()
|
|
void SetControllerPlatform(const FName InControllerPlatform);
|
|
UFUNCTION()
|
|
FName GetControllerPlatform() const;
|
|
|
|
DECLARE_EVENT_OneParam(ULyraSettingsLocal, FInputConfigDelegate, const FLoadedMappableConfigPair& /*Config*/);
|
|
|
|
/** Delegate called when a new input config has been registered */
|
|
FInputConfigDelegate OnInputConfigRegistered;
|
|
|
|
/** Delegate called when a registered input config has been activated */
|
|
FInputConfigDelegate OnInputConfigActivated;
|
|
|
|
/** Delegate called when a registered input config has been deactivate */
|
|
FInputConfigDelegate OnInputConfigDeactivated;
|
|
|
|
/** Register the given input config with the settings to make it available to the player. */
|
|
void RegisterInputConfig(ECommonInputType Type, const UPlayerMappableInputConfig* NewConfig, const bool bIsActive);
|
|
|
|
/** Unregister the given input config. Returns the number of configs removed. */
|
|
int32 UnregisterInputConfig(const UPlayerMappableInputConfig* ConfigToRemove);
|
|
|
|
/** Get an input config with a certain name. If the config doesn't exist then nullptr will be returned. */
|
|
UFUNCTION(BlueprintCallable)
|
|
const UPlayerMappableInputConfig* GetInputConfigByName(FName ConfigName) const;
|
|
|
|
/** Get all currently registered input configs */
|
|
const TArray<FLoadedMappableConfigPair>& GetAllRegisteredInputConfigs() const { return RegisteredInputConfigs; }
|
|
|
|
/**
|
|
* Get all registered input configs that match the input type.
|
|
*
|
|
* @param Type The type of config to get, ECommonInputType::Count will include all configs.
|
|
* @param OutArray Array to be populated with the current registered input configs that match the type
|
|
*/
|
|
void GetRegisteredInputConfigsOfType(ECommonInputType Type, OUT TArray<FLoadedMappableConfigPair>& OutArray) const;
|
|
|
|
/**
|
|
* Returns the display name of any actions with that key bound to it
|
|
*
|
|
* @param InKey The key to check for current mappings of
|
|
* @param OutActionNames Array to store display names of actions of bound keys
|
|
*/
|
|
void GetAllMappingNamesFromKey(const FKey InKey, TArray<FName>& OutActionNames);
|
|
|
|
/**
|
|
* Maps the given keyboard setting to the new key
|
|
*
|
|
* @param MappingName The name of the FPlayerMappableKeyOptions that you would like to change
|
|
* @param NewKey The new key to bind this option to
|
|
* @param LocalPlayer local player to reset the keybinding on
|
|
*/
|
|
void AddOrUpdateCustomKeyboardBindings(const FName MappingName, const FKey NewKey, ULyraLocalPlayer* LocalPlayer);
|
|
|
|
/**
|
|
* Resets keybinding to its default value in its input mapping context
|
|
*
|
|
* @param MappingName The name of the FPlayerMappableKeyOptions that you would like to change
|
|
* @param LocalPlayer local player to reset the keybinding on
|
|
*/
|
|
void ResetKeybindingToDefault(const FName MappingName, ULyraLocalPlayer* LocalPlayer);
|
|
|
|
/** Resets all keybindings to their default value in their input mapping context
|
|
* @param LocalPlayer local player to reset the keybinding on
|
|
*/
|
|
void ResetKeybindingsToDefault(ULyraLocalPlayer* LocalPlayer);
|
|
|
|
const TMap<FName, FKey>& GetCustomPlayerInputConfig() const { return CustomKeyboardConfig; }
|
|
|
|
private:
|
|
void LoadUserControlBusMix();
|
|
|
|
UPROPERTY(Config)
|
|
float OverallVolume = 1.0f;
|
|
UPROPERTY(Config)
|
|
float MusicVolume = 1.0f;
|
|
UPROPERTY(Config)
|
|
float SoundFXVolume = 1.0f;
|
|
UPROPERTY(Config)
|
|
float DialogueVolume = 1.0f;
|
|
UPROPERTY(Config)
|
|
float VoiceChatVolume = 1.0f;
|
|
|
|
UPROPERTY(Transient)
|
|
TMap<FName/*SoundClassName*/, TObjectPtr<USoundControlBus>> ControlBusMap;
|
|
|
|
UPROPERTY(Transient)
|
|
TObjectPtr<USoundControlBusMix> ControlBusMix = nullptr;
|
|
|
|
UPROPERTY(Transient)
|
|
bool bSoundControlBusMixLoaded;
|
|
|
|
UPROPERTY(Config)
|
|
float SafeZoneScale = -1;
|
|
|
|
/**
|
|
* The name of the controller the player is using. This is maps to the name of a UCommonInputBaseControllerData
|
|
* that is available on this current platform. The gamepad data are registered per platform, you'll find them
|
|
* in <Platform>Game.ini files listed under +ControllerData=...
|
|
*/
|
|
UPROPERTY(Config)
|
|
FName ControllerPlatform;
|
|
|
|
UPROPERTY(Config)
|
|
FName ControllerPreset = TEXT("Default");
|
|
|
|
/** The name of the current input config that the user has selected. */
|
|
UPROPERTY(Config)
|
|
FName InputConfigName = TEXT("Default");
|
|
|
|
/**
|
|
* Array of currently registered input configs. This is populated by game feature plugins
|
|
*
|
|
* @see UGameFeatureAction_AddInputConfig
|
|
*/
|
|
UPROPERTY(VisibleAnywhere)
|
|
TArray<FLoadedMappableConfigPair> RegisteredInputConfigs;
|
|
|
|
/** Array of custom key mappings that have been set by the player. Empty by default. */
|
|
UPROPERTY(Config)
|
|
TMap<FName, FKey> CustomKeyboardConfig;
|
|
|
|
private:
|
|
void OnAppActivationStateChanged(bool bIsActive);
|
|
void ReapplyThingsDueToPossibleDeviceProfileChange();
|
|
|
|
private:
|
|
FDelegateHandle OnApplicationActivationStateChangedHandle;
|
|
};
|