LiraNuna's Development Blog

Nintendo DS 2D HW Tutorials
By LiraNuna

Lesson 3: Diving Into the Map

Table of content

The Palette – How it really looks
Tile Flipping
Merging the two
Map format

The DS has a powerful tiling engine. It can do more then just display the tiles – Each tile can be flipped on both horizontal and vertical axises and use a different palette set. In this lesson, we will go deeper and focus on the map’s format, as well as the different palette sets formats.

The Palette – How it really looks
The palette is a collection of 256 colors made up from 16 palettes of 16 colors (16×16).

On 16col mode, the palette is made up from 16 palettes of 16 colors.

On 16col mode, each tile can use a different set of 16col palette. This way we can manipulate the same tile using different color schemes.

Tile Flipping
Tile flipping is one of the strongest features to manipulate tile’s look. It enables the tile to be flipped both horizontally and vertically, giving the tile a whole new look.

Types of Flipping

Tile flipping can be used to save VRAM usage to leave more space for other tiles, or to avoid having duplicated tiles.

Merging the two
Using both Tile flipping and tile palettes is possible – and even recommended to get best size optimized results.
It is possible to create impressive scenes using low number of tiles and a full palette. For example, using only 2 tiles to create the following scene:

A tiled scene made using only 2 palettes and 2 tiles.

Map format
To use those features, we will have to change the tile attributes in the map. To do so, we need to look deeper into the map format.

A single tile in a map.
Tile Index – The number of the tile to use from the tile set.
Horizontal Flip – Horizontal flip flag
Vertical Flip
– Vertical flip flag
Palette – Number of the palette to use from the 16 available palettes.

To demonstrate tile flipping and palette selecting, we will use only one tile, that will very easy to notice when flipped.
For this cause, I made this image.

Blank tile and an arrow

Since only 16col tiles can use 16×16 color mode, we will have to convert the image in 16col mode this time.

gfx2gba -t8 -c16 -D -P arrowTile.bmp

The -D option will not save map data (Since we are making our own), and -P will not save Palette data (same as map). Please note that this time i have used -c16 instead of -c256. This tells gfx2gba to convert the image to 16col format. After converting, we can include the data in our project.

To show the usage of tile flipping and palettes, we will use one tile shaped as an arrow and flip it 3 times using 4 different colors from different palettes.

	// Including libnds’ set of defines
#include <nds.h>
// Include basic memory functions
#include <string.h>
	// Including our converted graphics
#include "arrowTile_bin.h"
	// Macro to translate 2D coord into 1D map array
#define POS2IDX(x, y)    (x + (y*32))
	// Set of defines for tile flipping
#define TILE_FLIP_NONE    (0 << 10)
#define TILE_FLIP_X       (1 << 10)
#define TILE_FLIP_Y       (2 << 10)
	// Macro for palette selecting
#define TILE_PAL(n) ((n) << 12)
int main()
		// Setting up video mode
		// This time we will use 16 colors on 16 palettes
	REG_BG0CNT = BG_32x32 | BG_COLOR_16 | BG_MAP_BASE(0) | BG_TILE_BASE(1);
		// Setting VRAM Bank A for Background display
		// Copying the tiles to tile base 1
	memcpy((void*)BG_TILE_RAM(1), arrowTile_bin, arrowTile_bin_size);
		// Setting colors on palette
	BG_PALETTE[1] = RGB15(31, 0, 0);
	BG_PALETTE[17] = RGB15(0, 31, 0);
	BG_PALETTE[33] = RGB15(0, 0, 31);
	BG_PALETTE[49] = RGB15(31, 31, 31);
		// Setting a pointer to the BG0's map base
	u16* bg0Map = (u16*)BG_TILE_RAM(0);
		// Plotting the first tile on the map
		// none flipped - red arrow
	bg0Map[POS2IDX(1, 1)] = 1 | TILE_FLIP_NONE | TILE_PAL(0);
		// Plotting the second tile on the map
		// horizontal flip - green arrow
	bg0Map[POS2IDX(1, 3)] = 1 | TILE_FLIP_X | TILE_PAL(1);
		// Plotting the third tile on the map
		// vertical flip - blue arrow
	bg0Map[POS2IDX(1, 5)] = 1 | TILE_FLIP_Y | TILE_PAL(2);
		// Plotting the last tile on the map
		// horizontal and vertical flip - white arrow
	bg0Map[POS2IDX(1, 7)] = 1 | TILE_FLIP_XY | TILE_PAL(3);
		// Infinite loop to keep the program running

Download complete project files HERE.