tweex[dot]net
Welcome to the Madhouse

So what I have been doing since my last update. Well, I have played through Batman: Arkham Asylum, AND YOU SHOULD TOO! It’s a great game (given, the boss fights aren’t up to much) but I love the sneaky, pick people off one a time, parts (the Batclaw has to be my favourite weapon for doing this, just catch someone unaware and yank them over the side of a fence for an instant incapacitation).

I have also been back at Uni, so have been working on a variety of game programming related tasks. My modules for this semester are Artificial Intelligence Techniques, Advanced 3D Graphics, Network Programming and my Applied Research Project (my dissertation - which is actually a year long module).

AI
AI has been interesting so far. We started by looking into State Machines, and then Behaviour Layering before moving onto Steering Systems and Path-finding. The culmination of this is that I currently have a demo application that uses a state machine to drive the steering behaviours of a steering system following a path calculated by an A* path-finding algorithm.


AI path-finding demo, using the Insimnax Framework

A3D
Advanced 3D Graphics has three “mini-assessments”, one of which I have already completed (Shaders), and the second of which I am currently half way through (Animation). The final one will be large-scene rendering.

The shaders assignment took the form of a report looking into a particular field. This was a partner exercise and we worked on Post-processing effects.

The animation assignment is looking at skeletal animation with blending, as well as being able to influence particular bones in a mesh to make them perform certain things (like look at a point of interest). Being able to attach objects to a mesh is also another desired feature. All this is being done in DirectX 9 and I currently have instanced skinned meshes (software and HLSL) with animation event callbacks.

Instanced, animated, Tiny’s

Network Programming
Network programming involves making a game (I am using C# and XNA) which can have 4 or more players playing over a network. I am making a 4-player version of Asteroids and currently have the “player-chat” lobby part of this working, as well as a nice framework for handling application layer packets.


Main lobby

ARP
My dissertation is on the topic of “Visual Scripting Systems for Games”. Not much to report on this yet since it has been mostly research based so far.

Insimnax Framework
The Insimnax Framework is a game framework I am currently working on which makes heavy use of OGRE 3D. The framework itself is currently a wrapper to make getting started and using OGRE 3D easier, although I have plans to extend it by adding “systems” such as GUI, Physics and Audio. I am currently using this framework for my AI project and hope to use it for my dissertation too. I plan to release it under an MIT license once it has reached a decent (and somewhat stable) stage of its development.

… and finally
Oh yeah, did you hear about Epic releasing the UDK for free?! Crazy!

Templates and Streams; the perfect couple

Recently I’ve been doing some work templatifying my two I/O classes, and from that have come to the conclusion that templates and streams make for the ultimate generic programming tool. Previously I had a load of old duplicate bloat code in these classes, that was all removed and replaced by one templated member function, and two specialised template functions from it, and best of all since this code is now able to take external streams as input/output sources, it means that I no longer have one code path for handing files, and another code path for serialising to memory. Instead I just pass an fstream when working with files, and a stringstream when I want to serialise to/from memory, simple!

One of the best changes the templates and streams has made is to my tryParse function. Previously there were a load of these, each handling a different variable type using old C functions. Now the function has been replaced by a single templated function, and a stringstream. If you try and tryParse a type a stringstream can’t handle, it just doesn’t compile, best of all is that you can still expand the function using template specialisation if you want to tryParse to your own custom types.

//! Try and parse a string to another type
//! \return true if the conversion was ok, false otherwise
template <typename T>
bool tryParse(
	const std::string &str,		//!< String to convert
	T &out				//!< Output variable
	)
{
	std::stringstream sstream;
	sstream.exceptions(std::ios::failbit | std::ios::badbit);
	sstream << str;
	try { sstream >> out; }
	catch(std::exception&) { return false; }
	return true;
}

I actually worked out the total number of lines of code before, and after my changes. The results are below:

Old:
Reader 		- 183   (header) 1,042 (source)
Writer 		- 209   (header)   839 (source)
TryParse 	- 50    (header)   115 (source)
Total 		- 2,438

New:
Reader 		- 271   (header)   351 (source)
Writer 		- 226   (header)   245 (source)
TryParse 	- 30    (header)     0 (source)
Total 		- 1,123

Quite impressive :) (Although I did cheat slightly since the new reader and writer have a macro which removes a lot of code repetition from the header, it probably saves ~39 lines of code from each class, so ~78 in all. Still that would only make it 1,201 lines of code which is still a huge saving for something that has more functionality with less code).

[C++] Anything to/from a Hex String

Introduction

I recently needed to be able to convert any instance of an object in C++ to a file so it could be serialised, and then restored later; I did most of this by writing out each member variable of the object individually at the most basic level. This works fine and is easy enough to implement; but then came the time to do the “generic” version, the version that could write out any object (such as a struct) as a whole.

