📄 gfx.cpp
字号:
/*
* ============================================================================
* Name : CGlobalData from GlobalData.cpp
* Part of : Game
* Created : 2003-06-16 by Qiu Wei Min
* Modified : 2003-09-03 by Zheng Jie Sheng to adapt on LGVX6000
* Implementation notes:
*
* Version :
* Copyright: Gameloft S.A.
* ============================================================================
*/
// INCLUDE FILES
#include "gfx.h"
#include "simplememory.h"
#include "resfile.h"
#include "imath.h"
#include "Sysdef.h"
// ================= MEMBER FUNCTIONS =======================
unsigned short BlendColor(unsigned short s, unsigned short d)
{
//(255-((255-s)*(255-d)))/255
unsigned short tempr = 255-(255-RCOLOR(s))*(255-RCOLOR(d))/255, tempg = 255-(255-GCOLOR(s))*(255-GCOLOR(d))/255,
tempb = 255-(255-BCOLOR(s))*(255-BCOLOR(d))/255;
return MAKERGB(tempr, tempg, tempb);
}
CGfx::CGfx(CEngine *pEngine)
{
for(int i=0;i<256;i++)
m_tmppal[i] = 0;
m_pEngine = pEngine;
m_pVideo = NULL;
m_bw_level = 0;
m_pLastBWPal = NULL;
idisp = m_pEngine->m_pIDisplay;
}
CGfx::~CGfx()
{
}
GFXBMP* CGfx::LoadBmp(const char *pName, bool bGlobal)
{
CResFile *pFile = m_pEngine->GetRes();
void *h = pFile->FindRecord(pName);
GFXBMP *p;
if(h == NULL)
{
SYS_ASSERT(0);
return NULL;
}
p = (GFXBMP*)pFile->ReadBMPToHeap(h, bGlobal);
return p;
}
//##ModelId=402850A40343
void CGfx::Blt8_16(GFXBMP *pDes, int dx, int dy, int w, int h, GFXBMP *pSrc, int sx, int sy, int flag)
{
int hflip = flag & GFX_FLIPX; // flip flag
int vflip = flag & GFX_FLIPY;
unsigned short *pD, *pE, *pPal;
unsigned char *pS;
int i;
int s_space, d_space;
//copy to buffer
if(m_bw_level)
{
ComputBWPalette((unsigned short*)pSrc->pData, pSrc->npal);
pPal = m_tmppal + ((flag >> 8) & 0xff);
}
else
pPal = (unsigned short*)pSrc->pData + ((flag >> 8) & 0xff);
pS = pSrc->pData + pSrc->w * sy + sx + pSrc->npal * 2;
s_space= (pSrc->w - w);
pD = (unsigned short*)(pDes->pData + (pDes->w * dy + dx) * 2);
if( hflip && vflip){
d_space = -pDes->w + w;
pD += (h-1) *pDes->w +(w-1); //move to(w-1,h-1)
} else if( hflip ){
d_space = pDes->w + w ;
pD += w -1; //move to (w-1,0)
} else if( vflip)
{
d_space = -pDes->w - w ;
pD += (h-1)*pDes->w; //move to the (0,7)
} else { //no flip
d_space = pDes->w - w;
}
if(pSrc->flag & GFXBMP_TRANS)
{
if((flag & GFX_SEMITRANS) == 0)
{
for(i = 0; i < h; i++)
{
if(!hflip)
{
pE = pD + w;
while(pD < pE)
{
if( *pS)
*pD = pPal[*pS];
pD++;
pS++;
}
}
else
{
pE = pD - w;
while(pD > pE)
{
if( *pS)
*pD = pPal[*pS];
pD--;
pS++;
}
}
pS += s_space;
pD += d_space;
}
}
else
{
for(i = 0; i < h; i++)
{
if(!hflip)
{
pE = pD + w;
while(pD < pE)
{
if( *pS)
{
*pD = BlendColor(pPal[*pS], *pD);//(pPal[*pS] >> 1) & 0x777) + ((*pD >> 1) & 0x777);
}
pD++;
pS++;
}
}
else
{
pE = pD - w;
while(pD > pE)
{
if( *pS)
{
*pD = BlendColor(pPal[*pS], *pD);//((pPal[*pS] >> 1) & 0x777) + ((*pD >> 1) & 0x777);
}
pD--;
pS++;
}
}
pS += s_space;
pD += d_space;
}
}
}
else {
for(i = 0; i < h; i++)
{
if(!hflip)
{
pE = pD + w - 8;
while(pD < pE)
{
*pD++ = pPal[*pS++];
*pD++ = pPal[*pS++];
*pD++ = pPal[*pS++];
*pD++ = pPal[*pS++];
*pD++ = pPal[*pS++];
*pD++ = pPal[*pS++];
*pD++ = pPal[*pS++];
*pD++ = pPal[*pS++];
}
pE += 8;
while(pD < pE)
{
*pD++ = pPal[*pS++];
}
}
else
{
pE = pD - w + 8;
while(pD > pE)
{
*pD-- = pPal[*pS++];
*pD-- = pPal[*pS++];
*pD-- = pPal[*pS++];
*pD-- = pPal[*pS++];
*pD-- = pPal[*pS++];
*pD-- = pPal[*pS++];
*pD-- = pPal[*pS++];
*pD-- = pPal[*pS++];
}
pE -= 8;
while(pD > pE)
{
*pD-- = pPal[*pS++];
}
}
pS += s_space;
pD += d_space;
}
}
}
//##ModelId=402850A40339
void CGfx::Blt16_16(GFXBMP *pDes, int dx, int dy, int w, int h, GFXBMP *pSrc, int sx, int sy, int flag)
{
register unsigned short *pS, *pD;
//
unsigned short *pE;
int i;
//
pS = (unsigned short*)(pSrc->pData + (pSrc->w * sy + sx) * 2);
pD = (unsigned short*)(pDes->pData + (pDes->w * dy + dx) * 2);
if(flag == 0)
{
//SYS_ASSERT(((int)pS & 0x3) == 0 && ((int)pD & 0x3) == 0);
#if !defined AEE_SIMULATOR //&& !defined BREW11
if(((int)pS & 0x3) == 0 && ((int)pD & 0x3) == 0)
LongCopy2((unsigned char*)pD, (unsigned char*)pS, w*2, h, (pDes->w - w)*2,(pSrc->w - w)*2);
#else
//LongCopy1(pD, pS, w, h, (pDes->w - w),(pSrc->w - w));
for( i = 0; i < h; i++)
{
pE = pD + w;
while(pD < pE)
{
*pD++ = *pS++;
}
pD += (pDes->w - w);
pS += (pSrc->w - w);
}
#endif
}
else if (flag & GFX_SEMITRANS)
{
for( i = 0; i < h; i++)
{
pE = pD + w;
while(pD < pE)
{
//color blend
*pD = BlendColor(*pS, *pD);
pS++;
pD++;
}
pD += (pDes->w - w);
pS += (pSrc->w - w);
}
}
}
//##ModelId=402850A4032C
void CGfx::Blt(GFXBMP *pDes, int dx, int dy, int w, int h, GFXBMP *pSrc, int sx, int sy, int flag)
{
SYS_ASSERT(pSrc!=NULL);
SYS_ASSERT(pDes!=NULL);
int invisible;
//set clip area, it's long and puzzling...
if(dx < 0 )
{
if(flag & GFX_ROT90)
{
h += dx;
if(flag & GFX_FLIPX) sy -= dx;
}
else
{
w += dx;
if(!(flag & GFX_FLIPX)) sx -= dx;
}
dx= 0;
}
if(flag & GFX_ROT90)
{
invisible = dx + h - pDes->w;
if(invisible > 0)
{
if(!(flag & GFX_FLIPX)) sy += invisible;
h -= invisible;
}
}
else
{
invisible = dx + w - pDes->w;
if(invisible > 0)
{
if(flag & GFX_FLIPX) sx += invisible;
w -= invisible;
}
}
if(dy < 0 )
{
if(flag & GFX_ROT90)
{
w += dy;
if(!(flag & GFX_FLIPY)) sx -= dy;
}
else
{
h += dy;
if(!(flag & GFX_FLIPY)) sy -= dy;
}
dy= 0;
}
if(flag & GFX_ROT90)
{
invisible = dy + w - pDes->h;
if(invisible > 0)
{
if(flag & GFX_FLIPY) sx += invisible;
w -= invisible;
}
}
else
{
invisible = dy + h - pDes->h;
if(invisible > 0)
{
if(flag & GFX_FLIPY) sy += invisible;
h -= invisible;
}
}
if(w<=0 || h <=0)
return;
if(pDes->bpp == 16)
{
if(pSrc->bpp == 8)
{
Blt8_16(pDes, dx, dy, w, h, pSrc, sx, sy, flag);
}
else// if(pSrc->flag == 0)
Blt16_16(pDes, dx, dy, w, h, pSrc, sx, sy, flag);
//else //if(pSrc->flag & GFXBMP_ALPHA)
{
//SYS_ASSERT(0);
//Blt16_16_Alpha(pDes, dx, dy, w, h, pSrc, sx, sy, flag);
}
}
}
//##ModelId=402850A40320
void CGfx::DrawBmp(int dx, int dy, int w, int h, GFXBMP *pSrc, int sx, int sy, int flag)
{
SYS_ASSERT(m_pVideo != NULL);
Blt(m_pVideo, dx, dy, w, h, pSrc, sx, sy, flag);
}
//this function is only worked for 8 bits indexed bitmaps. And it's not optimized.
void CGfx::DrawRotBmp(int dx, int dy, int w, int h, GFXBMP *pSrc, int sx, int sy, int rotangle, int flag)
{
/*
int i, j;
unsigned short *pD, *pPal;
unsigned char *pS;
int tempdx, tempdy;
pPal = (unsigned short*)pSrc->pData;
pS = pSrc->pData + pSrc->npal * 2;
pD = (unsigned short*)(m_pVideo->pData);
for( i = 0; i < h; i++)
{
for( j = 0; j < w; j++)
{
tempdx = ((j*Cosinus(rotangle)-i*Sinus(rotangle))>>COS_SIN_SHIFT) + dx;
tempdy = ((j*Sinus(rotangle)+i*Cosinus(rotangle))>>COS_SIN_SHIFT) + dy;
if (tempdx < m_pVideo->w && tempdy < m_pVideo->h && tempdx >= 0 && tempdy >=0 )
{
pD[tempdy*m_pVideo->w + tempdx] = BlendColor(pPal[pS[pSrc->w*i+j]], pD[tempdy*m_pVideo->w + tempdx]);
}
}
}
*/
int l, t, r, b, i, j, u, v, vcos, vsin;
unsigned short *pD, *pPal;
unsigned char *pS;
l = -w>>1; t = -h>>1; r = l + w; b = t + h;
int xy[4][2];
Rotate(l, t, xy[0][0], xy[0][1], rotangle);
Rotate(r, t, xy[1][0], xy[1][1], rotangle);
Rotate(l, b, xy[2][0], xy[2][1], rotangle);
Rotate(r, b, xy[3][0], xy[3][1], rotangle);
l = xy[0][0]; r = xy[0][0];
t = xy[0][1]; b = xy[0][1];
for(i = 1; i < 4; i++)
{
if(l > xy[i][0]) l = xy[i][0];
if(r < xy[i][0]) r = xy[i][0];
if(t > xy[i][1]) t = xy[i][1];
if(b < xy[i][1]) b = xy[i][1];
}
l += dx; t += dy; r += dx; b += dy;
if(l < 0) l = 0;
if(r > m_pVideo->w) r = m_pVideo->w - 1;
if(t < 0) t = 0;
if(b > m_pVideo->h) b = m_pVideo->h - 1;
vcos = Cosinus(rotangle);
vsin = Sinus(rotangle);
pPal = (unsigned short*)pSrc->pData + ((flag >> 8) & 0xff);
for(i = t; i <= b; i++)
{
pD = (unsigned short*)m_pVideo->pData + i * m_pVideo->w + l;
for(j = l; j <= r; j++, pD++)
{
u = (((j - dx) * vcos - (i - dy) * vsin) >> COS_SIN_SHIFT) + (w>>1);
if(u < 0 || u >= w) continue;
v = (((j - dx) * vsin + (i - dy) * vcos) >> COS_SIN_SHIFT) + (h>>1);
if(v < 0 || v >= h) continue;
pS = pSrc->pData + (sy + v) * pSrc->w + (sx + u) + pSrc->npal * 2;
if(*pS)
*pD = BlendColor(pPal[*pS], *pD);
}
}
}
//##ModelId=402850A40318
void CGfx::DrawOpaque( int dx, int dy, int w, int h, GFXBMP *pSrc, int sx, int sy )
{
int invisible;
//set clip area, it's long and puzzling...
if(dx < 0 )
{
w += dx;
sx -= dx;
dx= 0;
}
invisible = dx + w - m_pVideo->w;
if(invisible > 0)
{
w -= invisible;
}
if(dy < 0 )
{
h += dy;
sy -= dy;
dy= 0;
}
invisible = dy + h - m_pVideo->h;
if(invisible > 0)
{
h -= invisible;
}
if(w<=0 || h <=0)
return;
if(m_pVideo->bpp == 16)
{
if(pSrc->bpp == 8)
{
Blt8_16(m_pVideo, dx, dy, w, h, pSrc, sx, sy, 0);
}
else if(pSrc->flag == 0)
Blt16_16(m_pVideo, dx, dy, w, h, pSrc, sx, sy, 0);
else if(pSrc->flag & GFXBMP_ALPHA)
{
SYS_ASSERT(0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -