Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- A follow-up to SomeGuy712x's Eating Block Sprite Behavior video: https://www.youtube.com/watch?v=GIN1To_Nwqg
- -------
- The game represents the adjacent solid blocks bitwise, in the format 0000udlr. For example, if there are solid blocks above and to the left of the eating block (but not below or to the right), it'll use the byte 00001010 binary, or 0A hex.
- It then uses this adjacent-block byte as an index to the direction table located at $039279.
- Direction table ($039279):
- 00 00 01 00 02 00 00 00
- 03 00 00
- This direction byte is then used as an index for two speed tables:
- X-speed table ($03926F):
- 10 F0 00 00 00
- Y-speed table ($039274):
- 00 00 10 F0 00
- Continuing with the previous example, a direction byte of 00 (index 0A in the table) will retrieve an X-speed of 10 and a Y-speed of 00. So the eating block moves to the right, even though there's no adjacent block to the right.
- Note that speeds >= 80 are considered negative (leftward or upward).
- Summarizing the direction table:
- udlr :index: X,Y speed --> explanation
- 0000 : 00 : 10,00 --> no adj : moves right (unused since the block vanishes without calling the direction table)
- 0001 : 00 : 10,00 --> r only : moves right
- 0010 : 01 : F0,00 --> l only : moves left
- 0011 : 00 : 10,00 --> l+r : moves right
- 0100 : 02 : 00,10 --> d only : moves down
- 0101 : 00 : 10,00 --> d+r : moves right
- 0110 : 00 : 10,00 --> d+l : moves right(!)
- 0111 : 00 : 10,00 --> d+l+r : moves right
- 1000 : 03 : 00,F0 --> u only : moves up
- 1001 : 00 : 10,00 --> u+r : moves right
- 1010 : 00 : 10,00 --> u+l : moves right(!)
- Note how it defaults to index 00 (right) for all normally-unused combinations of directions. Simple enough so far.
- Now here's where it gets interesting. The direction table isn't long enough for all possible adjacent-block bit combinations. However, the game doesn't care about the overflow, and will load $039279+adjacentblockbyte anyway, even though it's actually loading code bytes rather than data:
- Direction table ($039279), extended:
- 00 00 01 00 02 00 00 00
- 03 00 00 [22 B2 90 01 BC]
- These additional direction bytes are still used as indexes to the speed tables, overflowing them as well. I won't show the extended tables here for length reasons, but these are the bytes obtained:
- udlr :index: X,Y speed --> explanation
- 1011 : 22 : 03,03 --> u+l+r : slowly moves diagonally down-right, at 3/16 the usual speed
- 1100 : B2 : 20,16 --> u+d : moves right at double speed and down at 11/8 speed
- 1101 : 90 : 01,34 --> u+d+r : moves down at 13/4 the usual speed (and very slightly right, but too little to matter before it latches on to the next block)
- 1110 : 01 : F0,00 --> u+d+l : moves left, nothing special here
- 1111 : BC : 60,93 --> all : moves up-right extremely quickly
- From this code analysis I discovered two additional behaviors that weren't in SomeGuy's video:
- 1. Similar to how u+l+r and u+d+r "latch on" after a single irregular movement, u+d can latch on as well, if a block is placed in the correct location. However, that location is 11 tiles down, 16 tiles right.
- 2. After 4 u+d+r movements, the block becomes desynced, due to that 01 speed to the right adding up into a full pixel over time. Instead of moving 1 tile down then latching on, it'll quickly move down until it despawns. (Try it with a 3-block-wide down-right staircase.)
- I also tested the creating block, but the invalid direction bytes unfortunately can't be given to edited creating block paths, since the game filters out only the two lowest bits to determine the direction. Even with a hex-edit to filter out the four lowest bits instead (the upper four bits are used for distance), it still wouldn't be very interesting, since it'd only overflow the speed tables as far as the direction table, which gives little to no speed.
- ---
- Addendum:
- In hacks that use FastROM, the code after the direction table, instead of being JSL $0190B2 [22 B2 90 01], will be JSL $8190B2 [22 B2 90 81]. As such, u+d+l no longer functions as an ordinary leftward movement with FastROM.
Advertisement
Add Comment
Please, Sign In to add comment