Difference between revisions of "Null Sprite"
m (show toc) |
m (→Wings) |
||
Line 53: | Line 53: | ||
| $009E || Sprite number || $019D || Stack (uninitialized) || Must be $00-$0C for wings (Koopa sprite) | | $009E || Sprite number || $019D || Stack (uninitialized) || Must be $00-$0C for wings (Koopa sprite) | ||
|- | |- | ||
− | | $15F6 || Sprite OAM YXPPCCCT byte || $16F5 || Score sprite X position, high byte, #2 || CCC bits (----xxx-) must be 000, 011, or 111 (shell color) | + | | $15F6 || Sprite OAM YXPPCCCT byte || $16F5 || Score sprite X position, high byte, #2 || CCC bits (----xxx-) must be 000, 011, or 111 for wings (shell color) |
|- | |- | ||
| $187B || Miscellaneous sprite table || $197A || Sprite killed flag, #$42 || Must be non-zero for disco shell | | $187B || Miscellaneous sprite table || $197A || Sprite killed flag, #$42 || Must be non-zero for disco shell |
Latest revision as of 03:16, 20 August 2022
Overview
The null sprite is the non-existent sprite Yoshi has in his mouth when the slot number that indicates which sprite he is holding is outside the normal range of [0, 11]. In most cases, this index is -1, or 255. Spitting out the null sprite will appear to do nothing, as nothing leaves Yoshi's mouth; however, spitting out a null sprite can cause many different kinds of glitches (the most notable being Powerup Incrementation). Getting a null sprite in Yoshi's mouth is easily achieved by utilizing the Double Tongue glitch, or by duplicating a Yoshi block to partially transfer data from one Yoshi to another.
Technical Information
There are two important memory locations that help the game determine which sprite is in Yoshi's mouth. The first is a timer that indicates how long until Yoshi swallows a sprite. This is normally set to zero, which indicates that there is no sprite in Yoshi's mouth. When this memory address is set to something other than zero (usually 255), it begins counting down slowly. While the value is non-zero, Yoshi has a sprite in his mouth. When it finally reaches zero, the sprite is swallowed. This memory address is a standalone register, and there is only one (since there can normally only be one Yoshi present at a time).
The second memory address controls which of the 12 sprite slots Yoshi has in his mouth, given that he is holding something. The normal range of this value is [0, 11], which corresponds to one of the currently loaded sprites in the game. If Yoshi has nothing in his mouth (i.e. the previous value mentioned above is zero), this memory address is set to $FF, which is -1 or 255 (depending on if you treat the value as signed or unsigned). This memory address is located in a table of length 12--each of the 12 sprite slots have an entry into this table. The table can be used for many different things depending on which sprite is occupying the slot. When Yoshi is in the slot, the value corresponds to the sprite slot that is in his mouth. Since there is more than one entry into this table, if somehow multiple Yoshis were to exist, they could have different values in this table.
By using one of the glitches mentioned above, we can trick the game into a state where the first value is non-zero (that is, something is in Yoshi's mouth), but the second value (the slot index) is still 255. This is referred to the null sprite.
Memory that can be Modified
When a normal sprite is spit out of Yoshi's mouth, several different memory values that relate to that sprite are updated in order to make it look like it is being spat out. This includes stuff like the sprite's position and velocity, and other properties. In order to make sure the correct sprite is updated with these properties, it utilizes the sprite slot number that Yoshi has in his mouth. However, if Yoshi has a null sprite, this index is 255, which indexes all of these tables out of bounds, since they normally only have 12 entries. Here is a list of the properties that are modified.
Intended Table Address | Description | Effective Address | Description | Value Written |
---|---|---|---|---|
$00E4 | Sprite X position, low byte | $01E3 | Stack (uninitialized*) | Yoshi's X position low byte, +/- $10 (depending on direction facing) |
$14E0 | Sprite X position, high byte | $15DF | Sprite interaction table, #3 | Yoshi's X position high byte, +/- 0 or 1 (depending on direction facing) |
$00D8 | Sprite Y position, low byte | $01D7 | Stack (uninitialized) | Yoshi's Y position low byte |
$14D4 | Sprite Y position, high byte | $15D3 | Sprite about to be eaten table, #3 | Yoshi's Y position high byte |
$00C2 | Miscellaneous sprite table | $01C1 | Stack (uninitialized) | 0 |
$15D0 | Sprite about to be eaten | $16CF | Bounce sprite interaction table, #2 | 0 |
$1626 | Sprite kill counter | $1725 | Extended sprite X position, low byte, #6 | 0 |
$14C8 | Sprite status | $15C7 | Sprite off-screen processing table, #3 | $09 (if standing), $0A (if ducking) |
$157C | Sprite facing direction | $167B | Tweaker byte 4, #1 | Yoshi's facing direction (0 or 1) |
$00B6 | Sprite X speed | $01B5 | stack (uninitialized) | +/- $30 (if standing), +/- $10 (if ducking) |
$00AA | Sprite Y speed | $01A9 | stack (uninitialized) | 0 |
* This value is far enough down in the stack that it actually is used by the game in certain contexts, most notably while standing on a brown swinging platform.
Wings
Sometimes Yoshi has wings while he has a null sprite in his mouth, and sometimes he doesn't. This is dependent on uninitialized memory. Essentially, the game reads a memory address that is never ever written to by the game at any point. This means that the value that gets read is undefined and depends on the resting state of the specific memory chip in the console. Therefore, it could be possible that certain consoles "default" to having wings, and others "default" to not having wings. In the case of emulators, flash carts, and other software implementations, the state of the memory is usually initialized to a consistent, known state before the game is even started. This will result in Yoshi always or never having wings, depending on the implementation.
Here are some relevant memory locations.
Intended Table Address | Description | Effective Address | Description | Value Needed |
---|---|---|---|---|
$009E | Sprite number | $019D | Stack (uninitialized) | Must be $00-$0C for wings (Koopa sprite) |
$15F6 | Sprite OAM YXPPCCCT byte | $16F5 | Score sprite X position, high byte, #2 | CCC bits (----xxx-) must be 000, 011, or 111 for wings (shell color) |
$187B | Miscellaneous sprite table | $197A | Sprite killed flag, #$42 | Must be non-zero for disco shell |
The $019D stack value is the most important byte. The natural resting state of the memory chip at this particular memory location must be $00-$0C for Yoshi to have wings. If it is, then the game thinks the null sprite is a Koopa sprite, and will then check another table to see what color the Koopa is. Normal values for the CCC bits in this table are 010, 011, 100, or 101 (yellow, blue, red, green), but 000 and 111 will give Yoshi wings as well. The value at $16F5 is generally zero most of the time, which works. Additionally, if the value at $197A happens to be non-zero, Yoshi will not only have wings, but will have stomping power and spit fire as if he had a disco shell in his mouth.