Sprite: Difference between revisions
Piranhaplant (talk | contribs) No edit summary |
Piranhaplant (talk | contribs) No edit summary |
||
(7 intermediate revisions by the same user not shown) | |||
Line 7: | Line 7: | ||
{| class="wikitable" |
{| class="wikitable" |
||
|- |
|- |
||
! Offset !! Length !! Type !! Description |
! Offset !! Length !! [[Data types|Type]] !! Description |
||
|- |
|- |
||
| 0x00 || 2 || bit field || [[#Sprite properties|Sprite properties]] |
| 0x00 || 2 || bit field || [[#Sprite properties|Sprite properties]] |
||
Line 17: | Line 17: | ||
| 0x06 || 2 || int16 || Y position |
| 0x06 || 2 || int16 || Y position |
||
|- |
|- |
||
| 0x08 || 4 || pointer32 || Pointer to sprite tile data |
| 0x08 || 4 || optional pointer32 || Pointer to sprite tile data |
||
|- |
|- |
||
| 0x0C || 2 || uint16 x2 || Parent entity ID |
| 0x0C || 2 || uint16 x2 || Parent entity ID |
||
Line 61: | Line 61: | ||
{| class="wikitable" |
{| class="wikitable" |
||
|- |
|- |
||
! Offset !! Length !! Type !! Description |
! Offset !! Length !! [[Data types|Type]] !! Description |
||
|- |
|- |
||
| 0x00 || 1 || byte || Tile count (also see [[#Extended sprite tile data|extended sprite tile data]]) |
| 0x00 || 1 || byte || Tile count (also see [[#Extended sprite tile data|extended sprite tile data]]) |
||
Line 72: | Line 72: | ||
{| class="wikitable" |
{| class="wikitable" |
||
|- |
|- |
||
! Offset !! Length !! Type !! Description |
! Offset !! Length !! [[Data types|Type]] !! Description |
||
|- |
|- |
||
| 0x00 || 2 || int16 || X position |
| 0x00 || 2 || int16 || X position |
||
Line 83: | Line 83: | ||
|} |
|} |
||
The sprite graphics are located at [[$84:8000]] and each is 0x80 bytes long, so the address of the graphics for a given tile number can be calculated as "0x20000 + TileNumber * 0x80". |
The sprite graphics are located at [[$84:8000]] and each 16x16 tile is 0x80 bytes long, so the address of the graphics for a given tile number can be calculated as "0x20000 + TileNumber * 0x80". |
||
==== Tile properties ==== |
==== Tile properties ==== |
||
Line 100: | Line 100: | ||
== Sprite types == |
== Sprite types == |
||
⚫ | |||
Highlighted rows are sprite types that are considered solid (see [[#Solid sprites|solid sprites]]). |
|||
⚫ | |||
|- |
|- |
||
! Type !! Description |
! Type !! Description !! Solid to<br />players !! Solid to<br />monsters |
||
|- |
|- |
||
| 0x0000 || None. Sprites set to this type will have no collision. |
| 0x0000 || None. Sprites set to this type will have no collision. || || |
||
|- |
|- |
||
| 0x0001 || Victim |
| 0x0001 || Victim || || ✓ |
||
|- |
|- |
||
| 0x0002 || Monster that does no damage |
| 0x0002 || Monster that does no damage || || ✓ |
||
|- class="highlightrow" |
|||
⚫ | |||
|- class="highlightrow" |
|||
⚫ | |||
|- |
|- |
||
⚫ | |||
⚫ | |||
|- |
|- |
||
⚫ | |||
| 0x0006 || Julie |
|||
|- |
|- |
||
⚫ | |||
⚫ | |||
|- |
|- |
||
| |
| 0x0006 || Julie || || ✓ |
||
|- class="highlightrow" |
|||
⚫ | |||
|- class="highlightrow" |
|||
⚫ | |||
|- class="highlightrow" |
|||
⚫ | |||
|- |
|- |
||
⚫ | |||
⚫ | |||
|- |
|- |
||
| 0x0008 || Unused type that damages [[evil doll axe]]s || || |
|||
⚫ | |||
|- |
|- |
||
⚫ | |||
⚫ | |||
|- |
|- |
||
⚫ | |||
⚫ | |||
|- |
|- |
||
⚫ | |||
⚫ | |||
|- |
|- |
||
| |
| 0x000C || [[Squirt gun]] [[item pickup]] || || |
||
|- |
|- |
||
| |
| 0x000D || [[Fire extinguisher]] item pickup || || |
||
|- |
|- |
||
| |
| 0x000E || [[Martian bubble gun]] item pickup || || |
||
|- |
|- |
||
| |
| 0x000F || [[Weed-eater]] item pickup || || |
||
|- |
|- |
||
| |
| 0x0010 || [[Ancient artifact]] item pickup || || |
||
|- |
|- |
||
| |
| 0x0011 || [[Bazooka]] item pickup || || |
||
|- |
|- |
||
| |
| 0x0012 || [[Soda pop cans]] item pickup || || |
||
|- |
|- |
||
| |
| 0x0013 || [[Tomatoes]] item pickup || || |
||
|- |
|- |
||
| |
| 0x0014 || [[Ice pops]] item pickup || || |
||
|- |
|||
⚫ | |||
|- |
|||
⚫ | |||
|- |
|||
| 0x0017 || [[Silverware]] item pickup || || |
|||
|- |
|||
| 0x0018 || [[Football]] item pickup || || |
|||
|- |
|||
| 0x0019 || [[Flamethrower]] item pickup || || |
|||
|- class="breakrow" |
|- class="breakrow" |
||
| 0x0021 || [[Key]] item pickup |
| 0x0021 || [[Key]] item pickup || || |
||
|- |
|||
⚫ | |||
|- |
|||
⚫ | |||
|- |
|||
⚫ | |||
|- |
|||
⚫ | |||
|- |
|- |
||
| |
| 0x0026 || [[Grey potion]] item pickup || || |
||
|- |
|- |
||
| |
| 0x0027 || [[Hamburger]] item pickup || || |
||
|- |
|- |
||
| |
| 0x0028 || [[First aid kit]] item pickup || || |
||
|- |
|- |
||
| |
| 0x0029 || [[Pandora's box]] item pickup || || |
||
|- |
|- |
||
| |
| 0x002A || [[Skeleton key]] item pickup || || |
||
|- |
|- |
||
| |
| 0x002B || [[Decoys]] item pickup || || |
||
|- |
|- |
||
| |
| 0x002C || [[Pile of keys]] || || |
||
|- |
|- |
||
| |
| 0x002D || [[Secret item]] || || |
||
|- |
|- |
||
| |
| 0x002E || [[1up]] || || |
||
|- |
|- |
||
| |
| 0x002F || [[Gold]] || || |
||
|- |
|- |
||
| |
| 0x0030 || [[Dollar bills]] || || |
||
|- |
|- |
||
| |
| 0x0031 || Unused item pickup type || || |
||
|- |
|- |
||
| 0x0032 || Unused item pickup type || || |
|||
| 0x002E || [[1up]] |
|||
|- |
|- |
||
⚫ | |||
| 0x002F || [[Gold]] |
|||
|- |
|- |
||
| |
| 0x0034 || [[Jelly blob]] shot || ✓ || ✓ |
||
|- |
|- |
||
⚫ | |||
⚫ | |||
|- |
|- |
||
| |
| 0x0036 || Frozen monster || ✓ || ✓ |
||
|- |
|- |
||
⚫ | |||
⚫ | |||
|- class="highlightrow" |
|||
| 0x0034 || [[Jelly blob]] shot |
|||
|- class="highlightrow" |
|||
⚫ | |||
|- class="highlightrow" |
|||
| 0x0036 || Frozen monster |
|||
|- |
|- |
||
⚫ | |||
⚫ | |||
|- class="highlightrow" |
|||
⚫ | |||
|- class="breakrow" |
|- class="breakrow" |
||
| 0x0040 || Victim insta-killer used by [[Debug.asm]] |
| 0x0040 || Victim insta-killer used by [[Debug.asm]] || || |
||
|- class="breakrow" |
|- class="breakrow" |
||
| 0x005C || [[Squirt gun]] shot from Zeke |
| 0x005C || [[Squirt gun]] shot from Zeke || || ✓ |
||
|- |
|- |
||
| 0x005D || [[Fire extinguisher]] shot from Zeke |
| 0x005D || [[Fire extinguisher]] shot from Zeke || || ✓ |
||
|- |
|- |
||
| 0x005E || [[Martian bubble gun]] shot from Zeke |
| 0x005E || [[Martian bubble gun]] shot from Zeke || || ✓ |
||
|- |
|- |
||
| 0x005F || [[Weed-eater]] shot from Zeke |
| 0x005F || [[Weed-eater]] shot from Zeke || || ✓ |
||
|- |
|- |
||
| 0x0060 || [[Ancient artifact]] shot from Zeke/invincible after dying damage from Zeke |
| 0x0060 || [[Ancient artifact]] shot from Zeke/invincible after dying damage from Zeke || || ✓ |
||
|- |
|- |
||
| 0x0061 || [[Bazooka]] shot from Zeke |
| 0x0061 || [[Bazooka]] shot from Zeke || || ✓ |
||
|- |
|- |
||
| 0x0062 || [[Soda pop cans]]/[[Flamethrower]] shot from Zeke |
| 0x0062 || [[Soda pop cans]]/[[Flamethrower]] shot from Zeke || || ✓ |
||
|- |
|- |
||
| 0x0063 || [[Tomatoes]] shot from Zeke |
| 0x0063 || [[Tomatoes]] shot from Zeke || || ✓ |
||
|- |
|- |
||
| 0x0064 || [[Ice pops]]/[[Bananas]] shot from Zeke |
| 0x0064 || [[Ice pops]]/[[Bananas]] shot from Zeke || || ✓ |
||
|- |
|- |
||
| 0x0065 || Unused, but damages [[fire]] |
| 0x0065 || Unused, but damages [[fire]] || || ✓ |
||
|- |
|- |
||
| 0x0066 || [[Plate]] shot from Zeke |
| 0x0066 || [[Plate]] shot from Zeke || || ✓ |
||
|- |
|- |
||
| 0x0067 || [[Silverware]] shot from Zeke |
| 0x0067 || [[Silverware]] shot from Zeke || || ✓ |
||
|- |
|- |
||
| 0x0068 || [[Football]] shot from Zeke |
| 0x0068 || [[Football]] shot from Zeke || || ✓ |
||
|- |
|- |
||
| 0x0069 || Pop-up wall |
| 0x0069 || Pop-up wall || || ✓ |
||
|- |
|- |
||
| 0x006A || Unused weapon shot type |
| 0x006A || Unused weapon shot type || || ✓ |
||
|- |
|- |
||
| 0x006B || Unused weapon shot type |
| 0x006B || Unused weapon shot type || || ✓ |
||
|- |
|- |
||
| 0x006C || Unused weapon shot type |
| 0x006C || Unused weapon shot type || || ✓ |
||
|- |
|- |
||
| 0x006D || Unused weapon shot type |
| 0x006D || Unused weapon shot type || || ✓ |
||
|- |
|- |
||
| 0x006E || Unused weapon shot type |
| 0x006E || Unused weapon shot type || || ✓ |
||
|- |
|- |
||
| 0x006F || [[Pandora's box]] shot from Zeke |
| 0x006F || [[Pandora's box]] shot from Zeke || || ✓ |
||
|- |
|- |
||
| 0x0070 || [[Monster potion]] punch from Zeke |
| 0x0070 || [[Monster potion]] punch from Zeke || || ✓ |
||
|- class="breakrow" |
|- class="breakrow" |
||
| 0x00FF || |
| 0x00FF || One-shot monster/victim went off screen || || |
||
|} |
|} |
||
Line 271: | Line 269: | ||
== Collision == |
== Collision == |
||
[[Entity|Entities]] can call [[$80:8475]] to set a collision handler for the sprites they own. When a sprite collides with another sprite, the collision handler of the parent entity of each sprite is called, with the type of the sprite it collided with provided in the accumulator. In addition, [[$7E:0076]] and [[$7E:0078]] can be used to access the two sprites involved in the collision. The collision handlers are set per entity, so even if an entity has multiple sprites, they must share the same collision handler. |
[[Entity|Entities]] can call [[$80:8475]] to set a collision handler for the sprites they own. When a sprite collides with another sprite, the collision handler of the parent entity of each sprite is called, with the type of the sprite it collided with provided in the accumulator. In addition, [[$7E:0076]] and [[$7E:0078]] can be used to access the two sprites involved in the collision. The collision handlers are set per entity, so even if an entity has multiple sprites, they must share the same collision handler. Collision handlers are run outside the context of the entity, so [[$80:8353]] cannot be called to wait. However, the direct page will be set to the entity memory, so data from there can be accessed. |
||
The collision handler returns a value in the carry flag. If this value is set, then the entity will be immediately resumed, regardless of how much was left in its current wait timer. |
The collision handler returns a value in the carry flag. If this value is set, then the entity will be immediately resumed, regardless of how much was left in its current wait timer. |
||
Sprites are considered collided if their X and Y positions are both less than 8 pixels apart, they are both on-screen, they both have non-zero sprite type, and they have different sprite types. Collision can also triggered over an arbitrary area by calling [[$80:BF1B]]. The same restrictions on sprite type apply to this as well. |
Sprites are considered collided if their X and Y positions are both less than 8 pixels apart, they are both on-screen (meaning they must be visible), they both have non-zero sprite type, and they have different sprite types. Collision can also triggered over an arbitrary area by calling [[$80:BF1B]]. The same restrictions on sprite type apply to this as well. |
||
=== Solid sprites === |
=== Solid sprites === |
||
Certain sprite types are considered solid. That is, players |
Certain sprite types are considered solid. That is, players or monsters will not be able to move through them. Sprite types that are solid are shown in the [[#Sprite types|sprite type]] table above. In addition, types 0x39 through 0x5B are solid to both players and monsters, and types 0x71 and greater are solid to monsters, but these types are not used in the original game. |
||
Solid sprites are implemented in a different way from normal sprite collision. An entity must manually call [[$80:BFC8]] to check if a given position is |
Solid sprites are implemented in a different way from normal sprite collision. An entity must manually call [[$80:BFC8]] to check if a given position is solid to players, or [[$80:BF67]] to check if a position is solid to monsters. |
||
The area for solid sprites is slightly smaller than for regular collision. A position is considered touching a solid sprite if it is within 6 pixels of the right or bottom, or within 5 pixels of the left or top. The area is smaller so that sprites will trigger regular collision before stopping due to running into a solid sprite. |
The area for solid sprites is slightly smaller than for regular collision. A position is considered touching a solid sprite if it is within 6 pixels of the right or bottom, or within 5 pixels of the left or top. The area is smaller so that sprites will trigger regular collision before stopping due to running into a solid sprite. |
Latest revision as of 16:36, 13 July 2024
Sprites are used to display things on the screen using the SNES's "objects". All sprites are made of a number of 16x16 objects. There can be up to 32 sprites displayed at a time.
Sprite data structure[edit]
Sprites in the sprite table ($7E:185E) have the following format:
Offset | Length | Type | Description |
---|---|---|---|
0x00 | 2 | bit field | Sprite properties |
0x02 | 2 | int16 | X position |
0x04 | 2 | int16 | Z position |
0x06 | 2 | int16 | Y position |
0x08 | 4 | optional pointer32 | Pointer to sprite tile data |
0x0C | 2 | uint16 x2 | Parent entity ID |
0x0E | 2 | uint16 | Sprite type |
0x10 | 2 | uint16 | Alternate palette (shifted 9 bits left to align with the tile properties palette) |
0x12 | 2 | optional pointer16 | Pointer to next sprite |
The "pointer to next sprite" value creates a linked list of all sprites. The first element of the list is set by $7E:1B5E. The sprites are ordered in the list from front-most to back-most. That is, sprites earlier in the list will appear in front of sprites later in the list. See "display ordering" for details.
Sprite properties[edit]
Bit mask | Description |
---|---|
0x0001 | Sprite entry is used |
0x0002 | Flip horizontally |
0x0004 | Flip vertically |
0x0008 | Background priority |
0x0010 | Use alternate palette |
0x0020 | Appear on top of other sprites |
0x4000 | Absolute positioning |
0x8000 | Visible |
Sprite Tile Data[edit]
Sprite tile data is generally located in the ROM, and contains the arrangement of 16x16 tiles used to make up the full sprite.
Header[edit]
Offset | Length | Type | Description |
---|---|---|---|
0x00 | 1 | byte | Tile count (also see extended sprite tile data) |
Tile data[edit]
This data is repeated for each tile (up to "Tile count" from the header)
Offset | Length | Type | Description |
---|---|---|---|
0x00 | 2 | int16 | X position |
0x02 | 2 | int16 | Y position |
0x04 | 2 | bit field | Tile properties |
0x06 | 2 | uint16 | Tile number |
The sprite graphics are located at $84:8000 and each 16x16 tile is 0x80 bytes long, so the address of the graphics for a given tile number can be calculated as "0x20000 + TileNumber * 0x80".
Tile properties[edit]
Bit mask | Description |
---|---|
0x0E00 | Palette |
0x4000 | Flip horizontally |
0x8000 | Flip vertically |
Sprite types[edit]
Type | Description | Solid to players |
Solid to monsters |
---|---|---|---|
0x0000 | None. Sprites set to this type will have no collision. | ||
0x0001 | Victim | ✓ | |
0x0002 | Monster that does no damage | ✓ | |
0x0003 | Monster | ✓ | ✓ |
0x0004 | Ant that isn't holding an item pickup | ✓ | ✓ |
0x0005 | Zeke | ✓ | |
0x0006 | Julie | ✓ | |
0x0007 | Wall breaking from player punching it as a monster | ||
0x0008 | Unused type that damages evil doll axes | ||
0x0009 | Monster projectiles | ✓ | ✓ |
0x000A | Giant baby flattening the player | ✓ | ✓ |
0x000B | Bubble shot by martian | ✓ | ✓ |
0x000C | Squirt gun item pickup | ||
0x000D | Fire extinguisher item pickup | ||
0x000E | Martian bubble gun item pickup | ||
0x000F | Weed-eater item pickup | ||
0x0010 | Ancient artifact item pickup | ||
0x0011 | Bazooka item pickup | ||
0x0012 | Soda pop cans item pickup | ||
0x0013 | Tomatoes item pickup | ||
0x0014 | Ice pops item pickup | ||
0x0015 | Bananas item pickup | ||
0x0016 | Plate item pickup | ||
0x0017 | Silverware item pickup | ||
0x0018 | Football item pickup | ||
0x0019 | Flamethrower item pickup | ||
0x0021 | Key item pickup | ||
0x0022 | Speed shoes item pickup | ||
0x0023 | Monster potion item pickup | ||
0x0024 | Ghost kid potion item pickup | ||
0x0025 | Random potion item pickup | ||
0x0026 | Grey potion item pickup | ||
0x0027 | Hamburger item pickup | ||
0x0028 | First aid kit item pickup | ||
0x0029 | Pandora's box item pickup | ||
0x002A | Skeleton key item pickup | ||
0x002B | Decoys item pickup | ||
0x002C | Pile of keys | ||
0x002D | Secret item | ||
0x002E | 1up | ||
0x002F | Gold | ||
0x0030 | Dollar bills | ||
0x0031 | Unused item pickup type | ||
0x0032 | Unused item pickup type | ||
0x0033 | Unused | ||
0x0034 | Jelly blob shot | ✓ | ✓ |
0x0035 | Football player | ✓ | ✓ |
0x0036 | Frozen monster | ✓ | ✓ |
0x0037 | Exit door | ✓ | |
0x0038 | Decoys/Player who is invincible after dying | ✓ | ✓ |
0x0040 | Victim insta-killer used by Debug.asm | ||
0x005C | Squirt gun shot from Zeke | ✓ | |
0x005D | Fire extinguisher shot from Zeke | ✓ | |
0x005E | Martian bubble gun shot from Zeke | ✓ | |
0x005F | Weed-eater shot from Zeke | ✓ | |
0x0060 | Ancient artifact shot from Zeke/invincible after dying damage from Zeke | ✓ | |
0x0061 | Bazooka shot from Zeke | ✓ | |
0x0062 | Soda pop cans/Flamethrower shot from Zeke | ✓ | |
0x0063 | Tomatoes shot from Zeke | ✓ | |
0x0064 | Ice pops/Bananas shot from Zeke | ✓ | |
0x0065 | Unused, but damages fire | ✓ | |
0x0066 | Plate shot from Zeke | ✓ | |
0x0067 | Silverware shot from Zeke | ✓ | |
0x0068 | Football shot from Zeke | ✓ | |
0x0069 | Pop-up wall | ✓ | |
0x006A | Unused weapon shot type | ✓ | |
0x006B | Unused weapon shot type | ✓ | |
0x006C | Unused weapon shot type | ✓ | |
0x006D | Unused weapon shot type | ✓ | |
0x006E | Unused weapon shot type | ✓ | |
0x006F | Pandora's box shot from Zeke | ✓ | |
0x0070 | Monster potion punch from Zeke | ✓ | |
0x00FF | One-shot monster/victim went off screen |
Weapon shots from Julie are the same type as those from Zeke, except with the high bit set.
Display ordering[edit]
Sprites are sorted in order to have the correct sprites display on top of each other. The criteria used is as follows:
- Sprites with the "Appear on top of other sprites" property set will appear on top of those that don't.
- If two sprites have the same above value, the one with the greater value for "Y position" will appear on top.
Positioning[edit]
There are two positioning options for sprites, which is determined by the "Absolute positioning" property.
If absolute positioning is not enabled, the camera position ($7E:1B6A and $7E:1B6C) is subtracted from the X and Y positions. Then the Z position is subtracted from the Y position. This has the effect of shifting the sprite upwards on the screen without changing the display ordering.
If absolute positioning is enabled, the X and Y positions are treated as absolute screen positions, and the camera position is not used. Sprites with this setting enabled are also always considered on-screen, thus will always be processed. The Z position is also not used in this mode.
Collision[edit]
Entities can call $80:8475 to set a collision handler for the sprites they own. When a sprite collides with another sprite, the collision handler of the parent entity of each sprite is called, with the type of the sprite it collided with provided in the accumulator. In addition, $7E:0076 and $7E:0078 can be used to access the two sprites involved in the collision. The collision handlers are set per entity, so even if an entity has multiple sprites, they must share the same collision handler. Collision handlers are run outside the context of the entity, so $80:8353 cannot be called to wait. However, the direct page will be set to the entity memory, so data from there can be accessed.
The collision handler returns a value in the carry flag. If this value is set, then the entity will be immediately resumed, regardless of how much was left in its current wait timer.
Sprites are considered collided if their X and Y positions are both less than 8 pixels apart, they are both on-screen (meaning they must be visible), they both have non-zero sprite type, and they have different sprite types. Collision can also triggered over an arbitrary area by calling $80:BF1B. The same restrictions on sprite type apply to this as well.
Solid sprites[edit]
Certain sprite types are considered solid. That is, players or monsters will not be able to move through them. Sprite types that are solid are shown in the sprite type table above. In addition, types 0x39 through 0x5B are solid to both players and monsters, and types 0x71 and greater are solid to monsters, but these types are not used in the original game.
Solid sprites are implemented in a different way from normal sprite collision. An entity must manually call $80:BFC8 to check if a given position is solid to players, or $80:BF67 to check if a position is solid to monsters.
The area for solid sprites is slightly smaller than for regular collision. A position is considered touching a solid sprite if it is within 6 pixels of the right or bottom, or within 5 pixels of the left or top. The area is smaller so that sprites will trigger regular collision before stopping due to running into a solid sprite.
Necrofy enhancements[edit]
Extra sprite graphics[edit]
The ROM only includes space for 2982 sprite tiles. In order to allow for more graphics, tiles with a tile number greater than or equal to this value are located in a second section of sprite graphics. The location and size of this is specified in the Necrofy properties. The total number of sprite tiles still can't exceed 0x1000 (4096) or it would overflow the table at $7E:2128.
Extended sprite tile data[edit]
In order to allow extra tiles to be added to existing sprite tile data, the format was extended. In the extended format, if the high bit of the "Tile count" is set, then following the tile data is a 4 byte pointer to additional sprite tile data (and the high bit is removed from the tile count). There is also 4 zero bytes following the pointer. The data located at the pointer contains the full sprite tile data including the header.
Related RAM addresses[edit]
Address | Length | Type | Description |
---|---|---|---|
$7E:185E | 0x280 | byte[0x14][0x20] | Sprite table. 0x14 bytes for each of 0x20 sprites. |
$7E:1B5E | 2 | pointer16 | Pointer to first sprite in sprite table ($7E:185E) |