// Copyright Epic Games, Inc. All Rights Reserved.

#include "GameFramework/GameUserSettings.h"
#include "HAL/FileManager.h"
#include "Misc/ConfigCacheIni.h"
#include "HAL/IConsoleManager.h"
#include "GenericPlatform/GenericApplication.h"
#include "Misc/App.h"
#include "EngineGlobals.h"
#include "Kismet/KismetSystemLibrary.h"
#include "Engine/GameViewportClient.h"
#include "UnrealEngine.h"
#include "Framework/Application/SlateApplication.h"
#include "Engine/GameEngine.h"
#include "Sound/AudioSettings.h"
#include "Sound/SoundCue.h"
#include "AudioDevice.h"
#include "DynamicResolutionState.h"
#include "HAL/PlatformFramePacer.h"

extern EWindowMode::Type GetWindowModeType(EWindowMode::Type WindowMode);

enum EGameUserSettingsVersion
{
  /** Version for user game settings. All settings will be wiped if the serialized version differs. */
  UE_GAMEUSERSETTINGS_VERSION 5
};


UGameUserSettings::UGameUserSettings(const FObjectInitializerObjectInitializer)
  Super(ObjectInitializer)
{
  // this will only call the base version of SetToDefaults but some constructors may rely on it being set
  SetToDefaults();
}

FIntPoint UGameUserSettings::GetScreenResolution() const
{
  return FIntPoint(ResolutionSizeXResolutionSizeY);
}

FIntPoint UGameUserSettings::GetLastConfirmedScreenResolution() const
{
  return FIntPoint(LastUserConfirmedResolutionSizeXLastUserConfirmedResolutionSizeY);
}

FIntPoint UGameUserSettings::GetDesktopResolution() const
{
  FDisplayMetrics DisplayMetrics;
  if (FSlateApplication::IsInitialized())
  {
    FSlateApplication::Get().GetInitialDisplayMetrics(DisplayMetrics);
  }
  else
  {
    if (FApp::CanEverRender())
    {
      FDisplayMetrics::RebuildDisplayMetrics(DisplayMetrics);
    }
    else
    {
      // assume headless
      DisplayMetrics.PrimaryDisplayWidth 0;
      DisplayMetrics.PrimaryDisplayHeight 0;
    }
  }
  return FIntPoint(DisplayMetrics.PrimaryDisplayWidthDisplayMetrics.PrimaryDisplayHeight);
}

void UGameUserSettings::SetScreenResolution(FIntPoint Resolution)
{
  if (ResolutionSizeX != Resolution.|| ResolutionSizeY != Resolution.Y)
  {
    ResolutionSizeX Resolution.X;
    ResolutionSizeY Resolution.Y;
    UpdateResolutionQuality();
  }
}

static EWindowMode::Type GetPlatformFullscreenMode(int InFullscreenMode)
{
  EWindowMode::Type Mode EWindowMode::ConvertIntToWindowMode(InFullscreenMode);

  return (!FPlatformProperties::SupportsWindowedMode()) ? EWindowMode::Fullscreen Mode;
}

EWindowMode::Type UGameUserSettings::GetFullscreenMode() const
{
  return GetPlatformFullscreenMode(FullscreenMode);
}

EWindowMode::Type UGameUserSettings::GetLastConfirmedFullscreenMode() const
{
  return GetPlatformFullscreenMode(LastConfirmedFullscreenMode);
}

void UGameUserSettings::SetFullscreenMode(EWindowMode::Type InFullscreenMode)
{
  if (FullscreenMode != InFullscreenMode)
  {
    switch (InFullscreenMode)
    {
    case EWindowMode::Fullscreen:
      FullscreenMode 0;
      break;
    case EWindowMode::WindowedFullscreen:
      FullscreenMode 1;
      break;
    case EWindowMode::Windowed:
    default:
      FullscreenMode 2;
      break;
    }

    UpdateResolutionQuality();
  }
}

EWindowMode::Type UGameUserSettings::GetPreferredFullscreenMode() const
{
  return PreferredFullscreenMode == EWindowMode::Fullscreen EWindowMode::WindowedFullscreen;
}

void UGameUserSettings::SetVSyncEnabled(bool bEnable)
{
  bUseVSync bEnable;
}

bool UGameUserSettings::IsVSyncEnabled() const
{
  return bUseVSync;
}

void UGameUserSettings::SetDynamicResolutionEnabled(bool bEnable)
{
  bUseDynamicResolution bEnable;
}

bool UGameUserSettings::IsDynamicResolutionEnabled() const
{
  return bUseDynamicResolution;
}

bool UGameUserSettings::IsScreenResolutionDirty() const
{
  bool bIsDirty false;
  if (GEngine && GEngine->GameViewport && GEngine->GameViewport->ViewportFrame)
  {
    bIsDirty = (ResolutionSizeX != GSystemResolution.ResX || ResolutionSizeY != GSystemResolution.ResY) ? true false;
  }
  return bIsDirty;
}

bool UGameUserSettings::IsFullscreenModeDirty() const
{
  bool bIsDirty false;
  if (GEngine && GEngine->GameViewport && GEngine->GameViewport->ViewportFrame)
  {
    EWindowMode::Type CurrentFullscreenMode GEngine->GameViewport->Viewport->GetWindowMode();
    EWindowMode::Type NewFullscreenMode GetFullscreenMode();
    bIsDirty = (CurrentFullscreenMode != NewFullscreenMode);
  }
  return bIsDirty;
}

bool UGameUserSettings::IsVSyncDirty() const
{
  bool bIsDirty false;
  if (GEngine && GEngine->GameViewport && GEngine->GameViewport->ViewportFrame)
  {
    static const auto CVar IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.VSync"));
    bIsDirty = (bUseVSync != (CVar->GetValueOnGameThread() != 0));
  }
  return bIsDirty;
}

bool UGameUserSettings::IsDynamicResolutionDirty() const
{
  bool bIsDirty false;
  if (GEngine && GEngine->GameViewport && GEngine->GameViewport->ViewportFrame)
  {
    bIsDirty = (bUseDynamicResolution != GEngine->GetDynamicResolutionUserSetting());
  }
  return bIsDirty;
}

bool UGameUserSettings::IsDirty() const
{
  return IsScreenResolutionDirty() || IsFullscreenModeDirty() || IsVSyncDirty() || IsDynamicResolutionDirty();
}

void UGameUserSettings::ConfirmVideoMode()
{
  LastConfirmedFullscreenMode FullscreenMode;
  LastUserConfirmedResolutionSizeX ResolutionSizeX;
  LastUserConfirmedResolutionSizeY ResolutionSizeY;
}

void UGameUserSettings::RevertVideoMode()
{
  FullscreenMode LastConfirmedFullscreenMode;
  ResolutionSizeX LastUserConfirmedResolutionSizeX;
  ResolutionSizeY LastUserConfirmedResolutionSizeY;
}

void UGameUserSettings::SetToDefaults()
{
  ResolutionSizeX LastUserConfirmedResolutionSizeX GetDefaultResolution().X;
  ResolutionSizeY LastUserConfirmedResolutionSizeY GetDefaultResolution().Y;
  WindowPosX GetDefaultWindowPosition().X;
  WindowPosY GetDefaultWindowPosition().Y;
  FullscreenMode GetDefaultWindowMode();
  FrameRateLimit 0.0f;
  MinResolutionScale Scalability::MinResolutionScale;
  DesiredScreenWidth 1280;
  DesiredScreenHeight 720;
  LastUserConfirmedDesiredScreenWidth DesiredScreenWidth;
  LastUserConfirmedDesiredScreenHeight DesiredScreenHeight;
  LastCPUBenchmarkResult = -1.0f;
  LastGPUBenchmarkResult = -1.0f;
  LastCPUBenchmarkSteps.Empty();
  LastGPUBenchmarkSteps.Empty();
  LastGPUBenchmarkMultiplier 1.0f;
  LastRecommendedScreenWidth = -1.0f;
  LastRecommendedScreenHeight = -1.0f;

  static const auto CVar IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.FullScreenMode"));
  PreferredFullscreenMode CVar->GetValueOnGameThread();

  ScalabilityQuality.SetDefaults();

  if (FApp::CanEverRender())
  {
    UpdateResolutionQuality();
  }

  bUseDynamicResolution false;
  bUseHDRDisplayOutput FPlatformMisc::UseHDRByDefault();
  HDRDisplayOutputNits 1000;
}

bool UGameUserSettings::IsVersionValid()
{
  return (Version == UE_GAMEUSERSETTINGS_VERSION);
}

void UGameUserSettings::UpdateVersion()
{
  Version UE_GAMEUSERSETTINGS_VERSION;
}

