Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Problems deleting bitmap

This thread is locked; no one can reply to it. rss feed Print
Problems deleting bitmap
Lasaqus7
Member #15,950
May 2015

Hi All

Hope someone can help me with this issue. I'm currently doing a project to make a 2d rpg style game.

Im using Visual Studio 2013, Windows 7 64bit and Allegro 5.

I have come to a section whereby I cannot seem to resolve an error.

What I am trying to do is allow the player to go up to a quest giver and if the quest is available then once the user has pressed space the quest will appear on screen. Then once the player has decided to accept or decline the quest then the quest image disappears and the player can continue on with the game.

I'm not sure if this is the right way to do it, but my quest is a bitmap which I am loading and trying to delete in an else if statement.

I have tried putting the al_destroy_bitmap code in lots of places inside the QuestInfo function and also in the "state = Playing" section and everytime I run it, either nothing happens onscreen or VisualStudio crashed with a Access Violation reading location error

As a heads up I am coding without the use of classes (This is part of the project requirements)

I am also very new to C++/Allegro5 so my coding may not be implemented the best way.

Any help is very much appreciated.

This is my code section of where I am trying to do this

#SelectExpand
1 2void QuestInfo(Quests &Status, ALLEGRO_EVENT_QUEUE *event_queue, ALLEGRO_EVENT &ev) 3{ 4 Status.ID = QUESTS; 5 Status.Available = true; 6 Status.Accepted = false; 7 Status.Completed = false; 8 NPCQuestOne.QuestHere = true; 9 10 if (NPCQuestOne.QuestHere == true && Status.Available == true) 11 { 12 DrawQuestWindow(Status); 13 al_wait_for_event(event_queue, &ev); 14 } 15 else if (NPCQuestOne.QuestHere == false && Status.Available == false) 16 al_destroy_bitmap(Status.image); 17 18 if (ev.type = ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) 19 { 20 if (ev.mouse.button & 1 && ev.mouse.x > 70 && ev.mouse.x < 245 && ev.mouse.y > 470 && ev.mouse.y < 515) 21 { 22 Status.Available = false; 23 Status.Accepted = true; 24 NPCQuestOne.QuestHere = false; 25//I've tried al_destroy_bitmap here 26 } 27 else if (ev.mouse.button & 1 && ev.mouse.x > 285 && ev.mouse.x < 460 && ev.mouse.y > 470 && ev.mouse.y < 515) 28 { 29 Status.Available = true; 30 Status.Accepted = false; 31 NPCQuestOne.QuestHere = true; 32 } 33//I've tried al_destroy_bitmap here 34 } 35//I've tried al_destroy_bitmap here 36} 37 38void DrawQuestWindow(Quests &Status) 39{ 40 al_draw_bitmap(Status.image, Status.x, Status.y, 0); 41}

I did trying posting all my code but it was 40k over the limit, so if you require anymore please let me know

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Lasaqus7 said:

 if (NPCQuestOne.QuestHere == true && Status.Available == true) {
  DrawQuestWindow(Status);
  al_wait_for_event(event_queue, &ev);
 }
 else if (NPCQuestOne.QuestHere == false && Status.Available == false)
  al_destroy_bitmap(Status.image);

else if (NPCQuestOne.QuestHere == false && Status.Available == false)

What do these have to do with destroying your bitmap?

You may have meant

else if ((!NPCQuestOne.QuestHere || !Status.Available)) {
   // destroy image and exit quest screen
}

Because you would want to quit the quest screen if the NPC didn't have a Quest or if the quest was unavailable. But that's not what you're doing. You have hardcoded values in your function that will never change so it always does the same thing.

You want to load your bitmap once at the beginning of the game (checking to make sure it didn't return 0 indicating it didn't load properly) or at the beginning of the scene and then al_destroy_bitmap once at the end of the game or scene you are on. This way it is only in memory during your hero's visit to the quest giver. Or if it is a common occurrence, then keep it around longer - before and after the quest(s) is(are) sought.

int quest_num = -1;// negative one indicates there is no quest
if (-1 != (quest_num = CheckForQuestEvent())) {
 Quest q = GetQuest(quest_num);
 q.Image = GetImageForQuest(quest_num);
 if (!q.Image) {
  printf("Error. Failed to load %s\n" , GetImageNameForQuest(quest_num));
  return;
 }
 ShowQuest(q);
 al_destroy_bitmap(q.Image);
}

GullRaDriel
Member #3,861
September 2003
avatar

Edgar to the rescue ! :D

"Code is like shit - it only smells if it is not yours"
Allegro Wiki, full of examples and articles !!

Lasaqus7
Member #15,950
May 2015

Thanks Edgar for the reply

Lasaqus7 said:

if (NPCQuestOne.QuestHere == true && Status.Available == true) {
DrawQuestWindow(Status);
al_wait_for_event(event_queue, &ev);
}
else if (NPCQuestOne.QuestHere == false && Status.Available == false)
al_destroy_bitmap(Status.image);
else if (NPCQuestOne.QuestHere == false && Status.Available == false)

What do these have to do with destroying your bitmap?

That code ended up that way after trying to figure this out. It was the result of trying to add in code to try and get the action I wanted, but really all it is supposed to be is if there is a quest available at the quest giver then display a bitmap.
I did have everything working up to the point the user chooses Accept/Decline. So i know the bitmap was loading fine, then I ended up with this problem of trying to remove it on a mouse click event(that's why the mouse event is inside the function too).

Pretty difficult learning this and the only resource we got given was "watch youtube tutorials" and sometimes they just don't really cover the parts your doing.

I'll look at your code and figure out how to implement that into mine as it looks very different, and i'll get back to you if I can't :-)

Thanks again for the reply

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

I think what you're struggling with is the states of the quest operation that you want to operate on. There needs to be init code that deals with allocating memory and there needs to be destruction code that cleans it up when you're done. This means you can't hardcode the values for the quest inside the function, or else you need to wrap it with another function like I did.

The basic scheme should look like this :

Result WrapperFunction(Parameters p) {
  Data* dat = InitData(p);
  if (!dat) {Fail();}
  Result result = UseData(dat);
  FreeData(dat);
  return result;
}

Now your UseData function doesn't have to worry about allocating any memory at all, only using it properly.

So the UseData function, or in your case, the QuestInfo function, would simply display the image for the quest passed into it by the wrapper function until the user clicked on one of your onscreen mouse buttons.

beoran
Member #12,636
March 2011

Most likely you are still drawing the bitmap after you destroyed it. I'd load the bitmap a bit earlier and unload it later.

Apart from this problem, there is al_draw_text and, in allegro 5.1.9 al_draw_multiline_text, with which you could display the text of the quest without the need for a bitmap.

Lasaqus7
Member #15,950
May 2015

Thanks for your input but I couldn't get the bitmap section to work, but then again I was re-doing the code over and over and now it's all changed, although I do have 1 section of the quest working now.

Dizzy Egg
Member #10,824
March 2009
avatar

Couldn't you just check against NULL before deleting the bitmap, at least to get past crashing!

Something like:

if(myBitmap != NULL)
{
    al_destroy_bitmap(myBitmap);
}

If that stops it crashing at least you'll know the root cause, and can start fixing it from there?

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

Lasaqus7
Member #15,950
May 2015

It works now Dizzy, After getting to code working for the text showing on/off I decided to try and add in the bitmap for it. It was kinda the same issue and it works great.

Thanks for the reply

Go to: