Browse Source

Add fullscreen/windowed toggle. (#379)

* Add fullscreen/windowed toggle.

Signed-off-by: Mike Balfour <[email protected]>

* Make the resolution settings active but not exposed.

Signed-off-by: Mike Balfour <[email protected]>

* Added small comment explaining what the class is.

Signed-off-by: Mike Balfour <[email protected]>

---------

Signed-off-by: Mike Balfour <[email protected]>
Mike Balfour 2 years ago
parent
commit
ceb6730de7

+ 120 - 41
Gem/Code/Source/Components/UI/UiSettingsComponent.cpp

@@ -50,6 +50,8 @@ namespace MultiplayerSample
                 ->Field("GraphicsApi", &UiSettingsComponent::m_graphicsApiToggle)
                 ->Field("TextureQuality", &UiSettingsComponent::m_textureQualityToggle)
                 ->Field("MasterVolume", &UiSettingsComponent::m_masterVolumeToggle)
+                ->Field("Fullscreen", &UiSettingsComponent::m_fullscreenToggle)
+                ->Field("Resolution", &UiSettingsComponent::m_resolutionToggle)
                 ;
 
             if (AZ::EditContext* editContext = serializeContext->GetEditContext())
@@ -60,13 +62,28 @@ namespace MultiplayerSample
                     ->DataElement(AZ::Edit::UIHandlers::Default, &UiSettingsComponent::m_graphicsApiToggle, "Graphics Api", "The Graphics Api toggle elements.")
                     ->DataElement(AZ::Edit::UIHandlers::Default, &UiSettingsComponent::m_textureQualityToggle, "Texture Quality", "The Texture Quality toggle elements.")
                     ->DataElement(AZ::Edit::UIHandlers::Default, &UiSettingsComponent::m_masterVolumeToggle, "Master Volume", "The Master Volume toggle elements.")
+                    ->DataElement(AZ::Edit::UIHandlers::Default, &UiSettingsComponent::m_fullscreenToggle, "Fullscreen", "The Fullscreen toggle elements.")
+                    ->DataElement(AZ::Edit::UIHandlers::Default, &UiSettingsComponent::m_resolutionToggle, "Resolution", "The Resolution toggle elements.")
                     ;
             }
         }
     }
 
