diff --git a/src/duckstation/sdl_interface.cpp b/src/duckstation/sdl_interface.cpp index f15f8ba01..7754b35e3 100644 --- a/src/duckstation/sdl_interface.cpp +++ b/src/duckstation/sdl_interface.cpp @@ -428,8 +428,10 @@ void SDLInterface::Render() { DrawImGui(); - m_system->GetGPU()->ResetGraphicsAPIState(); + if (m_system) + m_system->GetGPU()->ResetGraphicsAPIState(); + glDisable(GL_SCISSOR_TEST); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT); @@ -446,26 +448,9 @@ void SDLInterface::Render() ImGui::NewFrame(); GL::Program::ResetLastProgram(); - m_system->GetGPU()->RestoreGraphicsAPIState(); -} -void SDLInterface::RenderPoweredOff() -{ - DrawPoweredOffWindow(); - ImGui::Render(); - - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - glClear(GL_COLOR_BUFFER_BIT); - - ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); - - SDL_GL_SwapWindow(m_window); - - ImGui_ImplSDL2_NewFrame(m_window); - ImGui_ImplOpenGL3_NewFrame(); - - ImGui::NewFrame(); + if (m_system) + m_system->GetGPU()->RestoreGraphicsAPIState(); } static std::tuple CalculateDrawRect(int window_width, int window_height, float display_ratio) @@ -520,7 +505,13 @@ void SDLInterface::DrawImGui() { DrawMainMenuBar(); - m_system->DrawDebugWindows(); + if (m_system) + m_system->DrawDebugWindows(); + else + DrawPoweredOffWindow(); + + if (m_about_window_open) + DrawAboutWindow(); DrawOSDMessages(); @@ -534,10 +525,15 @@ void SDLInterface::DrawMainMenuBar() if (ImGui::BeginMenu("System")) { - if (ImGui::MenuItem("Reset")) + const bool system_enabled = static_cast(m_system); + + if (ImGui::MenuItem("Reset", nullptr, false, system_enabled)) DoReset(); - ImGui::Separator(); + ImGui::MenuItem("Change Disc", nullptr, false, system_enabled); + + if (ImGui::MenuItem("Power Off", nullptr, false, system_enabled)) + DoPowerOff(); #if 0 if (ImGui::MenuItem("Enable Speed Limiter", nullptr, IsSpeedLimiterEnabled())) @@ -546,6 +542,13 @@ void SDLInterface::DrawMainMenuBar() ImGui::Separator(); + if (ImGui::MenuItem("Start Disc")) + DoStartDisc(); + if (ImGui::MenuItem("Start BIOS")) + DoStartBIOS(); + + ImGui::Separator(); + if (ImGui::BeginMenu("Load State")) { for (u32 i = 1; i <= 8; i++) @@ -566,6 +569,8 @@ void SDLInterface::DrawMainMenuBar() ImGui::EndMenu(); } + ImGui::Separator(); + if (ImGui::MenuItem("Exit")) m_running = false; @@ -604,27 +609,46 @@ void SDLInterface::DrawMainMenuBar() ImGui::EndMenu(); } - if (ImGui::BeginMenu("Debug")) + if (m_system) { - m_system->DrawDebugMenus(); - ImGui::EndMenu(); + if (ImGui::BeginMenu("Debug")) + { + m_system->DrawDebugMenus(); + ImGui::EndMenu(); + } + + ImGui::SetCursorPosX(ImGui::GetIO().DisplaySize.x - 210.0f); + + const u32 rounded_speed = static_cast(std::round(m_speed)); + if (m_speed < 90.0f) + ImGui::TextColored(ImVec4(1.0f, 0.4f, 0.4f, 1.0f), "%u%%", rounded_speed); + else if (m_speed < 110.0f) + ImGui::TextColored(ImVec4(1.0f, 1.0f, 1.0f, 1.0f), "%u%%", rounded_speed); + else + ImGui::TextColored(ImVec4(0.4f, 1.0f, 0.4f, 1.0f), "%u%%", rounded_speed); + + ImGui::SetCursorPosX(ImGui::GetIO().DisplaySize.x - 165.0f); + ImGui::Text("FPS: %.2f", m_fps); + + ImGui::SetCursorPosX(ImGui::GetIO().DisplaySize.x - 80.0f); + ImGui::Text("VPS: %.2f", m_vps); } - ImGui::SetCursorPosX(ImGui::GetIO().DisplaySize.x - 210.0f); + if (ImGui::BeginMenu("Help")) + { + if (ImGui::MenuItem("GitHub Repository")) + { + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "Add URL Opener", "https://github.com/stenzek/duckstation", + m_window); + } - const u32 rounded_speed = static_cast(std::round(m_speed)); - if (m_speed < 90.0f) - ImGui::TextColored(ImVec4(1.0f, 0.4f, 0.4f, 1.0f), "%u%%", rounded_speed); - else if (m_speed < 110.0f) - ImGui::TextColored(ImVec4(1.0f, 1.0f, 1.0f, 1.0f), "%u%%", rounded_speed); - else - ImGui::TextColored(ImVec4(0.4f, 1.0f, 0.4f, 1.0f), "%u%%", rounded_speed); + ImGui::Separator(); - ImGui::SetCursorPosX(ImGui::GetIO().DisplaySize.x - 165.0f); - ImGui::Text("FPS: %.2f", m_fps); + if (ImGui::MenuItem("About")) + m_about_window_open = true; - ImGui::SetCursorPosX(ImGui::GetIO().DisplaySize.x - 80.0f); - ImGui::Text("VPS: %.2f", m_vps); + ImGui::EndMenu(); + } ImGui::EndMainMenuBar(); } @@ -695,6 +719,35 @@ void SDLInterface::DrawPoweredOffWindow() ImGui::End(); } +void SDLInterface::DrawAboutWindow() +{ + ImGui::SetNextWindowPosCenter(ImGuiCond_FirstUseEver); + if (!ImGui::Begin("About DuckStation", &m_about_window_open)) + { + ImGui::End(); + return; + } + + ImGui::Text("DuckStation"); + ImGui::NewLine(); + ImGui::Text("Authors:"); + ImGui::Text(" Connor McLaughlin "); + ImGui::NewLine(); + ImGui::Text("Uses Dear ImGui (https://github.com/ocornut/imgui)"); + ImGui::Text("Uses libcue (https://github.com/lipnitsk/libcue)"); + ImGui::Text("Uses stb_image_write (https://github.com/nothings/stb)"); + ImGui::NewLine(); + ImGui::Text("Duck icon by icons8 (https://icons8.com/icon/74847/platforms.undefined.short-title)"); + + ImGui::NewLine(); + + ImGui::SetCursorPosX((ImGui::GetWindowSize().x - 60.0f) / 2.0f); + if (ImGui::Button("Close", ImVec2(60.0f, 20.0f))) + m_about_window_open = false; + + ImGui::End(); +} + void SDLInterface::AddOSDMessage(const char* message, float duration /*= 2.0f*/) { OSDMessage msg; @@ -768,6 +821,15 @@ void SDLInterface::DoReset() AddOSDMessage("System reset."); } +void SDLInterface::DoPowerOff() +{ + Assert(m_system); + + m_system.reset(); + m_display_texture = nullptr; + AddOSDMessage("System powered off."); +} + void SDLInterface::DoResume() {} void SDLInterface::DoStartDisc() @@ -865,7 +927,7 @@ void SDLInterface::Run() } else { - RenderPoweredOff(); + Render(); } } } diff --git a/src/duckstation/sdl_interface.h b/src/duckstation/sdl_interface.h index 6e764fc98..da77908cb 100644 --- a/src/duckstation/sdl_interface.h +++ b/src/duckstation/sdl_interface.h @@ -54,6 +54,7 @@ private: bool IsWindowFullscreen() const; void DrawImGui(); void DoReset(); + void DoPowerOff(); void DoResume(); void DoStartDisc(); void DoStartBIOS(); @@ -63,10 +64,10 @@ private: bool HandleSDLEvent(const SDL_Event* event); bool PassEventToImGui(const SDL_Event* event); void Render(); - void RenderPoweredOff(); void RenderDisplay(); void DrawMainMenuBar(); void DrawPoweredOffWindow(); + void DrawAboutWindow(); void DrawOSDMessages(); SDL_Window* m_window = nullptr; @@ -99,4 +100,6 @@ private: u32 m_last_internal_frame_number = 0; u32 m_last_global_tick_counter = 0; Timer m_fps_timer; + + bool m_about_window_open = false; };