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

315 lines
10 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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.
```cpp
// 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**:
```cpp
// 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**:
```cpp
// 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
```bash
# 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
```bash
# 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+