Refactor Bitmap SDL components to RAII
This commit is contained in:
@@ -11,47 +11,50 @@ namespace yaze {
|
|||||||
namespace app {
|
namespace app {
|
||||||
namespace gfx {
|
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)
|
Bitmap::Bitmap(int width, int height, int depth, uchar *data)
|
||||||
: width_(width), height_(height), depth_(depth), pixel_data_(data) {
|
: width_(width), height_(height), depth_(depth), pixel_data_(data) {
|
||||||
surface_ = SDL_CreateRGBSurfaceWithFormat(0, width, height, depth,
|
surface_ = std::unique_ptr<SDL_Surface, sdl_deleter>(
|
||||||
SDL_PIXELFORMAT_INDEX8);
|
SDL_CreateRGBSurfaceWithFormat(0, width, height, depth,
|
||||||
// Default grayscale palette
|
SDL_PIXELFORMAT_INDEX8),
|
||||||
for (int i = 0; i < 8; i++) {
|
sdl_deleter());
|
||||||
surface_->format->palette->colors[i].r = i * 31;
|
GrayscalePalette(surface_->format->palette);
|
||||||
surface_->format->palette->colors[i].g = i * 31;
|
|
||||||
surface_->format->palette->colors[i].b = i * 31;
|
|
||||||
}
|
|
||||||
surface_->pixels = data;
|
surface_->pixels = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
Bitmap::Bitmap(int width, int height, int depth, int data_size)
|
Bitmap::Bitmap(int width, int height, int depth, int data_size)
|
||||||
: width_(width), height_(height), depth_(depth), data_size_(data_size) {
|
: width_(width), height_(height), depth_(depth), data_size_(data_size) {
|
||||||
surface_ = SDL_CreateRGBSurfaceWithFormat(0, width, height, depth,
|
surface_ = std::unique_ptr<SDL_Surface, sdl_deleter>(
|
||||||
SDL_PIXELFORMAT_INDEX8);
|
SDL_CreateRGBSurfaceWithFormat(0, width, height, depth,
|
||||||
// Default grayscale palette
|
SDL_PIXELFORMAT_INDEX8),
|
||||||
for (int i = 0; i < 8; i++) {
|
sdl_deleter());
|
||||||
surface_->format->palette->colors[i].r = i * 31;
|
GrayscalePalette(surface_->format->palette);
|
||||||
surface_->format->palette->colors[i].g = i * 31;
|
|
||||||
surface_->format->palette->colors[i].b = i * 31;
|
|
||||||
}
|
|
||||||
|
|
||||||
pixel_data_ = (uchar *)SDL_malloc(data_size);
|
pixel_data_ = (uchar *)SDL_malloc(data_size);
|
||||||
surface_->pixels = pixel_data_;
|
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) {
|
void Bitmap::Create(int width, int height, int depth, uchar *data) {
|
||||||
width_ = width;
|
width_ = width;
|
||||||
height_ = height;
|
height_ = height;
|
||||||
depth_ = depth;
|
depth_ = depth;
|
||||||
pixel_data_ = data;
|
pixel_data_ = data;
|
||||||
surface_ = SDL_CreateRGBSurfaceWithFormat(0, width, height, depth,
|
surface_ = std::unique_ptr<SDL_Surface, sdl_deleter>(
|
||||||
SDL_PIXELFORMAT_INDEX8);
|
SDL_CreateRGBSurfaceWithFormat(0, width, height, depth,
|
||||||
// Default grayscale palette
|
SDL_PIXELFORMAT_INDEX8),
|
||||||
for (int i = 0; i < 8; i++) {
|
sdl_deleter());
|
||||||
surface_->format->palette->colors[i].r = i * 31;
|
GrayscalePalette(surface_->format->palette);
|
||||||
surface_->format->palette->colors[i].g = i * 31;
|
|
||||||
surface_->format->palette->colors[i].b = i * 31;
|
|
||||||
}
|
|
||||||
surface_->pixels = pixel_data_;
|
surface_->pixels = pixel_data_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,15 +64,11 @@ void Bitmap::Create(int width, int height, int depth, int size) {
|
|||||||
height_ = height;
|
height_ = height;
|
||||||
depth_ = depth;
|
depth_ = depth;
|
||||||
data_size_ = size;
|
data_size_ = size;
|
||||||
surface_ = SDL_CreateRGBSurfaceWithFormat(0, width, height, depth,
|
surface_ = std::unique_ptr<SDL_Surface, sdl_deleter>(
|
||||||
SDL_PIXELFORMAT_INDEX8);
|
SDL_CreateRGBSurfaceWithFormat(0, width, height, depth,
|
||||||
// Default grayscale palette
|
SDL_PIXELFORMAT_INDEX8),
|
||||||
for (int i = 0; i < 8; i++) {
|
sdl_deleter());
|
||||||
surface_->format->palette->colors[i].r = i * 31;
|
GrayscalePalette(surface_->format->palette);
|
||||||
surface_->format->palette->colors[i].g = i * 31;
|
|
||||||
surface_->format->palette->colors[i].b = i * 31;
|
|
||||||
}
|
|
||||||
|
|
||||||
pixel_data_ = (uchar *)SDL_malloc(size);
|
pixel_data_ = (uchar *)SDL_malloc(size);
|
||||||
surface_->pixels = pixel_data_;
|
surface_->pixels = pixel_data_;
|
||||||
}
|
}
|
||||||
@@ -80,14 +79,18 @@ void Bitmap::Create(int width, int height, int depth, uchar *data, int size,
|
|||||||
height_ = height;
|
height_ = height;
|
||||||
depth_ = depth;
|
depth_ = depth;
|
||||||
pixel_data_ = data;
|
pixel_data_ = data;
|
||||||
surface_ = SDL_CreateRGBSurfaceWithFormat(0, width, height, depth,
|
surface_ = std::unique_ptr<SDL_Surface, sdl_deleter>(
|
||||||
SDL_PIXELFORMAT_INDEX8);
|
SDL_CreateRGBSurfaceWithFormat(0, width, height, depth,
|
||||||
|
SDL_PIXELFORMAT_INDEX8),
|
||||||
|
sdl_deleter());
|
||||||
surface_->format->palette = palette.GetSDL_Palette();
|
surface_->format->palette = palette.GetSDL_Palette();
|
||||||
surface_->pixels = pixel_data_;
|
surface_->pixels = pixel_data_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bitmap::CreateTexture(std::shared_ptr<SDL_Renderer> renderer) {
|
void Bitmap::CreateTexture(std::shared_ptr<SDL_Renderer> renderer) {
|
||||||
texture_ = SDL_CreateTextureFromSurface(renderer.get(), surface_);
|
texture_ = std::unique_ptr<SDL_Texture, sdl_deleter>(
|
||||||
|
SDL_CreateTextureFromSurface(renderer.get(), surface_.get()),
|
||||||
|
sdl_deleter());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bitmap::ApplyPalette(const SNESPalette &palette) { palette_ = palette; }
|
void Bitmap::ApplyPalette(const SNESPalette &palette) { palette_ = palette; }
|
||||||
@@ -100,7 +103,7 @@ absl::StatusOr<std::vector<Bitmap>> Bitmap::CreateTiles() {
|
|||||||
bmp.Create(8, 8, 8, 32);
|
bmp.Create(8, 8, 8, 32);
|
||||||
auto surface = bmp.GetSurface();
|
auto surface = bmp.GetSurface();
|
||||||
SDL_Rect src_rect = {i, j, 8, 8};
|
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(
|
return absl::InvalidArgumentError(
|
||||||
"Failed to blit surface for Bitmap Tilesheet");
|
"Failed to blit surface for Bitmap Tilesheet");
|
||||||
}
|
}
|
||||||
@@ -110,6 +113,30 @@ absl::StatusOr<std::vector<Bitmap>> Bitmap::CreateTiles() {
|
|||||||
return tiles;
|
return tiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
absl::Status Bitmap::CreateFromTiles(const std::vector<Bitmap> &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 gfx
|
||||||
} // namespace app
|
} // namespace app
|
||||||
} // namespace yaze
|
} // namespace yaze
|
||||||
|
|||||||
@@ -28,21 +28,27 @@ class Bitmap {
|
|||||||
void ApplyPalette(const SNESPalette &palette);
|
void ApplyPalette(const SNESPalette &palette);
|
||||||
|
|
||||||
absl::StatusOr<std::vector<Bitmap>> CreateTiles();
|
absl::StatusOr<std::vector<Bitmap>> CreateTiles();
|
||||||
|
absl::Status CreateFromTiles(const std::vector<Bitmap> &tiles);
|
||||||
|
|
||||||
int GetWidth() const { return width_; }
|
int GetWidth() const { return width_; }
|
||||||
int GetHeight() const { return height_; }
|
int GetHeight() const { return height_; }
|
||||||
auto GetData() const { return pixel_data_; }
|
auto GetData() const { return pixel_data_; }
|
||||||
auto GetTexture() const { return texture_; }
|
auto GetTexture() const { return texture_.get(); }
|
||||||
auto GetSurface() const { return surface_; }
|
auto GetSurface() const { return surface_.get(); }
|
||||||
|
|
||||||
private:
|
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 width_ = 0;
|
||||||
int height_ = 0;
|
int height_ = 0;
|
||||||
int depth_ = 0;
|
int depth_ = 0;
|
||||||
int data_size_ = 0;
|
int data_size_ = 0;
|
||||||
uchar *pixel_data_;
|
uchar *pixel_data_;
|
||||||
SDL_Surface *surface_;
|
std::shared_ptr<SDL_Texture> texture_;
|
||||||
SDL_Texture *texture_;
|
std::shared_ptr<SDL_Surface> surface_;
|
||||||
SNESPalette palette_;
|
SNESPalette palette_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user