Skip to content

3.5. Rolling some graphics!

N•I•L edited this page Jan 3, 2022 · 2 revisions

A technical insight into DS graphics

2D Engines and video modes

First I think we should have a serious talk about Nintendo DS's video engines and modes. So there are two video engines, one for each screen. They are called the Main and Sub engine and both can be used with any of the two screens, but an engine can be assigned to at most one screen at a time. While DS hardware is capable of doing 3D graphics, we'll currently focus on the 2D graphics engine.

Each of the Main and Sub engine can render up to 4 backgrounds, called BG0, BG1, BG2 and BG3. BG3 renders first, therefore it is covered by all other backgrounds, while BG0 stays always on top, so nothing but sprites can overlap with it. Each background can draw a certain type of graphics which are specified to the engine by a video mode. Video modes are numbered from 0 to 6. You'll maybe recall the dogmatic phrase "Modes 0-2 are for text (tiled) background, while modes 3-6 are for bitmap backgrounds". Well, yes... and no. It's a bit more complex than that. It's true that video modes 3+ can display backgrounds encoded like a bitmap image (pixel by pixel), but they can also display "text"/tiled maps on some of the backgrounds.

Let's have a quick look at the main background types:

Background type Description
Text A text background builds a visual map from a set of predefined square tiles of a fixed size
Rotation Allows for larger size tiled backgrounds with the ability of scaling and rotation.
Extended Rotation Can be either a bitmap or a tiled background, supports scaling and rotation & alpha 16-bit colors
Large Bitmap Allows 1024x512px or 512x1024px sized 8bpp bitmap backgrounds

And let's see the video modes and how they affect backgrounds:

Mode BG0 BG1 BG2 BG3 Main engine only
0 Text Text Text Text
1 Text Text Text Rot
2 Text Text Rot Rot
3 Text Text Text Ex. Rot
4 Text Text Rot Ex. Rot
5 Text Text Ex. Rot Ex. Rot
6 Large Yes

Ok, I know, it's so much theory, and yet we've done nothing.

Before reaching the coding part, I insist to give a little piece of advice, or a "recipe" if you really want to make it easier for you to decide what video mode to choose.

  1. Do a bit of planning and be clear on what exactly do you expect your game to look like. Do you want a scroll RPG with map overlay effects like particles or raining animation? Then you should consider mode 3 which gives you 3 tiled background layers and a bitmap right over them to draw your special effects on. Are you a classic guy not interested in your game to be too extravagant? Why not use mode 0? Do you take the "background" idea too seriously and just want to have a static wallpaper? Then you don't have to care which mode to use as long as it's 3, 4 or 5. Using mode 5 seems to be the most popular choice among the homebrews, so you can go for it. Do you want to make a horizontal scroller like you'd simulate Jetpack Joyrade? Then mode 6 is for you.
  2. Read the docs. Always check your options. Maybe you expect a bit too much for a relatively old system like the DS. You have to be aware of what the hardware can offer to you. If you have a huuuuge map of 1000x1000px, good luck trying to make it work in mode 0 graphics. Even if it's basically a text background, note that mode 0 only works for backgrounds up to 512x512px, so your best option would be 1, 2 or 4's rotation background, or even any extended rotation background. Also you should consider that opposite to text background, you are limited to at most 2 (extended) rotation backgrounds, so you'll basically need to make your map fit in two layers. How is it possible to know all that? The answer is Docs. Just go read the docs!
  3. If still unsure about one thing or two, it's worth seeing the examples. They may give you an idea of how everything works and may answer some of your questions.

Oh, and almost forgot... a must-say thing:

DS Video Banks

The DS has 676KB of Video RAM, but you can't access all of it in a singular way. It is "banked", meaning that you need to map a VRAM memory zone to a certain map (labeled from A to I) in order to define the size and the purpose that memory zone is reserved for. This is how the engines know where to get their stuff from in order to gloriously draw it on the screen.

I'll give a brief insight into memory banks and some of their uses:

Main engine & video banks

VRAM Bank Purpose
A, B Can map Background data (tiles or bitmap) or Sprite data, max 128KB each bank
C, D Can map only Background data, 128KB each bank
E General purpose bank. Each can map 32KB of either Background, Sprites or Palette data
F, G General purpose bank. Each can map 16KB of either Background, Sprites or (Extended) Palette data

Sub engine & video banks

Here we kinda have some restrictions on what banks can we use for our sub engine:

VRAM Bank Purpose
C Can only map to 128KB of Background data
D Can only map to 128KB of Sprite data
H Can only map to 32KB of Background or Extended Palette data
I Can only map to 16KB of Background or Sprites, or 8KB of Object (Sprite) Extended Palette

The main idea is:

  • Banks A, B, C, D are spacious, but their usage is limited to Background and/or Object (Sprites). If you need to draw graphics on both of your screens, then you are kinda forced to use banks C & D for sub engine's background and sprites if you have a large piece of data to store, leaving only banks A and B for your main engine.
  • Banks E, F, G are Main engine only. They are smaller, but more flexible and can map to almost everything
  • Banks H, I are Sub engine only and their usage is basically limited to some particular stuff.

Banks are an intriguing challenge in DS programming (especially in the planning step of your project). Fortunately there is this tool that has you visualize the banks to make your life easier and your approaches more efficient.

References