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

📄 sprite_b.cpp

📁 仿游戏 Diablo 的源代码
💻 CPP
字号:
/* 精灵是一个带有透明色的 16/15-bit Bitmap,
  任何操作都过滤透明色,并带有明暗处理,
  目前明暗处理仅支持九级
  所有函数都尽可能使用MMX指令, 为提高速度宽度应设为4的倍数

  只能在具有MMX技术的CPU上运行 !
*/

#include "gl.h"
//#include "gengine.h"
#include "sprite.h"

#undef _SPRITE_BLIT_BETA_MMX_HEAD

// 透明色, 放入mm7
extern DWORD dwColorKey;
extern QWORD qwColorKey;
// 
extern DWORD dwAlphaMask1, dwAlphaMask2, dwAlphaMask4;
extern QWORD qwAlphaMask1, qwAlphaMask2, qwAlphaMask4;

void SpriteBlitBeta0MMX( Bitmap* dest, int x, int y, Bitmap* src )
{
	SPRITE_CLIP;

	int spitch = src->pitch - w*2;
	char* sline = src->line[sy] + sx*2;
	int dpitch = dest->pitch - w*2;
	char* dline = dest->line[y] + x*2;

	__asm{
		mov esi, sline;	
		mov edi, dline;
		cld;
		movq mm7, qwColorKey;
		mov edx, spitch;
		mov ecx, w;
		mov bx, word ptr dwColorKey;
line_begin:
		ALIGN 4;
		cmp ecx, 4;
		jl line_tail;

		movq mm0, [esi];
		movq mm3, [edi];
		movq mm2, mm0;
		sub ecx, 4;
		pcmpeqw mm2, mm7;
		add esi, 8;
		pand mm2, mm3;
		movq [edi], mm2;
		add edi, 8;
		jmp line_begin;

line_tail:
		jecxz next_line;
next_pixel:
		lodsw;
		dec ecx;
		cmp ax, bx;
		je trans_pixel;
		xor ax, ax;
		stosw;
		test ecx, ecx;
		jnz next_pixel;
		jmp next_line;
trans_pixel:
		add edi, 2;
		test ecx, ecx;
		jnz next_pixel;
next_line:
		add edi, dpitch;
		add esi, edx;
		mov ecx, w;
		dec h;
		jnz line_begin;

		emms;
		}
}

void SpriteBlitBeta1MMX( Bitmap* dest, int x, int y, Bitmap* src )
{
	SPRITE_CLIP;

#define _SPRITE_BLIT_BETA_MMX_HEAD 0
#include "sprite_b.hpp"
#undef _SPRITE_BLIT_BETA_MMX_HEAD

		movq mm6, qwAlphaMask1;
		mov dx, word ptr dwAlphaMask1;

#define _SPRITE_BLIT_BETA_MMX_HEAD 1
#include "sprite_b.hpp"
#undef _SPRITE_BLIT_BETA_MMX_HEAD

		psrlq mm0, 3;
		pand mm4, mm2;
		pand mm0, mm6;
		add esi, 8;
		pandn mm2, mm0;
		sub ecx, 4;
		por mm2, mm4;

#define _SPRITE_BLIT_BETA_MMX_HEAD 2
#include "sprite_b.hpp"
#undef _SPRITE_BLIT_BETA_MMX_HEAD

		shr ax, 3;
		and ax, dx;

#define _SPRITE_BLIT_BETA_MMX_HEAD 3
#include "sprite_b.hpp"
#undef _SPRITE_BLIT_BETA_MMX_HEAD

}

void SpriteBlitBeta2MMX( Bitmap* dest, int x, int y, Bitmap* src )
{
	SPRITE_CLIP;

#define _SPRITE_BLIT_BETA_MMX_HEAD 0
#include "sprite_b.hpp"
#undef _SPRITE_BLIT_BETA_MMX_HEAD

		movq mm6, qwAlphaMask2;
		mov dx, word ptr dwAlphaMask2;

#define _SPRITE_BLIT_BETA_MMX_HEAD 1
#include "sprite_b.hpp"
#undef _SPRITE_BLIT_BETA_MMX_HEAD

		psrlq mm0, 2;
		pand mm4, mm2;
		pand mm0, mm6;
		add esi, 8;
		pandn mm2, mm0;
		sub ecx, 4;
		por mm2, mm4;

#define _SPRITE_BLIT_BETA_MMX_HEAD 2
#include "sprite_b.hpp"
#undef _SPRITE_BLIT_BETA_MMX_HEAD

		shr ax, 2;
		and ax, dx;

#define _SPRITE_BLIT_BETA_MMX_HEAD 3
#include "sprite_b.hpp"
#undef _SPRITE_BLIT_BETA_MMX_HEAD

}

void SpriteBlitBeta3MMX( Bitmap* dest, int x, int y, Bitmap* src )
{
	SPRITE_CLIP;

#define _SPRITE_BLIT_BETA_MMX_HEAD 0
#include "sprite_b.hpp"
#undef _SPRITE_BLIT_BETA_MMX_HEAD

		movq mm6, qwAlphaMask1;
		movq mm5, qwAlphaMask4;

#define _SPRITE_BLIT_BETA_MMX_HEAD 1
#include "sprite_b.hpp"
#undef _SPRITE_BLIT_BETA_MMX_HEAD

		psrlq mm0, 3;
		psrlq mm3, 1;
		pand mm0, mm6;
		pand mm3, mm5;
		pand mm4, mm2;
		psubd mm3, mm0;
		add esi, 8;
		pandn mm2, mm3;
		sub ecx, 4;
		por mm2, mm4;

#define _SPRITE_BLIT_BETA_MMX_HEAD 2
#include "sprite_b.hpp"
#undef _SPRITE_BLIT_BETA_MMX_HEAD

		mov dx, ax;
		shr ax, 1;
		shr dx, 3;
		and ax, word ptr dwAlphaMask4;
		and dx, word ptr dwAlphaMask1;
		sub ax, dx;

#define _SPRITE_BLIT_BETA_MMX_HEAD 3
#include "sprite_b.hpp"
#undef _SPRITE_BLIT_BETA_MMX_HEAD

}

void SpriteBlitBeta4MMX( Bitmap* dest, int x, int y, Bitmap* src )
{
	SPRITE_CLIP;

	int spitch = src->pitch - w*2;
	char* sline = src->line[sy] + sx*2;
	int dpitch = dest->pitch - w*2;
	char* dline = dest->line[y] + x*2;

	__asm{
		mov esi, sline;	
		mov edi, dline;
		cld;
		movq mm7, qwColorKey;
		movq mm6, qwAlphaMask4;
		mov ecx, w;
		mov bx, word ptr dwColorKey;
		mov dx, word ptr dwAlphaMask4;
line_begin:
		ALIGN 4;
		cmp ecx, 4;
		jl line_tail;

		movq mm0, [esi];
		movq mm3, [edi];
		movq mm1, mm0;
		movq mm2, mm0;
		pcmpeqw mm1, mm7;
		psrlq mm0, 1;
		pcmpeqw mm2, mm7;

		pand mm0, mm6;
		pand mm2, mm3;
		pandn mm1, mm0;
		sub ecx, 4;
		por mm2, mm1;
		add esi, 8;
		movq [edi], mm2;
		add edi, 8;
		jmp line_begin;

line_tail:
		jecxz next_line;
next_pixel:
		lodsw;
		dec ecx;
		cmp ax, bx;
		je trans_pixel;
		shr ax, 1;
		and ax, dx;
		stosw;
		test ecx, ecx;
		jnz next_pixel;
		jmp next_line;
trans_pixel:
		add edi, 2;
		test ecx, ecx;
		jnz next_pixel;
next_line:
		add esi, spitch;
		add edi, dpitch;
		mov ecx, w;
		dec h;
		jnz line_begin;

		emms;
		}
}

