📄 ddrawfunc.cpp
字号:
#include "main.h"
#include "mmsystem.h"
LPDIRECTDRAWSURFACE DDS[MaxDDS];
DWORD *pS[MaxDDS];
long SP[MaxDDS];
long SW[MaxDDS];
long SH[MaxDDS];
LPDIRECTDRAW lpDD;
DWORD SrcKey=DDBLTFAST_SRCCOLORKEY| DDBLTFAST_WAIT;
DWORD NoKey=DDBLTFAST_NOCOLORKEY| DDBLTFAST_WAIT;
int error_code=-1;
BOOL InitDDraw( )
{
DDSURFACEDESC ddsd;
if (DirectDrawCreate(NULL,&lpDD,NULL)!=DD_OK)
return 0;
if (lpDD->SetCooperativeLevel(hwnd,DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN)!=DD_OK)
return 1;
if (lpDD->SetDisplayMode(640,480,32)!=DD_OK)
return 2;
ddsd.dwSize=sizeof(ddsd);
ddsd.dwFlags=DDSD_CAPS;
ddsd.ddsCaps.dwCaps=DDSCAPS_PRIMARYSURFACE;
if (lpDD->CreateSurface(&ddsd,&DDS[SPrimary],NULL)!=DD_OK)
return 3;
ddsd.dwSize=sizeof(ddsd);
ddsd.dwFlags=DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT;
ddsd.ddsCaps.dwCaps=DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY;
ddsd.dwHeight=480;
ddsd.dwWidth=640;
if ( DD_OK != lpDD->CreateSurface( &ddsd, &DDS[SBuffer], NULL ) )
return 4;
ddsd.dwHeight=640;
ddsd.dwWidth=1280;
if ( DD_OK != lpDD->CreateSurface( &ddsd, &DDS[SBack], NULL ) )
return 5;
ddsd.dwHeight=512;
ddsd.dwWidth=512;
if ( DD_OK != lpDD->CreateSurface( &ddsd, &DDS[SHuman], NULL ) )
return 5;
ddsd.dwHeight=97;
ddsd.dwWidth=416;
if ( DD_OK != lpDD->CreateSurface( &ddsd, &DDS[SBlock], NULL ) )
return 5;
ddsd.dwHeight=62;
ddsd.dwWidth=64;
if ( DD_OK != lpDD->CreateSurface( &ddsd, &DDS[SMap], NULL ) )
return 5;
ddsd.dwHeight=26;
ddsd.dwWidth=384;
if ( DD_OK != lpDD->CreateSurface( &ddsd, &DDS[SMouse], NULL ) )
return 5;
ddsd.dwHeight=20;
ddsd.dwWidth=170;
if ( DD_OK != lpDD->CreateSurface( &ddsd, &DDS[SOther], NULL ) )
return 5;
return -1;
}
void InitSurface( )
{
MCI_OPEN_PARMS OpenParms;
OpenParms.lpstrDeviceType =
(LPCSTR) MCI_DEVTYPE_SEQUENCER;
OpenParms.lpstrElementName = (LPCSTR) "northspr.mid"; //文件名
OpenParms.wDeviceID = 0;
mciSendCommand (NULL, MCI_OPEN,
MCI_WAIT | MCI_OPEN_TYPE |
MCI_OPEN_TYPE_ID | MCI_OPEN_ELEMENT,
(DWORD)(LPVOID) &OpenParms); //打开设备
MCI_PLAY_PARMS PlayParms;
PlayParms.dwFrom = 0; //从什么时间位置播放,单位为毫秒
mciSendCommand (OpenParms.wDeviceID, MCI_PLAY,
MCI_FROM, (DWORD)(LPVOID)&PlayParms); //播放MIDI
DDBLTFX ddBltFx;
ddBltFx.dwSize=sizeof(DDBLTFX);
ddBltFx.dwFillColor=0;
DDS[SPrimary]->Blt(NULL,NULL,NULL,DDBLT_WAIT|DDBLT_COLORFILL,&ddBltFx);
DDS[SBuffer]->Blt(NULL,NULL,NULL,DDBLT_WAIT|DDBLT_COLORFILL,&ddBltFx);
DDS[SBack]->Blt(NULL,NULL,NULL,DDBLT_WAIT|DDBLT_COLORFILL,&ddBltFx);
DDReLoadBitmap(DDS[SMap], "Map.BMP");
DDReLoadBitmap(DDS[SBlock], "Block.BMP");
DDReLoadBitmap(DDS[SHuman], "Sprite.BMP");
DDReLoadBitmap(DDS[SMouse], "Mouse.BMP");
DDReLoadBitmap(DDS[SOther],"Other.BMP");
DDSetColorKey(DDS[SHuman],0);
DDSetColorKey(DDS[SMap],RGB(255,0,255));
DDSetColorKey(DDS[SBack],0);
DDSetColorKey(DDS[SOther],0);
DDSetColorKey(DDS[SMouse],RGB(255,255,255));
DDSetColorKey(DDS[SBlock],RGB(255,0,255));
//初始化地图
for (int i=0;i<YSize;i++)
for (int j=0;j<XSize;j++)
{
MakeRect(0,map->MapData[i][j]*31,64,map->MapData[i][j]*31+31);
DDS[SBack]->BltFast(608-32*i+32*j,16*i+16*j,DDS[SMap],&rect,SrcKey);
}
}
void GetSurfaceData( )
{
SW[0]=640;
SH[0]=480;
for (int i=1;i<MaxDDS;i++)
{
DDSURFACEDESC ddsd;
ZeroMemory(&ddsd,sizeof(ddsd));
ddsd.dwSize=sizeof(ddsd);
DDS[i]->Lock(NULL,&ddsd,DDLOCK_WAIT,NULL);
SP[i]=ddsd.lPitch;
pS[i]=(DWORD *)ddsd.lpSurface;
SW[i]=ddsd.dwWidth;
SH[i]=ddsd.dwHeight;
DDS[i]->Unlock(&ddsd);
}
GameStatus=1;
}
void FlipSurface( )
{
HRESULT ddrval;
DDSURFACEDESC ddsd;
ZeroMemory(&ddsd,sizeof(ddsd));
ddsd.dwSize=sizeof(ddsd);
ddrval=DDS[SPrimary]->Lock(NULL,&ddsd,DDLOCK_WAIT,NULL);
pS[SPrimary]=(DWORD *)ddsd.lpSurface;
SP[SPrimary]=ddsd.lPitch;
MakeRect(0,0,640,480);
FastBlt(0,0,SPrimary,SBuffer,NoKey);
DDS[SPrimary]->Unlock(&ddsd);
if (ddrval==DDERR_SURFACELOST)
RestoreSurface( );
}
void RestoreSurface( )
{
for (int i=0;i<MaxDDS;i++)
DDS[i]->Restore( );
InitSurface( );
}
void FastBlt(int x,int y,int des_id,int src_id,DWORD mode)
{
DWORD *p=pS[des_id]+y*SP[des_id]/4+x;
DWORD *q=pS[src_id]+rect.top*SP[src_id]/4+rect.left;
long desP=SP[des_id];
long srcP=SP[src_id];
long asize=(rect.right-rect.left)/4;
long bsize=rect.bottom-rect.top;
if (asize*4==(rect.right-rect.left)) //可同时拷贝四个点
{
if (mode==NoKey)
{
__asm
{
ALIGN 8;
mov esi,p;
mov edi,q;
mov eax,asize;
mov ebx,bsize;
mov edx,desP;
outloop:
mov ecx,eax;
push edi;
push esi;
innloop:
movq mm0,[edi];
movq mm1,[edi+8];
movq [esi],mm0;
movq [esi+8],mm1;
add edi,16;
add esi,16;
dec ecx;
jnz innloop;
pop esi;
pop edi;
add esi,edx;
add edi,srcP;
dec ebx;
jnz outloop;
emms;
}
}
else
{
}
}
else //两个两个地拷贝
{
asize=(rect.right-rect.left)/2;
if (mode==NoKey)
{
__asm
{
ALIGN 8;
mov esi,p;
mov edi,q;
mov eax,asize;
mov ebx,bsize;
mov edx,desP;
zoutloop:
mov ecx,eax;
push edi;
push esi;
zinnloop:
movq mm0,[edi];
movq [esi],mm0;
add edi,8;
add esi,8;
dec ecx;
jnz zinnloop;
pop esi;
pop edi;
add esi,edx;
add edi,srcP;
dec ebx;
jnz zoutloop;
emms;
}
}
else
{
}
}
}
void MyBlt(int x,int y,int src_id,int dest_id,DWORD method)
{
int rl,rt,tx1,tx2,ty1,ty2,tl,tt;
RECT rect2=rect;
rl=rect.left;
rt=rect.top;
if (rect.left>=SW[src_id])
goto noblt;
if (rect.top>=SH[src_id])
goto noblt;
if (rect.right<=0)
goto noblt;
if (rect.bottom<=0)
goto noblt;
if (rect.left<0)
rect.left=0;
if (rect.top<0)
rect.top=0;
if (rect.right>SW[src_id])
rect.right=SW[src_id];
if (rect.bottom>SH[src_id])
rect.bottom=SH[src_id];
tx1=x+rect.left-rl;
ty1=y+rect.top-rt;
tx2=x+rect.right-rl;
ty2=y+rect.bottom-rt;
if (tx2<=0)
goto noblt;
if (ty2<=0)
goto noblt;
if (tx1>=SW[dest_id])
goto noblt;
if (ty1>=SH[dest_id])
goto noblt;
tl=tx1;
tt=ty1;
if (tx1<0)
tx1=0;
if (ty1<0)
ty1=0;
if (tx2>SW[dest_id])
tx2=SW[dest_id];
if (ty2>SH[dest_id])
ty2=SH[dest_id];
rl=rect.left;
rt=rect.top;
rect.left=tx1-tl+rl;
rect.top=ty1-tt+rt;
rect.right=tx2-tl+rl;
rect.bottom=ty2-tt+rt;
if (method==NoKey)
FastBlt(tx1,ty1,dest_id,src_id,method);
if (method==SrcKey)
DDS[dest_id]->BltFast(tx1,ty1,DDS[src_id],&rect,method);
noblt:
rect=rect2;
}
void FreeDDraw( )
{
if( lpDD != NULL )
{
for (int i=0;i<MaxDDS;i++)
{
if(DDS[i]!=NULL)
{
DDS[i]->Release( );
DDS[i]=NULL;
}
}
lpDD->Release( );
lpDD = NULL;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -