backend-infra-engineer: Post v0.3.9-hotfix7 snapshot (build cleanup)
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
# Gemini Pro 3 Build Setup Guide
|
||||
|
||||
Quick iteration setup for maximizing Gemini's effectiveness on YAZE.
|
||||
|
||||
## One-Time Setup
|
||||
|
||||
```bash
|
||||
# Use the dedicated Gemini build script (recommended)
|
||||
./scripts/gemini_build.sh
|
||||
|
||||
# Or manually configure with the Gemini preset
|
||||
cmake --preset mac-gemini
|
||||
|
||||
# Verify setup succeeded
|
||||
ls build_gemini/compile_commands.json
|
||||
```
|
||||
|
||||
## Fast Rebuild Cycle (~30s-2min)
|
||||
|
||||
```bash
|
||||
# Recommended: Use the build script
|
||||
./scripts/gemini_build.sh # Build yaze (default)
|
||||
./scripts/gemini_build.sh yaze_test # Build tests
|
||||
./scripts/gemini_build.sh --fresh # Clean reconfigure
|
||||
|
||||
# Or use cmake directly
|
||||
cmake --build build_gemini -j8 --target yaze
|
||||
|
||||
# Rebuild editor library (for src/app/editor/ changes)
|
||||
cmake --build build_gemini -j8 --target yaze_editor
|
||||
|
||||
# Rebuild zelda3 library (for src/zelda3/ changes)
|
||||
cmake --build build_gemini -j8 --target yaze_lib
|
||||
```
|
||||
|
||||
## Quick Validation (~2-3min)
|
||||
|
||||
```bash
|
||||
# Run stable tests (unit + integration, no ROM required)
|
||||
ctest --test-dir build_gemini -L stable -j4 --output-on-failure
|
||||
|
||||
# Run GUI smoke tests only (~1min)
|
||||
ctest --test-dir build_gemini -L gui --output-on-failure
|
||||
|
||||
# Run specific test by name
|
||||
ctest --test-dir build_gemini -R "OverworldRegression" --output-on-failure
|
||||
```
|
||||
|
||||
## Full Validation (when confident)
|
||||
|
||||
```bash
|
||||
# All tests
|
||||
ctest --test-dir build_gemini --output-on-failure -j4
|
||||
```
|
||||
|
||||
## Format Check (before committing)
|
||||
|
||||
```bash
|
||||
# Check format without modifying
|
||||
cmake --build build_gemini --target format-check
|
||||
|
||||
# Auto-format all code
|
||||
cmake --build build_gemini --target format
|
||||
```
|
||||
|
||||
## Key Directories
|
||||
|
||||
| Path | Purpose |
|
||||
|------|---------|
|
||||
| `src/app/editor/overworld/` | Overworld editor modules (8 files) |
|
||||
| `src/zelda3/overworld/` | Overworld data models |
|
||||
| `src/zelda3/dungeon/` | Dungeon data models |
|
||||
| `src/app/editor/dungeon/` | Dungeon editor components |
|
||||
| `test/unit/zelda3/` | Unit tests for zelda3 logic |
|
||||
| `test/e2e/` | GUI E2E tests |
|
||||
|
||||
## Iteration Strategy
|
||||
|
||||
1. **Make changes** to target files
|
||||
2. **Rebuild** with `cmake --build build_gemini -j8 --target yaze`
|
||||
3. **Test** with `ctest --test-dir build_gemini -L stable -j4`
|
||||
4. **Repeat** until all tests pass
|
||||
|
||||
## Common Issues
|
||||
|
||||
### Build fails with "target not found"
|
||||
```bash
|
||||
# Reconfigure (CMakeLists.txt changed)
|
||||
./scripts/gemini_build.sh --fresh
|
||||
# Or: cmake --preset mac-gemini --fresh
|
||||
```
|
||||
|
||||
### Tests timeout
|
||||
```bash
|
||||
# Run with longer timeout
|
||||
ctest --test-dir build_gemini -L stable --timeout 300
|
||||
```
|
||||
|
||||
### Need to see test output
|
||||
```bash
|
||||
ctest --test-dir build_gemini -L stable -V # Verbose
|
||||
```
|
||||
@@ -0,0 +1,245 @@
|
||||
# Gemini Pro 3 Antigravity - YAZE Development Session
|
||||
|
||||
## Context
|
||||
|
||||
You are working on **YAZE** (Yet Another Zelda3 Editor), a C++23 cross-platform ROM editor for The Legend of Zelda: A Link to the Past.
|
||||
|
||||
**Your previous session accomplished:**
|
||||
- Fixed ASM version check regression using `OverworldVersionHelper` abstraction
|
||||
- Improved texture queueing in `Tile16Editor`
|
||||
- The insight: `0xFF >= 3` evaluates true, incorrectly treating vanilla ROMs as v3
|
||||
|
||||
**Reference documentation available:**
|
||||
- `docs/internal/agents/gemini-overworld-system-reference.md` - Overworld architecture
|
||||
- `docs/internal/agents/gemini-dungeon-system-reference.md` - Dungeon architecture
|
||||
- `docs/internal/agents/gemini-build-setup.md` - Build commands
|
||||
|
||||
---
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
# 1. Setup build directory (use dedicated dir, not user's build/)
|
||||
cmake --preset mac-dbg -B build_gemini
|
||||
|
||||
# 2. Build editor
|
||||
cmake --build build_gemini -j8 --target yaze
|
||||
|
||||
# 3. Run stable tests
|
||||
ctest --test-dir build_gemini -L stable -j4 --output-on-failure
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task Categories
|
||||
|
||||
### Category A: Overworld Editor Gaps
|
||||
|
||||
#### A1. Texture Queueing TODOs (6 locations)
|
||||
**File:** `src/app/editor/overworld/overworld_editor.cc`
|
||||
**Lines:** 1392, 1397, 1740, 1809, 1819, 1962
|
||||
|
||||
These commented-out Renderer calls need to be converted to the Arena queue system:
|
||||
|
||||
```cpp
|
||||
// BEFORE (blocking - commented out)
|
||||
// Renderer::Get().RenderBitmap(&bitmap_);
|
||||
|
||||
// AFTER (non-blocking)
|
||||
gfx::Arena::Get().QueueTextureCommand(gfx::TextureCommand{
|
||||
.operation = gfx::TextureOperation::kCreate,
|
||||
.bitmap = &bitmap_,
|
||||
.priority = gfx::TexturePriority::kHigh
|
||||
});
|
||||
```
|
||||
|
||||
#### A2. Unimplemented Editor Methods
|
||||
**File:** `src/app/editor/overworld/overworld_editor.h` lines 82-87
|
||||
|
||||
| Method | Status | Complexity |
|
||||
|--------|--------|------------|
|
||||
| `Undo()` | Returns `UnimplementedError` | Medium |
|
||||
| `Redo()` | Returns `UnimplementedError` | Medium |
|
||||
| `Cut()` | Returns `UnimplementedError` | Simple |
|
||||
| `Find()` | Returns `UnimplementedError` | Medium |
|
||||
|
||||
#### A3. Entity Popup Static Variable Bug
|
||||
**File:** `src/app/editor/overworld/entity.cc`
|
||||
|
||||
Multiple popups use `static` variables that persist across calls, causing state contamination:
|
||||
|
||||
```cpp
|
||||
// CURRENT (BUG)
|
||||
bool DrawExitEditorPopup() {
|
||||
static bool set_done = false; // Persists! Wrong entity data shown
|
||||
static int doorType = ...;
|
||||
}
|
||||
|
||||
// FIX: Use local variables or proper state management
|
||||
bool DrawExitEditorPopup(ExitEditorState& state) {
|
||||
// state is passed in, not static
|
||||
}
|
||||
```
|
||||
|
||||
#### A4. Exit Editor Unconnected UI
|
||||
**File:** `src/app/editor/overworld/entity.cc` lines 216-264
|
||||
|
||||
UI elements exist but aren't connected to data:
|
||||
- Door type editing (Wooden, Bombable, Sanctuary, Palace)
|
||||
- Door X/Y position
|
||||
- Center X/Y, Link posture, sprite/BG GFX, palette
|
||||
|
||||
---
|
||||
|
||||
### Category B: Dungeon Object Rendering
|
||||
|
||||
#### B1. BothBG Dual-Layer Stubs (4 locations)
|
||||
**File:** `src/zelda3/dungeon/object_drawer.cc`
|
||||
|
||||
These routines should draw to BOTH BG1 and BG2 but only accept one buffer:
|
||||
|
||||
| Line | Routine | Status |
|
||||
|------|---------|--------|
|
||||
| 375-381 | `DrawRightwards2x4spaced4_1to16_BothBG` | STUB |
|
||||
| 437-442 | `DrawDiagonalAcute_1to16_BothBG` | STUB |
|
||||
| 444-449 | `DrawDiagonalGrave_1to16_BothBG` | STUB |
|
||||
| 755-761 | `DrawDownwards4x2_1to16_BothBG` | STUB |
|
||||
|
||||
**Fix:** Change signature to accept both buffers:
|
||||
```cpp
|
||||
// BEFORE
|
||||
void DrawRightwards2x4spaced4_1to16_BothBG(
|
||||
const RoomObject& obj, gfx::BackgroundBuffer& bg, ...);
|
||||
|
||||
// AFTER
|
||||
void DrawRightwards2x4spaced4_1to16_BothBG(
|
||||
const RoomObject& obj,
|
||||
gfx::BackgroundBuffer& bg1,
|
||||
gfx::BackgroundBuffer& bg2, ...);
|
||||
```
|
||||
|
||||
#### B2. Diagonal Routines Unclear Logic
|
||||
**File:** `src/zelda3/dungeon/object_drawer.cc` lines 401-435
|
||||
|
||||
Issues with `DrawDiagonalAcute_1to16` and `DrawDiagonalGrave_1to16`:
|
||||
- Hardcoded `size + 6` and 5 iterations (why?)
|
||||
- Coordinate formula `obj.y_ + (i - s)` can produce negative Y
|
||||
- No bounds checking
|
||||
- Only uses 4 tiles from larger span
|
||||
|
||||
#### B3. CustomDraw and DoorSwitcherer Stubs
|
||||
**File:** `src/zelda3/dungeon/object_drawer.cc`
|
||||
- Lines 524-532: `CustomDraw` - only draws first tile
|
||||
- Lines 566-575: `DrawDoorSwitcherer` - only draws first tile
|
||||
|
||||
#### B4. Unknown Object Names (30+ items)
|
||||
**File:** `src/zelda3/dungeon/room_object.h`
|
||||
|
||||
See `gemini-dungeon-system-reference.md` section 7 for full list of objects needing in-game verification.
|
||||
|
||||
---
|
||||
|
||||
### Category C: Already Complete (Verification Only)
|
||||
|
||||
#### C1. Tile16Editor Undo/Redo - COMPLETE
|
||||
**File:** `src/app/editor/overworld/tile16_editor.cc`
|
||||
- `SaveUndoState()` at lines 547, 1476, 1511, 1546, 1586, 1620
|
||||
- `Undo()` / `Redo()` at lines 1707-1760
|
||||
- Ctrl+Z/Ctrl+Y at lines 224-231
|
||||
- UI button at line 1101
|
||||
|
||||
**No work needed** - just verify it works.
|
||||
|
||||
#### C2. Entity Deletion Pattern - CORRECT
|
||||
**File:** `src/app/editor/overworld/entity.cc` line 319
|
||||
|
||||
The TODO comment is misleading. The `deleted` flag pattern IS correct for ROM editors:
|
||||
- Entities at fixed ROM offsets can't be "removed"
|
||||
- `entity_operations.cc` reuses deleted slots
|
||||
- Just clarify the comment if desired
|
||||
|
||||
---
|
||||
|
||||
## Prioritized Task List
|
||||
|
||||
### Phase 1: High Impact (45-60 min)
|
||||
1. **A1** - Texture queueing (6 TODOs) - Prevents UI freezes
|
||||
2. **B1** - BothBG dual-layer stubs (4 routines) - Completes dungeon rendering
|
||||
|
||||
### Phase 2: Medium Impact (30-45 min)
|
||||
3. **A3** - Entity popup static variable bug - Fixes data corruption
|
||||
4. **B2** - Diagonal routine logic - Fixes rendering artifacts
|
||||
|
||||
### Phase 3: Polish (30+ min)
|
||||
5. **A2** - Implement Undo/Redo for OverworldEditor
|
||||
6. **A4** - Connect exit editor UI to data
|
||||
7. **B3** - Implement CustomDraw/DoorSwitcherer
|
||||
|
||||
### Stretch Goals
|
||||
8. **B4** - Verify unknown object names (requires game testing)
|
||||
9. E2E cinematic tests (see `docs/internal/testing/dungeon-gui-test-design.md`)
|
||||
|
||||
---
|
||||
|
||||
## Code Patterns
|
||||
|
||||
### Texture Queue (Use This!)
|
||||
```cpp
|
||||
gfx::Arena::Get().QueueTextureCommand(gfx::TextureCommand{
|
||||
.operation = gfx::TextureOperation::kCreate, // or kUpdate
|
||||
.bitmap = &bitmap_,
|
||||
.priority = gfx::TexturePriority::kHigh
|
||||
});
|
||||
```
|
||||
|
||||
### Version-Aware Code
|
||||
```cpp
|
||||
auto version = OverworldVersionHelper::GetVersion(*rom_);
|
||||
if (OverworldVersionHelper::SupportsAreaEnum(version)) {
|
||||
// v3+ only
|
||||
}
|
||||
```
|
||||
|
||||
### Error Handling
|
||||
```cpp
|
||||
absl::Status MyFunction() {
|
||||
ASSIGN_OR_RETURN(auto data, LoadData());
|
||||
RETURN_IF_ERROR(ProcessData(data));
|
||||
return absl::OkStatus();
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Validation
|
||||
|
||||
```bash
|
||||
# After each change
|
||||
cmake --build build_gemini -j8 --target yaze
|
||||
ctest --test-dir build_gemini -L stable -j4 --output-on-failure
|
||||
|
||||
# Before finishing
|
||||
cmake --build build_gemini --target format-check
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Success Metrics
|
||||
|
||||
- [ ] `grep "TODO.*texture" src/app/editor/overworld/overworld_editor.cc` returns nothing
|
||||
- [ ] BothBG routines accept both buffer parameters
|
||||
- [ ] Static variable bug in entity popups fixed
|
||||
- [ ] `ctest -L stable` passes 100%
|
||||
- [ ] Code formatted
|
||||
|
||||
---
|
||||
|
||||
## File Quick Reference
|
||||
|
||||
| System | Key Files |
|
||||
|--------|-----------|
|
||||
| Overworld Editor | `src/app/editor/overworld/overworld_editor.cc` (3,204 lines) |
|
||||
| Entity UI | `src/app/editor/overworld/entity.cc` (491 lines) |
|
||||
| Tile16 Editor | `src/app/editor/overworld/tile16_editor.cc` (2,584 lines) |
|
||||
| Object Drawer | `src/zelda3/dungeon/object_drawer.cc` (972 lines) |
|
||||
| Room Object | `src/zelda3/dungeon/room_object.h` (633 lines) |
|
||||
@@ -0,0 +1,376 @@
|
||||
# YAZE Overworld System - Complete Technical Reference
|
||||
|
||||
Comprehensive reference for AI agents working on the YAZE Overworld editing system.
|
||||
|
||||
---
|
||||
|
||||
## 1. Architecture Overview
|
||||
|
||||
### File Structure
|
||||
```
|
||||
src/zelda3/overworld/
|
||||
├── overworld.h/cc # Main Overworld class (2,500+ lines)
|
||||
├── overworld_map.h/cc # Individual map (OverworldMap class)
|
||||
├── overworld_version_helper.h # Version detection & feature gates
|
||||
├── overworld_item.h/cc # Item entities
|
||||
├── overworld_entrance.h # Entrance/hole entities
|
||||
├── overworld_exit.h # Exit entities
|
||||
|
||||
src/app/editor/overworld/
|
||||
├── overworld_editor.h/cc # Main editor (3,204 lines)
|
||||
├── map_properties.cc # MapPropertiesSystem (1,759 lines)
|
||||
├── tile16_editor.h/cc # Tile16Editor (2,584 lines)
|
||||
├── entity.cc # Entity UI popups (491 lines)
|
||||
├── entity_operations.cc # Entity CRUD helpers (239 lines)
|
||||
├── overworld_entity_renderer.cc # Entity drawing (151 lines)
|
||||
├── scratch_space.cc # Tile storage utilities (444 lines)
|
||||
```
|
||||
|
||||
### Data Model Hierarchy
|
||||
```
|
||||
Rom (raw data)
|
||||
└── Overworld (coordinator)
|
||||
├── tiles16_[] (3,752-4,096 Tile16 definitions)
|
||||
├── tiles32_unique_[] (up to 8,864 Tile32 definitions)
|
||||
├── overworld_maps_[160] (individual map screens)
|
||||
│ └── OverworldMap
|
||||
│ ├── area_graphics_, area_palette_
|
||||
│ ├── bitmap_data_[] (256x256 rendered pixels)
|
||||
│ └── current_gfx_[] (graphics buffer)
|
||||
├── all_entrances_[] (~129 entrance points)
|
||||
├── all_holes_[] (~19 hole entrances)
|
||||
├── all_exits_[] (~79 exit points)
|
||||
├── all_items_[] (collectible items)
|
||||
└── all_sprites_[3][] (sprites per game state)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. ZSCustomOverworld Version System
|
||||
|
||||
### Version Detection
|
||||
```cpp
|
||||
// ROM address for version byte
|
||||
constexpr int OverworldCustomASMHasBeenApplied = 0x140145;
|
||||
|
||||
// Version values
|
||||
0xFF = Vanilla ROM (unpatched)
|
||||
0x01 = ZSCustomOverworld v1
|
||||
0x02 = ZSCustomOverworld v2
|
||||
0x03 = ZSCustomOverworld v3+
|
||||
```
|
||||
|
||||
### Feature Matrix
|
||||
|
||||
| Feature | Vanilla | v1 | v2 | v3 |
|
||||
|---------|---------|----|----|-----|
|
||||
| Basic map editing | Y | Y | Y | Y |
|
||||
| Large maps (2x2) | Y | Y | Y | Y |
|
||||
| Expanded pointers (0x130000+) | - | Y | Y | Y |
|
||||
| Custom BG colors | - | - | Y | Y |
|
||||
| Main palette per area | - | - | Y | Y |
|
||||
| Wide areas (2x1) | - | - | - | Y |
|
||||
| Tall areas (1x2) | - | - | - | Y |
|
||||
| Custom tile GFX (8 per map) | - | - | - | Y |
|
||||
| Animated GFX | - | - | - | Y |
|
||||
| Subscreen overlays | - | - | - | Y |
|
||||
|
||||
### OverworldVersionHelper API
|
||||
```cpp
|
||||
// src/zelda3/overworld/overworld_version_helper.h
|
||||
|
||||
enum class OverworldVersion { kVanilla=0, kZSCustomV1=1, kZSCustomV2=2, kZSCustomV3=3 };
|
||||
enum class AreaSizeEnum { SmallArea=0, LargeArea=1, WideArea=2, TallArea=3 };
|
||||
|
||||
// Detection
|
||||
static OverworldVersion GetVersion(const Rom& rom);
|
||||
static uint8_t GetAsmVersion(const Rom& rom);
|
||||
|
||||
// Feature gates (use these, not raw version checks!)
|
||||
static bool SupportsAreaEnum(OverworldVersion v); // v3 only
|
||||
static bool SupportsExpandedSpace(OverworldVersion v); // v1+
|
||||
static bool SupportsCustomBGColors(OverworldVersion v);// v2+
|
||||
static bool SupportsCustomTileGFX(OverworldVersion v); // v3 only
|
||||
static bool SupportsAnimatedGFX(OverworldVersion v); // v3 only
|
||||
static bool SupportsSubscreenOverlay(OverworldVersion v); // v3 only
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Tile System Architecture
|
||||
|
||||
### Tile Hierarchy
|
||||
```
|
||||
Tile8 (8x8 pixels) - Base SNES tile
|
||||
↓
|
||||
Tile16 (16x16 pixels) - 2x2 grid of Tile8s
|
||||
↓
|
||||
Tile32 (32x32 pixels) - 2x2 grid of Tile16s
|
||||
↓
|
||||
Map Screen (256x256 pixels) - 8x8 grid of Tile32s
|
||||
```
|
||||
|
||||
### Tile16 Structure
|
||||
```cpp
|
||||
// src/app/gfx/types/snes_tile.h
|
||||
|
||||
class TileInfo {
|
||||
uint16_t id_; // 9-bit tile8 ID (0-511)
|
||||
uint8_t palette_; // 3-bit palette (0-7)
|
||||
bool over_; // Priority flag
|
||||
bool vertical_mirror_; // Y-flip
|
||||
bool horizontal_mirror_; // X-flip
|
||||
};
|
||||
|
||||
class Tile16 {
|
||||
TileInfo tile0_; // Top-left
|
||||
TileInfo tile1_; // Top-right
|
||||
TileInfo tile2_; // Bottom-left
|
||||
TileInfo tile3_; // Bottom-right
|
||||
};
|
||||
|
||||
// ROM storage: 8 bytes per Tile16 at 0x78000 + (ID * 8)
|
||||
// Total: 4,096 Tile16s (0x0000-0x0FFF)
|
||||
```
|
||||
|
||||
### Tile16Editor Features (COMPLETE)
|
||||
The Tile16Editor at `tile16_editor.cc` is **fully implemented** with:
|
||||
|
||||
- **Undo/Redo System** (lines 1681-1760)
|
||||
- `SaveUndoState()` - captures current state
|
||||
- `Undo()` / `Redo()` - restore states
|
||||
- Ctrl+Z / Ctrl+Y keyboard shortcuts
|
||||
- 50-state stack with rate limiting
|
||||
|
||||
- **Clipboard Operations**
|
||||
- Copy/Paste Tile16s
|
||||
- 4 scratch space slots
|
||||
|
||||
- **Editing Features**
|
||||
- Tile8 composition into Tile16
|
||||
- Flip horizontal/vertical
|
||||
- Palette cycling (0-7)
|
||||
- Fill with single Tile8
|
||||
|
||||
---
|
||||
|
||||
## 4. Map Organization
|
||||
|
||||
### Index Scheme
|
||||
```
|
||||
Index 0x00-0x3F: Light World (64 maps, 8x8 grid)
|
||||
Index 0x40-0x7F: Dark World (64 maps, 8x8 grid)
|
||||
Index 0x80-0x9F: Special World (32 maps, 8x4 grid)
|
||||
|
||||
Total: 160 maps
|
||||
|
||||
Grid position: X = index % 8, Y = index / 8
|
||||
World position: X * 512 pixels, Y * 512 pixels
|
||||
```
|
||||
|
||||
### Multi-Area Maps
|
||||
```cpp
|
||||
enum class AreaSizeEnum {
|
||||
SmallArea = 0, // 1x1 screen (standard)
|
||||
LargeArea = 1, // 2x2 screens (4 quadrants)
|
||||
WideArea = 2, // 2x1 screens (v3 only)
|
||||
TallArea = 3, // 1x2 screens (v3 only)
|
||||
};
|
||||
|
||||
// IMPORTANT: Always use ConfigureMultiAreaMap() for size changes!
|
||||
// Never set area_size_ directly - it handles parent IDs and ROM persistence
|
||||
absl::Status Overworld::ConfigureMultiAreaMap(int parent_index, AreaSizeEnum size);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Entity System
|
||||
|
||||
### Entity Types
|
||||
| Type | Storage | Count | ROM Address |
|
||||
|------|---------|-------|-------------|
|
||||
| Entrances | `all_entrances_` | ~129 | 0xDB96F+ |
|
||||
| Holes | `all_holes_` | ~19 | 0xDB800+ |
|
||||
| Exits | `all_exits_` | ~79 | 0x15D8A+ |
|
||||
| Items | `all_items_` | Variable | 0xDC2F9+ |
|
||||
| Sprites | `all_sprites_[3]` | Variable | 0x4C881+ |
|
||||
|
||||
### Entity Deletion Pattern
|
||||
Entities use a `deleted` flag pattern - this is **CORRECT** for ROM editors:
|
||||
```cpp
|
||||
// Entities live at fixed ROM offsets, cannot be truly "removed"
|
||||
// Setting deleted = true marks them as inactive
|
||||
// entity_operations.cc reuses deleted slots for new entities
|
||||
item.deleted = true; // Proper pattern
|
||||
|
||||
// Renderer skips deleted entities (overworld_entity_renderer.cc)
|
||||
if (!item.deleted) { /* render */ }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Graphics Loading Pipeline
|
||||
|
||||
### Load Sequence
|
||||
```
|
||||
1. Overworld::Load(rom)
|
||||
└── LoadOverworldMaps()
|
||||
└── For each map (0-159):
|
||||
└── OverworldMap::ctor()
|
||||
├── LoadAreaInfo()
|
||||
└── LoadCustomOverworldData() [v3]
|
||||
|
||||
2. On map access: EnsureMapBuilt(map_index)
|
||||
└── BuildMap()
|
||||
├── LoadAreaGraphics()
|
||||
├── BuildTileset()
|
||||
├── BuildTiles16Gfx()
|
||||
├── LoadPalette()
|
||||
├── LoadOverlay()
|
||||
└── BuildBitmap()
|
||||
```
|
||||
|
||||
### Texture Queue System
|
||||
Use deferred texture loading via `gfx::Arena`:
|
||||
```cpp
|
||||
// CORRECT: Non-blocking, uses queue
|
||||
gfx::Arena::Get().QueueTextureCommand(gfx::TextureCommand{
|
||||
.operation = gfx::TextureOperation::kCreate,
|
||||
.bitmap = &some_bitmap_,
|
||||
.priority = gfx::TexturePriority::kHigh
|
||||
});
|
||||
|
||||
// WRONG: Blocking, causes UI freeze
|
||||
Renderer::Get().RenderBitmap(&some_bitmap_);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. ROM Addresses (Key Locations)
|
||||
|
||||
### Vanilla Addresses
|
||||
```cpp
|
||||
// Tile data
|
||||
kTile16Ptr = 0x78000 // Tile16 definitions
|
||||
kOverworldMapSize = 0x12844 // Map size bytes
|
||||
|
||||
// Graphics & Palettes
|
||||
kAreaGfxIdPtr = 0x7C9C // Area graphics IDs
|
||||
kOverworldMapPaletteGroup = 0x7D1C // Palette IDs
|
||||
|
||||
// Entities
|
||||
kOverworldEntranceMap = 0xDB96F // Entrance data
|
||||
kOverworldExitRooms = 0x15D8A // Exit room IDs
|
||||
kOverworldItemPointers = 0xDC2F9 // Item pointers
|
||||
```
|
||||
|
||||
### Expanded Addresses (v1+)
|
||||
```cpp
|
||||
// Custom data at 0x140000+
|
||||
OverworldCustomASMHasBeenApplied = 0x140145 // Version byte
|
||||
OverworldCustomAreaSpecificBGPalette = 0x140000 // BG colors (160*2)
|
||||
OverworldCustomMainPaletteArray = 0x140160 // Main palettes (160)
|
||||
OverworldCustomAnimatedGFXArray = 0x1402A0 // Animated GFX (160)
|
||||
OverworldCustomTileGFXGroupArray = 0x140480 // Tile GFX (160*8)
|
||||
OverworldCustomSubscreenOverlayArray = 0x140340 // Overlays (160*2)
|
||||
kOverworldMapParentIdExpanded = 0x140998 // Parent IDs (160)
|
||||
kOverworldMessagesExpanded = 0x1417F8 // Messages (160*2)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Known Gaps in OverworldEditor
|
||||
|
||||
### Critical: Texture Queueing TODOs (6 locations)
|
||||
```cpp
|
||||
// overworld_editor.cc - these Renderer calls need to be converted:
|
||||
Line 1392: // TODO: Queue texture for later rendering
|
||||
Line 1397: // TODO: Queue texture for later rendering
|
||||
Line 1740: // TODO: Queue texture for later rendering
|
||||
Line 1809: // TODO: Queue texture for later rendering
|
||||
Line 1819: // TODO: Queue texture for later rendering
|
||||
Line 1962: // TODO: Queue texture for later rendering
|
||||
```
|
||||
|
||||
### Unimplemented Core Methods
|
||||
```cpp
|
||||
// overworld_editor.h lines 82-87
|
||||
Undo() → Returns UnimplementedError
|
||||
Redo() → Returns UnimplementedError
|
||||
Cut() → Returns UnimplementedError
|
||||
Find() → Returns UnimplementedError
|
||||
```
|
||||
|
||||
### Entity Popup Static Variable Bug
|
||||
```cpp
|
||||
// entity.cc - Multiple popups use static variables that persist
|
||||
// Causes state contamination when editing multiple entities
|
||||
bool DrawExitEditorPopup() {
|
||||
static bool set_done = false; // BUG: persists across calls
|
||||
static int doorType = ...; // BUG: wrong entity's data shown
|
||||
}
|
||||
```
|
||||
|
||||
### Exit Editor Unimplemented Features
|
||||
```cpp
|
||||
// entity.cc lines 216-264
|
||||
// UI exists but not connected to data:
|
||||
- Door type editing (Wooden, Bombable, Sanctuary, Palace)
|
||||
- Door X/Y position
|
||||
- Center X/Y, Link posture, sprite/BG GFX, palette
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. Code Patterns to Follow
|
||||
|
||||
### Graphics Refresh
|
||||
```cpp
|
||||
// 1. Update model
|
||||
map.SetProperty(new_value);
|
||||
|
||||
// 2. Reload from ROM
|
||||
map.LoadAreaGraphics();
|
||||
|
||||
// 3. Queue texture update (NOT RenderBitmap!)
|
||||
gfx::Arena::Get().QueueTextureCommand(gfx::TextureCommand{
|
||||
.operation = gfx::TextureOperation::kUpdate,
|
||||
.bitmap = &map_bitmap_,
|
||||
.priority = gfx::TexturePriority::kHigh
|
||||
});
|
||||
```
|
||||
|
||||
### Version-Aware Code
|
||||
```cpp
|
||||
auto version = OverworldVersionHelper::GetVersion(*rom_);
|
||||
|
||||
// Use semantic helpers, not raw version checks
|
||||
if (OverworldVersionHelper::SupportsAreaEnum(version)) {
|
||||
// v3+ only code
|
||||
}
|
||||
```
|
||||
|
||||
### Entity Rendering Colors (0.85f alpha)
|
||||
```cpp
|
||||
ImVec4 entrance_color(1.0f, 0.85f, 0.0f, 0.85f); // Yellow-gold
|
||||
ImVec4 exit_color(0.0f, 1.0f, 1.0f, 0.85f); // Cyan
|
||||
ImVec4 item_color(1.0f, 0.0f, 0.0f, 0.85f); // Red
|
||||
ImVec4 sprite_color(1.0f, 0.0f, 1.0f, 0.85f); // Magenta
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. Testing
|
||||
|
||||
### Run Overworld Tests
|
||||
```bash
|
||||
# Unit tests
|
||||
ctest --test-dir build -R "Overworld" -V
|
||||
|
||||
# Regression tests
|
||||
ctest --test-dir build -R "OverworldRegression" -V
|
||||
```
|
||||
|
||||
### Test Files
|
||||
- `test/unit/zelda3/overworld_test.cc` - Core tests
|
||||
- `test/unit/zelda3/overworld_regression_test.cc` - Version helper tests
|
||||
@@ -0,0 +1,217 @@
|
||||
# Gemini Pro 3 Task Checklist
|
||||
|
||||
Prioritized checklist of all identified work items for YAZE development.
|
||||
|
||||
---
|
||||
|
||||
## Phase 1: Critical Rendering Issues (HIGH PRIORITY)
|
||||
|
||||
### Task A1: Texture Queueing TODOs
|
||||
**File:** `src/app/editor/overworld/overworld_editor.cc`
|
||||
**Impact:** Prevents UI freezes, enables proper texture loading
|
||||
**Time Estimate:** 25 min
|
||||
|
||||
- [ ] Line 1392: Convert commented Renderer call to Arena queue
|
||||
- [ ] Line 1397: Convert commented Renderer call to Arena queue
|
||||
- [ ] Line 1740: Convert commented Renderer call to Arena queue
|
||||
- [ ] Line 1809: Convert commented Renderer call to Arena queue
|
||||
- [ ] Line 1819: Convert commented Renderer call to Arena queue
|
||||
- [ ] Line 1962: Convert commented Renderer call to Arena queue
|
||||
- [ ] Verify: `grep "TODO.*texture" overworld_editor.cc` returns nothing
|
||||
- [ ] Test: Run stable tests, no UI freezes on map load
|
||||
|
||||
---
|
||||
|
||||
### Task B1: BothBG Dual-Layer Stubs
|
||||
**File:** `src/zelda3/dungeon/object_drawer.cc`
|
||||
**Impact:** Completes dungeon object rendering for dual-layer objects
|
||||
**Time Estimate:** 30 min
|
||||
|
||||
- [ ] Line 375-381: `DrawRightwards2x4spaced4_1to16_BothBG`
|
||||
- Change signature to accept both `bg1` and `bg2`
|
||||
- Call underlying routine for both buffers
|
||||
- [ ] Line 437-442: `DrawDiagonalAcute_1to16_BothBG`
|
||||
- Change signature to accept both buffers
|
||||
- [ ] Line 444-449: `DrawDiagonalGrave_1to16_BothBG`
|
||||
- Change signature to accept both buffers
|
||||
- [ ] Line 755-761: `DrawDownwards4x2_1to16_BothBG`
|
||||
- Change signature to accept both buffers
|
||||
- [ ] Update `DrawObject()` call sites to pass both buffers for BothBG routines
|
||||
- [ ] Test: Dungeon rooms with dual-layer objects render correctly
|
||||
|
||||
---
|
||||
|
||||
## Phase 2: Bug Fixes (MEDIUM PRIORITY)
|
||||
|
||||
### Task A3: Entity Popup Static Variable Bug
|
||||
**File:** `src/app/editor/overworld/entity.cc`
|
||||
**Impact:** Fixes data corruption when editing multiple entities
|
||||
**Time Estimate:** 20 min
|
||||
|
||||
- [ ] `DrawExitEditorPopup()` (line 152+):
|
||||
- Remove `static bool set_done`
|
||||
- Remove other static variables
|
||||
- Pass state via parameter or use popup ID
|
||||
- [ ] `DrawItemEditorPopup()` (line 320+):
|
||||
- Remove static variables
|
||||
- [ ] Other popup functions:
|
||||
- Audit for static state
|
||||
- [ ] Test: Edit multiple exits/items in sequence, verify correct data
|
||||
|
||||
---
|
||||
|
||||
### Task B2: Diagonal Routine Logic
|
||||
**File:** `src/zelda3/dungeon/object_drawer.cc` lines 401-435
|
||||
**Impact:** Fixes rendering artifacts for diagonal objects
|
||||
**Time Estimate:** 30 min
|
||||
|
||||
- [ ] `DrawDiagonalAcute_1to16`:
|
||||
- Verify/document the `size + 6` constant
|
||||
- Add bounds checking for negative Y coordinates
|
||||
- Handle edge cases at canvas boundaries
|
||||
- [ ] `DrawDiagonalGrave_1to16`:
|
||||
- Same fixes as acute version
|
||||
- [ ] Test: Place diagonal objects in dungeon editor, verify appearance
|
||||
|
||||
---
|
||||
|
||||
## Phase 3: Feature Completion (POLISH)
|
||||
|
||||
### Task A2: OverworldEditor Undo/Redo
|
||||
**File:** `src/app/editor/overworld/overworld_editor.h` lines 82-87
|
||||
**Impact:** Enables undo/redo for overworld edits
|
||||
**Time Estimate:** 45 min
|
||||
|
||||
- [ ] Design undo state structure:
|
||||
```cpp
|
||||
struct OverworldUndoState {
|
||||
int map_index;
|
||||
std::vector<uint16_t> tile_data;
|
||||
// Entity changes?
|
||||
};
|
||||
```
|
||||
- [ ] Add `undo_stack_` and `redo_stack_` members
|
||||
- [ ] Implement `Undo()` method
|
||||
- [ ] Implement `Redo()` method
|
||||
- [ ] Wire up Ctrl+Z / Ctrl+Y shortcuts
|
||||
- [ ] Test: Make edits, undo, redo - verify state restoration
|
||||
|
||||
---
|
||||
|
||||
### Task A4: Exit Editor UI Connection
|
||||
**File:** `src/app/editor/overworld/entity.cc` lines 216-264
|
||||
**Impact:** Makes exit editor fully functional
|
||||
**Time Estimate:** 30 min
|
||||
|
||||
- [ ] Connect door type radio buttons to `exit.door_type_`
|
||||
- [ ] Connect door X/Y inputs to exit data
|
||||
- [ ] Connect Center X/Y to exit scroll data
|
||||
- [ ] Connect palette/GFX fields to exit properties
|
||||
- [ ] Test: Edit exit properties, save ROM, verify changes persisted
|
||||
|
||||
---
|
||||
|
||||
### Task B3: CustomDraw and DoorSwitcherer
|
||||
**File:** `src/zelda3/dungeon/object_drawer.cc`
|
||||
**Impact:** Completes special object rendering
|
||||
**Time Estimate:** 30 min
|
||||
|
||||
- [ ] `CustomDraw` (lines 524-532):
|
||||
- Research expected behavior from ZScream/game
|
||||
- Implement proper drawing logic
|
||||
- [ ] `DrawDoorSwitcherer` (lines 566-575):
|
||||
- Research door switching animation/logic
|
||||
- Implement proper drawing
|
||||
- [ ] Test: Place custom objects, verify appearance
|
||||
|
||||
---
|
||||
|
||||
## Phase 4: Stretch Goals
|
||||
|
||||
### Task B4: Object Name Verification
|
||||
**File:** `src/zelda3/dungeon/room_object.h`
|
||||
**Impact:** Improves editor usability with proper names
|
||||
**Time Estimate:** 2+ hours (requires game testing)
|
||||
|
||||
See `gemini-dungeon-system-reference.md` section 7 for full list.
|
||||
|
||||
High-priority unknowns:
|
||||
- [ ] Line 234: Object 0x35 "WEIRD DOOR" - investigate
|
||||
- [ ] Lines 392-395: Objects 0xDE-0xE1 "Moving wall flag" - WTF IS THIS?
|
||||
- [ ] Lines 350-353: Diagonal layer 2 mask B objects - verify
|
||||
- [ ] Multiple "Unknown" objects in Type 2 and Type 3 ranges
|
||||
|
||||
---
|
||||
|
||||
### Task E2E: Cinematic Tests
|
||||
**Reference:** `docs/internal/testing/dungeon-gui-test-design.md`
|
||||
**Impact:** Visual regression testing, demo capability
|
||||
**Time Estimate:** 45+ min
|
||||
|
||||
- [ ] Create screenshot capture utility
|
||||
- [ ] Implement basic cinematic test sequence
|
||||
- [ ] Add visual diff comparison
|
||||
- [ ] Document test workflow
|
||||
|
||||
---
|
||||
|
||||
## Already Complete (Verification Only)
|
||||
|
||||
### Tile16Editor Undo/Redo
|
||||
**File:** `src/app/editor/overworld/tile16_editor.cc`
|
||||
**Status:** FULLY IMPLEMENTED
|
||||
|
||||
- [x] `SaveUndoState()` implemented
|
||||
- [x] `Undo()` / `Redo()` implemented
|
||||
- [x] Ctrl+Z / Ctrl+Y shortcuts working
|
||||
- [x] UI button at line 1101
|
||||
- [x] Stack management with limits
|
||||
|
||||
**Action:** Verify it works, no changes needed.
|
||||
|
||||
---
|
||||
|
||||
### Entity Deletion Pattern
|
||||
**File:** `src/app/editor/overworld/entity.cc` line 319
|
||||
**Status:** CORRECT (misleading TODO)
|
||||
|
||||
The `deleted` flag pattern IS correct for ROM editors:
|
||||
- Entities at fixed ROM offsets
|
||||
- `entity_operations.cc` reuses deleted slots
|
||||
- Renderer skips deleted entities
|
||||
|
||||
**Action:** Optionally clarify the TODO comment.
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference: File Locations
|
||||
|
||||
| Task | Primary File | Line Numbers |
|
||||
|------|--------------|--------------|
|
||||
| A1 | overworld_editor.cc | 1392, 1397, 1740, 1809, 1819, 1962 |
|
||||
| A2 | overworld_editor.h | 82-87 |
|
||||
| A3 | entity.cc | 152+, 320+ |
|
||||
| A4 | entity.cc | 216-264 |
|
||||
| B1 | object_drawer.cc | 375, 437, 444, 755 |
|
||||
| B2 | object_drawer.cc | 401-435 |
|
||||
| B3 | object_drawer.cc | 524-532, 566-575 |
|
||||
| B4 | room_object.h | Multiple (see section 7 of dungeon ref) |
|
||||
|
||||
---
|
||||
|
||||
## Validation Commands
|
||||
|
||||
```bash
|
||||
# Build
|
||||
cmake --build build_gemini -j8 --target yaze
|
||||
|
||||
# Test
|
||||
ctest --test-dir build_gemini -L stable -j4 --output-on-failure
|
||||
|
||||
# Format check
|
||||
cmake --build build_gemini --target format-check
|
||||
|
||||
# Specific test
|
||||
ctest --test-dir build_gemini -R "Overworld" -V
|
||||
ctest --test-dir build_gemini -R "Dungeon" -V
|
||||
```
|
||||
@@ -0,0 +1,165 @@
|
||||
# Gemini 3 Pro Prompt: Overworld Regression Fix and Improvements
|
||||
|
||||
## Context
|
||||
|
||||
You are working on **yaze** (Yet Another Zelda3 Editor), a C++23 ROM editor for The Legend of Zelda: A Link to the Past. A regression has been introduced that breaks loading of custom ROMs like "Oracle of Secrets" ROM hack.
|
||||
|
||||
## Primary Bug: ASM Version Check Inconsistency
|
||||
|
||||
### Root Cause Analysis
|
||||
|
||||
The recent refactoring introduced `OverworldVersionHelper` for centralized ROM version detection, but **not all code paths were updated to use it consistently**. Specifically:
|
||||
|
||||
**In `src/zelda3/overworld/overworld.cc:71`:**
|
||||
```cpp
|
||||
uint8_t asm_version = (*rom_)[OverworldCustomASMHasBeenApplied];
|
||||
if (asm_version >= 3) { // BUG: 0xFF (255) is >= 3!
|
||||
AssignMapSizes(overworld_maps_);
|
||||
} else {
|
||||
FetchLargeMaps(); // Vanilla ROMs need this path
|
||||
}
|
||||
```
|
||||
|
||||
**The bug**: `asm_version >= 3` evaluates to `true` for vanilla ROMs where `asm_version == 0xFF` (255), causing vanilla ROMs and custom ROMs without ZScream ASM patches to incorrectly call `AssignMapSizes()` instead of `FetchLargeMaps()`.
|
||||
|
||||
**Other places correctly check**:
|
||||
```cpp
|
||||
if (asm_version >= 3 && asm_version != 0xFF) { ... } // Correct
|
||||
```
|
||||
|
||||
### Inconsistent Locations Found
|
||||
|
||||
Search results showing mixed patterns:
|
||||
- `overworld.cc:71` - **BUG**: `if (asm_version >= 3)` - missing `&& asm_version != 0xFF`
|
||||
- `overworld.cc:449` - **BUG**: `if (expanded_flag != 0x04 || asm_version >= 3)` - missing check
|
||||
- `overworld.cc:506` - **BUG**: similar pattern
|
||||
- `overworld.cc:281` - **CORRECT**: `(asm_version < 3 || asm_version == 0xFF)`
|
||||
- `overworld.cc:373` - **CORRECT**: `if (asm_version >= 3 && asm_version != 0xFF)`
|
||||
- Other files also have inconsistencies
|
||||
|
||||
## Your Task
|
||||
|
||||
### Phase 1: Fix the Regression (CRITICAL)
|
||||
|
||||
1. **Update all ASM version checks** in overworld code to either:
|
||||
- Use `OverworldVersionHelper::GetVersion()` and semantic checks like `SupportsAreaEnum()`, OR
|
||||
- Consistently use `asm_version >= 3 && asm_version != 0xFF` pattern
|
||||
|
||||
2. **Key files to fix**:
|
||||
- `src/zelda3/overworld/overworld.cc`
|
||||
- `src/zelda3/overworld/overworld_map.cc`
|
||||
- `src/zelda3/overworld/overworld_item.cc`
|
||||
|
||||
3. **Priority fixes in `overworld.cc`**:
|
||||
- Line 71: Change to `if (asm_version >= 3 && asm_version != 0xFF)`
|
||||
- Line 449: Add `&& asm_version != 0xFF` check
|
||||
- Line 506: Add `&& asm_version != 0xFF` check
|
||||
- Review all other locations from the grep results
|
||||
|
||||
### Phase 2: Standardize Version Checking (Recommended)
|
||||
|
||||
Replace all raw `asm_version` checks with `OverworldVersionHelper`:
|
||||
|
||||
**Instead of:**
|
||||
```cpp
|
||||
uint8_t asm_version = (*rom_)[OverworldCustomASMHasBeenApplied];
|
||||
if (asm_version >= 3 && asm_version != 0xFF) {
|
||||
```
|
||||
|
||||
**Use:**
|
||||
```cpp
|
||||
auto version = OverworldVersionHelper::GetVersion(*rom_);
|
||||
if (OverworldVersionHelper::SupportsAreaEnum(version)) {
|
||||
```
|
||||
|
||||
This centralizes the logic and prevents future inconsistencies.
|
||||
|
||||
### Phase 3: Add Unit Tests
|
||||
|
||||
Create tests in `test/unit/zelda3/overworld_test.cc` to verify:
|
||||
1. Vanilla ROM (0xFF) uses `FetchLargeMaps()` path
|
||||
2. ZScream v3 ROM (0x03) uses `AssignMapSizes()` path
|
||||
3. Custom ROMs with other values behave correctly
|
||||
|
||||
## Key Files Reference
|
||||
|
||||
```
|
||||
src/zelda3/overworld/
|
||||
├── overworld.cc # Main loading logic
|
||||
├── overworld.h
|
||||
├── overworld_map.cc # Individual map handling
|
||||
├── overworld_map.h
|
||||
├── overworld_item.cc # Item loading
|
||||
├── overworld_item.h
|
||||
├── overworld_entrance.h # Entrance/Exit data
|
||||
├── overworld_exit.cc
|
||||
├── overworld_exit.h
|
||||
├── overworld_version_helper.h # Version detection helper
|
||||
```
|
||||
|
||||
## OverworldVersionHelper API
|
||||
|
||||
```cpp
|
||||
enum class OverworldVersion {
|
||||
kVanilla = 0, // 0xFF in ROM - no ZScream ASM
|
||||
kZSCustomV1 = 1,
|
||||
kZSCustomV2 = 2,
|
||||
kZSCustomV3 = 3 // Area enum system
|
||||
};
|
||||
|
||||
class OverworldVersionHelper {
|
||||
static OverworldVersion GetVersion(const Rom& rom);
|
||||
static bool SupportsAreaEnum(OverworldVersion v); // v3 only
|
||||
static bool SupportsExpandedSpace(OverworldVersion v); // v1+
|
||||
static bool SupportsCustomBGColors(OverworldVersion v); // v2+
|
||||
// ...
|
||||
};
|
||||
```
|
||||
|
||||
## Commits That Introduced the Regression
|
||||
|
||||
1. `1e39df88a3` - "refactor: enhance overworld entity properties and version handling"
|
||||
- Introduced `OverworldVersionHelper`
|
||||
- 15 files changed, +546 -282 lines
|
||||
|
||||
2. `5894809aaf` - "refactor: improve overworld map version handling and code organization"
|
||||
- Updated `OverworldMap` to use version helper
|
||||
- 4 files changed, +145 -115 lines
|
||||
|
||||
## Build & Test Commands
|
||||
|
||||
```bash
|
||||
# Configure
|
||||
cmake --preset mac-dbg
|
||||
|
||||
# Build
|
||||
cmake --build build --target yaze -j8
|
||||
|
||||
# Run unit tests
|
||||
ctest --test-dir build -L stable -R overworld
|
||||
|
||||
# Run the app to test loading
|
||||
./build/bin/Debug/yaze.app/Contents/MacOS/yaze --rom_file=/path/to/oracle_of_secrets.sfc
|
||||
```
|
||||
|
||||
## Success Criteria
|
||||
|
||||
1. Oracle of Secrets ROM loads correctly in the Overworld Editor
|
||||
2. Vanilla ALTTP ROMs continue to work
|
||||
3. ZScream v3 patched ROMs continue to work
|
||||
4. All existing unit tests pass
|
||||
5. No new compiler warnings
|
||||
|
||||
## Additional Context
|
||||
|
||||
- The editor supports multiple ROM types: Vanilla, ZScream v1/v2/v3 patched ROMs, and custom hacks
|
||||
- `OverworldCustomASMHasBeenApplied` address (0x130000) stores the version byte
|
||||
- 0xFF = vanilla (no patches), 1-2 = legacy ZScream, 3 = current ZScream
|
||||
- "Oracle of Secrets" is a popular ROM hack that may use 0xFF or a custom value
|
||||
|
||||
## Code Quality Requirements
|
||||
|
||||
- Follow Google C++ Style Guide
|
||||
- Use `absl::Status` for error handling
|
||||
- Run clang-format before committing
|
||||
- Update CLAUDE.md coordination board when done
|
||||
Reference in New Issue
Block a user