void SpriteBlitBeta5MMX( Bitmap* dest, int x, int y, Bitmap* src )
{
	SPRITE_CLIP;

#define _SPRITE_BLIT_BETA_MMX_HEAD 0
#include "sprite_b.hpp"
#undef _SPRITE_BLIT_BETA_MMX_HEAD

		movq mm6, qwAlphaMask1;
		movq mm5, qwAlphaMask4;

#define _SPRITE_BLIT_BETA_MMX_HEAD 1
#include "sprite_b.hpp"
#undef _SPRITE_BLIT_BETA_MMX_HEAD

		psrlq mm0, 1;
		psrlq mm3, 3;
		pand mm0, mm5;
		pand mm3, mm6;
		pand mm4, mm2;
		paddd mm0, mm3;
		add esi, 8;
		pandn mm2, mm0;
		sub ecx, 4;
		por mm2, mm4;

#define _SPRITE_BLIT_BETA_MMX_HEAD 2
#include "sprite_b.hpp"
#undef _SPRITE_BLIT_BETA_MMX_HEAD

		mov dx, ax;
		shr ax, 1;
		shr dx, 3;
		and ax, word ptr dwAlphaMask4;
		and dx, word ptr dwAlphaMask1;
		add ax, dx;

#define _SPRITE_BLIT_BETA_MMX_HEAD 3
#include "sprite_b.hpp"
#undef _SPRITE_BLIT_BETA_MMX_HEAD

}

void SpriteBlitBeta6MMX( Bitmap* dest, int x, int y, Bitmap* src )
{
	SPRITE_CLIP;

#define _SPRITE_BLIT_BETA_MMX_HEAD 0
#include "sprite_b.hpp"
#undef _SPRITE_BLIT_BETA_MMX_HEAD

		movq mm6, qwAlphaMask2;
		movq mm5, qwAlphaMask4;

#define _SPRITE_BLIT_BETA_MMX_HEAD 1
#include "sprite_b.hpp"
#undef _SPRITE_BLIT_BETA_MMX_HEAD

		/*psrlq mm0, 1;
		psrlq mm3, 2;
		pand mm0, mm5;
		pand mm3, mm6;
		pand mm4, mm2;
		paddd mm0, mm3;
		add esi, 8;
		pandn mm2, mm0;
		sub ecx, 4;
		por mm2, mm4;
*/
		psrlq mm3, 2;
		pand mm4, mm2;
		pand mm3, mm6;
		psubw mm0, mm3;
		add esi, 8;
		pandn mm2, mm0;
		sub ecx, 4;
		por mm2, mm4;

#define _SPRITE_BLIT_BETA_MMX_HEAD 2
#include "sprite_b.hpp"
#undef _SPRITE_BLIT_BETA_MMX_HEAD

		mov dx, ax;
		shr ax, 1;
		shr dx, 2;
		and ax, word ptr dwAlphaMask4;
		and dx, word ptr dwAlphaMask2;
		add ax, dx;

#define _SPRITE_BLIT_BETA_MMX_HEAD 3
#include "sprite_b.hpp"
#undef _SPRITE_BLIT_BETA_MMX_HEAD

}

void SpriteBlitBeta7MMX( Bitmap* dest, int x, int y, Bitmap* src )
{
	SPRITE_CLIP;

#define _SPRITE_BLIT_BETA_MMX_HEAD 0
#include "sprite_b.hpp"
#undef _SPRITE_BLIT_BETA_MMX_HEAD

		movq mm6, qwAlphaMask1;

#define _SPRITE_BLIT_BETA_MMX_HEAD 1
#include "sprite_b.hpp"
#undef _SPRITE_BLIT_BETA_MMX_HEAD

		psrlq mm0, 3;
		pand mm0, mm6;
		pand mm4, mm2;
		psubd mm3, mm0;
		add esi, 8;
		pandn mm2, mm3;
		sub ecx, 4;
		por mm2, mm4;

#define _SPRITE_BLIT_BETA_MMX_HEAD 2
#include "sprite_b.hpp"
#undef _SPRITE_BLIT_BETA_MMX_HEAD

		mov dx, ax;
		shr dx, 3;
		and dx, word ptr dwAlphaMask1;
		sub ax, dx;

#define _SPRITE_BLIT_BETA_MMX_HEAD 3
#include "sprite_b.hpp"
#undef _SPRITE_BLIT_BETA_MMX_HEAD

}

