diff options
Diffstat (limited to 'src/core/frontend')
| -rw-r--r-- | src/core/frontend/emu_window.cpp | 3 | ||||
| -rw-r--r-- | src/core/frontend/framebuffer_layout.cpp | 36 | ||||
| -rw-r--r-- | src/core/frontend/framebuffer_layout.h | 11 |
3 files changed, 49 insertions, 1 deletions
diff --git a/src/core/frontend/emu_window.cpp b/src/core/frontend/emu_window.cpp index 60b20d4e2..54fa5c7fa 100644 --- a/src/core/frontend/emu_window.cpp +++ b/src/core/frontend/emu_window.cpp | |||
| @@ -74,6 +74,9 @@ void EmuWindow::UpdateCurrentFramebufferLayout(unsigned width, unsigned height) | |||
| 74 | case Settings::LayoutOption::LargeScreen: | 74 | case Settings::LayoutOption::LargeScreen: |
| 75 | layout = Layout::LargeFrameLayout(width, height, Settings::values.swap_screen); | 75 | layout = Layout::LargeFrameLayout(width, height, Settings::values.swap_screen); |
| 76 | break; | 76 | break; |
| 77 | case Settings::LayoutOption::SideScreen: | ||
| 78 | layout = Layout::SideFrameLayout(width, height, Settings::values.swap_screen); | ||
| 79 | break; | ||
| 77 | case Settings::LayoutOption::Default: | 80 | case Settings::LayoutOption::Default: |
| 78 | default: | 81 | default: |
| 79 | layout = Layout::DefaultFrameLayout(width, height, Settings::values.swap_screen); | 82 | layout = Layout::DefaultFrameLayout(width, height, Settings::values.swap_screen); |
diff --git a/src/core/frontend/framebuffer_layout.cpp b/src/core/frontend/framebuffer_layout.cpp index d2d02f9ff..e9f778fcb 100644 --- a/src/core/frontend/framebuffer_layout.cpp +++ b/src/core/frontend/framebuffer_layout.cpp | |||
| @@ -141,6 +141,40 @@ FramebufferLayout LargeFrameLayout(unsigned width, unsigned height, bool swapped | |||
| 141 | return res; | 141 | return res; |
| 142 | } | 142 | } |
| 143 | 143 | ||
| 144 | FramebufferLayout SideFrameLayout(unsigned width, unsigned height, bool swapped) { | ||
| 145 | ASSERT(width > 0); | ||
| 146 | ASSERT(height > 0); | ||
| 147 | |||
| 148 | FramebufferLayout res{width, height, true, true, {}, {}}; | ||
| 149 | // Aspect ratio of both screens side by side | ||
| 150 | const float emulation_aspect_ratio = static_cast<float>(Core::kScreenTopHeight) / | ||
| 151 | (Core::kScreenTopWidth + Core::kScreenBottomWidth); | ||
| 152 | float window_aspect_ratio = static_cast<float>(height) / width; | ||
| 153 | MathUtil::Rectangle<unsigned> screen_window_area{0, 0, width, height}; | ||
| 154 | // Find largest Rectangle that can fit in the window size with the given aspect ratio | ||
| 155 | MathUtil::Rectangle<unsigned> screen_rect = | ||
| 156 | maxRectangle(screen_window_area, emulation_aspect_ratio); | ||
| 157 | // Find sizes of top and bottom screen | ||
| 158 | MathUtil::Rectangle<unsigned> top_screen = maxRectangle(screen_rect, TOP_SCREEN_ASPECT_RATIO); | ||
| 159 | MathUtil::Rectangle<unsigned> bot_screen = maxRectangle(screen_rect, BOT_SCREEN_ASPECT_RATIO); | ||
| 160 | |||
| 161 | if (window_aspect_ratio < emulation_aspect_ratio) { | ||
| 162 | // Apply borders to the left and right sides of the window. | ||
| 163 | u32 shift_horizontal = (screen_window_area.GetWidth() - screen_rect.GetWidth()) / 2; | ||
| 164 | top_screen = top_screen.TranslateX(shift_horizontal); | ||
| 165 | bot_screen = bot_screen.TranslateX(shift_horizontal); | ||
| 166 | } else { | ||
| 167 | // Window is narrower than the emulation content => apply borders to the top and bottom | ||
| 168 | u32 shift_vertical = (screen_window_area.GetHeight() - screen_rect.GetHeight()) / 2; | ||
| 169 | top_screen = top_screen.TranslateY(shift_vertical); | ||
| 170 | bot_screen = bot_screen.TranslateY(shift_vertical); | ||
| 171 | } | ||
| 172 | // Move the top screen to the right if we are swapped. | ||
| 173 | res.top_screen = swapped ? top_screen.TranslateX(bot_screen.GetWidth()) : top_screen; | ||
| 174 | res.bottom_screen = swapped ? bot_screen : bot_screen.TranslateX(top_screen.GetWidth()); | ||
| 175 | return res; | ||
| 176 | } | ||
| 177 | |||
| 144 | FramebufferLayout CustomFrameLayout(unsigned width, unsigned height) { | 178 | FramebufferLayout CustomFrameLayout(unsigned width, unsigned height) { |
| 145 | ASSERT(width > 0); | 179 | ASSERT(width > 0); |
| 146 | ASSERT(height > 0); | 180 | ASSERT(height > 0); |
| @@ -158,4 +192,4 @@ FramebufferLayout CustomFrameLayout(unsigned width, unsigned height) { | |||
| 158 | res.bottom_screen = bot_screen; | 192 | res.bottom_screen = bot_screen; |
| 159 | return res; | 193 | return res; |
| 160 | } | 194 | } |
| 161 | } | 195 | } // namespace Layout |
diff --git a/src/core/frontend/framebuffer_layout.h b/src/core/frontend/framebuffer_layout.h index 9a7738969..4983cf103 100644 --- a/src/core/frontend/framebuffer_layout.h +++ b/src/core/frontend/framebuffer_layout.h | |||
| @@ -54,6 +54,17 @@ FramebufferLayout SingleFrameLayout(unsigned width, unsigned height, bool is_swa | |||
| 54 | FramebufferLayout LargeFrameLayout(unsigned width, unsigned height, bool is_swapped); | 54 | FramebufferLayout LargeFrameLayout(unsigned width, unsigned height, bool is_swapped); |
| 55 | 55 | ||
| 56 | /** | 56 | /** |
| 57 | * Factory method for constructing a Frame with the Top screen and bottom | ||
| 58 | * screen side by side | ||
| 59 | * This is useful for devices with small screens, like the GPDWin | ||
| 60 | * @param width Window framebuffer width in pixels | ||
| 61 | * @param height Window framebuffer height in pixels | ||
| 62 | * @param is_swapped if true, the bottom screen will be the left display | ||
| 63 | * @return Newly created FramebufferLayout object with default screen regions initialized | ||
| 64 | */ | ||
| 65 | FramebufferLayout SideFrameLayout(unsigned width, unsigned height, bool is_swapped); | ||
| 66 | |||
| 67 | /** | ||
| 57 | * Factory method for constructing a custom FramebufferLayout | 68 | * Factory method for constructing a custom FramebufferLayout |
| 58 | * @param width Window framebuffer width in pixels | 69 | * @param width Window framebuffer width in pixels |
| 59 | * @param height Window framebuffer height in pixels | 70 | * @param height Window framebuffer height in pixels |