mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-10 08:09:26 +01:00
VideoCommon: Add support for icons in OSD messages.
This commit is contained in:
parent
7122c7e872
commit
cb13ad7a5f
@ -579,9 +579,6 @@ static void EmuThread(std::unique_ptr<BootParameters> boot, WindowSystemInfo wsi
|
|||||||
HW::Shutdown(system);
|
HW::Shutdown(system);
|
||||||
INFO_LOG_FMT(CONSOLE, "{}", StopMessage(false, "HW shutdown"));
|
INFO_LOG_FMT(CONSOLE, "{}", StopMessage(false, "HW shutdown"));
|
||||||
|
|
||||||
// Clear on screen messages that haven't expired
|
|
||||||
OSD::ClearMessages();
|
|
||||||
|
|
||||||
// The config must be restored only after the whole HW has shut down,
|
// The config must be restored only after the whole HW has shut down,
|
||||||
// not when it is still running.
|
// not when it is still running.
|
||||||
BootManager::RestoreConfig();
|
BootManager::RestoreConfig();
|
||||||
@ -600,7 +597,12 @@ static void EmuThread(std::unique_ptr<BootParameters> boot, WindowSystemInfo wsi
|
|||||||
PanicAlertFmt("Failed to initialize video backend!");
|
PanicAlertFmt("Failed to initialize video backend!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Common::ScopeGuard video_guard{[] { g_video_backend->Shutdown(); }};
|
Common::ScopeGuard video_guard{[] {
|
||||||
|
// Clear on screen messages that haven't expired
|
||||||
|
OSD::ClearMessages();
|
||||||
|
|
||||||
|
g_video_backend->Shutdown();
|
||||||
|
}};
|
||||||
|
|
||||||
if (cpu_info.HTT)
|
if (cpu_info.HTT)
|
||||||
Config::SetBaseOrCurrent(Config::MAIN_DSP_THREAD, cpu_info.num_cores > 4);
|
Config::SetBaseOrCurrent(Config::MAIN_DSP_THREAD, cpu_info.num_cores > 4);
|
||||||
|
@ -18,6 +18,10 @@
|
|||||||
|
|
||||||
#include "Core/Config/MainSettings.h"
|
#include "Core/Config/MainSettings.h"
|
||||||
|
|
||||||
|
#include "VideoCommon/AbstractGfx.h"
|
||||||
|
#include "VideoCommon/AbstractTexture.h"
|
||||||
|
#include "VideoCommon/TextureConfig.h"
|
||||||
|
|
||||||
namespace OSD
|
namespace OSD
|
||||||
{
|
{
|
||||||
constexpr float LEFT_MARGIN = 10.0f; // Pixels to the left of OSD messages.
|
constexpr float LEFT_MARGIN = 10.0f; // Pixels to the left of OSD messages.
|
||||||
@ -32,8 +36,8 @@ static std::atomic<int> s_obscured_pixels_top = 0;
|
|||||||
struct Message
|
struct Message
|
||||||
{
|
{
|
||||||
Message() = default;
|
Message() = default;
|
||||||
Message(std::string text_, u32 duration_, u32 color_)
|
Message(std::string text_, u32 duration_, u32 color_, std::unique_ptr<Icon> icon_ = nullptr)
|
||||||
: text(std::move(text_)), duration(duration_), color(color_)
|
: text(std::move(text_)), duration(duration_), color(color_), icon(std::move(icon_))
|
||||||
{
|
{
|
||||||
timer.Start();
|
timer.Start();
|
||||||
}
|
}
|
||||||
@ -42,7 +46,10 @@ struct Message
|
|||||||
Common::Timer timer;
|
Common::Timer timer;
|
||||||
u32 duration = 0;
|
u32 duration = 0;
|
||||||
bool ever_drawn = false;
|
bool ever_drawn = false;
|
||||||
|
bool should_discard = false;
|
||||||
u32 color = 0;
|
u32 color = 0;
|
||||||
|
std::unique_ptr<Icon> icon;
|
||||||
|
std::unique_ptr<AbstractTexture> texture;
|
||||||
};
|
};
|
||||||
static std::multimap<MessageType, Message> s_messages;
|
static std::multimap<MessageType, Message> s_messages;
|
||||||
static std::mutex s_messages_mutex;
|
static std::mutex s_messages_mutex;
|
||||||
@ -77,6 +84,33 @@ static float DrawMessage(int index, Message& msg, const ImVec2& position, int ti
|
|||||||
ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoNav |
|
ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoNav |
|
||||||
ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoFocusOnAppearing))
|
ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoFocusOnAppearing))
|
||||||
{
|
{
|
||||||
|
if (msg.icon)
|
||||||
|
{
|
||||||
|
if (!msg.texture)
|
||||||
|
{
|
||||||
|
const u32 width = msg.icon->width;
|
||||||
|
const u32 height = msg.icon->height;
|
||||||
|
TextureConfig tex_config(width, height, 1, 1, 1, AbstractTextureFormat::RGBA8, 0);
|
||||||
|
msg.texture = g_gfx->CreateTexture(tex_config);
|
||||||
|
if (msg.texture)
|
||||||
|
{
|
||||||
|
msg.texture->Load(0, width, height, width, msg.icon->rgba_data.data(),
|
||||||
|
sizeof(u32) * width * height);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// don't try again next time
|
||||||
|
msg.icon.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg.texture)
|
||||||
|
{
|
||||||
|
ImGui::Image(msg.texture.get(), ImVec2(static_cast<float>(msg.icon->width),
|
||||||
|
static_cast<float>(msg.icon->height)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Use %s in case message contains %.
|
// Use %s in case message contains %.
|
||||||
ImGui::TextColored(ARGBToImVec4(msg.color), "%s", msg.text.c_str());
|
ImGui::TextColored(ARGBToImVec4(msg.color), "%s", msg.text.c_str());
|
||||||
window_height =
|
window_height =
|
||||||
@ -91,17 +125,25 @@ static float DrawMessage(int index, Message& msg, const ImVec2& position, int ti
|
|||||||
return window_height;
|
return window_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddTypedMessage(MessageType type, std::string message, u32 ms, u32 argb)
|
void AddTypedMessage(MessageType type, std::string message, u32 ms, u32 argb,
|
||||||
|
std::unique_ptr<Icon> icon)
|
||||||
{
|
{
|
||||||
std::lock_guard lock{s_messages_mutex};
|
std::lock_guard lock{s_messages_mutex};
|
||||||
s_messages.erase(type);
|
|
||||||
s_messages.emplace(type, Message(std::move(message), ms, argb));
|
// A message may hold a reference to a texture that can only be destroyed on the video thread, so
|
||||||
|
// only mark the old typed message (if any) for removal. It will be discarded on the next call to
|
||||||
|
// DrawMessages().
|
||||||
|
auto range = s_messages.equal_range(type);
|
||||||
|
for (auto it = range.first; it != range.second; ++it)
|
||||||
|
it->second.should_discard = true;
|
||||||
|
|
||||||
|
s_messages.emplace(type, Message(std::move(message), ms, argb, std::move(icon)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddMessage(std::string message, u32 ms, u32 argb)
|
void AddMessage(std::string message, u32 ms, u32 argb, std::unique_ptr<Icon> icon)
|
||||||
{
|
{
|
||||||
std::lock_guard lock{s_messages_mutex};
|
std::lock_guard lock{s_messages_mutex};
|
||||||
s_messages.emplace(MessageType::Typeless, Message(std::move(message), ms, argb));
|
s_messages.emplace(MessageType::Typeless, Message(std::move(message), ms, argb, std::move(icon)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawMessages()
|
void DrawMessages()
|
||||||
@ -117,6 +159,12 @@ void DrawMessages()
|
|||||||
for (auto it = s_messages.begin(); it != s_messages.end();)
|
for (auto it = s_messages.begin(); it != s_messages.end();)
|
||||||
{
|
{
|
||||||
Message& msg = it->second;
|
Message& msg = it->second;
|
||||||
|
if (msg.should_discard)
|
||||||
|
{
|
||||||
|
it = s_messages.erase(it);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const s64 time_left = msg.TimeRemaining();
|
const s64 time_left = msg.TimeRemaining();
|
||||||
|
|
||||||
// Make sure we draw them at least once if they were printed with 0ms,
|
// Make sure we draw them at least once if they were printed with 0ms,
|
||||||
|
@ -4,7 +4,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
|
|
||||||
@ -35,10 +37,18 @@ constexpr u32 NORMAL = 5000;
|
|||||||
constexpr u32 VERY_LONG = 10000;
|
constexpr u32 VERY_LONG = 10000;
|
||||||
}; // namespace Duration
|
}; // namespace Duration
|
||||||
|
|
||||||
|
struct Icon
|
||||||
|
{
|
||||||
|
std::vector<u8> rgba_data;
|
||||||
|
u32 width = 0;
|
||||||
|
u32 height = 0;
|
||||||
|
}; // struct Icon
|
||||||
|
|
||||||
// On-screen message display (colored yellow by default)
|
// On-screen message display (colored yellow by default)
|
||||||
void AddMessage(std::string message, u32 ms = Duration::SHORT, u32 argb = Color::YELLOW);
|
void AddMessage(std::string message, u32 ms = Duration::SHORT, u32 argb = Color::YELLOW,
|
||||||
|
std::unique_ptr<Icon> icon = nullptr);
|
||||||
void AddTypedMessage(MessageType type, std::string message, u32 ms = Duration::SHORT,
|
void AddTypedMessage(MessageType type, std::string message, u32 ms = Duration::SHORT,
|
||||||
u32 argb = Color::YELLOW);
|
u32 argb = Color::YELLOW, std::unique_ptr<Icon> icon = nullptr);
|
||||||
|
|
||||||
// Draw the current messages on the screen. Only call once per frame.
|
// Draw the current messages on the screen. Only call once per frame.
|
||||||
void DrawMessages();
|
void DrawMessages();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user