Wednesday, December 31, 2008

Touched

No, I'm not loco. Nor am I feeling heart warmed. Nope, my "touched," is that I'm now handling "touches" events on the iPhone. Yes, yes, 27 days into it and I'm just now getting to that. Well, I wanted to figure out a bunch of others things, and still plenty more to learn, but right now I am at the point where most of my iPhone figuring out is done, that is what I need to do on the machine, load data (read from Bundle), save data (NSUserDefaults), bridging Objective-C with C++, setting up Opengl, landscape mode and translating my coords, and whatever else I can't think of now.

So, now I am handling the "touches," and it is very simple. The iPhone SDK is deliciously simple, once you figure out how the UIWindow, and UIViews work together. The handling of the "touches," is a very simple message,

-(void) touchesBegin: (NSSet*) touches withEvent : (UIEvent*) event
{
CGPoint screenLocation = [[touches anyObject] locationInView:self];
}

That's it! Do whatchalike with screenLocation point.

Well, in 11 or so more hours we will be into a new year. Overall, I am more than pleased with this year that is about to pass. I have plenty to be thankful for. I'm really excited about the year ahead, because I am pumped...("already I'm hyped, 'cause I'm amped!")...oh, oh, went old school on you there, but I'm very excited about my real j-o-b-ski and my side project.

So, I wish you all a very happy new year! Stay safe, stay calm, stay strong, stay grateful.

And, I have to make an endorsement, if you haven't seen the movie, "Slumdog Millionaire," check it out!

Signing off, Rod ji, iPhone walla. :)

Monday, December 29, 2008

Where Am I?

I've spent the day figuring out where I am.  No, not where I am in the project.  So far, I'm 25 days into this project and I know where I am, and actually ahead of where I had set goals for myself.  No, the where I am that I have spent the day on is, where I am when I go from iPhone screen coordinates to OpenGl ES coordinates.  

The iPhone is 320x480, but really 320x460 (the top 20 pixels is used for the iPhone Status Bar), with its origin at the top, left. OpenGl's origin is bottom, left.  So, that translation isn't difficult, but when I flipped the phone to landscape mode (which my game will be playing in) and I want the display to orient itself properly if the player rotates the device left or right, this is so if a left-handed player likes the thumb stop button in his/her right hand, then the change in viewport coordinates, and the OpenGl coordinates get all funky.  

On Windows or Mac OpenGL programming you have at your disposal "gluUnProject," to handle the conversions for you.  You just have to pass it the modelview, projection, and viewport matrices, along with screen coordinates, and it spits back to you the OGL coordinates.  However, in OpenGL ES none of the glu, glut, or glui is available.  So, I had to scrounge around to find the source(s) for the "gluUnProject," and hammer it into my test code.  

I'm glad to say that it is passing back coordinates that look reasonable.  Next up, I will code up the handling of the "touch," events, so that I can verify for sure when I flip the iPhone (I have an iTouch), and touch the screen that I am getting the correct coordinates.

I've also been testing things out in OpenGl and learning the changes, what I can and can't do in Opengl ES.

So, where am I, in regards to my early, high level, tasks I gave myself when I began...

Key (red = task completed, green = in progress, black = not started)
Tasks/Status

1) Learn the iPhone Tech
* Download/install iPhone
SDK
* Upgrade Mac OS $130

* Join iPhone Dev $99
* Read iPhone Docs/Samples
** iPhone OS Technology Overview
** Cocoa Fundamentals Guide
** iPhone Application Programming Guide
** iPhone Human Interface Guidelines
** iPhone Development Guide

** The Objective-C 2.0 Programming Language
** Write little tests programs to learn the iPhone Capabilities (memory allocation, file I/O, iPhone audio, WiFi, graphics, etc...) - (sprite displayed by Dec. 15th)

2) Test my game concepts out on the iPhone
3) Build tool(s) if needed
4) Solidify Game Design
5) Architect the game code
6) Develop game w/ scratch art
7) Drop in real assets
8) Test/Debug
9) Ship It

This is the high view of where am I.  The milestones I had set for myself this month I have met, and still have a week to go, so I am ahead.  My goal for the end of next month is to have a basic prototype of the game running with scratch art, have all the general mechanics figured out and working.  The prototype code is "throw away," code, it is quick and dirty code so I know that what I want to do I can do.  When I am confident I know all I need to, to do the game, then I will design the architecture and begin coding my engine.

Now, where's my bed?

Friday, December 26, 2008

Happy Holidays

I hope that you all will have a happy holidays whatever you celebrate. 

I've spent a few hours creating a clean gateway for myself to do all my game specific programming in C++.  I broke away from Jeff Larmarche's OGL framework, because his adds another layer (the controller) and it also has forward/backward references from/to view and controller, which was making it difficult for my bridging code, because I don't understand Objective-C well enough to modify his glview.m class.  In Objective-C if one of the implementation files has a reference to a C++ class the file extension has to change to .mm so that the compiler knows to use the Objective-C++ compiler.  However, just changing his class implementation file to .mm and doing nothing else causes errors.

So, I just took the GLSprite class that I got up and running with a little test 11 days ago, when I had my personal challenge of getting something up in 10 days.  I stripped out all their sample OGL code, and created my C++ class then gave a reference to it and instantiated it, and voila, I've got a gateway to my stuff.

So, now off to do small tests so that I can make sure I can do all I wish to do in the game, code up some graphics effects, code up some physics, etc....  Now, that my framework is up, now I can concentrate on what it is I know, and what I want to do.

I sent an email to the Imagination Tech/PowerVR folks.  They have an emulator and SDK for certain platforms using OpenGL ES.  Their site didn't list an emulator for Mac OS X, although I'm sure it is theirs that is running the iPhone Simulator.  I would like to have the same emulator running on my Mac, so that when I build my editor, I don't have to write specific graphics code for the editor and specific code for the engine, since ES does some things differently, not a lot, but it could eliminate preprocessor conditionals.  I will post what I find out.

Anyway...off to code.

Tuesday, December 23, 2008

Nirvana

Noooo...not "Come As You Are," Nirvana, but the calm state of being, peace of mind, Nirvana.

My bafflement in my last post, as to why the Objective-C doc said this,

Objective-C++ similarly strives to allow C++ class instances to serve as instance variables. This is possible as long as the C++ class in question (along with all of its superclasses) does not have any virtual member functions defined. If any virtual member functions are present, the C++ class may not serve as an Objective-C instance variable.

And, I was able to do this...

Class Foo
{
public:
Foo(){};

private:
virtual LookImAVirtualFunc(void){};
};


@interface Bar : NSObject
{
@private
Foo* foo;
}

Clearly Foo is a C++ class with a virtual function, and Bar is an Objective-C class with an instance to Foo, but the doc said. And, here's my gaff...the doc is *correct.* Objective-C class cannot have an instance to a C++ class that has virtual functions. However, an Objective-C class can have a *pointer* to a C++ class that has virtual functions. In my test I had a *pointer* and that is why it works.

If I had,

@interface Bar : NSObject
{
@private
Foo foo; // ERROR
}

which is the instance to the class. So, you can have a C++ class that has virtual functions as instance variables inside an Objective-C class, you just have to declare them as pointers.

Ahhh...serenity.



Thanks to Andre' Pang, Kai, and Uli Kusterer for answering my question on the obj-language@lists.apple.com.

Puzzling

The Objective-C 2.0 Programming Language on the iPhone Dev Docs under Mixing Objective-C and C++ states...

Objective-C++ similarly strives to allow C++ class instances to serve as instance variables.  This is possible as long as the C++ class in question (along with all of its superclasses) does not have any virtual member functions defined.  If any virtual member functions are present, the C++ class may not serve as an Objective-C instance variable.

Well, I did just that and it compiled/linked and ran.  Looking at the Instruments/Leaks all is well.  Hmmmn...so why does it work?  I took the bridge code I did yesterday and modified it to have a virtual member function in class Hello, and added another class StairwayToHeaven with a virtual member function.  Here's the code...


class StairwayToHeaven
{
public:
StairwayToHeaven()
{
printf("StairwayToHeaven:Ctor called.\n");
}

~StairwayToHeaven()
{
printf("StairwayToHeaven:dtor called.\n");
}

void PlayGame()
{
printf("StairwayToHeaven: Playing game.\n");
}

virtual void VirtualFunc(void)
{
printf("StairwayToHeaven: VirtualFunc called.\n");
}
};

class Hello
{
private:
id greeting_text;
StairwayToHeaven *pStairwayToHeaven;

public:
Hello()
{

greeting_text = @"Hello, world!";
pStairwayToHeaven = new StairwayToHeaven;
}

~Hello()
{
printf("Hello:dtor called\n");

delete pStairwayToHeaven;
}

Hello(const char* initial_greeting_text)
{
greeting_text = [[NSString alloc] initWithUTF8String:initial_greeting_text];

}

virtual void VirtualFunc(void)
{
printf("Hello: VirtualFunc called.\n");
}

void say_hello()
{
printf("%s\n", [greeting_text UTF8String]);
}

};

@interface Greeting : NSObject
{

@private
Hello *hello;
}

- (id) init;
- (void) dealloc;
- (void) sayGreeting;
- (void) sayGreeting:(Hello*)greeting;
- (void) doVirtualFunc;

@end

@implementation Greeting

- (id) init
{
if(self = [super init])
{
hello = new Hello();
}

return self;
}

- (void) dealloc
{
delete hello;
[super dealloc];
}

- (void) sayGreeting
{
hello->say_hello();
}

- (void) sayGreeting:(Hello*)greeting
{
greeting->say_hello();
}

- (void) doVirtualFunc
{
hello->VirtualFunc();
}

@end

#import
#include "test.h"
#include
#include

int main(int argc, char *argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

// notice here...dynamic typing
std::vector testVector;
id szTest = @"'ello Gov'ner!";

// testing in new C++ casting works in mixed Obj-C/C++
float fTest = 9.0f;
int nTest = static_cast(fTest);
printf("nTest = %d\n", nTest);

// instantiate the Greeting class
Greeting *greeting = [[Greeting alloc] init];

// test to see if I can use STL
testVector.push_back(greeting);
testVector.push_back(szTest);
printf("number of objects in the vector = %d\n", testVector.size());

// get the "sayGreeting" method from the Greeting class
SEL action = @selector (sayGreeting);

short i = 0;
for(std::vector::iterator it = testVector.begin(); it != testVector.end(); it++)
{
printf("In vector loop = %d\n", i++);

// check to see if the object is our Greeting object
if( [*it respondsToSelector: action] == YES )
[*it sayGreeting];
else
printf("%s\n", [*it cString]); // it is our other object
}

// can also do C++ straight up
Hello *hello = new Hello("Bonjour, monde!");

// then mix it with Obj-C
[greeting sayGreeting:hello];
[greeting doVirtualFunc];

delete hello;
[greeting release];

[pool release];

return 0;
}

I'll post a question to the Objective-C listserv and see what folks say.

Object-C/C++ya!

Monday, December 22, 2008

Getting A Boost

Tonight I set a task to grab Boost. I just wanted the libraries, not the source. So, I proceeded over to www.finkproject.org. Fink provides a free tool that allows you to grab packages and install to your Mac. Since, I'm still a Mac virgin I needed a simple tool, because I wasn't about to attempt to download, install, and build Boost...sheesh, this job turned out to be frustrating enough.

1) First I downloaded the Fink installer package from www.finkproject.org.
2) Double clicked on the install package that was downloaded. (this installed perfectly, and the Fink Installer appended the directory where it installed to /sw into my environment path).

Next to grab Boost...Fink has its own packaging mechanism, so you have to grab the packages from their site. Unfortunately, they haven't updated to Boost-1_37, so you have to make do with Boost-1_33.  (Here's where my frustration began) The files are protected so you have to run "sudo," to get prompted to enter your username and password.  This is your username/password of your Mac.  I haven't touched any flavors of Unix in 15 years, so I had to hunt to find how to give myself permission.  Searching the net I came across "sudo." So...

3) sudo fink install boost1.33-shlibs  (that is what you have to type...oh yeah, grab the terminal window from your /applications/utility folder. I moved it to my desktop for keeps).

After that grabs packages from the Fink site, type...

4) fink install boost1.33 (boost is now installed to /sw/include/boost-1_33_1

Thus, I went to XCode to include one of my Boost favorites, smart_ptr.h.  So, I type in #include "boost/smart_ptr.h" and compile, no need setting up code if I can't compile so that is all I added, and built.  Sheesh!  A compile error, smart_ptr.h could not be found.  Okay, how do I set an environment path on the Mac, after hunting for about an hour, I found a way that actually append the directory to the $PATH, ( echo 'export PATH=YOURPATHHERE:$PATH' >> ~/.profile, replacing "YOURPATHHERE") but that still didn't fix the XCode compile problem.

So, I found the Project Settings in XCode, goto Project, Edit Project Settings, Header Search Paths.  Double click that and hit the '+' button to enter the path where Fink installed Boost, "/sw/include/boost-1_33_1".

So, now I'm ready.  Damn it!  Still a compile error.  So, I went to the Boost folder (oh this is a peeve of mine with the Mac, the folders never give you the full paths of where you are...if someone knows if it is an option that needs to be set so that it appears on the folder, please shoot me a comment) to see if I had the path correct.  I did however, the file isn't "smart_ptr.h," on the Mac it is "smart_ptr.hpp."  So, with that change, I got my Boost.

Also, I kicked off "Time Machine," to backup my machine.  I backed up and burned all my Final Cut Pro stuff that was on my external HD to DVD, to make room.  The drive is 150 GB, the backup of my whole Mac is 87.78 GB.  The first time you run "Time Machine," it backs everything up, after that it only backs up whatever has changed.  So, I kicked that off around 8:15pm, the time is now 11:33pm and it has only copied over 44.64 GB.  So, it copied about half the machine in three hours, so I guess it has another three to go.

Well, I'm going to go do some more bridge testing, because I want to see what happens if a class has virtual functions.  I know that an Obj-C class cannot instantiate a C++ class (or its superclasses) that has virtual member functions defined.  

I want to find out if a C++ class inside an Obj-C class interface, can instantiate another class that has virtual member functions, because what I am trying to see if I can do is the following in iPhone code (the following code example is a snippet of what is found in the Delegate class in iPhone dev)...




- (void) RunGame
{
// lets assume StairwayToHeaven class is defined and apart of
// the Delegate class and has been instantiated
pStairwayToHeaven->RunGame(); // this would handle everything needed and all be in C++/Lua
}

/* That's where we initialize the game objects */
- (void) applicationDidFinishLaunching:(UIApplication*)application
{
CGRect rect = [[UIScreen mainScreen] bounds];
NSAutoreleasePool* pool = [NSAutoreleasePool new];
.
.
.

//Initializing game timer
_timer = [NSTimer scheduledTimerWithTimeInterval:(1.0 / kFPS) target:self selector:@selector(RunGame) userInfo:nil repeats:YES];

.
.
.
}

That is what I'm trying to do...have one interface out of Obj-C to C++/Lua heaven. I don't know if it is possible, but I intend to find out.

Sheesh

I did have the code correct. It's the HTML in the blog software, that is culling out the "<", ">" around the statement.

So, it screwed it up again...I'm not going to waste time w/ it, know that new C++ casting works.

Errata

I was just looking at my post, from early, early, this morning. And, something worked and I don't even know why. In the last post I had...

// testing in new C++ casting works in mixed Obj-C/C++
float fTest = 9.0f;
int nTest = static_cast(fTest); // it does
printf("nTest = %d\n", nTest);

Notice I have "static_cast(fTest);" some how that passed the compiler and linker, and still worked. What I wanted to do is see if new cast-ing worked in Obj-C, i.e.,

int Test = static_cast(fTest); // which it does.

So, that corrects, that.

Back to my day job (currently upgrading to VMWorkstation 6.5 and adding new comm communication, VMCI, to our Comm factory. Now, we can communicate via, straight sockets, Boost Asio sockets, and VMCI. Coding to interfaces make things very, very easy).

I've Bridged The Gap

I spent a few hours fooling around with the iPhone Views, and decided let me try the Objective-C/C++ bridging.  Well, it works like a charm.  I took the little test sample on the Apple Dev. Page and added some things I wanted to see if they would work.

Here's what I did...

// header file mixing C++ and Objective-C
// wouldn't want to really do this...keep the interface files separate for each class. 
// I just did it this way for sample/quick test purposes
// test.h

class Hello
{
private:
id greeting_text;

public:
Hello()
{

greeting_text = @"Hello, world!";
}

Hello(const char* initial_greeting_text)
{
greeting_text = [[NSString alloc] initWithUTF8String:initial_greeting_text];

}

void say_hello()
{
printf("%s\n", [greeting_text UTF8String]);
}

};

@interface Greeting : NSObject
{

@private
Hello *hello;
}

- (id) init;
- (void) dealloc;
- (void) sayGreeting;
- (void) sayGreeting:(Hello*)greeting;

@end

@implementation Greeting

- (id) init
{
if(self = [super init])
{
hello = new Hello();
}

return self;
}

- (void) dealloc
{
delete hello;
[super dealloc];
}

- (void) sayGreeting
{
hello->say_hello();
}

- (void) sayGreeting:(Hello*)greeting
{
greeting->say_hello();
}

@end


//
// C++ translation, Objective-C implementation, and main
// (again mixed together for easy reading)
//

#import
#include "test.h"
#include

int main(int argc, char *argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

// notice here...dynamic typing
std::vector testVector; // holds generic objects
id szTest = @"'ello Gov'ner!"; // Obj-C NSString (declared as a dynamic type)

// testing in new C++ casting works in mixed Obj-C/C++
float fTest = 9.0f;
int nTest = static_cast(fTest); // it does
printf("nTest = %d\n", nTest);

// instantiate the Greeting class
Greeting *greeting = [[Greeting alloc] init];

// test to see if I can use STL
testVector.push_back(greeting);
testVector.push_back(szTest);
printf("number of objects in the vector = %d\n", testVector.size());

// get the "sayGreeting" method from the Greeting class
SEL action = @selector (sayGreeting);
id tempObj;

short i = 0;
for(std::vector::iterator it = testVector.begin(); it != testVector.end(); it++)
{
printf("In vector loop = %d\n", i++);

// set the temp object
tempObj = *it;

// check to see if the object is our Greeting object
if( [tempObj respondsToSelector: action] == YES )
[*it sayGreeting];
else
printf("%s\n", [*it cString]); // it is our other object
}

// can also do C++ straight up
Hello *hello = new Hello("Bonjour, monde!");

// then mix it with Obj-C
[greeting sayGreeting:hello];

delete hello;
[greeting release];

[pool release];

return 0;
}

As you can see, you can mix the two together and also, take advantage of the dynamic typing in STL containers.  However, be careful as Ondra Cada, explained to me that you have to be weary about the memory management issues of Objective-C and garbage collection, if you leave an object around in a container for sometime and not use it, it could get thrown out, and well...leave you hanging (come on people, work with me).  Instead of using the STL Vector, you should use the NSArray in the Foundation class. 

I did this way to see what is possible with the language...I like it.  The built in "reflection," is fabulous, no fooling around with templates.

Okay, that's it for tonight (ahh morning).  Tomorrow, I will do a quick little test of archiving, writing/reading objects of diff types in/out.  Also, taking advantage of the Foundation class ability to serialize via XML and binary.  This is great for debug and release.  In debug you can XML to verify the data is correct, and then bundle it up in binary form for release.

Going to sleep.

Sunday, December 21, 2008

Bridging The Gap

Today I am writing little test apps that test bridging Objective-C 2.0 with C++. I want to test out the ability to call C++ classes from Objective-C, handling memory management, accessing Objective-C objects inside a C++ class (specifically "id"), making certain system calls via Objective-C, and dynamic binding.

As I mentioned in previous post, by me taking this approach I will be able to progress much faster, and also keep my code portable.

Time to go lay the bricks-and-mortar.

Friday, December 19, 2008

Thinking about...

I'm moving on to now to read up on Cocoa.

I've been mulling over in my mind, whether I would write my editor/engine all in Objective-C 2.0 or write a bridge to C++. I'm feeling like a rookie athlete. I'm new to Objective-C and thus, I'm doing a lot of thinking in the game, instead of things coming natural to me, and just reacting.

I think I will use Objective-C 2.0/Cocoa to handle system internals (the iPhone Framework, and Mac OS X), and use C++ for everything else. From the Apple docs..

In Objective-C++, you can call methods from either language in C++ code and in Objective-C methods. Pointers to objects in either language are just pointers, and as such can be used anywhere. For example, you can include pointers to Objective-C objects as data members of C++ classes, and you can include pointers to C++ objects as instance variables of Objective-C classes.

Of course, I'll be using OpenGL ES so that means C will be mixed in as well. I'll wrap the OGL ES in C++ classes. Also, thrown into this gumbo will be Lua which is C as well.

Some may be saying, "Apple's documentation says no interpreted code can be run on the iPhone, and Lua is interpreted." Well, I thought that as well, but then when I started seeing all the sophisticated games on the iPhone, I knew they hadn't reverted to using bit field logic in their games. The license agreement means that code that is intended to "download," and bypass the Apple Store cannot be run. Lua is running on the iPhone.

I am now 14 days into my journey. Wow! In 2 weeks I've actually accomplished quite a bit of things, and that is working on average 5-6 hours in the evening. I wish I could crank more time, but I do have to sleep, work my real job, and spend time with my two teenage boys.

I have implemented some things to help in my research time, and I wouldn't recommend for everyone. I keep a folder of printouts of things I wished to read and know, if traffic is backed up or crawling I get a little reading in. If I have some kind of appointment and have to wait, I'm reading...waiting in line for something, I'm reading. Anywhere I am alone (no one with me that I should be engaged in conversation) and there is free time I'm trying to maximize it.

I have put together a more detailed list of my tasks. I always keep narrowing the tasks to sub-tasks. I have created a tentative monthly milestones for myself as well. I have to have a road map, so that I'm not flailing all over the place. Every now and then I might diverge to try something that came to mind, but I've learned over the years that by giving myself imposed deadlines, and milestones, that on my journeys I will not get discourage because I can track and monitor what I have done with my time.

Right now at the beginning of this journey the road looks very, very long, but I know that I wrote, edited, storyboard, pre-production-ed, directed a weeks shoot, did another 3 days of pickup shots, and then edited a 4 hours of film down to a 40-minute movie (the movie, the movie, does this guy ever stop talking about that). The reason I bring it up is that I know the road looks daunting, but I know I can do the work, its just time...so since the time is limited I have to be laser focused and know the path.

Thursday, December 18, 2008

Going to be Objective

I just finished reading the Objective-C book. As, I said in an earlier post, I'm a believer. I will list what I like and don't like about the language. First the "Likes,"...

LIKES:

Archiving
Categories
Dynamic Binding
Fast Enumeration
Garbage Collection (caveat here)
Posing
Protocols

Dislikes:

Containers and the built in reference counts when accessing object elements
Memory management (retaining, releasing, dealloc-ing)

See the caveat in the "Likes," list next to Garbage Collection it is there because the iPhone does not support Garbage Collection, thus my "Dislikes," come into play. You have to be extremely careful and mindful of Object creation and use in Objective-C. In C++ you have to as well, but you can encapsulate it with the use of the Design Pattern, Singleton or with the STL auto_ptr or Booost's smart pointers. I'm going to have to be like Luke, in "Cool Hand Luke," and get my mind right, ("You run one time, you got yourself a set of chains. You run twice you got yourself two sets. You ain't gonna need no third set, 'cause you gonna get your mind right.")

I really like Dynamic Binding and Archiving. The two used together equals built in "Reflection, (somewhat)."

Well, the journey continues. I will now read up on Cocoa and make note of the differences between Mac and iPhone programming, since my game level editor and tools will be written to run on the Mac, and the game engine will be running on the iPhone. The game engine will be data-driven, but I want to be able to have the level editor be able to play test the levels in real-time, so the game engine will be leveraged to run inside the editor. This means I'll have some code that is specific to iPhone, and Mac OS X, i.e., OpenGL (running OGL ES on iPhone), and the UI objects will be utilizing different frameworks. So, I will have to make note of the differences, and have preprocessor directives to block out certain spots of code that I don't want compiled in.

Yes, Yes, I could write code with pattern(s) that could tell what environment I was running on and then set the behavior to fit, but the foot print of the iPhone is smaller so why compile in the excess baggage.

Tuesday, December 16, 2008

Still Reading...

I'm half-way through the Programming in Objective-C, and ahhh...I must say this is much better. I understand the language now and how it works. The Apple Docs were flying way to high for me. Now, I will be able to return to them later when I use as a reference and understand what is what.

I found a blog, too tired right now to remember the name of the blog, but the guy had done a daily blog of his experience at "iPhone Boot Camp," (you can "google," it and find). The camp is a 5 day/6 hour intensive hands-on retreat to learn every feature on the iPhone and how to program it. The camps are located in Atlanta,GA, Germany, and Italy. The camp cost is like $4500 for course, lodging, and food (airfare not included). The camp sounds great, but first I don't have $4500 to spend to go there, second I have deadlines at work, and third the iPhone sessions are all booked up until late next year, which is about *when* my game will be in the Apple Store (dude if you can't say it, then you don't believe it, and if you don't believe it, you won't achieve it..."I believe I can fly...").

So, what I did do is go to the iPhone Boot Camp site and printed off everything they cover, and printed out what the guy said he did daily at the camp, and I will mix in the things I need to learn to fit what I'm doing...I already have on my white board in my home office, the things I need to learn, but it is still good to compare to a course too. The intensive hands-on camp sounds great, and wish I could go, but I know me, if I did go to it, I would still have to come home and re-read it all, because that sounds way too fast for me to really grasp it.

Anyway, I'll do a bit more reading and then turn in for the night.

Sunday, December 14, 2008

Mission Accomplished

Okay...I did it.  I got the sprite up and running on the iPhone simulator.  I found a little Christmas cap PNG file, and used the GLSprite sample, made some modifications and viola, I accomplished my goal for myself. 

Let's take a look at my status...

Key (red = task completed, green = in progress, black = not started)
Tasks/Status

1) Learn the iPhone Tech
* Download/install iPhone SDK
* Upgrade Mac OS $130
* Join iPhone Dev $99
* Read iPhone Docs/Samples
** iPhone OS Technology Overview
** Cocoa Fundamentals Guide
** iPhone Application Programming Guide
** iPhone Human Interface Guidelines
** iPhone Development Guide

** The Objective-C 2.0 Programming Language
** Write little tests programs to learn the iPhone Capabilities (memory allocation, file I/O, iPhone audio, WiFi, graphics, etc...) - (sprite displayed by Dec. 15th)

2) Test my game concepts out on the iPhone
3) Build tool(s) if needed
4) Solidify Game Design
5) Architect the game code
6) Develop game w/ scratch art
7) Drop in real assets
8) Test/Debug
9) Ship It

Well, I think it has been a successful weekend.  I managed to get my development environment all setup, getting passed the iPhone SDK limitations of only running on an Intel processor baloney (stay humble for the programming Gods, stay humble.  Alright, I am...I take back "baloney.")  I built and ran code in the xCode environment, and got the sprite up on the simulator.

I'm going to spend time reading the "Programming in Objective-C," (by Stephen G. Kochan) book I purchased, and get a better understanding of the language from the ground up.  The Apple Documents are not good (imho) if you want to know/understand the language.

Adios!

The Setup






Yes, yes...tomorrow is Monday.  I'm working on it...


Saturday, December 13, 2008

Babies and Fools

 My grandmother always said, "God looks after babies and fools."  Well, seeing that I'm no baby, that means I'm a...(nahhhhh).  Well, let me tell you what happened and you tell me.  Today (while sitting here in the lounge at Ski Liberty, PA, while my oldest son and his friend snowboard) I decided I would get something up and moving on the iPhone so that I can achieve the milestone I set for myself, and also get on with my learning.  

So, we got here at 10:30am, it is now 4:30pm (and they are still out on the slopes...how do they do it).  Well, I figured just fire up xCode, build and run the "Hello, World," app and go from there.  I fire up xCode so that I could get the IDE to drop down the iPhone project setting for me.  Wait a minute, it isn't there.  I know I installed the sdk properly, days ago.  So, I go back to the installation folder and click again, and all is installed.  So, I google, to find why its not working.  

That's when the sinking feeling sunk in.  I read that iPhone SDK/Simulator runs only on Intel based Macs.  You see, I never read and for some reason never heard that iPhone SDK/Simulator only runs on Intel Processor based Macs.  My Powerbook is only 3 years old, and it is a PowerPC G4.  Do you hear me screaming in my brain, WTF!!!  WTF!!!

So, I google to see if anyone has worked around this.  I know from experience hacking the Nintendo DS, that now a days, anything is possible.  So, the first thing I stumble across is that the sdk installer sees that the processor it is trying to load to, isn't Intel, so I doesn't add the files for the iPhone, and the simulator.  However, all 50 of the packages that are needed are still in the install folder and you have to manually install them yourself.  So, 2 hours of installing, you know the developer feeling (excitement mixed with trepidation).  I fire up xCode, and too my excitement and joy, the iPhone project option is now in the drop down menu. Woooohoooo!

Next, build and run.  Arrrgghhhh!!  I get the build error that I'm running on an "invalid architecture."  Sheesh.  So, google this error message, and I find another site that says exactly what to modify in the iPhone Simulator specification file.  

Viola!  

I'm now running the iPhone SDK and simulator on my G4.  Now, I haven't tried the code running on an actual iPhone, since I have not paid the $99 to get my certificate to run on the actual device.  I guess I will find out when I try.  Anyway, I didn't have to shelve out $3K for a decent development mac.  I can now develop and test...later when I get to the point of App Store submitting, I will spring for a cheap Intel Mac to recompile on, and certify the app (if needed).

Now, why would Apple lock out PowerPC G# owners.  Now, there could be some really good reason, but I believe the real reason, was to sell new machines.  I could be wrong, but if it only takes a few additions to a specification file (still new to Mac dev, but this file is basically a INI file in the PC world), then there is no real hardware limitation that I see.  However, I won't get to cocky, I could run into the reason down the road and be thoroughly upset.  In the meantime...I'm up and running baby!

Since there are a few steps to detail to get your G3, G4, or G5 working with the iPhone SDK/Simulator I will give the credit where credit is due, and you can go to the sites, "3by9" by Mike Rundle, and "Lehmamic's Web Blog, This and That" (author unknown) to see what's needed.  Or shoot me a comment if you don't wish to go fishing around.  I will post the steps on a blog entry.  Right now, I'm just psyched to get on with my coding and testing out the iPhone/Simulator.

Now to get a sprite up on the screen and moving.  I still have a few hours before the boys get tired of snowboarding and there still is...tomorrow, tomorrow, it's just a day away.

Friday, December 12, 2008

It's Here!

My free iTouch has been delivered! I will open the box this evening, and get started by setting it up to be in the Dev Program, and allow me to sign code to run on the device.

My personal challenge of having something up and running by Monday is still on. I've got the weekend ahead of me. :)

L8R

Wednesday, December 10, 2008

I believe, I believe, I believe

Hey,hey,hey, I'm a believer...

After reading through the first parts of Objective-C, I can say that I'm a believer. When I initially saw some source code of Objective-C a few years ago, I quickly turned away from it. Even when I started thinking about doing this game for the iPhone, I figured, "well I will just do the necessary Objective-C/Cocoa stuff to get the thing running, and then wrap C++ code into Objective-C wrappers."

Well, reading through the documentation, my eyes have been opened, and I'm no longer a xenophobe. I know, I know, I haven't finished reading all the way through the doc, but I already know that I will be doing the game completely in Objective-C, and making judicious use of the Dot syntax as opposed to the square brackets [] to invoke the accessor methods, for those not familiar with Objective-C, but have seen it, the dot syntax allows you to replace the square brackets [] you see everywhere, with a dot syntax...a short cut to do the same thing, and is just a bit more appealing, and comfortable to my C/C++ eyes.


I am not going to evangelize (be like those folks, who go to church for the first time in their life, and then come out on fire trying to convert everyone they see), nope...just wanted to post that my fears of Objective-C are gone.

Hallelujah! Brother can I interest you in this pamphlet...haa haa...just kiddin'.

Tuesday, December 9, 2008

Late Start

Okay...I'm sitting down to read the Objective-C 2.0 doc, and the iPhone SDK is downloading. Getting a late start tonight, because I was helping my youngest son, prepare for his Algebra quiz tomorrow. I showed him how to transform a word problem into a linear equation, If Bob sells 200 items at a commission of 70%, and his weekly earnings is $1500, what is Bob's base salary?

I've ordered my FREE iTouch from the Apple Store using my American Express bonus points so it should be here by the end of the week (we'll see...the FedEx tracker said it was being shipped from Shanghai).

Going to read...oh by the way, if any of you have forgotten how to solve those algebra word problems via linear equation, it is...

1500 = 200 * .70 + base
1500 = 140 + base
1500 - 140 = base
1360 = base

Cya or Objective - Cya next posting.

Baggage Claim

The plane has touched down and I've made my dash to grab the translation manual (see previous post for reference). I realized that I personally need a better foundation before I will understand Cocoa. I am now going to read the Objective-C 2.0 Programming Language documentation. Others who are new to Cocoa & Objective-C might be able to understand Cocoa first before understanding Objective-C, but for me I need to be grounded in the actual coding language. To me its like learning Swahili, Spanish, or French, and being shown sentences, before learning the words. I'm going to go learn the alphabet first, then the words, and then I'll be able to construct sentences much more easily, and not only that, know WTF I'm saying.

So, off to...ahhh...I'm going to bed now...I'll start that tomorrow evening. Buhh-bye!

Oh yeah...I've provided a key now,for the Task/Status since some folks may not have read the earlier posts.

(Dude...did you say, "some folks," son... let me, let YOU, in on a little secret. NO ONE has read your earlier posts, no one cares what YOU have to say. How many comments have you read?...Well, there were 2 last year, and 1 just recently...how Gyuri even stumbled onto your *little* blog I don't even know.)

Key (red = task completed, green = in progress, black = not started)
Tasks/Status

1) Learn the iPhone Tech
* Download/install iPhone SDK
* Upgrade Mac OS $130
* Join iPhone Dev $99
* Read iPhone Docs/Samples
** iPhone OS Technology Overview
** Cocoa Fundamentals Guide
** iPhone Application Programming Guide
** iPhone Human Interface Guidelines
** iPhone Development Guide
** The Objective-C 2.0 Programming Language
** Write little test programs to learn the iPhone Capabilities (memory allocation, file I/O, iPhone audio, WiFi, graphics, etc...) - by Dec. 15th

2) Test my game concepts out on the iPhone
3) Build tool(s) if needed
4) Solidify Game Design
5) Architect the game code
6) Develop game w/ scratch art
7) Drop in real assets
8) Test/Debug
9) Ship It

Monday, December 8, 2008

Huhh...What?

Okay...right after work I went to the Apple Store in Bethesda, Md. and purchased the Mac OS X/Leopard, it is currently chugging away on my Mac Book Pro, installing itself. I'm spending my time continuing reading Cocoa/Objective-C and I must admit I'm bouncing around in my seat, hanging on for dear life, as I experience a bit of turbulence.

The Cocoa Fundamentals Guide is starting out to me at a very high altitude, "this is your captain speaking, we're experiencing a bit of turbulence, I'm turning the seat belt sign on...." I will continue pushing through, and hope that when I pay my $99 for the iPhone Developer Program that the Objective-C Primer I see listed will start with us boarding the plane. Hell, I'm flying high in coach, and I didn't even get stripped searched, pushed through the metal detector, thrown in that glass case and had that puff of air up my ass. What? You haven't experienced that at the airport check-in, must be because I'm a Black man! :)

I'll sit back and watch this foreign movie without the subtitles and see if I can make something out of it. As soon as this plane lands I'm hoping off, and grabbing a translation manual.

I'll pony up the $99 as soon as the Mac OS X upgrade finishes loading, and that will open the ivory tower up to me, and allow me to read the sacred tombs.

Tasks/Status

1) Learn the iPhone Tech
* Download/install iPhone SDK
* Upgrade Mac OS $130
* Join iPhone Dev $99
* Read iPhone Docs/Samples
** iPhone OS Technology Overview
** Cocoa Fundamentals Guide
** iPhone Application Programming Guide
** iPhone Human Interface Guidelines
** iPhone Development Guide
** The Objective-C 2.0 Programming Language
** Write little test programs to learn the iPhone Capabilities (memory allocation, file I/O, iPhone audio, WiFi, graphics, etc...) - by Dec. 15th

2) Test my game concepts out on the iPhone
3) Build tool(s) if needed
4) Solidify Game Design
5) Architect the game code
6) Develop game w/ scratch art
7) Drop in real assets
8) Test/Debug
9) Ship It

"Don't bully me, Daniel!"

Oh...I just read an article (yes, still with the magnifying glasses hiked on top of my regular glasses) about Steve Demeter. He developed the puzzle game, "Trism," for the iPhone. In the article he mentioned that he had a working prototype up of his game in 10 days. 1o DAYS! He knew nothing about the iPhone SDK, or Objective-C e'der. Now, how much of a working prototype do I believe he had in 10 days, I'm skeptical, but I love a good challenge. So, I'm challenging myself to have something up in running on the iPhone simulator, since I don't currently own an iPhone or iTouch, in the next 10 days. Since I started my research into iPhone development, last Friday (Decemeber 5th) that means I'm already 3 days behind, and now have 7 days to get something up and running.

