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

📄 gp_draw.cpp

📁 国产的RPG源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	if( ddrval == DD_OK ) 
	{
		x=ddsd.dwWidth;
		y=ddsd.dwHeight;
		return ddsd.lPitch>>1;		//不说了
	}	
	
	return false;
}

//****************************
//获取一个表面的宽度
int GetSurfaceWidth(LPDIRECTDRAWSURFACE surf)
{
	DDSURFACEDESC ddsd;
	HRESULT		ddrval;

	ddsd.dwSize=sizeof(ddsd);
	ddrval=surf->GetSurfaceDesc(&ddsd);
	if( ddrval == DD_OK ) 
	{
		return ddsd.dwWidth;
	}	
	
	return false;
}

//****************************
//获取一个表面的高度
int GetSurfaceHeight(LPDIRECTDRAWSURFACE surf)
{
	DDSURFACEDESC ddsd;
	HRESULT		ddrval;

	ddsd.dwSize=sizeof(ddsd);
	ddrval=surf->GetSurfaceDesc(&ddsd);
	if( ddrval == DD_OK ) 
	{
		return ddsd.dwHeight;
	}	
	
	return false;
}

//************************************
//开页面缓冲区,然后直接在缓冲区中操作
bool BeginDraw(LPDIRECTDRAWSURFACE lpSur)
{
    ddsd.dwSize = sizeof(ddsd);
    
	while( 1 )
	{ 
		ddrval = lpSur->Lock( NULL, &ddsd, DDLOCK_WAIT, NULL );	//锁定
		if( ddrval == DD_OK )
		{
		    break;
		}
		if( ddrval == DDERR_SURFACELOST )
		{
		    ddrval = restoreAll();
		  	if( ddrval != DD_OK ) return( false );
		} 
	}

  	GraphBuffer = (WORD *)ddsd.lpSurface;		//内存指针
	GraphWidth = ddsd.dwWidth;					//宽度
	GraphHeight = ddsd.dwHeight;				//高度
	GraphPitch  = ddsd.lPitch >> 1;	//lPitch以Byte为单位计数的,
									//GraphPitch以WORD为单位。所以GraphPitch = lPitch / 2;
    return( true );
}

//******************
//关闭缓冲区
bool EndDraw(LPDIRECTDRAWSURFACE lpSur)
{
   	ddrval = lpSur->Unlock( NULL );				//解锁
	if( ddrval != DD_OK ) return( false );
	return true;
}

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

//功能:以单色填充页面
//参数:目标表面,颜色
void FillSurface(LPDIRECTDRAWSURFACE surf, DWORD color)
{
	WORD color16=RGB16(color);				//转化成16色

	if( BeginDraw(surf) )
	{
	for( int i=0; i<GraphHeight; i++)
		for(int j=0; j<GraphWidth; j++)
			GraphBuffer[i*GraphPitch+j] = color16;		//直接填充
	EndDraw(surf);
	}
}

//以单色填充页面
void FillSurface(LPDIRECTDRAWSURFACE surf, WORD color)
{
	if( BeginDraw(surf) )
	{
	for( int i=0; i<GraphHeight; i++)
		for(int j=0; j<GraphWidth; j++)
			GraphBuffer[i*GraphPitch+j] = color;		//直接填充
	EndDraw(surf);
	}
}

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

//功能:特效淡入
//参数:风格,延时(缺省),颜色(缺省)
void FadeIn(int Style, int time, WORD Color)
{
	switch( Style )
	{
	case 0:	//无效果
		break;

	case 1:	//百叶窗
		ScreenIn();
		break;
	
	case 2:	//淡入淡出
		ColorIn(time, Color);
		break;
	}
}

//功能:特效淡出
//参数:风格,延时(缺省),目标表面(缺省)
void FadeOut(int Style, int time, LPDIRECTDRAWSURFACE lpSurf)
{
	switch( Style )
	{
	case 0:	//无效果
		break;

	case 1:	//百叶窗
		ScreenOut(lpSurf);
		break;
	
	case 2:	//淡入淡出
		ColorOut(lpSurf, time);
		break;
	}
}

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

