Front Page
Tutorials
Spotifind
Downloads
PicoDrive
Unlocking

Smartphone Game Programming

Tutorial 2: finding your way around the development environment and building real executables

Welcome to the second tutorial. In this part we're going to look at the different parts of the default HelloSmartphone project. We'll also tweak a few bits of it, to start building the front-end to the game. We'll use eVC 4 to write the code - mainly because it has fewer bugs than eVC3 - but we'll build executable files for both Smartphone 2002 and Windows Mobile 2003.

Start up eVC 4, and create a new Hello World project (named tutorial2 if you want an easy life), just as we did in tutorial 1. Note the window on the left hand side of the main window, showing "tutorial2 classes":

This window is a browser which allows you to view the files, resources and classes in your project. Best not to think about that at the moment - click on the "FileView" tab, and expand the "tutorial2 files" node that appears.

Now click on the "ResourceView" tab, and expand the "tutorial2 resources" node. You should be able to see "Data", "Menu", and "String Table".

String Tables

The different kinds of resource that eVC allows are obvious things like bitmaps, less-obvious things like menus, and obscure things such as strings. Open up the "String Table" node and click on the "String Table [English (U.S.)]" item. In the right-hand window you should be able to see three columns - "ID", "Value", and "Caption". What we have here is three simple pieces of text. They have an ID associated with them; when we want to use the pieces of text in the main code, we use the ID, it looks up the text, and prints it (or whatever).

Crazy, eh? I'm not sure why you'd do it this way - you don't have to but the default app does. You could just hard-code the pieces of text in the main code, inside double-quotes, and that's exactly what we'll do later on. It does mean you can change every instance of a string, throughout a program, by changing the String Table once. Either way, since they chose to use a String Table, I guess I get to (try to) explain what it does...!

Updated!

Thanks to Matthew Peddlesden of Atomic Systems who points out that a great reason to use string tables is for internationalisaion:

if you want to make a French version of the application you don’t need to modify the code, you just give it a different resource file full of French strings. It actually makes a huge amount of sense for larger applications, but for the smaller ones or ones where there are no plans to internationalise it’s probably acceptable to skip it and do it by embedding the strings :)

Thanks, Matt!

Menu Bars

Now open up the Menu node, and double-click on the "IDR_HELLO_MENUBAR" item. In the right-hand window, you get a strange vertical box with "OK" at the top. This is the "OK" menu item that you get on the left soft button on the default application. Right-click the "OK" menu item and call up its properties.

The ID of the OK menu item is shown - "IDOK". When we refer to it in the code, that's what we use. The caption, "OK", is what we actually see on-screen. Change it now to "Bye!". It'll prove the point later on when we compile it.

Note the other options here too. If we selected "Pop-up", then this would become the root of a sub-menu. Click it and you'll see what I mean, then click it off again. In the same way you can create Separators and so on too. Unfortunately the Smartphone only supports simple menus, so there are a bunch of things that eVC will let you do, but which will simply make your menus not work when you come to run the application. For instance, you can't have any sub-sub-menus on the left soft button - though you can on the right. You also shouldn't create menus with more than (I think) 10 menu items.

Now that we've finished looking round (most of) the resources, swap to the "FileView" tab int he left-hand window. If you then expand the "Source Files" node, you should be able to see "tutorial2.cpp" and "tutorial2.rc". Tutorial2.cpp is where the guts of the default application live.

I think it's time for a reminder of the disclaimer. As you'll remember from tutorial 1, I'm not trying to teach C or C++. If you want to write high-quality, easily maintained and debugged code, then make sure you make appropriate use of classes, inheritance, multiple source files and version control. There are many books on these subjects! On the other hand, if you just want to hack a game together to get a feel for Smartphone coding, then read on.

So let's have a look at the guts of the default app; double-click the "tutorial2.cpp" file. The system responds by presenting the tutorial2.cpp file in a window; the first line of the code reads:

// tutorial2.cpp : Defines the entry point for the application.

I'm not going to explain every line of the default application, because at this stage it wouldn't be helpful. Instead we'll follow the sequence things run in, so we can see where to inject code that does what we want.

WinMain

Scroll down to near the bottom of the file, where you should be able to see:

int WINAPI WinMain(

HINSTANCE hInstance,

HINSTANCE hPrevInstance,

LPWSTR lpCmdLine,

int nCmdShow

)

This is the entry point for the program, which is to say that when you run it, this is where it starts. WinMain is the name of a function we're declaring. When we run the program, Windows will call this function. Notice that there are four parameters for this function. I don't propose to explain them at this stage...!

