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};
42
69class Bitmap {
70 public:
71 Bitmap() = default;
72
82 Bitmap(int width, int height, int depth, const std::vector<uint8_t>& data);
83
92 Bitmap(int width, int height, int depth, const std::vector<uint8_t>& data,
93 const SnesPalette& palette);
94
98 Bitmap(const Bitmap& other);
99
103 Bitmap& operator=(const Bitmap& other);
104
108 Bitmap(Bitmap&& other) noexcept;
109
113 Bitmap& operator=(Bitmap&& other) noexcept;
114
118 ~Bitmap() = default;
119
123 void Create(int width, int height, int depth, std::span<uint8_t> data);
124
128 void Create(int width, int height, int depth,
129 const std::vector<uint8_t>& data);
130
134 void Create(int width, int height, int depth, int format,
135 const std::vector<uint8_t>& data);
136
140 void Reformat(int format);
141
145 void Fill(uint8_t value) {
146 std::fill(data_.begin(), data_.end(), value);
147 modified_ = true;
148 }
149
153 void CreateTexture();
154
158 void UpdateTexture();
159
166
171
200 void SetPalette(const SnesPalette& palette);
201
205 void SetPaletteWithTransparent(const SnesPalette& palette, size_t index,
206 int length = 7);
207
213 int sub_palette_index = 0);
214
218 void ApplyStoredPalette();
219
224 void UpdateSurfacePixels();
225
251 void SetPalette(const std::vector<SDL_Color>& palette);
252
256 void WriteToPixel(int position, uint8_t value);
257
264 void WriteToPixel(int x, int y, uint8_t value) {
265 if (x >= 0 && x < width_ && y >= 0 && y < height_) {
266 WriteToPixel(y * width_ + x, value);
267 }
268 }
269
276 uint8_t GetPixel(int x, int y) const {
277 if (x >= 0 && x < width_ && y >= 0 && y < height_) {
278 return data_[y * width_ + x];
279 }
280 return 0;
281 }
282
286 void WriteColor(int position, const ImVec4& color);
287
296 void SetPixel(int x, int y, const SnesColor& color);
297
304 void Resize(int new_width, int new_height);
305
312
319 uint8_t FindColorIndex(const SnesColor& color);
320
327
337 void Get8x8Tile(int tile_index, int x, int y, std::vector<uint8_t>& tile_data,
338 int& tile_data_offset);
339
348 void Get16x16Tile(int tile_x, int tile_y, std::vector<uint8_t>& tile_data,
349 int& tile_data_offset);
350
362 enum class BitmapPurpose : uint8_t {
363 kPreview, // Read-only preview (e.g. gfx-group sheet thumbnails).
364 kEditable, // User-editable scratchpad (default).
365 kSelectionSource, // Read-only tile/region picker source.
366 kCompositeOutput, // Post-render composite (room renderer output, etc).
367 };
368
373 int source_bpp = 8; // Original bits per pixel (3, 4, 8)
374 int palette_format = 0; // 0=full palette, 1=sub-palette with transparent
375 std::string
376 source_type; // "graphics_sheet", "tilemap", "screen_buffer", "mode7"
377 int palette_colors = 256; // Expected palette size
378 // Role this bitmap plays. Optional metadata for editors that want to
379 // distinguish preview / editable / selection / composite bitmaps.
381
382 BitmapMetadata() = default;
383 BitmapMetadata(int bpp, int format, const std::string& type,
384 int colors = 256)
385 : source_bpp(bpp),
386 palette_format(format),
387 source_type(type),
388 palette_colors(colors) {}
389 };
390
391 const SnesPalette& palette() const { return palette_; }
394 const BitmapMetadata& metadata() const { return metadata_; }
395
396 int width() const { return width_; }
397 int height() const { return height_; }
398 int depth() const { return depth_; }
399 auto size() const { return data_.size(); }
400 const uint8_t* data() const { return data_.data(); }
401 std::vector<uint8_t>& mutable_data() { return data_; }
402 SDL_Surface* surface() const { return surface_; }
403 TextureHandle texture() const { return texture_; }
404 const std::vector<uint8_t>& vector() const { return data_; }
405 uint8_t at(int i) const { return data_[i]; }
406 bool modified() const { return modified_; }
407 bool is_active() const { return active_; }
408 uint32_t generation() const { return generation_; }
409 void set_active(bool active) { active_ = active; }
410 void set_data(const std::vector<uint8_t>& data);
413
414 private:
415 friend class Arena;
416
417 // Arena alone may split a Bitmap's CPU and GPU resources during explicit
418 // owner retirement. Keeping these helpers private prevents ordinary callers
419 // from accidentally detaching a live bitmap.
431 active_ = false;
432 modified_ = false;
433 texture_pixels = nullptr;
435 }
436 int width_ = 0;
437 int height_ = 0;
438 int depth_ = 0;
439
440 bool active_ = false;
441 bool modified_ = false;
442
443 // Generation counter for staleness detection in deferred operations
444 // Incremented on each Create() call to detect reused/reallocated bitmaps
446 static inline uint32_t next_generation_ = 1;
447
448 // Pointer to the texture pixels
449 void* texture_pixels = nullptr;
450
451 // Pointer to the pixel data
453
469
470 // Metadata for tracking source format and palette requirements
472
473 // Data for the bitmap (indexed pixel values, 0-255)
474 std::vector<uint8_t> data_;
475
500
501 // Texture for the bitmap (managed by Arena)
503
504 // Optimized palette lookup cache for O(1) color index lookups
505 std::unordered_map<uint32_t, uint8_t> color_to_index_cache_;
506
507 // Dirty region tracking for efficient texture updates
508 struct DirtyRegion {
509 int min_x = 0, min_y = 0, max_x = 0, max_y = 0;
510 bool is_dirty = false;
511
512 void Reset() {
513 min_x = min_y = max_x = max_y = 0;
514 is_dirty = false;
515 }
516
517 void AddPoint(int x, int y) {
518 if (!is_dirty) {
519 min_x = max_x = x;
520 min_y = max_y = y;
521 is_dirty = true;
522 } else {
523 min_x = std::min(min_x, x);
524 min_y = std::min(min_y, y);
525 max_x = std::max(max_x, x);
526 max_y = std::max(max_y, y);
527 }
528 }
530
536 static uint32_t HashColor(const ImVec4& color);
537};
538
539// Type alias for a table of bitmaps - uses unique_ptr for stable pointers
540// across rehashes (prevents dangling pointers in deferred texture commands)
541using BitmapTable = std::unordered_map<int, std::unique_ptr<gfx::Bitmap>>;
542
546Uint32 GetSnesPixelFormat(int format);
547
548} // namespace gfx
549} // namespace yaze
550
551#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:69
const uint8_t * data() const
Definition bitmap.h:400
void set_texture(TextureHandle texture)
Definition bitmap.h:412
const SnesPalette & palette() const
Definition bitmap.h:391
SDL_Surface * surface_
SDL surface for rendering (contains the authoritative palette)
Definition bitmap.h:499
Bitmap & operator=(const Bitmap &other)
Copy assignment operator.
Definition bitmap.cc:90
void WriteToPixel(int position, uint8_t value)
Write a value to a pixel at the given position.
Definition bitmap.cc:592
SDL_Surface * DetachSurfaceForArena() noexcept
Definition bitmap.h:420
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:202
TextureHandle texture() const
Definition bitmap.h:403
~Bitmap()=default
Destructor.
BitmapPurpose
How a bitmap is used in the editor pipeline.
Definition bitmap.h:362
bool ValidateDataSurfaceSync()
Validate that bitmap data and surface pixels are synchronized.
Definition bitmap.cc:885
const std::vector< uint8_t > & vector() const
Definition bitmap.h:404
auto size() const
Definition bitmap.h:399
void UpdateSurfacePixels()
Update SDL surface with current pixel data from data_ vector Call this after modifying pixel data via...
Definition bitmap.cc:379
std::unordered_map< uint32_t, uint8_t > color_to_index_cache_
Definition bitmap.h:505
void Reformat(int format)
Reformat the bitmap to use a different pixel format.
Definition bitmap.cc:286
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:264
uint8_t * pixel_data_
Definition bitmap.h:452
const BitmapMetadata & metadata() const
Definition bitmap.h:394
static uint32_t HashColor(const ImVec4 &color)
Hash a color for cache lookup.
Definition bitmap.cc:815
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:687
BitmapMetadata & metadata()
Definition bitmap.h:393
void CreateTexture()
Creates the underlying SDL_Texture to be displayed.
Definition bitmap.cc:303
bool is_active() const
Definition bitmap.h:407
uint32_t generation_
Definition bitmap.h:445
SnesPalette * mutable_palette()
Definition bitmap.h:392
void QueueTextureUpdate(IRenderer *renderer)
Queue texture update for batch processing (improved performance)
void set_modified(bool modified)
Definition bitmap.h:411
void set_active(bool active)
Definition bitmap.h:409
void WriteColor(int position, const ImVec4 &color)
Write a color to a pixel at the given position.
Definition bitmap.cc:643
int height() const
Definition bitmap.h:397
void set_data(const std::vector< uint8_t > &data)
Definition bitmap.cc:864
uint8_t at(int i) const
Definition bitmap.h:405
void Resize(int new_width, int new_height)
Resize the bitmap to new dimensions (preserves existing data)
Definition bitmap.cc:765
static uint32_t next_generation_
Definition bitmap.h:446
void Fill(uint8_t value)
Fill the bitmap with a specific value.
Definition bitmap.h:145
void SetPixel(int x, int y, const SnesColor &color)
Set a pixel at the given x,y coordinates with SNES color.
Definition bitmap.cc:737
void SetPalette(const SnesPalette &palette)
Set the palette for the bitmap using SNES palette format.
Definition bitmap.cc:394
int width() const
Definition bitmap.h:396
BitmapMetadata metadata_
Definition bitmap.h:471
void ApplyStoredPalette()
Apply the stored palette to the surface (internal helper)
Definition bitmap.cc:327
std::vector< uint8_t > data_
Definition bitmap.h:474
int depth() const
Definition bitmap.h:398
void InvalidatePaletteCache()
Invalidate the palette lookup cache (call when palette changes)
Definition bitmap.cc:836
uint32_t generation() const
Definition bitmap.h:408
uint8_t GetPixel(int x, int y) const
Get the palette index at the given x,y coordinates.
Definition bitmap.h:276
void SetPaletteWithTransparent(const SnesPalette &palette, size_t index, int length=7)
Set the palette with a transparent color.
Definition bitmap.cc:466
std::vector< uint8_t > & mutable_data()
Definition bitmap.h:401
struct yaze::gfx::Bitmap::DirtyRegion dirty_region_
void * texture_pixels
Definition bitmap.h:449
void ApplyPaletteByMetadata(const SnesPalette &palette, int sub_palette_index=0)
Apply palette using metadata-driven strategy Chooses between SetPalette and SetPaletteWithTransparent...
Definition bitmap.cc:422
TextureHandle texture_
Definition bitmap.h:502
TextureHandle DetachTextureForArena() noexcept
Definition bitmap.h:425
SDL_Surface * surface() const
Definition bitmap.h:402
void MarkRetiredByArena() noexcept
Definition bitmap.h:430
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:703
uint8_t FindColorIndex(const SnesColor &color)
Find color index in palette using optimized hash map lookup.
Definition bitmap.cc:857
void UpdateTexture()
Updates the underlying SDL_Texture when it already exists.
Definition bitmap.cc:307
bool modified() const
Definition bitmap.h:406
gfx::SnesPalette palette_
Internal SNES palette storage (may be empty!)
Definition bitmap.h:468
void UpdateTextureData()
Updates the texture data from the surface.
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
@ 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:541
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:372
BitmapMetadata(int bpp, int format, const std::string &type, int colors=256)
Definition bitmap.h:383
void AddPoint(int x, int y)
Definition bitmap.h:517