// Copyright 2018 yuzu emulator team // Licensed under GPLv2 or any later version // Refer to the license.txt file included. #include #include "common/assert.h" #include "core/frontend/framebuffer_layout.h" #include "core/settings.h" namespace Layout { // Finds the largest size subrectangle contained in window area that is confined to the aspect ratio template static Common::Rectangle MaxRectangle(Common::Rectangle window_area, float screen_aspect_ratio) { float scale = std::min(static_cast(window_area.GetWidth()), window_area.GetHeight() / screen_aspect_ratio); return Common::Rectangle{0, 0, static_cast(std::round(scale)), static_cast(std::round(scale * screen_aspect_ratio))}; } FramebufferLayout DefaultFrameLayout(unsigned width, unsigned height) { ASSERT(width > 0); ASSERT(height > 0); // The drawing code needs at least somewhat valid values for both screens // so just calculate them both even if the other isn't showing. FramebufferLayout res{width, height}; const float emulation_aspect_ratio{static_cast(ScreenUndocked::Height) / ScreenUndocked::Width}; Common::Rectangle screen_window_area{0, 0, width, height}; Common::Rectangle screen = MaxRectangle(screen_window_area, emulation_aspect_ratio); float window_aspect_ratio = static_cast(height) / width; if (window_aspect_ratio < emulation_aspect_ratio) { screen = screen.TranslateX((screen_window_area.GetWidth() - screen.GetWidth()) / 2); } else { screen = screen.TranslateY((height - screen.GetHeight()) / 2); } res.screen = screen; return res; } FramebufferLayout FrameLayoutFromResolutionScale(u16 res_scale) { int width, height; if (Settings::values.use_docked_mode) { width = ScreenDocked::WidthDocked * res_scale; height = ScreenDocked::HeightDocked * res_scale; } else { width = ScreenUndocked::Width * res_scale; height = ScreenUndocked::Height * res_scale; } return DefaultFrameLayout(width, height); } } // namespace Layout