This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revisionNext revisionBoth sides next revision | ||
return_of_samus:technical_information:screen_transitions [2023/05/29 19:20] – [3x - Select solidity indexes] rt-55j | return_of_samus:technical_information:screen_transitions [2023/05/29 21:34] – Attempted to increase clarity and readability. rt-55j | ||
---|---|---|---|
Line 1: | Line 1: | ||
====== Screen Transitions ====== | ====== Screen Transitions ====== | ||
- | {{..: | + | {{..: |
- | Now, as discussed | + | It is recommended that you have a basic understanding of [[return_of_samus: |
- | ===== The Language | + | ===== Internal Workings |
- | Once the game identifies | + | Each screen on each map has a screen transition index associated with it. As long as the index is not zero, the screen transition corresponding |
- | First it checks if it has reached | + | Once the game identifies the script to use, it copies |
- | Scripts are limited to 64 (0x40) bytes in length, but you'll literally never hit that limit. | + | The interpreter first checks if it has reached the end of the script |
(Note that all 16-bit values (pointers, etc.) are assumed to be little-endian, | (Note that all 16-bit values (pointers, etc.) are assumed to be little-endian, | ||
+ | |||
+ | ===== Tokens/ | ||
+ | |||
+ | Here is a list of valid tokens/ | ||
==== FF - Terminating Operator ==== | ==== FF - Terminating Operator ==== | ||
Line 22: | Line 26: | ||
Copies a block of data starting at a specified bank and address to somewhere in RAM. | Copies a block of data starting at a specified bank and address to somewhere in RAM. | ||
- | Cases: | + | Syntax: |
- | * 01 bb ssss dddd llll - Saves bb:ssss as the source of a BG tileset (necessary for saving properly) | + | |
- | * 02 bb ssss dddd llll - Saves ssss as the source of a sprite tileset (necessary for saving properly) | + | |
- | * 0* bb ssss dddd llll - Just copies the data. | + | |
Operands: | Operands: | ||
Line 41: | Line 45: | ||
Copies the desired metatile table to $DA00-$DBFF in WRAM. | Copies the desired metatile table to $DA00-$DBFF in WRAM. | ||
- | The metatile table pointer list begins at 0x23F1A in ROM. | ||
- | |||
- | For some reason, the pointers are a little out of order. | ||
< | < | ||
- | 80 4C (final ruins) should be 3rd | + | 0 - finalLab |
- | 80 4A (inside ruins) should be second | + | 1 - ruinsInside |
- | 80 48 (bubbles/ | + | 2 - plantBubbles |
- | 80 4E (queen room) | + | 3 - queen |
- | 80 50 (first/last caves) | + | 4 - caveFirst |
- | 80 52 (outside/ | + | 5 - surface |
- | 94 55 (acid caves down) should be eighth | + | 6 - lavaCavesEmpty |
- | A8 56 (acid caves up) should be ninth | + | 7 - lavaCavesFull |
- | 80 54 (acid caves mid) should be seventh | + | 8 - lavaCavesMid |
- | BC 57 (outside ruins) | + | 9 - ruinsExt |
</ | </ | ||
+ | |||
+ | The lava caves adjust their lava levels by changing their metatiles to sets with more or fewer lava tiles during door transitions. | ||
+ | |||
+ | The metatile table pointer list begins at '' | ||
+ | |||
==== 2x - Select collision table ==== | ==== 2x - Select collision table ==== | ||
Copies the desired collision table to $DC00-$DCFF in WRAM. | Copies the desired collision table to $DC00-$DCFF in WRAM. | ||
- | |||
- | The collision table pointer list begins at 0x23EEA in ROM. | ||
< | < | ||
Line 71: | Line 75: | ||
6 - ruinsExt | 6 - ruinsExt | ||
7 - finalLab</ | 7 - finalLab</ | ||
- | ==== 3x - Select solidity indexes ==== | ||
- | Copies the desired solidity indexes to WRAM. | + | The collision table pointer list begins at 0x23EEA in ROM. |
- | The solidity indexes | + | ==== 3x - Select |
- | The bytes are copied | + | Copies the desired solidity indexes |
- | + | ||
- | * $D056 & $D812 - Samus' | + | |
- | * $D056 & $D813 - Enemy solidity index | + | |
- | * $D08A & $D814 - Projectile solidity index | + | |
- | Basically, for Samus, the way it works is that if an 8x8 tile is less than the specified index, then it is treated as a solid. | + | Basically, the way it works is that if an 8x8 tile is less than the specified index, then it is treated as a solid. |
< | < | ||
Line 96: | Line 95: | ||
Note that (by default) these match up perfectly with the collision values previously. | Note that (by default) these match up perfectly with the collision values previously. | ||
+ | |||
+ | The solidity indexes are stored in a table starting at 0x23EFA. Each entry row is four bytes wide, though only three are used. | ||
+ | |||
+ | The bytes are copied to these locations: | ||
+ | |||
+ | * $D056 & $D812 - Samus' solidity index | ||
+ | * $D056 & $D813 - Enemy solidity index | ||
+ | * $D08A & $D814 - Projectile solidity index | ||
+ | |||
==== 4* - Warp ==== | ==== 4* - Warp ==== | ||
Warps Samus to the specified map and screen. | Warps Samus to the specified map and screen. | ||
- | Form: 4byx | + | Syntax: '' |
Operands: | Operands: | ||
Line 120: | Line 128: | ||
==== 6* - Change acid & spike damage ==== | ==== 6* - Change acid & spike damage ==== | ||
- | Form: 6* xx yy | + | Syntax: '' |
Operands: | Operands: | ||
Line 127: | Line 135: | ||
* yy - spike damage | * yy - spike damage | ||
- | I'm not sure if this is ever used, but it's cool at least. | + | This is used towards the end of the game to increase the acid damage from $02 to $06. |
- | For reference, the default starting values are $02 and $08. | + | For reference, the default starting values are $02 and $08. (Note that damage values for Samus in this game are binary-coded decimal.) |
==== 7* - Exit Room After Last Boss Death ==== | ==== 7* - Exit Room After Last Boss Death ==== | ||
Line 138: | Line 146: | ||
- Disables LCD interrupt from last boss fight | - Disables LCD interrupt from last boss fight | ||
- Reloads the status bar into the window | - Reloads the status bar into the window | ||
+ | |||
==== 8* - Transition to the Queen Fight ==== | ==== 8* - Transition to the Queen Fight ==== | ||
Handles a lot of special stuff regarding the queen fight, but not everything. | Handles a lot of special stuff regarding the queen fight, but not everything. | ||
- | Form: 8a bbbb cccc dddd eeee | + | Form: '' |
* a: Bank for current room ($F) | * a: Bank for current room ($F) | ||
* b: Scroll Y position ($F48) | * b: Scroll Y position ($F48) | ||
Line 148: | Line 157: | ||
* d: Samus Y position ($F02) | * d: Samus Y position ($F02) | ||
* e: Samus X position ($EDE) | * e: Samus X position ($EDE) | ||
+ | |||
==== 9* - Conditional Operator ==== | ==== 9* - Conditional Operator ==== | ||
- | Form: 9* nn xxxx | + | Syntax: '' |
Operands: | Operands: | ||
Line 170: | Line 180: | ||
Forms: | Forms: | ||
- | - B1 bb xxxx - Load BG graphics page (128 tiles) to $9000 in VRAM. | + | |
- | - B2 bb xxxx - Load Sprite graphics page (64 tiles) to $8B00 in VRAM. | + | |
Operators: | Operators: | ||
Line 255: | Line 265: | ||
The game does not account for operators in the form of E* or F*. Using these will cause the game to freeze, because the interpreter will get stuck in an infinite loop. However, an intrepid hacker could use these to extend this language to do other radical things. | The game does not account for operators in the form of E* or F*. Using these will cause the game to freeze, because the interpreter will get stuck in an infinite loop. However, an intrepid hacker could use these to extend this language to do other radical things. | ||
- | ===== Example 1 ===== | + | ===== Shortcomings |
- | This the transition | + | Each screen can only have one transition |
- | < | + | Also, the only conditional operator that exists is for the metroid count. Checking any other byte of the save data (such as if a particular enemy or item has been collected) is unsupported. |
- | Let's make this easier to read: | + | With the disassembly, |
- | < | + | ===== Usage ===== |
- | A0 | + | |
- | B1 08 BC 69 | + | |
- | 26 | + | |
- | 36 | + | |
- | 19 | + | |
- | B2 06 20 5D | + | |
- | C5 | + | |
- | 49 E7 | + | |
- | FF | + | |
- | </ | + | |
- | Hypothetically, | + | Transition scripts can be edited in one of two ways: |
- | < | + | 1) Using the transition editor in LAMP. |
- | FADE | + | |
- | GFX_BG | + | |
- | COLLISION 6 | + | |
- | SOLID 6 | + | |
- | METATILE | + | |
- | GFX_SPR | + | |
- | SONG 5 | + | |
- | WARP 9,E,7 | + | |
- | END | + | |
- | </ | + | |
- | But that would be just silly. | + | 2) Editing [[https:// |
- | (Someone please do this.) | + | For reference, the macros the disassembly uses are as follows: |
- | ===== Example 2 ===== | + | | Opcode | Macro | |
+ | | 00 bb ssss dddd llll | COPY_DATA | | ||
+ | | 01 bb ssss dddd llll | COPY_BG | | ||
+ | | 02 bb ssss dddd llll | COPY_SPR | | ||
+ | | 1x | TILETABLE | | ||
+ | | 2x | COLLISION | | ||
+ | | 3x | SOLIDITY | | ||
+ | | 4b yx | WARP | | ||
+ | | 50 | ESCAPE_QUEEN | | ||
+ | | 60 xx yy | DAMAGE | | ||
+ | | 70 | EXIT_QUEEN | | ||
+ | | 8a bbbb cccc dddd eeee | ENTER_QUEEN | | ||
+ | | 90 nn xxxx | IF_MET_LESS | | ||
+ | | A0 | FADEOUT | | ||
+ | | B1 bb xxxx | LOAD_BG | | ||
+ | | B1 bb xxxx | LOAD_SPR | | ||
+ | | Cx | SONG | | ||
+ | | Dx | ITEM | | ||
+ | | FF | END_DOOR | | ||
- | Here's the transition to the first cave with acid. | + | ==== Example ==== |
- | < | + | This the transition from the save room in the first ruins to the exterior area: |
+ | |||
+ | < | ||
- | For reference, this is the transition script referred to in the conditional operator | + | Editing this by hand would by tedious and error-prone. However, with the disassembly |
- | < | + | < |
+ | FADEOUT | ||
+ | LOAD_BG gfx_ruinsExt | ||
+ | COLLISION $6 | ||
+ | SOLIDITY $6 | ||
+ | TILETABLE $9 | ||
+ | LOAD_SPR gfx_enemiesB | ||
+ | SONG $5 | ||
+ | WARP $9, $E7 | ||
+ | END_DOOR</ | ||
- | Deciphering | + | Notice how this is largely human-readable, |