Archive

Archive for the ‘MenuDS’ Category

Finally Created a C++ Library

October 22nd, 2007 Ant No comments

Not wanting to admit defeat after failing to get Woopsi forced into a proper library distribution, I decided to try with a simpler codebase and get MenuDS built as a library. A considerable amount of time later, and I’ve succeeded!

Once I’d figured out that I was better off using a makefile from a PALib example as my starting point, instead of the MenuDS makefile (taken from the VC++ template, which breaks hopelessly every time I try to modify it), I actually got the code to compile using a “make” command. Trying to convince the MenuDS demo to work with the library was even more time consuming, mainly because the error that I thought meant “cannot find includes” actually meant “you forgot to include the .o files in the archive, you eejit”.

I might tidy the code up, document it all, and then SourceForge it.

Categories: MenuDS Tags:

Bitmap Buttons!

October 21st, 2007 Ant No comments

Added another new feature - bitmap buttons. Bitmap buttons work like image buttons in DHTML. You specify an “up” image and a “down” image for the button (or a “normal” and a “clicked” image, in Woopsi parlance), and those images are displayed on the button instead of text.

This addition now means that Woopsi pretty much renders MenuDS obsolete, as it’s possible to use a combination of borderless screens, borderless windows, SuperBitmaps and BitmapButtons to replicate all of MenuDS’ functionality.

Here’s a screenshot:

Woopsi Bitmap Buttons

Haven’t got the correct computer switched on for SourceForge SFTP access, so I’ll upload a new demo there later. In the meantime, it can be downloaded from here:

Woopsi Demo 0.22

Categories: MenuDS, Woopsi 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.

More MenuDS Appearances

April 15th, 2007 Ant No comments

MenuDS got linked to by DCEmu, another site I’ve heard of. Huzzah, again!

Categories: MenuDS Tags:

No Work Today

April 13th, 2007 Ant No comments

No DS coding today. Not even any thinking about DS coding. Just a quick post to note that the MenuDS demo got linked on DS-Scene, which is a site I have actually heard of and visit fairly regularly.

It garnered two comments. The first decried MenuDS as being “useless and boring”; well, duh, it’s a demo of a menu system. Please pay attention at the back. The second pointed out that it’s a developer tool. At least someone gets it…

Anyway, now that the peripheral stuff’s taken care of, I can move onto the game. Whilst I’m thinking about this, I’ll just jot down some structure ideas:

  • Need a base sprite class that’ll handle drawing the sprites to the screen, collisions, positioning, etc;
  • Either need a base enemy class that inherits from the sprite class (and enemies inherit from that), or a single enemy class with a “type” member (not a clean solution), or (even better) a single enemy interface, and a set of enemy classes that inherit from the sprite class and implement the enemy interface (though I’ll need to check that C++ supports the concept of interfaces);
  • Need a player’s ship class that inherits from the sprite class;
  • Probably need a player class, that contains things like score, lives, etc (unless I just stick all of this in the ship class - why make things more complicated than they need to be?);
  • Need a “game” class, that acts as a single external interface/entry point to the game and runs all of the other code (good idea to keep player stats separate from the game class in case I decide to try and implement a simultaneous WiFi two player mode, or something daft like that - with this in mind, I wonder if it’s worth putting all of the joypad-handling code in the game class, rather than in the player class?);
  • Need a map class;
  • Need a bullet class that inherits from the sprite class.

I think that’s everything I’ll need. The complicated bit will be learning how the PALib sprite system works and writing the sprite class. Everything else should be pretty easy.

The time-consuming parts will be grabbing the images from the Amiga game (I wonder if there’s a Blitz sprite to IFF converter on the Aminet somewhere? I could write one if there isn’t - maybe that’d save some time) and grabbing the sound samples. The Amiga samples are very low quality, and don’t convert very well to the DS. Alternatively I could go back to the original source (via MAME) and grab the sounds myself, but the problem with this is that I don’t have MAME for the Mac, and it probably won’t perform very well in Parallels.

Another hugely important and time-consuming aspect of the game will be tweaking the way it plays until it’s enjoyable. This is where I hope the original Blitz code will prove most useful.

Categories: Defender DS, MenuDS Tags:

Menu System Released

April 12th, 2007 Ant No comments

The menu system is now in a state where I’m fairly happy with it, so I’ve decided to slap a GPL licence on it and release it. It doesn’t do everything I wanted - transitions and animated buttons are the most obvious ommissions - but it will suffice for a first release, and it’s perfect for Defender. I made a handful of amendments just before releasing it:

  • Disabled stylus interaction if the menu is being displayed on the top screen;
  • Tidied up menu and button creation, so that the bitmap objects are created inside them - this saves huge amounts of setup code;
  • Improved the destructors so that the whole shebang is deleted properly;
  • Wrote some documentation (which, now that I read it through again, has some stupid copy-and-paste mistakes in it).

Excitingly, the news of the first demo release made it onto a site called “Moddz” - it’s not one I’ve seen before, but I believe this net recognition makes me an Official DS Homebrew Coder. Huzzah!

The site’s here:

http://www.moddz.com/index.php

Anyway, I’m off t’pub for a well-earned drink.

Categories: MenuDS Tags:

Menu System Works!

April 11th, 2007 Ant No comments

Hierarchical menus are now working. Internally the menu system supports two types of buttons, “action” buttons and “menu” buttons. “Action” buttons execute functions when clicked via the use of pointers to functions. “Menu” buttons switch from one menu to another via menu pointers. Outside of the menu system there is a third option, the “back” button. This just uses the current menu’s parent menu as a pointer and creates a “menu” button using it.

The easiest way to build a menu system is to define the menus first, then add the buttons afterwards. This means you’ve got all of your menu pointers ready for the buttons to point at.

Some things I hadn’t thought of:

  • Need to be able to put text onto the menus using the TextWriter;
  • How can the menu system hold data like a life counter that will update when the variable updates? Make a pointer to the life data?
  • Still need to do the pad integration!
  • Need to handle the released sound.

Oh. Just tested the menu system in Mario Kart DS, and that uses immediate (click event rather than release event) menus. Bah. I’ll have to work in an option to set the menu event type.

(Later)

Scratch that, I’ve taken out the release event system as the two are pretty much incompatible with each other.

(Later still)

Pretty much finished, now. I’ve integrated the pad, added sounds to the pad up/down events and tidied various bits and bobs up. The trickiest bit was adding sound (again). It turned out that I was trying to access the menu set pointer from the wrong place, which was throwing all of the sound code out, but it took ages to work that out. Uploaded a demo to Simian Zombie and posted it to the PALib forum for feedback. Pretty sure that none will be forthcoming, but we’ll see.

MenuDS Screenshot

The binary files are at this link:

MenuDS

I haven’t done anything with the TextWriter yet, nor have I added animated buttons and backgrounds or transitions. That all seems a little superfluous at the moment.

Oh, another thing I’ve added - “Quit” buttons. This is a new button type both internally and externally. It allows the programmer to detect whether the menu system has reached a point where it can be discarded and the program can move on. I discovered that I couldn’t run two instances of the slideshow class as well as having the menu system in memory - I think I ran out of RAM. The “quit” button lets me free up the menu system memory outside of the menu structure and use it for more important things.

Aha, a sudden solution! The TextWriter thing’s easy to solve. If I had a “lives” button, for example, that button just needs to run a function that will:

  • Increase the current number of lives (wrap if limit hit);
  • Print the current number of lives to the screen next to the button using the TextWriter.

I need to extend the menu class so that it can run a function when the menu is first initialised; that way I can print the initial value of the lives variable.

The “B” button should navigate back to the previous menu.

(Later)

“B” button wired up, and sound generation moved into the MenuSet out of the menus - this makes more sense, and reduces the size of the menu objects. Menu initialisation functions work - they’re essentially “onLoad” events. Fixed some poor decisions in the TextWriter, too.

It now occurs to me that the TextWriter should be able to buffer the background, too. Doh!

I wonder if I should do unload events?

Thinking about it, I don’t think the menu system should reset the currently-selected option to the top of the list when you navigate to a sub-option/external function.

Categories: MenuDS Tags:

movem.l d0-d7/a0-a6,-(sp)

April 11th, 2007 Ant No comments

(Written 10/04/2007)

Googled for the Defender sourcecode and eventually found it. I’ve got the Amiga Format version of Blitz Basic 2 running in WinUAE in Parallels, but I’ll need to get the latest AmiBlitz working soon. Looking through the Defender code, I’m not sure how much use it’s going to be. Here’s a quick example:

