// Qualite video : un curseur Overall (Low a Epic) et quatre curseurs par groupe Scalability. // // Les quatre groupes sont les ombres, les textures, les effets et l'anti-aliasing // (sg.ShadowQuality, sg.TextureQuality, sg.EffectsQuality, sg.AntiAliasingQuality). // Les autres groupes Scalability, la GI, les VSM et la methode d'AA ne sont jamais ecrits. // Les lignes sont injectees dans SettingsScrollBox avant les reglages de couleur (LPColor*). // Enregistre dans Saved/Config/Windows/LPVideoQuality.ini, pas dans GameSettings.sav. // Voir Docs/Migration/etat/VQ/VQ2/VQ2-SPEC.md. #pragma once #include "CoreMinimal.h" #include "Containers/Ticker.h" #include "Styling/SlateTypes.h" #include "Subsystems/GameInstanceSubsystem.h" #include "LPVideoQualitySubsystem.generated.h" class UButton; class UScrollBox; class USlider; class UTextBlock; class UWidget; class UWorld; USTRUCT() struct FLPVideoLevels { GENERATED_BODY() // 0..3, ou -1 = Custom (les quatre groupes different). UPROPERTY() int32 Overall = 2; UPROPERTY() int32 Shadows = 2; UPROPERTY() int32 Textures = 2; UPROPERTY() int32 Effects = 2; UPROPERTY() int32 AA = 2; // Les quatre groupes valent Level (clampe 0..3), Overall = Level. static FLPVideoLevels FromOverall(int32 Level); // Clamp 0..3 des quatre groupes ; Overall = valeur commune, sinon -1. void Normalize(); bool operator==(const FLPVideoLevels& Other) const; }; UCLASS() class LIFEPLAY_API ULPVideoQualitySubsystem : public UGameInstanceSubsystem { GENERATED_BODY() public: virtual void Initialize(FSubsystemCollectionBase& Collection) override; virtual void Deinitialize() override; // Point d'entree unique de modification (UI, Recommended, VQ3). void SetLevels(FLPVideoLevels NewLevels, bool bFromOverall); FLPVideoLevels GetLevels() const { return Levels; } void RefreshWidgets(); UFUNCTION() void OnOverallChanged(float Value); UFUNCTION() void OnShadowsChanged(float Value); UFUNCTION() void OnTexturesChanged(float Value); UFUNCTION() void OnEffectsChanged(float Value); UFUNCTION() void OnAAChanged(float Value); UFUNCTION() void OnRecommendedClicked(); private: enum ERow { RowOverall, RowShadows, RowTextures, RowEffects, RowAA, NumRows }; struct FRowRefs { TWeakObjectPtr Slider; TWeakObjectPtr Readout; }; bool Tick(float DeltaTime); void EnsureControls(); void Load(); void Save() const; void ApplyToScalability(); void ReadFromScalability(); USlider* AddRow(ERow Row, UScrollBox* Scroll, UWidget*& OutRow, const TCHAR* Name, const TCHAR* Label, FName Handler, const TCHAR* Tip, const FSlateFontInfo& Font, const FSlateColor& Color, const FSliderStyle* SliderStyle); UWidget* MakeRecommendedRow(UScrollBox* Scroll, const FSlateFontInfo& Font, const FSlateColor& Color); static FString LevelLabel(int32 Level); FTSTicker::FDelegateHandle TickHandle; FRowRefs Rows[NumRows]; TWeakObjectPtr RecommendedButton; TWeakObjectPtr LastAppliedWorld; FLPVideoLevels Levels; // Vrai des qu'un INI existe ou que le joueur a modifie un niveau : seulement alors on ecrase l'etat moteur. bool bConfigured = false; // Garde anti-reentrance de RefreshWidgets. bool bRefreshing = false; };