Frontend: Re-implement fullscreen

This commit is contained in:
Connor McLaughlin 2019-11-15 14:57:27 +10:00
parent a25fe54a4b
commit f27ad2fa67
7 changed files with 63 additions and 16 deletions

View file

@ -39,6 +39,7 @@ public:
virtual void SetDisplayTexture(void* texture_handle, s32 offset_x, s32 offset_y, s32 width, s32 height, virtual void SetDisplayTexture(void* texture_handle, s32 offset_x, s32 offset_y, s32 width, s32 height,
u32 texture_width, u32 texture_height, float aspect_ratio) = 0; u32 texture_width, u32 texture_height, float aspect_ratio) = 0;
virtual void SetDisplayLinearFiltering(bool enabled) = 0; virtual void SetDisplayLinearFiltering(bool enabled) = 0;
virtual void SetDisplayTopMargin(int height) = 0;
virtual void Render() = 0; virtual void Render() = 0;

View file

@ -149,6 +149,11 @@ void D3D11HostDisplay::SetDisplayLinearFiltering(bool enabled)
m_display_linear_filtering = enabled; m_display_linear_filtering = enabled;
} }
void D3D11HostDisplay::SetDisplayTopMargin(int height)
{
m_display_top_margin = height;
}
void D3D11HostDisplay::SetVSync(bool enabled) void D3D11HostDisplay::SetVSync(bool enabled)
{ {
m_vsync = enabled; m_vsync = enabled;
@ -364,8 +369,8 @@ void D3D11HostDisplay::RenderDisplay()
// - 20 for main menu padding // - 20 for main menu padding
auto [vp_left, vp_top, vp_width, vp_height] = auto [vp_left, vp_top, vp_width, vp_height] =
CalculateDrawRect(m_window_width, std::max(m_window_height - 20, 1), m_display_aspect_ratio); CalculateDrawRect(m_window_width, std::max(m_window_height - m_display_top_margin, 1), m_display_aspect_ratio);
vp_top += 20; vp_top += m_display_top_margin;
m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
m_context->VSSetShader(m_display_vertex_shader.Get(), nullptr, 0); m_context->VSSetShader(m_display_vertex_shader.Get(), nullptr, 0);

View file

@ -31,6 +31,7 @@ public:
void SetDisplayTexture(void* texture, s32 offset_x, s32 offset_y, s32 width, s32 height, u32 texture_width, void SetDisplayTexture(void* texture, s32 offset_x, s32 offset_y, s32 width, s32 height, u32 texture_width,
u32 texture_height, float aspect_ratio) override; u32 texture_height, float aspect_ratio) override;
void SetDisplayLinearFiltering(bool enabled) override; void SetDisplayLinearFiltering(bool enabled) override;
void SetDisplayTopMargin(int height) override;
void SetVSync(bool enabled) override; void SetVSync(bool enabled) override;
@ -76,6 +77,7 @@ private:
s32 m_display_height = 0; s32 m_display_height = 0;
u32 m_display_texture_width = 0; u32 m_display_texture_width = 0;
u32 m_display_texture_height = 0; u32 m_display_texture_height = 0;
int m_display_top_margin = 0;
float m_display_aspect_ratio = 1.0f; float m_display_aspect_ratio = 1.0f;
bool m_display_texture_changed = false; bool m_display_texture_changed = false;

View file

@ -130,6 +130,11 @@ void OpenGLHostDisplay::SetDisplayLinearFiltering(bool enabled)
m_display_linear_filtering = enabled; m_display_linear_filtering = enabled;
} }
void OpenGLHostDisplay::SetDisplayTopMargin(int height)
{
m_display_top_margin = height;
}
void OpenGLHostDisplay::SetVSync(bool enabled) void OpenGLHostDisplay::SetVSync(bool enabled)
{ {
// Window framebuffer has to be bound to call SetSwapInterval. // Window framebuffer has to be bound to call SetSwapInterval.
@ -373,9 +378,9 @@ void OpenGLHostDisplay::RenderDisplay()
// - 20 for main menu padding // - 20 for main menu padding
const auto [vp_left, vp_top, vp_width, vp_height] = const auto [vp_left, vp_top, vp_width, vp_height] =
CalculateDrawRect(m_window_width, std::max(m_window_height - 20, 1), m_display_aspect_ratio); CalculateDrawRect(m_window_width, std::max(m_window_height - m_display_top_margin, 1), m_display_aspect_ratio);
glViewport(vp_left, m_window_height - (20 + vp_top) - vp_height, vp_width, vp_height); glViewport(vp_left, m_window_height - (m_display_top_margin + vp_top) - vp_height, vp_width, vp_height);
glDisable(GL_BLEND); glDisable(GL_BLEND);
glDisable(GL_CULL_FACE); glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST);

View file

@ -26,6 +26,7 @@ public:
void SetDisplayTexture(void* texture, s32 offset_x, s32 offset_y, s32 width, s32 height, u32 texture_width, void SetDisplayTexture(void* texture, s32 offset_x, s32 offset_y, s32 width, s32 height, u32 texture_width,
u32 texture_height, float aspect_ratio) override; u32 texture_height, float aspect_ratio) override;
void SetDisplayLinearFiltering(bool enabled) override; void SetDisplayLinearFiltering(bool enabled) override;
void SetDisplayTopMargin(int height) override;
void SetVSync(bool enabled) override; void SetVSync(bool enabled) override;
@ -59,6 +60,7 @@ private:
s32 m_display_height = 0; s32 m_display_height = 0;
u32 m_display_texture_width = 0; u32 m_display_texture_width = 0;
u32 m_display_texture_height = 0; u32 m_display_texture_height = 0;
int m_display_top_margin = 0;
float m_display_aspect_ratio = 1.0f; float m_display_aspect_ratio = 1.0f;
GLuint m_display_nearest_sampler = 0; GLuint m_display_nearest_sampler = 0;
GLuint m_display_linear_sampler = 0; GLuint m_display_linear_sampler = 0;

View file

@ -172,6 +172,15 @@ void SDLHostInterface::ResetPerformanceCounters()
void SDLHostInterface::SwitchGPURenderer() {} void SDLHostInterface::SwitchGPURenderer() {}
void SDLHostInterface::UpdateFullscreen()
{
SDL_SetWindowFullscreen(m_window, m_settings.display_fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
// We set the margin only in windowed mode, the menu bar is drawn on top in fullscreen.
m_display->SetDisplayTopMargin(
m_settings.display_fullscreen ? 0 : static_cast<int>(20.0f * ImGui::GetIO().DisplayFramebufferScale.x));
}
std::unique_ptr<SDLHostInterface> SDLHostInterface::Create(const char* filename /* = nullptr */, std::unique_ptr<SDLHostInterface> SDLHostInterface::Create(const char* filename /* = nullptr */,
const char* exp1_filename /* = nullptr */, const char* exp1_filename /* = nullptr */,
const char* save_state_filename /* = nullptr */) const char* save_state_filename /* = nullptr */)
@ -216,6 +225,8 @@ std::unique_ptr<SDLHostInterface> SDLHostInterface::Create(const char* filename
intf->UpdateAudioVisualSync(); intf->UpdateAudioVisualSync();
intf->UpdateFullscreen();
return intf; return intf;
} }
@ -229,11 +240,6 @@ void SDLHostInterface::ReportMessage(const char* message)
AddOSDMessage(message, 3.0f); AddOSDMessage(message, 3.0f);
} }
bool SDLHostInterface::IsWindowFullscreen() const
{
return ((SDL_GetWindowFlags(m_window) & SDL_WINDOW_FULLSCREEN) != 0);
}
static inline u32 SDLButtonToHostButton(u32 button) static inline u32 SDLButtonToHostButton(u32 button)
{ {
// SDL left = 1, middle = 2, right = 3 :/ // SDL left = 1, middle = 2, right = 3 :/
@ -488,6 +494,13 @@ void SDLHostInterface::HandleSDLKeyEvent(const SDL_Event* event)
} }
break; break;
case SDL_SCANCODE_F11:
{
if (!pressed)
DoToggleFullscreen();
}
break;
case SDL_SCANCODE_TAB: case SDL_SCANCODE_TAB:
{ {
if (!repeat) if (!repeat)
@ -570,6 +583,15 @@ void SDLHostInterface::DrawImGui()
void SDLHostInterface::DrawMainMenuBar() void SDLHostInterface::DrawMainMenuBar()
{ {
// We skip drawing the menu bar if we're in fullscreen and the mouse pointer isn't in range.
const float SHOW_THRESHOLD = 20.0f;
if (m_settings.display_fullscreen &&
ImGui::GetIO().MousePos.y >= (SHOW_THRESHOLD * ImGui::GetIO().DisplayFramebufferScale.x) &&
!ImGui::IsWindowFocused(ImGuiFocusedFlags_AnyWindow))
{
return;
}
if (!ImGui::BeginMainMenuBar()) if (!ImGui::BeginMainMenuBar())
return; return;
@ -730,8 +752,8 @@ void SDLHostInterface::DrawQuickSettingsMenu()
ImGui::EndMenu(); ImGui::EndMenu();
} }
if (ImGui::MenuItem("Fullscreen", nullptr, IsWindowFullscreen())) if (ImGui::MenuItem("Fullscreen", nullptr, &m_settings.display_fullscreen))
SDL_SetWindowFullscreen(m_window, IsWindowFullscreen() ? 0 : SDL_WINDOW_FULLSCREEN_DESKTOP); UpdateFullscreen();
if (ImGui::MenuItem("VSync", nullptr, &m_settings.gpu_vsync)) if (ImGui::MenuItem("VSync", nullptr, &m_settings.gpu_vsync))
{ {
@ -977,7 +999,9 @@ void SDLHostInterface::DrawSettingsWindow()
if (DrawSettingsSectionHeader("Display Output")) if (DrawSettingsSectionHeader("Display Output"))
{ {
ImGui::Checkbox("Fullscreen", &m_settings.display_fullscreen); if (ImGui::Checkbox("Fullscreen", &m_settings.display_fullscreen))
UpdateFullscreen();
if (ImGui::Checkbox("VSync", &m_settings.gpu_vsync)) if (ImGui::Checkbox("VSync", &m_settings.gpu_vsync))
{ {
UpdateAudioVisualSync(); UpdateAudioVisualSync();
@ -1132,10 +1156,11 @@ void SDLHostInterface::DrawOSDMessages()
ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoFocusOnAppearing; ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoFocusOnAppearing;
std::unique_lock<std::mutex> lock(m_osd_messages_lock); std::unique_lock<std::mutex> lock(m_osd_messages_lock);
const float scale = ImGui::GetIO().DisplayFramebufferScale.x;
auto iter = m_osd_messages.begin(); auto iter = m_osd_messages.begin();
float position_x = 10.0f; float position_x = 10.0f * scale;
float position_y = 10.0f + 20.0f; float position_y = (10.0f + (m_settings.display_fullscreen ? 0.0f : 20.0f)) * scale;
u32 index = 0; u32 index = 0;
while (iter != m_osd_messages.end()) while (iter != m_osd_messages.end())
{ {
@ -1156,7 +1181,7 @@ void SDLHostInterface::DrawOSDMessages()
if (ImGui::Begin(SmallString::FromFormat("osd_%u", index++), nullptr, window_flags)) if (ImGui::Begin(SmallString::FromFormat("osd_%u", index++), nullptr, window_flags))
{ {
ImGui::TextUnformatted(msg.text); ImGui::TextUnformatted(msg.text);
position_y += ImGui::GetWindowSize().y + (4.0f * ImGui::GetIO().DisplayFramebufferScale.x); position_y += ImGui::GetWindowSize().y + (4.0f * scale);
} }
ImGui::End(); ImGui::End();
@ -1299,6 +1324,12 @@ void SDLHostInterface::DoToggleSoftwareRendering()
m_system->RecreateGPU(); m_system->RecreateGPU();
} }
void SDLHostInterface::DoToggleFullscreen()
{
m_settings.display_fullscreen = !m_settings.display_fullscreen;
UpdateFullscreen();
}
void SDLHostInterface::DoModifyInternalResolution(s32 increment) void SDLHostInterface::DoModifyInternalResolution(s32 increment)
{ {
const u32 new_resolution_scale = const u32 new_resolution_scale =

View file

@ -68,9 +68,9 @@ private:
void ConnectDevices(); void ConnectDevices();
void ResetPerformanceCounters(); void ResetPerformanceCounters();
void SwitchGPURenderer(); void SwitchGPURenderer();
void UpdateFullscreen();
// We only pass mouse input through if it's grabbed // We only pass mouse input through if it's grabbed
bool IsWindowFullscreen() const;
void DrawImGui(); void DrawImGui();
void DoReset(); void DoReset();
void DoPowerOff(); void DoPowerOff();
@ -83,6 +83,7 @@ private:
void DoTogglePause(); void DoTogglePause();
void DoFrameStep(); void DoFrameStep();
void DoToggleSoftwareRendering(); void DoToggleSoftwareRendering();
void DoToggleFullscreen();
void DoModifyInternalResolution(s32 increment); void DoModifyInternalResolution(s32 increment);
void HandleSDLEvent(const SDL_Event* event); void HandleSDLEvent(const SDL_Event* event);