Add advanced technical documentation for ZScream custom overworld

- Introduced comprehensive documentation covering internal hook architecture, memory management, graphics loading pipeline, sprite loading system, cross-namespace integration, performance considerations, and debugging strategies.
- Detailed sections on adding custom features and modifying existing behaviors, including examples and code snippets.
- Included a complete hook list and memory map quick reference for developers.
This commit is contained in:
scawful
2025-10-03 15:50:34 -04:00
parent 4289e134aa
commit 26d35364af
6 changed files with 4076 additions and 96 deletions

View File

@@ -1,6 +1,56 @@
# Memory Map # Memory Map
This document provides a detailed map of the WRAM and SRAM memory regions, serving as a central reference for understanding the game's state. This document provides a detailed map of the WRAM and SRAM memory regions, serv| `$7EF358` | `WolfMask` | Flag indicating if the player has obtained the Wolf Mask. |
### Repurposed Vanilla SRAM Blocks
The following blocks were marked "unused" in vanilla ALTTP but are now utilized for OOS custom data:
#### **Block $7EF38A-$7EF3C4** - Collectibles & Custom Progression
*This is a large block of vanilla unused SRAM now used for various collectibles, side-quests, and tracking systems.*
| Address | Label | Description | Verified |
|----------|---------------------|--------------------------------------------------------------------------|----------|
| `$7EF38A` | `FishingRod` | Flag indicating if the player has the Fishing Rod. | ✓ |
| `$7EF38B` | `Bananas` | Number of bananas collected for side-quest. | ✓ |
| `$7EF38D` | `Pineapples` | Number of pineapples collected. | ✓ |
| `$7EF38F` | `RockMeat` | Number of rock meat items collected. | ✓ |
| `$7EF391` | `Seashells` | Number of secret seashells collected. | ✓ |
| `$7EF393` | `Honeycomb` | Number of honeycombs collected. | ✓ |
| `$7EF395` | `DekuSticks` | Number of Deku sticks collected. | ✓ |
| `$7EF396` | `TingleMaps` | Tingle map collection tracking. | ✓ |
| `$7EF397` | `TingleId` | Tingle identification value. | ✓ |
| `$7EF398` | `Scrolls` | Bitfield tracking lore scroll collection (7 dungeons: `.dgi zktm`). | ✓ |
| `$7EF39A` | `PrevScroll` | Tracks the previous scroll for re-reading old hints. | ✓ |
| `$7EF39B` | `MagicBeanProg` | Multi-day growth cycle tracking for magic bean side-quest (`.dts fwpb`). | ✓ |
| `$7EF39C` | `JournalState` | Current state of the player's journal. | ✓ |
| `$7EF39D` | `SRAM_StormsActive` | Flag indicating if the Song of Storms effect is active. | ✓ |
#### **Block $7EF403-$7EF4FD** - Partially Repurposed
*Most of this block remains unused, but OOS utilizes a portion for the Dreams collectible system.*
| Address | Label | Description | Verified |
|----------|-----------|--------------------------------------------------------------------|----------|
| `$7EF410` | `Dreams` | Bitfield tracking collection of three Dreams (`.cpw`: Courage, Power, Wisdom). | ✓ |
> **💡 Usage Notes:**
> - **Scrolls** (`$7EF398`): One scroll per dungeon (7 total). Bitfield format: `.dgi zktm` where each letter represents a dungeon (m=Mushroom Grotto, t=Tail Palace, k=Kalyxo Castle, z=Zora Temple, i=Glacia Estate, g=Goron Mines, d=Dragon Ship).
> - **MagicBeanProg** (`$7EF39B`): Tracks multi-day growth cycle with bitfield `.dts fwpb` (b=bean planted, w=watered, p=pollinated, f=first day, s=second day, t=third day, d=done).
> - **Dreams** (`$7EF410`): Similar to vanilla Pendants, tracks three key collectibles. Bitfield: `.cpw` (c=Courage, p=Power, w=Wisdom).
### SRAM Address Contradictions (Source File Notes)
The following addresses appear with both active label definitions and `UNUSED_` markers in `Core/sram.asm`. **The label definitions take precedence** - these addresses are actively used:
- `$7EF3D4` - Both `MakuTreeQuest` and `UNUSED_7EF3D4` (✓ **In Use**)
- `$7EF3D6` - Both `OOSPROG` and `UNUSED_7EF3D6` (✓ **In Use**)
- `$7EF38A` - Both `FishingRod` and `UNUSED_7EF38A` (✓ **In Use**)
These contradictions appear to be legacy comments from the vanilla ALTTP disassembly that were not removed when OOS repurposed these addresses.
as a central reference for understanding the game's state.
## 1. WRAM (Work RAM) - `$7E0000` ## 1. WRAM (Work RAM) - `$7E0000`
@@ -48,6 +98,8 @@ This section details the layout of the game's volatile memory.
This section details the layout of the save file memory. This section details the layout of the save file memory.
> **🔍 SRAM Verification Note**: All custom SRAM variables documented below have been cross-referenced with `Core/sram.asm`. Some addresses in the source file have contradictory `UNUSED_` markers alongside actual label definitions (e.g., `OOSPROG = $7EF3D6` vs `UNUSED_7EF3D6 = $7EF3D6`). **The actual usage takes precedence** - if a label is defined for an address, it is considered in-use regardless of `UNUSED_` markers. This appears to be a legacy comment artifact from the vanilla ALTTP disassembly.
### Key Vanilla SRAM Variables ### Key Vanilla SRAM Variables
*This section lists key vanilla save data locations, such as inventory, health, and progression flags, as defined in `Core/sram.asm`.* *This section lists key vanilla save data locations, such as inventory, health, and progression flags, as defined in `Core/sram.asm`.*

View File

@@ -48,6 +48,44 @@ Once a room is loaded, its specific behavior is governed by tags and flags.
The sprite engine in `bank_06.asm` iterates through these arrays each frame, executing the logic for each active sprite. The sprite engine in `bank_06.asm` iterates through these arrays each frame, executing the logic for each active sprite.
## 4.5. Custom WRAM Region (`$7E0730+`)
Oracle of Secrets adds a custom WRAM region starting at `$7E0730`, utilizing the MAP16OVERFLOW free RAM space. All custom variables documented here have been verified against `Core/ram.asm` and are actively used by the project's custom systems.
### Verified Custom WRAM Variables
| Address | Label | Description | Verified |
|------------|-------------------------|-----------------------------------------------------------|----------|
| `$7E0730` | `MenuScrollLevelV` | Vertical scroll position for the custom menu system | ✓ |
| `$7E0731` | `MenuScrollLevelH` | Horizontal scroll position for the custom menu system | ✓ |
| `$7E0732` | `MenuScrollHDirection` | Direction flag for horizontal menu scrolling (2 bytes) | ✓ |
| `$7E0734` | `MenuItemValueSpoof` | Temporary override for displayed menu item values (2 bytes)| ✓ |
| `$7E0736` | `ShortSpoof` | Shorter version of the spoof value (1 byte) | ✓ |
| `$7E0737` | `MusicNoteValue` | Current music note value for Ocarina system (2 bytes) | ✓ |
| `$7E0739` | `GoldstarOrHookshot` | Differentiates Hookshot (0) from Goldstar (1) mode | ✓ |
| `$7E073A` | `Neck_Index` | Index for multi-part sprite body tracking (e.g., bosses) | ✓ |
| `$7E073B` | `Neck1_OffsetX` | X-offset for first neck/body segment | ✓ |
| `$7E073C` | `Neck1_OffsetY` | Y-offset for first neck/body segment | ✓ |
| `$7E073D` | `Neck2_OffsetX` | X-offset for second neck/body segment | ✓ |
| `$7E073E` | `Neck2_OffsetY` | Y-offset for second neck/body segment | ✓ |
| `$7E073F` | `Neck3_OffsetX` | X-offset for third neck/body segment | ✓ |
| `$7E0740` | `Neck3_OffsetY` | Y-offset for third neck/body segment | ✓ |
| `$7E0741` | `Offspring1_Id` | Sprite ID of first child sprite (for boss mechanics) | ✓ |
| `$7E0742` | `Offspring2_Id` | Sprite ID of second child sprite (for boss mechanics) | ✓ |
| `$7E0743` | `Offspring3_Id` | Sprite ID of third child sprite (for boss mechanics) | ✓ |
| `$7E0744` | `Kydreeok_Id` | Sprite ID for Kydreeok boss entity | ✓ |
| `$7E0745` | `FishingOrPortalRod` | Differentiates Fishing Rod (1) from Portal Rod (2) | ✓ |
### Usage Notes
- **Menu System**: Variables `$7E0730-$7E0736` are exclusively used by the custom menu system (`Menu/menu.asm`) to manage smooth scrolling between the Items and Quest Status pages.
- **Item Differentiation**: `GoldstarOrHookshot` and `FishingOrPortalRod` are critical for shared inventory slots. These allow two distinct items to occupy a single menu slot, with the player able to switch between them using the L/R shoulder buttons.
- **Boss Mechanics**: The `Neck_*` and `Offspring_*` variables enable complex multi-part boss sprites (e.g., Kydreeok with multiple heads, Manhandla with independent parts). The parent sprite uses these to track and coordinate its child sprite components.
- **Memory Safety**: All variables in this region are placed within the MAP16OVERFLOW free RAM area, which is guaranteed to be unused by the vanilla game engine. This prevents conflicts with vanilla systems.
## 5. Long-Term Progression: SRAM and Custom Flags ## 5. Long-Term Progression: SRAM and Custom Flags
SRAM (`$7EF000+`) stores the player's save file and is the key to managing long-term quest progression. Oracle of Secrets heavily expands the vanilla save format to support its new data-driven systems. SRAM (`$7EF000+`) stores the player's save file and is the key to managing long-term quest progression. Oracle of Secrets heavily expands the vanilla save format to support its new data-driven systems.

File diff suppressed because it is too large Load Diff

View File

@@ -29,6 +29,96 @@ To ensure modern and maintainable assembly code, the project adheres to the foll
* **Data Structures:** Use `struct` for complex, related data (e.g., sprite state) and `table` for jump tables or data arrays. This improves readability and reduces errors from manual offset calculations. * **Data Structures:** Use `struct` for complex, related data (e.g., sprite state) and `table` for jump tables or data arrays. This improves readability and reduces errors from manual offset calculations.
* **Constants:** Use `!` or `define()` to create named constants for RAM/SRAM addresses, item IDs, sprite states, and other "magic numbers." This makes the code self-documenting and easier to maintain. * **Constants:** Use `!` or `define()` to create named constants for RAM/SRAM addresses, item IDs, sprite states, and other "magic numbers." This makes the code self-documenting and easier to maintain.
### 2.4. Namespace Architecture
Oracle of Secrets uses a mixed namespace architecture to organize code and manage symbol visibility:
* **`Oracle` Namespace:** Most custom code is placed within the `namespace Oracle { }` block. This includes Items, Menu, Masks, Time System, and most custom features.
* **ZScream (No Namespace):** The `ZSCustomOverworld` system operates outside any namespace, as it needs to hook directly into vanilla bank addresses.
* **Cross-Namespace Calling:** When Oracle code needs to call ZScream functions, or vice versa, proper exports must be defined:
```asm
// In ZScream file:
LoadOverworldSprites_Interupt:
{
; ... ZScream code ...
RTL
}
// Export to Oracle namespace:
namespace Oracle
{
Oracle_LoadOverworldSprites_Interupt = LoadOverworldSprites_Interupt
}
```
* **Bridge Functions:** When ZScream needs to call Oracle code, use a bridge function pattern:
```asm
// Oracle implementation:
namespace Oracle
{
CheckIfNight:
; Main implementation
RTL
}
// Bridge function (no namespace):
ZSO_CheckIfNight:
{
JSL Oracle_CheckIfNight ; Can call INTO Oracle
RTL
}
// Export bridge:
namespace Oracle
{
Oracle_ZSO_CheckIfNight = ZSO_CheckIfNight
}
```
**Important:** Always use the `Oracle_` prefix when calling exported functions from within the Oracle namespace. See `Docs/World/Overworld/ZSCustomOverworldAdvanced.md` Section 5 for detailed examples.
### 2.5. Processor State Management
The 65816 processor has critical flags (M and X) that control register sizes:
* **M Flag (bit 5):** Controls Accumulator size (0=16-bit, 1=8-bit)
* **X Flag (bit 4):** Controls Index register size (0=16-bit, 1=8-bit)
**Best Practices:**
1. **Initialize at function entry:**
```asm
MyFunction:
PHP ; Save caller's state
SEP #$30 ; Set to known 8-bit state
; ... your code ...
PLP ; Restore caller's state
RTL
```
2. **Be explicit about sizes:**
```asm
REP #$20 ; A = 16-bit
LDA.w #$1234 ; Load 16-bit value
SEP #$20 ; A = 8-bit
LDA.b #$12 ; Load 8-bit value only
```
3. **Document function requirements:**
```asm
; Function: CalculateOffset
; Inputs: A=16-bit (offset), X=8-bit (index)
; Outputs: A=16-bit (result)
; Status: Returns with P unchanged (uses PHP/PLP)
```
4. **Cross-namespace calls:** Be especially careful when calling between Oracle and ZScream code, as they may use different processor states.
See `Docs/General/Troubleshooting.md` Section 3 for common processor state issues and solutions.
## 3. Key Custom Systems ## 3. Key Custom Systems
Oracle of Secrets introduces several major custom systems that form the foundation of the hack. Oracle of Secrets introduces several major custom systems that form the foundation of the hack.
@@ -92,15 +182,77 @@ Macros are used extensively to simplify common tasks and improve code readabilit
### 5.1. Common Issues ### 5.1. Common Issues
* **`BRK` Instructions:** A `BRK` instruction indicates a crash. This is often caused by a P-register mismatch (e.g., calling a 16-bit routine when in 8-bit mode) or a corrupted stack. * **`BRK` Instructions:** A `BRK` instruction indicates a crash. This is often caused by:
* Jumping to invalid memory (uninitialized ROM, data instead of code)
* P-register mismatch (e.g., calling a 16-bit routine when in 8-bit mode)
* Stack corruption (unbalanced push/pop, JSR/JSL vs RTS/RTL mismatch)
* Return without matching call (RTL executed without previous JSL)
* **P-Register Mismatches:** Always ensure the M and X flags of the processor status register are in the correct state before calling a routine. Use `SEP` and `REP` to switch between 8-bit and 16-bit modes as needed. * **P-Register Mismatches:** Always ensure the M and X flags of the processor status register are in the correct state before calling a routine. Use `SEP` and `REP` to switch between 8-bit and 16-bit modes as needed.
* **Stack Corruption:** Ensure push/pop operations are balanced and that JSR is paired with RTS (2 bytes) while JSL is paired with RTL (3 bytes). Never mix them.
* **Namespace Visibility:** If you get "label not found" errors, verify:
* Label is exported with `Oracle_` prefix
* File is included in correct build order in `Oracle_main.asm`
* Namespace block is properly closed
* **Memory Conflicts:** If you get "overwrote some code" warnings:
* Check for overlapping `org` directives
* Use `assert pc() <= $ADDRESS` to protect boundaries
* Review ROM map in Section 6 for available space
**For comprehensive troubleshooting guidance, see `Docs/General/Troubleshooting.md` which covers:**
- BRK crash debugging with emulator tools
- Stack corruption patterns
- Processor status register issues
- Cross-namespace calling problems
- Memory conflicts and bank collisions
- Graphics/DMA timing issues
- ZScream-specific problems
### 5.2. Debugging Tools ### 5.2. Debugging Tools
* **Mesen-S (Recommended):** The most powerful SNES debugger with:
* Execution breakpoints with conditions
* Memory watchpoints (read/write/execute)
* Stack viewer
* Event viewer (NMI/IRQ timing)
* Live memory updates
* **BSNES-Plus:** Cycle-accurate emulator with:
* Memory editor with search
* Tilemap and VRAM viewers
* Debugger with disassembly
* **`!DEBUG` Flag:** The `!DEBUG` flag in `Util/macros.asm` can be used to enable or disable build-time logging. * **`!DEBUG` Flag:** The `!DEBUG` flag in `Util/macros.asm` can be used to enable or disable build-time logging.
* **`%print_debug()` Macro:** This macro can be used to print debug messages and register values during assembly. It is an invaluable tool for tracing code execution and identifying issues. * **`%print_debug()` Macro:** This macro can be used to print debug messages and register values during assembly. It is an invaluable tool for tracing code execution and identifying issues.
* **Emulator Debuggers:** Use an emulator with a robust debugger (e.g., Geiger's Snes9x) to step through code, set breakpoints, and inspect memory.
* **`usdasm`:** The `usdasm` disassembly is the primary reference for the original game's code. Use it to understand the context of vanilla routines that are being hooked or modified. * **Breadcrumb Tracking:** Add markers to narrow down crash locations:
```asm
LDA.b #$01 : STA.l $7F5000 ; Breadcrumb 1
JSL SuspiciousFunction
LDA.b #$02 : STA.l $7F5000 ; Breadcrumb 2
; After crash, check $7F5000 to see which breadcrumb was reached
```
* **Vanilla Disassembly:** The ALTTP disassembly in `ALTTP/` is the primary reference for the original game's code. Use it to understand the context of vanilla routines that are being hooked or modified.
### 5.3. Debugging Checklist
When encountering an issue:
1. ✅ Check error message carefully - Asar errors are usually precise
2. ✅ Verify namespace - Is label prefixed correctly?
3. ✅ Check stack balance - Equal push/pop counts?
4. ✅ Verify processor state - REP/SEP correct for operation?
5. ✅ Check memory bounds - Assertions in place?
6. ✅ Test in Mesen-S first - Best debugger for SNES
7. ✅ Use breadcrumbs - Narrow down crash location
8. ✅ Check build order - Files included in correct order?
9. ✅ Review recent changes - Compare with known working version
10. ✅ Read vanilla code - Understand what you're hooking
## 6. ROM Map & Memory Layout ## 6. ROM Map & Memory Layout
@@ -147,9 +299,15 @@ For a more detailed breakdown of the ROM map, refer to the `ZS ROM MAP.txt` file
The following documents have been generated by analyzing the codebase and project files. They serve as key references for understanding the project's architecture and gameplay systems. The following documents have been generated by analyzing the codebase and project files. They serve as key references for understanding the project's architecture and gameplay systems.
* **`Docs/MemoryMap.md`:** A comprehensive map of all custom WRAM and SRAM variables. See [MemoryMap.md](Core/MemoryMap.md) for details. * **`Docs/Core/MemoryMap.md`:** A comprehensive map of all custom WRAM and SRAM variables, including repurposed vanilla blocks. See [MemoryMap.md](../Core/MemoryMap.md) for details.
* **`Docs/QuestFlow.md`:** A detailed guide to the main story and side-quest progression, including trigger conditions and progression flags. See [QuestFlow.md](QuestFlow.md) for details. * **`Docs/Core/Ram.md`:** High-level overview of WRAM and SRAM usage with verified custom variables. See [Ram.md](../Core/Ram.md) for details.
* **`Docs/World/Overworld/ZSCustomOverworldAdvanced.md`:** Advanced technical guide for ZScream integration, including hook architecture, sprite loading system, cross-namespace integration, and performance considerations. See [ZSCustomOverworldAdvanced.md](../World/Overworld/ZSCustomOverworldAdvanced.md) for details.
* **`Docs/General/Troubleshooting.md`:** Comprehensive troubleshooting guide covering BRK crashes, stack corruption, processor state issues, namespace problems, memory conflicts, and graphics issues. See [Troubleshooting.md](Troubleshooting.md) for details.
* **`Docs/QuestFlow.md`:** A detailed guide to the main story and side-quest progression, including trigger conditions and progression flags. See [QuestFlow.md](../QuestFlow.md) for details.
* **`Docs/SpriteCreationGuide.md`:** A step-by-step tutorial for creating a new custom sprite using the project's frameworks and conventions. See [SpriteCreationGuide.md](SpriteCreationGuide.md) for details. * **`Docs/SpriteCreationGuide.md`:** A step-by-step tutorial for creating a new custom sprite using the project's frameworks and conventions. See [SpriteCreationGuide.md](SpriteCreationGuide.md) for details.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff