2 * PROJECT: ReactX Diagnosis Application
3 * LICENSE: LGPL - See COPYING in the top level directory
4 * FILE: base/applications/dxdiag/ddtest.c
5 * PURPOSE: ReactX DirectDraw tests
6 * COPYRIGHT: Copyright 2008 Kamil Hornicek
12 BOOL
DDPrimarySurfaceTest(HWND hWnd
);
13 BOOL
DDOffscreenBufferTest(HWND hWnd
, BOOL Fullscreen
);
14 VOID
DDRedrawFrame(LPDIRECTDRAWSURFACE lpDDSurface
);
15 VOID
DDUpdateFrame(LPDIRECTDRAWSURFACE lpDDPrimarySurface
,LPDIRECTDRAWSURFACE lpDDBackBuffer
, BOOL Fullscreen
, INT
*posX
, INT
*posY
, INT
*gainX
, INT
*gainY
, RECT
*rectDD
);
16 static LRESULT CALLBACK
WindowProc(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
);
18 #define TEST_DURATION 10000
21 #define DD_TEST_STEP 5
22 #define DD_SQUARE_SIZE 100
23 #define DD_SQUARE_STEP 2
26 BOOL
StartDDTest(HWND hWnd
, HINSTANCE hInstance
, INT resTestDescription
, INT resResult
, INT TestNr
)
28 WCHAR szTestDescription
[256];
34 LoadStringW(hInstance
, IDS_DDTEST_TITLE
, szCaption
, sizeof(szCaption
) / sizeof(WCHAR
));
35 LoadStringW(hInstance
, IDS_DDTEST_ERROR
, szError
, sizeof(szError
) / sizeof(WCHAR
));
36 LoadStringW(hInstance
, resTestDescription
, szTestDescription
, sizeof(szTestDescription
) / sizeof(WCHAR
));
37 LoadStringW(hInstance
, resResult
, szResult
, sizeof(szResult
) / sizeof(WCHAR
));
39 if(MessageBox(NULL
, szTestDescription
, szCaption
, MB_YESNO
| MB_ICONQUESTION
) == IDNO
)
42 ShowWindow(hWnd
, SW_SHOW
);
46 Result
= DDPrimarySurfaceTest(hWnd
);
49 Result
= DDOffscreenBufferTest(hWnd
, FALSE
);
52 Result
= DDOffscreenBufferTest(hWnd
, TRUE
);
58 ShowWindow(hWnd
, SW_HIDE
);
62 MessageBox(NULL
, szError
, szCaption
, MB_OK
| MB_ICONERROR
);
66 if(MessageBox(NULL
, szResult
, szCaption
, MB_YESNO
| MB_ICONQUESTION
) == IDYES
)
76 HINSTANCE hInstance
= NULL
;
77 WCHAR szDescription
[256];
80 winClass
.cbSize
= sizeof(WNDCLASSEX
);
81 winClass
.style
= CS_DBLCLKS
| CS_OWNDC
| CS_HREDRAW
| CS_VREDRAW
;
82 winClass
.lpfnWndProc
= WindowProc
;
83 winClass
.cbClsExtra
= 0;
84 winClass
.cbWndExtra
= 0;
85 winClass
.hInstance
= hInstance
;
88 winClass
.hbrBackground
= (HBRUSH
)GetStockObject(BLACK_BRUSH
);
89 winClass
.lpszMenuName
= NULL
;
90 winClass
.lpszClassName
= L
"ddtest";
91 winClass
.hIconSm
= LoadIcon(NULL
, IDI_APPLICATION
);
93 if (!RegisterClassEx(&winClass
))
96 hWnd
= CreateWindowEx(0, winClass
.lpszClassName
, NULL
,WS_POPUP
,
97 (GetSystemMetrics(SM_CXSCREEN
) - WIDTH
)/2,
98 (GetSystemMetrics(SM_CYSCREEN
) - HEIGHT
)/2,
99 WIDTH
, HEIGHT
, NULL
, NULL
, hInstance
, NULL
);
105 LoadStringW(hInstance
, IDS_DDTEST_DESCRIPTION
, szDescription
, sizeof(szDescription
) / sizeof(WCHAR
));
106 LoadStringW(hInstance
, IDS_DDTEST_DESCRIPTION
, szCaption
, sizeof(szCaption
) / sizeof(WCHAR
));
107 if(MessageBox(NULL
, szDescription
, szCaption
, MB_YESNO
| MB_ICONQUESTION
) == IDNO
)
110 StartDDTest(hWnd
, hInstance
, IDS_DDPRIMARY_DESCRIPTION
, IDS_DDPRIMARY_RESULT
, 1);
111 StartDDTest(hWnd
, hInstance
, IDS_DDOFFSCREEN_DESCRIPTION
, IDS_DDOFFSCREEN_RESULT
, 2);
112 StartDDTest(hWnd
, hInstance
, IDS_DDFULLSCREEN_DESCRIPTION
, IDS_DDFULLSCREEN_RESULT
, 3);
115 UnregisterClass(winClass
.lpszClassName
, hInstance
);
118 BOOL
DDPrimarySurfaceTest(HWND hWnd
){
122 LPDIRECTDRAW lpDD
= NULL
;
123 LPDIRECTDRAWSURFACE lpDDSurface
= NULL
;
124 DDSURFACEDESC DDSurfaceDesc
;
126 if(DirectDrawCreate(NULL
, &lpDD
, NULL
) != DD_OK
)
129 if(lpDD
->lpVtbl
->SetCooperativeLevel(lpDD
, hWnd
, DDSCL_NORMAL
) != DD_OK
)
131 lpDD
->lpVtbl
->Release(lpDD
);
135 /* create our primary surface */
136 ZeroMemory(&DDSurfaceDesc
, sizeof(DDSurfaceDesc
));
137 DDSurfaceDesc
.dwSize
= sizeof(DDSurfaceDesc
);
138 DDSurfaceDesc
.dwFlags
= DDSD_CAPS
;
139 DDSurfaceDesc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_3DDEVICE
;
140 DDSurfaceDesc
.dwBackBufferCount
= 0;
142 if(lpDD
->lpVtbl
->CreateSurface(lpDD
, &DDSurfaceDesc
, &lpDDSurface
, NULL
) != DD_OK
)
144 lpDD
->lpVtbl
->Release(lpDD
);
148 TimerID
= SetTimer(hWnd
, -1, (UINT
)TEST_DURATION
, NULL
);
152 if (PeekMessage(&msg
, NULL
, 0, 0, PM_REMOVE
))
154 if (msg
.message
== WM_TIMER
&& TimerID
== msg
.wParam
)
156 TranslateMessage(&msg
);
157 DispatchMessage(&msg
);
158 if (msg
.message
== WM_PAINT
)
159 DDRedrawFrame(lpDDSurface
);
162 KillTimer(hWnd
, TimerID
);
163 lpDDSurface
->lpVtbl
->Release(lpDDSurface
);
164 lpDD
->lpVtbl
->Release(lpDD
);
169 VOID
DDRedrawFrame(LPDIRECTDRAWSURFACE lpDDSurface
)
173 if (lpDDSurface
->lpVtbl
->GetDC(lpDDSurface
, &hdc
) == DD_OK
)
176 HBRUSH BlackBrush
, WhiteBrush
;
179 rct
.left
= (GetSystemMetrics(SM_CXSCREEN
) - WIDTH
)/2;
180 rct
.right
= (GetSystemMetrics(SM_CXSCREEN
) - WIDTH
)/2 + WIDTH
;
181 rct
.top
= (GetSystemMetrics(SM_CYSCREEN
) - HEIGHT
)/2;
182 rct
.bottom
= (GetSystemMetrics(SM_CYSCREEN
) - HEIGHT
)/2 + HEIGHT
;
184 BlackBrush
= CreateSolidBrush(RGB(0,0,0));
185 WhiteBrush
= CreateSolidBrush(RGB(255,255,255));
187 while((rct
.bottom
- rct
.top
) > DD_TEST_STEP
){
188 (Colour
)? FillRect(hdc
, &rct
, WhiteBrush
) : FillRect(hdc
, &rct
, BlackBrush
);
189 rct
.top
+= DD_TEST_STEP
;
190 rct
.bottom
-= DD_TEST_STEP
;
191 rct
.left
+= DD_TEST_STEP
;
192 rct
.right
-= DD_TEST_STEP
;
195 DeleteObject((HGDIOBJ
)BlackBrush
);
196 DeleteObject((HGDIOBJ
)WhiteBrush
);
197 lpDDSurface
->lpVtbl
->ReleaseDC(lpDDSurface
, hdc
);
202 BOOL
DDOffscreenBufferTest(HWND hWnd
, BOOL Fullscreen
){
203 UINT TimerID
, TimerIDUpdate
;
205 LPDIRECTDRAWSURFACE lpDDPrimarySurface
;
206 LPDIRECTDRAWSURFACE lpDDBackBuffer
;
207 DDSURFACEDESC DDSurfaceDesc
;
208 DDSURFACEDESC DDBBSurfaceDesc
;
213 INT posX
= 0, posY
= 10, xGain
= DD_SQUARE_STEP
, yGain
= DD_SQUARE_STEP
;
215 if(DirectDrawCreate(NULL
, &lpDD
, NULL
) != DD_OK
)
218 ZeroMemory(&DDSurfaceDesc
, sizeof(DDSurfaceDesc
));
219 DDSurfaceDesc
.dwSize
= sizeof(DDSurfaceDesc
);
223 if(lpDD
->lpVtbl
->SetCooperativeLevel(lpDD
, hWnd
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
) != DD_OK
)
225 lpDD
->lpVtbl
->Release(lpDD
);
228 if(lpDD
->lpVtbl
->SetDisplayMode(lpDD
, WIDTH
, HEIGHT
, 32) != DD_OK
)
230 lpDD
->lpVtbl
->Release(lpDD
);
233 DDSurfaceDesc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
234 DDSurfaceDesc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FLIP
| DDSCAPS_COMPLEX
;
235 DDSurfaceDesc
.dwBackBufferCount
= 1;
239 if(lpDD
->lpVtbl
->SetCooperativeLevel(lpDD
, hWnd
, DDSCL_NORMAL
) != DD_OK
)
241 lpDD
->lpVtbl
->Release(lpDD
);
244 DDSurfaceDesc
.dwFlags
= DDSD_CAPS
;
245 DDSurfaceDesc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
249 if(lpDD
->lpVtbl
->CreateSurface(lpDD
, &DDSurfaceDesc
, &lpDDPrimarySurface
, NULL
) != DD_OK
)
251 lpDD
->lpVtbl
->Release(lpDD
);
257 DDSCaps
.dwCaps
= DDSCAPS_BACKBUFFER
;
258 if (lpDDPrimarySurface
->lpVtbl
->GetAttachedSurface(lpDDPrimarySurface
, &DDSCaps
,&lpDDBackBuffer
) != DD_OK
)
260 lpDDPrimarySurface
->lpVtbl
->Release(lpDDPrimarySurface
);
261 lpDD
->lpVtbl
->Release(lpDD
);
267 /* create our offscreen back buffer */
268 ZeroMemory(&DDBBSurfaceDesc
,sizeof(DDBBSurfaceDesc
));
269 DDBBSurfaceDesc
.dwSize
= sizeof(DDBBSurfaceDesc
);
270 DDBBSurfaceDesc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
271 DDBBSurfaceDesc
.dwHeight
= HEIGHT
;
272 DDBBSurfaceDesc
.dwWidth
= WIDTH
;
273 DDBBSurfaceDesc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
275 if(lpDD
->lpVtbl
->CreateSurface(lpDD
, &DDBBSurfaceDesc
, &lpDDBackBuffer
, NULL
) != DD_OK
)
277 lpDD
->lpVtbl
->Release(lpDD
);
278 lpDDPrimarySurface
->lpVtbl
->Release(lpDDPrimarySurface
);
283 ClientToScreen(hWnd
, &wndPoint
);
284 GetClientRect(hWnd
, &rectDD
);
285 OffsetRect(&rectDD
, wndPoint
.x
, wndPoint
.y
);
288 /* set our timers, TimerID - for test timeout, TimerIDUpdate - for frame updating */
289 TimerID
= SetTimer(hWnd
, -1, (UINT
)TEST_DURATION
, NULL
);
290 TimerIDUpdate
= SetTimer(hWnd
, 2, (UINT
)10, NULL
);
294 if (PeekMessage(&msg
, NULL
, 0, 0, PM_REMOVE
))
296 if (msg
.message
== WM_TIMER
)
298 if(msg
.wParam
== TimerID
)
304 DDUpdateFrame(lpDDPrimarySurface
,lpDDBackBuffer
, Fullscreen
,&posX
, &posY
, &xGain
, &yGain
, &rectDD
);
307 TranslateMessage(&msg
);
308 DispatchMessage(&msg
);
312 lpDDPrimarySurface
->lpVtbl
->Release(lpDDPrimarySurface
);
313 /* backbuffer is released automatically when in fullscreen */
315 lpDDBackBuffer
->lpVtbl
->Release(lpDDBackBuffer
);
316 lpDD
->lpVtbl
->Release(lpDD
);
322 VOID
DDUpdateFrame(LPDIRECTDRAWSURFACE lpDDPrimarySurface
,LPDIRECTDRAWSURFACE lpDDBackBuffer
, BOOL Fullscreen
, INT
*posX
, INT
*posY
, INT
*gainX
, INT
*gainY
, RECT
*rectDD
)
327 /* clear back buffer and paint it black */
328 ZeroMemory(&DDBlitFx
, sizeof(DDBlitFx
));
329 DDBlitFx
.dwSize
= sizeof(DDBlitFx
);
330 DDBlitFx
.dwFillColor
= 0;
332 lpDDBackBuffer
->lpVtbl
->Blt(lpDDBackBuffer
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &DDBlitFx
);
334 if (lpDDBackBuffer
->lpVtbl
->GetDC(lpDDBackBuffer
, &hdc
) == DD_OK
)
340 rct
.right
= *posX
+DD_SQUARE_SIZE
;
342 rct
.bottom
= *posY
+DD_SQUARE_SIZE
;
344 WhiteBrush
= CreateSolidBrush(RGB(255,255,255));
345 FillRect(hdc
, &rct
, WhiteBrush
);
347 if(*posX
>= (WIDTH
- DD_SQUARE_SIZE
)) *gainX
= -(*gainX
);
348 if(*posY
>= (HEIGHT
- DD_SQUARE_SIZE
)) *gainY
= -(*gainY
);
349 if(*posX
< 0) *gainX
= -1*(*gainX
);
350 if(*posY
< 0) *gainY
= -1*(*gainY
);
355 lpDDBackBuffer
->lpVtbl
->ReleaseDC(lpDDBackBuffer
, hdc
);
359 lpDDPrimarySurface
->lpVtbl
->Flip(lpDDPrimarySurface
, NULL
, DDFLIP_WAIT
);
363 lpDDPrimarySurface
->lpVtbl
->Blt(lpDDPrimarySurface
, rectDD
, lpDDBackBuffer
, NULL
, DDBLT_WAIT
, NULL
);
368 static LRESULT CALLBACK
WindowProc(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
370 return DefWindowProc(hWnd
, msg
, wParam
, lParam
);