Hello guys. I am attempting to make a game and learn Allegro/C++ as I go. I learned Java in high school and basic C++ last semester in college. I think I understand most concepts, but one I for sure don't understand is memory management because that is something I didn't have to deal with in Java, and that may be what is making my program not work.
I am currently working on the level editor for my game (I haven't started the game yet), and I am having trouble with the TTF addon not working. I can successfully use the addon in my main .cpp file, but it isn't working in a separate class that I have made. It keeps telling me that it failed to initialize the ttf addon.
Here is the code in the main file that creates an instance of the separate class "OpenDialogue", which creates a dialogue box (bitmap) for opening a previously-made level.
isShowingDialog = true; currWorkPathCSTR = createDirectoryPath(currWorkPathAP, argv[0], "maps"); OpenDialogue oDialog (argv[0], "Open a Map", currWorkPathCSTR, ".dat");
Here is OpenDialogue.h:
And here is some of the code from OpenDialogue.cpp:
Basically, at line 9 in OpenDialogue.cpp, it says that it failed to load the TTF addon (and it may fail at loading the main font addon, but I don't know since that one doesn't have a return). That causes the game to crash (as expected because dialogueFont is NULL) at line 74.
At line 64, it also tells me that it failed to create dialogueFont (as expected, because the TTF addon wasn't initialized).
Am I missing something obvious? I'm not sure if I even have to initialize the addons in every file or not.
In main() the first things you should do are:
al_init(); al_init_font_addon(); al_init_ttf_addon(); // init whatever
You only need to do it once, and you must do it before you use any of their related functions. Don't put them in the constructors of your objects.
You need to be careful with constructors. Something like this won't work if the FooObject calls some other Allegro function because Allegro won't have been initialized yet:
FooObject Foo; al_init();
Disclaimer: I am both intoxicated and too tired to bother reading through your OP.
"Class file" sounds like a Java influence. You must try to understand that C++ is very different from Java. C (the language that Allegro is written in) is even more different.
A file doesn't mean fuck all to C or C++. These compilers think in terms of "translation units". There are various stages of C or C++ building that you need to aware of:
Preprocessing. The C preprocessor runs, processing directives (e.g., #include; or any line whose first non-whitespace character is a '#'), and effectively transforms the original source file (e.g., .c or .cpp) with them.
Compilation. These translation units are effectively preprocessed source files. These are typically translated into object files. Effectively, the object file is a binary interpretation of the translation unit (i.e., preprocessed source file).
Linking. The compiled translation units, as well as third-party libraries, are all linked together into some kind of executable output file.
(Think of each step above as a completely separate program)
The important distinction is that in a language like Java all of the available classes are available at once for interpretation and compilation (or at least, it seems practically so). In C or C++ each translation unit (preprocessed source file) only knows about itself (what it declares or defines) and whatever it #includes.
That said, much C or C++ code manipulates global data. In Allegro this is certainly true. Initializing Allegro or one of its addons (assuming you did so correctly) is global to the entire application. You only need to do so once. If it succeeds (see here) then it is considered initialized for the duration of the application (unless you happen to deinitialize it, but those APIs, if exposed at all, are rarely used in Allegro programs).
Glancing at your code I can say that it is wrong to initialize anything in Allegro within an "open dialog" method/function. That should typically not be handled by library routines, but instead by application code. If it is handled by a library routine it should be something more generic. That is to say, you don't need (nor want) to initialize Allegro nor its addons every time you open a dialog. You do it once for the duration of the application.
Here is the beginning of my main method in the main file. First come the variable declarations, then initializing Allegro stuff. I'm pretty sure it's in a good order.
I just tried removing the Allegro initializations from OpenDialogue.cpp, and it's still crashing, but it didn't crash at the same point this time. I can't figure out where it's crashing.
Regardless, I somehow have it working. It makes no sense to me. I hope someone can explain it. Here is what my new oDialog declaration looks like (same as before, but with printf statements).
isShowingDialog = true; currWorkPathCSTR = createDirectoryPath(currWorkPathAP, argv[0], "maps"); printf("creating oDialog instance"); // ?????? commenting this printf out makes the game crash in the OpenDialogue class in the same spot as before ???? OpenDialogue oDialog (argv[0], "Open a Map", currWorkPathCSTR, ".dat"); printf("created oDialog instance");
The only thing changed from the OpenDialogue.cpp class shown in my previous post is I added some prinf statements in there and commented out the Allegro initializations, but that's not the confusing part. The confusing part is in the code right above this paragraph. Commenting out that printf statement makes the game crash. That makes no sense to me. Maybe there are memory management problems and printf is somehow accessing memory and coincidentally fixing it? That seems pretty farfetched to me.