⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pgesurface.cpp

📁 使ppc屏幕变成黑白的程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// 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 + -