2007-12-16

Woopsi PacMan

The Pong demo in Woopsi is a bit crap. It served its purpose, but it doesn’t really do anything. I wanted a more interesting demo, but didn’t want to invest a lot of time in writing a new game, so decided that it would be simple to port my PacMan-for-Javascript to C++ and Woopsi.

Here’s the result:

WoopsiPacMan

Pong and PacMan on the same screen, running simultaneously, with no slowdown. It’s pretty much the same code as in the Javascript version, but with C++ features (accessors, etc) added in, and some minor optimisation in the drawing routines. Cursor keys move PacMan around. Putting this together illustrated a few things:

  • It seems that it’s actually faster to use a SuperBitmap as a game’s display than it is to use a gadget and its GraphicsPort. Probably due to the large overhead associated with clipping.
  • There still appears to be a bug in the SuperBitmap::drawFilledRect() routine (possibly related to clipping to the bitmap’s size).
  • Drawing with the GraphicsPort outside of the gadget’s draw(Rect) function is a really bad idea unless you’re redrawing everything in a VBL event, because Woopsi doesn’t fire any events to tell you when a window needs redrawing (due to the way I’ve optimised gadget erasing, there’s no easy way to add this in, either).

There are a few bugs in the demo (PacMan doesn’t get drawn when the window first opens, ghosts can collide with PacMan diagonally, and it’s far too fast), but it suffices for a quick tech demo.

A few fixes. Windows are blocked from being dragged out of the top of the screen - I realised that if a screen is partially dragged down, it was possible to then drag a window out the top. It was then impossible to drag it back down again.

The ScreenTitle and WindowBorderTop make copies of the text passed into them to prevent them from referencing deleted strings - Jeff noticed this one a while ago. The BitmapButton offsets its bitmap blitting co-ordinates by 1 to take into account the border size (if the gadget has a border). The SuperBitmap’s draw(Rect) routine was basically a copy of GraphicsPort::drawBitmap(), so I’ve deleted the code from SuperBitmap and used a call to the GraphicsPort instead. Lastly, the demo skin’s buttons are slightly larger, and are now clickable on a real DS.

Some more new features. I’ve added a filled circle routine to the SuperBitmap and GraphicsPort classes, and the Pong demo now has a round ball. The new woopsiRGB() function performs the same function as PA_RGB (ie. it automatically sets the alpha bit in the value it returns). There are a few other minor changes involving optimisations, etc.

Comments

Jeff on 2007-12-16 at 22:02 said:

Re: woopsiRGB()

Replacing an inline macro, which the compiler can turn into a very efficient constant load, with a subroutine call is going to cause a performance hit, AND generate larger code.

ant on 2007-12-16 at 22:38 said:

Good point, I’ll macro-ify it.