Search
Sponsored Links
Sponsored Reviews
Blog Advertising - Advertise on blogs with SponsoredReviews.com
Affiliate Banner
Hot Topics
Recommended
Links
web hosting
http://www.thetop10bestwebhosting.com/ - top web hosting sites, thetop10bestwebhosting.com

Archive for the ‘Windows Mobile’ Category

Twisted Pixels #4 ? A Button-Mashers Guide to Input

Windows Mobile 6.5 is the next version of Windows Mobile, and there are a few changes to how you program for the Windows Mobile platform. One of these changes was the subject of a recent blog post: Just say no to GAPI – What you need to know about AllKeys and input management.

Since this post is about input, go ahead and read that post, then come back and read the rest of this post about how input works in Windows Mobile, and how easy it can be to code for. 

Note: Just a reminder, this series is currently looking at the unmanaged APIs exposed by Windows Mobile, and how those APIs can be used by game developers.

I was asked a few weeks ago to write a sample application that demonstrated the use of “AllKeys”.  Since AllKeys is such a simple interface, I decided to make the task more challenging by writing an application that would display all key-press information, and would allow the user to see the difference in messages when AllKeys is turned on and when it is turned off.

AllKeysTest3Image

toolbox6_thumb2This program allows you to confirm the behavior of all the keys on your device, which is always helpful.  Different devices have different keys and buttons, and the mapping and behavior of these keys is not always obvious.  I hope it is a useful addition to your toolbox!  You can download the .exe as well as the source at: http://code.msdn.microsoft.com/tpix

Input Management

Input handling in Windows Mobile is not that different from the Windows desktop, and uses the same system of messages, but that does not help you if you have never programmed for Windows. Fortunately, handling input is one of the simpler parts of Windows programming, and the other parts (such as working with controls and child windows) aren’t usually needed for native game development.  There are plenty of references that describe how Windows processes messages, so I will not go into details here (Charles Petzold’s books are a long time favorite of mine – See Programming Windows).

The bottom line is that input is sent to an application in the form of a message, and every Windows program has what is called a message loop to process these and other messages named WndProc. If you are building an application in Visual Studio and use one of the starter Templates such as “Win32 Smart Device Project”, this message loop will be created for you along with other bits of code needed to create a basic Windows Mobile application.  Here is an example:

The Message Loop

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int wmId, wmEvent;
    PAINTSTRUCT ps;
    HDC hdc;

    static SHACTIVATEINFO s_sai;
    switch (message)
    {
        case WM_COMMAND:
            wmId    = LOWORD(wParam);
            wmEvent = HIWORD(wParam);
            // Parse the menu selections:
            switch (wmId)
            {
                case IDM_HELP_ABOUT:
                    DialogBox(g_hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, About);
                    break;
                case IDM_OK:
                    SendMessage (hWnd, WM_CLOSE, 0, 0);               
                    break;
                default:
                    return DefWindowProc(hWnd, message, wParam, lParam);
            }
            break;
        case WM_CREATE:
            SHMENUBARINFO mbi;

            memset(&mbi, 0, sizeof(SHMENUBARINFO));
            mbi.cbSize     = sizeof(SHMENUBARINFO);
            mbi.hwndParent = hWnd;
            mbi.nToolBarId = IDR_MENU;
            mbi.hInstRes   = g_hInst;

            if (!SHCreateMenuBar(&mbi))
            {
                g_hWndMenuBar = NULL;
            }
            else
            {
                g_hWndMenuBar = mbi.hwndMB;
            }

            // Initialize the shell activate info structure
            memset(&s_sai, 0, sizeof (s_sai));
            s_sai.cbSize = sizeof (s_sai);
            break;
        case WM_PAINT:
            hdc = BeginPaint(hWnd, &ps);
            // TODO: Add any drawing code here…
            EndPaint(hWnd, &ps);
            break;
        case WM_DESTROY:
            CommandBar_Destroy(g_hWndMenuBar);
            PostQuitMessage(0);
            break;

        case WM_ACTIVATE:
            // Notify shell of our activate message
            SHHandleWMActivate(hWnd, wParam, lParam, &s_sai, FALSE);
            break;
        case WM_SETTINGCHANGE:
            SHHandleWMSettingChange(hWnd, wParam, lParam, &s_sai);
            break;

        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

This is the default message handler created by Visual Studio in our starter project.  Note that it has no input handlers (yet!).

Many applications have more than one message loop. In fact, message loops are associated with the creation of a window, and so each window can (in theory) have a message loop.  On the other hand, some windows such as dialog boxes use the message loop of their parent for message handling.  You can see an example of that in the code above – look for “case IDM_HELP_ABOUT:” which processes messages from the "About” dialog box.

Key Messages in the Message Loop

Since we are only interested in processing input at the moment, I’ll ignore the rest of these messages and focus only on keyboard and button presses. The messages that we are interested in are:

WM_KEYDOWN:

WM_KEYUP:

WM_SYSKEYDOWN:

WM_SYSKEYUP:

WM_CHAR:

WM_SYSCHAR:

WM_DEADCHAR:

WM_SYSDEADCHAR:

In actual practice, the only messages that Windows Mobile applications are usually interested in are:

WM_KEYDOWN:

WM_KEYUP:

WM_CHAR:

Input is really pretty simple – when a button or key is pressed, WM_Keydown message is sent to the application.  When the key or button is released, WM_Keyup is sent.  You can tell which button has been pressed by looking at the data that is included with the message. 

In order to support different languages with a single hardware device, the OS is able to look at this VK key code and map it to one of many languages (which ever language is installed on your phone).  This translation usually follows the WM_KEYDOWN message, and is called WM_CHAR.  In the data for WM_CHAR, there is a field that contains the actual value of the character pressed.  If your program is compiled to use Unicode, this will be the format of the character. For English devices, the WM_CHAR data is usually the same value as the WM_KEYDOWN value, but this can not be assumed for any other language, and might even change from version to version as language mappings are refined.

Working with Message Data

Message data is received by the message loop in the form of the cryptically named wParam and lParam parameters.  These are two integer parameters that are passed into the message loop at the same time as the message.

Message data varies according to message type.  In the example above, For the WM_COMMAND message, the data is mapped as follows:

            wmId    = LOWORD(wParam);
            wmEvent = HIWORD(wParam);

The message data for the keypress messages listed above includes the virtual key code, which is mapped like this:

            long nVirtKey = wParam;

You can compare the value of the virtual key code with the predefined VK_ identifiers to determine which key was pressed.

Unlike message handling, the reference documentation for virtual key codes on MSDN is quite thorough. See the topic Using Virtual Key Codes, and it’s child topic Virtual Key Codes for the latest, most accurate information.  More general information can be found in the Keyboard section of the documentation.

Character Mapping

In order to support different languages with a single hardware device, the OS is able to look at this VK key code and map it (depending on the language your phone is set to) to a specific character.  This character is then sent to your application as part of a WM_CHAR message.

WM_CHAR usually follows the WM_KEYDOWN message, and is most often followed by the WM_KEYUP message. In the data for WM_CHAR, there is a field that contains the actual, language dependent character value of the key pressed.  If your program is compiled to use Unicode (which is the default), this will be the format of the character. For English devices, the WM_CHAR data is usually the same value as the WM_KEYDOWN value, but this can not be assumed for any other language, and might even change from version to version as language mappings are refined.

Most Windows Mobile applications expect keyboard input to represent text, and so these applications pay attention to the WM_CHAR message, since this represents the value of the keypress in the local language.  For game developers, needs may be different – a button or key may be mapped to a specific game action that has no relation to the local language – W,A,S,D,X may be mapped to direction keys, for example.  In this case, it would be better to respond to the WM_KEYDOWN message, since the VK_ code from that message will be consistent across different languages.

Capturing Button Presses

The non-character buttons (such as the d-pad on many phones) are handled in a similar way, but there is a slight twist.  Many of these buttons are tied to specific tasks in the operating system, and if you press them, the OS may intercept the message and it will never arrive in your application.  Instead, (for example) you may find your application sent to the background as the phone dialer starts up.

There are times when game developers want to have access to these buttons, and if we stay alert and get out of the way when a call comes in, it is ok to ask the OS to send these messages to our own application for processing.  In this way a game programmer can get the messages from the d-pad at the bottom of many devices, and can also get messages from the action button in the center of the d-pad.  For an example of these buttons on a virtual device, look at the emulator image above.

You ask the OS to send your application all button press information is through the API call AllKeysAllKeys (TRUE) tells the OS to send all button presses to the application, and AllKeys (FALSE) resets things so that the OS can do it’s own processing of these keys.

The best way (currently) to learn about AllKeys is to read up on it on this post: Just say no to GAPI – What you need to know about AllKeys and input management, and then download the source to the sample app mentioned in this article – look at the code, and run it on your device and see what happens when you start mashing buttons!

Note: You have to be especially sensitive when programming for a mobile device due to the fact that the device is – first and foremost – a phone, and you need to write code that allows your applications to get out of the way when a phone call comes in.  In fact, that sounds like a good topic for a separate blog article, so lets leave it at that.

just say no to GAPI ? What you need to know about AllKeys and input management.

The Games API (GAPI) was a technology that allowed Windows Mobile 2003 applications to quickly draw graphics onto the device screen. It also contained functions that allowed an application to request all button press messages, even the ones that were normally intercepted by the Windows Mobile operating system.

The graphics component of GAPI was replaced by DirectDraw (which allowed hardware acceleration) in Windows Mobile 5.0. Application compatibility was maintained so that older programs would still work.

Most of the reference material for GAPI was removed from the Windows Mobile 6.1 documentation set, although the input functions were kept, so that applications could still request all key and button presses.  Application compatibility was maintained for this release as well.

This is all changing for the next generation of Windows Mobile, Windows Mobile 6.5.  Although some devices may still support GAPI, there is no longer a requirement for device manufacturers or mobile operators to ship or test for compatibility with GAPI.  This means that applications that require GAPI will provide an unpredictable experience for users on Windows Mobile 6.5 devices.

Another important change is that acceptance to the Windows Marketplace for Mobile and Designed for Windows Mobile certification requires no application dependencies on GAPI.

In order to replace the input functionality that GAPI once provided, a new keyboard API function is being made public.  This function is AllKeys(), and is defined below.  One great thing about this substitution is that AllKeys has been a part of Windows Mobile as long as GAPI, and is actually the API call that GAPI wrapped in order to publicly expose this functionality. This means that the transition to AllKeys should be easy, and backwards compatibility should be maintained.

You can migrate your input code to AllKeys in the following way:

Replace:

·         GXOpenInput() with AllKeys(TRUE).

·         GXCloseInput() with AllKeys(FALSE).

While AllKeys is set to true, all key presses will be sent to your application for handling.

Since GXOpenInput and GXCloseInput were simply wrappers for a call to AllKeys, so this substitution should cause no change in behavior in your programs.

The following is the definition of the new AllKeys API.

AllKeys

This function allows your programs to request that all key presses be sent directly to the requesting application. Normally some buttons are intercepted by the operating system for its own use, but games and input – intensive applications may want access to these buttons for their own use.

Syntax

BOOL AllKeys(

     BOOL bAllKeys

);

Parameters

Parameter

Description

bAllKeys

[in] If bAllKeys is set to TRUE, this function allows all keyboard events to be sent to the application. (This includes the soft-key buttons and back button).

If it is set to FALSE, this function specifies standard keyboard event behavior. Some events including soft-key buttons and the back button are not sent to the application.

Return Value

Nonzero indicates success. Zero indicates failure. To get extended error information, call GetLastError.

Sample Code

The following C++ code illustrates how to use AllKeys. In the application that this sample is taken from, a check box is used to set AllKeys to true or false.

// process checkbox

case IDC_ALL_KEYS_CHECK_BOX:

if (g_AllKeys == true)

    {

    // Allow the OS to intercept some button presses

     AllKeys(FALSE);

    g_AllKeys = false;

    // set button state

    SendMessage(hwndCtl,BM_SETCHECK, BST_UNCHECKED,0);

    }

else

    {

    // Do not allow os to intercept button presses

    AllKeys(TRUE);

    g_AllKeys = true;

    //set button state

    SendMessage(hwndCtl,BM_SETCHECK, BST_CHECKED,0);

    }

Requirements

OS Versions: Windows Mobile 2003 and later.

Header: Winuser.h.

Twisted Pixels #3 ? Memory Mysteries

Previous post: Twisted Pixels #2: Doing Graphics! 

What’s going on?

To recap – I have a program that works in the emulator, but does not run on real hardware.  The question is why.

After reading the following memory model posts:

Slaying the Virtual Memory Monster (http://blogs.msdn.com/hegenderfer/archive/2007/08/31/slaying-the-virtual-memory-monster.aspx)

Slaying the Virtual Memory Monster – Part II (http://blogs.msdn.com/hegenderfer/archive/2007/10/01/slaying-the-virtual-memory-monster-part-ii.aspx)

Visualizing the Windows Mobile Virtual Memory Monster (http://www.codeproject.com/KB/mobile/VirtualMemory.aspx)

I strongly suspect that the problem I reported in my last post is memory related. The Donuts2 sample code tests to see if the proper interfaces are implemented in the device drivers, and everything seems ok there. The failure comes during the allocation of memory for a DirectDraw surface, which makes sense for a memory problem.  One other thing – after I posted the last article, I found a device that does run the application, and it has fewer applications pre-installed, and no UI shell.

Windows Mobile 6.1 inherits the memory architecture of Windows CE 5.0, and this model was originally designed when a small footprint was very important. Because of this, Windows Mobile has only 32 MB of virtual memory space for your application to occupy. It does not matter how much memory is built into your device, you can only use that memory in 32 bit slots. There are additional issues that further reduce the amount of available memory, and these are well described in the posts mentioned above, so I will not go into detail here.

Note: This memory limitation has been removed from Windows Embedded 6.0, and we can hope that this change will find its way into a future version of Windows Mobile.

You can’t debug what you can’t test, and there are two tools that let us examine virtual memory conditions on Windows Mobile:

  • DumpMem.exe, which can be downloaded at: http://support.microsoft.com/kb/326164/ . This is an old tool that allows you to create a detailed text dump of the contents of all virtual memory on your device. Part II of Slaying the Virtual Memory Monster gives great detail on how to use this tool.
  • VirtualMemory.exe, which is published on The Code Project in the project “Visualizing the Windows Mobile Virtual Memory Monster“. The link to this project is given above. This is a visual tool that is much easier to use, although it may lack the detail that you need to investigate particularly thorny problems.

toolbox6  I do like the memory visualization tool VirtualMemory.exe included in the page Visualizing the Windows Mobile Virtual Memory Monster (Link above), and have added it to my debugging toolbox, although I can’t use it today. Another invaluable tool allows the creation of screen shots on the device. Although there are several free utilities available, the one I found to work the best was SPB’s “SPB Screenshot” utility, which can be downloaded from the publisher at:

http://www.spbclub.com/forum/viewtopic.php?t=12483

That’s another one for the toolbox.

Because Donuts2.exe runs full screen, and captures all input, I was unable to run either of these memory profiling applications to test my theory. At this point, I could have instrumented the sample to log memory conditions to a file (or perhaps to execute DumpMem), but that is time consuming, and I don’t really care enough about this one example to try. If this was a production application, it would be well worth while to study the information on memory model, and test till there were no questions left. I do have some simple questions that I would like to answer, and I’ll try to do that in a later post.

Although I’ve failed to slay the monster, I think I understand it a bit better than I did before. It seems strange that a sample in the current SDK would fail like this – Perhaps some other phones have fewer apps installed than my stock Diamond. I was able to borrow a few other devices and started testing performance on other devices.

No luck with my old HTC Hermes, and no luck on a Samsung I780. No luck with a couple of other older phones. I was about to give up when a friend dropped by my office to show off a new ASUS P835 running Windows Mobile 6.1. Just for fun we tried it – and it worked. SPBScreenshot does not seem to work with DirectX apps, so you will have to take my word for it, but performance was good, and the app conformed to the large high resolution screen, and the seemed responsive, with a reasonable frame rate.

Out of curiosity I ran VirtualMemory on some of the phones and on the emulator just to get an idea of what can be expected and to look at variance between different phones. DLL space goes from the top of the screen to the bottom.  Program space goes from the bottom to the top.  As I understand it, the limiting factor is the lowest DLL loaded into memory.

Emulator memory map

Figure 1. Emulator memory map (Windows Mobile 6.1)

Diamond memory map

Figure 2. HTC Diamond memory map (Windows Mobile 6.1)

It is clear that the HTC has more DLL memory pre-allocated, which is likely interfering with my application. That’s the price that a user has to pay to have an awesome interface like TouchFLO.

So – the lesson learned today is that available memory varies from phone to phone, and there can be issues that show up on some phones and not on others. It is always good coding practice to check for failure every time you allocate memory, and that becomes particularly important here. One of the challenges of writing games for the mobile platform is dealing with resource issues, and this will remain an issue for the developer of Windows Mobile 6 software.

Next up – Getting Input.

Windows Mobile Blog: Moving Day

As of today the Windows Mobile Blog has moved and officially joined the Windows Blog. There are now two options for subscribing to our content.

Windows Mobile Blog | RSS
Our mobile insiders and technical experts will post content directly to the new Windows Mobile Blog. These posts will also bubble up to the higher level Windows Blog.

Windows Blog | RSS
In addition to our mobile content, you can also read Windows desktop blogs by subscribing to this broad feed.

Feel free to subscribe to both! We look forward to hearing from you on the new site!

Tags: , , , , , , ,

Windows Mobile Blog: Coming Soon!

<html>Hello World</html>

We’re moving our blog here to join our friends in Windows.

See you in July!

Tags: , , , , ,
Sponsored Links
Recent Visitors