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

📄 sprite_a.cpp

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

  使用前应调用InitSprite( ), 以完成初始化任务 !

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

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

#undef _SPRITE_BLIT_ALPHA_MMX_HEAD

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

static Bitmap* bmp;	//for test 

SpriteBlitAlphaFunc spriteBlitAlpha[9];
SpriteBlitBetaFunc spriteBlitBeta[9];
SpriteBlitAlphaFunc SpriteBlitAlpha;
SpriteBlitBetaFunc SpriteBlitBeta;


int InitSprite( void )
{
	if( screenInfo.colorDepth == 16 ){
		dwColorKey = 0xf81ff81f;
		qwColorKey = 0xf81ff81ff81ff81f;
		dwAlphaMask1 = 0x18e318e3;			// 1/8
		dwAlphaMask2 = 0x39e739e7;			// 1/4
		dwAlphaMask4 = 0x7bef7bef;			// 1/2
		qwAlphaMask1 = 0x18e318e318e318e3;
		qwAlphaMask2 = 0x39e739e739e739e7;
		qwAlphaMask4 = 0x7bef7bef7bef7bef;
	}
	else if( screenInfo.colorDepth == 15 ){
		dwColorKey = 0x7c1f7c1f;
		qwColorKey = 0x7c1f7c1f7c1f7c1f;
		dwAlphaMask1 = 0x0c630c63;
		dwAlphaMask2 = 0x1ce71ce7;
		dwAlphaMask4 = 0x3def3def;
		qwAlphaMask1 = 0x0c630c630c630c63;
		qwAlphaMask2 = 0x1ce71ce71ce71ce7;
		qwAlphaMask4 = 0x3def3def3def3def;
	}
	else
		return -1;

	if( cpu.mmx ){
		spriteBlitAlpha[0] = SpriteBlitAlpha0MMX;
		spriteBlitAlpha[1] = SpriteBlitAlpha1MMX;
		spriteBlitAlpha[2] = SpriteBlitAlpha2MMX;
		spriteBlitAlpha[3] = SpriteBlitAlpha3MMX;
		spriteBlitAlpha[4] = SpriteBlitAlpha4MMX;
		spriteBlitAlpha[5] = SpriteBlitAlpha5MMX;
		spriteBlitAlpha[6] = SpriteBlitAlpha6MMX;
		spriteBlitAlpha[7] = SpriteBlitAlpha7MMX;
		spriteBlitAlpha[8] = SpriteBlitAlpha8MMX;

		spriteBlitBeta[0] = SpriteBlitBeta0MMX;
		spriteBlitBeta[1] = SpriteBlitBeta1MMX;
		spriteBlitBeta[2] = SpriteBlitBeta2MMX;
		spriteBlitBeta[3] = SpriteBlitBeta3MMX;
		spriteBlitBeta[4] = SpriteBlitBeta4MMX;
		spriteBlitBeta[5] = SpriteBlitBeta5MMX;
		spriteBlitBeta[6] = SpriteBlitBeta6MMX;
		spriteBlitBeta[7] = SpriteBlitBeta7MMX;
		spriteBlitBeta[8] = SpriteBlitBeta8MMX;
	}
	SpriteBlitAlpha = spriteBlitAlpha[7];
	SpriteBlitBeta = spriteBlitBeta[7];

	bmp = LoadTga( "test.tga", NULL );
	if( bmp == NULL )
		return -1;

	return 0;
}

void SpriteSetDrawMode( int mode, DWORD degree )
{
	degree = ((degree >> 5) >= 8)? 8 : (degree >> 5 )+1;
	if( mode & Bitmap::AlphaMode )
		SpriteBlitAlpha = spriteBlitAlpha[degree];
	else
		SpriteBlitBeta = spriteBlitBeta[degree];
}

void SpriteBlitAlpha0MMX( Bitmap* dest, int x, int y, Bitmap* src )
{
}

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

#define _SPRITE_BLIT_ALPHA_MMX_HEAD 0
#include "sprite.hpp"
#undef _SPRITE_BLIT_ALPHA_MMX_HEAD

		movq mm6, qwAlphaMask1;

#define _SPRITE_BLIT_ALPHA_MMX_HEAD 1
#include "sprite.hpp"
#undef _SPRITE_BLIT_ALPHA_MMX_HEAD

		// do 1/8 alpha blend;
		psrlw mm1, 3;
		psrlw mm4, 3;
		pand mm1, mm6;
		pand mm4, mm6;
		paddw mm1, mm3;
		movq mm5, mm2;
		psubw mm1, mm4;
		pand mm3, mm5;
		pandn mm2, mm1;
		sub ecx, 4;
		por mm2, mm3;

#define _SPRITE_BLIT_ALPHA_MMX_HEAD 2
#include "sprite.hpp"
#undef _SPRITE_BLIT_ALPHA_MMX_HEAD

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

#define _SPRITE_BLIT_ALPHA_MMX_HEAD 3
#include "sprite.hpp"
#undef _SPRITE_BLIT_ALPHA_MMX_HEAD

}

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

#define _SPRITE_BLIT_ALPHA_MMX_HEAD 0
#include "sprite.hpp"
#undef _SPRITE_BLIT_ALPHA_MMX_HEAD

		movq mm6, qwAlphaMask2;

#define _SPRITE_BLIT_ALPHA_MMX_HEAD 1
#include "sprite.hpp"
#undef _SPRITE_BLIT_ALPHA_MMX_HEAD

		// do 1/4 alpha blend;
		psrlw mm1, 2;
		psrlw mm4, 2;
		pand mm1, mm6;
		pand mm4, mm6;
		paddw mm1, mm3;
		movq mm5, mm2;
		psubw mm1, mm4;
		pand mm3, mm5;
		pandn mm2, mm1;
		sub ecx, 4;
		por mm2, mm3;

#define _SPRITE_BLIT_ALPHA_MMX_HEAD 2
#include "sprite.hpp"
#undef _SPRITE_BLIT_ALPHA_MMX_HEAD

		shr ax, 2;
		mov bx, dx;
		and ax, word ptr dwAlphaMask2;
		shr dx, 2;
		add ax, bx;
		and dx, word ptr dwAlphaMask2;
		sub ax, dx;

#define _SPRITE_BLIT_ALPHA_MMX_HEAD 3
#include "sprite.hpp"
#undef _SPRITE_BLIT_ALPHA_MMX_HEAD

}

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

#define _SPRITE_BLIT_ALPHA_MMX_HEAD 0
#include "sprite.hpp"
#undef _SPRITE_BLIT_ALPHA_MMX_HEAD

		movq mm6, qwAlphaMask2;	// 1/4
		movq mm5, qwAlphaMask1;	// 1/8

#define _SPRITE_BLIT_ALPHA_MMX_HEAD 1
#include "sprite.hpp"
#undef _SPRITE_BLIT_ALPHA_MMX_HEAD

		// do 3/8 alpha blend;
		psrlw mm1, 2;
		psrlw mm3, 2;
		pand mm1, mm6;
		pand mm3, mm6;
		paddw mm1, mm3;
		movq mm0, mm1;
		psrlq mm1, 1;
		paddw mm3, mm0;
		pand mm1, mm5;
		movq mm0, mm2;
		paddw mm1, mm3;
		pand mm0, mm4;
		pandn mm2, mm1;
		sub ecx, 4;
		por mm2, mm0;


#define _SPRITE_BLIT_ALPHA_MMX_HEAD 2
#include "sprite.hpp"
#undef _SPRITE_BLIT_ALPHA_MMX_HEAD

		shr ax, 2;
		shr dx, 2;
		and ax, word ptr dwAlphaMask2;
		mov bx, ax;
		and dx, word ptr dwAlphaMask2;
		shr bx, 1;
		add ax, dx;
		and bx, word Ptr dwAlphaMask1;
		shr dx, 1;
		add ax, bx;
		and dx, word ptr dwAlphaMask1;
		add ax, dx;

#define _SPRITE_BLIT_ALPHA_MMX_HEAD 3
#include "sprite.hpp"
#undef _SPRITE_BLIT_ALPHA_MMX_HEAD

}

void SpriteBlitAlpha4MMX( Bitmap* dest, int x, int y, Bitmap* src )
{
	SPRITE_CLIP;
	
#define _SPRITE_BLIT_ALPHA_MMX_HEAD 0
#include "sprite.hpp"
#undef _SPRITE_BLIT_ALPHA_MMX_HEAD

		movq mm6, qwAlphaMask4;	// 1/2

#define _SPRITE_BLIT_ALPHA_MMX_HEAD 1
#include "sprite.hpp"
#undef _SPRITE_BLIT_ALPHA_MMX_HEAD

		// do 1/2 alpha blend;
		psrlw mm0, 1;
		movq mm5, mm2;
		psrlw mm4, 1;
		pand mm0, mm6;
		pand mm4, mm6;
		pand mm3, mm5;
		paddw mm0, mm4;
		pandn mm2, mm0;
		sub ecx, 4;
		por mm2, mm3;

#define _SPRITE_BLIT_ALPHA_MMX_HEAD 2
#include "sprite.hpp"
#undef _SPRITE_BLIT_ALPHA_MMX_HEAD

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

#define _SPRITE_BLIT_ALPHA_MMX_HEAD 3
#include "sprite.hpp"
#undef _SPRITE_BLIT_ALPHA_MMX_HEAD

}

