Glorious were the days when we programmed our games in a mostly linear fashion. We didn’t have to worry about multitasking, DirectX or message pumps. We just programmed games.
It was a very big jump to port our creations to DirectX, but that was the way that the market was leading. Most importantly, you could achieve a performance that could only have been dreamed without the hardware acceleration and tuning that the DirectX team provided.
But there was this big problem: the Windows Message Pump. It is simply not adequate for game programming. In this article I propose to present an effective way to encapsulate the message pump, provide a linear programming model and, as a very desirable side effect, allow correct ALT-TAB application switching.
The Message Pump
The Windows operating systems demands that our application constantly check for inbound messages for all our members (windows, buttons, listboxes, or whatever). The Windows Messaging System is the heart of the cooperative model that the Microsoft team adopted. We can’t just simply forget about the message pump, because it informs us of important things like ‘You’ve been deactivated’, and ‘You’ve been reactivated’, among many others. A typical Windows application has the following basic layout:
All the application’s operativity is defined in the member’s methods, and in fact, it’s a very comfortable programming model to make simple windows applications. But it’s simply not very adequate for games.
The most used technique to start making games under Windows is to replace the GetMessage() function, which blocks the execution thread, with a couple of functions. PeekMessage() will check if any messages are waiting, and the PM_NOREMOVE parameter tells the function not to remove the message from the queue. If this function returns true, the GetMessage() function can then be used to retrieve the message. Otherwise, if no message is to be processed, we can call our UpdateWorld() function, that will be in charge of updating all the world variables and rendering the new scene. The following code shows this:
This basic Message Pump can be optimized by inserting a flag that indicates whether the game is active (i.e. not minimized), and, if we are not active, instead of updating the world, we call the WaitMessage() function, which will set the application in an idle state until a new message arrives.