Saturday, 3 October 2009

MP3 support added

I've added MP3 support to the audio system (more specifically the SoundResourceHandle) using the MAD library. I'd like to implement streaming MP3's from memory, this should be possible using MAD although for now I probably won't bother. The only problem is that a 4mb MP3 could expand to a 50mb sound file in memory, although with the obscene amounts of memory people have these days it shouldn't be a problem (it will become a problem if I port the game to any other systems).

Audio System in place

I've uploaded the audio system for the game. Currently it only supports XAudio2 which is the new API designed to replace DirectSound. The way the audio system is structured is to allow new audio API's to be easily plugged in, it is based around the design presented by Mike McShaffry in Game Coding Complete (3rd edition). The reason I chose this design was because it presents a very clean interface and easy to understand relationships between the various components. The game code requests that the Audio System create it a new sound effect object which it does based on a loaded resource. The game code can then use that sound effect object (AbstractSoundEffect) to play/stop/pause sounds. The use of the interface AbstractSoundEffect by the game code obviously hides any underlying implementations. The AbstractSoundEffect then passes any buffered audio data onto the AudioSystem in order for it to be mixed with other active sounds and the final sound produced through the players speakers.

There are some tweaks that need to be done to my XAudio2 implmentation for performance reasons. I'm finding that having every sound effect maintain it's own "SourceVoice" is killing performance, only a few active sound effects can drop the frame rate quite substantially. In order to solve this I'll probably keep a set of pre-made source voices in the XAudio2AudioSystem class which active SoundEffects can then request and release when they're finished. If a system attempts to play a sound effect but no active source voices are available then the effect will either be queued or not played at all (in the case of extremely timing senstive effects where playing it late would just seem odd).

Although changes do need to be made to the Audio System the interfaces won't change. This means I can use them in other systems without the problem of having to alter that code at a later point.

Wednesday, 30 September 2009

Audio System coming along

Some changes were made to the resource cache as based on Mike McShaffry's "Game Coding Complete 3rd Ed.", an excellent games programming book may I add. The resource cache is now much more flexible and allows it to maintain things like D3D Textures for sprites. These changes were done to facilitate the introduction of the sound component which seems to be coming along nicely.

I am currently planning to support 3 audio types, uncompressed WAV, OGG and MP3. My plan is to stream music and large audio files straight from the harddrive. How this will work in the context of the resource cache remains to be seen. One option is to leave music files seperate from the resource cache, although I'm not too keen on this. The only other option is to somehow stream the music from the compressed zip that makes up the resource files. This seems like a difficult job however, since I'll essentially have to decompress the audio twice, one from the zip and secondly from Mp3 or whatever format into raw PCM data that can then be used by the underlying audio API.

The sound will be done on windows using XAudio2. DirectSound seems to be one the way out now and XAudio2 is also cross-compatible with the X-Box 360 which is a bonus If I want to port it (meaning I can leave most of the audio code intact). I haven't decided on the API's for other platforms yet, but I'll cross that bridge when I come to it.

Sunday, 20 September 2009

Basic Main Menu in place

I've implemented a pretty simple main menu with some buttons on it. None of the buttons are hooked up yet so that'll probably be the next task. The main menu is accessed after the user passes the splash screen. Text/Graphics should be added to these screens. I'll probably add some sort of disclaimer/GNU notice on the splash and the title on the main menu. For the background I want to play a video, this will probably be a video of me playing the game when I get the game/video components implemented.

Thursday, 17 September 2009

User interface coming along

Development recently has been focused on the user interface. This effected several changes in other systems like the renderer and platform also. I really want to get on with the fun part (developing the actual game) but as I've mentioned my approach is to have as many other components in place as possible first. It shouldn't really matter what order you write your code in though, if your design is modular and clean.

Developing a user interface is easy whilst developing a good user interface is very hard. With the user interface for PhysTank (as with most games) easy is taken over functional. A fully fledged UI API would contain a richly featured widget system, incorporating buttons, sliders, dialog boxes etc no dissimilar to the java swing libraries, developed entirely in a blackbox fashion and probably farmed out to a seperate library. There are C++ API's that exist which contain this and deciding whether to use one of these or roll your own is often a tough choice. For PhysTank the UI doesn't have to be particularly complex, I probably won't be using that many floating dialog boxes or slider controls, so where appropriate will fashion my own thrown together widgets. In a game that does require a more complex UI I would definitely recommend using an API like GTK. Using common API's like this rather than rolling your own will not only save you lots of time but since most UI API's are designed around making sure users have a certain degree of familiarity you won't be confusing your players with weird and wonderful designs. I will probably be using one of these API's when it comes to writing the level editor.

The User Interface still has a long way to come, and I probably won't polish it off until (very) late in development, but as long as there's something in place that gives the player reasonable feedback about what's going on in the game it'll do. Next up on my check list is to implement a basic main menu for the game, also further down the line colour schemes. One problem I'm having is deciding how screen elements (pictures, text etc.) should be placed and scaled on screen. If the user ups the resolution from 800x600 to 1024x768 for example, or higher, then icons and text will appear too small on the screen. In order to fix this these things have to be scaled dynamically based on some "ideal" resolution (i.e if the ideal resolution was 800x600 then on a 1024x768 display that would be a scale factor of 1.28 for the on screen elements). Doing this in an elegant manner isn't easy, and I may just have to resort to having the renderer scale things automatically and all positions given in the range 0-1 and maybe implement scaling functions for text (GetFontSizeScaled() for example).

Sunday, 13 September 2009

Changes to the physics system.

I've changed the Physics component to expose more the underlying Box2D implementation. The reason for doing this is that I didn't see much point in building a complete wrapper only to act as a relay to Box2D function calls and restrict functionality available to the game. Due to this the Physics class has become more of a helper class, defining functions which will make future code look cleaner and easy to understand, such as functions to create physics bodies and shapes rather than having shape and body definitions all over the place.

The other changes include adding an AbstractCollideable and AbstractCollisionHandler to the Physics component. Game entities will be able to inherit from AbstractCollideable and be notified of when a collision occurs between them and another body/shape. The other type of collision handler, AbstractCollisionHandler, can be registered in order to receive global collision notifications. This would be useful for the sound system for example, which could implement this class to play sounds when a collision occurs.

As is often the case when using third-party code, finding the right implementation in your code can be somewhat of a nightmare. Your natural instinct is to encapsulate the third party code in your own set of classes which masks its use to the rest of your application logic. The problem with this is that the used code can often be quite large and have a fairly complex interface, so unless you want to spend a great deal of time encapsulating every small function call you're probably going to end up masking some of the used library's functionality.

The alternative to is present the third-party code directly to your application. The problem with this is that it very much ties it to your game, so if you find a better solution to the problem down the line, then replacing the system can be quite a long drawn out and loborious task. It's extremely difficult to create a "one-size-fits-all" interface class for systems with complex interfaces. It's very rarely you'll find a perfect solution to this problem. In PhysTank you can see both approaches, with the Renderer I've very much gone down the route of masking functionality in favour of portability and modularity, where with the Physics component I'm tieing the Physics API being used to my game. The difference is that the Physics API should be portable between various platforms since it itself has been written platform-independent, where as there a good chance the rendering code can't be (especially in the case of Direct3D).

I am not entirely happy with the approach but as is often the case with Game Development, trade-offs are part and parcel.

Thursday, 10 September 2009

Help

I should mention that I'm always looking for help, coding, asset creation etc. If you're interested in working on a fun project either e-mail me or leave a comment and we'll work out giving your repository access.

I really should work on the design documentation so everyone has a better idea of what the game actually involves.