refactor(scenes): flux centralitzat amb SceneId+ExitRequest; TitleScene attract → LOGO amb fade-to-black
This commit is contained in:
1 parent
25ce524470
commit
b6d6ee471c
17 files changed
+368
-121
No files matched your search
@@ -0,0 +1,39 @@
|
||||
#include "core/rendering/transitions/fade_to_black.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
|
||||
#include "core/rendering/screen.hpp"
|
||||
|
||||
namespace Transitions {
|
||||
|
||||
void FadeToBlack::begin(int duration_ms) {
|
||||
duration_ms_ = duration_ms;
|
||||
elapsed_ms_ = 0;
|
||||
}
|
||||
|
||||
void FadeToBlack::tick(int delta_ms) {
|
||||
if (duration_ms_ <= 0) { return; }
|
||||
elapsed_ms_ = std::min(elapsed_ms_ + delta_ms, duration_ms_);
|
||||
}
|
||||
|
||||
auto FadeToBlack::progress() const -> float {
|
||||
if (duration_ms_ <= 0) { return 0.0F; }
|
||||
return std::clamp(static_cast<float>(elapsed_ms_) / static_cast<float>(duration_ms_), 0.0F, 1.0F);
|
||||
}
|
||||
|
||||
void FadeToBlack::render() const {
|
||||
if (duration_ms_ <= 0) { return; }
|
||||
const float P = progress();
|
||||
// Alpha lineal — sense corba quadràtica (això és prerogativa del
|
||||
// dissolve mosaic, on volem que la mascara fosca arribe tard
|
||||
// perquè es vegen els blocs). Per al fade net, lineal 0..255.
|
||||
const auto ALPHA = static_cast<std::uint8_t>(std::round(255.0F * P));
|
||||
if (ALPHA == 0) { return; }
|
||||
|
||||
auto& screen = Screen::get();
|
||||
screen.blendRect(0, 0, screen.getCanvasWidth(), screen.getCanvasHeight(), 0x00000000U, ALPHA);
|
||||
}
|
||||
|
||||
} // namespace Transitions
|
||||
@@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
namespace Transitions {
|
||||
|
||||
// Fade-out lineal a negre. A diferència de `Mosaic`, no rebina cap
|
||||
// píxel; només posa una capa negra amb alpha creixent (0 → 255) al
|
||||
// damunt del canvas. És la transició "neta" per defecte; ideal per a
|
||||
// sortides on no convé l'estètica chunky de l'arcade dissolve.
|
||||
//
|
||||
// Mateixa interfície que `Mosaic` (begin/tick/render/isActive/
|
||||
// isFinished/progress) perquè els llocs de crida puguen escollir-ne
|
||||
// una o l'altra sense canviar el patró d'ús.
|
||||
class FadeToBlack {
|
||||
public:
|
||||
FadeToBlack() = default;
|
||||
|
||||
// Arrenca un fade nou. Si ja n'hi havia un actiu, el reemplaça.
|
||||
// `duration_ms <= 0` deixa l'efecte inactiu.
|
||||
void begin(int duration_ms);
|
||||
|
||||
void tick(int delta_ms);
|
||||
|
||||
[[nodiscard]] auto isActive() const -> bool { return duration_ms_ > 0 && elapsed_ms_ < duration_ms_; }
|
||||
[[nodiscard]] auto isFinished() const -> bool { return duration_ms_ > 0 && elapsed_ms_ >= duration_ms_; }
|
||||
[[nodiscard]] auto progress() const -> float;
|
||||
|
||||
// Pinta la capa negra amb alpha proporcional al `progress()`.
|
||||
// Cridar després del render normal de l'escena, abans de
|
||||
// `Screen::present()`.
|
||||
void render() const;
|
||||
|
||||
private:
|
||||
int duration_ms_{0};
|
||||
int elapsed_ms_{0};
|
||||
};
|
||||
|
||||
} // namespace Transitions
|
||||
Reference in new issue
Block a user