+    AzFramework::NativeWindowHandle UiSettingsComponent::GetWindowHandle()
+    {
+        AzFramework::NativeWindowHandle windowHandle = nullptr;
+        AzFramework::WindowSystemRequestBus::BroadcastResult(
+            windowHandle,
+            &AzFramework::WindowSystemRequestBus::Events::GetDefaultWindowHandle);
+
+        return windowHandle;
+    }
+
     void UiSettingsComponent::Activate()
     {
+        // Listen for window notifications so that we can detect fullscreen/windowed changes.
+        AzFramework::WindowNotificationBus::Handler::BusConnect(GetWindowHandle());
+
         // Loads and applies the current user settings when this component activates.
         // The user settings should *already* be loaded and applied at Launcher startup, but connecting to the server
         // and switching levels can cause some engine settings to reset themselves, so this will reapply the desired
@@ -74,45 +91,32 @@ namespace MultiplayerSample
         MultiplayerSampleUserSettingsRequestBus::Broadcast(&MultiplayerSampleUserSettingsRequestBus::Events::Load);
 
         // Initialize the toggles to the current values
-        OnGraphicsApiToggle(ToggleDirection::None);
-        OnTextureQualityToggle(ToggleDirection::None);
-        OnMasterVolumeToggle(ToggleDirection::None);
-
-        // Start listening for button presses
-        UiButtonBus::Event(m_graphicsApiToggle.m_leftButtonEntity, &UiButtonInterface::SetOnClickCallback,
-            [this]([[maybe_unused]] AZ::EntityId buttonEntityId, [[maybe_unused]] AZ::Vector2 position) 
-            { 
-                OnGraphicsApiToggle(ToggleDirection::Left); 
-            });
-        UiButtonBus::Event(m_graphicsApiToggle.m_rightButtonEntity, &UiButtonInterface::SetOnClickCallback,
-            [this]([[maybe_unused]] AZ::EntityId buttonEntityId, [[maybe_unused]] AZ::Vector2 position)
-            {
-                OnGraphicsApiToggle(ToggleDirection::Right);
-            });
-        UiButtonBus::Event(m_textureQualityToggle.m_leftButtonEntity, &UiButtonInterface::SetOnClickCallback,
-            [this]([[maybe_unused]] AZ::EntityId buttonEntityId, [[maybe_unused]] AZ::Vector2 position)
-            {
-                OnTextureQualityToggle(ToggleDirection::Left);
-            });
-        UiButtonBus::Event(m_textureQualityToggle.m_rightButtonEntity, &UiButtonInterface::SetOnClickCallback,
-            [this]([[maybe_unused]] AZ::EntityId buttonEntityId, [[maybe_unused]] AZ::Vector2 position)
-            {
-                OnTextureQualityToggle(ToggleDirection::Right);
-            });
-        UiButtonBus::Event(m_masterVolumeToggle.m_leftButtonEntity, &UiButtonInterface::SetOnClickCallback,
-            [this]([[maybe_unused]] AZ::EntityId buttonEntityId, [[maybe_unused]] AZ::Vector2 position)
-            {
-                OnMasterVolumeToggle(ToggleDirection::Left);
-            });
-        UiButtonBus::Event(m_masterVolumeToggle.m_rightButtonEntity, &UiButtonInterface::SetOnClickCallback,
-            [this]([[maybe_unused]] AZ::EntityId buttonEntityId, [[maybe_unused]] AZ::Vector2 position)
-            {
-                OnMasterVolumeToggle(ToggleDirection::Right);
-            });
+        InitializeToggle(m_graphicsApiToggle, OnGraphicsApiToggle);
+        InitializeToggle(m_textureQualityToggle, OnTextureQualityToggle);
+        InitializeToggle(m_masterVolumeToggle, OnMasterVolumeToggle);
+        InitializeToggle(m_fullscreenToggle, OnFullscreenToggle);
+        InitializeToggle(m_resolutionToggle, OnResolutionToggle);
     }
 
     void UiSettingsComponent::Deactivate()
     {
+        AzFramework::WindowNotificationBus::Handler::BusDisconnect();
+    }
+
+    void UiSettingsComponent::InitializeToggle(UiToggle& toggle, AZStd::function<void(UiToggle&, ToggleDirection)> toggleUpdateFn)
+    {
+        toggleUpdateFn(toggle, ToggleDirection::None);
+
+        UiButtonBus::Event(toggle.m_leftButtonEntity, &UiButtonInterface::SetOnClickCallback,
+            [&toggle, toggleUpdateFn]([[maybe_unused]] AZ::EntityId buttonEntityId, [[maybe_unused]] AZ::Vector2 position)
+            {
+                toggleUpdateFn(toggle, ToggleDirection::Left);
+            });
+        UiButtonBus::Event(toggle.m_rightButtonEntity, &UiButtonInterface::SetOnClickCallback,
+            [&toggle, toggleUpdateFn]([[maybe_unused]] AZ::EntityId buttonEntityId, [[maybe_unused]] AZ::Vector2 position)
+            {
+                toggleUpdateFn(toggle, ToggleDirection::Right);
+            });
     }
 
     template<typename ValueType>
@@ -145,7 +149,7 @@ namespace MultiplayerSample
         }
     }
 
-    void UiSettingsComponent::OnGraphicsApiToggle(ToggleDirection toggleDirection)
+    void UiSettingsComponent::OnGraphicsApiToggle(UiToggle& toggle, ToggleDirection toggleDirection)
     {
         // This list is expected to match the values in AZ::RHI::ApiIndex.
         const AZStd::vector<AZStd::pair<AZStd::string, AZStd::string>> valuesToLabels =
@@ -170,7 +174,7 @@ namespace MultiplayerSample
         // Rotate the index based on toggle direction.
         uint32_t graphicsApiIndex = GetRotatedIndex(valuesToLabels, graphicsApi, toggleDirection);
 
-        UiTextBus::Event(m_graphicsApiToggle.m_labelEntity, &UiTextInterface::SetText, valuesToLabels[graphicsApiIndex].second);
+        UiTextBus::Event(toggle.m_labelEntity, &UiTextInterface::SetText, valuesToLabels[graphicsApiIndex].second);
 
         MultiplayerSampleUserSettingsRequestBus::Broadcast(
             &MultiplayerSampleUserSettingsRequestBus::Events::SetGraphicsApi, valuesToLabels[graphicsApiIndex].first);
@@ -178,7 +182,7 @@ namespace MultiplayerSample
         MultiplayerSampleUserSettingsRequestBus::Broadcast(&MultiplayerSampleUserSettingsRequestBus::Events::Save);
     }
 
