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
);
17 #define TEST_DURATION 10000
18 #define DD_TEST_WIDTH 640
19 #define DD_TEST_HEIGHT 480
20 #define DD_TEST_STEP 5
21 #define DD_SQUARE_SIZE 100
22 #define DD_SQUARE_STEP 2
25 BOOL
StartDDTest(HWND hWnd
, HINSTANCE hInstance
, INT resTestDescription
, INT resResult
, INT TestNr
)
27 WCHAR szTestDescription
[256];
33 LoadStringW(hInstance
, IDS_MAIN_DIALOG
, szCaption
, sizeof(szCaption
) / sizeof(WCHAR
));
34 LoadStringW(hInstance
, IDS_DDTEST_ERROR
, szError
, sizeof(szError
) / sizeof(WCHAR
));
35 LoadStringW(hInstance
, resTestDescription
, szTestDescription
, sizeof(szTestDescription
) / sizeof(WCHAR
));
36 LoadStringW(hInstance
, resResult
, szResult
, sizeof(szResult
) / sizeof(WCHAR
));
38 if(MessageBox(NULL
, szTestDescription
, szCaption
, MB_YESNO
| MB_ICONQUESTION
) == IDNO
)
41 ShowWindow(hWnd
, SW_SHOW
);
45 Result
= DDPrimarySurfaceTest(hWnd
);
48 Result
= DDOffscreenBufferTest(hWnd
, FALSE
);
51 Result
= DDOffscreenBufferTest(hWnd
, TRUE
);
57 ShowWindow(hWnd
, SW_HIDE
);
61 MessageBox(NULL
, szError
, szCaption
, MB_OK
| MB_ICONERROR
);
65 if(MessageBox(NULL
, szResult
, szCaption
, MB_YESNO
| MB_ICONQUESTION
) == IDYES
)
75 HINSTANCE hInstance
= NULL
;
76 WCHAR szDescription
[256];
79 winClass
.cbSize
= sizeof(WNDCLASSEX
);
80 winClass
.style
= CS_DBLCLKS
| CS_OWNDC
| CS_HREDRAW
| CS_VREDRAW
;
81 winClass
.lpfnWndProc
= DefWindowProc
;
82 winClass
.cbClsExtra
= 0;
83 winClass
.cbWndExtra
= 0;
84 winClass
.hInstance
= hInstance
;
87 winClass
.hbrBackground
= (HBRUSH
)GetStockObject(BLACK_BRUSH
);
88 winClass
.lpszMenuName
= NULL
;
89 winClass
.lpszClassName
= L
"ddtest";
90 winClass
.hIconSm
= LoadIcon(NULL
, IDI_APPLICATION
);
92 if (!RegisterClassEx(&winClass
))
95 hWnd
= CreateWindowEx(0, winClass
.lpszClassName
, NULL
,WS_POPUP
,
96 (GetSystemMetrics(SM_CXSCREEN
) - DD_TEST_WIDTH
)/2,
97 (GetSystemMetrics(SM_CYSCREEN
) - DD_TEST_HEIGHT
)/2,
98 DD_TEST_WIDTH
, DD_TEST_HEIGHT
, NULL
, NULL
, hInstance
, NULL
);
104 LoadStringW(hInstance
, IDS_DDTEST_DESCRIPTION
, szDescription
, sizeof(szDescription
) / sizeof(WCHAR
));
105 LoadStringW(hInstance
, IDS_MAIN_DIALOG
, szCaption
, sizeof(szCaption
) / sizeof(WCHAR
));
106 if(MessageBox(NULL
, szDescription
, szCaption
, MB_YESNO
| MB_ICONQUESTION
) == IDNO
)
109 StartDDTest(hWnd
, hInstance
, IDS_DDPRIMARY_DESCRIPTION
, IDS_DDPRIMARY_RESULT
, 1);
110 StartDDTest(hWnd
, hInstance
, IDS_DDOFFSCREEN_DESCRIPTION
, IDS_DDOFFSCREEN_RESULT
, 2);
111 StartDDTest(hWnd
, hInstance
, IDS_DDFULLSCREEN_DESCRIPTION
, IDS_DDFULLSCREEN_RESULT
, 3);
114 UnregisterClass(winClass
.lpszClassName
, hInstance
);
117 BOOL
DDPrimarySurfaceTest(HWND hWnd
){
121 LPDIRECTDRAW lpDD
= NULL
;
122 LPDIRECTDRAWSURFACE lpDDSurface
= NULL
;
123 DDSURFACEDESC DDSurfaceDesc
;
125 if(DirectDrawCreate(NULL
, &lpDD
, NULL
) != DD_OK
)
128 if(lpDD
->lpVtbl
->SetCooperativeLevel(lpDD
, hWnd
, DDSCL_NORMAL
) != DD_OK
)
130 lpDD
->lpVtbl
->Release(lpDD
);
134 /* create our primary surface */
135 ZeroMemory(&DDSurfaceDesc
, sizeof(DDSurfaceDesc
));
136 DDSurfaceDesc
.dwSize
= sizeof(DDSurfaceDesc
);
137 DDSurfaceDesc
.dwFlags
= DDSD_CAPS
;
138 DDSurfaceDesc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_3DDEVICE
;
139 DDSurfaceDesc
.dwBackBufferCount
= 0;
141 if(lpDD
->lpVtbl
->CreateSurface(lpDD
, &DDSurfaceDesc
, &lpDDSurface
, NULL
) != DD_OK
)
143 lpDD
->lpVtbl
->Release(lpDD
);
147 TimerID
= SetTimer(hWnd
, -1, (UINT
)TEST_DURATION
, NULL
);
151 if (PeekMessage(&msg
, NULL
, 0, 0, PM_REMOVE
))
153 if (msg
.message
== WM_TIMER
&& TimerID
== msg
.wParam
)
155 TranslateMessage(&msg
);
156 DispatchMessage(&msg
);
157 if (msg
.message
== WM_PAINT
)
158 DDRedrawFrame(lpDDSurface
);
161 KillTimer(hWnd
, TimerID
);
162 lpDDSurface
->lpVtbl
->Release(lpDDSurface
);
163 lpDD
->lpVtbl
->Release(lpDD
);
168 VOID
DDRedrawFrame(LPDIRECTDRAWSURFACE lpDDSurface
)
172 if (lpDDSurface
->lpVtbl
->GetDC(lpDDSurface
, &hdc
) == DD_OK
)
175 HBRUSH BlackBrush
, WhiteBrush
;
178 rct
.left
= (GetSystemMetrics(SM_CXSCREEN
) - DD_TEST_WIDTH
)/2;
179 rct
.right
= (GetSystemMetrics(SM_CXSCREEN
) - DD_TEST_WIDTH
)/2 + DD_TEST_WIDTH
;
180 rct
.top
= (GetSystemMetrics(SM_CYSCREEN
) - DD_TEST_HEIGHT
)/2;
181 rct
.bottom
= (GetSystemMetrics(SM_CYSCREEN
) - DD_TEST_HEIGHT
)/2 + DD_TEST_HEIGHT
;
183 BlackBrush
= CreateSolidBrush(RGB(0,0,0));
184 WhiteBrush
= CreateSolidBrush(RGB(255,255,255));
186 while((rct
.bottom
- rct
.top
) > DD_TEST_STEP
){
187 (Colour
)? FillRect(hdc
, &rct
, WhiteBrush
) : FillRect(hdc
, &rct
, BlackBrush
);
188 rct
.top
+= DD_TEST_STEP
;
189 rct
.bottom
-= DD_TEST_STEP
;
190 rct
.left
+= DD_TEST_STEP
;
191 rct
.right
-= DD_TEST_STEP
;
194 DeleteObject((HGDIOBJ
)BlackBrush
);
195 DeleteObject((HGDIOBJ
)WhiteBrush
);
196 lpDDSurface
->lpVtbl
->ReleaseDC(lpDDSurface
, hdc
);
201 BOOL
DDOffscreenBufferTest(HWND hWnd
, BOOL Fullscreen
){
202 UINT_PTR TimerID
, TimerIDUpdate
;
204 LPDIRECTDRAWSURFACE lpDDPrimarySurface
;
205 LPDIRECTDRAWSURFACE lpDDBackBuffer
;
206 DDSURFACEDESC DDSurfaceDesc
;
207 DDSURFACEDESC DDBBSurfaceDesc
;
212 INT posX
= 0, posY
= 10, xGain
= DD_SQUARE_STEP
, yGain
= DD_SQUARE_STEP
;
214 if(DirectDrawCreate(NULL
, &lpDD
, NULL
) != DD_OK
)
217 ZeroMemory(&DDSurfaceDesc
, sizeof(DDSurfaceDesc
));
218 DDSurfaceDesc
.dwSize
= sizeof(DDSurfaceDesc
);
222 if(lpDD
->lpVtbl
->SetCooperativeLevel(lpDD
, hWnd
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
) != DD_OK
)
224 lpDD
->lpVtbl
->Release(lpDD
);
227 if(lpDD
->lpVtbl
->SetDisplayMode(lpDD
, DD_TEST_WIDTH
, DD_TEST_HEIGHT
, 32) != DD_OK
)
229 lpDD
->lpVtbl
->Release(lpDD
);
232 DDSurfaceDesc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
233 DDSurfaceDesc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FLIP
| DDSCAPS_COMPLEX
;
234 DDSurfaceDesc
.dwBackBufferCount
= 1;
238 if(lpDD
->lpVtbl
->SetCooperativeLevel(lpDD
, hWnd
, DDSCL_NORMAL
) != DD_OK
)
240 lpDD
->lpVtbl
->Release(lpDD
);
243 DDSurfaceDesc
.dwFlags
= DDSD_CAPS
;
244 DDSurfaceDesc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
248 if(lpDD
->lpVtbl
->CreateSurface(lpDD
, &DDSurfaceDesc
, &lpDDPrimarySurface
, NULL
) != DD_OK
)
250 lpDD
->lpVtbl
->Release(lpDD
);
256 DDSCaps
.dwCaps
= DDSCAPS_BACKBUFFER
;
257 if (lpDDPrimarySurface
->lpVtbl
->GetAttachedSurface(lpDDPrimarySurface
, &DDSCaps
,&lpDDBackBuffer
) != DD_OK
)
259 lpDDPrimarySurface
->lpVtbl
->Release(lpDDPrimarySurface
);
260 lpDD
->lpVtbl
->Release(lpDD
);
266 /* create our offscreen back buffer */
267 ZeroMemory(&DDBBSurfaceDesc
,sizeof(DDBBSurfaceDesc
));
268 DDBBSurfaceDesc
.dwSize
= sizeof(DDBBSurfaceDesc
);
269 DDBBSurfaceDesc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
270 DDBBSurfaceDesc
.dwHeight
= DD_TEST_HEIGHT
;
271 DDBBSurfaceDesc
.dwWidth
= DD_TEST_WIDTH
;
272 DDBBSurfaceDesc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
274 if(lpDD
->lpVtbl
->CreateSurface(lpDD
, &DDBBSurfaceDesc
, &lpDDBackBuffer
, NULL
) != DD_OK
)
276 lpDD
->lpVtbl
->Release(lpDD
);
277 lpDDPrimarySurface
->lpVtbl
->Release(lpDDPrimarySurface
);
282 ClientToScreen(hWnd
, &wndPoint
);
283 GetClientRect(hWnd
, &rectDD
);
284 OffsetRect(&rectDD
, wndPoint
.x
, wndPoint
.y
);
287 /* set our timers, TimerID - for test timeout, TimerIDUpdate - for frame updating */
288 TimerID
= SetTimer(hWnd
, -1, (UINT
)TEST_DURATION
, NULL
);
289 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
>= (DD_TEST_WIDTH
- DD_SQUARE_SIZE
)) *gainX
= -(*gainX
);
348 if(*posY
>= (DD_TEST_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
);