#pragma once #include // Abstracció mínima del destí de renderitzat CPU. Tots els blitters del // projecte (Surface, els HUDs via Screen::fillRect, ...) emeten píxels en // format ARGB8888 sobre una única superfície lògica que el backend GPU // després transfereix a la textura "scene". L'accés va per la funció // activeCanvas() en lloc de Screen::get() directament, per a que els // consumidors no depenguen del cicle de vida de Screen ni del seu header. namespace Rendering { // Bit alpha completament opac, ja preposicionat al canal alt del // píxel ARGB8888. Qualsevol RGB | OPAQUE_ALPHA produeix el píxel final. inline constexpr std::uint32_t OPAQUE_ALPHA = 0xFF000000U; struct Canvas { std::uint32_t* pixels{nullptr}; int width{0}; int height{0}; }; // Rectangle de clip (en píxels de canvas). Els blitters han de comprovar // `clip` abans d'escriure cada píxel; fora del rectangle no es dibuixa. // `push/pop` permet niar clips (tot i que de moment només en tenim un // nivell d'ús, el menú). Si la pila és buida, `activeClip` retorna el // canvas complet — comportament "sense clip". struct Clip { int x{0}; int y{0}; int w{0}; int h{0}; }; // Retorna el canvas actiu del joc. En aquesta fase del projecte n'hi ha // sempre un i només un (el de Screen); en el futur, si cal renderitzar // off-screen (miniatures, efectes), es podrà pushejar/popar per ací. [[nodiscard]] auto activeCanvas() -> Canvas; // Clip actiu. Si ningú ha fet push, és tot el canvas. [[nodiscard]] auto activeClip() -> Clip; // Restringeix el dibuix al rectangle donat fins al proper popClip(). // El rectangle es retalla contra el canvas (cap clip pot excedir els // seus límits, així els blitters poden assumir-los sans). void pushClip(Clip rect); // Desapila el clip actiu i restaura l'anterior. Si no hi havia cap // push previ, l'operació és idempotent i queda a "canvas complet". void popClip(); } // namespace Rendering