Skip to content

Commit 2bfcdfa

Browse files
ISSOtmavivace
andauthored
Add "rendering overview" document (#501)
* Rename "rendering" to "graphics" This makes the section more obvious, and the page itself an overview of the graphics at a high level—the *rendering* process will be described separately in one of the upcoming commits. * Create rendering overview doc Move related information there, to avoid burying it in the middle of hardware reg documentation. Will reorganise and clean it up next. * Clean up rendering overview (first pass) * Clean up rendering overview (second pass) * Update src/Rendering.md Co-authored-by: Eldred Habert <[email protected]> * Update src/Rendering.md Co-authored-by: Eldred Habert <[email protected]> * Update src/Audio.md Co-authored-by: Eldred Habert <[email protected]> * Address reviews --------- Co-authored-by: Antonio Vivace <[email protected]>
1 parent 8aad64e commit 2bfcdfa

File tree

5 files changed

+137
-126
lines changed

5 files changed

+137
-126
lines changed

src/Graphics.md

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# Graphics Overview
2+
3+
The Game Boy outputs graphics to a 160×144 pixel LCD, using a quite complex
4+
mechanism to facilitate rendering.
5+
6+
::: warning Terminology
7+
8+
Sprites/graphics terminology can vary a lot among different platforms, consoles,
9+
users and communities. You may be familiar with slightly different definitions.
10+
Keep also in mind that some definitions refer to lower (hardware) tools
11+
and some others to higher abstractions concepts.
12+
13+
:::
14+
15+
## Tiles
16+
17+
Similarly to other retro systems, pixels are not manipulated
18+
individually, as this would be expensive CPU-wise. Instead, pixels are grouped
19+
in 8×8 squares, called _tiles_ (or sometimes "patterns" or "characters"), often considered as
20+
the base unit in Game Boy graphics.
21+
22+
A tile does not encode color information. Instead, a tile assigns a
23+
_color ID_ to each of its pixels, ranging from 0 to 3. For this reason,
24+
Game Boy graphics are also called _2bpp_ (2 bits per pixel). When a tile is used
25+
in the Background or Window, these color IDs are associated with a _palette_. When
26+
a tile is used in an object, the IDs 1 to 3 are associated with a palette, but
27+
ID 0 means transparent.
28+
29+
## Palettes
30+
31+
A palette consists of an array of colors, 4 in the Game Boy's case.
32+
Palettes are stored differently in monochrome and color versions of the console.
33+
34+
Modifying palettes enables graphical effects such as quickly flashing some graphics (damage,
35+
invulnerability, thunderstorm, etc.), fading the screen, "palette swaps", and more.
36+
37+
## Layers
38+
39+
The Game Boy has three "layers", from back to front: the Background, the Window,
40+
and the Objects. Some features and behaviors break this abstraction,
41+
but it works for the most part.
42+
43+
### Background
44+
45+
The background is composed of a _tilemap_. A tilemap is a
46+
large grid of tiles. However, tiles aren't directly written to tilemaps,
47+
they merely contain references to the tiles.
48+
This makes reusing tiles very cheap, both in CPU time and in
49+
required memory space, and it is the main mechanism that helps work around the
50+
paltry 8 KiB of video RAM.
51+
52+
The background can be made to scroll as a whole, writing to two
53+
hardware registers. This makes scrolling very cheap.
54+
55+
### Window
56+
57+
The window is sort of a second background layer on top of the background.
58+
It is fairly limited: it has no transparency, it's always a
59+
rectangle and only the position of the top-left pixel can be controlled.
60+
61+
Possible usage include a fixed status bar in an otherwise scrolling game (e.g.
62+
_Super Mario Land 2_).
63+
64+
### Objects
65+
66+
The background layer is useful for elements scrolling as a whole, but
67+
it's impractical for objects that need to move separately, such as the player.
68+
69+
The _objects_ layer is designed to fill this gap: _objects_ are made of 1 or 2 stacked tiles (8×8 or 8×16 pixels)
70+
and can be displayed anywhere on the screen.
71+
72+
::: tip NOTE
73+
74+
Several objects can be combined (they can be called _metasprites_) to draw
75+
a larger graphical element, usually called "sprite". Originally, the term "sprites"
76+
referred to fixed-sized objects composited together, by hardware, with a background.
77+
Use of the term has since become more general.
78+
79+
:::
80+
81+
To summarise:
82+
83+
- **Tile**, an 8×8-pixel chunk of graphics.
84+
- **Object**, an entry in object attribute memory, composed of 1 or 2
85+
tiles. Can be moved independently of the background.

src/Rendering.md

+47-58
Original file line numberDiff line numberDiff line change
@@ -1,85 +1,74 @@
1-
# Rendering Overview
1+
# Rendering overview
22

3-
The Game Boy outputs graphics to a 160×144 pixel LCD, using a quite complex
4-
mechanism to facilitate rendering.
3+
## Terminology
54

6-
::: warning Terminology
5+
The entire frame is not drawn atomically; instead, the image is drawn by the **<abbr>PPU</abbr>** (Pixel-Processing Unit) progressively, **directly to the screen**.
6+
A frame consists of 154 **scanlines**; during the first 144, the screen is drawn top to bottom, left to right.
77

8-
Sprites/graphics terminology can vary a lot among different platforms, consoles,
9-
users and communities. You may be familiar with slightly different definitions.
10-
Keep also in mind that some definitions refer to lower (hardware) tools
11-
and some others to higher abstractions concepts.
8+
The main implication of this rendering process is the existence of **raster effects**: modifying some rendering parameters in the middle of rendering.
9+
The most famous raster effect is modifying the [scrolling registers](<#LCD Position and Scrolling>) between scanlines to create a ["wavy" effect](https://gbdev.io/guides/deadcscroll#effects).
10+
11+
A "**dot**" = one 2<sup>22</sup> Hz (≅ 4.194 MHz) time unit.
12+
Dots remain the same regardless of whether the CPU is in [double speed](<#FF4D — KEY1 (CGB Mode only): Prepare speed switch>), so there are 4 dots per single-speed CPU cycle, and 2 per double-speed CPU cycle.
13+
14+
::: tip
15+
16+
Note that a frame is not exactly one 60<sup>th</sup> of a second: the Game Boy runs slightly slower than 60 Hz, as one frame takes ~16.74 ms instead of ~16.67 (the error is 0.45%).
1217

1318
:::
1419

15-
## Tiles
20+
## PPU modes
1621

17-
Similarly to other retro systems, pixels are not manipulated
18-
individually, as this would be expensive CPU-wise. Instead, pixels are grouped
19-
in 8×8 squares, called _tiles_ (or sometimes "patterns" or "characters"), often considered as
20-
the base unit in Game Boy graphics.
22+
<figure><figcaption>
2123

22-
A tile does not encode color information. Instead, a tile assigns a
23-
_color ID_ to each of its pixels, ranging from 0 to 3. For this reason,
24-
Game Boy graphics are also called _2bpp_ (2 bits per pixel). When a tile is used
25-
in the Background or Window, these color IDs are associated with a _palette_. When
26-
a tile is used in an object, the IDs 1 to 3 are associated with a palette, but
27-
ID 0 means transparent.
24+
During a frame, the Game Boy's PPU cycles between four modes as follows:
2825

29-
## Palettes
26+
</figcaption>
3027

31-
A palette consists of an array of colors, 4 in the Game Boy's case.
32-
Palettes are stored differently in monochrome and color versions of the console.
28+
{{#include imgs/ppu_modes_timing.svg:2:}}
3329

34-
Modifying palettes enables graphical effects such as quickly flashing some graphics (damage,
35-
invulnerability, thunderstorm, etc.), fading the screen, "palette swaps", and more.
30+
</figure>
3631

37-
## Layers
32+
While the PPU is accessing some video-related memory, [that memory is inaccessible to the CPU](<#Accessing VRAM and OAM>) (writes are ignored, and reads return garbage values, usually $FF).
3833

39-
The Game Boy has three "layers", from back to front: the Background, the Window,
40-
and the Objects. Some features and behaviors break this abstraction,
41-
but it works for the most part.
34+
Mode | Action | Duration | Accessible video memory
35+
----:|--------------------------------------------|--------------------------------------|-------------------------
36+
2 | Searching for OBJs which overlap this line | 80 dots | VRAM, CGB palettes
37+
3 | Sending pixels to the LCD | Between 172 and 289 dots, see below | None
38+
0 | Waiting until the end of the scanline | 376 - mode 3's duration | VRAM, OAM, CGB palettes
39+
1 | Waiting until the next frame | 4560 dots (10 scanlines) | VRAM, OAM, CGB palettes
4240

43-
### Background
41+
## Mode 3 length
4442

45-
The background is composed of a _tilemap_. A tilemap is a
46-
large grid of tiles. However, tiles aren't directly written to tilemaps,
47-
they merely contain references to the tiles.
48-
This makes reusing tiles very cheap, both in CPU time and in
49-
required memory space, and it is the main mechanism that helps work around the
50-
paltry 8 KiB of video RAM.
43+
During Mode 3, by default the PPU outputs one pixel to the screen per dot, from left to right; the screen is 160 pixels wide, so the minimum Mode 3 length is 160 + 12[^first12] = 172 dots.
5144

52-
The background can be made to scroll as a whole, writing to two
53-
hardware registers. This makes scrolling very cheap.
45+
Unlike most game consoles, the Game Boy does not always output pixels steadily[^crt]: some features cause the rendering process to stall for a couple dots.
46+
Any extra time spent stalling *lengthens* Mode 3; but since scanlines last for a fixed number of dots, Mode 0 is therefore shortened by that same amount of time.
5447

55-
### Window
48+
Three things can cause Mode 3 "penalties":
5649

57-
The window is sort of a second background layer on top of the background.
58-
It is fairly limited: it has no transparency, it's always a
59-
rectangle and only the position of the top-left pixel can be controlled.
50+
- **Background scrolling**: At the very beginning of Mode 3, rendering is paused for [`SCX`](<#FF42–FF43 — SCY, SCX: Viewport Y position, X position>) % 8 dots while the same number of pixels are discarded from the leftmost tile.
51+
- **Window**: After the last non-window pixel is emitted, a 6-dot penalty is incurred while the BG fetcher is being set up for the window.
52+
- **Objects**: Each object drawn during the scanline (even partially) incurs a 6- to 11-dot penalty ([see below](<#OBJ penalty algorithm>)).
6053

61-
Possible usage include a fixed status bar in an otherwise scrolling game (e.g.
62-
_Super Mario Land 2_).
54+
On DMG and GBC in DMG mode, mid-scanline writes to [`BGP`](<#FF47 — BGP (Non-CGB Mode only): BG palette data>) allow observing this behavior precisely, as any delay shifts the write's effect to the left by that many dots.
6355

64-
### Objects
56+
### OBJ penalty algorithm
6557

66-
The background layer is useful for elements scrolling as a whole, but
67-
it's impractical for objects that need to move separately, such as the player.
58+
Only the OBJ's leftmost pixel matters here, transparent or not; it is designated as "The Pixel" in the following.
6859

69-
The _objects_ layer is designed to fill this gap: _objects_ are made of 1 or 2 stacked tiles (8×8 or 8×16 pixels)
70-
and can be displayed anywhere on the screen.
60+
1. Determine the tile (background or window) that The Pixel is within. (This is affected by horizontal scrolling and/or the window!)
61+
2. If that tile has **not** been considered by a previous OBJ yet[^order]:
62+
1. Count how many of that tile's pixels are strictly to the right of The Pixel.
63+
2. Subtract 2.
64+
3. Incur this many dots of penalty, or zero if negative (from waiting for the BG fetch to finish).
65+
3. Incur a flat, 6-dot penalty (from fetching the OBJ's tile).
7166

72-
::: tip NOTE
67+
**Exception**: an OBJ with an OAM X position of 0 (thus, completely off the left side of the screen) always incurs a 11-cycle penalty, regardless of `SCX`.
7368

74-
Several objects can be combined (they can be called _metasprites_) to draw
75-
a larger graphical element, usually called "sprite". Originally, the term "sprites"
76-
referred to fixed-sized objects composited together, by hardware, with a background.
77-
Use of the term has since become more general.
7869

79-
:::
70+
[^first12]: The 12 extra cycles come from two tile fetches at the beginning of Mode 3. One is the first tile in the scanline (the one that gets shifted by `SCX` % 8 pixels), the other is simply discarded.
8071

81-
To summarise:
72+
[^crt]: The Game Boy can afford to "take pauses", because it writes to a LCD it fully controls; by contrast, home consoles like the NES or SNES are on a schedule imposed by the screen they are hooked up to. Taking pauses arguably simplified the PPU's design while allowing greater flexibility to game developers.
8273

83-
- **Tile**, an 8×8-pixel chunk of graphics.
84-
- **Object**, an entry in object attribute memory, composed of 1 or 2
85-
tiles. Can be moved independently of the background.
74+
[^order]: Since pixels are emitted from left to right, OBJs overlapping the scanline are considered from [leftmost](<#Byte 1 — X Position>) to rightmost, with ties broken by their index / OAM address (lowest first).

src/STAT.md

+2-55
Original file line numberDiff line numberDiff line change
@@ -33,67 +33,14 @@ Bit 1-0 - Mode Flag (Mode 0-3, see below) (Read Only)
3333
3: Transferring Data to LCD Controller
3434
```
3535

36-
The two lower STAT bits show the current status of the PPU.
36+
The two lower STAT bits show the current [status of the PPU](<#STAT modes>).
3737

3838
Bit 2 is set when [LY](<#FF44 — LY: LCD Y coordinate \[read-only\]>) contains the same value as [LYC](<#FF45 — LYC: LY compare>).
3939
It is constantly updated.
4040

4141
Bits 3-6 select which sources are used for [the STAT interrupt](<#INT $48 — STAT interrupt>).
4242

43-
## STAT modes
44-
45-
The LCD controller operates on a 2^22 Hz = 4.194 MHz dot clock. An
46-
entire frame is 154 scanlines = 70224 dots = 16.74 ms. On scanlines 0
47-
through 143, the PPU cycles through modes 2, 3, and 0 once
48-
every 456 dots. Scanlines 144 through 153 are mode 1.
49-
50-
The following sequence is typical when the display is enabled:
51-
52-
```
53-
Mode 2 2_____2_____2_____2_____2_____2___________________2____
54-
Mode 3 _33____33____33____33____33____33__________________3___
55-
Mode 0 ___000___000___000___000___000___000________________000
56-
Mode 1 ____________________________________11111111111111_____
57-
```
58-
59-
When the PPU is accessing some video-related memory, that memory is inaccessible
60-
to the CPU: writes are ignored, and reads return garbage values (usually $FF).
61-
62-
- During modes 2 and 3, the CPU cannot access [OAM](<#VRAM Sprite Attribute Table (OAM)>) ($FE00-FE9F).
63-
- During mode 3, the CPU cannot access VRAM or [CGB palette data registers](<#LCD Color Palettes (CGB only)>)
64-
($FF69,$FF6B).
65-
66-
Mode | Action | Duration | Accessible video memory
67-
-----|------------------------------------------------------------------|--------------------------------------------------------------------|-------------------------
68-
2 | Searching OAM for OBJs whose Y coordinate overlap this line | 80 dots | VRAM, CGB palettes
69-
3 | Reading OAM and VRAM to generate the picture | 168 to 291 dots, depending on object count | None
70-
0 | Nothing (HBlank) | 85 to 208 dots, depending on previous mode 3 duration | VRAM, OAM, CGB palettes
71-
1 | Nothing (VBlank) | 4560 dots (10 scanlines) | VRAM, OAM, CGB palettes
72-
73-
## Properties of STAT modes
74-
75-
Unlike most game consoles, the Game Boy can pause the dot clock briefly,
76-
making Mode 3 longer and Mode 0 shorter. It routinely takes a 6 to 11 dot
77-
break to fetch an OBJ's tile between background tile pattern fetches.
78-
On DMG and GBC in DMG mode, mid-scanline writes to [`BGP`](<#FF47 — BGP (Non-CGB Mode only): BG palette data>)
79-
allow observing this behavior, as the delay from drawing an OBJ shifts the
80-
write's effect to the left by that many dots.
81-
82-
Three things are known to pause the dot clock:
83-
84-
- Background scrolling: If `SCX % 8` is not zero at the start of the scanline, rendering is paused for that many dots while the shifter discards that many pixels from the leftmost tile.
85-
- Window: An active window pauses for at least 6 dots, as the background fetching mechanism starts over at the left side of the window.
86-
- Objects: Each object usually pauses for `11 - min(5, (x + SCX) % 8)` dots.
87-
Because object fetch waits for background fetch to finish, an object's cost depends on its position relative to the left side of the background tile under it. It's greater if an object is directly aligned over the background tile, less if the object is to the right. If the object's left side is over the window, use `255 - WX` instead of `SCX` in this formula.
88-
89-
::: warning TO BE VERIFIED
90-
91-
The exact pause duration for window start is
92-
not confirmed; it may have the same background fetch finish delay as
93-
an object. If two objects' left sides are over the same background or
94-
window tile, the second may pause for fewer dots.
95-
96-
:::
43+
### Spurious STAT interrupts
9744

9845
A hardware quirk in the monochrome Game Boy makes the LCD interrupt
9946
sometimes trigger when writing to STAT (including writing \$00) during

src/SUMMARY.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
# I/O Ports
1616

1717
- [Summary](./Hardware_Reg_List.md)
18-
- [Rendering](./Rendering.md)
18+
- [Graphics](./Graphics.md)
1919
- [Tile Data](./Tile_Data.md)
2020
- [Tile Maps](./Tile_Maps.md)
2121
- [OAM](./OAM.md)
@@ -24,7 +24,8 @@
2424
- [LCD Status Registers](./STAT.md)
2525
- [Scrolling](./Scrolling.md)
2626
- [Palettes](./Palettes.md)
27-
- [Pixel FIFO](./pixel_fifo.md)
27+
- [Rendering](./Rendering.md)
28+
- [Pixel FIFO](./pixel_fifo.md)
2829
- [Audio](./Audio.md)
2930
- [Audio Registers](./Audio_Registers.md)
3031
- [Audio Details](./Audio_details.md)

src/pixel_fifo.md

-11
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,5 @@
11
# Pixel FIFO
22

3-
::: tip TERMINOLOGY
4-
5-
All references to a dot are meant as dots (4.19 MHz). Dots remain the same regardless of
6-
CGB double speed.
7-
When it is stated that a certain action *lengthens mode 3* it means that mode 0 (HBlank) is
8-
shortened to make up for the additional time in mode 3, as shown in the following diagram.
9-
10-
:::
11-
12-
{{#include imgs/ppu_modes_timing.svg:2:}}
13-
143
## Introduction
154

165
FIFO stands for *First In, First Out*. The first pixel to be pushed to the

0 commit comments

Comments
 (0)