//淡入(time=每一帧的时间)
void ColorIn(int time, WORD Color)
{
	unsigned int alpha=2, oldtick, newtick;
	WORD *lpSurf, *lpTemp, BlackColor=Color;

	//建立临时页面
	LPDIRECTDRAWSURFACE Temp;
	CreateBitmap(Temp, ScreenWidth, ScreenHeight);
	//保存到临时页面
	if( WindowMode==0 )	//全屏
		Blt(Temp, 0, 0, lpDDSPrimary, RectScreen, false);
	else
		Blt(Temp, 0, 0, lpDDSPrimary, RectWindow, false);

	if( BeginDraw(lpDDSBack) )
	{
		lpSurf=GraphBuffer;
		EndDraw(lpDDSBack);
	}

	if( BeginDraw(Temp) )
	{
		lpTemp=GraphBuffer;
		EndDraw(Temp);
	}

	oldtick=timeGetTime();	//起始时间

	for(int i=0; i<16; i++)
	{
		//把主表面的点和传近来的点进行alpha混合到lpDDSBack
		for(int j=0; j<ScreenWidth*ScreenHeight; j++)
		{
			lpSurf[j]=Alpha_Pixel(BlackColor, lpTemp[j], alpha);
		}

		//延时
		newtick=timeGetTime();
		while( newtick-oldtick < (unsigned int)(time * i) )
		{
			newtick=timeGetTime();
		}
		
		//更新屏幕
		_UpdateScreen();
		
		//自动跳桢
		i=(newtick-oldtick)/time;
		//alpha增加
		alpha=i*2+2;

		if( i >= 15 ) //结束
		{
			alpha=31;
			for(int j=0; j<ScreenWidth*ScreenHeight; j++)
			{
				lpSurf[j]=Alpha_Pixel(BlackColor, lpTemp[j], alpha);
			}
			_UpdateScreen();
			break;
		}
	}
	
	//释放
	_RELEASE( Temp );
}

//淡出(time=每一帧的时间)
void ColorOut(LPDIRECTDRAWSURFACE dest, int time)
{
	unsigned int alpha=2, oldtick, newtick;
	WORD *lpSour, *lpDest, *lpBack;

	if( WindowMode != 0 )	//窗口
	{
		Blt(lpDDSSour, 0,0, lpDDSPrimary, RectWindow, false);
	}
	else
	{
		Blt(lpDDSSour, 0,0, lpDDSPrimary, RectScreen, false);
	}

	if( BeginDraw(lpDDSSour) )
	{
		lpSour=GraphBuffer;
		EndDraw(lpDDSSour);
	}

	if( BeginDraw(dest) )
	{
		lpDest=GraphBuffer;
		EndDraw(dest);
	}

	if( BeginDraw(lpDDSTemp) )
	{
		lpBack=GraphBuffer;
		EndDraw(lpDDSTemp);
	}

	oldtick=timeGetTime();

	for(int i=0; i<16; i++)
	{
		for(int j=0; j<ScreenWidth*ScreenHeight; j++)
		{
			//看看上面的函数对比一下
			//这个是从屏幕逐渐变化到dest页面
			lpBack[j]=Alpha_Pixel(lpDest[j], lpSour[j], alpha);
		}

		//延时
		newtick=timeGetTime();
		while( newtick-oldtick < (unsigned int)(time*i) )	
		{
			newtick=timeGetTime();
		}

		//更新屏幕
		_UpdateScreen(lpDDSTemp);

		//自动跳桢
		i=(newtick-oldtick)/time;
		alpha=i*2+2;

		if( i >= 15 ) //结束
		{
			alpha=31;
			for(int j=0; j<ScreenWidth*ScreenHeight; j++)
			{
				lpBack[j]=Alpha_Pixel(lpDest[j], lpSour[j], alpha);
			}
			_UpdateScreen(lpDDSTemp);
			break;
		}
	}
}

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

//残像淡入(suf:目标页面,step:残像的多少,time:延时 20左右)
void ScreenIn(int Step,int Time)
{
	long T1=0, T2=0;
	int tmp=ScreenHeight/Step;
	WORD *Dest;
	T1=T2=timeGetTime();
	
	//取页面指针
	if( BeginDraw(lpDDSBack) )
	{
		Dest=(WORD *)GraphBuffer;
		EndDraw(lpDDSBack);
	}
	
	for( int j=0; j<tmp; j++)
	{
		//延时
		while( T1-T2<Time )
		{
			T1=timeGetTime();
		}
		T2=T1;

		for(int i=0; i<Step; i++)
			memset(&Dest[ScreenWidth*i*tmp+ScreenWidth*j], 0, ScreenWidth*2);
		
		_UpdateScreen();		//更新屏幕
	}
}

//残像淡出(开始页面,目标页面,残像数,延时)
void ScreenOut(LPDIRECTDRAWSURFACE dest,int Step,int Time)
{
	long T1, T2;
	WORD *Dest,*Sour;
	T1=T2=timeGetTime();
	
	//临时页面
	LPDIRECTDRAWSURFACE lpDDSTemp;
	CreateBitmap(lpDDSTemp, ScreenWidth, ScreenHeight);

	if( WindowMode != 0 )	//窗口
	{
		Blt(lpDDSTemp, 0,0, dest, RectScreen, false);
		Blt(lpDDSBack, 0,0, lpDDSPrimary, RectWindow, false);
	}
	else
	{
		Blt(lpDDSTemp, 0,0, dest, RectScreen, false);
		Blt(lpDDSBack, 0,0, lpDDSPrimary, RectScreen, false);
	}

	//取目标页面指针
	if( BeginDraw(lpDDSBack) )
	{
		Sour=(WORD *)GraphBuffer;
		EndDraw(lpDDSBack);
	}

	//取目标页面指针
	if( BeginDraw(lpDDSTemp) )
	{
		Dest=(WORD *)GraphBuffer;
		EndDraw(lpDDSTemp);
	}
	
	for( int j=0; j<ScreenHeight/Step; j++)
	{
		//延时
		while( T1-T2<Time )
		{
			T1=timeGetTime();
		}
		T2=T1;
	
		for(int i=0; i<Step; i++)
		{
			int sult=ScreenWidth*i*(ScreenHeight/Step)+ScreenWidth*j;
			memcpy( &Sour[sult], &Dest[sult], ScreenWidth*2);
		}

		_UpdateScreen();		//更新屏幕
	}

	//释放
	_RELEASE( lpDDSTemp );
}

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

//把一个表面顺时针旋转90度(本函数仅限于正方型矩阵)
void RolSurface(LPDIRECTDRAWSURFACE SS,int w)
{
	WORD *Surf,*Temp;
	int Width;
	LPDIRECTDRAWSURFACE DS;
	
	//取页面指针
	if( BeginDraw(SS) )
	{
		Surf=(WORD *)GraphBuffer;
		Width=GraphPitch;
		EndDraw(SS);
	}

	CreateBitmap(DS, w, w, NULL, DDSCAPS_SYSTEMMEMORY);
	//取页面指针
	if( BeginDraw(DS) )
	{
		Temp=(WORD *)GraphBuffer;
		EndDraw(DS);
	}

	_asm{
		mov edi, Temp		//指针保存到esi和edi中
		mov esi, Surf

		mov ebx, 0			//两个循环变量i,j
_loop1:	mov ecx, 0	
_loop2:	mov eax, Width		//eax放的是要翻转的表面的跨度
		mul ebx				//i*Width+j
		add eax, ecx
		shl eax, 1			//乘2
		push eax			//压栈:(i*Width+j)*2
		
		mov eax, w			//正方行的边长
		dec eax				//减一
		sub eax, ecx		//减j
		mul Width			//乘上跨度
		add eax, ebx		//加上i
		shl eax, 1			//eax=((w-1-j)*Width+i)*2

		mov dx, [esi+eax]	//dx放的是当前点的位置
		pop eax				//恢复eax的值,eax = (i*Width+j)*2
		mov [edi+eax], dx	//放到新表面的相应点
		
		inc ecx				//j++
		cmp ecx, w			//j<w吗?
		jnz _loop2			//还没有就还是在第二层循环
		
		inc ebx				//否则,i++
		cmp ebx, w			//i<w吗?
		jnz _loop1			//还没有就继续循环
	}
		
	memcpy(Surf, Temp, (Width*w)*2);	//把temp复制到surf上
	//free(Temp);
}
//下面三个inline函数得到R,G,B的值
inline unsigned char GetRed(WORD color)
{
	if( Is555 )
		return (color>>7) & 0xff;
	else
		return (color>>8) & 0xff;
}

inline unsigned char GetGreen(WORD color)
{
	if( Is555 )
		return (color>>2) & 0xff;
	else
		return (color>>3) & 0xff;
}
	
inline unsigned char GetBlue(WORD color)
{
	return (color & 0x1f) << 3;
}

// 功能:将一个16位的DirectDraw表面,存为一张24位BMP位图
// 输入:表面指针,输出的文件名
// 输出:是否成功
bool SaveToBitmapFile(LPDIRECTDRAWSURFACE lpSurface, char* filename)
{
	WORD* lpBuffer;			// 表面指针
	int nPitch; 			// 表面跨距
	int nWidth, nHeight;	// 表面宽高
	
	// 打开文件s
	FILE* fp;
	if( (fp=fopen(filename, "wb")) != NULL )
	{
		// 锁定表面
		DDSURFACEDESC ddsd;
		ddsd.dwSize = sizeof(ddsd);
		HRESULT ddrval = lpSurface->Lock( NULL, &ddsd, DDLOCK_WAIT, NULL );
		if( ddrval == DD_OK )
		{
  			lpBuffer = (WORD *)ddsd.lpSurface;
			nWidth = ddsd.dwWidth;
			nHeight = ddsd.dwHeight;
			//lPitch以Byte为单位计数的,GraphPitch以WORD为单位。所以GraphPitch = lPitch / 2;
			nPitch  = ddsd.lPitch >> 1;	
		}

		// 保存文件头
		BITMAPFILEHEADER FileHeader;
		FileHeader.bfType = 'BM';
		FileHeader.bfSize = nWidth * nHeight * 3 + 0x36;
		FileHeader.bfReserved1 = 0;
		FileHeader.bfReserved2 = 0;
		FileHeader.bfOffBits = 0x36;
		fwrite(&FileHeader, sizeof(BITMAPFILEHEADER), 1, fp);
		
		// 保存文件信息
		BITMAPINFOHEADER Header;
		Header.biSize = sizeof(BITMAPINFOHEADER);	// 结构的大小
		Header.biWidth = nWidth;					// 宽
		Header.biHeight = nHeight;					// 高
		Header.biPlanes = 1;						// 固定
		Header.biBitCount = 24;						// 颜色数
		Header.biCompression = BI_RGB;				// 是否压缩
		Header.biSizeImage = nWidth * nHeight * 3;	// 图片的大小
		Header.biXPelsPerMeter = 0;
		Header.biYPelsPerMeter = 0;
		Header.biClrUsed = 0;
		Header.biClrImportant = 0;
		fwrite(&Header, Header.biSize, 1, fp);

		// 写入具体内容(从下向上存放)
		fseek(fp, 0x36, SEEK_SET);
		WORD word;
		lpBuffer += nWidth * (nHeight - 1);
		for(int i=0; i<nHeight; i++)
		{
			for(int j=0; j<nWidth; j++)
			{
				word = *lpBuffer;
				fputc( GetBlue( word ), fp);	// 蓝
				fputc( GetGreen( word ), fp);	// 绿
				fputc( GetRed( word ), fp);		// 红
				lpBuffer++;
			}
			lpBuffer -= nPitch*2;	// 指针转到上一行的开始
		}

		fclose(fp);

		// 解锁表面
		ddrval = lpSurface->Unlock( NULL );
		return true;
	}

	return false;
}

⌨️ 快捷键说明

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