Eliminats mètodes sense callers: - Sprite::getRect() (DEAD-04) - Sprite::incX / incY (DEAD-05) - AnimatedSprite::getCurrentAnimationSize() (DEAD-07) - Surface::getSurfaceData() (DEAD-08) Sprite::update passa a ser virtual amb cos buit inline al header, en lloc de la definició a .cpp amb (void)delta_time; desapareix una línia de "parxejament" sense alterar la polimorfia (Player::update, heretat via AnimatedSprite/MovingSprite, continua fent override correctament). Això tanca DEAD-10 i PATCH-04 alhora. Els ctors per defecte Sprite()/MovingSprite() s'apunten com WONTFIX al document: són necessaris per a la cadena de construcció base d'Animated Sprite (que no delega explícitament al ctor parametritzat). Build + smoke 5s xvfb OK (exit 124). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
81 lines
3.2 KiB
C++
81 lines
3.2 KiB
C++
#pragma once
|
|
|
|
#include <SDL3/SDL.h>
|
|
|
|
#include <array>
|
|
#include <cstdint>
|
|
#include <memory>
|
|
#include <numeric>
|
|
#include <string>
|
|
|
|
// Cada Surface manté la seua propia paleta (256 colors ARGB). El destí del
|
|
// render es l'ARGB framebuffer del joc, mantingut per Screen, així que
|
|
// l'arquitectura és: sprites paletats → imatge final ARGB (>256 colors).
|
|
using Palette = std::array<Uint32, 256>;
|
|
using SubPalette = std::array<Uint8, 256>;
|
|
|
|
auto loadPaletteFromGif(const std::string& file_path) -> Palette;
|
|
|
|
struct SurfaceData {
|
|
std::shared_ptr<Uint8[]> data;
|
|
int width{0};
|
|
int height{0};
|
|
|
|
SurfaceData() = default;
|
|
SurfaceData(int w, int h)
|
|
: data(std::shared_ptr<Uint8[]>(new Uint8[static_cast<std::size_t>(w) * static_cast<std::size_t>(h)](), std::default_delete<Uint8[]>())),
|
|
width(w),
|
|
height(h) {}
|
|
SurfaceData(int w, int h, std::shared_ptr<Uint8[]> pixels)
|
|
: data(std::move(pixels)),
|
|
width(w),
|
|
height(h) {}
|
|
|
|
SurfaceData(SurfaceData&&) noexcept = default;
|
|
auto operator=(SurfaceData&&) noexcept -> SurfaceData& = default;
|
|
SurfaceData(const SurfaceData&) = delete;
|
|
auto operator=(const SurfaceData&) -> SurfaceData& = delete;
|
|
};
|
|
|
|
class Surface {
|
|
public:
|
|
// Crea una surface buida (paleta a zero) amb les dimensions donades.
|
|
Surface(int w, int h);
|
|
// Carrega pixels + paleta des d'un fitxer GIF.
|
|
explicit Surface(const std::string& file_path);
|
|
~Surface() = default;
|
|
|
|
static auto loadSurface(const std::string& file_path) -> SurfaceData;
|
|
|
|
// Vobla la regió indicada al framebuffer ARGB del joc usant la paleta propia.
|
|
void render(int x, int y, const SDL_FRect* src_rect = nullptr, SDL_FlipMode flip = SDL_FLIP_NONE) const;
|
|
// Igual que render() però substituint els píxels amb valor source_color per
|
|
// target_color abans d'aplicar la paleta. Útil per a la classe Text: els
|
|
// glifs guarden "tinta" amb un únic índex i es recoloren per paràmetre.
|
|
void renderWithColorReplace(int x, int y, Uint8 source_color, Uint8 target_color, const SDL_FRect* src_rect = nullptr, SDL_FlipMode flip = SDL_FLIP_NONE) const;
|
|
|
|
void clear(Uint8 color);
|
|
void putPixel(int x, int y, Uint8 color);
|
|
[[nodiscard]] auto getPixel(int x, int y) const -> Uint8;
|
|
|
|
[[nodiscard]] auto getWidth() const -> int { return surface_data_->width; }
|
|
[[nodiscard]] auto getHeight() const -> int { return surface_data_->height; }
|
|
|
|
[[nodiscard]] auto getTransparentColor() const -> Uint8 { return transparent_color_; }
|
|
void setTransparentColor(Uint8 color = 0) { transparent_color_ = color; }
|
|
|
|
void setPalette(const Palette& palette) { palette_ = palette; }
|
|
[[nodiscard]] auto getPaletteColor(Uint8 index) const -> Uint32 { return palette_[index]; }
|
|
|
|
static void initializeSubPalette(SubPalette& palette) { std::iota(palette.begin(), palette.end(), 0); }
|
|
|
|
private:
|
|
std::shared_ptr<SurfaceData> surface_data_;
|
|
Palette palette_{};
|
|
SubPalette sub_palette_{};
|
|
// Convenció de tots els GIFs del projecte (sprites i fonts): l'índex 0
|
|
// és el color de fons/transparent. Els tilesets que usen un altre índex
|
|
// han de cridar setTransparentColor() explícitament.
|
|
Uint8 transparent_color_{0};
|
|
};
|