yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
Tile16 Editor Palette System

Status: Work in Progress - Documentation for the ongoing Tile16 Editor palette system redesign, implementation, and refactoring improvements.

Executive Summary

The tile16 editor palette system is undergoing a complete redesign to resolve critical crashes and ensure proper color alignment between the tile16 editor and overworld display. Significant progress has been made addressing fundamental architectural issues with palette mapping, implementing crash fixes, and creating an improved three-column layout. However, palette handling for the tile8 source canvas and palette button functionality remain works in progress.

Problem Analysis

Critical Issues Identified

  1. SIGBUS Crash in SnesColor::rgb()
    • Root Cause: SetPaletteWithTransparent() method used incorrect index * 7 calculation
    • Impact: Crashes when selecting palette buttons 4-7 due to out-of-bounds memory access
    • Location: bitmap.cc:371 - start_index = index * 7
  2. Fundamental Architecture Misunderstanding
    • Root Cause: Attempting to use SetPaletteWithTransparent() instead of SetPalette()
    • Impact: Broke the 256-color palette system that the overworld relies on
    • Reality: Overworld system uses complete 256-color palettes with SetPalette()
  3. Color Mapping Misunderstanding
    • Root Cause: Confusion about how color mapping works in the graphics system
    • Impact: Incorrect palette handling in tile16 editor
    • Reality: Pixel data already contains correct color indices for the 256-color palette

Solution Architecture

Core Design Principles

  1. Use Same Palette System as Overworld: Use SetPalette() with complete 256-color palette
  2. Direct Color Mapping: The pixel data in graphics already contains correct color indices that map to the 256-color palette
  3. Proper Bounds Checking: Prevent out-of-bounds memory access in palette operations
  4. Consistent Architecture: Match overworld editor's palette handling exactly

256-Color Overworld Palette Structure

Based on analysis of SetColorsPalette() in overworld_map.cc:

Row 0-1: HUD palette (32 colors) - Slots 0-31
Row 2-6: MAIN palette (35 colors) - Slots 32-87 (rows 2-6, cols 1-7)
Row 7: ANIMATED palette (7 colors) - Slots 112-118 (row 7, cols 1-7)
Row 8: Sprite AUX1 + AUX3 (14 colors) - Slots 128-141
Row 9-12: Global sprites (60 colors) - Slots 144-203
Row 13: Sprite palette 1 (7 colors) - Slots 208-214
Row 14: Sprite palette 2 (7 colors) - Slots 224-230
Row 15: Armor palettes (15 colors) - Slots 240-254
Right side (cols 9-15):
Row 2-4: AUX1 palette (21 colors) - Slots 136-151
Row 5-7: AUX2 palette (21 colors) - Slots 152-167

Sheet-to-Palette Mapping

Sheet 0,3,4: → AUX1 region (slots 136-151)
Sheet 5,6: → AUX2 region (slots 152-167)
Sheet 1,2: → MAIN region (slots 32-87)
Sheet 7: → ANIMATED region (slots 112-118)

Palette Button Mapping

Button Sheet 0,3,4 (AUX1) Sheet 1,2 (MAIN) Sheet 5,6 (AUX2) Sheet 7 (ANIMATED)
0 136 32 152 112
1 138 39 154 113
2 140 46 156 114
3 142 53 158 115
4 144 60 160 116
5 146 67 162 117
6 148 74 164 118
7 150 81 166 119

Implementation Details

1. Fixed SetPaletteWithTransparent Method

File: src/app/gfx/bitmap.cc

Before:

auto start_index = index * 7; // WRONG: Creates invalid indices for buttons 4-7

After:

// Extract 8-color sub-palette starting at the specified index
// Always start with transparent color (index 0)
colors.push_back(ImVec4(0, 0, 0, 0));
// Extract up to 7 colors from the palette starting at index
for (size_t i = 0; i < 7 && (index + i) < palette.size(); ++i) {
auto &pal_color = palette[index + i];
colors.push_back(pal_color.rgb());
}

2. Corrected Tile16 Editor Palette System

File: src/app/editor/overworld/tile16_editor.cc

Before:

// WRONG: Trying to extract 8-color sub-palettes
current_gfx_individual_[i].SetPaletteWithTransparent(display_palette, base_palette_slot, 8);

After:

// CORRECT: Use complete 256-color palette (same as overworld system)
// The pixel data already contains correct color indices for the 256-color palette
current_gfx_individual_[i].SetPalette(display_palette);

3. Palette Coordination Flow

