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

📄 asl_bitmap.cpp

📁 泡泡堂单机版(含ASL游戏引擎源码 泡泡堂单机版(含ASL游戏引擎源码
💻 CPP
📖 第 1 页 / 共 4 页
字号:

//-----------------------------------------------------------------------------
// 函数名: ASLBitmap::Line()
// 功  能: 绘制直线
// 参  数: [cl] - 直线颜色
//         [x1] - 起点x坐标
//         [y1] - 起点y坐标
//         [x2] - 终点x坐标
//         [y2] - 终点y坐标
//         [size] - 线宽
// 返回值: [void] - 无
//-----------------------------------------------------------------------------
void ASLBitmap::Line(COLOR cl, int x1, int y1, int x2, int y2, int size)
{
	ASSERT(m_hBitmap != NULL);

	HPEN hpen, hpenold;

	// 按指定颜色设置画笔
	hpen = CreatePen(PS_SOLID, size, GetRGB32(cl));
	hpenold = (HPEN)SelectObject(m_hDC, hpen);

	// 调用GDI函数画线
	MoveToEx(m_hDC, x1, y1, (LPPOINT)NULL);
	LineTo(m_hDC, x2, y2);

	// 恢复原画笔
	SelectObject(m_hDC, hpenold);
	
	// 删除创建的画笔
	DeleteObject(hpen);
}

//-----------------------------------------------------------------------------
// 函数名: ASLBitmap::Rect()
// 功  能: 绘制矩形(仅边框)
// 参  数: [cl] - 颜色
//         [x1] - 左上角x坐标
//         [y1] - 左上角y坐标
//         [x2] - 右下角x坐标
//         [y2] - 右下角y坐标
//         [size] - 线宽
// 返回值: [void] - 无
//-----------------------------------------------------------------------------
void ASLBitmap::Rect(COLOR cl, int x1, int y1, int x2, int y2, int size)
{
	ASSERT(m_hBitmap != NULL);

	HPEN hpen, hpenold;

	// 按指定颜色设置画笔
	hpen = CreatePen(PS_SOLID, size, GetRGB32(cl));
	hpenold = (HPEN)SelectObject(m_hDC, hpen);

	// 调用GDI函数画矩形
	::Rectangle(m_hDC, x1, y1, x2, y2);

	// 恢复原画笔
	SelectObject(m_hDC, hpenold);
	
	// 删除创建的画笔
	DeleteObject(hpen);
}

//-----------------------------------------------------------------------------
// 函数名: ASLBitmap::FillRect()
// 功  能: 填充矩形
// 参  数: [color] - 颜色
//         [x1] - 左上角x坐标
//         [y1] - 左上角y坐标
//         [x2] - 右下角x坐标
//         [y2] - 右下角y坐标
// 返回值: [void] - 无
//-----------------------------------------------------------------------------
void ASLBitmap::FillRect(COLOR color, int x1, int y1, int x2, int y2)
{
	ASSERT(m_hBitmap != NULL);

	// 对目标矩形进行调整
	RECT rc;
	SetRect(&rc, x1, y1, x2, y2);
	if (!_Clip(rc))
	{
		return;
	}

	const char *pdst = (char*)m_pData + m_nPitch * rc.top + rc.left * 2;
	const int nWidth = rc.right - rc.left;
	const int nHeight = rc.bottom - rc.top;
	const int pad = m_nPitch - nWidth * 2;

	if (nWidth <= 0 || nHeight <= 0)
	{
		return;
	}

	__asm
	{
		mov ax, color
		mov edi, pdst
		movd mm0, eax
		mov ebx, nHeight
		punpcklwd mm0, mm0
		mov edx, pad
		punpckldq mm0, mm0
		mov esi, nWidth
		mov ecx, esi
		cld
		align 4
_nextqword:
		sub ecx, 4
		jle _residual
		movq [edi], mm0
		add edi, 8
		jmp _nextqword
_residual:
		add ecx, 4
		rep stosw
		add edi, edx
		mov ecx, esi
		dec ebx
		jnz _nextqword

		emms
	}
}

//-----------------------------------------------------------------------------
// 函数名: ASLBitmap::Ellipse()
// 功  能: 绘制椭圆(仅边框)
// 参  数: [cl] - 颜色
//         [x1] - 左上角x坐标
//         [y1] - 左上角y坐标
//         [x2] - 右下角x坐标
//         [y2] - 右下角y坐标
//         [size] - 线宽
// 返回值: [void] - 无
//-----------------------------------------------------------------------------
void ASLBitmap::Ellipse(COLOR cl, int x1, int y1, int x2, int y2, int size)
{
	ASSERT(m_hBitmap != NULL);

	HPEN hpen, hpenold;

	// 按指定颜色设置画笔
	hpen = CreatePen(PS_SOLID, size, GetRGB32(cl));
	hpenold = (HPEN)SelectObject(m_hDC, hpen);
	
	// 调用GDI函数画椭圆
	::Ellipse(m_hDC, x1, y1, x2, y2);

	// 恢复原画笔
	SelectObject(m_hDC, hpenold);
	
	// 删除创建的画笔
	DeleteObject(hpen);
}

//-----------------------------------------------------------------------------
// 函数名: ASLBitmap::FillEllipse()
// 功  能: 填充椭圆
// 参  数: [cl] - 颜色
//         [x1] - 左上角x坐标
//         [y1] - 左上角y坐标
//         [x2] - 右下角x坐标
//         [y2] - 右下角y坐标
// 返回值: [void] - 无
//-----------------------------------------------------------------------------
void ASLBitmap::FillEllipse(COLOR cl, int x1, int y1, int x2, int y2)
{
	ASSERT(m_hBitmap != NULL);

	HPEN hpen, hpenold;
	HBRUSH hbrush, hbrushold;

	// 按指定颜色设置画笔和画刷
	hpen = CreatePen(PS_SOLID, 1, GetRGB32(cl));
	hpenold = (HPEN)SelectObject(m_hDC, hpen);	
	hbrush = CreateSolidBrush(GetRGB32(cl));
	hbrushold = (HBRUSH)SelectObject(m_hDC, hbrush);

	// 调用GDI函数画椭圆
	::Ellipse(m_hDC, x1, y1, x2, y2);

	// 恢复原画笔、画刷
	SelectObject(m_hDC, hpenold);
	SelectObject(m_hDC, hbrushold);

	// 删除创建的画笔、画刷
	DeleteObject(hpen);
	DeleteObject(hbrush);
}

//-----------------------------------------------------------------------------
// 函数名: ASLBitmap::Filter()
// 功  能: 滤镜效果
// 参  数: [cl] - 滤镜颜色
// 返回值: [void] - 无
//-----------------------------------------------------------------------------
void ASLBitmap::Filter(COLOR cl)
{
	//int rmax = GetRed(cl);
	//int gmax = GetGreen(cl);
	//int bmax = GetBlue(cl);
	//int r, g, b;

	//for (int i = 0; i < m_nPitch/2 * m_nHeight; ++i)
	//{
	//	r = GetRed(m_pData[i]);
	//	g = GetGreen(m_pData[i]);
	//	b = GetBlue(m_pData[i]);
	//	r = r > rmax ? rmax : r;
	//	g = g > gmax ? gmax : g;
	//	b = b > bmax ? bmax : b;

	//	m_pData[i] = RGB16(r, g, b);
	//}
	UINT count = m_nPitch * m_nHeight / 8;
	COLOR *p = m_pData;

	__asm
	{
		mov ecx, count
		movd mm7, cl
		punpcklwd mm7, mm7
		punpckldq mm7, mm7
		mov edi, p
		align 4
_next:
		movq mm0, [edi]
		pand mm0, mm7
		movq [edi], mm0
		add edi, 8
		loop _next

		emms
	}
}

//-----------------------------------------------------------------------------
// 函数名: ASLBitmap::ConvertGray()
// 功  能: 将位图灰度化
// 参  数: [void] - 无
// 返回值: [void] - 无
//-----------------------------------------------------------------------------
void ASLBitmap::ConvertGray(void)
{
	int r, g, b, gray;
	for (int i = 0; i < m_nPitch/2 * m_nHeight; ++i)
	{
		r = GetRed(m_pData[i]);
		g = GetGreen(m_pData[i]);
		b = GetBlue(m_pData[i]);
		gray = (r * 3 + g * 6 + b) / 10;
		m_pData[i] = RGB16(gray, gray, gray);
	}
}

//-----------------------------------------------------------------------------
// 函数名: ASLBitmap::Mix()
// 功  能: 将位图与指定颜色按比例混合(可实现淡入淡出)
// 参  数: [cl] - 颜色
//         [nAlpha] - 混合度 0 - 256
//         [*rect] - 绘制区矩形, 为空时表示整张位图
// 返回值: [void] - 无
//-----------------------------------------------------------------------------
void ASLBitmap::Mix(COLOR cl, int nAlpha, const RECT &rc)
{
	ASSERT(m_hBitmap != NULL);

	RECT rect;
	if (EqualRect(&rc, &DEFAULTRECT))
	{
		rect = m_rcClip;
	}
	else
	{
		rect = rc;
		if (!_Clip(rect))
		{
			return;
		}
	}

	int nWidth = rc.right - rc.left;
	int nHeight = rc.bottom - rc.top;

	if (nWidth <= 0 || nHeight <= 0)
	{
		return;
	}

	if (nAlpha < 0)
	{
		nAlpha = 0;
	}
	else if (nAlpha > 256)
	{
		nAlpha = 256;
	}

	if (nAlpha == 0)
	{
		return;
	}
	else if (nAlpha == 256)
	{
		FillRect(cl, rect.left, rect.top, rect.right, rect.bottom);
	}
	else
	{
		BYTE *pdst = (BYTE*)m_pData + m_nPitch * rect.top + rect.left * 2;
		const __int64 alpha64 = Bit16To64(nAlpha >> 3);
		const __int64 clr64 = Bit16To64(cl);

		for (int i = 0; i < nHeight; ++i)
		{
			asmMix(pdst, nWidth, clr64, alpha64);
			pdst += m_nPitch;
		}
	}
}



/******************************************************************************
 * 私有函数函数
 ******************************************************************************/

//-----------------------------------------------------------------------------
// 函数名: ASLBitmap::_AdjustDrawPos()
// 功  能: 调整绘图位置
// 参  数: [&bmDest] - 目标位图
//         [&xDest] - 目标x坐标
//         [&yDest] - 目标y坐标
//         [&rcSrc] - 源绘制区矩形
// 返回值: true - 需要绘制
//         false - 超出范围, 无需绘制
//-----------------------------------------------------------------------------
bool ASLBitmap::_AdjustDrawPos(const ASLBitmap &bmDest, int &xDest, int &yDest, 
							   RECT &rcSrc) const
{
	if (!_Clip(rcSrc))
	{
		return false;
	}

	RECT rcDst, rcTmp;

	rcDst.left = xDest;
	rcDst.top = yDest;
	rcDst.right = rcDst.left + (rcSrc.right - rcSrc.left);
	rcDst.bottom = rcDst.top + (rcSrc.bottom - rcSrc.top);
	rcTmp = rcDst;

	if (!bmDest._Clip(rcTmp))
	{
		return false;
	}

	if (rcTmp.left > rcDst.left)
	{
		rcSrc.left += rcTmp.left - rcDst.left;
	}
	if (rcTmp.top > rcDst.top)
	{
		rcSrc.top += rcTmp.top - rcDst.top;
	}
	if (rcTmp.right < rcDst.right)
	{
		rcSrc.right += rcTmp.right - rcDst.right;
	}
	if (rcTmp.bottom < rcDst.bottom)
	{
		rcSrc.bottom += rcTmp.bottom - rcDst.bottom;
	}

	xDest = rcTmp.left;
	yDest = rcTmp.top;

	return true;
}

//-----------------------------------------------------------------------------
// 函数名: ASLBitmap::_Clip()
// 功  能: 将矩形按本位图裁剪矩形进行裁剪
// 参  数: [&rect] - 待裁剪矩形
// 返回值: true - 该矩形有效
//         false - 该矩形无效
//-----------------------------------------------------------------------------
bool ASLBitmap::_Clip(RECT &rect) const
{
	ASSERT(rect.right >= rect.left && rect.bottom > rect.top);

	if (rect.left >= m_nWidth || rect.top >= m_nHeight 
		|| rect.bottom <= 0 || rect.right <= 0)
	{
		return false;
	}

	if (rect.left < 0)
	{
		rect.left = 0;
	}
	if (rect.top < 0)
	{
		rect.top = 0;
	}
	if (rect.right > m_nWidth)
	{
		rect.right = m_nWidth;
	}
	if (rect.bottom > m_nHeight)
	{
		rect.bottom = m_nHeight;
	}

	return true;
}

} // namespace ASL

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -