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

📄 asl_asm.cpp

📁 泡泡堂单机版(含ASL游戏引擎源码 泡泡堂单机版(含ASL游戏引擎源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	static const __int64 mask = 0x7BEF7BEF7BEF7BEF;

	__asm
	{
		mov edi, pDst
		mov esi, pSrc
		movq mm6, ck64
		movq mm7, mask
		mov ecx, nWidth
		movd edx, mm6
		cld
		align 4
_nextqword:
		sub ecx, 4
		jl _residual
		// 跳过4字全为透明色
		cmp [esi], edx
		jnz _notequal
		cmp [esi+4], edx
		jnz _notequal
		jmp _finishone
_notequal:
		movq mm0, [esi]
		movq mm1, [edi]
		movq mm5, mm0
		movq mm2, mm1
		pcmpeqw mm5, mm6	// mm5为透明掩码
		psrlq mm2, 1
		psrlq mm0, 1
		pand mm2, mm7
		pand mm0, mm7
		paddw mm2, mm0		// mm2为混合结果
		pand mm1, mm5		// 目的数据非透明点置0
		psubusw mm2, mm5	// 混合结果透明点置0
		por mm1, mm2		// 相或得最终结果
		movq [edi], mm1
_finishone:
		add esi, 8
		add edi, 8
		jmp _nextqword
_residual:
		add ecx, 4
		je _done
_alpha16:
		lodsw
		cmp ax, dx
		je _skip
		mov bx, [edi]
		shr bx, 1
		shr ax, 1
		and bx, 0x7BEF
		and ax, 0x7BEF
		add ax, bx
		mov [edi], ax
_skip:
		add edi, 2
		loop _alpha16
_done:
		emms
	}
}

//-----------------------------------------------------------------------------
// 函数名: asmAlphaChannel()
// 功  能: alpha通道位图绘制
// 参  数: [*pSrc] - 源位图数据
//         [*pDst] - 目的位图数据
//         [*pAlpha] - alpha通道数据
//         [nWidth] - 待处理宽度
// 返回值: [void] - 无
//-----------------------------------------------------------------------------
void asmAlphaChannel(BYTE *pSrc, BYTE *pDst, BYTE *pAlpha, int nWidth)
{
	__asm
	{
		mov edi, pDst		// edi = 目的指针
		mov esi, pSrc		// esi = 源指针
		mov ecx, nWidth		// ecx = 宽度
		mov eax, pAlpha
		align 4
_nextqword:
		sub ecx, 4
		jl _residual
		movq mm3, [edi]		movq mm0, [esi]		movd mm7, [eax]		pxor mm6, mm6				punpcklbw mm7, mm6		psrlw mm7, 3	}	// 调用Alpha混合宏	ALPHABLEND()	__asm	{		add esi, 8		movq [edi], mm0		add eax, 4		add edi, 8
		jmp _nextqword
_residual:
		add ecx, 4
		jz _done			// ecx=0, 已完成
		test ecx, 2
		jz _onein			// ecx=1, 转单象素处理
		movd mm3, [edi]		// ecx!=1, 先拷贝2象素
		movd mm0, [esi]
		test ecx, 1
		jz _startres		// ecx=2, 开始剩余处理
		mov dx, [edi+4]		// ecx=3, 再拷贝一个象素
		movd mm6, edx
		mov dx, [esi+4]
		psllq mm6, 32
		por mm3, mm6
		movd mm6, edx
		psllq mm6, 32
		por mm0, mm6
		jmp _startres
_onein:						// 单象素处理
		mov dx, [edi]
		movd mm3, edx
		mov dx, [esi]
		movd mm0, edx
_startres:
		movd mm7, [eax]
		pxor mm6, mm6		punpcklbw mm7, mm6		psrlw mm7, 3
	}

	// 调用Alpha混合宏	ALPHABLEND()

	__asm
	{		test ecx, 2		jz _oneout		movd [edi], mm0		sub ecx, 2		jz _done		psrlq mm0, 32		add edi, 4_oneout:		movd edx, mm0		mov [edi], dx
_done:
		emms
	}
}

//-----------------------------------------------------------------------------
// 函数名: asmAdditive()
// 功  能: 色饱和位图绘制
// 参  数: [*pSrc] - 源位图数据
//         [*pDst] - 目的位图数据
//         [nWidth] - 待处理宽度
// 返回值: [void] - 无
//-----------------------------------------------------------------------------
void asmAdditive(BYTE *pSrc, BYTE *pDst, int nWidth)
{
	static const __int64 maskRB = 0xF81FF81FF81FF81F;
	static const __int64 maskG  = 0x07E007E007E007E0;

	__asm
	{
		mov edi, pDst		// 目的指针
		mov esi, pSrc		// 源指针
		mov ecx, nWidth		// 以字为单位的宽度
		movq mm7, maskRB	// 红蓝掩码,		11111 000000 11111b
		movq mm6, maskG		// 绿掩码,			00000 111111 00000b
		align 4
_nextqword:					// 64位色饱和开始
		sub ecx, 4			// 宽度减4
		jl _residual		// 小于0则跳转到非对齐位处理
		movq mm0, [esi]
		movq mm2, [edi]
	}
		
	// 调用色饱和处理宏
	ADDITIVE()

	__asm
	{
		movq [edi], mm0
		add esi, 8
		add edi, 8
		jmp _nextqword
_residual:
		add ecx, 4
		jz _done			// ecx=0, 已完成
		test ecx, 2
		jz _onein			// ecx=1, 转单象素处理
		movd mm2, [edi]		// ecx!=1, 先拷贝2象素
		movd mm0, [esi]
		test ecx, 1
		jz _startres		// ecx=2, 开始剩余处理
		mov dx, [edi+4]		// ecx=3, 再拷贝一个象素
		movd mm5, edx
		mov dx, [esi+4]
		psllq mm5, 32
		por mm2, mm5
		movd mm5, edx
		psllq mm5, 32
		por mm0, mm5
		jmp _startres
_onein:						// 单象素处理
		mov dx, [edi]
		movd mm2, edx
		mov dx, [esi]
		movd mm0, edx
_startres:
	}

	// 调用色饱和处理宏
	ADDITIVE()	__asm	{		test ecx, 2		jz _oneout			// ecx为1,则写入1个象素数据		movd [edi], mm0		// ecx为2或3,先写入2个象素		sub ecx, 2		jz _done			// ecx为2,则结束		psrlq mm0, 32		// ecx为3,再写入1个象素		add edi, 4_oneout:		movd edx, mm0		mov [edi], dx		// 写入一个象素_done:
		emms	}
}

//-----------------------------------------------------------------------------
// 函数名: asmMix()
// 功  能: 位图与指定颜色半透明混合
// 参  数: [*pDst]	- 目的位图数据指针
//         [nWidth]	- 待绘制宽度
//         [clr64]	- 待混合颜色
//         [alpha]	- 透明度
// 返回值: [void]	- 无
//-----------------------------------------------------------------------------
void asmMix(BYTE *pDst, int nWidth, __int64 clr64, __int64 alpha)
{
	__asm
	{
		mov edi, pDst		// edi = 目的指针
		mov ecx, nWidth		// ecx = 宽度
		movq mm7, alpha		// 透明度
		align 4
_nextqword:
		sub ecx, 4
		jl _residual
		movq mm3, [edi]		movq mm0, clr64	}			// 调用Alpha混合宏	ALPHABLEND()	__asm	{		add esi, 8		movq [edi], mm0		add edi, 8
		jmp _nextqword
_residual:
		add ecx, 4
		jz _done			// ecx=0, 已完成
		test ecx, 2
		jz _onein			// ecx=1, 转单象素处理
		movd mm3, [edi]		// ecx!=1, 先拷贝2象素
		test ecx, 1
		jz _startres		// ecx=2, 开始剩余处理
		mov dx, [edi+4]		// ecx=3, 再拷贝一个象素
		movd mm6, edx
		psllq mm6, 32
		por mm3, mm6
		jmp _startres
_onein:						// 单象素处理
		mov dx, [edi]
		movd mm3, edx
_startres:
		movq mm0, clr64
	}

	// 调用Alpha混合宏	ALPHABLEND()	__asm	{		test ecx, 2		jz _oneout		movd [edi], mm0			sub ecx, 2		jz _done		psrlq mm0, 32		add edi, 4_oneout:		movd edx, mm0		mov [edi], dx
_done:
		emms
	}
}

