Cross-Platform Game Development for C++ Devs

CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

Do you dream of writing the next hit game title but aren’t sure how to get started? Are you interested in game development just for the fun of it? Take a close look at a versatile cross-platform gaming engine that’s freely available for the beginning game developer.

A (Very) Brief History of 3D Gaming Engines

In gaming, more so than any other programming discipline, it is important to specify the platform correctly from the start. Will you support Windows, Linux, and OS X? Isn’t using OpenGL enough to get you there? OpenGL was designed in the early 1990’s for $25,000 Unix CAD workstations and later adapted to Windows and low-end platforms as the gaming industry drove the cost of graphics accelerators down from $2,000 a pop to the $150 mass-market price point you see today.

Indeed, many people would cite the revolutionary game Quake, written for OpenGL in 1996, as the direct cause of this. However, achieving Quake-level gameplay standards required more: world-class audio support, network connectivity, user-input device support, and real-time management capabilities—just to name a few. The solution for both requirements, cross-platform support and the extras that make a game exciting, is a decent game development platform.

Simple DirectMedia Layer for C++, Java, and More

Well, that’s all very interesting history, but it doesn’t really address the question of where fragging coders should start: Not every game is going to be a Quake clone. One option that has been touted for its many virtues is Simple DirectMedia Layer (SDML). This cross-platform multimedia library provides low-level access to audio, keyboard, mouse, joystick, OpenGL, and 2D video framebuffer. SDML supports most every platform I can think of, including Linux, Windows, all MacOS variants, WinCE, Dreamcast, and others. It shows up in MPEG players, hardware emulators, and many popular games, including the award-winning Linux port of Civilization: Call To Power.

SDML is written in C, but works with C++ natively, and has bindings to several other languages, including Ada, Eiffel, Java, Lua, ML, Perl, PHP, Pike, Python, and Ruby. The sky is the limit with SDML, which happens to be the engine for my favorite open source flight simulator, GL-117 (see Figure 1). In fact, 513 games currently are built on top of the SDML engine and registered on the SDML homepage.

Figure 1. The View from GL-117

Tunnel Vision Demo Program

The best way to get inside a game engine is to look at some sample code. Take a brief look at a 2-D tunnel-type display in SDML (see Figure 2) to see what you can do in just a few lines of code. This example might be something you use for a screen-saver, music visualization, and so forth. I’ve trimmed the actual drawing code for brevity. Follow my comments for a description of how SDML works:

#include "Tunnel.h"

// SDL Stuff
SDL_Surface     *screen;
SDL_Surface     *bBuffer;
SDL_Surface     *Image;
SDL_Rect        rScreen;
SDL_Rect        rBuffer;

// --------------------------------------------------------------

int main (int argc, char **argv)
{

  int flag = SDL_SWSURFACE;    // Requests a software surface.
                               // Software surfaces are in
                               // system memory, and are not
                               // generally as fast as hardware
                               // surfaces
#ifdef WIN32
  int fullscreen = MessageBox(NULL, "Show Full Screen (y/n):",
                              "Screen Setting", MB_YESNO);

  if (fullscreen==IDYES)     {
      flag |= SDL_FULLSCREEN;    // Take over whole screen, if
                                 // user desires
    }
#endif

  Tunnel_Timer();    // Read initial system clock

  SDL_Init( SDL_INIT_VIDEO );    // Initialize just the video
                                 // subsystem
 // Set screen to 320x240 with 32-bit color
 screen = SDL_SetVideoMode( 320, 240, 32, flag);

// Request hardware buffers for the screen surface, if available
  bBuffer = SDL_CreateRGBSurface( SDL_HWSURFACE, screen->w,
                                  screen->h,
                                  screen->format->BitsPerPixel,
                                  screen->format->Rmask,
                                  screen->format->Gmask,
                                  screen->format->Bmask,
                                  screen->format->Amask);

// This is the seed image that you will convolute when you get going
  Image = SDL_LoadBMP( "tunnel_map.bmp" );

  Image = SDL_ConvertSurface(Image, screen->format, SDL_HWSURFACE);

  rBuffer.x = 0;
  rBuffer.y = 0;
  rBuffer.w = bBuffer->w;
  rBuffer.h = bBuffer->h;

  // Ignore most events, including mouse, and disable the cursor
  SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
  SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
  SDL_ShowCursor( SDL_DISABLE );

  Tunnel.Set( 320, 240 );    // Tunnel will fill the whole buffer
  Tunnel.Precalc( 16 );      // Inner circle diameter

  while (SDL_PollEvent(NULL)==0)    {
      float fTime = Tunnel_GetTime();

      // Surfaces must be locked before modification, especially
      // if the buffer resides in the graphics hardware memory
      SDL_LockSurface(bBuffer);
      SDL_LockSurface(Image);

      Tunnel.Draw(bBuffer, Image, 180*sin(fTime), fTime*100);

      SDL_UnlockSurface(bBuffer);    // After updating, you may
                                     // unlock
      SDL_UnlockSurface(Image);

      // Push the buffer out to the screen draw area and force
      // a repaint
      SDL_BlitSurface( bBuffer, NULL, screen, &rBuffer );
      SDL_UpdateRect( screen, 0, 0, 0, 0 );
    }

  Tunnel.Free();
}

Figure 2. Spinning and Twisting 2D Tunnel Demo

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read