Language :
 

TinyXML and std::wstring

April 22nd, 2009

Level management (and content) is easily done with XML files. On Windows Mobile, we can use MSXML which is part of the system. However, it sounds like it is slow to work with. Many people advise to use lightweight, non-validating parser. So I chose TinyXML.

However, everything related to the filesystem on WM is based on std::wstring. And TinyXML, even in it’s “USE_STL” implementation, only support std::string and char*. So I thought that before falling back to MSXML, I could try to convert TinyXML to std::wstring.

First, I searched and replaced everything => 

char* to WCHAR*

std::string to std::wstring

All methods ( such as atoi ) converted to their wide char equivalent (… _wtoi)

oh… and all these “String” to L”String” :)

Everything went pretty smoothly, and I was able to get it to compile. However, nothing was working. Here’s the 2 problems that needed to be solved :

1) My XML file was saved as a standard ASCII file, not containing wide chars. I used UltraEdit’s convert to unicode function, and this solved the problem. I could see in the debugger that the file content was all right. Still, it could not be processed.

2) TinyXML is “aware” of Microsoft’s UTF-8 headers – 3 bytes at the beginning of the file. But it does not check for UTF16 signature. I simply added a check for “FEFF”, at the same spot where the UTF-8 check is done, and this solved it.

I can not guarantee everything works, but all the functionality I needed, navigating through nodes and gettings values, work perfectly fine !

Current Directory on Windows Mobile

April 16th, 2009

So it seems there is no “Current Directory” on windows mobile. If you open a file like this : 

fopen(“MyFile.xml”, … )

it will look for it at the root of the pocket pc. While it can be sufficient for testing, you don’t want to mess up this directory with files related to your application.

What you can do, is retrieve the pathname of the module ( application ) that is currently running : 

 

WCHAR lPath[256];

GetModuleFileName(NULL, lPath, 255);

std::wstring lPathWStr(lPath);

lPathWStr = lPathWStr.substr(0, lPathWStr.find_last_of(‘\\’)).append(L”\\MyFile.xml”);

 

This way, you can navigate to the folder where your application is stored, and add your data files in there, where they belong.

Also something interesting, to move configuration, or additional data files to your Emulator, you can setup a shared folder. In  your emulator : File => Configure => General Tab

All files drag&dropped in this folder ( on your computer ) will appear in the “Storage Card” of your Emulator, and you can move them around with the file explorer.

VSync not really working on Axim X51v

April 16th, 2009

Some time ago, when I started the development of my application, I remember having an issue with the Diamond. If I let the screen refresh as fast as possible, I experience a strange flickering on a random part of the screen. Never the whole screen, but a spot large enough to be annoying. After much time spent, I found out that adding a sleep(8) after the hardware page flip fixes the issue.  By the way, “8″ is the least amount of time spent to make the flickering disappear.

Does this mean that I can’t start drawing in my backbuffer straight after it has been flipped ? I should give some time to the hardware for the flipping, and then go ahead with my business ?

Since the diamond now uses hardware page flipping, I realized that it’s performance dropped (!) This is obviously due to the sleep(8). What if I remove it ?

6-7 fps improvement on the Diamond

8-9 fps improvement on the Axim, but flicker is back

Now, does this only happen on the Axim ? Maybe it’s a flaw in the hardware ? Or maybe it only concerns my own ROM.

And what would be the fix ? Should I assume that only the Axim is impacted, and I can put in a special case for it, or should I add some options to let the user tweak it himself ?

Hardware page flip… or not ?

April 16th, 2009

Always more issues coming in. When I check the device caps of the diamond, I know that it is able of handling hardware flips, and a backbuffer. When I call DirectDraw’s CreateSurface, I receive an E_OUT_OF_MEMORY error. How nice is that ? So I implemented a fallback mechanism, doing a manual copy to simulate the page flip. It worked out nicely.

However, since I can’t stop playing with my device, I have installed a newer rom, from http://www.xda-developers.com.  Somehow, the device is now initialized correctly using hardware page flipping. Was it a bug in Windows Mobile, and the newer build fixed it ? Was it a bug in the device driver ? I probably will never know…

Fun with GetAsyncKeyState() and the Emulator

April 14th, 2009

This is something that made me waste enough time that I can spend a few more minutes to write about it.

