Archive

Archive for the ‘Defender DS’ Category

Defender DS Sourcecode

November 12th, 2007 Ant No comments

Based on the fact that I don’t get much time to work on my homebrew projects, and that Woopsi is currently monopolising all of that time, I’ve decided to release what little of DefenderDS I managed to put together.

The archive is here:

DefenderDS

As usual, it’s a VC++ project. The whole lot is under the BSD licence, so pinch any bits that you want for your own projects (remembering to abide by the few restrictions imposed by the licence).

Defender Title Screen

From what I remember, the interesting parts of the code are the animated sprite class, palette cycler class and the sprite number management system (which would need to be stripped out of the Game class and inserted into a new class to be useful). The sprite class simulates a fixed-point single decimal place for sub-pixel movements, by internally multiplying all its values by 10 (though it doesn’t do sub-pixel rendering, natch). The wrap-around functions are specific to Defender, though, and probably won’t be much use elsewhere.

The code is getting on for 8 months old, so I’d probably do things in a different way now. Looking through it, I can’t see any obvious problems, though, aside from it not drawing an explicit distinction between class members and other variables in the naming convention.

So far, it has the following features:

  • Background mountains
  • Humans
  • Landers that scout for humans, tracking the mountain terrain
  • Lander warp-in
  • Lander explosions
  • Lander mutation
  • Scrolling
  • Palette cycling
  • Scanner

My homebrewing plans for the future mainly involve Woopsi - getting the library finished, possibly porting it to the GP2X-F200, and then maybe even writing some applications with it (as that was the whole point of the exercise). Unfortunately, that means DefenderDS is probably a dead project. Shame, really, as this whole blog exists solely because I wanted to keep a development diary for the game. Funny how things turn out, innit? Still, DefenderDS served its purpose - it was an introduction into DS homebrewing, let me dust off my Blitz BASIC skills, and expanded my C++ knowledge.

Categories: Defender DS Tags:

DefenderDS Returns Back!

July 3rd, 2007 Ant No comments

Back to coding DefenderDS after a break of just over two months. Think I ran out of steam for a while, and I’m trying to get back into it now.

First thing I’ve done is sort out the explosion creation/destruction object initialisation. The explosions weren’t getting destroyed once they’d played, in order to reduce the amount of work done each time they were shown. The problem with this is that each explosion consumes around 12 sprites. If we have 8 landers, 4 pods, the player’s ship, 4 player bullets, a dozen enemy bullets and a dozen humans in a level, we’ve already used up 41 sprites. 25 of those have explosion objects, which gives us around 300 explosion sprites hanging around in memory for no reason. As the DS can only work with 127 sprites at once (I say “only”, but to put it into perspective I think the Amiga had 8 hardware sprites), it obviously wasn’t going to work.

Explosions are now destroyed and created when they are needed, which should prevent us from ever hitting the sprite limit.

I’ve tidied up the mountain code. Previously, I was passing a pointer to the mountain data into the game object’s constructor, which in turn passed it to the mountain drawing object and the scanner. This is clearly bonkers, as it is much easier just to #include the mountain data in the files containing those two classes.

Finally, I’m putting some thought into the way the scanner, mountain and game objects are created. They are currently created as standard objects, but I think a singleton pattern would probably be a better solution. How many scanners am I likely to create simultaneously? How many games do I want to run at the same time? The answer to both is just one, so it doesn’t make much sense to have to pass pointers around when using the singleton pattern would be much easier.

I can see why I’ve written it the way it is at the moment. I’ve spent far too much time developing web systems and so have become instinctively suspicious of using static members, methods or classes. In a web system, be it PHP or .NET, anything marked as static is shared across the entire application, not just the current session. Websites are multi-user, so if user A sets a static property, user B will see the same value. Should user B set it to something else and user A attempt to retrieve the property, they will be given the new value, not the value they set it to.

In DS development, though, this isn’t a concern. There will only ever be one instance of Defender running on the DS, and only one user will ever be playing it. Makes things easier.

Categories: Defender DS Tags:

Why?

April 29th, 2007 Ant No comments

So, why am I writing Defender for the DS? This is pretty much the reason:

http://makingtheswitch.wordpress.com/2007/04/28/when-did-i-become-such-a-tool/

This is the first project of my own that I’ve worked on in about 18 months, or about 2 years if you ignore anything to do with websites, Pong or half-finished games written in SQL.

Categories: Defender DS Tags:

More Explosions

April 25th, 2007 Ant No comments

Explosions now work. Had them working more or less OK much earlier, but more or less wasn’t quite good enough. Wrote a routine that calculated where each fragment of the sprite had to go and moved it to that location. Easy enough. Then realised that one row of fragments and one column of fragments weren’t moving - the explosion was off-centre.

Kept mucking around with the algorithm until I realised it made no sense (it made sense when I wrote it), so started again on paper. Such a simple routine yet got into all sorts of tangles trying to write it.

Anyway, it now works properly, in two directions - it functions as both an explosion (fragments radiate from a single point) and an implosion (fragments congregate to a single point). Means the same class doubles as the enemy explosion routine and the enemy warp-in routine.

Note to self (as I won’t remember this later) - when dealing with shapes that appear to have unusual explosion patterns, the missing fragments are just blank sprites. This is the standard situation (an “O” represents a fragment in the explosion):

OOOO
OOOO
OOOO
OOOO

This is the “unusual” situation:

__O__
_OOO_
OOOOO
_OOO_
__O__

It looks like it’s an exploding diamond shape, but the underscores are just blank sprites. (This is the way the pod explodes.)

Oh, and sprite palette changing still doesn’t work in anything but DeSmuME. I was looking at the wrong emulator ealier.

Categories: Defender DS Tags:

Palettes, Sprite Numbers and Global Variables

April 25th, 2007 Ant No comments

Trying to chop up the existing sprites and use them as explosion graphics turned out to be impractical due to the way the sprite system works in PALib. Decided to use individual files instead, but then I ran into a problem - the DS can have 15 sprite palettes, and I’ve already got more than 15 different sprite bitmaps. Checking the PALib forum reveals that PAGfx can use the same palette for multiple sprites so long as the total number of colours doesn’t exceed 256. It’s easy to do; just change the PAGfx.ini file so that all sprites use the same palette name:

Sprite1.bmp 256colours sprite0
Sprite2.bmp 256colours sprite0
Sprite3.bmp 256colours sprite0

Each bitmap uses a palette called “sprite0”. PAGfx automatically adds any new colours from each image into the palette. Clever stuff; I thought I was going to have to do it manually.

Apart from reducing the number of sprite palettes to 1, this had two beneficial effects. I no longer have to pass palette numbers around in sprite constructors, which saves a small amount of hassle. It’s also somehow fixed the mutants’ palette cycling routine. Not sure how, but I’m not complaining.

Another change I’ve made is the way that the game handles sprite numbers. The DS can have up to 128 2D sprites running simultaneously. In the PALib, each sprite is given a unique number between 0 and 127 and is tracked using that number. I originally implemented a simple system in which the “Game” class tracks the current sprite number. Every new sprite is passed a pointer to the current instance of the Game class, and they request a sprite number from that instance in its constructor. Each time a request is made the game increases its internal count of sprites used.

This works OK until sprites start getting deleted and new sprites added, at which point it all falls apart. It would be possible to create and delete a single sprite 128 times, and then, when trying to add another sprite, the DS would crash because we’re trying to allocate sprite 129. We wouldn’t even have a single sprite active at that point.

Instead, I’ve gone for something more akin to the way Flash handles movie clips. The Game class now stores an array of 128 boolean values. When a new sprite requests a sprite number, the game scans along the array for the first false value, sets that value to true, and returns its index. When a sprite is destroyed it tells the game to set that array item back to false. This way, sprite numbers are freed up as sprites are removed from the game, and the game class always returns the lowest free sprite number.

Today’s final discovery involves global variables. Up until now I’ve been passing bitmap pointers created by PAGfx between classes because they’re inaccessible in files other than “main.cpp”. This got impractical when I began working with explosions - passing 12 bitmap pointers between three or four different classes was just not practical. Searched the PALib forum and discovered that all I had to do was include the “all_gfx.h” file in my other files, the same as any other header file. Doh!

Categories: DS Coding, Defender DS, PALib Tags:

Vectors and Memory Leaks

April 25th, 2007 Ant No comments

After I’d got libnds working in VC++ I went back to coding DefenderDS with PALib. First task was to fix a bug that caused the game to crash if there were no humans left for landers to pick up. That was pretty simple.

Whilst fixing that, though, I realised that my sprite destructor wasn’t getting called when a lander or human was removed from their respective vectors, or when the vector was emptied. The empty code looked like this:

while (landers.size() > 0) {
    landers.pop_back();
}

I used this code because I’d read that using the “.clear()” method didn’t dispose of the objects pointed to by the pointers in the vector. Did some googling to work out what was going on, and it turns out that I’ve made a classic beginner’s mistake. The “pop_back()” method just removes the pointer. Now that I think about it, this is horribly obvious. So, I’ve changed the code to do this instead:

for (u8 i = 0; i < landers.size(); i++) {
    delete landers[i];
}
 
landers.clear();

No more memory leaks. I’ve fixed this problem in DefenderDS, MenuDS, SlideshowDS and ScrollingTextDS, but haven’t got around to releasing new versions yet.

Explosions

April 23rd, 2007 Ant No comments

Quick update. Need to add in player’s ship before work on enemies can continue. Also need to write explosion code, which is a little bit more interesting, so working on that. Original game uses “x.frags” files, where “x” is the name of the sprite, to store explosion bitmaps. Think I can do this more efficiently by just splitting up the bitmaps I’m using as the enemy sprites into chunks.

Will give it a go and see what happens.

PALib has ceased development today - author is taking some time away from it. Having had dreams about IK++ for a month whilst working on that, and once dreaming the code for a complete version of Asteroids in Blitz BASIC*, I can sympathise with his position. Sometimes you just have to abandon your code and do something else or you’ll go mad, especially if you work as a programmer as well as code in your spare time. However, that still leaves me with non-functioning sprite palette code. Bah.

*I never did write a version of Asteroids for the Amiga. After spending a night writing it in my sleep, the last thing I wanted to do was write it all over again whilst awake.

Categories: Defender DS, PALib Tags:

Mutants and Bugs

April 22nd, 2007 Ant No comments

Landers now get converted into mutants when they ascend off-screen. I hit a bit of a snag with the mutants - in the original game, the mutants use the palette cycling effect instead of animation. I had to alter the palette cycling routine so that it was possible to manipulate sprite palettes as well as background palettes (the two are apparently separate).

That was tricky enough (not modifying the code, that was easy; the difficult bit was working out that the PALib works with the two palettes as completely separate entities). Finally got it working in DeSmuME. Fantastic. Try it on real hardware.

Doesn’t work.

Try it in No$GBA and it doesn’t work there either, so I tried it on my original DS and it still doesn’t work. No idea what the problem is, but after testing it with a very simple example that comes with the PALib I’ve concluded that I’ve come across another PALib bug. Submitted the bug to the forum, but I’m now stuck with broken palette cycling until it’s fixed.

Gahh.

Categories: Defender DS, PALib Tags:

Human Pickup #2

April 22nd, 2007 Ant No comments

To answer my previous question, landers that don’t have a human to pick up should just wander the landscape. This is now in place. Landers also now choose the shortest route to a human. Previously they couldn’t calculate distances across the world wrap boundary, so if a human was at position 2040, for example, and the lander was at position 1 (ie. 10 pixels apart), the lander would travel to the right (across over 2000 pixels) instead of travelling left (10 pixels).

Categories: Defender DS Tags:

Human Pickup

April 19th, 2007 Ant No comments

Landers now pick up humans. The whole thing is state-driven - the landers have a state (eg. “looking for human”, “descending to human”, “ascending with human”) as do the humans (“walking”, “falling”, “ready for pickup”).

One bug remaining - what should a lander do if there are no more humans left to pick up?

Categories: Defender DS Tags: