Video: backgrounds, sprites & scanlines
Build a scanline from tiles, sprites, priorities and blending, then follow the frame to the screen.
On this page
A GBA game usually does not draw a complete finished picture into a modern-style framebuffer. It supplies tiles, maps, sprite attributes, colours and display settings. The console’s video hardware combines those ingredients while the screen is scanned. GBAx must reproduce that composition and its timing before the desktop frontend can display the resulting image.
That distinction explains why a game can run its logic correctly yet show a broken background, missing sprite or incorrect fade. The CPU may have written the intended data, but the display model still has to interpret it according to the console’s rules.
The ingredients of a GBA image
Video RAM holds graphics data. Depending on the display mode, it contains tile patterns and background maps or bitmap pixels. Palette RAM supplies colour entries for indexed graphics. OAM—Object Attribute Memory—holds sprite positions, dimensions, tile selections, priorities and transformation information. Display registers choose which layers are enabled and how they are composed.
A tiled background works by reusing small patterns. A map identifies which tile appears at each position, and the tile data identifies pixel colours or palette indexes. Scrolling changes which part of that larger arrangement is visible. Sprites, called objects in the hardware documentation, add independently positioned images such as characters, projectiles and interface elements.
| Input | What it describes | Example |
|---|---|---|
| Tile and map data | Reusable graphic patterns and their placement. | A repeating ground texture across a level. |
| OAM | Sprite placement and attributes. | A character moving independently of the background. |
| Palette RAM | Colours selected by indexed pixels. | A palette swap that changes a character’s appearance. |
| Display registers | Mode, scroll, layer order, windows and colour effects. | A foreground layer covering part of a sprite. |
Display modes change how the data is interpreted
The GBA has several background modes. Modes 0–2 arrange different combinations of regular tiled and affine backgrounds. Affine backgrounds use transformation parameters to rotate, scale or otherwise map background coordinates. They help create effects that look three-dimensional without a modern polygon-rendering pipeline.
Modes 3–5 provide bitmap backgrounds. Mode 3 uses a 240 × 160 direct-colour image. Mode 4 uses palette-indexed pixels and selectable frame pages. Mode 5 uses a smaller 160 × 128 direct-colour bitmap with selectable pages. The same bytes in VRAM can therefore have a different meaning after the display mode changes.
The renderer cannot assume that every game uses tiles, or that every pixel directly contains its final colour. It must choose the correct path from the current display state. Sprites and permitted effects then interact with the selected background mode.
How the software renderer builds a scanline
In the reviewed source, video.c schedules display-phase events. For a visible line, the HBlank callback invokes the renderer’s drawScanline operation when that frame is being rendered. The software implementation is in video-software.c, with related drawing routines in the renderer directory.
The renderer establishes the current window regions, prepares applicable sprite and background data, and combines candidates according to priorities and effect settings. A transparent source pixel does not necessarily cover what is behind it. Two visible pixels may require an alpha blend, while another configuration brightens or darkens selected layers.
- Select sourcesRead the mode, enabled layers, maps, tiles and sprites.
- Find pixelsApply scroll or affine coordinates and palette lookup.
- ComposeResolve priority, transparency, windows and colour effects.
- OutputStore the finished scanline in the frame image.
A worked example: a sprite behind a foreground
Imagine a character walking behind a tree. The game can place the character in a sprite and the tree canopy in a background layer. At a particular screen coordinate, the renderer may find a sprite pixel, a canopy pixel and a ground pixel. It must choose which source is visible using the configured priorities and transparency rules.
Where the canopy’s graphic is transparent, the sprite can remain visible. Where the canopy supplies an opaque pixel with the appropriate priority, it covers the character. A window can change which layers are allowed in a region, and a blend configuration can alter the final colour. The renderer repeats this decision across the line, rather than simply drawing every sprite over a completed background.
An error in priority handling can make the whole character appear in front of the tree. An incorrect transparent-colour rule can create a rectangular block around it. Both are display-emulation problems, even if the character’s position and game logic are correct.
Scanlines, blanking and the shared clock
The visible image is 240 × 160 pixels, but the emulated display timeline includes blanking periods. The reviewed constants use 1,232 cycles per line and 228 lines per frame, producing 280,896 cycles per frame. The extra lines form the vertical-blank interval used by many games to prepare their next image.
The code changes status flags as it enters and leaves display phases. It can trigger HBlank/VBlank DMA and request enabled display interrupts. These events must stay aligned with CPU execution and other components: a register write before a transition may have a different effect from the same write after it.
This source revision defines its horizontal drawing and blanking event phases as 1,008 and 224 cycles. Together they make 1,232. These are the core’s scheduling constants; do not replace them with a calculation based only on the 240 visible pixels when reasoning about this implementation.
Why mid-frame changes are difficult
Games can change display registers while a frame is in progress. They may update scroll values between lines, switch effects or use HBlank DMA to feed a sequence of transformation values. A screenshot assembled from only the final register values at the end of a frame would miss that history.
The core therefore combines register handling with timed rendering and display events. Its software renderer works at scanline boundaries and includes state/caching rules; this should not be presented as an unrestricted promise to model every possible sub-scanline effect perfectly. Timing-sensitive scenes are useful tests precisely because they expose where a model differs from hardware.
Emulated rendering and monitor presentation
Once the core has produced pixels, the frontend still has to put them in a window. Window size, fullscreen, scaling, filtering and presentation synchronisation belong to that stage. Increasing the window size does not make the original game generate higher-resolution textures or new artwork.
This distinction also separates two kinds of visual issue. A stable wrong pixel or layer ordering in the same scene can point toward emulation. Uneven movement that changes with host display settings may concern presentation. Comparing a saved screenshot, a known scene and the selected output settings helps make the report useful.
For the events that drive the rendering schedule, continue with Timers, DMA & interrupts. For the memory holding tiles, maps and sprite attributes, see Memory & the system bus.
Sources & implementation
Implementation references follow GBAx 2.0.0 Preview 1, commit c1a826ae. The hardware implementation derives from mGBA; these links point to the matching GBAx source, rather than assuming a newer upstream revision behaves identically.
Need help with a specific problem? Start with troubleshooting →
