What I did was declared global.h for all of my global variables. And initialize them basically. For my "main / general" variables (eg camera, position, iteration numbers, ...) they were all declared separately. Mostly:
include "global.h" Vector position_g = ... Vector angles_g = ... int time_g = 0; int main () { ... }
But for variables that were "section specific", i.e. in only one game mode / level, I did the union and listing.
enum mainGame{skipLevel, ...}; enum mainMenu {viewingSettings, ...}; typedef union generic_union { int i; char c; bool b; char s[100];
And the globalData variable is declared.
extern generic * globalData; // in global.h generic * globalData = NULL; // in main
What can be used now:
int main () { ... globalData = malloc (sizeof (generic)*numGlobals); globalData[skipLevel].b = false; ... }
Now that in your keystroke function, you can assign a key to switch globalData [skipLevel]. And in any other file, all you have to do is enable global.h.
include "global.h" void onKeyPress (... ) { If (inMainGame) { If (key == SPACE) { globalData [skipLevel] = true; } }
And finally, use:
include "global.h" void levelManager () { ... if (globalData[skipLevel]) level++; ... }
Pros You only need to bind variable 1 and turn it on.
You can free variables that you no longer want or use in this case. (very useful for reducing "pollution"). If only one variable is required for one game mode, then all you need to save, if you need 48, is just as easy!
It can easily handle any type of variable by adding it to the union.
Fully portable
vs It is necessary to remember the type of variable in order to dereference a common union (not so difficult)
And tracking the use of enums (you can use a style for enums like mainMenu_e to solve this problem)
It adds complexity, but as the number of variables increases, such a system, because it's worth it.
Personally, I think this is very neat, despite a few extra moving parts. If this is unclear, let me know and I will try to fix it :)