Tuesday, May 13, 2008

What?

Okay, okay, so blogging means you have to keep it up. :) Well, my day job has been keeping me very busy. We are trying to get our product out the door, and I've been in mad bug fixing phase. I really don't know when I'm going to get back to my DS programming, but I do hope soon.

On a more serious note, I'd like to share some information with you. Please check out this site. I'd like to raise your awareness to the mistreatment of Baha'i' students in Iran...


http://iran.bahai.us/iranian-bahai-school-children

Thanks...I hope to get back to DS programming soon.

Till then happy coding and gaming.

Wednesday, March 26, 2008

Yea Boyeee!

It's been a while. I can't tell you how buried I've been in the *real* world. And, when I wasn't digging out of overworked, over tasked, and sometimes overwhelmed, I was just vegging on Madden, 2K MLB, and Half-Life2.

I am still pushing towards an April 15th (I don't like the term "deadline,") beta release date at work, so I don't think I'll have any meaningful posts about the DS. Although, I do have a game now in mind.

In the meantime if you haven't heard this rapper before check him out...quite different, and something for the Real G's (real geeks that is :) ).

http://www.myspace.com/mcfrontalot

Till next time...

Monday, February 25, 2008

Finding One's Self

Here's the formulas I promised to help you find yourself in your world. Suppose you have a world that is 4x6 in size, with world map size 2x2, that would give you...

4x6 = 24 world entries
2x2 = 4 map entries

24/4 = 6 overall maps

thus,

x,y = (y-1) * cols + x = overall position

world entries - overall position/map entries = eliminated maps

overall maps - eliminated maps = found map #

found map # * map entries - overall position = alpha

map entries - alpha = real position - 1

This is how you can find where ever you are based on your world and map sizes.

Good luck!

Sunday, February 24, 2008

Where The Hell Have You Been!?

"Okay...don't have me sitting here for weeks on you...waiting for you to blog...where the hell have you been!?"

Ahhh...I've been caught up in real world work, I apologize.

Ok...weeks ago I said I would present the formula for finding exactly where you are in your world based on the size of your world, down to the tile and pixels. I actually, figured out the formula 2 days after I said I would, but just got caught up in so much work (I'm the lead/sole programmer on a virtual machine/security application).

I'm actually going to take a nap right at this moment, but I will post the formula before the day is over. I promise...just way too tired to do it and explain right now, but if anyone is out there ("if they were, you've lost them now dummy...people not waiting on you.") I wanted to update the blog.

So, before the day is over...stay tuned.

I'll be baaahhhccck!

Wednesday, January 23, 2008

What's Next?

Some have asked for the source, so I will clean it up and some how get a link on this blog for you to grab it, or just email it to those that have asked. I'll will try to get it up before Friday.

Before, I do the object placing in the world, scrolling, and removing/restoring object when visible, I will work on determining where I am in my defined tile map world. I will move a sprite around in my world, and find out the tile entry it is on. By knowing this, I can then define tiles in my world that are, passable, setting boundaries in my tile maps, and thus the beginnings of a simple tile level editor.

I will once again set a time frame for myself for figuring this out. For the scrolling, I gave myself 3 weeks and got it done in 2 weeks (actual time worked on it was approx. 40 hours).

Till next time...

Tuesday, January 22, 2008

Find It Here

Just adding some keywords for search engines to help those looking for a Nintendo DS Tile Scroll Algorithm, with smooth scrolling.

I think that covers it. :)

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'!"