x3=((xp+864) LSR 4)&127+95:y3=Int((y+28) LSR 3) If x3<>hsx OR y3<>hsy Gosub alloff Use BitMap 2 BlitMode EraseMode Blit 30,hsx,hsy BlitMode CookieMode Blit 30,x3,y3 hsx=x3:hsy=y3 Use BitMap db Gosub allon EndIf

Aside from the fact that I can’t remember most of the Blitz-specific commands, we’re dealing with proper retro code here - no comments, meaninglessly short variable names, gosubs instead of functions and magic numbers. All of this junk is interspersed with this kind of thing:

MOVE #$0020,$dff09a

Yep, it’s Motorola 68000 assembly. Good job I bought those books on asm and the 68k CPU, really. Looks like they’ve used floating point (well, emulated floating point) maths, too. I’d rather avoid using floats if possible because they’re so slow, so I’ll probably have to rework the algorithms (if I can work the damn things out).

Started extracting the sound. Apparently sounds need to be in 8-bit signed RAW format. They’re currently in IFF-8SVX format, which is nothing more than 8-bit signed RAW with a header. If I can get hold of the 8SVX spec I can automate stripping the header and I won’t need to worry about converting the samples. Handy!

Windows problems are currently getting in the way of any further progress, though. My virtual Windows disk is now so fragmented that it’s taking forever to do anything at all. All stop whilst Windows defrags. Fortunately I didn’t bother to dual boot and kept Windows safely confined in Parallels, or I’d be stuck waiting for the damn thing to finish churning now. Deleted a load of stuff, too - won’t be needing the XNA framework or C# for a start.

(Later)

Tidied up the destructor for the slideshow - it now runs multiple times without crashing. I wasn’t clearing the vector and one of the array properly. (Though running it too many times still crashes it - there’s something I’ve missed…)

Also made improvements to the menu system. Added a pointer back to the menu set for each menu, so I can store menu-wide variables in there. The menu set now contains pointers to the the button clicked/released sound files, for example. Menus also contain a pointer to their parent (if they are submenus) to enable the back button to work (when I write it). Enabled the clicked sound.

There were two tricky things here. The most difficult was getting the cyclic dependencies sorted out. As the menus contain a pointer to the menu set, and the menu set contains a vector of menus, we have a problem where file A includes file B, which includes file A. Cyclic dependency. The solution is to scrap the problematic include and replace it with a forward definition. So, instead of having this in “menuset.h”:

#include "menu.h"

include <vector>

using namespace std;

class MenuSet { private: vector<Menu*> menus; }

We have this:

#include <vector>

using namespace std;

class Menu;

class MenuSet { private: vector<Menu*> menus; }

In the menuset.cpp file, we need to include both “menuset.h” and “menu.h”.

This only works if we’re dealing with pointers. If we had a vector of menu objects, rather than pointers to menu objects, we’d be stuffed.

The second tricky problem was getting the sounds into the class. This is tricky because you need to pass in a pointer to the size of the sound, not just a pointer to the sound itself. The datatypes are:

const void *sound; const u32 *sound_size;

The functions (defines, actually) that play back sounds expect the sound_size variable to have the name “sound_size”, where “sound” is the name of the sound. Just to make things more complicated, the docs for the PALib suggest that any sounds (with the name “<name>.raw” in the data directory) included in the project (with “#include “<name>.h”, where “name” is the name of the file minus the extension) will be available within the project as “<name>_raw” (where name is the name of the file minus the extension). In fact, they are available as just “<name>” (minus extension, etc).

I’ve also tidied up the menu system’s destructors.

Random thoughts:

  • I wonder if I can write an OctaMED player? I vaguely remember the C sourcecode for the player and a description of the file format shipping with SoundStudio;
  • I wonder if I can make the high score save file adhere to the IFF standard? Just been reading about that, y’see…
Categories: Amiga Porting, MenuDS Tags:

Random Thoughts

April 11th, 2007 Ant No comments

(Written 09/04/2007)

Not much done today. Just spent a few minutes changing the menu so that if you click a button and drag the stylus off it, then drag the stylus back on again, the button remembers that it has been clicked and shows the highlighted image again. I had a thought yesterday - what’s the interface standard for buttons? Do they respond immediately to the down event, or do they wait for the release event (the way I’ve done it)? A quick check of the BIOS menu suggests that I’ve got it right.

Stuff that needs doing after I’ve written the game, whilst I think about it:

  • High score table/high score saving;
  • Web interaction (version checking, etc);
  • Title screen music;
  • Attract sequence.

When pausing, I thought it might be neat to play the original Game Boy “dit-dit dit-dit” pause sound. Might try and work the Konami cheat in somewhere, too.

Categories: Defender DS, MenuDS Tags:

Sine Scroller

April 11th, 2007 Ant No comments

(Written 08/04/2007)

More refactoring. I’m now splitting most of the ScrollingText class into a ScrollingTextBase base class. That will reduce the amount of repeated code in the sine scroller to almost none.

This is the first time I’ve tried working with inheritance in C++ in about 3 or 4 years, during which time I’ve used several other more modern OO languages, so trying to switch back to the unfriendly syntax employed in C++ is difficult. Still, after an hour or so of fiddling and reading I’ve got it all working. Now on to the sine scroller.

(Some time later)

The sine scroller now works, and I’ve fixed a few bugs in the rest of the code. It uses the same FIFO system as the scroller to move the Y position of each letter around.

Uploaded it to Simian Zombie.

Sine Scroller Screenshot

(Later)

Ah, it seems I’ll need to recompile the PALib with a specific commandline argument to enable WiFi support. I’ll probably ignore it for the moment and come back to it when I’ve got everything else finished. Assuming I structure everything properly, which is the reason I’m tackling presentation before the game itself, it should be easy to add it in at the end.

Menus, then. Structuring them is easy - this is exactly what I do every day at work. So, I’ve got a MenuButton class, a Menu class that contains a vector of buttons and sub-menus (instant menu tree) and a MenuSet class. The last one isn’t strictly necessary, but I’m planning to wrap a lot of generic functionality into that class instead of duplicating it down the tree and wasting memory. The only difficulty here is working out how to receive events from the menu - does C++ have an event system? Will I need to write one myself? How about a message queue instead? Or just using delegates? How do delegates work? (One phonecall later - they’re apparently “pointers to functions” in C++, not “delegates”.) Lots of research needed here…

(Half an hour later)

Not as difficult as I thought, then! Heh. It works like this. Inside the button class, we declare a pointer to a function as a member, like so:

private: void (*action)();

There are three things to note here. The type of the member should match the return type of the function that we’re making a pointer to, so the function “void myFunction()” would work, whilst the function “int anotherFunction()” would not. The next thing to note is that we declare the pointer inside brackets; this isn’t strictly necessary, but it’s apparently a convention that indicates the variable is a function pointer. The last thing to notice is the pair of brackets after the declaration - this lets the compiler know that we’re creating a function pointer. If the function we’re making a pointer to has arguments, these should be specified in the brackets. If we wanted to make a pointer to this function, for example:

int myFunction(int myInt, int anotherInt);

We’d use the following pointer:

int (*myPointer)(int myInt, int anotherInt);

For the purposes of the menu system, we just need to use the first example - a function with a void return type and no arguments. Once we’ve assigned the pointer a memory address (as you would with any other pointer, ie. “action = myFunction” - note the lack of brackets after the function), we call it like this:

(*action)();

All I have to do to make a button execute a function (defined in the main.cpp file) is pass the function to the button object as an argument and then click the button. Fantastic!

(Later)

Another PALib bug that I’d spotted before but hadn’t noted down. There’s an odd problem with the DMA_Copy() function. All of the parameters have to be in brackets or it doesn’t work properly. For example, the top line gives different results to the second line:

DMA_Copy(100 + 120, 200 + 220, 12, DMA_16NOW); DMA_Copy((100 + 120), (200 + 220), 12, DMA_16NOW);

Aside from the new bug, which I’ve worked around, the menu system works! I can display buttons of any size at any position on the screen. Clicking and holding a button changes its image to “selected”; releasing it performs the button’s action; and dragging the stylus off the button resets it to “unselected”. Once whatever it was that ran drops us back into the menu system it redraws itself. Each menu can have its own background image.

Things to do:

  • Buttons need a “selected by keypad” image, to allow the pad to work;
  • Keypad needs wiring up;
  • Functions to allow changing between submenus;
  • Refresh() function to force a menu to redraw (useful if the menu changes a variable (“lives”, for example) and needs to update itself);
  • Need a “back” button;
  • Animated buttons? Possibly not this time around…
  • Attach sounds to click and release events;
  • Transitions? Again, possibly not this time around.

It looks like the slideshow will only run once - trying to run it again crashes the DS. Need to look into that.

Categories: Defender DS, MenuDS, PALib, Text Scroller Tags: