If you use a single loop for everything (even the GUI), you just need the set_close_button_callback() to set a flag, and to check the flag once per loop
Yes. Exactly. I'll keep the game, the menu and intro, the options, the credits, the highscores (and I'm pretty sure we can come up with even more parts) in one main loop. I'm pretty sure this will make the program easily maintainable and less error prone.
Best solution right now would be to create a state machine framework with the check in the base class. Which adds problems on its own (esp. if you don't want to use c++ ).
If you just want to throw a game together, I found that having different procedures for all the different parts works out best. But then you have to remember to handle the close button.
Well, actually, even forcing the user to remember to write your own close button procedure isn't quite clever. Why not installing a default procedure setting a global variable (like al_window_close_requested). Then we have reduced the overhead from "writing and installing the procedure, then checking the flag" down to "checking the flag".
Normally an allegro game runs fine, but the "little things" annoy the user. Like problems when tabbing in and out of an allegro app. Like choppy mouse movement or too fast / too slow mouse movement after setting a different display mode.
If you're writing a mouse controlled game, having to worry about the mouse at all (besides checking position of the pointer and state of the buttons) is a bad thing, heh.
On the other hand, these "problems" are pretty irrelevant if you just want to code a game "just for fun".