14 : width_(width), height_(height) {}
17 const size_t total_tiles =
static_cast<size_t>((
width_ / 8) * (
height_ / 8));
18 if (
buffer_.size() != total_tiles) {
24 const size_t total_pixels =
static_cast<size_t>(
width_ *
height_);
31 const size_t total_pixels =
static_cast<size_t>(
width_ *
height_);
38 const size_t total_pixels =
static_cast<size_t>(
width_ *
height_);
60 if (x_pos < 0 || y_pos < 0) {
65 if (x_pos >= tiles_w || y_pos >= tiles_h) {
69 buffer_[y_pos * tiles_w + x_pos] = value;
75 if (x_pos < 0 || y_pos < 0 || x_pos >= tiles_w || y_pos >= tiles_h) {
78 const size_t index =
static_cast<size_t>(y_pos * tiles_w + x_pos);
119 const uint8_t keep_mask =
static_cast<uint8_t
>(~static_cast<uint8_t>(source));
126 int start_x,
int start_y,
127 int width,
int height) {
131 const uint8_t keep_mask =
static_cast<uint8_t
>(~static_cast<uint8_t>(source));
132 const int end_x = std::min(start_x + width,
width_);
133 const int end_y = std::min(start_y + height,
height_);
134 for (
int y = std::max(start_y, 0); y < end_y; ++y) {
135 for (
int x = std::max(start_x, 0); x < end_x; ++x) {
142 int start_x,
int start_y,
int width,
144 if (width <= 0 || height <= 0) {
148 const uint8_t source_mask =
static_cast<uint8_t
>(source);
149 const int end_x = std::min(start_x + width,
width_);
150 const int end_y = std::min(start_y + height,
height_);
151 for (
int y = std::max(start_y, 0); y < end_y; ++y) {
152 for (
int x = std::max(start_x, 0); x < end_x; ++x) {
184 std::vector<SDL_Color> palette(256);
186 for (
int i = 0; i < 256; i++) {
187 palette[i] = {
static_cast<Uint8
>(i),
static_cast<Uint8
>(i),
188 static_cast<Uint8
>(i), 255};
191 palette[255] = {0, 0, 0, 0};
205 const uint8_t* tiledata,
int indexoffset) {
208 constexpr int kGfxBufferSize = 0x10000;
209 constexpr int kMaxTileRow = 63;
212 int tile_col_idx = tile.
id_ % 16;
213 int tile_row_idx = tile.
id_ / 16;
216 if (tile_row_idx > kMaxTileRow) {
220 int tile_base_x = tile_col_idx * 8;
228 const uint8_t pal = tile.
palette_ & 0x07;
229 const uint8_t palette_offset =
static_cast<uint8_t
>(pal * 16);
235 uint8_t priority = tile.
over_ ? 1 : 0;
238 for (
int py = 0; py < 8; py++) {
241 for (
int px = 0; px < 8; px++) {
246 int src_index = (src_row * 128) + src_col + tile_base_x + tile_base_y;
249 if (src_index < 0 || src_index >= kGfxBufferSize)
252 uint8_t pixel = tiledata[src_index];
257 uint8_t final_color = pixel + palette_offset;
258 int dest_index = indexoffset + (py *
width_) + px;
261 if (dest_index >= 0 && dest_index < max_dest) {
262 canvas[dest_index] = final_color;
289 for (
int yy = 0; yy < tiles_h; yy++) {
290 for (
int xx = 0; xx < tiles_w; xx++) {
291 uint16_t word =
buffer_[xx + yy * tiles_w];
294 if (word == 0xFFFF) {
319 int tile_offset = (yy * 8 *
width_) + (xx * 8);
337 int tile_address,
int tile_address_floor,
338 uint8_t floor_graphics) {
342 LOG_DEBUG(
"[DrawFloor]",
"Creating bitmap: %dx%d, active=%d, width=%d",
346 LOG_DEBUG(
"[DrawFloor]",
"After Create: active=%d, width=%d, height=%d",
350 "Bitmap already exists: active=%d, width=%d, height=%d",
354 auto floor_offset =
static_cast<uint8_t
>(floor_graphics << 4);
357 gfx::TileInfo floorTile1(rom_data[tile_address + floor_offset],
358 rom_data[tile_address + floor_offset + 1]);
359 gfx::TileInfo floorTile2(rom_data[tile_address + floor_offset + 2],
360 rom_data[tile_address + floor_offset + 3]);
361 gfx::TileInfo floorTile3(rom_data[tile_address + floor_offset + 4],
362 rom_data[tile_address + floor_offset + 5]);
363 gfx::TileInfo floorTile4(rom_data[tile_address + floor_offset + 6],
364 rom_data[tile_address + floor_offset + 7]);
366 gfx::TileInfo floorTile5(rom_data[tile_address_floor + floor_offset],
367 rom_data[tile_address_floor + floor_offset + 1]);
368 gfx::TileInfo floorTile6(rom_data[tile_address_floor + floor_offset + 2],
369 rom_data[tile_address_floor + floor_offset + 3]);
370 gfx::TileInfo floorTile7(rom_data[tile_address_floor + floor_offset + 4],
371 rom_data[tile_address_floor + floor_offset + 5]);
372 gfx::TileInfo floorTile8(rom_data[tile_address_floor + floor_offset + 6],
373 rom_data[tile_address_floor + floor_offset + 7]);
388 for (
int xx = 0; xx < 16; xx++) {
389 for (
int yy = 0; yy < 32; yy++) {
391 SetTileAt((xx * 4) + 1, (yy * 2), word2);
392 SetTileAt((xx * 4) + 2, (yy * 2), word3);
393 SetTileAt((xx * 4) + 3, (yy * 2), word4);
395 SetTileAt((xx * 4), (yy * 2) + 1, word5);
396 SetTileAt((xx * 4) + 1, (yy * 2) + 1, word6);
397 SetTileAt((xx * 4) + 2, (yy * 2) + 1, word7);
398 SetTileAt((xx * 4) + 3, (yy * 2) + 1, word8);
void EnsureBG1RevealMaskAllocated()
void ClearBG1RevealMask()
void DrawTile(const TileInfo &tile_info, uint8_t *canvas, const uint8_t *tiledata, int indexoffset)
void DrawBackground(std::span< uint8_t > gfx16_data)
void SetBG1RevealMaskRect(BG1RevealMaskSource source, int start_x, int start_y, int width, int height)
std::vector< uint8_t > & mutable_bg1_reveal_mask_data()
BackgroundBuffer(int width=512, int height=512)
std::vector< uint8_t > coverage_buffer_
void SetPriorityAt(int x, int y, uint8_t priority)
std::vector< uint8_t > & mutable_priority_data()
std::vector< uint8_t > bg1_reveal_mask_buffer_
uint8_t GetPriorityAt(int x, int y) const
void SetTileAt(int x, int y, uint16_t value)
void EnsureTileBufferAllocated()
void DrawFloor(const std::vector< uint8_t > &rom_data, int tile_address, int tile_address_floor, uint8_t floor_graphics)
std::vector< uint8_t > priority_buffer_
std::vector< uint8_t > & mutable_coverage_data()
void EnsureBitmapInitialized()
void EnsureCoverageBufferAllocated()
void ClearCoverageBuffer()
void ClearBG1RevealMaskRect(BG1RevealMaskSource source, int start_x, int start_y, int width, int height)
uint16_t GetTileAt(int x, int y) const
void EnsurePriorityBufferAllocated()
void ClearPriorityBuffer()
std::vector< uint16_t > buffer_
void Create(int width, int height, int depth, std::span< uint8_t > data)
Create a bitmap with the given dimensions and data.
void SetPalette(const SnesPalette &palette)
Set the palette for the bitmap using SNES palette format.
std::vector< uint8_t > & mutable_data()
SDL_Surface * surface() const
SNES 16-bit tile metadata container.
#define LOG_DEBUG(category, format,...)
Contains classes for handling graphical data.
uint16_t TileInfoToWord(TileInfo tile_info)
TileInfo WordToTileInfo(uint16_t word)