[DXDIAG] Rename WIDTH, HEIGHT, InitListViewColumns and SetDeviceDetails. Zap WindowPr...
[reactos.git] / base / applications / dxdiag / ddtest.c
1 /*
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
7 *
8 */
9
10 #include "precomp.h"
11
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
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
23
24
25 BOOL StartDDTest(HWND hWnd, HINSTANCE hInstance, INT resTestDescription, INT resResult, INT TestNr)
26 {
27 WCHAR szTestDescription[256];
28 WCHAR szCaption[256];
29 WCHAR szResult[256];
30 WCHAR szError[256];
31 BOOL Result;
32
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));
37
38 if(MessageBox(NULL, szTestDescription, szCaption, MB_YESNO | MB_ICONQUESTION) == IDNO)
39 return FALSE;
40
41 ShowWindow(hWnd, SW_SHOW);
42
43 switch(TestNr){
44 case 1:
45 Result = DDPrimarySurfaceTest(hWnd);
46 break;
47 case 2:
48 Result = DDOffscreenBufferTest(hWnd, FALSE);
49 break;
50 case 3:
51 Result = DDOffscreenBufferTest(hWnd, TRUE);
52 break;
53 default:
54 Result = FALSE;
55 }
56
57 ShowWindow(hWnd, SW_HIDE);
58
59 if(!Result)
60 {
61 MessageBox(NULL, szError, szCaption, MB_OK | MB_ICONERROR);
62 return FALSE;
63 }
64
65 if(MessageBox(NULL, szResult, szCaption, MB_YESNO | MB_ICONQUESTION) == IDYES)
66 return TRUE;
67
68 return FALSE;
69 }
70
71 VOID DDTests()
72 {
73 WNDCLASSEX winClass;
74 HWND hWnd;
75 HINSTANCE hInstance = NULL;
76 WCHAR szDescription[256];
77 WCHAR szCaption[256];
78
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;
85 winClass.hIcon = 0;
86 winClass.hCursor = 0;
87 winClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
88 winClass.lpszMenuName = NULL;
89 winClass.lpszClassName = L"ddtest";
90 winClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
91
92 if (!RegisterClassEx(&winClass))
93 return;
94
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);
99
100 if (!hWnd){
101 return;
102 }
103
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)
107 return;
108
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);
112
113 DestroyWindow(hWnd);
114 UnregisterClass(winClass.lpszClassName, hInstance);
115 }
116
117 BOOL DDPrimarySurfaceTest(HWND hWnd){
118 UINT TimerID;
119 MSG msg;
120
121 LPDIRECTDRAW lpDD = NULL;
122 LPDIRECTDRAWSURFACE lpDDSurface = NULL;
123 DDSURFACEDESC DDSurfaceDesc;
124
125 if(DirectDrawCreate(NULL, &lpDD, NULL) != DD_OK)
126 return FALSE;
127
128 if(lpDD->lpVtbl->SetCooperativeLevel(lpDD, hWnd, DDSCL_NORMAL) != DD_OK)
129 {
130 lpDD->lpVtbl->Release(lpDD);
131 return FALSE;
132 }
133
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;
140
141 if(lpDD->lpVtbl->CreateSurface(lpDD, &DDSurfaceDesc, &lpDDSurface, NULL) != DD_OK)
142 {
143 lpDD->lpVtbl->Release(lpDD);
144 return FALSE;
145 }
146
147 TimerID = SetTimer(hWnd, -1, (UINT)TEST_DURATION, NULL);
148
149 while (TRUE)
150 {
151 if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
152 {
153 if (msg.message == WM_TIMER && TimerID == msg.wParam)
154 break;
155 TranslateMessage(&msg);
156 DispatchMessage(&msg);
157 if (msg.message == WM_PAINT)
158 DDRedrawFrame(lpDDSurface);
159 }
160 }
161 KillTimer(hWnd, TimerID);
162 lpDDSurface->lpVtbl->Release(lpDDSurface);
163 lpDD->lpVtbl->Release(lpDD);
164
165 return TRUE;
166 }
167
168 VOID DDRedrawFrame(LPDIRECTDRAWSURFACE lpDDSurface)
169 {
170 HDC hdc;
171
172 if (lpDDSurface->lpVtbl->GetDC(lpDDSurface, &hdc) == DD_OK)
173 {
174 RECT rct;
175 HBRUSH BlackBrush, WhiteBrush;
176 BOOL Colour = FALSE;
177
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;
182
183 BlackBrush = CreateSolidBrush(RGB(0,0,0));
184 WhiteBrush = CreateSolidBrush(RGB(255,255,255));
185
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;
192 Colour = !Colour;
193 }
194 DeleteObject((HGDIOBJ)BlackBrush);
195 DeleteObject((HGDIOBJ)WhiteBrush);
196 lpDDSurface->lpVtbl->ReleaseDC(lpDDSurface, hdc);
197 }
198 }
199
200
201 BOOL DDOffscreenBufferTest(HWND hWnd, BOOL Fullscreen){
202 UINT_PTR TimerID, TimerIDUpdate;
203 LPDIRECTDRAW lpDD;
204 LPDIRECTDRAWSURFACE lpDDPrimarySurface;
205 LPDIRECTDRAWSURFACE lpDDBackBuffer;
206 DDSURFACEDESC DDSurfaceDesc;
207 DDSURFACEDESC DDBBSurfaceDesc;
208 DDSCAPS DDSCaps;
209 MSG msg;
210 RECT rectDD;
211 POINT wndPoint;
212 INT posX = 0, posY = 10, xGain = DD_SQUARE_STEP, yGain = DD_SQUARE_STEP;
213
214 if(DirectDrawCreate(NULL, &lpDD, NULL) != DD_OK)
215 return FALSE;
216
217 ZeroMemory(&DDSurfaceDesc, sizeof(DDSurfaceDesc));
218 DDSurfaceDesc.dwSize = sizeof(DDSurfaceDesc);
219
220 if(Fullscreen)
221 {
222 if(lpDD->lpVtbl->SetCooperativeLevel(lpDD, hWnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN) != DD_OK)
223 {
224 lpDD->lpVtbl->Release(lpDD);
225 return FALSE;
226 }
227 if(lpDD->lpVtbl->SetDisplayMode(lpDD, DD_TEST_WIDTH, DD_TEST_HEIGHT, 32) != DD_OK)
228 {
229 lpDD->lpVtbl->Release(lpDD);
230 return FALSE;
231 }
232 DDSurfaceDesc.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
233 DDSurfaceDesc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
234 DDSurfaceDesc.dwBackBufferCount = 1;
235 }
236 else
237 {
238 if(lpDD->lpVtbl->SetCooperativeLevel(lpDD, hWnd, DDSCL_NORMAL) != DD_OK)
239 {
240 lpDD->lpVtbl->Release(lpDD);
241 return FALSE;
242 }
243 DDSurfaceDesc.dwFlags = DDSD_CAPS;
244 DDSurfaceDesc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
245 }
246
247
248 if(lpDD->lpVtbl->CreateSurface(lpDD, &DDSurfaceDesc, &lpDDPrimarySurface, NULL) != DD_OK)
249 {
250 lpDD->lpVtbl->Release(lpDD);
251 return FALSE;
252 }
253
254 if(Fullscreen)
255 {
256 DDSCaps.dwCaps = DDSCAPS_BACKBUFFER;
257 if (lpDDPrimarySurface->lpVtbl->GetAttachedSurface(lpDDPrimarySurface, &DDSCaps,&lpDDBackBuffer) != DD_OK)
258 {
259 lpDDPrimarySurface->lpVtbl->Release(lpDDPrimarySurface);
260 lpDD->lpVtbl->Release(lpDD);
261 return FALSE;
262 }
263 }
264 else
265 {
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;
273
274 if(lpDD->lpVtbl->CreateSurface(lpDD, &DDBBSurfaceDesc, &lpDDBackBuffer, NULL) != DD_OK)
275 {
276 lpDD->lpVtbl->Release(lpDD);
277 lpDDPrimarySurface->lpVtbl->Release(lpDDPrimarySurface);
278 return FALSE;
279 }
280 wndPoint.x = 0;
281 wndPoint.y = 0;
282 ClientToScreen(hWnd, &wndPoint);
283 GetClientRect(hWnd, &rectDD);
284 OffsetRect(&rectDD, wndPoint.x, wndPoint.y);
285 }
286
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);
290 (void)TimerIDUpdate;
291
292 while (TRUE)
293 {
294 if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
295 {
296 if (msg.message == WM_TIMER)
297 {
298 if(msg.wParam == TimerID)
299 {
300 break;
301 }
302 else
303 {
304 DDUpdateFrame(lpDDPrimarySurface,lpDDBackBuffer, Fullscreen,&posX, &posY, &xGain, &yGain, &rectDD);
305 }
306 }
307 TranslateMessage(&msg);
308 DispatchMessage(&msg);
309 }
310 }
311
312 lpDDPrimarySurface->lpVtbl->Release(lpDDPrimarySurface);
313 /* backbuffer is released automatically when in fullscreen */
314 if(!Fullscreen)
315 lpDDBackBuffer->lpVtbl->Release(lpDDBackBuffer);
316 lpDD->lpVtbl->Release(lpDD);
317
318 return TRUE;
319 }
320
321
322 VOID DDUpdateFrame(LPDIRECTDRAWSURFACE lpDDPrimarySurface ,LPDIRECTDRAWSURFACE lpDDBackBuffer, BOOL Fullscreen, INT *posX, INT *posY, INT *gainX, INT *gainY, RECT *rectDD)
323 {
324 HDC hdc;
325 DDBLTFX DDBlitFx;
326
327 /* clear back buffer and paint it black */
328 ZeroMemory(&DDBlitFx, sizeof(DDBlitFx));
329 DDBlitFx.dwSize = sizeof(DDBlitFx);
330 DDBlitFx.dwFillColor = 0;
331
332 lpDDBackBuffer->lpVtbl->Blt(lpDDBackBuffer, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &DDBlitFx);
333
334 if (lpDDBackBuffer->lpVtbl->GetDC(lpDDBackBuffer, &hdc) == DD_OK)
335 {
336 RECT rct;
337 HBRUSH WhiteBrush;
338
339 rct.left = *posX;
340 rct.right = *posX+DD_SQUARE_SIZE;
341 rct.top = *posY;
342 rct.bottom = *posY+DD_SQUARE_SIZE;
343
344 WhiteBrush = CreateSolidBrush(RGB(255,255,255));
345 FillRect(hdc, &rct, WhiteBrush);
346
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);
351
352 *posX += *gainX;
353 *posY += *gainY;
354
355 lpDDBackBuffer->lpVtbl->ReleaseDC(lpDDBackBuffer, hdc);
356
357 if(Fullscreen)
358 {
359 lpDDPrimarySurface->lpVtbl->Flip(lpDDPrimarySurface, NULL, DDFLIP_WAIT);
360 }
361 else
362 {
363 lpDDPrimarySurface->lpVtbl->Blt(lpDDPrimarySurface, rectDD, lpDDBackBuffer, NULL, DDBLT_WAIT, NULL);
364 }
365 }
366 }