Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Help me!

This thread is locked; no one can reply to it. rss feed Print
Help me!
tremendoustoast
Member #15,522
February 2014

Hello,

I have been working on a game for a few days now but keep coming across problems where it says unhandled exception.
I have come to the realization they are all caused by the same problem.

-"allegro-5.0.7-monolith-md-debug.pdb not loaded"
-"allegro-5.0.7-monolith-md-debug.pdb contains the debug information required to find the source for the module allegro-5.0.7-monolit-md-debug.dll"

I have included an image of the error it's throwing.

Any help with this issue would be great because i just have no idea how to go about fixing it.:'(

The program falls apart when this code is called for the second time;

#SelectExpand
1bool got_event = al_get_next_event(event_queue, &allegro_event); 2 3 if (got_event == false) return; // no event waiting

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

I have been working on a game for a few days now but keep coming across problems where it says unhandled exception.
I have come to the realization they are all caused by the same problem.

Use your debugger and see what line it is crashing on. Your image says line 70. Show us your code with <code>code goes here...</code> tags.

Quote:

-"allegro-5.0.7-monolith-md-debug.pdb not loaded"
-"allegro-5.0.7-monolith-md-debug.pdb contains the debug information required to find the source for the module allegro-5.0.7-monolit-md-debug.dll"

All it means is there is no associated pdb debugging file to go along with the dll. A pdb file contains debugging symbols so you can tell where it is crashing.

Quote:

The program falls apart when this code is called for the second time;

If it is crashing on al_get_next_event, then allegro hasn't been initialized, or the event queue is invalid, or the address of the event is invalid. I don't think that is really what is wrong though.

tremendoustoast
Member #15,522
February 2014

Thanks for the reply,
The program crashes on the first line of the code I've already shown you.

The code is for a class I've called AllegroStart.

What i want the class to do is to handle the initialization of allegro as well as event handling, the problem i'm having has started occurring since trying to include a timer in the program.

Here is the entire Class;
Header File-

#SelectExpand
1#pragma once 2#include <allegro5/allegro.h> 3#include <allegro5/allegro_native_dialog.h> 4#include <string> 5#include<iostream> 6#include "conio.h" 7using namespace std; 8 9class AllegroStart 10{ 11private: 12 enum KEYS_PRESSED_LIST 13 { 14 KEY_ESCAPE, KEY_W, KEY_A, KEY_S, KEY_D, KEY_F, SIZE_OF_KEYS_PRESSED_ENUM 15 }; 16 17 bool keys_pressed[SIZE_OF_KEYS_PRESSED_ENUM]; 18 19 ALLEGRO_DISPLAY* display = NULL; 20 ALLEGRO_EVENT_QUEUE* event_queue = NULL; 21 ALLEGRO_BITMAP* bitmap = NULL; 22 ALLEGRO_BITMAP* bitmap_with_transparency = NULL; 23 ALLEGRO_TIMER* timer = NULL; 24 int frames_per_second = 60; 25 bool update_logic = true; 26 bool render_frame = true; 27 int consecutive_logic_updates = 0; 28 int max_consecutive_logic_updates = 10; 29 30 31public: 32 // Method declarations 33 AllegroStart(); 34 int initialise_allegro(); 35 void process_events(); 36 ALLEGRO_TIMER* StartTimer(); 37 bool DoLogic(); 38 bool DoRender(); 39 bool PressedEscape(); 40 bool PressedW(); 41 bool PressedA(); 42 bool PressedS(); 43 bool PressedD(); 44 bool PressedF(); 45 ~AllegroStart(); 46};

.cpp file

