It's free to join Gamasutra!|Have a question? Want to know who runs this site? Here you go.|Targeting the game development market with your product or service? Get info on advertising here.||For altering your contact information or changing email subscription preferences.
Registered members can log in here.Back to the home page.

Search articles, jobs, buyers guide, and more.

By Jacco Bikker
[Author's Bio]

Gamasutra
November 17, 2003

Introduction

Mobilecore on Pocket PC

Printer Friendly Version
   

 

Change Login/Pwd
Post A Job
Post A Project
Post Resume
Post An Event
Post A Contractor
Post A Product
Write An Article
Get In Art Gallery
Submit News

 


 


[Submit Letter]

[View All...]
  



Upcoming Events:
Workshop on Network and Systems Support for Games (NetGames 2009)
Paris, France
11.23.09

EVA 09 - Exposicion de Videojuegos Argentina
Buenos Aires, Argentina
12.04.09

Flash GAMM Kyiv 2009
Kyiv, Ukraine
12.05.09

Game Connect: Asia Pacific (GCAP)
Melbourne, Australia
12.06.09

ICIDS 2009 – Interactive Storytelling
Guimaraes, Portugal
12.09.09

[Submit Event]
[View All...]

 


[Enter Forums...]

Note: Discussion forums for Gamasutra are hosted by the IGDA, which is free to join.
 

 

 


Features

Mobilecore: A Cross-Platform Framework For ARM-Based Mobile Games

Mobilecore on Pocket PC

As your game will be derived from the Core class, a Pocket PC version will only require a Pocket PC specific version of the Core class, with the same interface as the Symbian version. Luckily, this is not a problem.


Compaq's iPaqs are one of many Pocket PC devices.

The biggest "problem" on the Pocket PC is the fact that, just as under Win32, we start out in C. A WinMain function is the entry point of the application. The WinMain will create a window for the application, prepare the device for full-screen graphics output, instantiate and initialize the Core object, and start the event loop and Tick() mechanism.

About this full-screen graphics output: On the Pocket PC this is usually handled by the GX library, which is provided by Microsoft. There are some good alternatives, but I'll stick to GX for the moment.

The problem with GX is that it does not get rid of the title bar of the application: There's an area at the top of the screen that does not respond to stylus presses and where the clock sometimes flickers through. Getting rid of the title bar is quite a task. It tends to return whenever the system updates it, which is often: Alarms, the battery icon, and a few other things all re-display the taskbar. Therefore, quite a bit of effort is put into making sure the thing stays away.

Another problem with GX is that it offers the choice between direct or buffered access to the device frame buffer. As some devices have rotated frame buffers, doing a direct blit is not going to do the job. To make things worse, some iPaqs (the 3800 series) perform terribly unless you write directly to a hard-coded frame buffer address. If you want to know all the specifics, check out the Core implementation for Pocket PC. Otherwise, simply use Mobilecore.

The Pocket PC also implements the FullPath method, since the Pocket PC OS has the same problem as the Symbian OS: no relative paths. Perhaps someone can explain to me why Microsoft left this out?

The rest of the Pocket PC implementation will be familiar to Win32 coders: The WinMain starts to call Tick(), and updates the screen. A message pump and a WndProc handle incoming events such as button presses and stylus movement. These events are then passed to Core so that the game can use them.

You can load the Pocket PC version of Mobilecore into Embedded Visual Tools, which can be downloaded for free from the Microsoft website: http://www.microsoft.com/mobile/. The IDE is the same as used in Visual C++, so you'll feel right at home. You will need to transfer files by hand to your device, or you can build a nice installer package using one of the available tools.

Mobilecore on PC

It's good to have a PC port of the library for obvious reasons: An application can be developed more easily on a PC, because the whole edit-compile-run cycle is much shorter (seconds instead of minutes). Besides that, there are very good debugging tools available for PC. I really like the built-in debugger of Visual Studio 6.0, and without it I'm virtually blind. For the tough-to-find problems and a last-minute leak checking I use BoundsChecker.

Obviously, not all bugs can be found by debugging on a PC. One example: x86 CPUs accept byte read and writes on odd memory addresses, while ARM processors don't allow this. That's not a big deal, but it can cause a crash in code that works perfectly on the desktop machine. Other things that can go wrong are path names: Code compiles just fine if you don't use the FullPath method, but it will not behave as you intended when you try it on a Symbian device or Pocket PC.

But there are more advantages to working on a PC than debugging and faster development. If a programmer can use a PC to test the application, he doesn't need to have full-time access to the actual target device. A key advantage is that the PC can run the application in varying resolutions so that the game's graphics code can easily be tested for all target devices. Finally, graphics output can be captured easily from the PC version. It's even possible to send a PC demo of your game around.

Fortunately, the PC version is a piece of cake, especially since the Pocket PC version is already done. I choose to use a simple bit of GDI code for graphics output. It's not the best performing code you'll see, but as the PC only serves as a development and testing platform, it makes no sense to optimize it any further.

Like the Pocket PC, the PC version starts in C with a WinMain. The WinMain instantiates the Core and passes events using a message pump.

Using Mobilecore

To use Mobilecore for a game project, you simply derive a game class from the Core class, and implement the pure virtual methods (see listing 3).


class MyGame : public Core
{
public:
     MyGame();
     ~MyGame();
     bool Tick();
     void ButtonUp( int a_Key );
     void ButtonDown( int a_Key );
};

Listing 3: Minimal declaration of a derived game class.

That's theory, but reality is a bit more complicated. If your game uses 3D polygonal objects, this is going to do the job just fine, as vector graphics scale perfectly and will run in any resolution. For a demo you don't need controls, so you don't need to worry about stylus input for the P800 (a device that almost completely lacks hardware buttons).

For the average game, you will need to take into account some hardware differences -- most notably the resolution. You can use the Windows version to test your game on various screen sizes. At Overloaded, we found that tile-based games can quite easily be adapted for various resolutions. Often such a game can be left mostly unmodified; the player will simply see less on smaller displays. Some situations in the game may need to be tweaked because of this, but in general, the amount of extra work is limited. When the resolution change is more drastic (we also develop for J2ME devices with very small screens), it may be necessary to have multiple tile and sprite sets.

The "tick" mechanism and the assumption that the game is using a state-driven approach could also limit the usefulness of the library for porting existing applications. Whether or not an existing game can easily be ported to other platforms using Mobilecore depends on whether or not the game can be changed into a state-driven application (if the game is not already working this way, of course).

Now there's one little issue that I didn't mention yet: global variables. Symbian does not support them. As DLLs can be in ROM or RAM on the device, the Symbian OS simply crashes on all write operations to non-static global data. While there are lots of ways to prevent using global data, in some cases it's just very inconvenient. But there is a way around this. Symbian allows you to use one global 32-bit value. It's stored in a memory location pointed to by Dll::Tls() (which stands for "thread local storage"). In this variable, we can store a pointer to a struct or class that contains all the global data that we wish to use. Have a look at listing 4:


struct Globals
{
     Overloaded::Engine* m_Engine;
     CSymbianContainer* m_System;
     Overloaded::MManager* m_MManager;
     Overloaded::TManager* m_TManager;
     Overloaded::Rasterizer* m_Rasterizer;
};
#ifndef __SYMBIAN32__
     extern Globals* DATA;
#else
     #define DATA ((Globals*)Dll::Tls())
#endif

Listing 4: Global data in Symbian.

This is a snippet from the racing game, Fantom Overdrive. As the game uses a custom memory manager for fast allocation and recycling of vertices and other data, I really needed some global data. In listing 4, the Symbian way of accessing global data is DATA->m_Engine, which maps to ((Globals*)Dl::Tls())->m_Engine, while the PC way is more direct.

The same approach can be used for static data members of classes. If class Vertex needs a static Engine pointer s_Engine, just add s_Vertex_Engine to the Globals struct. From there on, instead of using s_Engine, you use DATA->s_Vertex_Engine. Not perfect, but pretty close.

To compensate for the ugly globals hack, I will demonstrate how to use the Symbian device buttons that are not available to all devices. If you look at the class declaration of the Core for Symbian, you will see a list of keys that is different from the list of buttons defined in the CORE.H file. Mobilecore assumes that all devices have four directional buttons--one "fire" button and two other buttons. Some devices have fewer buttons, so your game needs to be prepared for that, as well as the fact that some devices have many more buttons. Devices such as the N-Gage actually have a full numeric keypad, which may come in handy in some situations. If you want to use Symbian-specific code, you can do so by checking for the __SYMBIAN32__ definition. Likewise, you can check for _WIN32_WCE when running on a Pocket PC device.

Adding Functionality

Mobilecore offers games an easy and platform-independent (though currently processor-dependent) way of accessing a frame buffer, the stylus, and hardware buttons. There are some things missing however.

Sound. Implementing a multi-channel audio system requires an accessible audio stream. I have implemented this for Pocket PC, Symbian and PC, and this code will be available shortly.

Communications. Many (if not all) devices support some form of communication. Pocket PCs can use infrared, Bluetooth or wi-fi to communicate with each other; Symbian phones are Bluetooth enabled and are also capable of infrared communications, in addition to GPRS and GSM data transport. In order to build multiplayer games it would be interesting to have some generic way of communicating. Although it's probably too much to go for device-independent communications (playing a game between a 7650 and a Pocket PC over Bluetooth would be awesome!), these days you can't really get away with a game that does not offer some form of multiplayer gaming.

Vibration, backlight, and scroll wheels. Some devices allow direct manipulation of the backlight or the vibration hardware. It would be nice if Mobilecore were enhanced to supported this, so that a game can use these features on devices that support it.

Further Development

I have created a SourceForge project for Mobilecore at the following URL:
http://www.sourceforge.com/projects/mobilecore/

Here you can download the latest version. If you are familiar with one of the "missing platforms," you are more than welcome to join in.

As the current code is only a few weeks old, there is lots of work to be done. I would really like to support more platforms, but the existing platforms will need continuous improvement too. The Pocket PC version could use more diversity (for instance, there are faster libraries for full-screen frame buffer access than Microsoft's GX).

For Symbian, there are other issues: For instance, while the stdio and stdlib functions are available, they are somewhat hidden in the SDK and documentation, and for a good reason: The implementation is not without problems. If you check the code that determines the full path for a given filename, you'll see that I had to code strstr myself to prevent problems. Issues such as these need to be identified and fixed.

I assume that every platform is going to have its list of issues. Therefore I have submitted Mobilecore to SourceForge; I hope that there will be at least one expert for each platform.

Further Reading

If you want to know more about mobile games development, you may want to check out the following links:

Tapwave developer pages:
http://my.tapwave.com/developers/index.asp

Forum Nokia:
http://www.forum.nokia.com/main.html

3D graphics for mobile devices:
http://www.flipcode.com/articles/article_mobilegfx01.shtml

GP32 coding page that makes you want a GP32 badly:
http://www.devrs.com/gp32/

PalmOS developer community at PalmSource:
http://www.palmsource.com/developers/

Peter van Sebille's MAME for Symbian with lots of technical information:
http://www.symbian.com/developer/techlib/papers/mame/mamedream.html#MAME.MAME-029


______________________________________________________

[back to] Introduction


join | contact us | advertise | write | my profile
news | features | companies | jobs | resumes | education | product guide | projects | store



Copyright © 2003 CMP Media LLC

privacy policy
| terms of service