diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp index 9d495f8d02..ed36e02b8c 100644 --- a/Source/Core/Core/Core.cpp +++ b/Source/Core/Core/Core.cpp @@ -170,13 +170,6 @@ void DisplayMessage(const std::string& message, int time_in_ms) if (!IsRunning()) return; - // Actually displaying non-ASCII could cause things to go pear-shaped - for (const char& c : message) - { - if (!std::isprint(c)) - return; - } - OSD::AddMessage(message, time_in_ms); Host_UpdateTitle(message); } diff --git a/Source/Core/DolphinWX/Frame.cpp b/Source/Core/DolphinWX/Frame.cpp index 28ef4c1386..4b088ed808 100644 --- a/Source/Core/DolphinWX/Frame.cpp +++ b/Source/Core/DolphinWX/Frame.cpp @@ -1467,14 +1467,16 @@ void CFrame::ParseHotkeys() if (IsHotkey(HK_INCREASE_IR)) { - OSDChoice = 1; ++g_Config.iEFBScale; + OSDPrintInternalResolution(); } if (IsHotkey(HK_DECREASE_IR)) { - OSDChoice = 1; if (--g_Config.iEFBScale < SCALE_AUTO) + { g_Config.iEFBScale = SCALE_AUTO; + } + OSDPrintInternalResolution(); } if (IsHotkey(HK_TOGGLE_CROP)) { @@ -1482,26 +1484,24 @@ void CFrame::ParseHotkeys() } if (IsHotkey(HK_TOGGLE_AR)) { - OSDChoice = 2; // Toggle aspect ratio g_Config.iAspectRatio = (g_Config.iAspectRatio + 1) & 3; + OSDPrintAspectRatio(); } if (IsHotkey(HK_TOGGLE_EFBCOPIES)) { - OSDChoice = 3; // Toggle EFB copies between EFB2RAM and EFB2Texture g_Config.bSkipEFBCopyToRam = !g_Config.bSkipEFBCopyToRam; + OSDPrintEFB(); } if (IsHotkey(HK_TOGGLE_FOG)) { - OSDChoice = 4; g_Config.bDisableFog = !g_Config.bDisableFog; + OSDPrintFog(); } Core::SetIsThrottlerTempDisabled(IsHotkey(HK_TOGGLE_THROTTLE, true)); if (IsHotkey(HK_DECREASE_EMULATION_SPEED)) { - OSDChoice = 5; - if (SConfig::GetInstance().m_EmulationSpeed <= 0.0f) SConfig::GetInstance().m_EmulationSpeed = 1.0f; else if (SConfig::GetInstance().m_EmulationSpeed >= 0.2f) @@ -1512,17 +1512,19 @@ void CFrame::ParseHotkeys() if (SConfig::GetInstance().m_EmulationSpeed >= 0.95f && SConfig::GetInstance().m_EmulationSpeed <= 1.05f) SConfig::GetInstance().m_EmulationSpeed = 1.0f; + + OSDPrintEmulationSpeed(); } if (IsHotkey(HK_INCREASE_EMULATION_SPEED)) { - OSDChoice = 5; - if (SConfig::GetInstance().m_EmulationSpeed > 0.0f) SConfig::GetInstance().m_EmulationSpeed += 0.1f; if (SConfig::GetInstance().m_EmulationSpeed >= 0.95f && SConfig::GetInstance().m_EmulationSpeed <= 1.05f) SConfig::GetInstance().m_EmulationSpeed = 1.0f; + + OSDPrintEmulationSpeed(); } if (IsHotkey(HK_SAVE_STATE_SLOT_SELECTED)) { @@ -1737,3 +1739,79 @@ void CFrame::HandleSignal(wxTimerEvent& event) return; Close(); } + +void CFrame::OSDPrintInternalResolution() +{ + std::string text; + switch (g_Config.iEFBScale) + { + case SCALE_AUTO: + text = "Auto (fractional)"; + break; + case SCALE_AUTO_INTEGRAL: + text = "Auto (integral)"; + break; + case SCALE_1X: + text = "Native"; + break; + case SCALE_1_5X: + text = "1.5x"; + break; + case SCALE_2X: + text = "2x"; + break; + case SCALE_2_5X: + text = "2.5x"; + break; + default: + text = StringFromFormat("%dx", g_Config.iEFBScale - 3); + break; + } + + OSD::AddMessage("Internal Resolution: " + text); +} + +void CFrame::OSDPrintAspectRatio() +{ + std::string text; + switch (g_Config.iAspectRatio) + { + case ASPECT_AUTO: + text = "Auto"; + break; + case ASPECT_STRETCH: + text = "Stretch"; + break; + case ASPECT_ANALOG: + text = "Force 4:3"; + break; + case ASPECT_ANALOG_WIDE: + text = "Force 16:9"; + break; + } + + OSD::AddMessage("Aspect Ratio: " + text + (g_Config.bCrop ? " (crop)" : "")); +} + +void CFrame::OSDPrintEFB() +{ + OSD::AddMessage(std::string("Copy EFB: ") + + (g_Config.bSkipEFBCopyToRam ? "to Texture" : "to RAM")); +} + +void CFrame::OSDPrintFog() +{ + OSD::AddMessage(std::string("Fog: ") + (g_Config.bDisableFog ? "Disabled" : "Enabled")); +} + +void CFrame::OSDPrintEmulationSpeed() +{ + std::string text = "Speed Limit: "; + + if (SConfig::GetInstance().m_EmulationSpeed <= 0) + text += "Unlimited"; + else + text += StringFromFormat("%li%%", std::lround(SConfig::GetInstance().m_EmulationSpeed * 100.f)); + + OSD::AddMessage(text); +} diff --git a/Source/Core/DolphinWX/Frame.h b/Source/Core/DolphinWX/Frame.h index cbcee5e374..d4894ad2b8 100644 --- a/Source/Core/DolphinWX/Frame.h +++ b/Source/Core/DolphinWX/Frame.h @@ -335,6 +335,13 @@ private: bool InitControllers(); + // OSD + void OSDPrintInternalResolution(); + void OSDPrintAspectRatio(); + void OSDPrintEFB(); + void OSDPrintFog(); + void OSDPrintEmulationSpeed(); + // Event table DECLARE_EVENT_TABLE(); }; diff --git a/Source/Core/VideoBackends/D3D/Render.cpp b/Source/Core/VideoBackends/D3D/Render.cpp index d7babc9ff7..8306bf935f 100644 --- a/Source/Core/VideoBackends/D3D/Render.cpp +++ b/Source/Core/VideoBackends/D3D/Render.cpp @@ -939,7 +939,7 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, CD3D11_VIEWPORT(0.0f, 0.0f, (float)GetBackbufferWidth(), (float)GetBackbufferHeight()); D3D::context->RSSetViewports(1, &vp); - Renderer::DrawDebugText(); + Renderer::PrintDebugMessages(); OSD::DrawMessages(); D3D::EndFrame(); diff --git a/Source/Core/VideoBackends/D3D12/Render.cpp b/Source/Core/VideoBackends/D3D12/Render.cpp index 6124534204..37ce87362c 100644 --- a/Source/Core/VideoBackends/D3D12/Render.cpp +++ b/Source/Core/VideoBackends/D3D12/Render.cpp @@ -920,7 +920,7 @@ void Renderer::SwapImpl(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height // Reset viewport for drawing text D3D::SetViewportAndScissor(0, 0, GetBackbufferWidth(), GetBackbufferHeight()); - Renderer::DrawDebugText(); + Renderer::PrintDebugMessages(); OSD::DrawMessages(); D3D::EndFrame(); diff --git a/Source/Core/VideoBackends/OGL/Render.cpp b/Source/Core/VideoBackends/OGL/Render.cpp index bde616deac..a5ba1a0f3f 100644 --- a/Source/Core/VideoBackends/OGL/Render.cpp +++ b/Source/Core/VideoBackends/OGL/Render.cpp @@ -1587,7 +1587,7 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, // Reset viewport for drawing text glViewport(0, 0, GLInterface->GetBackBufferWidth(), GLInterface->GetBackBufferHeight()); - DrawDebugText(); + PrintDebugMessages(); // Do our OSD callbacks OSD::DoCallbacks(OSD::CallbackType::OnFrame); diff --git a/Source/Core/VideoBackends/Software/SWRenderer.cpp b/Source/Core/VideoBackends/Software/SWRenderer.cpp index 5a0bd246a9..5fb6f59f8c 100644 --- a/Source/Core/VideoBackends/Software/SWRenderer.cpp +++ b/Source/Core/VideoBackends/Software/SWRenderer.cpp @@ -152,7 +152,7 @@ void SWRenderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, OSD::DoCallbacks(OSD::CallbackType::OnFrame); - DrawDebugText(); + PrintDebugMessages(); SWOGLWindow::s_instance->ShowImage(GetCurrentColorTexture(), fbWidth * 4, fbWidth, fbHeight, 1.0); diff --git a/Source/Core/VideoCommon/OnScreenDisplay.cpp b/Source/Core/VideoCommon/OnScreenDisplay.cpp index 62997cd150..d0f6f24825 100644 --- a/Source/Core/VideoCommon/OnScreenDisplay.cpp +++ b/Source/Core/VideoCommon/OnScreenDisplay.cpp @@ -21,18 +21,24 @@ static std::multimap s_callbacks; static std::multimap s_messages; static std::mutex s_messages_mutex; +static std::string CleanMessage(std::string message) +{ + std::replace_if(message.begin(), message.end(), [](char c) { return !std::isprint(c); }, '?'); + return message; +} + void AddTypedMessage(MessageType type, const std::string& message, u32 ms, u32 rgba) { std::lock_guard lock(s_messages_mutex); s_messages.erase(type); - s_messages.emplace(type, Message(message, Common::Timer::GetTimeMs() + ms, rgba)); + s_messages.emplace(type, Message(CleanMessage(message), Common::Timer::GetTimeMs() + ms, rgba)); } void AddMessage(const std::string& message, u32 ms, u32 rgba) { std::lock_guard lock(s_messages_mutex); s_messages.emplace(MessageType::Typeless, - Message(message, Common::Timer::GetTimeMs() + ms, rgba)); + Message(CleanMessage(message), Common::Timer::GetTimeMs() + ms, rgba)); } void DrawMessage(const Message& msg, int top, int left, int time_left) @@ -52,7 +58,7 @@ void DrawMessages() std::lock_guard lock(s_messages_mutex); u32 now = Common::Timer::GetTimeMs(); - int left = 20, top = 35; + int left = 20, top = 20; auto it = s_messages.begin(); while (it != s_messages.end()) diff --git a/Source/Core/VideoCommon/OnScreenDisplay.h b/Source/Core/VideoCommon/OnScreenDisplay.h index a05f4058ef..a36f845a16 100644 --- a/Source/Core/VideoCommon/OnScreenDisplay.h +++ b/Source/Core/VideoCommon/OnScreenDisplay.h @@ -22,6 +22,14 @@ struct Message enum class MessageType { + FPS, + FrameCount, + RTC, + + MovieInputCount, + MovieLag, + MovieInput, + NetPlayPing, NetPlayBuffer, @@ -48,7 +56,7 @@ constexpr u32 VERY_LONG = 10000; // On-screen message display (colored yellow by default) void AddMessage(const std::string& message, u32 ms = Duration::SHORT, u32 rgba = Color::YELLOW); void AddTypedMessage(MessageType type, const std::string& message, u32 ms = Duration::SHORT, - u32 rgba = Color::YELLOW); + u32 rgba = Color::CYAN); void DrawMessage(const Message& msg, int top, int left, int time_left); // draw one message void DrawMessages(); // draw the current messages on the screen. Only call once // per frame. diff --git a/Source/Core/VideoCommon/RenderBase.cpp b/Source/Core/VideoCommon/RenderBase.cpp index a8911a7cdd..ed4b324f83 100644 --- a/Source/Core/VideoCommon/RenderBase.cpp +++ b/Source/Core/VideoCommon/RenderBase.cpp @@ -32,6 +32,7 @@ #include "Core/Host.h" #include "Core/Movie.h" +#include "OnScreenDisplay.h" #include "VideoCommon/AVIDump.h" #include "VideoCommon/BPMemory.h" #include "VideoCommon/CPMemory.h" @@ -48,8 +49,6 @@ // TODO: Move these out of here. int frameCount; -int OSDChoice; -static int OSDTime; std::unique_ptr g_renderer; @@ -99,9 +98,6 @@ Renderer::Renderer() : frame_data(), bLastFrameDumped(false) #if defined _WIN32 || defined HAVE_LIBAV bAVIDumping = false; #endif - - OSDChoice = 0; - OSDTime = 0; } Renderer::~Renderer() @@ -297,145 +293,44 @@ void Renderer::SetScreenshot(const std::string& filename) } // Create On-Screen-Messages -void Renderer::DrawDebugText() +void Renderer::PrintDebugMessages() { - std::string final_yellow, final_cyan; - - if (g_ActiveConfig.bShowFPS || SConfig::GetInstance().m_ShowFrameCount) + if (g_ActiveConfig.bShowFPS) { - if (g_ActiveConfig.bShowFPS) - final_cyan += StringFromFormat("FPS: %u", g_renderer->m_fps_counter.GetFPS()); + OSD::AddTypedMessage(OSD::MessageType::FPS, + StringFromFormat("FPS: %u", g_renderer->m_fps_counter.GetFPS())); + } - if (g_ActiveConfig.bShowFPS && SConfig::GetInstance().m_ShowFrameCount) - final_cyan += " - "; - if (SConfig::GetInstance().m_ShowFrameCount) + if (SConfig::GetInstance().m_ShowFrameCount) + { + OSD::AddTypedMessage( + OSD::MessageType::FrameCount, + StringFromFormat("Frame: %llu", (unsigned long long)Movie::GetCurrentFrame())); + + if (Movie::IsPlayingInput()) { - final_cyan += StringFromFormat("Frame: %llu", (unsigned long long)Movie::GetCurrentFrame()); - if (Movie::IsPlayingInput()) - final_cyan += - StringFromFormat("\nInput: %llu / %llu", (unsigned long long)Movie::GetCurrentInputCount(), - (unsigned long long)Movie::GetTotalInputCount()); + OSD::AddTypedMessage(OSD::MessageType::MovieInputCount, + StringFromFormat("Input: %llu / %llu", + (unsigned long long)Movie::GetCurrentInputCount(), + (unsigned long long)Movie::GetTotalInputCount())); } - - final_cyan += "\n"; - final_yellow += "\n"; } if (SConfig::GetInstance().m_ShowLag) { - final_cyan += StringFromFormat("Lag: %" PRIu64 "\n", Movie::GetCurrentLagCount()); - final_yellow += "\n"; + OSD::AddTypedMessage(OSD::MessageType::MovieLag, + StringFromFormat("Lag: %" PRIu64 "\n", Movie::GetCurrentLagCount())); } if (SConfig::GetInstance().m_ShowInputDisplay) { - final_cyan += Movie::GetInputDisplay(); - final_yellow += "\n"; + OSD::AddTypedMessage(OSD::MessageType::MovieInput, Movie::GetInputDisplay()); } if (SConfig::GetInstance().m_ShowRTC) { - final_cyan += Movie::GetRTCDisplay(); - final_yellow += "\n"; + OSD::AddTypedMessage(OSD::MessageType::RTC, Movie::GetRTCDisplay()); } - - // OSD Menu messages - if (OSDChoice > 0) - { - OSDTime = Common::Timer::GetTimeMs() + 3000; - OSDChoice = -OSDChoice; - } - - if ((u32)OSDTime > Common::Timer::GetTimeMs()) - { - std::string res_text; - switch (g_ActiveConfig.iEFBScale) - { - case SCALE_AUTO: - res_text = "Auto (fractional)"; - break; - case SCALE_AUTO_INTEGRAL: - res_text = "Auto (integral)"; - break; - case SCALE_1X: - res_text = "Native"; - break; - case SCALE_1_5X: - res_text = "1.5x"; - break; - case SCALE_2X: - res_text = "2x"; - break; - case SCALE_2_5X: - res_text = "2.5x"; - break; - default: - res_text = StringFromFormat("%dx", g_ActiveConfig.iEFBScale - 3); - break; - } - const char* ar_text = ""; - switch (g_ActiveConfig.iAspectRatio) - { - case ASPECT_AUTO: - ar_text = "Auto"; - break; - case ASPECT_STRETCH: - ar_text = "Stretch"; - break; - case ASPECT_ANALOG: - ar_text = "Force 4:3"; - break; - case ASPECT_ANALOG_WIDE: - ar_text = "Force 16:9"; - } - - const char* const efbcopy_text = g_ActiveConfig.bSkipEFBCopyToRam ? "to Texture" : "to RAM"; - - // The rows - const std::string lines[] = { - std::string("Internal Resolution: ") + res_text, - std::string("Aspect Ratio: ") + ar_text + (g_ActiveConfig.bCrop ? " (crop)" : ""), - std::string("Copy EFB: ") + efbcopy_text, - std::string("Fog: ") + (g_ActiveConfig.bDisableFog ? "Disabled" : "Enabled"), - SConfig::GetInstance().m_EmulationSpeed <= 0 ? - "Speed Limit: Unlimited" : - StringFromFormat("Speed Limit: %li%%", - std::lround(SConfig::GetInstance().m_EmulationSpeed * 100.f)), - }; - - enum - { - lines_count = sizeof(lines) / sizeof(*lines) - }; - - // The latest changed setting in yellow - for (int i = 0; i != lines_count; ++i) - { - if (OSDChoice == -i - 1) - final_yellow += lines[i]; - final_yellow += '\n'; - } - - // The other settings in cyan - for (int i = 0; i != lines_count; ++i) - { - if (OSDChoice != -i - 1) - final_cyan += lines[i]; - final_cyan += '\n'; - } - } - - final_cyan += Common::Profiler::ToString(); - - if (g_ActiveConfig.bOverlayStats) - final_cyan += Statistics::ToString(); - - if (g_ActiveConfig.bOverlayProjStats) - final_cyan += Statistics::ToStringProj(); - - // and then the text - g_renderer->RenderText(final_cyan, 20, 20, 0xFF00FFFF); - g_renderer->RenderText(final_yellow, 20, 20, 0xFFFFFF00); } void Renderer::UpdateDrawRectangle(int backbuffer_width, int backbuffer_height) diff --git a/Source/Core/VideoCommon/RenderBase.h b/Source/Core/VideoCommon/RenderBase.h index 81554f5e78..9c6c3a5375 100644 --- a/Source/Core/VideoCommon/RenderBase.h +++ b/Source/Core/VideoCommon/RenderBase.h @@ -38,7 +38,6 @@ struct EfbPokeData // TODO: Move these out of here. extern int frameCount; -extern int OSDChoice; // Renderer really isn't a very good name for this class - it's more like "Misc". // The long term goal is to get rid of this class and replace it with others that make @@ -103,7 +102,7 @@ public: static float EFBToScaledYf(float y) { return y * ((float)GetTargetHeight() / (float)EFB_HEIGHT); } // Random utilities static void SetScreenshot(const std::string& filename); - static void DrawDebugText(); + static void PrintDebugMessages(); virtual void RenderText(const std::string& text, int left, int top, u32 color) = 0;