-    void UiSettingsComponent::OnTextureQualityToggle(ToggleDirection toggleDirection)
+    void UiSettingsComponent::OnTextureQualityToggle(UiToggle& toggle, ToggleDirection toggleDirection)
     {
         const AZStd::vector<AZStd::pair<int16_t, AZStd::string>> valuesToLabels =
         {
@@ -199,7 +203,7 @@ namespace MultiplayerSample
         // Rotate the index based on toggle direction.
         uint32_t textureQualityIndex = GetRotatedIndex(valuesToLabels, textureQuality, toggleDirection);
 
-        UiTextBus::Event(m_textureQualityToggle.m_labelEntity, &UiTextInterface::SetText, valuesToLabels[textureQualityIndex].second);
+        UiTextBus::Event(toggle.m_labelEntity, &UiTextInterface::SetText, valuesToLabels[textureQualityIndex].second);
 
         MultiplayerSampleUserSettingsRequestBus::Broadcast(
             &MultiplayerSampleUserSettingsRequestBus::Events::SetTextureQuality, valuesToLabels[textureQualityIndex].first);
@@ -207,7 +211,7 @@ namespace MultiplayerSample
         MultiplayerSampleUserSettingsRequestBus::Broadcast(&MultiplayerSampleUserSettingsRequestBus::Events::Save);
     }
 
-    void UiSettingsComponent::OnMasterVolumeToggle(ToggleDirection toggleDirection)
+    void UiSettingsComponent::OnMasterVolumeToggle(UiToggle& toggle, ToggleDirection toggleDirection)
     {
         const AZStd::vector<AZStd::pair<uint8_t, AZStd::string>> valuesToLabels =
         {
@@ -235,7 +239,7 @@ namespace MultiplayerSample
         // Rotate the index based on toggle direction.
         uint32_t masterVolumeIndex = GetRotatedIndex(valuesToLabels, masterVolume, toggleDirection);
 
-        UiTextBus::Event(m_masterVolumeToggle.m_labelEntity, &UiTextInterface::SetText, valuesToLabels[masterVolumeIndex].second);
+        UiTextBus::Event(toggle.m_labelEntity, &UiTextInterface::SetText, valuesToLabels[masterVolumeIndex].second);
 
         MultiplayerSampleUserSettingsRequestBus::Broadcast(
             &MultiplayerSampleUserSettingsRequestBus::Events::SetMasterVolume, valuesToLabels[masterVolumeIndex].first);
@@ -243,4 +247,79 @@ namespace MultiplayerSample
         MultiplayerSampleUserSettingsRequestBus::Broadcast(&MultiplayerSampleUserSettingsRequestBus::Events::Save);
     }
 
+    void UiSettingsComponent::OnFullscreenToggle(UiToggle& toggle, ToggleDirection toggleDirection)
+    {
+        const AZStd::vector<AZStd::pair<bool, AZStd::string>> valuesToLabels =
+        {
+            { false, "Windowed" },
+            { true, "Fullscreen" },
+        };
+
+        // Get the current fullscreen state. Unlike the other settings, we'll get this from the current window state so that we
+        // handle things like Alt-enter that can change our windowing state regardless of what our user settings thinks.
+
+        // Start by defaulting to the user setting.
+        bool fullscreen = false;
+        MultiplayerSampleUserSettingsRequestBus::BroadcastResult(
+            fullscreen, &MultiplayerSampleUserSettingsRequestBus::Events::GetFullscreen);
+
+        // Next, try to get the current state from the window. If it fails to get the state, we'll auto-default to the
+        // user setting value that we fetched above.
+        AzFramework::WindowRequestBus::EventResult(fullscreen,
+            GetWindowHandle(), &AzFramework::WindowRequestBus::Events::GetFullScreenState);
+
+        // Rotate the index based on toggle direction.
+        uint32_t fullscreenIndex = GetRotatedIndex(valuesToLabels, fullscreen, toggleDirection);
+
+        UiTextBus::Event(toggle.m_labelEntity, &UiTextInterface::SetText, valuesToLabels[fullscreenIndex].second);
+
+        MultiplayerSampleUserSettingsRequestBus::Broadcast(
+            &MultiplayerSampleUserSettingsRequestBus::Events::SetFullscreen, valuesToLabels[fullscreenIndex].first);
+
+        MultiplayerSampleUserSettingsRequestBus::Broadcast(&MultiplayerSampleUserSettingsRequestBus::Events::Save);
+    }
+
+    void UiSettingsComponent::OnResolutionToggle(UiToggle& toggle, ToggleDirection toggleDirection)
+    {
+        const AZStd::vector<AZStd::pair<AZStd::pair<uint32_t, uint32_t>, AZStd::string>> valuesToLabels =
+        {
+            { {1280, 720}, "1280 x 720" },
+            { {1920, 1080}, "1920 x 1080" },
+            { {1920, 1200}, "1920 x 1200" },
+            { {2560, 1440}, "2560 x 1440" },
+            { {2560, 1600}, "2560 x 1600" },
+            { {3840, 2160}, "3840 x 2160" },
+            { {3840, 2400}, "3840 x 2400" },
+        };
+
+        // Get the current resolution value.
+        AZStd::pair<uint32_t, uint32_t> resolution = { 1920, 1080 };
+        MultiplayerSampleUserSettingsRequestBus::BroadcastResult(
+            resolution, &MultiplayerSampleUserSettingsRequestBus::Events::GetResolution);
+
+        // Rotate the index based on toggle direction.
+        uint32_t resolutionIndex = GetRotatedIndex(valuesToLabels, resolution, toggleDirection);
+
+        UiTextBus::Event(toggle.m_labelEntity, &UiTextInterface::SetText, valuesToLabels[resolutionIndex].second);
+
+        MultiplayerSampleUserSettingsRequestBus::Broadcast(
+            &MultiplayerSampleUserSettingsRequestBus::Events::SetResolution, valuesToLabels[resolutionIndex].first);
+
+        MultiplayerSampleUserSettingsRequestBus::Broadcast(&MultiplayerSampleUserSettingsRequestBus::Events::Save);
+    }
+
+    void UiSettingsComponent::OnWindowResized([[maybe_unused]] uint32_t width, [[maybe_unused]] uint32_t height)
+    {
+        // Refresh the windowed / fullscreen setting. There is no direct notification for fullscreen changes,
+        // so we detect it indirectly by listening for OnWindowResized and OnRefreshRateChanged messages.
+        OnFullscreenToggle(m_fullscreenToggle, ToggleDirection::None);
+    }
+
+    void UiSettingsComponent::OnRefreshRateChanged([[maybe_unused]] uint32_t refreshRate)
+    {
+        // Refresh the windowed / fullscreen setting. There is no direct notification for fullscreen changes,
+        // so we detect it indirectly by listening for OnWindowResized and OnRefreshRateChanged messages.
+        OnFullscreenToggle(m_fullscreenToggle, ToggleDirection::None);
+    }
+
 }

+ 21 - 3
Gem/Code/Source/Components/UI/UiSettingsComponent.h

@@ -9,6 +9,7 @@
 
 
 #include <AzCore/Component/Component.h>
+#include <AzFramework/Windowing/WindowBus.h>
 
 namespace MultiplayerSample
 {
@@ -22,8 +23,13 @@ namespace MultiplayerSample
         AZ::EntityId m_rightButtonEntity;
     };
 
+    // This component is attached to the UI Settings screen and handles the logic for changing the user setting values
+    // when the UI toggles are toggled. It activates on level load, not on settings screen navigation as one might think.
+    // On activation, it reapplies all of the MPS user settings while initializing the toggles to help ensure that the
+    // previously-applied settings weren't overridden by the server or by level loads.
     class UiSettingsComponent
         : public AZ::Component
+        , public AzFramework::WindowNotificationBus::Handler
     {
     public:
         AZ_COMPONENT(UiSettingsComponent, "{6F0F5495-E766-444C-808E-4EB91AD891D6}");
@@ -33,6 +39,12 @@ namespace MultiplayerSample
         void Activate() override;
         void Deactivate() override;
     private:
+        // WindowNotificationBus overrides
+        void OnWindowResized(uint32_t width, uint32_t height) override;
+        void OnRefreshRateChanged([[maybe_unused]] uint32_t refreshRate) override;
+
+        static AzFramework::NativeWindowHandle GetWindowHandle();
+
         enum class ToggleDirection
         {
             None,
@@ -40,9 +52,13 @@ namespace MultiplayerSample
             Right
         };
 
-        void OnGraphicsApiToggle(ToggleDirection toggleDirection);
-        void OnTextureQualityToggle(ToggleDirection toggleDirection);
-        void OnMasterVolumeToggle(ToggleDirection toggleDirection);
+        void InitializeToggle(UiToggle& toggle, AZStd::function<void(UiToggle&, ToggleDirection)> toggleUpdateFn);
+
+        static void OnGraphicsApiToggle(UiToggle& toggle, ToggleDirection toggleDirection);
+        static void OnTextureQualityToggle(UiToggle& toggle, ToggleDirection toggleDirection);
+        static void OnMasterVolumeToggle(UiToggle& toggle, ToggleDirection toggleDirection);
+        static void OnFullscreenToggle(UiToggle& toggle, ToggleDirection toggleDirection);
+        static void OnResolutionToggle(UiToggle& toggle, ToggleDirection toggleDirection);
 
         template<typename ValueType>
         static uint32_t GetRotatedIndex(
@@ -52,5 +68,7 @@ namespace MultiplayerSample
         UiToggle m_graphicsApiToggle;
         UiToggle m_textureQualityToggle;
         UiToggle m_masterVolumeToggle;
+        UiToggle m_fullscreenToggle;
+        UiToggle m_resolutionToggle;
     };
 }

+ 102 - 1
Gem/Code/Source/UserSettings/MultiplayerSampleUserSettings.cpp

@@ -10,11 +10,13 @@
 #include <Atom/RPI.Public/Image/StreamingImage.h>
 #include <Atom/RPI.Public/Image/StreamingImagePool.h>
 
+#include <AzCore/Console/IConsole.h>
 #include <AzCore/IO/GenericStreams.h>
 #include <AzCore/Settings/SettingsRegistry.h>
 #include <AzCore/Settings/SettingsRegistryMergeUtils.h>
 #include <AzCore/Utils/Utils.h>
 #include <AzFramework/FileFunc/FileFunc.h>
+#include <AzFramework/Windowing/WindowBus.h>
 #include <IAudioSystem.h>
 #include <UserSettings/MultiplayerSampleUserSettings.h>
 
@@ -24,7 +26,9 @@ namespace MultiplayerSample
         : m_graphicsApiKey(BaseRegistryKey + FixedString("/ApiName"))
         , m_masterVolumeKey(BaseRegistryKey + FixedString("/MasterVolume"))
         , m_textureQualityKey(BaseRegistryKey + FixedString("/TextureQuality"))
-
+        , m_fullscreenKey(BaseRegistryKey + FixedString("/Fullscreen"))
+        , m_resolutionWidthKey(BaseRegistryKey + FixedString("/Resolution/Width"))
+        , m_resolutionHeightKey(BaseRegistryKey + FixedString("/Resolution/Height"))
     {
         MultiplayerSampleUserSettingsRequestBus::Handler::BusConnect();
 
@@ -73,11 +77,15 @@ namespace MultiplayerSample
             AZStd::string apiName = GetGraphicsApi();
             uint8_t masterVolume = GetMasterVolume();
             int16_t textureQuality = GetTextureQuality();
+            bool fullscreen = GetFullscreen();
+            AZStd::pair<uint32_t, uint32_t> resolution = GetResolution();
 
             // Set the settings values, which will notify the engine as well as write the keys back into the registry.
             SetGraphicsApi(apiName);
             SetMasterVolume(masterVolume);
             SetTextureQuality(textureQuality);
+            SetFullscreen(fullscreen);
+            SetResolution(resolution);
         }
     }
 
