//
//
//
#include <windows.h>
#include <ddraw.h>
#include "resource.h"
#define NAME TEXT("DDExample1")
#define TITLE TEXT("Direct Draw Example 1")
#define IMAGE_COUNT 2
#define NUM_SPRITES 5
#define SCREEN_WIDTH 240
#define SCREEN_HEIGHT 320
#define SCREEN_BPP 8
#define SPRITE_DIAMETER 32
TCHAR fileNames[IMAGE_COUNT][MAX_PATH] =
{
L"\\Windows\\1.bmp",
L"\\Windows\\2.bmp"
};
static const TCHAR szMsg[] = TEXT("Page Flipping Test: Press F12 to exit");
static const TCHAR szFrontMsg[] = TEXT("Front buffer (F12 to quit)");
static const TCHAR szBackMsg[] = TEXT("Back buffer (F12 to quit)");
HINSTANCE g_hInst = NULL;
HWND g_hwnd = NULL;
int curImage = 0;
RECT rect;
DWORD g_dwLastTick;
BOOL g_bActive = FALSE;
LPDIRECTDRAW g_pDD = NULL; // DirectDraw object
LPDIRECTDRAWSURFACE g_pDDSPrimary = NULL; // DirectDraw primary surface
LPDIRECTDRAWSURFACE g_pDDSBack = NULL; // DirectDraw back surface
LPDIRECTDRAWSURFACE g_pBmp = NULL;
//LPDIRECTDRAWSURFACE g_pBmp[IMAGE_COUNT] = {0};
LPDIRECTDRAWSURFACE g_pDDSLogo = NULL;
struct SPRITE_STRUCT
{
FLOAT fPosX;
FLOAT fPosY;
FLOAT fVelX;
FLOAT fVelY;
};
SPRITE_STRUCT g_Sprite[NUM_SPRITES];
void UpdateSprite(SPRITE_STRUCT* pSprite, FLOAT fTimeDelta);
HRESULT ProcessNextFrame();
void ReleaseAllObjects(void);
void UpdateFrame();
void MakeRect(int left, int top, int right, int bottom);
LPDIRECTDRAWSURFACE BitmapSurface(LPCTSTR fileName);
LPDIRECTDRAWSURFACE SpriteSurface(LPCTSTR fileName);
BOOL InitDDraw();
BOOL InitWindow(HINSTANCE hInstance, int nShowCmd);
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
static HRESULT PASCAL EnumFunction(LPDIRECTDRAWSURFACE pSurface, LPDDSURFACEDESC lpSurfaceDesc, LPVOID lpContext);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd)
{
g_hInst = hInstance;
ZeroMemory(&g_Sprite, sizeof(SPRITE_STRUCT) * NUM_SPRITES);
srand( GetTickCount());
if(!InitWindow(hInstance, nShowCmd))
{
return FALSE;
}
g_dwLastTick = timeGetTime();
MSG msg;
//while(GetMessage(&msg, NULL, 0, 0))
//{
// TranslateMessage(&msg);
// DispatchMessage(&msg);
//}
while(TRUE)
{
if(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
{
if(0 == GetMessage(&msg, NULL, 0, 0))
{
return (int)msg.wParam;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
if(g_bActive)
{
if(FAILED(ProcessNextFrame()))
{
return FALSE;
}
}
else
{
// Make sure we go to sleep if we have nothing else to do
//WaitMessage();
// Ignore time spent inactive
g_dwLastTick = timeGetTime();//获得当前系统时间
}
}
}
return (int)msg.wParam;
}
BOOL InitWindow(HINSTANCE hInstance, int nShowCmd)
{
WNDCLASS wc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wc.hCursor = NULL;
wc.hIcon = LoadIcon(NULL, MAKEINTRESOURCE(IDI_ICON1));
wc.hInstance = hInstance;
wc.lpfnWndProc = WndProc;
wc.lpszClassName = NAME;
wc.lpszMenuName = NULL;
wc.style = CS_HREDRAW | CS_VREDRAW;
if(!RegisterClass(&wc))
{
return FALSE;
}
g_hwnd = CreateWindow(/*WS_EX_TOPMOST,*/
NAME,
TITLE,
WS_POPUP,
0,
0,
GetSystemMetrics(SM_CXSCREEN),
GetSystemMetrics(SM_CYSCREEN),
NULL,
NULL,
hInstance,
NULL);
if(!g_hwnd)
{
return FALSE;
}
ShowWindow(g_hwnd, nShowCmd);
UpdateWindow(g_hwnd);
SetFocus(g_hwnd);
InitDDraw();
return TRUE;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_LBUTTONUP:
PostMessage(hwnd, WM_DESTROY, 0, 0);
break;
case WM_DESTROY:
{
ReleaseAllObjects();
PostQuitMessage(0);
}
break;
case WM_SIZE:
if( SIZE_MAXHIDE==wParam || SIZE_MINIMIZED==wParam )
g_bActive = FALSE;
else
g_bActive = TRUE;
//UpdateFrame();
break;
case WM_EXITMENULOOP:
g_dwLastTick = timeGetTime();
break;
case WM_MOVE:
//UpdateFrame();
break;
case WM_TIMER:
{
//KillTimer(hwnd, 1);
//curImage++;
//if(curImage>1)
//{
// curImage = 0;
//}
UpdateFrame();
}
break;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
BOOL InitDDraw()
{
DDSURFACEDESC ddsd;
if(DD_OK != DirectDrawCreate(NULL, &g_pDD, NULL))
{
return FALSE;
}
if(DD_OK != g_pDD->SetCooperativeLevel(g_hwnd, DDSCL_FULLSCREEN))
{
return FALSE;
}
//if(DD_OK != g_pDD->SetDisplayMode(240,320,24,0,0))
//{
// return FALSE;
//}
DDCAPS ddCaps;
DDCAPS ddHelCaps;
g_pDD->GetCaps(&ddCaps, &ddHelCaps);
if (!(ddCaps.ddsCaps.dwCaps & DDSCAPS_BACKBUFFER))
{
return FALSE;
//return InitFail(hWnd, E_FAIL, szNoBackBufferMsg);
}
if (!(ddCaps.ddsCaps.dwCaps & DDSCAPS_FLIP))
{
return FALSE;
//return InitFail(hWnd, E_FAIL, szNoFlipSurfacesMsg);
}
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP;
ddsd.dwBackBufferCount = 1;
if(DD_OK != g_pDD->CreateSurface(&ddsd, &g_pDDSPrimary, NULL))
{
return FALSE;
}
//ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
if(DD_OK != g_pDDSPrimary->EnumAttachedSurfaces(&g_pDDSBack, EnumFunction))
{
return FALSE;
}
g_pBmp = BitmapSurface(MAKEINTRESOURCE(IDB_BITMAP1));
if(!g_pBmp)
{
return FALSE;
}
g_pDDSLogo = SpriteSurface(MAKEINTRESOURCE(IDB_DIRECTX));
if(!g_pDDSLogo)
{
return FALSE;
}
DDCOLORKEY ddck;
ddck.dwColorSpaceLowValue = RGB(0,0,0);
ddck.dwColorSpaceHighValue = RGB(0,0,0);
g_pDDSLogo->SetColorKey(DDCKEY_SRCBLT, &ddck);
for(int iSprite = 0; iSprite < NUM_SPRITES; iSprite++)
{
// Set the sprite's position and velocity
// 设置这些 sprite(小怪物)的初始坐标随机产生
g_Sprite[iSprite].fPosX = (float) (rand() % SCREEN_WIDTH);
g_Sprite[iSprite].fPosY = (float) (rand() % SCREEN_HEIGHT);
// 速度也随机产生
g_Sprite[iSprite].fVelX = 500.0f * rand() / RAND_MAX - 250.0f;
g_Sprite[iSprite].fVelY = 500.0f * rand() / RAND_MAX - 250.0f;
//g_Sprite[iSprite].fVelX = (FLOAT)(500.0f * rand() / RAND_MAX);
//g_Sprite[iSprite].fVelY = (FLOAT)(500.0f * rand() / RAND_MAX);
}
UpdateFrame();
//SetTimer(g_hwnd, 1, 50, 0);
return TRUE;
}
static HRESULT PASCAL EnumFunction(LPDIRECTDRAWSURFACE pSurface, LPDDSURFACEDESC lpSurfaceDesc, LPVOID lpContext)
{
static BOOL bCalled = FALSE;
if(!bCalled)
{
//lpSurfaceDesc->ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
*((LPDIRECTDRAWSURFACE *)lpContext) = pSurface;
bCalled = TRUE;
return DDENUMRET_OK;
}
else
{
OutputDebugString(L"DDEX1: Enumerated more than surface?");
pSurface->Release();
return DDENUMRET_CANCEL;
}
}
LPDIRECTDRAWSURFACE SpriteSurface(LPCTSTR fileName)
{
HDC hdc;
HBITMAP hBitmap;
LPDIRECTDRAWSURFACE surf;
hBitmap = LoadBitmap(g_hInst, fileName);
//hBitmap = (HBITMAP)LoadImage(g_hInst, fileName, IMAGE_BITMAP, 0, 0, 0);
if(!hBitmap)
{
return NULL;
}
BITMAP bmp;
GetObject(hBitmap, sizeof(BITMAP), &bmp);
int surfWidth = bmp.bmWidth;
int surfHeight = bmp.bmHeight;
DDSURFACEDESC ddsd;
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY;
ddsd.dwWidth = 32;
ddsd.dwHeight = 32;
if(DD_OK != g_pDD->CreateSurface(&ddsd, &surf, NULL))
{
DeleteObject(hBitmap);
return NULL;
}
else
{
surf->GetDC(&hdc);
HDC bitDC = CreateCo