- Updated the gfx_optimizations_complete.md to streamline the overview and implementation details of graphics optimizations, removing completed status indicators and enhancing clarity on future recommendations. - Introduced imgui_widget_testing_guide.md, detailing the usage of YAZE's ImGui testing infrastructure for automated GUI testing, including architecture, integration steps, and best practices. - Created ollama_integration_status.md to document the current status of Ollama integration, highlighting completed tasks, ongoing issues, and next steps for improvement. - Revised developer_guide.md to reflect the latest updates in AI provider configuration and input methods for the z3ed agent, ensuring clarity on command-line flags and supported providers.
7.1 KiB
Dungeon Editor Developer Guide
1. Implementation Plan
Goal: Implement fully functional dungeon room editing based on ZScream's proven approach.
1.1. Current State Analysis
- Working: Room header loading, basic class structures (
Room,RoomObject), graphics loading, and UI framework. - Not Working: Object parsing, drawing, placement, and saving. The core issue is the incomplete implementation of the 3-byte object encoding/decoding scheme and the failure to render object tiles to the background buffer.
1.2. ZScream's Approach
ZScream's implementation relies on several key concepts that need to be ported:
- Object Encoding: Three different 3-byte encoding formats for objects based on their ID range (Type 1, Type 2, Type 3).
- Layer Separation: Objects are organized into three layers (BG1, BG2, BG3) separated by
0xFFFFmarkers in the ROM. - Object Loading: A loop parses the object data, decodes each 3-byte entry based on its type, and handles layer and door markers.
- Object Drawing: Each object's constituent tiles are drawn to the correct background buffer (
tilesBg1BufferortilesBg2Buffer), which is then used to render the final room image.
1.3. Implementation Tasks
- Core Object System (High Priority):
- Implement the three different object encoding and decoding schemes.
- Enhance the room object parser to correctly handle layers and door sections.
- Implement tile loading for objects from the ROM's subtype tables.
- Create an object drawing system that renders the loaded tiles to the correct background buffer.
- Editor UI Integration (Medium Priority):
- Implement object placement, selection, and drag-and-drop on the canvas.
- Create UI panels for editing object properties (position, size, layer).
- Save System (High Priority):
- Implement the serialization of room objects back into the 3-byte ROM format, respecting layers and markers.
- Implement the logic to write the serialized data back to the ROM, handling potential room size expansion.
2. Graphics Rendering Pipeline
This section provides a comprehensive analysis of how the dungeon editor renders room graphics.
2.1. Architecture Diagram
┌─────────────────────────────────────────────────────────────────┐
│ ROM Data │
│ ┌────────────────────────┐ ┌──────────────────────────────────┐│
│ │ Room Headers │ │ Dungeon Palettes ││
│ │ - Palette ID │ │ - dungeon_main[id] ││
│ │ - Blockset ID │ │ - sprites_aux1[id] ││
│ └────────────────────────┘ └──────────────────────────────────┘│
└───────────────────────────┬─────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Room Loading (room.cc) │
│ ├─ Load 16 blocks (graphics sheets) │
│ └─ Copy graphics to a 32KB buffer (`current_gfx16_`) │
└───────────────────────────┬─────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Room::RenderRoomGraphics() Pipeline │
│ │
│ Step 1: DrawFloor() on BG1 and BG2 buffers │
│ └─ Populates buffers with repeating floor tile pattern. │
│ │
│ Step 2: RenderObjectsToBackground() │
│ └─ Iterates room objects and draws their tiles into the BG1/BG2 buffers.│
│ │
│ Step 3: DrawBackground() on BG1 and BG2 │
│ └─ Converts tile words in buffers to 8bpp indexed pixel data in a Bitmap.│
│ │
│ Step 4: Apply Palette & Create/Update Texture │
│ ├─ Get dungeon_main palette for the room. │
│ ├─ Apply palette to the Bitmap. │
│ └─ Create or update an SDL_Texture from the paletted Bitmap. │
└─────────────────────────────────────────────────────────────────┘
2.2. Blank Canvas Bug: Root Cause Analysis
A critical "blank canvas" bug was diagnosed and fixed. The root cause was multifaceted:
-
Missing Object Rendering: The
RenderObjectsToBackground()step was missing entirely. The background buffers only contained the floor pattern, so walls and objects were never drawn.- Fix: Implemented
RenderObjectsToBackground()to iterate through all loaded room objects and draw their constituent tiles into the correct background buffer (bg1orbg2).
- Fix: Implemented
-
Missing Palette Application: The indexed-pixel
Bitmapwas being converted to a texture without its palette. SDL had no information to map the color indices to actual colors, resulting in a blank texture.- Fix: Added a call to
bitmap.SetPaletteWithTransparent()before theCreateAndRenderBitmap()orUpdateBitmap()call.
- Fix: Added a call to
-
Incorrect Tile Word Format: The floor drawing logic was writing only the tile ID to the buffer, discarding the necessary palette information within the 16-bit tile word.
- Fix: Modified the code to use
gfx::TileInfoToWord()to ensure the full 16-bit value, including palette index, was written.
- Fix: Modified the code to use
-
Incorrect Palette ID: The system was hardcoded to use palette
0for all rooms, causing most dungeons to render with incorrect, "gargoyle-y" colors.- Fix: Modified the code to use the specific
paletteID loaded from each room's header.
- Fix: Modified the code to use the specific
Key Takeaway: The entire rendering pipeline, from buffer population to palette application, must be executed in the correct order for graphics to appear.