📄 asl_asm.cpp
字号:
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 + -