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

📄 asl_asm.cpp

📁 泡泡堂单机版(含ASL游戏引擎源码 泡泡堂单机版(含ASL游戏引擎源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//-----------------------------------------------------------------------------
//
//    ____ Azure Star Game Engine 蓝星游戏引擎 ____
//
//    Copyright (c) 2006, 蓝星工作室
//    All rights reserved.
//
//    文件名称: asl_asm.cpp
//    摘    要: MMX加速的图像处理函数实现(被ASLBitmap, ASLFont类使用)
//
//    当前版本: 1.0
//    作    者: 汤  祺
//    创建日期: 2006-8-7
//
//-----------------------------------------------------------------------------

#include "asl_asm.h"

namespace ASL
{

//-----------------------------------------------------------------------------// 宏名: ALPHABLEND()// 功能: 执行4字Alpha混合, 本宏使用所有8个mmx寄存器// 输入: mm3 - 目的颜色//       mm0 - 源颜色//       mm7 - 33级alpha值(0~32)// 输出: mm0 - 结果颜色// 算法: alpha混合公式为: src * alpha + dst * (1 - alpha)//       变形为: (src - dst) * alpha + dst  其中alpha范围0~1//       对于33级alpha值, 计算前留出5位空白防止溢出, 计算完成后右移5位// 逐行注释://       movq mm4, mm3		; g1 mm4 = dst3 dst3 dst1 dst0//       movq mm5, mm3		; b1 mm5 = dst3 dst3 dst1 dst0//       movq mm6, mm3		; r1 mm6 = dst3 dst3 dst1 dst0//       psrlw mm3, 5		; r2 mm3 = dst?: 00000rrrrrgggggg//       pand mm4, mask_g	; g2 mm4 = dst?: 00000gggggg00000//       pand mm5, mask_b	; b2 mm5 = dst?: 00000000000bbbbb//       movq mm1, mm0		; g3 mm1 = src3 src2 src1 src0//       movq mm2, mm0		; b3 mm2 = src3 src2 src1 src0//       psrlw mm0, 5		; r3 mm0 = src?: 00000rrrrrgggggg//       pand mm1, mask_g	; g4 mm1 = src?: 00000gggggg00000//       pand mm2, mask_b	; b4 mm2 = src?: 00000000000bbbbb//       psubw mm0, mm3		; r4 mm0 = src? - dst?//       psubw mm1, mm4		; g5 mm1 = src? - dst?//       pmullw mm0, mm7	; r5 mm0 = (src? - dst?) * alpha?//       psubw mm2, mm5		; b5 mm2 = src? - dst?//       pmullw mm1, mm7	; g6 mm1 = (src? - dst?) * alpha?//       paddw mm0, mm6		; r6 mm0 = (src? - dst?) * alpha? + dst?//       pmullw mm2, mm7	; b6 mm2 = (src? - dst?) * alpha?//       psrlw mm1, 5		; g7 mm1右移5位,使alpha值范围变为0~1//       psrlw mm2, 5		; b7 mm2右移5位,使alpha值范围变为0~1//       paddw mm1, mm4		; g8 mm1 = (src? - dst?) * alpha? + dst?//       paddw mm2, mm5		; b8 mm2 = (src? - dst?) * alpha? + dst?//       pand mm0, mask_r	; r7 mm0 = result?: rrrrr00000000000//       pand mm1, mask_g	; g9 mm1 = result?: 00000gggggg00000//       pand mm2, mask_b	; b9 mm2 = result?: 00000ggggggbbbbb//       por mm0, mm1		; mm0 = result?: rrrrrgggggg00000//       por mm0, mm2		; mm0 = result?: rrrrrggggggbbbbb//-----------------------------------------------------------------------------
#define ALPHABLEND()			\
		__asm movq mm4, mm3		\		__asm movq mm5, mm3		\		__asm movq mm6, mm3		\		__asm psrlw mm3, 5		\		__asm pand mm4, mask_g	\		__asm pand mm5, mask_b	\		__asm movq mm1, mm0		\		__asm movq mm2, mm0		\		__asm psrlw mm0, 5		\		__asm pand mm1, mask_g	\		__asm pand mm2, mask_b	\		__asm psubw mm0, mm3	\		__asm psubw mm1, mm4	\		__asm pmullw mm0, mm7	\		__asm psubw mm2, mm5	\		__asm pmullw mm1, mm7	\		__asm paddw mm0, mm6	\		__asm pmullw mm2, mm7	\		__asm psrlw mm1, 5		\		__asm psrlw mm2, 5		\		__asm paddw mm1, mm4	\		__asm paddw mm2, mm5	\		__asm pand mm0, mask_r	\		__asm pand mm1, mask_g	\		__asm pand mm2, mask_b	\		__asm por mm0, mm1		\		__asm por mm0, mm2

//-----------------------------------------------------------------------------
// 宏名: ADDITIVE()// 功能: 执行4字色饱和处理, 本宏使用寄存器: mm0, mm1, mm2, mm3, mm6, mm7// 输入: mm0 - 源颜色//       mm2 - 目的颜色//       mm6 - 绿掩码//       mm7 - 红蓝掩码// 输出: mm0 - 结果颜色// 算法: // 逐行注释:
//-----------------------------------------------------------------------------
#define ADDITIVE()				\
		__asm movq mm1, mm0		\
		__asm movq mm3, mm2		\
		__asm pand mm0, mm7		\
		__asm por mm2, mm6		\
		__asm pand mm1, mm6		\
		__asm por mm3, mm7		\
		__asm paddusb mm0, mm2	\
		__asm paddusw mm1, mm3	\
		__asm pand mm0, mm1


// 全局常量定义
const __int64 mask_r = 0xF800F800F800F800;		// 红色掩码
const __int64 mask_g = 0x07E007E007E007E0;		// 绿色掩码
const __int64 mask_b = 0x001F001F001F001F;		// 蓝色掩码

//-----------------------------------------------------------------------------
// 函数名: asmDrawPlain()
// 功  能: 普通位图绘制
// 参  数: [*pSrc] - 源位图数据
//         [*pDst] - 目的位图数据
//         [nWidth] - 待处理宽度
// 返回值: [void] - 无
//-----------------------------------------------------------------------------
void asmDrawPlain(BYTE *pSrc, BYTE *pDst, int nWidth)
{
	__asm
	{
		mov edi, pDst		// edi = 目的指针
		mov esi, pSrc		// esi = 源指针
		mov ecx, nWidth		// ecx = 宽度
		cld
		align 4
_nextqword:
		sub ecx, 4
		jl _residual
		movq mm0, [esi]		// 从源地址取4象素数据
		add esi, 8
		movq [edi], mm0		// 直接写入目的地址
		add edi, 8
		jmp _nextqword
_residual:
		add ecx, 4
		jz _done
		rep movsw
_done:
		emms
	}
}

//-----------------------------------------------------------------------------
// 函数名: asmDrawColorkey()
// 功  能: 普通位图绘制(带Colorkey处理)
// 参  数: [*pSrc] - 源位图数据
//         [*pDst] - 目的位图数据
//         [nWidth] - 待处理宽度
//         [ck64] - 64位颜色键
// 返回值: [void] - 无
//-----------------------------------------------------------------------------
void asmDrawColorkey(BYTE *pSrc, BYTE *pDst, int nWidth, __int64 ck64)
{
	__asm
	{
		movq mm7, ck64		// 64位颜色键
		mov edi, pDst		// edi = 目的指针
		mov esi, pSrc		// esi = 源指针
		mov ecx, nWidth		// ecx = 宽度
		movd edx, mm7		// 取32位颜色键, 用于剩余处理
		cld
		align 4
_nextqword:
		sub ecx, 4
		jl _residual
		movq mm0, [esi]		// 从源地址取4象素数据
		add esi, 8
		movq mm1, mm0		// 源数据给mm1
		pcmpeqw mm0, mm7	// mm0为透明掩码
		psubusw mm1, mm0	// 源数据透明点置0
		pand mm0, [edi]		// 目的数据非透明点置0
        por mm0, mm1		// 相与得结果数据
		movq [edi], mm0		// 结果送目的地址
		add edi, 8
		jmp _nextqword
_residual:					// 剩余处理
		add ecx, 4
		jz _done
_draw16:
		lodsw				// 从源地址取1象素数据
		cmp ax, dx			// 将其与透明色比较
		jz _nextone			// 相等则跳过
		mov [edi], ax		// 不等则写入目的地址
_nextone:
		add edi, 2
		dec ecx
		jnz _draw16
_done:
		emms
	}
}

//-----------------------------------------------------------------------------
// 函数名: asmAlphaPlain()
// 功  能: 半透明位图绘制(实际33级透明度)
// 参  数: [*pSrc] - 源位图数据
//         [*pDst] - 目的位图数据
//         [nWidth] - 待处理宽度
//         [alpha] - 透明度 0-256
// 返回值: [void] - 无
//-----------------------------------------------------------------------------
void asmAlphaPlain(BYTE *pSrc, BYTE *pDst, int nWidth, __int64 alpha)
{
	__asm
	{
		mov edi, pDst		// edi = 目的指针
		mov esi, pSrc		// esi = 源指针
		mov ecx, nWidth		// ecx = 宽度
		movq mm7, alpha		// 透明度
		align 4
_nextqword:
		sub ecx, 4
		jl _residual
		movq mm3, [edi]		movq mm0, [esi]	}	// 调用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象素
		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:
	}

	// 调用Alpha混合宏	ALPHABLEND()

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

//-----------------------------------------------------------------------------
// 函数名: asmAlphaColorkey()
// 功  能: 半透明位图绘制(带Colorkey处理)
// 参  数: [*pSrc] - 源位图数据
//         [*pDst] - 目的位图数据
//         [nWidth] - 待处理宽度
//         [alpha] - 透明度 0-256
//         [ck64] - 64位颜色键
// 返回值: [void] - 无
//-----------------------------------------------------------------------------
void asmAlphaColorkey(BYTE *pSrc, BYTE *pDst, int nWidth, __int64 alpha, 
					  __int64 ck64)
{
	__asm
	{
		mov edi, pDst		// edi = 目的指针
		mov esi, pSrc		// esi = 源指针
		mov ecx, nWidth		// ecx = 宽度
		cld
		align 4
_nextqword:
		sub ecx, 4
		jl _residual
		movq mm1, ck64
		movd eax, mm1
		cmp [esi], eax
		jnz _notequal
		cmp [esi+4], eax
		jnz _notequal
		jmp _finishone
_notequal:
		movq mm3, [edi]		movq mm0, [esi]				movq mm7, alpha		pcmpeqw mm1, mm0				psubusw mm7, mm1	}	// 调用Alpha混合宏	ALPHABLEND()	__asm	{		movq [edi], mm0_finishone:		add esi,8
		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:		movq mm1, ck64				movq mm7, alpha		pcmpeqw mm1, mm0				psubusw mm7, mm1	}	// 调用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
	}
}

//-----------------------------------------------------------------------------
// 函数名: asmFastPlain()
// 功  能: 快速半透明位图绘制(50%-50%)
// 参  数: [*pSrc] - 源位图数据
//         [*pDst] - 目的位图数据
//         [nWidth] - 待处理宽度
// 返回值: [void] - 无
//-----------------------------------------------------------------------------
void asmFastPlain(BYTE *pSrc, BYTE *pDst, int nWidth)
{
	static const __int64 mask = 0x7BEF7BEF7BEF7BEF;

	// 算法: 将颜色值全部右移一位, 再与掩码做且运算, 则三色分量均除以2
	//       源数据和目的数据均做上述操作, 再相加即实现半透明
	__asm
	{
		mov edi, pDst		// edi = 目的指针
		mov esi, pSrc		// esi = 源指针
		movq mm7, mask		// 64位掩码
		mov ecx, nWidth		// ecx = 宽度
		movd edx, mm7		// 将32位掩码给edx, 用于剩余处理
		cld
		align 4
_nextqword:
		sub ecx, 4
		jl _residual
		movq mm0, [esi]		// 取源数据到mm0
		movq mm1, [edi]		// 取目的数据到mm1
		psrlq mm0, 1		// src? = 0rrrrrggggggbbbb
		psrlq mm1, 1		// dst? = 0rrrrrggggggbbbb
		pand mm0, mm7		// src? = 0rrrr0ggggg0bbbb
		pand mm1, mm7		// dst? = 0rrrr0ggggg0bbbb
		paddw mm0, mm1		// result? = rrrrrggggggbbbbb
		add esi, 8
		movq [edi], mm0		// 写回目的地址
		add edi, 8
		jmp _nextqword
_residual:					// 剩余处理
		add ecx, 4
		jz _done
_alpha16:
		lodsw
		mov bx, [edi];
		shr bx, 1;
		shr ax, 1;
		and bx, dx;
		and ax, dx;			
		add ax, bx;
		stosw
		dec ecx
		jnz _alpha16
_done:
		emms
	}
}

//-----------------------------------------------------------------------------
// 函数名: asmFastColorkey()
// 功  能: 快速半透明位图绘制(带Colorkey处理)
// 参  数: [*pSrc] - 源位图数据
//         [*pDst] - 目的位图数据
//         [nWidth] - 待处理宽度
//         [ck64] - 64位颜色键
// 返回值: [void] - 无
//-----------------------------------------------------------------------------
void asmFastColorkey(BYTE *pSrc, BYTE *pDst, int nWidth, __int64 ck64)
{

⌨️ 快捷键说明

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