//-----------------------------------------------------------------------------
// 函数名: asmPlainFont()
// 功  能: 普通字体绘制
// 参  数: [*pSrc]	- 8位字符点阵数据(绘制点全1,不绘点全0)
//         [*pDst]	- 目的位图
//         [nWidth]	- 待处理宽度
//         [clr64]	- 文字颜色
// 返回值: [void]	- 无
//-----------------------------------------------------------------------------
void asmPlainFont(BYTE *pSrc, BYTE *pDst, int nWidth, __int64 clr64)
{
	__asm
	{
		mov edi, pDst		// edi = 目的指针
		mov esi, pSrc		// esi = 字符点阵数据指针
		mov ecx, nWidth		// ecx = 宽度
		cld
		align 4
_nextqword:					// 4字处理开始
		sub ecx, 4			// 宽度减4
		jl _residual		// 结果小于4,转剩余处理
		movq mm0, [edi]		// 目的颜色
		movd mm7, [esi]		// mm7 = 8位字符点阵数据
		movq mm1, clr64		// mm1 = 64位颜色值
		punpcklbw mm7, mm7	// 8位点阵数据扩展为16位
		movd edx, mm1

		pand mm1, mm7		// 不绘点的源颜色值清0
		psubusw mm0, mm7	// 待绘点的目的颜色清0
        por mm0, mm1		// 相或得结果颜色

		add esi, 4
		movq [edi], mm0		// 写入4个象素
		add edi, 8
		jmp _nextqword
_residual:					// 剩余处理
		add ecx, 4
		jz _done
_draw16:
		lodsb				// 取一个象素信息
		cmp al, 0
		je _newline			// 为0则直接跳过
		mov [edi], dx		// 把颜色写入目的象素
_newline:
		add edi, 2
		dec ecx
		jnz _draw16
_done:
		emms
	}
}

//-----------------------------------------------------------------------------
// 函数名: asmSmoothFont()
// 功  能: 平滑字体绘制
// 参  数: [*pAlpha]	- 8位alpha通道(65级alpha值)
//         [*pDst]		- 目的位图
//         [nWidth]		- 待处理宽度
//         [clr64]		- 文字颜色
// 返回值: [void]		- 无
//-----------------------------------------------------------------------------
void asmSmoothFont(BYTE *pAlpha, BYTE *pDst, int nWidth, __int64 clr64)
{
	__asm
	{
		mov edi, pDst		// edi = 目的指针
		mov esi, pAlpha		// esi = alpha通道数据指针
		mov ecx, nWidth		// ecx = 宽度
		align 4
_nextqword:					// 4字处理开始
		sub ecx, 4			// 宽度减4
		jl _residual		// 结果小于4,转剩余处理
		movd mm7, [esi]		// 取8位alpha值
		pxor mm6, mm6		// mm6清0
		punpcklbw mm7, mm6	// 扩展alpha值为16位
		psrlw mm7, 1		// 将65级alpha值转为33级
		movq mm3, [edi]		// 取目的颜色		movq mm0, clr64		// 取64位颜色值	}	// 调用Alpha混合宏	ALPHABLEND()	__asm	{		add esi, 4		movq [edi], mm0		// 写入4个象素		add edi, 8
		jmp _nextqword

_residual:
		// 剩余处理
		// [ecx]+4之后可能的值为0、1、2、3,分别处理
		// 只需处理edi的取数,alpha通道数据已留出空白,可以直接取4字节而不溢出
		add ecx, 4
		jz _done			// ecx=0, 已完成
		test ecx, 2
		jz _onein			// ecx=1, 转单象素处理
		movd mm3, [edi]		// ecx!=1, 先拷贝2象素
		test ecx, 1
		jz _startres		// ecx=2, 开始剩余处理
		mov dx, [edi+4]		// ecx=3, 再拷贝一个象素
		movd mm6, edx
		psllq mm6, 32
		por mm3, mm6
		jmp _startres
_onein:						// 单象素处理
		mov dx, [edi]
		movd mm3, edx
_startres:					// 处理过程开始
		movd mm7, [esi]		// 取8位alpha通道数据
		pxor mm6, mm6		// mm6清0
		punpcklbw mm7, mm6	// 扩展alpha值为16位
		psrlw mm7, 1		// 将65级alpha值变为33级
		movq mm0, clr64		// 取64位颜色值	}	// 调用Alpha混合宏	ALPHABLEND()	__asm	{		test ecx, 2		jz _oneout			// ecx为1,则写入1个象素数据		movd [edi], mm0		// ecx为2或3,先写入2个象素		sub ecx, 2		jz _done			// ecx为2,则结束		psrlq mm0, 32		// ecx为3,再写入1个象素		add edi, 4_oneout:		movd edx, mm0		mov [edi], dx		// 写入一个象素_done:
		emms
	}
}

} // namespace ASL

⌨️ 快捷键说明

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