yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
bitmap.h
Go to the documentation of this file.
1#ifndef YAZE_APP_GFX_BITMAP_H
2#define YAZE_APP_GFX_BITMAP_H
3
5
6#include <cstdint>
7#include <memory>
8#include <span>
9#include <unordered_map>
10#include <vector>
11
14
15namespace yaze {
16
21namespace gfx {
22
23class Arena;
24
25// Pixel format constants
26constexpr Uint32 SNES_PIXELFORMAT_INDEXED =
27 SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX8, 0, 0, 8, 1);
28
29constexpr Uint32 SNES_PIXELFORMAT_4BPP = SDL_DEFINE_PIXELFORMAT(
30 /*type=*/SDL_PIXELTYPE_INDEX8, /*order=*/0,
31 /*layouts=*/0, /*bits=*/4, /*bytes=*/1);
32
33constexpr Uint32 SNES_PIXELFORMAT_8BPP = SDL_DEFINE_PIXELFORMAT(
34 /*type=*/SDL_PIXELTYPE_INDEX8, /*order=*/0,
35 /*layouts=*/0, /*bits=*/8, /*bytes=*/1);
36
39 k4bpp = 1,
40 k8bpp = 2,
41 kRgba = 3, // Display output: packed R, G, B, A bytes, not ROM indices.
42};
43
70class Bitmap {
71 public:
72 Bitmap() = default;
73
83 Bitmap(int width, int height, int depth, const std::vector<uint8_t>& data);
84
93 Bitmap(int width, int height, int depth, const std::vector<uint8_t>& data,
94 const SnesPalette& palette);
95
99 Bitmap(const Bitmap& other);
100
104 Bitmap& operator=(const Bitmap& other);
105
109 Bitmap(Bitmap&& other) noexcept;
110
114 Bitmap& operator=(Bitmap&& other) noexcept;
115
119 ~Bitmap() = default;
120
124 void Create(int width, int height, int depth, std::span<uint8_t> data);
125
129 void Create(int width, int height, int depth,
130 const std::vector<uint8_t>& data);
131
135 void Create(int width, int height, int depth, int format,
136 const std::vector<uint8_t>& data);
137
141 void Reformat(int format);
142
146 void Fill(uint8_t value) {
147 std::fill(data_.begin(), data_.end(), value);
148 modified_ = true;
149 }
150
154 void CreateTexture();
155
159 void UpdateTexture();
160
167
172
201 void SetPalette(const SnesPalette& palette);
202
206 void SetPaletteWithTransparent(const SnesPalette& palette, size_t index,
207 int length = 7);
208
214 int sub_palette_index = 0);
215
219 void ApplyStoredPalette();
220
225 void UpdateSurfacePixels();
226
252 void SetPalette(const std::vector<SDL_Color>& palette);
253
257 void WriteToPixel(int position, uint8_t value);
258
265 void WriteToPixel(int x, int y, uint8_t value) {
266 if (x >= 0 && x < width_ && y >= 0 && y < height_) {
267 WriteToPixel(y * width_ + x, value);
268 }
269 }
270
277 uint8_t GetPixel(int x, int y) const {
278 if (x >= 0 && x < width_ && y >= 0 && y < height_) {
279 return data_[y * width_ + x];
280 }
281 return 0;
282 }
283
287 [[deprecated("Choose an explicit palette slot and use WriteToPixel")]]
288 void WriteColor(int position, const ImVec4& color);
289
298 void SetPixel(int x, int y, const SnesColor& color);
299
306 void Resize(int new_width, int new_height);
307
314
321 uint8_t FindColorIndex(const SnesColor& color);
322
329
339 void Get8x8Tile(int tile_index, int x, int y, std::vector<uint8_t>& tile_data,
340 int& tile_data_offset);
341
350 void Get16x16Tile(int tile_x, int tile_y, std::vector<uint8_t>& tile_data,
351 int& tile_data_offset);
352
364 enum class BitmapPurpose : uint8_t {
365 kPreview, // Read-only preview (e.g. gfx-group sheet thumbnails).
366 kEditable, // User-editable scratchpad (default).
367 kSelectionSource, // Read-only tile/region picker source.
368 kCompositeOutput, // Post-render composite (room renderer output, etc).
369 };
370
375 int source_bpp = 8; // Original bits per pixel (3, 4, 8)
376 int palette_format = 0; // 0=full palette, 1=sub-palette with transparent
377 std::string
378 source_type; // "graphics_sheet", "tilemap", "screen_buffer", "mode7"
379 int palette_colors = 256; // Expected palette size
380 // Role this bitmap plays. Optional metadata for editors that want to
381 // distinguish preview / editable / selection / composite bitmaps.
383
384 BitmapMetadata() = default;
385 BitmapMetadata(int bpp, int format, const std::string& type,
386 int colors = 256)
387 : source_bpp(bpp),
388 palette_format(format),
389 source_type(type),
390 palette_colors(colors) {}
391 };
392
393 const SnesPalette& palette() const { return palette_; }
396 const BitmapMetadata& metadata() const { return metadata_; }
397
398 int width() const { return width_; }
399 int height() const { return height_; }
400 int depth() const { return depth_; }
401 bool IsIndexed() const { return depth_ <= 8; }
402 // Read display colors without treating RGBA bytes as palette indices.
403 // Source palette rows remain on indexed sheets; composite output has none.
404 SDL_Color ReadColor(int x, int y) const;
405 std::vector<uint8_t> ToRgba() const;
406 auto size() const { return data_.size(); }
407 const uint8_t* data() const { return data_.data(); }
408 std::vector<uint8_t>& mutable_data() { return data_; }
409 SDL_Surface* surface() const { return surface_; }
410 TextureHandle texture() const { return texture_; }
411 const std::vector<uint8_t>& vector() const { return data_; }
412 uint8_t at(int i) const { return data_[i]; }
413 bool modified() const { return modified_; }
414 bool is_active() const { return active_; }
415 uint32_t generation() const { return generation_; }
416 void set_active(bool active) { active_ = active; }
417 void set_data(const std::vector<uint8_t>& data);
420
421 private:
422 friend class Arena;
423 void CopySurfaceState(const Bitmap& other);
424
425 // Arena alone may split a Bitmap's CPU and GPU resources during explicit
426 // owner retirement. Keeping these helpers private prevents ordinary callers
427 // from accidentally detaching a live bitmap.
439 active_ = false;
440 modified_ = false;
441 texture_pixels = nullptr;
443 }
444 int width_ = 0;
445 int height_ = 0;
446 int depth_ = 0;
447
448 bool active_ = false;
449 bool modified_ = false;
450
451 // Generation counter for staleness detection in deferred operations
452 // Incremented on each Create() call to detect reused/reallocated bitmaps
454 static inline uint32_t next_generation_ = 1;
455
456 // Pointer to the texture pixels
457 void* texture_pixels = nullptr;
458
459 // Pointer to the pixel data
461
477
478 // Metadata for tracking source format and palette requirements
480
481 // Packed rows: one byte per indexed pixel, or four RGBA bytes per pixel.
482 std::vector<uint8_t> data_;
483
508
509 // Texture for the bitmap (managed by Arena)
511
512 // Optimized palette lookup cache for O(1) color index lookups
513 std::unordered_map<uint32_t, uint8_t> color_to_index_cache_;
514
515 // Dirty region tracking for efficient texture updates
516 struct DirtyRegion {
517 int min_x = 0, min_y = 0, max_x = 0, max_y = 0;
518 bool is_dirty = false;
519
520 void Reset() {
521 min_x = min_y = max_x = max_y = 0;
522 is_dirty = false;
523 }
524
525 void AddPoint(int x, int y) {
526 if (!is_dirty) {
527 min_x = max_x = x;
528 min_y = max_y = y;
529 is_dirty = true;
530 } else {
531 min_x = std::min(min_x, x);
532 min_y = std::min(min_y, y);
533 max_x = std::max(max_x, x);
534 max_y = std::max(max_y, y);
535 }
536 }
538
544 static uint32_t HashColor(const ImVec4& color);
545};
546
547// Type alias for a table of bitmaps - uses unique_ptr for stable pointers
548// across rehashes (prevents dangling pointers in deferred texture commands)
549using BitmapTable = std::unordered_map<int, std::unique_ptr<gfx::Bitmap>>;
550
554Uint32 GetSnesPixelFormat(int format);
555
556} // namespace gfx
557} // namespace yaze
558
559#endif // YAZE_APP_GFX_BITMAP_H
Resource management arena for efficient graphics memory handling.
Definition arena.h:47
Represents a bitmap image optimized for SNES ROM hacking.
Definition bitmap.h:70
const uint8_t * data() const
Definition bitmap.h:407
void set_texture(TextureHandle texture)
Definition bitmap.h:419
const SnesPalette & palette() const
Definition bitmap.h:393
SDL_Surface * surface_
SDL surface for rendering (contains the authoritative palette)
Definition bitmap.h:507
Bitmap & operator=(const Bitmap &other)
Copy assignment operator.
Definition bitmap.cc:88
void WriteToPixel(int position, uint8_t value)
Write a value to a pixel at the given position.
Definition bitmap.cc:649
SDL_Surface * DetachSurfaceForArena() noexcept
Definition bitmap.h:428
void Create(int width, int height, int depth, std::span< uint8_t > data)
Create a bitmap with the given dimensions and data.
Definition bitmap.cc:198
TextureHandle texture() const
Definition bitmap.h:410
~Bitmap()=default
Destructor.
BitmapPurpose
How a bitmap is used in the editor pipeline.
Definition bitmap.h:364
bool ValidateDataSurfaceSync()
Validate that bitmap data and surface pixels are synchronized.
Definition bitmap.cc:916
const std::vector< uint8_t > & vector() const
Definition bitmap.h:411
auto size() const
Definition bitmap.h:406
void UpdateSurfacePixels()
Update SDL surface with current pixel data from data_ vector Call this after modifying pixel data via...
Definition bitmap.cc:373
std::unordered_map< uint32_t, uint8_t > color_to_index_cache_
Definition bitmap.h:513
void Reformat(int format)
Reformat the bitmap to use a different pixel format.
Definition bitmap.cc:280
void WriteToPixel(int x, int y, uint8_t value)
Write a palette index to a pixel at the given x,y coordinates.
Definition bitmap.h:265
bool IsIndexed() const
Definition bitmap.h:401
uint8_t * pixel_data_
Definition bitmap.h:460
const BitmapMetadata & metadata() const
Definition bitmap.h:396
static uint32_t HashColor(const ImVec4 &color)
Hash a color for cache lookup.
Definition bitmap.cc:852
void CopySurfaceState(const Bitmap &other)
Definition bitmap.cc:391
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)
Definition bitmap.cc:716
BitmapMetadata & metadata()
Definition bitmap.h:395
void CreateTexture()
Creates the underlying SDL_Texture to be displayed.
Definition bitmap.cc:297
bool is_active() const
Definition bitmap.h:414
uint32_t generation_
Definition bitmap.h:453
SnesPalette * mutable_palette()
Definition bitmap.h:394
void QueueTextureUpdate(IRenderer *renderer)
Queue texture update for batch processing (improved performance)
void set_modified(bool modified)
Definition bitmap.h:418
void set_active(bool active)
Definition bitmap.h:416
void WriteColor(int position, const ImVec4 &color)
Write a color to a pixel at the given position.
Definition bitmap.cc:705
int height() const
Definition bitmap.h:399
void set_data(const std::vector< uint8_t > &data)
Definition bitmap.cc:901
uint8_t at(int i) const
Definition bitmap.h:412
void Resize(int new_width, int new_height)
Resize the bitmap to new dimensions (preserves existing data)
Definition bitmap.cc:798
static uint32_t next_generation_
Definition bitmap.h:454
void Fill(uint8_t value)
Fill the bitmap with a specific value.
Definition bitmap.h:146
void SetPixel(int x, int y, const SnesColor &color)
Set a pixel at the given x,y coordinates with SNES color.
Definition bitmap.cc:766
void SetPalette(const SnesPalette &palette)
Set the palette for the bitmap using SNES palette format.
Definition bitmap.cc:452
int width() const
Definition bitmap.h:398
BitmapMetadata metadata_
Definition bitmap.h:479
SDL_Color ReadColor(int x, int y) const
Definition bitmap.cc:414
void ApplyStoredPalette()
Apply the stored palette to the surface (internal helper)
Definition bitmap.cc:321
std::vector< uint8_t > data_
Definition bitmap.h:482
int depth() const
Definition bitmap.h:400
void InvalidatePaletteCache()
Invalidate the palette lookup cache (call when palette changes)
Definition bitmap.cc:873
uint32_t generation() const
Definition bitmap.h:415
uint8_t GetPixel(int x, int y) const
Get the palette index at the given x,y coordinates.
Definition bitmap.h:277
void SetPaletteWithTransparent(const SnesPalette &palette, size_t index, int length=7)
Set the palette with a transparent color.
Definition bitmap.cc:524
std::vector< uint8_t > & mutable_data()
Definition bitmap.h:408
struct yaze::gfx::Bitmap::DirtyRegion dirty_region_
void * texture_pixels
Definition bitmap.h:457
void ApplyPaletteByMetadata(const SnesPalette &palette, int sub_palette_index=0)
Apply palette using metadata-driven strategy Chooses between SetPalette and SetPaletteWithTransparent...
Definition bitmap.cc:480
TextureHandle texture_
Definition bitmap.h:510
TextureHandle DetachTextureForArena() noexcept
Definition bitmap.h:433
SDL_Surface * surface() const
Definition bitmap.h:409
void MarkRetiredByArena() noexcept
Definition bitmap.h:438
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)
Definition bitmap.cc:732
uint8_t FindColorIndex(const SnesColor &color)
Find color index in palette using optimized hash map lookup.
Definition bitmap.cc:894
void UpdateTexture()
Updates the underlying SDL_Texture when it already exists.
Definition bitmap.cc:301
bool modified() const
Definition bitmap.h:413
gfx::SnesPalette palette_
Internal SNES palette storage (may be empty!)
Definition bitmap.h:476
void UpdateTextureData()
Updates the texture data from the surface.
std::vector< uint8_t > ToRgba() const
Definition bitmap.cc:435
Defines an abstract interface for all rendering operations.
Definition irenderer.h:60
SNES Color container.
Definition snes_color.h:110
Represents a palette of colors for the Super Nintendo Entertainment System (SNES).
BitmapFormat
Definition bitmap.h:37
@ kRgba
Definition bitmap.h:41
@ kIndexed
Definition bitmap.h:38
@ k8bpp
Definition bitmap.h:40
@ k4bpp
Definition bitmap.h:39
std::unordered_map< int, std::unique_ptr< gfx::Bitmap > > BitmapTable
Definition bitmap.h:549
constexpr Uint32 SNES_PIXELFORMAT_8BPP
Definition bitmap.h:33
constexpr Uint32 SNES_PIXELFORMAT_INDEXED
Definition bitmap.h:26
void * TextureHandle
An abstract handle representing a texture.
Definition irenderer.h:47
constexpr Uint32 SNES_PIXELFORMAT_4BPP
Definition bitmap.h:29
Uint32 GetSnesPixelFormat(int format)
Convert bitmap format enum to SDL pixel format.
Definition bitmap.cc:33
SDL2/SDL3 compatibility layer.
Metadata for tracking bitmap source format and palette requirements.
Definition bitmap.h:374
BitmapMetadata(int bpp, int format, const std::string &type, int colors=256)
Definition bitmap.h:385
void AddPoint(int x, int y)
Definition bitmap.h:525