Overworld System:
ProcessGraphicsBuffer() → adds 0x88 offset to sheets 0,3,4,5
BuildTiles16Gfx() → combines with palette info
current_gfx_bmp_ → contains properly offset pixel data
Tile16 Editor:
Initialize() → receives current_gfx_bmp_ with correct data
LoadTile8() → extracts tiles with existing pixel values
SetPalette() → applies complete 256-color palette
Display → correct colors shown automatically

UI/UX Refactoring

New Three-Column Layout

The tile16 editor layout was completely restructured into a unified 3-column table for better space utilization:

Column 1: Tile16 Blockset (35% width)

  • Complete 512-tile blockset display
  • Integrated zoom slider (0.5x - 4.0x)
  • Zoom in/out buttons for quick adjustments
  • Click to select tiles for editing
  • Full vertical scrolling support

Column 2: Tile8 Source Tileset (35% width)

  • All 8x8 source tiles
  • Palette group selector (OW Main, OW Aux, etc.)
  • Integrated zoom slider (1.0x - 8.0x)
  • Click to select tiles for painting
  • Full vertical scrolling support

Column 3: Editor & Controls (30% width)

  • Tile16 editor canvas with dynamic zoom (2.0x - 8.0x)
  • Canvas size adjusts automatically with zoom level
  • All controls in compact vertical layout:
    • Tile8 preview and ID
    • Flip controls (X, Y, Priority)
    • Palette selector (8 buttons)
    • Action buttons (Clear, Copy, Paste)
    • Save/Discard changes
    • Undo button
    • Advanced controls (collapsible)
    • Debug information (collapsible)

Benefits:

  • Better space utilization - all three main components visible simultaneously
  • Improved workflow - blockset, source tiles, and editor all in one view
  • Resizable columns allow users to adjust layout to preference

Canvas Context Menu Fixes

Problem: The "Advanced Canvas Properties" and "Scaling Controls" popup dialogs were not appearing when selected from the context menu.

Solution:

  • Changed popup windows from modal popups to regular windows
  • Added boolean flags show_advanced_properties_ and show_scaling_controls_ to track window state
  • Windows now appear as floating windows instead of modal dialogs
  • Added public accessor methods:
    • OpenAdvancedProperties()
    • OpenScalingControls()
    • CloseAdvancedProperties()
    • CloseScalingControls()

Files Modified:

Dynamic Zoom Controls

Each canvas now has independent zoom control with real-time feedback:

Tile16 Blockset Zoom:

  • Range: 0.5x to 4.0x
  • Slider control with +/- buttons
  • Properly scales mouse coordinate calculations

Tile8 Source Zoom:

  • Range: 1.0x to 8.0x
  • Essential for viewing small pixel details
  • Correctly accounts for zoom in tile selection

Tile16 Editor Zoom:

  • Range: 2.0x to 8.0x
  • Canvas size dynamically adjusts with zoom
  • Grid scales proportionally
  • Mouse coordinates properly transformed

Implementation Details:

// Mouse coordinate calculations account for dynamic zoom
int tile_x = static_cast<int>(mouse_pos.x / (8 * tile8_zoom));
// Grid drawing scaled with zoom
tile16_edit_canvas_.DrawGrid(8.0F * tile16_zoom / 4.0F);
// Canvas display size calculated dynamically
float canvas_display_size = 16 * tile16_zoom + 4;

Testing Protocol

Crash Prevention Testing

  1. Load ROM and open tile16 editor
  2. Test all palette buttons 0-7 - should not crash
  3. Verify color display - should match overworld appearance
  4. Test different graphics sheets - should use appropriate palette regions

Color Alignment Testing

  1. Select tile16 in overworld - note colors displayed
  2. Open tile16 editor - load same tile
  3. Test palette buttons 0-7 - colors should match overworld
  4. Verify sheet-specific behavior - different sheets should show different colors

UI/UX Testing

  1. Canvas Popups: Right-click on each canvas → verify "Advanced Properties" and "Scaling Controls" open correctly
  2. Zoom Controls: Test each zoom slider and button for all three canvases
  3. Tile Selection: Verify clicking works at various zoom levels for blockset, tile8 source, and tile16 editor
  4. Layout Responsiveness: Resize window and columns to verify proper behavior
  5. Workflow: Test complete tile editing workflow from selection to save

Error Handling

Bounds Checking

  • Palette Index Validation: Ensure palette indices don't exceed palette size
  • Sheet Index Validation: Ensure sheet indices are within valid range (0-7)
  • Surface Validation: Ensure SDL surface exists before palette operations

Fallback Mechanisms

  • Default Palette: Use MAIN region if sheet detection fails
  • Safe Indices: Clamp palette indices to valid ranges
  • Error Logging: Comprehensive logging for debugging

Debug Information Display

The debug panel (collapsible by default) shows:

  1. Current State: Tile16 ID, Tile8 ID, selected palette button
  2. Mapping Info: Sheet index, actual palette slot
  3. Reference Table: Complete button-to-slot mapping for all sheets
  4. Color Preview: Visual display of actual colors being used

Known Issues and Ongoing Work

Completed Items ✅

  • No Crashes: Fixed SIGBUS errors - palette buttons 0-7 work without crashing
  • Three-Column Layout: Unified layout with blockset, tile8 source, and editor
  • Dynamic Zoom Controls: Independent zoom for all three canvases
  • Canvas Popup Fixes: Advanced properties and scaling controls now working
  • Stable Memory: No memory leaks or corruption
  • Code Architecture: Proper bounds checking and error handling

Active Issues ⚠️

1. Tile8 Source Canvas Palette Issues

  • Problem: The tile8 source canvas (displaying current area graphics) does not show correct colors
  • Impact: Source tiles appear with incorrect palette, making it difficult to preview how tiles will look
  • Root Cause: Area graphics not receiving proper palette application
  • Status: Under investigation - may be related to graphics buffer processing

2. Palette Button Functionality

  • Problem: Palette buttons (0-7) do not properly update the displayed colors
  • Impact: Cannot switch between different palette groups as intended
  • Expected Behavior: Clicking palette buttons should change the active palette for tile8 graphics
  • Actual Behavior: Button clicks do not trigger palette updates correctly
  • Status: Needs implementation of proper palette switching logic

3. Color Alignment Between Canvases

  • Problem: Colors in tile8 source canvas don't match tile16 editor canvas
  • Impact: Inconsistent visual feedback during tile editing
  • Related To: Issues #1 and #2 above
  • Status: Blocked by palette button functionality

Current Status Summary

Component Status Notes
Crash Prevention ✅ Complete No SIGBUS errors
Three-Column Layout ✅ Complete Fully functional
Zoom Controls ✅ Complete All canvases working
Tile16 Editor Palette ✅ Complete Shows correct colors
Tile8 Source Palette ⚠️ In Progress Incorrect colors displayed
Palette Button Updates ⚠️ In Progress Not updating palettes
Sheet-Aware Logic ⚠️ Partial Foundation in place, needs fixes
Overall Color System ⚠️ In Progress Ongoing development

Future Enhancements

  1. Zoom Presets: Add preset buttons (1x, 2x, 4x) for quick zoom levels
  2. Zoom Sync: Option to sync zoom levels across related canvases
  3. Canvas Layout Persistence: Save user's preferred column widths and zoom levels
  4. Keyboard Shortcuts: Add +/- keys for zoom control
  5. Mouse Wheel Zoom: Ctrl+Wheel to zoom canvases
  6. Performance Optimization: Cache palette calculations for frequently used combinations
  7. Extended Debug Tools: Add pixel-level color comparison tools
  8. Palette Preview: Real-time preview of palette changes before applying
  9. Batch Operations: Apply palette changes to multiple tiles simultaneously

Maintenance Notes

  1. Palette Structure Changes: Update GetActualPaletteSlot() if overworld palette structure changes
  2. Sheet Detection: Verify GetSheetIndexForTile8() logic if graphics organization changes
  3. ProcessGraphicsBuffer: Monitor for changes in pixel data offset logic
  4. Static Zoom Variables: User preferences preserved across sessions

Next Steps

Immediate Priorities

  1. Fix Tile8 Source Canvas Palette Application
    • Investigate graphics buffer processing for area graphics
    • Ensure consistent palette application across all graphics sources
    • Test with different area graphics combinations
  2. Implement Palette Button Update Logic
    • Add proper event handling for palette button clicks
    • Trigger palette refresh for tile8 source canvas
    • Update visual feedback to show active palette
  3. Verify Color Consistency
    • Ensure tile8 source colors match tile16 editor
    • Test sheet-specific palette regions
    • Validate color mapping for all graphics sheets

Investigation Areas

  • Review current_gfx_individual_ palette application
  • Check palette group management for tile8 source
  • Verify graphics buffer offset logic for area graphics
  • Test palette switching across different overworld areas

Development Status: January 2025
Status: Partial implementation - UI complete, palette system in progress
Not yet ready for production use - active development ongoing