Jump to content
  • Advertisement

Archived

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

theNestruo

Win32 message loop and game loop

This topic is 5711 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

Hi... I'm doing an OpenGL game, but I think my main loop is very very confusing (altough it works). It's something like this:
    
int WINAPI WinMain (BLAH blah, BLAH blah, BLAH blah, BLAH blah) {

  // Register a class, create a window


  // Create a rendering context into the window


  // Initialize the game logic


  // Main loop

  for (;;) {

    // If the application is active, then ...

    if (isAppActive) {
      // If there're any message, then ...

      if (PeekMessage (&msg, hWnd, 0, 0, PM_REMOVE)) {
        if (msg.message==WM_QUIT)
          break;
        TranslateMessage (&msg);
        DispatchMessage  (&msg);
      }
      // Update the game

      UpdateGame ();
      RenderScene ();

    // If the application isn't active, then ...

    } else {
      // Wait for a message

      switch (GetMessage (&msg, hWnd, 0, 0)) {
        // WM_QUIT received

        case 0:
          goto out;
        // GetMessage failed

        case -1:
          // Show an error message

          return 1;
      }
      TranslateMessage (&msg);
      DispatchMessage  (&msg);
    }
  }

out:

  // Terminate the game


  // Destroy the rendering context


  return (msg.wParam);
}
    
Can someone show me a better way to do it, please? Thanks in advance. theNestruo Syntax error in 2410 Ok [edited by - theNestruo on April 20, 2003 1:02:38 PM]

Share this post


Link to post
Share on other sites
Advertisement
Your basic structure is OK. The only reservation I have is the fact that you are using gotos. You should minimise your jumps for efficiency.

Share this post


Link to post
Share on other sites
Why are you using a for(; loop instead of a while(1) loop?

Also as the previous poster said, you don''t really want to use GOTOs - a simple boolean flag (like ''while(!bDone)'') would work fine here.

Share this post


Link to post
Share on other sites
quote:
Original post by superpig
Why are you using a for(; loop instead of a while(1) loop?


Just to avoid one (useless) comparision each time the loop iterares. Anyway, I've changed it to "while (!done)", so that "optimization" is gone away.

EDIT: I've found a much better way to do it:

  
int WINAPI WinMain (...) {
// Create a window, init. the game, OpenGL, etc...

// ...

// Main loop

for (;;) {
// Prevent CPU usage:

if (!isAppActive) WaitMessage ();
// Message loop:

if (PeekMessage (&mensaje, hVentana, 0, 0, PM_REMOVE)) {
if (mensaje.message==WM_QUIT)
break;
TranslateMessage (&mensaje);
DispatchMessage (&mensaje);
}
// Game Loop:

if (isAppActive) {
UpdateGame ();
RenderScene ();
}
}
// ...

// Terminate game, OpenGL, etc...

return (mensaje.wParam);
}

theNestruo

Syntax error in 2410
Ok

[edited by - theNestruo on April 20, 2003 7:56:35 PM]

Share this post


Link to post
Share on other sites
Here''s the code of how MS handles it from their DX SDK:


  
PeekMessage( &msg, NULL, 0U, 0U, PM_NOREMOVE );

while( WM_QUIT != msg.message )
{
// Use PeekMessage() if the app is active, so we can use idle time to

// render the scene. Else, use GetMessage() to avoid eating CPU time.

if( m_bActive )
bGotMsg = ( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) != 0 );
else
bGotMsg = ( GetMessage( &msg, NULL, 0U, 0U ) != 0 );

if( bGotMsg )
{
// Translate and dispatch the message

if( hAccel == NULL || m_hWnd == NULL ||
0 == TranslateAccelerator( m_hWnd, hAccel, &msg ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
}
else
{
if( m_bDeviceLost )
{
// Yield some CPU time to other processes

Sleep( 100 ); // 100 milliseconds

}
// Render a frame during idle time (no messages are waiting)

if( m_bActive )
{
if( FAILED( Render3DEnvironment() ) )
SendMessage( m_hWnd, WM_CLOSE, 0, 0 );
}
}
}


It can be modified to change into OpenGL standards. Then again, it is MS code, so not sure you would want to

Share this post


Link to post
Share on other sites
Hi (again)!
Thank you, Nytegard; that code (with some modifications) works perfect!

Anyway, I have another problem... When I was trying to use the code of my last post, after closing the window, the application remained active, and using 99% of the CPU. I tried to change the main loop to the minimum (see the next code block), but it had no effect.

  
while (GetMessage (blah blah blah)) {
TranslateMessage (&mensaje);
DispatchMessage (&mensaje);
}

It closes perfectly when I call PostQuitMessage when processing the WM_CLOSE message... But when I do it "as in book is" (WM_CLOSE calls DestroyWindow, WM_DESTROY calls PostQuitMessage) the application never closes and I need to kill the task with the "taskmgr".
I''m very confused with this... Can anyone explain me what I''m doing wrong?
Thank you in advance!

theNestruo

Syntax error in 2410
Ok

Share this post


Link to post
Share on other sites
quote:
Original post by theNestruo
Original post by superpig
Why are you using a for(; loop instead of a while(1) loop?

Just to avoid one (useless) comparision each time the loop iterares. Anyway, I''ve changed it to "while (!done)", so that "optimization" is gone away.




Does for(; compile to better machine code than while(1)?

Share this post


Link to post
Share on other sites
quote:
Original post by theNestruo
for (;; )
Original post by superpig
Why are you using a for(;; ) loop instead of a while(1) loop?
Original post by theNestruo
Just to avoid one (useless) comparision each time the loop iterares.
Original post by rypyr
Does for(;; ) compile to better machine code than while(1)?


The dissasembly button told me so...

4: for (;; ) {
5: if (i==1) break;
0040B46F cmp dword ptr [ebp-4],1
0040B473 jne main+27h (0040b477)
0040B475 jmp main+29h (0040b479)
6: }
0040B477 jmp main+1Fh (0040b46f)
7:
8: while (1) {
0040B479 mov eax,1
0040B47E test eax,eax
0040B480 je main+3Ch (0040b48c)
9: if (i==1) break;
0040B482 cmp dword ptr [ebp-4],1
0040B486 jne main+3Ah (0040b48a)
0040B488 jmp main+3Ch (0040b48c)
10: }
0040B48A jmp main+29h (0040b479)


theNestruo

Syntax error in 2410
Ok

[Edit: I replaced some for(; with for(;; )]

[edited by - theNestruo on April 21, 2003 7:34:37 PM]

Share this post


Link to post
Share on other sites
Ok, it''s solved now. Halcyon and BlueDev helped me a lot. The second parameter of the GetMessage and the PeekMessage calls should be NULL instead of hWnd.

theNestruo

Syntax error in 2410
Ok

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
What compiler is that? That''s horrible
Is that perchance a debug build?

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

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

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!