From ZeldaHacking Wiki
Jump to: navigation, search

Oracles-disasm is the repository name for the Oracle of Ages & Seasons disassembly, based on the US region ROMs. It is capable of re-assembling into Ages and Seasons ROMs.

For setup instructions, see Setting up oracles-disasm.


Oracles-disasm is hands down the easiest way to make asm hacks, if you know what you're doing.

Copying compressed graphics and text to ZOLE roms

Using oracles-disasm is the only (easy) way to edit compressed graphics. You can use this in conjunction with ZOLE for things like titlescreen editing.

Start by making sure that you've set it up in modifiable mode. Then, run tools/misc/ <filename>, where <filename> is the location of your ZOLE rom (not rom.gbc). This will copy all compressed graphics (gfx_compressible/) and text (text/text.txt) into the given rom. It won't touch uncompressed graphics (gfx/).

The script corrupts room layouts, but this doesn't matter for ZOLE roms because ZOLE patches the game to read room layouts from elsewhere (uncompressed).

Level editing with LynnaLab

Similar to ZOLE, LynnaLab can edit levels through the disassembly's files.

Symbol files

Whenever a ROM is build from oracles-disasm, a corresponding ".sym" file is created along with it. This file contains addresses for all of the labels in the disassembly (but not most variables, yet). You can make a copy of this file to debug non-disassembly roms as well.

As long as the filename matches that of the ROM that is opened, the BGB and NO$GMB emulators can read this file to give you debugging symbols; for example, when modifying code in bgb, you can type something like call showText, and that will be understood.

The hack-base branch

There are two main branches, the "master" branch and the "hack-base" branch. "master" is designed to build vanilla Ages and Seasons ROM files, while "hack-base" has certain changes designed to make hacking easier.

In the "master" branch, precompressed assets (text, graphics, large rooms) are used. This makes it impossible to modify these assets.

This behaviour can be disabled by running the command "./" in the root of the repository, though, even on the "master" branch. But beyond that, the "hack-base" branch makes more changes.

Changes (both games)

  • Precompressed assets are NOT used, meaning everything is modifiable.
  • Tilesets are expanded and stored uncompressed. Each tileset has its own fully unique graphics file (they do not share any graphics unlike in the "master" branch). As a result the ROM is expanded to 2 megabytes.
  • Large rooms are stored uncompressed, because the original compression algorithm is weird.
  • The "ENABLE_BUGFIXES" compilation flag is set, which fixes a few bugs in the original game's code.

Changes (ages)

  • Disabled the function "setPastCliffPalettesToRed", which only exists because certain tileset data between past and present tilesets is reused; this function modifies cliff colors. But since tilesets were expanded as explained earlier, this function is no longer necessary.
  • The "Maku Path" dungeon existed twice. This is still the case, but now the two dungeons reference distinct data, allowing them to be modified independently of each other.

Changes (seasons)

Currently DOES NOT BUILD on this branch. (This will change in the future.)

Naming conventions

There are a few rules which oracles-disasm tries to abide by.

Functions dealing with objects are generally named as follows:

Function name prefix Behaviour
object Expects an object to be passed through register 'd', and either the 'hActiveObjectType' variable or the 'e' register for the object's type.
item Expects an "item" type object to be passed through register 'd' (an object in memory dx00-dx3f).
interaction Expects an "interaction" type object to be passed through register 'd' (an object in memory dx40-dx7f).
enemy Expects an "enemy" type object to be passed through register 'd' (an object in memory dx80-dxbf).
part Expects a "part" type object to be passed through register 'd' (an object in memory dxc0-dxff).

To "pass an object through register 'd'" means to set 'd' to the high byte of the object's address. For instance, if the object is an "enemy" stored at $d080-$d0bf, 'd' would be set to $d0. The function will infer the lower byte of the address by either assuming it's an enemy, reading from the 'hActiveObjectType' variable, or checking the 'e' register.