Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » How to use Allegro's GUI menu system?

This thread is locked; no one can reply to it. rss feed Print
How to use Allegro's GUI menu system?
kholdstayr
Member #7,575
August 2006

I am having problems effectively utilizing Allegro's GUI dialog menu bar. Right now I am working on a simple solitaire card game and I put up a simple menu that has a Start Game item. Clicking on the Start Game menu item runs a callback function that starts up the game code.

The problem is that I don't know any tricks to keep the menu "active" while the game is being played. For example once my game code starts up, the menu no longer draws itself since the callback function I supply hasn't yet returned back to the do_dialog() system (when the game is running). I finally figured out that I could keep the menu drawn on the screen by running the object_message() function with a redraw message, but that doesn't allow the menu to be clicked on still. How can I keep the menu somewhat active and still run the game code? Are there any good tricks to use?

I was thinking it would be possible to monitor the X-Y coords of the mouse in the game code and if they approach the top of the screen (where the menu is) I could active the menu. I am guessing there is any easier way that I haven't figured out yet.

miran
Member #2,407
June 2002

The recommended solution:

1. Your play_game() function just sets a flag and returns immediately.

2. The actual game is a d_game_proc() kind of thing that is part of the menu dialog and checks the value of the above flag to see whether a game is supposed to be played or not.

--
sig used to be here

James Stanley
Member #7,275
May 2006
avatar

Or you could use update_dialog() instead of do_dialog(), check the allegro manual for more information, because it's not quite as simple as that.

Kitty Cat
Member #2,815
October 2002
avatar

Quote:

2. The actual game is a d_game_proc() kind of thing that is part of the menu dialog and checks the value of the above flag to see whether a game is supposed to be played or not.

This is actually a good idea, if you want to have a responsive GUI using Allegro's routines and not have to worry about managing all the other widgets. Just make the MSG_IDLE handler do the logic loop (after checking that it's time to), then return D_REDRAWME. Then set your MSG_DRAW handler to draw and display your game section. You can even make your menus send custom messages to your game dialog to make it change states in real-time. Tracking MSG_CHAR messages should be done in place of keypressed/readkey, and you can use the key[] array like normal. You'd want to return D_WANTFOCUS for MSG_LOSTFOCUS and MSG_WANTFOCUS events.

Just make sure to disable using KEY_ESC to quit the dialog (unless that's what you want). And don't use a d_yield_proc. If you want to rest, do it in your game loop after checking that you don't need to run logic yet.

Of course, you probably don't want to do anything for MSG_START/MSG_END messages. IIRC, there's a problem with MSG_START that it gets called multiple times, so for initialization/cleanup you'd want to do it right before/after do_dialog.

An example of this kind of setup would be:

1volatile unsigned int timer;
2void update_timer()
3{
4 timer++;
5}
6END_OF_FUNCTION(update_timer);
7 
8int d_game_proc(int msg, DIALOG *d, int c)
9{
10 switch(msg)
11 {
12 case MSG_DRAW:
13 // Careful. This will be called before the first logic run,
14 // so make sure it won't die
15 draw_scene(buffer);
16 blit(buffer, screen, ...);
17 return D_O_K;
18 
19 case MSG_IDLE:
20 if(timer == 0)
21 {
22 // Ahead of schedule. rest a bit to ease CPU usage
23 // (not needed, but nice to do), then return control
24 rest(1);
25 return D_O_K;
26 }
27 // Do all waiting logic
28 while(timer > 0) {
29 do_logic();
30 timer--;
31 }
32 // Ready to draw
33 return D_REDRAWME;
34 
35 case MSG_CHAR:
36 // We got a keypress. 'c' (third parameter) is the same format as
37 // returned by readkey()
38 if(c>>8 == KEY_ESC)
39 return D_CLOSE;
40 
41 // So other widgets don't get what was intended for us
42 return D_USED_CHAR;
43 
44 case MSG_WANTFOCUS:
45 case MSG_LOSTFOCUS:
46 // Try to keep focus
47 return D_WANTFOCUS;
48 }
49}
50 
51DIALOG game_dialog[] = {
52 // Should be at the top
53 { d_game_proc, ... },
54 ...
55};
56 
57int main()
58{
59 ...
60 
61 init_game();
62 timer = 0;
63 do_dialog(game_dialog, 0);
64 deinit_game();
65 
66 return 0;
67}

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

kholdstayr
Member #7,575
August 2006

Thanks for the help people. I implemented a game_proc function and it works pretty well. I also realized that my clear_to_color() function was drawing over the menu bar, which I hadn't thought about before. I made it so my clear to color doesn't overwrite the menu bar anymore, which is also a big help.

Go to: