The best way to show the capabilities of the respective devices is to show them side-by-side. Here is a table showing the capabilities of the most popular PocketPC devices on the market. Also shown are a couple of popular Palm devices for comparison.
As you can see, the PocketPC machines are all more expensive than the Palms, but the capabilities of the PocketPC's are disproportionately greater. Numbers, though, can only give you part of the story. Here's a comparison of some of the best of the PocketPC offerings compared with the best color Palm titles.
How Do You Program for PocketPC?
Well, you're in luck. Not only are there some very capable developer tools for PocketPC, they're available for a song. You can purchase Microsoft's eMbedded Visual Tools 3.0 CD from Microsoft for only the cost of shipping and handling. The package includes eMbedded Visual C++, eMbedded Visual Basic, and emulators for the platforms mentioned above.
The tools are very mature and robust. In fact, they're almost identical to their Windows-only brethren, Visual C++ 6.0 and Visual Basic 6.0. The biggest difference is that they do not generate native x86 Windows applications. The C++ compiler cross-compiles to the aforementioned processors, while eMbedded Visual Basic produces files that are interpreted by a VBScript-style interpreter on the target device.
Let's dispense early on with Visual Basic for games, though. Since eMbedded Visual Basic produces programs that are interpreted by the PocketPC's rather rudimentary VBScript interpreter, eMbedded Visual Basic isn't really suitable for games. If you need a form-based data-collector or something to perform field calculations for you, it's ideal. For games, though, it's just not there. Let's concentrate on the eMbedded Visual C++.
How the compiler works
There are two ways to develop an app for PocketPC, and you will very likely be using both methods interchangably.
The first is by compiling your game for a connected device, then uploading, running, and debugging the game over the connection (usually serial). While this sounds complicated, it's actually quite simple. eMbedded Visual C++ works through MS's ActiveSync software, which is the software used to connect your PocketPC to your computer to exchange data with your address book and calendar. If your PocketPC is connected via ActiveSync, you've done all that's necessary to develop for your device. Simply choose the processor that your device has and press the "make" button just as if you were making a standard Windows application. The file will be compiled, linked, and sent over to the device. Press the "run" button, and your app will pop up on the device's screen. Set a breakpoint in your code, and the code will stop when it gets to that point. Examine a variable in memory, and Visual C++ will get the value and show it to you on your main screen. Neat, huh?
As you may have already figured out, though, there is one chief disadvantage to this approach -- speed. While compiling the file and sending it over to the device happens at a reasonable speed, debugging is downright glacial. The device and eMbedded Visual C++ are constantly having to update each other as to the status of your running program. You'll probably want to save debugging on the device as a last resort to fix bugs that don't show up under the next method -- compiling for the PocketPC emulator.
The second method is to develop for the on-screen PocketPC emulator. Calling it an emulator, though, is a bit of a misnomer. Rather than make processor-emulators for the various processors out there, MS simply built a version of Windows CE that runs on an x86 processor. To compile for the emulator, you set the target processor as the x86 CE Emulator, press the "make" button, and eMbedded Visual C++ will generate a Windows CE app that runs on the x86 processor. Pressing the "run" button will then run your app in the on-screen Windows CE emulator.
The principal advantage to this approach is speed. Speed speed speed. Using the on-screen emulator, you can run an application under the debugger and it will run just as quickly as if you were debugging a native Windows application. Copying the app to the on-screen emulator and running is almost instantaneous. Developing an app for the on-screen emulator will make you feel right at home if you're used to developing standard Windows apps under Visual C++ 6.0.
There are plenty of disadvantages, though, to this approach. For one, you're compiling for a processor that simply doesn't exist in the PocketPC world. If a particular device has some picadillos germaine to its processor, you won't see them when it runs on the emulator. Also, the emulator takes on the capabilities of the compiling machine, so you'll likely be developing your app on a 24-bit screen even though there are no PocketPC's with 24-bit screens. Furthermore, your emulated app will likely be running much faster emulated than on the device, so you won't get a good feel for how your game plays if you develop solely for the emulator. Finally, the emulator only runs on Windows NT or Windows 2000 for reasons that will be clear later. If you have Windows 95/98/ME, you're stuck with developing on the connected device.
Most PocketPC developers quickly find that they need to work between the two different methods to develop a PocketPC game. For the bulk of development, the on-screen emulator is the way to go. It's a great way to get your app up and running quickly, and debugging is a breeze. From time to time, though, you'll need to compile on the device so you can ensure that the graphics look right, the game is playing at a reasonable speed, and no bugs are creeping in that aren't showing up on the emulator. Thankfully, switching between one approach and another is as simple as choosing the target processor on the toolbar and recompiling.
The PocketPC API
If this all looks great, and you're chomping at the bit to convert your large-scale DirectDraw-based isometric RPG title to the PocketPC, there's something you need to know.
The PocketPC API is different from the Win32 API
Sorry to throw a bucket of cold water on your plans, but if you have grand designs on simply recompiling your code and having it work, it's not going to happen that easily. A significant chunk of the Win32 API functions (around 90% of 'em, actually) aren't there.
Hey, where's GlobalAlloc?
Operating systems are evolutionary things. Every year a new version comes out with new capabilities, some of which supercede existing capabilities. The OS makers, though, often must leave antiquated function calls in place to keep from breaking old apps. Since there weren't going to be any old CE apps, the designers went through the Win32 API with a fine-toothed comb to prune it down to its bare essentials -- a library that would still allow you to create powerful apps, but without supporting a lot of antiquated function calls. Hence, if you're looking for AddAtom() or GetWindowWord(), you won't find them.
After dumping the dead wood, the designers went through the list of similar, yet redundant functions. For the most part, if there existed several functions that did a similar job, they just kept the one or two that could best cover the capabilities of the rest. Hence, MoveTo() and LineTo() are gone, but PolyLine() is still there. CreateFont() is gone, but CreateFontIndirect() is still there. DrawText() was better than TextOut(), so DrawText() got to stay. You get the idea. Just be prepared, when developing a PocketPC app, to hunt for updated versions of some of your favorite API functions.
You can ignore Unicode no longer
Something else you're going to have to get used to is text-handling. Since Unicode is the way of the world, and supporting both ANSI and Unicode would take up more space than necessary, ANSI strings got the boot. All of the PocketPC functions that take strings are expecting Unicode strings. So don't type:
MessageBox (hWnd, "This is my first CE app", "Hello World", MB_OK);
You'll just upset your compiler. What it wants to see is:
MessageBox (hWnd, TEXT("This is my first CE app"), TEXT("Hello World"), MB_OK);
The TEXT-macro simply converts a string at compile-time to unicode format. This goes for every hard-coded string in your application, from window-class-names to filenames you pass to the file-handling commands. There are Unicode equivalents for all of your favorite string-handling functions, so don't get too upset. Just kiss the venerable old char * goodbye.
Direct3D, DirectDraw, DirectInput, DirectPlay, and OpenGL
PocketPC doesn't support them. In fact, the API functions that aren't part of the Kernel, Window, and GDI modules of Windows probably aren't there. While some extensions like Winsock are still around (supporting IR communication, cool eh?), many of the latter-day add-ons to Windows are nowhere to be found.
Don't dispair, though. There a couple of game-related technologies available that will help you ease the pain of working for the platform.