Add comprehensive documentation for sprites and systems
- Introduced detailed analysis for the Minecart system, highlighting its state machine, track system, and areas for improvement. - Created an NPCs analysis document, summarizing various NPC sprites and their functionalities. - Added an Objects analysis document, covering interactive elements like collectibles, ice blocks, and minecarts. - Documented the Overlord sprite system, detailing its role in spawning other sprites and managing events. - Compiled a Dungeons & Indoor Areas document, outlining custom room tags, enhanced mechanics, and advanced collision systems. - Developed an Overworld Systems Analysis, focusing on the ZSCustomOverworld architecture and its core features. - Added a Time System document, explaining the in-game clock and day/night cycle management. - Documented the ZScream Custom Overworld, detailing its data-driven approach and key features.
This commit is contained in:
103
Docs/World/Overworld/Overworld.md
Normal file
103
Docs/World/Overworld/Overworld.md
Normal file
@@ -0,0 +1,103 @@
|
||||
# Overworld Systems Analysis
|
||||
|
||||
## 1. Overview
|
||||
|
||||
The `Overworld/` directory contains all code and data related to the game's overworld, including rendering, transitions, time-based events, and custom features. The architecture is centered around `ZSCustomOverworld.asm` (ZSOW), a powerful data-driven system that replaces most of the vanilla game's hardcoded overworld logic.
|
||||
|
||||
The primary goal of the overworld code is to provide a flexible and expandable framework for creating a dynamic world. This is achieved by hooking into the original game's engine and replacing static logic with routines that read from configurable data tables in expanded ROM space.
|
||||
|
||||
## 2. Core Systems
|
||||
|
||||
These two systems form the backbone of the custom overworld engine.
|
||||
|
||||
### 2.1. `ZSCustomOverworld.asm` (ZSOW)
|
||||
|
||||
ZSOW is the heart of the overworld engine. It replaces vanilla logic for palettes, graphics, overlays, transitions, and sprite loading with a highly configurable, data-driven approach. Its behavior is defined by a large pool of data tables starting at `org $288000`.
|
||||
|
||||
**Key Responsibilities:**
|
||||
|
||||
* **Data-Driven Configuration:** Reads from tables like `.MainPaletteTable`, `.OWGFXGroupTable`, and `.OverlayTable` to define the look and feel of each of the 160 overworld screens.
|
||||
* **Flexible Layouts:** Fixes vanilla transition bugs and adds support for non-standard area sizes (e.g., 2x1 "wide" and 1x2 "tall" areas) via custom camera boundary tables (`.ByScreen..._New`).
|
||||
* **Dynamic Sprite Loading:** Uses the `.Overworld_SpritePointers_state_..._New` tables to load different sprite sets based on the current game state (`$7EF3C5`), allowing enemy and NPC populations to change as the story progresses.
|
||||
* **Extensive Hooks:** Intercepts dozens of vanilla routines to apply its custom logic. Key hooks include `PreOverworld_LoadProperties_Interupt` (`$0283EE`) for loading area properties, `OverworldHandleTransitions` (`$02A9C4`) for screen transitions, and `LoadOverworldSprites_Interupt` (`$09C4C7`) for sprite loading.
|
||||
|
||||
### 2.2. `time_system.asm`
|
||||
|
||||
This system implements a full 24-hour day/night cycle, which is crucial for many of the game's puzzles and atmospheric effects.
|
||||
|
||||
**Key Features:**
|
||||
|
||||
* **In-Game Clock:** Maintains the current time in SRAM (`Hours` at `$7EE000`, `Minutes` at `$7EE001`).
|
||||
* **Palette Modulation:** The `ColorSubEffect` routine dynamically modifies palettes written to CGRAM to simulate changing light levels. It uses lookup tables to determine the correct color subtraction values for each hour.
|
||||
* **Time-Based Events:** Includes logic for daily events (e.g., the Magic Bean side-quest) and handling time manipulation via the Song of Time.
|
||||
* **HUD Integration:** The `DrawClockToHud` routine displays the current time on the player's HUD.
|
||||
|
||||
## 3. Sub-Systems and Features
|
||||
|
||||
These files implement specific, modular overworld features.
|
||||
|
||||
### 3.1. `entrances.asm`
|
||||
|
||||
This file expands the vanilla entrance system, allowing for more complex and custom door behaviors.
|
||||
|
||||
* It hooks the main entrance routine (`$1BBBF4`) to call `Overworld_UseEntrance`, which uses an expanded list of valid door tile types (`ValidDoorTypesExpanded`).
|
||||
* It contains the logic to check for follower restrictions and other entry conditions before transitioning the player to an interior map.
|
||||
|
||||
### 3.2. `overlays.asm`
|
||||
|
||||
This system manages complex, animated overlays for special entrances that are triggered on the overworld map, such as opening a dungeon.
|
||||
|
||||
* It defines multi-frame animation sequences for events like the Zora Temple waterfall parting, the castle drawbridge lowering, and the Fortress of Secrets entrance opening.
|
||||
* Each animation is a state machine that uses a timer (`$C8`) and a frame counter (`$B0`) to step through a sequence of tile-drawing and screen-shaking routines.
|
||||
|
||||
### 3.3. `lost_woods.asm`
|
||||
|
||||
This implements the classic "repeating maze" puzzle for the Lost Woods (Area `$29`).
|
||||
|
||||
* It hooks into the overworld transition logic to check if the player is exiting the Lost Woods screen.
|
||||
* It compares the player's exit direction against a correct, predefined sequence.
|
||||
* If the sequence is wrong, it manually manipulates the player and camera coordinates to loop them back to the same screen, creating the illusion of being lost.
|
||||
|
||||
### 3.4. `special_areas.asm`
|
||||
|
||||
This file enhances the functionality of vanilla "special overworld" areas (like the Master Sword grove), allowing them to be used as full-featured screens.
|
||||
|
||||
* `Overworld_CheckForSpecialOverworldTrigger` checks if the player is interacting with a tile that should lead to a special area.
|
||||
* `LoadSpecialOverworld` is a critical function that sets up the unique properties for these areas, including camera boundaries, palettes, and GFX, by reading from its own set of data tables. This allows for more than the original game's limited number of special areas.
|
||||
|
||||
### 3.5. `custom_gfx.asm`
|
||||
|
||||
This file contains routines for loading custom graphics sheets into VRAM for specific overworld areas or events. The primary example is `CheckForChangeGraphicsNormalLoadBoat`, which loads custom boat graphics when the player is in area `$30`.
|
||||
|
||||
### 3.6. `world_map.asm`
|
||||
|
||||
This file contains significant modifications to the full-screen world map.
|
||||
|
||||
* It replaces the vanilla icon drawing logic with custom routines (`DrawPowerPendant`, `DrawMasterSwordIcon`, etc.) to display the status of new quest items and dungeons.
|
||||
* It includes logic to display different icons based on Light World vs. Dark World and overall game progression (`OOSPROG`).
|
||||
* It implements custom DMA routines (`DMAOwMap`, `DMAOwMapGfx`) to load entirely new world map tilesets and graphics from expanded ROM (`$408000` and `$418000`).
|
||||
|
||||
## 4. System Interactions & Porting Status
|
||||
|
||||
Integrating ZSOW with existing custom systems is an ongoing effort. The status of these interactions is critical for development.
|
||||
|
||||
* **Time System (Palette Modulation):** **Compatible.** The Time System's `LoadDayNightPaletteEffect` acts as a filter on all CGRAM writes. When ZSOW loads a new base palette for an area, the Time System intercepts the write and applies the day/night color subtraction automatically.
|
||||
|
||||
* **Day/Night Sprites:** **Resolved.** The conflict where ZSOW's sprite loader bypassed the old day/night logic has been fixed. A `JSL CheckIfNight` call is now integrated directly into ZSOW's `LoadOverworldSprites_Interupt`. This allows ZSOW's sprite tables to correctly load different sprite sets for day and night by using adjacent game states (e.g., state 2 for day, state 3 for night).
|
||||
|
||||
* **Lost Woods Puzzle:** **Direct Conflict.** The Lost Woods puzzle's transition override is currently incompatible with ZSOW's more complex transition handler. The `lost_woods.asm` code needs to be refactored into a subroutine that can be called from within `OverworldHandleTransitions` in `ZSCustomOverworld.asm`.
|
||||
|
||||
* **Song of Storms (Overlays):** **Resolved.** The conflict where ZSOW would overwrite the rain overlay on screen transitions has been fixed. A new SRAM flag (`SRAM_StormsActive`) tracks the storm state, and a new routine, `HandleStormsOverlay`, is called every frame to enforce the rain overlay if the flag is active, ensuring it persists across transitions.
|
||||
|
||||
## 5. File Index
|
||||
|
||||
* `ZSCustomOverworld.asm`: The core data-driven overworld engine. Manages palettes, GFX, overlays, transitions, and sprite loading.
|
||||
* `time_system.asm`: Manages the 24-hour clock, day/night palette effects, and time-based events.
|
||||
* `overworld.asm`: Main include file for the directory; contains various small patches.
|
||||
* `entrances.asm`: Handles logic for entering caves, houses, and dungeons from the overworld.
|
||||
* `overlays.asm`: Manages animated entrance sequences (e.g., waterfalls, drawbridges).
|
||||
* `lost_woods.asm`: Implements the Lost Woods maze puzzle.
|
||||
* `special_areas.asm`: Expands the functionality of special overworld areas like the Master Sword grove.
|
||||
* `custom_gfx.asm`: Routines for loading custom graphics for specific areas or objects.
|
||||
* `world_map.asm`: Code for the custom full-screen world map, including new icons and map graphics.
|
||||
* `HardwareRegisters.asm`: `struct` definitions for SNES hardware registers, used for context.
|
||||
74
Docs/World/Overworld/TimeSystem.md
Normal file
74
Docs/World/Overworld/TimeSystem.md
Normal file
@@ -0,0 +1,74 @@
|
||||
# Time System (`Overworld/time_system.asm`)
|
||||
|
||||
## Overview
|
||||
|
||||
This system manages the in-game clock, day/night cycle, and associated palette effects. It runs continuously, updating the time and adjusting visual elements like the sky color and sprite palettes based on the current hour.
|
||||
|
||||
## Key Functionality
|
||||
|
||||
- **Clock:** A 24-hour clock is maintained in SRAM (`Hours` at `$7EE000`, `Minutes` at `$7EE001`).
|
||||
- **Palette Modulation:** The core of the system is `ColorSubEffect`, which subtracts values from the red, green, and blue components of palettes based on the time of day, using lookup tables.
|
||||
- **Time-Based Events:** The system checks for daily events (like the Magic Bean quest) and handles time manipulation effects (like the Song of Time).
|
||||
- **HUD Display:** It includes logic to draw the current time to the HUD.
|
||||
|
||||
## Analysis & Areas for Improvement
|
||||
|
||||
The time system is functional but could be significantly improved in terms of structure, readability, and maintainability.
|
||||
|
||||
### 1. Move Patches to `Core/patches.asm`
|
||||
|
||||
- **Observation:** The file contains numerous `org` patches that modify vanilla game logic to hook in the time system.
|
||||
- **Suggestion:** Relocate all `org` blocks to the centralized `Core/patches.asm` file. This is the most important cleanup step.
|
||||
- **Benefit:** This will separate the new system's implementation from the act of patching it into the original code, making both parts easier to understand and manage.
|
||||
|
||||
### 2. Use a `struct` for Time-Related Variables
|
||||
|
||||
- **Observation:** Time-related variables are defined as individual labels pointing to SRAM addresses (e.g., `Hours`, `Minutes`, `TimeSpeed`, `!BlueVal`).
|
||||
- **Suggestion:** Group these related variables into a single `struct`.
|
||||
|
||||
*Example:*
|
||||
```asm
|
||||
struct TimeState
|
||||
Hours db
|
||||
Minutes db
|
||||
TimeSpeed db
|
||||
; ... other vars ...
|
||||
BlueVal dw
|
||||
GreenVal dw
|
||||
RedVal dw
|
||||
endstruct
|
||||
|
||||
; Then access with:
|
||||
LDA TimeState.Hours, X
|
||||
```
|
||||
- **Benefit:** This provides a clear, high-level definition of the data structure, improves readability, and makes it easier to manage memory layout.
|
||||
|
||||
### 3. Use `subroutine` for Code Blocks
|
||||
|
||||
- **Observation:** The file consists of many large, labeled blocks of code (e.g., `RunClock`, `DrawClockToHud`, `ColorSubEffect`).
|
||||
- **Suggestion:** Convert these blocks to use `subroutine`/`endsubroutine`.
|
||||
- **Benefit:** This clearly defines the scope of each piece of logic, makes labels within them local by default, and improves overall code structure.
|
||||
|
||||
### 4. Refactor Large Subroutines
|
||||
|
||||
- **Observation:** `RunClock` is a very large and complex subroutine with multiple responsibilities and deep nesting.
|
||||
- **Suggestion:** Break `RunClock` into smaller, more focused subroutines.
|
||||
- `TimeSystem_CheckCanRun`: A subroutine to check the game state (`$10`, `$11`) and decide if the clock should tick.
|
||||
- `TimeSystem_IncrementTime`: A subroutine to handle the core logic of incrementing minutes and hours.
|
||||
- `TimeSystem_UpdatePalettes`: A subroutine to call the palette update logic when the hour changes.
|
||||
- **Benefit:** Smaller, single-purpose functions are easier to read, debug, and maintain.
|
||||
|
||||
### 5. Replace Magic Numbers with Constants
|
||||
|
||||
- **Observation:** The code is replete with hardcoded values for time, palettes, and game states.
|
||||
- **Suggestion:** Define constants for these values using `!` or `define()`.
|
||||
|
||||
*Example:*
|
||||
```asm
|
||||
!TIME_SPEED_NORMAL = $3F
|
||||
!GAME_STATE_OVERWORLD = $09
|
||||
|
||||
LDA.b #!TIME_SPEED_NORMAL : STA.l TimeSpeed
|
||||
LDA $10 : CMP #!GAME_STATE_OVERWORLD : BEQ .overworld
|
||||
```
|
||||
- **Benefit:** Makes the code self-documenting and reduces the risk of errors when modifying these values.
|
||||
59
Docs/World/Overworld/ZSCustomOverworld.md
Normal file
59
Docs/World/Overworld/ZSCustomOverworld.md
Normal file
@@ -0,0 +1,59 @@
|
||||
# ZScream Custom Overworld (`Overworld/ZSCustomOverworld.asm`)
|
||||
|
||||
## 1. Overview
|
||||
|
||||
ZSCustomOverworld is a powerful and extensive system that replaces large parts of the vanilla *A Link to the Past* overworld engine. Its primary purpose is to remove hardcoded behaviors and replace them with a data-driven approach, allowing for a highly customizable overworld.
|
||||
|
||||
Instead of relying on hardcoded logic for palettes, graphics, and layouts, ZSCustomOverworld reads this information from a large pool of data tables located in expanded ROM space (starting at `$288000`). These tables are designed to be edited by the ZScream overworld editor.
|
||||
|
||||
## 2. Key Features
|
||||
|
||||
- **Custom Palettes & Colors:** Assign a unique main palette and background color to every overworld screen.
|
||||
- **Custom Graphics:** Assign custom static tile graphics (GFX groups) and animated tile sets to each area.
|
||||
- **Custom Overlays:** Add or remove subscreen overlays (like rain, fog, and clouds) on a per-area basis.
|
||||
- **Flexible Layouts:** Fixes vanilla bugs related to screen transitions and adds support for new area sizes, such as 2x1 "wide" and 1x2 "tall" areas, in addition to the standard 1x1 and 2x2.
|
||||
- **Expanded Special Worlds:** Allows the normally limited "special world" areas (like the Master Sword grove) to be used as full-featured overworld screens.
|
||||
|
||||
## 3. Core Architecture: Data Tables
|
||||
|
||||
The system's flexibility comes from a large data pool starting at `org $288000`. Key tables include:
|
||||
|
||||
- **`.BGColorTable`:** A table of 16-bit color values for the background of each overworld screen.
|
||||
- **`.EnableTable`:** A series of flags to enable or disable specific features of ZSCustomOverworld, such as custom palettes or overlays.
|
||||
- **`.MainPaletteTable`:** An index (`$00` to `$05`) into the game's main overworld palette sets for each screen.
|
||||
- **`.MosaicTable`:** A bitfield for each screen to control mosaic transitions on a per-direction basis.
|
||||
- **`.AnimatedTable`:** The GFX sheet ID for animated tiles for each screen.
|
||||
- **`.OverlayTable`:** The overlay ID (e.g., `$9F` for rain) for each screen. `$FF` means no overlay.
|
||||
- **`.OWGFXGroupTable`:** A large table defining the 8 GFX group sheets to be loaded for each overworld screen.
|
||||
- **`.Overworld_ActualScreenID_New`:** A table that defines the "parent" screen for multi-screen areas (e.g., for a 2x2 area, all four screens point to the top-left screen's ID).
|
||||
- **`.ByScreen..._New` Tables:** Four tables (`ByScreen1` for right, `2` for left, `3` for down, `4` for up) that define the camera boundaries for screen transitions. These are crucial for supporting non-standard area sizes.
|
||||
- **`.Overworld_SpritePointers_state_..._New` Tables:** These tables define which sprite set to load for each overworld area based on the game state (`state_0` for the intro, `state_1` for post-Agahnim 1, `state_2` for post-Ganon). This allows for different enemy and NPC populations as the story progresses.
|
||||
|
||||
## 4. Key Hooks & Functions
|
||||
|
||||
ZSCustomOverworld replaces dozens of vanilla routines. Some of the most critical hooks are:
|
||||
|
||||
- `org $0283EE` (**`PreOverworld_LoadProperties_Interupt`**):
|
||||
- **Original:** `Overworld_LoadProperties`. This function loads music, palettes, and GFX when transitioning from a dungeon/house to the overworld.
|
||||
- **New Logic:** The ZS version is heavily modified to read from the custom data tables for palettes and GFX instead of using hardcoded logic. It also removes hardcoded music changes for certain exits.
|
||||
|
||||
- `org $02C692` (**`Overworld_LoadAreaPalettes`**):
|
||||
- **Original:** A routine to load overworld palettes.
|
||||
- **New Logic:** Reads the main palette index from the `.MainPaletteTable` instead of using a hardcoded value.
|
||||
|
||||
- `org $02A9C4` (**`OverworldHandleTransitions`**):
|
||||
- **Original:** The main logic for handling screen-to-screen transitions on the overworld.
|
||||
- **New Logic:** This is one of the most heavily modified sections. The new logic uses the custom tables (`.ByScreen...`, `.Overworld_ActualScreenID_New`, etc.) to handle transitions between areas of different sizes, fixing vanilla bugs and allowing for new layouts.
|
||||
|
||||
- `org $02AF58` (**`Overworld_ReloadSubscreenOverlay_Interupt`**):
|
||||
- **Original:** Logic for loading subscreen overlays.
|
||||
- **New Logic:** Reads the overlay ID from the `.OverlayTable` instead of using hardcoded checks for specific areas (like the Misery Mire rain).
|
||||
|
||||
- `org $09C4C7` (**`LoadOverworldSprites_Interupt`**):
|
||||
- **Original:** `LoadOverworldSprites`. This function determines which sprites to load for the current overworld screen.
|
||||
- **New Logic:** The ZS version reads from the `.Overworld_SpritePointers_state_..._New` tables based on the current game state (`$7EF3C5`) to get a pointer to the correct sprite set for the area. This allows for dynamic sprite populations.
|
||||
|
||||
## 5. Configuration
|
||||
|
||||
- **`!UseVanillaPool`:** A flag that, when set to 1, forces the system to use data tables that mimic the vanilla game's behavior. This is useful for debugging.
|
||||
- **`!Func...` Flags:** A large set of individual flags that allow for enabling or disabling specific hooks. This provides granular control for debugging and compatibility testing.
|
||||
Reference in New Issue
Block a user