diff options
Diffstat (limited to 'src/common')
| -rw-r--r-- | src/common/framebuffer_layout.cpp | 338 | ||||
| -rw-r--r-- | src/common/math_util.h | 12 |
2 files changed, 100 insertions, 250 deletions
diff --git a/src/common/framebuffer_layout.cpp b/src/common/framebuffer_layout.cpp index 42cfa32a9..d50c141bb 100644 --- a/src/common/framebuffer_layout.cpp +++ b/src/common/framebuffer_layout.cpp | |||
| @@ -9,290 +9,128 @@ | |||
| 9 | #include "video_core/video_core.h" | 9 | #include "video_core/video_core.h" |
| 10 | 10 | ||
| 11 | namespace Layout { | 11 | namespace Layout { |
| 12 | static FramebufferLayout DefaultFrameLayout(unsigned width, unsigned height) { | ||
| 13 | 12 | ||
| 14 | ASSERT(width > 0); | 13 | static const float TOP_SCREEN_ASPECT_RATIO = |
| 15 | ASSERT(height > 0); | 14 | static_cast<float>(VideoCore::kScreenTopHeight) / VideoCore::kScreenTopWidth; |
| 16 | 15 | static const float BOT_SCREEN_ASPECT_RATIO = | |
| 17 | FramebufferLayout res {width, height, true, true, {}, {}}; | 16 | static_cast<float>(VideoCore::kScreenBottomHeight) / VideoCore::kScreenBottomWidth; |
| 18 | 17 | static const float BOT_TO_TOP_SCREEN_RATIO_DIFFERENCE = | |
| 19 | float window_aspect_ratio = static_cast<float>(height) / width; | 18 | BOT_SCREEN_ASPECT_RATIO - TOP_SCREEN_ASPECT_RATIO; |
| 20 | float emulation_aspect_ratio = static_cast<float>(VideoCore::kScreenTopHeight * 2) / | 19 | |
| 21 | VideoCore::kScreenTopWidth; | 20 | // Finds the largest size subrectangle contained in window area that is confined to the aspect ratio |
| 22 | 21 | template <class T> | |
| 23 | if (window_aspect_ratio > emulation_aspect_ratio) { | 22 | static MathUtil::Rectangle<T> maxRectangle(MathUtil::Rectangle<T> window_area, |
| 24 | // Window is narrower than the emulation content => apply borders to the top and bottom | 23 | float screen_aspect_ratio) { |
| 25 | int viewport_height = static_cast<int>(std::round(emulation_aspect_ratio * width)); | 24 | float scale = std::min(static_cast<float>(window_area.GetWidth()), |
| 26 | 25 | window_area.GetHeight() / screen_aspect_ratio); | |
| 27 | res.top_screen.left = 0; | 26 | return MathUtil::Rectangle<T>{0, 0, static_cast<T>(scale), |
| 28 | res.top_screen.right = res.top_screen.left + width; | 27 | static_cast<T>(scale * screen_aspect_ratio)}; |
| 29 | res.top_screen.top = (height - viewport_height) / 2; | ||
| 30 | res.top_screen.bottom = res.top_screen.top + viewport_height / 2; | ||
| 31 | |||
| 32 | int bottom_width = static_cast<int>((static_cast<float>(VideoCore::kScreenBottomWidth) / | ||
| 33 | VideoCore::kScreenTopWidth) * (res.top_screen.right - res.top_screen.left)); | ||
| 34 | int bottom_border = ((res.top_screen.right - res.top_screen.left) - bottom_width) / 2; | ||
| 35 | |||
| 36 | res.bottom_screen.left = bottom_border; | ||
| 37 | res.bottom_screen.right = res.bottom_screen.left + bottom_width; | ||
| 38 | res.bottom_screen.top = res.top_screen.bottom; | ||
| 39 | res.bottom_screen.bottom = res.bottom_screen.top + viewport_height / 2; | ||
| 40 | } else { | ||
| 41 | // Otherwise, apply borders to the left and right sides of the window. | ||
| 42 | int viewport_width = static_cast<int>(std::round(height / emulation_aspect_ratio)); | ||
| 43 | |||
| 44 | res.top_screen.left = (width - viewport_width) / 2; | ||
| 45 | res.top_screen.right = res.top_screen.left + viewport_width; | ||
| 46 | res.top_screen.top = 0; | ||
| 47 | res.top_screen.bottom = res.top_screen.top + height / 2; | ||
| 48 | |||
| 49 | int bottom_width = static_cast<int>((static_cast<float>(VideoCore::kScreenBottomWidth) / | ||
| 50 | VideoCore::kScreenTopWidth) * (res.top_screen.right - res.top_screen.left)); | ||
| 51 | int bottom_border = ((res.top_screen.right - res.top_screen.left) - bottom_width) / 2; | ||
| 52 | |||
| 53 | res.bottom_screen.left = res.top_screen.left + bottom_border; | ||
| 54 | res.bottom_screen.right = res.bottom_screen.left + bottom_width; | ||
| 55 | res.bottom_screen.top = res.top_screen.bottom; | ||
| 56 | res.bottom_screen.bottom = res.bottom_screen.top + height / 2; | ||
| 57 | } | ||
| 58 | |||
| 59 | return res; | ||
| 60 | } | 28 | } |
| 61 | 29 | ||
| 62 | static FramebufferLayout DefaultFrameLayout_Swapped(unsigned width, unsigned height) { | 30 | FramebufferLayout DefaultFrameLayout(unsigned width, unsigned height, bool swapped) { |
| 63 | |||
| 64 | ASSERT(width > 0); | 31 | ASSERT(width > 0); |
| 65 | ASSERT(height > 0); | 32 | ASSERT(height > 0); |
| 66 | 33 | ||
| 67 | FramebufferLayout res {width, height, true, true, {}, {}}; | 34 | FramebufferLayout res{width, height, true, true, {}, {}}; |
| 35 | // Default layout gives equal screen sizes to the top and bottom screen | ||
| 36 | MathUtil::Rectangle<unsigned> screen_window_area{0, 0, width, height / 2}; | ||
| 37 | MathUtil::Rectangle<unsigned> top_screen = | ||
| 38 | maxRectangle(screen_window_area, TOP_SCREEN_ASPECT_RATIO); | ||
| 39 | MathUtil::Rectangle<unsigned> bot_screen = | ||
| 40 | maxRectangle(screen_window_area, BOT_SCREEN_ASPECT_RATIO); | ||
| 68 | 41 | ||
| 69 | float window_aspect_ratio = static_cast<float>(height) / width; | 42 | float window_aspect_ratio = static_cast<float>(height) / width; |
| 70 | float emulation_aspect_ratio = static_cast<float>(VideoCore::kScreenTopHeight * 2) / | 43 | // both screens height are taken into account by multiplying by 2 |
| 71 | VideoCore::kScreenTopWidth; | 44 | float emulation_aspect_ratio = TOP_SCREEN_ASPECT_RATIO * 2; |
| 72 | |||
| 73 | if (window_aspect_ratio > emulation_aspect_ratio) { | ||
| 74 | // Window is narrower than the emulation content => apply borders to the top and bottom | ||
| 75 | int viewport_height = static_cast<int>(std::round(emulation_aspect_ratio * width)); | ||
| 76 | |||
| 77 | res.top_screen.left = 0; | ||
| 78 | res.top_screen.right = res.top_screen.left + width; | ||
| 79 | 45 | ||
| 80 | int bottom_width = static_cast<int>((static_cast<float>(VideoCore::kScreenBottomWidth) / | 46 | if (window_aspect_ratio < emulation_aspect_ratio) { |
| 81 | VideoCore::kScreenTopWidth) * (res.top_screen.right - res.top_screen.left)); | 47 | // Apply borders to the left and right sides of the window. |
| 82 | int bottom_border = ((res.top_screen.right - res.top_screen.left) - bottom_width) / 2; | 48 | top_screen = |
| 83 | 49 | top_screen.TranslateX((screen_window_area.GetWidth() - top_screen.GetWidth()) / 2); | |
| 84 | res.bottom_screen.left = bottom_border; | 50 | bot_screen = |
| 85 | res.bottom_screen.right = res.bottom_screen.left + bottom_width; | 51 | bot_screen.TranslateX((screen_window_area.GetWidth() - bot_screen.GetWidth()) / 2); |
| 86 | res.bottom_screen.top = (height - viewport_height) / 2; | ||
| 87 | res.bottom_screen.bottom = res.bottom_screen.top + viewport_height / 2; | ||
| 88 | |||
| 89 | res.top_screen.top = res.bottom_screen.bottom; | ||
| 90 | res.top_screen.bottom = res.top_screen.top + viewport_height / 2; | ||
| 91 | } else { | 52 | } else { |
| 92 | // Otherwise, apply borders to the left and right sides of the window. | ||
| 93 | int viewport_width = static_cast<int>(std::round(height / emulation_aspect_ratio)); | ||
| 94 | res.top_screen.left = (width - viewport_width) / 2; | ||
| 95 | res.top_screen.right = res.top_screen.left + viewport_width; | ||
| 96 | |||
| 97 | int bottom_width = static_cast<int>((static_cast<float>(VideoCore::kScreenBottomWidth) / | ||
| 98 | VideoCore::kScreenTopWidth) * (res.top_screen.right - res.top_screen.left)); | ||
| 99 | int bottom_border = ((res.top_screen.right - res.top_screen.left) - bottom_width) / 2; | ||
| 100 | |||
| 101 | res.bottom_screen.left = res.top_screen.left + bottom_border; | ||
| 102 | res.bottom_screen.right = res.bottom_screen.left + bottom_width; | ||
| 103 | res.bottom_screen.top = 0; | ||
| 104 | res.bottom_screen.bottom = res.bottom_screen.top + height / 2; | ||
| 105 | |||
| 106 | res.top_screen.top = res.bottom_screen.bottom; | ||
| 107 | res.top_screen.bottom = res.top_screen.top + height / 2; | ||
| 108 | } | ||
| 109 | |||
| 110 | return res; | ||
| 111 | } | ||
| 112 | |||
| 113 | static FramebufferLayout SingleFrameLayout(unsigned width, unsigned height) { | ||
| 114 | |||
| 115 | ASSERT(width > 0); | ||
| 116 | ASSERT(height > 0); | ||
| 117 | |||
| 118 | FramebufferLayout res {width, height, true, false, {}, {}}; | ||
| 119 | |||
| 120 | float window_aspect_ratio = static_cast<float>(height) / width; | ||
| 121 | float emulation_aspect_ratio = static_cast<float>(VideoCore::kScreenTopHeight) / | ||
| 122 | VideoCore::kScreenTopWidth; | ||
| 123 | |||
| 124 | if (window_aspect_ratio > emulation_aspect_ratio) { | ||
| 125 | // Window is narrower than the emulation content => apply borders to the top and bottom | 53 | // Window is narrower than the emulation content => apply borders to the top and bottom |
| 126 | int viewport_height = static_cast<int>(std::round(emulation_aspect_ratio * width)); | 54 | top_screen = top_screen.TranslateY(height / 2 - top_screen.GetHeight()); |
| 127 | 55 | // Recalculate the bottom screen to account for the width difference between top and bottom | |
| 128 | res.top_screen.left = 0; | 56 | screen_window_area = {0, 0, width, top_screen.GetHeight()}; |
| 129 | res.top_screen.right = res.top_screen.left + width; | 57 | bot_screen = maxRectangle(screen_window_area, BOT_SCREEN_ASPECT_RATIO); |
| 130 | res.top_screen.top = (height - viewport_height) / 2; | 58 | bot_screen = bot_screen.TranslateX((top_screen.GetWidth() - bot_screen.GetWidth()) / 2); |
| 131 | res.top_screen.bottom = res.top_screen.top + viewport_height; | ||
| 132 | |||
| 133 | res.bottom_screen.left = 0; | ||
| 134 | res.bottom_screen.right = VideoCore::kScreenBottomWidth; | ||
| 135 | res.bottom_screen.top = 0; | ||
| 136 | res.bottom_screen.bottom = VideoCore::kScreenBottomHeight; | ||
| 137 | } else { | ||
| 138 | // Otherwise, apply borders to the left and right sides of the window. | ||
| 139 | int viewport_width = static_cast<int>(std::round(height / emulation_aspect_ratio)); | ||
| 140 | |||
| 141 | res.top_screen.left = (width - viewport_width) / 2; | ||
| 142 | res.top_screen.right = res.top_screen.left + viewport_width; | ||
| 143 | res.top_screen.top = 0; | ||
| 144 | res.top_screen.bottom = res.top_screen.top + height; | ||
| 145 | |||
| 146 | // The Rasterizer still depends on these fields to maintain the right aspect ratio | ||
| 147 | res.bottom_screen.left = 0; | ||
| 148 | res.bottom_screen.right = VideoCore::kScreenBottomWidth; | ||
| 149 | res.bottom_screen.top = 0; | ||
| 150 | res.bottom_screen.bottom = VideoCore::kScreenBottomHeight; | ||
| 151 | } | 59 | } |
| 152 | 60 | // Move the top screen to the bottom if we are swapped. | |
| 61 | res.top_screen = swapped ? top_screen.TranslateY(height / 2) : top_screen; | ||
| 62 | res.bottom_screen = swapped ? bot_screen : bot_screen.TranslateY(height / 2); | ||
| 153 | return res; | 63 | return res; |
| 154 | } | 64 | } |
| 155 | 65 | ||
| 156 | static FramebufferLayout SingleFrameLayout_Swapped(unsigned width, unsigned height) { | 66 | FramebufferLayout SingleFrameLayout(unsigned width, unsigned height, bool swapped) { |
| 157 | |||
| 158 | ASSERT(width > 0); | 67 | ASSERT(width > 0); |
| 159 | ASSERT(height > 0); | 68 | ASSERT(height > 0); |
| 69 | // The drawing code needs at least somewhat valid values for both screens | ||
| 70 | // so just calculate them both even if the other isn't showing. | ||
| 71 | FramebufferLayout res{width, height, !swapped, swapped, {}, {}}; | ||
| 160 | 72 | ||
| 161 | FramebufferLayout res {width, height, false, true, {}, {}}; | 73 | MathUtil::Rectangle<unsigned> screen_window_area{0, 0, width, height}; |
| 74 | MathUtil::Rectangle<unsigned> top_screen = | ||
| 75 | maxRectangle(screen_window_area, TOP_SCREEN_ASPECT_RATIO); | ||
| 76 | MathUtil::Rectangle<unsigned> bot_screen = | ||
| 77 | maxRectangle(screen_window_area, BOT_SCREEN_ASPECT_RATIO); | ||
| 162 | 78 | ||
| 163 | float window_aspect_ratio = static_cast<float>(height) / width; | 79 | float window_aspect_ratio = static_cast<float>(height) / width; |
| 164 | float emulation_aspect_ratio = static_cast<float>(VideoCore::kScreenBottomHeight) / | 80 | float emulation_aspect_ratio = (swapped) ? BOT_SCREEN_ASPECT_RATIO : TOP_SCREEN_ASPECT_RATIO; |
| 165 | VideoCore::kScreenBottomWidth; | ||
| 166 | |||
| 167 | if (window_aspect_ratio > emulation_aspect_ratio) { | ||
| 168 | // Window is narrower than the emulation content => apply borders to the top and bottom | ||
| 169 | int viewport_height = static_cast<int>(std::round(emulation_aspect_ratio * width)); | ||
| 170 | |||
| 171 | res.bottom_screen.left = 0; | ||
| 172 | res.bottom_screen.right = res.bottom_screen.left + width; | ||
| 173 | res.bottom_screen.top = (height - viewport_height) / 2; | ||
| 174 | res.bottom_screen.bottom = res.bottom_screen.top + viewport_height; | ||
| 175 | |||
| 176 | // The Rasterizer still depends on these fields to maintain the right aspect ratio | ||
| 177 | res.top_screen.left = 0; | ||
| 178 | res.top_screen.right = VideoCore::kScreenTopWidth; | ||
| 179 | res.top_screen.top = 0; | ||
| 180 | res.top_screen.bottom = VideoCore::kScreenTopHeight; | ||
| 181 | } else { | ||
| 182 | // Otherwise, apply borders to the left and right sides of the window. | ||
| 183 | int viewport_width = static_cast<int>(std::round(height / emulation_aspect_ratio)); | ||
| 184 | |||
| 185 | res.bottom_screen.left = (width - viewport_width) / 2; | ||
| 186 | res.bottom_screen.right = res.bottom_screen.left + viewport_width; | ||
| 187 | res.bottom_screen.top = 0; | ||
| 188 | res.bottom_screen.bottom = res.bottom_screen.top + height; | ||
| 189 | |||
| 190 | res.top_screen.left = 0; | ||
| 191 | res.top_screen.right = VideoCore::kScreenTopWidth; | ||
| 192 | res.top_screen.top = 0; | ||
| 193 | res.top_screen.bottom = VideoCore::kScreenTopHeight; | ||
| 194 | } | ||
| 195 | |||
| 196 | return res; | ||
| 197 | } | ||
| 198 | |||
| 199 | static FramebufferLayout LargeFrameLayout(unsigned width, unsigned height) { | ||
| 200 | |||
| 201 | ASSERT(width > 0); | ||
| 202 | ASSERT(height > 0); | ||
| 203 | |||
| 204 | FramebufferLayout res{ width, height, true, true,{},{} }; | ||
| 205 | |||
| 206 | float window_aspect_ratio = static_cast<float>(width) / height; | ||
| 207 | float top_screen_aspect_ratio = static_cast<float>(VideoCore::kScreenTopWidth) / | ||
| 208 | VideoCore::kScreenTopHeight; | ||
| 209 | |||
| 210 | int viewport_height = static_cast<int>(std::round((width - VideoCore::kScreenBottomWidth) / | ||
| 211 | top_screen_aspect_ratio)); | ||
| 212 | int viewport_width = static_cast<int>(std::round((height * top_screen_aspect_ratio) + | ||
| 213 | VideoCore::kScreenBottomWidth)); | ||
| 214 | float emulation_aspect_ratio = static_cast<float>(width) / viewport_height; | ||
| 215 | 81 | ||
| 216 | if (window_aspect_ratio < emulation_aspect_ratio) { | 82 | if (window_aspect_ratio < emulation_aspect_ratio) { |
| 217 | // Window is narrower than the emulation content => apply borders to the top and bottom | 83 | top_screen = |
| 218 | res.top_screen.left = 0; | 84 | top_screen.TranslateX((screen_window_area.GetWidth() - top_screen.GetWidth()) / 2); |
| 219 | res.top_screen.right = width - VideoCore::kScreenBottomWidth; | 85 | bot_screen = |
| 220 | res.top_screen.top = (height - viewport_height) / 2; | 86 | bot_screen.TranslateX((screen_window_area.GetWidth() - bot_screen.GetWidth()) / 2); |
| 221 | res.top_screen.bottom = viewport_height + res.top_screen.top; | ||
| 222 | |||
| 223 | res.bottom_screen.left = res.top_screen.right; | ||
| 224 | res.bottom_screen.right = width; | ||
| 225 | res.bottom_screen.bottom = res.top_screen.bottom; | ||
| 226 | res.bottom_screen.top = res.bottom_screen.bottom - VideoCore::kScreenBottomHeight; | ||
| 227 | } else { | 87 | } else { |
| 228 | // Otherwise, apply borders to the left and right sides of the window. | 88 | top_screen = top_screen.TranslateY((height - top_screen.GetHeight()) / 2); |
| 229 | res.top_screen.left = (width - viewport_width) / 2; | 89 | bot_screen = bot_screen.TranslateY((height - bot_screen.GetHeight()) / 2); |
| 230 | res.top_screen.right = (top_screen_aspect_ratio * height) + res.top_screen.left; | ||
| 231 | res.top_screen.top = 0; | ||
| 232 | res.top_screen.bottom = height; | ||
| 233 | |||
| 234 | res.bottom_screen.left = res.top_screen.right; | ||
| 235 | res.bottom_screen.right = res.bottom_screen.left + VideoCore::kScreenBottomWidth; | ||
| 236 | res.bottom_screen.bottom = height; | ||
| 237 | res.bottom_screen.top = height - VideoCore::kScreenBottomHeight; | ||
| 238 | } | 90 | } |
| 239 | 91 | res.top_screen = top_screen; | |
| 92 | res.bottom_screen = bot_screen; | ||
| 240 | return res; | 93 | return res; |
| 241 | } | 94 | } |
| 242 | 95 | ||
| 243 | static FramebufferLayout LargeFrameLayout_Swapped(unsigned width, unsigned height) { | 96 | FramebufferLayout LargeFrameLayout(unsigned width, unsigned height, bool swapped) { |
| 244 | |||
| 245 | ASSERT(width > 0); | 97 | ASSERT(width > 0); |
| 246 | ASSERT(height > 0); | 98 | ASSERT(height > 0); |
| 247 | 99 | ||
| 248 | FramebufferLayout res {width, height, true, true, {}, {}}; | 100 | FramebufferLayout res{width, height, true, true, {}, {}}; |
| 249 | 101 | // Split the window into two parts. Give 4x width to the main screen and 1x width to the small | |
| 250 | float window_aspect_ratio = static_cast<float>(width) / height; | 102 | // To do that, find the total emulation box and maximize that based on window size |
| 251 | float bottom_screen_aspect_ratio = static_cast<float>(VideoCore::kScreenBottomWidth) / | 103 | float window_aspect_ratio = static_cast<float>(height) / width; |
| 252 | VideoCore::kScreenBottomHeight; | 104 | float emulation_aspect_ratio = |
| 253 | 105 | swapped | |
| 254 | int viewport_height = static_cast<int>(std::round((width - VideoCore::kScreenTopWidth) / | 106 | ? VideoCore::kScreenBottomHeight * 4 / |
| 255 | bottom_screen_aspect_ratio)); | 107 | (VideoCore::kScreenBottomWidth * 4.0f + VideoCore::kScreenTopWidth) |
| 256 | int viewport_width = static_cast<int>(std::round((height * bottom_screen_aspect_ratio) + | 108 | : VideoCore::kScreenTopHeight * 4 / |
| 257 | VideoCore::kScreenTopWidth)); | 109 | (VideoCore::kScreenTopWidth * 4.0f + VideoCore::kScreenBottomWidth); |
| 258 | float emulation_aspect_ratio = static_cast<float>(width) / viewport_height; | 110 | float large_screen_aspect_ratio = swapped ? BOT_SCREEN_ASPECT_RATIO : TOP_SCREEN_ASPECT_RATIO; |
| 111 | float small_screen_aspect_ratio = swapped ? TOP_SCREEN_ASPECT_RATIO : BOT_SCREEN_ASPECT_RATIO; | ||
| 112 | |||
| 113 | MathUtil::Rectangle<unsigned> screen_window_area{0, 0, width, height}; | ||
| 114 | MathUtil::Rectangle<unsigned> total_rect = | ||
| 115 | maxRectangle(screen_window_area, emulation_aspect_ratio); | ||
| 116 | MathUtil::Rectangle<unsigned> large_screen = | ||
| 117 | maxRectangle(total_rect, large_screen_aspect_ratio); | ||
| 118 | MathUtil::Rectangle<unsigned> fourth_size_rect = total_rect.Scale(.25f); | ||
| 119 | MathUtil::Rectangle<unsigned> small_screen = | ||
| 120 | maxRectangle(fourth_size_rect, small_screen_aspect_ratio); | ||
| 259 | 121 | ||
| 260 | if (window_aspect_ratio < emulation_aspect_ratio) { | 122 | if (window_aspect_ratio < emulation_aspect_ratio) { |
| 261 | // Window is narrower than the emulation content => apply borders to the top and bottom | 123 | large_screen = |
| 262 | res.bottom_screen.left = 0; | 124 | large_screen.TranslateX((screen_window_area.GetWidth() - total_rect.GetWidth()) / 2); |
| 263 | res.bottom_screen.right = width - VideoCore::kScreenTopWidth; | ||
| 264 | res.bottom_screen.top = (height - viewport_height) / 2; | ||
| 265 | res.bottom_screen.bottom = viewport_height + res.bottom_screen.top; | ||
| 266 | |||
| 267 | res.top_screen.left = res.bottom_screen.right; | ||
| 268 | res.top_screen.right = width; | ||
| 269 | res.top_screen.bottom = res.bottom_screen.bottom; | ||
| 270 | res.top_screen.top = res.top_screen.bottom - VideoCore::kScreenTopHeight; | ||
| 271 | } else { | 125 | } else { |
| 272 | // Otherwise, apply borders to the left and right sides of the window. | 126 | large_screen = large_screen.TranslateY((height - total_rect.GetHeight()) / 2); |
| 273 | res.bottom_screen.left = (width - viewport_width) / 2; | ||
| 274 | res.bottom_screen.right = (bottom_screen_aspect_ratio * height) + res.bottom_screen.left; | ||
| 275 | res.bottom_screen.top = 0; | ||
| 276 | res.bottom_screen.bottom = height; | ||
| 277 | |||
| 278 | res.top_screen.left = res.bottom_screen.right; | ||
| 279 | res.top_screen.right = res.top_screen.left + VideoCore::kScreenTopWidth; | ||
| 280 | res.top_screen.bottom = height; | ||
| 281 | res.top_screen.top = height - VideoCore::kScreenTopHeight; | ||
| 282 | } | 127 | } |
| 283 | 128 | // Shift the small screen to the bottom right corner | |
| 129 | small_screen = | ||
| 130 | small_screen.TranslateX(large_screen.right) | ||
| 131 | .TranslateY(large_screen.GetHeight() + large_screen.top - small_screen.GetHeight()); | ||
| 132 | res.top_screen = swapped ? small_screen : large_screen; | ||
| 133 | res.bottom_screen = swapped ? large_screen : small_screen; | ||
| 284 | return res; | 134 | return res; |
| 285 | } | 135 | } |
| 286 | |||
| 287 | FramebufferLayout DefaultFrameLayout(unsigned width, unsigned height, bool is_swapped) { | ||
| 288 | return is_swapped ? DefaultFrameLayout_Swapped(width, height) : DefaultFrameLayout(width, height); | ||
| 289 | } | ||
| 290 | |||
| 291 | FramebufferLayout SingleFrameLayout(unsigned width, unsigned height, bool is_swapped) { | ||
| 292 | return is_swapped ? SingleFrameLayout_Swapped(width, height) : SingleFrameLayout(width, height); | ||
| 293 | } | ||
| 294 | |||
| 295 | FramebufferLayout LargeFrameLayout(unsigned width, unsigned height, bool is_swapped) { | ||
| 296 | return is_swapped ? LargeFrameLayout_Swapped(width, height) : LargeFrameLayout(width, height); | ||
| 297 | } | ||
| 298 | } | 136 | } |
diff --git a/src/common/math_util.h b/src/common/math_util.h index 41d89666c..570ec8e56 100644 --- a/src/common/math_util.h +++ b/src/common/math_util.h | |||
| @@ -38,6 +38,18 @@ struct Rectangle { | |||
| 38 | T GetHeight() const { | 38 | T GetHeight() const { |
| 39 | return std::abs(static_cast<typename std::make_signed<T>::type>(bottom - top)); | 39 | return std::abs(static_cast<typename std::make_signed<T>::type>(bottom - top)); |
| 40 | } | 40 | } |
| 41 | Rectangle<T> TranslateX(const T x) const { | ||
| 42 | return Rectangle{left + x, top, right + x, bottom}; | ||
| 43 | } | ||
| 44 | Rectangle<T> TranslateY(const T y) const { | ||
| 45 | return Rectangle{left, top + y, right, bottom + y}; | ||
| 46 | } | ||
| 47 | Rectangle<T> Scale(const float s) const { | ||
| 48 | ASSERT(s > 0); | ||
| 49 | return Rectangle { | ||
| 50 | left, top, static_cast<T>((right + left) * s), static_cast<T>((top + bottom) * s) | ||
| 51 | }; | ||
| 52 | } | ||
| 41 | }; | 53 | }; |
| 42 | 54 | ||
| 43 | } // namespace MathUtil | 55 | } // namespace MathUtil |