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

📄 bitmap24.cpp

📁 仿游戏 Diablo 的源代码
💻 CPP
字号:
#include "bitmap.hpp"
#include "gl.h"

PixelInfo pixelInfo24 = {
	0xff0000,// Red mask in color ( color's type : int )
	0,	// how many bits to shift right to convert color(int) to the actual pixel value 
	0xff0000,// the Red value in pixel
	16,	// how many bits to shift right to get Red value from pixel
	0xff0000,	// green
	0,
	0xff0000,
	8,
	0xff0000,	//blue
	0,
	0xff0000,
	0
};


DWORD Bitmap24::GetPixel( int x, int y )
{
	if( x < 0 || x >= width || y < 0 || y >= height )
		return -1;
	
	return *( long* )( line[y] + x*3 ) & 0xffffff;
}

// drawMode will do its work
// solid xor blend
void Bitmap24::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;
	}
	
	long pixel = color;
	
	if( drawMode & XorMode )
		pixel ^= *(long*)( line[y] + x*3 );
	else if( drawMode & AlphaMode )
		pixel = pixel;	// how to do alpha blend ?
		
	*(short*)( line[y] + x*3 ) = (short)pixel;
	*(char*)( line[y] + x*3 + 2 ) = (char)(pixel >> 16);
}

// set current draw color
void Bitmap24::SetColor( int color )
{
	Bitmap24::color = color & 0xffffff;
}

void Bitmap24::SetColorKey( int color )
{
	Bitmap24::colorKey = color & 0xffffff;
}

// void Bitmap24::BlitMask( ....... )
BLITMASK( 24 )

void Bitmap24::Blit( Bitmap* dest, int x, int y, int sx, int sy, int w, int h )
{
/*	if( sx >= width || sy >= height )
		return;
		
	int dcl, dct, dcb, dcr;
	
	if( sx < 0 ){
		dx -= sx;
		w += sx;
		sx = 0;
	}
	if( sy < 0 ){
		dy -= sy;
		w += sy;
		sy = 0;
	}
	if( sx+w > width ){
		w = width - sx;
	}
	if( sy+h > height ){
		h = height - sy;
	}
	
	if( dest->clip ){
		dcl = dest->cl;
		dct = dest->ct;
		dcr = dest->cr;
		dcb = dest->cb;
	}
	else{
		dcl = dct = 0;
		dcb = dest->height;
		dcr = dest->width;
	}
	if( dx < dcl ){
		sx += dcl - dx;
		w -= dcl - dx;
		dx = dcl;
	}
	if( dy < dct ){
		sy += dct - dy;
		h -= dct - dy;
		dy = dct;
	}
	if( dx + w > dcr )
		w = dcr - dx;
	if( dy + h > dcb )
		h = dcb - dy;
*/
	BLITCLIP()
			
	if( dest == this ){
		if( y > sy )
			BlitInside24( x, y, sx, sy, w, h );
		else if( y == sy && sx < x )
			BlitInside24( x, y, sx, sy, w, h );
		else
			BlitOutside24( (Bitmap24*)dest, x, y, sx, sy, w, h );
	}
	else{
		BlitOutside24( (Bitmap24*)dest, x, y, sx, sy, w, h );
	}
}

void Bitmap24::BlitInside24( int x, int y, int sx, int sy, int w, int h )
{
	char** dline = line;
	char** sline = line;

	__asm{
		push es;
		mov ax, ds;
		mov es, ax;
		
		mov ecx, w;
		mov eax, sx;
		mov ebx, x;
		add eax, ecx;
		add ebx, ecx;
		mov sx, eax;
		mov x, ebx;
		shl eax, 1;
		shl ebx, 1;
		add sx, eax;
		add x, ebx;
		shl ecx, 1;
		add w, ecx;
		
		mov ebx, h;
		mov eax, y;
		mov edx, sy;
		shl eax, 2;
		shl edx, 2;
		std;
		
		blitinside24_loop:
		mov ecx, w;
		mov esi, sline;
		mov esi, [esi+edx];
		add esi, sx;
		mov edi, dline;
		mov edi, dword ptr [edi+eax];
		add edi, x;
		shr ecx, 1;
		jnc blitinside24_dww;
		movsb;
	blitinside24_dww:
		shr ecx, 1;
		jnc blitinside24_dwdw;
		movsw;
	blitinside24_dwdw:
		repnz movsd;
		add edx, 4;
		add eax, 4;
		dec ebx;
		jnz blitinside24_loop;
		
		pop es;
	}
}

// blit from a bitmap to another bitmap
// no reverse at all
void Bitmap24::BlitOutside24( Bitmap24* dest, int x, int y, int sx, int sy, int w, int h )
{
	char** dline = dest->line;
	char** sline = Bitmap24::line;

	__asm{
		push es;
		mov ax, ds;
		mov es, ax;
		
		mov eax, sx;
		mov ebx, x;
		shl eax, 1;
		shl ebx, 1;
		add sx, eax;
		add x, ebx;
		
		mov ebx, h;
		mov eax, y;
		mov edx, sy;
		shl eax, 2;
		shl edx, 2;
		mov ecx, w;
		shl ecx, 1;
		add w, ecx;
		cld;
		
		blitoutside24_loop:
		mov ecx, w;
		mov esi, sline;
		mov esi, [esi+edx];
		add esi, sx;
		mov edi, dline;
		mov edi, [edi+eax];
		add edi, x;
		shr ecx, 1;
		jnc blitoutside24_dww;
		movsb;
	blitoutside24_dww:
		shr ecx, 1;
		jnc blitoutside24_dwdw;
		movsw;
	blitoutside24_dwdw:
		repnz movsd;
		add edx, 4;
		add eax, 4;
		dec ebx;
		jnz blitoutside24_loop;
		
		pop es;
	}
}

// blit to another bitmap with SOURCE color key
void Bitmap24::BlitMasked24( Bitmap24* dest, int x, int y, int sx, int sy, int w, int h )
{
	char** dline = dest->line;
	char** sline = Bitmap24::line;
	int colorkey = Bitmap24::colorKey;

	__asm{
		push es;
		mov ax, ds;
		mov es, ax;
		
		shl y, 2;
		shl sy, 2;
		mov eax, sx;
		mov ebx, x;
		shl eax, 1;
		shl ebx, 1;
		add sx, eax;
		add x, ebx;
		mov eax, colorkey;
		mov ebx, h;
		
	blitmasked24_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;
		
	blitmasked24_loop:
		mov edx, ds:[esi] 	/* source pixel */;
		add esi, 3;
		and edx, 0xffffff;
		cmp edx, eax 	/* is transparent ? */;
		je blitmasked24_skip;
		mov es:[edi], dx;
		shr edx, 16;
		mov es:[edi+2], dl;
	blitmasked24_skip:
		add edi, 3;
		loop blitmasked24_loop;
		
		add y, 4;
		add sy, 4;
		dec ebx;
		jnz blitmasked24_w;
		pop es;
	}
}

// clear a rectangle area with the color
// clip will do its work
void Bitmap24::Clear( int l, int t, int w, int h, int color )
{
	char **line = Bitmap24::line;
	
	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;
	}

BYTE p[13];
		
	__asm{
		push es;
		mov ax, ds;
		mov es, ax;
		
		mov eax, color;
		lea esi, p;
		mov [esi], eax;
		mov [esi+3], eax;
		mov [esi+6], eax;
		mov [esi+9], eax;
		mov ebx, l
		shl ebx, 1;
		add l, ebx;
		
		mov edx, t;
		mov ebx, h;
		shl edx, 2;
		mov eax, [esi];
		mov ebx, [esi+4];
		cld;
		
	clear24_loop:
		push edx;
		mov edi, line;
		mov edi, [edi+edx];
		add edi, l;
		mov edx, [esi+8];
		mov ecx, w;
		cmp ecx, 4;
		jb clear24_shortloop;
		
		sub ecx, 4;
	clear24_12loop:
		mov es:[edi], eax;
		mov es:[edi+4], ebx;
		mov es:[edi+8], edx;
		add edi, 12;
		sub ecx, 4;
		jns clear24_12loop;
		add ecx, 4;
		jz clear24_line;
		
	clear24_shortloop:
		mov es:[edi], ax;
		mov es:[edi+2], dl;
		add edi, 3;
		dec ecx;
		jnz clear24_shortloop;
		
	clear24_line:
		pop edx;
		add edx, 4;
		dec h;
		jnz clear24_loop;
		
		pop es;
	}
}

Bitmap* Bitmap24::ConvertFormat( int colordepth )
{
	int i, j;
	DWORD* src;
	short* dest;
	Bitmap* temp;

	switch( colordepth ){
	case 15:
	case 16:
		if( colordepth == 15 )
			temp = new Bitmap15;
		else
			temp = new Bitmap16;
		if( temp == NULL )
			return NULL;
		
		if( colordepth == 16 ){
			for( dest=(short*)line[0], i=0; i<height; i++ ){
				src = (DWORD*)line[i];
				for( j=0; j<width; j++, src=(DWORD*)((DWORD)src+3), dest++ )
					*dest = (short)(((*src & 0xf80000) >> 8) | ((*src & 0xfc00) >> 5)
							| ((*src & 0xf8 ) >> 3));
			}
			temp->colorKey = (( colorKey & 0xf80000) >> 8 ) | ((colorKey & 0xfc00) >> 5 )
							| (( colorKey & 0xf8 ) >> 3);
			temp->color = (( color & 0xf80000) >> 8 ) | ((color & 0xfc00) >> 5 )
							| (( color & 0xf8 ) >> 3);
		}
		else{
			for( dest=(short*)line[0], i=0; i<height; i++ ){
				src = (DWORD*)line[i];
				for( j=0; j<width; j++, src=(DWORD*)((DWORD)src+3), dest++ )
					*dest = (short)(((*src & 0xf80000) >> 9) | ((*src & 0xf800) >> 6)
							| ((*src & 0xf8 ) >> 3));
			}
			temp->colorKey = (( colorKey & 0xf80000) >> 9 ) | ((colorKey & 0xf800) >> 6 )
							| (( colorKey & 0xf8 ) >> 3);
			temp->color = (( color & 0xf80000) >> 9 ) | ((color & 0xf800) >> 6 )
							| (( color & 0xf8 ) >> 3);
		}
		temp->pitch = width * 2;
		temp->line = line;
		for( i=1; i<height; i++ )
			temp->line[i] = temp->line[i-1] + width * 2;
		temp->dat = realloc( dat, width * height * 2 );
		line = NULL;
		dat = NULL;
		break;

	default:
		return NULL;
	}

	temp->width = width;
	temp->height = height;
	temp->colorDepth = colordepth;
	temp->clip = clip;
	temp->cl = cl;
	temp->cr = cr;
	temp->ct = ct;
	temp->cb = cb;
	delete this;

	return temp;
}

⌨️ 快捷键说明

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