Difference between revisions of "Level Data Format"

From Super Mario World Speedrunning Wiki
Jump to: navigation, search
m (Sprite Data format table correction)
m (Updating version)
 
(95 intermediate revisions by 2 users not shown)
Line 1: Line 1:
 +
LM-related information should be accurate as of version 3.50.
 +
 
== Pointer Tables ==
 
== Pointer Tables ==
 
{| class="wikitable"
 
{| class="wikitable"
Line 5: Line 7:
 
| '''$05E000''' || Layer 1 data || 0x200 levels, 3 bytes each (1,536 bytes)
 
| '''$05E000''' || Layer 1 data || 0x200 levels, 3 bytes each (1,536 bytes)
 
|-
 
|-
| '''$05E600''' || Layer 2 data || 0x200 levels, 3* bytes each (1,536 bytes)
+
| '''$05E600''' || Layer 2 data || 0x200 levels, 3 bytes<sup>1</sup> each (1,536 bytes)
 
|-
 
|-
| '''$05EC00''' || Sprite data || 0x200 levels, 2** bytes each (1,024 bytes)
+
| '''$05EC00''' || Sprite data || 0x200 levels, 2 bytes<sup>2</sup> each (1,024 bytes)
 
|}
 
|}
<nowiki />* If the long byte of the Layer 2 data is #$FF, it will get replaced by #$0C and the data will be interpreted as a BG tilemap rather than object data.<br />
+
<small><sup>1</sup> In the original SMW, if the long byte of the Layer 2 pointer is 0xFF, it will be replaced by 0x0C and the data will be interpreted as a BG tilemap rather than object data. Lunar Magic changes this so full 24-bit addresses are used either way; see the section on [[#Background Data|background data]] for more details.<br />
<nowiki />** All sprite data is located in bank 07.
+
<sup>2</sup> In the original SMW, all sprite data is in bank 7. Lunar Magic adds a 512-byte table for the bank byte at $0EF100.</small>
  
  
Line 17: Line 19:
 
{| class="wikitable"
 
{| class="wikitable"
 
! colspan="5" | Format
 
! colspan="5" | Format
|-  
+
|- style="font-family:consolas, monospace"
 
| BBBLLLLL || CCCOOOOO || 3MMMSSSS || TTPPPFFF || IIVVZZZZ
 
| BBBLLLLL || CCCOOOOO || 3MMMSSSS || TTPPPFFF || IIVVZZZZ
 
|}
 
|}
{| class="wikitable"
+
{| class="wikitable" style="font-family:consolas, monospace"
 
| BBB  || BG palette
 
| BBB  || BG palette
 
|-
 
|-
Line 50: Line 52:
  
 
== Secondary Level Header ==
 
== Secondary Level Header ==
The secondary level header consists of four bytes, spread across four seperate tables with one byte per level.
+
The secondary level header consists of four bytes, spread across four seperate tables with one byte per level. Lunar Magic adds a fifth byte at $05DE00 as well, and from v3.00 onwards adds two more at $06FC00 and $06FE00 respectively. Yet another byte was added in v3.40 onwards at $06FA00.
 
{| class="wikitable"
 
{| class="wikitable"
! colspan="4" | Format
+
! colspan="9" | Format
|-  
+
|- style="font-family:consolas, monospace"
! $05F000 !! $05F200 !! $05F400 !! $05F600
+
! LM version
 +
! $05F000 !! $05F200 !! $05F400 !! $05F600 !! $05DE00<sup>1</sup> !! $06FA00<sup>1</sup> !! $06FC00<sup>1</sup> !! $06FE00<sup>1</sup>
 +
|- style="font-family:consolas, monospace"
 +
! < 3.00
 +
| hhhhyyyy || 33AAAxxx || MMMMffbb || NUVEEEEE || IWPYX---
 +
|- style="font-family:consolas, monospace"
 +
! 3.00-3.33
 +
| hhhhyyyy || 33AAAxxx || MMMMffbb || NUVEEEEE || IWPXXtTT || || OFYYYYYY || RL-ooooo
 +
|- style="font-family:consolas, monospace"
 +
! 3.40+
 +
| hhhhyyyy || 33AAAxxx || MMMMffbb || NUVEEEEE || IWPXXtTT || SHCvvvvv || OFYYYYYY || RL-ooooo
 +
|}
 +
{| class="wikitable" style="font-family:consolas, monospace"
 +
| (H)hhhh      || Layer 2 scroll setting, or specifically the Layer 2 horizontal scroll setting if the S bit is set
 +
|-
 +
| (YYYYYY)yyyy || Main entrance Y position<sup>2</sup>
 +
|-
 +
| 33          || Layer 3 setting
 +
|-
 +
| AAA          || Main entrance Mario action
 +
|-
 +
| (XX)xxx      || Main entrance X position<sup>2</sup>
 +
|-
 +
| MMMM        || Midway entrance screen number
 +
|-
 +
| ff          || Main entrance FG initial position, if R bit is clear
 +
|-
 +
| bb          || Main entrance BG initial position, if R bit is clear
 +
|-
 +
| Fffbb        || Main entrance FG/BG offset, if R bit is set
 +
|-
 +
| N            || Disable No-Yoshi Intro flag
 +
|-
 +
| U            || Unknown/unused vertical position flag
 +
|-
 +
| V            || Vertical positioning flag
 +
|-
 +
| EEEEE        || Main entrance screen number
 +
|-
 +
| I            || Slippery flag<sup>1</sup>
 +
|-
 +
| W            || Water flag<sup>1</sup>
 +
|-
 +
| P            || Flag to use X/Y position method 2<sup>1</sup>
 +
|-
 +
| t            || Smart spawn flag<sup>1</sup>
 +
|-
 +
| TT          || Sprite spawn range<sup>1</sup>
 +
|-
 +
| S            || Flag to use separate settings for the Layer 2 horizontal/vertical scroll rates.<sup>1</sup>
 +
|-
 +
| C            || Flag to auto-set the number of screens in the level<sup>1</sup>
 +
|-
 +
| vvvvv        || Layer 2 vertical scroll setting, if S bit is set<sup>1</sup>
 +
|-
 +
| O            || Flag to set BG relative to FG<sup>1</sup>
 +
|-
 +
| R            || Flag to set main entrance FG/BG setting relative to player<sup>1</sup>
 +
|-
 +
| L            || Flag to face the main entrance left<sup>1</sup>
 +
|-
 +
| ooooo        || BG height (-1), or relative BG offset if O bit is set (absolute 0 = 0x10)<sup>1</sup>
 +
|}
 +
Prior to v3.00 of Lunar Magic, the X and Y position values are swapped in vertical levels. In 3.00 onward, they are not.
 +
 
 +
<small><sup>1</sup> Added by Lunar Magic; not used in the original game.<br />
 +
<sup>2</sup> The capitalized Y and X bits are added by Lunar Magic when using X/Y position method 2, but are unused in the original game. Note that versions of Lunar Magic prior to v3.00 only provide one extra bit each.</small>
 +
 
 +
Additionally, there is an ninth table added in Lunar Magic v3.00, which can be found at <code>read3(read3($05D9A2)+70)</code>, and is used for supporting the expanded level format system. It has the following format:
 +
{| class="wikitable"
 +
! colspan="5" | Format
 +
|- style="font-family:consolas, monospace"
 +
| TB0MMMMM
 +
|}
 +
{| class="wikitable" style="font-family:consolas, monospace"
 +
| T            || Indicates the level uses either Layer 2 or Layer 3
 +
|-
 +
| B            || Flag to show the bottom row of the level
 +
|-
 +
| 0            || Should always be set to 0. Currently reserved for bit 5 of the sprite header when loaded in RAM.
 
|-
 
|-
| SSSSYYYY || 33AAAXXX || MMMMFFBB || IUVEEEEE
+
| MMMMM        || Horizontal level mode
 
|}
 
|}
 +
 +
 +
 +
==== Midway Entrances ====
 +
Lunar Magic also adds similar data for midway entrances when they're set to have seperate settings. This data is stored in a dynamically-located set of tables, however; they can all be found in order at <code>read3(read3($05D9E4)+$0A)</code>.
 
{| class="wikitable"
 
{| class="wikitable"
| SSSS  || Layer 2 scroll setting
+
! colspan="5" | Format
 +
|- style="font-family:consolas, monospace"
 +
! LM version
 +
! Table 1 !! Table 2 !! Table 3 || Table 4
 +
|- style="font-family:consolas, monospace"
 +
! < 3.00
 +
| IWIMYAAA || yyyyxxxx || ----ffbb
 +
|- style="font-family:consolas, monospace"
 +
! 3.00+
 +
| IWHMXAAA || yyyyxxxx || RLE-ffbb || -F<u>YYYYYY</u>
 +
|}
 +
{| class="wikitable" style="font-family:consolas, monospace"
 +
| I          || Slippery flag
 +
|-
 +
| W          || Water flag
 
|-
 
|-
| YYYY  || Level entrance Y position
+
| H          || Flag to use seperate midway entrance (if clear, all remaining bits of these settings except the M bit are ignored)
 
|-
 
|-
| 33    || Layer 3 setting
+
| M          || Bit 4 of midway screen number. Bits 0-3 come from secondary header.
 
|-
 
|-
| AAA  || Level entrance Mario action
+
| YYYYYYyyyy || Midway entrance Y position
 
|-
 
|-
| XXX  || Level entrance X position
+
| AAA        || Midway entrance Mario action
 
|-
 
|-
| MMMM  || Midway entrance screen number
+
| Xxxxx      || Midway entrance X position (bit 4 is effectively ignored in horizontal levels, only used in vertical ones)
 
|-
 
|-
| FF    || FG initial position
+
| R          || Set main entrance FG/BG setting relative to player<sup>1</sup>
 
|-
 
|-
| BB    || BG initial position
+
| ff        || Midway FG initial position, if R bit is clear
 
|-
 
|-
| I    || Disable No-Yoshi Intro flag
+
| bb        || Midway BG initial position, if R bit is clear
 
|-
 
|-
| U    || Unknown/unused vertical position flag
+
| Fffbb      || Main entrance FG/BG offset, if R bit is set
 
|-
 
|-
| V    || Vertical positioning flag
+
| L          || Face entrance left
 
|-
 
|-
| EEEEE || Level entrance screen number
+
| E          || Redirect midway entrance to other level; see below.
 
|}
 
|}
 +
Prior to v3.00 of Lunar Magic, the X and Y position values are swapped in vertical levels. In 3.00 onward, they are not.
 +
 +
If the E bit is set, table 2 instead serves as bits 0-7 of the destination level, and bit 0 of table 3 serves as bit 8.
  
  
 
== Sprite Header ==
 
== Sprite Header ==
 
The first byte of sprite data is the sprite header, which handles some miscellaneous sprite-related information.
 
The first byte of sprite data is the sprite header, which handles some miscellaneous sprite-related information.
 +
 +
The "new sprite system flag" indicates that the sprite data uses the FF byte for specifying additional options, rather than acting as a null terminator. More information can be found in the section on [[#Sprite Data|the actual data]].
 
{| class="wikitable"
 
{| class="wikitable"
 
! Format
 
! Format
|-
+
|- style="font-family:consolas, monospace"
| SBMMMMMM
+
| SBNMMMMM
 
|}
 
|}
{| class="wikitable"
+
{| class="wikitable" style="font-family:consolas, monospace"
| S      || Sprite buoyancy
+
| S      || Sprite buoyancy<sup>1</sup>
 
|-
 
|-
 
| B      || Sprite buoyancy (disable sprite-Layer 2 interaction)
 
| B      || Sprite buoyancy (disable sprite-Layer 2 interaction)
 
|-
 
|-
| MMMMMM || Sprite memory*
+
| N      || New sprite system flag<sup>2</sup>
 +
|-
 +
| MMMMM || Sprite memory<sup>3</sup>
 
|}
 
|}
<nowiki />* Although values up to #$3F are possible, only up to #$12 are actually intended for use.
+
<small>
 
+
<sup>1</sup> Sprite buoyancy is a pair of flags that controls how sprites interact with water or lava. It is required for some sprites to behave correctly. Enabling this can cause lag if too many sprites are onscreen at once. Disabling Layer 2 interaction can mitigate this lag.<br/>
 +
<sup>2</sup> Added in Lunar Magic v3.00. Part of the sprite memory setting in the original game and older versions.<br/>
 +
<sup>3</sup> Although values up to #$1F (or #$3F in the original game) are possible, only up to #$12 are actually intended for use.
 +
</small>
  
 
== Object Data ==
 
== Object Data ==
Line 106: Line 216:
  
 
The data consists of a [[#Primary Level Header|five byte header]], followed by a list of all the objects. If the first byte of an object is #$FF, it indicates the end of the data has been reached.
 
The data consists of a [[#Primary Level Header|five byte header]], followed by a list of all the objects. If the first byte of an object is #$FF, it indicates the end of the data has been reached.
 +
 +
The "new screen" flag described in most of the below formats increases the high X position of it and all following objects by one. In order to decrease it or increase it by a larger amount, a [[#Screen Jump|screen jump]] must be used.
  
  
Line 112: Line 224:
 
{| class="wikitable"
 
{| class="wikitable"
 
! colspan="3" | Format
 
! colspan="3" | Format
|-  
+
|- style="font-family:consolas, monospace"
 
| NBBYYYYY || bbbbXXXX || SSSSSSSS
 
| NBBYYYYY || bbbbXXXX || SSSSSSSS
 
|}
 
|}
{| class="wikitable"
+
{| class="wikitable" style="font-family:consolas, monospace"
 
| N        || New Screen flag
 
| N        || New Screen flag
 
|-
 
|-
| BBbbbb  || Object number
+
| BBbbbb  || Standard object number
 
|-
 
|-
 
| YYYYY    || Y position
 
| YYYYY    || Y position
Line 126: Line 238:
 
| SSSSSSSS || Settings
 
| SSSSSSSS || Settings
 
|}
 
|}
The "new screen" flag increases the object high X position by one. In order to increase it by a larger amount, a [[#Screen Jump|screen jump]] must be used.<br />
 
 
In vertical levels, the X and Y position values are swapped.
 
In vertical levels, the X and Y position values are swapped.
 +
{| class="wikitable mw-collapsible mw-collapsed" style="text-align:center"
 +
! colspan="4" style="width:25em" | Standard Object List
 +
|-
 +
! ID !! Object name              !! colspan="2" | Settings byte usage
 +
|-
 +
| 00 || (Extended Objects)      || colspan="2" | Extended object ID
 +
|-
 +
| 01 || Water (Blue)            || Height            || Width
 +
|-
 +
| 02 || Invisible coin blocks    || Height            || Width
 +
|-
 +
| 03 || Invisible note blocks    || Height            || Width
 +
|-
 +
| 04 || Invisible POW coins      || Height            || Width
 +
|-
 +
| 05 || Coins                    || Height            || Width
 +
|-
 +
| 06 || Walk-through dirt        || Height            || Width
 +
|-
 +
| 07 || Water (Other color)      || Height            || Width
 +
|-
 +
| 08 || Note blocks              || Height            || Width
 +
|-
 +
| 09 || Turn blocks              || Height            || Width
 +
|-
 +
| 0A || Coin ? blocks            || Height            || Width
 +
|-
 +
| 0B || Throw blocks            || Height            || Width
 +
|-
 +
| 0C || Black piranha plants    || Height            || Width
 +
|-
 +
| 0D || Cement blocks            || Height            || Width
 +
|-
 +
| 0E || Brown blocks            || Height            || Width
 +
|-
 +
| 0F || Vertical pipes          || Height            || Type
 +
|-
 +
| 10 || Horizontal pipes        || Type              || Width
 +
|-
 +
| 11 || Bullet shooter          || Height            || Unused
 +
|-
 +
| 12 || Slopes                  || Height            || Type
 +
|-
 +
| 13 || Ledge edges              || Height            || Type
 +
|-
 +
| 14 || Ground ledge            || Height            || Width
 +
|-
 +
| 15 || Midway/Goal point        || Height            || Type
 +
|-
 +
| 16 || Blue coins              || Height            || Width
 +
|-
 +
| 17 || Rope/Clouds              || Type              || Width
 +
|-
 +
| 18 || Water surface (ani)      || Height            || Width
 +
|-
 +
| 19 || Water surface (not ani)  || Height            || Width
 +
|-
 +
| 1A || Lava surface (ani)      || Height            || Width
 +
|-
 +
| 1B || Net top edge            || Height            || Width
 +
|-
 +
| 1C || Donut bridge            || Unused            || Width
 +
|-
 +
| 1D || Net bottom edge          || Height            || Width
 +
|-
 +
| 1E || Net vertical edge        || Height            || Type
 +
|-
 +
| 1F || Vert. Pipe/Bone/Log      || Height            || Unused
 +
|-
 +
| 20 || Horiz. Pipe/Bone/Log    || Unused            || Width
 +
|-
 +
| 21 || Long ground ledge        || colspan="2" | Width
 +
|-
 +
| 22 || LM - Direct Map16 page 0 || colspan="2" | Special handling
 +
|-
 +
| 23 || LM - Direct Map16 page 1 || colspan="2" | Special handling
 +
|-
 +
| 24 || LM - Old FG/BG/SP bypass || colspan="2" | Special handling
 +
|-
 +
| 25 || LM - Old AN2 bypass      || colspan="2" | Special handling
 +
|-
 +
| 26 || LM - Music bypass        || colspan="2" | Special handling
 +
|-
 +
| 27 || LM - Direct Map16 object || colspan="2" | Special handling
 +
|-
 +
| 28 || LM - Time limit bypass  || colspan="2" | Special handling
 +
|-
 +
| 29 || LM - Reserved            || colspan="2" | N/A
 +
|-
 +
| 2A || LM - Reserved            || colspan="2" | N/A
 +
|-
 +
| 2B || LM - Reserved            || colspan="2" | N/A
 +
|-
 +
| 2C || LM - Reserved            || colspan="2" | N/A
 +
|-
 +
| 2D || LM - Reserved            || colspan="2" | N/A
 +
|-
 +
| 2E || Tileset Specific 1      || colspan="2" | Various
 +
|-
 +
| 2F || Tileset Specific 2      || colspan="2" | Various
 +
|-
 +
| 30 || Tileset Specific 3      || colspan="2" | Various
 +
|-
 +
| 31 || Tileset Specific 4      || colspan="2" | Various
 +
|-
 +
| 32 || Tileset Specific 5      || colspan="2" | Various
 +
|-
 +
| 33 || Tileset Specific 6      || colspan="2" | Various
 +
|-
 +
| 34 || Tileset Specific 7      || colspan="2" | Various
 +
|-
 +
| 35 || Tileset Specific 8      || colspan="2" | Various
 +
|-
 +
| 36 || Tileset Specific 9      || colspan="2" | Various
 +
|-
 +
| 37 || Tileset Specific 10      || colspan="2" | Various
 +
|-
 +
| 38 || Tileset Specific 11      || colspan="2" | Various
 +
|-
 +
| 39 || Tileset Specific 12      || colspan="2" | Various
 +
|-
 +
| 3A || Tileset Specific 13      || colspan="2" | Various
 +
|-
 +
| 3B || Tileset Specific 14      || colspan="2" | Various
 +
|-
 +
| 3C || Tileset Specific 15      || colspan="2" | Various
 +
|-
 +
| 3D || Tileset Specific 16      || colspan="2" | Various
 +
|-
 +
| 3E || Tileset Specific 17      || colspan="2" | Various
 +
|-
 +
| 3F || Tileset Specific 18      || colspan="2" | Various
 +
|}
 +
The above list shows the usage of the settings byte for each standard object; when an object has two columns for the usage, the right column is the lower nibble while the left is the higher nibble (i.e. #$HW for most objects). The usage can also be seen in Lunar Magic's object window, next to the object ID, though LM displays them in reverse order.
  
  
Line 134: Line 379:
 
{| class="wikitable"
 
{| class="wikitable"
 
! colspan="3" | Format
 
! colspan="3" | Format
|-  
+
|- style="font-family:consolas, monospace"
 
| N00YYYYY || 0000XXXX || BBBBBBBB
 
| N00YYYYY || 0000XXXX || BBBBBBBB
 
|}
 
|}
{| class="wikitable"
+
{| class="wikitable" style="font-family:consolas, monospace"
 
| N        || New Screen flag
 
| N        || New Screen flag
 
|-
 
|-
Line 146: Line 391:
 
| BBBBBBBB || Extended object number
 
| BBBBBBBB || Extended object number
 
|}
 
|}
The "new screen" flag increases the object high X position by one. In order to increase it by a larger amount, a [[#Screen Jump|screen jump]] must be used.<br />
 
 
In vertical levels, the X and Y position values are swapped.
 
In vertical levels, the X and Y position values are swapped.
 +
{| class="wikitable mw-collapsible mw-collapsed"
 +
! colspan="2" style="width:25em" | Extended Object List
 +
|-
 +
! ID    !! Object name
 +
|-
 +
| 00    || Special - Screen Exit
 +
|-
 +
| 01    || Special - Screen Jump
 +
|-
 +
| 02    || Special - 15-bit Screen Exit
 +
|-
 +
| 03    || Special - Alternative Screen Jump
 +
|-
 +
| 04-0F || Unused
 +
|-
 +
| 10    || Small door
 +
|-
 +
| 11    || Invisible ? block (1-UP)
 +
|-
 +
| 12    || Invisible note block
 +
|-
 +
| 13    || Top left corner edge tile 1
 +
|-
 +
| 14    || Top right corner edge tile 1
 +
|-
 +
| 15    || Small POW door
 +
|-
 +
| 16    || Invisible POW ? block
 +
|-
 +
| 17    || Green star block
 +
|-
 +
| 18    || 3-UP moon
 +
|-
 +
| 19    || Invisible 1-UP #1
 +
|-
 +
| 1A    || Invisible 1-UP #2
 +
|-
 +
| 1B    || Invisible 1-UP #3
 +
|-
 +
| 1C    || Invisible 1-UP #4
 +
|-
 +
| 1D    || Red berry
 +
|-
 +
| 1E    || Pink berry
 +
|-
 +
| 1F    || Green berry
 +
|-
 +
| 20    || Always turning block
 +
|-
 +
| 21    || Bottom right of midway point (unused)
 +
|-
 +
| 22    || Bottom right of midway point (unused)
 +
|-
 +
| 23    || Note block (flower/feather/star)
 +
|-
 +
| 24    || ON/OFF block
 +
|-
 +
| 25    || Direction coins ? block
 +
|-
 +
| 26    || Note block
 +
|-
 +
| 27    || Note block, bounce on all sides
 +
|-
 +
| 28    || Turn block (Flower)
 +
|-
 +
| 29    || Turn block (Feather)
 +
|-
 +
| 2A    || Turn block (Star)
 +
|-
 +
| 2B    || Turn block (Star 2/1-UP/Vine)
 +
|-
 +
| 2C    || Turn block (Multiple coins)
 +
|-
 +
| 2D    || Turn block (Coin)
 +
|-
 +
| 2E    || Turn block (Nothing)
 +
|-
 +
| 2F    || Turn block (POW)
 +
|-
 +
| 30    || ? block (Flower)
 +
|-
 +
| 31    || ? block (Feather)
 +
|-
 +
| 32    || ? block (Star)
 +
|-
 +
| 33    || ? block (Star 2)
 +
|-
 +
| 34    || ? block (Multiple coins)
 +
|-
 +
| 35    || ? block (Key/Wings/Balloon/Shell)
 +
|-
 +
| 36    || ? block (Yoshi)
 +
|-
 +
| 37    || ? block (Shell)
 +
|-
 +
| 38    || ? block (Shell)
 +
|-
 +
| 39    || Turn block, unbreakable (Feather)
 +
|-
 +
| 3A    || Top left corner edge tile 2
 +
|-
 +
| 3B    || Top right corner edge tile 2
 +
|-
 +
| 3C    || Top left corner edge tile 3
 +
|-
 +
| 3D    || Top right corner edge tile 3
 +
|-
 +
| 3E    || Top left corner edge tile 4
 +
|-
 +
| 3F    || Top right corner edge tile 4
 +
|-
 +
| 40    || Transculent block
 +
|-
 +
| 41    || Yoshi Coin
 +
|-
 +
| 42    || Top left slope
 +
|-
 +
| 43    || Top right slope
 +
|-
 +
| 44    || Purple triangle, left
 +
|-
 +
| 45    || Purple triangle, right
 +
|-
 +
| 46    || Midway point rope
 +
|-
 +
| 47    || Door
 +
|-
 +
| 48    || Invisible POW door
 +
|-
 +
| 49    || Ghost house exit
 +
|-
 +
| 4A    || Climbing net door
 +
|-
 +
| 4B    || Conveyor end tile 1
 +
|-
 +
| 4C    || Conveyor end tile 2
 +
|-
 +
| 4D    || Line guide, top left 1/4 large circle
 +
|-
 +
| 4E    || Line guide, top right 1/4 large circle
 +
|-
 +
| 4F    || Line guide, bottom left 1/4 large circle
 +
|-
 +
| 50    || Line guide, bottom right 1/4 large circle
 +
|-
 +
| 51    || Line guide, top left 1/4 small circle
 +
|-
 +
| 52    || Line guide, top right 1/4 small circle
 +
|-
 +
| 53    || Line guide, bottom left 1/4 small circle
 +
|-
 +
| 54    || Line guide, bottom right 1/4 small circle
 +
|-
 +
| 55    || Line guide end, for horizontal line
 +
|-
 +
| 56    || Line guide end, for vertical line
 +
|-
 +
| 57    || Switch palace bottom right corner tile
 +
|-
 +
| 58    || Switch palace bottom left corner tile
 +
|-
 +
| 59    || Switch palace top right corner tile
 +
|-
 +
| 5A    || Switch palace top left corner tile
 +
|-
 +
| 5B    || Bit of brick background tile 1
 +
|-
 +
| 5C    || Bit of brick background tile 2
 +
|-
 +
| 5D    || Bit of brick background tile 3
 +
|-
 +
| 5E    || Bit of brick background tile 4
 +
|-
 +
| 5F    || Large background area
 +
|-
 +
| 60    || Lava/mud top right corner edge
 +
|-
 +
| 61    || Ghost house clock
 +
|-
 +
| 62    || Ghost house top left to bottom right beam 1
 +
|-
 +
| 63    || Ghost house top right to bottom left beam 1
 +
|-
 +
| 64    || Ghost house cobweb, top right
 +
|-
 +
| 65    || Ghost house cobweb, top left
 +
|-
 +
| 66    || Ghost house top right to bottom left beam 2
 +
|-
 +
| 67    || Ghost house top left to bottom right beam 2
 +
|-
 +
| 68    || Cloud fringe, bottom and right edge
 +
|-
 +
| 69    || Cloud fringe, bottom and left edge
 +
|-
 +
| 6A    || Cloud fringe, bottom right
 +
|-
 +
| 6B    || Cloud fringe, bottom left
 +
|-
 +
| 6C    || Cloud fringe on white, bottom and right edge
 +
|-
 +
| 6D    || Cloud fringe on white, bottom and left edge
 +
|-
 +
| 6E    || Cloud fringe on white, bottom right
 +
|-
 +
| 6F    || Cloud fringe on white, bottom left
 +
|-
 +
| 70    || Bit of canvass 1
 +
|-
 +
| 71    || Canvass 1
 +
|-
 +
| 72    || Canvass 2
 +
|-
 +
| 73    || Canvass 3
 +
|-
 +
| 74    || Canvass 4
 +
|-
 +
| 75    || Canvass tile 1
 +
|-
 +
| 76    || Canvass tile 2
 +
|-
 +
| 77    || Canvass tile 3
 +
|-
 +
| 78    || Canvass tile 4
 +
|-
 +
| 79    || Canvass tile 5
 +
|-
 +
| 7A    || Canvass tile 6
 +
|-
 +
| 7B    || Canvass tile 7
 +
|-
 +
| 7C    || Bit of canvas 2
 +
|-
 +
| 7D    || Bit of canvas 3
 +
|-
 +
| 7E    || Bit of canvas 4
 +
|-
 +
| 7F    || Torpedo launcher
 +
|-
 +
| 80    || Ghost house entrance
 +
|-
 +
| 81    || Water weed
 +
|-
 +
| 82    || Big bush 1
 +
|-
 +
| 83    || Big bush 2
 +
|-
 +
| 84    || Castle entrance
 +
|-
 +
| 85    || Yoshi's house
 +
|-
 +
| 86    || Arrow sign
 +
|-
 +
| 87    || ! block, green
 +
|-
 +
| 88    || Tree branch, left
 +
|-
 +
| 89    || Tree branch, right
 +
|-
 +
| 8A    || Switch, green
 +
|-
 +
| 8B    || Switch, yellow
 +
|-
 +
| 8C    || Switch, blue
 +
|-
 +
| 8D    || Switch, red
 +
|-
 +
| 8E    || ! block, yellow
 +
|-
 +
| 8F    || Ghost house window
 +
|-
 +
| 90    || Boss door
 +
|-
 +
| 91    || Steep left slope (vert. lev.)
 +
|-
 +
| 92    || Steep right slope (vert. lev.)
 +
|-
 +
| 93    || Normal left slope (vert. lev.)
 +
|-
 +
| 94    || Normal right slope (vert. lev.)
 +
|-
 +
| 95    || Very steep left slope (vert. lev.)
 +
|-
 +
| 96    || Very steep right slope (vert. lev.)
 +
|-
 +
| 97    || Switch palace right and bottom edge tile
 +
|-
 +
| 98-FF || Unused
 +
|}
  
  
Line 154: Line 687:
 
{| class="wikitable"
 
{| class="wikitable"
 
! colspan="4" | Format
 
! colspan="4" | Format
|-  
+
|- style="font-family:consolas, monospace"
| 000PPPPP || 0000WUSH || 00000000 || DDDDDDDD
+
| 000ppppp || 0000wush || 00000000 || dddddddd
 +
|}
 +
{| class="wikitable" style="font-family:consolas, monospace"
 +
| ppppp    || Screen number
 +
|-
 +
| w        || Midway / Water flag<sup>1,2</sup>
 +
|-
 +
| u        || LM-modified flag<sup>1,3</sup>
 +
|-
 +
| s        || Secondary exit flag
 +
|-
 +
| hdddddddd || Destination level / secondary exit ID
 
|}
 
|}
 +
<small><sup>1</sup> Added by Lunar Magic; not used in the original game.<br />
 +
<sup>2</sup> If the secondary exit flag is clear, links to the destination level's midway entrance. Else, makes the destination level a water level.<br />
 +
<sup>3</sup> Indicates the screen exit uses the secondary exit flag added by LM rather than SMW's default functionality.</small>
 +
 +
In an unmodified SMW, if the last screen exit in the data has the secondary exit flag set, all screen exits in the level will be interpreted as secondary exits.<br />
 +
Additionally, in an unmodified SMW, the high bit of the current level is used as the high bit of the destination level / secondary exit ID.
 +
 +
As of Lunar Magic v2.50, an alternate version of this object also exists as [[#Extended Object 02|extended object 02]]. This version adds an extra byte to the data, for the purpose of having 15-bit destinations (0000-1FFF) instead of 9-bit (000-1FF). It's used for the secondary exit expansion hijack.
 +
 +
 +
=== Screen Jump ===
 +
Screen jumps function as extended object 01, and change the high X position of proceding objects to a specified screen. They can be used to skip over screens if no objects exist on them, or to move back a screen to change the Z ordering of an object crossing over a screen boundary. Lunar Magic also inserts them in the event of an object that would have its first byte as FF, since that would terminate the object data early; it solves this by using a screen jump to move to that object's screen instead of through the object's "new screen" bit, thereby reducing that object's first byte to 7F instead of FF.
 +
 +
Like standard and extended objects, they consist of three bytes.
 
{| class="wikitable"
 
{| class="wikitable"
| PPPPP    || Screen number
+
! colspan="3" | Format
 +
|- style="font-family:consolas, monospace"
 +
| 000HHHHH || 0000VVVV || 00000001
 +
|}
 +
{| class="wikitable" style="font-family:consolas, monospace"
 +
| HHHHH || Horizontal screen number (or just screen number in vertical levels)
 +
|-
 +
| VVVV  || Vertical subscreen number, divided by 2<sup>1</sup>
 +
|}
 +
<small><sup>1</sup> Added in Lunar Magic v3.00 onwards; not used in the original game. Not used at all in vertical levels, as the H bits are just used instead.</small>
 +
 
 +
Although Lunar Magic v3.00 adds the VVVV bits for vertical jumping, it's not enough for levels using horizontal mode 1C, which has a level height of 0x1F screens. For that, an alternative screen jump is added as [[#Extended Object 03|extended object 03]], which swaps the usage of the H and V bits.
 +
 
 +
 
 +
== Lunar Magic Objects ==
 +
Lunar Magic adds some additional objects under standard IDs 22-28, with 29-2C additionally reserved for future use, and object 2D reserved for user-defined objects.
 +
 
 +
=== Object 22/23 ===
 +
Object 22 and 23 are used for direct tiles from Map16 pages 0 and 1 respectively. They're four bytes long rather than three.
 +
{| class="wikitable"
 +
! colspan="4" | Format
 +
|- style="font-family:consolas, monospace"
 +
| N10YYYYY || 001BXXXX || HHHHWWWW || bbbbbbbb
 +
|}
 +
{| class="wikitable" style="font-family:consolas, monospace"
 +
| N        || New Screen flag
 +
|-
 +
| Bbbbbbbbb || Map16 tile number
 +
|-
 +
| YYYYY    || Y position
 +
|-
 +
| XXXX      || X position
 +
|-
 +
| HHHH      || Height
 +
|-
 +
| WWWW      || Width
 +
|}
 +
In vertical levels, the X and Y position values are swapped.
 +
 
 +
 
 +
=== Object 24/25 ===
 +
Objects 24 and 25 are deprecated objects used to handle the old GFX bypass system, which used a list system for specifying ExGFX files. The new Super GFX bypass renders these unnecessary.
 +
{| class="wikitable"
 +
! colspan="4" | Format
 +
|- style="font-family:consolas, monospace"
 +
! Object 24
 +
| N10-SSSS || 0100ssss || FFFFFFFF
 +
|- style="font-family:consolas, monospace"
 +
! Object 25
 +
| N10-UUUU || 0101uuuu || AAAAAAAA
 +
|}
 +
{| class="wikitable" style="font-family:consolas, monospace"
 +
| N        || New Screen flag
 
|-
 
|-
| W        || Water flag* (secondary exit)
+
| SSSSssss || GFX list to use for sprite GFX, plus 1
 
|-
 
|-
| U        || LM-modified flag**
+
| FFFFFFFF || GFX list to use for FG/BG GFX, plus 1
 
|-
 
|-
| S        || Secondary exit flag
+
| UUUUuuuu || Unused? Stored to $FA.
 
|-
 
|-
| H        || High bit of destination level / secondary exit ID*
+
| AAAAAAAA || GFX file for AN2, plus 1
 
|-
 
|-
| DDDDDDDD || Low byte of destination level / secondary exit ID
+
|?        || Unused?
 
|}
 
|}
<nowiki />* Added by Lunar Magic; not used in the original game.<br />
+
Note: the GFX list for FG/BG graphics does not include the extra files BG2 and BG3.
<nowiki />** Indicates the screen exit uses the secondary exit flag added by LM rather than SMW's default functionality.
 
  
In an unmodified SMW, if the last screen exit in the data has the secondary exit flag set, all screen exits in the level will be interpreted as secondary exits.<br />
+
 
In an unmodified SMW, the high bit of the current level is used as the high bit of the destination level / secondary exit ID.
+
=== Object 26 ===
 +
Object 26 handles the music bypass.
 +
{| class="wikitable"
 +
! colspan="3" | Format
 +
|- style="font-family:consolas, monospace"
 +
| N10-UUUU || 0101uuuu || MMMMMMMM
 +
|}
 +
{| class="wikitable" style="font-family:consolas, monospace"
 +
| N        || New Screen flag
 +
|-
 +
| MMMMMMMM  || Song ID to use, plus one.
 +
|-
 +
| UUUUuuuu  || Unused? Functions identical to the M bits.
 +
|-
 +
| -        || Currently unused
 +
|}
 +
 
 +
 
 +
=== Object 27/29 ===
 +
Objects 27 and 29 handles Map16 objects other than those handled by object 22/23. Object 27 in particular handles Map16 pages 00-3F, while object 29 handles 40-7F. There are five different forms of the objects, depending on how the tiles are selected and stretched, and whether they use a conditional direct Map16 flag.
 +
{| class="wikitable"
 +
! colspan="9" | Format (for object 27)
 +
|- style="font-family:consolas, monospace"
 +
! Single-screen, single tile
 +
| N10YYYYY || 0111XXXX || HHHHWWWW || 00BBBBBB || bbbbbbbb
 +
|- style="font-family:consolas, monospace"
 +
! Multiple tiles unstretched
 +
| N10YYYYY || 0111XXXX || hhhhwwww || 01BBBBBB || bbbbbbbb
 +
|- style="font-family:consolas, monospace"
 +
! Single-screen, multiple tiles
 +
| N10YYYYY || 0111XXXX || HHHHWWWW || 10BBBBBB || bbbbbbbb || hhhhwwww
 +
|- style="font-family:consolas, monospace"
 +
! Multi-screen
 +
| N10YYYYY || 0111XXXX || 0WWWWWWW || 11BBBBBB || bbbbbbbb || hhhhwwww || HHHHHHHH
 +
|- style="font-family:consolas, monospace"
 +
! Conditional direct map16
 +
| N10YYYYY || 0111XXXX || 1WWWWWWW || 11BBBBBB || bbbbbbbb || hhhhwwww || HHHHHHHH || ACCCCCCC
 +
|}
 +
<small><nowiki />* Object 29 is handled identically, except the high 4 bits of the second byte are 1001 instead of 0111.</small>
 +
{| class="wikitable" style="font-family:consolas, monospace"
 +
| N              || New Screen flag
 +
|-
 +
| BBBBBBbbbbbbbb || Base Map16 tile number
 +
|-
 +
| YYYYY          || Y position
 +
|-
 +
| XXXX          || X position
 +
|-
 +
| HHHH(HHHH)      || Height<sup>1</sup>
 +
|-
 +
| WWWW(WWW)      || Width
 +
|-
 +
| hhhh          || Height of Map16 selection
 +
|-
 +
| wwww          || Width of Map16 selection
 +
|-
 +
| CCCCCCC        || Conditional direct Map16 flag to use
 +
|-
 +
| A              || Flag to indicate the conditional direct Map16 flag should add 0x100 to the Map16 number rather than hide/display
 +
|}
 +
In vertical levels, the X and Y position values are swapped.
 +
 
 +
<small><sup>1</sup> Although the height of multi-screen objects are 8-bit, only values up to #$80 are properly supported.</small>
  
  
=== Screen Jump ===
+
=== Object 28 ===
Screen jumps function as extended object 01, and change the high X position of proceding objects to a specified screen. They can be used to skip over screens if no objects exit on them, or to move back a screen to change the Z ordering of an object crossing over a screen boundary. Like standard and extended objects, they consist of three bytes.
+
Object 28 handles the time limit bypass.
 
{| class="wikitable"
 
{| class="wikitable"
 
! colspan="3" | Format
 
! colspan="3" | Format
|-  
+
|- style="font-family:consolas, monospace"
| 000PPPPP || 0000---- || 00000001
+
| N10-BBBB || 0001AAAA || R---CCCC
 +
|}
 +
{| class="wikitable" style="font-family:consolas, monospace"
 +
| N    || New Screen flag
 +
|-
 +
| AAAA || Ones
 +
|-
 +
| BBBB || Tens
 +
|-
 +
| CCCC || Hundreds
 +
|-
 +
| R    || Force timer reset flag
 +
|-
 +
| ---- || Currently unused
 +
|}
 +
 
 +
 
 +
=== Object 2D ===
 +
Object 2D is reserved by Lunar Magic for 5-byte custom user-defined objects. Although it's parsed by LM's hijacks, it's not actually tied to any routines normally.
 +
{| class="wikitable"
 +
! colspan="5" | Format
 +
|- style="font-family:consolas, monospace"
 +
| N10YYYYY || 1101XXXX || SSSSSSSS || AAAAAAAA || BBBBBBBB
 +
|}
 +
{| class="wikitable" style="font-family:consolas, monospace"
 +
| N        || New Screen flag
 +
|-
 +
| YYYYY    || Y position
 +
|-
 +
| XXXX    || X position
 +
|-
 +
| SSSSSSSS || Settings
 +
|-
 +
| AAAAAAAA || Extension byte A
 +
|-
 +
| BBBBBBBB || Extension byte B
 +
|}
 +
[https://www.smwcentral.net/?p=section&a=details&id=12379 ObjecTool] uses extension byte A as the custom object number, while byte B is left free for use.
 +
 
 +
In vertical levels, the X and Y position values are swapped.
 +
 
 +
 
 +
=== Extended Object 02 ===
 +
Extended object 02 serves as an expansion to the [[#Screen Exits|standard screen exit object]]. It's mostly identical to the original object, except byte 2 is moved to end to allow its high bits to be used.
 +
{| class="wikitable"
 +
! colspan="5" | Format
 +
|- style="font-family:consolas, monospace"
 +
| 000ppppp || 0000---- || 00000010 || dddddddd || HHHHw11h
 +
|}
 +
{| class="wikitable" style="font-family:consolas, monospace"
 +
| ppppp        || Screen number
 +
|-
 +
| w            || Water flag
 +
|-
 +
| HHHHhdddddddd || Secondary exit ID
 +
|-
 +
| ----          || Currently unused
 
|}
 
|}
 +
 +
 +
=== Extended Object 03 ===
 +
Extended object 03 serves as an alternative to the [[#Screen Jump|standard screen jump object]], with the only difference being that the H and V bits are swapped. It is exclusively only ever used in horizontal level mode 1C, in order to jump to screens 10-1F.
 
{| class="wikitable"
 
{| class="wikitable"
| PPPPP || Screen number
+
! colspan="3" | Format
 +
|- style="font-family:consolas, monospace"
 +
| 000VVVVV || 0000HHHH || 00000011
 +
|}
 +
{| class="wikitable" style="font-family:consolas, monospace"
 +
| VVVVV  || Vertical subscreen number, divided by 2
 
|-
 
|-
| ----  || Currently unused
+
| HHHH || Horizontal screen number
 
|}
 
|}
  
  
 
== Background Data ==
 
== Background Data ==
When Layer 2 is stored as a background tilemap (see the note on the [[#Pointer Tables|pointer table]]), it's written as a raw tilemap with no header, compressed in the LC_RLE1 format.
+
When Layer 2 is stored as a background tilemap, it's compressed in the LC_RLE1 format:
 
{| class="wikitable"
 
{| class="wikitable"
 
! colspan="2" | Format
 
! colspan="2" | Format
|-  
+
|- style="font-family:consolas, monospace"
 
| RLLLLLLL || ...
 
| RLLLLLLL || ...
 
|}
 
|}
{| class="wikitable"
+
{| class="wikitable" style="font-family:consolas, monospace"
 
| R        || RLE flag
 
| R        || RLE flag
 
|-
 
|-
Line 205: Line 941:
 
| ...      || If the RLE flag is clear, the following (length + 1) bytes are intepreted as direct tile data.<br />If the RLE flag is set, the following byte is repeated (length + 1) times.
 
| ...      || If the RLE flag is clear, the following (length + 1) bytes are intepreted as direct tile data.<br />If the RLE flag is set, the following byte is repeated (length + 1) times.
 
|}
 
|}
The entire left half of the BG is stored first, then the right half. A command of FF FF indicates the end of the data.
+
A command of FF FF indicates the end of the data.
 +
 
 +
In its decompressed form, the tilemap data is written as direct 8-bit Map16 tiles numbers, with the entire left half of the BG written first, then the right half; in LM-modified ROMs, these sections extend a full 32 tiles vertically, although in the original game they only are 27 tiles tall. Additionally, in the original game, the high byte of each tile is then determined by where the data is actually located (page 0 if less than $0CE8FE, page 1 if greater), while in a LM-modified ROM, the high bytes of the tiles are just written in a second (identically-formatted) block following the low bytes.
 +
 
 +
 
 +
Lastly, in the original game, whether or not Layer 2 is a BG tilemap or object data is determined by the bank byte of the [[#Pointer Tables|data's pointer]]; if #$FF, it gets interpreted as a BG (and the byte is changed to #$0C), whereas any other value indicates object data. Lunar Magic changes this functionality so that BG tilemaps use the full 24-bit pointer, and instead moves the flag to determine its format to $0EF310:
 +
{| class="wikitable"
 +
! Format
 +
|- style="font-family:consolas, monospace"
 +
| bbBBVFCT
 +
|}
 +
{| class="wikitable" style="font-family:consolas, monospace"
 +
|-
 +
| V    || Flag to indicate a vanilla BG tilemap is being used
 +
|-
 +
| C    || Flag to indicate a custom BG tilemap is being used
 +
|-
 +
| F    || Flag to indicate the usage of the high nibble, when using a BG tilemap
 +
|-
 +
| BB  || F bit set: Map16 bank to use for the BG<sup>1</sup>
 +
|-
 +
| bbBB || F bit clear: High byte for all BG Map16 tiles (only used for compatability with the original system)
 +
|-
 +
| T    || Deprecated bit used to enable a feature that would allow the ExGFX file defined for the LT3 slot to be loaded as a Layer 2 background (effectively, turning it into an "LT2" slot). As of v3.31, this feature is no longer supported and should not be used.
 +
|}
 +
<small><sup>1</sup> Although values up to F is supported, only the first 8 are actually used. See the section on [[#Background Map16 Tiles|background Map16 tiles]] for more details.</small>
 +
 
 +
Neither of the V or C bits being set indicates that the level uses an object Layer 2 instead of a BG tilemap.
  
  
 
== Sprite Data ==
 
== Sprite Data ==
Sprite data consists of a [[#Sprite Header|single-byte header]], followed by a list of all the sprites. If the first byte of a sprite is #$FF, it indicates the end of the data has been reached.
+
Sprite data consists of a [[#Sprite Header|single-byte header]], followed by a list of all the sprites. In the original game and versions of Lunar Magic prior to v3.00, if the first byte of a sprite is FF, it indicates the end of the data has been reached. In version 3.00 and above, FF FE is used instead (see below for more details). Each sprite in the data generally has the following 3-byte format:
 +
 
 
{| class="wikitable"
 
{| class="wikitable"
 
! colspan="3" | Format
 
! colspan="3" | Format
|-  
+
|- style="font-family:consolas, monospace"
 
| yyyyEESY || XXXXssss || NNNNNNNN
 
| yyyyEESY || XXXXssss || NNNNNNNN
 
|}
 
|}
{| class="wikitable"
+
{| class="wikitable" style="font-family:consolas, monospace"
 
| Yyyyy    || Y position
 
| Yyyyy    || Y position
 
|-
 
|-
Line 227: Line 991:
 
|}
 
|}
 
In vertical levels, the X and Y position values are swapped.
 
In vertical levels, the X and Y position values are swapped.
 +
 +
In LM v3.00 and above, a new sprite system (indicated by bit 6 of the sprite header) uses the FF value to specify additional commands in the proceeding byte. The following values are currently available for that:
 +
{| class="wikitable"
 +
! Value || Function
 +
|- style="font-family:consolas, monospace"
 +
| 00-7F || Y position jump. The upper 7 bits of the Y position for all proceeding sprites are set to this value.
 +
|- style="font-family:consolas, monospace"
 +
| FE    || End of data.
 +
|- style="font-family:consolas, monospace"
 +
| FF    || Normal sprite for which the first byte is FF (this value acts as that byte).
 +
|}
 +
Any other command values are currently unused.
 +
 +
It is worth noting that a particular sprite's data may not be limited to 3 bytes. As of Lunar Magic v1.80, any sprite may have up to 12 additional extension bytes defined, which immediately follow the relevant sprite's data (for up to 15 bytes total per sprite). You can determine if any sprites do this by checking if <code>read1($0EF30F)</code> equals 0x42; if so, then a 0x400-byte table of each sprite's data size can be found at <tt>read3($0EF30C)</tt>. The first 0x100 bytes of this table correspond to extra bit 0, the next 0x100 correspond to extra bit 1, etc.
 +
 +
It is also worth noting that in the original game, the sprite data is generally limited to a maximum of 128 sprites, due to the usage of the table at $7E1938 for tracking whether sprites should be able to respawn (which only has 128 bytes allocated). Lunar Magic will normally warn when sprites are placed above this limit, although the warning can be disabled by clearing bit 0 of $0FFFE0.
  
  
Line 232: Line 1,012:
 
Secondary entrance data consists of four bytes, spread across four seperate 512-byte tables with one byte per secondary exit ID.
 
Secondary entrance data consists of four bytes, spread across four seperate 512-byte tables with one byte per secondary exit ID.
 
{| class="wikitable"
 
{| class="wikitable"
! colspan="4" | Format
+
! colspan="7" | Format
|-  
+
|- style="font-family:consolas, monospace;text-align:center"
! $05F800 !! $05FA00 !! $05FC00 !! $05FE00
+
! LM Version
 +
! $05F800  !! $05FA00  !! $05FC00  !! $05FE00  !! read3($05DC86) !! read3($05DC8B)
 +
|- style="font-family:consolas, monospace;text-align:center"
 +
| < 3.00
 +
| dddddddd || bbffyyyy || xxxSSSSS || IPYXDAAA
 +
|- style="font-family:consolas, monospace;text-align:center"
 +
| 3.00+
 +
| dddddddd || bbffyyyy || xxxSSSSS || IPXXDAAA || EFYYYYYY || RLW-----
 +
|}
 +
{| class="wikitable" style="font-family:consolas, monospace"
 +
| Ddddddddd    || Destination level
 +
|-
 +
| bb          || BG initial position, if R bit is clear
 +
|-
 +
| ff          || FG initial position, if R bit is clear
 +
|-
 +
| Fbbff        || Main entrance FG/BG offset, if R bit is set
 +
|-
 +
| (YYYYYY)yyyy || Entrance Y position<sup>2</sup>
 +
|-
 +
| (XX)xxx      || Entrance X position<sup>2</sup>
 +
|-
 +
| SSSSS        || Entrance screen number
 +
|-
 +
| I            || Slippery level flag<sup>1</sup>
 +
|-
 +
| P            || Uses X/Y position method 2<sup>1</sup>
 +
|-
 +
| AAA          || Mario entrance action.<sup>1</sup>
 +
|-
 +
| E            || "Exit to Overworld" flag; see below.<sup>1</sup>
 +
|-
 +
| R            || Set main entrance FG/BG setting relative to player<sup>1</sup>
 +
|-
 +
| L            || Face entrance left<sup>1</sup>
 +
|-
 +
| W            || Water level flag<sup>1</sup>
 +
|}
 +
Prior to v3.00 of Lunar Magic, the X and Y position values are swapped in vertical levels. In 3.00 onward, they are not.
 +
 
 +
<small><sup>1</sup> Added by Lunar Magic; not used in the original game.<br />
 +
<sup>2</sup> The capitalized Y and X bits are added by Lunar Magic when using X/Y position method 2, but are unused otherwise.</small>
 +
 
 +
 
 +
In Lunar Magic v3.00 onward, if the E bit (exit to overworld) is set, then a different format is used:
 +
{| class="wikitable"
 +
! colspan="6" | Format
 +
|- style="font-family:consolas, monospace;text-align:center"
 +
! $05F800 !! $05FA00 !! $05FC00 !! $05FE00  !! read3($05DC86) !! read3($05DC8B)
 +
|- style="font-family:consolas, monospace;text-align:center"
 +
| dddddddd || LLLLLLLL || BBBBBBBB || --ETDAAA || 1------- || --------
 +
|}
 +
{| class="wikitable" style="font-family:consolas, monospace"
 +
| Ddddddddd || Destination level. Unused, but still modified by LM.
 +
|-
 +
| LLLLLLLL  || Location index to use, if T bit is set
 +
|-
 +
| BBBBBBBB  || Base event to use, if E bit is is set
 +
|-
 +
| E        || "Use a different base event" flag
 +
|-
 +
| T        || "Teleport to location index" flag
 +
|-
 +
| AAA      || Overworld entrance action.
 +
|}
 +
 
 +
 
 +
As of Lunar Magic v2.50, the first four secondary entrance tables may also be dynamically allocated to expand their size. They can be found at:
 +
{| class="wikitable" style="font-family:consolas, monospace"
 +
|-
 +
! $05F800
 +
| read3($0DE191)
 +
|-
 +
! $05FA00
 +
| read3($0DE198)
 +
|-
 +
! $05FC00
 +
| read3($0DE19F)
 +
|-
 +
! $05FE00
 +
| read3($05DC81)
 +
|}
 +
 
 +
 
 +
== ExAnimation Data ==
 +
ExAnimation data is stored in two parts, the first being the general animation information and the second being the individual animation information. Note that, unlike most other data on this page, the below values are being described in hexadecimal rather than binary.
 +
{| class="wikitable"
 +
! colspan="10" | General Animation Format
 +
|- style="font-family:consolas, monospace"
 +
| SS || EE || cc || CC || ii || II || mm || MM || FF... || dd DD...
 +
|}
 +
{| class="wikitable" style="font-family:consolas, monospace"
 +
| SS      || Highest used animation slot, plus 1
 +
|-
 +
| EE      || Which alternate GFX file the level uses (00-03)
 +
|-
 +
| 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 data<sup>1</sup> (with #$0002 referring to the byte after the first value here)
 +
|}
 +
<small><sup>1</sup> Indices are included up to the highest used slot. If a slot before that isn't used, its index is 0000.</small>
 +
 
 +
{| class="wikitable"
 +
! colspan="6" | Individual Animation Format
 +
|- style="font-family:consolas, monospace"
 +
| AA || TT || FF || dd || DD || mm MM...
 +
|}
 +
{| class="wikitable" style="font-family:consolas, monospace"
 +
| AA      || Animation type
 +
|-
 +
| TT      || Trigger
 +
|-
 +
| FF      || Number of frames (-1)
 +
|-
 +
| DDdd    || Tiles only: VRAM destination<sup>1</sup>
 +
|-
 +
| DD      || Colors only: number of colors to animate (-1)<sup>1</sup>
 +
|-
 +
| 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
 +
|}
 +
<small><sup>1</sup> The highest bit being 1 indicates the slot uses the level's alternative GFX file.</small>
 +
 
 +
Global ExAnimation data can be found with <code>read1(read3($0583AE)+$5C)<<8+(read2(read3($0583AE)+$65))</code>. If <code>read2(read3($0583ae)+$5B)</code> returns #$0000, the ROM has no global ExAnimation data.
 +
 
 +
The 24-bit pointers to level ExAnimation data can be found with <code>read3(read3($0583ae)+$EA)</code>. If the second byte of the pointer is zero, then that level doesn't have animation data.
 +
 
 +
 
 +
Additionally, there's a 512-byte table at $03FE00 that stores each level's animation settings.
 +
{| class="wikitable"
 +
! Format
 +
|- style="font-family:consolas, monospace"
 +
| PTLG----
 +
|}
 +
{| class="wikitable" style="font-family:consolas, monospace"
 +
| P    || Disable original game's palette animations
 +
|-
 +
| T    || Disable original game's tile animations
 +
|-
 +
| L    || Disable LM's level animations
 +
|-
 +
| G    || Disable LM's global animations
 
|-
 
|-
| DDDDDDDD || BBFFYYYY || XXXSSSSS || L---HAAA
+
| ---- || Currently unused
 +
|}
 +
 
 +
== ExGFX Files ==
 +
ExGFX files can be found in a large table at <code>read3($0FF7FF)</code>, with 32 bytes per level. The files are listed in 16-bit, in the order:
 +
{| class="wikitable"
 +
| AN2 || LT3
 +
| BG3 || BG2 || FG3 || BG1 || FG2 || FG1
 +
| SP4 || SP3 || SP2 || SP1
 +
| LG4 || LG3 || LG2 || LG1
 
|}
 
|}
 +
Additionally, the high bytes of some of these files contain extra information:
 
{| class="wikitable"
 
{| class="wikitable"
| DDDDDDDD || Low byte of destination level
+
! colspan="2" | Format
 +
|- style="font-family:consolas, monospace"
 +
! AN2
 +
| G3T?----
 +
|- style="font-family:consolas, monospace"
 +
! LT3
 +
| DDFF----
 +
|- style="font-family:consolas, monospace"
 +
! BG3
 +
| AAAA----
 +
|- style="font-family:consolas, monospace"
 +
! SP3
 +
| <u>yyyy</u>----
 +
|- style="font-family:consolas, monospace"
 +
! SP2
 +
| HV<u>YY</u>----
 +
|- style="font-family:consolas, monospace"
 +
! SP1
 +
| SCXX----
 +
|- style="font-family:consolas, monospace"
 +
! LG4
 +
| yOIB----
 +
|- style="font-family:consolas, monospace"
 +
! LG3
 +
| YYYY----
 +
|- style="font-family:consolas, monospace"
 +
! LG2
 +
| hhhh----
 +
|- style="font-family:consolas, monospace"
 +
! LG1
 +
| vvvv----
 +
|}
 +
{| class="wikitable" style="font-family:consolas, monospace"
 +
| G                  || Enable Super GFX Bypass
 +
|-
 +
| 3                  || Enable Layer 3 Bypass
 +
|-
 +
| T                  || Enable Layer 3 Tilemap Bypass
 +
|-
 +
| DD                  || Layer 3 destination for file
 +
|-
 +
| FF                  || Layer 3 file size
 +
|-
 +
| AAAA                || Layer 3 act-as setting
 +
|-
 +
| C                  || Enable CGADSUB for Layer 3
 +
|-
 +
| S                  || Move Layer 3 to subscreen
 +
|-
 +
| XX                  || Initial Layer 3 X position
 +
|-
 +
| B                  || Enable advanced bypass of Layer 3
 
|-
 
|-
| BB      || BG initial position
+
| O                  || Make sprites beyond level boundaries interact with air instead of water
 
|-
 
|-
| FF      || FG initial position
+
| I                  || Fix layer 3 scroll sync issue
 
|-
 
|-
| YYYY    || Entrance Y position
+
| <u>YYyyyy</u>YYYYy  || Initial Layer 3 Y position
 
|-
 
|-
| XXX      || Entrance X position
+
| Hhhhh              || Layer 3 horizontal scroll setting
 
|-
 
|-
| SSSSS    || Entrance screen number
+
| Vvvvv              || Layer 3 vertical scroll setting
 
|-
 
|-
| L        || Slippery level flag*
+
|?                    || Unused?
 
|-
 
|-
| ---     || Currently unused
+
| ----                || Normal high byte of GFX files
 +
|}
 +
 
 +
 
 +
Note that the actual GFX data pointers can be found in various places:
 +
{| class="wikitable"
 +
! File || Pointer location
 +
|-
 +
|style="text-align: center;"| 00-31
 +
| <code>$00B992</code> (low), <code>$00B9C4</code> (high), <code>$00B9F6</code> (bank)
 +
|-
 +
|style="text-align: center;"| 60-63
 +
| <code>$03BCC0</code> (24-bit pointers)
 +
|-
 +
|style="text-align: center;"| 80-FF
 +
| <code>$0FF600</code> (24-bit pointers)
 +
|-
 +
|style="text-align: center;"| 100-FFF
 +
| <code>read3($0FF937)</code> (24-bit pointers)
 +
|}
 +
 
 +
 
 +
== Palette Data ==
 +
Palette data is normally handled by the [[#Primary Level Header|primary level header]]. More information on parsing the data there can be found [http://smwc.me/1314089 here].
 +
 
 +
Lunar Magic determines whether a level uses SMW's original palette system or a custom palette by a 24-bit table at $0EF600. If a level's pointer is $000000, it does not use a custom palette, else the value is used as a pointer to the palette data. Custom palettes contain all 257 colors the level uses, with the first color being the back area color.
 +
 
 +
All palette data is stored as 16-bit SNES RGB values:
 +
{| class="wikitable"
 +
! colspan="2" | Format
 +
|- style="font-family:consolas, monospace"
 +
| -BBBBBGG || GGGRRRRR
 +
|}
 +
{| class="wikitable" style="font-family:consolas, monospace"
 +
| BBBBB || Blue component
 
|-
 
|-
| H        || High bit of destination level*
+
| GGGGG || Green component
 
|-
 
|-
| AAA      || Entrance Mario action
+
| RRRRR || Red component
 
|}
 
|}
<nowiki />* Added by Lunar Magic; not used in the original game.
+
It's worth noting that for proper conversion for these values to 24-bit RGB values, they should not only be multiplied by 8, but also scaled by a factor of <code>33/32</code> in order to span the full color space.
 +
 
 +
 
 +
== Map16 Data ==
 +
Map16 tilemap data is formatted fairly straightforward. The data consists of 8 bytes per 16x16, with 2 bytes for each 8x8 making it up. These two bytes are the tile number and the YXPCCCTT settings respectively for the tile, and the four tiles are ordered top left, bottom left, top right, bottom right.
 +
 
 +
Getting the location of this data requires a bit of work, however. Vanilla tiles (i.e. tiles on page 0 or 1) use a large pointer table in RAM at [https://www.smwcentral.net/?p=nmap&m=smwram#7E0FBE $0FBE]; this table has two bytes per tile, which are used as a pointer to their full Map16 data in ROM (the bank byte is assumed to be 0x0D). Lunar Magic then writes custom tiles to a set of tables based on the page number the tile is on; unlike the vanilla tiles, these tables just contain the direct data rather than pointers to data. Each page's Map16 table can be found at the following locations:
 +
 
 +
{| class="wikitable"
 +
! Pages !! Location
 +
|- style="font-family:consolas, monospace"
 +
| 02-0F
 +
| style="text-align:left" | read1($06F557)<<16|read2($06F553)
 +
|- style="font-family:consolas, monospace"
 +
| 10-1F
 +
| style="text-align:left" | read1($06F560)<<16|read2($06F55C)
 +
|- style="font-family:consolas, monospace"
 +
| 20-2F
 +
| style="text-align:left" | read1($06F56B)<<16|read2($06F567)+1
 +
|- style="font-family:consolas, monospace"
 +
| 30-3F
 +
| style="text-align:left" | read1($06F574)<<16|read2($06F570)+1
 +
|- style="font-family:consolas, monospace"
 +
| 40-4F
 +
| style="text-align:left" | read1($06F598)<<16|read2($06F594)
 +
|- style="font-family:consolas, monospace"
 +
| 50-5F
 +
| style="text-align:left" | read1($06F5A1)<<16|read2($06F59D)
 +
|- style="font-family:consolas, monospace"
 +
| 60-6F
 +
| style="text-align:left" | read1($06F5AC)<<16|read2($06F5A8)+1
 +
|- style="font-family:consolas, monospace"
 +
| 70-7F
 +
| style="text-align:left" | read1($06F5B5)<<16|read2($06F5B1)+1
 +
|}
 +
 
 +
In addition to this, a ROM may have tileset-specific Map16 enabled on page 2, which can be determined by checking if read1($06F547) is non-zero. If this is the case, then page 2's Map16 can instead be found in a separate table located at <code>(read1($06F58A)<<16|read2($06F586))+$1000</code>. This table has 0x800 bytes per tileset; effectively, you can find each tile's Map16 with an index of <code>0ttttbbb bbbbb000</code>, where <code>tttt</code> is the tilemap number and <code>bbbbbbbb</code> is the lower 8 bits of the tile number.
 +
 
 +
==== Acts-Like Setting ====
 +
In addition to the visual aspect, each Map16 tile also has an "acts-like" setting which determines the base vanilla tile the block borrows interaction from. All the settings for pages 00-3F can be found at <code>read3($06F624)</code>, while pages 40-7F can be found at <code>read3($06F63A)</code>. Each block receives two bytes in these tables, for the 16-bit tile number they're set to act like. To get the true acts-like setting for a particular tile, repeat lookups in this table using each returned tile number until a tile less than 0x200 is found.
 +
 
 +
==== Background Map16 Tiles ====
 +
Background Map16 data can be found using a pointer table located at $0EFD50, where each set of 0x10 pages receives one 24-bit pointer. The data itself is otherwise formatted the same as the foreground tiles.
 +
 
 +
Lunar Magic actually does pad this table to 16 pointers, but only the first 8 are actually intended for use (the remaining 8 will always be 000000). It is possible they will be given a use in a later version.
  
 
[[Category:Technical Information]]
 
[[Category:Technical Information]]

Latest revision as of 08:56, 13 October 2024

LM-related information should be accurate as of version 3.50.

Pointer Tables

Address Description Format
$05E000 Layer 1 data 0x200 levels, 3 bytes each (1,536 bytes)
$05E600 Layer 2 data 0x200 levels, 3 bytes1 each (1,536 bytes)
$05EC00 Sprite data 0x200 levels, 2 bytes2 each (1,024 bytes)

1 In the original SMW, if the long byte of the Layer 2 pointer is 0xFF, it will be replaced by 0x0C and the data will be interpreted as a BG tilemap rather than object data. Lunar Magic changes this so full 24-bit addresses are used either way; see the section on background data for more details.
2 In the original SMW, all sprite data is in bank 7. Lunar Magic adds a 512-byte table for the bank byte at $0EF100.


Primary Level Header

The first five bytes of object data for Layer 1 is the primary level header, which dictates various information about the level. Layer 2 object data also contains this header, but it is skipped over and ignored.

Format
BBBLLLLL CCCOOOOO 3MMMSSSS TTPPPFFF IIVVZZZZ
BBB BG palette
LLLLL Length of level (number of screens, -1)
CCC Back area color
OOOOO Level mode
3 Layer 3 priority
MMM Music
SSSS Sprite GFX setting
TT Timer setting
PPP Sprite palette
FFF FG palette
II Item memory setting
VV Vertical scroll setting
ZZZZ FG/BG GFX setting


Secondary Level Header

The secondary level header consists of four bytes, spread across four seperate tables with one byte per level. Lunar Magic adds a fifth byte at $05DE00 as well, and from v3.00 onwards adds two more at $06FC00 and $06FE00 respectively. Yet another byte was added in v3.40 onwards at $06FA00.

Format
LM version $05F000 $05F200 $05F400 $05F600 $05DE001 $06FA001 $06FC001 $06FE001
< 3.00 hhhhyyyy 33AAAxxx MMMMffbb NUVEEEEE IWPYX---
3.00-3.33 hhhhyyyy 33AAAxxx MMMMffbb NUVEEEEE IWPXXtTT OFYYYYYY RL-ooooo
3.40+ hhhhyyyy 33AAAxxx MMMMffbb NUVEEEEE IWPXXtTT SHCvvvvv OFYYYYYY RL-ooooo
(H)hhhh Layer 2 scroll setting, or specifically the Layer 2 horizontal scroll setting if the S bit is set
(YYYYYY)yyyy Main entrance Y position2
33 Layer 3 setting
AAA Main entrance Mario action
(XX)xxx Main entrance X position2
MMMM Midway entrance screen number
ff Main entrance FG initial position, if R bit is clear
bb Main entrance BG initial position, if R bit is clear
Fffbb Main entrance FG/BG offset, if R bit is set
N Disable No-Yoshi Intro flag
U Unknown/unused vertical position flag
V Vertical positioning flag
EEEEE Main entrance screen number
I Slippery flag1
W Water flag1
P Flag to use X/Y position method 21
t Smart spawn flag1
TT Sprite spawn range1
S Flag to use separate settings for the Layer 2 horizontal/vertical scroll rates.1
C Flag to auto-set the number of screens in the level1
vvvvv Layer 2 vertical scroll setting, if S bit is set1
O Flag to set BG relative to FG1
R Flag to set main entrance FG/BG setting relative to player1
L Flag to face the main entrance left1
ooooo BG height (-1), or relative BG offset if O bit is set (absolute 0 = 0x10)1

Prior to v3.00 of Lunar Magic, the X and Y position values are swapped in vertical levels. In 3.00 onward, they are not.

1 Added by Lunar Magic; not used in the original game.
2 The capitalized Y and X bits are added by Lunar Magic when using X/Y position method 2, but are unused in the original game. Note that versions of Lunar Magic prior to v3.00 only provide one extra bit each.

Additionally, there is an ninth table added in Lunar Magic v3.00, which can be found at read3(read3($05D9A2)+70), and is used for supporting the expanded level format system. It has the following format:

Format
TB0MMMMM
T Indicates the level uses either Layer 2 or Layer 3
B Flag to show the bottom row of the level
0 Should always be set to 0. Currently reserved for bit 5 of the sprite header when loaded in RAM.
MMMMM Horizontal level mode


Midway Entrances

Lunar Magic also adds similar data for midway entrances when they're set to have seperate settings. This data is stored in a dynamically-located set of tables, however; they can all be found in order at read3(read3($05D9E4)+$0A).

Format
LM version Table 1 Table 2 Table 3 Table 4
< 3.00 IWIMYAAA yyyyxxxx ----ffbb
3.00+ IWHMXAAA yyyyxxxx RLE-ffbb -FYYYYYY
I Slippery flag
W Water flag
H Flag to use seperate midway entrance (if clear, all remaining bits of these settings except the M bit are ignored)
M Bit 4 of midway screen number. Bits 0-3 come from secondary header.
YYYYYYyyyy Midway entrance Y position
AAA Midway entrance Mario action
Xxxxx Midway entrance X position (bit 4 is effectively ignored in horizontal levels, only used in vertical ones)
R Set main entrance FG/BG setting relative to player1
ff Midway FG initial position, if R bit is clear
bb Midway BG initial position, if R bit is clear
Fffbb Main entrance FG/BG offset, if R bit is set
L Face entrance left
E Redirect midway entrance to other level; see below.

Prior to v3.00 of Lunar Magic, the X and Y position values are swapped in vertical levels. In 3.00 onward, they are not.

If the E bit is set, table 2 instead serves as bits 0-7 of the destination level, and bit 0 of table 3 serves as bit 8.


Sprite Header

The first byte of sprite data is the sprite header, which handles some miscellaneous sprite-related information.

The "new sprite system flag" indicates that the sprite data uses the FF byte for specifying additional options, rather than acting as a null terminator. More information can be found in the section on the actual data.

Format
SBNMMMMM
S Sprite buoyancy1
B Sprite buoyancy (disable sprite-Layer 2 interaction)
N New sprite system flag2
MMMMM Sprite memory3

1 Sprite buoyancy is a pair of flags that controls how sprites interact with water or lava. It is required for some sprites to behave correctly. Enabling this can cause lag if too many sprites are onscreen at once. Disabling Layer 2 interaction can mitigate this lag.
2 Added in Lunar Magic v3.00. Part of the sprite memory setting in the original game and older versions.
3 Although values up to #$1F (or #$3F in the original game) are possible, only up to #$12 are actually intended for use.

Object Data

Object data is used to define Layer 1 and Layer 2 foreground data. The Z order of the objects is determined by the order they're written; an object earlier in the data, for instance, will appear below an object written later.

The data consists of a five byte header, followed by a list of all the objects. If the first byte of an object is #$FF, it indicates the end of the data has been reached.

The "new screen" flag described in most of the below formats increases the high X position of it and all following objects by one. In order to decrease it or increase it by a larger amount, a screen jump must be used.


Standard Objects

Standard objects are 3 bytes long. The 'settings byte' usage varies depending on the object, but generally specifies the height and width of the object.

Format
NBBYYYYY bbbbXXXX SSSSSSSS
N New Screen flag
BBbbbb Standard object number
YYYYY Y position
XXXX X position
SSSSSSSS Settings

In vertical levels, the X and Y position values are swapped.

Standard Object List
ID Object name Settings byte usage
00 (Extended Objects) Extended object ID
01 Water (Blue) Height Width
02 Invisible coin blocks Height Width
03 Invisible note blocks Height Width
04 Invisible POW coins Height Width
05 Coins Height Width
06 Walk-through dirt Height Width
07 Water (Other color) Height Width
08 Note blocks Height Width
09 Turn blocks Height Width
0A Coin ? blocks Height Width
0B Throw blocks Height Width
0C Black piranha plants Height Width
0D Cement blocks Height Width
0E Brown blocks Height Width
0F Vertical pipes Height Type
10 Horizontal pipes Type Width
11 Bullet shooter Height Unused
12 Slopes Height Type
13 Ledge edges Height Type
14 Ground ledge Height Width
15 Midway/Goal point Height Type
16 Blue coins Height Width
17 Rope/Clouds Type Width
18 Water surface (ani) Height Width
19 Water surface (not ani) Height Width
1A Lava surface (ani) Height Width
1B Net top edge Height Width
1C Donut bridge Unused Width
1D Net bottom edge Height Width
1E Net vertical edge Height Type
1F Vert. Pipe/Bone/Log Height Unused
20 Horiz. Pipe/Bone/Log Unused Width
21 Long ground ledge Width
22 LM - Direct Map16 page 0 Special handling
23 LM - Direct Map16 page 1 Special handling
24 LM - Old FG/BG/SP bypass Special handling
25 LM - Old AN2 bypass Special handling
26 LM - Music bypass Special handling
27 LM - Direct Map16 object Special handling
28 LM - Time limit bypass Special handling
29 LM - Reserved N/A
2A LM - Reserved N/A
2B LM - Reserved N/A
2C LM - Reserved N/A
2D LM - Reserved N/A
2E Tileset Specific 1 Various
2F Tileset Specific 2 Various
30 Tileset Specific 3 Various
31 Tileset Specific 4 Various
32 Tileset Specific 5 Various
33 Tileset Specific 6 Various
34 Tileset Specific 7 Various
35 Tileset Specific 8 Various
36 Tileset Specific 9 Various
37 Tileset Specific 10 Various
38 Tileset Specific 11 Various
39 Tileset Specific 12 Various
3A Tileset Specific 13 Various
3B Tileset Specific 14 Various
3C Tileset Specific 15 Various
3D Tileset Specific 16 Various
3E Tileset Specific 17 Various
3F Tileset Specific 18 Various

The above list shows the usage of the settings byte for each standard object; when an object has two columns for the usage, the right column is the lower nibble while the left is the higher nibble (i.e. #$HW for most objects). The usage can also be seen in Lunar Magic's object window, next to the object ID, though LM displays them in reverse order.


Extended Objects

Extended objects function as standard object 00, and are also 3 bytes long.

Format
N00YYYYY 0000XXXX BBBBBBBB
N New Screen flag
YYYYY Y position
XXXX X position
BBBBBBBB Extended object number

In vertical levels, the X and Y position values are swapped.

Extended Object List
ID Object name
00 Special - Screen Exit
01 Special - Screen Jump
02 Special - 15-bit Screen Exit
03 Special - Alternative Screen Jump
04-0F Unused
10 Small door
11 Invisible ? block (1-UP)
12 Invisible note block
13 Top left corner edge tile 1
14 Top right corner edge tile 1
15 Small POW door
16 Invisible POW ? block
17 Green star block
18 3-UP moon
19 Invisible 1-UP #1
1A Invisible 1-UP #2
1B Invisible 1-UP #3
1C Invisible 1-UP #4
1D Red berry
1E Pink berry
1F Green berry
20 Always turning block
21 Bottom right of midway point (unused)
22 Bottom right of midway point (unused)
23 Note block (flower/feather/star)
24 ON/OFF block
25 Direction coins ? block
26 Note block
27 Note block, bounce on all sides
28 Turn block (Flower)
29 Turn block (Feather)
2A Turn block (Star)
2B Turn block (Star 2/1-UP/Vine)
2C Turn block (Multiple coins)
2D Turn block (Coin)
2E Turn block (Nothing)
2F Turn block (POW)
30  ? block (Flower)
31  ? block (Feather)
32  ? block (Star)
33  ? block (Star 2)
34  ? block (Multiple coins)
35  ? block (Key/Wings/Balloon/Shell)
36  ? block (Yoshi)
37  ? block (Shell)
38  ? block (Shell)
39 Turn block, unbreakable (Feather)
3A Top left corner edge tile 2
3B Top right corner edge tile 2
3C Top left corner edge tile 3
3D Top right corner edge tile 3
3E Top left corner edge tile 4
3F Top right corner edge tile 4
40 Transculent block
41 Yoshi Coin
42 Top left slope
43 Top right slope
44 Purple triangle, left
45 Purple triangle, right
46 Midway point rope
47 Door
48 Invisible POW door
49 Ghost house exit
4A Climbing net door
4B Conveyor end tile 1
4C Conveyor end tile 2
4D Line guide, top left 1/4 large circle
4E Line guide, top right 1/4 large circle
4F Line guide, bottom left 1/4 large circle
50 Line guide, bottom right 1/4 large circle
51 Line guide, top left 1/4 small circle
52 Line guide, top right 1/4 small circle
53 Line guide, bottom left 1/4 small circle
54 Line guide, bottom right 1/4 small circle
55 Line guide end, for horizontal line
56 Line guide end, for vertical line
57 Switch palace bottom right corner tile
58 Switch palace bottom left corner tile
59 Switch palace top right corner tile
5A Switch palace top left corner tile
5B Bit of brick background tile 1
5C Bit of brick background tile 2
5D Bit of brick background tile 3
5E Bit of brick background tile 4
5F Large background area
60 Lava/mud top right corner edge
61 Ghost house clock
62 Ghost house top left to bottom right beam 1
63 Ghost house top right to bottom left beam 1
64 Ghost house cobweb, top right
65 Ghost house cobweb, top left
66 Ghost house top right to bottom left beam 2
67 Ghost house top left to bottom right beam 2
68 Cloud fringe, bottom and right edge
69 Cloud fringe, bottom and left edge
6A Cloud fringe, bottom right
6B Cloud fringe, bottom left
6C Cloud fringe on white, bottom and right edge
6D Cloud fringe on white, bottom and left edge
6E Cloud fringe on white, bottom right
6F Cloud fringe on white, bottom left
70 Bit of canvass 1
71 Canvass 1
72 Canvass 2
73 Canvass 3
74 Canvass 4
75 Canvass tile 1
76 Canvass tile 2
77 Canvass tile 3
78 Canvass tile 4
79 Canvass tile 5
7A Canvass tile 6
7B Canvass tile 7
7C Bit of canvas 2
7D Bit of canvas 3
7E Bit of canvas 4
7F Torpedo launcher
80 Ghost house entrance
81 Water weed
82 Big bush 1
83 Big bush 2
84 Castle entrance
85 Yoshi's house
86 Arrow sign
87  ! block, green
88 Tree branch, left
89 Tree branch, right
8A Switch, green
8B Switch, yellow
8C Switch, blue
8D Switch, red
8E  ! block, yellow
8F Ghost house window
90 Boss door
91 Steep left slope (vert. lev.)
92 Steep right slope (vert. lev.)
93 Normal left slope (vert. lev.)
94 Normal right slope (vert. lev.)
95 Very steep left slope (vert. lev.)
96 Very steep right slope (vert. lev.)
97 Switch palace right and bottom edge tile
98-FF Unused


Screen Exits

Screen exits function as extended object 00. Unlike the rest of object data, they're 4 bytes long rather than 3.

Format
000ppppp 0000wush 00000000 dddddddd
ppppp Screen number
w Midway / Water flag1,2
u LM-modified flag1,3
s Secondary exit flag
hdddddddd Destination level / secondary exit ID

1 Added by Lunar Magic; not used in the original game.
2 If the secondary exit flag is clear, links to the destination level's midway entrance. Else, makes the destination level a water level.
3 Indicates the screen exit uses the secondary exit flag added by LM rather than SMW's default functionality.

In an unmodified SMW, if the last screen exit in the data has the secondary exit flag set, all screen exits in the level will be interpreted as secondary exits.
Additionally, in an unmodified SMW, the high bit of the current level is used as the high bit of the destination level / secondary exit ID.

As of Lunar Magic v2.50, an alternate version of this object also exists as extended object 02. This version adds an extra byte to the data, for the purpose of having 15-bit destinations (0000-1FFF) instead of 9-bit (000-1FF). It's used for the secondary exit expansion hijack.


Screen Jump

Screen jumps function as extended object 01, and change the high X position of proceding objects to a specified screen. They can be used to skip over screens if no objects exist on them, or to move back a screen to change the Z ordering of an object crossing over a screen boundary. Lunar Magic also inserts them in the event of an object that would have its first byte as FF, since that would terminate the object data early; it solves this by using a screen jump to move to that object's screen instead of through the object's "new screen" bit, thereby reducing that object's first byte to 7F instead of FF.

Like standard and extended objects, they consist of three bytes.

Format
000HHHHH 0000VVVV 00000001
HHHHH Horizontal screen number (or just screen number in vertical levels)
VVVV Vertical subscreen number, divided by 21

1 Added in Lunar Magic v3.00 onwards; not used in the original game. Not used at all in vertical levels, as the H bits are just used instead.

Although Lunar Magic v3.00 adds the VVVV bits for vertical jumping, it's not enough for levels using horizontal mode 1C, which has a level height of 0x1F screens. For that, an alternative screen jump is added as extended object 03, which swaps the usage of the H and V bits.


Lunar Magic Objects

Lunar Magic adds some additional objects under standard IDs 22-28, with 29-2C additionally reserved for future use, and object 2D reserved for user-defined objects.

Object 22/23

Object 22 and 23 are used for direct tiles from Map16 pages 0 and 1 respectively. They're four bytes long rather than three.

Format
N10YYYYY 001BXXXX HHHHWWWW bbbbbbbb
N New Screen flag
Bbbbbbbbb Map16 tile number
YYYYY Y position
XXXX X position
HHHH Height
WWWW Width

In vertical levels, the X and Y position values are swapped.


Object 24/25

Objects 24 and 25 are deprecated objects used to handle the old GFX bypass system, which used a list system for specifying ExGFX files. The new Super GFX bypass renders these unnecessary.

Format
Object 24 N10-SSSS 0100ssss FFFFFFFF
Object 25 N10-UUUU 0101uuuu AAAAAAAA
N New Screen flag
SSSSssss GFX list to use for sprite GFX, plus 1
FFFFFFFF GFX list to use for FG/BG GFX, plus 1
UUUUuuuu Unused? Stored to $FA.
AAAAAAAA GFX file for AN2, plus 1
? Unused?

Note: the GFX list for FG/BG graphics does not include the extra files BG2 and BG3.


Object 26

Object 26 handles the music bypass.

Format
N10-UUUU 0101uuuu MMMMMMMM
N New Screen flag
MMMMMMMM Song ID to use, plus one.
UUUUuuuu Unused? Functions identical to the M bits.
- Currently unused


Object 27/29

Objects 27 and 29 handles Map16 objects other than those handled by object 22/23. Object 27 in particular handles Map16 pages 00-3F, while object 29 handles 40-7F. There are five different forms of the objects, depending on how the tiles are selected and stretched, and whether they use a conditional direct Map16 flag.

Format (for object 27)
Single-screen, single tile N10YYYYY 0111XXXX HHHHWWWW 00BBBBBB bbbbbbbb
Multiple tiles unstretched N10YYYYY 0111XXXX hhhhwwww 01BBBBBB bbbbbbbb
Single-screen, multiple tiles N10YYYYY 0111XXXX HHHHWWWW 10BBBBBB bbbbbbbb hhhhwwww
Multi-screen N10YYYYY 0111XXXX 0WWWWWWW 11BBBBBB bbbbbbbb hhhhwwww HHHHHHHH
Conditional direct map16 N10YYYYY 0111XXXX 1WWWWWWW 11BBBBBB bbbbbbbb hhhhwwww HHHHHHHH ACCCCCCC

* Object 29 is handled identically, except the high 4 bits of the second byte are 1001 instead of 0111.

N New Screen flag
BBBBBBbbbbbbbb Base Map16 tile number
YYYYY Y position
XXXX X position
HHHH(HHHH) Height1
WWWW(WWW) Width
hhhh Height of Map16 selection
wwww Width of Map16 selection
CCCCCCC Conditional direct Map16 flag to use
A Flag to indicate the conditional direct Map16 flag should add 0x100 to the Map16 number rather than hide/display

In vertical levels, the X and Y position values are swapped.

1 Although the height of multi-screen objects are 8-bit, only values up to #$80 are properly supported.


Object 28

Object 28 handles the time limit bypass.

Format
N10-BBBB 0001AAAA R---CCCC
N New Screen flag
AAAA Ones
BBBB Tens
CCCC Hundreds
R Force timer reset flag
---- Currently unused


Object 2D

Object 2D is reserved by Lunar Magic for 5-byte custom user-defined objects. Although it's parsed by LM's hijacks, it's not actually tied to any routines normally.

Format
N10YYYYY 1101XXXX SSSSSSSS AAAAAAAA BBBBBBBB
N New Screen flag
YYYYY Y position
XXXX X position
SSSSSSSS Settings
AAAAAAAA Extension byte A
BBBBBBBB Extension byte B

ObjecTool uses extension byte A as the custom object number, while byte B is left free for use.

In vertical levels, the X and Y position values are swapped.


Extended Object 02

Extended object 02 serves as an expansion to the standard screen exit object. It's mostly identical to the original object, except byte 2 is moved to end to allow its high bits to be used.

Format
000ppppp 0000---- 00000010 dddddddd HHHHw11h
ppppp Screen number
w Water flag
HHHHhdddddddd Secondary exit ID
---- Currently unused


Extended Object 03

Extended object 03 serves as an alternative to the standard screen jump object, with the only difference being that the H and V bits are swapped. It is exclusively only ever used in horizontal level mode 1C, in order to jump to screens 10-1F.

Format
000VVVVV 0000HHHH 00000011
VVVVV Vertical subscreen number, divided by 2
HHHH Horizontal screen number


Background Data

When Layer 2 is stored as a background tilemap, it's compressed in the LC_RLE1 format:

Format
RLLLLLLL ...
R RLE flag
LLLLLLL Length
... If the RLE flag is clear, the following (length + 1) bytes are intepreted as direct tile data.
If the RLE flag is set, the following byte is repeated (length + 1) times.

A command of FF FF indicates the end of the data.

In its decompressed form, the tilemap data is written as direct 8-bit Map16 tiles numbers, with the entire left half of the BG written first, then the right half; in LM-modified ROMs, these sections extend a full 32 tiles vertically, although in the original game they only are 27 tiles tall. Additionally, in the original game, the high byte of each tile is then determined by where the data is actually located (page 0 if less than $0CE8FE, page 1 if greater), while in a LM-modified ROM, the high bytes of the tiles are just written in a second (identically-formatted) block following the low bytes.


Lastly, in the original game, whether or not Layer 2 is a BG tilemap or object data is determined by the bank byte of the data's pointer; if #$FF, it gets interpreted as a BG (and the byte is changed to #$0C), whereas any other value indicates object data. Lunar Magic changes this functionality so that BG tilemaps use the full 24-bit pointer, and instead moves the flag to determine its format to $0EF310:

Format
bbBBVFCT
V Flag to indicate a vanilla BG tilemap is being used
C Flag to indicate a custom BG tilemap is being used
F Flag to indicate the usage of the high nibble, when using a BG tilemap
BB F bit set: Map16 bank to use for the BG1
bbBB F bit clear: High byte for all BG Map16 tiles (only used for compatability with the original system)
T Deprecated bit used to enable a feature that would allow the ExGFX file defined for the LT3 slot to be loaded as a Layer 2 background (effectively, turning it into an "LT2" slot). As of v3.31, this feature is no longer supported and should not be used.

1 Although values up to F is supported, only the first 8 are actually used. See the section on background Map16 tiles for more details.

Neither of the V or C bits being set indicates that the level uses an object Layer 2 instead of a BG tilemap.


Sprite Data

Sprite data consists of a single-byte header, followed by a list of all the sprites. In the original game and versions of Lunar Magic prior to v3.00, if the first byte of a sprite is FF, it indicates the end of the data has been reached. In version 3.00 and above, FF FE is used instead (see below for more details). Each sprite in the data generally has the following 3-byte format:

Format
yyyyEESY XXXXssss NNNNNNNN
Yyyyy Y position
EE Extra bits
XXXX X position
Sssss Screen number
NNNNNNNN Sprite ID

In vertical levels, the X and Y position values are swapped.

In LM v3.00 and above, a new sprite system (indicated by bit 6 of the sprite header) uses the FF value to specify additional commands in the proceeding byte. The following values are currently available for that:

Value Function
00-7F Y position jump. The upper 7 bits of the Y position for all proceeding sprites are set to this value.
FE End of data.
FF Normal sprite for which the first byte is FF (this value acts as that byte).

Any other command values are currently unused.

It is worth noting that a particular sprite's data may not be limited to 3 bytes. As of Lunar Magic v1.80, any sprite may have up to 12 additional extension bytes defined, which immediately follow the relevant sprite's data (for up to 15 bytes total per sprite). You can determine if any sprites do this by checking if read1($0EF30F) equals 0x42; if so, then a 0x400-byte table of each sprite's data size can be found at read3($0EF30C). The first 0x100 bytes of this table correspond to extra bit 0, the next 0x100 correspond to extra bit 1, etc.

It is also worth noting that in the original game, the sprite data is generally limited to a maximum of 128 sprites, due to the usage of the table at $7E1938 for tracking whether sprites should be able to respawn (which only has 128 bytes allocated). Lunar Magic will normally warn when sprites are placed above this limit, although the warning can be disabled by clearing bit 0 of $0FFFE0.


Secondary Entrances

Secondary entrance data consists of four bytes, spread across four seperate 512-byte tables with one byte per secondary exit ID.

Format
LM Version $05F800 $05FA00 $05FC00 $05FE00 read3($05DC86) read3($05DC8B)
< 3.00 dddddddd bbffyyyy xxxSSSSS IPYXDAAA
3.00+ dddddddd bbffyyyy xxxSSSSS IPXXDAAA EFYYYYYY RLW-----
Ddddddddd Destination level
bb BG initial position, if R bit is clear
ff FG initial position, if R bit is clear
Fbbff Main entrance FG/BG offset, if R bit is set
(YYYYYY)yyyy Entrance Y position2
(XX)xxx Entrance X position2
SSSSS Entrance screen number
I Slippery level flag1
P Uses X/Y position method 21
AAA Mario entrance action.1
E "Exit to Overworld" flag; see below.1
R Set main entrance FG/BG setting relative to player1
L Face entrance left1
W Water level flag1

Prior to v3.00 of Lunar Magic, the X and Y position values are swapped in vertical levels. In 3.00 onward, they are not.

1 Added by Lunar Magic; not used in the original game.
2 The capitalized Y and X bits are added by Lunar Magic when using X/Y position method 2, but are unused otherwise.


In Lunar Magic v3.00 onward, if the E bit (exit to overworld) is set, then a different format is used:

Format
$05F800 $05FA00 $05FC00 $05FE00 read3($05DC86) read3($05DC8B)
dddddddd LLLLLLLL BBBBBBBB --ETDAAA 1------- --------
Ddddddddd Destination level. Unused, but still modified by LM.
LLLLLLLL Location index to use, if T bit is set
BBBBBBBB Base event to use, if E bit is is set
E "Use a different base event" flag
T "Teleport to location index" flag
AAA Overworld entrance action.


As of Lunar Magic v2.50, the first four secondary entrance tables may also be dynamically allocated to expand their size. They can be found at:

$05F800 read3($0DE191)
$05FA00 read3($0DE198)
$05FC00 read3($0DE19F)
$05FE00 read3($05DC81)


ExAnimation Data

ExAnimation data is stored in two parts, the first being the general animation information and the second being the individual animation information. Note that, unlike most other data on this page, the below values are being described in hexadecimal rather than binary.

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 level uses (00-03)
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 the first value here)

1 Indices are included up to the highest used slot. If a slot before that isn't used, its index 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 destination1
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 level's alternative GFX file.

Global ExAnimation data can be found with read1(read3($0583AE)+$5C)<<8+(read2(read3($0583AE)+$65)). If read2(read3($0583ae)+$5B) returns #$0000, the ROM has no global ExAnimation data.

The 24-bit pointers to level ExAnimation data can be found with read3(read3($0583ae)+$EA). If the second byte of the pointer is zero, then that level doesn't have animation data.


Additionally, there's a 512-byte table at $03FE00 that stores each level's animation settings.

Format
PTLG----
P Disable original game's palette animations
T Disable original game's tile animations
L Disable LM's level animations
G Disable LM's global animations
---- Currently unused

ExGFX Files

ExGFX files can be found in a large table at read3($0FF7FF), with 32 bytes per level. The files are listed in 16-bit, in the order:

AN2 LT3 BG3 BG2 FG3 BG1 FG2 FG1 SP4 SP3 SP2 SP1 LG4 LG3 LG2 LG1

Additionally, the high bytes of some of these files contain extra information:

Format
AN2 G3T?----
LT3 DDFF----
BG3 AAAA----
SP3 yyyy----
SP2 HVYY----
SP1 SCXX----
LG4 yOIB----
LG3 YYYY----
LG2 hhhh----
LG1 vvvv----
G Enable Super GFX Bypass
3 Enable Layer 3 Bypass
T Enable Layer 3 Tilemap Bypass
DD Layer 3 destination for file
FF Layer 3 file size
AAAA Layer 3 act-as setting
C Enable CGADSUB for Layer 3
S Move Layer 3 to subscreen
XX Initial Layer 3 X position
B Enable advanced bypass of Layer 3
O Make sprites beyond level boundaries interact with air instead of water
I Fix layer 3 scroll sync issue
YYyyyyYYYYy Initial Layer 3 Y position
Hhhhh Layer 3 horizontal scroll setting
Vvvvv Layer 3 vertical scroll setting
? Unused?
---- Normal high byte of GFX files


Note that the actual GFX data pointers can be found in various places:

File Pointer location
00-31 $00B992 (low), $00B9C4 (high), $00B9F6 (bank)
60-63 $03BCC0 (24-bit pointers)
80-FF $0FF600 (24-bit pointers)
100-FFF read3($0FF937) (24-bit pointers)


Palette Data

Palette data is normally handled by the primary level header. More information on parsing the data there can be found here.

Lunar Magic determines whether a level uses SMW's original palette system or a custom palette by a 24-bit table at $0EF600. If a level's pointer is $000000, it does not use a custom palette, else the value is used as a pointer to the palette data. Custom palettes contain all 257 colors the level uses, with the first color being the back area color.

All palette data is stored as 16-bit SNES RGB values:

Format
-BBBBBGG GGGRRRRR
BBBBB Blue component
GGGGG Green component
RRRRR Red component

It's worth noting that for proper conversion for these values to 24-bit RGB values, they should not only be multiplied by 8, but also scaled by a factor of 33/32 in order to span the full color space.


Map16 Data

Map16 tilemap data is formatted fairly straightforward. The data consists of 8 bytes per 16x16, with 2 bytes for each 8x8 making it up. These two bytes are the tile number and the YXPCCCTT settings respectively for the tile, and the four tiles are ordered top left, bottom left, top right, bottom right.

Getting the location of this data requires a bit of work, however. Vanilla tiles (i.e. tiles on page 0 or 1) use a large pointer table in RAM at $0FBE; this table has two bytes per tile, which are used as a pointer to their full Map16 data in ROM (the bank byte is assumed to be 0x0D). Lunar Magic then writes custom tiles to a set of tables based on the page number the tile is on; unlike the vanilla tiles, these tables just contain the direct data rather than pointers to data. Each page's Map16 table can be found at the following locations:

Pages Location
02-0F read1($06F557)<<16|read2($06F553)
10-1F read1($06F560)<<16|read2($06F55C)
20-2F read1($06F56B)<<16|read2($06F567)+1
30-3F read1($06F574)<<16|read2($06F570)+1
40-4F read1($06F598)<<16|read2($06F594)
50-5F read1($06F5A1)<<16|read2($06F59D)
60-6F read1($06F5AC)<<16|read2($06F5A8)+1
70-7F read1($06F5B5)<<16|read2($06F5B1)+1

In addition to this, a ROM may have tileset-specific Map16 enabled on page 2, which can be determined by checking if read1($06F547) is non-zero. If this is the case, then page 2's Map16 can instead be found in a separate table located at (read1($06F58A)<<16|read2($06F586))+$1000. This table has 0x800 bytes per tileset; effectively, you can find each tile's Map16 with an index of 0ttttbbb bbbbb000, where tttt is the tilemap number and bbbbbbbb is the lower 8 bits of the tile number.

Acts-Like Setting

In addition to the visual aspect, each Map16 tile also has an "acts-like" setting which determines the base vanilla tile the block borrows interaction from. All the settings for pages 00-3F can be found at read3($06F624), while pages 40-7F can be found at read3($06F63A). Each block receives two bytes in these tables, for the 16-bit tile number they're set to act like. To get the true acts-like setting for a particular tile, repeat lookups in this table using each returned tile number until a tile less than 0x200 is found.

Background Map16 Tiles

Background Map16 data can be found using a pointer table located at $0EFD50, where each set of 0x10 pages receives one 24-bit pointer. The data itself is otherwise formatted the same as the foreground tiles.

Lunar Magic actually does pad this table to 16 pointers, but only the first 8 are actually intended for use (the remaining 8 will always be 000000). It is possible they will be given a use in a later version.