From 221a9b023d8c9ca55c093823e9efd6d13d0a54a2 Mon Sep 17 00:00:00 2001 From: Kevin Hartman Date: Fri, 29 Aug 2014 22:23:12 -0700 Subject: Viewport scaling and display density independence The view is scaled to be as large as possible, without changing the aspect, within the bounds of the window. On "retina" displays, or other displays where window units != pixels, the view should no longer draw incorrectly. --- src/citra/emu_window/emu_window_glfw.cpp | 5 +++++ src/citra/emu_window/emu_window_glfw.h | 5 ++++- 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'src/citra') diff --git a/src/citra/emu_window/emu_window_glfw.cpp b/src/citra/emu_window/emu_window_glfw.cpp index 0c774bbc5..d0f6e9a9e 100644 --- a/src/citra/emu_window/emu_window_glfw.cpp +++ b/src/citra/emu_window/emu_window_glfw.cpp @@ -34,6 +34,10 @@ const bool EmuWindow_GLFW::IsOpen() { return glfwWindowShouldClose(m_render_window) == 0; } +void EmuWindow_GLFW::GetFramebufferSize(int* fbWidth, int* fbHeight) { + glfwGetFramebufferSize(m_render_window, fbWidth, fbHeight); +} + /// EmuWindow_GLFW constructor EmuWindow_GLFW::EmuWindow_GLFW() { keyboard_id = KeyMap::NewDeviceId(); @@ -64,6 +68,7 @@ EmuWindow_GLFW::EmuWindow_GLFW() { glfwSetWindowUserPointer(m_render_window, this); glfwSetKeyCallback(m_render_window, OnKeyEvent); + DoneCurrent(); } diff --git a/src/citra/emu_window/emu_window_glfw.h b/src/citra/emu_window/emu_window_glfw.h index 7c3072145..e96228765 100644 --- a/src/citra/emu_window/emu_window_glfw.h +++ b/src/citra/emu_window/emu_window_glfw.h @@ -21,7 +21,7 @@ public: /// Makes the graphics context current for the caller thread void MakeCurrent() override; - + /// Releases (dunno if this is the "right" word) the GLFW context from the caller thread void DoneCurrent() override; @@ -32,6 +32,9 @@ public: void ReloadSetKeymaps() override; + /// Gets the size of the window in pixels + void GetFramebufferSize(int* fbWidth, int* fbHeight); + private: GLFWwindow* m_render_window; ///< Internal GLFW render window -- cgit v1.2.3 From bd8f491e4c08e9b9a7b852de0b50c144da8ac8c8 Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Sun, 12 Oct 2014 18:14:57 +0200 Subject: Fixup EmuWindow interface and implementations thereof. --- src/citra/emu_window/emu_window_glfw.cpp | 51 ++++++++++++++++++++++---------- src/citra/emu_window/emu_window_glfw.h | 13 ++++---- 2 files changed, 44 insertions(+), 20 deletions(-) (limited to 'src/citra') diff --git a/src/citra/emu_window/emu_window_glfw.cpp b/src/citra/emu_window/emu_window_glfw.cpp index d0f6e9a9e..28aa3450c 100644 --- a/src/citra/emu_window/emu_window_glfw.cpp +++ b/src/citra/emu_window/emu_window_glfw.cpp @@ -2,6 +2,8 @@ // Licensed under GPLv2 // Refer to the license.txt file included. +#include + #include "common/common.h" #include "video_core/video_core.h" @@ -10,22 +12,21 @@ #include "citra/emu_window/emu_window_glfw.h" +EmuWindow_GLFW* EmuWindow_GLFW::GetEmuWindow(GLFWwindow* win) { + return static_cast(glfwGetWindowUserPointer(win)); +} + /// Called by GLFW when a key event occurs void EmuWindow_GLFW::OnKeyEvent(GLFWwindow* win, int key, int scancode, int action, int mods) { - if (!VideoCore::g_emu_window) { - return; - } - - int keyboard_id = ((EmuWindow_GLFW*)VideoCore::g_emu_window)->keyboard_id; + int keyboard_id = GetEmuWindow(win)->keyboard_id; if (action == GLFW_PRESS) { EmuWindow::KeyPressed({key, keyboard_id}); - } - - if (action == GLFW_RELEASE) { + } else if (action == GLFW_RELEASE) { EmuWindow::KeyReleased({key, keyboard_id}); } + HID_User::PadUpdateComplete(); } @@ -34,8 +35,18 @@ const bool EmuWindow_GLFW::IsOpen() { return glfwWindowShouldClose(m_render_window) == 0; } -void EmuWindow_GLFW::GetFramebufferSize(int* fbWidth, int* fbHeight) { - glfwGetFramebufferSize(m_render_window, fbWidth, fbHeight); +void EmuWindow_GLFW::OnFramebufferResizeEvent(GLFWwindow* win, int width, int height) { + _dbg_assert_(GUI, width > 0); + _dbg_assert_(GUI, height > 0); + + GetEmuWindow(win)->NotifyFramebufferSizeChanged(std::pair(width, height)); +} + +void EmuWindow_GLFW::OnClientAreaResizeEvent(GLFWwindow* win, int width, int height) { + _dbg_assert_(GUI, width > 0); + _dbg_assert_(GUI, height > 0); + + GetEmuWindow(win)->NotifyClientAreaSizeChanged(std::pair(width, height)); } /// EmuWindow_GLFW constructor @@ -54,20 +65,30 @@ EmuWindow_GLFW::EmuWindow_GLFW() { // GLFW on OSX requires these window hints to be set to create a 3.2+ GL context. glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - + m_render_window = glfwCreateWindow(VideoCore::kScreenTopWidth, (VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight), - m_window_title.c_str(), NULL, NULL); + GetWindowTitle().c_str(), NULL, NULL); if (m_render_window == NULL) { printf("Failed to create GLFW window! Exiting..."); exit(1); } - - // Setup callbacks + glfwSetWindowUserPointer(m_render_window, this); - glfwSetKeyCallback(m_render_window, OnKeyEvent); + // Notify base interface about window state + int width, height; + glfwGetFramebufferSize(m_render_window, &width, &height); + OnFramebufferResizeEvent(m_render_window, width, height); + + glfwGetWindowSize(m_render_window, &width, &height); + OnClientAreaResizeEvent(m_render_window, width, height); + + // Setup callbacks + glfwSetKeyCallback(m_render_window, OnKeyEvent); + glfwSetFramebufferSizeCallback(m_render_window, OnFramebufferResizeEvent); + glfwSetWindowSizeCallback(m_render_window, OnClientAreaResizeEvent); DoneCurrent(); } diff --git a/src/citra/emu_window/emu_window_glfw.h b/src/citra/emu_window/emu_window_glfw.h index e96228765..0da688a54 100644 --- a/src/citra/emu_window/emu_window_glfw.h +++ b/src/citra/emu_window/emu_window_glfw.h @@ -4,10 +4,10 @@ #pragma once -#include - #include "common/emu_window.h" +struct GLFWwindow; + class EmuWindow_GLFW : public EmuWindow { public: EmuWindow_GLFW(); @@ -30,12 +30,15 @@ public: /// Whether the window is still open, and a close request hasn't yet been sent const bool IsOpen(); - void ReloadSetKeymaps() override; + static void OnClientAreaResizeEvent(GLFWwindow* win, int width, int height); - /// Gets the size of the window in pixels - void GetFramebufferSize(int* fbWidth, int* fbHeight); + static void OnFramebufferResizeEvent(GLFWwindow* win, int width, int height); + + void ReloadSetKeymaps() override; private: + static EmuWindow_GLFW* GetEmuWindow(GLFWwindow* win); + GLFWwindow* m_render_window; ///< Internal GLFW render window /// Device id of keyboard for use with KeyMap -- cgit v1.2.3 From 722ce2258949c5edf81c946faedfd040efeb38a6 Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Sun, 12 Oct 2014 22:46:33 +0200 Subject: EmuWindow: Add support for specifying minimal client area sizes. --- src/citra/emu_window/emu_window_glfw.cpp | 21 +++++++++++++++++++++ src/citra/emu_window/emu_window_glfw.h | 2 ++ 2 files changed, 23 insertions(+) (limited to 'src/citra') diff --git a/src/citra/emu_window/emu_window_glfw.cpp b/src/citra/emu_window/emu_window_glfw.cpp index 28aa3450c..7e1e1c9a6 100644 --- a/src/citra/emu_window/emu_window_glfw.cpp +++ b/src/citra/emu_window/emu_window_glfw.cpp @@ -46,6 +46,15 @@ void EmuWindow_GLFW::OnClientAreaResizeEvent(GLFWwindow* win, int width, int hei _dbg_assert_(GUI, width > 0); _dbg_assert_(GUI, height > 0); + // TODO: It's actually more interesting to us what the framebuffer size ends up being. + int adjusted_width = std::max(width, GetEmuWindow(win)->GetActiveConfig().min_client_area_size.first); + int adjusted_height = std::max(height, GetEmuWindow(win)->GetActiveConfig().min_client_area_size.second); + + if (adjusted_width != width || adjusted_height != height) { + glfwSetWindowSize(win, adjusted_width, adjusted_height); + return; + } + GetEmuWindow(win)->NotifyClientAreaSizeChanged(std::pair(width, height)); } @@ -136,3 +145,15 @@ void EmuWindow_GLFW::ReloadSetKeymaps() { KeyMap::SetKeyMapping({Settings::values.pad_sup_key, keyboard_id}, HID_User::PAD_CIRCLE_UP); KeyMap::SetKeyMapping({Settings::values.pad_sdown_key, keyboard_id}, HID_User::PAD_CIRCLE_DOWN); } + +void EmuWindow_GLFW::OnMinimalClientAreaChangeRequest(const std::pair& minimal_size) { + std::pair current_size; + glfwGetWindowSize(m_render_window, ¤t_size.first, ¤t_size.second); + + _dbg_assert_(GUI, (int)minimal_size.first > 0 && (int)minimal_size.second > 0); + int new_width = std::max(current_size.first, (int)minimal_size.first); + int new_height = std::max(current_size.second, (int)minimal_size.second); + + if (current_size != std::make_pair(new_width, new_height)) + glfwSetWindowSize(m_render_window, new_width, new_height); +} diff --git a/src/citra/emu_window/emu_window_glfw.h b/src/citra/emu_window/emu_window_glfw.h index 0da688a54..61cef4e65 100644 --- a/src/citra/emu_window/emu_window_glfw.h +++ b/src/citra/emu_window/emu_window_glfw.h @@ -37,6 +37,8 @@ public: void ReloadSetKeymaps() override; private: + void OnMinimalClientAreaChangeRequest(const std::pair& minimal_size) override; + static EmuWindow_GLFW* GetEmuWindow(GLFWwindow* win); GLFWwindow* m_render_window; ///< Internal GLFW render window -- cgit v1.2.3 From 182476c96a6c75e90a90cbb52048bf754fdd786d Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Thu, 13 Nov 2014 18:17:39 +0100 Subject: EmuWindow: Remove window title getters/setters. The window title is none of the emulation core's business. The GUI code is free to put whatever it wants there. Providing properly thread-safe window title getters and setters is a mess anyway. --- src/citra/emu_window/emu_window_glfw.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/citra') diff --git a/src/citra/emu_window/emu_window_glfw.cpp b/src/citra/emu_window/emu_window_glfw.cpp index 7e1e1c9a6..9e6f91578 100644 --- a/src/citra/emu_window/emu_window_glfw.cpp +++ b/src/citra/emu_window/emu_window_glfw.cpp @@ -75,9 +75,10 @@ EmuWindow_GLFW::EmuWindow_GLFW() { glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - m_render_window = glfwCreateWindow(VideoCore::kScreenTopWidth, - (VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight), - GetWindowTitle().c_str(), NULL, NULL); + std::string window_title = Common::StringFromFormat("Citra | %s-%s", Common::g_scm_branch, Common::g_scm_desc); + m_render_window = glfwCreateWindow(VideoCore::kScreenTopWidth, + (VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight), + window_title.c_str(), NULL, NULL); if (m_render_window == NULL) { printf("Failed to create GLFW window! Exiting..."); -- cgit v1.2.3 From 963c923d5931dc9d20eb298001282da88e31c31a Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Thu, 13 Nov 2014 20:47:46 +0100 Subject: citra GLFW: Ignore minimal window size hints. GLFW provides no proper support for this, hence we just allow any window size to be used. --- src/citra/emu_window/emu_window_glfw.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'src/citra') diff --git a/src/citra/emu_window/emu_window_glfw.cpp b/src/citra/emu_window/emu_window_glfw.cpp index 9e6f91578..8efb39e2e 100644 --- a/src/citra/emu_window/emu_window_glfw.cpp +++ b/src/citra/emu_window/emu_window_glfw.cpp @@ -46,14 +46,8 @@ void EmuWindow_GLFW::OnClientAreaResizeEvent(GLFWwindow* win, int width, int hei _dbg_assert_(GUI, width > 0); _dbg_assert_(GUI, height > 0); - // TODO: It's actually more interesting to us what the framebuffer size ends up being. - int adjusted_width = std::max(width, GetEmuWindow(win)->GetActiveConfig().min_client_area_size.first); - int adjusted_height = std::max(height, GetEmuWindow(win)->GetActiveConfig().min_client_area_size.second); - - if (adjusted_width != width || adjusted_height != height) { - glfwSetWindowSize(win, adjusted_width, adjusted_height); - return; - } + // NOTE: GLFW provides no proper way to set a minimal window size. + // Hence, we just ignore the corresponding EmuWindow hint. GetEmuWindow(win)->NotifyClientAreaSizeChanged(std::pair(width, height)); } -- cgit v1.2.3