- Updated the testing guide to clarify the testing framework's organization and execution methods, improving user understanding. - Refactored CMakeLists to include new platform-specific files, ensuring proper integration of the rendering backend. - Modified main application files to utilize the new IRenderer interface, enhancing flexibility in rendering operations. - Implemented deferred texture management in various components, allowing for more efficient graphics handling and improved performance. - Introduced new methods for texture creation and updates, streamlining the rendering process across the application. - Enhanced logging and error handling in the rendering pipeline to facilitate better debugging and diagnostics.
158 lines
5.2 KiB
C++
158 lines
5.2 KiB
C++
#ifndef YAZE_GFX_TILEMAP_H
|
|
#define YAZE_GFX_TILEMAP_H
|
|
|
|
#include "absl/container/flat_hash_map.h"
|
|
#include "app/gfx/backend/irenderer.h"
|
|
#include "app/gfx/bitmap.h"
|
|
#include "app/gfx/snes_tile.h"
|
|
|
|
#include <list>
|
|
#include <unordered_map>
|
|
|
|
namespace yaze {
|
|
namespace gfx {
|
|
|
|
/**
|
|
* @brief Simple 2D coordinate pair for tilemap dimensions
|
|
*/
|
|
struct Pair {
|
|
int x; ///< X coordinate or width
|
|
int y; ///< Y coordinate or height
|
|
};
|
|
|
|
/**
|
|
* @brief Smart tile cache with LRU eviction for efficient memory management
|
|
*
|
|
* Performance Optimizations:
|
|
* - LRU eviction policy to keep frequently used tiles in memory
|
|
* - Configurable cache size to balance memory usage and performance
|
|
* - O(1) tile access and insertion
|
|
* - Automatic cache management with minimal overhead
|
|
*/
|
|
struct TileCache {
|
|
static constexpr size_t MAX_CACHE_SIZE = 1024;
|
|
std::unordered_map<int, Bitmap> cache_;
|
|
std::list<int> access_order_;
|
|
|
|
/**
|
|
* @brief Get a cached tile by ID
|
|
* @param tile_id Tile identifier
|
|
* @return Pointer to cached tile bitmap or nullptr if not cached
|
|
*/
|
|
Bitmap* GetTile(int tile_id) {
|
|
auto it = cache_.find(tile_id);
|
|
if (it != cache_.end()) {
|
|
// Move to front of access order (most recently used)
|
|
access_order_.remove(tile_id);
|
|
access_order_.push_front(tile_id);
|
|
return &it->second;
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
/**
|
|
* @brief Cache a tile bitmap
|
|
* @param tile_id Tile identifier
|
|
* @param bitmap Tile bitmap to cache
|
|
*/
|
|
void CacheTile(int tile_id, Bitmap&& bitmap) {
|
|
if (cache_.size() >= MAX_CACHE_SIZE) {
|
|
// Remove least recently used tile
|
|
int lru_tile = access_order_.back();
|
|
access_order_.pop_back();
|
|
cache_.erase(lru_tile);
|
|
}
|
|
|
|
cache_[tile_id] = std::move(bitmap);
|
|
access_order_.push_front(tile_id);
|
|
}
|
|
|
|
/**
|
|
* @brief Clear the cache
|
|
*/
|
|
void Clear() {
|
|
cache_.clear();
|
|
access_order_.clear();
|
|
}
|
|
|
|
/**
|
|
* @brief Get cache statistics
|
|
* @return Number of cached tiles
|
|
*/
|
|
size_t Size() const { return cache_.size(); }
|
|
};
|
|
|
|
/**
|
|
* @brief Tilemap structure for SNES tile-based graphics management
|
|
*
|
|
* The Tilemap class provides comprehensive tile management for ROM hacking:
|
|
*
|
|
* Key Features:
|
|
* - Atlas bitmap containing all tiles in a single texture
|
|
* - Smart tile cache with LRU eviction for optimal memory usage
|
|
* - Tile metadata storage (mirroring, palette, etc.)
|
|
* - Support for both 8x8 and 16x16 tile sizes
|
|
* - Efficient tile lookup and rendering
|
|
*
|
|
* Performance Optimizations:
|
|
* - Hash map storage for O(1) tile access
|
|
* - LRU tile caching to minimize memory usage
|
|
* - Atlas-based rendering to minimize draw calls
|
|
* - Tile metadata caching for fast property access
|
|
*
|
|
* ROM Hacking Specific:
|
|
* - SNES tile format support (4BPP, 8BPP)
|
|
* - Tile mirroring and flipping support
|
|
* - Palette index management per tile
|
|
* - Integration with SNES graphics buffer format
|
|
*/
|
|
struct Tilemap {
|
|
Bitmap atlas; ///< Master bitmap containing all tiles
|
|
TileCache tile_cache; ///< Smart tile cache with LRU eviction
|
|
std::vector<std::array<gfx::TileInfo, 4>> tile_info; ///< Tile metadata (4 tiles per 16x16)
|
|
Pair tile_size; ///< Size of individual tiles (8x8 or 16x16)
|
|
Pair map_size; ///< Size of tilemap in tiles
|
|
};
|
|
|
|
std::vector<uint8_t> FetchTileDataFromGraphicsBuffer(
|
|
const std::vector<uint8_t> &data, int tile_id, int sheet_offset);
|
|
|
|
Tilemap CreateTilemap(IRenderer* renderer, std::vector<uint8_t> &data, int width, int height,
|
|
int tile_size, int num_tiles, SnesPalette &palette);
|
|
|
|
void UpdateTilemap(IRenderer* renderer, Tilemap &tilemap, const std::vector<uint8_t> &data);
|
|
|
|
void RenderTile(IRenderer* renderer, Tilemap &tilemap, int tile_id);
|
|
|
|
void RenderTile16(IRenderer* renderer, Tilemap &tilemap, int tile_id);
|
|
void UpdateTile16(IRenderer* renderer, Tilemap &tilemap, int tile_id);
|
|
|
|
void ModifyTile16(Tilemap &tilemap, const std::vector<uint8_t> &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<uint8_t> &data,
|
|
const TileInfo &top_left, const TileInfo &top_right,
|
|
const TileInfo &bottom_left, const TileInfo &bottom_right,
|
|
int sheet_offset);
|
|
|
|
std::vector<uint8_t> GetTilemapData(Tilemap &tilemap, int tile_id);
|
|
|
|
/**
|
|
* @brief Render multiple tiles using atlas rendering for improved performance
|
|
* @param tilemap Tilemap containing tiles to render
|
|
* @param tile_ids Vector of tile IDs to render
|
|
* @param positions Vector of screen positions for each tile
|
|
* @param scales Vector of scale factors for each tile (optional, defaults to 1.0)
|
|
* @note This function uses atlas rendering to reduce draw calls significantly
|
|
*/
|
|
void RenderTilesBatch(IRenderer* renderer, Tilemap& tilemap, const std::vector<int>& tile_ids,
|
|
const std::vector<std::pair<float, float>>& positions,
|
|
const std::vector<std::pair<float, float>>& scales = {});
|
|
|
|
} // namespace gfx
|
|
} // namespace yaze
|
|
|
|
#endif // YAZE_GFX_TILEMAP_H
|