2009-11-03

More Bitmap Loading

Following Chase-san’s request, Woopsi’s BitmapIO class can now load 16-bit BMP files (in 555 or 565 pixel encoding, or indeed any other pixel encoding you can throw at it). It can also cope with V4 and V5 DIB headers in addition to V3.

I finally found a free graphics program for Windows that could save 16-bit images in the form of Pixelformer. I’ve used it for all of about 20 seconds but it looks like it might be a pretty decent pixel editor. It uses the V4 header format, unfortunately, hence the added support for V4 and V5 headers.

I haven’t had chance to do much testing yet, so there are probably bugs.

2009-10-22

Woopsi, Bitmaps and Python 3

Back when I was programming mediocre games in AMOS, one of my friends decided he wanted to code too. I introduced him to the basics and he quickly advanced way beyond me. Whilst I was struggling to get simple things working in BASIC he was writing demo effects - fire, spinning 3D environments, toruses - in Pascal and C. One of the most impressive programs that he wrote, at least to me, was a BMP loader. I had no idea how to go about writing anything like that. I put it down to two things:

  • BASIC, and the way it hides all implementation details from the coder to the point that he finds himself doing nothing but bolting together existing library functions (ie. “loadBMP()”, “saveBMP()”, “makeAnAmazingGame()”);
  • The total lack of any useful books on coding where I grew up.

You could point out that if he could learn with no books, I could too, and he’s probably just smarter than me. That’s probably true.

Anyhoo, having just spent a month manually serialising objects for network transmission in C++ (exciting new project to be released soon), I decided it was time to write my own BMP loader for Woopsi.

Instead of leaping straight into the C++ code, I figured I’d make a prototype in Python first:

BitmapLoader

This is a Python 3 class that can load BMP files in either 1, 4, 8 or 24-bit colour depth. 16-bit support would be possible fairly simply, but I didn’t have a BMP in the right depth whilst writing this. It can only load uncompressed bitmaps. Finally, it supports all versions of the BMP DIB header, but it treats V4 and V5 as V3 and discards the extra data.

Once that was written, getting a C++ version created was simple. Woopsi now has two new classes in the “bonus” folder:

  • BinaryFile, which can read and write binary files (works with both the SDL and DS libfat versions, as libfat is POSIX compliant for files);
  • BitmapIO, which can load and save BMP files.

The Woopsi version is rather more limited than the Python version. It will only load and save 24-bit bitmaps. It can only deal with version 3 of the DIB header (the most popular BMP format, as far as I can tell). It will only load uncompressed bitmaps.

Usage is like so:

// Loading
Bitmap* bitmap = BitmapIO::loadBMP("/mypicture.bmp");

// Saving
BitmapIO::saveBMP("/myotherpicture.bmp");

Writing the BMP code highlighted a number of bugs in other parts of Woopsi, all of which are now fixed. The Bitmap::getPixel() method didn’t work for bitmaps larger than 65535 pixels. The Bitmap::drawBitmap() method wasn’t calling DC_FlushRange() before trying to DMA copy the source bitmap, leading to rows of black pixels. The SuperBitmap class has an overload for drawBitmap() that accepts a Bitmap object.

Lastly, there’s a new example program demonstrating the BitmapIO functionality.