backend-infra-engineer: Release v0.3.0 snapshot

This commit is contained in:
scawful
2025-09-27 00:25:45 -04:00
parent 8ce29e1436
commit e32ac75b9c
346 changed files with 55946 additions and 11764 deletions

View File

@@ -0,0 +1,56 @@
# Getting Started
This software allows you to modify "The Legend of Zelda: A Link to the Past" (US or JP) ROMs. Built for compatibility with ZScream projects and designed to be cross-platform.
## Quick Start
1. **Download** the latest release for your platform
2. **Load ROM** via File > Open ROM
3. **Select Editor** from the toolbar (Overworld, Dungeon, Graphics, etc.)
4. **Make Changes** and save your project
## General Tips
- **Experiment Flags**: Enable/disable features in File > Options > Experiment Flags
- **Backup Files**: Enabled by default - each save creates a timestamped backup
- **Extensions**: Load custom tools via the Extensions menu (C library and Python module support)
## Supported Features
| Feature | Status | Details |
|---------|--------|---------|
| Overworld Maps | ✅ Complete | Edit and save tile32 data |
| OW Map Properties | ✅ Complete | Edit and save map properties |
| OW Entrances | ✅ Complete | Edit and save entrance data |
| OW Exits | ✅ Complete | Edit and save exit data |
| OW Sprites | 🔄 In Progress | Edit sprite positions, add/remove sprites |
| Dungeon Editor | 🔄 In Progress | View room metadata and edit room data |
| Palette Editor | 🔄 In Progress | Edit and save palettes, palette groups |
| Graphics Sheets | 🔄 In Progress | Edit and save graphics sheets |
| Graphics Groups | ✅ Complete | Edit and save graphics groups |
| Hex Editor | ✅ Complete | View and edit ROM data in hex |
| Asar Patching | ✅ Complete | Apply Asar 65816 assembly patches to ROM |
## Command Line Interface
The `z3ed` CLI tool provides ROM operations:
```bash
# Apply Asar assembly patch
z3ed asar patch.asm --rom=zelda3.sfc
# Extract symbols from assembly
z3ed extract patch.asm
# Validate assembly syntax
z3ed validate patch.asm
# Launch interactive TUI
z3ed --tui
```
## Extending Functionality
YAZE provides a pure C library interface and Python module for building extensions and custom sprites without assembly. Load these under the Extensions menu.
This feature is still in development and not fully documented yet.

View File

@@ -0,0 +1,153 @@
# Build Instructions
YAZE uses CMake 3.16+ with modern target-based configuration. For VSCode users, install the CMake extensions:
- https://marketplace.visualstudio.com/items?itemName=twxs.cmake
- https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools
## Quick Start
### macOS (Apple Silicon)
```bash
cmake --preset debug
cmake --build build
```
### Linux / Windows
```bash
cmake -B build -DCMAKE_BUILD_TYPE=Debug
cmake --build build
```
### Minimal Build
```bash
cmake -B build -DYAZE_MINIMAL_BUILD=ON
cmake --build build
```
## Dependencies
### Required
- CMake 3.16+
- C++23 compiler (GCC 13+, Clang 16+, MSVC 2019+)
- Git with submodule support
### Bundled Libraries
- SDL2, ImGui, Abseil, Asar, GoogleTest
- Native File Dialog Extended (NFD)
- All dependencies included in repository
## Platform Setup
### macOS
```bash
# Install Xcode Command Line Tools
xcode-select --install
# Optional: Install Homebrew dependencies (auto-detected)
brew install cmake pkg-config
```
### Linux (Ubuntu/Debian)
```bash
sudo apt-get update
sudo apt-get install -y build-essential cmake ninja-build pkg-config \
libgtk-3-dev libdbus-1-dev
```
### Windows
**Option 1 - Minimal (Recommended for CI):**
- Visual Studio 2019+ with C++ CMake tools
- No additional dependencies needed (all bundled)
**Option 2 - Full Development:**
- Install vcpkg and dependencies from `vcpkg.json`
## Build Targets
### Applications
- **yaze**: Main GUI editor application
- **z3ed**: Command-line interface tool
### Libraries
- **yaze_c**: C API library for extensions
- **asar-static**: 65816 assembler library
### Development (Debug Builds Only)
- **yaze_emu**: Standalone SNES emulator
- **yaze_test**: Comprehensive test suite
## Build Configurations
### Debug (Full Features)
```bash
cmake --preset debug # macOS
# OR
cmake -B build -DCMAKE_BUILD_TYPE=Debug # All platforms
```
**Includes**: NFD, ImGuiTestEngine, PNG support, emulator, all tools
### Minimal (CI/Fast Builds)
```bash
cmake -B build -DYAZE_MINIMAL_BUILD=ON
```
**Excludes**: Emulator, CLI tools, UI tests, optional dependencies
### Release
```bash
cmake --preset release # macOS
# OR
cmake -B build -DCMAKE_BUILD_TYPE=Release # All platforms
```
## IDE Integration
### VS Code
1. Install CMake Tools extension
2. Open project, select "Debug" preset
3. Language server uses `compile_commands.json` automatically
### CLion
- Opens CMake projects directly
- Select Debug configuration
### Xcode (macOS)
```bash
cmake --preset debug -G Xcode
open build/yaze.xcodeproj
```
## Features by Build Type
| Feature | Debug | Release | Minimal (CI) |
|---------|-------|---------|--------------|
| GUI Editor | ✅ | ✅ | ✅ |
| Native File Dialogs | ✅ | ✅ | ❌ |
| PNG Support | ✅ | ✅ | ❌ |
| Emulator | ✅ | ✅ | ❌ |
| CLI Tools | ✅ | ✅ | ❌ |
| Test Suite | ✅ | ❌ | ✅ (limited) |
| UI Testing | ✅ | ❌ | ❌ |
## Troubleshooting
### Architecture Errors (macOS)
```bash
# Clean and use ARM64-only preset
rm -rf build
cmake --preset debug # Uses arm64 only
```
### Missing Headers (Language Server)
```bash
# Regenerate compile commands
cmake --preset debug
cp build/compile_commands.json .
# Restart VS Code
```
### CI Build Failures
Use minimal build configuration that matches CI:
```bash
cmake -B build -DYAZE_MINIMAL_BUILD=ON -DYAZE_ENABLE_UI_TESTS=OFF
cmake --build build
```

141
docs/03-asar-integration.md Normal file
View File

@@ -0,0 +1,141 @@
# Asar 65816 Assembler Integration
Complete cross-platform ROM patching with assembly code support, symbol extraction, and validation.
## Quick Examples
### Command Line
```bash
# Apply assembly patch to ROM
z3ed asar my_patch.asm --rom=zelda3.sfc
# Extract symbols without patching
z3ed extract my_patch.asm
# Validate assembly syntax
z3ed validate my_patch.asm
```
### C++ API
```cpp
#include "app/core/asar_wrapper.h"
yaze::app::core::AsarWrapper wrapper;
wrapper.Initialize();
// Apply patch to ROM
auto result = wrapper.ApplyPatch("patch.asm", rom_data);
if (result.ok() && result->success) {
for (const auto& symbol : result->symbols) {
std::cout << symbol.name << " @ $" << std::hex << symbol.address << std::endl;
}
}
```
## Assembly Patch Examples
### Basic Hook
```assembly
org $008000
custom_hook:
sei ; Disable interrupts
rep #$30 ; 16-bit A and X/Y
; Your custom code
lda #$1234
sta $7E0000
rts
custom_data:
db "YAZE", $00
dw $1234, $5678
```
### Advanced Features
```assembly
!player_health = $7EF36C
!custom_ram = $7E2000
macro save_context()
pha : phx : phy
endmacro
org $008000
advanced_hook:
%save_context()
sep #$20
lda #$A0 ; Full health
sta !player_health
%save_context()
rtl
```
## API Reference
### AsarWrapper Class
```cpp
class AsarWrapper {
public:
absl::Status Initialize();
absl::StatusOr<AsarPatchResult> ApplyPatch(
const std::string& patch_path,
std::vector<uint8_t>& rom_data);
absl::StatusOr<std::vector<AsarSymbol>> ExtractSymbols(
const std::string& asm_path);
absl::Status ValidateAssembly(const std::string& asm_path);
};
```
### Data Structures
```cpp
struct AsarSymbol {
std::string name; // Symbol name
uint32_t address; // Memory address
std::string opcode; // Associated opcode
std::string file; // Source file
int line; // Line number
};
struct AsarPatchResult {
bool success; // Whether patch succeeded
std::vector<std::string> errors; // Error messages
std::vector<AsarSymbol> symbols; // Extracted symbols
uint32_t rom_size; // Final ROM size
};
```
## Testing
### ROM-Dependent Tests
```cpp
YAZE_ROM_TEST(AsarIntegration, RealRomPatching) {
auto rom_data = TestRomManager::LoadTestRom();
AsarWrapper wrapper;
wrapper.Initialize();
auto result = wrapper.ApplyPatch("test.asm", rom_data);
EXPECT_TRUE(result.ok());
}
```
ROM tests are automatically skipped in CI with `--label-exclude ROM_DEPENDENT`.
## Error Handling
| Error | Cause | Solution |
|-------|-------|----------|
| `Unknown command` | Invalid opcode | Check 65816 instruction reference |
| `Label not found` | Undefined label | Define the label or check spelling |
| `Invalid hex value` | Bad hex format | Use `$1234` format |
| `Buffer too small` | ROM needs expansion | Check if ROM needs to be larger |
## Development Workflow
1. **Write assembly patch**
2. **Validate syntax**: `z3ed validate patch.asm`
3. **Extract symbols**: `z3ed extract patch.asm`
4. **Apply to test ROM**: `z3ed asar patch.asm --rom=test.sfc`
5. **Test in emulator**

208
docs/04-api-reference.md Normal file
View File

@@ -0,0 +1,208 @@
# API Reference
Comprehensive reference for the YAZE C API and C++ interfaces.
## C API (`incl/yaze.h`, `incl/zelda.h`)
### Core Library Functions
```c
// Initialization
yaze_status yaze_library_init(void);
void yaze_library_shutdown(void);
// Version management
const char* yaze_get_version_string(void);
int yaze_get_version_number(void);
bool yaze_check_version_compatibility(const char* expected_version);
// Status utilities
const char* yaze_status_to_string(yaze_status status);
```
### ROM Operations
```c
// ROM loading and management
zelda3_rom* yaze_load_rom(const char* filename);
void yaze_unload_rom(zelda3_rom* rom);
yaze_status yaze_save_rom(zelda3_rom* rom, const char* filename);
bool yaze_is_rom_modified(const zelda3_rom* rom);
```
### Graphics Operations
```c
// SNES color management
snes_color yaze_rgb_to_snes_color(uint8_t r, uint8_t g, uint8_t b);
void yaze_snes_color_to_rgb(snes_color color, uint8_t* r, uint8_t* g, uint8_t* b);
// Bitmap operations
yaze_bitmap* yaze_create_bitmap(int width, int height, uint8_t bpp);
void yaze_free_bitmap(yaze_bitmap* bitmap);
```
### Palette System
```c
// Palette creation and management
snes_palette* yaze_create_palette(uint8_t id, uint8_t size);
void yaze_free_palette(snes_palette* palette);
snes_palette* yaze_load_palette_from_rom(const zelda3_rom* rom, uint8_t palette_id);
```
### Message System
```c
// Message handling
zelda3_message* yaze_load_message(const zelda3_rom* rom, uint16_t message_id);
void yaze_free_message(zelda3_message* message);
yaze_status yaze_save_message(zelda3_rom* rom, const zelda3_message* message);
```
## C++ API
### AsarWrapper (`src/app/core/asar_wrapper.h`)
```cpp
namespace yaze::app::core {
class AsarWrapper {
public:
// Initialization
absl::Status Initialize();
void Shutdown();
bool IsInitialized() const;
// Core functionality
absl::StatusOr<AsarPatchResult> ApplyPatch(
const std::string& patch_path,
std::vector<uint8_t>& rom_data,
const std::vector<std::string>& include_paths = {});
absl::StatusOr<std::vector<AsarSymbol>> ExtractSymbols(
const std::string& asm_path,
const std::vector<std::string>& include_paths = {});
// Symbol management
std::optional<AsarSymbol> FindSymbol(const std::string& name);
std::vector<AsarSymbol> GetSymbolsAtAddress(uint32_t address);
std::map<std::string, AsarSymbol> GetSymbolTable();
// Utility functions
absl::Status ValidateAssembly(const std::string& asm_path);
std::string GetVersion();
void Reset();
};
}
```
### Data Structures
#### ROM Version Support
```c
typedef enum zelda3_version {
ZELDA3_VERSION_US = 1,
ZELDA3_VERSION_JP = 2,
ZELDA3_VERSION_SD = 3,
ZELDA3_VERSION_RANDO = 4,
// Legacy aliases maintained for compatibility
US = ZELDA3_VERSION_US,
JP = ZELDA3_VERSION_JP,
SD = ZELDA3_VERSION_SD,
RANDO = ZELDA3_VERSION_RANDO,
} zelda3_version;
```
#### SNES Graphics
```c
typedef struct snes_color {
uint16_t raw; // Raw 15-bit SNES color
uint8_t red; // Red component (0-31)
uint8_t green; // Green component (0-31)
uint8_t blue; // Blue component (0-31)
} snes_color;
typedef struct snes_palette {
uint8_t id; // Palette ID
uint8_t size; // Number of colors
snes_color* colors; // Color array
} snes_palette;
```
#### Message System
```c
typedef struct zelda3_message {
uint16_t id; // Message ID (0-65535)
uint32_t rom_address; // Address in ROM
uint16_t length; // Length in bytes
uint8_t* raw_data; // Raw ROM data
char* parsed_text; // Decoded UTF-8 text
bool is_compressed; // Compression flag
uint8_t encoding_type; // Encoding type
} zelda3_message;
```
## Error Handling
### Status Codes
```c
typedef enum yaze_status {
YAZE_OK = 0, // Success
YAZE_ERROR_UNKNOWN = -1, // Unknown error
YAZE_ERROR_INVALID_ARG = 1, // Invalid argument
YAZE_ERROR_FILE_NOT_FOUND = 2, // File not found
YAZE_ERROR_MEMORY = 3, // Memory allocation failed
YAZE_ERROR_IO = 4, // I/O operation failed
YAZE_ERROR_CORRUPTION = 5, // Data corruption detected
YAZE_ERROR_NOT_INITIALIZED = 6, // Component not initialized
} yaze_status;
```
### Error Handling Pattern
```c
yaze_status status = yaze_library_init();
if (status != YAZE_OK) {
printf("Failed to initialize YAZE: %s\n", yaze_status_to_string(status));
return 1;
}
zelda3_rom* rom = yaze_load_rom("zelda3.sfc");
if (rom == nullptr) {
printf("Failed to load ROM file\n");
return 1;
}
// Use ROM...
yaze_unload_rom(rom);
yaze_library_shutdown();
```
## Extension System
### Plugin Architecture
```c
typedef struct yaze_extension {
const char* name; // Extension name
const char* version; // Version string
const char* description; // Description
const char* author; // Author
int api_version; // Required API version
yaze_status (*initialize)(yaze_editor_context* context);
void (*cleanup)(void);
uint32_t (*get_capabilities)(void);
} yaze_extension;
```
### Capability Flags
```c
#define YAZE_EXT_CAP_ROM_EDITING 0x0001 // ROM modification
#define YAZE_EXT_CAP_GRAPHICS 0x0002 // Graphics operations
#define YAZE_EXT_CAP_AUDIO 0x0004 // Audio processing
#define YAZE_EXT_CAP_SCRIPTING 0x0008 // Scripting support
#define YAZE_EXT_CAP_IMPORT_EXPORT 0x0010 // Data import/export
```
## Backward Compatibility
All existing code continues to work without modification due to:
- Legacy enum aliases (`US`, `JP`, `SD`, `RANDO`)
- Original struct field names maintained
- Duplicate field definitions for old/new naming conventions
- Typedef aliases for renamed types

173
docs/A1-testing-guide.md Normal file
View File

@@ -0,0 +1,173 @@
# Testing Guide
Comprehensive testing framework with efficient CI/CD integration and ROM-dependent test separation.
## Test Categories
### Stable Tests (STABLE)
**Always run in CI/CD - Required for releases**
- **AsarWrapperTest**: Core Asar functionality tests
- **SnesTileTest**: SNES tile format handling
- **CompressionTest**: Data compression/decompression
- **SnesPaletteTest**: SNES palette operations
- **HexTest**: Hexadecimal utilities
- **AsarIntegrationTest**: Asar integration without ROM dependencies
**Characteristics:**
- Fast execution (< 30 seconds total)
- No external dependencies (ROMs, complex setup)
- High reliability and deterministic results
### ROM-Dependent Tests (ROM_DEPENDENT)
**Only run in development with available ROM files**
- **AsarRomIntegrationTest**: Real ROM patching and symbol extraction
- **ROM-based integration tests**: Tests requiring actual game ROM files
**Characteristics:**
- Require specific ROM files to be present
- Test real-world functionality
- Automatically skipped in CI if ROM files unavailable
### Experimental Tests (EXPERIMENTAL)
**Run separately, allowed to fail**
- **CpuTest**: 65816 CPU emulation tests
- **Spc700Test**: SPC700 audio processor tests
- **ApuTest**: Audio Processing Unit tests
- **PpuTest**: Picture Processing Unit tests
**Characteristics:**
- May be unstable due to emulation complexity
- Test advanced/experimental features
- Allowed to fail without blocking releases
## Command Line Usage
```bash
# Run only stable tests (release-ready)
ctest --test-dir build --label-regex "STABLE"
# Run experimental tests (allowed to fail)
ctest --test-dir build --label-regex "EXPERIMENTAL"
# Run Asar-specific tests
ctest --test-dir build -R "*Asar*"
# Run tests excluding ROM-dependent ones
ctest --test-dir build --label-exclude "ROM_DEPENDENT"
# Run with specific preset
ctest --preset stable
ctest --preset experimental
```
## CMake Presets
```bash
# Development workflow
cmake --preset dev
cmake --build --preset dev
ctest --preset dev
# CI workflow
cmake --preset ci
cmake --build --preset ci
ctest --preset ci
# Release workflow
cmake --preset release
cmake --build --preset release
ctest --preset stable
```
## Writing Tests
### Stable Tests
```cpp
TEST(SnesTileTest, UnpackBppTile) {
std::vector<uint8_t> tile_data = {0xAA, 0x55, 0xAA, 0x55};
std::vector<uint8_t> result = UnpackBppTile(tile_data, 2);
EXPECT_EQ(result.size(), 64);
// Test specific pixel values...
}
```
### ROM-Dependent Tests
```cpp
YAZE_ROM_TEST(AsarIntegration, RealRomPatching) {
auto rom_data = TestRomManager::LoadTestRom();
if (!rom_data.has_value()) {
GTEST_SKIP() << "ROM file not available";
}
AsarWrapper wrapper;
wrapper.Initialize();
auto result = wrapper.ApplyPatch("test.asm", *rom_data);
EXPECT_TRUE(result.ok());
}
```
### Experimental Tests
```cpp
TEST(CpuTest, InstructionExecution) {
// Complex emulation tests
// May be timing-sensitive or platform-dependent
}
```
## CI/CD Integration
### GitHub Actions
```yaml
# Main CI pipeline
- name: Run Stable Tests
run: ctest --label-regex "STABLE"
# Experimental tests (allowed to fail)
- name: Run Experimental Tests
run: ctest --label-regex "EXPERIMENTAL"
continue-on-error: true
```
### Test Execution Strategy
1. **Stable tests run first** - Quick feedback for developers
2. **Experimental tests run in parallel** - Don't block on unstable tests
3. **ROM tests skipped** - No dependency on external files
4. **Selective test execution** - Only run relevant tests for changes
## Test Development Guidelines
### Writing Stable Tests
- **Fast execution**: Aim for < 1 second per test
- **No external dependencies**: Self-contained test data
- **Deterministic**: Same results every run
- **Core functionality**: Test essential features only
### Writing ROM-Dependent Tests
- **Use TestRomManager**: Proper ROM file handling
- **Graceful skipping**: Skip if ROM not available
- **Real-world scenarios**: Test with actual game data
- **Label appropriately**: Always include ROM_DEPENDENT label
### Writing Experimental Tests
- **Complex scenarios**: Multi-component integration
- **Advanced features**: Emulation, complex algorithms
- **Performance tests**: May vary by system
- **GUI components**: May require display context
## Performance and Maintenance
### Regular Review
- **Monthly review** of experimental test failures
- **Promote stable experimental tests** to stable category
- **Deprecate obsolete tests** that no longer provide value
- **Update test categorization** as features mature
### Performance Monitoring
- **Track test execution times** for CI efficiency
- **Identify slow tests** for optimization or recategorization
- **Monitor CI resource usage** and adjust parallelism
- **Benchmark critical path tests** for performance regression

239
docs/B1-contributing.md Normal file
View File

