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
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`
@@ -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.
> **🔍 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
*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.
## 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
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.
* **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
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
* **`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.
* **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
* **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.
* **`%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
@@ -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.
* **`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.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff