|
1 | 1 |
|
2 | | -# VRAM Sprite Attribute Table (OAM) |
| 2 | +# Object Attribute Memory (OAM) |
3 | 3 |
|
4 | | -The Game Boy PPU can display up to 40 sprites either in 8x8 or |
5 | | -in 8x16 pixels. Because of a limitation of hardware, only ten sprites |
6 | | -can be displayed per scan line. Sprite tiles have the same format as |
7 | | -BG tiles, but they are taken from the Sprite Tiles Table located at |
| 4 | +The Game Boy PPU can display up to 40 movable objects (or sprites), each 8×8 or |
| 5 | +8×16 pixels. Because of a limitation of hardware, only ten objects |
| 6 | +can be displayed per scanline. Object tiles have the same format as |
| 7 | +BG tiles, but they are taken from tile blocks 0 and 1 located at |
8 | 8 | $8000-8FFF and have unsigned numbering. |
9 | 9 |
|
10 | | -Sprite attributes reside in the Sprite Attribute Table (OAM: Object |
11 | | -Attribute Memory) at \$FE00-FE9F. Each of the 40 entries consists of |
| 10 | +Object attributes reside in the object attribute memory (OAM) at \$FE00-FE9F. |
| 11 | +(This corresponds to the sprite attribute table on a TMS9918 VDP.) |
| 12 | +Each of the 40 entries consists of |
12 | 13 | four bytes with the following meanings: |
13 | 14 |
|
14 | 15 | ## Byte 0 — Y Position |
15 | 16 |
|
16 | | -Y = Sprite's vertical position on the screen + 16. So for example, |
17 | | -Y=0 hides a sprite, |
18 | | -Y=2 hides an 8×8 sprite but displays the last two rows of an 8×16 sprite, |
19 | | -Y=16 displays a sprite at the top of the screen, |
20 | | -Y=144 displays an 8×16 sprite aligned with the bottom of the screen, |
21 | | -Y=152 displays an 8×8 sprite aligned with the bottom of the screen, |
22 | | -Y=154 displays the first six rows of a sprite at the bottom of the screen, |
23 | | -Y=160 hides a sprite. |
| 17 | + |
| 18 | + |
| 19 | +Y = Object's vertical position on the screen + 16. So for example: |
| 20 | + |
| 21 | +- Y=0 hides an object, |
| 22 | +- Y=2 hides an 8×8 object but displays the last two rows of an 8×16 object, |
| 23 | +- Y=16 displays an object at the top of the screen, |
| 24 | +- Y=144 displays an 8×16 object aligned with the bottom of the screen, |
| 25 | +- Y=152 displays an 8×8 object aligned with the bottom of the screen, |
| 26 | +- Y=154 displays the first six rows of an object at the bottom of the screen, |
| 27 | +- Y=160 hides an object. |
24 | 28 |
|
25 | 29 | ## Byte 1 — X Position |
26 | 30 |
|
27 | | -X = Sprite's horizontal position on the screen + 8. This works similarly |
28 | | -to the examples above, except that the width of a sprite is always 8. An |
29 | | -off-screen value (X=0 or X\>=168) hides the sprite, but the sprite still |
30 | | -affects the priority ordering, thus other sprites with lower priority may be |
31 | | -left out due to the ten sprites limit per scan-line. |
32 | | -A better way to hide a sprite is to set its Y-coordinate off-screen. |
| 31 | +X = Object's horizontal position on the screen + 8. This works similarly |
| 32 | +to the examples above, except that the width of an object is always 8. An |
| 33 | +off-screen value (X=0 or X\>=168) hides the object, but the object still |
| 34 | +contributes to the limit of ten objects per scanline. |
| 35 | +This can cause objects later in OAM not to be drawn on that line. |
| 36 | +A better way to hide an object is to set its Y-coordinate off-screen. |
33 | 37 |
|
34 | 38 | ## Byte 2 — Tile Index |
35 | 39 |
|
36 | | -In 8x8 mode (LCDC bit 2 = 0), this byte specifies the sprite's only tile index ($00-$FF). |
37 | | -This unsigned value selects a tile from the memory area at $8000-$8FFF. |
| 40 | +In 8×8 mode (LCDC bit 2 = 0), this byte specifies the object's only tile index (\$00-\$FF). |
| 41 | +This unsigned value selects a tile from the memory area at \$8000-\$8FFF. |
38 | 42 | In CGB Mode this could be either in |
39 | 43 | VRAM bank 0 or 1, depending on bit 3 of the following byte. |
40 | | -In 8x16 mode (LCDC bit 2 = 1), the memory area at $8000-$8FFF is still interpreted |
41 | | -as a series of 8x8 tiles, where every 2 tiles form a sprite. In this mode, this byte |
42 | | -specifies the index of the first (top) tile of the sprite. This is enforced by the |
43 | | -hardware: the least significant bit of the tile index is ignored; that is, the top 8x8 |
44 | | -tile is "NN & $FE", and the bottom 8x8 tile is "NN | $01". |
| 44 | +In 8×16 mode (LCDC bit 2 = 1), the memory area at \$8000-\$8FFF is still interpreted |
| 45 | +as a series of 8×8 tiles, where every 2 tiles form an object. In this mode, this byte |
| 46 | +specifies the index of the first (top) tile of the object. This is enforced by the |
| 47 | +hardware: the least significant bit of the tile index is ignored; that is, the top 8×8 |
| 48 | +tile is "NN & \$FE", and the bottom 8×8 tile is "NN | \$01". |
45 | 49 |
|
46 | 50 | ## Byte 3 — Attributes/Flags |
47 | 51 |
|
@@ -87,7 +91,7 @@ limit, possibly causing another object later in OAM not |
87 | 91 | to be drawn. To keep off-screen objects from affecting on-screen ones, make |
88 | 92 | sure to set their Y coordinate to Y = 0 or Y ≥ 160 |
89 | 93 | (144 + 16). |
90 | | -(Y ≤ 8 also works if [object size](<#LCDC.2 — OBJ size>) is set to 8x8.) |
| 94 | +(Y ≤ 8 also works if [object size](<#LCDC.2 — OBJ size>) is set to 8×8.) |
91 | 95 |
|
92 | 96 | ### Drawing priority |
93 | 97 |
|
|
0 commit comments