void UGameUserSettings::UpdateResolutionQuality()
{
  const int32 MinHeight UKismetSystemLibrary::GetMinYResolutionFor3DView();
  const int32 ScreenWidth = (FullscreenMode == EWindowMode::WindowedFullscreen) ? GetDesktopResolution().ResolutionSizeX;
  const int32 ScreenHeight = (FullscreenMode == EWindowMode::WindowedFullscreen) ? GetDesktopResolution().ResolutionSizeY;
  MinResolutionScale FMath::Max<float>(Scalability::MinResolutionScale, ((float)MinHeight / (float)ScreenHeight) * 100.0f);

  if (bUseDesiredScreenHeight)
  {
    ScalabilityQuality.ResolutionQuality GetDefaultResolutionScale();
  }
  else
  {
    ScalabilityQuality.ResolutionQuality FMath::Max(ScalabilityQuality.ResolutionQualityMinResolutionScale);
  }
}

float UGameUserSettings::GetDefaultResolutionScale()
{
  const int32 ScreenWidth = (FullscreenMode == EWindowMode::WindowedFullscreen) ? GetDesktopResolution().ResolutionSizeX;
  const int32 ScreenHeight = (FullscreenMode == EWindowMode::WindowedFullscreen) ? GetDesktopResolution().ResolutionSizeY;
  const int32 ClampedWidth = (ScreenWidth && DesiredScreenWidth ScreenWidth) ? ScreenWidth DesiredScreenWidth;
  const int32 ClampedHeight = (ScreenHeight && DesiredScreenHeight ScreenHeight) ? ScreenHeight DesiredScreenHeight;

  const float DesiredResQuality FindResolutionQualityForScreenSize(ClampedWidthClampedHeight);
  return FMath::Max(DesiredResQualityMinResolutionScale);
}

float UGameUserSettings::GetRecommendedResolutionScale()
{
  const float RecommendedResQuality FindResolutionQualityForScreenSize(LastRecommendedScreenWidthLastRecommendedScreenHeight);

  return FMath::Max(RecommendedResQualityMinResolutionScale);
}

float UGameUserSettings::FindResolutionQualityForScreenSize(float Widthfloat Height)
{
  float ResolutionQuality 100.0f;

  const FIntPoint ScreenSize = (FullscreenMode == EWindowMode::WindowedFullscreen) ? GetDesktopResolution() : FIntPoint(ResolutionSizeXResolutionSizeY);
  const float ScreenAspectRatio = (float)ScreenSize./ (float)ScreenSize.Y;
  const float AspectRatio Width Height;

  // If the screen aspect ratio is different than the target resolution's aspect ratio, we need to adjust the target width and height
  if (!FMath::IsNearlyEqual(ScreenAspectRatioAspectRatio))
  {
    if (ScreenAspectRatio AspectRatio)
    {
      // For smaller aspect ratios we allow more vertical space so that the screen width matches the width of the original mode
      Height = (Height AspectRatio) / ScreenAspectRatio;
    }
    else
    {
      // For wider screens we try to choose a screen size that'd have similar total number of pixels as the original mode
      Height FMath::Sqrt((Height Height AspectRatio) / ScreenAspectRatio);
    }
    Width Height AspectRatio;
  }

  if (Height ScreenSize.Y)
  {
    ResolutionQuality = ((float)Height / (float)ScreenSize.Y) * 100.0f;
  }

  return ResolutionQuality;
}

void UGameUserSettings::SetFrameRateLimitCVar(float InLimit)
{
  GEngine->SetMaxFPS(FMath::Max(InLimit0.0f));
}

void UGameUserSettings::SetSyncIntervalCVar(int32 InInterval)
{
  static IConsoleVariableSyncIntervalCVar IConsoleManager::Get().FindConsoleVariable(TEXT("rhi.syncinterval"));
  if (ensure(SyncIntervalCVar))
  {
    SyncIntervalCVar->Set(InIntervalECVF_SetByCode);
  }
}

void UGameUserSettings::SetSyncTypeCVar(int32 InType)
{
  static IConsoleVariableSyncIntervalCVar IConsoleManager::Get().FindConsoleVariable(TEXT("r.GTSyncType"));
  if (ensure(SyncIntervalCVar))
  {
    SyncIntervalCVar->Set(InTypeECVF_SetByCode);
  }
}

float UGameUserSettings::GetEffectiveFrameRateLimit()
{
  return FrameRateLimit;
}

void UGameUserSettings::SetPreferredFullscreenMode(int32 Mode)
{
  PreferredFullscreenMode Mode;

  auto CVar IConsoleManager::Get().FindConsoleVariable(TEXT("r.FullScreenMode"));
  if (CVar)
  {
    CVar->Set(ModeECVF_SetByGameSetting);
  }
}

