diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp index 071302e17f..e135a60be8 100644 --- a/Source/Core/Core/Core.cpp +++ b/Source/Core/Core/Core.cpp @@ -172,13 +172,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 5cfbc79937..92f4fac8fb 100644 --- a/Source/Core/DolphinWX/Frame.cpp +++ b/Source/Core/DolphinWX/Frame.cpp @@ -1446,14 +1446,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)) { @@ -1461,28 +1463,26 @@ 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(); } if (IsHotkey(HK_TOGGLE_TEXTURES)) g_Config.bHiresTextures = !g_Config.bHiresTextures; 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) @@ -1493,17 +1493,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)) { @@ -1718,3 +1720,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 2f2f4ce6aa..32335f2b44 100644 --- a/Source/Core/DolphinWX/Frame.h +++ b/Source/Core/DolphinWX/Frame.h @@ -338,6 +338,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/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..cf8d66db72 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, diff --git a/Source/Core/VideoCommon/RenderBase.cpp b/Source/Core/VideoCommon/RenderBase.cpp index 4f093c4ee6..67ef0d8a61 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; @@ -106,9 +105,6 @@ Renderer::Renderer() : frame_data(), bLastFrameDumped(false) #if defined _WIN32 || defined HAVE_LIBAV bAVIDumping = false; #endif - - OSDChoice = 0; - OSDTime = 0; } Renderer::~Renderer() @@ -302,146 +298,46 @@ void Renderer::SetScreenshot(const std::string& filename) s_bScreenshot = true; } -// Create On-Screen-Messages void Renderer::DrawDebugText() { - std::string final_yellow, final_cyan; + auto draw_text = [](OSD::MessageType type, const std::string& message) { + OSD::AddTypedMessage(type, message, OSD::Duration::SHORT, OSD::Color::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()); + draw_text(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) + { + draw_text(OSD::MessageType::FrameCount, + StringFromFormat("Frame: %" PRIx64, 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()); + draw_text(OSD::MessageType::MovieInputCount, + StringFromFormat("Input: %" PRIx64 " / %" PRIx64, Movie::GetCurrentInputCount(), + Movie::GetTotalInputCount())); } - - final_cyan += "\n"; - final_yellow += "\n"; } if (SConfig::GetInstance().m_ShowLag) { - final_cyan += StringFromFormat("Lag: %" PRIu64 "\n", Movie::GetCurrentLagCount()); - final_yellow += "\n"; + draw_text(OSD::MessageType::MovieLag, + StringFromFormat("Lag: %" PRIu64 "\n", Movie::GetCurrentLagCount())); } if (SConfig::GetInstance().m_ShowInputDisplay) { - final_cyan += Movie::GetInputDisplay(); - final_yellow += "\n"; + draw_text(OSD::MessageType::MovieInput, Movie::GetInputDisplay()); } if (SConfig::GetInstance().m_ShowRTC) { - final_cyan += Movie::GetRTCDisplay(); - final_yellow += "\n"; + draw_text(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 b0d2ac1234..584c8dbec6 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