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

📄 bim16mmx.cpp

📁 仿游戏 Diablo 的源代码
💻 CPP
字号:
/* 
*	移植自WatcomC++,于1999年4月14日
*
*/

#include "gl.h"
#include "bitmap.hpp"

Bitmap16MMX::Bitmap16MMX() : Bitmap16( 16 )
{
}

void Bitmap16MMX::BlitInside( int x, int y, int sx, int sy, int w, int h )
{
	char** line = Bitmap16::line;

	__asm{
		push es;
		mov ax, ds;
		mov es, ax;
		/* copy from the bottom to the top */;
		mov eax, sy;
		mov ebx, h;
		dec ebx;
		add eax, ebx;
		mov sy, eax;
		add y, ebx;
		inc ebx;
		
		mov ecx, w;
		mov edx, sx;
		dec ecx;
		add edx, ecx;
		mov sx, edx;
		add x, ecx;
		std;
		inc ecx;
		shl sx, 1;
		shl x, 1;
		mov edx, y;
		shl eax, 2;
		shl edx, 2;
		
		cmp ecx, 1;
		jg blitinside16_dw;
		
	blitinside16_w: 	/* the width is one word */;
		mov esi, line;
		mov edi, esi;
		mov esi, dword ptr [esi+eax];
		add esi, sx;
		mov edi, dword ptr [edi+edx];
		add edi, x;
		mov ecx, w;
		repnz movsw;
		sub eax, 4;
		sub edx, 4;
		dec ebx;
		jnz blitinside16_w;
		jmp blitinside16_end;
		
	blitinside16_dw:	/* the width is larger than 1 */;
		mov ecx, w;
		mov esi, line;
		mov edi, esi;
		mov esi, dword ptr [esi+eax];
		add esi, sx;
		mov edi, dword ptr [edi+edx];
		add edi, x;
		shr ecx, 1;
		jnc blitinside16_dwdw;
		movsw;
	blitinside16_dwdw:;
		sub esi, 2;
		sub edi, 2;
		repnz movsd;
		sub eax, 4;
		sub edx, 4;
		dec ebx;
		jnz blitinside16_dw;
		
	blitinside16_end:;
		pop es;
	}

}

// blit from a bitmap to another bitmap
// no reverse at all, optimized for MMX
void Bitmap16MMX::BlitOutside( Bitmap* dest, int x, int y, int sx, int sy, int w, int h )
{
	char** dline = dest->line;
	char** sline = line;
	int dpitch = dest->pitch;
	int spitch = pitch;

	__asm{
		push es;
		mov ax, ds;
		mov es, ax;
		
		mov ebx, h;
		cld;
		mov ecx, w;
		mov eax, y;
		mov edx, sy;
		shl eax, 2;
		shl edx, 2;
		shl sx, 1;
		shl x, 1;
		mov esi, sline;
		mov esi, [esi+edx];
		add esi, sx;
		mov edi, dline;
		mov edi, [edi+eax];
		add edi, x;
		shl ecx, 1;
		mov edx, spitch;
		mov eax, dpitch;
		sub edx, ecx;
		sub eax, ecx;
		shr ecx, 1;
		
		cmp ecx, 4;
		jl width_less_than_4;
		
	blitoutside16_dwloop: /* width is larger than 4 */;
		shr ecx, 1;
		jnc blitoutside16_dwl;
		movsw;
	blitoutside16_dwl:;
		shr ecx, 1;
		jnc blitoutside16_qw;
		movsd;
	blitoutside16_qw:;
		movq mm0, [esi];
		add esi, 8;
		movq [edi], mm0;
		add edi, 8;
		loop blitoutside16_qw;
		mov ecx, w;
		add esi, edx;
		add edi, eax;
		dec ebx;
		jnz blitoutside16_dwloop;
		emms;
		jmp blitoutside16_end;
		
	width_less_than_4:;
		repnz movsw;
		add esi, edx;
		add edi, eax;
		mov ecx, w;
		dec ebx;
		jnz width_less_than_4;
		
	blitoutside16_end:;
		pop es;
	}
}