I have been trapping key usage with the GetAsyncKeyState() method. Quite handy. But somehow, I have been unable to catch the “action” button of the D-Pad within the emulator. Just an annoyance, as I can map another key, and it works fine on my two devices ( Dell Axim and HTC Diamond ). But what if another device shows the same issues ?

So I looked around… I tried many things, such as GAPI ( GXOpenInput() ) as I thought maybe the key was being trapped. I tried to setup some hotkeys, … nothing would do. The sample I had started coding from did not implement the basic WM_KEYDOWN handling routine. Of course, as it was replaced by GetAsyncKeyState(). I made sure to trap this message, and miracle, I was able to catch this button.

Now, I am unsure how nice it is to have 2 separate bits of codes doing basically the same thing. Also, I guess I will need to make sure some actions are not done twice. But this is the only way I could trap the middle D-Pad button on the emulator. All else has failed.

Low performance issue solved!

April 6th, 2009

I’m in the early stage of my project. Currently, I have a very basic collision handling mechanism, and I’m blitting a “few” sprites to screen. On the emulator, everything seems to work fine. However, when I transfer the software to an actual device, either the Touch Diamond or the Axim X51v, two devices with good specs, I received the following FPS :

Axim : 11FPS

Touch : 21FPS

These low values are really annoying, especially that I intend to add way more “features” to my game, meaning that these values will go down ! So I had to find out quickly why the performance was so low.

I probably should’ve used a profiler, but somehow, I just commented out of the program some parts of the code. Taking out the collision handling logic did not even give me a single added FPS. So it was definitely with the blitting. Removing most objects ( about 100 of them ), gave me a very decent increase. Now what’s a game if you can’t see what’s going on ? :)

So I tried something else. It seems that it is not the number of pixels written that takes time, but the number of calls to the blit engine. Since most of the time, the objects shown do not change, I blit everything once in an offscreen surface. I draw the modifications on that surface, and I finally blit the whole updated surface on the screen. The same amount of pixels are transfered, but with less than 10 calls to ->blt(), instead of more than a hundred before.

Axim : 40fps ( but very smooth display, due to the usage of hardware page flipping )

Touch : 47fps

Clearly, that did the trick. I guess that we need to think a little when using these devices, which makes developing for them much more fun :)

Backbuffer on the Touch Diamond ???

April 4th, 2009

So I’ve decided to go with DirectDraw as the basis for the graphics in my game. It’s pretty straigthforward to initialize, and there’s quite a few tutorials on it. Well, not that many related to Windows Mobile but still…

I have used a tutorial – Ski Time Mobile – to get myself started. It’s aimed for non-touchscreen devices, with a rather small screen. Anyhow, the initialization routine they use for DirectDraw works fine on the emulator, and on my Axim. But on the Touch Diamond…

The following code is used to determine device capabilities :

    // True if backbuffers and flipping are supported by hardware
    m_bPageFlipping = CheckSurfaceCaps(DDSCAPS_BACKBUFFER | DDSCAPS_FLIP);

I receive true for both the Axim and the Touch, but on this following call :

        ZeroMemory(&ddsdPrim, sizeof(ddsdPrim));
        ddsdPrim.dwSize            = sizeof(ddsdPrim);
        ddsdPrim.dwFlags           = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
        ddsdPrim.ddsCaps.dwCaps    = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP;
        ddsdPrim.dwBackBufferCount = 1;
        HRESULT lHR;

        // Create Primary Surface
        if (FAILED(lHR = m_pDD->CreateSurface(&ddsdPrim, &m_pDDPrimaryBuffer, 0)))
        {   
            m_bPageFlipping = false;
        }

The creation of the Primary Surface fails, only on the Touch. I can’t remember the error, I’d need to check. Anyway, I thought that I would implement some fallback mechanism. If this call fails, we’re back to flipping our buffers manually.

What scares me is… how many of these weird results would I experience if I had more devices ? Welcome to Windows Mobile I guess :)

Windows Mobile – Game Development

April 4th, 2009

I’ve started developing a game for my windows mobile game, quite a while ago – almost one year to be correct. The number of problems I have encountered is huge. I will use this blog to write down my findings.

I own two windows mobile devices. An Axim X51v from Dell (PDA), and a Touch Diamond from HTC (Phone). Both devices have a screen resolution of 640×480, which gives pretty awesome graphics on such small screens.

Hopefully, I can manage to release a full game someday, before the marketplace goes live :)