diff --git a/rpcs3/Emu/RSX/Overlays/overlay_animation.cpp b/rpcs3/Emu/RSX/Overlays/overlay_animation.cpp index ec429dad6a..7c361e4519 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_animation.cpp +++ b/rpcs3/Emu/RSX/Overlays/overlay_animation.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#pragma optimize("", off) #include "overlay_animation.h" #include "overlay_controls.h" @@ -9,6 +8,38 @@ namespace rsx { namespace overlays { + void animation_base::begin_animation(u64 frame) + { + frame_start = frame; + frame_end = u64(frame + duration * g_cfg.video.vblank_rate); + } + + f32 animation_base::get_progress_ratio(u64 frame) const + { + if (!frame_start) + { + return 0.f; + } + + f32 t = f32(frame - frame_start) / (frame_end - frame_start); + + switch (type) { + case animation_type::linear: + break; + case animation_type::ease_in_quad: + t = t * t; + break; + case animation_type::ease_out_quad: + t = t * (2.0 - t); + break; + case animation_type::ease_in_out_cubic: + t = t > 0.5 ? 4.0 * std::pow((t - 1.0), 3.0) + 1.0 : 4.0 * std::pow(t, 3.0); + break; + } + + return t; + } + void animation_translate::apply(compiled_resource& resource) { if (!active) @@ -36,9 +67,7 @@ namespace rsx if (frame_start == 0) { start = current; - frame_start = frame; - frame_end = u64(frame + duration * g_cfg.video.vblank_rate); - + begin_animation(frame); return; } @@ -49,23 +78,8 @@ namespace rsx return; } - f32 t = f32(frame - frame_start) / (frame_end - frame_start); - - switch (type) { - case animation_type::linear: - break; - case animation_type::ease_in_quad: - t = t * t; - break; - case animation_type::ease_out_quad: - t = t * (2.0 - t); - break; - case animation_type::ease_in_out_cubic: - t = t > 0.5 ? 4.0 * std::pow((t - 1.0), 3.0) + 1.0 : 4.0 * std::pow(t, 3.0); - break; - } - - current = (1.f - t) * start + t * end; + f32 t = get_progress_ratio(frame); + current = lerp(start, end, t); } void animation_translate::finish() @@ -80,5 +94,55 @@ namespace rsx on_finish(); } } + + void animation_color_interpolate::apply(compiled_resource& data) + { + if (!active) + { + return; + } + + for (auto& cmd : data.draw_commands) + { + cmd.config.color *= current; + } + } + + void animation_color_interpolate::update(u64 frame) + { + if (!active) + { + return; + } + + if (frame_start == 0) + { + start = current; + begin_animation(frame); + return; + } + + if (frame >= frame_end) + { + finish(); + return; + } + + f32 t = get_progress_ratio(frame); + current = lerp(start, end, t); + } + + void animation_color_interpolate::finish() + { + active = false; + frame_start = 0; + frame_end = 0; + current = end; + + if (on_finish) + { + on_finish(); + } + } }; } diff --git a/rpcs3/Emu/RSX/Overlays/overlay_animation.h b/rpcs3/Emu/RSX/Overlays/overlay_animation.h index d3d842e03e..a5cd0f9332 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_animation.h +++ b/rpcs3/Emu/RSX/Overlays/overlay_animation.h @@ -19,8 +19,23 @@ namespace rsx struct animation_base { + protected: + u64 frame_start = 0; + u64 frame_end = 0; + + void begin_animation(u64 frame); + f32 get_progress_ratio(u64 frame) const; + + template + T lerp(const T& a, const T& b, f32 t) const + { + return (a * (1.f - t)) + (b * t); + } + + public: bool active = false; animation_type type { animation_type::linear }; + f32 duration = 1.f; // in seconds std::function on_finish; @@ -34,12 +49,23 @@ namespace rsx vector3f start{}; // Set `current` instead of this // NOTE: Necessary because update() is called after rendering, // resulting in one frame of incorrect translation - u64 frame_start = 0; - u64 frame_end = 0; public: vector3f current{}; vector3f end{}; - f32 duration{}; // in seconds + + void apply(compiled_resource& data) override; + void update(u64 frame) override; + void finish(); + }; + + struct animation_color_interpolate : animation_translate + { + private: + color4f start{}; + + public: + color4f current{}; + color4f end{}; void apply(compiled_resource& data) override; void update(u64 frame) override;