2014-01-03

Relocation and SDL2

Things have been a little quiet here recently. I am pushing ever westward; this time I moved from sunny Littleton, Colorado, to the equally-sunny Mountain View, California. I’m close enough to Google’s headquarters to be able to see their city-wide free wifi on my laptop, but far enough away that I can’t use it.

Relocation is something of a theme. The little coding time I’ve had has mainly been spent moving repositories from Mercurial/BitBucket to Git/GitHub so that I can hang out with the cool kids. Actually, I’ve been using Git exclusively for about five months and find that, when I do need to use Mercurial, I can’t remember how it works. Within the repositories, I’ve done some relocating too: consolidating DS and SDL code.

SDL2 was released not too long ago and I thought I’d have a play and see if it offered anything new. It seems the most important change for my SDL projects was the inclusion of automatic texture format conversion within the library itself, meaning it has built-in support for converting and displaying bitmaps in ARGB1555 format. This means that all of my DS projects no longer need to keep track of two bitmaps - one in ARGB8888 and one in ARGB1555 format - when in SDL mode.

Upgrading to SDL2 has allowed me to merge the SDL and DS codebases together, meaning I now have a single repository that will build for the DS and OSX out of the box. Getting them to build in Windows and Linux should be trivial. Additionally, the makefiles for the DS versions all work with the latest devkitARM. Something must have changed in the build system as all of the makefiles were broken.

In other news, I’ve been tinkering with Woopsi again. The complex, C#-inspired EventArgs system is out and I replaced it with the set of arguments that are relevant to each event. Gadgets no longer support multiple event handlers; each can now have just a single handler. Much tidier.

2011-07-04

Really Bad Eggs Progress

The final version of Really Bad Eggs is almost ready. All of the coding is done. I’m just waiting for a title screen graphic from Noj, creator of the Simian Zombie monkey, before I release it.

As you’d expect from a jump from an alpha version to a full release, there are many substantial changes. First off, I’ve ditched the Tetris-style mechanics in the single-player game. Like I said in the last blog post, the single-player version of Puyo Puyo is dull no matter what you do. The real excitement comes from suddenly being given a dozen garbage eggs to deal with, which doesn’t happen when playing solo. “Game A” is now “Practice”, and “Game B” no longer exists.

The AI is almost entirely new - I rewrote it pretty much from scratch. It is considerably better at playing with 5 and 6 block colours than the previous version, and on a similar level when playing with 4 blocks. To test the performance of the new AI I had it play against the old AI as a benchmark. I watched each match and tweaked the code to deal with errors that it was making. As 4-colour matches took around 20 minutes each, this was a laborious task…

As an interesting aside, the new AI can rotate shapes in all 4 orientations, but enabling this ability led to it getting resoundingly beaten by the old AI in almost every match. I’ve got a few of theories as to why. It could be that playing horizontally reduces the opportunity for the AI to create vertical towers and hasten its own death. It could be that placing blocks horizontally leads to greater opportunities for accidentally creating sequences of chains. Lastly, it could be that, given the opportunity to place blocks vertically, the AI is more likely to block off a potential chain when adding to it by placing the chain block’s partner above it. The new AI will only use horizontal rotations.

The final version of the game includes a practice mode (single player renamed), easy, medium and hard AI modes, and a two-player mode. I initially dismissed the two-player mode as impossible, given the dismal state of wifi on the DS and the awkwardness of using a single DS between two people. However, the shared DS option was so trivial to implement that I added it in. I’ve included a suggestion in the readme that players switch sides between rounds of a two-player game to ensure that the player on the right isn’t at a complete disadvantage.

All of the block colours, bitmaps, sound effects and music are now in place. Various bugs have been squashed. It will compile and run in MacOSX thank to the usual SDL abstractions that I build into my DS code. Unfortunately, the SDL_mixer library does not support playing samples at user-defined frequencies, so the chain explosion glissando doesn’t increase in pitch each time a new chain sequence is created.

If you’re a regular reader (though I don’t think I have any regular readers), you might have noticed that I haven’t blogged much about this game. Other than the initial announcement/release, there’s been nothing. There is a reason for that: Really Bad Eggs was fairly trivial to write. Other than a mildly interesting graph traversal algorithm to identify chained eggs, the game is a simple grid-based Tetris clone. There really wasn’t much to blog about. Like EarthShakerDS, though, it was enormous fun to write.

One thing that is worth blogging about is the template I’ve put together for WoopsiGfx projects:

WoopsiGfx Template

This extends libwoopsigfx with:

  • Abstractions for the DS’ buttons that will compile with SDL and map to keys;
  • Abstractions for the DS’ touchscreen that will compile with SDL and map to the mouse;
  • Double-buffered framebuffer class that can be used as a wrapper around an SDL surface;
  • Hardware class that initialises the DS into a state ready for libwoopsigfx;
  • Makefile that builds and includes Maxmod-compatible files in the /sfx folder;
  • Pre-built folder structure.

You can take the template and get a libwoopsigfx-based game running in no time. Even better, the same code should compile on just about any platform with an SDL port so that you can test your code in a real debugger. Coding without a debugger or any kind of profiler makes you proficient at debugging by the seat of your pants, but sometimes it’s nice just to run Xcode’s memory leak identifier and have it spot problems for you. EarthShakerDS used an embryonic version of this template, whilst Really Bad Eggs uses the latest version.

2010-01-24

Woopsi 0.44 Released

Time for another release:

http://www.sourceforge.net/projects/woopsi

There’s nothing in this release that I haven’t blogged about already, but here’s a quick summary:

  • Unicode (UTF-8) support throughout entire Woopsi system;
  • FileRequester upgraded from bonus folder to main library;
  • Key repeat events;
  • Text in TextBox follows cursor;
  • Dozens of fixes and improvements.

In addition to this, I’ve deleted the old screenshots from the SourceForge page and uploaded a couple of new ones. Hopefully any sites that report the news of the release will use those instead of the shots from version 0.21.

EDIT: Additionally, I’ve released the Xcode/SDL version of 0.44, for anyone out there developing on a Mac and needing a debugger.

2009-11-15

SDL and Woopsi2x Mark 2

Continuing the bitmap changes released in Woopsi 0.40, I’ve altered the bitmap and graphics classes so that all interaction with a bitmap’s data must occur through the bitmap class’ accessor methods. This has enabled me to change the FrameBuffer class so that it includes the SDL code that was previously floating around in the woopsifuncs files.

Instead of Woopsi mimicking the DS’ framebuffer with an intermediate array of u16s, the FrameBuffer class accesses the SDL surface directly. The FrameBuffer class still includes a u16 array, but that is used as a way of avoiding lengthy 24-bit to 16-bit conversions every time a pixel is read or written. Woopsi therefore maintains a 24-bit SDL surface and a 16-bit array and keeps them in sync by making changes to both whenever one is altered. This has resulted in a massive speed increase. Whereas the entire framebuffer simulator array was previously written to the SDL surface every VBL, only changed pixels are now written.

As a test of the new system I’ve compiled it in Xcode (no noticable change) and Code::Blocks for Windows. In the latter Woopsi is now far too fast to be usable; I probably need to put a call to SDL_Delay in there somewhere.

I’ve also compiled it for the GP2x F-200. I ported it a while ago but gave up because the GP2x’s touch screen is utterly atrocious. At the time Woopsi was too slow to be usable due to the extra copying the SDL version was performing. Now it runs at the same speed as the DS version.

woopsi2x

Here’s a pre-compiled binary and the sourcecode for Woopsi2x. Note that this is simply a test; I have no intention of maintaining a GP2x port because of the hopeless touchscreen. I’m hoping to make a Pandora port when the hardware is released.

Try it for yourself to find out just how bad the GP2x touch screen is!

2009-02-05

Woopsi Progress and News

After some delay, here is the latest Woopsi news.

First of all, there’s a new program out that uses Woopsi called ‘fileNinja”:

http://sourceforge.net/projects/fileninja/

fileNinja was released late last year, but it’s taken me this long to blog about it. Part of the reason for that is my inability to test it - the DS’ crappy wireless isn’t compatible with my Airport Extreme so I can’t use fileNinja. Shame, because it’s something I’ve wanted for a while - a DS FTP client.

In other news, EigenmathDS has had a new release:

http://sourceforge.net/projects/eigenmatds/

It now has graphs and matrices, amongst other updates. There’s a blog here:

http://eigenmatds.sourceforge.net/

Lastly, Richard “Quirky” Quirk, author of several of my favourite GBA homebrew games (including the excellent Cyclone, which I should really copy to the DS) has decided to use Woopsi as the GUI for a new version of Bunjalloo, which appears to be the last remaining homebrew DS web browser. His blog can be found here:

http://quirkygba.blogspot.com/

Regarding Woopsi progress, Quirky has submitted about a dozen bugfixes for memory leaks, crashes, etc. Check the changelog for a full list. They include a number of SDL fixes, including fixing the file requester for SDL operation. I’ve added a few bugfixes myself, and a couple of new features as requested by leonelhs in the forum. It is now possible to retrieve children from gadgets by their index number (Gadget::getChild()) and it is possible to determine how many children a gadget has (Gadget::getChildCount()). There’s a context menu example in the “examples” folder, too.

2008-06-17

Woopsi Status Report

Woopsi progress is suffering at the moment due to my other commitments, but I’ll get back to it soon. I’m patching up bugs as they get reported in the forums, though, or if I spot any when I’m fixing other problems.

Two fixes today. First of all, the Screen class was still bitshifting left by 8 places instead of multiplying by SCREEN_WIDTH in its drag() routine. Although the bitshift is potentially faster, it’s a barrier to portability and I’m guessing that the compiler is smart enough to replace the multiply with a shift anyway.

Secondly, I noticed that the XOR dragging rect displayed when dragging a window could be dragged out of the parent screen if the screen had itself been dragged down. This is now fixed.

Both of these fixes came out of my search for an SDL bug identified by John in the forum (he’s managed to get SDL working with VC++, and documented the process).

Here’s something for discussion. Jeff notes that gadgets should raise “MOVED_FORWARD” and “MOVED_BACK” events when their z-order is changed. However, the z-order is controlled by the parent gadget. The only way to raise these events would be if the parent gadget called “child->raiseMoveForwardEvent()” or something similar when the order changed. This goes against the conventions in the rest of the system. Only the gadget should be able to raise events from itself.

The way around this is to expose the child gadget vector (or introduce methods for working with it, such as “getChildCount()”, “swapChildOrder(source, dest)”, etc) and allow gadgets to re-order their parents’ children. This means that each gadget can control how it re-orders itself instead of parents assuming that their children should all be re-ordered in the same way, and allows the usual way of raising events. It introduces other complexities, though. Thoughts?

2008-04-26

ListBox Rethink

Got the ListBox to scroll by just making it inherit from the ScrollingPanel and adjusting the canvas height every time a new list item is added. Easy! Except there’s a problem.

The ScrollingPanel only uses the DMA hardware to scroll portions of itself that aren’t overlapped by child gadgets. Child gadgets are responsible for redrawing themselves when the panel tells them to move. Scrolling children is just an illusion created by calling child->moveTo(newX, newY) whenever the canvas co-ordinates change. The problem is that redrawing all of the children every frame is a slow process. Works great on the Mac, but not so good on the DS.

I’m going to have to change the ListBox so that it doesn’t use child gadgets. Instead, I’ll need to draw each option manually (allowing the ScrollingPanel to use the DMA hardware when scrolling), work out where clicks are, etc. Tedious, but fortunately the clipping is all done for me.

Couple of other small changes. The SDL/Xcode project has a new icon:

Woopsi OSX Icon

Lastly, Gadget::redrawDirty(), which is called when a gadget higher in the z-order is erased, wasn’t clipping to parent gadgets. I hate having to monkey about in the clipping system, but that’s now fixed.

2008-04-26

Arghitecture, More Modal Gadgets and SDL Updates

Following some fast-paced discussion regarding the last set of changes, I’ve made some more alterations.

The Woopsi class now uses the new modal system to run its own loop. This is only of interest if you’re following the old design pattern of writing your own main loop. You should replace a call to woopsiApplication->run() or woopsiApplication->play() with a call to woopsiApplication->goModal().

I realised that having a custom loop within the Woopsi class is a bit daft when that class already has built-in functionality to run a loop courtesy of the Gadget class. This change has let me take out the custom loop code.

Gadgets are now only modal whilst the Woopsi instance is itself modal. The upshot of this is that calling woopsiApplication->stopModal(), in order to quit Woopsi, will now force any other modal gadgets to cede control back to the main loop so that it can exit.

I’ve added a few bugfixes. All attempts to dereference woopsiApplication are now guarded within NULL checks, which should prevent any NULL pointer-related crashes.

The SDL code has seen some improvements, too. I’ve merged the SDL quit code into the Woopsi::shutdown() method. This method should be called last in any overrides, unless you don’t want to quit SDL, in which case it’s your own responsibility to shut down SDL.

Quitting an SDL Woopsi application now stops Woopsi being modal, which means (aha!) all gadgets stop being modal and the application exits correctly.

The SDL event pump is now part of Woopsi::processOneVBL(), which means that as long as VBLs are getting processed, Woopsi will listen for quit events.

Lastly, I’ve merged the DS and SDL versions of the woopsifuncs files. This means that the SDL and DS “woopsi” folders are now identical. In fact, the only difference between a DS Woopsi project and an SDL Woopsi project is the need to include the supplied “sdl/nds.h” file in the SDL project. This includes a “USING_SDL” define again, since switching to a check for “_SDLH” didn’t work for me.

2008-04-08

Bugfixes and Refactoring; Xcode Goes Bananas

Loads of updates today. First of all, almost all of the classes are now javadoc commented. I’ve just got the skinned classes left to do, but as I might revist those I’m not documenting them for now. I need to document each class’ members, too. The autodocs generated by doxygen now look quite good, although there’s a lot of scope for more detail.

Next up, bugfixes. John spotted an overflow problem in the Font and MonoFont scanGlyph() function which was preventing font bitmaps with dimensions >=256 pixels from working properly. The MultiLineTextBox restores its visible/invisible property properly after being resized. The ContextMenu crash I found earlier seems to have been a bug in the PacMan demo rather than the ContextMenu itself, which I’ve also fixed.

On to the big changes now. There are two big API changes in the latest SVN code. I’ve refactored the active/inactive/focused/blurred system. The “active” flag has been replaced by a “hasFocus” flag, “setActiveGadget()” has become “setFocusedGadget()”, “_activeGadget” has become “_focusedGadget”, and the “setActive()” method has been absorbed into the “focus()” and “blur()” methods. There isn’t a huge number of differences, but it has made the whole thing much easier to follow.

The next big change is the visible/invisible system. This has bugged me for a while. If I call “gadget->setVisible(false)”, the gadget stays on the screen. I have to call “gadget->erase()” to make the gadget go away, but that doesn’t make “gadget->isVisible()” return false. What is going on?

The problem is that the “visible” flag and access methods don’t refer to gadget visibility; they refer to whether the gadget’s drawing methods are enabled or not. What I’ve done is give this block of functionality more sensible names. The “visible” flag has been replaced with a “drawingEnabled” flag. The “setVisible()” and “isVisible()” methods have been removed, and “enableDrawing()”, “disableDrawing()” and “isDrawingEnabled()” methods have taken their place. As an added bonus, “isDrawingEnabled()” only returns true if the gadget is neither deleted nor hidden, which makes working with it a little easier.

It’s now possible to determine if a gadget is hidden or not by calling its “isHidden()” method. The hidden status is stored in a new flag. There’s another new flag, too - I’ve moved the “visibleRegionCacheInvalid” bool into the flags struct.

Another thing that’s been bugging me is the spelling of “closable”. All occurrences of “closeable” in the flags, flag enum and getter methods are now spelt correctly.

Lastly, I’ve split the PacMan demo up into separate files for each class. Much easier to read now.

All of this has the potential to cause mayhem for people who are upgrading…

In other news, I decided to try and fix the ContextMenu crash bug last night by using the SDL version of Woopsi in Xcode. Synced the two versions in SVN, pulled down the latest copy in OSX, loaded up Xcode. Or tried to. Xcode crashed before it had finished loading. It refused to start up.

Had a look around on the internets, which recommended that I try repairing permissions in the Disk Utility. That didn’t work. The other suggestion was that it could be a corrupt setting in my user’s library folder. Tested this by moving everything out of the library to another folder. No luck. Started copying everything back, but due to the incompetence of the user stupidity of Finder I found that I’d copied some of the folders into other sub folders, and didn’t have any way of getting them back. Nuts.

Unfortunately, my Time Machine backup was a week out of date due to the incompetence of the user way Airport Extreme disks have to be mounted manually before Time Machine can back up to them. After a hell of a lot of fighting with Time Machine I got it to restore most of my settings. The bookmarks I’ve lost can’t have been all that important as I can’t remember what they were.

Xcode still didn’t work.

However, I tried to load it up this morning and it worked fine. Madness.

2008-01-23

Woopsi2x

Thought I’d have a play with the GP2x development kit. 10 minutes later:

Woopsi2x

This is Woopsi, compiled using the GP2x dev kit, running in Windows using SDL. Doesn’t quite work yet as there appear to be a few incorrect constants. I need to get hold of an F-200 build of SDL as the version that comes with the dev kit I’m using doesn’t seem to include the mouse handling code.

As a proof-of-concept, though, it does the job. The GP2x loses the second screen, but the screen is 320x240 instead of the DS’ 256x192 so it really only loses half of a DS screen. Having everything on one screen is a bit of a bonus, too.

EDIT:

After some more minor tinkering with the SDL code:

Woopsi2×2

Now that the screens are the right size and aren’t overlapping, the mouse code works in the Windows compile. I need to test the GP2x compile, but I’d need to trim the top screen off first.

I’m not sure what’s happened to the button glyphs…

This highlights a problem in the code - it makes assumptions about the size of the screens. Not particularly helpful if you want to make portable code.

In addition to this, I’ve updated the main VC++ project to match the Xcode version. All of the (very buggy, as per the last post) scroller code is in there.

EDIT EDIT:

Heh, simple. It’s very slow, but when you realise that the entire display is being drawn pixel by pixel to a RAM buffer, then copied pixel by pixel to the frame buffer (plus the non-existent top screen is still being rendered in RAM), you can see that there’s plenty of room for optimisation.

Oh, and the mouse code doesn’t work. Not sure if I need updated SDL libs or if I need to change the way that Woopsi interacts with the stylus on this machine.

And the glyphs are back. They’re missing from the PC version because of the unsigned/signed char problem. I should fix that.

Woopsi2×3