#SelectExpand
1#include "AllegroStart.h" 2 3AllegroStart::AllegroStart() 4{ 5 frames_per_second = 60; 6 update_logic = true; 7 render_frame = true; 8 consecutive_logic_updates = 0; 9 max_consecutive_logic_updates = 10; 10} 11 12int AllegroStart::initialise_allegro() 13{ 14 if (!al_init()) 15 { 16 cout << "Allegro initialisation failed" << endl; 17 cout << "Press any key to exit" << endl; 18 _getch(); 19 return -1; 20 } 21 22 // tell allegro program needs keyboard input 23 if (!al_install_keyboard()) 24 { 25 cout << "Keyboard initialisation failed" << endl; 26 cout << "Press any key to exit" << endl; 27 _getch(); 28 return -1; 29 } 30 31 // initialise keypress array 32 for (int i = 0; i < SIZE_OF_KEYS_PRESSED_ENUM; i++) 33 { 34 keys_pressed[i] = false; 35 } 36 37 display = al_create_display(800, 640); // create a display window of size 640 by 480 38 39 if (!display) 40 { 41 cout << "Display initialisation failed" << endl; 42 cout << "Press any key to exit" << endl; 43 _getch(); 44 return -1; 45 } 46 47 al_set_window_position(display, 250, 50); // position display window on screen 48 49 // need to create an event queue so allegro can respond to events, such as keypresses 50 event_queue = al_create_event_queue(); 51 52 if (!event_queue) 53 { 54 cout << "Event queue creation failed" << endl; 55 cout << "Press any key to exit" << endl; 56 _getch(); 57 al_destroy_display(display); 58 return -1; 59 } 60 61 // register display with the event queue, so display change events can be processed 62 al_register_event_source(event_queue, al_get_display_event_source(display)); 63 64 // register keyboard with the event queue, so keypress events can be processed 65 al_register_event_source(event_queue, al_get_keyboard_event_source()); 66 67 // creates a timer 68 timer = al_create_timer(1.0 / frames_per_second); 69 70 //register Timer with the event queue 71 al_register_event_source(event_queue, al_get_timer_event_source(timer)); 72 73 return 0; 74} 75 76void AllegroStart::process_events() 77{ 78 ALLEGRO_EVENT allegro_event; 79 80 // get the next event from the event queue 81 bool got_event = al_get_next_event(event_queue, &allegro_event); 82 83 if (got_event == false) return; // no event waiting 84 85 // test if a key is pressed down, update global keypress array 86 if (allegro_event.type == ALLEGRO_EVENT_KEY_DOWN) 87 { 88 switch (allegro_event.keyboard.keycode) 89 { 90 case ALLEGRO_KEY_ESCAPE: 91 keys_pressed[KEY_ESCAPE] = true; 92 break; 93 case ALLEGRO_KEY_W: 94 keys_pressed[KEY_W] = true; 95 break; 96 case ALLEGRO_KEY_A: 97 keys_pressed[KEY_A] = true; 98 break; 99 case ALLEGRO_KEY_S: 100 keys_pressed[KEY_S] = true; 101 break; 102 case ALLEGRO_KEY_D: 103 keys_pressed[KEY_D] = true; 104 break; 105 case ALLEGRO_KEY_F: 106 keys_pressed[KEY_F]= true; 107 break; 108 } 109 } 110 // Test if a key is let go, update global keypress array 111 else if (allegro_event.type == ALLEGRO_EVENT_KEY_UP) 112 { 113 switch (allegro_event.keyboard.keycode) 114 { 115 case ALLEGRO_KEY_ESCAPE: 116 keys_pressed[KEY_ESCAPE] = false; 117 break; 118 case ALLEGRO_KEY_W: 119 keys_pressed[KEY_W] = false; 120 break; 121 case ALLEGRO_KEY_A: 122 keys_pressed[KEY_A] = false; 123 break; 124 case ALLEGRO_KEY_S: 125 keys_pressed[KEY_S] = false; 126 break; 127 case ALLEGRO_KEY_D: 128 keys_pressed[KEY_D] = false; 129 break; 130 case ALLEGRO_KEY_F: 131 keys_pressed[KEY_F] = false; 132 break; 133 } 134 } 135 else if(got_event && allegro_event.type == ALLEGRO_EVENT_TIMER) 136{ 137 138// if logic taking too long ensures frame is rendered occasionally and input is responsive 139// this essentially ignores logic updates if there are a lot of consecutive ones 140 141 if(++consecutive_logic_updates < max_consecutive_logic_updates) 142 { 143 update_logic = true; 144 } 145 146 // only render frame if no events left to process 147 if(al_is_event_queue_empty(event_queue)) 148 { 149 render_frame = true; 150 consecutive_logic_updates=0; 151 } 152} 153 154} 155 156ALLEGRO_TIMER* AllegroStart::StartTimer() 157{ 158 return timer; 159} 160 161bool AllegroStart::DoLogic() 162{ 163 if (update_logic) 164 { 165 return update_logic; 166 update_logic = false; 167 } 168} 169 170bool AllegroStart::DoRender() 171{ 172 if(render_frame) 173 { 174 175 return render_frame; 176 render_frame = false; 177 } 178} 179bool AllegroStart::PressedEscape() 180{ 181 return keys_pressed[KEY_ESCAPE]; 182} 183 184bool AllegroStart::PressedW() 185{ 186 return keys_pressed[KEY_W]; 187} 188bool AllegroStart::PressedA() 189{ 190 return keys_pressed[KEY_A]; 191} 192bool AllegroStart::PressedS() 193{ 194 return keys_pressed[KEY_S]; 195} 196 197bool AllegroStart::PressedD() 198{ 199 return keys_pressed[KEY_D]; 200} 201 202bool AllegroStart::PressedF() 203{ 204 return keys_pressed[KEY_F]; 205} 206 207 208AllegroStart::~AllegroStart() 209{ 210 al_destroy_display(display); 211 al_destroy_event_queue(event_queue); 212 al_destroy_timer(timer); 213}

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

