Jump to content
  • Advertisement
Sign in to follow this  
tom_mai78101

How do you make a program start idling after finish rendering DirectX sprites?

This topic is 2604 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Here's the Windows Procedure:


[source lang="cpp"]

MSG msg_struct;
ZeroMemory(&msg_struct, sizeof(MSG));
while (msg_struct.message != WM_QUIT)
{
??if (GetMessage(&msg_struct, NULL, NULL, NULL)) //PeekMessage(&msg_struct, NULL, NULL, NULL, PM_REMOVE)
??{
????TranslateMessage(&msg_struct);
????DispatchMessage(&msg_struct);
??}
??else
??{
????UpdateWindow(Core::global_hWnd);
????if (!Core::RunDirect3DStuffs(Core::global_hWnd))
??????return 1;
??}
}

[/source]

The commented part means that anytime I switch the GetMessage() with PeekMessage() and vice versa, I always see my program hangs upon initial startup, then the mouse cursor keeps playing the "Busy..." idle animation. (The blue circle in Windows 7/Vista, or the hourglass animation in Windows XP.)

Until my mouse leaves the window, it will not change back to "Idle" arrow. (The normal pointing-to-the-upper-left arrow.) I'm curious to know how do developers get rid of this minor problem? What is the solution?

Thanks in advance.

Share this post


Link to post
Share on other sites
Advertisement
Maybe try the following variant (based on the loop provided at http://www.mvps.org/directx/articles/writing_the_game_loop.htm):
MSG msg_struct;
// prime the message structure
PeekMessage(&msg_struct, NULL, 0, 0, PM_NOREMOVE);
while (msg_struct.message != WM_QUIT)
{
if (PeekMessage(&msg_struct, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg_struct);
DispatchMessage(&msg_struct);
}
else // you may not want the below to be an else condition - this depends on your own program so try both ways and see which works the way you want
{
// http://msdn.microsoft.com/en-us/library/dd145167%28v=vs.85%29.aspx
// don't mix D3D stuff with WM_PAINT - it's evil
// UpdateWindow(Core::global_hWnd);
if (!Core::RunDirect3DStuffs(Core::global_hWnd))
return 1;
}
}

Share this post


Link to post
Share on other sites
Then it's the same thing. It's just like adding a do...while to the current while loop.

Would throttling increase the chance that my program can idle, which is what I really wanted? When it's idling, my mouse would then return to normal cursor animation, instead of hanging there.

Share this post


Link to post
Share on other sites
It would appear the main change to make is to use while( PeekMessage(...) ) instead of if( PeekMessage(...) ).

Something like:

while( running )
{
while( PeekMessage(...) )
{
if( message==WM_QUIT ) //.. exit the procedure. e.g., return( some_code )
Translate...
Dispatch...
}
if( DoD3DStuff(...) ) DoStuff(...);
}

It's more common in a run loop ( that's not a Window Procedure, by the way.. that's different ) to process all the windows messages that are in the queue each time through the loop before you update the window.

Share this post


Link to post
Share on other sites

It would appear the main change to make is to use while( PeekMessage(...) ) instead of if( PeekMessage(...) ).
It's more common in a run loop ( that's not a Window Procedure, by the way.. that's different ) to process all the windows messages that are in the queue each time through the loop before you update the window.


Then under what conditions would the message queue becomes empty and my program then automatiically becomes idle?

Because I see that, even though my message queue is empty, the program is too busy checking if the message queue is still empty (accordingly to the while(PeekMessage()) second loop.) or not.

In short, how do people make the program idle when the game loads and boots up the main menu? Right when it finishes the main menu rendering, the mouse would be normal (i.e. Not running the "Busy..." animation).

Share this post


Link to post
Share on other sites
GetMessage() is a blocking function - it won't return until there is a message posted and only returns false on WM_QUIT, so the loop you initially posted will only enter the else block once, just before the program exits.

The loop Buckeye posted is the conventional way to do a Win32 game loop.

Share this post


Link to post
Share on other sites

[quote name='Buckeye' timestamp='1304726195' post='4807538']
It would appear the main change to make is to use while( PeekMessage(...) ) instead of if( PeekMessage(...) ).
It's more common in a run loop ( that's not a Window Procedure, by the way.. that's different ) to process all the windows messages that are in the queue each time through the loop before you update the window.


Then under what conditions would the message queue becomes empty and my program then automatiically becomes idle?

Because I see that, even though my message queue is empty, the program is too busy checking if the message queue is still empty (accordingly to the while(PeekMessage()) second loop.) or not.

In short, how do people make the program idle when the game loads and boots up the main menu? Right when it finishes the main menu rendering, the mouse would be normal (i.e. Not running the "Busy..." animation).
[/quote]
The message loop becomes empty when all the messages have been processed. Once you're into the game loop, the queue will be empty most of the time. PeekMessage returns FALSE when there's no message and you'll move on to if( DoStuff ).

Share this post


Link to post
Share on other sites
Note, that the loop with the if also reads all the messages. Because the Update function is in the else block.

I just wanted to note that. It seems that everyone is so carried away with the while thing, that no one notices that the if-else block does the same in this case (there are cases when not (I cannot think of any at the moment), and I use while too)

Share this post


Link to post
Share on other sites

Note, that the loop with the if also reads all the messages. Because the Update function is in the else block.

I just wanted to note that. It seems that everyone is so carried away with the while thing, that no one notices that the if-else block does the same in this case (there are cases when not (I cannot think of any at the moment), and I use while too)

You make a good point, szecs, only if PeekMessage is used, not GetMessage. GetMessage always returns non-zero unless the message is WM_QUIT, making the if( GetMessage() )... else alternate-routine construct ( OP ) valueless.

Share this post


Link to post
Share on other sites
Is that code part of your window procedure or your message pump (maybe message pump isn't the correct terminology, but it's what I've always called it)? Because, as Buckeye said, it isn't a window procedure and if you use it as one things will not work as expected. Here is a small example of how a (minimal) window procedure and a message pump could look (untested):


//Use this window procedure when creating the window
LRESULT WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
return DefWindowProc(hWnd, msg, wParam, lParam);
}

void MessagePump()
{
MSG msg;
while (PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}

void MainLoop()
{
while (running)
{
MessagePump();
//Do everything else one would like to do in a frame
}
}


In the above code you probably would want to detect relevant messages, such as the window being closed, etc.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!