1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

small refactoring in mapHandler, first part of object-to-screen blitting (8bpp with alpha to 24bpp/32bpp without alpha) that will improve speed and memory usage (faster flag color selecting, 8bpp instead of 32bpp defHandlers, no need of secondAlphaTransform)

This commit is contained in:
mateuszb 2008-02-09 14:44:32 +00:00
parent 7942f97870
commit 2b91d6129b
4 changed files with 184 additions and 331 deletions

View File

@ -15,7 +15,8 @@ SDL_Surface * CSDL_Ext::newSurface(int w, int h, SDL_Surface * mod) //creates ne
SDL_Surface * CSDL_Ext::copySurface(SDL_Surface * mod) //returns copy of given surface
{
return SDL_DisplayFormat(mod);
//return SDL_DisplayFormat(mod);
return SDL_ConvertSurface(mod, mod->format, mod->flags);
}
bool isItIn(const SDL_Rect * rect, int x, int y)
{
@ -489,6 +490,96 @@ SDL_Surface * CSDL_Ext::secondAlphaTransform(SDL_Surface * src, SDL_Surface * al
}
}
return hide2;
//return copySurface(src);
}
void CSDL_Ext::blit8bppAlphaTo24bpp(SDL_Surface * src, SDL_Rect * srcRect, SDL_Surface * dst, SDL_Rect * dstRect)
{
if(src && src->format->BytesPerPixel==1 && dst && (dst->format->BytesPerPixel==3 || dst->format->BytesPerPixel==4)) //everything's ok
{
int xFromSrc=-1, xToSrc=-1,
yFromSrc=-1, yToSrc=-1; //source pseudorect without errors
int xO=-1, yO=-1; //dst offsets
if(srcRect)
{
xFromSrc = srcRect->x;
yFromSrc = srcRect->y;
xToSrc = srcRect->w + srcRect->x;
yToSrc = srcRect->h + srcRect->y;
}
else
{
xFromSrc = 0;
yFromSrc = 0;
xToSrc = src->w;
yToSrc = src->h;
if(dstRect)
{
if(dstRect->w<xToSrc)
{
xToSrc = dstRect->w;
}
if(dstRect->h<yToSrc)
{
yToSrc = dstRect->h;
}
}
else
{
if(dst->w<xToSrc)
{
xToSrc = dst->w;
}
if(dst->h<yToSrc)
{
yToSrc = dst->h;
}
}
}
if(dstRect)
{
xO = dstRect->x - xFromSrc;
yO = dstRect->y - yFromSrc;
}
else
{
xO = -xFromSrc;
yO = -yFromSrc;
}
if(xO+xToSrc>dst->w)
{
xToSrc = dst->w - xO;
}
if(yO+yToSrc>dst->h)
{
yToSrc = dst->h - yO;
}
if(xO+xFromSrc<0)
{
xFromSrc = - xO;
}
if(yO+yFromSrc<0)
{
yFromSrc = - yO;
}
for(int x=xFromSrc; x<xToSrc; ++x)
{
for(int y=yFromSrc; y<yToSrc; ++y)
{
SDL_Color tbc = src->format->palette->colors[*((Uint8*)src->pixels + y*src->pitch + x)]; //color to blit
Uint8 * p = (Uint8*)dst->pixels + (y+yO)*dst->pitch + (x+xO)*dst->format->BytesPerPixel; //place to blit at
p[0] = ((Uint32)tbc.unused*(Uint32)p[0] + (Uint32)tbc.r*(Uint32)(255-tbc.unused))>>8; //red
p[1] = ((Uint32)tbc.unused*(Uint32)p[1] + (Uint32)tbc.g*(Uint32)(255-tbc.unused))>>8; //green
p[2] = ((Uint32)tbc.unused*(Uint32)p[2] + (Uint32)tbc.b*(Uint32)(255-tbc.unused))>>8; //blue
}
}
}
}
Uint32 CSDL_Ext::colorToUint32(const SDL_Color * color)

View File

@ -35,6 +35,7 @@ namespace CSDL_Ext
SDL_Color SDL_GetPixelColor(SDL_Surface *surface, int x, int y);
SDL_Surface * alphaTransform(SDL_Surface * src); //adds transparency and shadows (partial handling only; see examples of using for details)
SDL_Surface * secondAlphaTransform(SDL_Surface * src, SDL_Surface * alpha); //alpha is a surface we want to blit src to
void blit8bppAlphaTo24bpp(SDL_Surface * src, SDL_Rect * srcRect, SDL_Surface * dst, SDL_Rect * dstRect); //blits 8 bpp surface with alpha channel to 24 bpp surface
void fullAlphaTransform(SDL_Surface *& src); //performs first and second alpha transform
Uint32 colorToUint32(const SDL_Color * color); //little endian only
void printTo(std::string text, int x, int y, TTF_Font * font, SDL_Color kolor=tytulowy, SDL_Surface * dst=ekran, unsigned char quality = 2);// quality: 0 - lowest, 1 - medium, 2 - highest; prints at right bottom corner of specific area. position of corner indicated by (x, y)