void SpriteBlitBeta8MMX( Bitmap* dest, int x, int y, Bitmap* src )
{
	SPRITE_CLIP;

	int spitch = src->pitch - w*2;
	char* sline = src->line[sy] + sx*2;
	int dpitch = dest->pitch - w*2;
	char* dline = dest->line[y] + x*2;

	__asm{
		mov esi, sline;	
		mov edi, dline;
		cld;
		movq mm7, qwColorKey;
		mov edx, spitch;
		mov ecx, w;
		mov bx, word ptr dwColorKey;
line_begin:
		ALIGN 4;
		cmp ecx, 4;
		jl line_tail;

		movq mm0, [esi];
		movq mm3, [edi];
		movq mm2, mm0;
		movq mm1, mm0;
		pcmpeqw mm2, mm7;
		pcmpeqw mm1, mm7;

		pand mm2, mm3;
		pandn mm1, mm0;
		sub ecx, 4;
		por mm2, mm1;
		add esi, 8;
		movq [edi], mm2;
		add edi, 8;
		jmp line_begin;

line_tail:
		jecxz next_line;
next_pixel:
		lodsw;
		dec ecx;
		cmp ax, bx;
		je trans_pixel;
		stosw;
		test ecx, ecx;
		jnz next_pixel;
		jmp next_line;
trans_pixel:
		add edi, 2;
		test ecx, ecx;
		jnz next_pixel;
next_line:
		add edi, dpitch;
		add esi, edx;
		mov ecx, w;
		dec h;
		jnz line_begin;

		emms;
		}
}

// 32级亮度
void SpriteBlitBeta9MMX( Bitmap* dest, int x, int y, Bitmap* src, int brightness )
{
	SPRITE_CLIP;

	int spitch = src->pitch - w*2;
	char* sline = src->line[sy] + sx*2;
	int dpitch = dest->pitch - w*2;
	char* dline = dest->line[y] + x*2;

	__asm{
		lea eax, colorMask;
		shr brightness, 3;
		movq mm4, [eax];
		movq mm5, [eax+8];
		movq mm6, [eax+16];
		mov esi, sline;	
		mov edi, dline;
		mov eax, brightness;
		cld;
		mov ebx, eax;
		shl eax, 16;
		mov ecx, w;
		mov ax, bx;
		movd mm7, eax;
		movq mm0, mm7;
		punpcklwd mm0, mm7;	//brightness is in mm0
line_begin:
		ALIGN 4;
		cmp ecx, 4;
		jl line_tail;

		movq mm1, [esi];
		movq mm7, mm1;
		movq mm3, mm1;
		movq mm2, mm1;
		pcmpeqw mm7, qwColorKey;
		pand mm3, mm6;
		pand mm2, mm5;
		pmullw mm3, mm0;
		psrlw mm2, 5;
		pand mm1, mm4;
		pmullw mm2, mm0;
		psrlw mm1, 5;
		pand mm2, mm5;
		psrlw mm3, 5;
		pmullw mm1, mm0;
		por mm2, mm3;
		pand mm1, mm4;
		sub ecx, 2;
		por mm1, mm2;
		movq mm3, mm7;
		movq mm2, [edi];
		pandn mm3, mm1;
		pand mm2, mm7;
		sub ecx, 2;
		por mm2, mm3;
		add esi, 8;
		movq [edi], mm2;

		add edi, 8;
		jmp line_begin;

line_tail:
		jecxz next_line;
next_pixel:
		lodsw;
		dec ecx;
		cmp ax, word ptr dwColorKey;
		je trans_pixel;
		mov ebx, eax;
		and eax, gMask;
		and ebx, rbMask;
		shl eax, 16;
		or  eax, ebx;
		mul brightness;
		shr eax, 5;
		mov ebx, eax;
		shr eax, 16;
		and ebx, rbMask;
		and eax, gMask;
		or eax, ebx;
		stosw;
		test ecx, ecx;
		jnz next_pixel;
		jmp next_line;
trans_pixel:
		add edi, 2;
		test ecx, ecx;
		jnz next_pixel;
next_line:
		add edi, dpitch;
		add esi, spitch;
		mov ecx, w;
		dec h;
		jnz line_begin;

		emms;
		}
}

void SpriteBlitBeta10MMX( Bitmap* dest, int x, int y, Bitmap* src, int b1, int b2, short* buf )
{
	SPRITE_CLIP;

	int spitch = src->pitch - w*2;
	char* sline = src->line[sy] + sx*2;
	int dpitch = dest->pitch - w*2;
	char* dline = dest->line[y] + x*2;

	__asm{
		mov edx, src;	//calculate brightness
		cld;
		mov edi, buf;
		mov ebx, b1;
		mov eax, b2;
		mov ecx, [edx]src.width;
		mov esi, edi;
		shr b2, 3;
		sub eax, ebx;
		jz set_same_bright;
		cdq;
		shl eax, 16;
		shl ebx, 16;
		idiv ecx;
		xchg eax, ebx;
		dec ecx;
		shl ebx, 1;
		mov edx, eax;
set_brightness:
		shr eax, 19;
		stosw;
		mov eax, edx;
		add eax, ebx;
		mov edx, eax;
		loop set_brightness;
		mov eax, b2;
		stosw;
		jmp set_bright_end;
set_same_bright:
		mov eax, ebx;
		shr eax, 3;
		repnz stosw;
set_bright_end:

		mov esi, buf;
		mov edx, sx;
		lea eax, colorMask;
		shl edx, 1;
		movq mm4, [eax];
		add edx, esi;
		movq mm5, [eax+8];
		movq mm6, [eax+16];
		mov esi, sline;	
		mov edi, dline;
		mov ecx, w;
		mov buf, edx;
line_begin:
		ALIGN 4;
		cmp ecx, 4;
		jl line_tail;

		movq mm1, [esi];
		movq mm0, [edx];
		movq mm7, mm1;
		movq mm3, mm1;
		movq mm2, mm1;
		pcmpeqw mm7, qwColorKey;
		pand mm3, mm6;
		pand mm2, mm5;
		pmullw mm3, mm0;
		psrlw mm2, 5;
		pand mm1, mm4;
		pmullw mm2, mm0;
		psrlw mm1, 5;
		pand mm2, mm5;
		psrlw mm3, 5;
		pmullw mm1, mm0;
		por mm2, mm3;
		pand mm1, mm4;
		add edx, 8;
		por mm1, mm2;
		movq mm3, mm7;
		movq mm2, [edi];
		pandn mm3, mm1;
		pand mm2, mm7;
		sub ecx, 4;
		por mm2, mm3;
		add esi, 8;
		movq [edi], mm2;

		add edi, 8;
		jmp line_begin;

line_tail:
		jecxz next_line;
next_pixel:
		lodsw;
		dec ecx;
		cmp ax, word ptr dwColorKey;
		je trans_pixel;
		mov ebx, eax;
		and eax, gMask;
		and ebx, rbMask;
		shl eax, 16;
		or  eax, ebx;
		mul b2;
		shr eax, 5;
		mov ebx, eax;
		shr eax, 16;
		and ebx, rbMask;
		and eax, gMask;
		or eax, ebx;
		stosw;
		test ecx, ecx;
		jnz next_pixel;
		jmp next_line;
trans_pixel:
		add edi, 2;
		test ecx, ecx;
		jnz next_pixel;
next_line:
		mov edx, buf;
		add edi, dpitch;
		add esi, spitch;
		mov ecx, w;
		dec h;
		jnz line_begin;

		emms;
		}
}

⌨️ 快捷键说明

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