📄 cdraw.cpp
字号:
#include "../GameH.h"
//ddraw 封装
//小飞侠 制作
//2004
LPDIRECTDRAW7 lpDD;
LPDIRECTDRAWSURFACE7 lpDDS[DDS_NUM];
//****************Lock 相关*********************
WORD *GraphBuffer = 0; // 绘图缓冲区
int GraphPitch = 0; // 缓冲区跨度
int GraphWidth = 0; //页面宽度
int GraphHeight = 0; //页面高度
DDSURFACEDESC2 ddsd;
bool Is555=false; //是否为555格式
//--------------------------------------------------------------------------------------------------------------------//
// ddraw 封装 //
// DDS_DDraw7 2005年2月16日 小飞侠制作、整理 //
//--------------------------------------------------------------------------------------------------------------------//
BOOL InitDDraw(HWND Hwnd,int WindowS)
{
if ( DirectDrawCreateEx (NULL, (void **)&lpDD, IID_IDirectDraw7, NULL) != DD_OK ) return FALSE; //创建DirectDraw对象
if ( lpDD->SetCooperativeLevel (Hwnd,DDSCL_FPUSETUP|DDSCL_NORMAL) != DD_OK ) return FALSE; //设置DirectDraw控制级
//DDSCL_FPUSETUP|
//if ( lpDD->SetCooperativeLevel (Hwnd,DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN) != DD_OK ) return FALSE; //设置DirectDraw控制级
//if ( lpDD->SetDisplayMode( ScreenWidth, ScreenHeight, 16, 0, 0) != DD_OK ) return FALSE; //设置显示模式
ZeroMemory(&ddsd, sizeof(DDSURFACEDESC2));//设置页面内存大小
ddsd.dwSize = sizeof( ddsd );
ddsd.dwFlags = DDSD_CAPS; //没有后台缓存
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
if ( lpDD->CreateSurface( &ddsd, &lpDDS[0], NULL ) != DD_OK ) return FALSE; //创建主页面
ddsd.dwSize = sizeof( ddsd );
ddsd.dwFlags = DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY; //这是离屏页面
ddsd.dwHeight=ScreenHeight; //高
ddsd.dwWidth=ScreenWidth; //宽
if ( DD_OK != lpDD->CreateSurface( &ddsd, &lpDDS[1], NULL ) ) return FALSE; //创建后台缓存
if ( DD_OK != lpDD->CreateSurface( &ddsd, &lpDDS[2], NULL ) ) return FALSE; //创建背景图页面
if ( DD_OK != lpDD->CreateSurface( &ddsd, &lpDDS[4], NULL ) ) return FALSE; //创建地图表面
if ( DD_OK != lpDD->CreateSurface( &ddsd, &lpDDS[5], NULL ) ) return FALSE; //创建Alpha页面
if ( DD_OK != lpDD->CreateSurface( &ddsd, &lpDDS[6], NULL ) ) return FALSE; //创建临时页面
if ( DD_OK != lpDD->CreateSurface( &ddsd, &lpDDS[7], NULL ) ) return FALSE; //创建临时页面1
ddsd.dwHeight=CH; //高
ddsd.dwWidth=CW; //宽
if ( DD_OK != lpDD->CreateSurface( &ddsd, &lpDDS[3], NULL ) ) return FALSE; //创建鼠标页面
return TRUE; //返回TRUE
}
bool CreateSurface(LPDIRECTDRAWSURFACE7 &tmpS,char *FileName,int Width,int Height)
{
//如果没有制定图片信息,就去找
if (FileName!=NULL&&Width<=0&&Height<=0)
if (LoadPicInfo(FileName,Width,Height)==false) return false; //读取失败
ZeroMemory(&ddsd, sizeof(DDSURFACEDESC2));//设置页面内存大小
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY; //这是离屏页面
ddsd.dwHeight=Height; //高
ddsd.dwWidth=Width; //宽
if ( lpDD->CreateSurface( &ddsd, &tmpS, NULL ) == DD_OK)
{
if (FileName!=NULL) LoadPic(false,tmpS,FileName);
DDSetColorKey(tmpS,colorkey); //设定颜色键
return true;
}
return false;
}
//释放页面 By Flysky
//2005
void FreeDDraw()
{
if( lpDD != NULL ) //判断DirectDraw对象是否有效
{
if( lpDDS[0] != NULL ) //判断主页面对象是否有效
{
lpDDS[0]->Release(); //释放
lpDDS[0] = NULL;
}
//如果还有别的页面也像lpDDSPrimary一样释放
lpDD->Release( ); //释放
lpDD = NULL;
}
}
//恢复页面显示 By Flysky
//2005
void RestoreSurface()
{
lpDD->RestoreAllSurfaces();
//DDraw7 以下需要这样
// for (int i=0;i<DDS_NUM;)
//{
// lpDDS[i]->Restore( );
// i++;
//}
}
//翻转页面(无后台缓存) By Flysky 云风
//2005
void FlipSurface()
{
if (CheckMMX()==false)
{
HRESULT ddrval=lpDDS[0]->BltFast(0,0,lpDDS[1],NULL,NoKey);
if(ddrval==DDERR_SURFACELOST) RestoreSurface();
}
else
{
//MMX快速翻页
BeginDraw(lpDDS[1]);
BYTE *pSrc=(BYTE *)GraphBuffer; //源页面
int srcPitch=GraphPitch <<1;
int Width=GraphWidth;//宽度
int Height=GraphHeight; //高度
BeginDraw(lpDDS[0]);
BYTE *pDest=(BYTE *)GraphBuffer;
int DestPitch=GraphPitch <<1;
if (Width>GraphWidth) Width=GraphWidth;//宽度
if (Height>GraphHeight) Height=GraphHeight; //高度
int iX=Width <<1; //计算一共的数据块
for (int y=0;y<Height;y++)
{
//Qmemcpy(pDest, pSrc,iX); //拷贝内存
Qmemcpy(pDest, pSrc,iX);//拷贝内存
pSrc+=srcPitch; //移至下一行
pDest+=DestPitch; //移至下一行
}
EndDraw(lpDDS[1]);
EndDraw(lpDDS[0]);
}
}
//设定颜色键 By Flysky 微软
//2005
void SetColorKey(COLORREF rgb)
{
int i;
for (i=0;i<DDS_NUM;i++)
{
DDSetColorKey(lpDDS[i],rgb);
}
}
//***********************************************************
//功能:快速位图拷贝
//参数:目标表面,目标x,目标y,原表面,拷贝范围,是否带透明色
//By SoftBoy Flysky
void BltFast(LPDIRECTDRAWSURFACE7 SS,int x,int y,
LPDIRECTDRAWSURFACE7 DS,LPRECT rcRect,DWORD Flag)
{
if (rcRect!=NULL)
{
//边界检查
if( x<0 )
{
rcRect->left = rcRect->left - x;
x=0;
}
else if( x+ rcRect->right - rcRect->left > ScreenWidth )
{
rcRect->right = rcRect->left + ScreenWidth - x;
}
if( y<0 )
{
rcRect->top = rcRect->top - y;
y=0;
}
else if( y+ rcRect->bottom - rcRect->top > ScreenHeight )
{
rcRect->bottom = rcRect->top + ScreenHeight - y;
}
}
SS->BltFast( x, y, DS, rcRect, Flag);
}
//***********************************************************
//功能:位图拷贝
//参数:目标表面,目标x,目标y,原表面,拷贝范围,是否带透明色
//By SoftBoy Flysky
void Blt(LPDIRECTDRAWSURFACE7 SS,int x,int y,
LPDIRECTDRAWSURFACE7 DS,RECT rcRect,DWORD Flag)
{
HRESULT ddrval;
//边界检查
if( x<0 )
{
rcRect.left = rcRect.left - x;
x=0;
}
else
if( x+ rcRect.right - rcRect.left > ScreenWidth )
{
rcRect.right = rcRect.left + ScreenWidth - x;
}
if( y<0 )
{
rcRect.top = rcRect.top - y;
y=0;
}
else
if( y+ rcRect.bottom - rcRect.top > ScreenHeight )
{
rcRect.bottom = rcRect.top + ScreenHeight - y;
}
while( 1 )
{
ddrval = SS->BltFast( x, y, DS, &rcRect, Flag);
if( ddrval == DD_OK )
{
return;
}
if( ddrval == DDERR_SURFACELOST )
{
RestoreSurface();
return;
}
if( ddrval != DDERR_WASSTILLDRAWING )
{
return;
}
}
}
//=================================================================================================
// 更新1
//=================================================================================================
//***********************************************************
//功能:带缩放的位图拷贝
//参数:目标表面,目标矩阵,原表面,拷贝范围,是否带透明色
//By SoftBoy Flysky
BOOL SBlt(LPDIRECTDRAWSURFACE7 SS,RECT sr,
LPDIRECTDRAWSURFACE7 DS,RECT dr,BOOL Flag)
{
DWORD Flags= (Flag==FALSE)?0:DDBLT_KEYSRC;
HRESULT ddrval;
//边界检查
int SWidth=sr.right-sr.left, SHeight=sr.bottom-sr.top;
int DWidth=dr.right-dr.left, DHeight=dr.bottom-dr.top;
if( sr.left<0 )
{
dr.left += (DWidth * (-sr.left)) / SWidth;
sr.left=0;
}
if( sr.top<0 )
{
dr.top += (DHeight * (-sr.top)) / SHeight;
sr.top=0;
}
if( sr.right > ScreenWidth )
{
dr.right -= (DWidth * (sr.right-ScreenWidth)) / SWidth;
sr.right=ScreenWidth;
}
if( sr.bottom > ScreenHeight )
{
dr.bottom -= (DHeight *(sr.bottom-ScreenHeight)) / SHeight;
sr.bottom=ScreenHeight;
}
while( 1 )
{
ddrval = SS->Blt( &sr, DS, &dr, Flags, 0);
if( ddrval == DD_OK )
{
return TRUE;
}
if( ddrval == DDERR_SURFACELOST )
{
RestoreSurface();
return TRUE;
}
if( ddrval != DDERR_WASSTILLDRAWING )
{
return FALSE;
}
}
if(ddrval != DD_OK)
{
return FALSE;
}
}
//取得象素格式
//LpDD为目标表面
//By Flysky
void PixFormat(LPDIRECTDRAWSURFACE7 LpDD)
{
DDPIXELFORMAT DDPixelFormat;
ZeroMemory(&DDPixelFormat,sizeof(DDPixelFormat));
DDPixelFormat.dwSize=sizeof(DDPixelFormat);
LpDD->GetPixelFormat(&DDPixelFormat);//得到象素格式(在16位色下分555和565)
if((DDPixelFormat.dwGBitMask>>5)==0x1f)//00000011111
{
s_dwAlphaMask=_ALPHA555RGBMASK;
Is555=true;
}
else if((DDPixelFormat.dwGBitMask>>5)==0x3f)//00000111111
{
s_dwAlphaMask=_ALPHA565RGBMASK;
Is555=false;
}
}
//********************************************
//功能:清屏
//参数:目标表面,颜色值
//By Flysky MSDN
void Clrscr(LPDIRECTDRAWSURFACE7 surf,WORD color )
{
DDBLTFX ddbltfx;
ddbltfx.dwSize=sizeof(ddbltfx);
ddbltfx.dwFillColor=color;
surf->Blt(NULL,NULL,NULL,DDBLT_COLORFILL,&ddbltfx);
}
//************************************
//开页面缓冲区,然后直接在缓冲区中操作
//By Flysky SoftBoy
bool BeginDraw(LPDIRECTDRAWSURFACE7 lpSur)
{
HRESULT ddrval;
ddsd.dwSize = sizeof(ddsd);
while( 1 )
{
ddrval = lpSur->Lock( NULL, &ddsd, DDLOCK_WAIT, NULL ); //锁定
if( ddrval == DD_OK )
{
break;
}
if( ddrval == DDERR_SURFACELOST )
{
RestoreSurface();
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 );
}
//******************
//关闭缓冲区
//By Flysky SoftBoy
bool EndDraw(LPDIRECTDRAWSURFACE7 lpSur)
{
HRESULT ddrval;
ddrval = lpSur->Unlock( NULL ); //解锁
if( ddrval != DD_OK ) return( false );
return true;
}
//=================================================================================================
// 更新2
//=================================================================================================
//16位RGB换算
//By Flysky
WORD RGB16(WORD r, WORD g, WORD b)
{
//简单
if(Is555==true)
//rrrrr|ggggg|bbbbb 0xf8 = 11111000b
return RGBto555(r,g,b); //使用#define函数
//return ((r&0xf8)<<7) | ((g&0xf8)<<2) | ((b&0xf8)>>3);
else
//rrrrr|gggggg|bbbbb 0xfc = 11111100
return RGBto565(r,g,b); //使用#define函数
//return ((r&0xf8)<<8) | ((g&0xfc)<<3) | ((b&0xf8)>>3);
}
//24位转16位
//By Flysky
WORD RGB16(DWORD color)
{
WORD r,g,b;
//也比较简单
r=(WORD)(color>>16);
g=(WORD)(color>>8);
b=(WORD)color;
if(Is555==true)
return RGBto555(r,g,b); //使用#define函数
//return ((r&0xf8)<<7) | ((g&0xf8)<<2) | ((b&0xf8)>>3);
else
return RGBto565(r,g,b); //使用#define函数
//return ((r&0xf8)<<8) | ((g&0xfc)<<3) | ((b&0xf8)>>3);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -