21 using std::runtime_error::runtime_error;
37 return SDL_PIXELFORMAT_INDEX8;
43 return SDL_PIXELFORMAT_INDEX8;
48 const std::vector<uint8_t> &data)
49 : width_(width), height_(height), depth_(depth), data_(data) {
54 const std::vector<uint8_t> &data,
const SnesPalette &palette)
65 : width_(other.width_),
66 height_(other.height_),
68 active_(other.active_),
69 modified_(other.modified_),
70 palette_(other.palette_),
111 : width_(other.width_),
112 height_(other.height_),
113 depth_(other.depth_),
114 active_(other.active_),
115 modified_(other.modified_),
116 texture_pixels(other.texture_pixels),
117 pixel_data_(other.pixel_data_),
118 palette_(std::move(other.palette_)),
119 data_(std::move(other.data_)),
120 surface_(other.surface_),
121 texture_(other.texture_) {
126 other.active_ =
false;
127 other.modified_ =
false;
128 other.texture_pixels =
nullptr;
129 other.pixel_data_ =
nullptr;
130 other.surface_ =
nullptr;
131 other.texture_ =
nullptr;
135 if (
this != &other) {
137 height_ = other.height_;
138 depth_ = other.depth_;
139 active_ = other.active_;
140 modified_ = other.modified_;
141 texture_pixels = other.texture_pixels;
142 pixel_data_ = other.pixel_data_;
143 palette_ = std::move(other.palette_);
144 data_ = std::move(other.data_);
145 surface_ = other.surface_;
146 texture_ = other.texture_;
152 other.active_ =
false;
153 other.modified_ =
false;
154 other.texture_pixels =
nullptr;
155 other.pixel_data_ =
nullptr;
156 other.surface_ =
nullptr;
157 other.texture_ =
nullptr;
168 const std::vector<uint8_t> &data) {
187 const std::vector<uint8_t> &data) {
189 SDL_Log(
"Bitmap data is empty\n");
198 SDL_Log(
"Data provided to Bitmap is empty.\n");
207 SDL_Log(
"Bitmap::Create.SDL_CreateRGBSurfaceWithFormat failed: %s\n",
286 SDL_Log(
"Warning: Bitmap surface has no palette (non-indexed format?)\n");
415 throw std::invalid_argument(
"Invalid palette index");
419 throw std::invalid_argument(
"Invalid palette length (must be 0-7 for SNES palettes)");
423 throw std::invalid_argument(
"Palette index + length exceeds size");
427 std::vector<ImVec4> colors;
430 colors.push_back(
ImVec4(0, 0, 0, 0));
434 for (
size_t i = 0; i < 7 && (index + i) <
palette.
size(); ++i) {
444 while (colors.size() < 8) {
445 colors.push_back(
ImVec4(0, 0, 0, 1.0f));
455 surface_->format->palette->colors[color_index].r =
static_cast<Uint8>(colors[color_index].x * 255.0f);
456 surface_->format->palette->colors[color_index].g =
static_cast<Uint8>(colors[color_index].y * 255.0f);
457 surface_->format->palette->colors[color_index].b =
static_cast<Uint8>(colors[color_index].z * 255.0f);
458 surface_->format->palette->colors[color_index].a =
static_cast<Uint8>(colors[color_index].w * 255.0f);
478 SDL_Log(
"ERROR: WriteToPixel - position %d out of bounds (size: %zu)",
479 position,
data_.size());
485 SDL_Log(
"ERROR: WriteToPixel - bitmap not active or data empty (active=%s, size=%zu)",
496 SDL_Log(
"ERROR: WriteToPixel - surface or pixels are null (surface=%p, pixels=%p)",
503 SDL_Log(
"ERROR: WriteToPixel - pixel_data_ is null after assignment");
508 data_[position] = value;
567 std::vector<uint8_t> &tile_data,
568 int &tile_data_offset) {
572 for (
int i = 0; i < 8; i++) {
573 for (
int j = 0;
j < 8;
j++) {
583 std::vector<uint8_t> &tile_data,
584 int &tile_data_offset) {
585 for (
int ty = 0;
ty < 16;
ty++) {
586 for (
int tx = 0;
tx < 16;
tx++) {
622 int position = y *
width_ + x;
623 if (position >= 0 && position <
static_cast<int>(
data_.size())) {
625 data_[position] = color_index;
653 if (!
data_.empty()) {
703 return (r << 24) | (g << 16) | (b << 8) |
a;
746 SDL_Log(
"Warning: set_data called with empty data vector");
765 SDL_Log(
"ValidateDataSurfaceSync: surface or data is null/empty");
771 size_t data_size =
data_.size();
775 SDL_Log(
"ValidateDataSurfaceSync: invalid sizes - surface: %zu, data: %zu",
782 SDL_Log(
"ValidateDataSurfaceSync: data and surface are not synchronized");
SDL_Surface * AllocateSurface(int width, int height, int depth, int format)
void QueueTextureCommand(TextureCommandType type, Bitmap *bitmap)
Represents a bitmap image optimized for SNES ROM hacking.
const uint8_t * data() const
const SnesPalette & palette() const
Bitmap & operator=(const Bitmap &other)
Copy assignment operator.
void WriteToPixel(int position, uint8_t value)
Write a value to a pixel at the given position.
void Create(int width, int height, int depth, std::span< uint8_t > data)
Create a bitmap with the given dimensions and data.
bool ValidateDataSurfaceSync()
Validate that bitmap data and surface pixels are synchronized.
const std::vector< uint8_t > & vector() const
void UpdateSurfacePixels()
Update SDL surface with current pixel data from data_ vector Call this after modifying pixel data via...
std::unordered_map< uint32_t, uint8_t > color_to_index_cache_
void Reformat(int format)
Reformat the bitmap to use a different pixel format.
static uint32_t HashColor(const ImVec4 &color)
Hash a color for cache lookup.
void Get8x8Tile(int tile_index, int x, int y, std::vector< uint8_t > &tile_data, int &tile_data_offset)
Extract an 8x8 tile from the bitmap (SNES standard tile size)
void CreateTexture()
Creates the underlying SDL_Texture to be displayed.
void WriteColor(int position, const ImVec4 &color)
Write a color to a pixel at the given position.
void set_data(const std::vector< uint8_t > &data)
void Resize(int new_width, int new_height)
Resize the bitmap to new dimensions (preserves existing data)
void SetPixel(int x, int y, const SnesColor &color)
Set a pixel at the given x,y coordinates with SNES color.
void SetPalette(const SnesPalette &palette)
Set the palette for the bitmap.
void ApplyStoredPalette()
Apply the stored palette to the surface (internal helper)
std::vector< uint8_t > data_
void InvalidatePaletteCache()
Invalidate the palette lookup cache (call when palette changes)
void SetPaletteWithTransparent(const SnesPalette &palette, size_t index, int length=7)
Set the palette with a transparent color.
struct yaze::gfx::Bitmap::DirtyRegion dirty_region_
void ApplyPaletteByMetadata(const SnesPalette &palette, int sub_palette_index=0)
Apply palette using metadata-driven strategy Chooses between SetPalette and SetPaletteWithTransparent...
void Get16x16Tile(int tile_x, int tile_y, std::vector< uint8_t > &tile_data, int &tile_data_offset)
Extract a 16x16 tile from the bitmap (SNES metatile size)
uint8_t FindColorIndex(const SnesColor &color)
Find color index in palette using optimized hash map lookup.
void UpdateTexture()
Updates the underlying SDL_Texture when it already exists.
gfx::SnesPalette palette_
RAII timer for automatic timing management.
constexpr ImVec4 rgb() const
Get RGB values (WARNING: stored as 0-255 in ImVec4)
Represents a palette of colors for the Super Nintendo Entertainment System (SNES).
uint16_t ConvertRgbToSnes(const snes_color &color)
Convert RGB (0-255) to SNES 15-bit color.
constexpr Uint32 SNES_PIXELFORMAT_8BPP
constexpr Uint32 SNES_PIXELFORMAT_4BPP
Uint32 GetSnesPixelFormat(int format)
Convert bitmap format enum to SDL pixel format.
Main namespace for the application.
void AddPoint(int x, int y)