Jump to content
  • Advertisement
Sign in to follow this  
OmerKocak

What is the proper implementation of "quit on X-out" in windowed games?

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

I've just started to code simple games with help from the 'Lazy Foo' articles.

To quit the program on an X-out, he keeps a quit variable in his main function and all the main loops break out in case the quit variable is 'true'.

This seemed very reasonable at first but as my codes grew in size, it got too tiring to implement "return something to the main function in case user X'ed out so the main function can set the quit variable to true".


Is it proper practice to;

1- Define the quit variable globally so i can set it easily from within each function.

2- Implement a seperate function that frees the memory, cleans up and quits with "exit()", so i don't bother with a variable but just call that function .


One can choose to do things as he/she likes and the proper way depends on the circumstance but i was wondering if these methods are of the the "stay away if you do not realy need them" kind.

Share this post


Link to post
Share on other sites
Advertisement
Your looking for the "correct" way of doing it..
I am not sure if this is the correct way of doing it but its what I do =)

In the event of a fatal error etc etc I just send a PostQuitMessage(errorcode)

And Take care of it in my windows message proc when I see WM_QUIT


edit: Something like this for your message pump
MSG msg;//message structure
for(;;) //message pump
{
//look for a message
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
//check that we arent quitting
if(msg.message==WM_QUIT) break;
//translate message
TranslateMessage(&msg);
//dispatch message
DispatchMessage(&msg);

}
else
{
if ( Program_Running() == 0) // good call
{//This is just example code, Program_Running() would make its own call to PostQuitMessage with its errorcode

}
else //bail out we had a error
{
MessageBox(NULL, "Failed in Program_Running()" , "Fatal Error", MB_OK);
PostQuitMessage(99);
}
}

}

Share this post


Link to post
Share on other sites
Generally, you want only one input loop, and this loop isn't too "far" from your main loop. You shouldn't need to pass this variable up through too many layers. One option is to use a callback/functor to handle this. My input systems are generally mappings of events to functors, in this case the functor can set a quit flag higher up.

I wouldn't go with a global quit variable. An exit function will not correctly clean up all resources, you should allow this to happen as the stack naturally unwinds so that RAII resources are destroyed.

To be honest, if this is causing you trouble in simple games I suspect you are vastly over-engineering the solution.

Share this post


Link to post
Share on other sites
A quit flag is a good way to do it. The problem comes when you have many things that can cause that flag. Try to reduce that, when my window closes I catch some kind of exit event (using Ogre3d). The other way I quit is if my game state machine is empty (if the game isn't in any state then just quit). You could pass the quit flag around by reference if you need to but I would focus more on reducing what can actually exit the game.

Share this post


Link to post
Share on other sites
The only correct way of exiting is making sure everything in your program is cleaned up and nothing is dangling. Do it the way it makes sense to you. It's like if you told 5 separate people to sketch a picture of an alien, there isn't 1 correct answer, there would just be 5 different interpretations of an alien : )

Share this post


Link to post
Share on other sites
@ yewbie : Thanx. I do not use win API. Though from what i understand, you happen to send a message to windows that you want to terminate ( with PostQuitMessage() ) . And what do you do in your main() to quit? Or does windows take the leash from there on and just terminates your app?..


Generally, you want only one input loop, and this loop isn't too "far" from your main loop. You shouldn't need to pass this variable up through too many layers. One option is to use a callback/functor to handle this. My input systems are generally mappings of events to functors, in this case the functor can set a quit flag higher up.

I wouldn't go with a global quit variable. An exit function will not correctly clean up all resources, you should allow this to happen as the stack naturally unwinds so that RAII resources are destroyed.

To be honest, if this is causing you trouble in simple games I suspect you are vastly over-engineering the solution.


@rip-off: So it's better to go on with the quit flag in the main and check my implementation again if i end up passing the quit variable for too many layers. Thanx, that was what i needed to hear..


A quit flag is a good way to do it. The problem comes when you have many things that can cause that flag. Try to reduce that, when my window closes I catch some kind of exit event (using Ogre3d). The other way I quit is if my game state machine is empty (if the game isn't in any state then just quit). You could pass the quit flag around by reference if you need to but I would focus more on reducing what can actually exit the game.


@Nanoha: Nope, it's the X-out that was bothering me.. When i am in a get_sting_input function thats in the hi_score_menu function thats in the game_over_scene function thats in the main function and the user just presses the exit button of the window, it was a pain to get the quit flag to main.. But from what i understand, it's not the implementation of quit thats wrong, its that i'm layering too much..

Share this post


Link to post
Share on other sites

@ yewbie : Thanx. I do not use win API. Though from what i understand, you happen to send a message to windows that you want to terminate ( with PostQuitMessage() ) . And what do you do in your main() to quit? Or does windows take the leash from there on and just terminates your app?..


PostQuitMessage sends at WM_QUIT message and in my code during the message loop (on the next frame) WM_QUIT is processed and breaks the "infinite" while loop.

Share this post


Link to post
Share on other sites
Your answer is very Win32 specific, yewbie. I think that the generalisation of your answer, applicable to SDL, is to have one "master" event loop, which I would agree with.


When i am in a get_sting_input function thats in the hi_score_menu function thats in the game_over_scene function thats in the main function and the user just presses the exit button of the window, it was a pain to get the quit flag to main.. But from what i understand, it's not the implementation of quit thats wrong, its that i'm layering too much..
[/quote]
This sounds like get_string_input has its own input loop?

I would generally model it differently. For simple games, game over/high score are not functions, but states. Control is continually passed from the main loop into the active state: to react to input, update and render.

In simple games the active state can be an enumeration, with a switch in main() to pass control to the correct states. Something like this:

enum GameState
{
MainMenu,
RunGame,
GameOver,
HighScore,
Exit
};

int main(...)
{
setup();

GameState current = MainMenu;
while(current != Exit)
{
SDL_Event event;
while(SDL_PollEvent(&event))
{
switch(current)
{
case MainMenu: handleMenuEvents(event); break;
case RunGame: handleGameEvents(event); break;
case GameOver: handleCutSceneEvents(event); break;
case HighScore: handleHighScoreEvents(event); break;
}
}

GameState next = current;

switch(current)
{
case MainMenu:
next = updateMenu();
renderMenu();
break;

case RunGame:
next = updateGame();
renderGame();
break;

case GameOver:
next = updateCutScene();
renderCutScene();
break;

case HighScore:
next = updateHighScore();
renderHighScore();
break;
}

if(current != next)
{
transition(current, next);
current = next;
}
}
cleanup();
}

In more complex games with lots of per-state information, I might model each state as a class that implements an interface, with pure virtual update(), onEvent() and render() member functions. I would use a class to leverage RAII for setup/teardown of the per-state data.

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.

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!