-
DalÜφ p°φklad ukazuje, jak inicializovat DirectDraw, vytvo°it u₧ivatelskou
paletu a zobrazit ji na DirectDrawSurface. ZaΦneme v²voj novΘ aplikace.
Formulß° nechßme prßzdn², je u n∞j pouze dopln∞n konstruktor a vytvo°ena
obsluha udßlosti OnPaint. Do deklarace t°φdy formulß°e bylo dopln∞no
n∞kolik ve°ejn²ch slo₧ek (t°i metody a p∞t datov²ch slo₧ek):
void __fastcall InitializeDirectDraw();
void __fastcall SetupPrimarySurface();
void __fastcall ShowPalette();
int ddColors, ddWidth, ddHeight;
IDirectDraw *DirectDraw;
IDirectDrawSurface *PrimarySurface;
Nßsleduje v²pis zdrojovΘho souboru formulß°e:
#include <vcl.h>
#pragma hdrstop
#include "DDCP.h"
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
BorderStyle = bsNone;
InitializeDirectDraw();
}
void __fastcall TForm1::InitializeDirectDraw()
{
DirectDrawCreate(NULL, &DirectDraw,
NULL);
DirectDraw->SetCooperativeLevel(Handle,
DDSCL_ALLOWREBOOT |
DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
DirectDraw->SetDisplayMode(640, 480,
8);
SetupPrimarySurface();
}
void __fastcall TForm1::SetupPrimarySurface()
{
DDSURFACEDESC ddsd;
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
DirectDraw->CreateSurface(&ddsd,
&PrimarySurface, NULL);
}
void __fastcall TForm1::ShowPalette()
{
RECT rect;
rect.top = 60;
DDBLTFX ddbltfx;
ZeroMemory(&ddbltfx, sizeof(ddbltfx));
ddbltfx.dwSize = sizeof(ddbltfx);
IDirectDrawPalette *palette332;
PALETTEENTRY pe[256];
// algoritmus pro paletu 332
for(int i = 0; i < 256; i++)
{
pe[i].peRed = (BYTE) (((i
>> 5)& 7)* 255/ 7);
pe[i].peGreen = (BYTE)
(((i >> 2)& 7)* 255/ 7);
pe[i].peBlue = (BYTE)
(((i >> 0)& 3)* 255/ 3);
pe[i].peFlags = (BYTE)0;
}
DirectDraw->CreatePalette(DDPCAPS_8BIT,
pe, &palette332, NULL);
PrimarySurface->SetPalette(palette332);
for (int i = 0; i < 255; i++)
{
ddbltfx.dwFillColor =
i;
if(i % 16 == 0)
{
rect.top +=
20;
rect.left
= 160;
rect.right
= rect.left + 10;
rect.bottom
= rect.top + 10;
}
else
{
rect.left
+= 20;
rect.right
= rect.left + 10;
}
PrimarySurface->Blt(&rect,
NULL, NULL, DDBLT_COLORFILL, &ddbltfx);
}
}
void __fastcall TForm1::FormPaint(TObject
*Sender)
{
DDBLTFX ddbltfx;
ZeroMemory(&ddbltfx, sizeof(ddbltfx));
ddbltfx.dwSize = sizeof(ddbltfx);
ddbltfx.dwFillColor = RGB(0x00, 0x00,
0x00);
PrimarySurface->Blt(NULL, NULL, NULL,
DDBLT_COLORFILL, &ddbltfx);
ShowPalette();
}
Program si prostudujte. Po jeho spuÜt∞nφ je inicializovßn DirectDraw,
vytvo°ena primßrnφ vrstva, vytvo°ena a zobrazena paleta. Program nenφ mo₧no
b∞₧n²m zp∙sobem ukonΦit.
-
DalÜφ program ukazuje koncepci zavßd∞nφ bitovΘ mapy do DirectDraw. Program
ukazuje p°epφnßnφ mezi dv∞mi vrstvami (jedna obsahuje bitovou mapu a druhß
je Φernß). Obrßzek tedy blikß. Tento program pou₧φvß pomocnou knihovnu
funkcφ pro zavßd∞nφ bitov²ch map a palet ze zdroj∙. Nßsleduje v²pis hlaviΦkovΘho
souboru tΘto zdrojovΘ jednotky (soubor ddutil.h):
/* Copyright (C) 1995 Microsoft Corporation.
All Rights Reserved.
* File:
ddutil.cpp
* Content:
Routines for loading bitmap and palettes from resources
*********************************************************************/
#ifdef __cplusplus
extern "C" {
/* Assume C declarations for C++ */
#endif /* __cplusplus */
extern IDirectDrawPalette * DDLoadPalette(IDirectDraw
*pdd,
LPCSTR
szBitmap);
extern IDirectDrawSurface * DDLoadBitmap(IDirectDraw
*pdd,
LPCSTR
szBitmap, int dx, int dy);
extern HRESULT DDReLoadBitmap(IDirectDrawSurface
*pdds,LPCSTR szBitmap);
extern HRESULT DDCopyBitmap(IDirectDrawSurface
*pdds, HBITMAP hbm,
int
x, int y, int dx, int dy);
extern DWORD DDColorMatch(IDirectDrawSurface
*pdds, COLORREF rgb);
extern HRESULT DDSetColorKey(IDirectDrawSurface
*pdds, COLORREF rgb);
#ifdef __cplusplus
}
#endif /* __cplusplus */
Zdrojov² soubor ddutil.cpp mß nßsledujφcφ obsah:
#undef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <windowsx.h>
#include <ddraw.h>
#include "ddutil.h"
/*
* DDLoadBitmap - zavßd∞nφ vrstvy
DirectDraw ze zdroje bitovΘ mapy.
*/
extern "C" IDirectDrawSurface * DDLoadBitmap(IDirectDraw
*pdd,
LPCSTR szBitmap, int dx, int dy)
{
HBITMAP
hbm;
BITMAP
bm;
DDSURFACEDESC
ddsd;
IDirectDrawSurface *pdds;
// pokus o zavedenφ bitovΘ mapy jako
zdroje, p°i ne·sp∞chu ji zavedeme
// ze souboru
hbm = (HBITMAP)LoadImage(GetModuleHandle(NULL),
szBitmap,
IMAGE_BITMAP, dx, dy, LR_CREATEDIBSECTION);
if (hbm == NULL)
hbm = (HBITMAP)LoadImage(NULL,
szBitmap, IMAGE_BITMAP, dx, dy,
LR_LOADFROMFILE|LR_CREATEDIBSECTION);
if (hbm == NULL) return NULL;
// zφskßnφ velikosti bitovΘ mapy
GetObject(hbm, sizeof(bm), &bm);
// vytvo°enφ vrstvy pro tuto bitovou
mapu
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT
|DDSD_WIDTH;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
ddsd.dwWidth = bm.bmWidth;
ddsd.dwHeight = bm.bmHeight;
if (pdd->CreateSurface(&ddsd,
&pdds, NULL) != DD_OK) return NULL;
DDCopyBitmap(pdds, hbm, 0, 0, 0, 0);
DeleteObject(hbm);
return pdds;
}
/*
* DDReLoadBitmap - zavedenφ bitovΘ
mapy ze souboru nebo zdroje
* na vrstvu (pou₧φvßno k op∞tovnΘmu
zavedenφ vrstvy po obnoveni).
*/
HRESULT DDReLoadBitmap(IDirectDrawSurface
*pdds, LPCSTR szBitmap)
{
HBITMAP
hbm;
HRESULT
hr;
hbm = (HBITMAP)LoadImage(GetModuleHandle(NULL),
szBitmap,
IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
if (hbm == NULL)
hbm = (HBITMAP)LoadImage(NULL, szBitmap,
IMAGE_BITMAP, 0, 0,
LR_LOADFROMFILE|LR_CREATEDIBSECTION);
if (hbm == NULL)
{
OutputDebugString("handle
is null\n");
return E_FAIL;
}
hr = DDCopyBitmap(pdds, hbm, 0, 0,
0, 0);
if (hr != DD_OK) OutputDebugString("ddcopybitmap
failed\n");
DeleteObject(hbm);
return hr;
}
/*
* DDCopyBitmap - kreslenφ bitovΘ
mapy na vrstv∞
*/
extern "C" HRESULT DDCopyBitmap(IDirectDrawSurface
*pdds, HBITMAP hbm,
int x, int y, int dx, int dy)
{
HDC
hdcImage;
HDC
hdc;
BITMAP
bm;
DDSURFACEDESC
ddsd;
HRESULT
hr;
if (hbm == NULL || pdds == NULL) return
E_FAIL;
// obnovenφ vrstvy
pdds->Restore();
// v²b∞r bitovΘ mapy v memoryDC, kterou
chceme pou₧φt
hdcImage = CreateCompatibleDC(NULL);
if (!hdcImage) OutputDebugString("createcompatible
dc failed\n");
SelectObject(hdcImage, hbm);
// zφskßnφ velikosti bitovΘ mapy
GetObject(hbm, sizeof(bm), &bm);
dx = dx == 0 ? bm.bmWidth :
dx;
dy = dy == 0 ? bm.bmHeight : dy;
// zφskßnφ velikosti vrstvy
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;
pdds->GetSurfaceDesc(&ddsd);
if ((hr = pdds->GetDC(&hdc)) ==
DD_OK)
{
StretchBlt(hdc, 0, 0,
ddsd.dwWidth, ddsd.dwHeight, hdcImage, x, y,
dx, dy, SRCCOPY);
pdds->ReleaseDC(hdc);
}
DeleteDC(hdcImage);
return hr;
}
//
// DDLoadPalette - vytvo°enφ objektu palety
DirectDraw ze zdroje bitovΘ
// mapy (pokud zdroj neexistuje vytvo°φme
implicitnφ paletu 332).
//
#pragma warn -pia-
extern "C" IDirectDrawPalette * DDLoadPalette(IDirectDraw
*pdd,
LPCSTR szBitmap)
{
IDirectDrawPalette* ddpal;
int
i;
int
n;
int
fh;
HRSRC
h;
LPBITMAPINFOHEADER lpbi;
PALETTEENTRY
ape[256];
RGBQUAD *
prgb;
// vytvo°enφ palety 332 jako implicitnφ
for (i=0; i<256; i++)
{
ape[i].peRed
= (BYTE)(((i >> 5) & 0x07) * 255 / 7);
ape[i].peGreen = (BYTE)(((i
>> 2) & 0x07) * 255 / 7);
ape[i].peBlue =
(BYTE)(((i >> 0) & 0x03) * 255 / 3);
ape[i].peFlags = (BYTE)0;
}
// zφskßnφ ukazatele na zdroj bitovΘ
mapy
if (szBitmap && (h = FindResource(NULL,
szBitmap, RT_BITMAP)))
{
lpbi = (LPBITMAPINFOHEADER)LockResource(LoadResource(NULL,
h));
if (!lpbi) OutputDebugString("lock
resource failed\n");
prgb = (RGBQUAD*)((BYTE*)lpbi
+ lpbi->biSize);
if (lpbi == NULL || lpbi->biSize
< sizeof(BITMAPINFOHEADER)) n = 0;
else if (lpbi->biBitCount
> 8) n = 0;
else if (lpbi->biClrUsed
== 0) n = 1 << lpbi->biBitCount;
else n = lpbi->biClrUsed;
// tabulka barev DIB mß
svΘ bavy uloeny jako BGR a ne RGB
for(i=0; i<n; i++ )
{
ape[i].peRed
= prgb[i].rgbRed;
ape[i].peGreen
= prgb[i].rgbGreen;
ape[i].peBlue
= prgb[i].rgbBlue;
ape[i].peFlags
= 0;
}
}
else if (szBitmap && (fh =
_lopen(szBitmap, OF_READ)) != -1)
{
BITMAPFILEHEADER bf;
BITMAPINFOHEADER bi;
_lread(fh, &bf, sizeof(bf));
_lread(fh, &bi, sizeof(bi));
_lread(fh, ape, sizeof(ape));
_lclose(fh);
if (bi.biSize != sizeof(BITMAPINFOHEADER))
n = 0;
else if (bi.biBitCount
> 8) n = 0;
else if (bi.biClrUsed
== 0) n = 1 << bi.biBitCount;
else n = bi.biClrUsed;
// tabulka barev DIB mß
svΘ bavy uloeny jako BGR a ne RGB
for(i=0; i<n; i++ )
{
BYTE r = ape[i].peRed;
ape[i].peRed
= ape[i].peBlue;
ape[i].peBlue
= r;
}
}
pdd->CreatePalette(DDPCAPS_8BIT, ape,
&ddpal, NULL);
return ddpal;
}
#pragma warn -pia
/*
* DDColorMatch - p°evod RGB barvy na
fyzickΘ barvy
*/
extern "C" DWORD DDColorMatch(IDirectDrawSurface
*pdds, COLORREF rgb)
{
COLORREF rgbT;
HDC hdc;
DWORD dw = CLR_INVALID;
DDSURFACEDESC ddsd;
HRESULT hres;
if (rgb != CLR_INVALID &&
pdds->GetDC(&hdc) == DD_OK)
{
rgbT = GetPixel(hdc, 0,
0); // ulo₧enφ souΦasnΘ barvy
SetPixel(hdc, 0, 0, rgb);
// nastavenφ vlastnφ barvy
pdds->ReleaseDC(hdc);
}
ddsd.dwSize = sizeof(ddsd);
while((hres=pdds->Lock(NULL,&ddsd,0,NULL))==DDERR_WASSTILLDRAWING);
if (hres == DD_OK)
{
dw = *(DWORD *)ddsd.lpSurface;
if(ddsd.ddpfPixelFormat.dwRGBBitCount
< 32)
dw &=
(1 << ddsd.ddpfPixelFormat.dwRGBBitCount)-1;
pdds->Unlock(NULL);
}
if (rgb != CLR_INVALID &&
pdds->GetDC(&hdc) == DD_OK)
{
SetPixel(hdc, 0, 0, rgbT);
pdds->ReleaseDC(hdc);
}
return dw;
}
/*
* DDSetColorKey - nastavenφ barevnΘho
klφΦe pro vrstvu
*/
extern "C" HRESULT DDSetColorKey(IDirectDrawSurface
*pdds, COLORREF rgb)
{
DDCOLORKEY
ddck;
ddck.dwColorSpaceLowValue =
DDColorMatch(pdds, rgb);
ddck.dwColorSpaceHighValue = ddck.dwColorSpaceLowValue;
return pdds->SetColorKey(DDCKEY_SRCBLT,
&ddck);
}
ZaΦneme v²vojem novΘ aplikace. Do projektu p°idßme v²Üe uveden² zdrojov²
soubor. NaÜe aplikace pot°ebuje soubor zdroj∙ bitovΘ mapy. Bitovou
mapu si stßhneme a ulo₧φme do stejnΘho adresß°e jako ostatnφ soubory
projektu. K vytvo°enφ souboru zdroj∙ z tΘto bitovΘ mapy vytvo°φme soubor
ddex2.rc,
kter² takΘ p°idßme k projektu (ve stejnΘm adresß°i jako je projekt) s nßsledujφcφm
obsahem:
BACK BITMAP BACK.BMP
Na formulß° vlo₧φme komponentu Timer a vytvo°φme n∞kolik obsluh
udßlostφ. HlaviΦkov² soubor formulß°e vypadß takto:
#ifndef MainH
#define MainH
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <Menus.hpp>
#include <ExtCtrls.hpp>
class TForm1 : public TForm
{
__published:
TTimer *Timer1;
void __fastcall FormDestroy(TObject *Sender);
void __fastcall FormKeyDown(TObject *Sender, WORD &Key,
TShiftState Shift);
void __fastcall FormPaint(TObject *Sender);
void __fastcall Timer1Timer(TObject *Sender);
private:
LPDIRECTDRAW
lpDD; // objekt
DirectDraw
LPDIRECTDRAWSURFACE lpDDSPrimary;
// primßrnφ vrstva DirectDraw
LPDIRECTDRAWSURFACE lpDDSBack;
// zadnφ vrstva DirectDraw
LPDIRECTDRAWPALETTE lpDDPal;
// paleta DirectDraw
BOOL
bActive;
BYTE phase;
AnsiString FrontMsg;
AnsiString BackMsg;
void __fastcall Start();
public:
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
Zdrojov² soubor formulß°e tvo°φ:
#include <vcl.h>
#include <ddraw.h>
#pragma hdrstop
#include "Main.h"
#include "ddutil.h"
#pragma resource "*.dfm"
#define TIMER_ID
1
#define TIMER_RATE
500
TForm1 *Form1;
char szBackground[] = "BACK";
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
lpDD = NULL;
phase = 0;
bActive = False;
FrontMsg = "Front buffer (F12 or Esc
to quit)";
BackMsg = "Back buffer (F12 or Esc
to quit)";
}
void __fastcall TForm1::FormDestroy(TObject
*Sender)
{
if(lpDD != NULL)
{
if(lpDDSPrimary != NULL)
{
lpDDSPrimary->Release();
lpDDSPrimary
= NULL;
}
if(lpDDPal != NULL )
{
lpDDPal->Release();
lpDDPal =
NULL;
}
lpDD->Release();
lpDD = NULL;
}
}
void __fastcall TForm1::Start()
{
HRESULT ddrval;
DDSURFACEDESC ddsd;
DDSCAPS ddscaps;
char buf[256];
ddrval = DirectDrawCreate(NULL, &lpDD,
NULL);
if(ddrval == DD_OK)
{
ddrval = lpDD->SetCooperativeLevel(Handle,
DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN);
if(ddrval == DD_OK)
{
ddrval = lpDD->SetDisplayMode(640,
480, 8);
if(ddrval
== DD_OK)
{
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE |
DDSCAPS_FLIP | DDSCAPS_COMPLEX;
ddsd.dwBackBufferCount = 1;
ddrval = lpDD->CreateSurface(&ddsd, &lpDDSPrimary, NULL);
if(ddrval == DD_OK)
{
ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
ddrval = lpDDSPrimary->GetAttachedSurface(&ddscaps,
&lpDDSBack);
if(ddrval == DD_OK)
{
lpDDPal = DDLoadPalette(lpDD, szBackground);
if (lpDDPal == NULL) goto error;
ddrval = lpDDSPrimary->SetPalette(lpDDPal);
if( ddrval != DD_OK ) goto error;
ddrval = DDReLoadBitmap(lpDDSBack, szBackground);
if( ddrval != DD_OK ) goto error;
Timer1->Enabled = True;
bActive = True;
return;
}
}
}
}
}
error:
wsprintf(buf, "Direct Draw Init Failed
(%08lx)\n", ddrval);
MessageBox(Handle, buf, "ERROR", MB_OK);
Close();
}
void __fastcall TForm1::FormKeyDown(TObject
*Sender, WORD &Key,
TShiftState Shift)
{
switch (Key)
{
case VK_F3:
Start();
break;
case VK_ESCAPE:
case VK_F12:
Close();
break;
}
}
void __fastcall TForm1::FormPaint(TObject
*Sender)
{
RECT rc;
SIZE size;
char szMsg[]="Page Flipping Test:
Press F3 to start, F12 or Esc to exit";
if (!bActive)
{
HDC DC = GetDC(Handle);
rc = GetClientRect();
GetTextExtentPoint(DC,
szMsg, lstrlen(szMsg), &size);
SetBkColor(DC, RGB(0,
0, 0));
SetTextColor(DC, RGB(255,
255, 0));
TextOut(DC, (rc.right
- size.cx)/2, (rc.bottom - size.cy)/2,
szMsg, sizeof(szMsg)-1);
ReleaseDC(Handle, DC);
}
}
void __fastcall TForm1::Timer1Timer(TObject
*Sender)
{
HDC DC;
if (lpDDSBack->GetDC(&DC) == DD_OK)
{
if(phase)
{
SetBkColor(DC,
RGB(0, 0, 255));
SetTextColor(DC,
RGB(255, 255, 0));
TextOut(DC,
0, 0, FrontMsg.c_str(), FrontMsg.Length());
phase = 0;
}
else
{
SetBkColor(DC,
RGB(0, 0, 255));
SetTextColor(DC,
RGB(0, 255, 255));
TextOut(DC,
0, 0, BackMsg.c_str(), BackMsg.Length());
phase = 1;
}
lpDDSBack->ReleaseDC(DC);
}
while(1)
{
HRESULT ddrval;
ddrval = lpDDSPrimary->Flip(
NULL, 0 );
if( ddrval == DD_OK )
break;
if( ddrval == DDERR_SURFACELOST
)
{
ddrval = lpDDSPrimary->Restore();
if( ddrval
!= DD_OK ) break;
ddrval = DDReLoadBitmap(lpDDSBack,
szBackground);
if( ddrval
!= DD_OK ) break;
}
if( ddrval != DDERR_WASSTILLDRAWING
) break;
}
}
Zde jsou pou₧ity nßm ji₧ znßmΘ metody. Aplikaci vyzkouÜejte.
-
Jako poslednφ aplikaci pou₧φvajφcφ DirectDraw si ukß₧eme aplikaci provßd∞jφcφ
ji₧ skuteΦnou animaci. ZaΦneme v²voj novΘ aplikace. Tato aplikace op∞t
vyu₧φvß funkce z jednotky ddutil.cpp (jako p°edchozφ aplikace).
P°idßme tedy tuto jednotku k naÜemu projektu (hlaviΦkov² soubor ddutil.h
musφ b²t ve stejnΘm adresß°i). Aplikace op∞t bude pot°ebovat soubor zdroj∙
s bitovou mapou. Stßhneme si bitovou mapu a umφstφme
ji do adresß°e projektu. Z tΘto bitovΘ mapy vytvo°φme soubor zdroj∙ pomocφ
nßsledujφcφho soubor∙ (je zapot°ebφ aby byl v adresß°i projektu, nazveme
jej ddex4.rc a p°idßme jej k projektu):
#include "resource.h"
ALL BITMAP ALL.BMP
IDR_MENU MENU DISCARDABLE
BEGIN
POPUP "&File"
BEGIN
MENUITEM "E&xit", IDM_EXIT
END
END
Vidφme ₧e tento soubor vklßdß hlaviΦkov² soubor resource.h.
Tento hlaviΦkov² soubor obsahuje (umφstφme jej do stejnΘho adresß°e; jsou
zde definice identifikßtor∙ prvk∙ souboru zdroj∙):
#define IDR_MENU
102
#define IDM_EXIT
40001
HlaviΦkov² soubor formulß°e mß nßsledujφcφ obsah:
#ifndef MainH
#define MainH
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#define WM_INFOSTART WM_USER
class TForm1 : public TForm
{
__published:
void __fastcall FormDestroy(TObject
*Sender);
void __fastcall FormKeyDown(TObject
*Sender, WORD &Key,
TShiftState Shift);
void __fastcall FormPaint(TObject
*Sender);
private:
LPDIRECTDRAW lpDD;
LPDIRECTDRAWSURFACE lpDDSPrimary;
LPDIRECTDRAWSURFACE lpDDSBack;
LPDIRECTDRAWSURFACE lpDDSOne;
LPDIRECTDRAWPALETTE lpDDPal;
BOOL FActive;
BOOL FRunApp;
void UpdateFrame(void);
void Start();
void InitFail();
HRESULT RestoreAll(void);
MESSAGE void MyMove(TMessage &Message);
public:
__fastcall TForm1(TComponent* Owner);
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(WM_INFOSTART, TMessage,
MyMove);
END_MESSAGE_MAP(TForm);
};
extern TForm1 *Form1;
#endif
a zdrojov² soubor formulß°e obsahuje:
#include <vcl.h>
#include <ddraw.h>
#pragma hdrstop
#include "ddutil.h"
#include "Main.h"
#pragma resource "*.dfm"
#define NAME "DDExample4"
#define TITLE "Direct Draw Example 4"
char szBitmap[] = "ALL";
TForm1 *Form1;
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
FRunApp = True;
FActive = False;
}
MESSAGE void TForm1::MyMove(TMessage &Message)
{
do {
UpdateFrame();
Application->ProcessMessages();
} while(FRunApp == True);
}
void TForm1::InitFail()
{
MessageBox(Handle, "DirectDraw
Init FAILED", TITLE, MB_OK );
Close();
}
void TForm1::Start()
{
HRESULT ddrval;
DDSURFACEDESC ddsd;
DDSCAPS ddscaps;
ddrval = DirectDrawCreate( NULL, &lpDD,
NULL );
if( ddrval != DD_OK )
{
InitFail();
return;
}
ddrval = lpDD->SetCooperativeLevel(Handle,
DDSCL_EXCLUSIVE |
DDSCL_FULLSCREEN );
if( ddrval != DD_OK )
{
InitFail();
return;
}
ddrval = lpDD->SetDisplayMode( 640,
480, 8);
if( ddrval != DD_OK )
{
InitFail();
return;
}
ddsd.dwSize = sizeof( ddsd );
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE
|
DDSCAPS_FLIP | DDSCAPS_COMPLEX;
ddsd.dwBackBufferCount = 1;
ddrval = lpDD->CreateSurface( &ddsd,
&lpDDSPrimary, NULL );
if( ddrval != DD_OK )
{
InitFail();
return;
}
ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
ddrval = lpDDSPrimary->GetAttachedSurface(&ddscaps,
&lpDDSBack);
if( ddrval != DD_OK )
{
InitFail();
return;
}
lpDDPal = DDLoadPalette(lpDD, szBitmap);
if (lpDDPal)
lpDDSPrimary->SetPalette(lpDDPal);
lpDDSOne = DDLoadBitmap(lpDD, szBitmap,
0, 0);
if( lpDDSOne == NULL )
{
InitFail();
return;
}
DDSetColorKey(lpDDSOne, RGB(0,0,0));
}
void __fastcall TForm1::FormDestroy(TObject
*Sender)
{
if( lpDD != NULL )
{
if( lpDDSPrimary != NULL
)
{
lpDDSPrimary->Release();
lpDDSPrimary
= NULL;
}
if( lpDDSOne != NULL )
{
lpDDSOne->Release();
lpDDSOne =
NULL;
}
if( lpDDPal != NULL )
{
lpDDPal->Release();
lpDDPal =
NULL;
}
lpDD->Release();
lpDD = NULL;
}
}
void __fastcall TForm1::FormKeyDown(TObject
*Sender, WORD &Key,
TShiftState Shift)
{
switch (Key)
{
case VK_F3:
FActive =
True;
Start();
PostMessage(Handle,
WM_INFOSTART, 0, 0);
break;
case VK_ESCAPE:
case VK_F12:
FRunApp =
False;
FActive =
False;
Close();
break;
}
}
HRESULT TForm1::RestoreAll( void )
{
HRESULT ddrval;
ddrval = lpDDSPrimary->Restore();
if( ddrval == DD_OK )
{
ddrval = lpDDSOne->Restore();
if( ddrval == DD_OK ) DDReLoadBitmap(lpDDSOne,
szBitmap);
}
return ddrval;
}
void TForm1::UpdateFrame( void )
{
static DWORD lastTickCount[3] = {0,0,0};
static int currentFrame[3] =
{0,0,0};
DWORD thisTickCount;
RECT rcRect;
DWORD delay[3] = {50, 78, 13};
int i;
int xpos[3] = {288, 190,
416};
int ypos[3] = {128, 300,
256};
HRESULT ddrval;
thisTickCount = GetTickCount();
for(i=0; i<3; i++)
{
if((thisTickCount - lastTickCount[i])
> delay[i])
{
lastTickCount[i]
= thisTickCount;
currentFrame[i]++;
if(currentFrame[i]
> 59) currentFrame[i] = 0;
}
}
rcRect.left = 0;
rcRect.top = 0;
rcRect.right = 640;
rcRect.bottom = 480;
while(1)
{
ddrval = lpDDSBack->BltFast(
0, 0, lpDDSOne,
&rcRect, DDBLTFAST_NOCOLORKEY
);
if( ddrval == DD_OK )
break;
if( ddrval == DDERR_SURFACELOST
)
{
ddrval = RestoreAll();
if( ddrval
!= DD_OK ) return;
}
if( ddrval != DDERR_WASSTILLDRAWING
) return;
}
if(ddrval != DD_OK) return;
for(i=0; i<3; i++)
{
rcRect.left
= currentFrame[i]%10*64;
rcRect.top
= currentFrame[i]/10*64 + 480;
rcRect.right = currentFrame[i]%10*64
+ 64;
rcRect.bottom = currentFrame[i]/10*64
+ 64 + 480;
while( 1 )
{
ddrval = lpDDSBack->BltFast(
xpos[i], ypos[i], lpDDSOne,
&rcRect, DDBLTFAST_SRCCOLORKEY );
if( ddrval
== DD_OK ) break;
if( ddrval
== DDERR_SURFACELOST )
{
ddrval = RestoreAll();
if( ddrval != DD_OK ) return;
}
if( ddrval
!= DDERR_WASSTILLDRAWING ) return;
}
}
while( 1 )
{
ddrval = lpDDSPrimary->Flip(
NULL, 0 );
if( ddrval == DD_OK )
break;
if( ddrval == DDERR_SURFACELOST
)
{
ddrval = RestoreAll();
if( ddrval
!= DD_OK ) break;
}
if( ddrval != DDERR_WASSTILLDRAWING
) break;
}
}
void __fastcall TForm1::FormPaint(TObject
*Sender)
{
AnsiString S = "F3 to Start, Esc to
Exit";
HDC DC = GetDC(Handle);
if (!FActive)
{
SetBkMode(DC, TRANSPARENT);
TextOut(DC, 25, 100, S.c_str(),
S.Length());
}
ReleaseDC(Handle, DC);
}
Aplikace je hotova, m∙₧eme ji vyzkouÜej. Pokuste se zjistit, jak je
animace provßd∞na.
-
Pokuste se vytvo°it n∞jakou jinou aplikaci, ve kterΘ se bude provßd∞t animace.