📄 pgesurface.cpp
字号:
// PGESurface.cpp: implementation of the CPGESurface class.
//
//////////////////////////////////////////////////////////////////////
#include "PGESurface.h"
#include "math.h"
extern DWORD g_dwDrawCmds;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
__inline WORD RGBto16bit555(unsigned char r,unsigned char g,unsigned char b)
{
return (((WORD)r<<7)&0x7c00)|(((WORD)g<<2)&0x03e0)|((WORD)b>>3);
}
_inline void MakeAlpha(WORD* wpSrc, WORD* wpDes, BYTE btAlpha);
__inline void MakeADD(WORD* wpSrc, WORD* wpDes);
#define PI 3.1415926
int farSin[360]; // sin函数值表
int farCos[360]; // cos函数值表
CPGESurface::CPGESurface(CPGEDevice* pDevice)
{
m_dwClassID = PGE_SURFACE;
m_pwMainData = NULL;
m_bLocked = FALSE;
m_pDevice = pDevice;
memset(&m_SurfaceInfo, 0, sizeof(m_SurfaceInfo));
m_SurfaceInfo.wSurfaceTp = PGE_NOMARL_SURFACE;
m_dwMaskColor = PGE_NONECOLOR;
m_dwDataSize = 0;
m_pFont = NULL;
m_pbtAlphaChanle = NULL;
m_pbtAlphaChanleStatic = NULL;
m_bAlphaChanle = FALSE;
m_btAlpha = 16;
m_pwPal = NULL;
m_btSurfaceBit = 16;
m_btUserData = 0;
if (farSin[0])
for (int i=0; i<360; i++)
{
farSin[i] = sin((float)(PI *(float)i)/180)*1024;
farCos[i] = cos((float)(PI *(float)i)/180)*1024;
if(i==0)
{
farSin[i] = 0;
farCos[i] = 1*1024;
}
else if (i==90)
{
farSin[i] = 1*1024;
farCos[i] = 0*1024;
}
else if (i==180)
{
farSin[i] = 0*1024;
farCos[i] = -1*1024;
}
else if (i==270)
{
farSin[i] = -1*1024;
farCos[i] = 0*1024;
}
else if (i==360)
{
farSin[i] = 0;
farCos[i] = 1*1024;
}
}
m_dwScale = (1<<14);
m_iRot = 0;
}
CPGESurface::~CPGESurface()
{
if (m_btUserData<255)
{
SAFE_DELETE_ARY(m_pwMainData);
SAFE_DELETE(m_pFont);
SAFE_DELETE_ARY(m_pbtAlphaChanle);
SAFE_DELETE_ARY(m_pbtAlphaChanleStatic);
SAFE_DELETE_ARY(m_pwPal);
}
}
void CPGESurface::Clean()
{
memset(m_pwMainData, 0, m_dwDataSize*sizeof(WORD));
}
PGE_RESULT CPGESurface::CreateSurface(WORD wGrHeight, WORD wGrWide, BYTE btSurfaceTp, DWORD dwMaskColor)
{
if (NULL != m_pwMainData)
{
if (m_SurfaceInfo.wSurfaceTp == PGE_MAIN_SURFACE)
{
return PGE_FAIL;
}
delete m_pwMainData;
}
m_SurfaceInfo.wSurfaceTp = btSurfaceTp;
m_SurfaceInfo.wHeigh = wGrHeight;
m_SurfaceInfo.wWiedth = wGrWide;
m_dwMaskColor = dwMaskColor;
if (PGE_MAIN_SURFACE == btSurfaceTp)
{
DWORD dwDeviceSize = m_pDevice->GetDeviceSize();
m_dwDataSize = dwDeviceSize;
m_pwMainData = new WORD[m_dwDataSize];
return PGE_OK;
}
m_dwDataSize = wGrWide * wGrHeight;
if (PGE_PGP_SURFACE == btSurfaceTp)
{
return PGE_OK;
//if (!m_pbtAlphaChanleStatic) m_pbtAlphaChanleStatic = new BYTE[m_dwDataSize];
}
else
{
m_pwMainData = new WORD[m_dwDataSize];
if (m_bAlphaChanle)
{
if (!m_pbtAlphaChanle) m_pbtAlphaChanle = new BYTE[m_dwDataSize];
if (!m_pbtAlphaChanleStatic) m_pbtAlphaChanleStatic = new BYTE[m_dwDataSize];
}
}
return PGE_OK;
}
void CPGESurface::Lock(void** pBuff)
{
(*pBuff) = m_pwMainData;
m_bLocked = TRUE;
}
void CPGESurface::unLock()
{
m_bLocked = FALSE;
}
DWORD CPGESurface::GetMaskColor()
{
return m_dwMaskColor;
}
void CPGESurface::SetScale(float fScale)
{
if (fScale <= 0.0f) fScale = 1.0f;
m_dwScale = fScale*(1<<14);
}
float CPGESurface::GetScale()
{
return (float)m_dwScale/(1<<14);
}
DWORD CPGESurface::GetScaleOffset()
{
return m_dwScale;
}
void CPGESurface::SetRot(int iRot)
{
if (iRot > 359) iRot = 359;
if (iRot < 0) iRot = 0;
m_iRot = iRot;
}
int CPGESurface::GetRot()
{
return m_iRot;
}
DWORD CPGESurface::GetDataSize()
{
return m_dwDataSize;
}
WORD* CPGESurface::GetPal()
{
return m_pwPal;
}
void CPGESurface::Blt8(CPGESurface* pSrcSurface, RECT* prSrc, RECT* prDis, WORD wFlag)
{
WORD wDrawFlag = wFlag & 0xf;
BOOL bMask = wFlag & 0xf0;
BOOL bRotScl = wFlag & 0xf00;
RECT rSrc;// = *prSrc;
RECT rDis;// = *prDis;
PGESurfaceInfo* pSrcInfo = pSrcSurface->GetSurfaceInfo();
// 正式版不提供有效性检查
if (prSrc == NULL)
{
rSrc.left = rSrc.top = 0;
rSrc.bottom = pSrcInfo->wHeigh;
rSrc.right = pSrcInfo->wWiedth;
}
else
{
rSrc = *prSrc;
}
if (prDis == NULL)
{
rDis.left = rDis.top = 0;
rDis.bottom = m_SurfaceInfo.wHeigh;
rDis.right = m_SurfaceInfo.wWiedth;
}
else
{
rDis = *prDis;
}
if (rSrc.top > pSrcInfo->wHeigh) rSrc.top = pSrcInfo->wHeigh; // 是否超过源图像的边界
if (rSrc.bottom > pSrcInfo->wHeigh) rSrc.bottom = pSrcInfo->wHeigh;
if (rSrc.left > pSrcInfo->wWiedth) rSrc.left = pSrcInfo->wWiedth;
if (rSrc.right > pSrcInfo->wWiedth) rSrc.right = pSrcInfo->wWiedth;
if ((rSrc.bottom- rSrc.top)+rDis.top > rDis.bottom) rSrc.bottom = rDis.bottom-rDis.top + rSrc.top; // 是否超过目的图像的边界
if ((rSrc.right- rSrc.left)+rDis.left > rDis.right) rSrc.right = rDis.right-rDis.left + rSrc.left;
int ix = 0, iy = 0, idx = rDis.left, idy = rDis.top;
WORD wDisHeight = rDis.bottom - rDis.top; // 目的矩形高
WORD wDisWide = rDis.right - rDis.left; // 目的矩形宽
WORD wSrcWide = rSrc.right - rSrc.left;
BYTE* pwSrc = NULL;
WORD* pwDis = m_pwMainData;
DWORD dwDisPos = 0;
DWORD dwSrcPos = 0; // 目的和源像素的偏移量
DWORD dwSrcMask = PGE_NONECOLOR;
WORD* pPal = pSrcSurface->GetPal();
int x,y,nx,ny,iRot;
DWORD dwScale;
#define PosRotScl \
y = (rDis.top + (iy-rSrc.top)) - (rDis.top + ((rSrc.bottom - rSrc.top)>>1)); \
x = rDis.left - rSrc.left + ix - (rDis.left + ((rSrc.right - rSrc.left)>>1)); \
dwScale = pSrcSurface->GetScaleOffset(); \
iRot = pSrcSurface->GetRot(); \
if (dwScale == 16384) \
{ \
nx = ((x*farCos[iRot])>>10) + ((y*farSin[iRot])>>10) \
+(rDis.left+((rSrc.right - rSrc.left)>>1)); \
ny = ((y*farCos[iRot])>>10) - ((x*farSin[iRot])>>10) \
+(rDis.top+((rSrc.bottom - rSrc.top)>>1)); \
} \
else \
{ \
nx = ((((x*farCos[iRot])>>10)*(long)dwScale)>>14) + ((y*farSin[iRot])>>10) \
+(rDis.left+((rSrc.right - rSrc.left)>>1)); \
ny = ((((y*farCos[iRot])>>10)*(long)dwScale)>>14) - ((x*farSin[iRot])>>10) \
+(rDis.top+((rSrc.bottom - rSrc.top)>>1)); \
} \
if (nx < 0) continue; \
nx = nx > m_SurfaceInfo.wWiedth ? m_SurfaceInfo.wWiedth : nx; \
ny = ny > m_SurfaceInfo.wHeigh ? m_SurfaceInfo.wHeigh : ny; \
dwDisPos = ny*m_SurfaceInfo.wWiedth+nx; \
if (dwDisPos >= m_dwDataSize) continue; \
#define RotSclFi \
if (dwDisPos < m_dwDataSize-m_SurfaceInfo.wWiedth && dwDisPos > m_SurfaceInfo.wWiedth) \
{ \
*(pwDis + dwDisPos+1) = *(pwDis + dwDisPos); \
*(pwDis + dwDisPos-1) = *(pwDis + dwDisPos); \
*(pwDis + dwDisPos+m_SurfaceInfo.wWiedth) = *(pwDis + dwDisPos); \
*(pwDis + dwDisPos+m_SurfaceInfo.wWiedth + 1) = *(pwDis + dwDisPos); \
*(pwDis + dwDisPos+m_SurfaceInfo.wWiedth - 1) = *(pwDis + dwDisPos); \
*(pwDis + dwDisPos-m_SurfaceInfo.wWiedth) = *(pwDis + dwDisPos); \
*(pwDis + dwDisPos-m_SurfaceInfo.wWiedth + 1) = *(pwDis + dwDisPos); \
*(pwDis + dwDisPos-m_SurfaceInfo.wWiedth - 1) = *(pwDis + dwDisPos); \
} \
if (wDrawFlag == PGE_BLT_ALPHA) // 如果使用alpha
{
pSrcSurface->Lock((void**)&pwSrc); // 锁定源表面
BYTE* pbtSrcAlpha = pSrcSurface->GetAlphaChanle();
BYTE btSrcAlphaVal = pSrcSurface->GetAlphaVal();
if (bMask) dwSrcMask = pSrcSurface->GetMaskColor();
DWORD dwSrcCol = rSrc.top * pSrcInfo->wWiedth;
DWORD dwDisCol = rDis.top * m_SurfaceInfo.wWiedth;
for(iy=rSrc.top; iy<rSrc.bottom; iy++)
{
if (iy-rSrc.top > wDisHeight) break; // 如果超出目的矩形的下边缘,则裁剪掉
idx = rDis.left;
for(ix=rSrc.left; ix<rSrc.right; ix++)
{
if(ix-rSrc.left > wDisWide) break; // 如果超出目的矩形的右边缘,则裁剪掉
dwSrcPos = dwSrcCol + ix; // 源地址偏移
if(pPal[pwSrc[dwSrcPos]] == dwSrcMask) continue; // 去掉遮罩颜色
if (!bRotScl)
{
dwDisPos = dwDisCol + idx; // 目的地址偏移
if (pbtSrcAlpha == NULL)
{
MakeAlpha(pPal+(*(pwSrc + dwSrcPos)),
pwDis + dwDisPos,
btSrcAlphaVal);
}
else
{
if (pbtSrcAlpha[dwSrcPos] == 31)
{
*(pwDis + dwDisPos) = pPal[*(pwSrc + dwSrcPos)];
}
else if (pbtSrcAlpha[dwSrcPos] != 0)
{
MakeAlpha(pPal+(*(pwSrc + dwSrcPos)),
pwDis + dwDisPos,
pbtSrcAlpha[dwSrcPos]);
}
// 在物体周围画一个框
//if (dwSrcPos>1 && dwSrcPos < pSrcSurface->GetDataSize())
//{
// if ((pbtSrcAlpha[dwSrcPos] == 0 && pbtSrcAlpha[dwSrcPos+1] !=0)
// || (pbtSrcAlpha[dwSrcPos+1] == 0 && pbtSrcAlpha[dwSrcPos] !=0))
// {
// *(pwDis + dwDisPos) = PGE_PURPLE;
// }
//}
//*(pwDis + dwDisPos)=*(pwSrc + dwSrcPos);
}
}
else
{
PosRotScl;
if (pbtSrcAlpha == NULL)
{
MakeAlpha(pPal+(*(pwSrc + dwSrcPos)),
pwDis + dwDisPos,
btSrcAlphaVal);
}
else
{
if (pbtSrcAlpha[dwSrcPos] == 31)
{
*(pwDis + dwDisPos) = pPal[*(pwSrc + dwSrcPos)];
}
else if (pbtSrcAlpha[dwSrcPos] != 0)
{
MakeAlpha(pPal+(*(pwSrc + dwSrcPos)),
pwDis + dwDisPos,
pbtSrcAlpha[dwSrcPos]);
}
//*(pwDis + dwDisPos)=*(pwSrc + dwSrcPos);
}
RotSclFi;
}
idx++;
}
// idy++;
dwSrcCol += pSrcInfo->wWiedth; //行
dwDisCol += m_SurfaceInfo.wWiedth;
}
pSrcSurface->unLock();
}
else if (wDrawFlag == PGE_BLT_NORMAL)
{
pSrcSurface->Lock((void**)&pwSrc); // 锁定源表面
dwSrcMask = pSrcSurface->GetMaskColor();
for(iy=rSrc.top; iy<rSrc.bottom; iy++)
{
if (iy-rSrc.top > wDisHeight) break; // 如果超出目的矩形的下边缘,则裁剪掉
idx = rDis.left;
for(ix=rSrc.left; ix<rSrc.right; ix++)
{
if(ix-rSrc.left > wDisWide) break; // 如果超出目的矩形的右边缘,则裁剪掉
dwSrcPos = iy * pSrcInfo->wWiedth + ix; // 源地址偏移
if (!bRotScl)
{
dwDisPos = idy * m_SurfaceInfo.wWiedth + idx; // 目的地址偏移
if (dwSrcMask != pPal[pwSrc[dwSrcPos]])
{
*(pwDis + dwDisPos)=pPal[*(pwSrc + dwSrcPos)];
}
}
else
{
PosRotScl;
if (dwSrcMask != pPal[pwSrc[dwSrcPos]])
{
*(pwDis + dwDisPos)=pPal[*(pwSrc + dwSrcPos)];
}
RotSclFi;
}
idx++;
}
idy++;
}
pSrcSurface->unLock();
}
else if (wDrawFlag == PGE_BLT_ADD)
{
pSrcSurface->Lock((void**)&pwSrc); // 锁定源表面
if (bMask) dwSrcMask = pSrcSurface->GetMaskColor();
for(iy=rSrc.top; iy<rSrc.bottom; iy++)
{
if (iy-rSrc.top > wDisHeight) break; // 如果超出目的矩形的下边缘,则裁剪掉
idx = rDis.left;
for(ix=rSrc.left; ix<rSrc.right; ix++)
{
if(ix-rSrc.left > wDisWide) break; // 如果超出目的矩形的右边缘,则裁剪掉
dwSrcPos = iy * pSrcInfo->wWiedth + ix; // 源地址偏移
if (!bRotScl)
{
dwDisPos = idy * m_SurfaceInfo.wWiedth + idx; // 目的地址偏移
if (pPal[pwSrc[dwSrcPos]] != dwSrcMask)
{
MakeADD(pPal+(*(pwSrc + dwSrcPos)), pwDis + dwDisPos);
}
}
else
{
PosRotScl;
if (pPal[pwSrc[dwSrcPos]] != dwSrcMask)
{
MakeADD(pPal+(*(pwSrc + dwSrcPos)), pwDis + dwDisPos);
}
RotSclFi;
}
idx++;
}
idy++;
}
pSrcSurface->unLock();
}
}
void CPGESurface::Blt(CPGESurface* pSrcSurface, RECT* prSrc, RECT* prDis, WORD wFlag)
{
if (m_btSurfaceBit == 8)
{
return;
}
if (pSrcSurface->m_btSurfaceBit == 8)
{
Blt8(pSrcSurface, prSrc, prDis, wFlag);
return;
}
WORD wDrawFlag = wFlag & 0xf;
BOOL bMask = wFlag & 0xf0;
BOOL bRotScl = wFlag & 0xf00;
BOOL bAndAlpha = wFlag & 0xf000;
RECT rSrc;// = *prSrc;
RECT rDis;// = *prDis;
PGESurfaceInfo* pSrcInfo = pSrcSurface->GetSurfaceInfo();
// 正式版不提供有效性检查
if (prSrc == NULL)
{
rSrc.left = rSrc.top = 0;
rSrc.bottom = pSrcInfo->wHeigh;
rSrc.right = pSrcInfo->wWiedth;
}
else
{
rSrc = *prSrc;
}
if (prDis == NULL)
{
rDis.left = rDis.top = 0;
rDis.bottom = m_SurfaceInfo.wHeigh;
rDis.right = m_SurfaceInfo.wWiedth;
}
else
{
rDis = *prDis;
}
if (rSrc.top > pSrcInfo->wHeigh) rSrc.top = pSrcInfo->wHeigh; // 是否超过源图像的边界
if (rSrc.bottom > pSrcInfo->wHeigh) rSrc.bottom = pSrcInfo->wHeigh;
if (rSrc.left > pSrcInfo->wWiedth) rSrc.left = pSrcInfo->wWiedth;
if (rSrc.right > pSrcInfo->wWiedth) rSrc.right = pSrcInfo->wWiedth;
if ((rSrc.bottom- rSrc.top)+rDis.top > rDis.bottom) rSrc.bottom = rDis.bottom-rDis.top + rSrc.top; // 是否超过目的图像的边界
if ((rSrc.right- rSrc.left)+rDis.left > rDis.right) rSrc.right = rDis.right-rDis.left + rSrc.left;
int ix = 0, iy = 0, idx = rDis.left, idy = rDis.top;
WORD wDisHeight = rDis.bottom - rDis.top; // 目的矩形高
WORD wDisWide = rDis.right - rDis.left; // 目的矩形宽
WORD wSrcWide = rSrc.right - rSrc.left;
WORD* pwSrc = NULL;
WORD* pwDis = m_pwMainData;
DWORD dwDisPos = 0, dwSrcPos = 0; // 目的和源像素的偏移量
DWORD dwSrcMask = PGE_NONECOLOR;
int x,y,nx,ny,iRot;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -