From 120eb544bf37d37f5e8e438ebb36de61311f75a1 Mon Sep 17 00:00:00 2001 From: scawful Date: Thu, 15 May 2025 22:40:54 -0400 Subject: [PATCH] Add 16x16 tile rendering and modification functions - Introduced RenderTile16 and UpdateTile16 functions for rendering and updating 16x16 tiles in the Tilemap. - Added ModifyTile16 function to facilitate the composition and placement of tile parts within the Tilemap. - Updated Tilemap structure to include a vector for storing tile information. - Refactored related functions to enhance tile handling and rendering capabilities. --- src/app/gfx/tilemap.cc | 61 ++++++++++++++++++++++++++++++++++++++-- src/app/gfx/tilemap.h | 14 ++++++++- src/app/gfx/tilesheet.cc | 34 ---------------------- src/app/gfx/tilesheet.h | 4 --- 4 files changed, 71 insertions(+), 42 deletions(-) diff --git a/src/app/gfx/tilemap.cc b/src/app/gfx/tilemap.cc index 1e46902a..f067b71a 100644 --- a/src/app/gfx/tilemap.cc +++ b/src/app/gfx/tilemap.cc @@ -4,6 +4,7 @@ #include "app/core/platform/renderer.h" #include "app/gfx/bitmap.h" +#include "app/gfx/snes_tile.h" namespace yaze { namespace gfx { @@ -38,7 +39,34 @@ void RenderTile(Tilemap &tilemap, int tile_id) { } } -namespace { +void RenderTile16(Tilemap &tilemap, int tile_id) { + if (tilemap.tile_bitmaps.find(tile_id) == tilemap.tile_bitmaps.end()) { + int tiles_per_row = tilemap.atlas.width() / tilemap.tile_size.x; + int tile_x = (tile_id % tiles_per_row) * tilemap.tile_size.x; + int tile_y = (tile_id / tiles_per_row) * tilemap.tile_size.y; + std::vector tile_data(tilemap.tile_size.x * tilemap.tile_size.y, + 0x00); + int tile_data_offset = 0; + tilemap.atlas.Get16x16Tile(tile_x, tile_y, tile_data, tile_data_offset); + tilemap.tile_bitmaps[tile_id] = + Bitmap(tilemap.tile_size.x, tilemap.tile_size.y, 8, tile_data, + tilemap.atlas.palette()); + auto bitmap_ptr = &tilemap.tile_bitmaps[tile_id]; + core::Renderer::Get().RenderBitmap(bitmap_ptr); + } +} + +void UpdateTile16(Tilemap &tilemap, int tile_id) { + int tiles_per_row = tilemap.atlas.width() / tilemap.tile_size.x; + int tile_x = (tile_id % tiles_per_row) * tilemap.tile_size.x; + int tile_y = (tile_id / tiles_per_row) * tilemap.tile_size.y; + std::vector tile_data(tilemap.tile_size.x * tilemap.tile_size.y, + 0x00); + int tile_data_offset = 0; + tilemap.atlas.Get16x16Tile(tile_x, tile_y, tile_data, tile_data_offset); + tilemap.tile_bitmaps[tile_id].set_data(tile_data); + core::Renderer::Get().UpdateBitmap(&tilemap.tile_bitmaps[tile_id]); +} std::vector FetchTileDataFromGraphicsBuffer( const std::vector &data, int tile_id, int sheet_offset) { @@ -72,6 +100,8 @@ std::vector FetchTileDataFromGraphicsBuffer( return tile_data; } +namespace { + void MirrorTileDataVertically(std::vector &tile_data) { for (int y = 0; y < 4; ++y) { for (int x = 0; x < 8; ++x) { @@ -113,11 +143,35 @@ void ComposeAndPlaceTilePart(Tilemap &tilemap, const std::vector &data, } } // namespace +void ModifyTile16(Tilemap &tilemap, const std::vector &data, + const TileInfo &top_left, const TileInfo &top_right, + const TileInfo &bottom_left, const TileInfo &bottom_right, + int sheet_offset, int tile_id) { + // Calculate the base position for this Tile16 in the full-size bitmap + int tiles_per_row = tilemap.atlas.width() / tilemap.tile_size.x; + int tile16_row = tile_id / tiles_per_row; + int tile16_column = tile_id % tiles_per_row; + int base_x = tile16_column * tilemap.tile_size.x; + int base_y = tile16_row * tilemap.tile_size.y; + + // Compose and place each part of the Tile16 + ComposeAndPlaceTilePart(tilemap, data, top_left, base_x, base_y, + sheet_offset); + ComposeAndPlaceTilePart(tilemap, data, top_right, base_x + 8, base_y, + sheet_offset); + ComposeAndPlaceTilePart(tilemap, data, bottom_left, base_x, base_y + 8, + sheet_offset); + ComposeAndPlaceTilePart(tilemap, data, bottom_right, base_x + 8, base_y + 8, + sheet_offset); + + tilemap.tile_info[tile_id] = {top_left, top_right, bottom_left, bottom_right}; +} + void ComposeTile16(Tilemap &tilemap, const std::vector &data, const TileInfo &top_left, const TileInfo &top_right, const TileInfo &bottom_left, const TileInfo &bottom_right, int sheet_offset) { - int num_tiles = tilemap.tile_bitmaps.size(); + int num_tiles = tilemap.tile_info.size(); int tiles_per_row = tilemap.atlas.width() / tilemap.tile_size.x; int tile16_row = num_tiles / tiles_per_row; int tile16_column = num_tiles % tiles_per_row; @@ -132,12 +186,13 @@ void ComposeTile16(Tilemap &tilemap, const std::vector &data, sheet_offset); ComposeAndPlaceTilePart(tilemap, data, bottom_right, base_x + 8, base_y + 8, sheet_offset); + + tilemap.tile_info.push_back({top_left, top_right, bottom_left, bottom_right}); } std::vector GetTilemapData(Tilemap &tilemap, int tile_id) { int tile_size = tilemap.tile_size.x; std::vector data(tile_size * tile_size); - int num_tiles = tilemap.map_size.x; int index = tile_id * tile_size * tile_size; int width = tilemap.atlas.width(); diff --git a/src/app/gfx/tilemap.h b/src/app/gfx/tilemap.h index 6e285704..0ad23ffe 100644 --- a/src/app/gfx/tilemap.h +++ b/src/app/gfx/tilemap.h @@ -1,9 +1,9 @@ #ifndef YAZE_GFX_TILEMAP_H #define YAZE_GFX_TILEMAP_H +#include "absl/container/flat_hash_map.h" #include "app/gfx/bitmap.h" #include "app/gfx/snes_tile.h" -#include "absl/container/flat_hash_map.h" namespace yaze { namespace gfx { @@ -16,10 +16,14 @@ struct Pair { struct Tilemap { Bitmap atlas; absl::flat_hash_map tile_bitmaps; + std::vector> tile_info; Pair tile_size; Pair map_size; }; +std::vector FetchTileDataFromGraphicsBuffer( + const std::vector &data, int tile_id, int sheet_offset); + Tilemap CreateTilemap(std::vector &data, int width, int height, int tile_size, int num_tiles, SnesPalette &palette); @@ -27,6 +31,14 @@ void UpdateTilemap(Tilemap &tilemap, const std::vector &data); void RenderTile(Tilemap &tilemap, int tile_id); +void RenderTile16(Tilemap &tilemap, int tile_id); +void UpdateTile16(Tilemap &tilemap, int tile_id); + +void ModifyTile16(Tilemap &tilemap, const std::vector &data, + const TileInfo &top_left, const TileInfo &top_right, + const TileInfo &bottom_left, const TileInfo &bottom_right, + int sheet_offset, int tile_id); + void ComposeTile16(Tilemap &tilemap, const std::vector &data, const TileInfo &top_left, const TileInfo &top_right, const TileInfo &bottom_left, const TileInfo &bottom_right, diff --git a/src/app/gfx/tilesheet.cc b/src/app/gfx/tilesheet.cc index 7efa5a00..c708c859 100644 --- a/src/app/gfx/tilesheet.cc +++ b/src/app/gfx/tilesheet.cc @@ -9,40 +9,6 @@ namespace yaze { namespace gfx { -absl::StatusOr CreateTilesheetFromGraphicsBuffer( - const uint8_t* graphics_buffer, int width, int height, TileType tile_type, - int sheet_id) { - Tilesheet tilesheet; - - // Calculate the offset in the graphics buffer based on the sheet ID - int sheet_offset = sheet_id * width * height; - - // Initialize the tilesheet with the specified width, height, and tile type - tilesheet.Init(width, height, tile_type); - - // Iterate over the tiles in the sheet and copy them into the tilesheet - for (int row = 0; row < height; ++row) { - for (int col = 0; col < width; ++col) { - // Calculate the index of the current tile in the graphics buffer - int tile_index = sheet_offset + (row * width + col) * 64; - - // Copy the tile data into the tilesheet - for (int y = 0; y < 8; ++y) { - for (int x = 0; x < 8; ++x) { - int src_index = tile_index + (y * 8 + x); - int dest_x = col * 8 + x; - int dest_y = row * 8 + y; - int dest_index = (dest_y * width * 8) + dest_x; - tilesheet.mutable_bitmap()->mutable_data()[dest_index] = - graphics_buffer[src_index]; - } - } - } - } - - return tilesheet; -} - void Tilesheet::Init(int width, int height, TileType tile_type) { internal_data_.resize(0x20000); bitmap_ = std::make_shared(width, height, 8, internal_data_); diff --git a/src/app/gfx/tilesheet.h b/src/app/gfx/tilesheet.h index fc77d312..81cff193 100644 --- a/src/app/gfx/tilesheet.h +++ b/src/app/gfx/tilesheet.h @@ -127,10 +127,6 @@ class Tilesheet { std::shared_ptr bitmap_; }; -absl::StatusOr CreateTilesheetFromGraphicsBuffer( - const uint8_t* graphics_buffer, int width, int height, TileType tile_type, - int sheet_id); - } // namespace gfx } // namespace yaze