Here are the first seven lines of code in the first function of our program, WinMain:

MSG msg;

HWND hwnd = NULL;

BOOL fActivated;

WNDCLASS wc;

HWND hwndMain;

TCHAR szAppTitle[20];

g_hInst = hInstance;

These are variable declarations. We're creating a new variable of type MSG, a new variable of type HWND (which we're setting to null at the same time), and so on. The first part - CAPITALISED - shows the type of variable we're declaring, the second the name of the variable. Also note that in C, lines of code end with a semi-colon, and further note that C is very CaSe-SeNsItIVe, if you didn't already know...!

Window Handles

HWND is of particular significance. It's a handle to a window. What's a handle to a window? Well, one of the first things the application is going to do, is create the window within which we display the "Hello Smartphone" message. When we create that window, we need a way to refer to it later on. That's what makes it a "handle" to the window.

If that didn't make sense, don't worry. All you need to know is that when we create a window, we get an HWND in return, and when we refer to that window later on, we use the same HWND.

So we create an HWND variable now, and we'll use it later to store the handle of the main application window we create.

Just like we have a handle to our window, there's also a handle to the application itself. Again, an odd concept if you haven't come across it before, but it's just a way of referring to the application when we need to. Again, don't worry if it's not clear yet, it will be one day...

Next up:

if(0 == LoadString(g_hInst, IDS_HELLO_TITLE, szAppTitle, ARRAYSIZE(szAppTitle)))

{

return(0);

}

These three lines load the "Hello Smartphone" string, from the String Table resource, into a TCHAR variable we declared earlier on. This is so we can print it on-screen. Told you it was crazy.

Next comes a bunch of lines which "just have to be there". They are there to set up some variables we use when we finally create that all-important window. Indeed, if you scroll down a few lines you should be able to see:

hwndMain = CreateWindow(g_szAppWndClass, szAppTitle,

WS_CLIPCHILDREN, // Setting this to 0 gives a default style we don't want. Use a benign style bit instead.

CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,

NULL, NULL, g_hInst, NULL );

The first thing to note is that we are, obviously, creating the window. The second thing to note is that "hwndMain = CreateWindow...", in other words, hwndMain will be set to equal the return value of CreateWindow. This is how we get the handle to our new window. Told you so.

Notice that CreateWindow takes a large number of parameters. This is not unusual for a Windows Application Programming Interface (API) function. We're asking Windows to create a window for us, and Windows wants to know a lot about what kind of window we want. In particular, one of the parameters the default app uses is "szAppTitle". Just a few lines ago we "crazily" loaded a string into this variable, and now we're passing it into the CreateWindow function call.

Now press F1 to call up "Embedded Visual C++ Version 4.0" help. Use the index to look up CreateWindow.

The help supplied with eVC 4 varies from quite good to superb (and is, I might add, somewhat better than that supplied with eVC 3). The CreateWindow page tells you what each of the parameters are, what they do, and what data type they use. Note that the second parameter is "LPCTSTR lpWindowName". That's what we've "crazily" used szAppTitle for.

Go back to eVC and change the line that reads:

hwndMain = CreateWindow(g_szAppWndClass, szAppTitle,

so that it reads

hwndMain = CreateWindow(g_szAppWndClass, L"gamesforsmartphones.com",

- and do feel free to replace "gamesforsmartphones.com" with the short text string of your choice. Note the strange L"..." syntax. Don't ask me why it works like that. Maybe someone can assist with an explanation?

Updated!

Matt Peddlesden suggests following this link to read up about Unicode and Wide strings, which explains (sort-of) why we use the "L" prefix. I say sort-of because I still don't feel like I understand it properly myself... maybe one day!

Anyway...

if(!hwndMain)

{

return(0);

}

This code just says, if we didn't get a handle to the window after all (maybe Windows is shutting down and refused to create it for us), then shut the program down.

ShowWindow(hwndMain, nCmdShow);

UpdateWindow(hwndMain);

This code pops the new window to the front of the screen, then it forces a screen update so that the screen contents are drawn for the first time.

And finally:

while(GetMessage(&msg, NULL, 0, 0))

{

TranslateMessage (&msg);

DispatchMessage(&msg);

}

return msg.wParam;

Messages

Okay, take a deep breath.

Messages are central to the idea of how Windows works. Whenever "something" happens, a message is generated and sent to the appropriate place. For instance, when you press the left soft button to open a menu on the HelloSmartphone app, Windows sends a message to the HelloSmartphone app indicating that the left soft button has been pressed. HelloSmartphone can then go off and work out what to do in response. Another example - when you tell your phone to shut down, Windows sends messages to all the running programs, telling them to shut down now - or be shut down forcibly!

The specific code above, well, it gets, translates, and dispatches messages. I'm sure someone can tell me what that means, exactly. Suffice it to say that we don't need to mess with this code, but we will encounter messages again later on. Hence the explanation now.

Glad that's out of the way. In the next tutorial we'll look at the code in the HelloSmartphone app which handles the "OK" button - or, as we changed it earlier on, the "bye" button.

Creating Executables

Which reminds me that we haven't actually seen the "bye!" button in action yet. Just as we did in tutorial 1, Build -> Execute tutorial2.exe - having first made sure that the emulator and CPU options are set correctly:

The app should start up, and there should be two things to notice. First, the title bar now shows whatever you put in the L"..." string earlier on. Second, the left soft button is now labelled "Bye!". Told you so!

EXEs for Real Phones

Now we can build a version for real phones. Change the build settings to look like this:

Go to the Build menu, and choose "Build". There's no point choosing "Execute" because it won't now run on the emulator until you change the build settings back. If you get a warning that "The Intel 80486 CPU does not support configuration ... ! Executable will not run on this device. Continue?" dialog, click No. The executable has already been built, by this stage.

If you have a real (and unlocked) Windows Mobile 2003 phone, you can run this executable on it - once you've found it, that is. It's in the "tutorial2\ARMV4Rel" directory of wherever you created the project, and it's called "tutorial2.exe" of course. Copy this file to your phone and run it using a file explorer like Binarys Smart Explorer. You should find works exactly the same.

Now we need to build a Smartphone 2002 version, for those poor souls who don't have a 2003-based phone. First, shut down eVC 4 and the emulator. Now, make a backup copy of the entire "tutorial2" folder, called "tutorial2 for 2002". Go into that folder and find tutorial2.vcw - load this file up, but make sure you load it into eVC version 3!

When we move from version 4 to version 3, it causes some settings to be dropped. So you will get a "project does not contain any configurations supported..." error don't worry, just click OK. Similarly, ignore the error about "commctrl.h", if you get one - just click OK again - and the same for "not all of the windows could be opened".

No configurations - no problem. We just create new ones. Click Build -> Configurations; on the resulting box, click "Add". Leave "CPU" set to "Win32 (WCE ARM)", but change "Copy settings from:" to "*Default Release Configuration". OK the box, then close the "Configurations" box.

You might notice that the build settings, hitherto greyed-out, will now read "Smartphone 2002", "Win32 (WCE ARM Release)", and "Smartphone 2002 emulation". This is a Good Thing!

There's one more setting we have to tweak. Go to Project -> Settings. Change to the "Link" tab and note that "Object/library modules" is set to

commctrl.lib coredll.lib

We need to change this to read:

commctrl.lib coredll.lib aygshell.lib

- this was pre-set for us in the original eVC 4 project but has been lost by importing into eVC 3.

Now it's safe to go to Build -> Build tutorial2.exe. The Emulator will start up, but again by this point the EXE file has been made. You can go and find it in the "tutorial2\ARMRel" directory. Copy it to your Smartphone 2002 phone and it should run. Funnily enough, it will also probably run fine on a Windows Mobile 2003 phone, but it's probably better to use a 2003 version for a 2003 phone.

The End!

And that's it! In the next tutorial we'll start off with a menu with "Start Game" and "Quit" options. We'll hang a dialog box off the Start Game option, as a placeholder for the game itself. We'll also scratch the surface of the all-important Game API (GAPI), and display our first bitmap on-screen.

Help!

Are you having problems with the above tutorial?

First off, try "getting out of the car, then getting back in again" - which is to say, reboot your PC then try again (yeah, I know...). The eVC development tools (both versions 3 and 4) are buggy and prone to errors like "Platform Manager failed" for no (apparent) reason. Many of these problems can be cleared with the aid of a simple reboot.

Having other problems? Why not email me and let me know what the problem is. I certainly can't guarantee I can help, but if I can, I will. If I can't help with a particular problem, I'll put a description of the problem here. Maybe some kind-hearted soul will mail me an answer or suggestion - if they do, I'll put it up alongside the original question.

Questions and Answers

No questions have yet been submitted on this tutorial.

Source Code

There is no source code for this tutorial.

Front Page
Tutorials
Spotifind
Downloads
PicoDrive
Unlocking
Google
 
Web www.gamesforsmartphones.co.uk
www.modaco.com www.msmobiles.com

all content copyright unless otherwise stated

source code may be used freely for any purpose
binaries must not be posted to any other site or distributed on any medium; however you are allowed to download binaries from this site for personal use only