This is an old revision of the document!
Sprite objects are general use spritemaps, driven by an instruction set. Generally, they are utilized as 'particle effects', such as dust, explosions, or flashes, but they are also utilized by certain enemies to allow for additional sprite-maps to be drawn simultaneously without requiring additional enemies. If you're programming a custom item, enemy, or other such thing, sprite objects are a great, simple way to add graphical effects to your custom code.
To spawn a sprite object, you first need to set 4 addresses in ram with parameters for that sprite object:
$12: The X position to spawn your sprite object $14: The Y position to spawn your sprite object $16: the Sprite object ID (see table below) $18: The base tile number and palette bits to spawn your sprite object with
To actually spawn the sprite object, you need to call the routine in bank $B4 which does so, using the following operation:
JSL $B4BC26
For any sprite object that uses graphics from the game's uncompressed, general use sprite graphic set, you're most likely going to need to store zero to $18. In cases where sprite objects need to use different palettes or graphics sets, the value stored to $18 will vary.
In order to delete a sprite object, the instruction list of that sprite object needs to run the instruction $BD07. Otherwise, you can clear all of the sprite objects by calling the routine at $B4BD97.
Sprite Object ID | Description | Base tile number / palette bits |
---|---|---|
00 | Grapple Flash | #$0000 |
01 | Charge beam sparks | #$0000 |
02 | Charge beam sparks + flash | #$0000 |
03 | Super missile explosion | #$0000 |
04 | Bomb explosion | #$0000 |
05 | Ice beam particles | #$0000 |
06 | Dud shot | #$0000 |
07 | Power bomb | #$0000 |
08 | Some sort of energy shot, only 1 frame | #$0000 |
09 | Smoke plume | #$0000 |
0A | Dust 1 | #$0000 |
0B | Dust 2 | #$0000 |
0C | Unused? Explosion | #$0000 |
0D | Small health pickup | #$0000 |
0E | Large health pickup | #$0000 |
0F | Morph bomb | #$0000 |
10 | Slower small health pickup | #$0000 |
11 | Screw attack kill particles | #$0000 |
12 | Large, fast dust | #$0000 |
13 | Large, fast dust with a glitchy end frame | #$0000 |
14 | Large, fast dust with an extended glitchy end frame | #$0000 |
15 | Large, slow dust | #$0000 |
16 | Glitched space pirate shot? | #$0000 |
17 | Glitched space pirate shot? | #$0000 |
18 | Bubbles | #$0000 |
19 | Save station electricity? | #$0000 |
1A | Slowly extending vertical shutter | #$0000 |
1B | Somewhat quickly contracting vertical shutter | #$0000 |
1C | Elevator platform, permanent | #$0000 |
1D | Large enemy explosion | #$0000 |
32 | Metroid electricity | $0F96,X : ORA $0F98,X |
34 | Metroid shell | $0F96,X : ORA $0F98,X |
Within bank $B4, where the routines which create and clear sprite objects reside, you can also find the actual sprite object data. This data includes:
In order to create additional sprite objects without overwriting any data, you will need to repoint the Sprite Object pointer table. In order to do this:
At this point, all additional sprite objects and other modifications to your Sprite Object pointer table should be done to the newly repointed table. To avoid confusion, I suggest that you mark the old table as freespace by filling it with $FF
Sprite Object instructions are functionally identical to just about any other instruction formats in the rest of the rom. To put it simply, instruction lists are broken up into 4 or 3 byte chunks, containing 2 byte instructions and 1 byte arguments. These chunks follow two formats:
DW $TTTT, $PPPP ;wait $TTTT time before setting the spritemap to $PPPP. $TTTT must be < $8000, or it will be parsed as a pointer. DW $PPPP, $AA ;run the code at $PPPP with the parameter $AA. $PPPP must be >= $8000, or it will be parsed as a frame delay.
This might seem complex at first, but in practice, it can be quite simple, especially considering that Sprite Objects rarely need to run code. This instruction list, for example, would run a simple animation:
DW $0004, $F800 ;Wait 4 frames and then set the spritemap to $F800 DW $0004, $F807 ;Wait 4 frames and then set the spritemap to $F807 DW $0002, $F80E ;Wait 2 frames and then set the spritemap to $F80E DW $0001, $F815 ;Wait 1 frame and then set the spritemap to $F815 DW $0002, $F80E ;Wait 2 frames and then set the spritemap to $F80E DW $0004, $F807 ;Wait 4 frames and then set the spritemap to $F807 DW $BD07 ;Run the code at $BD07, no argument. (This points to the 'delete Sprite Object' routine.)
Note: All relevant Sprite Object instructions can be found in PJ's bank log.