I haven't looked super closely but you may be making a copy of your AllegroStart object. If that happens, the destructor will be called which will shutdown allegro which will make any further calls to allegro functions fail.

Show the code where you use your AllegroStart object.

tremendoustoast
Member #15,522
February 2014

AllegroStart is only used in my main.cpp source file, here is the code from that file (i know, it's messy, all a work it progress!!)

#SelectExpand
1#include <allegro5/allegro.h> 2#include <allegro5/allegro_native_dialog.h> 3#include<iostream> 4#include <vector> 5#include "conio.h" 6using namespace std; 7 8#include "AllegroStart.h" 9#include "Creature.h" 10#include "Projectile.h" 11#include "Hero.h" 12#include "Monster.h" 13#include "Arena.h" 14AllegroStart* alleg; 15Projectile* projectiles[4]; 16Hero* Hero1; 17 18Monster* Monster1; 19Monster* Monster2; 20Monster* Monster3; 21Monster* Monster4; 22vector<Monster*> MonsterVector; 23Arena* Arena1; 24void Logic(); 25void Render(); 26 27int bum = 0; 28int man[4]; 29int main() 30 31{ 32 alleg = new AllegroStart(); 33 Hero1 = new Hero(5, 100, 200, "assets/PlaceHolderDude.bmp", 200, 2, Arena1); 34 Arena1 = new Arena(); 35 Monster1 = new Monster(100, 200, "assets/Monster.bmp", 100, 2, Arena1); 36 Monster2 = new Monster(100, 200, "assets/Monster.bmp", 100, 2, Arena1); 37 Monster3 = new Monster(100, 200, "assets/Monster.bmp", 100, 2, Arena1); 38 Monster4 = new Monster(100, 200, "assets/Monster.bmp", 100, 2, Arena1); 39 40 MonsterVector.push_back(Monster1); 41 MonsterVector.push_back(Monster2); 42 MonsterVector.push_back(Monster3); 43 MonsterVector.push_back(Monster4); 44 45 int x = 0; 46 47 48 while (x < 4) 49 { 50 projectiles[x] = new Projectile(); 51 projectiles[x]->SetValues(10, 1, 1, 1, "assets/Bullet.bmp"); 52 x++; 53 } 54 55 // initialise everything 56 bool init_ok = alleg->initialise_allegro(); 57 58 if (init_ok != 0) 59 { 60 return init_ok; // exit if init failed 61 } 62 63 al_start_timer(alleg->StartTimer()); 64 65 // loop until escape key is pressed 66 while (x<5) // changed this for debugging purposes! 67 { 68 alleg->process_events(); // deal with events, such as mouse and keyboard input 69 70 if(alleg->DoLogic()) 71 { 72 73 Logic(); 74 } 75 if(alleg->DoRender()) 76 { 77 Render(); 78 } 79 80 } 81 82 alleg->~AllegroStart(); 83 84 delete alleg; 85 86 for (int count = 0; count < MonsterVector.size(); count++) 87 { 88 89 MonsterVector[count]->~Monster(); 90 delete MonsterVector[count]; 91 } 92 93 Hero1->~Hero(); 94 delete Hero1; 95 96 int g = 0; 97 while (g < 4) 98 { 99 projectiles[g]->~Projectile(); 100 101 g++; 102 103 } 104 return 0; 105} 106 107 108 void Logic() 109 { 110 111 // check keys pressed to update variables 112 if (alleg->PressedW()) 113 { 114 Hero1->Up(); 115 } 116 117 if (alleg->PressedA()) 118 { 119 Hero1->Left(); 120 } 121 122 if (alleg->PressedS()) 123 { 124 Hero1->Down(); 125 } 126 127 if (alleg->PressedD()) 128 { 129 Hero1->Right(); 130 } 131 132 if (alleg->PressedF()) 133 { 134 if (bum == 0) 135 { 136 137 int y = 0; 138 int count = 1; 139 140 while (y<4) 141 { 142 if (count>0) 143 { 144 if (!projectiles[y]->isFiring()) 145 { 146 projectiles[y]->Fire(1, Hero1->Getx(), Hero1->Gety()); 147 bum = 5; 148 man[y] = 50; 149 count--; 150 } 151 } 152 153 y++; 154 } 155 } 156 } 157 158 if (bum > 0) 159 { 160 bum--; 161 } 162 163 int p = 0; 164 while (p < 4) 165 { 166 if (projectiles[p]->isFiring()) 167 { 168 projectiles[p]->Firing(); 169 if (man[p] == 1) 170 { 171 projectiles[p]->Stop(1); 172 } 173 } 174 p++; 175 man[p]--; 176 } 177 178 } 179 180void Render() 181 { 182 al_clear_to_color(al_map_rgb(0, 0, 0)); // colour entire display with rgb colour 183 184 Arena1->Render(); 185 Hero1->Draw(); 186 Monster1->Draw(); 187 188 al_flip_display(); // show what has just been drawn 189 }

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

tremendoustoast
Member #15,522
February 2014

That's great, thank you for the help so far! ;D

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Things are bound to go wrong because you it looks like you are loading assets before allegro is initialized. You create Hero and Monster objects before calling bool init_ok = alleg->initialise_allegro();.

{ 
 alleg = new AllegroStart();
 Hero1 = new Hero(5 , 100 , 200 , "assets/PlaceHolderDude.bmp" , 200 , 2 , Arena1);
 Arena1 = new Arena();
 Monster1 = new Monster(100, 200, "assets/Monster.bmp", 100, 2, Arena1);
 Monster2 = new Monster(100, 200, "assets/Monster.bmp", 100, 2, Arena1);
 Monster3 = new Monster(100, 200, "assets/Monster.bmp", 100, 2, Arena1);
 Monster4 = new Monster(100, 200, "assets/Monster.bmp", 100, 2, Arena1);

You need to insert your initialization code here :

#SelectExpand
1 alleg = new AllegroStart();
2 3 // initialise everything
4 bool init_ok = alleg->initialise_allegro();
5 if (init_ok != 0) { 6 return init_ok; // exit if init failed 7 } 8 9 Hero1 = new Hero(5 , 100 , 200 , "assets/PlaceHolderDude.bmp" , 200 , 2 , Arena1); 10 Arena1 = new Arena(); 11 Monster1 = new Monster(100, 200, "assets/Monster.bmp", 100, 2, Arena1); 12 Monster2 = new Monster(100, 200, "assets/Monster.bmp", 100, 2, Arena1); 13 Monster3 = new Monster(100, 200, "assets/Monster.bmp", 100, 2, Arena1); 14 Monster4 = new Monster(100, 200, "assets/Monster.bmp", 100, 2, Arena1);

tremendoustoast
Member #15,522
February 2014

Hey,
I've made the change you suggested, it explains why i was having trouble with some other parts of the program previously, however, it hasn't fixed the problem with 'got_event'.

pkrcel
Member #14,001
February 2012

I found very difficult to go through your codeflow, but would you like to explain what this:

bool AllegroStart::DoLogic()
  { 
  if (update_logic)
     { 
     return update_logic; 
     update_logic = false; 
     } 
  }

should accomplish?

It is unlikely that Google shares your distaste for capitalism. - Derezo
If one had the eternity of time, one would do things later. - Johan Halmén

tremendoustoast
Member #15,522
February 2014

Ok so basically, i have broken tasks in main into logic tasks and render task and placed them in separate functions.

That method will return true if logic tasks need to be performed and then the boolean attribute used to say whether logic tasks need to be performed will be set to false again.

The reason i am using these functions is to allow the program extra time to process tasks if it is needed, this way you won't get a back log of render/logic tasks creating a more steady frame rate

Thomas Fjellstrom
Member #476
June 2000
avatar

I think he's trying to hint at the fact that your logic in DoLogic is a bit flawed.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

tremendoustoast
Member #15,522
February 2014

Oh shit... man if i had a nickel for every time i did something like this.

pkrcel
Member #14,001
February 2012

Well the fact is thay is only an example of the flawed points in your code.

Which apart for some naive things like using a vector to store elements you...singularly allocated (I'm looking at those monsters....) it's not THAT bas as you state in the OP...there's just a bit of WAY TOO MUCH BOILERPLATE, but that's fine.

The problem is I can't really follow along your code, how it "flows".

You said that you get the SEGFAULT only the SECOND time you run over the 'got_event' bit...is this still the case after Edgar's suggestion?

EDIT:

The reason i am using these functions is to allow the program extra time to process tasks if it is needed, this way you won't get a back log of render/logic tasks creating a more steady frame rate

Barring my difficulties in understanding the code (which are there!) I don't think this would be the case since ouy're counting frames but not checking how much time you spend in logic.

Anyway I would suggest you drop this kind of optimization for now, it's quite an advanced topic...unlikely you will need that now.

On the other hand, I've (mentally) simulated two consecutive runs of the innner loop but can't find a good reason for al_get_next_event throw a fit without reason....it is very very very likely that the second time that is called there is no event (maybe also the first), but in that case that is clearly guarded but the bool check right after.

I now strongly suspect there's an unmatched closing curly brace somewhere...

It is unlikely that Google shares your distaste for capitalism. - Derezo
If one had the eternity of time, one would do things later. - Johan Halmén

tremendoustoast
Member #15,522
February 2014

Yes,

-I have changed the code so that my initialise_allgro function is being called before any other class objects are created.

#SelectExpand
1int main() 2 3{ 4 alleg = new AllegroStart(); 5 6 // initialise everything 7 bool init_ok = alleg->initialise_allegro(); 8 9 if (init_ok != 0) 10 { 11 return init_ok; // exit if init failed 12 } 13 14 Hero1 = new Hero(5, 100, 200, "assets/PlaceHolderDude.bmp", 200, 2, Arena1); 15 Arena1 = new Arena();

-I have changed the code so that update_logic and update_render are being set to false after the methods have been called(by creating 2 methods which just set the values to false when called)

Game loop in main

#SelectExpand
1 alleg->process_events(); // deal with events, such as mouse and keyboard input 2 3 if(alleg->DoLogic()) 4 { 5 Logic(); 6 alleg->EndLogic(); 7 } 8 if(alleg->DoRender()) 9 { 10 Render(); 11 alleg->EndRender(); 12 }

Methods in AllegroStart

#SelectExpand
1bool AllegroStart::DoLogic() 2{ 3 if (update_logic) 4 { 5 return update_logic; 6 7 } 8} 9 10bool AllegroStart::DoRender() 11{ 12 if(render_frame) 13 { 14 15 return render_frame; 16 } 17} 18 19void AllegroStart::EndLogic() 20{ 21 update_logic = false; 22} 23void AllegroStart::EndRender() 24{ 25 render_frame = false; 26}

After changing this the program still crashes when it reaches bool got_event = al_get_next_event(event_queue, &allegro_event)
for the second time.

pkrcel
Member #14,001
February 2012

Just in case, I was editing my previous post before you posted again.

You may want to check.

EDIT: well braces match it seems...

It is unlikely that Google shares your distaste for capitalism. - Derezo
If one had the eternity of time, one would do things later. - Johan Halmén

tremendoustoast
Member #15,522
February 2014

ah, i'm following a tutorial and my understanding of how that piece of code works is clearly not right.

Despite this I just can't see any reason why it would stop on that line of code...

pkrcel
Member #14,001
February 2012

You could share you Visual Studio Solution, maybe someone (even me if I get back to my VS machine) can follow along the code.

Maybe :P

It is unlikely that Google shares your distaste for capitalism. - Derezo
If one had the eternity of time, one would do things later. - Johan Halmén

Dizzy Egg
Member #10,824
March 2009
avatar

I'm just guessing here, but would it make any difference if you started the timer before registering it for events?

Probably not but you never know...

----------------------------------------------------
Please check out my songs:
https://soundcloud.com/dont-rob-the-machina

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

#SelectExpand
1bool AllegroStart::DoLogic() 2 { 3 if (update_logic) { 4 return update_logic; 5 }
6 }
7 bool AllegroStart::DoRender() { 8 if(render_frame) { 9 return render_frame; 10 }
11 }
12 void AllegroStart::EndLogic() { 13 update_logic = false; 14 } 15 void AllegroStart::EndRender() { 16 render_frame = false; 17 }

You should turn on your compiler warnings. On both of the highlighted lines if update_logic or render_frame is false then the program execution will fall through to whatever is after it in the binary code. The execution pointer could end up anywhere, and it is likely to crash indeterminately.

Your compiler should have said something like 'missing return statement for non-void function'. I think gcc would have warned about it with -Wall. I don't have a C++ compiler handy to test though.

If that's still not it, post all of your current main again and maybe attach a zip of your sources.

pkrcel
Member #14,001
February 2012

I strongly suspect that compiler optimizations would make the thing inlined and thus MAYBE leave things unchanged with no harm.

But I completely missed that due to cross-posting...whatever the crash, those two functions won't do any good cause there's nowhere the properties are being set again (to true).

I second Edgar's suggestion, maybewe are able to run the sources into a debugger...

It is unlikely that Google shares your distaste for capitalism. - Derezo
If one had the eternity of time, one would do things later. - Johan Halmén

tremendoustoast
Member #15,522
February 2014

{"name":"GoodNewsEveryone.jpg","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/c\/6\/c6698fa12292b680f739bfd436f0731e.jpg","w":990,"h":749,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/c\/6\/c6698fa12292b680f739bfd436f0731e"}GoodNewsEveryone.jpg
GOOD NEWS EVERYONE!
I was fed up of just sitting around hoping it would work so i continued programming a different section of the game and something i did seems to have fixed the problem!! Now to fix the 7234 other problems!

EDIT
Forgot to say THANK YOU to everybody for your help in improving my code in other areas! Never really use forums anymore but you guys were really helpful and didn't destroy me for my poor coding.

Go to: