The masked_blit documentation mentions the source and destination bitmaps must have the same color depth. I don't know that it would cause a crash, but might be something to look at.
Printable View
The masked_blit documentation mentions the source and destination bitmaps must have the same color depth. I don't know that it would cause a crash, but might be something to look at.
I have all color depths set to 32 bit
Another thing to mention if I move the call to another function it works fine
You're not working with threads are you? All I can think of right now is to examine the pointers and make sure they are valid during the call that crashes. Is everything initialized to proper values at that point?
No threads at all actually. And yes as far as I can tell they have valid values.
Could I see a sample of where it doesn't crash?
Sure deal.
This is the whole function (in case I do something special in here I forgot about) I added 3 or so lines at the end just to test it drawing and it does draw top left corner of my screen a blackorb looking deal.
Code:void RedrawScreen()
{
if(FPSCNT == 0)FPSCNT = GetTickCount();
FPS++;
int mm,nm;
mm = player->GetY() - 10;
nm = player->GetX() - 14;
blit(LAYOUT,BUFFER,0,0,0,0,scrx,scry);
//Draw the map first complete map draw so if we have streched objects we can still use them
//We do it this way for changing tiles and such if we didn't want that we could put it in a layer by itself.
for(int m = 0;m < 21;m++)
{
for(int n = 0;n < 29;n++)
{
if(mm+m < 0 || nm+n < 0 || mm+m >= mymap->GetY() || nm+n >= mymap->GetX())
{
}else
{
blit(mymap->GetTile(nm+n,mm+m),BUFFER,0,0,48+n*32,48+m*32,32,32);
}
}
}
//Draw all the NPCs, monsters, and player
for(int m = 0;m < 21;m++)
{
for(int n = 0;n < 29;n++)
{
if(mm+m < 0 || nm+n < 0 || mm+m >= mymap->GetY() || nm+n >= mymap->GetX())
{
}else
{
for(int p = 0;p < max(mymap->GetNumObj(),max(mymap->GetNumNPC(),mymap->GetNumMonster()));p++)
{
if(p < mymap->GetNumObj())// Layer 0 BELOW everything but tiles so its good for doors and rugs.
{
tmpObj = mymap->GetObj(p);
if(tmpObj != NULL && tmpObj->GetLayer() == 0 && tmpObj->GetMapX() - nm == n && tmpObj->GetMapY() - mm == m && tmpObj->GetMapX() >= nm && tmpObj->GetMapX() <= nm+28 && tmpObj->GetMapY() >= mm && tmpObj->GetMapY() <= mm+21)
{
masked_blit(tmpObj->GetImage(),BUFFER,tmpObj->GetFrame()*tmpObj->GetX(),0,48+(tmpObj->GetMapX() - nm)*32,48+(tmpObj->GetMapY() - mm)*32,tmpObj->GetX(),tmpObj->GetY());
}
}
if(p < mymap->GetNumNPC())
{
tmpNPC = mymap->GetNPC(p);
if(tmpNPC != NULL && tmpNPC->GetX() - nm == n && tmpNPC->GetY() - mm == m && tmpNPC->GetX() >= nm && tmpNPC->GetX() <= nm+28 && tmpNPC->GetY() >= mm && tmpNPC->GetY() <= mm+21)
{
masked_blit(tmpNPC->GetIGPic(),BUFFER,(DOWN*3+step)*charx,0,48+(tmpNPC->GetX() - nm)*32-(charx/2)+16,48+(tmpNPC->GetY() - mm)*32-(chary/2),charx,chary);
}
}
if(p < mymap->GetNumMonster())
{
tmpMonster = mymap->GetMonster(p);
if(tmpMonster != NULL && tmpMonster->GetX() - nm == n && tmpMonster->GetY() - mm == m && tmpMonster->GetX() >= nm && tmpMonster->GetX() <= nm+28 && tmpMonster->GetY() >= mm && tmpMonster->GetY() <= mm+21)
{
if(!tmpMonster->IsDead())
{
masked_blit(tmpMonster->GetPic(),BUFFER,(tmpMonster->GetDir()*3+tmpMonster->GetStep())*charx,0,48+(tmpMonster->GetX() - nm)*32-(charx/2)+16,48+(tmpMonster->GetY() - mm)*32-(chary/2),charx,chary);
}else
if(GetTickCount()-tmpMonster->GetTimeOfDeath() < 1000)
{
masked_blit(tmpMonster->GetPic(),BUFFER,((GetTickCount()-tmpMonster->GetTimeOfDeath())/250)*charx,50,48+(tmpMonster->GetX() - nm)*32-(charx/2)+16,48+(tmpMonster->GetY() - mm)*32-(chary/2),charx,chary);
}
}
}
}
if(player->GetX()-nm == n && player->GetY()-mm == m)
{
if(!player->SwingingSword())
masked_blit(CHARACTER,BUFFER,(direction*3+player->GetStep())*charx,0,(scrx/2)-(charx/2),(scry/2)-(chary/2)-16,charx,chary);
else
masked_blit(CHARACTER,BUFFER,(direction*3+player->GetStep())*charx,chary,(scrx/2)-(charx/2),(scry/2)-(chary/2)-16,charx,chary);
}
}
}
masked_blit(mymap->GetLayerOne(),BUFFER,32*nm,(32*(mm+m)),48,48+(32*m),32*29,32);
}
// Highest object use layer 2 for clouds or overhead pipes etc.
masked_blit(mymap->GetLayerTwo(),BUFFER,32*nm,32*mm,48,48,32*29,32*21);
for(int m = 0;m < 21;m++)
{
for(int n = 0;n < 29;n++)
{
if(mm+m < 0 || nm+n < 0 || mm+m >= mymap->GetY() || nm+n >= mymap->GetX())
{
}else
{
for(int p = 0;p < mymap->GetNumObj();p++)
{
tmpObj = mymap->GetObj(p);
if(tmpObj != NULL && tmpObj->GetLayer() == 3 && tmpObj->GetMapX() - nm == n && tmpObj->GetMapY() - mm == m && tmpObj->GetMapX() >= nm && tmpObj->GetMapX() <= nm+28 && tmpObj->GetMapY() >= mm && tmpObj->GetMapY() <= mm+21)
{
masked_blit(tmpObj->GetImage(),BUFFER,tmpObj->GetFrame()*tmpObj->GetX(),0,48+(tmpObj->GetMapX() - nm)*32,48+(tmpObj->GetMapY() - mm)*32,tmpObj->GetX(),tmpObj->GetY());
}
}
}
}
}
if(drawlights)
for(int ap = 0;ap < mymap->GetNumObj();ap++) //for lighting not draws
{
tmpObj = mymap->GetObj(ap);
if(tmpObj != NULL && tmpObj->IsLightSource() && tmpObj->GetMapX() >= nm && tmpObj->GetMapX() <= nm+28 && tmpObj->GetMapY() >= mm && tmpObj->GetMapY() <= mm+21)
{
int ax = (tmpObj->GetMapX() - nm)*32;
int ay = (tmpObj->GetMapY() - mm)*32;
OnTheFlyLighting(tmpObj,ax,ay);
}
}
//draw the damage floats note if we hit more than 10 monsters with a spell not all the damage will draw - yet
for(int zmz=0;zmz<10;zmz++)
{
if(DamageFloats[zmz].damage != -1)
{
int timedifferance = GetTickCount() - DamageFloats[zmz].time;
char damagestr[3];
damagestr[2] = '\0';
if(DamageFloats[zmz].damage / 10 > 0)
{
damagestr[0] = '0' + DamageFloats[zmz].damage / 10;
}
else damagestr[0] = ' ';
damagestr[1] = '0' + DamageFloats[zmz].damage%10;
//multi color support with fades
int r,g,b;
r = getr32(DamageFloats[zmz].color)-(timedifferance/50)*2;
g = getg32(DamageFloats[zmz].color)-(timedifferance/50)*2;
b = getb32(DamageFloats[zmz].color)-(timedifferance/50)*2;
if(r < 0)r =0;
if(g < 0)g =0;
if(b < 0)b =0;
//draw with color
textout_ex(BUFFER,big_font,damagestr,DamageFloats[zmz].x,DamageFloats[zmz].y-((timedifferance/50)*1),
makecol(r,g,b),-1);
//housekeeping
if(timedifferance >= 1500)DamageFloats[zmz].damage = -1;
}
}
for(int azmz=0;azmz<15;azmz++)
{
if(Spells[azmz].Draw)
{
masked_blit(Spells[azmz].myspell->GetAnimation(),BUFFER,((GetTickCount()-Spells[azmz].StartTime)/Spells[azmz].myspell->GetFrameLength())*Spells[azmz].myspell->GetX(),0,(scrx/2)-Spells[azmz].myspell->GetX()/2,(scry/2)-Spells[azmz].myspell->GetY()/2,Spells[azmz].myspell->GetX(),Spells[azmz].myspell->GetY());
if(GetTickCount()-Spells[azmz].StartTime >= Spells[azmz].myspell->GetFrameLength()*Spells[azmz].myspell->GetNumFrames())
Spells[azmz].Draw = false; //no delete b/c it is not ours to delete.
}
}
if(showfps == true)
{
char countstr[20];
strcpy(countstr,"FPS: ");
countstr[5] = '0' + (OLDFPS%1000)/100;
countstr[6] = '0' + (OLDFPS%100)/10;
countstr[7] = '0' + OLDFPS%10;
countstr[8] = '\0';
textout_ex(BUFFER,big_font,countstr,0,0,makecol(255,255,255),-1);
}
masked_blit(HEALTHBAR,BUFFER,19,0,10,100+(player->GetHpLostAsPercent()*2)+scry/2,19,200-(player->GetHpLostAsPercent()*2));
masked_blit(HEALTHBAR,BUFFER,0,0,10,100+scry/2,19,200);
masked_blit(HEALTHBAR,BUFFER,38,0,990,100+(player->GetManaLostAsPercent()*2)+scry/2,19,200-(player->GetManaLostAsPercent()*2));
masked_blit(HEALTHBAR,BUFFER,0,0,990,100+scry/2,19,200);
masked_blit(XPBAR,BUFFER,0,7,(scrx/2)-75,750,(int)(player->GetXpAsPercent()*1.5),7);
masked_blit(XPBAR,BUFFER,0,0,(scrx/2)-75,750,150,7);
//THESES LINES HERE!!!!!!!!!!!!!!!!!!!!!!!!
Item *temp;
temp = resman->GetItem(2);
masked_blit(temp->GetPic(),BUFFER,0,0,0,0,64,64);
blit(BUFFER,screen,0,0,0,0,scrx,scry);
if(GetTickCount()-FPSCNT >= 1000)
{
OLDFPS = FPS;
FPS = 0;
FPSCNT = 0;
}
}
Okay, just to be clear, when you add those lines to RedrawScreen() it works fine, right?
I'm wondering about your loop inside of Run_Inventory(). Correct me if I'm wrong, but the user presses 'I' and that brings up the inventory which stays up until they press 'I' again?
Yes and Yes
Okay, well, this doesn't address your crashing, but Run_Inventory() has a tight loop. I'm assuming you have a separate polling function that deals with input handling? You would never be able to exit the inventory because the program is stuck drawing it forever and never allowing any other portion of the game to execute, unless you are using some other kind of input handling that I'm not aware of.
Out of curiosity, though, do you know if the game crashes the first time it tries to blit that item? Or does it happen the nth time? The blit function might not like being in that loop.
I am aware all I need it to do atm is draw then I will add the user input via mouse to move items around and equip etc all the good stuff. The first time to my knowledge.
What if you remove this line:
Does it still crash? Just wondering if it is having trouble doing a masked blit on top of another. It doesn't seem like you are doing that in RedrawScreen(), so maybe that's why it's fine.Code:masked_blit(INVENTORY,BUFFER,0,0,0,0,scrx,scry); //toss the grids.
Actually depending on the situation I do masked_blit over a masked_blit in RedrawScreen() there are far more variables in that to say it never happens (as the character height is actually > 1 tile's height)
If I remove that there is still an issue. Man I wish the debugger would work and not crash right now.
So I am still thinking maybe sometimes I get a good pointer sometimes I don't the question is why.
Code:void Item::SetPicPath(char *path,RGB *pal)
{
ofstream load_error;
load_error.open("Load Error.txt");
load_error<<"path: "<<path<<endl;
if(strcmp(path,"NULL") != 0)
{
load_error<<"path is not NULL"<<endl;
if(PIC)destroy_bitmap(PIC);
picpath = new char[strlen(path)+1];
strcpy(picpath,path);
load_error<<"pic path: "<<picpath<<endl;
PIC = load_bitmap(picpath,pal);
load_error<<"PIC: "<<PIC<<endl;
delete[] picpath;
if(!PIC)allegro_message("ERROR LOADING ITEM");
}
load_error.close();
}
So I keep hacking at this since it is holding the whole inventory routine up as far as testing goes...Code:path: art/Icons/BlackOrb.bmp
path is not NULL
pic path: art/Icons/BlackOrb.bmp
PIC: 0x9cae200
Decided to make a Item * and play with it and try to get the same crash/error.
What do I find but the program freezes up or enters a huge loop as soon as I try to draw using my GetPic() function - I have used this function with less error checking in my code elsewhere with no problems does anyone know if there is an Item class/struct/union floating around somewhere that is snagging me up? I am going to try to change it to myItem class and see if that fixes it.
I want to mention now I can not get it to work in either spot maybe this is headway or maybe I am going backwards here. Can't even get one instance of the class to blit so it is acting like the memory is having issues.
Oddly enough I have the picture working now. I had to remove all the SAMPLE * from the class I am not sure why it had me do this it would seem like they are unrelated and now my conclusion is there is something with Allegro that is not liking how things are implemented. Maybe someone has some experiance with allegro out there and has seen this before, maybe not if you are out there help :P.
Thanks to everyone that helped out even with memory leaks I would be tracking those down for a long long time I have no doubt.
I have written a pretty decent bitmap manager class for allegro for my now suspended development space shooter.
Attached is the wrapper class I wrote.
This might make you life easier when dealing with copying bitmaps and such.
Thanks - but generally I won't be copying bitmaps since really I just need to pass a pointer around so they actually all read from the same place - I intend to remove that code it was for troubleshooting. Most animations are run off timers and frames within a bitmap so everyone can look at the same bitmap and decide what they are doing :)
So I went to the allegro forums trying to get help since it seemed possibly specific to their class(es).
http://www.allegro.cc/forums/thread/.../861731#target
That is the response.