Help with modifying Mappy code to work with multithreading
ryancoboy

Hey everyone, I was hoping someone with experience using mappy could help me out. I'm using multithreading. In my main thread I'm displaying the map and doing normal logic stuff. I'm using another thread to load maps. By using another thread to load maps I've needed change mappy's draw code to convert memory bitmaps to video bitmaps.

I did made this change in the MapDrawBG() function. with this code:

void MapDrawBG (int mapxo, int mapyo, int mapx, int mapy,int mapw, int maph)
{
    ......
    
    if (al_get_bitmap_flags((ALLEGRO_BITMAP *) blkdatapt->bgoff) & ALLEGRO_MEMORY_BITMAP)
    {
    ALLEGRO_BITMAP* Temp = al_clone_bitmap((ALLEGRO_BITMAP*) blkdatapt->bgoff);
    al_destroy_bitmap((ALLEGRO_BITMAP *)blkdatapt->bgoff);
    (ALLEGRO_BITMAP*)blkdatapt->bgoff = Temp;
    }
    
    ......
}

Thanks to "kazzmir" for this.

However the program crashes when the MapFreeMem() function is called in my second thread.
for example:
1. Initial map loads (in my main thread)
2. walk into a new area
3. new map loads (in the second thread)
4. walk back to the previous area
5. Crash (in the second thread)

Specifically at this part:

#SelectExpand
1void MapFreeMem(void) 2{ 3 ...... 4 if (abmTiles != NULL) 5 { 6 i = 0; 7 8 while (abmTiles[i]!=NULL) 9 { 10 al_destroy_bitmap (abmTiles[i]); //Crash Happens Here 11 i++; 12 } 13 free (abmTiles); 14 abmTiles = NULL; 15 } 16 ...... 17}

I'm hoping some with a lot of experience with mappy can help me out. I've uploaded the complete source for mappy (my modified version) for anyone who needs/wants to look at it.

The mappy source code, with the addition of mulithreading, is kind of difficult for me to understand. One of these days I'll need to re-write it to be 100% C++. But in the mean time if someone could help me tackle this problem that be great.

Thanks,
-Ryan

Audric

As said by Trent in your other topic, you can't access graphics stuff from two threads at the same time.
Releasing video bitmaps is one kind of "access".

ryancoboy

@Audric: If i read what you and Trent said correctly, it seems like you guys are saying the call to MapFreeMem() in my second thread is cause of the error. Am I correct?

Regardless I just spent a bunch of time modifying my code to make it so MapFreeMem() is only called in my Main thread. Yet, I get the exact same error, at the exact same spot, in my call to MapFreeMem(). before.

Any ideas?

Thanks,
-Ryan

Neil Walker

Not that it will help but:

1. There is a C++ version of mappy, it's at the mappy website, I think he calls it the universal version or something like that

2. If you think moving to Allegro 5 might help in any way, there is a version available here: http://www.allegro.cc/forums/thread/606962

3. Could you use memory bitmaps not video, they should be ok across threads

ryancoboy

@Neil Walker: I am using Allegro 5.0.5 currently, and I'm using a modified version of your converted mappy code.
Also, "your" mappy code isn't 100% C++ it uses a lot of C stuff in it. It still works with C++, but still uses old C features. I want to one day take out all that C stuff and replace it with it's C++ counterpart. I couldn't find the universal version you mentioned. Everything I found still uses C in some way.
The problem with using memory bitmaps is that they are extremely slow. I already tried running memory bitmaps only on my old laptop. The difference being a game that was playable with minimal lag (using video) and a game that was completely unresponsive and laggy (using memory).

Right now what i have it doing is:
Loading the data for the map in a second thread.
I'm then replacing that data with a converted video version in my main thread.
When I load go to load another new map I use the MapFreeMem() function in my main thread.
That is when I get the error.

Is this still wrong? I'm starting to run out of ideas for how to do this.

EDIT: Finally Fixed my problem!

For anyone else who may need help on this in the future:
1. Switch to using Allegro 5.1.X
2. Replace this:

ALLEGRO_BITMAP* Temp = al_clone_bitmap((ALLEGRO_BITMAP*) blkdatapt->bgoff);
al_destroy_bitmap((ALLEGRO_BITMAP *)blkdatapt->bgoff);
(ALLEGRO_BITMAP*)blkdatapt->bgoff = Temp;

with this:

al_convert_bitmap((ALLEGRO_BITMAP *) blkdatapt->bgoff);

Thanks to @kazzmir for showing me this alternate method.

Thread #611392. Printed from Allegro.cc