2009-12-13

Creating Fonts and Bitmaps

More work on fonts. Jeff’s solution for creating PackedFont fonts is fantastic - instead of mucking around with u16 arrays, he subclasses the fonts and does all of the work for you. Instead of this:


PackedFont1* myFont = new PackedFont(somearray, somewidth, someheight, blah, blah);

…you have this:


NewTopaz* myFont = new NewTopaz();

So much easier.

I’ve shamelessly stolen this idea and reworked the existing “FontBitPacker” application so that it follows this pattern. I’ve heavily modified it so that the app will convert BMP files to either MonoFont, Font, PackedFont1 or PackedFont16 font classes. As long as they have version 3.5 of the .NET framework, Windows users no longer need to faff about with PAGfx or the bmp2font Python script. The new “bmp2font” .NET console application (which the FontBitPacker has become) will do all of the font conversion work needed for Woopsi.

This pattern seemed like such a good idea I’ve used it for bitmaps, too. Instead of converting BMP files with PAGfx, then using the “all_gfx” files to include the bitmap data before wrapping them up in a BitmapWrapper class, it is now possible to use a new “bmp2bitmap” .NET app to convert straight from a BMP file to a BitmapWrapper subclass.

These new programs have enabled me to delete the PAGfx binary and the files it converted from the Woopsi demo folder. I’ve replaced the converted files with classes converted with bmp2bitmap.

2009-10-24

Woopsi 0.39 Released

A new release! Download it at the SourceForge page as soon as SourceForge decide to update the front page. In the meantime, here’s a direct link:

Woopsi Source 0.39

Excitingly, in upgrading to the new layout, SourceForge appear to have lost all of the release notes I painstakingly appended to each Woopsi release.

Anyway, here’s a quick recap of the features in this latest version.

New Features

The TextBox and MultiLineTextBox now listen for the d-pad and respond to left/right presses by moving the cursor in the corresponding direction. This only happens if the gadget in question has focus.

The source distribution includes a new “tests” folder. Now that Woopsi is maturing it’s about time that I tested it properly. Each gadget in the system will eventually have a comprehensive test application in this folder; for the moment, just the CycleButton and RadioButtonGroup have test programs here.

As mentioned in the last post, Woopsi can now load and save 24-bit BMP files. It has two new classes in the “bonus” folder - BinaryFile and BitmapIO - to handle this. There is a new “BitmapLoader” example in the “examples” folder.

Bugfixes

As you’d expect, now that there’s a test harness for them, there are a number of bugfixes to both the CycleButton and RadioButtonGroup gadgets. There are few bugfixes to the base Gadget class that were similarly highlighted by the new tests. The Bitmap class also has had some fixes implemented to solve problems that arose when writing the BMP loader. Other bugfixes are listed in the changelog.

There are two important fixes that haven’t been mentioned on the blog before. Firstly, the problem detailed on the 11th in which overlapping gadgets were drawn incorrectly is now fixed.

The second bug arose from a similar situation. If a gadget is disabled and overlaps another gadget, any attempts to click the uppermost, disabled gadget fell through to the lower gadget. This is clearly incorrect behaviour and has been rectified. Disabled gadgets previously neglected to capture clicks; they now capture the clicks but do not react to them.

If you have implemented your own classes, or subclassed existing classes and overridden the “click()” method, you will probably need to change your code. The previous click() template looked like this:

bool MyGadget::click(s16 x, s16 y) {
if (Gadget::click(x, y)) {
    redraw();
    return true;
}

return false;
}

It should now look like this:

bool MyGadget::click(s16 x, s16 y) {
    if (Gadget::click(x, y)) {

        if (isEnabled()) {
            redraw();
        }

        return true;
    }

    return false;
}

Note the extra “isEnabled()’ check.

Known Issues

Just a small one. The RadioButtonGroup does not re-raise any events raised by its child RadioButtons. This means that it is impossible to listen for click/release/drag/etc events from a RadioButtonGroup. This is a minor problem, however, as these events are not particularly useful for this gadget. The useful event is “value changed”, which is raised.

Forthcoming Changes - The Fate of PALib Support

I mentioned back in January that I was no longer checking PALib compatibility. I think it is about time that I removed PALib support from Woopsi. It doesn’t make any sense to leave it in, as I’m not using it for anything, but it does clutter up the code and require an extra makefile. The next release of Woopsi will be PALib-free.

2009-01-11

DevKitPro v24 Compatibility

Those of you keeping up with devKitPro releases will probably have noticed that Woopsi is not compatible with version 24 - devKitARM now includes a built-in “DynamicArray” type which was causing all sorts of problems. I’ve fixed that, plus I’ve reworked the hardware setup code to work with the new register names, touchscreen functions, etc.

A couple of notes on upgrading to handle devKitPro v24. If you call irqInit() and irqEnable() to switch on VBL interrupts, you’ll stop the touchscreen from working. That took ages to find and fix.

Lastly, a word on PALib. PALib has massive problems at the moment. Aside from the fact that the original author, Mollusc, now appears to have a real development job and has stopped maintaining it, the library hasn’t worked correctly with any of the recent devKitPro updates. In fact, you could argue (as most of the GBADev guys do) that PALib has never really worked correctly; I fixed plenty of bugs in it myself trying to get it working. Anyway, Woopsi currently works with dkp24 (when built with the libnds makefile) and also with dkp23 (when built with PALib and the appropriate makefile). However, I can’t maintain the two environments on my laptop at the same time (not enough disk space for two 10GB virtual machines until I can afford to get a new hard disk - not so easy now that I’m a student again and spent Christmas in Italy). This means I’m not checking compatibility with PALib any more, but as the hardware-hitting code shouldn’t change, I don’t foresee any problems. Unless the PALib maintainers do something crazy.

Anyhoo, latest change are in SVN. Expect a real release in the next few days. The only change that could affect user code is the name change from “DynamicArray” to “WoopsiArray”.

2007-10-19

XCode PALib Template

Following on from the previous post about getting PALib and devKitARM set up in OSX, here’s some instructions for creating a PALib template project:

  • Download the PALib XCode Template
  • Unzip the archive
  • Drag the resultant folder to “/Library/Application Support/Apple/Developer Tools/Project Templates”

All done! To create a project using the template:

  • Fire up XCode
  • Choose “File/New Project” from the top menu
  • Select “PAlib” from the template list
  • Click “Next”
  • Choose a project name and a location for the project
  • Click “Finish”

You’ve now created a basic PALib project that will compile (ROMs are put in the “release” folder) and run in an emulator.

2007-10-17

Woopsi Version 2 Ideas #3, PALib Licencing, and Woopsi Docs

More Woopsi ideas that might make it into version 2. First of all, I pre-ordered a GP2X F200 as soon as I received an email announcing it. I’m hoping that the d-pad isn’t as spectacularly unusable as the mini joystick employed on the original GP2X and the three revisions of GP32, and I’m also hoping that it won’t suffer from the quality control problems that plagued the first edition of the F100 (though mine doesn’t seem to have any of the reported issues).

Anyway, rubbish d-pad or not, I’m planning on investigating the possibility of porting Woopsi to the new GP2X. Unless GPH manage to screw up the touchscreen as badly as they screwed up the joysticks, that is - if that happens I’ll just write it off as a bad idea.

Another idea - as I’m going to have to alter all of the hardware-specific sections of Woopsi for the GP2X anyway, I might look at stripping the PALib code out at the same time. I foresee there being two major barriers to widespread adoption of Woopsi - firstly, it uses C++, whereas most DS developers probably use C, and secondly, it uses PALib, which abstracts away the complexities of the hardware and is therefore frowned upon by the more purist homebrewers. C++ has to stay, as only a crazy person (or Linus Torvalds, apparently, who it seems will approach every problem with the same rusty screwdriver he’s been using for the past 20 or so years, because he’s seen a few people make a mess when using other tools such as step ladders or those new-fangled electric screwdrivers) would try to write a GUI with C when there are more suitable alternatives around. PALib isn’t a necessary requirement, however, and it would be annoyingly tedious but possible to strip it out of Woopsi and replace it with libnds calls instead.

On a side note, I’m slightly disturbed to discover that no-one seems to know what licence PALib has been released under. SourceForge lists its licence as “None Listed” (helpful), whilst no-one on the PALib forum has responded to a question I posted about it. The PALib installer doesn’t contain a licence or any mention of one. It doesn’t even have a copyright notice anywhere. To me, this suggests that it’s considered public domain. Either that, or choosing a licence didn’t occur to the developers. If it’s the former, then I could strip out the PALib dependency simply by merging the functions I use into the Woopsi sourcecode. If it’s the latter, then I’m dubious about using PALib when I have no idea what terms I’m implicitly agreeing to follow every time I hit the compile button.

Some other things that I think may be potential barriers to Woopsi adoption are:

  • It looks like an operating system from the early 90s
  • It hasn’t been designed specifically for the DS’ ergonomics (contrast with the beautiful iPod Touch/iPhone interface)
  • Homebrewers generally don’t want to use other peoples’ code - they want to create and discover things for themselves

I disregard all of these minor barriers because they are intentional in the design of Woopsi - I want to create an interface that looks like Workbench 3.0.

Here’s an idea that I want to integrate into version 1 - bitmap buttons. These are just like standard buttons, except they display a bitmap instead of text. When held down, they show a different bitmap. Should be easy to implement.

The addition of bitmap buttons will let me take Woopsi in unusual directions. For example, we can create a window the size of a screen, make it borderless, and add a superbitmap to it. We can then add a set of borderless bitmap buttons, and we’ve created an interface more akin to MenuDS than a windowing system.

Lastly, I’ve added a load of documentation to the Woopsi SourceForge project, which you can find here:

woopsi.sourceforge.net

2007-04-11

Defender - Diary of a Game

(Written 27/03/2007)

This game really starts with Pong. For me it does, anyway. Pretty much the first thing I code for a new platform is always Pong. It’s a simple enough game to be able to put together in no time at all, it provides the opportunity to work with input and output, and, unlike “Hello World”, you get something useful at the end. So, my first DS project was Pong. I’ve written this loads of times before. So far, I’ve written Pong in AMOS, Blitz Basic, RM Basic, QBasic, Spectrum Basic, Modula-2, Flash, bas2c for the Cybiko, C for the Cybiko, C for OSX (SDL), C for the GP32, C for the GBA and Java. Those are the ones I remember, anyway. Here’s a quick list of the things I discovered whilst writing it:

  • Initialising a screen for text output screws up any other kind of output on that screen (took me a while to figure out that one);
  • The latest version of PALib has a bug in its sound code, so C++ projects won’t compile unless the offending functions are modified and cast to (u32*);
  • PALib is much easier to work with than libnds;
  • I like working with objects.

I even got to bung in the OctaMED module I wrote 12 years ago for the Blitz Basic version.

PongDS

I took away two main things from writing PongDS. Firstly, I’m going to use PALib. Libnds is great, but PALib offers so much more. If I knew more C code I’d probably be willing to give libnds more of a chance, but I really just want to get a few games running. The real low-level stuff can come later.

Secondly, I’m going to use C++. This is tricky because I haven’t got an awful lot of C/C++ experience, and I’ve never really finished any object-orientated games. My Java games don’t have any presentation (intro sequences, options screens, etc), and I switched from Flash to Java just before ActionScript 2 appeared. Before then, real object-orientation in Flash for games was impossible because it was just too damned slow. Any games I make will therefore have to be structured in a way I’ve never really attempted before in a language I’m not too familiar with. I could code in straight C, which would halve the amount of new things to learn, but I’ve been working on object-orientated business apps for so long now that the thought of going back to a procedural language when there’s a perfectly good OO language around really doesn’t appeal.

Choosing a project to work on was more difficult than I expected. I’ve got a few ideas for things I’d like to do with the XNA framework, but until Parallels supports 3D acceleration that’s out of the question - I’ve just switched over to a MacBook and refuse to go back to a Windows box. Parallels is fine, but no dual booting and definitely no Windows-specific hardware, other than the Thinkpad I lug around for work and my file server. No interesting game ideas leapt out at me for the DS until I hit upon the idea of Defender. I love Defender. Specifically, I love Mark Sibly’s version of Defender for the Amiga, which must be one of the first games I ever had the sourcecode to and tried to tinker with. It seems such a perfect fit to the DS and looking around on the net, it seems that the DS is starved of a decent Defender clone. The official version is crap, and the only homebrew version is a half-finished port of Defendguin. No thanks. Some initial thoughts about the port:

Controls

  • Up: Up
  • Down: Down
  • Left: Left
  • Right: Right
  • B: Fire
  • A: Autofire
  • L: Smartbomb
  • R: Hyperspace
  • Start: Pause
  • Select: Reset (whilst paused)

That breaks with the arcade tradition, but then I hate the arcade controls. The controls above are chosen based on the assumption that, had the original coder had access to a joystick, he’d have used that instead of the dozen buttons on the arcade machine.

Game

I’m going to copy Mark Sibly’s version shamelessly. I’m going to steal his sound effects. They’re stolen from the arcade anyway, so he can’t complain. I’m also going to pinch his graphics and pilfer his sourcecode. Essentially, I’m going to port it to the DS from Amiga Blitz, with a few DS-specific enhancements.

Screen Layout

The main action will be on the top screen. I’ll have a score, hi-score and life counter at the top of the screen, and the main playfield below. The second screen will show the map, which will fill about 2/3-¾ of the screen, and a “Defender” logo below it. I might pinch the marquee from the arcade for that.

Options

A few options to make things easier for those of us who are hopeless at Defender:

  • Number of lives (3-5)
  • SFX test?
  • Number of smartbombs (3-5)
  • Number of continues?

Music

I haven’t written any four-track MOD files in years, and I was never particularly good at it when I did write them. I might fire up the Amiga and give it a go, though. Music will be limited to the title/options screens if there is any.

High Scores

It occurred to me that web-based high-scores would be great. It then occurred to me that if this game is open-source (it’ll be released under the GPL when it’s done, same as everything else I do), the authentication method will be visible to everyone. There will be no security on the high-scores, so people can cheat without making any effort. Scratch that idea, then. High-scores will have to be saved to the local non-volatile RAM (or whatever the DS uses as long-term storage).

Game Structure

  • Start off with a logo sequence
  • Next to options screens
  • Then game

Corporate logos make homebrew look much more professional. Hate the damn things in commercial games because you can’t skip them, so skipping them has to be possible in this game.

Today I’ve been working on the logo sequence. I’ve got an old friend with considerably more artistic talent than me working on a new logo for Simian Zombie, and he seems to have loads of good ideas. They match my own - if only I didn’t have stupid fingers I like to think I’d have come up with something similar.

To this end, I’ve written a handy slideshow class, that consists of three parts. First of all, I’ve got a bitmap class that takes 8-bit or 16-bit image data converted by PAGfx and stores it in an easy-to-use fashion - loading a bitmap into a screen is now just a question of calling “bitmap.draw()‘. It abstracts away the 8-bit/16-bit difference, too - one class does both completely transparently. Secondly, I’ve got a SlideshowImage class, which stores a bitmap and the length of time it should be displayed. Finally, I’ve got the slideshow class itself, which stores a sequence of images and cycles through them one by one until the user presses something or it hits the end of the sequence. It’ll then exit or loop, depending on how it’s been set up.

In half a dozen lines of code, I can now have two totally different slideshows running on the DS’ screens, showing a mix of 8-bit and 16-bit images. I knew there was a reason to go for C++ over C. One observation - in C++, when trying to load an 8-bit palette into a screen, you have to cast it as (void*) or you’ll get an error. Looks like another bug in PALib.