Starting Menu: a separate event loop?

Member
Posts: 185
Joined: 2005.02
Post: #1
Ok, I was thinking about how I would add a menu at the beginning of my game. Should I just add another event loop so that it looks like this?
Code:
int main(int argc, char *argv[])
{    
    init();
    menuMainLoop();
       gameMainLoop();
    cleanUp();
    
    return 0;
}
Code:
void MenuMainLoop(void)
{
    SDL_Event event;
    int done = 0;
    
    while (!done && !quit)
    {
        while (SDL_PollEvent (&event))
        {
            switch (event.type)
            {
                case SDL_KEYDOWN:
                    Menu_ProcessKeyDown(event.key.keysym);
                    break;
                case SDL_KEYUP:
                    Menu_ProcessKeyUp(event.key.keysym);
                    break;
                case SDL_QUIT:
                    quit = 1;
                    break;
                default:
                    break;
            }
        }
        
        upsdateMenu();
        display();
    }
    return;    
}

void gameMainLoop(void)
{
    SDL_Event event;
    
    while (!quit)
    {
        while (SDL_PollEvent (&event))
        {
            switch (event.type)
            {
                case SDL_KEYDOWN:
                    ProcessKeyDown(event.key.keysym);
                    break;
                case SDL_KEYUP:
                    ProcessKeyUp(event.key.keysym);
                    break;
                case SDL_QUIT:
                    quit = 1;
                    break;
                default:
                    break;
            }
        }
        
        UpdateGame();
        display();
    }
    return;    
}

With whatever event that causes exiting the menu setting done to 1.

Or is there another more predominant way to implement a main menu?
Quote this message in a reply
Member
Posts: 245
Joined: 2005.11
Post: #2
That is a perfectly serviceable way to go, but can get quite messy if you have lots of menu screens and things. A tidier way to do it is to introduce the notion of an engine state, which is checked every loop and the appropriate function is then called.
Code:
int state;

int main(int argc, char *argv[])
{    
    init();     //this should set state=1 in addition to what it already does
    loop();
    cleanUp();
    
    return 0;
}

void loop()
{
     while (!state)
          {
          switch (state)
                    {
                    case 1:
                              doMainMenu();
                              break;
                    case 2:
                              doGame();
                              break;
                    //do any other menus the same way
                    }
          }
}

The doGame() and doMainMenu() functions above shold not contain any loops - just run through everything once then return. If the player selects a menu option, simply change the state to 2 to play game or state=0 to quit.
This approach may be a little over complex at the moment but it is easily extensible in all kinds of ways.
Quote this message in a reply
Member
Posts: 185
Joined: 2005.02
Post: #3
yeah, that makes sense. Thanks!
Quote this message in a reply
Sage
Posts: 1,199
Joined: 2004.10
Post: #4
The way I approach this kind of thing in my game(s) is to have game state represented as a stack, with the topmost element in the stack receiving user input events and being responsible for rendering.

The game might start by "pushing" a main-menu state on the stack. The main menu state would render the menu and process events. Clicking on "settings" would push a settings state on the stack, and it would receive and process input until you clicked "Save" or "Cancel", at which point it would be popped off the stack, returning game state to the main menu.

This approach has worked really well for me, and allows me to skip the often hairy state-machine approach that you get with the long-switch-statement approach. Not that there's anything wrong with that approach, but the stack approach I take makes it stupid easy to have in-game settings and the like.
Quote this message in a reply
Member
Posts: 185
Joined: 2005.02
Post: #5
Shock oh Stacks, yes I could use stacks for lots of things... Thanks!
Quote this message in a reply
Member
Posts: 245
Joined: 2005.11
Post: #6
I'd never thought of that. I may have to start upgrading my engine state variable to a stack now. I can do that without having to replace my big switch statements though. Rasp
Quote this message in a reply
Sage
Posts: 1,199
Joined: 2004.10
Post: #7
Certainly -- there isn't anything wrong with switch statements! But stacks are useful in some places, and switches others. When dealing with macro level engine state -- menus, pause screens, settings screens, etc, I find stacks to be useful.
Quote this message in a reply
Member
Posts: 161
Joined: 2005.07
Post: #8
TomorrowPlusX Wrote:The way I approach this kind of thing in my game(s) is to have game state represented as a stack, with the topmost element in the stack receiving user input events and being responsible for rendering.
That's actually a really nice idea. I've always used the switch statement approach, but that definitely seems like a much cleaner and functional solution given the way menu systems work.

EDIT: Oh, all it makes it very easy to have those menu systems where the game settings or game save states appear as overlays to the previous menu - you'd just have to iterate through the items in the stack, calling each item's draw function.
Quote this message in a reply
Sage
Posts: 1,199
Joined: 2004.10
Post: #9
imikedaman Wrote:That's actually a really nice idea. I've always used the switch statement approach, but that definitely seems like a much cleaner and functional solution given the way menu systems work.

EDIT: Oh, all it makes it very easy to have those menu systems where the game settings or game save states appear as overlays to the previous menu - you'd just have to iterate through the items in the stack, calling each item's draw function.

That's exactly how I do it.

Specifically, my Application class has a stack of "ApplicationDelegate" instances. The delegates can label themselves as "opaque" or "transparent" and the Application draws each from the last opaque to the top of the stack. So when I hit "pause" in my game, the pause menu displays over the game world.

Of course, there's a lot of hokey pokey in there, but it's actually really easy to implement.
Quote this message in a reply
Member
Posts: 161
Joined: 2005.07
Post: #10
TomorrowPlusX Wrote:That's exactly how I do it.
Yes I know - I already quoted you saying it and everything. Wacko

Anywho, thanks for the nice idea!
Quote this message in a reply
Sage
Posts: 1,199
Joined: 2004.10
Post: #11
imikedaman Wrote:Yes I know - I already quoted you saying it and everything. Wacko

Anywho, thanks for the nice idea!

Heh. yeah, I was clarifying the drawing mechanism, is all.
Quote this message in a reply
Member
Posts: 161
Joined: 2005.07
Post: #12
Quote:Heh. yeah, I was clarifying the drawing mechanism, is all.
Heh, yeah - I realized a little too late that you were referring to the iterative draw loop to have the menu overlays, not repeating yourself. Smile
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Menu Item Question gradyeightythree 2 3,080 Apr 30, 2007 12:31 PM
Last Post: SethWillits
  Cocoa Event Loop/NSTimer revisited Fenris 6 5,177 Oct 29, 2005 11:27 PM
Last Post: maaaaark
  Fullscreen menu problem KiroNeem 2 2,943 Aug 30, 2005 02:32 PM
Last Post: KiroNeem
  Vanishing Menu Bar Prince Aron 6 4,239 May 3, 2003 03:30 PM
Last Post: OneSadCookie
  When to run event loop... SethWillits 3 3,803 Aug 11, 2002 07:48 AM
Last Post: ededed