views:

276

answers:

3

I'm working on a Windows game, and I have this:

bool game_cont;

LRESULT WINAPI WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
    case WM_QUIT: case WM_CLOSE: case WM_DESTROY: game_cont = false; break;
    }
    return DefWindowProc(hWnd, msg, wParam, lParam);
}

int WINAPI WinMain(/*lots of parameters*/)
{
    //tedious initialization

    //game loop
    while(game_cont)
    {
        //give message to WinProc
        if(!GameRun()) game_cont = false;
    }
    return 0;
}

and I am wondering if there is a better way to do this (ignoring timers &c. for right now) than to have game_cont be global. In short, I need to be able to exit the while in WinMain from WinProc, so that if the user presses the closes out of the game in a way other that the game's in game menu, the program wont keep running in memory. (As it did when I tested this without the game_cont.. statement in WinProc.

Oh, and on a side note, GameRun is basically a bool that returns false when the game ends, and true otherwise.

+1  A: 

You could use exit. Use atexit to make sure that WM_CLOSE gets to the message que when its time to exit.

I don't know what's the ultimate design here, but it's an idea.

Styggentorsken
A: 

You could make game_cont static to your main file which has WinMain/WinProc, but I don't know of a significantly better structure.

Justin Love
+8  A: 

Yes, use PeekMessage, it's the standard in game development.

This is the best approach, I believe:

int Run()
{
    MSG msg;
    while(true)
    {
     if(::PeekMessage(&msg,0,0,0 PM_REMOVE))
     {
      if(msg.message == WM_QUIT || 
                       msg.message == WM_CLOSE || 
                       msg.message == WM_DESTROY)
       break;

      ::TranslateMessage(&msg);
      ::DispatchMessage(&msg);     
     }
     else
     {
      //Run game code
                    if(!GameRun())
                         break;
     }
    }
}

Also, look at this (specially the first answer)

Seth Illgard
I would probably pass a 'game ending' value through to the GameRun code to allow it to clean up when you choose to exit the app, rather than just using 'break'. But the general structure is exactly right.
Kylotan
Thanks for the comment. Yes, I think that would be better.
Seth Illgard