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:
scawful
2025-10-02 12:44:30 -04:00
parent 27ffaf16d8
commit 6ba634caa4
23 changed files with 500 additions and 0 deletions

View File

@@ -0,0 +1,84 @@
# Custom Items System
This document details the functionality of new and modified items in Oracle of Secrets, based on analysis of the `Items/` directory.
## 1. Overview
The item roster has been significantly expanded with new mechanics, and many vanilla items have been reworked to provide new functionality. The system is managed through a combination of hooks into the main player state machine and custom routines for each item.
## 2. Vanilla Item Modifications
Several items from the original game have been altered.
### Hookshot / Goldstar
- **Files:** `goldstar.asm`
- **Functionality:** The Hookshot can be upgraded to the **Goldstar**, a powerful morning star weapon. The two items share an inventory slot.
- **Switching:** When the Goldstar is obtained, the player can switch between the Hookshot and Goldstar by pressing the L/R shoulder buttons while it is selected in the menu. The current mode is tracked by the `GoldstarOrHookshot` WRAM variable.
- **Goldstar Mechanics:** When active, the item functions as a short-range, powerful melee weapon with its own collision and damage properties, distinct from the Hookshot's grappling mechanic.
### Ice Rod
- **File:** `ice_rod.asm`
- **Functionality:** The Ice Rod's projectile now freezes water tiles it hits, creating temporary 16x16 ice platforms. This allows the player to cross water gaps.
- **Implementation:** The `LinkItem_IceRod` routine hooks into the ancilla tile collision logic. When the projectile hits a water tile, it dynamically modifies the tilemap properties in RAM and DMAs new ice graphics to VRAM.
### Bug-Catching Net -> Roc's Feather
- **File:** `jump_feather.asm`
- **Functionality:** The vanilla Bug-Catching Net has been completely replaced by **Roc's Feather**. This item allows Link to perform a short hop.
- **Implementation:** `LinkItem_JumpFeather` initiates the jump by setting Link's state to a recoil/ledge hop state and applying a burst of vertical velocity.
### Bottles
- **File:** `bottle_net.asm`
- **Functionality:** The Bug-Catching Net is no longer required to catch bees, fairies, etc. The Bottle item now has a dual function:
1. If the bottle is **empty**, using it initiates the `LinkItem_CatchBottle` routine, which performs a net-catching swing.
2. If the bottle is **full**, using it calls `LinkItem_Bottles`, which consumes the contents (e.g., drinks a potion, releases a fairy).
### Book of Mudora -> Book of Secrets
- **File:** `book_of_secrets.asm`
- **Functionality:** The Book of Mudora is now the **Book of Secrets**. While its vanilla function of translating Hylian text remains, it has a new secret-revealing capability.
- **Implementation:** The `Dungeon_RevealSecrets` routine checks if the L button is held while inside a building. If it is, it disables the `BG2` layer, which can be used to hide secret passages or objects behind walls that are part of that background layer.
## 3. New Active Items
### Ocarina
- **File:** `ocarina.asm`
- **Functionality:** A multi-song instrument. When selected, the player can cycle through learned songs using the L/R shoulder buttons. Pressing 'Y' plays the selected song, triggering its unique effect.
- **Songs & Effects:**
- **Song of Healing:** Heals certain NPCs or triggers quest events.
- **Song of Storms:** Toggles a rain overlay on the overworld, which can affect the environment (e.g., watering the Magic Bean).
- **Song of Soaring:** Warps the player to pre-defined locations (the vanilla flute's bird travel).
- **Song of Time:** Toggles the in-game time between day and night.
### Shared Slot: Portal Rod & Fishing Rod
- **Files:** `portal_rod.asm`, `fishing_rod.asm`
- **Functionality:** These two distinct items share a single inventory slot. If the player has the upgrade (`$7EF351 >= 2`), they can swap between the two by pressing L/R in the menu.
- **Portal Rod:** Fires a projectile that creates a portal sprite (blue or orange). The `Ancilla_HandlePortalCollision` logic detects when another projectile (like an arrow) hits a portal and teleports it to the other portal's location.
- **Fishing Rod:** Initiates a fishing minigame. `LinkItem_FishingRod` spawns a "floater" sprite, and the player can reel it in to catch fish or other items from a prize table.
## 4. New Passive Items
### Magic Rings
- **File:** `magic_rings.asm`
- **Functionality:** Passive items that grant buffs when equipped in one of the three ring slots in the Quest Status menu. The effects are applied by hooking into various game logic routines.
- **Implemented Rings:**
- **Power Ring:** Increases sword damage.
- **Armor Ring:** Reduces damage taken by half.
- **Heart Ring:** Slowly regenerates health over time.
- **Light Ring:** Allows the sword to shoot beams even when Link is not at full health (down to -2 hearts from max).
- **Blast Ring:** Increases the damage of bombs.
- **Steadfast Ring:** Prevents or reduces knockback from enemy hits.
## 5. Consumable Items (Magic Bag)
- **File:** `all_items.asm`
- **Functionality:** The Magic Bag is a sub-menu that holds new consumable items. The `Link_ConsumeMagicBagItem` routine is a jump table that executes the effect for the selected item.
- **Consumables:**
- **Banana:** Implemented. Restores a small amount of health (`#$10`).
- **Pineapple, Rock Meat, Seashells, Honeycombs, Deku Sticks:** Placeholder entries exist in the jump table, but their effects are not yet implemented (the routines just contain `RTS`).

View File

@@ -0,0 +1,145 @@
# Mask System
This document provides a detailed analysis of the Mask System in Oracle of Secrets, based on the code in the `Masks/` directory. The system allows Link to transform into various forms, each with unique graphics, palettes, and abilities.
## 1. System Architecture
The Mask System is built around a central WRAM variable and a set of core routines that handle transformations, graphics, and palettes.
- **`!CurrentMask` (`$02B2`):** A WRAM variable that stores the ID of the currently active mask. A value of `0x00` represents Link's normal human form.
- **`!LinkGraphics` (`$BC`):** A WRAM variable that holds the bank number for Link's current graphics sheet. The Mask System changes this value to load the appropriate sprite graphics for each form.
### Mask IDs
| ID | Mask / Form |
|------|---------------|
| `00` | Human (Default) |
| `01` | Deku Mask |
| `02` | Zora Mask |
| `03` | Wolf Mask |
| `04` | Bunny Hood |
| `05` | Minish Form |
| `06` | GBC Form |
| `07` | Moosh Form |
## 2. Core Routines & Hooks (`Masks/mask_routines.asm`)
A set of shared routines and hooks form the backbone of the system.
- **`Link_TransformMask`:** This is the primary function for changing forms. It is typically called when the player uses a mask item.
- **Trigger:** It requires a new R-button press (`CheckNewRButtonPress`) to prevent rapid toggling.
- **Logic:** It takes a mask ID in the A register. If the requested mask is already active, it reverts Link to his human form. Otherwise, it sets `!CurrentMask`, updates the graphics bank in `$BC` from a lookup table, and calls `Palette_ArmorAndGloves` to apply the new look.
- **Effect:** It spawns a "poof" of smoke (`AddTransformationCloud`) and plays a sound effect.
- **`Palette_ArmorAndGloves` (Hook):** This routine hooks the vanilla palette loading function (`$1BEDF9`). It checks `!CurrentMask` and jumps to the appropriate `Update...Palette` routine for the active form, ensuring the correct colors are loaded. If no mask is active, it proceeds with the vanilla logic for loading Link's tunic color.
- **`LinkItem_CheckForSwordSwing_Masks` (Hook):** This routine hooks the vanilla sword swing check (`$079CD9`). It prevents certain forms (Deku, Wolf, Minish, Moosh) from using the sword, while allowing others (Zora, GBC Link) to use it freely.
- **Reset Routines:**
- `ResetToLinkGraphics`: Reverts Link to his default graphics and `!CurrentMask = 0`.
- `ForceResetMask_GameOver` / `ForceResetMask_SaveAndQuit`: Hooks into the game over and save/quit routines to ensure Link's form is reset before the game saves or restarts.
## 3. Transformation Masks
These masks grant Link new forms with significant new abilities.
### Deku Mask
- **File:** `Masks/deku_mask.asm`
- **Transformation:** Replaces the Quake Medallion. Pressing 'Y' with the item selected transforms Link.
- **Abilities:**
- **Spin Attack:** Pressing 'Y' performs a spinning attack.
- **Deku Bubble:** If not on a Deku Flower, the spin attack also shoots a bubble projectile (`Ancilla0E_MagicBubble`).
- **Hover:** If standing on a Deku Flower (tile property check sets WRAM `$71`), the spin attack launches Link into the air, allowing him to hover for a short time.
- **Bomb Drop:** While hovering, pressing 'Y' drops a bomb.
- **Cancel Hover:** Pressing 'B' or letting the timer expire cancels the hover.
- **Key Flags & Variables:**
- `!CurrentMask`: `0x01`
- `DekuFloating` (`$70`): Flag set when Link is hovering.
- `DekuHover` (`$71`): Flag set when Link is standing on a Deku Flower, enabling the hover ability.
- **Code Interactions:**
- Hooks `LinkItem_Quake` (`$07A64B`).
- Repurposes Link's "Using Quake Medallion" state (`$5D = 0x0A`) for the hover ability.
- Hooks `LinkOAM_DrawShield` (`$0DA780`) to prevent the shield from being drawn.
### Zora Mask
- **File:** `Masks/zora_mask.asm`
- **Transformation:** Replaces the Bombos Medallion. Pressing 'Y' with the item selected transforms Link.
- **Abilities:**
- **Diving:** Allows Link to dive in deep water by pressing 'Y'. Pressing 'Y' again resurfaces.
- **Overworld Diving:** When diving in the overworld, Link becomes invincible, moves faster, and is hidden beneath a ripple effect.
- **Dungeon Diving:** When diving in a dungeon, Link moves to the lower layer (`$EE=0`), allowing him to swim under floors and obstacles.
- **Sword:** The Zora form can use the sword.
- **Key Flags & Variables:**
- `!CurrentMask`: `0x02`
- `!ZoraDiving` (`$0AAB`): Flag set when Link is currently underwater.
- **Code Interactions:**
- Hooks `LinkItem_Bombos` (`$07A569`).
- Hooks the end of `LinkState_Swimming` (`$079781`) to handle the dive input.
- Hooks the end of `LinkState_Default` (`$0782D2`) to handle resurfacing in dungeons.
- Hooks `Link_HopInOrOutOfWater_Vertical` (`$07C307`) to reset the dive state when using water stairs.
### Wolf Mask
- **File:** `Masks/wolf_mask.asm`
- **Transformation:** Shares an item slot with the Flute. When selected, it replaces the Shovel. Pressing 'Y' transforms Link.
- **Abilities:**
- **Dig:** When transformed, pressing 'Y' executes the vanilla `LinkItem_Shovel` routine, allowing Wolf Link to dig for items without needing the shovel.
- **Key Flags & Variables:**
- `!CurrentMask`: `0x03`
- **Code Interactions:**
- Hooks the `LinkItem_Shovel` vector (`$07A313`) to a new `LinkItem_ShovelAndFlute` routine that dispatches between the Flute and Wolf Mask logic based on the selected item (`$0202`).
### Minish Form
- **File:** `Masks/minish_form.asm`
- **Transformation:** Context-sensitive. When standing on a special portal tile (`ID 64`), pressing 'R' transforms Link into Minish form. Pressing 'R' on the portal again reverts him.
- **Abilities:**
- **Access Minish Areas:** Allows Link to pass through special small openings (`Tile ID 65`).
- **Restricted Actions:** Cannot lift objects.
- **Key Flags & Variables:**
- `!CurrentMask`: `0x05`
- **Code Interactions:**
- Hooks the overworld (`$07DAF2`) and underworld (`$07D8A0`) tile collision tables to add handlers for the portal and passage tiles.
- Hooks the lift check (`$079C32`) to disable lifting while in Minish form.
### Moosh Form
- **File:** `Masks/moosh.asm`
- **Transformation:** The trigger for transforming into Moosh is not defined within the mask's own file, but is handled by `Link_TransformMoosh`.
- **Abilities:**
- **Hover Dash:** Attempting to use the Pegasus Boots (dash) while in Moosh form will instead trigger a short hover, similar to the Deku Mask's ability.
- **Key Flags & Variables:**
- `!CurrentMask`: `0x07`
- **Code Interactions:**
- Hooks the dash initiation logic (`$079093`) to intercept the dash and call `PrepareQuakeSpell`, which sets Link's state to `0x0A` (hover).
- Shares the hover/recoil animation logic with the Deku Mask.
## 4. Passive & Cosmetic Forms
### Bunny Hood
- **File:** `Masks/bunny_hood.asm`
- **Transformation:** Replaces the Ether Medallion. Pressing 'Y' activates the Bunny Hood state. This is a state change, not a visual transformation.
- **Abilities:**
- **Increased Speed:** While the Bunny Hood is the active mask (`!CurrentMask = 0x04`), Link's movement speed is increased across various actions (walking, carrying, etc.). The specific speed values are defined in `BunnySpeedTable`.
- **Key Flags & Variables:**
- `!CurrentMask`: `0x04`
- **Code Interactions:**
- Hooks `LinkItem_Ether` (`$07A494`) to trigger the state change.
- Hooks the velocity calculation in the player engine (`$07E330`) to load custom speed values from a table.
### GBC Form
- **File:** `Masks/gbc_form.asm`
- **Transformation:** An automatic, cosmetic transformation that occurs whenever Link is in the Dark World.
- **Abilities:**
- Changes Link's graphics to a Game Boy Color-inspired sprite.
- Applies a unique, limited-color palette. The palette correctly reflects Link's current tunic (Green, Blue, or Red).
- This form can still use the sword.
- **Key Flags & Variables:**
- `!CurrentMask`: `0x06`
- `$0FFF`: The vanilla Dark World flag.
- **Code Interactions:**
- Hooks numerous overworld, underworld, and transition routines to consistently apply the effect when in the Dark World and remove it when in the Light World.

View File

@@ -0,0 +1,77 @@
# Custom Menu & HUD System
This document provides a detailed analysis of the custom menu and Heads-Up Display (HUD) systems in Oracle of Secrets, based on the code in the `Menu/` directory.
## 1. Overview
The project features a completely custom menu and HUD, replacing the vanilla systems. The menu is a robust, multi-screen system, while the HUD provides a clean, modern interface for in-game stats.
- **Menu System**: A two-page design that separates selectable items from quest status and equipment. It is accessible by pressing the Start button.
- **HUD System**: A persistent on-screen display for health, magic, rupees, and the currently equipped item.
## 2. Menu System Architecture
The entire menu operates as a large state machine, with the main entry point being `Menu_Entry` in `Menu/menu.asm`. The flow is controlled by the value in WRAM `$0200`.
### 2.1. Main State Machine
The `Menu_Entry` routine uses a jump table (`.vectors`) to execute different subroutines based on the state in `$0200`. This modular approach allows for a clean separation of tasks like initialization, drawing, input handling, and screen transitions.
**Key States in `$0200`:**
| State ID | Label | Purpose |
|----------|----------------------------|-------------------------------------------------------------------------|
| `0x00` | `Menu_InitGraphics` | Initializes the menu, clears player state, and prepares for drawing. |
| `0x01` | `Menu_UploadRight` | Draws the entire right-hand screen (Quest Status). |
| `0x02` | `Menu_UploadLeft` | Draws the entire left-hand screen (Item Selection). |
| `0x04` | `Menu_ItemScreen` | The main interactive state for the Item screen. Handles cursor movement. |
| `0x05` | `Menu_ScrollTo` | Handles the smooth scrolling animation when moving from Items to Quest. |
| `0x06` | `Menu_StatsScreen` | The main interactive state for the Quest Status screen. |
| `0x0A` | `Menu_Exit` | Exits the menu, restores the game state, and updates the equipped item. |
| `0x0C` | `Menu_MagicBag` | A sub-menu for viewing collectible items. |
| `0x0D` | `Menu_SongMenu` | A sub-menu for selecting Ocarina songs. |
| `0x0E` | `Menu_Journal` | A sub-menu for reading the player's journal. |
| `0x09` | `Menu_RingBox` | A sub-menu for managing magic rings. |
### 2.2. Item Selection Screen (Left Page)
This is the primary interactive screen where the player selects their Y-button item.
- **Drawing (`DrawYItems`):** This routine is responsible for rendering all 24 item slots. It reads the SRAM address for each slot from `Menu_AddressIndex` (`menu_select_item.asm`), checks if the player owns the item, and then calls `DrawMenuItem`.
- **`DrawMenuItem`:** This generic function is the core of the drawing system. It takes an item's SRAM value (e.g., Sword level 0-4) and uses it to look up the correct 16x16 tile data from a large graphics table in `Menu/menu_gfx_table.asm`. This makes the menu highly data-driven.
- **Selection (`menu_select_item.asm`):** Cursor movement is handled by `Menu_FindNextItem`, `Menu_FindPrevItem`, etc. These routines intelligently skip over empty slots, ensuring the cursor always lands on a valid item. The currently selected slot index is stored in `$0202`.
### 2.3. Quest Status Screen (Right Page)
This screen is a static display of the player's overall progress.
- **Drawing:** It is rendered by a series of functions in `menu_draw.asm`, including:
- `Menu_DrawQuestItems`: Draws equipped sword, shield, tunic, etc.
- `Menu_DrawPendantIcons` & `Menu_DrawTriforceIcons`: Reads SRAM flags to draw collected pendants and crystals.
- `Menu_DrawCharacterName`: Reads the player's name from SRAM and renders it.
- `DrawLocationName`: Reads the current overworld area (`$008A`) or underworld room (`$00A0`) and looks up the corresponding name from the tables in `menu_map_names.asm`.
## 3. HUD System Architecture
The HUD is a separate system that hooks the vanilla game's NMI rendering routines. Its main entry point is `HUD_Update` in `Menu/menu_hud.asm`.
- **Functionality:** The `HUD_Update` routine runs every frame during gameplay. It reads player stats directly from SRAM and WRAM and draws them to the VRAM buffer for the top of the screen.
- **Key Drawing Logic:**
- **Hearts:** `HUD_UpdateHearts` is a loop that draws empty hearts based on `MAXHP` (`$7EF36C`) and then overlays full/partial hearts based on `CURHP` (`$7EF36D`).
- **Magic Meter:** It reads `MagicPower` (`$7EF36E`) and uses the `MagicTilemap` lookup table to find the correct tiles to display the green bar.
- **Counters:** It uses a `HexToDecimal` routine to convert the values for Rupees, Bombs, and Arrows into drawable digits.
- **Equipped Item:** `HUD_UpdateItemBox` reads the currently equipped item index (`$0202`), finds its graphics data in the `HudItems` table, and draws the icon in the top-left box.
## 4. Data-Driven Design & Areas for Improvement
The entire menu and HUD are heavily data-driven, which is a major strength.
- **Graphics:** All item icons for both the menu and HUD are defined in data tables in `menu_gfx_table.asm` and `menu_hud.asm`, not hardcoded.
- **Item Layout:** The position and SRAM address of every item in the menu are defined in the `Menu_ItemCursorPositions` and `Menu_AddressIndex` tables, allowing the layout to be easily changed.
- **Text:** Item names, location names, and other text are all stored in data tables in `menu_text.asm` and `menu_map_names.asm`.
This analysis confirms the suggestions in the placeholder `Menu.md` file:
1. **Refactor Redundant Code:** The input handling logic for the Magic Bag, Song Menu, and Ring Box is nearly identical and is a prime candidate for being refactored into a single, reusable subroutine.
2. **Use `table` for Jump Tables:** The main `Menu_Entry` jump table is created with manual `dw` directives and would be cleaner and safer if generated with asar's `table` directive.
3. **Replace Hardcoded Values:** Hardcoded state values (e.g., `LDA.b #$0C : STA.w $0200`) should be replaced with named constants (`!MENU_STATE_MAGIC_BAG = $0C`) for readability and maintainability.

View File

@@ -0,0 +1,137 @@
# Music Creation Guide
This document details the process for creating and integrating custom music into Oracle of Secrets. The project uses the native Super Nintendo Packet Chip (N-SPC) music format, abstracted through a powerful set of `asar` macros.
## 1. N-SPC Music Format Primer
Music in the N-SPC engine is structured around eight independent channels. Each channel is a stream of bytes that are read sequentially. The stream consists of two types of data:
- **Commands:** Special bytes (from `$E0` to `$FF`) that control aspects of the sound, such as setting the instrument, changing volume, or calling a subroutine.
- **Notes:** A note consists of a duration byte followed by one or more tone bytes. The duration byte (e.g., `$48` for a quarter note) determines how long the following tone(s) will play.
## 2. The Macro System (`Core/music_macros.asm`)
To make composing more intuitive, the project uses a comprehensive library of macros that wrap the raw N-SPC commands into readable names. All music files must include `Core/music_macros.asm`.
### Key Concepts
- **Note Durations:** Constants are defined for standard note lengths (e.g., `!4th`, `!8th`, `!16th`).
- **Note Tones:** Constants are defined for all notes across several octaves (e.g., `C4`, `G4s` for G#4, `A5`).
- **Special Notes:** `Tie` (`$C8`) continues the previous note for the new duration, and `Rest` (`$C9`) signifies silence.
### Core Macros
- **`%SetInstrument(id)`:** Sets the instrument for the current channel (e.g., `%SetInstrument($09)` for Strings). Helper macros like `%Strings()`, `%Piano()`, etc., exist for common instruments.
- **`%SetTempo(value)`:** Sets the overall playback speed of the song.
- **`%SetMasterVolume(value)` / `%SetChannelVolume(value)`:** Sets the volume for the entire song or just the current channel.
- **`%CallSubroutine(address, repeats)`:** The most important macro for structuring songs. It jumps to a labeled subroutine, plays it `repeats+1` times, and then returns. **This is the primary method for looping musical phrases.**
- **`%VibratoOn(delay, rate, depth)`:** Adds a vibrato effect.
- **`%TremoloOn(delay, rate, depth)`:** Adds a tremolo (volume fluctuation) effect.
- **`%SetPan(value)`:** Sets the stereo position (left/right) of the channel.
- **`%EchoVBits(switch, left, right)`:** Enables and configures echo for the channel.
## 3. Song File Structure
Every song `.asm` file follows a standard structure.
#### 1. Header
The file begins with a header that defines metadata for the song engine.
```asm
MyNewSong:
!ARAMAddr = $D86A ; Base address in ARAM for this song
dw !ARAMAddr+$0A ; Pointer to the Intro section
dw !ARAMAddr+$1A ; Pointer to the Main (looping) section
dw $00FF ; Default fade-in
dw !ARAMAddr+$02 ; Start of the looping section data
dw $0000
```
#### 2. Channel Pointers
Next is a table of pointers to each of the eight channel data blocks. The `!ARAMC` constant is used to make these pointers relative to the song's ARAM address.
```asm
.Channels
!ARAMC = !ARAMAddr-MyNewSong
dw .Channel0+!ARAMC
dw .Channel1+!ARAMC
; ...up to 8 channels, use dw $0000 for unused channels
```
#### 3. Channel Data
Each channel is a block of code containing commands and notes.
```asm
.Channel0
%SetMasterVolume($DA)
%SetTempo(62)
%SetInstrument($02) ; Tympani
%SetDurationN(!4th, $7F)
%CallSubroutine(.sub1+!ARAMC, 23) ; Call subroutine .sub1 24 times
db End ; $00, signifies end of channel data
```
#### 4. Subroutines
The bulk of a song is made of small, labeled subroutines containing musical phrases. These are placed after the channel data.
```asm
.sub1
db !4th, B1, B1, !8th, Tie, C2, !4th, F3s
db End ; Subroutines must also end with $00
```
## 4. How to Add a New Song
1. **Create the File:** Create a new `.asm` file in the `Music/` directory.
2. **Copy Template:** Copy the contents of an existing song (e.g., `stone_tower_temple_v2.asm`) into your new file to use as a template.
3. **Set Header:** Change the main label (e.g., `MyNewSong:`) and set the `!ARAMAddr`. This address must be unique and not conflict with other songs.
4. **Compose:** Write your music in the channel and subroutine blocks using the note constants and macros.
5. **Integrate the Song:**
- Open `Music/all_music.asm` and add an `incsrc` for your new file.
- To replace a vanilla song, find its label in the ROM map and use `org` to place your new song at that address. For example, to replace the Lost Woods theme:
```asm
org $1AADDE ; Original address of Lost Woods theme
incsrc "Music/MyNewSong.asm"
```
- To add a new song to the expanded Dark World bank, open `Music/expanded.asm` and add a new entry to the `SongBank_OverworldExpanded_Main` table.
## 5. Proposals for Improved Organization
The current system is functional but can be made more readable and maintainable.
1. **Standardize Subroutine Naming:** The current convention of `.sub1`, `.sub101`, etc., is ambiguous. A clearer naming scheme would greatly improve readability.
- **Proposal:** Name subroutines based on their musical function, like `.MelodyVerseA`, `.BasslineIntro`, `.PercussionFill1`. This makes the main channel blocks easier to read as a high-level song structure.
2. **Create a Common Patterns Library:** Many songs use similar rhythmic or melodic patterns (e.g., a standard 4/4 drum beat, an arpeggiated chord).
- **Proposal:** Create a `Music/common_patterns.asm` file. This file could contain a library of generic, reusable subroutines for things like drum patterns, basslines, or common arpeggios. Songs could then `incsrc` this library and call these patterns, reducing code duplication and speeding up composition.
3. **Develop Advanced Composition Macros:** The existing helper macros are basic. More advanced macros could abstract away the manual process of defining and calling subroutines.
- **Proposal:**
- `%DefineMeasure(Name, Notes...)`: A macro that takes a name and a list of notes and automatically creates a correctly formatted subroutine block.
- `%PlayMeasure(Name, Repeats)`: A macro that automatically calculates the relative address (`+!ARAMC`) and calls `%CallSubroutine`.
- **Example Workflow with Proposed Macros:**
```asm
; --- Subroutine Definitions ---
%DefineMeasure(VerseMelody, !8th, C4, D4, E4, F4, G4, A4, B4, C5)
%DefineMeasure(VerseBass, !4th, C2, G2, A2, F2)
; --- Channel Data ---
.Channel0
; ... setup ...
%PlayMeasure(VerseMelody, 4) ; Plays the melody 4 times
db End
.Channel1
; ... setup ...
%PlayMeasure(VerseBass, 4) ; Plays the bassline 4 times
db End
```
This approach would make the main channel data blocks read like a high-level song arrangement, significantly improving clarity.
4. **Improve In-File Documentation:**
- **Proposal:** Encourage the use of comments to label major song sections directly within the channel data (e.g., `; --- VERSE 1 ---`, `; --- CHORUS ---`). This provides crucial signposting when navigating complex song files.