From f4d59d6beb8609ed642b45dab367310571549ec1 Mon Sep 17 00:00:00 2001 From: Rodrigo Delduca Date: Fri, 27 Sep 2024 09:51:33 -0300 Subject: [PATCH] Work in progress --- .pre-commit-config.yaml | 8 +-- src/deleters.hpp | 2 +- src/entity.cpp | 14 ++++- src/entity.hpp | 6 ++ src/pixmap.cpp | 129 ++++++++++++++-------------------------- src/pixmap.hpp | 2 +- 6 files changed, 68 insertions(+), 93 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b855ae0..8f3ee2e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,7 +7,7 @@ repos: - id: check-yaml - id: check-json - id: check-added-large-files - - repo: https://github.com/pre-commit/mirrors-clang-format - rev: v19.1.0 - hooks: - - id: clang-format + # - repo: https://github.com/pre-commit/mirrors-clang-format + # rev: v19.1.0 + # hooks: + # - id: clang-format diff --git a/src/deleters.hpp b/src/deleters.hpp index ff563ae..c2e2427 100644 --- a/src/deleters.hpp +++ b/src/deleters.hpp @@ -2,7 +2,7 @@ #include "common.hpp" -struct Deleter { +struct SDL_Deleter { inline void operator()(SDL_Surface *ptr) { if (ptr) { SDL_FreeSurface(ptr); diff --git a/src/entity.cpp b/src/entity.cpp index 27dc20a..4d4a914 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -9,7 +9,7 @@ using namespace framework; entity::entity(const std::string &id) - : _id(id), _point(0, 0), _angle(0.0), _alpha(255), _fn(nullptr) { + : _id(id), _point(0, 0), _angle(0.0), _flip(graphics::flip::none), _alpha(255), _fn(nullptr) { } entity::~entity() { @@ -32,7 +32,7 @@ void entity::update() { void entity::draw() const { if (_pixmap) { - _pixmap->draw(_point, _angle, _alpha); + _pixmap->draw(_point, _angle, _flip, _alpha); } } @@ -80,6 +80,14 @@ double_t entity::angle() const { return _angle; } +void entity::set_flip(graphics::flip flip) { + _flip = flip; +} + +graphics::flip entity::get_flip() { + return _flip; +} + void entity::set_alpha(const uint8_t alpha) { _alpha = alpha; } @@ -106,4 +114,4 @@ void entity::set_pixmap(const std::string &filename) { void entity::play_sound(const std::string &filename) { _resourcemanager->soundmanager()->play(filename); -} \ No newline at end of file +} diff --git a/src/entity.hpp b/src/entity.hpp index 4ea22c2..5e2b042 100644 --- a/src/entity.hpp +++ b/src/entity.hpp @@ -2,6 +2,7 @@ #include "common.hpp" +#include "pixmap.hpp" #include "point.hpp" namespace framework { @@ -37,6 +38,10 @@ class entity : public std::enable_shared_from_this { double_t angle() const; + void set_flip(graphics::flip flip); + + graphics::flip get_flip(); + void set_alpha(const uint8_t alpha); uint8_t alpha() const; @@ -58,6 +63,7 @@ class entity : public std::enable_shared_from_this { std::shared_ptr _pixmap; geometry::point _point; double_t _angle; + graphics::flip _flip; uint8_t _alpha; std::shared_ptr _entitymanager; diff --git a/src/pixmap.cpp b/src/pixmap.cpp index 444c7bb..4b6b9a0 100644 --- a/src/pixmap.cpp +++ b/src/pixmap.cpp @@ -4,6 +4,8 @@ #include "io.hpp" #include "renderer.hpp" #include +#include +#include using namespace graphics; @@ -23,93 +25,52 @@ pixmap::pixmap(const std::shared_ptr renderer, const auto buffer = storage::io::read(filename); - std::unique_ptr decoder{spng_ctx_new(0), - &spng_ctx_free}; + auto ctx = std::unique_ptr>( + spng_ctx_new(0), + [](spng_ctx* ptr) { + if (ptr) { + spng_ctx_free(ptr); + } + } + ); + + if (const auto error = spng_set_png_buffer(ctx.get(), buffer.data(), buffer.size()); error != SPNG_OK) { + throw std::runtime_error(fmt::format("[spng_set_png_buffer] error while parsing image: {}, error: {}", filename, spng_strerror(error))); + } + + spng_ihdr ihdr{}; + if (const auto error = spng_get_ihdr(ctx.get(), &ihdr); error != SPNG_OK) { + throw std::runtime_error(fmt::format("[spng_get_ihdr] error while getting image information: {}, error: {}", filename, spng_strerror(error))); + } + + const int format = SPNG_FMT_RGBA8; + size_t length = 0; + if (const auto error = spng_decoded_image_size(ctx.get(), format, &length); error != SPNG_OK) { + throw std::runtime_error(fmt::format("[spng_decoded_image_size] error while getting image size: {}, error: {}", filename, spng_strerror(error))); + } - if (auto error = - spng_set_png_buffer(decoder.get(), buffer.data(), buffer.size()); - error != SPNG_OK) { - throw std::runtime_error(fmt::format( - "[spng_set_png_buffer] error while parsing PNG: {}, error: {}", - filename, spng_strerror(error))); + std::vector output(length); + if (const auto error = spng_decode_image(ctx.get(), output.data(), length, format, SPNG_DECODE_TRNS); error != SPNG_OK) { + throw std::runtime_error(fmt::format("[spng_decode_image] error while decoding image: {}, error: {}", filename, spng_strerror(error))); } - // auto result = avifResult{}; - - // std::unique_ptr decoder{ - // avifDecoderCreate(), &avifDecoderDestroy}; - - // result = avifDecoderSetIOMemory(decoder.get(), - // reinterpret_cast(&buffer[0]), buffer.size()); - // if (result != AVIF_RESULT_OK) { - // throw std::runtime_error(fmt::format("[avifDecoderSetIOMemory] error - // while " - // "setting IO on AVIF: {}, error: - // {}", filename, - // avifResultToString(result))); - // } - - // result = avifDecoderParse(decoder.get()); - // if (result != AVIF_RESULT_OK) { - // throw std::runtime_error(fmt::format( - // "[avifDecoderParse] error while parsing AVIF: {}, error: {}", - // filename, avifResultToString(result))); - // } - - // result = avifDecoderNextImage(decoder.get()); - // if (result != AVIF_RESULT_OK) { - // throw std::runtime_error(fmt::format( - // "[avifDecoderNextImage] error while decoding AVIF: {}, error: {}", - // filename, avifResultToString(result))); - // } - - // _size = geometry::size{decoder->image->width, decoder->image->height}; - - // std::unique_ptr surface{ - // SDL_CreateRGBSurfaceWithFormat(0, decoder->image->width, - // decoder->image->height, 0, - // SDL_PIXELFORMAT_ARGB8888), - // SDL_FreeSurface}; - - // if (!surface) { - // throw std::runtime_error( - // fmt::format("[SDL_CreateRGBSurfaceWithFormat] error while creating - // " - // "surface with format: {}, error {}", - // filename, SDL_GetError())); - // } - - // avifRGBImage rgb{}; - // rgb.width = surface->w; - // rgb.height = surface->h; - // rgb.depth = 8; - // #if SDL_BYTEORDER == SDL_LIL_ENDIAN - // rgb.format = AVIF_RGB_FORMAT_BGRA; - // #else - // rgb.format = AVIF_RGB_FORMAT_ARGB; - // #endif - // rgb.pixels = (uint8_t *)surface->pixels; - // rgb.rowBytes = (uint32_t)surface->pitch; - - // if (avifImageYUVToRGB(decoder->image, &rgb) != AVIF_RESULT_OK) { - // throw std::runtime_error( - // fmt::format("[avifImageYUVToRGB] error while converting YUV to RGB - // on " - // "avifImage: {}", - // filename)); - // } - - // _texture = texture_ptr(SDL_CreateTextureFromSurface(*renderer, - // surface.get()), - // SDL_Deleter()); - - // if (!_texture) { - // throw std::runtime_error( - // fmt::format("[SDL_CreateTextureFromSurface] error while creating " - // "texture from surface: {}", - // filename)); - // } + _size = geometry::size{ihdr.width, ihdr.height}; + + std::unique_ptr surface{ + SDL_CreateRGBSurfaceWithFormat(0, _size.width(), _size.height(), 0, SDL_PIXELFORMAT_ABGR8888), + SDL_FreeSurface + }; + if (!surface) { + throw std::runtime_error(fmt::format("[SDL_CreateRGBSurfaceWithFormat] error while creating surface with format: {}, error {}", filename, SDL_GetError())); + } + + std::memcpy(surface->pixels, output.data(), length); + ctx.reset(); + _texture = texture_ptr(SDL_CreateTextureFromSurface(*renderer, surface.get()), SDL_Deleter()); + + if (!_texture) { + throw std::runtime_error(fmt::format("[SDL_CreateTextureFromSurface] error while creating texture from surface: {}", filename)); + } } void pixmap::draw(const geometry::point &point, const double_t angle, flip flip, diff --git a/src/pixmap.hpp b/src/pixmap.hpp index 4aa96c1..8c29367 100644 --- a/src/pixmap.hpp +++ b/src/pixmap.hpp @@ -5,7 +5,7 @@ #include "point.hpp" #include "size.hpp" -typedef std::unique_ptr texture_ptr; +typedef std::unique_ptr texture_ptr; namespace graphics { enum class flip : int32_t {