@@ -0,0 +1,239 @@
# Contributing
Guidelines for contributing to the YAZE project.
## Development Setup
### Prerequisites
- **CMake 3.16+**: Modern build system
- **C++23 Compiler**: GCC 13+, Clang 16+, MSVC 2022 17.8+
- **Git**: Version control with submodules
### Quick Start
```bash
# Clone with submodules
git clone --recursive https://github.com/scawful/yaze.git
cd yaze
# Build with presets
cmake --preset dev
cmake --build --preset dev
# Run tests
ctest --preset stable
```
## Code Style
### C++ Standards
- **C++23**: Use modern language features
- **Google C++ Style**: Follow Google C++ style guide
- **Naming**: Use descriptive names, avoid abbreviations
### File Organization
```cpp
// Header guards
#pragma once
// Includes (system, third-party, local)
#include <vector>
#include "absl/status/status.h"
#include "app/core/asar_wrapper.h"
// Namespace usage
namespace yaze::app::editor {
class ExampleClass {
public:
// Public interface
absl::Status Initialize();
private:
// Private implementation
std::vector<uint8_t> data_;
};
}
```
### Error Handling
```cpp
// Use absl::Status for error handling
absl::Status LoadRom(const std::string& filename) {
if (filename.empty()) {
return absl::InvalidArgumentError("Filename cannot be empty");
}
// ... implementation
return absl::OkStatus();
}
// Use absl::StatusOr for operations that return values
absl::StatusOr<std::vector<uint8_t>> ReadFile(const std::string& filename);
```
## Testing Requirements
### Test Categories
- **Stable Tests**: Fast, reliable, no external dependencies
- **ROM-Dependent Tests**: Require ROM files, skip in CI
- **Experimental Tests**: Complex, may be unstable
### Writing Tests
```cpp
// Stable test example
TEST(SnesTileTest, UnpackBppTile) {
std::vector<uint8_t> tile_data = {0xAA, 0x55};
auto result = UnpackBppTile(tile_data, 2);
EXPECT_TRUE(result.ok());
EXPECT_EQ(result->size(), 64);
}
// ROM-dependent test example
YAZE_ROM_TEST(AsarIntegration, RealRomPatching) {
auto rom_data = TestRomManager::LoadTestRom();
if (!rom_data.has_value()) {
GTEST_SKIP() << "ROM file not available";
}
// ... test implementation
}
```
### Test Execution
```bash
# Run stable tests (required)
ctest --label-regex "STABLE"
# Run experimental tests (optional)
ctest --label-regex "EXPERIMENTAL"
# Run specific test
ctest -R "AsarWrapperTest"
```
## Pull Request Process
### Before Submitting
1. **Run tests**: Ensure all stable tests pass
2. **Check formatting**: Use clang-format
3. **Update documentation**: Update relevant docs if needed
4. **Test on multiple platforms**: Verify cross-platform compatibility
### Pull Request Template
```markdown
## Description
Brief description of changes
## Type of Change
- [ ] Bug fix
- [ ] New feature
- [ ] Breaking change
- [ ] Documentation update
## Testing
- [ ] Stable tests pass
- [ ] Manual testing completed
- [ ] Cross-platform testing (if applicable)
## Checklist
- [ ] Code follows project style guidelines
- [ ] Self-review completed
- [ ] Documentation updated
- [ ] Tests added/updated
```
## Development Workflow
### Branch Strategy
- **main**: Stable, release-ready code
- **feature/**: New features and enhancements
- **fix/**: Bug fixes
- **docs/**: Documentation updates
### Commit Messages
```
type(scope): brief description
Detailed explanation of changes, including:
- What was changed
- Why it was changed
- Any breaking changes
Fixes #issue_number
```
### Types
- **feat**: New features
- **fix**: Bug fixes
- **docs**: Documentation changes
- **style**: Code style changes
- **refactor**: Code refactoring
- **test**: Test additions/changes
- **chore**: Build/tooling changes
## Architecture Guidelines
### Component Design
- **Single Responsibility**: Each class should have one clear purpose
- **Dependency Injection**: Use dependency injection for testability
- **Interface Segregation**: Keep interfaces focused and minimal
### Memory Management
- **RAII**: Use RAII for resource management
- **Smart Pointers**: Prefer unique_ptr and shared_ptr
- **Avoid Raw Pointers**: Use smart pointers or references
### Performance
- **Profile Before Optimizing**: Measure before optimizing
- **Use Modern C++**: Leverage C++23 features for performance
- **Avoid Premature Optimization**: Focus on correctness first
## Documentation
### Code Documentation
- **Doxygen Comments**: Use Doxygen format for public APIs
- **Inline Comments**: Explain complex logic
- **README Updates**: Update relevant README files
### API Documentation
```cpp
/**
* @brief Applies an assembly patch to ROM data
* @param patch_path Path to the assembly patch file
* @param rom_data ROM data to patch (modified in place)
* @param include_paths Optional include paths for assembly
* @return Result containing success status and extracted symbols
* @throws std::invalid_argument if patch_path is empty
*/
absl::StatusOr<AsarPatchResult> ApplyPatch(
const std::string& patch_path,
std::vector<uint8_t>& rom_data,
const std::vector<std::string>& include_paths = {});
```
## Community Guidelines
### Communication
- **Be Respectful**: Treat all contributors with respect
- **Be Constructive**: Provide helpful feedback
- **Be Patient**: Remember that everyone is learning
### Getting Help
- **GitHub Issues**: Report bugs and request features
- **Discussions**: Ask questions and discuss ideas
- **Discord**: [Oracle of Secrets Discord](https://discord.gg/MBFkMTPEmk)
## Release Process
### Version Numbering
- **Semantic Versioning**: MAJOR.MINOR.PATCH
- **v0.3.0**: Current stable release
- **Pre-release**: v0.4.0-alpha, v0.4.0-beta
### Release Checklist
- [ ] All stable tests pass
- [ ] Documentation updated
- [ ] Changelog updated
- [ ] Cross-platform builds verified
- [ ] Release notes prepared

55
docs/B2-ci-cd-fixes.md Normal file
View File

@@ -0,0 +1,55 @@
# Platform Compatibility Improvements
Recent improvements to ensure YAZE works reliably across all supported platforms.
## Native File Dialog Support
YAZE now features native file dialogs on all platforms:
- **macOS**: Cocoa-based file selection with proper sandboxing support
- **Windows**: Windows Explorer integration with COM APIs
- **Linux**: GTK3 dialogs that match system appearance
- **Fallback**: Bespoke implementation when native dialogs unavailable
## Cross-Platform Build Reliability
Enhanced build system ensures consistent compilation:
- **Windows**: Resolved MSVC compatibility issues and dependency conflicts
- **Linux**: Fixed standard library compatibility for older distributions
- **macOS**: Proper support for both Intel and Apple Silicon architectures
- **All Platforms**: Bundled dependencies eliminate external package requirements
## Build Configuration Options
YAZE supports different build configurations for various use cases:
### Full Build (Development)
Includes all features: emulator, CLI tools, UI testing framework, and optional libraries.
### Minimal Build
Streamlined build excluding complex components, optimized for automated testing and CI environments.
## Implementation Details
The build system automatically detects platform capabilities and adjusts feature sets accordingly:
- **File Dialogs**: Uses native platform dialogs when available, with cross-platform fallbacks
- **Dependencies**: Bundles all required libraries to eliminate external package requirements
- **Testing**: Separates ROM-dependent tests from unit tests for CI compatibility
- **Architecture**: Supports both Intel and Apple Silicon on macOS without conflicts
## Platform-Specific Adaptations
### Windows
- Complete COM-based file dialog implementation
- MSVC compatibility improvements for modern C++ features
- Resource file handling for proper application integration
### macOS
- Cocoa-based native file dialogs with sandboxing support
- Universal binary support for Intel and Apple Silicon
- Proper bundle configuration for macOS applications
### Linux
- GTK3 integration for native file dialogs
- Package manager integration for system dependencies
- Support for multiple compiler toolchains (GCC, Clang)

View File

@@ -0,0 +1,55 @@
# Platform Compatibility Improvements
Recent improvements to ensure YAZE works reliably across all supported platforms.
## Native File Dialog Support
YAZE now features native file dialogs on all platforms:
- **macOS**: Cocoa-based file selection with proper sandboxing support
- **Windows**: Windows Explorer integration with COM APIs
- **Linux**: GTK3 dialogs that match system appearance
- **Fallback**: Bespoke implementation when native dialogs unavailable
## Cross-Platform Build Reliability
Enhanced build system ensures consistent compilation:
- **Windows**: Resolved MSVC compatibility issues and dependency conflicts
- **Linux**: Fixed standard library compatibility for older distributions
- **macOS**: Proper support for both Intel and Apple Silicon architectures
- **All Platforms**: Bundled dependencies eliminate external package requirements
## Build Configuration Options
YAZE supports different build configurations for various use cases:
### Full Build (Development)
Includes all features: emulator, CLI tools, UI testing framework, and optional libraries.
### Minimal Build
Streamlined build excluding complex components, optimized for automated testing and CI environments.
## Implementation Details
The build system automatically detects platform capabilities and adjusts feature sets accordingly:
- **File Dialogs**: Uses native platform dialogs when available, with cross-platform fallbacks
- **Dependencies**: Bundles all required libraries to eliminate external package requirements
- **Testing**: Separates ROM-dependent tests from unit tests for CI compatibility
- **Architecture**: Supports both Intel and Apple Silicon on macOS without conflicts
## Platform-Specific Adaptations
### Windows
- Complete COM-based file dialog implementation
- MSVC compatibility improvements for modern C++ features
- Resource file handling for proper application integration
### macOS
- Cocoa-based native file dialogs with sandboxing support
- Universal binary support for Intel and Apple Silicon
- Proper bundle configuration for macOS applications
### Linux
- GTK3 integration for native file dialogs
- Package manager integration for system dependencies
- Support for multiple compiler toolchains (GCC, Clang)

109
docs/B3-build-presets.md Normal file
View File

@@ -0,0 +1,109 @@
# Build Presets Guide
CMake presets for development workflow and architecture-specific builds.
## 🍎 macOS ARM64 Presets (Recommended for Apple Silicon)
### For Development Work:
```bash
# ARM64-only development build with ROM testing
cmake --preset macos-dev
cmake --build --preset macos-dev
# ARM64-only debug build
cmake --preset macos-debug
cmake --build --preset macos-debug
# ARM64-only release build
cmake --preset macos-release
cmake --build --preset macos-release
```
### For Distribution:
```bash
# Universal binary (ARM64 + x86_64) - use only when needed for distribution
cmake --preset macos-debug-universal
cmake --build --preset macos-debug-universal
cmake --preset macos-release-universal
cmake --build --preset macos-release-universal
```
## 🔧 Why This Fixes Architecture Errors
**Problem**: The original presets used `CMAKE_OSX_ARCHITECTURES: "x86_64;arm64"` which forced CMake to build universal binaries. This caused issues because:
- Dependencies like Abseil tried to use x86 SSE instructions (`-msse4.1`)
- These instructions don't exist on ARM64 processors
- Build failed with "unsupported option '-msse4.1' for target 'arm64-apple-darwin'"
**Solution**: The new ARM64-only presets use `CMAKE_OSX_ARCHITECTURES: "arm64"` which:
- ✅ Only targets ARM64 architecture
- ✅ Prevents x86-specific instruction usage
- ✅ Uses ARM64 optimizations instead
- ✅ Builds much faster (no cross-compilation)
## 📋 Available Presets
| Preset Name | Architecture | Purpose | ROM Tests |
|-------------|-------------|---------|-----------|
| `macos-dev` | ARM64 only | Development | ✅ Enabled |
| `macos-debug` | ARM64 only | Debug builds | ❌ Disabled |
| `macos-release` | ARM64 only | Release builds | ❌ Disabled |
| `macos-debug-universal` | Universal | Distribution debug | ❌ Disabled |
| `macos-release-universal` | Universal | Distribution release | ❌ Disabled |
## 🚀 Quick Start
For most development work on Apple Silicon:
```bash
# Clean build
rm -rf build
# Configure for ARM64 development
cmake --preset macos-dev
# Build
cmake --build --preset macos-dev
# Run tests
cmake --build --preset macos-dev --target test
```
## 🛠️ IDE Integration
### VS Code with CMake Tools:
1. Open Command Palette (`Cmd+Shift+P`)
2. Run "CMake: Select Configure Preset"
3. Choose `macos-dev` or `macos-debug`
### CLion:
1. Go to Settings → Build, Execution, Deployment → CMake
2. Add new profile with preset `macos-dev`
### Xcode:
```bash
# Generate Xcode project
cmake --preset macos-debug -G Xcode
open build/yaze.xcodeproj
```
## 🔍 Troubleshooting
If you still get architecture errors:
1. **Clean completely**: `rm -rf build`
2. **Check preset**: Ensure you're using an ARM64 preset (not universal)
3. **Verify configuration**: Check that `CMAKE_OSX_ARCHITECTURES` shows only `arm64`
```bash
# Verify architecture setting
cmake --preset macos-debug
grep -A 5 -B 5 "CMAKE_OSX_ARCHITECTURES" build/CMakeCache.txt
```
## 📝 Notes
- **ARM64 presets**: Fast builds, no architecture conflicts
- **Universal presets**: Slower builds, for distribution only
- **Deployment target**: ARM64 presets use macOS 11.0+ (when Apple Silicon was introduced)
- **Universal presets**: Still support macOS 10.15+ for backward compatibility

98
docs/C1-changelog.md Normal file
View File

@@ -0,0 +1,98 @@
# Changelog
## 0.3.0 (September 2025)
### Major Features
- **Complete Theme Management System**: 5+ built-in themes with custom theme creation and editing
- **Multi-Session Workspace**: Work with multiple ROMs simultaneously in enhanced docked interface
- **Enhanced Welcome Screen**: Themed interface with quick access to all editors and features
- **Asar 65816 Assembler Integration**: Complete cross-platform ROM patching with assembly code
- **ZSCustomOverworld v3**: Full integration with enhanced overworld editing capabilities
- **Advanced Message Editing**: Enhanced text editing interface with improved parsing and real-time preview
- **GUI Docking System**: Improved docking and workspace management for better user workflow
- **Symbol Extraction**: Extract symbol names and opcodes from assembly files
- **Modernized Build System**: Upgraded to CMake 3.16+ with target-based configuration
### User Interface & Theming
- **Built-in Themes**: Classic YAZE, YAZE Tre, Cyberpunk, Sunset, Forest, and Midnight themes
- **Theme Editor**: Complete custom theme creation with save-to-file functionality
- **Animated Background Grid**: Optional moving grid with color breathing effects
- **Theme Import/Export**: Share custom themes with the community
- **Responsive UI**: All UI elements properly adapt to selected themes
### Enhancements
- **Enhanced CLI Tools**: Improved z3ed with modern command line interface and TUI
- **CMakePresets**: Added development workflow presets for better productivity
- **Cross-Platform CI/CD**: Multi-platform automated builds and testing with lenient code quality checks
- **Professional Packaging**: NSIS, DMG, and DEB/RPM installers
- **ROM-Dependent Testing**: Separated testing infrastructure for CI compatibility with 46+ core tests
- **Comprehensive Documentation**: Updated guides, help menus, and API documentation
### Technical Improvements
- **Modern C++23**: Latest language features for performance and safety
- **Memory Safety**: Enhanced memory management with RAII and smart pointers
- **Error Handling**: Improved error handling using absl::Status throughout
- **Cross-Platform**: Consistent experience across Windows, macOS, and Linux
- **Performance**: Optimized rendering and data processing
### Bug Fixes
- **Graphics Arena Crash**: Fixed double-free error during Arena singleton destruction
- **SNES Tile Format**: Corrected tile unpacking algorithm based on SnesLab documentation
- **Palette System**: Fixed color conversion functions (ImVec4 float to uint8_t conversion)
- **CI/CD**: Fixed missing cstring include for Ubuntu compilation
- **ROM Loading**: Fixed file path issues in tests
## 0.2.2 (December 2024)
- DungeonMap editing improvements
- ZSCustomOverworld support
- Cross platform file handling
## 0.2.1 (August 2024)
- Improved MessageEditor parsing
- Added integration test window
- Bitmap bug fixes
## 0.2.0 (July 2024)
- iOS app support
- Graphics Sheet Browser
- Project Files
## 0.1.0 (May 2024)
- Bitmap bug fixes
- Error handling improvements
## 0.0.9 (April 2024)
- Documentation updates
- Entrance tile types
- Emulator subsystem overhaul
## 0.0.8 (February 2024)
- Hyrule Magic Compression
- Dungeon Room Entrances
- PNG Export
## 0.0.7 (January 2024)
- OverworldEntities
- Entrances
- Exits
- Items
- Sprites
## 0.0.6 (November 2023)
- ScreenEditor DungeonMap
- Tile16 Editor
- Canvas updates
## 0.0.5 (November 2023)
- DungeonEditor
- DungeonObjectRenderer
## 0.0.4 (November 2023)
- Tile16Editor
- GfxGroupEditor
- Add GfxGroups functions to Rom
- Add Tile16Editor and GfxGroupEditor to OverworldEditor
## 0.0.3 (October 2023)
- Emulator subsystem
- SNES PPU and PPURegisters

62
docs/D1-roadmap.md Normal file
View File

@@ -0,0 +1,62 @@
# Roadmap
## 0.4.X (Next Major Release)
### Core Features
- **Overworld Sprites**: Complete sprite editing with add/remove functionality
- **Enhanced Dungeon Editing**: Advanced room object editing and manipulation
- **Tile16 Editing**: Enhanced editor for creating and modifying tile16 data
- **Plugin Architecture**: Framework for community extensions and custom tools
- **Graphics Sheets**: Complete editing, saving, and re-importing of sheets
- **Project Refactoring**: Clean up resource loading and memory usage
### Technical Improvements
- **Sprite Property Editor**: Add support for changing sprite behavior and attributes
- **Custom Sprites**: Support creating and editing custom sprites
- **Asar Patching**: Stabilize existing patching system for advanced modifications
## 0.5.X
### Advanced Features
- **SCAD Format**: Polish and finalize the scad file integration
- **Hex Editing Improvements**: Enhance user interface for direct ROM manipulation
- **Music Editing**: Add an interface to edit and manage music data
## 0.6.X
### Platform & Integration
- **Cross-Platform Stability**: Test and refine builds across Windows, macOS, iOS, and Linux
- **Plugin/Integration Framework**: Provide hooks or scripting for community add-ons
## 0.7.X
### Performance & Polish
- **Performance Optimizations**: Remove bottlenecks in rendering and data processing
- **Documentation Overhaul**: Update manuals, guides, and in-app tooltips
## 0.8.X
### Beta Preparation
- **Beta Release**: Code freeze on major features, focus on bug fixes and polish
- **User Interface Refinements**: Improve UI consistency, iconography, and layout
- **Internal Cleanup**: Remove deprecated code, finalize API calls
## 1.0.0
### Stable Release
- **Stable Release**: Final, production-ready version
- **Changelog**: Comprehensive summary of all changes since 0.0.0
## Current Focus Areas
### Immediate Priorities (v0.4.X)
1. **Dungeon Editor Refactoring**: Complete component-based architecture
2. **Sprite System**: Implement comprehensive sprite editing
3. **Graphics Pipeline**: Enhance graphics editing capabilities
4. **Plugin System**: Enable community extensions
### Long-term Vision
- **Community-Driven**: Robust plugin system for community contributions
- **Cross-Platform Excellence**: Seamless experience across all platforms
- **Performance**: Optimized for large ROMs and complex modifications
- **Accessibility**: User-friendly interface for both beginners and experts

View File

@@ -0,0 +1,360 @@
# Dungeon Editor Guide
## Overview
The Yaze Dungeon Editor is a comprehensive tool for editing Zelda 3: A Link to the Past dungeon rooms, objects, sprites, items, entrances, doors, and chests. It provides an integrated editing experience with real-time rendering, coordinate system management, and advanced features for dungeon modification.
## Architecture
### Core Components
#### 1. DungeonEditorSystem
- **Purpose**: Central coordinator for all dungeon editing operations
- **Location**: `src/app/zelda3/dungeon/dungeon_editor_system.h/cc`
- **Features**:
- Room management (loading, saving, creating, deleting)
- Sprite management (enemies, NPCs, interactive objects)
- Item management (keys, hearts, rupees, etc.)
- Entrance/exit management (room connections)
- Door management (locked doors, key requirements)
- Chest management (treasure placement)
- Undo/redo system
- Event callbacks for real-time updates
#### 2. DungeonObjectEditor
- **Purpose**: Specialized editor for room objects (walls, floors, decorations)
- **Location**: `src/app/zelda3/dungeon/dungeon_object_editor.h/cc`
- **Features**:
- Object placement and editing
- Layer management (BG1, BG2, BG3)
- Object size editing with scroll wheel
- Collision detection and validation
- Selection and multi-selection
- Grid snapping
- Real-time preview
#### 3. ObjectRenderer
- **Purpose**: High-performance rendering system for dungeon objects
- **Location**: `src/app/zelda3/dungeon/object_renderer.h/cc`
- **Features**:
- Graphics cache for performance optimization
- Memory pool management
- Performance monitoring and statistics
- Object parsing from ROM data
- Palette support and color management
- Batch rendering for efficiency
#### 4. DungeonEditor (UI Layer)
- **Purpose**: User interface and interaction handling
- **Location**: `src/app/editor/dungeon/dungeon_editor.h/cc`
- **Features**:
- Integrated tabbed interface
- Canvas-based room editing
- Coordinate system management
- Object preview system
- Real-time rendering
- Compact editing panels
## Coordinate System
### Room Coordinates vs Canvas Coordinates
The dungeon editor uses a two-tier coordinate system:
1. **Room Coordinates**: 16x16 tile units (as used in the ROM)
2. **Canvas Coordinates**: Pixel coordinates for rendering
#### Conversion Functions
```cpp
// Convert room coordinates to canvas coordinates
std::pair<int, int> RoomToCanvasCoordinates(int room_x, int room_y) const {
return {room_x * 16, room_y * 16};
}
// Convert canvas coordinates to room coordinates
std::pair<int, int> CanvasToRoomCoordinates(int canvas_x, int canvas_y) const {
return {canvas_x / 16, canvas_y / 16};
}
// Check if coordinates are within canvas bounds
bool IsWithinCanvasBounds(int canvas_x, int canvas_y, int margin = 32) const;
```
### Coordinate System Features
- **Automatic Bounds Checking**: Objects outside visible canvas area are culled
- **Scrolling Support**: Canvas handles scrolling internally with proper coordinate transformation
- **Grid Alignment**: 16x16 pixel grid for precise object placement
- **Margin Support**: Configurable margins for partial object visibility
## Object Rendering System
### Object Types
The system supports three main object subtypes based on ROM structure:
1. **Subtype 1** (0x00-0xFF): Standard room objects (walls, floors, decorations)
2. **Subtype 2** (0x100-0x1FF): Interactive objects (doors, switches, chests)
3. **Subtype 3** (0x200+): Special objects (stairs, warps, bosses)
### Rendering Pipeline
1. **Object Loading**: Objects are loaded from ROM data using `LoadObjects()`
2. **Tile Parsing**: Object tiles are parsed using `ObjectParser`
3. **Graphics Caching**: Frequently used graphics are cached for performance
4. **Palette Application**: SNES palettes are applied to object graphics
5. **Canvas Rendering**: Objects are rendered to canvas with proper coordinate transformation
### Performance Optimizations
- **Graphics Cache**: Reduces redundant graphics sheet loading
- **Memory Pool**: Efficient memory allocation for rendering
- **Batch Rendering**: Multiple objects rendered in single pass
- **Bounds Culling**: Objects outside visible area are skipped
- **Cache Invalidation**: Smart cache management based on palette changes
## User Interface
### Integrated Editing Panels
The dungeon editor features a consolidated interface with:
#### Main Canvas
- **Room Visualization**: Real-time room rendering with background layers
- **Object Display**: Objects rendered with proper positioning and sizing
- **Interactive Editing**: Click-to-select, drag-to-move, scroll-to-resize
- **Grid Overlay**: Optional grid display for precise positioning
- **Coordinate Display**: Real-time coordinate information
#### Compact Editing Panels
1. **Object Editor**
- Mode selection (Select, Insert, Edit, Delete)
- Layer management (BG1, BG2, BG3)
- Object type selection
- Size editing with scroll wheel
- Configuration options (snap to grid, show grid)
2. **Sprite Editor**
- Sprite placement and management
- Enemy and NPC configuration
- Layer assignment
- Quick sprite addition
3. **Item Editor**
- Item placement (keys, hearts, rupees)
- Hidden item configuration
- Item type selection
- Room assignment
4. **Entrance Editor**
- Room connection management
- Bidirectional connection support
- Position configuration
- Connection validation
5. **Door Editor**
- Door placement and configuration
- Lock status management
- Key requirement setup
- Direction and target room assignment
6. **Chest Editor**
- Treasure chest placement
- Item and quantity configuration
- Big chest support
- Opened status tracking
7. **Properties Editor**
- Room metadata management
- Dungeon settings
- Music and ambient sound configuration
- Boss room and save room flags
### Object Preview System
- **Real-time Preview**: Objects are previewed in the canvas as they're selected
- **Centered Display**: Preview objects are centered in the canvas for optimal viewing
- **Palette Support**: Previews use current palette settings
- **Information Display**: Object properties are shown in preview window
## Integration with ZScream
The dungeon editor is designed to be compatible with ZScream C# patterns:
### Room Loading
- Uses same room loading patterns as ZScream
- Compatible with ZScream room data structures
- Supports ZScream room naming conventions
### Object Parsing
- Follows ZScream object parsing logic
- Compatible with ZScream object type definitions
- Supports ZScream size encoding
### Coordinate System
- Matches ZScream coordinate conventions
- Uses same tile size calculations
- Compatible with ZScream positioning logic
## Testing and Validation
### Integration Tests
The system includes comprehensive integration tests:
1. **Basic Object Rendering**: Tests fundamental object rendering functionality
2. **Multi-Palette Rendering**: Tests rendering with different palettes
3. **Real Room Object Rendering**: Tests with actual ROM room data
4. **Disassembly Room Validation**: Tests specific rooms from disassembly
5. **Performance Testing**: Measures rendering performance and memory usage
6. **Cache Effectiveness**: Tests graphics cache performance
7. **Error Handling**: Tests error conditions and edge cases
### Test Data
Tests use real ROM data from `build/bin/zelda3.sfc`:
- **Room 0x0000**: Ganon's room (from disassembly)
- **Room 0x0002, 0x0012**: Sewer rooms (from disassembly)
- **Room 0x0020**: Agahnim's tower (from disassembly)
- **Additional rooms**: 0x0001, 0x0010, 0x0033, 0x005A
### Performance Benchmarks
- **Rendering Time**: < 500ms for 100 objects
- **Memory Usage**: < 100MB for large object sets
- **Cache Hit Rate**: Optimized for frequent object access
- **Coordinate Conversion**: O(1) coordinate transformation
## Usage Examples
### Basic Object Editing
```cpp
// Load a room
auto room_result = dungeon_editor_system_->GetRoom(0x0000);
// Add an object
auto status = object_editor_->InsertObject(5, 5, 0x10, 0x12, 0);
// Parameters: x, y, object_type, size, layer
// Render objects
auto result = object_renderer_->RenderObjects(objects, palette);
```
### Coordinate Conversion
```cpp
// Convert room coordinates to canvas coordinates
auto [canvas_x, canvas_y] = RoomToCanvasCoordinates(room_x, room_y);
// Check if coordinates are within bounds
if (IsWithinCanvasBounds(canvas_x, canvas_y)) {
// Render object at this position
}
```
### Object Preview
```cpp
// Create preview object
auto preview_object = zelda3::RoomObject(id, 8, 8, 0x12, 0);
preview_object.set_rom(rom_);
preview_object.EnsureTilesLoaded();
// Render preview
auto result = object_renderer_->RenderObject(preview_object, palette);
```
## Configuration Options
### Editor Configuration
```cpp
struct EditorConfig {
bool snap_to_grid = true;
int grid_size = 16;
bool show_grid = true;
bool show_preview = true;
bool auto_save = false;
int auto_save_interval = 300;
bool validate_objects = true;
bool show_collision_bounds = false;
};
```
### Performance Configuration
```cpp
// Object renderer settings
object_renderer_->SetCacheSize(100);
object_renderer_->EnablePerformanceMonitoring(true);
// Canvas settings
canvas_.SetCanvasSize(ImVec2(512, 512));
canvas_.set_draggable(true);
```
## Troubleshooting
### Common Issues
1. **Objects Not Displaying**
- Check if ROM is loaded
- Verify object tiles are loaded with `EnsureTilesLoaded()`
- Check coordinate bounds with `IsWithinCanvasBounds()`
2. **Coordinate Misalignment**
- Use coordinate conversion functions
- Check canvas scrolling settings
- Verify grid alignment
3. **Performance Issues**
- Enable graphics caching
- Check memory usage with `GetMemoryUsage()`
- Monitor performance stats with `GetPerformanceStats()`
4. **Preview Not Showing**
- Verify object is within canvas bounds
- Check palette is properly set
- Ensure object has valid tiles
### Debug Information
The system provides comprehensive debug information:
- Object count and statistics
- Cache hit/miss rates
- Memory usage tracking
- Performance metrics
- Coordinate system validation
## Future Enhancements
### Planned Features
1. **Advanced Object Editing**
- Multi-object selection and manipulation
- Object grouping and layers
- Advanced collision detection
2. **Enhanced Rendering**
- Real-time lighting effects
- Animation support
- Advanced shader effects
3. **Improved UX**
- Keyboard shortcuts
- Context menus
- Undo/redo visualization
4. **Integration Features**
- ZScream project import/export
- Collaborative editing
- Version control integration
## Conclusion
The Yaze Dungeon Editor provides a comprehensive, high-performance solution for editing Zelda 3 dungeon rooms. With its integrated interface, robust coordinate system, and advanced rendering capabilities, it offers both novice and expert users the tools needed to create and modify dungeon content effectively.
The system's compatibility with ZScream patterns and comprehensive testing ensure reliability and consistency with existing tools, while its modern architecture provides a foundation for future enhancements and features.

View File

@@ -0,0 +1,364 @@
# Dungeon Editor Design Plan
## Overview
This document provides a comprehensive guide for future developers working on the Zelda 3 Dungeon Editor system. The dungeon editor has been refactored into a modular, component-based architecture that separates concerns and improves maintainability.
## Architecture Overview
### Core Components
The dungeon editor system consists of several key components:
1. **DungeonEditor** - Main orchestrator class that manages the overall editor state
2. **DungeonRoomSelector** - Handles room and entrance selection UI
3. **DungeonCanvasViewer** - Manages the main canvas rendering and room display
4. **DungeonObjectSelector** - Provides object selection, editing panels, and tile graphics
5. **ObjectRenderer** - Core rendering engine for dungeon objects
6. **DungeonEditorSystem** - High-level system for managing dungeon editing operations
### File Structure
```
src/app/editor/dungeon/
├── dungeon_editor.h/cc # Main editor orchestrator
├── dungeon_room_selector.h/cc # Room/entrance selection component
├── dungeon_canvas_viewer.h/cc # Canvas rendering component
├── dungeon_object_selector.h/cc # Object editing component
└── dungeon_editor_system.h/cc # Core editing system
src/app/zelda3/dungeon/
├── object_renderer.h/cc # Object rendering engine
├── dungeon_object_editor.h/cc # Object editing logic
├── room.h/cc # Room data structures
├── room_object.h/cc # Object data structures
└── room_entrance.h/cc # Entrance data structures
```
## Component Responsibilities
### DungeonEditor (Main Orchestrator)
**Responsibilities:**
- Manages overall editor state and ROM data
- Coordinates between UI components
- Handles data initialization and propagation
- Implements the 3-column layout (Room Selector | Canvas | Object Selector)
**Key Methods:**
- `UpdateDungeonRoomView()` - Main UI update loop
- `Load()` - Initialize editor with ROM data
- `set_rom()` - Update ROM reference across components
### DungeonRoomSelector
**Responsibilities:**
- Room selection and navigation
- Entrance selection and editing
- Active room management
- Room list display with names
**Key Methods:**
- `Draw()` - Main rendering method
- `DrawRoomSelector()` - Room list and selection
- `DrawEntranceSelector()` - Entrance editing interface
- `set_rom()`, `set_rooms()`, `set_entrances()` - Data access methods
### DungeonCanvasViewer
**Responsibilities:**
- Main canvas rendering and display
- Room graphics loading and management
- Object rendering with proper coordinates
- Background layer management
- Coordinate conversion (room ↔ canvas)
**Key Methods:**
- `Draw(int room_id)` - Main canvas rendering
- `LoadAndRenderRoomGraphics()` - Graphics loading
- `RenderObjectInCanvas()` - Object rendering
- `RoomToCanvasCoordinates()` - Coordinate conversion
- `RenderRoomBackgroundLayers()` - Background rendering
### DungeonObjectSelector
**Responsibilities:**
- Object selection and preview
- Tile graphics display
- Compact editing panels for all editor modes
- Object renderer integration
**Key Methods:**
- `Draw()` - Main rendering with tabbed interface
- `DrawRoomGraphics()` - Tile graphics display
- `DrawIntegratedEditingPanels()` - Editing interface
- `DrawCompactObjectEditor()` - Object editing controls
- `DrawCompactSpriteEditor()` - Sprite editing controls
- Similar methods for Items, Entrances, Doors, Chests, Properties
## Data Flow
### Initialization Flow
1. **ROM Loading**: `DungeonEditor::Load()` is called with ROM data
2. **Component Setup**: ROM and data pointers are propagated to all components
3. **Graphics Initialization**: Room graphics are loaded and cached
4. **UI State Setup**: Active rooms, palettes, and editor modes are initialized
### Runtime Data Flow
1. **User Interaction**: User selects rooms, objects, or editing modes
2. **State Updates**: Components update their internal state
3. **Data Propagation**: Changes are communicated between components
4. **Rendering**: All components re-render with updated data
### Key Data Structures
```cpp
// Main editor state
std::array<zelda3::Room, 0x128> rooms_;
std::array<zelda3::RoomEntrance, 0x8C> entrances_;
ImVector<int> active_rooms_;
gfx::PaletteGroup current_palette_group_;
// Component instances
DungeonRoomSelector room_selector_;
DungeonCanvasViewer canvas_viewer_;
DungeonObjectSelector object_selector_;
```
## Integration Patterns
### Component Communication
Components communicate through:
1. **Direct method calls** - Parent calls child methods
2. **Data sharing** - Shared pointers to common data structures
3. **Event propagation** - State changes trigger updates
### ROM Data Management
```cpp
// ROM propagation pattern
void DungeonEditor::set_rom(Rom* rom) {
rom_ = rom;
room_selector_.set_rom(rom);
canvas_viewer_.SetRom(rom);
object_selector_.SetRom(rom);
}
```
### State Synchronization
Components maintain their own state but receive updates from the main editor:
- Room selection state is managed by `DungeonRoomSelector`
- Canvas rendering state is managed by `DungeonCanvasViewer`
- Object editing state is managed by `DungeonObjectSelector`
## UI Layout Architecture
### 3-Column Layout
The main editor uses a 3-column ImGui table layout:
```cpp
if (BeginTable("#DungeonEditTable", 3, kDungeonTableFlags, ImVec2(0, 0))) {
TableSetupColumn("Room/Entrance Selector", ImGuiTableColumnFlags_WidthFixed, 250);
TableSetupColumn("Canvas", ImGuiTableColumnFlags_WidthStretch);
TableSetupColumn("Object Selector/Editor", ImGuiTableColumnFlags_WidthFixed, 300);
// Column 1: Room Selector
TableNextColumn();
room_selector_.Draw();
// Column 2: Canvas
TableNextColumn();
canvas_viewer_.Draw(current_room);
// Column 3: Object Selector
TableNextColumn();
object_selector_.Draw();
}
```
### Component Internal Layout
Each component manages its own internal layout:
- **DungeonRoomSelector**: Tabbed interface (Rooms | Entrances)
- **DungeonCanvasViewer**: Canvas with controls and debug popup
- **DungeonObjectSelector**: Tabbed interface (Graphics | Editor)
## Coordinate System
### Room Coordinates vs Canvas Coordinates
- **Room Coordinates**: 16x16 tile units (0-15 for a standard room)
- **Canvas Coordinates**: Pixel coordinates for rendering
- **Conversion**: `RoomToCanvasCoordinates(x, y) = (x * 16, y * 16)`
### Bounds Checking
All rendering operations include bounds checking:
```cpp
bool IsWithinCanvasBounds(int canvas_x, int canvas_y, int margin = 32) const;
```
## Error Handling & Validation
### ROM Validation
All components validate ROM state before operations:
```cpp
if (!rom_ || !rom_->is_loaded()) {
ImGui::Text("ROM not loaded");
return;
}
```
### Bounds Validation
Graphics operations include bounds checking:
```cpp
if (room_id < 0 || room_id >= rooms_->size()) {
return; // Skip invalid operations
}
```
## Performance Considerations
### Caching Strategy
- **Object Render Cache**: Cached rendered bitmaps to avoid re-rendering
- **Graphics Cache**: Cached graphics sheets for frequently accessed data
- **Memory Pool**: Efficient memory allocation for temporary objects
### Rendering Optimization
- **Viewport Culling**: Objects outside visible area are not rendered
- **Lazy Loading**: Graphics are loaded only when needed
- **Selective Updates**: Only changed components re-render
## Testing Strategy
### Integration Tests
The system includes comprehensive integration tests:
- `dungeon_object_renderer_integration_test.cc` - Core rendering tests
- `dungeon_editor_system_integration_test.cc` - System integration tests
- `dungeon_object_renderer_mock_test.cc` - Mock ROM testing
### Test Categories
1. **Real ROM Tests**: Tests with actual Zelda 3 ROM data
2. **Mock ROM Tests**: Tests with simulated ROM data
3. **Performance Tests**: Rendering performance benchmarks
4. **Error Handling Tests**: Validation and error recovery
## Future Development Guidelines
### Adding New Features
1. **Identify Component**: Determine which component should handle the feature
2. **Extend Interface**: Add necessary methods to component header
3. **Implement Logic**: Add implementation in component source file
4. **Update Integration**: Modify main editor to use new functionality
5. **Add Tests**: Create tests for new functionality
### Component Extension Patterns
```cpp
// Adding new data access method
void Component::SetNewData(const NewDataType& data) {
new_data_ = data;
}
// Adding new rendering method
void Component::DrawNewFeature() {
// Implementation
}
// Adding to main Draw method
void Component::Draw() {
// Existing code
DrawNewFeature();
}
```
### Data Flow Extension
When adding new data types:
1. Add to main editor state
2. Create setter methods in relevant components
3. Update initialization in `Load()` method
4. Add to `set_rom()` propagation if ROM-dependent
### UI Layout Extension
For new UI elements:
1. Determine placement (new tab, new panel, etc.)
2. Follow existing ImGui patterns
3. Maintain consistent spacing and styling
4. Add to appropriate component's Draw method
## Common Pitfalls & Solutions
### Memory Management
- **Issue**: Dangling pointers to ROM data
- **Solution**: Always validate ROM state before use
### Coordinate System
- **Issue**: Objects rendering at wrong positions
- **Solution**: Use coordinate conversion helper methods
### State Synchronization
- **Issue**: Components showing stale data
- **Solution**: Ensure data propagation in setter methods
### Performance Issues
- **Issue**: Slow rendering with many objects
- **Solution**: Implement viewport culling and caching
## Debugging Tools
### Debug Popup
The canvas viewer includes a comprehensive debug popup with:
- Object statistics and metadata
- Cache information
- Performance metrics
- Object type breakdowns
### Logging
Key operations include logging for debugging:
```cpp
std::cout << "Loading room graphics for room " << room_id << std::endl;
```
## Build Integration
### CMake Configuration
New components are automatically included via:
```cmake
# In CMakeLists.txt
file(GLOB YAZE_SRC_FILES "src/app/editor/dungeon/*.cc")
```
### Dependencies
Key dependencies:
- ImGui for UI rendering
- gfx library for graphics operations
- zelda3 library for ROM data structures
- absl for status handling
## Conclusion
This modular architecture provides a solid foundation for future dungeon editor development. The separation of concerns makes the codebase maintainable, testable, and extensible. Future developers should follow the established patterns and extend components rather than modifying the main orchestrator class.
For questions or clarifications, refer to the existing integration tests and component implementations as examples of proper usage patterns.

View File

@@ -0,0 +1,248 @@
# DungeonEditor Refactoring Plan
## Overview
This document outlines the comprehensive refactoring of the 1444-line `dungeon_editor.cc` file into focused, single-responsibility components.
## Component Structure
### ✅ Created Components
#### 1. DungeonToolset (`dungeon_toolset.h/cc`)
**Responsibility**: Toolbar UI management
- Background layer selection (All/BG1/BG2/BG3)
- Placement mode selection (Object/Sprite/Item/etc.)
- Undo/Redo buttons with callbacks
- **Replaces**: `DrawToolset()` method (~70 lines)
#### 2. DungeonObjectInteraction (`dungeon_object_interaction.h/cc`)
**Responsibility**: Object selection and placement
- Mouse interaction handling
- Object selection rectangle (like OverworldEditor)
- Drag and drop operations
- Coordinate conversion utilities
- **Replaces**: All mouse/selection methods (~400 lines)
#### 3. DungeonRenderer (`dungeon_renderer.h/cc`)
**Responsibility**: All rendering operations
- Object rendering with caching
- Background layer composition
- Layout object visualization
- Render cache management
- **Replaces**: All rendering methods (~200 lines)
#### 4. DungeonRoomLoader (`dungeon_room_loader.h/cc`)
**Responsibility**: ROM data loading
- Room loading from ROM
- Room size calculation
- Entrance loading
- Graphics loading coordination
- **Replaces**: Room loading methods (~150 lines)
#### 5. DungeonUsageTracker (`dungeon_usage_tracker.h/cc`)
**Responsibility**: Resource usage analysis
- Blockset/spriteset/palette usage tracking
- Usage statistics display
- Resource optimization insights
- **Replaces**: Usage statistics methods (~100 lines)
## Refactored DungeonEditor Structure
### Before Refactoring: 1444 lines
```cpp
class DungeonEditor {
// 30+ methods handling everything
// Mixed responsibilities
// Large data structures
// Complex dependencies
};
```
### After Refactoring: ~400 lines
```cpp
class DungeonEditor {
// Core editor interface (unchanged)
void Initialize() override;
absl::Status Load() override;
absl::Status Update() override;
absl::Status Save() override;
// High-level UI orchestration
absl::Status UpdateDungeonRoomView();
void DrawCanvasAndPropertiesPanel();
void DrawRoomPropertiesDebugPopup();
// Component coordination
void OnRoomSelected(int room_id);
private:
// Focused components
DungeonToolset toolset_;
DungeonObjectInteraction object_interaction_;
DungeonRenderer renderer_;
DungeonRoomLoader room_loader_;
DungeonUsageTracker usage_tracker_;
// Existing UI components
DungeonRoomSelector room_selector_;
DungeonCanvasViewer canvas_viewer_;
DungeonObjectSelector object_selector_;
// Core data and state
std::array<zelda3::Room, 0x128> rooms_;
bool is_loaded_ = false;
// etc.
};
```
## Method Migration Map
### Core Editor Methods (Keep in main file)
-`Initialize()` - Component initialization
-`Load()` - Delegates to room_loader_
-`Update()` - High-level update coordination
-`Save()`, `Undo()`, `Redo()` - Editor interface
-`UpdateDungeonRoomView()` - UI orchestration
### UI Methods (Keep for coordination)
-`DrawCanvasAndPropertiesPanel()` - Tab management
-`DrawRoomPropertiesDebugPopup()` - Debug popup
-`DrawDungeonTabView()` - Room tab management
-`DrawDungeonCanvas()` - Canvas coordination
-`OnRoomSelected()` - Room selection handling
### Methods Moved to Components
#### → DungeonToolset
-`DrawToolset()` - Toolbar rendering
#### → DungeonObjectInteraction
-`HandleCanvasMouseInput()` - Mouse handling
-`CheckForObjectSelection()` - Selection rectangle
-`DrawObjectSelectRect()` - Selection drawing
-`SelectObjectsInRect()` - Selection logic
-`PlaceObjectAtPosition()` - Object placement
-`DrawSelectBox()` - Selection visualization
-`DrawDragPreview()` - Drag preview
-`UpdateSelectedObjects()` - Selection updates
-`IsObjectInSelectBox()` - Selection testing
- ❌ Coordinate conversion helpers
#### → DungeonRenderer
-`RenderObjectInCanvas()` - Object rendering
-`DisplayObjectInfo()` - Object info overlay
-`RenderLayoutObjects()` - Layout rendering
-`RenderRoomBackgroundLayers()` - Background rendering
-`RefreshGraphics()` - Graphics refresh
- ❌ Object cache management
#### → DungeonRoomLoader
-`LoadDungeonRoomSize()` - Room size calculation
-`LoadAndRenderRoomGraphics()` - Graphics loading
-`ReloadAllRoomGraphics()` - Bulk reload
- ❌ Room size and address management
#### → DungeonUsageTracker
-`CalculateUsageStats()` - Usage calculation
-`DrawUsageStats()` - Usage display
-`DrawUsageGrid()` - Usage visualization
-`RenderSetUsage()` - Set usage rendering
## Component Communication
### Callback System
```cpp
// Object placement callback
object_interaction_.SetObjectPlacedCallback([this](const auto& object) {
renderer_.ClearObjectCache();
});
// Toolset callbacks
toolset_.SetUndoCallback([this]() { Undo(); });
toolset_.SetPaletteToggleCallback([this]() { palette_showing_ = !palette_showing_; });
// Object selection callback
object_selector_.SetObjectSelectedCallback([this](const auto& object) {
object_interaction_.SetPreviewObject(object, true);
toolset_.set_placement_type(DungeonToolset::kObject);
});
```
### Data Sharing
```cpp
// Update components with current room
void OnRoomSelected(int room_id) {
current_room_id_ = room_id;
object_interaction_.SetCurrentRoom(&rooms_, room_id);
// etc.
}
```
## Benefits of Refactoring
### 1. **Reduced Complexity**
- Main file: 1444 → ~400 lines (72% reduction)
- Single responsibility per component
- Clear separation of concerns
### 2. **Improved Testability**
- Individual components can be unit tested
- Mocking becomes easier
- Isolated functionality testing
### 3. **Better Maintainability**
- Changes isolated to relevant components
- Easier to locate and fix bugs
- Cleaner code reviews
### 4. **Enhanced Extensibility**
- New features added to appropriate components
- Component interfaces allow easy replacement
- Plugin-style architecture possible
### 5. **Cleaner Dependencies**
- UI separate from data manipulation
- Rendering separate from business logic
- Clear component boundaries
## Implementation Status
### ✅ Completed
- Created all component header files
- Created component implementation stubs
- Updated DungeonEditor header with components
- Basic component integration
### 🔄 In Progress
- Method migration from main file to components
- Component callback setup
- Legacy method removal
### ⏳ Pending
- Full method implementation in components
- Complete integration testing
- Documentation updates
- Build system updates
## Migration Strategy
### Phase 1: Create Components ✅
- Define component interfaces
- Create header and implementation files
- Set up basic structure
### Phase 2: Integrate Components 🔄
- Add components to DungeonEditor
- Set up callback systems
- Begin method delegation
### Phase 3: Move Methods
- Systematically move methods to components
- Update method calls to use components
- Remove old implementations
### Phase 4: Cleanup
- Remove unused member variables
- Clean up includes
- Update documentation
This refactoring transforms the monolithic DungeonEditor into a well-organized, component-based architecture that's easier to maintain, test, and extend.

View File

@@ -0,0 +1,271 @@
# Dungeon Object System
## Overview
The Dungeon Object System provides a comprehensive framework for editing and managing dungeon rooms, objects, and layouts in The Legend of Zelda: A Link to the Past. This system combines real-time visual editing with precise data manipulation to create a powerful dungeon creation and modification toolkit.
## Architecture
### Core Components
The dungeon system is built around several key components that work together to provide a seamless editing experience:
#### 1. DungeonEditor (`src/app/editor/dungeon/dungeon_editor.h`)
The main interface that orchestrates all dungeon editing functionality. It provides:
- **Windowed Canvas System**: Fixed-size canvas that prevents UI layout disruption
- **Tabbed Room Interface**: Multiple rooms can be open simultaneously for easy comparison and editing
- **Integrated Object Placement**: Direct object placement from selector to canvas
- **Real-time Preview**: Live object preview follows mouse cursor during placement
#### 2. DungeonObjectSelector (`src/app/editor/dungeon/dungeon_object_selector.h`)
Combines object browsing and editing in a unified interface:
- **Object Browser**: Visual grid of all available objects with real-time previews
- **Object Editor**: Integrated editing panels for sprites, items, entrances, doors, and chests
- **Callback System**: Notifies main editor when objects are selected for placement
#### 3. DungeonCanvasViewer (`src/app/editor/dungeon/dungeon_canvas_viewer.h`)
Specialized canvas for rendering dungeon rooms:
- **Background Layer Rendering**: Proper BG1/BG2 layer composition
- **Object Rendering**: Cached object rendering with palette support
- **Coordinate System**: Seamless translation between room and canvas coordinates
#### 4. Room Management System (`src/app/zelda3/dungeon/room.h`)
Core data structures for room representation:
- **Room Objects**: Tile-based objects (walls, floors, decorations)
- **Room Layout**: Structural elements and collision data
- **Sprites**: Enemy and NPC placement
- **Entrances/Exits**: Room connections and transitions
## Object Types and Hierarchies
### Room Objects
Room objects are the fundamental building blocks of dungeon rooms. They follow a hierarchical structure:
#### Type 1 Objects (0x00-0xFF)
Basic structural elements:
- **0x10-0x1F**: Wall objects (various types and orientations)
- **0x20-0x2F**: Floor tiles (stone, wood, carpet, etc.)
- **0x30-0x3F**: Decorative elements (torches, statues, pillars)
- **0x40-0x4F**: Interactive elements (switches, blocks)
#### Type 2 Objects (0x100-0x1FF)
Complex multi-tile objects:
- **0x100-0x10F**: Large wall sections
- **0x110-0x11F**: Complex floor patterns
- **0x120-0x12F**: Multi-tile decorations
#### Type 3 Objects (0x200+)
Special dungeon-specific objects:
- **0x200-0x20F**: Boss room elements
- **0x210-0x21F**: Puzzle-specific objects
- **0xF9-0xFA**: Chests (small and large)
### Object Properties
Each object has several key properties:
```cpp
class RoomObject {
int id_; // Object type identifier
int x_, y_; // Position in room (16x16 tile units)
int size_; // Size modifier (affects rendering)
LayerType layer_; // Rendering layer (0=BG, 1=MID, 2=FG)
// ... additional properties
};
```
## How Object Placement Works
### Selection Process
1. **Object Browser**: User selects an object from the visual grid
2. **Preview Generation**: Object is rendered with current room palette
3. **Callback Trigger**: Selection notifies main editor via callback
4. **Preview Update**: Main editor receives object and enables placement mode
### Placement Process
1. **Mouse Tracking**: Preview object follows mouse cursor on canvas
2. **Coordinate Translation**: Mouse position converted to room coordinates
3. **Visual Feedback**: Semi-transparent preview shows placement position
4. **Click Placement**: Left-click places object at current position
5. **Room Update**: Object added to room data and cache cleared for redraw
### Code Flow
```cpp
// Object selection in DungeonObjectSelector
if (ImGui::Selectable("", is_selected)) {
preview_object_ = selected_object;
object_loaded_ = true;
// Notify main editor
if (object_selected_callback_) {
object_selected_callback_(preview_object_);
}
}
// Object placement in DungeonEditor
void PlaceObjectAtPosition(int room_x, int room_y) {
auto new_object = preview_object_;
new_object.x_ = room_x;
new_object.y_ = room_y;
new_object.set_rom(rom_);
new_object.EnsureTilesLoaded();
room.AddTileObject(new_object);
object_render_cache_.clear(); // Force redraw
}
```
## Rendering Pipeline
### Object Rendering
The system uses a sophisticated rendering pipeline:
1. **Tile Loading**: Object tiles loaded from ROM based on object ID
2. **Palette Application**: Room-specific palette applied to object
3. **Bitmap Generation**: Object rendered to bitmap with proper composition
4. **Caching**: Rendered objects cached for performance
5. **Canvas Drawing**: Bitmap drawn to canvas at correct position
### Performance Optimizations
- **Render Caching**: Objects cached based on ID, position, size, and palette hash
- **Bounds Checking**: Only objects within canvas bounds are rendered
- **Lazy Loading**: Graphics and objects loaded on-demand
- **Palette Hashing**: Efficient cache invalidation when palettes change
## User Interface Components
### Three-Column Layout
The dungeon editor uses a carefully designed three-column layout:
#### Column 1: Room Control Panel (280px fixed)
- **Room Selector**: Browse and select rooms
- **Debug Controls**: Room properties in table format
- **Object Statistics**: Live object counts and cache status
#### Column 2: Windowed Canvas (800px fixed)
- **Tabbed Interface**: Multiple rooms open simultaneously
- **Fixed Dimensions**: Prevents UI layout disruption
- **Real-time Preview**: Object placement preview follows cursor
- **Layer Visualization**: Proper background/foreground rendering
#### Column 3: Object Selector/Editor (stretch)
- **Object Browser Tab**: Visual grid of available objects
- **Object Editor Tab**: Integrated editing for sprites, items, etc.
- **Placement Tools**: Object property editing and placement controls
### Debug and Control Features
#### Room Properties Table
Real-time editing of room attributes:
```
Property | Value
------------|--------
Room ID | 0x001 (1)
Layout | [Hex Input]
Blockset | [Hex Input]
Spriteset | [Hex Input]
Palette | [Hex Input]
Floor 1 | [Hex Input]
Floor 2 | [Hex Input]
Message ID | [Hex Input]
```
#### Object Statistics
Live feedback on room contents:
- Total objects count
- Layout objects count
- Sprites count
- Chests count
- Cache status and controls
## Integration with ROM Data
### Data Sources
The system integrates with multiple ROM data sources:
#### Room Headers (`0x1F8000`)
- Room layout index
- Blockset and spriteset references
- Palette assignments
- Floor type definitions
#### Object Data
- Object definitions and tile mappings
- Size and layer information
- Interaction properties
#### Graphics Data
- Tile graphics (4bpp SNES format)
- Palette data (15-color palettes)
- Blockset compositions
### Assembly Integration
The system references the US disassembly (`assets/asm/usdasm/`) for:
- Room data structure validation
- Object type definitions
- Memory layout verification
- Data pointer validation
## Comparison with ZScream
### Architectural Differences
YAZE's approach differs from ZScream in several key ways:
#### Component-Based Architecture
- **YAZE**: Modular components with clear separation of concerns
- **ZScream**: More monolithic approach with integrated functionality
#### Real-time Rendering
- **YAZE**: Live object preview with mouse tracking
- **ZScream**: Static preview with separate placement step
#### UI Organization
- **YAZE**: Fixed-width columns prevent layout disruption
- **ZScream**: Resizable panels that can affect overall layout
#### Caching Strategy
- **YAZE**: Sophisticated object render caching with hash-based invalidation
- **ZScream**: Simpler caching approach
### Shared Concepts
Both systems share fundamental concepts:
- Object-based room construction
- Layer-based rendering
- ROM data integration
- Visual object browsing
## Best Practices
### Performance
1. **Use Render Caching**: Don't clear cache unnecessarily
2. **Bounds Checking**: Only render visible objects
3. **Lazy Loading**: Load graphics and objects on-demand
4. **Efficient Callbacks**: Minimize callback frequency
### Code Organization
1. **Separation of Concerns**: Keep UI, data, and rendering separate
2. **Clear Interfaces**: Use callbacks for component communication
3. **Error Handling**: Validate ROM data and handle errors gracefully
4. **Memory Management**: Clean up resources properly
### User Experience
1. **Visual Feedback**: Provide clear object placement preview
2. **Consistent Layout**: Use fixed dimensions for stable UI
3. **Contextual Information**: Show relevant object properties
4. **Efficient Workflow**: Minimize clicks for common operations
## Future Enhancements
### Planned Features
1. **Drag and Drop**: Direct object dragging from selector to canvas
2. **Multi-Selection**: Select and manipulate multiple objects
3. **Copy/Paste**: Copy object configurations between rooms
4. **Undo/Redo**: Full edit history management
5. **Template System**: Save and load room templates
### Technical Improvements
1. **GPU Acceleration**: Move rendering to GPU for better performance
2. **Advanced Caching**: Predictive loading and intelligent cache management
3. **Background Processing**: Asynchronous ROM data loading
4. **Memory Optimization**: Reduce memory footprint for large dungeons
This documentation provides a comprehensive understanding of how the YAZE dungeon object system works, from high-level architecture to low-level implementation details. The system is designed to be both powerful for advanced users and accessible for newcomers to dungeon editing.

View File

@@ -0,0 +1,492 @@
# Overworld Loading Guide
This document provides a comprehensive guide to understanding how overworld loading works in both ZScream (C#) and yaze (C++), including the differences between vanilla ROMs and ZSCustomOverworld v2/v3 ROMs.
## Table of Contents
1. [Overview](#overview)
2. [ROM Types and Versions](#rom-types-and-versions)
3. [Overworld Map Structure](#overworld-map-structure)
4. [Loading Process](#loading-process)
5. [ZScream Implementation](#zscream-implementation)
6. [Yaze Implementation](#yaze-implementation)
7. [Key Differences](#key-differences)
8. [Common Issues and Solutions](#common-issues-and-solutions)
## Overview
Both ZScream and yaze are Zelda 3 ROM editors that support editing overworld maps. They handle three main types of ROMs:
- **Vanilla ROMs**: Original Zelda 3 ROMs without modifications
- **ZSCustomOverworld v2**: ROMs with expanded overworld features
- **ZSCustomOverworld v3**: ROMs with additional features like overlays and custom background colors
## ROM Types and Versions
### Version Detection
Both editors detect the ROM version using the same constant:
```cpp
// Address: 0x140145
constexpr int OverworldCustomASMHasBeenApplied = 0x140145;
// Version values:
// 0xFF = Vanilla ROM
// 0x02 = ZSCustomOverworld v2
// 0x03 = ZSCustomOverworld v3
```
### Feature Support by Version
| Feature | Vanilla | v2 | v3 |
|---------|---------|----|----|
| Basic Overworld Maps | ✅ | ✅ | ✅ |
| Area Size Enum | ❌ | ❌ | ✅ |
| Main Palette | ❌ | ✅ | ✅ |
| Custom Background Colors | ❌ | ✅ | ✅ |
| Subscreen Overlays | ✅ | ✅ | ✅ |
| Animated GFX | ❌ | ❌ | ✅ |
| Custom Tile Graphics | ❌ | ❌ | ✅ |
| Vanilla Overlays | ✅ | ✅ | ✅ |
**Note:** Subscreen overlays are visual effects (fog, rain, backgrounds, etc.) that are shared between vanilla ROMs and ZSCustomOverworld. ZSCustomOverworld v2+ expands on this by adding support for custom overlay configurations and additional overlay types.
## Overworld Map Structure
### Core Properties
Each overworld map contains the following core properties:
```cpp
class OverworldMap {
// Basic properties
uint8_t index_; // Map index (0-159)
uint8_t parent_; // Parent map ID
uint8_t world_; // World type (0=LW, 1=DW, 2=SW)
uint8_t game_state_; // Game state (0=Beginning, 1=Zelda, 2=Agahnim)
// Graphics and palettes
uint8_t area_graphics_; // Area graphics ID
uint8_t area_palette_; // Area palette ID
uint8_t main_palette_; // Main palette ID (v2+)
std::array<uint8_t, 3> sprite_graphics_; // Sprite graphics IDs
std::array<uint8_t, 3> sprite_palette_; // Sprite palette IDs
// Map properties
uint16_t message_id_; // Message ID
bool mosaic_; // Mosaic effect enabled
bool large_map_; // Is large map (vanilla)
AreaSizeEnum area_size_; // Area size (v3)
// Custom features (v2/v3)
uint16_t area_specific_bg_color_; // Custom background color
uint16_t subscreen_overlay_; // Subscreen overlay ID (references special area maps)
uint8_t animated_gfx_; // Animated graphics ID
std::array<uint8_t, 8> custom_gfx_ids_; // Custom tile graphics
// Overlay support (vanilla and custom)
uint16_t vanilla_overlay_id_; // Vanilla overlay ID
bool has_vanilla_overlay_; // Has vanilla overlay data
std::vector<uint8_t> vanilla_overlay_data_; // Raw overlay data
};
```
## Overlays and Special Area Maps
### Understanding Overlays
Overlays in Zelda 3 are **visual effects** that are displayed over or behind the main overworld map. They include effects like fog, rain, canopy, backgrounds, and other atmospheric elements. Overlays are collections of tile positions and tile IDs that specify where to place specific graphics on the map.
### Special Area Maps (0x80-0x9F)
The special area maps (0x80-0x9F) contain the actual tile data for overlays. These maps store the graphics that overlays reference and use to create visual effects:
- **0x80-0x8F**: Various special area maps containing overlay graphics
- **0x90-0x9F**: Additional special area maps including more overlay graphics
### Overlay ID Mappings
Overlay IDs directly correspond to special area map indices. Common overlay mappings:
| Overlay ID | Special Area Map | Description |
|------------|------------------|-------------|
| 0x0093 | 0x93 | Triforce Room Curtain |
| 0x0094 | 0x94 | Under the Bridge |
| 0x0095 | 0x95 | Sky Background (LW Death Mountain) |
| 0x0096 | 0x96 | Pyramid Background |
| 0x0097 | 0x97 | First Fog Overlay (Master Sword Area) |
| 0x009C | 0x9C | Lava Background (DW Death Mountain) |
| 0x009D | 0x9D | Second Fog Overlay (Lost Woods/Skull Woods) |
| 0x009E | 0x9E | Tree Canopy (Forest) |
| 0x009F | 0x9F | Rain Effect (Misery Mire) |
### Drawing Order
Overlays are drawn in a specific order based on their type:
- **Background Overlays** (0x95, 0x96, 0x9C): Drawn behind the main map tiles
- **Foreground Overlays** (0x9D, 0x97, 0x93, 0x94, 0x9E, 0x9F): Drawn on top of the main map tiles with transparency
### Vanilla Overlay Loading
In vanilla ROMs, overlays are loaded by parsing SNES assembly-like commands that specify tile positions and IDs:
```cpp
absl::Status LoadVanillaOverlay() {
uint8_t asm_version = (*rom_)[OverworldCustomASMHasBeenApplied];
// Only load vanilla overlays for vanilla ROMs
if (asm_version != 0xFF) {
has_vanilla_overlay_ = false;
return absl::OkStatus();
}
// Load overlay pointer for this map
int address = (kOverlayPointersBank << 16) +
((*rom_)[kOverlayPointers + (index_ * 2) + 1] << 8) +
(*rom_)[kOverlayPointers + (index_ * 2)];
// Parse overlay commands:
// LDA #$xxxx - Load tile ID into accumulator
// LDX #$xxxx - Load position into X register
// STA $xxxx - Store tile at position
// STA $xxxx,x - Store tile at position + X
// INC A - Increment accumulator (for sequential tiles)
// JMP $xxxx - Jump to another overlay routine
// END (0x60) - End of overlay data
return absl::OkStatus();
}
```
### Special Area Graphics Loading
Special area maps require special handling for graphics loading:
```cpp
void LoadAreaInfo() {
if (parent_ >= kSpecialWorldMapIdStart) {
// Special World (SW) areas
if (asm_version >= 3 && asm_version != 0xFF) {
// Use expanded sprite tables for v3
sprite_graphics_[0] = (*rom_)[kOverworldSpecialSpriteGfxGroupExpandedTemp +
parent_ - kSpecialWorldMapIdStart];
} else {
// Use original sprite tables for v2/vanilla
sprite_graphics_[0] = (*rom_)[kOverworldSpecialGfxGroup +
parent_ - kSpecialWorldMapIdStart];
}
// Handle special cases for specific maps
if (index_ == 0x88 || index_ == 0x93) {
area_graphics_ = 0x51;
area_palette_ = 0x00;
} else if (index_ == 0x95) {
// Make this the same GFX as LW death mountain areas
area_graphics_ = (*rom_)[kAreaGfxIdPtr + 0x03];
area_palette_ = (*rom_)[kOverworldMapPaletteIds + 0x03];
} else if (index_ == 0x96) {
// Make this the same GFX as pyramid areas
area_graphics_ = (*rom_)[kAreaGfxIdPtr + 0x5B];
area_palette_ = (*rom_)[kOverworldMapPaletteIds + 0x5B];
} else if (index_ == 0x9C) {
// Make this the same GFX as DW death mountain areas
area_graphics_ = (*rom_)[kAreaGfxIdPtr + 0x43];
area_palette_ = (*rom_)[kOverworldMapPaletteIds + 0x43];
}
}
}
```
## Loading Process
### 1. Version Detection
Both editors first detect the ROM version:
```cpp
uint8_t asm_version = rom[OverworldCustomASMHasBeenApplied];
```
### 2. Map Initialization
For each of the 160 overworld maps (0x00-0x9F):
```cpp
// ZScream
var map = new OverworldMap(index, overworld);
// Yaze
OverworldMap map(index, rom);
```
### 3. Property Loading
The loading process varies by ROM version:
#### Vanilla ROMs (asm_version == 0xFF)
```cpp
void LoadAreaInfo() {
// Load from vanilla tables
message_id_ = rom[kOverworldMessageIds + index_ * 2];
area_graphics_ = rom[kOverworldMapGfx + index_];
area_palette_ = rom[kOverworldMapPaletteIds + index_];
// Determine large map status
large_map_ = (rom[kOverworldMapSize + index_] != 0);
// Load vanilla overlay
LoadVanillaOverlay();
}
```
#### ZSCustomOverworld v2/v3
```cpp
void LoadAreaInfo() {
// Use expanded tables for v3
if (asm_version >= 3) {
message_id_ = rom[kOverworldMessagesExpanded + index_ * 2];
area_size_ = static_cast<AreaSizeEnum>(rom[kOverworldScreenSize + index_]);
} else {
message_id_ = rom[kOverworldMessageIds + index_ * 2];
area_size_ = large_map_ ? LargeArea : SmallArea;
}
// Load custom overworld data
LoadCustomOverworldData();
}
```
### 4. Custom Data Loading
For ZSCustomOverworld ROMs:
```cpp
void LoadCustomOverworldData() {
// Load main palette
main_palette_ = rom[OverworldCustomMainPaletteArray + index_];
// Load custom background color
if (rom[OverworldCustomAreaSpecificBGEnabled] != 0) {
area_specific_bg_color_ = rom[OverworldCustomAreaSpecificBGPalette + index_ * 2];
}
// Load v3 features
if (asm_version >= 3) {
subscreen_overlay_ = rom[OverworldCustomSubscreenOverlayArray + index_ * 2];
animated_gfx_ = rom[OverworldCustomAnimatedGFXArray + index_];
// Load custom tile graphics (8 sheets)
for (int i = 0; i < 8; i++) {
custom_gfx_ids_[i] = rom[OverworldCustomTileGFXGroupArray + index_ * 8 + i];
}
}
}
```
## ZScream Implementation
### OverworldMap Constructor
```csharp
public OverworldMap(byte index, Overworld overworld) {
Index = index;
this.overworld = overworld;
// Load area info
LoadAreaInfo();
// Load custom data if available
if (ROM.DATA[Constants.OverworldCustomASMHasBeenApplied] != 0xFF) {
LoadCustomOverworldData();
}
// Build graphics and palette
BuildMap();
}
```
### Key Methods
- `LoadAreaInfo()`: Loads basic map properties from ROM
- `LoadCustomOverworldData()`: Loads ZSCustomOverworld features
- `LoadPalette()`: Loads and processes palette data
- `BuildMap()`: Constructs the final map bitmap
**Note**: ZScream is the original C# implementation that yaze is designed to be compatible with.
## Yaze Implementation
### OverworldMap Constructor
```cpp
OverworldMap::OverworldMap(int index, Rom* rom) : index_(index), rom_(rom) {
LoadAreaInfo();
LoadCustomOverworldData();
SetupCustomTileset(asm_version);
}
```
### Key Methods
- `LoadAreaInfo()`: Loads basic map properties
- `LoadCustomOverworldData()`: Loads ZSCustomOverworld features
- `LoadVanillaOverlay()`: Loads vanilla overlay data
- `LoadPalette()`: Loads and processes palette data
- `BuildTileset()`: Constructs graphics tileset
- `BuildBitmap()`: Creates the final map bitmap
### Current Status
**ZSCustomOverworld v2/v3 Support**: Fully implemented and tested
**Vanilla ROM Support**: Complete compatibility maintained
**Overlay System**: Both vanilla and custom overlays supported
**Map Properties System**: Integrated with UI components
**Graphics Loading**: Optimized with caching and performance monitoring
## Key Differences
### 1. Language and Architecture
| Aspect | ZScream | Yaze |
|--------|---------|------|
| Language | C# | C++ |
| Memory Management | Garbage Collected | Manual (RAII) |
| Graphics | System.Drawing | Custom OpenGL |
| UI Framework | WinForms | ImGui |
### 2. Data Structures
**ZScream:**
```csharp
public class OverworldMap {
public byte Index { get; set; }
public AreaSizeEnum AreaSize { get; set; }
public Bitmap GFXBitmap { get; set; }
// ... other properties
}
```
**Yaze:**
```cpp
class OverworldMap {
uint8_t index_;
AreaSizeEnum area_size_;
std::vector<uint8_t> bitmap_data_;
// ... other member variables
};
```
### 3. Error Handling
**ZScream:** Uses exceptions and try-catch blocks
**Yaze:** Uses `absl::Status` return values and `RETURN_IF_ERROR` macros
### 4. Graphics Processing
**ZScream:** Uses .NET's `Bitmap` class and GDI+
**Yaze:** Uses custom `gfx::Bitmap` class with OpenGL textures
## Common Issues and Solutions
### 1. Version Detection Issues
**Problem:** ROM not recognized as ZSCustomOverworld
**Solution:** Check that `OverworldCustomASMHasBeenApplied` is set correctly
### 2. Palette Loading Errors
**Problem:** Maps appear with wrong colors
**Solution:** Verify palette group addresses and 0xFF fallback handling
### 3. Graphics Not Loading
**Problem:** Blank textures or missing graphics
**Solution:** Check graphics buffer bounds and ProcessGraphicsBuffer implementation
### 4. Overlay Issues
**Problem:** Vanilla overlays not displaying
**Solution:**
- Verify overlay pointer addresses and SNES-to-PC conversion
- Ensure special area maps (0x80-0x9F) are properly loaded with correct graphics
- Check that overlay ID mappings are correct (e.g., 0x009D → map 0x9D)
- Verify that overlay preview shows the actual bitmap of the referenced special area map
**Problem:** Overlay preview showing incorrect information
**Solution:** Ensure overlay preview correctly maps overlay IDs to special area map indices and displays the appropriate bitmap from the special area maps (0x80-0x9F)
### 5. Large Map Problems
**Problem:** Large maps not rendering correctly
**Solution:** Check parent-child relationships and large map detection logic
### 6. Special Area Graphics Issues
**Problem:** Special area maps (0x80-0x9F) showing blank or incorrect graphics
**Solution:**
- Verify special area graphics loading in `LoadAreaInfo()`
- Check that special cases for maps like 0x88, 0x93, 0x95, 0x96, 0x9C are handled correctly
- Ensure proper sprite graphics table selection for v2 vs v3 ROMs
- Verify that special area maps use the correct graphics from referenced LW/DW maps
## Best Practices
### 1. Version-Specific Code
Always check the ASM version before accessing version-specific features:
```cpp
uint8_t asm_version = (*rom_)[OverworldCustomASMHasBeenApplied];
if (asm_version >= 3) {
// v3 features
} else if (asm_version == 0xFF) {
// Vanilla features
}
```
### 2. Error Handling
Use proper error handling for ROM operations:
```cpp
absl::Status LoadPalette() {
RETURN_IF_ERROR(LoadPaletteData());
RETURN_IF_ERROR(ProcessPalette());
return absl::OkStatus();
}
```
### 3. Memory Management
Be careful with memory management in C++:
```cpp
// Good: RAII and smart pointers
std::vector<uint8_t> data;
std::unique_ptr<OverworldMap> map;
// Bad: Raw pointers without cleanup
uint8_t* raw_data = new uint8_t[size];
OverworldMap* map = new OverworldMap();
```
### 4. Thread Safety
Both editors use threading for performance:
```cpp
// Yaze: Use std::async for parallel processing
auto future = std::async(std::launch::async, [this](int map_index) {
RefreshChildMap(map_index);
}, map_index);
```
## Conclusion
Understanding the differences between ZScream and yaze implementations is crucial for maintaining compatibility and adding new features. Both editors follow similar patterns but use different approaches due to their respective languages and architectures.
The key is to maintain the same ROM data structure understanding while adapting to each editor's specific implementation patterns.

View File

@@ -1,94 +0,0 @@
# Build Instructions
For VSCode users, use the following CMake extensions
- https://marketplace.visualstudio.com/items?itemName=twxs.cmake
- https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools
Yaze uses CMake to build the project. If you are unexperienced with CMake, please refer to the [CMake documentation](https://cmake.org/documentation/).
The gui editor is built using SDL2 and ImGui. For reference on how to use ImGui, see the [Getting Started](https://github.com/ocornut/imgui/wiki/Getting-Started) guide. For SDL2, see the [SDL2 documentation](https://wiki.libsdl.org/).
For those who want to reduce compile times, consider installing the dependencies on your system.
## Windows
### vcpkg
For Visual Studio users, follow the [Install and use packages with CMake](https://learn.microsoft.com/en-us/vcpkg/get_started/get-started) tutorial from Microsoft.
Define the following dependencies in `vcpkg.json`
```
{
"dependencies": [
"abseil",
"sdl2",
"libpng"
]
}
```
Target the architecture in `CMakePresets.json`
```
{
"name": "vcpkg",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build",
"architecture": {
"value": "arm64/x64",
"strategy": "external"
},
"cacheVariables": {
"CMAKE_TOOLCHAIN_FILE": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake",
"CMAKE_SYSTEM_PROCESSOR": "arm64/x64"
}
}
```
### msys2
[msys2](https://www.msys2.org/) is an alternative you may use for a Unix-like environment on Windows. Beware that this is for more experienced developers who know how to manage their system PATH.
Add to environment variables `C:\msys64\mingw64\bin`
Install the following packages using `pacman -S <package-name>`
- `mingw-w64-x86_64-gcc`
- `mingw-w64-x86_64-gcc-libs`
- `mingw-w64-x86_64-cmake`
- `mingw-w64-x86_64-sdl2`
- `mingw-w64-x86_64-libpng`
- `mingw-w64-x86_64-abseil-cpp`
For `yaze_py` you will need Boost Python
- `mingw-w64-x86_64-boost`
# macOS
Prefer to use clang provided with XCode command line tools over gcc.
Install the following packages using `brew install <package-name>`
- `cmake`
- `sdl2`
- `zlib`
- `libpng`
- `abseil`
- `boost-python3`
# iOS
Xcode is required to build for iOS. Currently testing with iOS 18 on iPad Pro.
The xcodeproject file is located in the `ios` directory.
You will need to link `SDL2.framework` and `libpng.a` to the project.
# GNU/Linux
You can use your package manager to install the same dependencies as macOS.
I trust you know how to use your package manager.

View File

@@ -1,102 +0,0 @@
# Changelog
## 0.2.2 (12-31-2024)
- DungeonMap editing improvements
- ZSCustomOverworld support
- Cross platform file handling
## 0.2.1 (08-20-2024)
- Improved MessageEditor parsing
- Added integration test window
- Bitmap bug fixes
## 0.2.0 (07-20-2024)
- iOS app support
- Graphics Sheet Browser
- Project Files
## 0.1.0 (05-11-2024)
- Bitmap bug fixes
- Error handling improvements
## 0.0.9 (04-14-2024)
- Documentation updates
- Entrance tile types
- Emulator subsystem overhaul
## 0.0.8 (02-08-2024)
- Hyrule Magic Compression
- Dungeon Room Entrances
- Png Export
## 0.0.7 (01-27-2024)
- OverworldEntities
- Entrances
- Exits
- Items
- Sprites
## 0.0.6 (11-22-2023)
- ScreenEditor DungeonMap
- Tile16 Editor
- Canvas updates
## 0.0.5 (11-21-2023)
- DungeonEditor
- DungeonObjectRenderer
## 0.0.4 (11-11-2023)
- Tile16Editor
- GfxGroupEditor
- Add GfxGroups fns to Rom
- Add Tile16Editor and GfxGroupEditor to OverworldEditor
## 0.0.3 (10-26-2023)
- Emulator subsystem
- Snes Ppu and PpuRegisters
- Direct Memory Access
- Cpu Tests
- Read/Write Tile16 functions
- CompressionV3
- Rom::LoadLinkGraphics
## 0.0.2 (08-26-2023)
- Emulator subsystem
- Spc700
- Emulator loop
- Clock and MockClock
- Ppu and Apu cycling
- Setup Snes initialization
- 65816 Cpu opcodes
- JP Font support
- SCAD Format support for CGX, COL, OBJ files
- Overworld Save
- Overworld Map Tile Editing
## 0.0.1 (07-22-2023)
- GraphicsEditor
- Palette management
- lc_lz2 Compression
- SnesTo8bppSheet
- Bitmap Canvas
## 0.0.0 (06-08-2022)
- Started project
- Added ImGui
- Added SDL2
- Added yaze_test target with gtest

View File

@@ -1,108 +0,0 @@
# Contributing
This project is looking for contributors to help improve the software and enhance the user experience. If you are interested in contributing, please read the following guidelines and suggestions for areas where you can make a difference.
Discussion on the editor and its development can be found on the [Oracle of Secrets Discord](https://discord.gg/MBFkMTPEmk) server.
## Style Guide
When contributing to the project, please follow these guidelines to ensure consistency and readability across the codebase:
C++ Code should follow the [Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html) with the following exceptions:
- Boost libraries are allowed, but require cross platform compatibility.
Objective-C Code should follow the [Google Objective-C Style Guide](https://google.github.io/styleguide/objcguide.html).
Python Code should follow the [PEP 8 Style Guide](https://pep8.org/).
Assembly code should follow the [65816 Style Guide](docs/asm-style-guide.md).
## Testing Facilities
The project includes the `yaze_test` target which defines unit tests and an integration test window. The unit tests make use of GoogleTest and GoogleMock. The integration test window is an ImGui window build out of the yaze::core::Controller and yaze::test::integration::TestEditor. The integration test window can be accessed by passing the argument `integration` to the target.
New modules should define unit tests in the `src/test` directory and integration tests in the `src/test/integration` directory. The `yaze_test` target will automatically include all tests in these directories.
## Key Areas of Contribution
### 1. Extensions System
Yaze *(stylized as yaze)* emphasizes extensibility. The `yaze_ext` library allows developers to build and integrate extensions using C, C++, or Python. This system is central to yaze's modular design, enabling new features, custom editors, or tools to be added without modifying the core codebase.
- C/C++ Extensions: Utilize the `yaze_extension` interface to integrate custom functionality into the editor. You can add new tabs, manipulate ROM data, or extend the editors capabilities with custom tools.
- Python Extensions: Currently unimplemented, Python extensions will allow developers to write scripts that interact with the editor, modify ROM data, or automate repetitive tasks.
Examples of Extensions:
- UI enhancements like additional menus, panels, or status displays.
- Rom manipulation tools for editing data structures, such as the overworld maps or dungeon objects.
- Custom editors for specific tasks, like file format conversion, data visualization, or event scripting.
### 2. Sprite Builder System
The sprite builder system in yaze is based on the [ZSpriteMaker](https://github.com/Zarby89/ZSpriteMaker/) project and allows users to create custom sprites for use in ROM hacks. The goal is to support ZSM files and provide an intuitive interface for editing sprites without the need for writing assembly code. Contributions to the sprite builder system might include:
- Implementing new features for sprite editing, such as palette management, animation preview, or tileset manipulation.
- Extending the sprite builder interface by writing assembly code for sprite behavior.
### 3. Emulator Subsystem
yaze includes an emulator subsystem that allows developers to test their modifications directly within the editor. The emulator can currently run certain test ROMs but lacks the ability to play any complex games with audio because of timing issues with the APU and Spc700. Contributions to the emulator subsystem might include:
- Improving the accuracy and performance of the emulator to support more games and features.
- Implementing new debugging tools, such as memory viewers, breakpoints, or trace logs.
- Extending the emulator to support additional features, such as save states, cheat codes, or multiplayer modes.
## Building the Project
For detailed instructions on building YAZE, including its dependencies and supported platforms, refer to [build-instructions.md](docs/build-instructions.md).
## Getting Started
1. Clone the Repository:
```bash
git clone https://github.com/yourusername/yaze.git
cd yaze
```
2. Initialize the Submodules:
```bash
git submodule update --init --recursive
```
3. Build the Project:
Follow the instructions in the [build-instructions.md](docs/build-instructions.md). file to configure and build the project on your target platform.
4. Run the Application:
After building, you can run the application on your chosen platform and start exploring the existing features.
## Contributing your Changes
1. Fork the Repository:
Create a fork of the project on GitHub and clone your fork to your local machine.
2. Create a Branch:
Create a new branch for your feature or bugfix.
```bash
git checkout -b feature/my-new-feature
```
3. Implement Your Changes:
Follow the guidelines above to implement new features, extensions, or improvements.
4. Test Your Changes:
Ensure your changes dont introduce new bugs or regressions. Write unit tests where applicable.
5. Submit a Pull Request:
Push your changes to your fork and submit a pull request to the main repository. Provide a clear description of your changes and why they are beneficial.

View File

@@ -1,60 +0,0 @@
# Getting Started
This software allows you to modify "The Legend of Zelda: A Link to the Past" (US or JP) ROMs.
This editor is built to be compatible with ZScream projects and is designed to be cross platform.
Please note that this project is currently a work in progress, and some features may not be fully implemented or may be subject to change.
## General Tips
- Experiment flags determine whether certain features are enabled or not. To change your flags, go to `File` > `Options` > `Experiment Flags` or in the Settings tab.
- Backup files are enabled by default. Each save will produce a timestamped copy of your ROM before you last saved. You can disable this feature in the settings.
## Extending Functionality
In addition to the built-in features, this software provides a pure C library interface and a Python module that can be used for building extensions and custom sprites without assembly. In the editor these can be loaded under the `Extensions` menu.
This feature is still in development and is not yet fully documented.
## Supported Features
| Feature | Status | Details |
|---------|--------|-------------|
| Overworld Maps | Done | Edit and save tile32 data. |
| Overworld Map Properties | Done | Edit and save map properties. |
| Overworld Entrances | Done | Edit and save entrance data. |
| Overworld Exits | Done | Edit and save exit data. |
| Overworld Sprites | In Progress | Edit sprite positions, add and remove sprites. |
| Tile16 Editing | Todo | Edit and save tile16 data. |
| Dungeon | In Progress | View dungeon room metadata and edit room data. |
| Palette | In Progress | Edit and save palettes, palette groups. |
| Graphics Sheets | In Progress | Edit and save graphics sheets. |
| Graphics Groups | Done | Edit and save graphics groups. |
| Sprite | Todo | View-only sprite data. |
| Custom Sprites | Todo | Edit and create custom sprite data. |
| Music | Todo | Edit music data. |
| Dungeon Maps | Todo | Edit dungeon maps. |
| Scad Format | Done-ish | Open and view scad files (SCR, CGX, COL) |
| Hex Editing | Done | View and edit ROM data in hex. |
| Asar Patching | In Progress | Apply Asar patches to your ROM or Project. |
## Command Line Interface
Included with the editor is a command line interface (CLI) that allows you to perform various operations on your ROMs from the command line. This aims to reduce the need for multiple tools in zelda3 hacking like Zcompress, LunarExpand, LunarAddress, Asar, and others.
| Command | Arg | Params | Status |
|---------|-----|--------|--------|
| Apply BPS Patch | -a | rom_file bps_file | In progress |
| Create BPS Patch | -c | bps_file src_file modified_file | Not started |
| Asar Patch | -asar | asm_file rom_file | In progress |
| Open ROM | -o | rom_file | Complete |
| Backup ROM | -b | rom_file [new_file] | In progress |
| Expand ROM | -x | rom_file file_size | Not started |
| Transfer Tile16 | -t | src_rom dest_rom tile32_id_list(csv) | Complete |
| Export Graphics | -e | rom_file bin_file | In progress |
| Import Graphics | -i | bin_file rom_file | Not started |
| SNES to PC Address | -s | address | Complete |
| PC to SNES Address | -p | address | Complete |

43
docs/index.md Normal file
View File

@@ -0,0 +1,43 @@
# YAZE Documentation
Yet Another Zelda3 Editor - A comprehensive ROM editor for The Legend of Zelda: A Link to the Past.
## Quick Start
- [Getting Started](01-getting-started.md) - Basic setup and usage
- [Build Instructions](02-build-instructions.md) - Cross-platform build guide
- [Asar Integration](03-asar-integration.md) - 65816 assembler usage
- [API Reference](04-api-reference.md) - C/C++ API documentation
## Development
- [Testing Guide](A1-testing-guide.md) - Testing framework and best practices
- [Contributing](B1-contributing.md) - Development guidelines and standards
- [Platform Compatibility](B2-platform-compatibility.md) - Cross-platform support details
- [Build Presets](B3-build-presets.md) - CMake preset usage guide
## Technical Documentation
### Assembly & Code
- [Assembly Style Guide](E1-asm-style-guide.md) - 65816 assembly coding standards
### Editor Systems
- [Dungeon Editor Guide](E2-dungeon-editor-guide.md) - Complete dungeon editing guide
- [Dungeon Editor Design](E3-dungeon-editor-design.md) - Architecture and development guide
- [Dungeon Editor Refactoring](E4-dungeon-editor-refactoring.md) - Component-based architecture plan
- [Dungeon Object System](E5-dungeon-object-system.md) - Object management framework
### Overworld System
- [Overworld Loading](F1-overworld-loading.md) - ZSCustomOverworld v3 implementation
## Key Features
- Complete GUI editor for all aspects of Zelda 3 ROM hacking
- Integrated Asar 65816 assembler for custom code patches
- ZSCustomOverworld v3 support for enhanced overworld editing
- Cross-platform support (Windows, macOS, Linux)
- Modern C++23 codebase with comprehensive testing
---
*Last updated: September 2025 - Version 0.3.0*

View File

@@ -1,85 +0,0 @@
# Infrastructure Overview
For developers to reference.
The goal of yaze is to build a cross platform editor for the Legend of Zelda: A Link to the Past. The project is built using C++20, SDL2, and ImGui. The project is built using CMake and is designed to be modular and extensible. The project is designed to be built on Windows, macOS, iOS, and Linux.
## Targets
- **yaze**: Desktop application for Windows/macOS/Linux
- **z3ed**: Command Line Interface
- **yaze_c**: C Library
- **yaze_py**: Python Module
- **yaze_test**: Unit test executable
- **yaze_ios**: iOS application
## Directory Structure
- **assets**: Hosts assets like fonts, icons, assembly source, etc.
- **cmake**: Contains CMake configurations.
- **docs**: Contains documentation for users and developers.
- **incl**: Contains the public headers for `yaze_c`
- **src**: Contains source files.
- **app**: Contains the GUI editor `yaze`
- **app/emu**: Contains a standalone Snes emulator application `yaze_emu`
- **cli**: Contains the command line interface `z3ed`
- **cli/python**: Contains the Python module `yaze_py`
- **ios**: Contains the iOS application `yaze_ios`
- **lib**: Contains the dependencies as git submodules
- **test**: Contains testing interface `yaze_test`
- **win32**: Contains Windows resource file and icon
## Dependencies
See [build-instructions.md](docs/build-instructions.md) for more information.
- **SDL2**: Graphics library
- **ImGui**: GUI library
- **Abseil**: C++ library
- **libpng**: Image library
- **Boost**: Python library
## Flow of Control
- app/yaze.cc
- Initializes `absl::FailureSignalHandler` for stack tracing.
- Runs the `core::Controller` loop.
- app/core/controller.cc
- Initializes SDLRenderer and SDLWindow
- Initializes ImGui, fonts, themes, and clipboard.
- Handles user input from keyboard and mouse.
- Renders the output to the screen.
- Handles the teardown of SDL and ImGui resources.
- app/editor/editor_manager.cc
- Handles the main menu bar
- Handles `absl::Status` errors as popups delivered to the user.
- Dispatches messages to the various editors.
- Update all the editors in a tab view.
- app/editor/code/assembly_editor.cc
- app/editor/dungeon/dungeon_editor.cc
- app/editor/graphics/graphics_editor.cc
- app/editor/graphics/gfx_group_editor.cc
- app/editor/graphics/palette_editor.cc
- app/editor/graphics/tile16_editor.cc
- app/editor/message/message_editor.cc
- app/editor/music/music_editor.cc
- app/editor/overworld/overworld_editor.cc
- app/editor/graphics/screen_editor.cc
- app/editor/sprite/sprite_editor.cc
- app/editor/system/settings_editor.cc
## Rom
- app/rom.cc
- app/rom.h
The Rom class provides methods to manipulate and access data from a ROM.
Currently implemented as a singleton with SharedRom which is not great but has helped with development velocity. Potential room for improvement is to refactor the editors to take the ROM as a parameter.
## Bitmap
- app/gfx/bitmap.cc
- app/gfx/bitmap.h
This class is responsible for creating, managing, and manipulating bitmap data, which can be displayed on the screen using SDL2 Textures and the ImGui draw list. It also provides functions for exporting these bitmaps to the clipboard in PNG format using libpng.