void UGameUserSettings::ValidateSettings()
{
  // Should we wipe all user settings?
  if (!IsVersionValid())
  {
    // First try loading the settings, if they haven't been loaded before.
    LoadSettings(true);

    // If it still an old version, delete the user settings file and reload defaults.
    if (!IsVersionValid())
    {
      // Force reset if there aren't any default .ini settings.
      SetToDefaults();
      static const auto CVarVSync IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.VSync"));
      SetVSyncEnabled(CVarVSync->GetValueOnGameThread() != 0);

      if (GEngine)
      {
        SetDynamicResolutionEnabled(GEngine->GetDynamicResolutionUserSetting());
      }

      IFileManager::Get().Delete(*GGameUserSettingsIni);
      LoadSettings(true);
    }
  }

  if (ResolutionSizeX <= || ResolutionSizeY <= 0)
  {
    SetScreenResolution(FIntPoint(GSystemResolution.ResXGSystemResolution.ResY));

    // Set last confirmed video settings
    LastConfirmedFullscreenMode FullscreenMode;
    LastUserConfirmedResolutionSizeX ResolutionSizeX;
    LastUserConfirmedResolutionSizeY ResolutionSizeY;
  }

  const int32 ScreenWidth = (FullscreenMode == EWindowMode::WindowedFullscreen) ? GetDesktopResolution().ResolutionSizeX;
  const int32 ScreenHeight = (FullscreenMode == EWindowMode::WindowedFullscreen) ? GetDesktopResolution().ResolutionSizeY;
  const int32 ClampedWidth = (ScreenWidth && DesiredScreenWidth ScreenWidth) ? ScreenWidth DesiredScreenWidth;
  const int32 ClampedHeight = (ScreenHeight && DesiredScreenHeight ScreenHeight) ? ScreenHeight DesiredScreenHeight;

  LastUserConfirmedDesiredScreenWidth DesiredScreenWidth;
  LastUserConfirmedDesiredScreenHeight DesiredScreenHeight;


  // We do not modify the user setting on console if HDR is not supported
  if (!FPlatformMisc::UseHDRByDefault())
  {
    if (bUseHDRDisplayOutput && !SupportsHDRDisplayOutput())
    {
      bUseHDRDisplayOutput false;
    }
  }

  LastConfirmedAudioQualityLevel AudioQualityLevel;

  // The user settings have now been validated for the current version.
  UpdateVersion();
}

void UGameUserSettings::ApplyNonResolutionSettings()
{
  QUICK_SCOPE_CYCLE_COUNTER(GameUserSettings_ApplyNonResolutionSettings);

  ValidateSettings();

  // Update vsync cvar
  {
    FString ConfigSection TEXT("SystemSettings");
#if WITH_EDITOR
    if (GIsEditor)
    {
      ConfigSection TEXT("SystemSettingsEditor");
    }
#endif
    int32 VSyncValue 0;
    if (GConfig->GetInt(*ConfigSectionTEXT("r.Vsync"), VSyncValueGEngineIni))
    {
      // VSync was already set by system settings. We are capable of setting it here.
    }
    else
    {
      static auto CVar IConsoleManager::Get().FindConsoleVariable(TEXT("r.VSync"));
      CVar->Set(IsVSyncEnabled(), ECVF_SetByGameSetting);
    }
  }

  GEngine->SetDynamicResolutionUserSetting(IsDynamicResolutionEnabled());

  if (!IsRunningDedicatedServer())
  {
    SetFrameRateLimitCVar(GetEffectiveFrameRateLimit());
  }

  // in init those are loaded earlier, after that we apply consolevariables.ini
  if (GEngine->IsInitialized())
  {
    Scalability::SetQualityLevels(ScalabilityQuality);
  }

  FAudioDeviceHandle AudioDevice GEngine->GetMainAudioDevice();
  if (AudioDevice)
  {
    FAudioQualitySettings AudioSettings AudioDevice->GetQualityLevelSettings();
    AudioDevice->SetMaxChannels(AudioSettings.MaxChannels);
  }

  IConsoleManager::Get().CallAllConsoleVariableSinks();

  bool bWithEditor false;
#if WITH_EDITOR
  if (GIsEditor)
  {
    bWithEditor true;
  }
#endif

  bool bEnableHDR = (IsHDRAllowed() && bUseHDRDisplayOutput && !bWithEditor);

  EnableHDRDisplayOutput(bEnableHDRHDRDisplayOutputNits);

}

void UGameUserSettings::ApplyResolutionSettings(bool bCheckForCommandLineOverrides)
{
#if UE_SERVER
  return;
#endif
  QUICK_SCOPE_CYCLE_COUNTER(GameUserSettings_ApplyResolutionSettings);

  ValidateSettings();

  EWindowMode::Type NewFullscreenMode GetFullscreenMode();

  // Request a resolution change
  RequestResolutionChange(ResolutionSizeXResolutionSizeYNewFullscreenModebCheckForCommandLineOverrides);

  if (NewFullscreenMode == EWindowMode::Fullscreen || NewFullscreenMode == EWindowMode::WindowedFullscreen)
  {
    SetPreferredFullscreenMode(NewFullscreenMode == EWindowMode::Fullscreen 1);
  }

  IConsoleManager::Get().CallAllConsoleVariableSinks();
}

void UGameUserSettings::ApplySettings(bool bCheckForCommandLineOverrides)
{
  ApplyResolutionSettings(bCheckForCommandLineOverrides);
  ApplyNonResolutionSettings();
  RequestUIUpdate();

  SaveSettings();
}

void UGameUserSettings::LoadSettings(bool bForceReload/*=false*/)
{
  QUICK_SCOPE_CYCLE_COUNTER(GameUserSettings_LoadSettings);

  if (bForceReload)
  {
    LoadConfigIni(bForceReload);
  }
  LoadConfig(GetClass(), *GGameUserSettingsIni);

  // Note: Scalability::LoadState() should not be needed as we already loaded the settings earlier (needed so the engine can startup with that before the game is initialized)
  ScalabilityQuality Scalability::GetQualityLevels();

  // Allow override using command-line settings
  bool bDetectingResolution ResolutionSizeX == || ResolutionSizeY == 0;

  if (bDetectingResolution)
  {
    ConfirmVideoMode();
  }

  // Update r.FullScreenMode CVar
  SetPreferredFullscreenMode(PreferredFullscreenMode);
}

void UGameUserSettings::RequestResolutionChange(int32 InResolutionXint32 InResolutionYEWindowMode::Type InWindowModebool bInDoOverrides /* = true */)
{
  if (bInDoOverrides)
  {
    UGameEngine::ConditionallyOverrideSettings(InResolutionXInResolutionYInWindowMode);
  }

  FSystemResolution::RequestResolutionChange(InResolutionXInResolutionYInWindowMode);
}

void UGameUserSettings::SaveSettings()
{
  QUICK_SCOPE_CYCLE_COUNTER(GameUserSettings_SaveSettings);

  // Save the Scalability state to the same ini file as it was loaded from in FEngineLoop::Preinit
  Scalability::SaveState(GIsEditor GEditorSettingsIni GGameUserSettingsIni);
  SaveConfig(CPF_Config, *GGameUserSettingsIni);
}

void UGameUserSettings::LoadConfigIni(bool bForceReload/*=false*/)
{
  // Load .ini, allowing merging
  FConfigCacheIni::LoadGlobalIniFile(GGameUserSettingsIniTEXT("GameUserSettings"), nullptrbForceReloadfalsetruetrue, *FPaths::GeneratedConfigDir());
}

void UGameUserSettings::PreloadResolutionSettings(bool bAllowCmdLineOverrides /*= true*/)
{
  // Note: This preloads resolution settings without loading the user settings object.  
  // When changing this code care must be taken to ensure the window starts at the same resolution as the in game resolution
  LoadConfigIni();

  FString ScriptEngineCategory TEXT("/Script/Engine.Engine");
  FString GameUserSettingsCategory TEXT("/Script/Engine.GameUserSettings");

  GConfig->GetString(*ScriptEngineCategoryTEXT("GameUserSettingsClassName"), GameUserSettingsCategoryGEngineIni);

  int32 ResolutionX GetDefaultResolution().X;
  int32 ResolutionY GetDefaultResolution().Y;
  EWindowMode::Type WindowMode GetDefaultWindowMode();
  bool bUseDesktopResolution false;
  bool bUseHDR FPlatformMisc::UseHDRByDefault();

  int32 Version 0;
  if (GConfig->GetInt(*GameUserSettingsCategoryTEXT("Version"), VersionGGameUserSettingsIni) && Version == UE_GAMEUSERSETTINGS_VERSION)
  {
    GConfig->GetBool(*GameUserSettingsCategoryTEXT("bUseDesktopResolution"), bUseDesktopResolutionGGameUserSettingsIni);

    int32 WindowModeInt = (int32)WindowMode;
    GConfig->GetInt(*GameUserSettingsCategoryTEXT("FullscreenMode"), WindowModeIntGGameUserSettingsIni);
    WindowMode EWindowMode::ConvertIntToWindowMode(WindowModeInt);

    GConfig->GetInt(*GameUserSettingsCategoryTEXT("ResolutionSizeX"), ResolutionXGGameUserSettingsIni);
    GConfig->GetInt(*GameUserSettingsCategoryTEXT("ResolutionSizeY"), ResolutionYGGameUserSettingsIni);

#if PLATFORM_DESKTOP
    if (bUseDesktopResolution && ResolutionX == && ResolutionY == && WindowMode != EWindowMode::Windowed)
    {
      // Grab display metrics so we can get the primary display output size.
      FDisplayMetrics DisplayMetrics;
      FDisplayMetrics::RebuildDisplayMetrics(DisplayMetrics);

      ResolutionX DisplayMetrics.PrimaryDisplayWidth;
      ResolutionY DisplayMetrics.PrimaryDisplayHeight;
    }
#endif

    GConfig->GetBool(*GameUserSettingsCategoryTEXT("bUseHDRDisplayOutput"), bUseHDRGGameUserSettingsIni);
  }

#if !PLATFORM_MANAGES_HDR_SETTING
  if (IsHDRAllowed())
  {
    // Set the user-preference HDR switch
    static auto CVarHDROutputEnabled IConsoleManager::Get().FindConsoleVariable(TEXT("r.HDR.EnableHDROutput"));
    if (CVarHDROutputEnabled)
    {
      CVarHDROutputEnabled->Set(bUseHDR 0ECVF_SetByGameSetting);
    }
  }
#endif

  RequestResolutionChange(ResolutionXResolutionYWindowModebAllowCmdLineOverrides);

  IConsoleManager::Get().CallAllConsoleVariableSinks();
}

FIntPoint UGameUserSettings::GetDefaultResolution()
{
  return FIntPoint::ZeroValue;
}

FIntPoint UGameUserSettings::GetDefaultWindowPosition()
{
  return FIntPoint(-1, -1);
}

EWindowMode::Type UGameUserSettings::GetDefaultWindowMode()
{
  // WindowedFullscreen should be the general default for games
  return EWindowMode::WindowedFullscreen;
}

int32 UGameUserSettings::GetSyncInterval()
{
  static IConsoleVariableSyncIntervalCVar IConsoleManager::Get().FindConsoleVariable(TEXT("rhi.syncinterval"));
  if (ensure(SyncIntervalCVar))
  {
    return SyncIntervalCVar->GetInt();
  }
  else
  {
    return 0;
  }
}

int32 UGameUserSettings::GetFramePace()
{
  return FPlatformRHIFramePacer::GetFramePace();
}

void UGameUserSettings::ResetToCurrentSettings()
{
  if (GEngine && GEngine->GameViewport && GEngine->GameViewport->GetWindow().IsValid())
  {
    //handle the fullscreen setting
    SetFullscreenMode(GetWindowModeType(GEngine->GameViewport->GetWindow()->GetWindowMode()));

    //set the current resolution
    SetScreenResolution(FIntPoint(GSystemResolution.ResXGSystemResolution.ResY));

    // Set the current VSync state
    static const auto CVarVSync IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.VSync"));
    SetVSyncEnabled(CVarVSync->GetValueOnGameThread() != 0);

    // Set the current dynamic resolution state
    SetDynamicResolutionEnabled(GEngine->GetDynamicResolutionUserSetting());

    // Reset to confirmed settings
    FullscreenMode LastConfirmedFullscreenMode;
    ResolutionSizeX LastUserConfirmedResolutionSizeX;
    ResolutionSizeY LastUserConfirmedResolutionSizeY;

    DesiredScreenWidth LastUserConfirmedDesiredScreenWidth;
    DesiredScreenHeight LastUserConfirmedDesiredScreenHeight;

    // Reset the quality settings to the current levels
    ScalabilityQuality Scalability::GetQualityLevels();

    // Reset the audio quality level
    AudioQualityLevel LastConfirmedAudioQualityLevel;

    UpdateResolutionQuality();
  }
}

void UGameUserSettings::SetWindowPosition(int32 WinXint32 WinY)
{
  WindowPosX WinX;
  WindowPosY WinY;
}

FIntPoint UGameUserSettings::GetWindowPosition()
{
  return FIntPoint(WindowPosXWindowPosY);
}

