mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	Merge pull request #5906 from SachinVin/android2
Backport some more stuff from android
This commit is contained in:
		
						commit
						6dfb74a8b9
					
				
					 12 changed files with 331 additions and 19 deletions
				
			
		|  | @ -696,8 +696,8 @@ void SetUserPath(const std::string& path) { | |||
|         g_paths.emplace(UserPath::ConfigDir, user_path + CONFIG_DIR DIR_SEP); | ||||
|         g_paths.emplace(UserPath::CacheDir, user_path + CACHE_DIR DIR_SEP); | ||||
| #elif ANDROID | ||||
|         if (FileUtil::Exists(ROOT_DIR DIR_SEP SDCARD_DIR)) { | ||||
|             user_path = ROOT_DIR DIR_SEP SDCARD_DIR DIR_SEP EMU_DATA_DIR DIR_SEP; | ||||
|         if (FileUtil::Exists(DIR_SEP SDCARD_DIR)) { | ||||
|             user_path = DIR_SEP SDCARD_DIR DIR_SEP EMU_DATA_DIR DIR_SEP; | ||||
|             g_paths.emplace(UserPath::ConfigDir, user_path + CONFIG_DIR DIR_SEP); | ||||
|             g_paths.emplace(UserPath::CacheDir, user_path + CACHE_DIR DIR_SEP); | ||||
|         } | ||||
|  |  | |||
|  | @ -541,11 +541,11 @@ void System::Shutdown(bool is_deserializing) { | |||
|     archive_manager.reset(); | ||||
|     service_manager.reset(); | ||||
|     dsp_core.reset(); | ||||
|     cpu_cores.clear(); | ||||
|     kernel.reset(); | ||||
|     cpu_cores.clear(); | ||||
|     timing.reset(); | ||||
| 
 | ||||
|     if (video_dumper->IsDumping()) { | ||||
|     if (video_dumper && video_dumper->IsDumping()) { | ||||
|         video_dumper->StopDumping(); | ||||
|     } | ||||
| 
 | ||||
|  | @ -554,6 +554,8 @@ void System::Shutdown(bool is_deserializing) { | |||
|         room_member->SendGameInfo(game_info); | ||||
|     } | ||||
| 
 | ||||
|     memory.reset(); | ||||
| 
 | ||||
|     LOG_DEBUG(Core, "Shutdown OK"); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -73,6 +73,14 @@ static bool IsWithinTouchscreen(const Layout::FramebufferLayout& layout, unsigne | |||
|                   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) { | ||||
|         return (framebuffer_y >= layout.bottom_screen.top && | ||||
|                 framebuffer_y < layout.bottom_screen.bottom && | ||||
|                 ((framebuffer_x >= layout.bottom_screen.left && | ||||
|                   framebuffer_x < layout.bottom_screen.right) || | ||||
|                  (framebuffer_x >= layout.cardboard.bottom_screen_right_eye + (layout.width / 2) && | ||||
|                   framebuffer_x < layout.cardboard.bottom_screen_right_eye + | ||||
|                                       layout.bottom_screen.GetWidth() + (layout.width / 2)))); | ||||
|     } else { | ||||
|         return (framebuffer_y >= layout.bottom_screen.top && | ||||
|                 framebuffer_y < layout.bottom_screen.bottom && | ||||
|  | @ -82,9 +90,14 @@ static bool IsWithinTouchscreen(const Layout::FramebufferLayout& layout, unsigne | |||
| } | ||||
| 
 | ||||
| std::tuple<unsigned, unsigned> EmuWindow::ClipToTouchScreen(unsigned new_x, unsigned new_y) const { | ||||
|     if (Settings::values.render_3d == Settings::StereoRenderOption::SideBySide) { | ||||
|         if (new_x >= framebuffer_layout.width / 2) | ||||
|     if (new_x >= framebuffer_layout.width / 2) { | ||||
|         if (Settings::values.render_3d == Settings::StereoRenderOption::SideBySide) | ||||
|             new_x -= framebuffer_layout.width / 2; | ||||
|         else if (Settings::values.render_3d == Settings::StereoRenderOption::CardboardVR) | ||||
|             new_x -= | ||||
|                 (framebuffer_layout.width / 2) - (framebuffer_layout.cardboard.user_x_shift * 2); | ||||
|     } | ||||
|     if (Settings::values.render_3d == 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 { | ||||
|  | @ -98,13 +111,17 @@ std::tuple<unsigned, unsigned> EmuWindow::ClipToTouchScreen(unsigned new_x, unsi | |||
|     return std::make_tuple(new_x, new_y); | ||||
| } | ||||
| 
 | ||||
| void EmuWindow::TouchPressed(unsigned framebuffer_x, unsigned framebuffer_y) { | ||||
| bool EmuWindow::TouchPressed(unsigned framebuffer_x, unsigned framebuffer_y) { | ||||
|     if (!IsWithinTouchscreen(framebuffer_layout, framebuffer_x, framebuffer_y)) | ||||
|         return; | ||||
|         return false; | ||||
| 
 | ||||
|     if (Settings::values.render_3d == Settings::StereoRenderOption::SideBySide && | ||||
|         framebuffer_x >= framebuffer_layout.width / 2) | ||||
|     if (framebuffer_x >= framebuffer_layout.width / 2) { | ||||
|         if (Settings::values.render_3d == Settings::StereoRenderOption::SideBySide) | ||||
|             framebuffer_x -= framebuffer_layout.width / 2; | ||||
|         else if (Settings::values.render_3d == 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) { | ||||
|         touch_state->touch_x = | ||||
|  | @ -126,6 +143,7 @@ void EmuWindow::TouchPressed(unsigned framebuffer_x, unsigned framebuffer_y) { | |||
|     } | ||||
| 
 | ||||
|     touch_state->touch_pressed = true; | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| void EmuWindow::TouchReleased() { | ||||
|  | @ -145,7 +163,8 @@ void EmuWindow::TouchMoved(unsigned framebuffer_x, unsigned framebuffer_y) { | |||
|     TouchPressed(framebuffer_x, framebuffer_y); | ||||
| } | ||||
| 
 | ||||
| void EmuWindow::UpdateCurrentFramebufferLayout(unsigned width, unsigned height) { | ||||
| 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 = | ||||
|  | @ -156,6 +175,12 @@ void EmuWindow::UpdateCurrentFramebufferLayout(unsigned width, unsigned 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; | ||||
| 
 | ||||
|         switch (layout_option) { | ||||
|         case Settings::LayoutOption::SingleScreen: | ||||
|             layout = Layout::SingleFrameLayout(width, height, Settings::values.swap_screen, | ||||
|  | @ -169,6 +194,13 @@ void EmuWindow::UpdateCurrentFramebufferLayout(unsigned width, unsigned height) | |||
|             layout = Layout::SideFrameLayout(width, height, Settings::values.swap_screen, | ||||
|                                              Settings::values.upright_screen); | ||||
|             break; | ||||
|         case Settings::LayoutOption::MobilePortrait: | ||||
|             layout = Layout::MobilePortraitFrameLayout(width, height, Settings::values.swap_screen); | ||||
|             break; | ||||
|         case Settings::LayoutOption::MobileLandscape: | ||||
|             layout = Layout::MobileLandscapeFrameLayout(width, height, Settings::values.swap_screen, | ||||
|                                                         2.25f, false); | ||||
|             break; | ||||
|         case Settings::LayoutOption::Default: | ||||
|         default: | ||||
|             layout = Layout::DefaultFrameLayout(width, height, Settings::values.swap_screen, | ||||
|  | @ -177,6 +209,9 @@ void EmuWindow::UpdateCurrentFramebufferLayout(unsigned width, unsigned height) | |||
|         } | ||||
|         UpdateMinimumWindowSize(min_size); | ||||
|     } | ||||
|     if (Settings::values.render_3d == Settings::StereoRenderOption::CardboardVR) { | ||||
|         layout = Layout::GetCardboardSettings(layout); | ||||
|     } | ||||
|     NotifyFramebufferLayoutChanged(layout); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -115,8 +115,9 @@ public: | |||
|      * Signal that a touch pressed event has occurred (e.g. mouse click pressed) | ||||
|      * @param framebuffer_x Framebuffer x-coordinate that was pressed | ||||
|      * @param framebuffer_y Framebuffer y-coordinate that was pressed | ||||
|      * @returns True if the coordinates are within the touchpad, otherwise false | ||||
|      */ | ||||
|     void TouchPressed(unsigned framebuffer_x, unsigned framebuffer_y); | ||||
|     bool TouchPressed(unsigned framebuffer_x, unsigned framebuffer_y); | ||||
| 
 | ||||
|     /// Signal that a touch released event has occurred (e.g. mouse click released)
 | ||||
|     void TouchReleased(); | ||||
|  | @ -159,7 +160,8 @@ public: | |||
|      * Convenience method to update the current frame layout | ||||
|      * Read from the current settings to determine which layout to use. | ||||
|      */ | ||||
|     void UpdateCurrentFramebufferLayout(unsigned width, unsigned height); | ||||
|     void UpdateCurrentFramebufferLayout(unsigned width, unsigned height, | ||||
|                                         bool is_portrait_mode = {}); | ||||
| 
 | ||||
|     std::unique_ptr<TextureMailbox> mailbox = nullptr; | ||||
| 
 | ||||
|  |  | |||
|  | @ -117,6 +117,82 @@ FramebufferLayout DefaultFrameLayout(u32 width, u32 height, bool swapped, bool u | |||
|     return res; | ||||
| } | ||||
| 
 | ||||
| FramebufferLayout MobilePortraitFrameLayout(u32 width, u32 height, bool swapped) { | ||||
|     ASSERT(width > 0); | ||||
|     ASSERT(height > 0); | ||||
| 
 | ||||
|     FramebufferLayout res{width, height, true, true, {}, {}}; | ||||
|     // Default layout gives equal screen sizes to the top and bottom screen
 | ||||
|     Common::Rectangle<u32> screen_window_area{0, 0, width, height / 2}; | ||||
|     Common::Rectangle<u32> top_screen = maxRectangle(screen_window_area, TOP_SCREEN_ASPECT_RATIO); | ||||
|     Common::Rectangle<u32> bot_screen = maxRectangle(screen_window_area, BOT_SCREEN_ASPECT_RATIO); | ||||
| 
 | ||||
|     float window_aspect_ratio = static_cast<float>(height) / width; | ||||
|     // both screens height are taken into account by multiplying by 2
 | ||||
|     float emulation_aspect_ratio = TOP_SCREEN_ASPECT_RATIO * 2; | ||||
| 
 | ||||
|     if (window_aspect_ratio < emulation_aspect_ratio) { | ||||
|         // Apply borders to the left and right sides of the window.
 | ||||
|         top_screen = | ||||
|             top_screen.TranslateX((screen_window_area.GetWidth() - top_screen.GetWidth()) / 2); | ||||
|         bot_screen = | ||||
|             bot_screen.TranslateX((screen_window_area.GetWidth() - bot_screen.GetWidth()) / 2); | ||||
|     } else { | ||||
|         // Window is narrower than the emulation content
 | ||||
|         // Recalculate the bottom screen to account for the width difference between top and bottom
 | ||||
| 
 | ||||
|         bot_screen = bot_screen.TranslateX((top_screen.GetWidth() - bot_screen.GetWidth()) / 2); | ||||
|     } | ||||
| 
 | ||||
|     // Move the top screen to the bottom if we are swapped.
 | ||||
|     res.top_screen = swapped ? top_screen.TranslateY(bot_screen.GetHeight()) : top_screen; | ||||
|     res.bottom_screen = swapped ? bot_screen : bot_screen.TranslateY(top_screen.GetHeight()); | ||||
| 
 | ||||
|     return res; | ||||
| } | ||||
| 
 | ||||
| FramebufferLayout MobileLandscapeFrameLayout(u32 width, u32 height, bool swapped, | ||||
|                                              float scale_factor, bool center_vertical) { | ||||
|     ASSERT(width > 0); | ||||
|     ASSERT(height > 0); | ||||
| 
 | ||||
|     FramebufferLayout res{width, height, true, true, {}, {}}; | ||||
|     // Split the window into two parts. Give 4x width to the main screen and 1x width to the small
 | ||||
|     // To do that, find the total emulation box and maximize that based on window size
 | ||||
|     float window_aspect_ratio = static_cast<float>(height) / width; | ||||
|     float emulation_aspect_ratio = | ||||
|         swapped ? Core::kScreenBottomHeight * scale_factor / | ||||
|                       (Core::kScreenBottomWidth * scale_factor + Core::kScreenTopWidth) | ||||
|                 : Core::kScreenTopHeight * scale_factor / | ||||
|                       (Core::kScreenTopWidth * scale_factor + Core::kScreenBottomWidth); | ||||
|     float large_screen_aspect_ratio = swapped ? BOT_SCREEN_ASPECT_RATIO : TOP_SCREEN_ASPECT_RATIO; | ||||
|     float small_screen_aspect_ratio = swapped ? TOP_SCREEN_ASPECT_RATIO : BOT_SCREEN_ASPECT_RATIO; | ||||
| 
 | ||||
|     Common::Rectangle<u32> screen_window_area{0, 0, width, height}; | ||||
|     Common::Rectangle<u32> total_rect = maxRectangle(screen_window_area, emulation_aspect_ratio); | ||||
|     Common::Rectangle<u32> large_screen = maxRectangle(total_rect, large_screen_aspect_ratio); | ||||
|     Common::Rectangle<u32> fourth_size_rect = total_rect.Scale(1.f / scale_factor); | ||||
|     Common::Rectangle<u32> small_screen = maxRectangle(fourth_size_rect, small_screen_aspect_ratio); | ||||
| 
 | ||||
|     if (window_aspect_ratio < emulation_aspect_ratio) { | ||||
|         large_screen = | ||||
|             large_screen.TranslateX((screen_window_area.GetWidth() - total_rect.GetWidth()) / 2); | ||||
|     } else if (center_vertical) { | ||||
|         large_screen = large_screen.TranslateY((height - total_rect.GetHeight()) / 2); | ||||
|     } | ||||
| 
 | ||||
|     // Shift the small screen to the bottom right corner
 | ||||
|     small_screen = small_screen.TranslateX(large_screen.right); | ||||
|     if (center_vertical) { | ||||
|         small_screen.TranslateY(large_screen.GetHeight() + large_screen.top - | ||||
|                                 small_screen.GetHeight()); | ||||
|     } | ||||
| 
 | ||||
|     res.top_screen = swapped ? small_screen : large_screen; | ||||
|     res.bottom_screen = swapped ? large_screen : small_screen; | ||||
|     return res; | ||||
| } | ||||
| 
 | ||||
| FramebufferLayout SingleFrameLayout(u32 width, u32 height, bool swapped, bool upright) { | ||||
|     ASSERT(width > 0); | ||||
|     ASSERT(height > 0); | ||||
|  | @ -346,6 +422,22 @@ FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale) { | |||
|             layout = SideFrameLayout(width, height, Settings::values.swap_screen, | ||||
|                                      Settings::values.upright_screen); | ||||
|             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); | ||||
|             break; | ||||
|         case Settings::LayoutOption::MobileLandscape: | ||||
|             if (Settings::values.swap_screen) { | ||||
|                 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); | ||||
|             break; | ||||
|         case Settings::LayoutOption::Default: | ||||
|         default: | ||||
|             if (Settings::values.upright_screen) { | ||||
|  | @ -360,9 +452,92 @@ FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale) { | |||
|             break; | ||||
|         } | ||||
|     } | ||||
|     if (Settings::values.render_3d == Settings::StereoRenderOption::CardboardVR) { | ||||
|         layout = Layout::GetCardboardSettings(layout); | ||||
|     } | ||||
|     return layout; | ||||
| } | ||||
| 
 | ||||
| FramebufferLayout GetCardboardSettings(FramebufferLayout layout) { | ||||
|     FramebufferLayout newLayout = layout; | ||||
|     float top_screen_left = 0; | ||||
|     float top_screen_top = 0; | ||||
|     float bottom_screen_left = 0; | ||||
|     float bottom_screen_top = 0; | ||||
| 
 | ||||
|     float cardboardScreenScale = Settings::values.cardboard_screen_size / 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; | ||||
| 
 | ||||
|     float cardboardScreenWidth; | ||||
|     float cardboardScreenHeight; | ||||
|     switch (Settings::values.layout_option) { | ||||
|     case Settings::LayoutOption::MobileLandscape: | ||||
|     case Settings::LayoutOption::SideScreen: | ||||
|         // If orientation is portrait, only use MobilePortrait
 | ||||
|         if (!is_portrait) { | ||||
|             cardboardScreenWidth = top_screen_width + bottom_screen_width; | ||||
|             cardboardScreenHeight = is_swapped ? bottom_screen_height : top_screen_height; | ||||
|             if (is_swapped) | ||||
|                 top_screen_left += bottom_screen_width; | ||||
|             else | ||||
|                 bottom_screen_left += top_screen_width; | ||||
|             break; | ||||
|         } else { | ||||
|             [[fallthrough]]; | ||||
|         } | ||||
|     case Settings::LayoutOption::SingleScreen: | ||||
|     default: | ||||
|         if (!is_portrait) { | ||||
|             // Default values when using LayoutOption::SingleScreen
 | ||||
|             cardboardScreenWidth = is_swapped ? bottom_screen_width : top_screen_width; | ||||
|             cardboardScreenHeight = is_swapped ? bottom_screen_height : top_screen_height; | ||||
|             break; | ||||
|         } else { | ||||
|             [[fallthrough]]; | ||||
|         } | ||||
|     case Settings::LayoutOption::MobilePortrait: | ||||
|         cardboardScreenWidth = top_screen_width; | ||||
|         cardboardScreenHeight = top_screen_height + bottom_screen_height; | ||||
|         bottom_screen_left += (top_screen_width - bottom_screen_width) / 2.0f; | ||||
|         if (is_swapped) | ||||
|             top_screen_top += bottom_screen_height; | ||||
|         else | ||||
|             bottom_screen_top += top_screen_height; | ||||
|         break; | ||||
|     } | ||||
|     float cardboardMaxXShift = (layout.width / 2.0f - cardboardScreenWidth) / 2.0f; | ||||
|     float cardboardUserXShift = (Settings::values.cardboard_x_shift / 100.0f) * cardboardMaxXShift; | ||||
|     float cardboardMaxYShift = ((float)layout.height - cardboardScreenHeight) / 2.0f; | ||||
|     float cardboardUserYShift = (Settings::values.cardboard_y_shift / 100.0f) * cardboardMaxYShift; | ||||
| 
 | ||||
|     // Center the screens and apply user Y shift
 | ||||
|     newLayout.top_screen.left = top_screen_left + cardboardMaxXShift; | ||||
|     newLayout.top_screen.top = top_screen_top + cardboardMaxYShift + cardboardUserYShift; | ||||
|     newLayout.bottom_screen.left = bottom_screen_left + cardboardMaxXShift; | ||||
|     newLayout.bottom_screen.top = bottom_screen_top + cardboardMaxYShift + cardboardUserYShift; | ||||
| 
 | ||||
|     // Set the X coordinates for the right eye and apply user X shift
 | ||||
|     newLayout.cardboard.top_screen_right_eye = newLayout.top_screen.left - cardboardUserXShift; | ||||
|     newLayout.top_screen.left += cardboardUserXShift; | ||||
|     newLayout.cardboard.bottom_screen_right_eye = | ||||
|         newLayout.bottom_screen.left - cardboardUserXShift; | ||||
|     newLayout.bottom_screen.left += cardboardUserXShift; | ||||
|     newLayout.cardboard.user_x_shift = cardboardUserXShift; | ||||
| 
 | ||||
|     // Update right/bottom instead of passing new variables for width/height
 | ||||
|     newLayout.top_screen.right = newLayout.top_screen.left + top_screen_width; | ||||
|     newLayout.top_screen.bottom = newLayout.top_screen.top + top_screen_height; | ||||
|     newLayout.bottom_screen.right = newLayout.bottom_screen.left + bottom_screen_width; | ||||
|     newLayout.bottom_screen.bottom = newLayout.bottom_screen.top + bottom_screen_height; | ||||
| 
 | ||||
|     return newLayout; | ||||
| } | ||||
| 
 | ||||
| std::pair<unsigned, unsigned> GetMinimumSizeFromLayout(Settings::LayoutOption layout, | ||||
|                                                        bool upright_screen) { | ||||
|     unsigned min_width, min_height; | ||||
|  |  | |||
|  | @ -9,6 +9,13 @@ | |||
| 
 | ||||
| namespace Layout { | ||||
| 
 | ||||
| /// Describes the horizontal coordinates for the right eye screen when using Cardboard VR
 | ||||
| struct CardboardSettings { | ||||
|     float top_screen_right_eye; | ||||
|     float bottom_screen_right_eye; | ||||
|     float user_x_shift; | ||||
| }; | ||||
| 
 | ||||
| /// Describes the layout of the window framebuffer (size and top/bottom screen positions)
 | ||||
| struct FramebufferLayout { | ||||
|     u32 width; | ||||
|  | @ -19,6 +26,8 @@ struct FramebufferLayout { | |||
|     Common::Rectangle<u32> bottom_screen; | ||||
|     bool is_rotated = true; | ||||
| 
 | ||||
|     CardboardSettings cardboard; | ||||
| 
 | ||||
|     /**
 | ||||
|      * Returns the ration of pixel size of the top screen, compared to the native size of the 3DS | ||||
|      * screen. | ||||
|  | @ -35,6 +44,29 @@ struct FramebufferLayout { | |||
|  */ | ||||
| FramebufferLayout DefaultFrameLayout(u32 width, u32 height, bool is_swapped, bool upright); | ||||
| 
 | ||||
| /**
 | ||||
|  * Factory method for constructing a mobile portrait FramebufferLayout | ||||
|  * @param width Window framebuffer width in pixels | ||||
|  * @param height Window framebuffer height in pixels | ||||
|  * @param is_swapped if true, the bottom screen will be displayed above the top screen | ||||
|  * @return Newly created FramebufferLayout object with mobile portrait screen regions initialized | ||||
|  */ | ||||
| FramebufferLayout MobilePortraitFrameLayout(u32 width, u32 height, bool is_swapped); | ||||
| 
 | ||||
| /**
 | ||||
|  * Factory method for constructing a Frame with the a 4x size Top screen with a 1x size bottom | ||||
|  * screen on the right | ||||
|  * This is useful in particular because it matches well with a 1920x1080 resolution monitor | ||||
|  * @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 | ||||
|  * @param scale_factor Scale factor to use for bottom screen with respect to top screen | ||||
|  * @param center_vertical When true, centers the top and bottom screens vertically | ||||
|  * @return Newly created FramebufferLayout object with default screen regions initialized | ||||
|  */ | ||||
| FramebufferLayout MobileLandscapeFrameLayout(u32 width, u32 height, bool is_swapped, | ||||
|                                              float scale_factor, bool center_vertical); | ||||
| 
 | ||||
| /**
 | ||||
|  * Factory method for constructing a FramebufferLayout with only the top or bottom screen | ||||
|  * @param width Window framebuffer width in pixels | ||||
|  | @ -81,6 +113,13 @@ FramebufferLayout CustomFrameLayout(u32 width, u32 height); | |||
|  */ | ||||
| FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale); | ||||
| 
 | ||||
| /**
 | ||||
|  * Convenience method for transforming a frame layout when using Cardboard VR | ||||
|  * @param layout frame layout to transform | ||||
|  * @return layout transformed with the user cardboard settings | ||||
|  */ | ||||
| FramebufferLayout GetCardboardSettings(FramebufferLayout layout); | ||||
| 
 | ||||
| std::pair<unsigned, unsigned> GetMinimumSizeFromLayout(Settings::LayoutOption layout, | ||||
|                                                        bool upright_screen); | ||||
| 
 | ||||
|  |  | |||
|  | @ -76,7 +76,7 @@ void UnregisterFactory(const std::string& name) { | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * Create an input device from given paramters. | ||||
|  * Create an input device from given parameters. | ||||
|  * @tparam InputDeviceType the type of input devices to create | ||||
|  * @param params a serialized ParamPackage string contains all parameters for creating the device | ||||
|  */ | ||||
|  |  | |||
|  | @ -33,9 +33,11 @@ void Apply() { | |||
|     VideoCore::g_hw_shader_accurate_mul = values.shaders_accurate_mul; | ||||
|     VideoCore::g_use_disk_shader_cache = values.use_disk_shader_cache; | ||||
| 
 | ||||
| #ifndef ANDROID | ||||
|     if (VideoCore::g_renderer) { | ||||
|         VideoCore::g_renderer->UpdateCurrentFramebufferLayout(); | ||||
|     } | ||||
| #endif | ||||
| 
 | ||||
|     VideoCore::g_renderer_bg_color_update_requested = true; | ||||
|     VideoCore::g_renderer_sampler_update_requested = true; | ||||
|  |  | |||
|  | @ -24,6 +24,14 @@ enum class LayoutOption { | |||
|     SingleScreen, | ||||
|     LargeScreen, | ||||
|     SideScreen, | ||||
| 
 | ||||
|     // Similiar to default, but better for mobile devices in portrait mode. Top screen in clamped to
 | ||||
|     // the top of the frame, and the bottom screen is enlarged to match the top screen.
 | ||||
|     MobilePortrait, | ||||
| 
 | ||||
|     // Similiar to LargeScreen, but better for mobile devices in landscape mode. The screens are
 | ||||
|     // clamped to the top of the frame, and the bottom screen is a bit bigger.
 | ||||
|     MobileLandscape, | ||||
| }; | ||||
| 
 | ||||
| enum class MicInputType { | ||||
|  | @ -32,7 +40,14 @@ enum class MicInputType { | |||
|     Static, | ||||
| }; | ||||
| 
 | ||||
| enum class StereoRenderOption { Off, SideBySide, Anaglyph, Interlaced, ReverseInterlaced }; | ||||
| enum class StereoRenderOption { | ||||
|     Off, | ||||
|     SideBySide, | ||||
|     Anaglyph, | ||||
|     Interlaced, | ||||
|     ReverseInterlaced, | ||||
|     CardboardVR | ||||
| }; | ||||
| 
 | ||||
| namespace NativeButton { | ||||
| enum Values { | ||||
|  | @ -182,6 +197,10 @@ struct Values { | |||
|     StereoRenderOption render_3d; | ||||
|     std::atomic<u8> factor_3d; | ||||
| 
 | ||||
|     int cardboard_screen_size; | ||||
|     int cardboard_x_shift; | ||||
|     int cardboard_y_shift; | ||||
| 
 | ||||
|     bool filter_mode; | ||||
|     std::string pp_shader_name; | ||||
| 
 | ||||
|  |  | |||
|  | @ -11,9 +11,9 @@ | |||
| 
 | ||||
| RendererBase::RendererBase(Frontend::EmuWindow& window) : render_window{window} {} | ||||
| RendererBase::~RendererBase() = default; | ||||
| void RendererBase::UpdateCurrentFramebufferLayout() { | ||||
| void RendererBase::UpdateCurrentFramebufferLayout(bool is_portrait_mode) { | ||||
|     const Layout::FramebufferLayout& layout = render_window.GetFramebufferLayout(); | ||||
|     render_window.UpdateCurrentFramebufferLayout(layout.width, layout.height); | ||||
|     render_window.UpdateCurrentFramebufferLayout(layout.width, layout.height, is_portrait_mode); | ||||
| } | ||||
| 
 | ||||
| void RendererBase::RefreshRasterizerSetting() { | ||||
|  |  | |||
|  | @ -38,7 +38,7 @@ public: | |||
|     virtual void CleanupVideoDumping() = 0; | ||||
| 
 | ||||
|     /// Updates the framebuffer layout of the contained render window handle.
 | ||||
|     void UpdateCurrentFramebufferLayout(); | ||||
|     void UpdateCurrentFramebufferLayout(bool is_portrait_mode = {}); | ||||
| 
 | ||||
|     // Getter/setter functions:
 | ||||
|     // ------------------------
 | ||||
|  |  | |||
|  | @ -1016,6 +1016,16 @@ void RendererOpenGL::DrawScreens(const Layout::FramebufferLayout& layout, bool f | |||
|                                         ((float)top_screen.left / 2) + ((float)layout.width / 2), | ||||
|                                         (float)top_screen.top, (float)top_screen.GetWidth() / 2, | ||||
|                                         (float)top_screen.GetHeight()); | ||||
|             } else if (Settings::values.render_3d == Settings::StereoRenderOption::CardboardVR) { | ||||
|                 DrawSingleScreenRotated(screen_infos[0], layout.top_screen.left, | ||||
|                                         layout.top_screen.top, layout.top_screen.GetWidth(), | ||||
|                                         layout.top_screen.GetHeight()); | ||||
|                 glUniform1i(uniform_layer, 1); | ||||
|                 DrawSingleScreenRotated(screen_infos[1], | ||||
|                                         layout.cardboard.top_screen_right_eye + | ||||
|                                             ((float)layout.width / 2), | ||||
|                                         layout.top_screen.top, layout.top_screen.GetWidth(), | ||||
|                                         layout.top_screen.GetHeight()); | ||||
|             } else if (stereo_single_screen) { | ||||
|                 DrawSingleScreenStereoRotated( | ||||
|                     screen_infos[0], screen_infos[1], (float)top_screen.left, (float)top_screen.top, | ||||
|  | @ -1033,6 +1043,14 @@ void RendererOpenGL::DrawScreens(const Layout::FramebufferLayout& layout, bool f | |||
|                                  ((float)top_screen.left / 2) + ((float)layout.width / 2), | ||||
|                                  (float)top_screen.top, (float)top_screen.GetWidth() / 2, | ||||
|                                  (float)top_screen.GetHeight()); | ||||
|             } else if (Settings::values.render_3d == Settings::StereoRenderOption::CardboardVR) { | ||||
|                 DrawSingleScreen(screen_infos[0], layout.top_screen.left, layout.top_screen.top, | ||||
|                                  layout.top_screen.GetWidth(), layout.top_screen.GetHeight()); | ||||
|                 glUniform1i(uniform_layer, 1); | ||||
|                 DrawSingleScreen(screen_infos[1], | ||||
|                                  layout.cardboard.top_screen_right_eye + ((float)layout.width / 2), | ||||
|                                  layout.top_screen.top, layout.top_screen.GetWidth(), | ||||
|                                  layout.top_screen.GetHeight()); | ||||
|             } else if (stereo_single_screen) { | ||||
|                 DrawSingleScreenStereo(screen_infos[0], screen_infos[1], (float)top_screen.left, | ||||
|                                        (float)top_screen.top, (float)top_screen.GetWidth(), | ||||
|  | @ -1056,6 +1074,16 @@ void RendererOpenGL::DrawScreens(const Layout::FramebufferLayout& layout, bool f | |||
|                     screen_infos[2], ((float)bottom_screen.left / 2) + ((float)layout.width / 2), | ||||
|                     (float)bottom_screen.top, (float)bottom_screen.GetWidth() / 2, | ||||
|                     (float)bottom_screen.GetHeight()); | ||||
|             } else if (Settings::values.render_3d == Settings::StereoRenderOption::CardboardVR) { | ||||
|                 DrawSingleScreenRotated(screen_infos[2], layout.bottom_screen.left, | ||||
|                                         layout.bottom_screen.top, layout.bottom_screen.GetWidth(), | ||||
|                                         layout.bottom_screen.GetHeight()); | ||||
|                 glUniform1i(uniform_layer, 1); | ||||
|                 DrawSingleScreenRotated(screen_infos[2], | ||||
|                                         layout.cardboard.bottom_screen_right_eye + | ||||
|                                             ((float)layout.width / 2), | ||||
|                                         layout.bottom_screen.top, layout.bottom_screen.GetWidth(), | ||||
|                                         layout.bottom_screen.GetHeight()); | ||||
|             } else if (stereo_single_screen) { | ||||
|                 DrawSingleScreenStereoRotated(screen_infos[2], screen_infos[2], | ||||
|                                               (float)bottom_screen.left, (float)bottom_screen.top, | ||||
|  | @ -1076,6 +1104,16 @@ void RendererOpenGL::DrawScreens(const Layout::FramebufferLayout& layout, bool f | |||
|                                  ((float)bottom_screen.left / 2) + ((float)layout.width / 2), | ||||
|                                  (float)bottom_screen.top, (float)bottom_screen.GetWidth() / 2, | ||||
|                                  (float)bottom_screen.GetHeight()); | ||||
|             } else if (Settings::values.render_3d == Settings::StereoRenderOption::CardboardVR) { | ||||
|                 DrawSingleScreen(screen_infos[2], layout.bottom_screen.left, | ||||
|                                  layout.bottom_screen.top, layout.bottom_screen.GetWidth(), | ||||
|                                  layout.bottom_screen.GetHeight()); | ||||
|                 glUniform1i(uniform_layer, 1); | ||||
|                 DrawSingleScreen(screen_infos[2], | ||||
|                                  layout.cardboard.bottom_screen_right_eye + | ||||
|                                      ((float)layout.width / 2), | ||||
|                                  layout.bottom_screen.top, layout.bottom_screen.GetWidth(), | ||||
|                                  layout.bottom_screen.GetHeight()); | ||||
|             } else if (stereo_single_screen) { | ||||
|                 DrawSingleScreenStereo(screen_infos[2], screen_infos[2], (float)bottom_screen.left, | ||||
|                                        (float)bottom_screen.top, (float)bottom_screen.GetWidth(), | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue