Archived

This topic is now archived and is closed to further replies.

Endemoniada

Thread or Message Pump ?

Recommended Posts

Hi guys, I''m almost done with my arcade game and so far I''ve been using the Windows message loop to call my game heartbeat function. I have a tight optimized loop and it works well but not great. When a program is running in the background (like Media Player) I sometimes get jerky movement (I base the movement on the elapsed time of the frame) and it even hangs occasionally when no programs are running, after a fresh reset. Should I start a seperate thread to run the game ? How do the professional games do it ? Also, I''m using DirectInput for the mouse but handle WM_ONKEYDOWN messages for the keyboard, I''m going to switch to DirectInput for the keyboard also so I don''t need the Windows message pump for anything. I''m using the DirectX 9.0a SDK with VC++. I''m sorry if this has already been discussed. Thanks.

Share this post


Link to post
Share on other sites
There is no reason for starting another thread. It''s weird how so many people think of threads as a magic cure-all.

You must keep the windows loop because it handles important messages behind the scenes. Don''t use WM_TIMER. Some people say "don''t use WM_PAINT", but I haven''t seen a difference.

"Professional" games vary in implementation but here is one way.

/// This function waits for messages and dispatches them. It does not return until a WM_QUIT message is received. If

/// an idle function is supplied, the idle function is called rather than waiting for a message when there are none

/// to be processed.

///

/// @param hWnd Window handle

/// @param pCB The address of the idle function to be called when there are no messages to process, or 0.


int MessageLoop( HWND hWnd, MessageLoopIdleCallback pCB/* = 0*/ )
{
bool skipIdle = false;

while ( true )
{
MSG msg;

// If there is no idle function, or the idle function no longer needs to be called, or there is a message

// waiting, get (or wait for) the next message and process it. Otherwise, call the idle function.


if ( pCB == 0 || skipIdle || PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) )
{
if ( GetMessage( &msg, NULL, 0, 0 ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
{
return msg.wParam;
}

skipIdle = false; // Allow the idle function to be called again.

}
else
{
// Call the idle function. If it returns false, it no longer needs to be called -- set ''skipIdle'' so it

// won''t be called again until after another message is processed.


skipIdle = !pCB( hWnd );
}
}
}

Share this post


Link to post
Share on other sites