@@ -180,6 +188,99 @@ namespace MultiplayerSample
         }
     }
 
+    bool MultiplayerSampleUserSettings::GetFullscreen()
+    {
+        bool fullscreen = false;
+
+        if (auto* registry = AZ::SettingsRegistry::Get(); registry != nullptr)
+        {
+            registry->Get(fullscreen, m_fullscreenKey.c_str());
+        }
+
+        return fullscreen;
+    }
+
+    void MultiplayerSampleUserSettings::SetFullscreen(bool fullscreen)
+    {
+        if (auto* registry = AZ::SettingsRegistry::Get(); registry != nullptr)
+        {
+            if (AZ::IConsole* console = AZ::Interface<AZ::IConsole>::Get(); console)
+            {
+                // Change the fullscreen state if we haven't created the window yet.
+                AZ::CVarFixedString commandString = AZ::CVarFixedString::format("r_fullscreen %u", fullscreen ? 1 : 0);
+                console->PerformCommand(commandString.c_str());
+
+                // Change the fullscreen state if the window already exists
+                AzFramework::NativeWindowHandle windowHandle = nullptr;
+                AzFramework::WindowSystemRequestBus::BroadcastResult(
+                    windowHandle,
+                    &AzFramework::WindowSystemRequestBus::Events::GetDefaultWindowHandle);
+
+                AzFramework::WindowRequestBus::Event(
+                    windowHandle,
+                    &AzFramework::WindowRequestBus::Events::SetFullScreenState, fullscreen);
+            }
+
+            registry->Set(m_fullscreenKey.c_str(), fullscreen);
+        }
+    }
+
+    AZStd::pair<uint32_t, uint32_t> MultiplayerSampleUserSettings::GetResolution()
+    {
+        uint64_t width = 1920;
+        uint64_t height = 1080;
+
+        if (auto* registry = AZ::SettingsRegistry::Get(); registry != nullptr)
+        {
+            registry->Get(width, m_resolutionWidthKey.c_str());
+            registry->Get(height, m_resolutionHeightKey.c_str());
+        }
+
+        return { aznumeric_cast<uint32_t>(width), aznumeric_cast<uint32_t>(height) };
+    }
+
+    void MultiplayerSampleUserSettings::SetResolution(AZStd::pair<uint32_t, uint32_t> resolution)
+    {
+        if (auto* registry = AZ::SettingsRegistry::Get(); registry != nullptr)
+        {
+            if (AZ::IConsole* console = AZ::Interface<AZ::IConsole>::Get(); console)
+            {
+                // This will technically change the window resolution to whatever is requrested, but it should 
+                // ideally take into account the current DPI scaling and what the maximum resolution of the monitor is.
+                
+                // Change the resolution if the window doesn't exist yet.
+                AZ::CVarFixedString commandString = AZ::CVarFixedString::format("r_width %u", resolution.first);
+                console->PerformCommand(commandString.c_str());
+
+                commandString = AZ::CVarFixedString::format("r_height %u", resolution.second);
+                console->PerformCommand(commandString.c_str());
+
+                // Change the resolution if the window already exists.
+                AzFramework::NativeWindowHandle windowHandle = nullptr;
+                AzFramework::WindowSystemRequestBus::BroadcastResult(
+                    windowHandle,
+                    &AzFramework::WindowSystemRequestBus::Events::GetDefaultWindowHandle);
+
+                bool fullscreen = false;
+                AzFramework::WindowRequestBus::EventResult(
+                    fullscreen, windowHandle,
+                    &AzFramework::WindowRequestBus::Events::GetFullScreenState);
+
+                // Don't resize if we're in fullscreen mode.
+                if (!fullscreen)
+                {
+                    AzFramework::WindowRequestBus::Event(
+                        windowHandle,
+                        &AzFramework::WindowRequestBus::Events::ResizeClientArea,
+                        AzFramework::WindowSize(resolution.first, resolution.second), AzFramework::WindowPosOptions());
+                }
+            }
+
+            registry->Set(m_resolutionWidthKey.c_str(), aznumeric_cast<uint64_t>(resolution.first));
+            registry->Set(m_resolutionHeightKey.c_str(), aznumeric_cast<uint64_t>(resolution.second));
+        }
+    }
+
     void MultiplayerSampleUserSettings::Save()
     {
         AZ::IO::FixedMaxPath userSettingsSavePath = m_userSettingsPath;

+ 19 - 0
Gem/Code/Source/UserSettings/MultiplayerSampleUserSettings.h

@@ -44,6 +44,14 @@ namespace MultiplayerSample
         // Anything lower doesn't really provide any benefit.
         virtual int16_t GetTextureQuality() = 0;
         virtual void SetTextureQuality(int16_t textureQuality) = 0;
+
+        // Change between fullscreen and windowed.
+        virtual bool GetFullscreen() = 0;
+        virtual void SetFullscreen(bool fullscreen) = 0;
+
+        // Change the rendering resolution (width, height)
+        virtual AZStd::pair<uint32_t, uint32_t> GetResolution() = 0;
+        virtual void SetResolution(AZStd::pair<uint32_t, uint32_t> resolution) = 0;
     };
 
     using MultiplayerSampleUserSettingsRequestBus = AZ::EBus<MultiplayerSampleUserSettingsRequests>;
@@ -70,6 +78,14 @@ namespace MultiplayerSample
 
         int16_t GetTextureQuality() override;
         void SetTextureQuality(int16_t textureQuality) override;
+
+        bool GetFullscreen() override;
+        void SetFullscreen(bool fullscreen) override;
+
+
+        AZStd::pair<uint32_t, uint32_t> GetResolution() override;
+        void SetResolution(AZStd::pair<uint32_t, uint32_t> resolution) override;
+
     private:
         using FixedString = AZStd::fixed_string<256>;
 
@@ -82,6 +98,9 @@ namespace MultiplayerSample
         const FixedString m_graphicsApiKey;
         const FixedString m_textureQualityKey;
         const FixedString m_masterVolumeKey;
+        const FixedString m_fullscreenKey;
+        const FixedString m_resolutionWidthKey;
+        const FixedString m_resolutionHeightKey;
 
         // The path to the user settings file.
         AZ::IO::FixedMaxPath m_userSettingsPath;

File diff suppressed because it is too large
+ 273 - 301
UICanvases/Settings.uicanvas


Some files were not shown because too many files changed in this diff