mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	Add per game configuration options (#6187)
* common: Move settings to common from core. - Removes a dependency on core and input_common from common. * code: Wrap settings values * Port from yuzu to allow per game settings * citra_qt: Initial per-game settings dialog * citra_qt: Use new API for read/save of config values * citra_qt: Per game audio settings * citra_qt: Per game graphics settings * citra_qt: Per game system settings * citra_qt: Per game general settings * citra_qt: Document and run clang format * citra_qt: Make icon smaller and centered * citra_qt: Remove version number * Not sure how to extract that, can always add it back later * citra_qt: Wrap UISettings * citra_qt: Fix unthottled fps setting * citra_qt: Remove margin in emulation tab * citra_qt: Implement some suggestions * Bring back speed switch hotkey * Allow configuration when game is running * Rename/adjust UI stuff * citra_qt: Fix build with separate windows * citra_qt: Address feedback * citra_qt: Log per-game settings before launching games * citra_qt: Add shader cache options * Also fix android build * citra_qt: Add DLC menu option * citra_qt: Run clang-format * citra_qt: Adjust for time offset * citra_qt: Implement suggestions * Run clang-format Co-authored-by: bunnei <bunneidev@gmail.com>
This commit is contained in:
		
							parent
							
								
									f261daf2fa
								
							
						
					
					
						commit
						48ee112ceb
					
				
					 92 changed files with 3171 additions and 1546 deletions
				
			
		|  | @ -4,9 +4,10 @@ | |||
| 
 | ||||
| #include <cmath> | ||||
| #include <mutex> | ||||
| #include "common/settings.h" | ||||
| #include "core/3ds.h" | ||||
| #include "core/frontend/emu_window.h" | ||||
| #include "core/frontend/input.h" | ||||
| #include "core/settings.h" | ||||
| 
 | ||||
| namespace Frontend { | ||||
| /// We need a global touch state that is shared across the different window instances
 | ||||
|  | @ -63,14 +64,14 @@ EmuWindow::~EmuWindow() = default; | |||
|  */ | ||||
| static bool IsWithinTouchscreen(const Layout::FramebufferLayout& layout, unsigned framebuffer_x, | ||||
|                                 unsigned framebuffer_y) { | ||||
|     if (Settings::values.render_3d == Settings::StereoRenderOption::SideBySide) { | ||||
|     if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::SideBySide) { | ||||
|         return (framebuffer_y >= layout.bottom_screen.top && | ||||
|                 framebuffer_y < layout.bottom_screen.bottom && | ||||
|                 ((framebuffer_x >= layout.bottom_screen.left / 2 && | ||||
|                   framebuffer_x < layout.bottom_screen.right / 2) || | ||||
|                  (framebuffer_x >= (layout.bottom_screen.left / 2) + (layout.width / 2) && | ||||
|                   framebuffer_x < (layout.bottom_screen.right / 2) + (layout.width / 2)))); | ||||
|     } else if (Settings::values.render_3d == Settings::StereoRenderOption::CardboardVR) { | ||||
|     } else if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::CardboardVR) { | ||||
|         return (framebuffer_y >= layout.bottom_screen.top && | ||||
|                 framebuffer_y < layout.bottom_screen.bottom && | ||||
|                 ((framebuffer_x >= layout.bottom_screen.left && | ||||
|  | @ -88,13 +89,13 @@ static bool IsWithinTouchscreen(const Layout::FramebufferLayout& layout, unsigne | |||
| 
 | ||||
| std::tuple<unsigned, unsigned> EmuWindow::ClipToTouchScreen(unsigned new_x, unsigned new_y) const { | ||||
|     if (new_x >= framebuffer_layout.width / 2) { | ||||
|         if (Settings::values.render_3d == Settings::StereoRenderOption::SideBySide) | ||||
|         if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::SideBySide) | ||||
|             new_x -= framebuffer_layout.width / 2; | ||||
|         else if (Settings::values.render_3d == Settings::StereoRenderOption::CardboardVR) | ||||
|         else if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::CardboardVR) | ||||
|             new_x -= | ||||
|                 (framebuffer_layout.width / 2) - (framebuffer_layout.cardboard.user_x_shift * 2); | ||||
|     } | ||||
|     if (Settings::values.render_3d == Settings::StereoRenderOption::SideBySide) { | ||||
|     if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::SideBySide) { | ||||
|         new_x = std::max(new_x, framebuffer_layout.bottom_screen.left / 2); | ||||
|         new_x = std::min(new_x, framebuffer_layout.bottom_screen.right / 2 - 1); | ||||
|     } else { | ||||
|  | @ -122,14 +123,14 @@ bool EmuWindow::TouchPressed(unsigned framebuffer_x, unsigned framebuffer_y) { | |||
|         return false; | ||||
| 
 | ||||
|     if (framebuffer_x >= framebuffer_layout.width / 2) { | ||||
|         if (Settings::values.render_3d == Settings::StereoRenderOption::SideBySide) | ||||
|         if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::SideBySide) | ||||
|             framebuffer_x -= framebuffer_layout.width / 2; | ||||
|         else if (Settings::values.render_3d == Settings::StereoRenderOption::CardboardVR) | ||||
|         else if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::CardboardVR) | ||||
|             framebuffer_x -= | ||||
|                 (framebuffer_layout.width / 2) - (framebuffer_layout.cardboard.user_x_shift * 2); | ||||
|     } | ||||
|     std::lock_guard guard(touch_state->mutex); | ||||
|     if (Settings::values.render_3d == Settings::StereoRenderOption::SideBySide) { | ||||
|     if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::SideBySide) { | ||||
|         touch_state->touch_x = | ||||
|             static_cast<float>(framebuffer_x - framebuffer_layout.bottom_screen.left / 2) / | ||||
|             (framebuffer_layout.bottom_screen.right / 2 - | ||||
|  | @ -173,55 +174,59 @@ void EmuWindow::UpdateCurrentFramebufferLayout(unsigned width, unsigned height, | |||
|                                                bool is_portrait_mode) { | ||||
|     Layout::FramebufferLayout layout; | ||||
|     const auto layout_option = Settings::values.layout_option; | ||||
|     const auto min_size = | ||||
|         Layout::GetMinimumSizeFromLayout(layout_option, Settings::values.upright_screen); | ||||
|     const auto min_size = Layout::GetMinimumSizeFromLayout( | ||||
|         layout_option.GetValue(), Settings::values.upright_screen.GetValue()); | ||||
| 
 | ||||
|     if (Settings::values.custom_layout == true) { | ||||
|     if (Settings::values.custom_layout.GetValue() == true) { | ||||
|         layout = Layout::CustomFrameLayout(width, height); | ||||
|     } else { | ||||
|         width = std::max(width, min_size.first); | ||||
|         height = std::max(height, min_size.second); | ||||
| 
 | ||||
|         // If in portrait mode, only the MobilePortrait option really makes sense
 | ||||
|         const Settings::LayoutOption layout_option = is_portrait_mode | ||||
|                                                          ? Settings::LayoutOption::MobilePortrait | ||||
|                                                          : Settings::values.layout_option; | ||||
|         const Settings::LayoutOption layout_option = | ||||
|             is_portrait_mode ? Settings::LayoutOption::MobilePortrait | ||||
|                              : Settings::values.layout_option.GetValue(); | ||||
| 
 | ||||
|         switch (layout_option) { | ||||
|         case Settings::LayoutOption::SingleScreen: | ||||
|             layout = Layout::SingleFrameLayout(width, height, Settings::values.swap_screen, | ||||
|                                                Settings::values.upright_screen); | ||||
|             layout = | ||||
|                 Layout::SingleFrameLayout(width, height, Settings::values.swap_screen.GetValue(), | ||||
|                                           Settings::values.upright_screen.GetValue()); | ||||
|             break; | ||||
|         case Settings::LayoutOption::LargeScreen: | ||||
|             layout = Layout::LargeFrameLayout(width, height, Settings::values.swap_screen, | ||||
|                                               Settings::values.upright_screen); | ||||
|             layout = | ||||
|                 Layout::LargeFrameLayout(width, height, Settings::values.swap_screen.GetValue(), | ||||
|                                          Settings::values.upright_screen.GetValue()); | ||||
|             break; | ||||
|         case Settings::LayoutOption::SideScreen: | ||||
|             layout = Layout::SideFrameLayout(width, height, Settings::values.swap_screen, | ||||
|                                              Settings::values.upright_screen); | ||||
|             layout = Layout::SideFrameLayout(width, height, Settings::values.swap_screen.GetValue(), | ||||
|                                              Settings::values.upright_screen.GetValue()); | ||||
|             break; | ||||
| #ifndef ANDROID | ||||
|         case Settings::LayoutOption::SeparateWindows: | ||||
|             layout = Layout::SeparateWindowsLayout(width, height, is_secondary, | ||||
|                                                    Settings::values.upright_screen); | ||||
|                                                    Settings::values.upright_screen.GetValue()); | ||||
|             break; | ||||
| #endif | ||||
|         case Settings::LayoutOption::MobilePortrait: | ||||
|             layout = Layout::MobilePortraitFrameLayout(width, height, Settings::values.swap_screen); | ||||
|             layout = Layout::MobilePortraitFrameLayout(width, height, | ||||
|                                                        Settings::values.swap_screen.GetValue()); | ||||
|             break; | ||||
|         case Settings::LayoutOption::MobileLandscape: | ||||
|             layout = Layout::MobileLandscapeFrameLayout(width, height, Settings::values.swap_screen, | ||||
|                                                         2.25f, false); | ||||
|             layout = Layout::MobileLandscapeFrameLayout( | ||||
|                 width, height, Settings::values.swap_screen.GetValue(), 2.25f, false); | ||||
|             break; | ||||
|         case Settings::LayoutOption::Default: | ||||
|         default: | ||||
|             layout = Layout::DefaultFrameLayout(width, height, Settings::values.swap_screen, | ||||
|                                                 Settings::values.upright_screen); | ||||
|             layout = | ||||
|                 Layout::DefaultFrameLayout(width, height, Settings::values.swap_screen.GetValue(), | ||||
|                                            Settings::values.upright_screen.GetValue()); | ||||
|             break; | ||||
|         } | ||||
|         UpdateMinimumWindowSize(min_size); | ||||
|     } | ||||
|     if (Settings::values.render_3d == Settings::StereoRenderOption::CardboardVR) { | ||||
|     if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::CardboardVR) { | ||||
|         layout = Layout::GetCardboardSettings(layout); | ||||
|     } | ||||
|     NotifyFramebufferLayoutChanged(layout); | ||||
|  |  | |||
|  | @ -5,9 +5,9 @@ | |||
| #include <cmath> | ||||
| 
 | ||||
| #include "common/assert.h" | ||||
| #include "common/settings.h" | ||||
| #include "core/3ds.h" | ||||
| #include "core/frontend/framebuffer_layout.h" | ||||
| #include "core/settings.h" | ||||
| 
 | ||||
| namespace Layout { | ||||
| 
 | ||||
|  | @ -355,12 +355,14 @@ FramebufferLayout CustomFrameLayout(u32 width, u32 height) { | |||
| 
 | ||||
|     FramebufferLayout res{width, height, true, true, {}, {}, !Settings::values.upright_screen}; | ||||
| 
 | ||||
|     Common::Rectangle<u32> top_screen{ | ||||
|         Settings::values.custom_top_left, Settings::values.custom_top_top, | ||||
|         Settings::values.custom_top_right, Settings::values.custom_top_bottom}; | ||||
|     Common::Rectangle<u32> bot_screen{ | ||||
|         Settings::values.custom_bottom_left, Settings::values.custom_bottom_top, | ||||
|         Settings::values.custom_bottom_right, Settings::values.custom_bottom_bottom}; | ||||
|     Common::Rectangle<u32> top_screen{Settings::values.custom_top_left.GetValue(), | ||||
|                                       Settings::values.custom_top_top.GetValue(), | ||||
|                                       Settings::values.custom_top_right.GetValue(), | ||||
|                                       Settings::values.custom_top_bottom.GetValue()}; | ||||
|     Common::Rectangle<u32> bot_screen{Settings::values.custom_bottom_left.GetValue(), | ||||
|                                       Settings::values.custom_bottom_top.GetValue(), | ||||
|                                       Settings::values.custom_bottom_right.GetValue(), | ||||
|                                       Settings::values.custom_bottom_bottom.GetValue()}; | ||||
| 
 | ||||
|     res.top_screen = top_screen; | ||||
|     res.bottom_screen = bot_screen; | ||||
|  | @ -369,20 +371,21 @@ FramebufferLayout CustomFrameLayout(u32 width, u32 height) { | |||
| 
 | ||||
| FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale, bool is_secondary) { | ||||
|     FramebufferLayout layout; | ||||
|     if (Settings::values.custom_layout == true) { | ||||
|         layout = CustomFrameLayout( | ||||
|             std::max(Settings::values.custom_top_right, Settings::values.custom_bottom_right), | ||||
|             std::max(Settings::values.custom_top_bottom, Settings::values.custom_bottom_bottom)); | ||||
|     if (Settings::values.custom_layout.GetValue() == true) { | ||||
|         layout = CustomFrameLayout(std::max(Settings::values.custom_top_right.GetValue(), | ||||
|                                             Settings::values.custom_bottom_right.GetValue()), | ||||
|                                    std::max(Settings::values.custom_top_bottom.GetValue(), | ||||
|                                             Settings::values.custom_bottom_bottom.GetValue())); | ||||
|     } else { | ||||
|         int width, height; | ||||
|         switch (Settings::values.layout_option) { | ||||
|         switch (Settings::values.layout_option.GetValue()) { | ||||
|         case Settings::LayoutOption::SingleScreen: | ||||
| #ifndef ANDROID | ||||
|         case Settings::LayoutOption::SeparateWindows: | ||||
| #endif | ||||
|         { | ||||
|             const bool swap_screens = is_secondary || Settings::values.swap_screen; | ||||
|             if (Settings::values.upright_screen) { | ||||
|             const bool swap_screens = is_secondary || Settings::values.swap_screen.GetValue(); | ||||
|             if (Settings::values.upright_screen.GetValue()) { | ||||
|                 if (swap_screens) { | ||||
|                     width = Core::kScreenBottomHeight * res_scale; | ||||
|                     height = Core::kScreenBottomWidth * res_scale; | ||||
|  | @ -399,13 +402,13 @@ FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale, bool is_secondar | |||
|                     height = Core::kScreenTopHeight * res_scale; | ||||
|                 } | ||||
|             } | ||||
|             layout = | ||||
|                 SingleFrameLayout(width, height, swap_screens, Settings::values.upright_screen); | ||||
|             layout = SingleFrameLayout(width, height, swap_screens, | ||||
|                                        Settings::values.upright_screen.GetValue()); | ||||
|             break; | ||||
|         } | ||||
|         case Settings::LayoutOption::LargeScreen: | ||||
|             if (Settings::values.upright_screen) { | ||||
|                 if (Settings::values.swap_screen) { | ||||
|             if (Settings::values.upright_screen.GetValue()) { | ||||
|                 if (Settings::values.swap_screen.GetValue()) { | ||||
|                     width = Core::kScreenBottomHeight * res_scale; | ||||
|                     height = (Core::kScreenBottomWidth + Core::kScreenTopWidth / 4) * res_scale; | ||||
|                 } else { | ||||
|  | @ -413,7 +416,7 @@ FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale, bool is_secondar | |||
|                     height = (Core::kScreenTopWidth + Core::kScreenBottomWidth / 4) * res_scale; | ||||
|                 } | ||||
|             } else { | ||||
|                 if (Settings::values.swap_screen) { | ||||
|                 if (Settings::values.swap_screen.GetValue()) { | ||||
|                     width = (Core::kScreenBottomWidth + Core::kScreenTopWidth / 4) * res_scale; | ||||
|                     height = Core::kScreenBottomHeight * res_scale; | ||||
|                 } else { | ||||
|  | @ -421,51 +424,52 @@ FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale, bool is_secondar | |||
|                     height = Core::kScreenTopHeight * res_scale; | ||||
|                 } | ||||
|             } | ||||
|             layout = LargeFrameLayout(width, height, Settings::values.swap_screen, | ||||
|                                       Settings::values.upright_screen); | ||||
|             layout = LargeFrameLayout(width, height, Settings::values.swap_screen.GetValue(), | ||||
|                                       Settings::values.upright_screen.GetValue()); | ||||
|             break; | ||||
|         case Settings::LayoutOption::SideScreen: | ||||
|             if (Settings::values.upright_screen) { | ||||
|             if (Settings::values.upright_screen.GetValue()) { | ||||
|                 width = Core::kScreenTopHeight * res_scale; | ||||
|                 height = (Core::kScreenTopWidth + Core::kScreenBottomWidth) * res_scale; | ||||
|             } else { | ||||
|                 width = (Core::kScreenTopWidth + Core::kScreenBottomWidth) * res_scale; | ||||
|                 height = Core::kScreenTopHeight * res_scale; | ||||
|             } | ||||
|             layout = SideFrameLayout(width, height, Settings::values.swap_screen, | ||||
|                                      Settings::values.upright_screen); | ||||
|             layout = SideFrameLayout(width, height, Settings::values.swap_screen.GetValue(), | ||||
|                                      Settings::values.upright_screen.GetValue()); | ||||
|             break; | ||||
|         case Settings::LayoutOption::MobilePortrait: | ||||
|             width = Core::kScreenTopWidth * res_scale; | ||||
|             height = (Core::kScreenTopHeight + Core::kScreenBottomHeight) * res_scale; | ||||
|             layout = MobilePortraitFrameLayout(width, height, Settings::values.swap_screen); | ||||
|             layout = | ||||
|                 MobilePortraitFrameLayout(width, height, Settings::values.swap_screen.GetValue()); | ||||
|             break; | ||||
|         case Settings::LayoutOption::MobileLandscape: | ||||
|             if (Settings::values.swap_screen) { | ||||
|             if (Settings::values.swap_screen.GetValue()) { | ||||
|                 width = (Core::kScreenBottomWidth + Core::kScreenTopWidth / 2.25f) * res_scale; | ||||
|                 height = Core::kScreenBottomHeight * res_scale; | ||||
|             } else { | ||||
|                 width = (Core::kScreenTopWidth + Core::kScreenBottomWidth / 2.25f) * res_scale; | ||||
|                 height = Core::kScreenTopHeight * res_scale; | ||||
|             } | ||||
|             layout = MobileLandscapeFrameLayout(width, height, Settings::values.swap_screen, 2.25f, | ||||
|                                                 false); | ||||
|             layout = MobileLandscapeFrameLayout( | ||||
|                 width, height, Settings::values.swap_screen.GetValue(), 2.25f, false); | ||||
|             break; | ||||
|         case Settings::LayoutOption::Default: | ||||
|         default: | ||||
|             if (Settings::values.upright_screen) { | ||||
|             if (Settings::values.upright_screen.GetValue()) { | ||||
|                 width = (Core::kScreenTopHeight + Core::kScreenBottomHeight) * res_scale; | ||||
|                 height = Core::kScreenTopWidth * res_scale; | ||||
|             } else { | ||||
|                 width = Core::kScreenTopWidth * res_scale; | ||||
|                 height = (Core::kScreenTopHeight + Core::kScreenBottomHeight) * res_scale; | ||||
|             } | ||||
|             layout = DefaultFrameLayout(width, height, Settings::values.swap_screen, | ||||
|                                         Settings::values.upright_screen); | ||||
|             layout = DefaultFrameLayout(width, height, Settings::values.swap_screen.GetValue(), | ||||
|                                         Settings::values.upright_screen.GetValue()); | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
|     if (Settings::values.render_3d == Settings::StereoRenderOption::CardboardVR) { | ||||
|     if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::CardboardVR) { | ||||
|         layout = Layout::GetCardboardSettings(layout); | ||||
|     } | ||||
|     return layout; | ||||
|  | @ -478,17 +482,17 @@ FramebufferLayout GetCardboardSettings(FramebufferLayout layout) { | |||
|     float bottom_screen_left = 0; | ||||
|     float bottom_screen_top = 0; | ||||
| 
 | ||||
|     float cardboardScreenScale = Settings::values.cardboard_screen_size / 100.0f; | ||||
|     float cardboardScreenScale = Settings::values.cardboard_screen_size.GetValue() / 100.0f; | ||||
|     float top_screen_width = layout.top_screen.GetWidth() / 2.0f * cardboardScreenScale; | ||||
|     float top_screen_height = layout.top_screen.GetHeight() / 2.0f * cardboardScreenScale; | ||||
|     float bottom_screen_width = layout.bottom_screen.GetWidth() / 2.0f * cardboardScreenScale; | ||||
|     float bottom_screen_height = layout.bottom_screen.GetHeight() / 2.0f * cardboardScreenScale; | ||||
|     bool is_swapped = Settings::values.swap_screen; | ||||
|     bool is_portrait = layout.height > layout.width; | ||||
|     const bool is_swapped = Settings::values.swap_screen.GetValue(); | ||||
|     const bool is_portrait = layout.height > layout.width; | ||||
| 
 | ||||
|     float cardboardScreenWidth; | ||||
|     float cardboardScreenHeight; | ||||
|     switch (Settings::values.layout_option) { | ||||
|     switch (Settings::values.layout_option.GetValue()) { | ||||
|     case Settings::LayoutOption::MobileLandscape: | ||||
|     case Settings::LayoutOption::SideScreen: | ||||
|         // If orientation is portrait, only use MobilePortrait
 | ||||
|  | @ -524,9 +528,11 @@ FramebufferLayout GetCardboardSettings(FramebufferLayout layout) { | |||
|         break; | ||||
|     } | ||||
|     float cardboardMaxXShift = (layout.width / 2.0f - cardboardScreenWidth) / 2.0f; | ||||
|     float cardboardUserXShift = (Settings::values.cardboard_x_shift / 100.0f) * cardboardMaxXShift; | ||||
|     float cardboardUserXShift = | ||||
|         (Settings::values.cardboard_x_shift.GetValue() / 100.0f) * cardboardMaxXShift; | ||||
|     float cardboardMaxYShift = ((float)layout.height - cardboardScreenHeight) / 2.0f; | ||||
|     float cardboardUserYShift = (Settings::values.cardboard_y_shift / 100.0f) * cardboardMaxYShift; | ||||
|     float cardboardUserYShift = | ||||
|         (Settings::values.cardboard_y_shift.GetValue() / 100.0f) * cardboardMaxYShift; | ||||
| 
 | ||||
|     // Center the screens and apply user Y shift
 | ||||
|     newLayout.top_screen.left = top_screen_left + cardboardMaxXShift; | ||||
|  |  | |||
|  | @ -5,7 +5,7 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include "common/math_util.h" | ||||
| #include "core/settings.h" | ||||
| #include "common/settings.h" | ||||
| 
 | ||||
| namespace Layout { | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue