Difference between revisions of "Overworld Data Format"

From Super Mario World Speedrunning Wiki
Jump to: navigation, search
m (More edits.)
m (ExGFX pointer simplification)
 
(14 intermediate revisions by the same user not shown)
Line 1: Line 1:
LM-related information is accurate as of version 2.43.
+
LM-related information is accurate as of version 2.53.
  
 
== Position Format ==
 
== Position Format ==
Line 35: Line 35:
 
! Address !! Details !! LM-Modified Location
 
! Address !! Details !! LM-Modified Location
 
|-  
 
|-  
! $05D000
+
! style="text-align:center; font-family:consolas, monospace" | $05D000
 
| Tilemap for each individual Layer 1 tile. Four 8x8 tiles per tile, with two bytes per 8x8 (tile number, YXPCCCTT).
 
| Tilemap for each individual Layer 1 tile. Four 8x8 tiles per tile, with two bytes per 8x8 (tile number, YXPCCCTT).
 
| style="text-align:center; font-family:consolas, monospace" | (read1($04DCC1)<<16)|read2($04DCBC)
 
| style="text-align:center; font-family:consolas, monospace" | (read1($04DCC1)<<16)|read2($04DCBC)
 
|-
 
|-
! $0CF7DF
+
! style="text-align:center; font-family:consolas, monospace" | $0CF7DF
 
| Tilemap for the entire overworld, uncompressed. Loaded to $7EC800 during gameplay.
 
| Tilemap for the entire overworld, uncompressed. Loaded to $7EC800 during gameplay.
 
| style="text-align:center; font-family:consolas, monospace" | $0CF7DF
 
| style="text-align:center; font-family:consolas, monospace" | $0CF7DF
 
|-
 
|-
! N/A
+
! style="text-align:center; font-family:consolas, monospace" | N/A
| High bytes for the Layer 1 tilemap, compressed in LC_LZ2* format. Decompressed to $7FC800.
+
| High bytes for the Layer 1 tilemap, compressed in LC_LZ2<sup>1</sup> format. Decompressed to $7FC800.
 
| style="text-align:center; font-family:consolas, monospace" | (read1($04D827)<<16)|read2($04D821)
 
| style="text-align:center; font-family:consolas, monospace" | (read1($04D827)<<16)|read2($04D821)
 
|}
 
|}
<small><nowiki />* Or LC_LZ3 if the ROM uses it.</small>
+
<small><sup>1</sup> Or LC_LZ3 if the ROM uses it.</small>
  
  
Line 56: Line 56:
 
! Address !! Details !! LM-Modified Location
 
! Address !! Details !! LM-Modified Location
 
|-  
 
|-  
! $04D85D
+
! style="text-align:center; font-family:consolas, monospace" | $04D85D
 
| Location of the Layer 1 tile that each event reveals (#$0SYX format).
 
| Location of the Layer 1 tile that each event reveals (#$0SYX format).
 
| style="text-align:center; font-family:consolas, monospace" | read3($04EDBE)
 
| style="text-align:center; font-family:consolas, monospace" | read3($04EDBE)
 
|-
 
|-
! $04D93D
+
! style="text-align:center; font-family:consolas, monospace" | $04D93D
 
| VRAM locations to write the data for each event.
 
| VRAM locations to write the data for each event.
 
| style="text-align:center; font-family:consolas, monospace" | read3($04EDB8)
 
| style="text-align:center; font-family:consolas, monospace" | read3($04EDB8)
 
|}
 
|}
Note that only one tile can be revealed by these tables. To reveal more, [[#Silent_Events|silent events]] must be used.
+
Note that only one tile can be revealed per event by these tables. To reveal more, [[#Silent_Events|silent events]] must be used.
  
 
The list of what tile reveals what can be found at $04DA1D (before tiles) and $04DA33 (after tiles). These also correspond to Lunar Magic's "reveal tile list".
 
The list of what tile reveals what can be found at $04DA1D (before tiles) and $04DA33 (after tiles). These also correspond to Lunar Magic's "reveal tile list".
Line 77: Line 77:
 
! Address !! Details !! LM-Modified Location
 
! Address !! Details !! LM-Modified Location
 
|-
 
|-
! $04A533
+
! style="text-align:center; font-family:consolas, monospace" | $04A533
 
| Layer 2 tile numbers, compressed in LC_RLE1 format.
 
| Layer 2 tile numbers, compressed in LC_RLE1 format.
 
| style="text-align:center; font-family:consolas, monospace" | (read1($04DC79)<<16)|read2($04DC72)
 
| style="text-align:center; font-family:consolas, monospace" | (read1($04DC79)<<16)|read2($04DC72)
 
|-
 
|-
! $04C02B
+
! style="text-align:center; font-family:consolas, monospace" | $04C02B
 
| Layer 2 tile YXPCCCTT, compressed in LC_RLE1 format.
 
| Layer 2 tile YXPCCCTT, compressed in LC_RLE1 format.
 
| style="text-align:center; font-family:consolas, monospace" | (read1($04DC79)<<16)|read2($04DC8D)
 
| style="text-align:center; font-family:consolas, monospace" | (read1($04DC79)<<16)|read2($04DC8D)
Line 93: Line 93:
 
! Address !! Details !! LM-Modified Location
 
! Address !! Details !! LM-Modified Location
 
|-
 
|-
! $04DD8D
+
! style="text-align:center; font-family:consolas, monospace" | $04DD8D
 
| Table of data for all the events. Four bytes per tile; the first two are the 'source' (index to $0C8000), and the second two are the 'destination' (index to $7F4000).
 
| Table of data for all the events. Four bytes per tile; the first two are the 'source' (index to $0C8000), and the second two are the 'destination' (index to $7F4000).
 
| style="text-align:center; font-family:consolas, monospace" | read3($04E49F)
 
| style="text-align:center; font-family:consolas, monospace" | read3($04E49F)
 
|-
 
|-
! $04E359
+
! style="text-align:center; font-family:consolas, monospace" | $04E359
 
| Indices to $04DD8D, indexed by event number. The number of tiles in any given event is determined by the difference from the next event's index (i.e. [event + 1] - [event]).
 
| Indices to $04DD8D, indexed by event number. The number of tiles in any given event is determined by the difference from the next event's index (i.e. [event + 1] - [event]).
| style="text-align:center; font-family:consolas, monospace" | $04E359
+
| style="text-align:center; font-family:consolas, monospace" | $04E359<sup>1</sup>
 
|-
 
|-
! $0C8000
+
! style="text-align:center; font-family:consolas, monospace" | $0C8000
| Tilemap (tile numbers) for the event tiles, uncompressed. The first x900* bytes are the 6x6 tiles, while the next x400 are the 2x2.
+
| Tilemap (tile numbers) for the event tiles, uncompressed. The first x900<sup>2</sup> bytes are the 6x6 tiles, while the next x400 are the 2x2.
 
| style="text-align:center; font-family:consolas, monospace" | read3($04EAF5)
 
| style="text-align:center; font-family:consolas, monospace" | read3($04EAF5)
 
|-
 
|-
! $0C8D00
+
! style="text-align:center; font-family:consolas, monospace" | $0C8D00
 
| Tilemap (YXPCCCTT) for the event tiles, compressed in LC_RLE1. Has the same format as $0C8000 when uncompressed.
 
| Tilemap (YXPCCCTT) for the event tiles, compressed in LC_RLE1. Has the same format as $0C8000 when uncompressed.
 
| style="text-align:center; font-family:consolas, monospace" | (read1($04DD4A)<<16)|read2($04DD45)
 
| style="text-align:center; font-family:consolas, monospace" | (read1($04DD4A)<<16)|read2($04DD45)
Line 111: Line 111:
 
To convert tile numbers in LM to indices in $0C8000, 6x6 tiles can be found as <code>#$24 * tileNum</code>, while 2x2 tiles can be found as <code>(#$04 * tileNum) + #$0900</code>*.
 
To convert tile numbers in LM to indices in $0C8000, 6x6 tiles can be found as <code>#$24 * tileNum</code>, while 2x2 tiles can be found as <code>(#$04 * tileNum) + #$0900</code>*.
  
<small><nowiki />* It should be noted that LM has an option to change this amount. To get the size in case it changed, use <code>read2($04E4C0)</code>.</small>
+
<small><sup>1</sup> If Lunar Magic's overworld level expansion hijack is applied, this table is instead moved dynamically to <code>read3($04E471)</code>.<br />
 +
<sup>2</sup> It should be noted that LM has an option to change this amount. To get the size in case it changed, use <code>read2($04E4C0)</code>.</small>
  
  
Line 124: Line 125:
 
! Address !! Details
 
! Address !! Details
 
|-
 
|-
! $04FC1E
+
! style="text-align:center; font-family:consolas, monospace" | $04FC1E
 
| 16-bit X positions for the two smoke sprites; the first is the main map, and the second is Yoshi's Island. This sprite can not be used on other submaps.
 
| 16-bit X positions for the two smoke sprites; the first is the main map, and the second is Yoshi's Island. This sprite can not be used on other submaps.
 
|-
 
|-
! $04FC22
+
! style="text-align:center; font-family:consolas, monospace" | $04FC22
 
| 16-bit Y positions for the two smoke sprites; the first is the main map, and the second is Yoshi's Island. This sprite can not be used on other submaps.
 
| 16-bit Y positions for the two smoke sprites; the first is the main map, and the second is Yoshi's Island. This sprite can not be used on other submaps.
 
|-
 
|-
! $04F666
+
! style="text-align:center; font-family:consolas, monospace" | $04F666
 
| 16-bit X offsets for the three submap ghosts from their main map counterparts. #$0001 will move the ghost one pixel right, #$FFFF will move it one pixel left.
 
| 16-bit X offsets for the three submap ghosts from their main map counterparts. #$0001 will move the ghost one pixel right, #$FFFF will move it one pixel left.
 
|-
 
|-
! $04F66C
+
! style="text-align:center; font-family:consolas, monospace" | $04F66C
 
| 16-bit Y offsets for the three submap ghosts from their main map counterparts. #$0001 will move the ghost one pixel down, #$FFFF will move it one pixel up.
 
| 16-bit Y offsets for the three submap ghosts from their main map counterparts. #$0001 will move the ghost one pixel down, #$FFFF will move it one pixel up.
 
|-
 
|-
! $04FA2E
+
! style="text-align:center; font-family:consolas, monospace" | $04FA2E
 
| Low byte of the X position for the three overworld fish, indexed by the Layer 1 tile that spawns it (4E-50).
 
| Low byte of the X position for the three overworld fish, indexed by the Layer 1 tile that spawns it (4E-50).
 
|-
 
|-
! $04FA31
+
! style="text-align:center; font-family:consolas, monospace" | $04FA31
 
| High byte of the X position for the three overworld fish, indexed by the Layer 1 tile that spawns it (4E-50).
 
| High byte of the X position for the three overworld fish, indexed by the Layer 1 tile that spawns it (4E-50).
 
|-
 
|-
! $04FA34
+
! style="text-align:center; font-family:consolas, monospace" | $04FA34
 
| Low byte of the Y position for the three overworld fish, indexed by the Layer 1 tile that spawns it (4E-50).
 
| Low byte of the Y position for the three overworld fish, indexed by the Layer 1 tile that spawns it (4E-50).
 
|-
 
|-
! $04FA37
+
! style="text-align:center; font-family:consolas, monospace" | $04FA37
 
| High byte of the Y position for the three overworld fish, indexed by the Layer 1 tile that spawns it (4E-50).
 
| High byte of the Y position for the three overworld fish, indexed by the Layer 1 tile that spawns it (4E-50).
 
|-
 
|-
! $04FB88
+
! style="text-align:center; font-family:consolas, monospace" | $04FB88
 
| Low byte of the X position for the overworld Koopa Kids, indexed by the Layer 1 tile that spawns it (49-4B).
 
| Low byte of the X position for the overworld Koopa Kids, indexed by the Layer 1 tile that spawns it (49-4B).
 
|-
 
|-
! $04FB8B
+
! style="text-align:center; font-family:consolas, monospace" | $04FB8B
 
| High byte of the X position for the overworld Koopa Kids, indexed by the Layer 1 tile that spawns it (49-4B).
 
| High byte of the X position for the overworld Koopa Kids, indexed by the Layer 1 tile that spawns it (49-4B).
 
|-
 
|-
! $04FB8E
+
! style="text-align:center; font-family:consolas, monospace" | $04FB8E
 
| Low byte of the Y position for the overworld Koopa Kids, indexed by the Layer 1 tile that spawns it (49-4B).
 
| Low byte of the Y position for the overworld Koopa Kids, indexed by the Layer 1 tile that spawns it (49-4B).
 
|-
 
|-
! $04FB91
+
! style="text-align:center; font-family:consolas, monospace" | $04FB91
 
| High byte of the Y position for the overworld Koopa Kids, indexed by the Layer 1 tile that spawns it (49-4B).
 
| High byte of the Y position for the overworld Koopa Kids, indexed by the Layer 1 tile that spawns it (49-4B).
 
|}
 
|}
 
As a sidenote, the main overworld sprite data is only read a single time on titlescreen load, then never again.
 
As a sidenote, the main overworld sprite data is only read a single time on titlescreen load, then never again.
 +
 +
 +
As of Lunar Magic v2.50, a second sprite table exclusively made for custom sprites has been added. Unlike the original table, this one does not have a fixed size; you can have up to 24 custom sprites per submap. This table can be found with <code>read3($0EF55D)</code>.
 +
 +
The first part of the data is 16-bit indices to each submap's data, in the standard submap order (for a total of 14 bytes).
 +
The second part is the actual sprite data. Each sprite has 4 bytes associated with it:
 +
{| class="wikitable"
 +
! colspan="5" | Custom Sprite Data Format
 +
|- style="font-family:consolas, monospace"
 +
| xnnnnnnn yyyXXXXX hhhhhYYY eeeeeeee
 +
|}
 +
{| class="wikitable" style="font-family:consolas, monospace"
 +
| nnnnnnn  || Sprite number
 +
|-
 +
| XXXXXx  || X position (in 8x8s, relative to either 0,0 or 2,41).
 +
|-
 +
| YYYyyy  || Y position (in 8x8s, relative to either 0,0 or 2,41).
 +
|-
 +
| hhhhh    || Height. Determines how "far above the ground" the sprite should appear.
 +
|-
 +
| eeeeeeee || Extra bits.
 +
|}
 +
Lunar Magic does nothing with this table outside of allowing you to edit it, however, so the data currently serves no purpose until a tool implements it.
  
  
Line 173: Line 197:
 
! Address !! Details !! LM-Modified Location
 
! Address !! Details !! LM-Modified Location
 
|-
 
|-
! $04E8E4
+
! style="text-align:center; font-family:consolas, monospace" | $04E8E4
 
| The original game's indexing system. Contains event numbers associated with an offscreen tile, with the index for the event used as an index to the below tables. One event can have multiple entries.
 
| The original game's indexing system. Contains event numbers associated with an offscreen tile, with the index for the event used as an index to the below tables. One event can have multiple entries.
 
| style="text-align:center; font-family:consolas, monospace" | N/A
 
| style="text-align:center; font-family:consolas, monospace" | N/A
 
|-
 
|-
! N/A
+
! style="text-align:center; font-family:consolas, monospace" | N/A
 
| Lunar Magic's indexing system. Contains 16-bit indices to the below tables; the number of tiles per event is determined by the difference between the current event's index and the next.
 
| Lunar Magic's indexing system. Contains 16-bit indices to the below tables; the number of tiles per event is determined by the difference between the current event's index and the next.
| style="text-align:center; font-family:consolas, monospace" | read3(read3($04E9F7)+$0D)
+
| style="text-align:center; font-family:consolas, monospace" | read3(read3($04E9F8)+$0D)
 
|-
 
|-
! $04E910
+
! style="text-align:center; font-family:consolas, monospace" | $04E910
 
| Indicates whether the tile is on Layer 1 (#$00) or Layer 2 (#$01).
 
| Indicates whether the tile is on Layer 1 (#$00) or Layer 2 (#$01).
| style="text-align:center; font-family:consolas, monospace" | read3(read3($04E9F7)+$34)
+
| style="text-align:center; font-family:consolas, monospace" | read3(read3($04E9F8)+$34)
 
|-
 
|-
! $04E93C
+
! style="text-align:center; font-family:consolas, monospace" | $04E93C
 
| 16-bit locations of each tile, as direct indices to the Layer 1 tilemap at $7EC800 or Layer 2 tilemap at $7F4000.
 
| 16-bit locations of each tile, as direct indices to the Layer 1 tilemap at $7EC800 or Layer 2 tilemap at $7F4000.
| style="text-align:center; font-family:consolas, monospace" | read3(read3($04E9F7)+$28)
+
| style="text-align:center; font-family:consolas, monospace" | read3(read3($04E9F8)+$28)
 
|-
 
|-
! $04E994
+
! style="text-align:center; font-family:consolas, monospace" | $04E994
 
| 16-bit tile number to use. For Layer 1 tiles, this is just the tile number as normal; for Layer 2, it's the tile's index in $0C8000.
 
| 16-bit tile number to use. For Layer 1 tiles, this is just the tile number as normal; for Layer 2, it's the tile's index in $0C8000.
 
| style="text-align:center; font-family:consolas, monospace" | read3(read3($04E9F8)+$22)
 
| style="text-align:center; font-family:consolas, monospace" | read3(read3($04E9F8)+$22)
Line 201: Line 225:
 
! Address !! Details
 
! Address !! Details
 
|-
 
|-
! $049078
+
! style="text-align:center; font-family:consolas, monospace" | $049078
 
| Translevel numbers that have hardcoded paths. #$FF indicates Chocolate Island 2's pipe (see $049082/$049084).
 
| Translevel numbers that have hardcoded paths. #$FF indicates Chocolate Island 2's pipe (see $049082/$049084).
 
|-
 
|-
 
|-
 
|-
! $04910E
+
! style="text-align:center; font-family:consolas, monospace" | $04910E
 
| Index table for each of the translevels at $049078 to the hardcoded path data.
 
| Index table for each of the translevels at $049078 to the hardcoded path data.
 
|-
 
|-
! $049086
+
! style="text-align:center; font-family:consolas, monospace" | $049086
 
| Hardcoded path data. This consists of a list of all the Layer 1 tiles that Mario walks over, ending in a level tile.
 
| Hardcoded path data. This consists of a list of all the Layer 1 tiles that Mario walks over, ending in a level tile.
 
|-
 
|-
! $0490CA
+
! style="text-align:center; font-family:consolas, monospace" | $0490CA
 
| Directions Mario moves on each of the tiles listed at in the hardcoded path data; the first value also determines the direction of the path from the original level tile. #$00 = up, #$02 = down, #$04 = left, #$06 = right.
 
| Directions Mario moves on each of the tiles listed at in the hardcoded path data; the first value also determines the direction of the path from the original level tile. #$00 = up, #$02 = down, #$04 = left, #$06 = right.
 
|-
 
|-
! $049082
+
! style="text-align:center; font-family:consolas, monospace" | $049082
 
| 16-bit X position of Chocolate Island 2's pipe, as a sprite position (i.e. Mario's position on it).
 
| 16-bit X position of Chocolate Island 2's pipe, as a sprite position (i.e. Mario's position on it).
 
|-
 
|-
! $049084  
+
! style="text-align:center; font-family:consolas, monospace" | $049084  
 
| 16-bit Y position of Chocolate Island 2's pipe, as a sprite position (i.e. Mario's position on it).
 
| 16-bit Y position of Chocolate Island 2's pipe, as a sprite position (i.e. Mario's position on it).
 
|}
 
|}
Line 230: Line 254:
 
! Address !! Details !! LM-Modified Location
 
! Address !! Details !! LM-Modified Location
 
|-
 
|-
! $048431
+
! style="text-align:center; font-family:consolas, monospace" | $048431
 
| Two-byte values containing the source tile X position (first byte) and submap (second byte) for each warp.
 
| Two-byte values containing the source tile X position (first byte) and submap (second byte) for each warp.
 
| style="text-align:center; font-family:consolas, monospace" | read3(read3($04850A)+$14)
 
| style="text-align:center; font-family:consolas, monospace" | read3(read3($04850A)+$14)
 
|-
 
|-
! $048467
+
! style="text-align:center; font-family:consolas, monospace" | $048467
 
| Two-byte values containing the source tile Y position (first byte) for each warp. Second byte is unused.
 
| Two-byte values containing the source tile Y position (first byte) for each warp. Second byte is unused.
 
| style="text-align:center; font-family:consolas, monospace" | read3(read3($04850A)+$24)
 
| style="text-align:center; font-family:consolas, monospace" | read3(read3($04850A)+$24)
 
|-
 
|-
! $04849D
+
! style="text-align:center; font-family:consolas, monospace" | $04849D
 
| 16-bit destination X position and submap for each warp, in the format <code>%----SSSX xxxxxxxx</code>.
 
| 16-bit destination X position and submap for each warp, in the format <code>%----SSSX xxxxxxxx</code>.
 
| style="text-align:center; font-family:consolas, monospace" | read3(read3($048567)+$07)
 
| style="text-align:center; font-family:consolas, monospace" | read3(read3($048567)+$07)
 
|-
 
|-
! $0484D3
+
! style="text-align:center; font-family:consolas, monospace" | $0484D3
 
| 16-bit destination Y position.
 
| 16-bit destination Y position.
 
| style="text-align:center; font-family:consolas, monospace" | read3(read3($048567)+$19)
 
| style="text-align:center; font-family:consolas, monospace" | read3(read3($048567)+$19)
Line 254: Line 278:
 
! Address !! Details !! LM-Modified Location
 
! Address !! Details !! LM-Modified Location
 
|-
 
|-
! $049964
+
! style="text-align:center; font-family:consolas, monospace" | $049964
 
| Exit path location table (where Mario enters). Order is the 16-bit Y position, 16-bit X position, and 8-bit submap.
 
| Exit path location table (where Mario enters). Order is the 16-bit Y position, 16-bit X position, and 8-bit submap.
 
| style="text-align:center; font-family:consolas, monospace" | read3(read3($049A36)+$11)
 
| style="text-align:center; font-family:consolas, monospace" | read3(read3($049A36)+$11)
 
|-
 
|-
! $0499AA
+
! style="text-align:center; font-family:consolas, monospace" | $0499AA
 
| Exit path destination table (where Mario exits). Order is the 16-bit Y position, 16-bit X position, and 8-bit submap.
 
| Exit path destination table (where Mario exits). Order is the 16-bit Y position, 16-bit X position, and 8-bit submap.
 
| style="text-align:center; font-family:consolas, monospace" | read3(read3($049A36)+$2C)
 
| style="text-align:center; font-family:consolas, monospace" | read3(read3($049A36)+$2C)
 
|-
 
|-
! $0499F0
+
! style="text-align:center; font-family:consolas, monospace" | $0499F0
| Extra exit path destination table (where Mario exits). This contains two bytes per path, for the destination tile's Y and X position respectively.*
+
| Extra exit path destination table (where Mario exits). This contains two bytes per path, for the destination tile's Y and X position respectively.<sup>1</sup>
 
| style="text-align:center; font-family:consolas, monospace" | read3(read3($049A36)+$48)
 
| style="text-align:center; font-family:consolas, monospace" | read3(read3($049A36)+$48)
 
|}
 
|}
<small><nowiki />* Generally, this table is just the positions in $0499AA divided by 16. However, if Mario exits moving upwards or leftwards, you should subtract 1 from the Y or X position respectively before dividing.</small>
+
<small><sup>1</sup> Generally, this table is just the positions in $0499AA divided by 16. However, if Mario exits moving upwards or leftwards, you should subtract 1 from the Y or X position respectively before dividing.</small>
  
  
Line 275: Line 299:
 
! Address !! Details !! LM-Modified Location
 
! Address !! Details !! LM-Modified Location
 
|-
 
|-
! $04E5B6
+
! style="text-align:center; font-family:consolas, monospace" | $04E5B6
 
| Locations of the levels with destruction events (#$0SYX format).
 
| Locations of the levels with destruction events (#$0SYX format).
 
| style="text-align:center; font-family:consolas, monospace" | read3($04E69C)
 
| style="text-align:center; font-family:consolas, monospace" | read3($04E69C)
 
|-
 
|-
! $04E587
+
! style="text-align:center; font-family:consolas, monospace" | $04E587
 
| VRAM locations to store the destroyed tiles for each event, written as the first two bytes of its stripe header (<code>%0010YXyy yyyxxxxx</code>).
 
| VRAM locations to store the destroyed tiles for each event, written as the first two bytes of its stripe header (<code>%0010YXyy yyyxxxxx</code>).
 
| style="text-align:center; font-family:consolas, monospace" | read3($04EEC9)
 
| style="text-align:center; font-family:consolas, monospace" | read3($04EEC9)
 
|-
 
|-
! $04E5D6
+
! style="text-align:center; font-family:consolas, monospace" | $04E5D6
 
| List of events that activate a destruction. Only used on overworld load, for reloading previously-destroyed tiles.
 
| List of events that activate a destruction. Only used on overworld load, for reloading previously-destroyed tiles.
 
| style="text-align:center; font-family:consolas, monospace" | read3($04E67C)
 
| style="text-align:center; font-family:consolas, monospace" | read3($04E67C)
Line 294: Line 318:
 
Once assigned, translevels for each Layer 1 tile are written to a table at $7ED000 and exit directions are written to a table at $7FD800. These tables are formatted the same way as the Layer 1 tilemap at $7EC800, so if you have the index to a level tile there, you can get its translevel and exit directions from the other two tables using the same index.
 
Once assigned, translevels for each Layer 1 tile are written to a table at $7ED000 and exit directions are written to a table at $7FD800. These tables are formatted the same way as the Layer 1 tilemap at $7EC800, so if you have the index to a level tile there, you can get its translevel and exit directions from the other two tables using the same index.
  
Lunar Magic, of course, changes translevels to be assignable on a tile-by-tile basis. It stores the data to a table at <code>(read1($04D808)<<16)|read2($04D803)</code>, compressed in the LC_LZ2 format (or LC_LZ3 if the ROM has it enabled). This data decompresses to $7ED000 as normal.
+
Lunar Magic, of course, changes translevels to be assignable on a tile-by-tile basis. It stores both the translevels and exit directions to a table at <code>(read1($04D808)<<16)|read2($04D803)</code>, compressed in the LC_LZ2 format (or LC_LZ3 if the ROM has it enabled). This data decompresses to $7ED000 as normal.
  
 
The data tables for the directions and event associated with that translevel, however, remain unmoved:
 
The data tables for the directions and event associated with that translevel, however, remain unmoved:
Line 300: Line 324:
 
! Address !! Details
 
! Address !! Details
 
|-
 
|-
! $04D678
+
! style="text-align:center; font-family:consolas, monospace" | $04D678
 
| Direction to move after beating a level, indexed by translevel. Formatted as <code>%nnss----</code> for the normal direction nn and secret direction ss. %00 = up, %01 = down, %10 = left, %11 = right.
 
| Direction to move after beating a level, indexed by translevel. Formatted as <code>%nnss----</code> for the normal direction nn and secret direction ss. %00 = up, %01 = down, %10 = left, %11 = right.
 
|-
 
|-
! $05D608
+
! style="text-align:center; font-family:consolas, monospace" | $05D608
 
| Events triggered by each translevel.
 
| Events triggered by each translevel.
 
|}
 
|}
 +
In regards to the direction to move after beating a level, technically SMW parses directions for two additional exits, although they aren't used. The original game formats the directions for these extra exits as <code>%nnssxyz0</code>, with exit 3 using bits <code>xy</code> and exit 4 using bits <code>yz</code>. In Lunar Magic v3.00+, support for these were officially added, with the format being revised to <code>%aabbccdd</code>, using <code>cc</code> and <code>dd</code> for exit 3 and 4 respectively.
  
  
Line 316: Line 341:
 
! Address !! Details
 
! Address !! Details
 
|-
 
|-
! $009EE0
+
! style="text-align:center; font-family:consolas, monospace" | $009EE0
 
| The original game's initial flag table. Each entry consists of two bytes: the first is the translevel to modify, and the second is the flags to set in $1EA2.
 
| The original game's initial flag table. Each entry consists of two bytes: the first is the translevel to modify, and the second is the flags to set in $1EA2.
 
|-
 
|-
! $05DDA0
+
! style="text-align:center; font-family:consolas, monospace" | $05DDA0<sup>1</sup>
 
| Lunar Magic's initial flag table. Every translevel has a single byte, containing the flags to set in $1EA2.
 
| Lunar Magic's initial flag table. Every translevel has a single byte, containing the flags to set in $1EA2.
 
|-
 
|-
! $009EF0
+
! style="text-align:center; font-family:consolas, monospace" | $009EF0
 
| Initial values for $1F11-$1F26.
 
| Initial values for $1F11-$1F26.
 
|}
 
|}
 +
<small><sup>1</sup> If Lunar Magic's overworld level expansion is applied, $05DDA0 is moved to $03BE80.</small>
  
  
Line 332: Line 358:
 
! Address !! Details
 
! Address !! Details
 
|-
 
|-
! $049AC5
+
! style="text-align:center; font-family:consolas, monospace" | $049AC5
 
| The level string table, indexed by the three offset tables. If the high bit of a byte is set, it indicates the last character in the string.
 
| The level string table, indexed by the three offset tables. If the high bit of a byte is set, it indicates the last character in the string.
 
|-
 
|-
! $049C91
+
! style="text-align:center; font-family:consolas, monospace" | $049C91
 
| Offset table A. If the first byte pointed to has the high bit set, this part is completely skipped.
 
| Offset table A. If the first byte pointed to has the high bit set, this part is completely skipped.
 
|-
 
|-
! $049CCF
+
! style="text-align:center; font-family:consolas, monospace" | $049CCF
 
| Offset table B. If the first byte pointed to is #$9F, this part is completely skipped.
 
| Offset table B. If the first byte pointed to is #$9F, this part is completely skipped.
 
|-
 
|-
! $049CED
+
! style="text-align:center; font-family:consolas, monospace" | $049CED
 
| Offset table C.
 
| Offset table C.
 
|-
 
|-
! $04A0FC
+
! style="text-align:center; font-family:consolas, monospace" | $04A0FC
 
| Assembly table for each level's name. Contains indexes to the offset tables in a 16-bit format: <code>%-aaaaaaa bbbbcccc</code>.
 
| Assembly table for each level's name. Contains indexes to the offset tables in a 16-bit format: <code>%-aaaaaaa bbbbcccc</code>.
 
|}
 
|}
  
Lunar Magic logically scraps this system entirely, for a single large table at <code>read3($03BB57)</code> containing every level's name (26 bytes per name).
+
Lunar Magic logically scraps this system entirely, for a single large table at <code>read3($03BB57)</code> containing every level's name (19 bytes per name).
  
  
Line 368: Line 394:
 
|}
 
|}
  
Lunar Magic changes this to a single table containing all sixteen 16-bit ExGFX files for each submap, for 32 bytes total per submap. This table can be found at <code>(read1(read3($00A141)+$12)<<16)|read2(read3($00A141)+$09)</code>. The ExGFX files are ordered as:
+
Lunar Magic changes this to a single table containing all sixteen 16-bit ExGFX files for each submap, for 32 bytes total per submap. This table can be found at <code>(read1($0FFAC2)<<16)|read2($0FFAB9)</code>. The exact order of ExGFX files may vary, though, depending on whether the user has enabled Lunar Magic's option to merge the FG1/FG2 slots with SP3/SP4, which enables the usage of the FG5 and FG6 slots:
 
{| class="wikitable"
 
{| class="wikitable"
 +
! Merge disabled
 
| AN2 || LT3
 
| AN2 || LT3
| BG3 || BG2 || FG3 || BG1 || FG2 || FG1
+
| (FG6) || (FG5)
 +
| FG4 || FG3 || FG2 || FG1
 
| SP4 || SP3 || SP2 || SP1
 
| SP4 || SP3 || SP2 || SP1
 +
| LG4 || LG3 || LG2 || LG1
 +
|-
 +
! Merge enabled
 +
| AN2 || LT3
 +
| --- || ---
 +
| FG6 || FG5 || FG4 || FG3 || FG2 || FG1
 +
| SP2 || SP1
 
| LG4 || LG3 || LG2 || LG1
 
| LG4 || LG3 || LG2 || LG1
 
|}
 
|}
 +
While the values of the FG5/FG6 slots are retained in the third and fourth slots when the merge option is disabled, they are not actually used. Those two slots meanwhile go unused when the merge option actually is enabled.
 +
 
Addionally, AN2 and LT3 contain some extra information in their high bytes:
 
Addionally, AN2 and LT3 contain some extra information in their high bytes:
 
{| class="wikitable"
 
{| class="wikitable"
Line 406: Line 443:
 
! Address !! Details
 
! Address !! Details
 
|-
 
|-
! $00AD1E
+
! style="text-align:center; font-family:consolas, monospace" | $00AD1E
 
| Table of Layer 2 palette IDs for each submap, as values for indexing to $00ABDF.
 
| Table of Layer 2 palette IDs for each submap, as values for indexing to $00ABDF.
 
|-
 
|-
! $00ABDF
+
! style="text-align:center; font-family:consolas, monospace" | $00ABDF
 
| 16-bit pointers to the palette table for each Layer 2 palette ID, starting at $00B3D8 (normal) or $00B732 (Special World passed).
 
| 16-bit pointers to the palette table for each Layer 2 palette ID, starting at $00B3D8 (normal) or $00B732 (Special World passed).
 
|-
 
|-
! $00B3D8
+
! style="text-align:center; font-family:consolas, monospace" | $00B3D8
 
| All the Layer 2 palette data (palettes 4-7, colors 1-7). Default order is Yoshi, main, Star, Vanilla/Bowser, Forest, Special.
 
| All the Layer 2 palette data (palettes 4-7, colors 1-7). Default order is Yoshi, main, Star, Vanilla/Bowser, Forest, Special.
 
|-
 
|-
! $00B732
+
! style="text-align:center; font-family:consolas, monospace" | $00B732
 
| All the Layer 2 palette data (palettes 4-7, colors 1-7) after the Special World is beaten. Default order is Yoshi, main, Star, Vanilla/Bowser, Forest, Special.
 
| All the Layer 2 palette data (palettes 4-7, colors 1-7) after the Special World is beaten. Default order is Yoshi, main, Star, Vanilla/Bowser, Forest, Special.
 
|-
 
|-
! $00B528
+
! style="text-align:center; font-family:consolas, monospace" | $00B528
 
| Layer 1 palette data (palettes 2-7, colors 9-F).
 
| Layer 1 palette data (palettes 2-7, colors 9-F).
 
|-
 
|-
! $00B58A
+
! style="text-align:center; font-family:consolas, monospace" | $00B58A
 
| Sprite palette data (palettes 9-F, colors 1-7). Note that palette F is also used for animating the lightning effect.
 
| Sprite palette data (palettes 9-F, colors 1-7). Note that palette F is also used for animating the lightning effect.
 
|-
 
|-
! $00B5EC
+
! style="text-align:center; font-family:consolas, monospace" | $00B5EC
 
| Layer 3 palette data (palettes 0-1, colors 8-F).
 
| Layer 3 palette data (palettes 0-1, colors 8-F).
 
|}
 
|}
Line 451: Line 488:
 
| FF...  || Frame numbers to initialize each of the specified manual triggers to
 
| FF...  || Frame numbers to initialize each of the specified manual triggers to
 
|-
 
|-
| DDdd... || Indices to each animation slot's data* (with #$0002 referring to the byte after this value)
+
| DDdd... || Indices to each animation slot's data<sup>1</sup> (with #$0002 referring to the byte after this value)
 
|}
 
|}
<small><nowiki />* Indices are included up to the highest used slot. If a slot before that isn't used, its indice is 0000.</small>
+
<small><sup>1</sup> Indices are included up to the highest used slot. If a slot before that isn't used, its indice is 0000.</small>
  
 
{| class="wikitable"
 
{| class="wikitable"
Line 469: Line 506:
 
| DDdd    || Tiles only: VRAM destination*
 
| DDdd    || Tiles only: VRAM destination*
 
|-
 
|-
| DD      || Colors only: number of colors to animate (-1)*
+
| DD      || Colors only: number of colors to animate (-1)<sup>1</sup>
 
|-
 
|-
 
| dd      || Colors only: palette destination
 
| dd      || Colors only: palette destination
Line 475: Line 512:
 
| MMmm... || Memory address for each frame's tile/color data, or direct SNES RGB values when animating a single color
 
| MMmm... || Memory address for each frame's tile/color data, or direct SNES RGB values when animating a single color
 
|}
 
|}
<small><nowiki />* The highest bit being 1 indicates the slot uses the sumbap's alternative GFX file.</small>
+
<small><sup>1</sup> The highest bit being 1 indicates the slot uses the sumbap's alternative GFX file.</small>
  
 
Global ExAnimation data can be found with <code>(read1(read3($048087)+$58)<<16)|read2(read3($048087)+$61)</code>. If <code>read2(read3($048087)+$61)</code> returns #$0000, the ROM has no global ExAnimation data.
 
Global ExAnimation data can be found with <code>(read1(read3($048087)+$58)<<16)|read2(read3($048087)+$61)</code>. If <code>read2(read3($048087)+$61)</code> returns #$0000, the ROM has no global ExAnimation data.
Line 529: Line 566:
 
! Address !! Details
 
! Address !! Details
 
|-
 
|-
! $05A590
+
! style="text-align:center; font-family:consolas, monospace" | $05A590
 
| Which translevels have message boxes. The high bit being set indicates message 2. The first 4 bytes are reserved for switch palaces, and the last (index x16) for Yoshi's House. If a message's level isn't found, index 0 is used by default.
 
| Which translevels have message boxes. The high bit being set indicates message 2. The first 4 bytes are reserved for switch palaces, and the last (index x16) for Yoshi's House. If a message's level isn't found, index 0 is used by default.
 
|-
 
|-
! $05A5A7
+
! style="text-align:center; font-family:consolas, monospace" | $05A5A7
 
| Indices to the start of each message's text at $05A5D9.
 
| Indices to the start of each message's text at $05A5D9.
 
|-
 
|-
! $05A5D9
+
! style="text-align:center; font-family:consolas, monospace" | $05A5D9
 
| All of the message box texts (tile numbers only). The high bit being set indicates a new line, and the 8th new line indicates the end of the message.
 
| All of the message box texts (tile numbers only). The high bit being set indicates a new line, and the 8th new line indicates the end of the message.
 
|}
 
|}
Line 543: Line 580:
 
! Address !! Details
 
! Address !! Details
 
|-
 
|-
! style="text-align:center; font-family:consolas, monospace" | $03BE80
+
! style="text-align:center; font-family:consolas, monospace" | $03BE80<sup>1</sup>
| 16-bit indices to the data for each message. Indexed by ((level * 2) + message number) * 2.
+
| 16-bit indices to the data for each message. Indexed by ((translevel * 2) + message number) * 2.
 
|-
 
|-
 
! style="text-align:center; font-family:consolas, monospace" | read3($03BC0B)
 
! style="text-align:center; font-family:consolas, monospace" | read3($03BC0B)
| The actual message data. For the most part, just raw tile numbers with 26 tiles per line, with the message ending after 8 lines. However, #$FE is used as a special value that prematurely ends the message's data.
+
| The actual message data. For the most part, just raw tile numbers with 18 tiles per line, with the message ending after 8 lines. However, #$FE is used as a special value that prematurely ends the message's data.
 
|}
 
|}
 +
<small><sup>1</sup>If Lunar Magic's overworld level expansion is applied, $03BE80 will instead be moved dynamically to <code>read3($03BBD9)</code>. Furthermore, it will consist of 24-bit pointers directly to the data rather than 16-bit indices.</small>
  
  
Line 563: Line 601:
 
! Address !! Details
 
! Address !! Details
 
|-
 
|-
! $00C9A7
+
! style="text-align:center; font-family:consolas, monospace" | $00C9A7
 
| Translevel numbers that activate each castle destruction cutscene, starting with Iggy. The last byte, at index 7, corresponds to Front Door.
 
| Translevel numbers that activate each castle destruction cutscene, starting with Iggy. The last byte, at index 7, corresponds to Front Door.
 
|-
 
|-
! $00CA13
+
! style="text-align:center; font-family:consolas, monospace" | $00CA13
 
| Translevel number for Back Door.
 
| Translevel number for Back Door.
 
|-
 
|-
! $04E660
+
! style="text-align:center; font-family:consolas, monospace" | $04E660
 
| Translevel number that causes an earthquake on the overworld after beating (level 18, Sunken Ghost Ship).
 
| Translevel number that causes an earthquake on the overworld after beating (level 18, Sunken Ghost Ship).
 
|-
 
|-
! $00CA0C
+
! style="text-align:center; font-family:consolas, monospace" | $00CA0C
 
| Translevel number where defeating the boss activates the secret exit (level 13, Donut Secret House).
 
| Translevel number where defeating the boss activates the secret exit (level 13, Donut Secret House).
 
|}
 
|}
Line 588: Line 626:
 
! Address !! Details
 
! Address !! Details
 
|-
 
|-
! $00AD2B
+
! style="text-align:center; font-family:consolas, monospace" | $00AD2B
 
| Translevel address (minus 1) that changes the overworld colors.
 
| Translevel address (minus 1) that changes the overworld colors.
 
|-
 
|-
! $02A986
+
! style="text-align:center; font-family:consolas, monospace" | $02A986
 
| Translevel address that changes green/red Koopas into blue/yellow Koopas.
 
| Translevel address that changes green/red Koopas into blue/yellow Koopas.
 
|-
 
|-
! $00AA74
+
! style="text-align:center; font-family:consolas, monospace" | $00AA74
 
| Translevel address that changes sprite graphics for Koopas, Piranha Plants, and Bullet Bills.
 
| Translevel address that changes sprite graphics for Koopas, Piranha Plants, and Bullet Bills.
 
|-
 
|-
! $019826
+
! style="text-align:center; font-family:consolas, monospace" | $019826
 
| Translevel address that prevents shells from displaying Koopa eyes (as part of the changed sprite graphics).
 
| Translevel address that prevents shells from displaying Koopa eyes (as part of the changed sprite graphics).
 
|-
 
|-
! $01B9CD
+
! style="text-align:center; font-family:consolas, monospace" | $01B9CD
 
| Translevel address that changes the climbing net Koopa's animation slightly (as part of the changed sprite graphics).
 
| Translevel address that changes the climbing net Koopa's animation slightly (as part of the changed sprite graphics).
 
|-
 
|-
! $02A986
+
! style="text-align:center; font-family:consolas, monospace" | $02A986
 
| Translevel address that changes the enemy names in the credits (as part of the changed sprite graphics).
 
| Translevel address that changes the enemy names in the credits (as part of the changed sprite graphics).
 
|}
 
|}
Line 614: Line 652:
  
 
The list of level tiles that can be destroyed (i.e. switch palaces, castles, forts) are at $04E5A7. Their 'after' tiles are at $04E5AC (upper tile) and $04E5B1 (lower tile).
 
The list of level tiles that can be destroyed (i.e. switch palaces, castles, forts) are at $04E5A7. Their 'after' tiles are at $04E5AC (upper tile) and $04E5B1 (lower tile).
 +
 +
The list of teleport locations used when losing to an overworld Koopa Kid sprite are at $048E49 (X position) and $048E4F (Y position). The Layer 1 tile that activates the first Koopa Kid is at $04FBA2 (with the other two Koopa Kids being +1 and +2 from the value there).
 +
 +
Lunar Magic contains two flags regarding overriding the overworld in bits 1 and 2 of $0FFFE0. If bit 1 is cleared, the overworld is considered overridden, and will warn the user when attempting to save it. If bit 2 is cleared, the overworld editor will allow the user to edit and save the overworld's text strings (for level names, message box text, and boss sequence text) without saving the entire overworld.
  
 
[[Category:Technical Information]]
 
[[Category:Technical Information]]

Latest revision as of 16:41, 1 October 2024

LM-related information is accurate as of version 2.53.

Position Format

Layer 1 data often uses a format for a tile's position referred to here as "#$0SYX format". This is a format that is composed of the tile's X position mod 16 (X), Y position mod 16 (Y), and submap (S). Submaps are ordered as:

Submap Value
Main Map 0
Yoshi's Island 1
Vanilla Dome 2
Forest of Illusion 3
Valley of Bowser 4
Special World 5
Star World 6

Keep in mind on submaps, the positions are offset from the way they appear in Lunar Magic. On all six submaps, subtract one from the X position (so the left-most column in LM is actaully on the right side). As an example, the position of Yoshi's Island 1 is #$0183 - submap 1, Y position 8, X position 4 (4 - 1 = 3).

Note that this submap offset also affects Layer 2 (subtract 2 from X, 1 from Y) and sprites (subtract #$10 from X, #$08 from Y).

The origin of this format isn't from any kind of index; instead, it's a combination of three addresses related to Mario's position: $1F11, $1F1F, and $1F21. As such, if you get a position from these addresses (or alternatively $1F17/$1F19), you won't have to account for the offset.


Layer 1

Layer 1 data is loaded to $7EC800 during gameplay. In an LM-modified ROM, $7FC800 also contains the high-byte of each tile.

To locate a specific tile there, use an index with the format %-----YYX yyyyxxxx, where YYyyyy is the Y position of the tile and Xxxxx is the X position. On submaps, subtract 1 from the X position.

Address Details LM-Modified Location
$05D000 Tilemap for each individual Layer 1 tile. Four 8x8 tiles per tile, with two bytes per 8x8 (tile number, YXPCCCTT). (read1($04DCC1)<<16)|read2($04DCBC)
$0CF7DF Tilemap for the entire overworld, uncompressed. Loaded to $7EC800 during gameplay. $0CF7DF
N/A High bytes for the Layer 1 tilemap, compressed in LC_LZ21 format. Decompressed to $7FC800. (read1($04D827)<<16)|read2($04D821)

1 Or LC_LZ3 if the ROM uses it.


Layer 1 Events

Layer 1 events directly overwrite data in $7EC800.

Address Details LM-Modified Location
$04D85D Location of the Layer 1 tile that each event reveals (#$0SYX format). read3($04EDBE)
$04D93D VRAM locations to write the data for each event. read3($04EDB8)

Note that only one tile can be revealed per event by these tables. To reveal more, silent events must be used.

The list of what tile reveals what can be found at $04DA1D (before tiles) and $04DA33 (after tiles). These also correspond to Lunar Magic's "reveal tile list".


Layer 2

Layer 2 data is stored in two compressed tables. They're decompressed to $7F4000 in an interleaved [tile number], [YXPCCCTT] format.

To locate a specific tile in the decompressed data, index the data with ((Y * 40) + X) * 2 for an X,Y position. On submaps, subtract 2 from X and 1 from Y.

Address Details LM-Modified Location
$04A533 Layer 2 tile numbers, compressed in LC_RLE1 format. (read1($04DC79)<<16)|read2($04DC72)
$04C02B Layer 2 tile YXPCCCTT, compressed in LC_RLE1 format. (read1($04DC79)<<16)|read2($04DC8D)


Layer 2 Events

Layer 2 events directly overwrite data in $7F4000. $0C8000 and $0C8D00 are decompressed to $7F0000 in an interleaved [tile number][YXPCCCTT] format.

Address Details LM-Modified Location
$04DD8D Table of data for all the events. Four bytes per tile; the first two are the 'source' (index to $0C8000), and the second two are the 'destination' (index to $7F4000). read3($04E49F)
$04E359 Indices to $04DD8D, indexed by event number. The number of tiles in any given event is determined by the difference from the next event's index (i.e. [event + 1] - [event]). $04E3591
$0C8000 Tilemap (tile numbers) for the event tiles, uncompressed. The first x9002 bytes are the 6x6 tiles, while the next x400 are the 2x2. read3($04EAF5)
$0C8D00 Tilemap (YXPCCCTT) for the event tiles, compressed in LC_RLE1. Has the same format as $0C8000 when uncompressed. (read1($04DD4A)<<16)|read2($04DD45)

To convert tile numbers in LM to indices in $0C8000, 6x6 tiles can be found as #$24 * tileNum, while 2x2 tiles can be found as (#$04 * tileNum) + #$0900*.

1 If Lunar Magic's overworld level expansion hijack is applied, this table is instead moved dynamically to read3($04E471).
2 It should be noted that LM has an option to change this amount. To get the size in case it changed, use read2($04E4C0).


Sprites

Sprite data is stored in a table at $04F625 (even in an LM-edited ROM), with 5 bytes per sprite. The first byte is the sprite number, then the 16-bit X position, and then the 16-bit Y position. The submap offset still applies to sprites, as well; subtract #$10 from the X position and #$08 from the Y position when on submaps to account for this.

However, that there is no distinction for positions between the main map and submaps. When loaded into VRAM, only one tilemap is loaded at a time: either the main map, or all the submaps (a demonstration of the overlap can be seen here). So, every sprite position technically refers to two spots: one on the main map, and an equivelent location on the submaps. Because of this, most sprites are coded to only actually appear on one or the other.

Certain sprites, specifically the overworld ghosts and Yoshi's House smoke, do actually exist on both tilemaps simultaneously. Similarly, the fish and Koopa Kid sprites both spawn three sprites despite only taking up one entry in the table. A list of the table locations for these unlisted positions are below:

Address Details
$04FC1E 16-bit X positions for the two smoke sprites; the first is the main map, and the second is Yoshi's Island. This sprite can not be used on other submaps.
$04FC22 16-bit Y positions for the two smoke sprites; the first is the main map, and the second is Yoshi's Island. This sprite can not be used on other submaps.
$04F666 16-bit X offsets for the three submap ghosts from their main map counterparts. #$0001 will move the ghost one pixel right, #$FFFF will move it one pixel left.
$04F66C 16-bit Y offsets for the three submap ghosts from their main map counterparts. #$0001 will move the ghost one pixel down, #$FFFF will move it one pixel up.
$04FA2E Low byte of the X position for the three overworld fish, indexed by the Layer 1 tile that spawns it (4E-50).
$04FA31 High byte of the X position for the three overworld fish, indexed by the Layer 1 tile that spawns it (4E-50).
$04FA34 Low byte of the Y position for the three overworld fish, indexed by the Layer 1 tile that spawns it (4E-50).
$04FA37 High byte of the Y position for the three overworld fish, indexed by the Layer 1 tile that spawns it (4E-50).
$04FB88 Low byte of the X position for the overworld Koopa Kids, indexed by the Layer 1 tile that spawns it (49-4B).
$04FB8B High byte of the X position for the overworld Koopa Kids, indexed by the Layer 1 tile that spawns it (49-4B).
$04FB8E Low byte of the Y position for the overworld Koopa Kids, indexed by the Layer 1 tile that spawns it (49-4B).
$04FB91 High byte of the Y position for the overworld Koopa Kids, indexed by the Layer 1 tile that spawns it (49-4B).

As a sidenote, the main overworld sprite data is only read a single time on titlescreen load, then never again.


As of Lunar Magic v2.50, a second sprite table exclusively made for custom sprites has been added. Unlike the original table, this one does not have a fixed size; you can have up to 24 custom sprites per submap. This table can be found with read3($0EF55D).

The first part of the data is 16-bit indices to each submap's data, in the standard submap order (for a total of 14 bytes). The second part is the actual sprite data. Each sprite has 4 bytes associated with it:

Custom Sprite Data Format
xnnnnnnn yyyXXXXX hhhhhYYY eeeeeeee
nnnnnnn Sprite number
XXXXXx X position (in 8x8s, relative to either 0,0 or 2,41).
YYYyyy Y position (in 8x8s, relative to either 0,0 or 2,41).
hhhhh Height. Determines how "far above the ground" the sprite should appear.
eeeeeeee Extra bits.

Lunar Magic does nothing with this table outside of allowing you to edit it, however, so the data currently serves no purpose until a tool implements it.


Silent Events

"Silent" events are LM's name for a special set of Layer 1 and Layer 2 event data that plays no sound effects or fade effect. Additionally, however, they don't update VRAM, and as such don't appear on-screen until the tile is reloaded. Because of this, they're mainly intended for tiles that are supposed to appear offscreen or in another submap.

The original game and Lunar Magic take two different approaches to this data, however. The original game has a table of the events associated with each offscreen event tile; once the event is found, the index for it is then used as the index to all other related tables. Lunar Magic instead changes this to use a 'divider'-like table of indices for each event, with the difference between one event's index and the next's determining the number of tiles used by it.

Address Details LM-Modified Location
$04E8E4 The original game's indexing system. Contains event numbers associated with an offscreen tile, with the index for the event used as an index to the below tables. One event can have multiple entries. N/A
N/A Lunar Magic's indexing system. Contains 16-bit indices to the below tables; the number of tiles per event is determined by the difference between the current event's index and the next. read3(read3($04E9F8)+$0D)
$04E910 Indicates whether the tile is on Layer 1 (#$00) or Layer 2 (#$01). read3(read3($04E9F8)+$34)
$04E93C 16-bit locations of each tile, as direct indices to the Layer 1 tilemap at $7EC800 or Layer 2 tilemap at $7F4000. read3(read3($04E9F8)+$28)
$04E994 16-bit tile number to use. For Layer 1 tiles, this is just the tile number as normal; for Layer 2, it's the tile's index in $0C8000. read3(read3($04E9F8)+$22)


Hardcoded Paths

Hardcoded paths are special Layer 1 paths that aren't displayed or editable by Lunar Magic. They function by temporarily overwriting the Layer 1 tile Mario is walking on until he eventually reaches a level tile.

Address Details
$049078 Translevel numbers that have hardcoded paths. #$FF indicates Chocolate Island 2's pipe (see $049082/$049084).
$04910E Index table for each of the translevels at $049078 to the hardcoded path data.
$049086 Hardcoded path data. This consists of a list of all the Layer 1 tiles that Mario walks over, ending in a level tile.
$0490CA Directions Mario moves on each of the tiles listed at in the hardcoded path data; the first value also determines the direction of the path from the original level tile. #$00 = up, #$02 = down, #$04 = left, #$06 = right.
$049082 16-bit X position of Chocolate Island 2's pipe, as a sprite position (i.e. Mario's position on it).
$049084 16-bit Y position of Chocolate Island 2's pipe, as a sprite position (i.e. Mario's position on it).


Star Warps and Pipes

Star warps and pipes are combined under a set of tables. The source positions are the location of the warp's Layer 1 tile (00-1F), while the destinations are positions for Mario (in pixels, not tiles).

If a tile's position can't be found in the source tables, the warp/pipe won't function at all. The destinations can be anywhere.

Address Details LM-Modified Location
$048431 Two-byte values containing the source tile X position (first byte) and submap (second byte) for each warp. read3(read3($04850A)+$14)
$048467 Two-byte values containing the source tile Y position (first byte) for each warp. Second byte is unused. read3(read3($04850A)+$24)
$04849D 16-bit destination X position and submap for each warp, in the format %----SSSX xxxxxxxx. read3(read3($048567)+$07)
$0484D3 16-bit destination Y position. read3(read3($048567)+$19)


Exit Paths

Exit path data is spread across two 5-byte tables and a third 2-byte table. Note that positions in this table correspond to Mario's (i.e. sprite) position, not the tile's position.

Address Details LM-Modified Location
$049964 Exit path location table (where Mario enters). Order is the 16-bit Y position, 16-bit X position, and 8-bit submap. read3(read3($049A36)+$11)
$0499AA Exit path destination table (where Mario exits). Order is the 16-bit Y position, 16-bit X position, and 8-bit submap. read3(read3($049A36)+$2C)
$0499F0 Extra exit path destination table (where Mario exits). This contains two bytes per path, for the destination tile's Y and X position respectively.1 read3(read3($049A36)+$48)

1 Generally, this table is just the positions in $0499AA divided by 16. However, if Mario exits moving upwards or leftwards, you should subtract 1 from the Y or X position respectively before dividing.


Destruction Events

Destruction events change castles, fortresses, and switch palace to an alternative tile after being beaten. In order for the destruction animation to occur, Mario must also be on a specified level tile at the time an event is beaten (although reloading the overworld will cause the tile to be destroyed anyway).

Address Details LM-Modified Location
$04E5B6 Locations of the levels with destruction events (#$0SYX format). read3($04E69C)
$04E587 VRAM locations to store the destroyed tiles for each event, written as the first two bytes of its stripe header (%0010YXyy yyyxxxxx). read3($04EEC9)
$04E5D6 List of events that activate a destruction. Only used on overworld load, for reloading previously-destroyed tiles. read3($04E67C)


Level-Specific Data

Each translevel has an assigned event and normal/secret exit directions. In the original game, translevels themselves are not actually stored anywhere in the original ROM, and are instead assigned automatically as level tiles come up in Layer 1 data.

Once assigned, translevels for each Layer 1 tile are written to a table at $7ED000 and exit directions are written to a table at $7FD800. These tables are formatted the same way as the Layer 1 tilemap at $7EC800, so if you have the index to a level tile there, you can get its translevel and exit directions from the other two tables using the same index.

Lunar Magic, of course, changes translevels to be assignable on a tile-by-tile basis. It stores both the translevels and exit directions to a table at (read1($04D808)<<16)|read2($04D803), compressed in the LC_LZ2 format (or LC_LZ3 if the ROM has it enabled). This data decompresses to $7ED000 as normal.

The data tables for the directions and event associated with that translevel, however, remain unmoved:

Address Details
$04D678 Direction to move after beating a level, indexed by translevel. Formatted as %nnss---- for the normal direction nn and secret direction ss. %00 = up, %01 = down, %10 = left, %11 = right.
$05D608 Events triggered by each translevel.

In regards to the direction to move after beating a level, technically SMW parses directions for two additional exits, although they aren't used. The original game formats the directions for these extra exits as %nnssxyz0, with exit 3 using bits xy and exit 4 using bits yz. In Lunar Magic v3.00+, support for these were officially added, with the format being revised to %aabbccdd, using cc and dd for exit 3 and 4 respectively.


Initial Save File Data

A number of details about a level are stored to $1EA2 during gameplay. Some of this data is automatically set once a save file is started, mainly for enabling certain paths between level tiles. The original game and Lunar Magic differ slightly in how this is done, however, as detailed in the table below.

Additionally, $1F11-$1F26 are also preset on file creation, for Mario/Luigi's initial positions.

Address Details
$009EE0 The original game's initial flag table. Each entry consists of two bytes: the first is the translevel to modify, and the second is the flags to set in $1EA2.
$05DDA01 Lunar Magic's initial flag table. Every translevel has a single byte, containing the flags to set in $1EA2.
$009EF0 Initial values for $1F11-$1F26.

1 If Lunar Magic's overworld level expansion is applied, $05DDA0 is moved to $03BE80.


Level Names

SMW uses a complicated name-lookup system, which involves splitting each level's name into three parts, which are then directed to a set of three offset tables. While it saves space, it's not particularly easy to work with.

Address Details
$049AC5 The level string table, indexed by the three offset tables. If the high bit of a byte is set, it indicates the last character in the string.
$049C91 Offset table A. If the first byte pointed to has the high bit set, this part is completely skipped.
$049CCF Offset table B. If the first byte pointed to is #$9F, this part is completely skipped.
$049CED Offset table C.
$04A0FC Assembly table for each level's name. Contains indexes to the offset tables in a 16-bit format: %-aaaaaaa bbbbcccc.

Lunar Magic logically scraps this system entirely, for a single large table at read3($03BB57) containing every level's name (19 bytes per name).


GFX Files

SMW uses a system similar to the one use in levels, where it uses a table of lists containing the four GFX files for each submap.

However, it has all the maps use the same files, making it somewhat redundant. SMW doesn't normally reload GFX files when loading a new submap either (only on level exit), so having different files would likely cause broken graphics.

Address Details
$04DC02 Layer 1/2 GFX lists for each submap, for $00A92B.
$00A92B Layer 1/2 GFX files (FG1-FG4) for each list. Overworld files specifically begin at $00A96F (lists 11-17).
$04A907 Sprite GFX files (SP1-SP4) for the whole overworld.

Lunar Magic changes this to a single table containing all sixteen 16-bit ExGFX files for each submap, for 32 bytes total per submap. This table can be found at (read1($0FFAC2)<<16)|read2($0FFAB9). The exact order of ExGFX files may vary, though, depending on whether the user has enabled Lunar Magic's option to merge the FG1/FG2 slots with SP3/SP4, which enables the usage of the FG5 and FG6 slots:

Merge disabled AN2 LT3 (FG6) (FG5) FG4 FG3 FG2 FG1 SP4 SP3 SP2 SP1 LG4 LG3 LG2 LG1
Merge enabled AN2 LT3 --- --- FG6 FG5 FG4 FG3 FG2 FG1 SP2 SP1 LG4 LG3 LG2 LG1

While the values of the FG5/FG6 slots are retained in the third and fourth slots when the merge option is disabled, they are not actually used. Those two slots meanwhile go unused when the merge option actually is enabled.

Addionally, AN2 and LT3 contain some extra information in their high bytes:

Format
AN2 ?3T?----
LT3 DDSS----
3 Enable Layer 3 Bypass
T Enable Layer 3 Tilemap Bypass
DD Layer 3 destination for file
SS Layer 3 file size
?? Unused?


Palettes

SMW stores the overworld palettes in a somewhat complicated way by assembling it in parts from a large palette table.

Colors themselves are stored in the standard 16-bit SNES RGB format (-BBBBBGG GGGRRRRR).

Address Details
$00AD1E Table of Layer 2 palette IDs for each submap, as values for indexing to $00ABDF.
$00ABDF 16-bit pointers to the palette table for each Layer 2 palette ID, starting at $00B3D8 (normal) or $00B732 (Special World passed).
$00B3D8 All the Layer 2 palette data (palettes 4-7, colors 1-7). Default order is Yoshi, main, Star, Vanilla/Bowser, Forest, Special.
$00B732 All the Layer 2 palette data (palettes 4-7, colors 1-7) after the Special World is beaten. Default order is Yoshi, main, Star, Vanilla/Bowser, Forest, Special.
$00B528 Layer 1 palette data (palettes 2-7, colors 9-F).
$00B58A Sprite palette data (palettes 9-F, colors 1-7). Note that palette F is also used for animating the lightning effect.
$00B5EC Layer 3 palette data (palettes 0-1, colors 8-F).

Lunar Magic scraps this system in favor of a single table instead. This table contains all 14 512-byte palettes for the maps (7 normal, 7 special), and can be found at (read1(read3($00AD33)+$1E)<<16)|read2(read3($00AD33)+$12).


ExAnimation Data

ExAnimation data is stored in two parts, the first being the general animation information and the second being the individual animation information.

General Animation Format
SS EE cc CC ii II mm MM FF... dd DD...
SS Highest used animation slot, plus 1
EE Which alternate GFX file the submap uses
CCcc Which custom triggers start uninitialized, bitwise
IIii Initial states for each custom trigger, when initialized
MMmm Which manual triggers are initialized, bitwise
FF... Frame numbers to initialize each of the specified manual triggers to
DDdd... Indices to each animation slot's data1 (with #$0002 referring to the byte after this value)

1 Indices are included up to the highest used slot. If a slot before that isn't used, its indice is 0000.

Individual Animation Format
AA TT FF dd DD mm MM...
AA Animation type
TT Trigger
FF Number of frames (-1)
DDdd Tiles only: VRAM destination*
DD Colors only: number of colors to animate (-1)1
dd Colors only: palette destination
MMmm... Memory address for each frame's tile/color data, or direct SNES RGB values when animating a single color

1 The highest bit being 1 indicates the slot uses the sumbap's alternative GFX file.

Global ExAnimation data can be found with (read1(read3($048087)+$58)<<16)|read2(read3($048087)+$61). If read2(read3($048087)+$61) returns #$0000, the ROM has no global ExAnimation data.

The 24-bit pointers to each submap's ExAnimation data can be found with read3(read3($048087)+$E1). If the second byte of the pointer is #$00, then that level doesn't have animation data.


Additionally, there's a 512-byte table at read3(read3($048087)+$4A) that stores each submap's animation settings.

Format
PTSG----
P Disable original game's level dot palette animation
T Disable original game's tile animations
S Disable LM's submap animations
G Disable LM's global animations
---- Currently unused

The fifth option in the animation settings, for disabling the original game's lightning palette animation, is a bitwise value at $04F709. With 1 indicating disable:

Format
myvfbSs-
m Main map
y Yoshi's Island
v Vanilla Dome
f Forest of Illusion
b Valley of Bowser
S Special World
s Star World
- Unused


Message Box Text

The original game handles message box by searching a table of levels that actually use them.

Address Details
$05A590 Which translevels have message boxes. The high bit being set indicates message 2. The first 4 bytes are reserved for switch palaces, and the last (index x16) for Yoshi's House. If a message's level isn't found, index 0 is used by default.
$05A5A7 Indices to the start of each message's text at $05A5D9.
$05A5D9 All of the message box texts (tile numbers only). The high bit being set indicates a new line, and the 8th new line indicates the end of the message.

Lunar Magic exchanges this system for a new one that skips the translevel table.

Address Details
$03BE801 16-bit indices to the data for each message. Indexed by ((translevel * 2) + message number) * 2.
read3($03BC0B) The actual message data. For the most part, just raw tile numbers with 18 tiles per line, with the message ending after 8 lines. However, #$FE is used as a special value that prematurely ends the message's data.

1If Lunar Magic's overworld level expansion is applied, $03BE80 will instead be moved dynamically to read3($03BBD9). Furthermore, it will consist of 24-bit pointers directly to the data rather than 16-bit indices.


Castle Destruction Text

Castle destruction text is handled by SMW's general stripe image upload routine, with its data pointed to by the list at $0084D0 (indices #$21-#$C6). Each line of the message texts has its own pointer there, although the lines for each message are in reverse (i.e. the first pointer is line 8, second is line 7, etc.). The messages themselves are in the correct order, though. Lunar Magic dynamically moves them, though, so you should check the pointer rather than the data as a whole.

$0CBE85 (or wherever Lunar Magic moves it) is where the text data actually begins. This data are written in the standard stripe image format, including the full 4-byte header.


Boss Sequence Levels

Lunar Magic's 'boss sequence levels' list refers to levels that activate special events or scenes after the level's end. These aren't located in a single location, however, and instead are at several locations:

Address Details
$00C9A7 Translevel numbers that activate each castle destruction cutscene, starting with Iggy. The last byte, at index 7, corresponds to Front Door.
$00CA13 Translevel number for Back Door.
$04E660 Translevel number that causes an earthquake on the overworld after beating (level 18, Sunken Ghost Ship).
$00CA0C Translevel number where defeating the boss activates the secret exit (level 13, Donut Secret House).


Music

The music for each submap is stored in a 7-byte table at $048D8A.

There's also a table at $048D74 that's worth noting. It contains the translevels (in 16-bit) that prevent the overworld music from loading after beating their boss, causing the overworld to be silent outside of sound effects.


Special World Changes

Lunar Magic's "Special World levels" list corresponds to a few different locations. Rather than actually being stored as a level number, the values at these locations are actually addresses, specically the address in $1EA2 that corresponds to the level (i.e. $1EA2 + the translevel number).

Address Details
$00AD2B Translevel address (minus 1) that changes the overworld colors.
$02A986 Translevel address that changes green/red Koopas into blue/yellow Koopas.
$00AA74 Translevel address that changes sprite graphics for Koopas, Piranha Plants, and Bullet Bills.
$019826 Translevel address that prevents shells from displaying Koopa eyes (as part of the changed sprite graphics).
$01B9CD Translevel address that changes the climbing net Koopa's animation slightly (as part of the changed sprite graphics).
$02A986 Translevel address that changes the enemy names in the credits (as part of the changed sprite graphics).


Miscellaneous

The list of no-auto-move levels are at $04906C, as translevels in 16-bit.

The list of level tiles that automatically activate save prompts after beating are at $048F7F.

The list of level tiles that can be destroyed (i.e. switch palaces, castles, forts) are at $04E5A7. Their 'after' tiles are at $04E5AC (upper tile) and $04E5B1 (lower tile).

The list of teleport locations used when losing to an overworld Koopa Kid sprite are at $048E49 (X position) and $048E4F (Y position). The Layer 1 tile that activates the first Koopa Kid is at $04FBA2 (with the other two Koopa Kids being +1 and +2 from the value there).

Lunar Magic contains two flags regarding overriding the overworld in bits 1 and 2 of $0FFFE0. If bit 1 is cleared, the overworld is considered overridden, and will warn the user when attempting to save it. If bit 2 is cleared, the overworld editor will allow the user to edit and save the overworld's text strings (for level names, message box text, and boss sequence text) without saving the entire overworld.