The I/O classes can write out/read in using either binary or text, the binary version of the generic writer is simply a case of writing out the length of the data, and then each byte of the data. The text version however required me to convert the bytes of data making up the object into something that was sensible as text, I decided to do this by converting each byte into a hex value and adding it to a string. As I was working on this I found that the information about how to do this without using some of the old C-style string manipulation functions is quite sparse on the net, so after much searching, trying, and failing, I now have a solution that works both ways using good old C++ string streams.

I should probably point out that I don’t think this solution is endian neutral, so you would likely want to add a method of endian detection and switching to ensure consistency across different architectures.

The Code

When a byte is encoded to hex string, each byte becomes two characters in the range 0 to F. For example, the value “10” would be written out as “0A”.

The code works by using a std::stringstream with hex mode set (std::hex), along with using zero’s for padding (std::setfill(‘0’)) and a fixed width of two for each byte added as hex (std::setw(2)).

The toHex function works by adding each byte of the passed data into the string stream as an integer with a width of two; because zero’s have been set as padding, any numbers which are added to the stream that are only one character long will be automatically prefixed with a zero resulting in the correct two character hex value being added to the string stream.

The fromHex function works by reading out two characters from the hex string into a string stream, these characters are then converted back into the byte value when read out from the string stream into an integer. Finally, the value of the integer is stored as the value of the byte, and the string is moved on to the next set of two characters.

Get the code.

Rant Tags Off

So to be fair to the PS3, I said that my experience has so far been mostly good (although I have a feeling this is because I haven’t tried to do anything complicated with the XMB yet). I guess my good experience comes from the fact that there are a few games I enjoy playing on it, and also the fact that I can use my debit card in the PlayStation Store which is something I can’t do in the XBOX Marketplace (they don’t accept Maestro cards).

The games in question are WipEout HD, and Ratchet and Clank. As I said before, WipEout HD is the main reason I bought a PS3, so finding out last week that there was going to be a DLC expansion for the game caused me to almost go running around the office like a crazed fangirlboy, the trailer for the game is below. Can’t wait to try Zone Battle and I really hope their definition of summer is more towards the start of summer :D

I have never played a Ratchet and Clank game before this one, and I feel now that I have been missing out. I love it! The humour in the game is fantastic and somewhat dark (which is also the main reason I love Portal so much) and I’m having a great time playing it, even despite the fact that I sometimes get stuck (game play wise) in a level, and that the enemy collision detecting often screws up a bit leaving them stuck (physically) in walls.

Rant Tags On

Warning: Rant ahead, if you are a PS3 fan-boy stop reading now. I don’t need your hate.

For my birthday this year I bought myself a PS3 to go with my nice new 42” 1080p HDTV, this now completes my collection of current generation consoles as I also have a 360 and a Wii so I can tell you that this opinion comes from someone who isn’t biased to a particular console. So why did I buy it? Two main reasons, I had a shiny new TV and wanted to see what all the fuss about Bluray was, and I also wanted to play WipEout HD; now leaving aside the fact that buying a console that cost almost £300 to play a £14 game is perhaps a sign of insanity on my part, I have to say my experience so far has been mostly good, bar one thing, “installing… please wait”.

I believe this video (32 - 38 seconds) pretty much sums up my opinion on installing games on the PS3. A friend from work lent me some games to play, one of which was GT5, I had 10 minutes spare before lunch so I thought “Hey, I’ll give it a go”… WRONG! It took 10 minutes just to install the damn thing to the hard drive (what the hell is this, a PC?!) and then took another 20 minutes to download and install updates; perhaps I wouldn’t have minded so much if the hassle of getting the game to play was worth it, but it distinctly wasn’t and I only played the game for about 10 minutes before moving onto another game I had been lent. The most amusing thing about the near constant updates, is when I bought WipEout HD from the PlayStation Store, downloaded it, went to play it and was told that there were five updates for the game… I’m sorry, but I just downloaded over a gigabyte of data and now I need to download more?! Why can’t you just update the version you have on the PlayStation Store so that I don’t have to bother with this? Oh right, yeah, that would make sense wouldn’t it; can’t have that.

Oh, and just don’t get me started on the XMB. No seriously, don’t.

Fences and what I do

I’ve taken to using Twitter to post updates on since I can do it more informally and whenever I feel like it.

Firstly, I’ve been using a program called Fences to help sort out my desktop icons and so far I’m finding it really handy to be able to group up my icons and not have Windows randomly decide to re-arrange them for me… bliss. You can see my desktop here.

