First, you need to understand how the VRAM banks work. In this case, I will discuss specifically about VRAM with respect to backgrounds.
VRAM Banks
On the main engine, you can use up to 512KB of VRAM for backgrounds. You can think of it as divided into four blocks of 128KB (in most cases). You do not have to use all four blocks, you do not have to use any blocks. But if you want backgrounds, you better use at least one. Each of VRAM_A, VRAM_B, VRAM_C, VRAM_D (these are the first four banks, or the "main" banks," of VRAM) can be mapped to any one of those four blocks. But you better not map two banks to the same block, or you may get unexpected results. Here is a table of how to map the banks to background VRAM:
Code: Select all
Main Engine Backgrounds
First 128KB of Background VRAM: Starts at CPU address 0x06000000
VRAM_A_MAIN_BG // First 128KB is the "default" setting for VRAM_A_MAIN_BG
VRAM_A_MAIN_BG_0x06000000 // Map Bank A to first 128KB
VRAM_B_MAIN_BG_0x06000000 // Map Bank B to first 128KB
VRAM_C_MAIN_BG_0x06000000 // Map Bank C to first 128KB
VRAM_D_MAIN_BG_0x06000000 // Map Bank D to first 128KB
Second 128KB of Background VRAM: Starts at CPU address 0x06020000
VRAM_B_MAIN_BG // Second 128KB is the "default" setting for VRAM_B_MAIN_BG
VRAM_A_MAIN_BG_0x06020000 // Map Bank A to second 128KB
VRAM_B_MAIN_BG_0x06020000 // Map Bank B to second 128KB
VRAM_C_MAIN_BG_0x06020000 // Map Bank C to second 128KB
VRAM_D_MAIN_BG_0x06020000 // Map Bank D to second 128KB
Third 128KB of Background VRAM: Starts at CPU address 0x06040000
VRAM_C_MAIN_BG // Third 128KB is the "default" setting for VRAM_C_MAIN_BG
VRAM_A_MAIN_BG_0x06040000 // Map Bank A to third 128KB
VRAM_B_MAIN_BG_0x06040000 // Map Bank B to third 128KB
VRAM_C_MAIN_BG_0x06040000 // Map Bank C to third 128KB
VRAM_D_MAIN_BG_0x06040000 // Map Bank D to third 128KB
Fourth 128KB of Background VRAM: Starts at CPU address 0x06060000
VRAM_D_MAIN_BG // Fourth 128KB is the "default" setting for VRAM_D_MAIN_BG
VRAM_A_MAIN_BG_0x06060000 // Map Bank A to fourth 128KB
VRAM_B_MAIN_BG_0x06060000 // Map Bank B to fourth 128KB
VRAM_C_MAIN_BG_0x06060000 // Map Bank C to fourth 128KB
VRAM_D_MAIN_BG_0x06060000 // Map Bank D to fourth 128KB
From the
banks page, you can see that there are a variety of other background VRAM mappings that you can use (including Banks E, F, and G). So you can see if you only mapped Bank B to background VRAM and you used VRAM_B_MAIN_BG, it actually starts at the second 128KB. Since there is no bank mapped to the first 128KB, any data read from the first 128KB will be read as 0. This will be problematic if you use map/tile bases that fall within the first 128KB.
Notice that the sub engine can only access up to 128KB of VRAM for backgrounds. The only "main" bank available for that is Bank C. You can alternatively use Banks H and I if you only need up to 48KB for the sub engine.
Backgrounds
Before I get into map/tile bases, you should know about backgrounds. On each engine, you can have up to four backgrounds (layers 0, 1, 2, 3). Depending on what video mode you choose, each layer will have a different mode. Here is a table:
Code: Select all
from "nds/arm9/background.h"
Main 2D engine
______________________________
|Mode | BG0 | BG1 | BG2 |BG3 | T = Text
| 0 | T | T | T | T | R = Rotation
| 1 | T | T | T | R | E = Extended
| 2 | T | T | R | R | L = Large Bitmap background
| 3 | T | T | T | E |
| 4 | T | T | R | E |
| 5 | T | T | E | E |
| 6 | | L | | |
------------------------------
Sub 2D engine
______________________________
|Mode | BG0 | BG1 | BG2 |BG3 |
| 0 | T | T | T | T |
| 1 | T | T | T | R |
| 2 | T | T | R | R |
| 3 | T | T | T | E |
| 4 | T | T | R | E |
| 5 | T | T | E | E |
------------------------------
Note: On the main engine, background layer 0 will be reserved for the 3D engine if you use MODE_#_3D.
Text means tiled; its map uses 16-bit entries. Rotation is also tiled, but you can rotate and scale the image (Text cannot rotate or scale); its map uses 8-bit entries. Extended means you can choose from the following:
- Rotation/Scale with 16-bit map entries (Non-Extended Rotation uses 8-bit map entries)
Rotation/Scale 8bpp bitmap (instead of tiled)
Rotation/Scale 16bpp bitmap (instead of tiled)
You can see that in order to use bitmapped backgrounds, it has to be an Extended layer. This limits you to video modes 3, 4, and 5. Note that the main engine and the sub engine do not have to use the same video mode.
Large bitmap is a feature on the main engine only. It allows you to use all 512KB to store a 512x1024 or a 1024x512 8bpp bitmap. I have never seen this used in practice. It uses up way too much VRAM.
Tiles and Maps
Now is where map/tile bases come into play. For a tiled background layer, the image is split up into 8x8 "tiles". They are basically 8x8 bitmaps. Tiled backgrounds are ALWAYS paletted. You can choose 8bpp or 4bpp tiles. The advantage of tiles is that tiles can be reused if there exists another tile which exactly matches or can be matched by horizontally and/or vertically flipping the tile. So the tiles are the "graphics" of the background, and they are stored at the "tile base." The "map" tells how to arrange the tiles in order to build the complete image. You can think of the tiles as a "palette" and the map is the "image" (compare to paletted bitmap, except each "map entry" in a bitmap is only one pixel). There are two types of map entries: 16-bit and 8-bit.
Map Entries
16-bit map entries (for Text and Extended Rotation backgrounds) can store the following information about a tile:
- Tile Number (index into the map)
Horizontal Flip (do I flip the tile horizontally when drawing?)
Vertical Flip (do I flip the tile vertically when drawing?)
Palette Number (in 4bpp tiled backgrounds, selects which "row" of the 256-color palette stored at BG_PALETTE(_SUB), in 8bpp tiled backgrounds, selects the "extended palette" (advanced topic))
8-bit map entries (for Non-Extended Rotation backgrounds) can store the following information about a tile:
- Tile Number (index into the map)
Note that with 16-bit maps you can index up to 1024 tiles, which is effectively 4096 due to horizontal/vertical flipping. With 8-bit map entries, you can only index up to 256 tiles, and there is no horizontal/vertical flipping, so it is much more limited. The advantage of using 8-bit maps is that it uses half the memory to store a map of the same size, at the expense of being limited to number of tiles and not being able to choose a palette.
Tile and Map Bases (Tile Graphics)
The tile base simply says where the tile data begins. The map base simply says where the map data begins. Look at
this example. Tile base is 0, and map base is 0. The tile data and map data occupy the same memory, so there will be corrupted graphics. You can fix it by changing the
tile base. Alternatively, you could change the
map base. Now the data does not overlap, and your graphics will be happy.
Note: A tile base is 16KB. A map base is 2KB.
Map Bases (Bitmapped Graphics)
There is no meaning to a tile base for bitmapped graphics, because there are no tiles! Instead a map base simply states where the graphics begin. In contrast to tile graphics, a map base is 16KB instead of 2KB.
Additional Info
You basically just need to make sure that the maps/graphics for your backgrounds do not overlap in VRAM. The
backgrounds page will help you with this. It will also emit code to help you set the appropriate video mode for the backgrounds you chose and to initialize each background. The
banks page will help you configure your VRAM banks.