void Bitmap16MMX::BlitMasked16( Bitmap* dest, int x, int y, int sx, int sy, int w, int h )
{
	char** dline = dest->line;
	char** sline = line;
	long colorkey = colorKey;

	__asm{
		push es;
		mov ax, ds;
		mov es, ax;
		
		mov ebx, h;
		shl y, 2;
		shl sy, 2;
		shl sx, 1;
		shl x, 1;
		mov esi, sline;
		add esi, sy;
		mov esi, [esi];
		add esi, sx;
		mov edi, dline;
		add edi, y;
		mov edi, [edi];
	/*	add edi, x;
		mov ecx, w;
		shl ecx, 1;
		sub spitch, ecx;
		sub dpitch, ecx;
		cmp ecx, 8;
		jge use_MMX;
	*/	
		mov eax, dword ptr colorkey;
	blitmasked16_w:;
		mov ecx, w;
	blitmask_pixel:;
		mov edx, [esi];
		cmp eax, edx;
		je trans_pixel;
		mov [edi], edx;
	trans_pixel:;
		add esi, 2;
		add edi, 2;
	/*	loop blitmask_pixel;
		add esi, spitch;
		add edi, dpitch;
		dec ebx;
		jnz blitmasked16_w;
		jmp blitmasked_end;
		
	use_MMX:;
		mov eax, word ptr colorkey;
		mov ecx, w;
		lea edx, colorkey;
		mov [edx+4], eax;
		movq mm0, colorkey;
	*/	movq mm1, mm0;
		packssdw mm0, mm1 	/* get colorkey */;
		mov h, ecx;
		and ecx, 0x3;
		shr h, 2;
		mov w, ecx;
	blit_head:;
	/*	jcxz only_4 */	/* 八的整数倍 */;
	blit_l1:;
		mov edx, [esi];
	/*	cmp edx, word ptr colorkey;
	*/	je trans_pixel_mmx;
		mov [edi], edx;
	trans_pixel_mmx:;
		add esi, 2;
		add edi, 2;
		loop blit_l1;
		
		mov ecx, h;
	/*	mov eax, 8;
	blit_MMX_loop:;
		movq mm1, [esi];
		movq mm2, mm1;
		pcmpeqw mm1, mm0;
		pandw mm2, mm1;
		movq mm3, [edi];
		pandnw mm3, mm1;
		porw mm3, mm2;
		movq [edi], mm3;
		add esi, eax;
		add edi, eax;
		loop blit_MMX_loop;
		add esi, spitch;
		add edi, dpitch;
	*/	mov ecx, w;
		dec ebx;
		jnz blit_head;
	blitmasked_end:;
		pop es;
		emms;
	}
}

void Bitmap16MMX::Clear( int l, int t, int w, int h, int color )
{
	char **line = Bitmap16::line;
	int pitch = Bitmap::pitch;
	
	color = (color & pixelInfo->colorRedMask) >> pixelInfo->colorRedPos //red
		| (color & pixelInfo->colorGreenMask) >> 5	// green	
		| (color & pixelInfo->colorBlueMask) >> 3;	//blue
	
	if( clip ){
		if( l < cl ){
			w -= cl - l;
			l = cl;
		}
		if( t < ct ){
			h -= ct - t;
			t = ct;
		}
		if( l + w > cr )
			w = cr - l;
		if( t + h > cb )
			h = cb - t;
	}
	else{
		if( l < 0 ){
			w += l;
			l = 0;
		}
		if( t < 0 ){
			h += t;
			t = 0;
		}
		if( l + w > width )
			w = width - l;
		if( t + h > height )
			h = height - t;
	}
	
	__asm{
		push es;
		mov ax, ds;
		mov es, ax;
		
		mov eax, color;
		mov ebx, eax;
		shl eax, 16;
		mov edx, t;
		mov ax, bx;
		mov ebx, h;
		shl edx, 2;
		cld;
		mov esi, l;
		shl esi, 1;
		mov ecx, w;
		mov edi, line;
		mov edi, [edi+edx];
		add edi, esi;
		mov edx, pitch;
		shl ecx, 1 
		sub edx, ecx;
		shr ecx, 2;
	/*	jnc clear16_dw;
	*/	
		clear16_end:;
		pop es;
	}
}

// blend this bitmap( alpha ) and src( 255-aplha ) bitmap to dest, 
// alpha 0-255, optimized for MMX
void Bitmap16MMX::BlitBlend( Bitmap* dest, int x, int y,
		int sx, int sy, int w, int h, int alpha, int method )
{
	char **dline = dest->line;
	char **sline = line;
	int colorkey = colorKey;
	
	BLITCLIP();
	
	__asm{
		shl x, 1;
		shl sx, 1;
		cld;
		shl sy, 2;
		shl y, 2;
		
	blit_line:;
		mov esi, sline;
		add esi, sy;
		mov esi, [esi];
		add esi, sx;
		mov edi, dline;
		add edi, y;
		mov edi, [edi];
		add edi, x;
		mov ecx, w;

	blitloop:;
		lodsw;
		mov dx, [edi];
		call [ebx];
		mov [edi], ax;
		add edi, 2;
		loop blitloop;
		
		add y, 4;
		add sy, 4;
		dec h;
		jnz blit_line;
	}
}

⌨️ 快捷键说明

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