diff --git a/rpcs3/Emu/RSX/Overlays/overlay_animation.cpp b/rpcs3/Emu/RSX/Overlays/overlay_animation.cpp index 3088c3eebc..1f0ff7a237 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_animation.cpp +++ b/rpcs3/Emu/RSX/Overlays/overlay_animation.cpp @@ -39,6 +39,13 @@ namespace rsx return t; } + void animation_translate::reset(u64 frame) + { + active = false; + current = start; + frame_start = 0; + } + void animation_translate::apply(compiled_resource& resource) { if (!active) @@ -94,6 +101,13 @@ namespace rsx } } + void animation_color_interpolate::reset(u64 frame) + { + active = false; + current = start; + frame_start = 0; + } + void animation_color_interpolate::apply(compiled_resource& data) { if (!active) diff --git a/rpcs3/Emu/RSX/Overlays/overlay_animation.h b/rpcs3/Emu/RSX/Overlays/overlay_animation.h index 405a2132db..d62e880ccf 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_animation.h +++ b/rpcs3/Emu/RSX/Overlays/overlay_animation.h @@ -43,6 +43,7 @@ namespace rsx std::function on_finish; virtual void apply(compiled_resource&) = 0; + virtual void reset(u64 frame) = 0; virtual void update(u64 frame) = 0; }; @@ -57,6 +58,7 @@ namespace rsx vector3f end{}; void apply(compiled_resource& data) override; + void reset(u64 frame) override; void update(u64 frame) override; void finish(); }; @@ -71,6 +73,7 @@ namespace rsx color4f end{}; void apply(compiled_resource& data) override; + void reset(u64 frame) override; void update(u64 frame) override; void finish(); }; diff --git a/rpcs3/Emu/RSX/Overlays/overlay_compile_notification.cpp b/rpcs3/Emu/RSX/Overlays/overlay_compile_notification.cpp index e0d5ea5b0d..e92079d448 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_compile_notification.cpp +++ b/rpcs3/Emu/RSX/Overlays/overlay_compile_notification.cpp @@ -23,7 +23,8 @@ namespace rsx 5'000'000, {}, message_pin_location::bottom, - s_shader_loading_icon24); + s_shader_loading_icon24, + true); } void show_ppu_compile_notification() @@ -39,7 +40,8 @@ namespace rsx 5'000'000, {}, message_pin_location::bottom, - s_ppu_loading_icon24); + s_ppu_loading_icon24, + true); } } } diff --git a/rpcs3/Emu/RSX/Overlays/overlay_message.cpp b/rpcs3/Emu/RSX/Overlays/overlay_message.cpp index ba181cc6e8..65f464c626 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_message.cpp +++ b/rpcs3/Emu/RSX/Overlays/overlay_message.cpp @@ -36,7 +36,7 @@ namespace rsx m_fade_out_animation.current = color4f(1.f); m_fade_out_animation.end = color4f(1.f, 1.f, 1.f, 0.f); m_fade_out_animation.duration = 1.f; - m_fade_out_animation.active = true; + m_fade_out_animation.active = false; back_color = color4f(0.25f, 0.25f, 0.25f, 0.85f); @@ -55,6 +55,11 @@ namespace rsx template message_item::message_item(std::string msg_id, u64, std::shared_ptr>, std::shared_ptr); template message_item::message_item(localized_string_id msg_id, u64, std::shared_ptr>, std::shared_ptr); + void message_item::reset_expiration() + { + m_expiration_time = get_expiration_time(m_visible_duration); + } + u64 message_item::get_expiration() const { // If reference counting is enabled and reached 0 consider it expired @@ -79,11 +84,7 @@ namespace rsx compiled_resource& message_item::get_compiled() { - auto& current_animation = m_fade_in_animation.active - ? m_fade_in_animation - : m_fade_out_animation; - - if (!m_processed || !current_animation.active) + if (!m_processed) { compiled_resources = {}; return compiled_resources; @@ -99,6 +100,10 @@ namespace rsx compiled_resources.add(m_icon->get_compiled()); } + auto& current_animation = m_fade_in_animation.active + ? m_fade_in_animation + : m_fade_out_animation; + current_animation.apply(compiled_resources); return compiled_resources; } @@ -120,10 +125,20 @@ namespace rsx { m_fade_in_animation.update(rsx::get_current_renderer()->vblank_count); } - else if (time + u64(m_fade_out_animation.duration * 1'000'000) > m_expiration_time) + else if (time + u64(m_fade_out_animation.duration * 1'000'000) > get_expiration()) { + // Only activate the animation if the message hasn't expired yet (prevents glitches afterwards). + if (time <= get_expiration()) + { + m_fade_out_animation.active = true; + } + m_fade_out_animation.update(rsx::get_current_renderer()->vblank_count); } + else if (m_fade_out_animation.active) + { + m_fade_out_animation.reset(rsx::get_current_renderer()->vblank_count); + } m_processed = true; } @@ -212,23 +227,31 @@ namespace rsx return cr; } - bool message::message_exists(message_pin_location location, localized_string_id id) + bool message::message_exists(message_pin_location location, localized_string_id id, bool allow_refresh) { - return message_exists(location, get_localized_u32string(id)); + return message_exists(location, get_localized_u32string(id), allow_refresh); } - bool message::message_exists(message_pin_location location, const std::string& msg) + bool message::message_exists(message_pin_location location, const std::string& msg, bool allow_refresh) { - return message_exists(location, utf8_to_u32string(msg)); + return message_exists(location, utf8_to_u32string(msg), allow_refresh); } - bool message::message_exists(message_pin_location location, const std::u32string& msg) + bool message::message_exists(message_pin_location location, const std::u32string& msg, bool allow_refresh) { - auto check_list = [&](const std::deque& list) + auto check_list = [&](std::deque& list) { - return std::any_of(list.cbegin(), list.cend(), [&](const message_item& item) + return std::any_of(list.begin(), list.end(), [&](message_item& item) { - return item.text_matches(msg); + if (item.text_matches(msg)) + { + if (allow_refresh) + { + item.reset_expiration(); + } + return true; + } + return false; }); }; diff --git a/rpcs3/Emu/RSX/Overlays/overlay_message.h b/rpcs3/Emu/RSX/Overlays/overlay_message.h index 53baedc2a8..7c6b14d3f3 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_message.h +++ b/rpcs3/Emu/RSX/Overlays/overlay_message.h @@ -23,6 +23,7 @@ namespace rsx void update(usz index, u64 time, u16 y_offset); void set_pos(u16 _x, u16 _y) override; + void reset_expiration(); u64 get_expiration() const; compiled_resource& get_compiled() override; @@ -54,7 +55,8 @@ namespace rsx u64 expiration, std::shared_ptr> refs, message_pin_location location = message_pin_location::top, - std::shared_ptr icon = {}) + std::shared_ptr icon = {}, + bool allow_refresh = false) { std::lock_guard lock(m_mutex_queue); @@ -66,13 +68,13 @@ namespace rsx { for (auto id : msg_id) { - if (!message_exists(location, id)) + if (!message_exists(location, id, allow_refresh)) { queue.emplace_back(id, expiration, refs, icon); } } } - else if (!message_exists(location, msg_id)) + else if (!message_exists(location, msg_id, allow_refresh)) { queue.emplace_back(msg_id, expiration, std::move(refs), icon); } @@ -96,9 +98,9 @@ namespace rsx void update_queue(std::deque& vis_set, std::deque& ready_set, message_pin_location origin); // Stacking. Extends the lifetime of a message instead of inserting a duplicate - bool message_exists(message_pin_location location, localized_string_id id); - bool message_exists(message_pin_location location, const std::string& msg); - bool message_exists(message_pin_location location, const std::u32string& msg); + bool message_exists(message_pin_location location, localized_string_id id, bool allow_refresh); + bool message_exists(message_pin_location location, const std::string& msg, bool allow_refresh); + bool message_exists(message_pin_location location, const std::u32string& msg, bool allow_refresh); }; template @@ -107,7 +109,8 @@ namespace rsx u64 expiration = 5'000'000, std::shared_ptr> refs = {}, message_pin_location location = message_pin_location::top, - std::shared_ptr icon = {}) + std::shared_ptr icon = {}, + bool allow_refresh = false) { if (auto manager = g_fxo->try_get()) { @@ -117,7 +120,7 @@ namespace rsx msg_overlay = std::make_shared(); msg_overlay = manager->add(msg_overlay); } - msg_overlay->queue_message(msg_id, expiration, std::move(refs), location, std::move(icon)); + msg_overlay->queue_message(msg_id, expiration, std::move(refs), location, std::move(icon), allow_refresh); } }