void UGameUserSettings::SetBenchmarkFallbackValues()
{
  ScalabilityQuality.SetBenchmarkFallback();
}

void UGameUserSettings::SetAudioQualityLevel(int32 QualityLevel)
{
  if (AudioQualityLevel != QualityLevel)
  {
    AudioQualityLevel QualityLevel;

    USoundCue::StaticAudioQualityChanged(QualityLevel);
  }
}

void UGameUserSettings::SetFrameRateLimit(float NewLimit)
{
  FrameRateLimit NewLimit;
}

float UGameUserSettings::GetFrameRateLimit() const
{
  return FrameRateLimit;
}

void UGameUserSettings::SetOverallScalabilityLevel(int32 Value)
{
  ScalabilityQuality.SetFromSingleQualityLevel(Value);
}

int32 UGameUserSettings::GetOverallScalabilityLevel() const
{
  return ScalabilityQuality.GetSingleQualityLevel();
}

void UGameUserSettings::GetResolutionScaleInformation(floatCurrentScaleNormalizedint32CurrentScaleValueint32MinScaleValueint32MaxScaleValueconst
{
  CurrentScaleValue ScalabilityQuality.ResolutionQuality;
  MinScaleValue MinResolutionScale;
  MaxScaleValue Scalability::MaxResolutionScale;
  CurrentScaleNormalized = ((float)CurrentScaleValue - (float)MinScaleValue) / (float)(MaxScaleValue MinScaleValue);
}

void UGameUserSettings::GetResolutionScaleInformationEx(floatCurrentScaleNormalizedfloatCurrentScaleValuefloatMinScaleValuefloatMaxScaleValueconst
{
  CurrentScaleValue ScalabilityQuality.ResolutionQuality;
  MinScaleValue MinResolutionScale;
  MaxScaleValue Scalability::MaxResolutionScale;
  CurrentScaleNormalized = ((float)CurrentScaleValue - (float)MinScaleValue) / (float)(MaxScaleValue MinScaleValue);
}

float UGameUserSettings::GetResolutionScaleNormalized() const
{
  float CurrentScaleNormalizedCurrentScaleValueMinScaleValueMaxScaleValue;
  GetResolutionScaleInformationEx(CurrentScaleNormalizedCurrentScaleValueMinScaleValueMaxScaleValue);

  return CurrentScaleNormalized;
}

void UGameUserSettings::SetResolutionScaleValue(int32 NewScaleValue)
{
  SetResolutionScaleValueEx((float)NewScaleValue);
}

void UGameUserSettings::SetResolutionScaleValueEx(float NewScaleValue)
{
  ScalabilityQuality.ResolutionQuality FMath::Clamp(NewScaleValueMinResolutionScaleScalability::MaxResolutionScale);
  const int32 ScreenWidth = (FullscreenMode == EWindowMode::WindowedFullscreen) ? GetDesktopResolution().ResolutionSizeX;
  const int32 ScreenHeight = (FullscreenMode == EWindowMode::WindowedFullscreen) ? GetDesktopResolution().ResolutionSizeY;
  DesiredScreenWidth ScreenWidth ScalabilityQuality.ResolutionQuality 100.0f;
  DesiredScreenHeight ScreenHeight ScalabilityQuality.ResolutionQuality 100.0f;
}

void UGameUserSettings::SetResolutionScaleNormalized(float NewScaleNormalized)
{
  const float RemappedValue FMath::Lerp((float)MinResolutionScale, (float)Scalability::MaxResolutionScaleNewScaleNormalized);
  SetResolutionScaleValueEx(RemappedValue);
}

void UGameUserSettings::SetViewDistanceQuality(int32 Value)
{
  ScalabilityQuality.SetViewDistanceQuality(Value);
}

int32 UGameUserSettings::GetViewDistanceQuality() const
{
  return ScalabilityQuality.ViewDistanceQuality;
}

void UGameUserSettings::SetShadowQuality(int32 Value)
{
  ScalabilityQuality.SetShadowQuality(Value);
}

int32 UGameUserSettings::GetShadowQuality() const
{
  return ScalabilityQuality.ShadowQuality;
}

void UGameUserSettings::SetAntiAliasingQuality(int32 Value)
{
  ScalabilityQuality.SetAntiAliasingQuality(Value);
}

int32 UGameUserSettings::GetAntiAliasingQuality() const
{
  return ScalabilityQuality.AntiAliasingQuality;
}

void UGameUserSettings::SetTextureQuality(int32 Value)
{
  ScalabilityQuality.SetTextureQuality(Value);
}

int32 UGameUserSettings::GetTextureQuality() const
{
  return ScalabilityQuality.TextureQuality;
}

void UGameUserSettings::SetVisualEffectQuality(int32 Value)
{
  ScalabilityQuality.SetEffectsQuality(Value);
}

int32 UGameUserSettings::GetVisualEffectQuality() const
{
  return ScalabilityQuality.EffectsQuality;
}

void UGameUserSettings::SetPostProcessingQuality(int32 Value)
{
  ScalabilityQuality.SetPostProcessQuality(Value);
}

int32 UGameUserSettings::GetPostProcessingQuality() const
{
  return ScalabilityQuality.PostProcessQuality;
}

void UGameUserSettings::SetFoliageQuality(int32 Value)
{
  ScalabilityQuality.SetFoliageQuality(Value);
}

int32 UGameUserSettings::GetFoliageQuality() const
{
  return ScalabilityQuality.FoliageQuality;
}

void UGameUserSettings::SetShadingQuality(int32 Value)
{
  ScalabilityQuality.SetShadingQuality(Value);
}

int32 UGameUserSettings::GetShadingQuality() const
{
  return ScalabilityQuality.ShadingQuality;
}

UGameUserSettingsUGameUserSettings::GetGameUserSettings()
{
  return GEngine->GetGameUserSettings();
}

void UGameUserSettings::RunHardwareBenchmark(int32 WorkScalefloat CPUMultiplierfloat GPUMultiplier)
{
  ScalabilityQuality Scalability::BenchmarkQualityLevels(WorkScaleCPUMultiplierGPUMultiplier);
  LastCPUBenchmarkResult ScalabilityQuality.CPUBenchmarkResults;
  LastGPUBenchmarkResult ScalabilityQuality.GPUBenchmarkResults;
  LastCPUBenchmarkSteps ScalabilityQuality.CPUBenchmarkSteps;
  LastGPUBenchmarkSteps ScalabilityQuality.GPUBenchmarkSteps;
  LastGPUBenchmarkMultiplier GPUMultiplier;
}

void UGameUserSettings::ApplyHardwareBenchmarkResults()
{
  // Apply the new settings and save them
  Scalability::SetQualityLevels(ScalabilityQuality);
  Scalability::SaveState(GGameUserSettingsIni);

  SaveSettings();
}

bool UGameUserSettings::SupportsHDRDisplayOutput() const
{
  return GRHISupportsHDROutput;
}

void UGameUserSettings::EnableHDRDisplayOutput(bool bEnableint32 DisplayNits /*= 1000*/)
{
  static IConsoleVariableCVarHDROutputEnabled IConsoleManager::Get().FindConsoleVariable(TEXT("r.HDR.EnableHDROutput"));

  if (CVarHDROutputEnabled)
  {
    if (bEnable && !(GRHISupportsHDROutput && IsHDRAllowed()))
    {
      UE_LOG(LogConsoleResponseDisplayTEXT("Tried to enable HDR display output but unsupported or disallowed, forcing off."));
      bEnable false;
    }

    // Only support 1000 and 2000 nit curves so push to closest
    int32 DisplayNitLevel = (DisplayNits 1500) ? 1000 2000;

    // Apply device-specific output encoding
    if (bEnable)
    {
#if PLATFORM_WINDOWS
      if (IsRHIDeviceNVIDIA() || IsRHIDeviceAMD())
      {
        // Force exclusive fullscreen
        SetPreferredFullscreenMode(0);
        SetFullscreenMode(GetPreferredFullscreenMode());
        ApplyResolutionSettings(false);
        RequestUIUpdate();
      }
#endif
      CVarHDROutputEnabled->Set(1ECVF_SetByGameSetting);
    }

    // Always test this branch as can be used to flush errors
    if (!bEnable)
    {
      CVarHDROutputEnabled->Set(0ECVF_SetByGameSetting);
    }

    // Update final requested state for saved config
#if !PLATFORM_PS4 && !PLATFORM_USES_FIXED_HDR_SETTING
    // Do not override the user setting on console (we rely on the OS setting)
    bUseHDRDisplayOutput bEnable;
#endif
    HDRDisplayOutputNits DisplayNitLevel;
  }
}

int32 UGameUserSettings::GetCurrentHDRDisplayNits() const
{
  return bUseHDRDisplayOutput HDRDisplayOutputNits 0;
}

bool UGameUserSettings::IsHDREnabled() const
{
  return bUseHDRDisplayOutput;
}