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

📄 bitmaphi.cpp

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

#include <malloc.h>
#include <string.h>
#include "bitmap.hpp"
#include "gl.h"

BitmapHi::BitmapHi( )
{
}

BitmapHi::~BitmapHi( )
{
	if( dat )
		delete dat;
	if( line )
		delete *line ;
}

DWORD BitmapHi::GetPixel( int x, int y )
{
	if( x < 0 || x >= width || y < 0 || y >= height )
		return -1;

	return ( (( WORD* )line[y])[x] );
}

// drawMode will do its work
// solid xor blend
void BitmapHi::PutPixel( int x, int y )
{
	if( clip ){
		if( x < cl || x >= cr || y < ct || y >= cb )
			return;
	}
	else{
		if( x < 0 || x >= width || y < 0 || y >= height )
			return;
	}
	
	short pixel = color;
	
	if( drawMode & XorMode )
		pixel ^= *(short*)( line[y] + x*2 );
	else if( drawMode & AlphaMode )
		pixel = pixel;//(short)blender->blender[ alpha ]( pixel, *(short*)( line[y] + x*2 ) );
		
	*(WORD*)( line[y] + x*2 ) = pixel;
}


void BitmapHi::Blit( Bitmap* dest, int x, int y, int sx, int sy, int w, int h )
{
	BLITCLIP()

	if( dest == this ){
		if( y > sy )
			BlitInside( x, y, sx, sy, w, h );
		else if( y == sy && sx < x )
			BlitInside( x, y, sx, sy, w, h );
		else
			BlitOutside( (Bitmap16*)dest, x, y, sx, sy, w, h );
	}
	else{
		BlitOutside( (Bitmap16*)dest, x, y, sx, sy, w, h );
	}
}

// the source bitmap and the destination bitmap are the same bitmap  
// reverse must be considered
void BitmapHi::BlitInside( int x, int y, int sx, int sy, int w, int h )
{
	char** line = BitmapHi::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
void BitmapHi::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, 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, 1;
		jg blitoutside16_dwloop;
		
		blitoutside16_w: 	/* width is one word */;
		movsw;
		add esi, edx;
		add edi, eax;
		dec ebx;
		jnz blitoutside16_w;
		jmp blitoutside16_end;
		
		mov ecx, w;
		blitoutside16_dwloop: 	/* width larger than one word */;
		shr ecx, 1;
		jnc blitoutside16_dwl;
		movsw;
	blitoutside16_dwl:
		repnz movsd;
		add esi, edx;
		add edi, eax;
		mov spitch, esi;
		mov ecx, w;
		dec ebx;
		jnz blitoutside16_dwloop;
		
		blitoutside16_end:
		pop es;
	}
}

// blit to another bitmap with SOURCE color key
void BitmapHi::BlitMask( Bitmap* dest, int x, int y, int sx, int sy, int w, int h )
{																		
	BLITCLIP()

	if( dest == this )
		return; /*failed */
	else{
		BlitMasked( (Bitmap*)dest, x, y, sx, sy, w, h );
	}
}

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

	_asm{
		push es;
		mov ax, ds;
		mov es, ax;
		
		mov eax, colorkey;
		mov ebx, h;
		shl y, 2;
		shl sy, 2;
		shl sx, 1;
		shl x, 1;
		
	blitmasked16_w:
		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;
		
	blitmasked16_loop:
		mov dx, ds:[esi] 	/* source pixel */;
		add esi, 2;
		cmp dx, ax 	/* is transparent ? */;
		je blitmasked16_skip;
		mov es:[edi], dx;
	blitmasked16_skip:
		add edi, 2;
		loop blitmasked16_loop;
		
		add y, 4;
		add sy, 4;
		dec ebx;
		jnz blitmasked16_w;
		pop es;
	}
}

// clear a rectangle area with the color
// clip will do its work
void BitmapHi::Clear( int l, int t, int w, int h, int color )
{
	char **line = BitmapHi::line;
	color = MakeColor( color );
	
	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;
		shr ecx, 1;
		jnc clear16_dw;
		
		jz clear16_onew;
		shr w, 1;
	clear16_dww: /* n long + one word */
		mov edi, line;
		mov edi, [edi+edx];
		add edi, esi;
		mov ecx, w;
		stosw;
		repnz stosd;
		add edx, 4;
		dec ebx;
		jnz clear16_dww;
		jmp clear16_end;
		;
	clear16_onew: 	/* only one word */
		mov edi, line;
		mov edi, [edi+edx];
		add edi, esi;
		stosw;
		add edx, 4;
		dec ebx;
		jnz clear16_onew;
		jmp clear16_end;
		
	clear16_dw: 	/* n long */
		shr w, 1;
	clear16_dwloop:
		mov edi, line;
		mov edi, [edi+edx];
		add edi, esi;
		mov ecx, w;
		repnz stosd;
		add edx, 4;
		dec ebx;
		jnz clear16_dwloop;
		
		clear16_end:
		pop es;
	}
}

⌨️ 快捷键说明

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