#include "core/rendering/transitions/mosaic.hpp" #include #include #include #include "core/rendering/screen.hpp" namespace Transitions { Mosaic::Mosaic(Params params) : params_(params) {} void Mosaic::begin(int duration_ms) { duration_ms_ = duration_ms; elapsed_ms_ = 0; } void Mosaic::tick(int delta_ms) { if (duration_ms_ <= 0) { return; } elapsed_ms_ = std::min(elapsed_ms_ + delta_ms, duration_ms_); } auto Mosaic::progress() const -> float { if (duration_ms_ <= 0) { return 0.0F; } return std::clamp(static_cast(elapsed_ms_) / static_cast(duration_ms_), 0.0F, 1.0F); } void Mosaic::render() const { if (duration_ms_ <= 0) { return; } const float P = progress(); const int MAX_BLOCK = std::max(1, params_.max_block_size); // Blocs de mida creixent al llarg del fade. A p=0 → 1 px (sense // efecte visible); a p=1 → max_block. Es fa cap-amunt amb ceil // perquè el primer increment arribi aviat (el salt visual de // 1→2 ja es nota). const int BLOCK = std::clamp(static_cast(std::ceil(static_cast(MAX_BLOCK) * P)), 1, MAX_BLOCK); auto& screen = Screen::get(); std::uint32_t* canvas = screen.getCanvasArgb(); const int W = screen.getCanvasWidth(); const int H = screen.getCanvasHeight(); if (BLOCK > 1) { // Sample-and-fill in-place. Per a cada bloc, mostregem el // píxel central (les vores poden caure fora del canvas en // blocs de la última columna/fila → clamp). for (int by = 0; by < H; by += BLOCK) { const int Y_END = std::min(by + BLOCK, H); const int SY = std::min(by + (BLOCK / 2), H - 1); for (int bx = 0; bx < W; bx += BLOCK) { const int X_END = std::min(bx + BLOCK, W); const int SX = std::min(bx + (BLOCK / 2), W - 1); const std::uint32_t COLOR = canvas[(SY * W) + SX]; for (int yy = by; yy < Y_END; ++yy) { std::uint32_t* row = canvas + (static_cast(yy) * W); std::fill(row + bx, row + X_END, COLOR); } } } } // Fade-to-black quadràtic per damunt: la mascara fosca arriba // tard (a p=0.5 només 25% d'alpha) perquè es vegin els blocs. const auto ALPHA = static_cast(std::round(255.0F * P * P)); if (ALPHA > 0) { screen.blendRect(0, 0, W, H, 0x00000000U, ALPHA); } } } // namespace Transitions