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

📄 brighter.cpp

📁 仿游戏 Diablo 的源代码
💻 CPP
字号:
#include <conio.h>
#include <time.h>

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

//////////////////////////////////////////////////////////////////////////////////
// 光影效果

#define MAX_LAMPS	32

int brighterInstalled = false;

// brightness是sight及其它光源(Lamp)合成后得到
// 大小为主画面的1/4,一个点代表主画面上四个点的亮度
Bitmap8 *brightness; // 320x176,合成后的亮度掩图 
static Bitmap8 *sight;		//320x176主角的视野
extern Cache cache;

void LampDrawMMX( Bitmap8 *src, int x, int y );
void LampDraw( Bitmap8 *src, int x, int y );

struct Lamp{	//光源
	Bitmap8* light;	//亮度掩图
	int x, y;		//光源位置
	Lamp** reg;
	void (*draw)( Bitmap8 *src, int x, int y );

	Lamp();
	inline void Draw( void ){	// 将lamp合成到birghtness
		draw( this->light, x, y );
	};

	void Register( void );	//注册光源:将cache内光源添加到 lamp 中, 刷新cache时调用
	void UnRegister( void );
};

Lamp* lamp[32];		// cache范围内的所有光源

Lamp::Lamp()
{
	light = NULL;
	x = y =0;
	reg = NULL;
	if( cpu.mmx )
		draw = LampDrawMMX;
	else
		draw = LampDraw;
}

void Lamp::Register( void )
{
	for( int i=0; i<MAX_LAMPS; i++ )
		if( lamp[i] == NULL ){
			lamp[i] = this;
			reg = &( lamp[i] );
			return;
		}
}

void Lamp::UnRegister( void )
{
	if( reg )
		( *reg ) = NULL;
}

void LampDrawMMX( Bitmap8 *src, int x, int y  )
{
	int w = src->width;
	int h = src->height;
	int sx, sy;
	x /= 2;
	y /= 2;
	if( x >= brightness->width || y >= brightness->height )
		return;

	if( x < 0 ){
		sx = -x; x = 0; w -= sx;
		if( w <= 0 ) return;
	}
	else sx = 0;
	if( y < 0 ){
		sy = -y; y=0; h -= sy;
		if( h <= 0 ) return;
	}
	else sy = 0;
	if( x + w > brightness->width )
		w = brightness->width - x;
	if( y + h > brightness->height )
		h = brightness->height - y;
		
	__asm{
		mov eax, brightness;
		mov ecx, src;
		mov edi, [eax]Bitmap.line;
		mov esi, [ecx]Bitmap.line;
		mov ebx, y;
		mov edx, sy;
		shl ebx, 2;
		shl edx, 2;
		mov edi, [edi+ebx];
		mov esi, [esi+edx];
		mov ebx, w;
		mov edx, ebx;
		and ebx, 7;
		shr edx, 3;
		add edi, x;
		add esi, sx;

		movd mm4, ebx;
		movd mm5, edx;
		mov ebx, [ecx]Bitmap.pitch;
		mov edx, [eax]Bitmap.pitch;
		cld;
		mov ecx, w;
		sub ebx, ecx;
		sub edx, ecx;

draw_loop:
		movd ecx, mm4;
		jecxz useMMX;
draw_head:
		lodsb;
		add al, [edi];
		jnc not_overflow;
		mov al, 0xff;
not_overflow:
		stosb;
		loop draw_head;
		
useMMX:
		movd ecx, mm5;
		jecxz end_of_draw;
		
MMXloop:
		movq mm0, [edi];
		paddusb mm0, [esi];
		movq [edi], mm0;
		add esi, 8;
		add edi, 8;
		loop MMXloop;
		
end_of_draw:
		add esi, ebx;
		add edi, edx;
		dec h;
		jnz draw_loop;
		emms;
	}
}

void LampDraw( Bitmap8 *src, int x, int y )
{
}

//-------------------------------------------------------------------------------------

static DWORD const brightdegree[8] = { 0x04210421, 0x04210421,
				0x0c630c63, 0x0c630c63,
				0x1ce71ce7, 0x1ce71ce7,
				0x3def3def, 0x3def3def };

static void CopySightToBrightness( void )
{
	if( sight->pitch == brightness->pitch ){
		__asm{
			mov eax, sight;
			mov edx, brightness;
			mov ebx, [eax]Bitmap.line;
			mov ecx, [edx]Bitmap.line;
			mov eax, 16;
			mov esi, [ebx];
			mov edi, [ecx];
			mov ecx, WIN_WIDTH*WIN_HEIGHT/16/4;
			ALIGN 4;
copy:
			movq mm0, [esi];
			movq mm1, [esi+8];
			movq [edi], mm0;
			add esi, eax;
			movq [edi+8], mm1;
			add edi, eax;
			dec ecx;
			jnz copy;
		}
	}
	else{
		__asm{
			mov eax, sight;
			mov ecx, WIN_WIDTH/16/2;
			mov edx, brightness;
			movd mm7, ecx;
			mov ebx, [eax]Bitmap.line;
			mov ecx, [edx]Bitmap.line;
			mov esi, [ebx];
			mov edi, [ecx];
			mov ebx, WIN_HEIGHT/2;
			mov eax, [eax]Bitmap.pitch;
			mov edx, [edx]Bitmap.pitch;
			sub eax, WIN_WIDTH/2;
			sub edx, WIN_WIDTH/2;
			mov ecx, WIN_WIDTH/16/2;
			ALIGN 4;
copy_line:
			movq mm0, [esi];
			movq mm1, [esi+8];
			movq [edi], mm0;
			movq [edi+8], mm1;
			add esi, 16;
			add edi, 16;
			dec ecx;
			jnz copy_line;
			//loop copy_line;
			
			add esi, eax;
			add edi, edx;
			movd ecx, mm7;
			dec ebx;
			jnz copy_line;
			emms;
		}
	}
}

int InitBrighter( void )
{
	int i;

	sight = ( Bitmap8* )LoadBmp( "bright.bmp", NULL );
	if( sight == NULL || sight->colorDepth != 8 
		|| sight->width < WIN_WIDTH/2 ){
//		delete brightness;
		return -1;
	}
	brightness = ( Bitmap8* )CreateBitmapEx( WIN_WIDTH/2, WIN_HEIGHT/2, 8 );
	if( brightness == NULL )
		return -1;
	sight->Blit( brightness, 0,0, 0,0,WIN_WIDTH/2, WIN_HEIGHT/2 );
	
	for( i=0; i<MAX_LAMPS; i++ )
		lamp[i] = NULL;

	Lamp *lp = new Lamp;
	lp->light = ( Bitmap8* )LoadBmp( "bright2.bmp", NULL );
	lp->x = 0;
	lp->y = 100;
	lp->Register();
	
	lp = new Lamp;
	lp->light = lamp[0]->light;
	lp->x = 640;
	lp->y = -1;
	lp->Register();

	lp = new Lamp;
	lp->light = lamp[0]->light;
	lp->x = 0;
	lp->y = 200;
	lp->Register();

	lp = new Lamp;
	lp->light = lamp[0]->light;
	lp->x = 400;
	lp->y = 200;
	lp->Register();

	if( lp->reg == NULL )
		return -1;

	brighterInstalled = true;
	return 0;
}

void CopyGroundBrightnessMMX( int sx, int sy )
{
	char **bline = brightness->line;
	char **sline = cache.ground->line;
	char **dline = backScreen->line;
	int bpitch = brightness->pitch - WIN_WIDTH/2;
	int dpitch = backScreen->pitch;
	int spitch = cache.ground->pitch;
	int lines = WIN_HEIGHT/2;
	
	if( sx < 0 || sy < 0 || sx > WIN_WIDTH || sy > WIN_HEIGHT )
		return;
	
//	cache.ground->Blit( backScreen, 0,0, sx,sy, 640,352 );
//	return;

	CopySightToBrightness();
//	return;
/*	for( int i=0; i<MAX_LAMPS; i++ )
		if( lamp[i] )
			lamp[i]->Draw();
*/		
	__asm{
		lea eax, colorMask;
		xor ebx, ebx;
		movq mm4, [eax]; 		/* red */
		movq mm5, [eax+8]; 		/* green  */
		movq mm6, [eax+16]; 	/* blue  */
		
		shl sx, 1;
		shl sy, 2;
		mov ebx, sline;
		mov ecx, dline;
		mov eax, bline;
		add ebx, sy;
		mov edi, [ecx];
		mov esi, [ebx];
		mov ebx, [eax];
		mov ecx, 160;
		add esi, sx;
		mov edx, dpitch;
		mov eax, spitch;
		ALIGN 4;
copy_line:
//		test ecx, 1;
		movq mm1, [esi];
//		jnz shift_mm7;
		pxor mm7, mm7;
		movd mm0, [ebx];
		movq mm2, mm1;
		punpcklbw mm0, mm7;
		inc ebx;
		movq mm7, mm0;
//		jmp mm0_ready;
//shift_mm7:
//		psrlq mm7, 32;
//		movq mm2, mm1;
//		movq mm0, mm7;
//mm0_ready:
		movq mm3, mm1;
		punpcklwd mm0, mm7;
		pand mm3, mm6;
		psrlw mm0, 3;
		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;
		movq mm3, [esi+eax];
		por mm1, mm2;
		movq [edi], mm1;

		movq mm2, mm3;
		movq mm1, mm3;
		//add ebx, 2;
		inc ebx;
		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 esi, 8;
		por mm1, mm2;
		movq [edi+edx], mm1;
		add edi, 8;

		dec ecx;
		jnz copy_line;

		mov ecx, 160;
		add ebx, bpitch;
		add esi, eax;
		add edi, edx;
		add esi, eax;
		add edi, edx;
		sub esi, 1280;
		sub edi, 1280;
		dec lines;
		jnz copy_line;
		emms;
	}
}


int testBrighter( void )
{
#ifdef _DEBUG
//	OutDebugString( " in testBrighter" );
#endif

	int i=0;
	CopyGroundBrightnessMMX( i, 0 );
	lamp[0]->x += 6;
	lamp[1]->x -= 6;
	if( lamp[0]->x > 640 ) 
		lamp[0]->x = -160;
	if( lamp[1]->x < -160 )
		lamp[1]->x = 640;

	return 0;
}

⌨️ 快捷键说明

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