Secondly, BlitzTech (where I work) has released a video of some of the features of the BlitzTech SDK, including the Scripting and Behaviour (State Machine) system which I am currently responsible for developing and maintaining. If you want to see what I work on on a day to day basis then you can find the video here (it’s the “Tools Demo” one).

[C++] Pointer Fun – SafeDelete

Introduction

SafeDelete and SafeArrayDelete are functions that will delete the data a pointer points to before setting it to NULL. The idea being that they leave the pointer in a safe NULL state so that you don’t try and use a pointer which points to invalid memory.

How to - With a Macro

You can implement a SafeDelete set-up using a macro, it might well look something like this:

#define SAFE_DELETE(ptr) { delete (ptr); (ptr) = NULL; }

Now that’s all well and good, and would perfectly do the job at hand, but we are C++ programmers and as such we prefer not to use macro’s unless we have to; after all, they can be tricky to debug since you can’t set breakpoints in them, they have no type safety which means you can come seriously unstuck if you pass something incorrect into one, and they can be tricky to read.

Attempt #1 – Just pass it a pointer… right?

Now, you might start off on your quest to convert that macro into a function by writing out the following code:

void safeDelete(void *ptr)
{
	delete ptr;
	ptr = NULL;
}

All looks fine, you are passing it in a pointer, deleting it and then setting the pointer to NULL… simple. So you use that in your application, the pointer is checked, it isn’t NULL so it gets deleted and set to NULL, cool. Then your code jumps out of the function and… what the hell?! The pointer passed into it is no longer NULL, but the data it points to has been deleted, the pointer is left dangling. Not a very safe SafeDelete.

So you’re now just left scratching your head, why did that happen? Simple, you passed a copy of the pointer into the function as a parameter, and you only changed that local copy.

People often have a misconception with pointers that they just somehow exist and magically point to a memory address, in actual fact, a pointer like the one shown above is an object on the stack that points to a memory address (also known as a pointee). If you know anything about that stack, that should tell you two things; firstly, the pointer object is passed into the function as a copy; secondly, that copy is destroyed once it falls out of scope.

The confusion over whether you are passing a pointer as a copy is easy to make since a pointer is essentially two things in one, this can be better explained by showing how const can work with a pointer.

void safeDelete(void *const ptr)
{
	delete ptr;
	ptr = NULL;
}

The above code should not compile, you should get an error about trying to assign to a value that is const. That is because you have made the pointer const, so you cannot change its value; this serves to clearly show that assigning NULL to the pointer is changing the pointer itself, and not the data it is pointing to.

Attempt #2 – A pointer to… a pointer?

If you want to be able to modify the location that a pointer points to after leaving a function (that is, essentially modify the pointer object itself) you need to pass it into the function like you would any other object that you want to modify; by using a pointer or a reference. First let’s look at the pointer to a pointer approach.

void safeDelete(void **ptr)
{
	delete *ptr;
	*ptr = NULL;
}

Well, that does the job all right. Note that you have to de-reference the pointer to a pointer that was passed into it before performing the required operations on it; this is so you are dealing with the pointer object you passed in from your function, and not the local copy of the pointer to a pointer.

The problem with this approach is that since pointers to pointers can’t be implicitly casted to a void** you have to do the cast yourself when passing to the function, which just looks ugly (and would get annoying fast).

int *ptr = new int(10);
safeDelete((void**)&ptr);

Attempt #3 – A reference to a pointer (and some trickery)

Just like you can created pointers to pointers, you can also create a reference to a pointer. These have all the usual features of references in C++ such as never being NULL, the syntax for creating such a thing is shown below.

void safeDelete(void *&ptr)
{
	delete ptr;
	ptr = NULL;
}

However, this code has a major flaw since it won’t compile. Why? Because you cannot create a reference to void so we need some template trickery to get this working correctly. As well as being able to create template classes, you can also create template functions and we will use this to our advantage to be able to create a reference to a pointer to a generic type.

template <typename T>
void safeDelete(T *&ptr)
{
	delete ptr;
	ptr = NULL;
}

This uses the template argument as the type for the reference to a pointer, this template trickery also allows us to do away with the nasty void** casting when using the function.

The final code

And here are the finished functions for safeDelete and safeArrayDelete.

template <typename T>
void safeDelete(T *&ptr)
{
	delete ptr;
	ptr = NULL;
}

template <typename T>
void safeArrayDelete(T *&ptr)
{
	delete[] ptr;
	ptr = NULL;
}

Note

You might be wondering why I don’t do an if to check if the pointer is non-NULL before trying to delete it. Well the default delete operators in C++ automatically ignore the deletion of a NULL (zero) pointer, so you can in-fact delete 0 as many times as you want; adding the if check does nothing but add extra CPU cycles.