View File

@ -796,7 +796,10 @@ SDL_Surface * CMapHandler::terrainRect(int x, int y, int dx, int dy, int level,
sr.x=bx*32;
sr.h=sr.w=32;
if(ttiles[x+bx][y+by][level].rivbitmap.size())
{
SDL_BlitSurface(ttiles[x+bx][y+by][level].rivbitmap[anim%ttiles[x+bx][y+by][level].rivbitmap.size()],NULL,su,&sr);
//CSDL_Ext::blit8bppAlphaTo24bpp(ttiles[x+bx][y+by][level].rivbitmap[anim%ttiles[x+bx][y+by][level].rivbitmap.size()],NULL,su,&sr);
}
}
}
////rivers printed
@ -832,6 +835,7 @@ SDL_Surface * CMapHandler::terrainRect(int x, int y, int dx, int dy, int level,
SDL_Rect pp = ttiles[x+bx][y+by][level].objects[h].second.first;
CGHeroInstance * themp = (dynamic_cast<CGHeroInstance*>(ttiles[x+bx][y+by][level].objects[h].first));
if(themp && themp->moveDir && !themp->isStanding && themp->ID!=62) //last condition - this is not prison
{
int imgVal = 8;
@ -840,147 +844,24 @@ SDL_Surface * CMapHandler::terrainRect(int x, int y, int dx, int dy, int level,
if(themp->type==NULL)
continue;
std::vector<Cimage> & iv = themp->type->heroClass->moveAnim->ourImages;
switch(themp->moveDir)
int gg;
for(gg=0; gg<iv.size(); ++gg)
{
case 1:
if(iv[gg].groupNumber==getHeroFrameNum(themp->moveDir, !themp->isStanding))
{
int gg;
for(gg=0; gg<iv.size(); ++gg)
{
if(iv[gg].groupNumber==10)
{
tb = iv[gg+heroAnim%imgVal].bitmap;
break;
}
}
SDL_BlitSurface(tb,&pp,su,&sr);
pp.y+=imgVal*2-32;
sr.y-=16;
SDL_BlitSurface(CGI->heroh->flags4[themp->getOwner()]->ourImages[gg+heroAnim%imgVal+35].bitmap, &pp, su, &sr);
break;
}
case 2:
{
int gg;
for(gg=0; gg<iv.size(); ++gg)
{
if(iv[gg].groupNumber==5)
{
tb = iv[gg+heroAnim%imgVal].bitmap;
break;
}
}
SDL_BlitSurface(tb,&pp,su,&sr);
pp.y+=imgVal*2-32;
sr.y-=16;
SDL_BlitSurface(CGI->heroh->flags4[themp->getOwner()]->ourImages[gg+heroAnim%imgVal+35].bitmap, &pp, su, &sr);
break;
}
case 3:
{
int gg;
for(gg=0; gg<iv.size(); ++gg)
{
if(iv[gg].groupNumber==6)
{
tb = iv[gg+heroAnim%imgVal].bitmap;
break;
}
}
SDL_BlitSurface(tb,&pp,su,&sr);
pp.y+=imgVal*2-32;
sr.y-=16;
SDL_BlitSurface(CGI->heroh->flags4[themp->getOwner()]->ourImages[gg+heroAnim%imgVal+35].bitmap, &pp, su, &sr);
break;
}
case 4:
{
int gg;
for(gg=0; gg<iv.size(); ++gg)
{
if(iv[gg].groupNumber==7)
{
tb = iv[gg+heroAnim%imgVal].bitmap;
break;
}
}
SDL_BlitSurface(tb,&pp,su,&sr);
pp.y+=imgVal*2-32;
sr.y-=16;
SDL_BlitSurface(CGI->heroh->flags4[themp->getOwner()]->ourImages[gg+heroAnim%imgVal+35].bitmap, &pp, su, &sr);
break;
}
case 5:
{
int gg;
for(gg=0; gg<iv.size(); ++gg)
{
if(iv[gg].groupNumber==8)
{
tb = iv[gg+heroAnim%imgVal].bitmap;
break;
}
}
SDL_BlitSurface(tb,&pp,su,&sr);
pp.y+=imgVal*2-32;
sr.y-=16;
SDL_BlitSurface(CGI->heroh->flags4[themp->getOwner()]->ourImages[gg+heroAnim%imgVal+35].bitmap, &pp, su, &sr);
break;
}
case 6: //ok
{
int gg;
for(gg=0; gg<iv.size(); ++gg)
{
if(iv[gg].groupNumber==9)
{
tb = iv[gg+heroAnim%imgVal].bitmap;
break;
}
}
SDL_BlitSurface(tb,&pp,su,&sr);
pp.y+=imgVal*2-32;
sr.y-=16;
SDL_BlitSurface(CGI->heroh->flags4[themp->getOwner()]->ourImages[gg+heroAnim%imgVal+35].bitmap, &pp, su, &sr);
break;
}
case 7:
{
int gg;
for(gg=0; gg<iv.size(); ++gg)
{
if(iv[gg].groupNumber==12)
{
tb = iv[gg+heroAnim%imgVal].bitmap;
break;
}
}
SDL_BlitSurface(tb,&pp,su,&sr);
pp.y+=imgVal*2-32;
sr.y-=16;
SDL_BlitSurface(CGI->heroh->flags4[themp->getOwner()]->ourImages[gg+heroAnim%imgVal+35].bitmap, &pp, su, &sr);
break;
}
case 8:
{
int gg;
for(gg=0; gg<iv.size(); ++gg)
{
if(iv[gg].groupNumber==11)
{
tb = iv[gg+heroAnim%imgVal].bitmap;
break;
}
}
SDL_BlitSurface(tb,&pp,su,&sr);
pp.y+=imgVal*2-32;
sr.y-=16;
SDL_BlitSurface(CGI->heroh->flags4[themp->getOwner()]->ourImages[gg+heroAnim%imgVal+35].bitmap, &pp, su, &sr);
tb = iv[gg+heroAnim%imgVal].bitmap;
break;
}
}
SDL_BlitSurface(tb,&pp,su,&sr);
//CSDL_Ext::blit8bppAlphaTo24bpp(tb,&pp,su,&sr);
pp.y+=imgVal*2-32;
sr.y-=16;
SDL_BlitSurface(CGI->heroh->flags4[themp->getOwner()]->ourImages[gg+heroAnim%imgVal+35].bitmap, &pp, su, &sr);
//CSDL_Ext::blit8bppAlphaTo24bpp(CGI->heroh->flags4[themp->getOwner()]->ourImages[gg+heroAnim%imgVal+35].bitmap, &pp, su, &sr);
}
else if(themp && themp->moveDir && themp->isStanding && themp->ID!=62) //last condition - this is not prison
else if(themp && themp->moveDir && themp->isStanding && themp->ID!=62) //last condition - this is not prison)
{
int imgVal = 8;
SDL_Surface * tb;
@ -988,190 +869,33 @@ SDL_Surface * CMapHandler::terrainRect(int x, int y, int dx, int dy, int level,
if(themp->type==NULL)
continue;
std::vector<Cimage> & iv = themp->type->heroClass->moveAnim->ourImages;
switch(themp->moveDir)
int gg;
for(gg=0; gg<iv.size(); ++gg)
{
case 1:
if(iv[gg].groupNumber==getHeroFrameNum(themp->moveDir, !themp->isStanding))
{
int gg;
for(gg=0; gg<iv.size(); ++gg)
{
if(iv[gg].groupNumber==13)
{
tb = iv[gg].bitmap;
break;
}
}
SDL_BlitSurface(tb,&pp,su,&sr);
if(themp->pos.x==x+bx && themp->pos.y==y+by)
{
SDL_Rect bufr = sr;
bufr.x-=2*32;
bufr.y-=1*32;
SDL_BlitSurface(CGI->heroh->flags4[themp->getOwner()]->ourImages[13*8+heroAnim%imgVal].bitmap, NULL, su, &bufr);
themp->flagPrinted = true;
}
break;
}
case 2:
{
int gg;
for(gg=0; gg<iv.size(); ++gg)
{
if(iv[gg].groupNumber==0)
{
tb = iv[gg].bitmap;
break;
}
}
SDL_BlitSurface(tb,&pp,su,&sr);
if(themp->pos.x==x+bx && themp->pos.y==y+by)
{
SDL_Rect bufr = sr;
bufr.x-=2*32;
bufr.y-=1*32;
SDL_BlitSurface(CGI->heroh->flags4[themp->getOwner()]->ourImages[heroAnim%imgVal].bitmap, NULL, su, &bufr);
themp->flagPrinted = true;
}
break;
}
case 3:
{
int gg;
for(gg=0; gg<iv.size(); ++gg)
{
if(iv[gg].groupNumber==1)
{
tb = iv[gg].bitmap;
break;
}
}
SDL_BlitSurface(tb,&pp,su,&sr);
if(themp->pos.x==x+bx && themp->pos.y==y+by)
{
SDL_Rect bufr = sr;
bufr.x-=2*32;
bufr.y-=1*32;
SDL_BlitSurface(CGI->heroh->flags4[themp->getOwner()]->ourImages[8+heroAnim%imgVal].bitmap, NULL, su, &bufr);
themp->flagPrinted = true;
}
break;
}
case 4:
{
int gg;
for(gg=0; gg<iv.size(); ++gg)
{
if(iv[gg].groupNumber==2)
{
tb = iv[gg].bitmap;
break;
}
}
SDL_BlitSurface(tb,&pp,su,&sr);
if(themp->pos.x==x+bx && themp->pos.y==y+by)
{
SDL_Rect bufr = sr;
bufr.x-=2*32;
bufr.y-=1*32;
SDL_BlitSurface(CGI->heroh->flags4[themp->getOwner()]->ourImages[2*8+heroAnim%imgVal].bitmap, NULL, su, &bufr);
themp->flagPrinted = true;
}
break;
}
case 5:
{
int gg;
for(gg=0; gg<iv.size(); ++gg)
{
if(iv[gg].groupNumber==3)
{
tb = iv[gg].bitmap;
break;
}
}
SDL_BlitSurface(tb,&pp,su,&sr);
if(themp->pos.x==x+bx && themp->pos.y==y+by)
{
SDL_Rect bufr = sr;
bufr.x-=2*32;
bufr.y-=1*32;
SDL_BlitSurface(CGI->heroh->flags4[themp->getOwner()]->ourImages[3*8+heroAnim%imgVal].bitmap, NULL, su, &bufr);
themp->flagPrinted = true;
}
break;
}
case 6:
{
int gg;
for(gg=0; gg<iv.size(); ++gg)
{
if(iv[gg].groupNumber==4)
{
tb = iv[gg].bitmap;
break;
}
}
SDL_BlitSurface(tb,&pp,su,&sr);
if(themp->pos.x==x+bx && themp->pos.y==y+by)
{
SDL_Rect bufr = sr;
bufr.x-=2*32;
bufr.y-=1*32;
SDL_BlitSurface(CGI->heroh->flags4[themp->getOwner()]->ourImages[4*8+heroAnim%imgVal].bitmap, NULL, su, &bufr);
themp->flagPrinted = true;
}
break;
}
case 7:
{
int gg;
for(gg=0; gg<iv.size(); ++gg)
{
if(iv[gg].groupNumber==15)
{
tb = iv[gg].bitmap;
break;
}
}
SDL_BlitSurface(tb,&pp,su,&sr);
if(themp->pos.x==x+bx && themp->pos.y==y+by)
{
SDL_Rect bufr = sr;
bufr.x-=2*32;
bufr.y-=1*32;
SDL_BlitSurface(CGI->heroh->flags4[themp->getOwner()]->ourImages[15*8+heroAnim%imgVal].bitmap, NULL, su, &bufr);
themp->flagPrinted = true;
}
break;
}
case 8:
{
int gg;
for(gg=0; gg<iv.size(); ++gg)
{
if(iv[gg].groupNumber==14)
{
tb = iv[gg].bitmap;
break;
}
}
SDL_BlitSurface(tb,&pp,su,&sr);
if(themp->pos.x==x+bx && themp->pos.y==y+by)
{
SDL_Rect bufr = sr;
bufr.x-=2*32;
bufr.y-=1*32;
SDL_BlitSurface(CGI->heroh->flags4[themp->getOwner()]->ourImages[14*8+heroAnim%imgVal].bitmap, NULL, su, &bufr);
themp->flagPrinted = true;
}
tb = iv[gg].bitmap;
break;
}
}
SDL_BlitSurface(tb,&pp,su,&sr);
//CSDL_Ext::blit8bppAlphaTo24bpp(tb,&pp,su,&sr);
if(themp->pos.x==x+bx && themp->pos.y==y+by)
{
SDL_Rect bufr = sr;
bufr.x-=2*32;
bufr.y-=1*32;
SDL_BlitSurface(CGI->heroh->flags4[themp->getOwner()]->ourImages[ getHeroFrameNum(themp->moveDir, !themp->isStanding) *8+heroAnim%imgVal].bitmap, NULL, su, &bufr);
//CSDL_Ext::blit8bppAlphaTo24bpp(CGI->heroh->flags4[themp->getOwner()]->ourImages[ getHeroFrameNum(themp->moveDir, !themp->isStanding) *8+heroAnim%imgVal].bitmap, NULL, su, &bufr);
themp->flagPrinted = true;
}
}
else
{
int imgVal = ttiles[x+bx][y+by][level].objects[h].first->defInfo->handler->ourImages.size();
SDL_BlitSurface(ttiles[x+bx][y+by][level].objects[h].first->defInfo->handler->ourImages[anim%imgVal].bitmap,&pp,su,&sr);
//CSDL_Ext::blit8bppAlphaTo24bpp(ttiles[x+bx][y+by][level].objects[h].first->defInfo->handler->ourImages[anim%imgVal].bitmap,&pp,su,&sr);
}
//printing appropriate flag colour
if(ttiles[x+bx][y+by][level].objects[h].second.second.size())
@ -1220,28 +944,12 @@ SDL_Surface * CMapHandler::terrainRect(int x, int y, int dx, int dy, int level,
sr.y=by*32;
sr.x=bx*32;
sr.h=sr.w=32;
if (!level)
if(bx+x>=0 && by+y>=0 && bx+x<CGI->mh->reader->map.width && by+y<CGI->mh->reader->map.height && !visibilityMap[bx+x][by+y][level])
{
//if( bx+x>-1 && by+y>-1 && bx+x<visibilityMap.size()-(-1) && by+y<visibilityMap[0].size()-(-1) && !visibilityMap[bx+x][by+y][0])
if(bx+x>=0 && by+y>=0 && bx+x<CGI->mh->reader->map.width && by+y<CGI->mh->reader->map.height && !visibilityMap[bx+x][by+y][0])
{
SDL_Surface * hide = getVisBitmap(bx+x, by+y, visibilityMap, 0);
//SDL_Surface * hide2 = CSDL_Ext::secondAlphaTransform(hide, su);
SDL_BlitSurface(hide, NULL, su, &sr);
//SDL_FreeSurface(hide2);
}
}
else
{
//if( bx+x>-1 && by+y>-1 && bx+x<visibilityMap.size()-(-1) && by+y<visibilityMap[0].size()-(-1) && !visibilityMap[bx+x][by+y][1])
if(bx+x>=0 && by+y>=0 && bx+x<CGI->mh->reader->map.width && by+y<CGI->mh->reader->map.height && !visibilityMap[bx+x][by+y][1])
{
SDL_Surface * hide = getVisBitmap(bx+x, by+y, visibilityMap, 1);
//SDL_Surface * hide2 = CSDL_Ext::secondAlphaTransform(hide, su);
SDL_BlitSurface(hide, NULL, su, &sr);
//SDL_FreeSurface(hide2);
}
SDL_Surface * hide = getVisBitmap(bx+x, by+y, visibilityMap, level);
SDL_BlitSurface(hide, NULL, su, &sr);
//CSDL_Ext::blit8bppAlphaTo24bpp(hide, NULL, su, &sr);
}
}
}
@ -1831,3 +1539,55 @@ bool CMapHandler::recalculateHideVisPosUnderObj(CGObjectInstance *obj, bool with
}
return true;
}
unsigned char CMapHandler::getHeroFrameNum(const unsigned char &dir, const bool &isMoving) const
{
if(isMoving)
{
switch(dir)
{
case 1:
return 10;
case 2:
return 5;
case 3:
return 6;
case 4:
return 7;
case 5:
return 8;
case 6:
return 9;
case 7:
return 12;
case 8:
return 11;
default:
return -1; //should never happen
}
}
else //if(isMoving)
{
switch(dir)
{
case 1:
return 13;
case 2:
return 0;
case 3:
return 1;
case 4:
return 2;
case 5:
return 3;
case 6:
return 4;
case 7:
return 15;
case 8:
return 14;
default:
return -1; //should never happen
}
}
}

View File

@ -105,6 +105,7 @@ public:
SDL_Surface * terrBitmap(int x, int y);
SDL_Surface * undTerrBitmap(int x, int y);
std::string getRandomizedDefName(CGDefInfo* di, CGObjectInstance * obj = NULL); //objinstance needed only for heroes and towns
unsigned char getHeroFrameNum(const unsigned char & dir, const bool & isMoving) const; //terrainRect helper function
};