// curtain.cpp - Implementació de la cortinilla negra // © 2026 JailDesigner #include "core/graphics/curtain.hpp" #include #include "core/defaults/game.hpp" #include "core/math/easing.hpp" namespace Graphics { namespace { constexpr float SCREEN_H = static_cast(Defaults::Game::HEIGHT); constexpr float SCREEN_W = static_cast(Defaults::Game::WIDTH); } // namespace Curtain::Curtain(Rendering::Renderer* renderer) : renderer_(renderer) {} void Curtain::cover(float duration) { // Caire superior de -H (fora, a dalt) fins a 0 (tela tapant tota la pantalla). from_ = -SCREEN_H; to_ = 0.0F; duration_ = duration; elapsed_ = 0.0F; active_ = true; } void Curtain::reveal(float duration) { // Caire superior de 0 (tapant) fins a +H (tela fora per baix). from_ = 0.0F; to_ = SCREEN_H; duration_ = duration; elapsed_ = 0.0F; active_ = true; } void Curtain::update(float delta_time) { if (!active_) { return; } elapsed_ += delta_time; } auto Curtain::topY() const -> float { if (duration_ <= 0.0F) { return to_; } const float T = std::clamp(elapsed_ / duration_, 0.0F, 1.0F); // Ease-in: la tela "cau" accelerant, com per gravetat. return Easing::lerp(from_, to_, Easing::easeInQuad(T)); } auto Curtain::isDone() const -> bool { return !active_ || elapsed_ >= duration_; } void Curtain::draw() const { if (!active_) { return; } const float TOP = topY(); // Si la tela ja ha sortit completament per baix, no hi ha res a pintar. if (TOP >= SCREEN_H) { return; } renderer_->pushRect(0.0F, TOP, SCREEN_W, SCREEN_H, 0.0F, 0.0F, 0.0F, 1.0F); } } // namespace Graphics