mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	Signed-off-by: elim <e_sliwka@tuta.io>
This commit is contained in:
		
							parent
							
								
									2d6aca4563
								
							
						
					
					
						commit
						0d516f6da5
					
				
					 9 changed files with 124 additions and 0 deletions
				
			
		|  | @ -200,6 +200,11 @@ void EmuWindow::UpdateCurrentFramebufferLayout(unsigned width, unsigned height, | |||
|                                          Settings::values.upright_screen.GetValue(), | ||||
|                                          Settings::values.large_screen_proportion.GetValue()); | ||||
|             break; | ||||
|         case Settings::LayoutOption::HybridScreen: | ||||
|             layout = | ||||
|                 Layout::HybridScreenLayout(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.GetValue(), | ||||
|                                              Settings::values.upright_screen.GetValue()); | ||||
|  |  | |||
|  | @ -299,6 +299,80 @@ FramebufferLayout LargeFrameLayout(u32 width, u32 height, bool swapped, bool upr | |||
|     return res; | ||||
| } | ||||
| 
 | ||||
| FramebufferLayout HybridScreenLayout(u32 width, u32 height, bool swapped, bool upright) { | ||||
|     ASSERT(width > 0); | ||||
|     ASSERT(height > 0); | ||||
| 
 | ||||
|     FramebufferLayout res{width, height, true, true, {}, {}, !upright, true, {}}; | ||||
| 
 | ||||
|     // Split the window into two parts. Give 2.25x width to the main screen,
 | ||||
|     // and make a bar on the right side with 1x width top screen and 1.25x width bottom screen
 | ||||
|     // To do that, find the total emulation box and maximize that based on window size
 | ||||
|     const float window_aspect_ratio = static_cast<float>(height) / width; | ||||
|     const float scale_factor = 2.25f; | ||||
| 
 | ||||
|     float main_screen_aspect_ratio = TOP_SCREEN_ASPECT_RATIO; | ||||
|     float hybrid_area_aspect_ratio = 27.f / 65; | ||||
|     float top_screen_aspect_ratio = TOP_SCREEN_ASPECT_RATIO; | ||||
|     float bot_screen_aspect_ratio = BOT_SCREEN_ASPECT_RATIO; | ||||
| 
 | ||||
|     if (swapped) { | ||||
|         main_screen_aspect_ratio = BOT_SCREEN_ASPECT_RATIO; | ||||
|         hybrid_area_aspect_ratio = | ||||
|             Core::kScreenBottomHeight * scale_factor / | ||||
|             (Core::kScreenBottomWidth * scale_factor + Core::kScreenTopWidth); | ||||
|     } | ||||
| 
 | ||||
|     if (upright) { | ||||
|         hybrid_area_aspect_ratio = 1.f / hybrid_area_aspect_ratio; | ||||
|         main_screen_aspect_ratio = 1.f / main_screen_aspect_ratio; | ||||
|         top_screen_aspect_ratio = TOP_SCREEN_UPRIGHT_ASPECT_RATIO; | ||||
|         bot_screen_aspect_ratio = BOT_SCREEN_UPRIGHT_ASPECT_RATIO; | ||||
|     } | ||||
| 
 | ||||
|     Common::Rectangle<u32> screen_window_area{0, 0, width, height}; | ||||
|     Common::Rectangle<u32> total_rect = maxRectangle(screen_window_area, hybrid_area_aspect_ratio); | ||||
|     Common::Rectangle<u32> large_main_screen = maxRectangle(total_rect, main_screen_aspect_ratio); | ||||
|     Common::Rectangle<u32> side_rect = total_rect.Scale(1.f / scale_factor); | ||||
|     Common::Rectangle<u32> small_top_screen = maxRectangle(side_rect, top_screen_aspect_ratio); | ||||
|     Common::Rectangle<u32> small_bottom_screen = maxRectangle(side_rect, bot_screen_aspect_ratio); | ||||
| 
 | ||||
|     if (window_aspect_ratio < hybrid_area_aspect_ratio) { | ||||
|         large_main_screen = large_main_screen.TranslateX((width - total_rect.GetWidth()) / 2); | ||||
|     } else { | ||||
|         large_main_screen = large_main_screen.TranslateY((height - total_rect.GetHeight()) / 2); | ||||
|     } | ||||
| 
 | ||||
|     // Scale the bottom screen so it's width is the same as top screen
 | ||||
|     small_bottom_screen = small_bottom_screen.Scale(1.25f); | ||||
|     if (upright) { | ||||
|         large_main_screen = large_main_screen.TranslateY(small_bottom_screen.GetHeight()); | ||||
|         // Shift small bottom screen to upper right corner
 | ||||
|         small_bottom_screen = | ||||
|             small_bottom_screen.TranslateX(large_main_screen.right - small_bottom_screen.GetWidth()) | ||||
|                 .TranslateY(large_main_screen.top - small_bottom_screen.GetHeight()); | ||||
| 
 | ||||
|         // Shift small top screen to upper left corner
 | ||||
|         small_top_screen = small_top_screen.TranslateX(large_main_screen.left) | ||||
|                                .TranslateY(large_main_screen.top - small_bottom_screen.GetHeight()); | ||||
|     } else { | ||||
|         // Shift the small bottom screen to the bottom right corner
 | ||||
|         small_bottom_screen = | ||||
|             small_bottom_screen.TranslateX(large_main_screen.right) | ||||
|                 .TranslateY(large_main_screen.GetHeight() + large_main_screen.top - | ||||
|                             small_bottom_screen.GetHeight()); | ||||
| 
 | ||||
|         // Shift small top screen to upper right corner
 | ||||
|         small_top_screen = | ||||
|             small_top_screen.TranslateX(large_main_screen.right).TranslateY(large_main_screen.top); | ||||
|     } | ||||
| 
 | ||||
|     res.top_screen = small_top_screen; | ||||
|     res.additional_screen = swapped ? small_bottom_screen : large_main_screen; | ||||
|     res.bottom_screen = swapped ? large_main_screen : small_bottom_screen; | ||||
|     return res; | ||||
| } | ||||
| 
 | ||||
