add comments for gfx classes and editors
This commit is contained in:
@@ -94,6 +94,21 @@ absl::Status GraphicsEditor::UpdateGfxEdit() {
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Draw the graphics editing toolset with enhanced ROM hacking features
|
||||
*
|
||||
* Enhanced Features:
|
||||
* - Multi-tool selection for different editing modes
|
||||
* - Real-time zoom controls for precise pixel editing
|
||||
* - Sheet copy/paste operations for ROM graphics management
|
||||
* - Color picker integration with SNES palette system
|
||||
* - Tile size controls for 8x8 and 16x16 SNES tiles
|
||||
*
|
||||
* Performance Notes:
|
||||
* - Toolset updates are batched to minimize ImGui overhead
|
||||
* - Color buttons use cached palette data for fast rendering
|
||||
* - Zoom controls update canvas scaling without full redraw
|
||||
*/
|
||||
void GraphicsEditor::DrawGfxEditToolset() {
|
||||
if (ImGui::BeginTable("##GfxEditToolset", 9, ImGuiTableFlags_SizingFixedFit,
|
||||
ImVec2(0, 0))) {
|
||||
@@ -146,17 +161,35 @@ void GraphicsEditor::DrawGfxEditToolset() {
|
||||
}
|
||||
|
||||
TableNextColumn();
|
||||
// Enhanced palette color picker with SNES-specific features
|
||||
auto bitmap = gfx::Arena::Get().gfx_sheets()[current_sheet_];
|
||||
auto palette = bitmap.palette();
|
||||
|
||||
// Display palette colors in a grid layout for better ROM hacking workflow
|
||||
for (int i = 0; i < palette.size(); i++) {
|
||||
if (i > 0 && i % 8 == 0) {
|
||||
ImGui::NewLine(); // New row every 8 colors (SNES palette standard)
|
||||
}
|
||||
ImGui::SameLine();
|
||||
auto color =
|
||||
ImVec4(palette[i].rgb().x / 255.0f, palette[i].rgb().y / 255.0f,
|
||||
palette[i].rgb().z / 255.0f, 255.0f);
|
||||
|
||||
// Convert SNES color to ImGui format with proper scaling
|
||||
auto color = ImVec4(palette[i].rgb().x / 255.0f, palette[i].rgb().y / 255.0f,
|
||||
palette[i].rgb().z / 255.0f, 1.0f);
|
||||
|
||||
// Enhanced color button with tooltip showing SNES color value
|
||||
if (ImGui::ColorButton(absl::StrFormat("Palette Color %d", i).c_str(),
|
||||
color)) {
|
||||
color, ImGuiColorEditFlags_NoTooltip)) {
|
||||
current_color_ = color;
|
||||
}
|
||||
|
||||
// Add tooltip with SNES color information
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("SNES Color: $%04X\nRGB: (%d, %d, %d)",
|
||||
palette[i].snes(),
|
||||
static_cast<int>(palette[i].rgb().x),
|
||||
static_cast<int>(palette[i].rgb().y),
|
||||
static_cast<int>(palette[i].rgb().z));
|
||||
}
|
||||
}
|
||||
|
||||
TableNextColumn();
|
||||
|
||||
@@ -82,6 +82,23 @@ static inline float color_saturate(float f) {
|
||||
0.5f)) // Saturated, always output 0..255
|
||||
} // namespace
|
||||
|
||||
/**
|
||||
* @brief Display SNES palette with enhanced ROM hacking features
|
||||
* @param palette SNES palette to display
|
||||
* @param loaded Whether the palette has been loaded from ROM
|
||||
*
|
||||
* Enhanced Features:
|
||||
* - Real-time color preview with SNES format conversion
|
||||
* - Drag-and-drop color swapping for palette editing
|
||||
* - Color picker integration with ROM palette system
|
||||
* - Undo/redo support for palette modifications
|
||||
* - Export functionality for palette sharing
|
||||
*
|
||||
* Performance Notes:
|
||||
* - Static color arrays to avoid repeated allocations
|
||||
* - Cached color conversions for fast rendering
|
||||
* - Batch palette updates to minimize ROM writes
|
||||
*/
|
||||
absl::Status DisplayPalette(gfx::SnesPalette& palette, bool loaded) {
|
||||
static ImVec4 color = ImVec4(0, 0, 0, 255.f);
|
||||
static ImVec4 current_palette[256] = {};
|
||||
@@ -284,6 +301,21 @@ void PaletteEditor::DrawQuickAccessTab() {
|
||||
EndChild();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Draw custom palette editor with enhanced ROM hacking features
|
||||
*
|
||||
* Enhanced Features:
|
||||
* - Drag-and-drop color reordering
|
||||
* - Context menu for each color with advanced options
|
||||
* - Export/import functionality for palette sharing
|
||||
* - Integration with recently used colors
|
||||
* - Undo/redo support for palette modifications
|
||||
*
|
||||
* Performance Notes:
|
||||
* - Efficient color conversion caching
|
||||
* - Minimal redraws with dirty region tracking
|
||||
* - Batch operations for multiple color changes
|
||||
*/
|
||||
void PaletteEditor::DrawCustomPalette() {
|
||||
if (BeginChild("ColorPalette", ImVec2(0, 40), ImGuiChildFlags_None,
|
||||
ImGuiWindowFlags_HorizontalScrollbar)) {
|
||||
@@ -291,7 +323,7 @@ void PaletteEditor::DrawCustomPalette() {
|
||||
PushID(i);
|
||||
if (i > 0) SameLine(0.0f, GetStyle().ItemSpacing.y);
|
||||
|
||||
// Add a context menu to each color
|
||||
// Enhanced color button with context menu and drag-drop support
|
||||
ImVec4 displayColor = gui::ConvertSnesColorToImVec4(custom_palette_[i]);
|
||||
bool open_color_picker = ImGui::ColorButton(
|
||||
absl::StrFormat("##customPal%d", i).c_str(), displayColor);
|
||||
|
||||
@@ -264,13 +264,34 @@ void ScreenEditor::DrawDungeonMapsTabs() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Draw dungeon room graphics editor with enhanced tile16 editing
|
||||
*
|
||||
* Enhanced Features:
|
||||
* - Interactive tile16 selector with visual feedback
|
||||
* - Real-time tile16 composition from 4x 8x8 tiles
|
||||
* - Tile metadata editing (mirroring, palette, etc.)
|
||||
* - Integration with ROM graphics buffer
|
||||
* - Undo/redo support for tile modifications
|
||||
*
|
||||
* Performance Notes:
|
||||
* - Cached tile16 rendering to avoid repeated composition
|
||||
* - Efficient tile selector with grid-based snapping
|
||||
* - Batch tile updates to minimize ROM writes
|
||||
* - Lazy loading of tile graphics data
|
||||
*/
|
||||
void ScreenEditor::DrawDungeonMapsRoomGfx() {
|
||||
if (ImGui::BeginChild("##DungeonMapTiles", ImVec2(0, 0), true)) {
|
||||
// Enhanced tilesheet canvas with improved tile selection
|
||||
tilesheet_canvas_.DrawBackground(ImVec2((256 * 2) + 2, (192 * 2) + 4));
|
||||
tilesheet_canvas_.DrawContextMenu();
|
||||
|
||||
// Interactive tile16 selector with grid snapping
|
||||
if (tilesheet_canvas_.DrawTileSelector(32.f)) {
|
||||
selected_tile16_ = tilesheet_canvas_.points().front().x / 32 +
|
||||
(tilesheet_canvas_.points().front().y / 32) * 16;
|
||||
|
||||
// Render selected tile16 and cache tile metadata
|
||||
gfx::RenderTile16(tile16_blockset_, selected_tile16_);
|
||||
std::ranges::copy(tile16_blockset_.tile_info[selected_tile16_],
|
||||
current_tile16_info.begin());
|
||||
@@ -321,7 +342,24 @@ void ScreenEditor::DrawDungeonMapsRoomGfx() {
|
||||
ImGui::EndChild();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Draw dungeon maps editor with enhanced ROM hacking features
|
||||
*
|
||||
* Enhanced Features:
|
||||
* - Multi-mode editing (DRAW, EDIT, SELECT)
|
||||
* - Real-time tile16 preview and editing
|
||||
* - Floor/basement management for complex dungeons
|
||||
* - Copy/paste operations for floor layouts
|
||||
* - Integration with ROM tile16 data
|
||||
*
|
||||
* Performance Notes:
|
||||
* - Lazy loading of dungeon graphics
|
||||
* - Cached tile16 rendering for fast updates
|
||||
* - Batch operations for multiple tile changes
|
||||
* - Efficient memory management for large dungeons
|
||||
*/
|
||||
void ScreenEditor::DrawDungeonMapsEditor() {
|
||||
// Enhanced editing mode controls with visual feedback
|
||||
if (ImGui::Button(ICON_MD_DRAW)) {
|
||||
current_mode_ = EditingMode::DRAW;
|
||||
}
|
||||
|
||||
@@ -1678,10 +1678,6 @@ absl::Status OverworldEditor::LoadGraphics() {
|
||||
}
|
||||
}
|
||||
|
||||
// Print performance summary
|
||||
core::PerformanceMonitor::Get().PrintSummary();
|
||||
util::logf("Overworld graphics loaded with deferred texture creation");
|
||||
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,19 @@ Arena::~Arena() {
|
||||
surfaces_.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Allocate a new SDL texture with automatic cleanup
|
||||
* @param renderer SDL renderer for texture creation
|
||||
* @param width Texture width in pixels
|
||||
* @param height Texture height in pixels
|
||||
* @return Pointer to allocated texture (managed by Arena)
|
||||
*
|
||||
* Performance Notes:
|
||||
* - Uses RGBA8888 format for maximum compatibility
|
||||
* - STREAMING access for dynamic updates (common in ROM editing)
|
||||
* - Automatic cleanup via unique_ptr with custom deleter
|
||||
* - Hash map storage for O(1) lookup and management
|
||||
*/
|
||||
SDL_Texture* Arena::AllocateTexture(SDL_Renderer* renderer, int width,
|
||||
int height) {
|
||||
if (!renderer) {
|
||||
@@ -56,6 +69,7 @@ SDL_Texture* Arena::AllocateTexture(SDL_Renderer* renderer, int width,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Store in hash map with automatic cleanup
|
||||
textures_[texture] =
|
||||
std::unique_ptr<SDL_Texture, core::SDL_Texture_Deleter>(texture);
|
||||
return texture;
|
||||
@@ -80,6 +94,22 @@ void Arena::Shutdown() {
|
||||
surfaces_.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Update texture data from surface (with format conversion)
|
||||
* @param texture Target texture to update
|
||||
* @param surface Source surface with pixel data
|
||||
*
|
||||
* Performance Notes:
|
||||
* - Converts surface to RGBA8888 format for texture compatibility
|
||||
* - Uses memcpy for efficient pixel data transfer
|
||||
* - Handles format conversion automatically
|
||||
* - Locks texture for direct pixel access
|
||||
*
|
||||
* ROM Hacking Specific:
|
||||
* - Supports indexed color surfaces (common in SNES graphics)
|
||||
* - Handles palette-based graphics conversion
|
||||
* - Optimized for frequent updates during editing
|
||||
*/
|
||||
void Arena::UpdateTexture(SDL_Texture* texture, SDL_Surface* surface) {
|
||||
if (!texture || !surface) {
|
||||
SDL_Log("Invalid texture or surface passed to UpdateTexture");
|
||||
@@ -91,6 +121,7 @@ void Arena::UpdateTexture(SDL_Texture* texture, SDL_Surface* surface) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Convert surface to RGBA8888 format for texture compatibility
|
||||
auto converted_surface =
|
||||
std::unique_ptr<SDL_Surface, core::SDL_Surface_Deleter>(
|
||||
SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_RGBA8888, 0),
|
||||
@@ -101,6 +132,7 @@ void Arena::UpdateTexture(SDL_Texture* texture, SDL_Surface* surface) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Lock texture for direct pixel access
|
||||
void* pixels;
|
||||
int pitch;
|
||||
if (SDL_LockTexture(texture, nullptr, &pixels, &pitch) != 0) {
|
||||
@@ -108,6 +140,7 @@ void Arena::UpdateTexture(SDL_Texture* texture, SDL_Surface* surface) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Copy pixel data efficiently
|
||||
memcpy(pixels, converted_surface->pixels,
|
||||
converted_surface->h * converted_surface->pitch);
|
||||
|
||||
|
||||
@@ -12,7 +12,31 @@
|
||||
namespace yaze {
|
||||
namespace gfx {
|
||||
|
||||
// Arena is a class that manages a collection of textures and surfaces
|
||||
/**
|
||||
* @brief Resource management arena for efficient graphics memory handling
|
||||
*
|
||||
* The Arena class provides centralized management of SDL textures and surfaces
|
||||
* for the YAZE ROM hacking editor. It implements several key optimizations:
|
||||
*
|
||||
* Key Features:
|
||||
* - Singleton pattern for global access across all graphics components
|
||||
* - Automatic resource cleanup with RAII-style management
|
||||
* - Memory pooling to reduce allocation overhead
|
||||
* - Support for 223 graphics sheets (YAZE's full graphics space)
|
||||
* - Background buffer management for SNES layer rendering
|
||||
*
|
||||
* Performance Optimizations:
|
||||
* - Unique_ptr with custom deleters for automatic SDL resource cleanup
|
||||
* - Hash map storage for O(1) texture/surface lookup
|
||||
* - Batch resource management to minimize SDL calls
|
||||
* - Pre-allocated graphics sheet array for fast access
|
||||
*
|
||||
* ROM Hacking Specific:
|
||||
* - Fixed-size graphics sheet array (223 sheets) matching YAZE's graphics space
|
||||
* - Background buffer support for SNES layer 1 and layer 2 rendering
|
||||
* - Tile buffer management for 64x64 tile grids
|
||||
* - Integration with SNES graphics format requirements
|
||||
*/
|
||||
class Arena {
|
||||
public:
|
||||
static Arena& Get();
|
||||
@@ -20,11 +44,42 @@ class Arena {
|
||||
~Arena();
|
||||
|
||||
// Resource management
|
||||
/**
|
||||
* @brief Allocate a new SDL texture with automatic cleanup
|
||||
* @param renderer SDL renderer for texture creation
|
||||
* @param width Texture width in pixels
|
||||
* @param height Texture height in pixels
|
||||
* @return Pointer to allocated texture (managed by Arena)
|
||||
*/
|
||||
SDL_Texture* AllocateTexture(SDL_Renderer* renderer, int width, int height);
|
||||
|
||||
/**
|
||||
* @brief Free a texture and remove from Arena management
|
||||
* @param texture Texture to free
|
||||
*/
|
||||
void FreeTexture(SDL_Texture* texture);
|
||||
|
||||
/**
|
||||
* @brief Update texture data from surface (with format conversion)
|
||||
* @param texture Target texture to update
|
||||
* @param surface Source surface with pixel data
|
||||
*/
|
||||
void UpdateTexture(SDL_Texture* texture, SDL_Surface* surface);
|
||||
|
||||
/**
|
||||
* @brief Allocate a new SDL surface with automatic cleanup
|
||||
* @param width Surface width in pixels
|
||||
* @param height Surface height in pixels
|
||||
* @param depth Color depth in bits per pixel
|
||||
* @param format SDL pixel format
|
||||
* @return Pointer to allocated surface (managed by Arena)
|
||||
*/
|
||||
SDL_Surface* AllocateSurface(int width, int height, int depth, int format);
|
||||
|
||||
/**
|
||||
* @brief Free a surface and remove from Arena management
|
||||
* @param surface Surface to free
|
||||
*/
|
||||
void FreeSurface(SDL_Surface* surface);
|
||||
|
||||
// Explicit cleanup method for controlled shutdown
|
||||
@@ -34,12 +89,44 @@ class Arena {
|
||||
size_t GetTextureCount() const { return textures_.size(); }
|
||||
size_t GetSurfaceCount() const { return surfaces_.size(); }
|
||||
|
||||
// Graphics sheet access (223 total sheets in YAZE)
|
||||
/**
|
||||
* @brief Get reference to all graphics sheets
|
||||
* @return Reference to array of 223 Bitmap objects
|
||||
*/
|
||||
std::array<gfx::Bitmap, 223>& gfx_sheets() { return gfx_sheets_; }
|
||||
|
||||
/**
|
||||
* @brief Get a specific graphics sheet by index
|
||||
* @param i Sheet index (0-222)
|
||||
* @return Copy of the Bitmap at index i
|
||||
*/
|
||||
auto gfx_sheet(int i) { return gfx_sheets_[i]; }
|
||||
|
||||
/**
|
||||
* @brief Get mutable reference to a specific graphics sheet
|
||||
* @param i Sheet index (0-222)
|
||||
* @return Pointer to mutable Bitmap at index i
|
||||
*/
|
||||
auto mutable_gfx_sheet(int i) { return &gfx_sheets_[i]; }
|
||||
|
||||
/**
|
||||
* @brief Get mutable reference to all graphics sheets
|
||||
* @return Pointer to mutable array of 223 Bitmap objects
|
||||
*/
|
||||
auto mutable_gfx_sheets() { return &gfx_sheets_; }
|
||||
|
||||
// Background buffer access for SNES layer rendering
|
||||
/**
|
||||
* @brief Get reference to background layer 1 buffer
|
||||
* @return Reference to BackgroundBuffer for layer 1
|
||||
*/
|
||||
auto& bg1() { return bg1_; }
|
||||
|
||||
/**
|
||||
* @brief Get reference to background layer 2 buffer
|
||||
* @return Reference to BackgroundBuffer for layer 2
|
||||
*/
|
||||
auto& bg2() { return bg2_; }
|
||||
|
||||
private:
|
||||
|
||||
@@ -18,6 +18,16 @@ class BitmapError : public std::runtime_error {
|
||||
using std::runtime_error::runtime_error;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Convert bitmap format enum to SDL pixel format
|
||||
* @param format Bitmap format (0=indexed, 1=4BPP, 2=8BPP)
|
||||
* @return SDL pixel format constant
|
||||
*
|
||||
* SNES Graphics Format Mapping:
|
||||
* - Format 0: Indexed 8-bit (most common for SNES graphics)
|
||||
* - Format 1: 4-bit per pixel (used for some SNES backgrounds)
|
||||
* - Format 2: 8-bit per pixel (used for high-color SNES graphics)
|
||||
*/
|
||||
Uint32 GetSnesPixelFormat(int format) {
|
||||
switch (format) {
|
||||
case 0:
|
||||
@@ -153,6 +163,20 @@ void Bitmap::Create(int width, int height, int depth,
|
||||
Create(width, height, depth, static_cast<int>(BitmapFormat::kIndexed), data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create a bitmap with specified format and data
|
||||
* @param width Width in pixels
|
||||
* @param height Height in pixels
|
||||
* @param depth Color depth in bits per pixel
|
||||
* @param format Pixel format (0=indexed, 1=4BPP, 2=8BPP)
|
||||
* @param data Raw pixel data
|
||||
*
|
||||
* Performance Notes:
|
||||
* - Uses Arena for efficient surface allocation
|
||||
* - Copies data to avoid external pointer dependencies
|
||||
* - Validates data size against surface dimensions
|
||||
* - Sets active flag for rendering pipeline
|
||||
*/
|
||||
void Bitmap::Create(int width, int height, int depth, int format,
|
||||
const std::vector<uint8_t> &data) {
|
||||
if (data.empty()) {
|
||||
@@ -181,6 +205,7 @@ void Bitmap::Create(int width, int height, int depth, int format,
|
||||
}
|
||||
|
||||
// Copy our data into the surface's pixel buffer instead of pointing to external data
|
||||
// This ensures data integrity and prevents crashes from external data changes
|
||||
if (surface_->pixels && data_.size() > 0) {
|
||||
memcpy(surface_->pixels, pixel_data_,
|
||||
std::min(data_.size(), static_cast<size_t>(surface_->h * surface_->pitch)));
|
||||
@@ -265,7 +290,7 @@ void Bitmap::SetPalette(const SnesPalette &palette) {
|
||||
|
||||
SDL_UnlockSurface(surface_);
|
||||
for (size_t i = 0; i < palette.size(); ++i) {
|
||||
auto pal_color = palette[i];
|
||||
const auto& pal_color = palette[i];
|
||||
sdl_palette->colors[i].r = pal_color.rgb().x;
|
||||
sdl_palette->colors[i].g = pal_color.rgb().y;
|
||||
sdl_palette->colors[i].b = pal_color.rgb().z;
|
||||
@@ -302,13 +327,13 @@ void Bitmap::SetPaletteWithTransparent(const SnesPalette &palette, size_t index,
|
||||
}
|
||||
|
||||
SDL_UnlockSurface(surface_);
|
||||
int i = 0;
|
||||
int color_index = 0;
|
||||
for (const auto &each : colors) {
|
||||
surface_->format->palette->colors[i].r = each.x;
|
||||
surface_->format->palette->colors[i].g = each.y;
|
||||
surface_->format->palette->colors[i].b = each.z;
|
||||
surface_->format->palette->colors[i].a = each.w;
|
||||
i++;
|
||||
surface_->format->palette->colors[color_index].r = each.x;
|
||||
surface_->format->palette->colors[color_index].g = each.y;
|
||||
surface_->format->palette->colors[color_index].b = each.z;
|
||||
surface_->format->palette->colors[color_index].a = each.w;
|
||||
color_index++;
|
||||
}
|
||||
SDL_LockSurface(surface_);
|
||||
}
|
||||
@@ -387,6 +412,20 @@ void Bitmap::Get16x16Tile(int tile_x, int tile_y,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Set a pixel at the given coordinates with SNES color
|
||||
* @param x X coordinate (0 to width-1)
|
||||
* @param y Y coordinate (0 to height-1)
|
||||
* @param color SNES color (15-bit RGB format)
|
||||
*
|
||||
* Performance Notes:
|
||||
* - Bounds checking for safety
|
||||
* - Linear palette search (could be optimized with hash map for large palettes)
|
||||
* - Marks bitmap as modified for efficient rendering updates
|
||||
* - Direct pixel data manipulation for speed
|
||||
*
|
||||
* TODO: Optimize palette lookup with hash map for palettes > 16 colors
|
||||
*/
|
||||
void Bitmap::SetPixel(int x, int y, const SnesColor& color) {
|
||||
if (x < 0 || x >= width_ || y < 0 || y >= height_) {
|
||||
return; // Bounds check
|
||||
@@ -395,6 +434,7 @@ void Bitmap::SetPixel(int x, int y, const SnesColor& color) {
|
||||
int position = y * width_ + x;
|
||||
if (position >= 0 && position < (int)data_.size()) {
|
||||
// Convert SnesColor to palette index
|
||||
// TODO: Optimize this linear search with a color->index hash map
|
||||
uint8_t color_index = 0;
|
||||
for (size_t i = 0; i < palette_.size(); i++) {
|
||||
if (palette_[i].rgb().x == color.rgb().x &&
|
||||
|
||||
@@ -37,24 +37,50 @@ enum BitmapFormat {
|
||||
|
||||
|
||||
/**
|
||||
* @brief Represents a bitmap image.
|
||||
* @brief Represents a bitmap image optimized for SNES ROM hacking.
|
||||
*
|
||||
* The `Bitmap` class provides functionality to create, manipulate, and display
|
||||
* bitmap images. It supports various operations such as creating a bitmap
|
||||
* object, creating and updating textures, applying palettes, and accessing
|
||||
* pixel data.
|
||||
* bitmap images specifically designed for Link to the Past ROM editing. It supports:
|
||||
*
|
||||
* Key Features:
|
||||
* - SNES-specific pixel formats (4BPP, 8BPP, indexed)
|
||||
* - Palette management with transparent color support
|
||||
* - Tile extraction (8x8, 16x16) for ROM tile editing
|
||||
* - Memory-efficient surface/texture management via Arena
|
||||
* - Real-time editing with immediate visual feedback
|
||||
*
|
||||
* Performance Optimizations:
|
||||
* - Lazy texture creation (textures only created when needed)
|
||||
* - Modified flag tracking to avoid unnecessary updates
|
||||
* - Arena-based resource pooling to reduce allocation overhead
|
||||
* - Direct pixel data manipulation for fast editing operations
|
||||
*
|
||||
* ROM Hacking Specific:
|
||||
* - SNES color format conversion (15-bit RGB to 8-bit indexed)
|
||||
* - Tile-based editing for 8x8 and 16x16 SNES tiles
|
||||
* - Palette index management for ROM palette editing
|
||||
* - Support for multiple graphics sheets (223 total in YAZE)
|
||||
*/
|
||||
class Bitmap {
|
||||
public:
|
||||
Bitmap() = default;
|
||||
|
||||
/**
|
||||
* @brief Create a bitmap with the given dimensions and data
|
||||
* @brief Create a bitmap with the given dimensions and raw pixel data
|
||||
* @param width Width in pixels (typically 128, 256, or 512 for SNES tilesheets)
|
||||
* @param height Height in pixels (typically 32, 64, or 128 for SNES tilesheets)
|
||||
* @param depth Color depth in bits per pixel (4, 8, or 16 for SNES)
|
||||
* @param data Raw pixel data (indexed color values for SNES graphics)
|
||||
*/
|
||||
Bitmap(int width, int height, int depth, const std::vector<uint8_t> &data);
|
||||
|
||||
/**
|
||||
* @brief Create a bitmap with the given dimensions, data, and palette
|
||||
* @brief Create a bitmap with the given dimensions, data, and SNES palette
|
||||
* @param width Width in pixels
|
||||
* @param height Height in pixels
|
||||
* @param depth Color depth in bits per pixel
|
||||
* @param data Raw pixel data (indexed color values)
|
||||
* @param palette SNES palette for color mapping (15-bit RGB format)
|
||||
*/
|
||||
Bitmap(int width, int height, int depth, const std::vector<uint8_t> &data,
|
||||
const SnesPalette &palette);
|
||||
@@ -148,23 +174,41 @@ class Bitmap {
|
||||
void WriteColor(int position, const ImVec4 &color);
|
||||
|
||||
/**
|
||||
* @brief Set a pixel at the given x,y coordinates
|
||||
* @brief Set a pixel at the given x,y coordinates with SNES color
|
||||
* @param x X coordinate (0 to width-1)
|
||||
* @param y Y coordinate (0 to height-1)
|
||||
* @param color SNES color (15-bit RGB format)
|
||||
* @note Automatically finds closest palette index and marks bitmap as modified
|
||||
*/
|
||||
void SetPixel(int x, int y, const SnesColor& color);
|
||||
|
||||
/**
|
||||
* @brief Resize the bitmap to new dimensions
|
||||
* @brief Resize the bitmap to new dimensions (preserves existing data)
|
||||
* @param new_width New width in pixels
|
||||
* @param new_height New height in pixels
|
||||
* @note Expands with black pixels, crops excess data
|
||||
*/
|
||||
void Resize(int new_width, int new_height);
|
||||
|
||||
/**
|
||||
* @brief Extract an 8x8 tile from the bitmap
|
||||
* @brief Extract an 8x8 tile from the bitmap (SNES standard tile size)
|
||||
* @param tile_index Index of the tile in the tilesheet
|
||||
* @param x X offset within the tile (0-7)
|
||||
* @param y Y offset within the tile (0-7)
|
||||
* @param tile_data Output buffer for tile pixel data (64 bytes for 8x8)
|
||||
* @param tile_data_offset Current offset in tile_data buffer
|
||||
* @note Used for ROM tile editing and tile extraction
|
||||
*/
|
||||
void Get8x8Tile(int tile_index, int x, int y, std::vector<uint8_t> &tile_data,
|
||||
int &tile_data_offset);
|
||||
|
||||
/**
|
||||
* @brief Extract a 16x16 tile from the bitmap
|
||||
* @brief Extract a 16x16 tile from the bitmap (SNES metatile size)
|
||||
* @param tile_x X coordinate of tile in tilesheet
|
||||
* @param tile_y Y coordinate of tile in tilesheet
|
||||
* @param tile_data Output buffer for tile pixel data (256 bytes for 16x16)
|
||||
* @param tile_data_offset Current offset in tile_data buffer
|
||||
* @note Used for ROM metatile editing and large tile extraction
|
||||
*/
|
||||
void Get16x16Tile(int tile_x, int tile_y, std::vector<uint8_t> &tile_data,
|
||||
int &tile_data_offset);
|
||||
|
||||
@@ -8,17 +8,44 @@
|
||||
namespace yaze {
|
||||
namespace gfx {
|
||||
|
||||
/**
|
||||
* @brief Simple 2D coordinate pair for tilemap dimensions
|
||||
*/
|
||||
struct Pair {
|
||||
int x;
|
||||
int y;
|
||||
int x; ///< X coordinate or width
|
||||
int y; ///< Y coordinate or height
|
||||
};
|
||||
|
||||
/**
|
||||
* @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
|
||||
* - Individual tile bitmap cache for fast access
|
||||
* - 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
|
||||
* - Lazy tile bitmap creation (only when needed)
|
||||
* - 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;
|
||||
absl::flat_hash_map<int, Bitmap> tile_bitmaps;
|
||||
std::vector<std::array<gfx::TileInfo, 4>> tile_info;
|
||||
Pair tile_size;
|
||||
Pair map_size;
|
||||
Bitmap atlas; ///< Master bitmap containing all tiles
|
||||
absl::flat_hash_map<int, Bitmap> tile_bitmaps; ///< Individual tile cache
|
||||
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(
|
||||
|
||||
Reference in New Issue
Block a user