Game State Pattern in C

Recently I’ve begun to write some sort of game/demo system from scratch in which I needed some kind of mechanism for states management. That’s because I didn’t want to drown in tons of switch statements.
Long time ago, I’ve stumbled upon managing game states in c++ article. Ideas presented there are good, but there was no option for me to use pure virtual functions and all that fancy C++ stuff, because of low memory & cpu budget. But still, I wanted to use similar mechanisms in my C program.
The code below isn’t platform dependent, so you can use it in your own programs on any platform. To get something from this article you should know something about C programming. I also suggest to check out the article about the C++ approach to get the overall idea what program state management is all about.


Post to Twitter Post to Facebook


Game project

Here are some screenshots from a project I’m working on for some time (in heavy multitasking mode ;)) with cooperation with several individuals. I’m putting everything together. Game is based on Unity3d (I’m not a great fan of it, but I’m curious how the things will turn out), so it’s not the low level stuff I have used to work. It will have single, online multiplayer modes and maybe some kind of editor.


Post to Twitter Post to Facebook


Done with math!

Well, not completely. Maths will stay and it won’t go away anywhere. I’ve just finished the basic math library for my engine. I had to implement classes for 2D, 3D, 4D vectors and two kinds of common matrices 3×3 and 4×4 and add wrappers around standard library math functions. Alot of boring stuff.
Well, I’m cheating a little because vector part I’ve made long time ago. I had only to change internal representation of those vectors. Earlier I’ve stored x, y, z, w coordinates inside individual class members (floats), but I’ve put them into one array of floats.
So, I can now easier bind program variables with use of glUniform* functions and fv postfix. It’s much more handy passing values in one data stream than individually one after another.

The only thing which I’m missing is member functions for setting identity matrices and transpose matrix functionality, but I save it for later and will add it when I will really need it.

I’ve also got simple basic GLSL shader manager with most basic shader programs:

  • flat shading
  • point light, diffuse lighting only
  • simple diffuse, directional, and vertex based light
  • texturing polygons
  • texturing polygons with modulation (multiplying of texture with underlying color)

What will be next? For sure first virtual camera implementation and first renderings without fixed pipeline. After that I think I will start to incorporate other systems for device input and sound.
So, to sum things up I’ve got system which works on linux (32/64 bit)/windows (support can be added easily for MacOS and OpenGL ES devices too), which contains maths module (trigonometry, common vector types and matrices), saving/loading startup configuration, logging functionality (which can be easily switched off or disabled in release builds), bare bones of platform agnostic OpenGL renderer with legacy/compatibility/core context creation, basic shader manager.
Everything working under cross platform windowing system of choice (Qt 4) and win32 api too. I was too lazy to implement GLX version, that’s why I went Qt :P.

So, things that will follow soon will be certainly ohhhh sooo cooooooooool! Like non-euclidean geometry, rendering and stuff 😉

lost in dimension

Post to Twitter Post to Facebook


Configuration window revisited

Making configuration dialog in plain win32 api wasn’t good option. I realized it when I was warming up before dive-in into Linux GLX api. What the hell am I doing, I thought for a while, and started to rethink my approach. Implementing OpenGL context creation for each platform wasn’t fun at all and for sure it could eat up more time that I wanted to invest.

I’ve decided to try the latest Qt (4.7) and I’ve begun seeking information about methods of creating new OpenGL 3.0> context in Qt windowing system. I’ve found only this old thread, no decent examples. Just like this kind of topic has died and nobody wanted to investigate it any further.

I’ve started to mess around with code from this thread, but after a while of browsing through Qt 4.7 documentation I’ve found out that new context creation is already supported.

Things turned out quite well and I’ve managed to redesign layout and rewrite the old dialog logic in few days and gain additional target systems. Adding other platforms will be easier now. I had only to reimplement some platform specific functions for resolution list retrieval, setting video mode in fullscreen and detecting/setting VSync (as there are different OpenGL extensions for each platform).
For now I’ve tested everything on Windows XP and Linux Ubuntu 32/64 bit (I don’t have resolution list retrieval/setting on Linux yet though) and two graphics cards (NVIDIA GTS 250 and low-end Intel GMA 950).
The other positive thing was that I was forced to move all OpenGL specific things to separate renderer class, so now I can easily reuse my OpenGL renderer code in other windowing systems.


Post to Twitter Post to Facebook


Saving/restoring rendering window configuration

I’ve added startup loading/saving capability today in my configuration class. I’m writing everything to simple xml file, it’s structure looks like this:

<window width="800" height="600" xpos="0" ypos="0" 
hz="75" bpp="32" FSAA="0" fullscreen="true" vsync="true"/>

Paths are not used yet and hold example values. For XML parsing I’ve used rapidXML. It was really easy to include it into my project. Firstly I’ve considered tinyXML, but rapidXML is alot faster and it is contained in single header file. (thanks to Sqward for pointing me out this parser! ;))
The only issue that I had was with example from documentation depicting iterating through nodes and attributes. Sample below is for nodes only, but for attribute case looks pretty similar, only methods are a bit different:

for (rapidxml::xml_node<> *node = doc.first_node("nodeName");
node; node = node->next_sibling()){
   // do something with node 

The code above resulted in endless loop in Visual Studio 2010 express compiler. I didn’t tried it with gcc yet – it looked like node==0 case was skipped and node was set to the first one resulting in a loop. So I had to replace it with something like this:

rapidxml::xml_node<> *node = doc.first_node("nodeName");
                 //do something for each node

With above XML structure I can specify desired resolution, window size and it’s position (if not in fullscreen mode), enable/disable fullscreen, set up paths to various engine resources such us scripts, material, textures, prerendered movies, background music and so on. I can also disable startup dialog and depend only on settings from configuration file.
The only two, three things are still missing. One is setting custom base directory, so all resources would be searched in paths relative to base directory. At this moment I’ve set the base directory as the application directory for Windows and user $HOME under Linux.
Second thing is overriding some configuration variables from commandline. But I will save it for later.
Third thing, XML could have a validation of some sort during load, to eliminate disaster if file is edited by hand or in case some settings are missing.

The logic behind saving/restoring configuration is simple. If no ‘config.ini’ (my default configuration file) is present configuration is set up with default, most common values.
After that there is a check if startup dialog has to be shown (which looks like in my previous post). If yes, values are used to set up desired resolution, windowed/fullscreen and so on. Else user is prompted to choose various options from dialog. Configuration is updated afterwards, so the same settings will be used on the next launch.

Anyway this was a very boring part, I’m glad it’s over ;).

Post to Twitter Post to Facebook