315 lines
10 KiB
Markdown
315 lines
10 KiB
Markdown
# 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+
|