Monday, January 21, 2008

"Keep Scrollin', scrollin', scrollin'..."

"Now I know ya'll be lovin' this right here...R.O.D. is right here. People in the house with there laptops in the air..."

Okay...whew...I was gettin' jiggy...oh, they don't say that anymore...showing my age. :)

Anyway, the tile, scroll engine is done. Well, not the engine, but the code that does all the tile, world scrolling is "oppperrratttiooonaaal." I'll clean it up and make it into a generic engine. Anyway, I know some of you are itching to see how to scroll. As, I mentioned previously I'll will post here some hand drawings to explain my scheme, and also will post the code. So, here it is...






Sheesh...the images loaded in look like crap but, if you can see the one above A shows the image of the background map divided into 4 regions I've been explaining in my previous posts. B, shows the 32x32 maps that will be loaded into those regions. I guess, I'll just get to the code, and have to figure out another way to get the diagrams up and in.

What I did to test my scheme was to make some 8x8 tiles filled with different colors. I then created test maps from those tiles, thus I have 32x32 tile maps of solid colors. This way when I scroll I can see if my test maps are loading and scrolling properly. So, my world that I'm scrolling over looks like a colorful patch quilt, but it is a good way to test.

Here's that code...

// black tile
const int nColor_Black = 0;
u8 blackTile[64]=
{
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0
};

// red tile
const int nColor_Red = 1;
u8 redTile[64]=
{
1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1
};

// green tile
const int nColor_Green = 2;
u8 greenTile[64]=
{
2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2
};

// blue tile
const int nColor_Blue = 3;
u8 blueTile[64]=
{
3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3
};

// yellow tile
const int nColor_Yellow = 4;
u8 yellowTile[64]=
{
4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4
};

// white tile
const int nColor_White = 5;
u8 whiteTile[64]=
{
5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5
};

The above are the tiles I created for testing, but in a game one of these tiles would represent some, small graphic element.

Here are the maps...

// file map1 with black tiles
u16 nWorldMap1[] =
{
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 1
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 2
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 3
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 4
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 5
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 6
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 7
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 8
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 9
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 10
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 11
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 12
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 13
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 14
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 15
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 16
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 17
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 18
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 19
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 20
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 21
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 22
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 23
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 24
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 25
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 26
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 27
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 28
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 29
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 30
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 31
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 32
};

// black maps
u16 *nWorldMap7, *nWorldMap13, *nWorldMap19;
nWorldMap7 = nWorldMap13 = nWorldMap19 = nWorldMap1;

// file with red tiles
u16 nWorldMap2[] =
{
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 1
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 2
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 3
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 4
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 5
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 6
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 7
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 8
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 9
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 10
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 11
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 12
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 13
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 14
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 15
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 16
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 17
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 18
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 19
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 20
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 21
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 22
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 23
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 24
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 25
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 26
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 27
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 28
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 29
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 30
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 31
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 32
};

u16 *nWorldMap8, *nWorldMap14, *nWorldMap20;
nWorldMap8 = nWorldMap14 = nWorldMap20 = nWorldMap2;

// fill map with green tiles
u16 nWorldMap3[] =
{
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 1
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 2
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 3
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 4
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 5
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 6
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 7
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 8
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 9
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 10
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 11
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 12
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 13
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 14
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 15
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 16
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 17
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 18
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 19
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 20
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 21
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 22
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 23
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 24
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 25
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 26
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 27
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 28
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 29
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 30
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 31
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 32
};

u16 *nWorldMap9, *nWorldMap15;
nWorldMap9= nWorldMap15 = nWorldMap3;

u16 nWorldMap4[] =
{
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 1
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 2
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 3
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 4
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 5
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 6
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 7
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 8
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 9
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 10
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 11
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 12
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 13
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 14
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 15
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 16
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 17
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 18
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 19
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 20
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 21
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 22
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 23
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 24
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 25
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 26
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 27
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 28
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 29
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 30
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 31
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 32
};

u16 *nWorldMap10, *nWorldMap16;
nWorldMap10 = nWorldMap16 = nWorldMap4;

// fill map with yellow tiles
u16 nWorldMap5[] =
{
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, // 1
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, // 2
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, // 3
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, // 4
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, // 5
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, // 6
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, // 7
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, // 8
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, // 9
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, // 10
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, // 11
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, // 12
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, // 13
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, // 14
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, // 15
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, // 16
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, // 17
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, // 18
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, // 19
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, // 20
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, // 21
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, // 22
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, // 23
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, // 24
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, // 25
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, // 26
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, // 27
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, // 28
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, // 29
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, // 30
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, // 31
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, // 32
};

u16 *nWorldMap11, *nWorldMap17;
nWorldMap11 = nWorldMap17 = nWorldMap5;

// fill map with white tiles
u16 nWorldMap6[] =
{
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, // 1
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, // 2
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, // 3
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, // 4
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, // 5
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, // 6
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, // 7
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, // 8
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, // 9
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, // 10
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, // 11
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, // 12
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, // 13
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, // 14
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, // 15
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, // 16
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, // 17
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, // 18
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, // 19
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, // 20
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, // 21
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, // 22
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, // 23
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, // 24
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, // 25
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, // 26
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, // 27
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, // 28
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, // 29
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, // 30
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, // 31
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, // 32
};

u16 *nWorldMap12, *nWorldMap18;
nWorldMap12 = nWorldMap18 = nWorldMap6;

You see the maps are 32x32 entries with the tile images in them, remember I'm doing solid patterns so that testing the tile scrolling is easily visible. Again, in a real game the different entries in the map would make up different tiles that could also be rotated or flipped, to make up a picture, landscape, etc... Note, that after I made one map of a solid color, I created pointers to other maps and assigned a map to them. This way, I saved time and memory not making duplicate maps filled with the same colors.

Next, is the setup code to set the background mode, tiles, palette,etc...

int main(void)
{
// enable interrupts
irqInit();
irqEnable(IRQ_VBLANK);

// set video mode and map vram to the background
videoSetMode(MODE_0_2D | DISPLAY_BG0_ACTIVE |
DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D | DISPLAY_SPR_1D_BMP); // display sprite active, in tile, and bitmap mode

//enable vram and map it to the right places
vramSetMainBanks(VRAM_A_MAIN_SPRITE, //A and B maped consecutivly as sprite memory
VRAM_B_MAIN_SPRITE, //this gives us 256KB which is the max
VRAM_C_MAIN_BG_0x06000000, //map C to background memory
VRAM_D_LCD); //not using D


// set the map regions
u16* mapRegion0 = (u16*)BG_MAP_RAM(0);
u16* mapRegion1 = (u16*)BG_MAP_RAM(1);
u16* mapRegion2 = (u16*)BG_MAP_RAM(2);
u16* mapRegion3 = (u16*)BG_MAP_RAM(3);

u8* tileMemory = (u8*) BG_TILE_RAM(1);

// tell the DS where we are putting everything and set the 256 color mode
// and that we are using a 32x32 tile map
BG0_CR = BG_64x64 | BG_COLOR_256 | BG_MAP_BASE(0) | BG_TILE_BASE(1);

// load our palette...
//pallette entry 0 is black by default
BG_PALETTE[1] = RGB15(31,0,0); // red
BG_PALETTE[2] = RGB15(0,31,0); // green
BG_PALETTE[3] = RGB15(0, 0, 31); // blue
BG_PALETTE[4] = RGB15(31, 31, 0); // yellow
BG_PALETTE[5] = RGB15(31, 31, 31); // white

// copy the tiles into tile memory one after the other
swiCopy(blackTile, tileMemory, 32);
swiCopy(redTile, tileMemory + sizeof(blackTile), 32);
swiCopy(greenTile, tileMemory + sizeof(blackTile)*2, 32);
swiCopy(blueTile, tileMemory + sizeof(blackTile)*3, 32);
swiCopy(yellowTile, tileMemory + sizeof(blackTile)*4, 32);
swiCopy(whiteTile, tileMemory + sizeof(blackTile)*5, 32);

Remember, I said that my test world is 5x4, 32x32 maps and the background map is divided into 2x2, 32x32 regions, 0,1,2,&3. The table below is how the region is laid out for each row and column. Thus, if the scroll engine determines that it is on map 15 = WorldMaps[14], plugging that into nMapToRegion tells us which region map 15 belongs, i.e., region = nMapToRegion[15-1]; I subtract one since map1 is at entry zero. To avoid all that offset, subtraction, just number the maps starting at zero. I'll make that change in my final engine.


Here's the code setting up the arrays, and variables used to do the region bounds checks...

int WorldMaps[] = {
1, 2, 3, 4, 5,
6, 7, 8, 9, 10,
11, 12, 13, 14, 15,
16, 17, 18, 19, 20,
};

int nMapToRegion[] = {
0, 1, 0, 1, 0,
2, 3, 2, 3, 2,
0, 1, 0, 1, 0,
2, 3, 2, 3, 2,
};

int nMap = 0;
int nRegion = 0;
int nRowT = 0;
int nRowB = 0;
int nColL = 0;
int nColR = 0;

int nWorldPos_rx = 255; // 32 * 8 - 1
int nWorldPos_lx = 0;
int nWorldPos_ty = 0;
int nWorldPos_by = 191; // 24 * 8 - 1

int nScroll_x = 0;
int nScroll_y = 0;

int held; // used for keypad inputs

I created lookup tables to easily grab the maps and regions...

std::vector vRegionLookup;
std::vector vMapLookup;

// set the regions in lookup table
vRegionLookup.push_back(mapRegion0);
vRegionLookup.push_back(mapRegion1);
vRegionLookup.push_back(mapRegion2);
vRegionLookup.push_back(mapRegion3);

// push the maps to lookup table
vMapLookup.push_back(nWorldMap1);
vMapLookup.push_back(nWorldMap2);
vMapLookup.push_back(nWorldMap3);
vMapLookup.push_back(nWorldMap4);
vMapLookup.push_back(nWorldMap5);
vMapLookup.push_back(nWorldMap6);
vMapLookup.push_back(nWorldMap7);
vMapLookup.push_back(nWorldMap8);
vMapLookup.push_back(nWorldMap9);
vMapLookup.push_back(nWorldMap10);
vMapLookup.push_back(nWorldMap11);
vMapLookup.push_back(nWorldMap12);
vMapLookup.push_back(nWorldMap13);
vMapLookup.push_back(nWorldMap14);
vMapLookup.push_back(nWorldMap15);
vMapLookup.push_back(nWorldMap16);
vMapLookup.push_back(nWorldMap17);
vMapLookup.push_back(nWorldMap18);
vMapLookup.push_back(nWorldMap19);
vMapLookup.push_back(nWorldMap20);

Note, the lookup table for the World Maps is done this way only for testing and convience, in a real game you won't be able to load your whole game universe if it has a big play area. You will have to devise a scheme to read in the maps based on game levels, world size, etc...but, this gives you an idea.

Also, here are some global constants I used as well...

const int nMapEntries_x = 5;
const int nMapEntries_y = 4;
const int nMapSize = 1024;
const int nRegionSize = 256; // 32 * 8
const int nScreen_Xdim = 31*8; // ds screen width
const int nScreen_Ydim = 23*8; // ds screen height
const int nWorldSize_x = 1279; // nMapEntries_x * 32 * 8 - 1;
const int nWorldSize_y = 1023; // nMapEntries_y * 32 * 8 - 1

And, what you have been waiting to see, the scroll code...

bool bHorzBoundsHit = false;
bool bVertBoundsHit = false;

while(1)
{
// get the keys
scanKeys();
held= keysHeld();

// adjust scroll
if(held & KEY_LEFT)
{
nScroll_x--;
nWorldPos_rx--;
nWorldPos_lx--;
}

if(held & KEY_RIGHT)
{
nScroll_x++;
nWorldPos_rx++;
nWorldPos_lx++;
}

if(held & KEY_UP)
{
nScroll_y--;
nWorldPos_ty--;
nWorldPos_by--;
}


if(held & KEY_DOWN)
{
nScroll_y++;
nWorldPos_by++;
nWorldPos_ty++;
}

// reset bounds hit flags
bHorzBoundsHit = false;
bVertBoundsHit = false;

// adjust coords...not an infinite world
if(nWorldPos_lx <= 0)
{
bHorzBoundsHit = true;
nWorldPos_lx = 0;
nWorldPos_rx = nScreen_Xdim;
nScroll_x = 0;
}

if(nWorldPos_rx >= nWorldSize_x)
{
bHorzBoundsHit = true;
nWorldPos_rx = nWorldSize_x;
nWorldPos_lx = nWorldPos_rx - nScreen_Xdim;
nScroll_x = nWorldPos_rx - nScreen_Xdim - 8;
}

if(nWorldPos_ty <= 0)
{
bVertBoundsHit = true;
nWorldPos_ty = 0;
nWorldPos_by = nScreen_Ydim;
nScroll_y = 0;
}

if(nWorldPos_by >= nWorldSize_y)
{
bVertBoundsHit = true;
nWorldPos_ty = nWorldSize_y - nScreen_Ydim;
nWorldPos_by = nWorldSize_y;
nScroll_y = nWorldSize_y - nScreen_Ydim - 8;

}

//
// determine boundary hits
//

// right region border hit
if((nWorldPos_rx % nRegionSize == 0) && !bHorzBoundsHit)
{
// determine if we have split rows
nRowT = nWorldPos_ty / nRegionSize;
nRowB = nWorldPos_by / nRegionSize;

if(nRowT != nRowB)
{
//
// split rows
//

// determine the map we're in
nMap = nRowT * nMapEntries_x + (nWorldPos_rx / nRegionSize);

// what region is this
nRegion = nMapToRegion[nMap];

// move the proper map into the proper region
swiCopy(vMapLookup[nMap], vRegionLookup[nRegion], nMapSize);

// determine the map we're in
nMap = nRowB * nMapEntries_x + (nWorldPos_rx / nRegionSize);

// what region is this
nRegion = nMapToRegion[nMap];

// move the proper map into the proper region
swiCopy(vMapLookup[nMap], vRegionLookup[nRegion], nMapSize);
}

else
{
// rowt == rowb (same row)

// determine the map we're in
nMap = nRowT * nMapEntries_x + (nWorldPos_rx / nRegionSize);

// what region is this
nRegion = nMapToRegion[nMap];

// move the proper map into the proper region
swiCopy(vMapLookup[nMap], vRegionLookup[nRegion], nMapSize);
}
}

// left region border hit
if((nWorldPos_lx % nRegionSize == 0) && !bHorzBoundsHit)
{
// determine if we have split rows
nRowT = nWorldPos_ty / nRegionSize;
nRowB = nWorldPos_by / nRegionSize;

if(nRowT != nRowB)
{
//
// split rows
//

// determine the map we're in
nMap = nRowT * nMapEntries_x + (nWorldPos_lx / nRegionSize);

// get the previous region (one before us)
nRegion = nMapToRegion[nMap-1];

// move the previous map into the proper region
swiCopy(vMapLookup[nMap-1], vRegionLookup[nRegion], nMapSize);

// determine the map we're in
nMap = nRowB * nMapEntries_x + (nWorldPos_lx / nRegionSize);

// get the previous region
nRegion = nMapToRegion[nMap-1];

// move the previous map into the proper region
swiCopy(vMapLookup[nMap-1], vRegionLookup[nRegion], nMapSize);
}

else
{
// rowt == rowb (same row)

// determine the map we're in
nMap = nRowT * nMapEntries_x + (nWorldPos_lx / nRegionSize);

// get the previous region (one before us)
nRegion = nMapToRegion[nMap-1];

// move the previous map into the proper region
swiCopy(vMapLookup[nMap-1], vRegionLookup[nRegion], nMapSize);
}
}

// top region border hit
if((nWorldPos_ty % nRegionSize == 0) && !bVertBoundsHit)
{
// determine if we have split columns
nColL = nWorldPos_lx / nRegionSize;
nColR = nWorldPos_rx / nRegionSize;

// find the row we're on
nRowT = nWorldPos_ty / nRegionSize;

if(nColL != nColR)
{
//
// split columns
//

// determine the map we're in
nMap = nRowT * nMapEntries_x + (nWorldPos_lx / nRegionSize) - nMapEntries_x;

// what region is this
nRegion = nMapToRegion[nMap];

// move the proper map into the proper region
swiCopy(vMapLookup[nMap], vRegionLookup[nRegion], nMapSize);

// determine the map we're in
nMap = nRowT * nMapEntries_x + (nWorldPos_rx / nRegionSize) - nMapEntries_x;

// what region is this
nRegion = nMapToRegion[nMap];

// move the proper map into the proper region
swiCopy(vMapLookup[nMap], vRegionLookup[nRegion], nMapSize);
}

else
{
// colL == colR (same columns)

// determine the map we're in
nMap = nRowT * nMapEntries_x + (nWorldPos_rx / nRegionSize) - nMapEntries_x;

// what region is this
nRegion = nMapToRegion[nMap];

// move the proper map into the proper region
swiCopy(vMapLookup[nMap], vRegionLookup[nRegion], nMapSize);
}
}

// bottom region border hit
if((nWorldPos_by % nRegionSize == 0) && !bVertBoundsHit)
{
// determine if we have split columns
nColL = nWorldPos_lx / nRegionSize;
nColR = nWorldPos_rx / nRegionSize;

// find the row we're on
nRowB = nWorldPos_by / nRegionSize;

if(nColL != nColR)
{
//
// split columns
//

// determine the map we're in
nMap = nRowB * nMapEntries_x + (nWorldPos_lx / nRegionSize);

// what region is this
nRegion = nMapToRegion[nMap];

// move the proper map into the proper region
swiCopy(vMapLookup[nMap], vRegionLookup[nRegion], nMapSize);

// determine the map we're in
nMap = nRowB * nMapEntries_x + (nWorldPos_rx / nRegionSize);

// what region is this
nRegion = nMapToRegion[nMap];

// move the proper map into the proper region
swiCopy(vMapLookup[nMap], vRegionLookup[nRegion], nMapSize);
}

else
{
// colL == colR (same column)

// determine the map we're in
nMap = nRowB * nMapEntries_x + (nWorldPos_rx / nRegionSize);

// what region is this
nRegion = nMapToRegion[nMap];

// move the proper map into the proper region
swiCopy(vMapLookup[nMap], vRegionLookup[nRegion], nMapSize);
}
}

swiWaitForVBlank();

// set the scroll registers (scroll background)
BG0_X0 = nScroll_x;
BG0_Y0 = nScroll_y;
}


That's it! You can now scroll anywhere in your world, up, down, left, right, and diagonal. Changing the test hard coded limits I have, you can make your world any size you like and scroll.

I treated the DS screen to have the coordinates, LX,TY (left x, top y) for the upper, left hand corner, and RX,BY (right x, bottom y) for the lower, right hand corner. When scrolling you might be hovering over two tiles and scrolling vertical or horizantally, that is why I test for split rows, and columns.

I will clean some things up in my test code and make a generic C++ class, tile, scroll engine. I'll next, test dropping objects in my world at arbitrary locations and see if I can scroll around, leave and comeback and they are still where I left them. Of course, they won't actually stay by themselves, I'll have to write the code to make them behave.

If anyone would like a copy of the source, to help them get started, shoot me an email or post here and I'll get a link up or email you a copy. I don't know who's reading or interested, so that would be a good barometer.

In the mean time..."keep scrollin', scrollin', scrollin'!"

1 comment:

Anonymous said...

I would love a source, im a noob at programming and need to make the background scroll in my game, but im curious as to whether "gridlines" between tiles will be visible, or that if there are none, on a solid background, would it be confusing to tell that the sprite is really moving around? Thanks. Im Cave Johnson at www.forum.gbadev.org/ so if its possible could you PM me the source(i dont know if its possible to PM files, again noob)?