====== Room header ====== ____________________________________ Room index | _________________________________ Area index | | ______________________________ X position (of top left corner) on the map | | | ___________________________ Y position (of top left corner) on the map | | | | ________________________ Room width (in units of screens = 16 blocks = 256 pixels) | | | | | _____________________ Room height (in units of screens = 16 blocks = 256 pixels) | | | | | | __________________ Up scroller | | | | | | | _______________ Down scroller | | | | | | | | ____________ CRE bitset | | | | | | | | | _________ Door list pointer | | | | | | | | | | ____ State conditions list | | | | | | | | | | | | | | | | | | | | | | ii aa xx yy ww hh uu dd cc dddd [...] Room headers define rooms, they exist in bank $8F and room header pointers are what SMILE displays as a dropdown box for room selection. They are variable length (due to the event header list) with ''E5E6'' as a terminator. The **state conditions list** defines conditions to load alternative state headers, they are checked //in order// and the first state condition whose check passes determines the state header to load. Due to this, state conditions must be specified in backwards chronological order. | 0 | Crateria | | 1 | Brinstar | | 2 | Norfair | | 3 | Wrecked Ship | | 4 | Maridia | | 5 | Tourian | | 6 | Ceres | | 7 | Debug |   Notes: * The **room index** is almost unused, aside from some specific checks to do with atmospheric graphics in some areas. * The **room width** may not exceed 15 due to the way block collision calculations are implemented * **Room width** * **room height** may not exceed 50 due to memory constraints * The **up scroller** defines the threshold Y position that Samus needs to exceed (relative to the screen) for the screen to start scrolling downwards when the camera is at the top of the room * The **down scroller** defines the threshold Y position that Samus needs to exceed (relative to the screen) for the screen to start scrolling upwards when the camera is at the bottom of the room * The **CRE bitset** defines some flags that affect how the CRE is loaded during door transitions: | 1 | Disable layer 1 during door transitions into and out of the room | | 2 | Reload the CRE | | 4 | Load extra large tileset | ===== State conditions list ===== ______________ State condition | _________ State condition parameters | | ___ State header pointer | | | eeee [...] ssss ; First state condition eeee [...] ssss ; Second state condition [...] ; Other state conditions E5E6 ; Default state condition (terminator) **State conditions** are two-byte pointers to code in bank $8F that may have parameters. If the check defined in the **state conditions** is passed, the **state header pointer** in that state condition header is used to load the room. The only exception is state condition $E5E6, the default, which doesn't have a **state header pointer** (the default state header simply follows this state condition header instead). ^ Condition ^ Parameters ^ Description ^ | $E5E6 | | Default | | $E5EB | ''dddd'' | Check passes if the current door pointer = ''d'' | | $E5FF | | Check passes if main area boss is dead | | $E612 | ''ee'' | Check passes if event ''e'' is set | | $E629 | ''bb'' | Check passes if area boss ''b'' is dead | | $E640 | | Check passes if morph ball has been collected | | $E652 | | Check passes if morph ball and missiles have been collected | | $E669 | | Check passes if power bombs have been collected | | $E678 | | Check passes if speed booster has been collected | Event numbers are given as follows: | 0 | Zebes is awake | | 1 | Shitroid ate sidehopper | | 2 | Mother Brain's glass is broken | | 3 | Zebetite 1 is destroyed | | 4 | Zebetite 2 is destroyed | | 5 | Zebetite 3 is destroyed | | 6 | Phantoon statue is grey | | 7 | Ridley statue is grey | | 8 | Draygon statue is grey | | 9 | Kraid statue is grey | | Ah | Entrance to Tourian is unlocked | | Bh | Maridia noobtube is broken | | Ch | Lower Norfair chozo has lowered the acid | | Dh | Shaktool cleared a path | | Eh | Zebes timebomb set | | Fh | Critters escaped | | 10h | 1st Metroid hall cleared | | 11h | 1st Metroid shaft cleared | | 12h | 2nd Metroid hall cleared | | 13h | 2nd Metroid shaft cleared | | 14h | //Unused// | | 15h | Outran speed booster lavaquake | Boss bits are given as follows: | 1 | Area boss (Kraid, Phantoon, Draygon, both Ridleys) | | 2 | Area mini-boss (Spore Spawn, Botwoon, Crocomire, //Mother Brain//) | | 4 | Area torizo (Bomb Torizo, Golden Torizo) |   ===== Door list ===== _________________ First door pointer (door BTS 0) | ____________ Second door pointer (door BTS 1) | | _______ Other door pointers (door BTS 2+) | | | aaaa bbbb [...] Door lists are a list of **door pointers** that can be used in a room, they exist in bank $8F. They are variable length with no terminator, and are indexed by door BTS (thus, there is an effective maximum of 128 door pointers). The **door pointers** themselves are two-byte pointers to door headers in bank $83. ==== Door header ==== _____________________________ Destination room header pointer (bank $8F) | ________________________ Elevator properties | | _____________________ Direction | | | __________________ Doorcap X position in blocks | | | | _______________ Doorcap Y position in blocks | | | | | ____________ X screen | | | | | | _________ Y screen | | | | | | | ______ Distance from door to spawn Samus | | | | | | | | _ Custom door ASM to execute (bank $8F) | | | | | | | | | rrrr ee oo xx yy XX YY dddd aaaa Door headers define doors, they exist in bank $83 and have a fixed length of 12 bytes. The **door ASM** can execute any arbitrary ASM and is often used to set scroll values for the new room where the door would normally be hidden inside a red scroll. If the **distance from door to spawn Samus** is negative (8000h..FFFFh), the standard value of 0x00C8 is used for horizontal doors or 0x0180 for vertical doors. The **elevator properties** are as follows: | 0x80 | Door is an elevator | | 0x40 | Switch map to new area | | 0x0i | Marks elevator index i as used (for debug mode) | The **orientation** values are as follows: | 0 | Right | | 1 | Left | | 2 | Down | | 3 | Up | | 4+ | Door spawns a closing door cap | ===== State header ===== _______________________________________________________________ Level data | ________________________________________________________ Tileset | | _____________________________________________________ Music data index | | | __________________________________________________ Music track | | | | _______________________________________________ FX ($83) | | | | | __________________________________________ Enemy population ($A1) | | | | | | _____________________________________ Enemy set ($B4) | | | | | | | ________________________________ Layer 2 scroll X | | | | | | | | _____________________________ Layer 2 scroll Y | | | | | | | | | __________________________ Scroll | | | | | | | | | | _____________________ Special x-ray blocks | | | | | | | | | | | ________________ Main ASM (FX2 in old SMILE) | | | | | | | | | | | | ___________ PLM population | | | | | | | | | | | | | ______ Library background | | | | | | | | | | | | | | _ Setup ASM (Layer1_2 in old SMILE) | | | | | | | | | | | | | | | llllll tt MM mm ffff eeee EEEE xx yy ssss xxxx AAAA pppp bbbb aaaa State headers define the parts of rooms that can change due to different events. | 0 | Upper Crateria | | 1 | Red Crateria | | 2 | Lower Crateria | | 3 | Old Tourian | | 4 | Wrecked Ship - power on | | 5 | Wrecked Ship - power off | | 6 | Green/blue Brinstar | | 7 | Red Brinstar / Kraid's lair | | 8 | Pre Tourian entrance corridor | | 9 | Heated Norfair | | Ah | Unheated Norfair | | Bh | Sandless Maridia | | Ch | Sandy Maridia | | Dh | Tourian | | Eh | Mother Brain's room | | Fh | Blue Ceres | | 10h | White Ceres | | 11h | Blue Ceres elevator | | 12h | White Ceres elevator | | 13h | Blue Ceres Ridley's room | | 14h | White Ceres Ridley's room | | 15h | Map room / Tourian entrance | | 16h | Wrecked Ship map room - power off | | 17h | Blue refill room | | 18h | Yellow refill room | | 19h | Save room | | 1Ah | Kraid's room | | 1Bh | Crocomire's room | | 1Ch | Draygon's room | | 0 | No change | | 3 | Title sequence | | 6 | Empty Crateria | | 9 | Lower Crateria | | Ch | Upper Crateria | | Fh | Green Brinstar | | 12h | Red Brinstar | | 15h | Upper Norfair | | 18h | Lower Norfair | | 1Bh | Maridia | | 1Eh | Tourian | | 21h | Mother Brain | | 24h | Boss fight 1 | | 27h | Boss fight 2 | | 2Ah | Miniboss fight | | 2Dh | Ceres | | 30h | Wrecked Ship | | 33h | Zebes boom | | 36h | Intro | | 39h | Death | | 3Ch | Credits | | 3Fh | "The last Metroid is in captivity" | | 42h | "The galaxy is at peace" | | 45h | Shitroid (same as boss fight 2) | | 48h | Samus theme (same as upper Crateria) | | 0 | No change | | 1 | Samus fanfare | | 2 | Item fanfare | | 3 | Elevator | | 4 | Pre-statue hall | | 5 | Song 0 | | 6 | Song 1 | | 7 | Song 2 |   Notes: * **Level data** is a three-byte pointer to compressed data defining the placement of layer 1 tiles, block properties (including BTS) and optionally custom layer 2 tile placement * The **tileset** is an index into a table that defines the tile table, tile graphics and palette * The **music data index** is an index into a music pointers that define songs 0, 1 and 2 * The **FX** is an (optional) pointer to data defining graphical effects such as animated tiles, palette glows and layer 3 (e.g. water, lava, spores) * The **enemy population** is a pointer to data defining enemy placement and other parameters * The **enemy set** is a pointer to data defining which enemies use which palettes * The **layer 2 scroll X/Y** is a value that determines whether or not custom layer 2 is used, and how fast layer 2 scrolls compared to layer 1 (parallax effect) * In binary, let **layer 2 scroll X/Y** = ''sssssssb'' * If ''b'' = 1, then the library background is used, otherwise custom layer 2 (defined in level data) is used * ''s'' = 0 is a special case that depends on ''b'' * If ''b'' = 0 (custom layer 2), then layer 2 and layer 1 scroll together at the same speed (like an extension of layer 1) * If ''b'' = 1 (library background), then layer 2 does not scroll at all (static image background) * Otherwise (if ''s'' != 0), layer 2 scroll speed = (layer 1 scroll speed) * (''s'' / 0x80) * The **scroll** is an (optional) pointer to data defining which 16x16 regions are scrollable * If **scroll** = 0, then every scroll region is set to green, except for the bottom row, which is set to blue * If **scroll** = 1, then every scroll region is set to green * The **special x-ray blocks** is an (optional) pointer to data defining custom x-ray block graphics * The **main ASM** is an (optional) pointer to code run every frame * The **PLM population** is an (optional) pointer to data defining PLM placement and parameters * The **library background** is an (optional) pointer to data defining operations for loading layer 2 * The **setup ASM** is an (optional) pointer to code run upon loading the room ==== Level data ==== ssssssssssssssss ; Size of decompressed layer 1 data (2 x the number of blocks) _______ Block type | ___ Y flip | | __ X flip | || _ Block number | ||| ttttyxnnnnnnnnnn ; First block ttttyxnnnnnnnnnn ; Second block [...] ; Other blocks bbbbbbbb ; First block BTS bbbbbbbb ; Second block BTS [...] Optional: 0000yxnnnnnnnnnn ; First block layer 2 0000yxnnnnnnnnnn ; Second block layer 2 [...] ; Other blocks layer 2 Level data is defined by specifying data for each 16px x 16px block in the room. This data is split into layer 1 blocks, BTS and optionally layer 2 blocks. Layer 1/2 are two bytes per block, BTS is one byte per block, and a two byte "decompressed layer 1" size. The decompressed size is followed by layer 1 data, followed by BTS, followed by layer 2 (if used) in that order. Level data is compressed in ROM. Layer 1 blocks uses the binary format shown above where: * **Block type** specifies the primary type of the block * **X/Y flip** flips the graphics of the block * **Block number** specifies the index of the block into the tile table (provides the graphics of the block) Layer 2 blocks use the same format, except that they have no **block type** (they are padded with zeros instead). **BTS** data further specifies the type of a block, depending on the primary block type used, e.g. different slope types. ^ Air types ^^ Solid types ^^ | 0 | Air | 8 | Solid block | | 1 | Slope | 9 | Door block | | 2 | Spike air | Ah | Spike block | | 3 | Special air | Bh | Special block | | 4 | Shootable air | Ch | Shootable block | | 5 | Horizontal extension | Dh | Vertical extension | | 6 | Unused air | Eh | Grapple block | | 7 | Bombable air | Fh | Bombable block | ^ Block type ^^ BTS ^^ Description ^ | 2 / Ah | Spike | 0 || Solid only. Generic spike (60 damage) | | ::: | ::: | 1 || Solid only. Kraid's lair spike (10h damage) | | ::: | ::: | 2 || Air only. Air spike (10h damage) | | ::: | ::: | 3 || Solid only. Draygon's broken turret (10h damage) | | ::: | ::: | Eh || Solid only. X-rayable block (used in Blue Brinstar boulder room) | | ::: | ::: | Fh || Solid only. Enemy breakable block (used in Shaktool's room) | | 3 / Bh | Special | 0 || 1x1 respawning crumble block | | ::: | ::: | 1 || 2x1 respawning crumble block | | ::: | ::: | 2 || 1x2 respawning crumble block | | ::: | ::: | 3 || 2x2 respawning crumble block | | ::: | ::: | 4 || 1x1 crumble block | | ::: | ::: | 5 || 2x1 crumble block | | ::: | ::: | 6 || 1x2 crumble block | | ::: | ::: | 7 || 2x2 crumble block | | ::: | ::: | 8 || Air only. Rightwards treadmill, disabled in Wrecked Ship unless Phantoon is dead | | ::: | ::: | 9 || Air only. Leftwards treadmill, disabled in Wrecked Ship unless Phantoon is dead | | ::: | ::: | Ah || Air only. Rightwards treadmill, always on | | ::: | ::: | Bh || Air only. Leftwards treadmill, always on | | ::: | ::: | Eh || Respawning speed boost block | | ::: | ::: | Fh || Speed boost block | | ::: | ::: | 44h || Generic PLM shot trigger | | ::: | ::: | 45h || Item collision detection | | ::: | ::: | 46h || Scroll PLM trigger | | ::: | ::: | 47h || Map station right access | | ::: | ::: | 48h || Map station left access | | ::: | ::: | 49h || Energy station right access | | ::: | ::: | 4Ah || Energy station left access | | ::: | ::: | 4Bh || Missile station right access | | ::: | ::: | 4Ch || Missile station left access | | ::: | ::: | 4Dh || Save station trigger | | ::: | ::: | Crateria/debug | 80h | Air only. Ice physics | | ::: | ::: | Brinstar | 80h | Floor plant | | ::: | ::: | ::: | 81h | Ceiling plant | | ::: | ::: | ::: | 82h | Respawning speed block, slower crumble animation | | ::: | ::: | ::: | 83h | Speed block, slower crumble animation | | ::: | ::: | ::: | 84h | Respawning speed block (used by dachora pit) | | ::: | ::: | ::: | 85h | Speed boost block | | ::: | ::: | Norfair | 83h | Lower Norfair chozo hand trigger | | ::: | ::: | Wrecked Ship | 80h | Wrecked Ship chozo hand trigger | | ::: | ::: | Maridia | 80h | Quicksand surface, can run on without sinking (used in snail room) | | ::: | ::: | ::: | 81h | Quicksand surface | | ::: | ::: | ::: | 82h | Quicksand surface | | ::: | ::: | ::: | 83h | Submerging quicksand (used in sand falls rooms) | | ::: | ::: | ::: | 84h | Sand falls - slow. Used in the ceilings of pre-Draygon mochtroid rooms (so basically unused) | | ::: | ::: | ::: | 85h | Sand falls - fast | | 7 / Fh | Bombable | 0 || 1x1 respawning bomb block | | ::: | ::: | 1 || 2x1 respawning bomb block | | ::: | ::: | 2 || 1x2 respawning bomb block | | ::: | ::: | 3 || 2x2 respawning bomb block | | ::: | ::: | 4 || 1x1 bomb block | | ::: | ::: | 5 || 2x1 bomb block | | ::: | ::: | 6 || 1x2 bomb block | | ::: | ::: | 7 || 2x2 bomb block | | 4 / Ch | Shootable | 0 || 1x1 respawning shot block | | ::: | ::: | 1 || 2x1 respawning shot block | | ::: | ::: | 2 || 1x2 respawning shot block | | ::: | ::: | 3 || 2x2 respawning shot block | | ::: | ::: | 4 || 1x1 shot block | | ::: | ::: | 5 || 2x1 shot block | | ::: | ::: | 6 || 1x2 shot block | | ::: | ::: | 7 || 2x2 shot block | | ::: | ::: | 8 || Respawning power bomb block | | ::: | ::: | 9 || Power bomb block | | ::: | ::: | Ah || Respawning super missile block | | ::: | ::: | Bh || Super missile block | | ::: | ::: | Ch || Fake super missile block (solid block but shows super missile block when x-rayed) | | ::: | ::: | Dh || Fake super missile block | | ::: | ::: | Eh || Fake super missile block | | ::: | ::: | Fh || Fake super missile block | | ::: | ::: | 10h || Gate blocks | | ::: | ::: | 40h || Blue door facing left | | ::: | ::: | 41h || Blue door facing right | | ::: | ::: | 42h || Blue door facing up | | ::: | ::: | 43h || Blue door facing down | | ::: | ::: | 44h || Generic shot trigger | | ::: | ::: | 45h || Item trigger | | ::: | ::: | 46h || Left blue gate trigger | | ::: | ::: | 47h || Right blue gate trigger | | ::: | ::: | 48h || Left red gate trigger | | ::: | ::: | 49h || Right red gate trigger | | ::: | ::: | 4Ah || Left green gate trigger | | ::: | ::: | 4Bh || Right green gate trigger | | ::: | ::: | 4Ch || Left orange gate trigger | | ::: | ::: | 4Dh || Right orange gate trigger | | ::: | ::: | 4Fh || Critters escape block | | Eh | Grapple block | 0 || Generic grapple block | | ::: | ::: | 1 || Respawning crumbling grapple block | | ::: | ::: | 2 || Non-respawning crumbling grapple block | | ::: | ::: | 80h+ || Grapple-through block |   ==== FX ==== __________________________________________ Door pointer | _____________________________________ Base Y position | | ________________________________ Target Y position | | | ___________________________ Y velocity | | | | ______________________ Timer | | | | | ___________________ Layer 3 type | | | | | | ________________ Default layer blending configuration (FX A) | | | | | | | _____________ FX layer 3 layer blending configuration (FX B) | | | | | | | | __________ Liquid options (FX C) | | | | | | | | | _______ Palette FX bitset | | | | | | | | | | ____ Animated tiles bitset | | | | | | | | | | | _ Palette blend | | | | | | | | | | | | dddd,bbbb,tttt,vvvv,tt,ff,AA,BB,CC,pp,aa,bb ; First FX entry dddd,bbbb,tttt,vvvv,tt,ff,AA,BB,CC,pp,aa,bb ; Second FX entry [...] ; Other FX entries 0000,bbbb,tttt,vvvv,tt,ff,AA,BB,CC,pp,aa,bb ; Default FX entry OR FFFF ; No FX FX defines roomwide graphical effects, they're stored in bank $83. A room either has a two byte ''FFFF'' entry specifying there is no FX, or it has optional door-dependent FX entries followed by the default entry. A door-dependent FX entries is used if the door taken into the room matches the entry's **door pointer**, if no doors match (or if there are no entries) the default entry is used. | 0 | None | | 2 | Lava | | 4 | Acid | | 6 | Water | | 8 | Spores | | Ah | Rain | | Ch | Fog | | 20h | Scrolling sky | | 22h | Unused | | 24h | Fireflea | | 26h | Tourian entrance statue | | 28h | Ceres Ridley | | 2Ah | Ceres elevator | | 2Ch | Haze | | 2/Eh/20h | Normal. BG1/BG2/sprites are drawn with BG3 added on top | | | 4 | Normal, but BG2 is disabled | Used by Phantoon | | 6 | Normal, but sprites aren't affected by BG3 and sprites are added to BG1/BG2 (instead of hidden) | Unused | | 8 | Normal, but BG1/sprites aren't affected by BG3 and sprites are added to BG2 (instead of hidden) | Used in some power off Wrecked Ship rooms | | Ah | Normal, but BG1 isn't affected by BG3 | Used with FX layer 3 type = spores | | Ch | Normal, but BG3 is disabled and colour math is subtractive | Used with FX layer 3 type = fireflea | | 10h/12h | Normal, but BG3 is disabled inside window 1 | Used by morph ball eye and varia/gravity suit pickup | | 14h/22h | Normal, but BG1 isn't affected by BG3 and colour math is subtractive | Sometimes use with FX layer 3 type = water | | 16h | BG1/sprites are drawn after the result of drawing BG2/BG3 is subtracted | Sometimes use with FX layer 3 type = water | | 18h/1Eh/30h | BG3 is drawn with the result of drawing BG1/BG2/sprites added on top | Used with FX layer 3 type = lava / acid / fog / Tourian entrance statue, sometimes use with FX layer 3 type = water | | 1Ah | Normal, but BG2 and BG3 have reversed roles | Used by Phantoon | | 1Ch | Normal, but BG2 and BG3 have reversed roles, colour addition is halved and backdrop is disabled | Unused | | 24h | BG1/BG2/sprites are drawn the backdrop is added on top inside window 1 | Used by Mother Brain | | 26h | Normal, but colour addition is halved | Unused | | 28h | Normal, but BG3 is disabled, colour math is subtractive, and the backdrop subtracts red if there is no power bomb explosion | Used in some default state Crateria rooms, some power off Wrecked Ship rooms, pre plasma beam rooms | | 2Ah | Normal, but BG3 is disabled, colour math is subtractive, and the backdrop subtracts orange if there is no power bomb explosion | Used in blue Brinstar rooms, Kraid's lair entrance, n00b tube side rooms, plasma beam room, some sand falls rooms | | 2Ch | Normal, but BG3 is disabled | Used by FX layer 3 type = haze and torizos | | 2Eh | Normal, but colour math is subtractive | Unused | | 32h | Normal, but BG1 isn't affected by BG3 and colour math is subtractive | Unused | | 34h | Normal, but power bombs don't affect BG2 | Unused | | 1 | Liquid flows (leftwards) | | 2 | Layer 2 is wavy | | 4 | Liquid physics are disabled (used in n00b tube room) | | 40h | Big tide (liquid fluctuates up and down, a la the gauntlet) | | 80h | Small tide (liquid fluctuates up and down) |   ==== Enemy population ==== ____________________________________ Enemy ID | _______________________________ X position | | __________________________ Y position | | | _____________________ Initialisation parameter (orientation in old SMILE, tilemaps in SMILE RF) | | | | ________________ Properties (special in SMILE) | | | | | ___________ Extra properties (special GFX bitset in SMILE, graphics in SMILE RF) | | | | | | ______ General purpose parameter (speed in SMILE) | | | | | | | _ General purpose parameter (speed 2 in SMILE) | | | | | | | | iiii xxxx yyyy oooo pppp gggg aaaa bbbb ; First enemy iiii xxxx yyyy oooo pppp gggg aaaa bbbb ; Second enemy [...] ; Other enemies FFFF ; Terminator nn ; Number of enemy deaths needed to clear current room Enemy population defines the placement of enemies, as well as some generic and enemy specific properties. They're stored in bank $A1 with each enemy being 16 bytes, plus a 3 byte overhead. The **initialisation parameter** is overwritten by generic enemy routines and so is often only used during enemy initialisation, the other two **general purpose parameters** do not have this restriction. The **properties** are as follows: | 8000h | Hitbox solid to Samus | | 4000h | Respawns if killed | | 2000h | Process instructions | | 1000h | Block plasma beam | | 800h | Process whilst off-screen | | 400h | Intangible | | 200h | Delete | | 100h | Invisible | The **extra properties** are as follows: | 4 | Enable extended spritemap format | | 1 | Disable enemy AI. Isn't disabled if intangible | ==== Enemy set ==== ______ Enemy ID | _ Palette index | | iiii pppp ; First enemy iiii pppp ; Second enemy [...] ; Other enemies FFFF ; Terminator Enemy set defines which enemies are allowed inside the room and which palette slot to use. They're stored in bank $B4 with each enemy being 4 bytes, plus the 2 byte terminator. Enemies that use the same palette may share the same palette index. Valid palette indices are 1, 2, 3 and 7; note that only palette 7 is affected by colour math. ==== Scroll ==== _______ First scroll | ____ Second scroll | | _ Other scrolls | | | aa bb [...] Scrolls define how the camera works for each 16x16 block (256px x 256px) area in left-to-right, top-down order (reading order). They're stored in bank $8F and are one byte per scroll. Scroll values are as follows: | 0 | Red. Cannot scroll into this area | | 1 | Blue. Hides the bottom 2 rows of the area | | 2 | Green. Unrestricted | ==== Special x-ray blocks ==== _______ X position | ____ Y position | | _ Block | | | xx yy nnnn ; First x-ray block xx yy nnnn ; Second x-ray block [...] ; Other x-ray blocks 0000 ; Terminator Special x-ray blocks display custom x-ray graphics for blocks at given positions in the room. They're stored in bank $8F with each block being 4 bytes, plus the 2 byte terminator. Special x-ray blocks are used in exactly one place in vanilla Super Metroid: the Bomb Torizo room during the escape sequence. It's a hacky way of allowing Samus to x-ray the shootable block in the bottom-right corner of the screen. Note that even after you've shot the shootable block, x-ray will still show the shootable block graphics. The **X/Y position** is specified in (16px x 16px) block units. The **block** uses the level data block format, except that the block type is ignored. Note that [[http://metroidconstruction.com/resource.php?id=54|flexglow]] uses this pointer for the flexglow table instead. ==== PLM population ==== ____________ PLM ID | _______ X position | | ____ Y position | | | _ Parameter | | | | iiii xx yy pppp ; First PLM iiii xx yy pppp ; Second PLM [...] ; Other PLMs 0000 ; Terminator PLM population defines the placement of PLMs, as well as some PLM specific properties. They're stored in bank $8F with each PLM being 6 bytes, plus the 2 byte terminator. PLMs with **PLM ID** >= $DF89 are considered to be "item PLMs", meaning the PLM argument specified in the PLM populations will be used as a unique ID and cannot be negative. ==== Library background ==== ______ Type | _ Parameters | | tttt [...] ; First background command tttt [...] ; Second background command [...] ; Other background commands 0000 ; Terminator The list of commands used in Super Metroid is as follows: ^ Type ^ Parameters ^ Description ^ | 2 | ssssss dddd nnnn | Transfer ''n'' bytes from ''s'' to ''d'' in VRAM | | 4 | ssssss dddd | Decompress ''s'' to ''d'' in bank $7E | | 6 | | Clear layer 3 | | 8 | ssssss dddd nnnn | Transfer ''n'' bytes from ''s'' to ''d'' in VRAM and set BG3 tiles base address = $2000 | | Ah | | Clear layer 2 | | Ch | | Clear Kraid's layer 2 | | Eh | DDDD ssssss dddd nnnn | Transfer ''n'' bytes from ''s'' to ''d'' in VRAM //if the current door pointer = ''D''// | ====== Object formats ====== Super Metroid has lots of specialised **object formats**, which are defined with an **instruction list** possibly combined with an "initialisation ASM". In general, **object formats** have a handler that, for each object, executes a **pre-instruction** and then interprets the **instruction list**. The **instruction list** is a list of **ASM instructions** and **special instructions**. **ASM instructions** have a negative value (meaning $8000..FFFF), which is a pointer to a function to be executed, followed by any parameter values that the function requires. **Special instructions** (usually graphical in nature) have a positive value (meaning $0000..7FFF), usually a timer value, followed by any parameter values. Common **ASM instructions** include looping, conditional execution, setting the pre-instruction, deleting the object and sleeping. The pre-instruction is a function that's executed before the object's instruction list is processed for the current frame. Objects that are sleeping are suspended from handling until they are awakened (usually by a pre-instruction set earlier in the object instruction list). ===== PLMs ===== PLMs (post-load modifications) are objects that modify level data blocks in real-time. They exist in bank $84 and are typically loaded with a room from a room header (e.g. items, doors) or spawned as part of a block interaction (e.g. shot block crumbling). PLM header: ______ Initialisation ASM pointer | _ Instruction list pointer | | aaaa iiii Door PLM header: ___________ Initialisation ASM pointer | ______ Instruction list pointer | | _ Instruction list pointer - door closing | | | aaaa iiii dddd The third pointer for door PLMs is used instead of the second pointer when the PLM is placed where a blue door would normally be closing when Samus enters a room. The **special instructions** for PLMs have the format: ______ Draw timer | _ Pointer to draw instruction | | tttt dddd The **draw timer** is how many frames to wait until the next instruction in the instruction list is proceeded to. The **draw instruction** format is a list of: nnnn ; Number of blocks bbbb [...] ; Blocks xx yy ; X and Y offsets from origin to start drawing from where the list is terminated by ''xx yy = 00 00''. Blocks are drawn from the PLM's position, the direction they're drawn in is given by the most significant bit of ''n''. If ''n'' < 8000h, the blocks are drawn in a horizontal line to the right. If ''n'' >= 8000h, ''n'' & 7FFFh blocks are drawn in a vertical line downwards. ===== Enemy projectiles ===== Enemy projectiles exist in bank $86 and are typically spawned by enemies and can use their graphics and palette. Enemy projectile header: __________________________________ Initialisation AI | _____________________________ (Initial) pre-instruction | | ________________________ Instruction list pointer | | | ___________________ X radius | | | | ________________ Y radius | | | | | _____________ Damage/properties | | | | | | ________ Touch AI | | | | | | | ___ Shot AI | | | | | | | | iiii pppp IIII xx yy Pddd tttt ssss The **properties** are as follows: | 8000h | Detect collisions with projectiles | | 4000h | Don't die on contact | | 2000h | Disable collisions with Samus | | 1000h | Low priority (drawn under enemies/Samus/projectiles) | The **special instructions** for enemy projectiles have the format: ______ Spritemap timer | _ Pointer to spritemap | | tttt ssss The **spritemap timer** is how many frames to wait until the next instruction in the instruction list is proceeded to. Within the spritemap, the tile numbers added to the base tile number set when the enemy projectile was spawned (so the projectile can access enemy graphics). ===== Animated tiles objects ===== Animated tiles objects are objects that modify tile graphics in real-time. They exist in bank $87 and are loaded with a room from an FX header. Animated tiles object header format: ___________ Instruction list pointer | ______ Size | | _ VRAM address | | | iiii ssss vvvv The **special instructions** for animated tiles objects have the format: ______ Animation timer | _ Pointer to tile graphics | | tttt ssss The **animation timer** is how many frames to wait until the next instruction in the instruction list is proceeded to. ===== HDMA objects ===== HDMA objects exist in bank $88 and are typically loaded with a room as part of FX or spawned by power bombs / x-ray. HDMA object header format: _______ HDMA options | ____ PPU register index | | _ Instruction list pointer | | | dd pp iiii The **special instructions** for HDMA objects have the format: ______ Table timer | _ Pointer to HDMA table | | tttt ssss The **table timer** is how many frames to wait until the next instruction in the instruction list is proceeded to. ===== Palette FX objects ===== Palette FX objects are objects that modify palette data in real-time. They exist in bank $8D and are loaded with a room from an FX header. Palette FX object header format: ______ Initialisation ASM pointer | _ Instruction list pointer | | aaaa iiii The **special instructions** for palette FX objects have the format: ______ Palette timer | _ Palette instruction list | | tttt [...] The **palette timer** is how many frames to wait until the next instruction in the instruction list is proceeded to. The ASM instructions are usually used for setting the initial colour index, which is an index into CGRAM equal to ''(p * 10h + c) * 2'' where ''p'' is the palette number and ''c'' is the colour index within the palette. **Palette instructions** are a mix of colours (which are positive values) and ASM instructions (negative values). Colours are written to successive positions in CGRAM starting from initial colour index. ASM instructions can modify the colour index between listed colour values, and the instruction $C595 is used to terminate the palette instruction list.