diff options
| author | bunnei <bunneidev@gmail.com> | 2015-03-07 18:18:40 -0500 | 
|---|---|---|
| committer | bunnei <bunneidev@gmail.com> | 2015-03-07 18:18:40 -0500 | 
| commit | 06bf4715810489548a9a3b5e9274dfc78bc3fc4d (patch) | |
| tree | a2722e2b7e1356d9cb9725f18f0561fcaf815ec1 /src/common | |
| parent | f29897ca6d712d1082c35fa3270fe2b525368fd5 (diff) | |
| parent | 9960c49c217d2c1ae202bdacd475c9a47cda39b9 (diff) | |
Merge pull request #636 from bunnei/refactor-screen-win
Set framebuffer layout from EmuWindow.
Diffstat (limited to 'src/common')
| -rw-r--r-- | src/common/emu_window.cpp | 50 | ||||
| -rw-r--r-- | src/common/emu_window.h | 32 | 
2 files changed, 75 insertions, 7 deletions
| diff --git a/src/common/emu_window.cpp b/src/common/emu_window.cpp index 48bb35db5..1082ae26d 100644 --- a/src/common/emu_window.cpp +++ b/src/common/emu_window.cpp @@ -3,6 +3,7 @@  // Refer to the license.txt file included.  #include "emu_window.h" +#include "video_core/video_core.h"  void EmuWindow::KeyPressed(KeyMap::HostDeviceKey key) {      Service::HID::PadState mapped_key = KeyMap::GetPadKey(key); @@ -15,3 +16,52 @@ void EmuWindow::KeyReleased(KeyMap::HostDeviceKey key) {      Service::HID::PadButtonRelease(mapped_key);  } + +EmuWindow::FramebufferLayout EmuWindow::FramebufferLayout::DefaultScreenLayout(int width, int height) { +    ASSERT(width > 0); +    ASSERT(height > 0); + +    EmuWindow::FramebufferLayout res = { width, height, {}, {} }; + +    float window_aspect_ratio = static_cast<float>(height) / width; +    float emulation_aspect_ratio = static_cast<float>(VideoCore::kScreenTopHeight * 2) / +        VideoCore::kScreenTopWidth; + +    if (window_aspect_ratio > emulation_aspect_ratio) { +        // Window is narrower than the emulation content => apply borders to the top and bottom +        int viewport_height = static_cast<int>(std::round(emulation_aspect_ratio * width)); + +        res.top_screen.left = 0; +        res.top_screen.right = res.top_screen.left + width; +        res.top_screen.top = (height - viewport_height) / 2; +        res.top_screen.bottom = res.top_screen.top + viewport_height / 2; + +        int bottom_width = static_cast<int>((static_cast<float>(VideoCore::kScreenBottomWidth) / +            VideoCore::kScreenTopWidth) * (res.top_screen.right - res.top_screen.left)); +        int bottom_border = ((res.top_screen.right - res.top_screen.left) - bottom_width) / 2; + +        res.bottom_screen.left = bottom_border; +        res.bottom_screen.right = res.bottom_screen.left + bottom_width; +        res.bottom_screen.top = res.top_screen.bottom; +        res.bottom_screen.bottom = res.bottom_screen.top + viewport_height / 2; +    } else { +        // Otherwise, apply borders to the left and right sides of the window. +        int viewport_width = static_cast<int>(std::round(height / emulation_aspect_ratio)); + +        res.top_screen.left = (width - viewport_width) / 2; +        res.top_screen.right = res.top_screen.left + viewport_width; +        res.top_screen.top = 0; +        res.top_screen.bottom = res.top_screen.top + height / 2; + +        int bottom_width = static_cast<int>((static_cast<float>(VideoCore::kScreenBottomWidth) / +            VideoCore::kScreenTopWidth) * (res.top_screen.right - res.top_screen.left)); +        int bottom_border = ((res.top_screen.right - res.top_screen.left) - bottom_width) / 2; + +        res.bottom_screen.left = res.top_screen.left + bottom_border; +        res.bottom_screen.right = res.bottom_screen.left + bottom_width; +        res.bottom_screen.top = res.top_screen.bottom; +        res.bottom_screen.bottom = res.bottom_screen.top + height / 2; +    } + +    return res; +} diff --git a/src/common/emu_window.h b/src/common/emu_window.h index 1ad4b82a3..b6862030e 100644 --- a/src/common/emu_window.h +++ b/src/common/emu_window.h @@ -8,6 +8,7 @@  #include "common/scm_rev.h"  #include "common/string_util.h"  #include "common/key_map.h" +#include "common/math_util.h"  /**   * Abstraction class used to provide an interface between emulation code and the frontend @@ -38,6 +39,23 @@ public:          std::pair<unsigned,unsigned> min_client_area_size;      }; +    /// Describes the layout of the window framebuffer (size and top/bottom screen positions) +    struct FramebufferLayout { + +        /** +         * Factory method for constructing a default FramebufferLayout +         * @param width Window framebuffer width in pixels +         * @param height Window framebuffer height in pixels +         * @return Newly created FramebufferLayout object with default screen regions initialized +         */ +        static FramebufferLayout DefaultScreenLayout(int width, int height); + +        unsigned width; +        unsigned height; +        MathUtil::Rectangle<unsigned> top_screen; +        MathUtil::Rectangle<unsigned> bottom_screen; +    }; +      /// Swap buffers to display the next frame      virtual void SwapBuffers() = 0; @@ -75,11 +93,11 @@ public:      }      /** -      * Gets the framebuffer size in pixels. +      * Gets the framebuffer layout (width, height, and screen regions)        * @note This method is thread-safe        */ -    const std::pair<unsigned,unsigned> GetFramebufferSize() const { -        return framebuffer_size; +    const FramebufferLayout& GetFramebufferLayout() const { +        return framebuffer_layout;      }      /** @@ -118,11 +136,11 @@ protected:      }      /** -     * Update internal framebuffer size with the given parameter. +     * Update framebuffer layout with the given parameter.       * @note EmuWindow implementations will usually use this in window resize event handlers.       */ -    void NotifyFramebufferSizeChanged(const std::pair<unsigned,unsigned>& size) { -        framebuffer_size = size; +    void NotifyFramebufferLayoutChanged(const FramebufferLayout& layout) { +        framebuffer_layout = layout;      }      /** @@ -143,7 +161,7 @@ private:          // By default, ignore this request and do nothing.      } -    std::pair<unsigned,unsigned> framebuffer_size; +    FramebufferLayout framebuffer_layout; ///< Current framebuffer layout      unsigned client_area_width;    ///< Current client width, should be set by window impl.      unsigned client_area_height;   ///< Current client height, should be set by window impl. | 
