Home Games Projects Blog Contact Private
Network

Posts Tagged ‘homebrew’

My Rather Comprehensive NDS Homebrew Link List

Development Tools/Libs

Tutorials

Misc

Emulators

Cool Demos

Nintendo Sues Distributors Of R4

Gamasutra has two interesting pieces of news on Nintendo.

According to the first one, Nintendo is suing the distributors of the R4 Revolution cartridge in Japan which allows to run software on the DS that is not licensed by Nintendo. They say it’s because of piracy, but such cartridges are also vital to homebrew development.

The other one says that Nintendo has improved its profits to $992 million in the first quarter of 2008. So, piracy can’t be that, can it?

Update: I just want to stress that I don’t support, do or glorify piracy in any way. It’s just that the DS wouldn’t be what it is without homebrew.

Update 2: According to this blog post, many sites selling the R4 are already down because they’re afraid of legal threats from Nintendo.

Update 3: Gizmondo reports:

The rush in demand [of R4s] has been amazing. These devices always sell well. But this weekend should be staggering, don’t you think?

Changed “producers” to “distributors” as I was obviously mistaken there.

Scrolling Tilemaps On The Nintendo DS

In an earlier post I talked about getting into Nintendo DS homebrew development. I’ve already read a lot and played with quite a few examples. There seem to be many basic tutorials on the topic, but unfortunately only a few tutorials pick up more advanced themes.

Anyway, there is a nice tutorial on handling tilemaps at Dev-Scene by Captain Apathy. This is again about the basics of tilemaps in the beginning, but in the end he talks about scrolling such maps with dynamically loading tile data from a bigger map as the biggest tilemap the NDS offers is 64 by 64 tiles. Unfortunately, he doesn’t give out any code showing that. So I took some time and tried to implement this kind of scrolling myself. I believe I’ve been successful, at least it seems to work.

The endeavor was not that easy because you have to keep track of quite a few coordinates in pixels as well as in tile indices. The algorithm now basically works likes this:

  1. Scrolling is at first handled by setting BG0_X0 and BG0_Y0, i. e. moving around the view in the tilemap the DS already knows about. This is possible because only 32×24 tiles are shown at once and a tilemap can contain up to 64×64 tiles.
  2. If a certain threshold of scrolled pixels is reached, the movement’s direction is determined and a certain number of rows (vertical movement) or columns (horizontal movement) of tiles is loaded into the DS’ memory map overwriting “old” tiles that lie in the other direction. This may get little difficult because the write operation may wrap around, e. g. if it would write over the right edge, it has to stop there and continue at left edge.
  3. Take care that the player cannot scroll too far so that he’d leave the map.

A screenshot:

Scrolling Tilemap

The code works in DeSmuME and on the actual DS. Download the complete source code including a Makefile here. It works with devkitPro and libnds.

Following are a few interesting spots of the code.

Setting a specific tile in a 64×64 map is not straight forward because on the DS a 64×64 map consists of four 32×32 maps that lie after another in memory:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
void setTile(u16* memoryMap, int x, int y, const u16 tileId)
{
	int n;
 
	// Wrap around:
	if(x < 0)
		x += 2 * _TILE_W;
	if(y < 0)
		y += 2 * _TILE_H;
 
	x %= 2 * _TILE_W;
	y %= 2 * _TILE_H;
 
	// Handle the 4 32x32 maps
	if(x >= _TILE_W && y >= _TILE_H)
	{
		n = 3;
		x -= _TILE_W;
		y -= _TILE_H;
	}
	else if(x >= _TILE_W)
	{
		n = 1;
		x -= _TILE_W;
 
	}
	else if(y >= _TILE_H)
	{
		n = 2;
		y -= _TILE_H;
	}
	else
	{
		n = 0;
	}
 
	memoryMap[n * _TILE_W * _TILE_H + x + y*_TILE_W] = tileId;
}

The next snippet is the core of the tilemap scrolling. It detects if loading of new tiles is necessary and, if it actually is, does so.

1
2
void updateView(u16* to)
{

At first, the position in the background (the tilemap) is set. We don’t have to care about wrapping around because the hardware takes care of that.

1
2
	BG0_X0 = position_x;
	BG0_Y0 = position_y;

We then check if loading of new tiles is necessary. This is done by comparing the covered distance with a threshold.

1
2
3
	// Horizontal movement:
	if(abs(position_x - position_x_last) >= THRESHOLD_X)
	{

Next, we have to check in which direction the player has moved.

1
		int direction = position_x < position_x_last ? -1 : 1;

If he has moved to the right, a few rows of tiles have to be appended to the right of the currently loaded tiles. This means that some “old” tiles are overwritten.

1
2
3
4
5
		if(direction == 1 && map_position_x + STEP + TILES_X <= MAP_WIDTH)
		{
			copyTiles(map_position_x + TILES_X, map_position_y, STEP, TILES_Y, to, last_x_update_index + 1, last_y_update_index + 1);
			map_position_x += direction * STEP;
		}

Moving to the left is similar. The current set of tiles is then prepended by new rows of tiles and thus overwriting “old” tiles on the right.

The code is analogous for vertical movement.

Quite a few things are missing to make this code run, but they can be found in the download mentioned above.