void SpriteBlitAlpha5MMX( Bitmap* dest, int x, int y, Bitmap* src )
{
	SPRITE_CLIP;
	
#define _SPRITE_BLIT_ALPHA_MMX_HEAD 0
#include "sprite.hpp"
#undef _SPRITE_BLIT_ALPHA_MMX_HEAD

		movq mm6, qwAlphaMask2;	// 1/4
		movq mm5, qwAlphaMask1; // 1/8

#define _SPRITE_BLIT_ALPHA_MMX_HEAD 1
#include "sprite.hpp"
#undef _SPRITE_BLIT_ALPHA_MMX_HEAD

		// do 5/8 alpha blend;
		psrlq mm0, 2;
		psrlq mm3, 2;
		pand mm0, mm6;
		pand mm0, mm6;
		paddd mm3, mm0;
		movq mm1, mm3;
		psrlq mm3, 1;
		paddd mm1, mm0;
		pand mm3, mm5;
		movq mm0, mm2;
		paddd mm1, mm3;
		pandn mm2, mm1;
		pand mm4, mm0;
		sub ecx, 4;
		por mm2, mm4;

#define _SPRITE_BLIT_ALPHA_MMX_HEAD 2
#include "sprite.hpp"
#undef _SPRITE_BLIT_ALPHA_MMX_HEAD

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

#define _SPRITE_BLIT_ALPHA_MMX_HEAD 3
#include "sprite.hpp"
#undef _SPRITE_BLIT_ALPHA_MMX_HEAD

}

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

#define _SPRITE_BLIT_ALPHA_MMX_HEAD 0
#include "sprite.hpp"
#undef _SPRITE_BLIT_ALPHA_MMX_HEAD

		movq mm6, qwAlphaMask2;

#define _SPRITE_BLIT_ALPHA_MMX_HEAD 1
#include "sprite.hpp"
#undef _SPRITE_BLIT_ALPHA_MMX_HEAD

		// do 3/4 alpha blend;
		psrlw mm4, 2;
		psrlw mm1, 2;
		pand mm4, mm6;
		pand mm1, mm6;
		paddw mm0, mm4;
		movq mm5, mm2;
		psubw mm0, mm1;
		pand mm3, mm5;
		pandn mm2, mm0;
		sub ecx, 4;
		por mm2, mm3;

#define _SPRITE_BLIT_ALPHA_MMX_HEAD 2
#include "sprite.hpp"
#undef _SPRITE_BLIT_ALPHA_MMX_HEAD

		mov bx, ax;
		shr dx, 2;
		shr bx, 2;
		and dx, word ptr dwAlphaMask2;
		and bx, word ptr dwAlphaMask2;
		sub ax, bx;
		add ax, dx;

#define _SPRITE_BLIT_ALPHA_MMX_HEAD 3
#include "sprite.hpp"
#undef _SPRITE_BLIT_ALPHA_MMX_HEAD

}

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

#define _SPRITE_BLIT_ALPHA_MMX_HEAD 0
#include "sprite.hpp"
#undef _SPRITE_BLIT_ALPHA_MMX_HEAD

		movq mm6, qwAlphaMask1;

#define _SPRITE_BLIT_ALPHA_MMX_HEAD 1
#include "sprite.hpp"
#undef _SPRITE_BLIT_ALPHA_MMX_HEAD

		// do 3/4 alpha blend;
		psrlw mm4, 3;
		psrlw mm1, 3;
		pand mm4, mm6;
		pand mm1, mm6;
		paddw mm0, mm4;
		movq mm5, mm2;
		psubw mm0, mm1;
		pand mm3, mm5;
		pandn mm2, mm0;
		sub ecx, 4;
		por mm2, mm3;

#define _SPRITE_BLIT_ALPHA_MMX_HEAD 2
#include "sprite.hpp"
#undef _SPRITE_BLIT_ALPHA_MMX_HEAD

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

#define _SPRITE_BLIT_ALPHA_MMX_HEAD 3
#include "sprite.hpp"
#undef _SPRITE_BLIT_ALPHA_MMX_HEAD

}

void SpriteBlitAlpha8MMX( 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;
		}
}

int testSprite( void )
{
//	screen->Clear( 0,0,640,480, 0x808000 );
/*	if( LockScreen() != 0 )
		return -1;
	for( int i=0; i<5; i++ ){
		SpriteBlitBeta9MMX( screen, 0, i*96, bmp, 255 );
		SpriteBlitAlpha2MMX( screen, 128, i*96, bmp );
		SpriteBlitAlpha2MMX( screen, 256, i*96, bmp );
		SpriteBlitAlpha2MMX( screen, 384, i*96, bmp );
		SpriteBlitAlpha2MMX( screen, 512, i*96, bmp );
	}
	return UnlockScreen();*/
	return 0;
}

⌨️ 快捷键说明

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