Sample - Portable Mobile Game Code

Posted by jiGGaK on April 26th, 2011

I’ve decided I want to try and break into the market of mobile gaming but I
needed a way to evaluate how practical it was to target multiple platforms at
once. Android and iOS are the main players right now but keeping myself open
to others seems like it would be a prudent step. And writing everything
from scratch multiple times is not an option.

If we look at all of the popular mobile platforms, they each provide some sort
of native development kit all based around a GCC toolchain with OpenGL ES 2.0.
So obviously we want to use as much portable C/C++ as possible, but what about
all the little (and not so little) differences between the platforms? I needed
to get my hands dirty and write a proof of concept.

The result is a simple bouncing ball
simulation and it runs on Android, iOS, and desktop (Mac, Windows, Linux).
Box2D is used for the physics engine, and the rest
of the code is licensed under the permissive beerware license;
please respect the license and buy me a beer… if we ever meet.

The code: what it is and is not

This is 2D only. This is not a framework. This is not everything
needed to make a game. The purpose of this demo is to get an idea for how one
might structure a project to maximize the use of portable code.

As it turns out using C/C++ for our game engine, logic, and graphics accounts
for quite a lot. But several platform specific aspects are worth mentioning.

The obvious first difference is the fact that Android is Java/Dalvik and iOS
is Objective C/Cocoa Touch. The basics for application development differ
significantly from platform to platform so we have to just grin and bear it.
For Android we need to use JNI (when targeting Android 2.3 and up the NDK
supports writing all code in C using native activies)
to call into our C/C++ code (avoid JNI inside render loop due to overhead).
On iOS Objective C is a pure superset of C so it mixes nicely. You can also
tell XCode to use the Objective C++ compiler which lets you freely mix C++
and Objective C by simply making sure your implementation files have a .mm
file extension.

On iOS the implementation is simple: resolve the path relative to the
applications bundle and read the file into memory.

Android was a bit more complicated. I had to do some JNI voodoo to call back
into the Dalvik VM to open and read files. The Java code itself was simple,
and the JNI code isn’t that bad either, but there is some serious
implications when it comes to JNI state. Basically in order to call back from
C/C++ into Dalvik we need a valid pointer to the JNI interface and the JNI
pointer to the instance of Activity
but these pointers are only guaranteed to be valid within the scope of a JNI
call. I ended up just saving the JNI related pointers into global variables
before calling any engine code that will call the loadAsset() function
(when targeting Android 2.3 and up the NDK provides a native asset loading API).

The last platform difference I want to mention is user input handling. In the
demo a simple struct is defined to abstract out the type of action and the
related (x,y) coordinate:

The render loop extracts these actions from a queue and handles them. The
threading model varies from platform to platform so it’s important to make
sure that actions are queued on the same thread as the renderer to avoid
potential race conditions.

Running the demo on desktop

To build on the desktop a few libraries are used to simplify the use of OpenGL:
freeglut for creating the window and OpenGL
context, and GLEW to check for OpenGL 2.0
(OpenGL ES 2.0 is a subset of OpenGL 2.0) support and include the various
OpenGL headers.

Use your distro’s package manager to install freeglut and GLEW:

$ sudo pacman -S freeglut glew

On Mac OS X an implementation of GLUT is provided with XCode. To install GLEW first install MacPorts and then run:

$ sudo port install glew

On Windows MinGW needs to be installed and configured.
Download the Automated MinGW Installer
package (at time of writing the mingw installer was mingw-get-inst-20110316.exe)
to simplify things and select C++ Compiler and MinGW Developer ToolKit
during setup.

Once installed download the freeglut and GLEW source packages and
compile/install them from the MinGW Shell:

To build the demo just run make in the desktop
directory. The asset loading implementation looks for assets in the path
../assets so be sure to run the balldemo executable from inside the desktop
directory.

Comment submitted

Thanks! Your comment will be reviewed shortly.

Rafael
July 4th, 2011

Works now . Thanks !

jiGGaK
July 4th, 2011

Sorry about that. For some reason I disabled the git vhost on my server and another vhost was interfering. Should be fine now.