| FramebufferLayout SideFrameLayout(u32 width, u32 height, bool swapped, bool upright) { | ||||
|     ASSERT(width > 0); | ||||
|     ASSERT(height > 0); | ||||
|  |  | |||
|  | @ -37,6 +37,9 @@ struct FramebufferLayout { | |||
|     Common::Rectangle<u32> bottom_screen; | ||||
|     bool is_rotated = true; | ||||
| 
 | ||||
|     bool additional_screen_enabled; | ||||
|     Common::Rectangle<u32> additional_screen; | ||||
| 
 | ||||
|     CardboardSettings cardboard; | ||||
| 
 | ||||
|     /**
 | ||||
|  | @ -99,6 +102,15 @@ FramebufferLayout SingleFrameLayout(u32 width, u32 height, bool is_swapped, bool | |||
|  */ | ||||
| FramebufferLayout LargeFrameLayout(u32 width, u32 height, bool is_swapped, bool upright, | ||||
|                                    float scale_factor); | ||||
| /**
 | ||||
|  * Factory method for constructing a frame with 2.5 times bigger top screen on the right, | ||||
|  * and 1x top and bottom screen on the left | ||||
|  * @param width Window framebuffer width in pixels | ||||
|  * @param height Window framebuffer height in pixels | ||||
|  * @param is_swapped if true, the bottom screen will be the large display | ||||
|  * @return Newly created FramebufferLayout object with default screen regions initialized | ||||
|  */ | ||||
| FramebufferLayout HybridScreenLayout(u32 width, u32 height, bool swapped, bool upright); | ||||
| 
 | ||||
| /**
 | ||||
|  * Factory method for constructing a Frame with the Top screen and bottom | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue