diff --git a/src/app/gfx/bitmap.cc b/src/app/gfx/bitmap.cc index c57427f1..d5d36cd0 100644 --- a/src/app/gfx/bitmap.cc +++ b/src/app/gfx/bitmap.cc @@ -11,47 +11,50 @@ namespace yaze { namespace app { namespace gfx { +namespace { +void GrayscalePalette(SDL_Palette *palette) { + for (int i = 0; i < 8; i++) { + palette->colors[i].r = i * 31; + palette->colors[i].g = i * 31; + palette->colors[i].b = i * 31; + } +} +} // namespace + Bitmap::Bitmap(int width, int height, int depth, uchar *data) : width_(width), height_(height), depth_(depth), pixel_data_(data) { - surface_ = SDL_CreateRGBSurfaceWithFormat(0, width, height, depth, - SDL_PIXELFORMAT_INDEX8); - // Default grayscale palette - for (int i = 0; i < 8; i++) { - surface_->format->palette->colors[i].r = i * 31; - surface_->format->palette->colors[i].g = i * 31; - surface_->format->palette->colors[i].b = i * 31; - } + surface_ = std::unique_ptr( + SDL_CreateRGBSurfaceWithFormat(0, width, height, depth, + SDL_PIXELFORMAT_INDEX8), + sdl_deleter()); + GrayscalePalette(surface_->format->palette); surface_->pixels = data; } Bitmap::Bitmap(int width, int height, int depth, int data_size) : width_(width), height_(height), depth_(depth), data_size_(data_size) { - surface_ = SDL_CreateRGBSurfaceWithFormat(0, width, height, depth, - SDL_PIXELFORMAT_INDEX8); - // Default grayscale palette - for (int i = 0; i < 8; i++) { - surface_->format->palette->colors[i].r = i * 31; - surface_->format->palette->colors[i].g = i * 31; - surface_->format->palette->colors[i].b = i * 31; - } - + surface_ = std::unique_ptr( + SDL_CreateRGBSurfaceWithFormat(0, width, height, depth, + SDL_PIXELFORMAT_INDEX8), + sdl_deleter()); + GrayscalePalette(surface_->format->palette); pixel_data_ = (uchar *)SDL_malloc(data_size); surface_->pixels = pixel_data_; } +// Pass raw pixel data directly to the surface +// Be sure to know what the hell you're doing if you use this one. void Bitmap::Create(int width, int height, int depth, uchar *data) { width_ = width; height_ = height; depth_ = depth; pixel_data_ = data; - surface_ = SDL_CreateRGBSurfaceWithFormat(0, width, height, depth, - SDL_PIXELFORMAT_INDEX8); - // Default grayscale palette - for (int i = 0; i < 8; i++) { - surface_->format->palette->colors[i].r = i * 31; - surface_->format->palette->colors[i].g = i * 31; - surface_->format->palette->colors[i].b = i * 31; - } + surface_ = std::unique_ptr( + SDL_CreateRGBSurfaceWithFormat(0, width, height, depth, + SDL_PIXELFORMAT_INDEX8), + sdl_deleter()); + GrayscalePalette(surface_->format->palette); + surface_->pixels = pixel_data_; } @@ -61,15 +64,11 @@ void Bitmap::Create(int width, int height, int depth, int size) { height_ = height; depth_ = depth; data_size_ = size; - surface_ = SDL_CreateRGBSurfaceWithFormat(0, width, height, depth, - SDL_PIXELFORMAT_INDEX8); - // Default grayscale palette - for (int i = 0; i < 8; i++) { - surface_->format->palette->colors[i].r = i * 31; - surface_->format->palette->colors[i].g = i * 31; - surface_->format->palette->colors[i].b = i * 31; - } - + surface_ = std::unique_ptr( + SDL_CreateRGBSurfaceWithFormat(0, width, height, depth, + SDL_PIXELFORMAT_INDEX8), + sdl_deleter()); + GrayscalePalette(surface_->format->palette); pixel_data_ = (uchar *)SDL_malloc(size); surface_->pixels = pixel_data_; } @@ -80,14 +79,18 @@ void Bitmap::Create(int width, int height, int depth, uchar *data, int size, height_ = height; depth_ = depth; pixel_data_ = data; - surface_ = SDL_CreateRGBSurfaceWithFormat(0, width, height, depth, - SDL_PIXELFORMAT_INDEX8); + surface_ = std::unique_ptr( + SDL_CreateRGBSurfaceWithFormat(0, width, height, depth, + SDL_PIXELFORMAT_INDEX8), + sdl_deleter()); surface_->format->palette = palette.GetSDL_Palette(); surface_->pixels = pixel_data_; } void Bitmap::CreateTexture(std::shared_ptr renderer) { - texture_ = SDL_CreateTextureFromSurface(renderer.get(), surface_); + texture_ = std::unique_ptr( + SDL_CreateTextureFromSurface(renderer.get(), surface_.get()), + sdl_deleter()); } void Bitmap::ApplyPalette(const SNESPalette &palette) { palette_ = palette; } @@ -100,7 +103,7 @@ absl::StatusOr> Bitmap::CreateTiles() { bmp.Create(8, 8, 8, 32); auto surface = bmp.GetSurface(); SDL_Rect src_rect = {i, j, 8, 8}; - if (SDL_BlitSurface(surface_, &src_rect, surface, nullptr) != 0) { + if (SDL_BlitSurface(surface_.get(), &src_rect, surface, nullptr) != 0) { return absl::InvalidArgumentError( "Failed to blit surface for Bitmap Tilesheet"); } @@ -110,6 +113,30 @@ absl::StatusOr> Bitmap::CreateTiles() { return tiles; } +absl::Status Bitmap::CreateFromTiles(const std::vector &tiles) { + if (tiles.empty()) { + return absl::InvalidArgumentError("Empty tiles"); + } + + SDL_Rect tile_rect = {0, 0, 8, 8}; + SDL_Rect dest_rect = {0, 0, 8, 8}; + for (const auto &tile : tiles) { + auto src = tile.GetSurface(); + if (SDL_BlitSurface(src, &tile_rect, surface_.get(), &dest_rect) != 0) { + return absl::InvalidArgumentError( + "Failed to blit surface for Bitmap Tilesheet"); + } + + dest_rect.x++; + if (dest_rect.x == 15) { + dest_rect.x = 0; + dest_rect.y++; + } + } + + return absl::OkStatus(); +} + } // namespace gfx } // namespace app } // namespace yaze diff --git a/src/app/gfx/bitmap.h b/src/app/gfx/bitmap.h index b6c602ad..183a2136 100644 --- a/src/app/gfx/bitmap.h +++ b/src/app/gfx/bitmap.h @@ -28,21 +28,27 @@ class Bitmap { void ApplyPalette(const SNESPalette &palette); absl::StatusOr> CreateTiles(); + absl::Status CreateFromTiles(const std::vector &tiles); int GetWidth() const { return width_; } int GetHeight() const { return height_; } auto GetData() const { return pixel_data_; } - auto GetTexture() const { return texture_; } - auto GetSurface() const { return surface_; } + auto GetTexture() const { return texture_.get(); } + auto GetSurface() const { return surface_.get(); } private: + struct sdl_deleter { + void operator()(SDL_Texture *p) const { SDL_DestroyTexture(p); } + void operator()(SDL_Surface *p) const { SDL_FreeSurface(p); } + }; + int width_ = 0; int height_ = 0; int depth_ = 0; int data_size_ = 0; uchar *pixel_data_; - SDL_Surface *surface_; - SDL_Texture *texture_; + std::shared_ptr texture_; + std::shared_ptr surface_; SNESPalette palette_; };