Files
yaze/docs/internal/hand-off/HANDOFF_DUNGEON_RENDERING.md

10 KiB
Raw Blame History

Dungeon Tile Rendering - Progress & Next Steps

Last Updated: 2025-12-01 Status: Major Progress - Floor/Walls working, object mappings expanded

Summary

Fixed multiple critical bugs in dungeon tile rendering:

  1. Graphics sheet loading order - Sheets now load before buffer copy
  2. Missing object mappings - Added 168 previously unmapped object IDs (0x50-0xF7)

Floor tiles, walls, and most objects now render with correct graphics. Some objects still have sizing or transparency issues that need attention.


Completed Fixes

Fix 1: Graphics Sheet Loading Order (984d3e02cd)

Root Cause: blocks_[] array was read BEFORE LoadRoomGraphics() initialized it.

// Before (broken): CopyRoomGraphicsToBuffer used stale blocks_[]
// After (fixed): LoadRoomGraphics(blockset) called FIRST
void Room::RenderRoomGraphics() {
  if (graphics_dirty_) {
    LoadRoomGraphics(blockset);    // Initialize blocks_[] FIRST
    CopyRoomGraphicsToBuffer();    // Now uses correct sheet IDs
    graphics_dirty_ = false;
  }
}

Fix 2: Missing Object-to-Routine Mappings (1d77f34f99)

Root Cause: Objects 0x50-0xF7 had no draw routine mappings, falling through to 1x1 fallback.

Added mappings for 168 object IDs:

Range Count Description
0x50-0x5F 16 Floor/decoration objects
0x6E-0x6F 2 Edge objects
0x70-0x7F 16 Mixed 4x4, 2x2, 2x4
0x80-0x8F 16 4x2, 4x3, 2x3 objects
0x90-0x9F 16 4x2, 2x2, 1x1 objects
0xA0-0xAF 16 Mostly 1x1
0xB0-0xBF 16 Mixed sizes
0xC0-0xCF 16 1x1, 4x2, 4x4
0xD0-0xDF 16 1x1, 4x2, 4x4, 2x2
0xE0-0xF7 24 4x2 and 1x1

Fix 3: MusicEditor Crash (984d3e02cd)

Root Cause: ImGui::GetID() called without valid window context during initialization. Fix: Deferred ClassId initialization to first Update() call.


Remaining Issues

1. Objects with Excessive Transparency

Symptoms: Objects render with mostly transparent tiles, appearing as partial/broken shapes.

Likely Causes:

  • Tile data contains pixel value 0 (transparent) for most pixels
  • Palette index mismatch - pixels reference wrong sub-palette
  • Tile ID points to blank/unused tile in graphics buffer

Debug Strategy:

// In DrawTileToBitmap, log pixel distribution
int transparent_count = 0, opaque_count = 0;
for (int py = 0; py < 8; py++) {
  for (int px = 0; px < 8; px++) {
    if (pixel == 0) transparent_count++;
    else opaque_count++;
  }
}
printf("[Tile %d] transparent=%d opaque=%d\n", tile_info.id_, transparent_count, opaque_count);

2. Objects with Incorrect Sizes

Symptoms: Objects appear smaller or larger than expected.

Likely Causes:

  • Draw routine assigned doesn't match object's tile layout
  • Tile count in kSubtype1TileLengths incorrect for object
  • Size repetition count wrong (size+1 vs size+7 etc.)

Debug Strategy:

// Log object dimensions vs expected
printf("[Object 0x%03X] routine=%d expected_tiles=%d actual=%zu size=%d\n",
       obj.id_, routine_id, expected_tile_count, tiles.size(), obj.size_);

3. Subtype 2/3 Objects Need Attention

Type 2 (0x100-0x13F) and Type 3 (0xF80-0xFFF) objects use different ROM tables and may have unique tile layouts.

Note: Type 2 size = 0 is intentional - these are fixed-size objects (chests, stairs) that don't repeat.

4. Tile Count Table Accuracy

The kSubtype1TileLengths[0xF8] table determines how many tiles to read per object. Some entries may be incorrect.

Verification Method: Compare with ZScream's DungeonObjectData.cs and ALTTP disassembly.


Testing Strategy

Manual Testing Checklist

  1. Room 000 (Ganon's Room): Verify floor pattern, walls, center platform
  2. Room 104: Check grass/garden tiles, walls, water features
  3. Room with chests: Verify Type 2 objects (chests render correctly)
  4. Room with stairs: Check spiral stairs, layer switching objects
  5. Room with pots: Verify pot objects (0x160-0x16F range)

Systematic Testing Approach

# Test specific rooms via CLI
./yaze --rom_file=zelda3.sfc --editor=Dungeon

# Add this to room.cc for batch testing
for (int room_id = 0; room_id < 296; room_id++) {
  LoadRoom(room_id);
  int missing_objects = CountObjectsWithFallbackDrawing();
  if (missing_objects > 0) {
    printf("Room %d: %d objects using fallback\n", room_id, missing_objects);
  }
}

Reference Rooms for Testing

Room ID Description Key Objects
0 Ganon's Room Floor tiles, walls, platform
2 Sanctuary Walls, altar, decoration
18 Eastern Palace Pillars, statues
89 Desert Palace Sand tiles, pillars
104 Garden Grass, bushes, walls

UI/UX Improvements for Dungeon Editor

Object Selection Enhancements

1. Object Palette Panel

┌─────────────────────────────────────┐
│ Object Palette                  [x] │
├─────────────────────────────────────┤
│ Category: [Walls ▼]                 │
│                                     │
│ ┌───┬───┬───┬───┐                   │
│ │0x0│0x1│0x2│0x3│  ← Visual tiles   │
│ └───┴───┴───┴───┘                   │
│ ┌───┬───┬───┬───┐                   │
│ │0x4│0x5│0x6│0x7│                   │
│ └───┴───┴───┴───┘                   │
│                                     │
│ Selected: Wall Corner (0x07)        │
│ Size: 2x2 tiles, Repeatable: Yes    │
└─────────────────────────────────────┘

2. Object Categories

  • Walls: 0x00-0x20 (horizontal/vertical walls, corners)
  • Floors: 0x33, 0x49-0x4F (floor tiles, patterns)
  • Decoration: 0x36-0x3E (statues, pillars, tables)
  • Interactive: 0x100+ (chests, switches, stairs)
  • Special: 0xF80+ (water, Somaria paths)

3. Object Inspector Panel

┌─────────────────────────────────────┐
│ Object Properties                   │
├─────────────────────────────────────┤
│ ID: 0x07        Type: Wall Corner   │
│ Position: (12, 8)  Size: 3          │
│ Layer: BG1      All BGs: No         │
│                                     │
│ Tile Preview:                       │
│ ┌───┬───┐                           │
│ │ A │ B │  A=0xC8, B=0xC2           │
│ ├───┼───┤  C=0xCB, D=0xCE           │
│ │ C │ D │                           │
│ └───┴───┘                           │
│                                     │
│ [Edit Tiles] [Copy] [Delete]        │
└─────────────────────────────────────┘

Canvas Improvements

1. Object Highlighting

  • Hover: Light outline around object bounds
  • Selected: Solid highlight with resize handles
  • Multi-select: Dashed outline for group selection

2. Grid Overlay Options

  • 8x8 tile grid (fine)
  • 16x16 block grid (standard)
  • 32x32 supertile grid (layout)

3. Layer Visibility

  • BG1 toggle (walls, floors)
  • BG2 toggle (overlays, transparency)
  • Objects only view
  • Collision overlay

Workflow Improvements

1. Object Placement Mode

[Draw] [Select] [Move] [Resize] [Delete]
         │
         └── Click to select objects
             Drag to move
             Shift+drag to copy

2. Object Size Adjustment

  • Drag object edge to resize (increases size repetition)
  • Ctrl+scroll to adjust size value
  • Number keys 1-9 for quick size presets

3. Undo/Redo System

  • Track object add/remove/move/resize
  • Snapshot-based for complex operations
  • 50-step undo history

Architecture Reference

Graphics Buffer Pipeline

ROM (3BPP compressed sheets)
    ↓ SnesTo8bppSheet()
gfx_sheets_ (8BPP, 16 base sheets × 128×32)
    ↓ CopyRoomGraphicsToBuffer()
current_gfx16_ (room-specific 64KB buffer)
    ↓ ObjectDrawer::DrawTileToBitmap()
bg1_bitmap / bg2_bitmap (512×512 room canvas)

Object Subtypes

Subtype ID Range ROM Table Description
1 0x00-0xF7 $01:8000 Standard objects (walls, floors)
2 0x100-0x13F $01:83F0 Special objects (chests, stairs)
3 0xF80-0xFFF $01:84F0 Complex objects (water, Somaria)

Draw Routine Reference

Routine Pattern Objects
0 2x2 rightwards (1-15 or 32) 0x00
1 2x4 rightwards 0x01-0x02
4 2x2 rightwards (1-16) 0x07-0x08
7 2x2 downwards (1-15 or 32) 0x60
8 4x2 downwards 0x61-0x62
16 4x4 block 0x33, 0x4D-0x4F, 0x70+
25 1x1 solid Single-tile objects

Debug Commands

# Run dungeon editor with debug output
./yaze --rom_file=zelda3.sfc --editor=Dungeon --debug

# Filter debug output for specific issues
./yaze ... 2>&1 | grep -E "Object|DrawTile|ParseSubtype"

# Check for objects using fallback drawing
./yaze ... 2>&1 | grep "fallback 1x1"

Future Enhancements

Short-term (Next Sprint)

  1. Fix remaining transparent object issues
  2. Add object category filtering in UI
  3. Implement object copy/paste

Medium-term

  1. Visual object palette with rendered previews
  2. Room template system (save/load object layouts)
  3. Object collision visualization

Long-term

  1. Drag-and-drop object placement from palette
  2. Smart object snapping (align to grid, other objects)
  3. Room comparison tool (diff between ROMs)
  4. Batch object editing (multi-select properties)

Files Reference

File Purpose
room.cc Room loading, graphics management
room_object.cc Object encoding/decoding
object_parser.cc Tile data lookup from ROM
object_drawer.cc Draw routine implementations
dungeon_editor_v2.cc Editor UI and interaction
dungeon_canvas_viewer.cc Canvas rendering

External References

  • ZScream's DungeonObjectData.cs - Object data reference
  • ALTTP disassembly bank_00.asm - RoomDrawObjectData at $00:9B52
  • ALTTP disassembly bank_01.asm - Draw routines at $01:8000+