So, for those not familiar with Mac OSX development that means I have to learn a new IDE (XCode), Objective-C, and the iPhone SDK, in 7 days in order to get something up on the screen. Ahhh...I like a good challenge.

Hmmmn...I've got a bunch of American Express bonus points that I've never used. I just did not want to spend 400K points on a calculator. However, I did see in their last catalog an iTouch. I will use the majority of my accumulated points on it (thus a free iTouch). I already own a 17" MacBook Pro (purchased 3 years ago to edit my 40 min. short film - which did get into 2 film festivals I brag...no need in being humble, that sh$t was hard work my friend, so I pat myself on the back every chance I get). So, I have to upgrade my OSX, $130. I'll stop by the Apple Store on the way home, and pick that up.

Thus my schedule of tasks stays the same (see below), with the caveat of my having little test program up and running by next Monday (keep in mind I have a day job -and we must all count our blessings for that, in this economy-) so you know I'll be scrambling.

Tasks/Status

1) Learn the iPhone Tech
* Download/install iPhone SDK
* Upgrade Mac OS $130
* Join iPhone Dev $99
* Read iPhone Docs/Samples
** iPhone OS Technology Overview
** Cocoa Fundamentals Guide
** iPhone Application Programming Guide
** iPhone Human Interface Guidelines
** iPhone Development Guide
** The Objective-C 2.0 Programming Language
** Write little test programs to learn the iPhone Capabilities (memory allocation, file I/O, iPhone audio, WiFi, graphics, etc...) - by Dec. 15th

2) Test my game concepts out on the iPhone
3) Build tool(s) if needed
4) Solidify Game Design
5) Architect the game code
6) Develop game w/ scratch art
7) Drop in real assets
8) Test/Debug
9) Ship It


Sad news...I was following Noel Llopis (game developer, author, biz owner) blog "Power Of Two Games," he and his friend where embarking on making a game w/ just the 2 of them. Sadly they have shut it down after about 2 years, and what do I read he's doing on his old/new blog, "Games From Within," iPhone game development.

Well, off to do my day job, and can't wait to get home this evening...10 DAYS! 10 DAYS! "Don't bully me, Daniel!"

Sunday, December 7, 2008

ZZZZZzzzzzzzzzzz

I've got a headache and my eyes hurt. The pain isn't from the iPhone studying, no, so far, I like what I'm reading (halfway through the Cocoa Fundamentals Guide). My headache and eyes hurting are from the fact that I'm waiting on my new glasses to come in on Thursday, so right now in order to read, I have a pair of those cheap magnifying glasses you get from the drug store, propped up over my current eye glasses to try and make the text bigger. The strain on my eyes is now palpable.

Well, it has been a good weekend start to my iPhone game development. As I type the iPhone commercial with the games just aired...must be a sign. :)

Good night.

Click, click, click

Click, click, click, that's the sound of me adjusting the view lense even tighter, zooming in closer on one of the bullets I listed under "Learn the iPhone Tech." I am talking about "Read iPhone Docs/Samples," after doing some reading last night and jumping from one topic to the next, iPhone Dev, Cocoa, Objective C, UKit Framework, blah, blah, blah. I decided that it was going to require a planned and detailed directions, so as to eliminate wasted sight-seeing on this journey. Believe me there's lots of cool sites and fascinating things to see, but I'm going to try and do them in order, and not break from the path, "oh look, look at that!," that way I'll be able to get where I'm trying to go in better time.

So, the breakdown of "Read iPhone Docs/Samples," is to read the docs in following order;

* iPhone OS Technology Overview
* Cocoa Fundamentals Guide
* iPhone Application Programming Guide
* iPhone Human Interface Guidelines
* iPhone Development Guide
* The Objective-C 2.0 Programming Language

I will keep a running status for myself here on the blog of what is currently being worked on or done (highlited in green), what's been accomplished (highlighted in red), and the remaining tasks will be listed.

I am a little neurotic about logging what I'm doing, I won't do it here, but at work I keep a digital logger, that I log everything I'm doing (dated & timed), so there are entries like every 10 minutes. It comes in handy when something stops working or I have forgotten something, I can quickly search my logs and viola, I'm usually saved.

Tasks/Status

1) Learn the iPhone Tech
* Download/install iPhone SDK
* Upgrade Mac OS $130
* Join iPhone Dev $99
* Read iPhone Docs/Samples
** iPhone OS Technology Overview
** Cocoa Fundamentals Guide
** iPhone Application Programming Guide
** iPhone Human Interface Guidelines
** iPhone Development Guide
** The Objective-C 2.0 Programming Language
** Write little test programs to learn the iPhone Capabilities (memory allocation, file I/O, iPhone audio, WiFi, graphics, etc...)

2) Test my game concepts out on the iPhone
3) Build tool(s) if needed
4) Solidify Game Design
5) Architect the game code
6) Develop game w/ scratch art
7) Drop in real assets
8) Test/Debug
9) Ship It

Off to read...

Saturday, December 6, 2008

iPhone Dev. Step 1

Okay, so "it begins." First things first, I've mapped out a temporary task/schedule list, that I've broken out into 9 key steps. Each step I will later redefine into even smaller tasks that I can easily track down to hourly tasks. I start out high, and then zero down. The following are the 9 high level steps.

1) Learn the iPhone Tech
2) Test my game concepts out on the iPhone
3) Build tool(s) if needed
4) Solidify Game Design
5) Architect the game code
6) Develop game w/ scratch art
7) Drop in real assets
8) Test/Debug
9) Ship It

So, breaking step 1, into some smaller tasks...

Learn the iPhone Tech

* Download/install iPhone SDK
* Upgrade Mac OS $130
* Join iPhone Dev $99
* Read iPhone Docs/Samples
* Write little test programs to learn the iPhone Capabilities (memory allocation, file I/O, iPhone audio, WiFi, graphics, etc...)

These are my step 1 tasks, and as I go along I will try to give updates of what I'm working on and what has been accomplished. So stay tuned...

On Fire

Okay...last time I posted I said I hadn't had time to do Nintendo DS programming, so I filled you in on my day time job work. Well, I am here to tell you that I have been inspired and back to working on a game in the evenings. However, not for the DS, but, for the iPhone.

Okay...even though I don't own an iPhone or iTouch at this moment I've been designing the game I want to do for it, and in the process of upgrading my Mac OS so that I can do the development. So, since this blog is the "RealityOfDreams," I propose to blog about my journey from idea, to final product. I will inform you of the decisions I am making and the code/architectural design directions that I am moving in. Hopefully, this will chronicle my steps, and provide some insight to some on what goes into making a game (even on a small scale).

Now, one thing I will not do in this blog is say what the game is or show screen shots, until it is near completion, yeah...that's right...I'm paranoid. "Dude! I could program that dumb idea of yours in 20 minutes!" I'm glad you can, so go do it, and dream up your own idea.

So, lets get to it...

This is going to be pretty much a "one man," project. However, I'm still going to employ software "Best Practices," as best I can. So, I am going to employ the development process, flesh out requirements, architect using GoF patterns, TDD (test driven development), see if I can implement some automated testing, build a "Tinderbox," (project builder, that grabs on specified time, latest checked in code, smoke tests, and builds the project, thus notifying if the build succeeded or not).

I will use quick and dirty artwork to verify my design, game play, and tech decisions...when all is finalized I will then employ an artist I know to render the real artwork, assets needed. The same goes for the music, and sound FFX in the game. I will not do any early users play testing/feedback, iterative process. Why? After you read the next paragraph, you will know why.

How did I arrive here, at this decision, "at this defining moment," (my man Obama, said that)...this game has been eating at me for some years now. In fact, I actually programmed it years ago for the PC, and folks played it and liked it. This will tell you how long ago that was, my oldest son (now 14 played), played the game when he was 4 years old. I programmed the game in 6 months, along with a great artist, and had users play and respond on the game play. Doing this in an iterative process I was able to tweak the game and make it fun. So, back to the previous paragraph, this is why I won't be getting feedback while I work, I am confident in the "fun factor," of the game. Arrogance, conceit, stupidity...no grasshopper, I have felt the pebbles of this path before. So, if it was sooo much fun, why haven't I heard of it, why can't I play the previous version?

To make a long story short, I did the cardinal sin, I never made a back up of the game (well...I believe that I did, but never could find it), and one day I came home and the code was wiped off the hard-drive, someone who will go nameless, removed the game to make room, to install some other bullsh&t on the computer. So, the despair, and anger I felt lasted for some time, and its always, been itching at me to re-do it. After looking at the iPhone, I decided that it is the perfect machine to recreate my game on.

Thus, for the past two days I've been "on fire," writing down my ideas, re-designing the game, making notes, jotting questions for myself to figure out, etc...I feel "alive," again. The creative sparks are flowing. Of course this is how we all begin...a ball of excitement and momentum, but can it be sustained, well, we'll see what happens..."The journey is the reward," (my man Steve Jobs, said that).

Thursday, October 30, 2008

New Direction

Okay...I don't even know who has been reading and who hasn't, but since my day job has completely stopped me from being able to hack the Nintendo DS, what I have decided to do is post what I am doing on my real job for now, and perhaps get back to DS hacking at some time.

What is your real job, Rod?

I hear you asking. Well, I work for a start up, Secure Command, LLC, and we are/have developed an application, Internet Cleanroom. Internet Cleanroom, works on virtual machine technology. My boss, Dr. Anup Ghosh, a leading researcher in computer security has taken his research and has made it a commercial product. I am the lead developer of the application.

What is Internet Cleanroom, Rod?

I thought you might ask that. Well, Internet Cleanroom, allows you to go anywhere, do anything on the Net without having to worry about malicious code, or infections. IC (Internet Cleanroom) is a preemptive measure, instead of running virus scans after the fact, to see if your machine has been infected, IC will let you know immediately, while it is taking place, more on that later. IC runs your designated applications in the safe, secure enviornment of a virtual machine.

A Virtual Machine?

Yes, if you are unfamiliar with virtual machine technology I can blog on that next time, but for now just imagine it as another computer (a separate desktop environment running your operating system) on your computer. This VM (virtual machine) is now where you work and do whatever you wish to do on the Net with no worries (hakuna matata). The IC, VM works like a whiteboard, do what you wish, download what you like, go where you like, do whatchalike (ahhh...my name is Humpty, pronounced with an Umpty...okay, okay, got a little jiggy there). So, back to the white board concept.

Imagine you go to some site, I don't know, www.hotparticleaccelerators.com, those leptons, quarks, and gluons, sure are sexy, anyway, you download some super-string theory article, and BOOM, the recreation of the Big-Bang theory has just blue screened your computer, or worse, some Bekenstein-Hawking radiation has slowly creeped onto your machine, and stealthily and systematically, is opening a black hole onto your computer. "There's no need to fear, IC is here!" You don't panic, you actually smirk at the intruder, and like a white board, you take out your eraser, wipe it away, and go on your merry way.

You are in the safe confines of a VM so all you do is hit the revert button on the application and poof, you have a new pristine environment.

That's it?

Yes, that's it, but wait, there's more...tell them what else they get Rod. IC allows you to see the culprits in action, with our technology will call "WebCanary," (like the canary in the coal mine). When you are working in a VM, and something spurious takes place, we immediately pop up a dialog box and inform you that an infection attempt is taking place, you can just revert the machine, but if you are like me, and curious, then you can click the button on the dialog, that allows you to see what the culprit is doing live. The WebCanary is a forensic tool that allows you to see all that the malicious software is doing, all the goodies, url redirection, buffer overflow attempts, renaming of files, registry writes, hidden file attempts, spawning of processes, etc... The processes the malicious software writes and launches, we capture and take a MD5 hash snapshot of it and we can verify if it is legit or not, and the most important thing to you is we capture the URL of the culprit. Actually, with the WebCanary, it is fun to try and find malicious sites, because now you can see exactly what the hackers are trying to do to your machine, its like holding a glass jar with angry hornets inside, and you can just watch, gaze up close, and if you are a little devilish, shake the jar around and watch them get angrier (hee hee hee).

Well, there is some other cool stuff IC does, but I've got to get back to work. Perhaps, I post some screen shots, or you can go to www.securecommand.com for more info. There is a beta on the site, that allows you to run a secure browser, but it doesn't include the WebCanary, but you can get an idea of the power and safety of working in the VM.

Until next time...be safe out there, its a crazy Web.

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