From 31b07fece51e082850beb0afd7e525c9d07b3d08 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Fri, 3 Jan 2020 15:41:34 +0300 Subject: [PATCH] rsx/overlays: Add support for animations - Adds animation support. This commit adds the base framework and implements a translate animation used to slide elements around the screen. This is then used to implement the sliding animation for the trophy notification. --- rpcs3/Emu/CMakeLists.txt | 1 + rpcs3/Emu/RSX/Overlays/overlay_animation.cpp | 76 +++++++++++++++ rpcs3/Emu/RSX/Overlays/overlay_animation.h | 94 +++++++++++++++++++ rpcs3/Emu/RSX/Overlays/overlay_controls.h | 10 -- .../Overlays/overlay_trophy_notification.cpp | 26 ++++- rpcs3/Emu/RSX/Overlays/overlays.h | 3 + rpcs3/emucore.vcxproj | 4 +- rpcs3/emucore.vcxproj.filters | 8 +- 8 files changed, 209 insertions(+), 13 deletions(-) create mode 100644 rpcs3/Emu/RSX/Overlays/overlay_animation.cpp create mode 100644 rpcs3/Emu/RSX/Overlays/overlay_animation.h diff --git a/rpcs3/Emu/CMakeLists.txt b/rpcs3/Emu/CMakeLists.txt index e3e01e6290..38db739119 100644 --- a/rpcs3/Emu/CMakeLists.txt +++ b/rpcs3/Emu/CMakeLists.txt @@ -359,6 +359,7 @@ target_sources(rpcs3_emu PRIVATE RSX/Common/TextureUtils.cpp RSX/Common/VertexProgramDecompiler.cpp RSX/Null/NullGSRender.cpp + RSX/Overlays/overlay_animation.cpp RSX/Overlays/overlay_edit_text.cpp RSX/Overlays/overlay_font.cpp RSX/Overlays/overlay_list_view.cpp diff --git a/rpcs3/Emu/RSX/Overlays/overlay_animation.cpp b/rpcs3/Emu/RSX/Overlays/overlay_animation.cpp new file mode 100644 index 0000000000..80f25ad398 --- /dev/null +++ b/rpcs3/Emu/RSX/Overlays/overlay_animation.cpp @@ -0,0 +1,76 @@ +#include "stdafx.h" +#include "overlay_animation.h" +#include "overlay_controls.h" + +namespace rsx +{ + namespace overlays + { + void animation_translate::apply(compiled_resource& resource) + { + if (progress == vector3i(0, 0, 0)) + { + return; + } + + const vertex delta = { static_cast(progress.x), static_cast(progress.y), static_cast(progress.z), 0.f }; + for (auto& cmd : resource.draw_commands) + { + for (auto& v : cmd.verts) + { + v += delta; + } + } + } + + void animation_translate::update(u64 t) + { + if (!active) + { + return; + } + + if (time == 0) + { + time = t; + return; + } + + const u64 delta = (t - time); + const u64 frames = delta / 16667; + + if (frames) + { + const int mag = frames * speed; + const vector3i new_progress = progress + direction * mag; + const auto d = new_progress.distance(progress_limit); + + if (distance >= 0) + { + if (d > distance) + { + // Exit condition + finish(); + return; + } + } + + progress = new_progress; + distance = d; + time = t; + } + } + + void animation_translate::finish() + { + active = false; + distance = -1; + time = 0; + + if (on_finish) + { + on_finish(); + } + } + }; +} diff --git a/rpcs3/Emu/RSX/Overlays/overlay_animation.h b/rpcs3/Emu/RSX/Overlays/overlay_animation.h new file mode 100644 index 0000000000..f411a499f9 --- /dev/null +++ b/rpcs3/Emu/RSX/Overlays/overlay_animation.h @@ -0,0 +1,94 @@ +#pragma once +#include "Utilities/types.h" +#include "Utilities/geometry.h" + +namespace rsx +{ + template + struct vector3_base : public position3_base + { + using position3_base::position3_base; + + vector3_base(T x, T y, T z) + { + this->x = x; + this->y = y; + this->z = z; + } + + vector3_base(const position3_base& other) + { + this->x = other.x; + this->y = other.y; + this->z = other.z; + } + + vector3_base operator * (const vector3_base& rhs) const + { + return { this->x * rhs.x, this->y * rhs.y, this->z * rhs.z }; + } + + vector3_base operator * (T rhs) const + { + return { this->x * rhs, this->y * rhs, this->z * rhs }; + } + + void operator *= (const vector3_base& rhs) + { + this->x *= rhs.x; + this->y *= rhs.y; + this->z *= rhs.z; + } + + void operator *= (T rhs) + { + this->x *= rhs; + this->y *= rhs; + this->z *= rhs; + } + + T dot(const vector3_base& rhs) const + { + return (this->x * rhs.x) + (this->y * rhs.y) + (this->z * rhs.z); + } + + T distance(const vector3_base& rhs) const + { + const vector3_base d = *this - rhs; + return d.dot(d); + } + }; + + using vector3i = vector3_base; + using vector3f = vector3_base; + + namespace overlays + { + struct compiled_resource; + + struct animation_base + { + bool active = false; + + virtual void apply(compiled_resource&) = 0; + virtual void update(u64 t) = 0; + }; + + struct animation_translate : animation_base + { + vector3i direction{}; + vector3i progress{}; + vector3i progress_limit{}; + + std::function on_finish; + + int speed = 0; + int distance = -1; + u64 time = 0; + + void apply(compiled_resource& data) override; + void update(u64 t) override; + void finish(); + }; + } +} diff --git a/rpcs3/Emu/RSX/Overlays/overlay_controls.h b/rpcs3/Emu/RSX/Overlays/overlay_controls.h index 0d4d32b704..d1eb4d1aef 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_controls.h +++ b/rpcs3/Emu/RSX/Overlays/overlay_controls.h @@ -781,16 +781,6 @@ namespace rsx } }; - struct animation_base - { - float duration = 0.f; - float t = 0.f; - overlay_element *ref = nullptr; - - virtual void update(float /*elapsed*/) {} - void reset() { t = 0.f; } - }; - struct layout_container : public overlay_element { std::vector> m_items; diff --git a/rpcs3/Emu/RSX/Overlays/overlay_trophy_notification.cpp b/rpcs3/Emu/RSX/Overlays/overlay_trophy_notification.cpp index a0f0e9672f..654644d370 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_trophy_notification.cpp +++ b/rpcs3/Emu/RSX/Overlays/overlay_trophy_notification.cpp @@ -20,12 +20,35 @@ namespace rsx text_view.set_font("Arial", 8); text_view.align_text(overlay_element::text_align::center); text_view.back_color.a = 0.f; + + sliding_animation.direction = { 1, 0, 0 }; + sliding_animation.speed = 10; + sliding_animation.progress = { -int(frame.w), 0, 0 }; + sliding_animation.progress_limit = { 0, 0, 0}; + sliding_animation.active = true; } void trophy_notification::update() { u64 t = get_system_time(); if (((t - creation_time) / 1000) > 7500) - close(); + { + if (!sliding_animation.active) + { + sliding_animation.direction.x = -1; + sliding_animation.progress_limit = { -int(frame.w), 0, 0 }; + sliding_animation.on_finish = [this] + { + close(); + }; + + sliding_animation.active = true; + } + } + + if (sliding_animation.active) + { + sliding_animation.update(t); + } } compiled_resource trophy_notification::get_compiled() @@ -34,6 +57,7 @@ namespace rsx result.add(image.get_compiled()); result.add(text_view.get_compiled()); + sliding_animation.apply(result); return result; } diff --git a/rpcs3/Emu/RSX/Overlays/overlays.h b/rpcs3/Emu/RSX/Overlays/overlays.h index 1558babd3d..77dd9f14a3 100644 --- a/rpcs3/Emu/RSX/Overlays/overlays.h +++ b/rpcs3/Emu/RSX/Overlays/overlays.h @@ -1,4 +1,5 @@ #pragma once +#include "overlay_animation.h" #include "overlay_controls.h" #include "../../../Utilities/date_time.h" @@ -505,6 +506,8 @@ namespace rsx u64 creation_time = 0; std::unique_ptr icon_info; + animation_translate sliding_animation; + public: trophy_notification(); diff --git a/rpcs3/emucore.vcxproj b/rpcs3/emucore.vcxproj index d4355889c8..d8305315d8 100644 --- a/rpcs3/emucore.vcxproj +++ b/rpcs3/emucore.vcxproj @@ -320,6 +320,7 @@ + @@ -591,6 +592,7 @@ + @@ -655,4 +657,4 @@ - \ No newline at end of file + diff --git a/rpcs3/emucore.vcxproj.filters b/rpcs3/emucore.vcxproj.filters index a9ae15c02e..7bb610a82a 100644 --- a/rpcs3/emucore.vcxproj.filters +++ b/rpcs3/emucore.vcxproj.filters @@ -773,6 +773,9 @@ Emu\GPU\RSX\Overlays + + Emu\GPU\RSX\Overlays + Emu\GPU\RSX\Overlays @@ -1519,6 +1522,9 @@ Emu\GPU\RSX\Capture + + Emu\GPU\RSX\Overlays + Emu\GPU\RSX\Overlays @@ -1601,4 +1607,4 @@ Emu\GPU\RSX\Overlays\Shaders - \ No newline at end of file +