2
* Copyright 2011 Henri Verbeet for CodeWeavers
4
* This library is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU Lesser General Public
6
* License as published by the Free Software Foundation; either
7
* version 2.1 of the License, or (at your option) any later version.
9
* This library is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
* Lesser General Public License for more details.
14
* You should have received a copy of the GNU Lesser General Public
15
* License along with this library; if not, write to the Free Software
16
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19
#include "wine/test.h"
33
static BOOL compare_float(float f, float g, unsigned int ulps)
43
if (abs(x - y) > ulps)
49
static BOOL compare_vec4(struct vec4 *vec, float x, float y, float z, float w, unsigned int ulps)
51
return compare_float(vec->x, x, ulps)
52
&& compare_float(vec->y, y, ulps)
53
&& compare_float(vec->z, z, ulps)
54
&& compare_float(vec->w, w, ulps);
57
static BOOL compare_color(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
59
if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
61
if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
63
if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
65
if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
69
static D3DCOLOR get_surface_color(IDirectDrawSurface4 *surface, UINT x, UINT y)
71
RECT rect = {x, y, x + 1, y + 1};
72
DDSURFACEDESC2 surface_desc;
76
memset(&surface_desc, 0, sizeof(surface_desc));
77
surface_desc.dwSize = sizeof(surface_desc);
79
hr = IDirectDrawSurface4_Lock(surface, &rect, &surface_desc, DDLOCK_READONLY | DDLOCK_WAIT, NULL);
80
ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
84
color = *((DWORD *)surface_desc.lpSurface) & 0x00ffffff;
86
hr = IDirectDrawSurface4_Unlock(surface, &rect);
87
ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
92
static IDirectDraw4 *create_ddraw(void)
98
if (FAILED(DirectDrawCreate(NULL, &ddraw1, NULL)))
101
hr = IDirectDraw_QueryInterface(ddraw1, &IID_IDirectDraw4, (void **)&ddraw4);
102
IDirectDraw_Release(ddraw1);
109
static IDirect3DDevice3 *create_device(HWND window, DWORD coop_level)
111
IDirect3DDevice3 *device = NULL;
112
IDirectDrawSurface4 *surface;
113
DDSURFACEDESC2 surface_desc;
114
IDirectDraw4 *ddraw4;
118
if (!(ddraw4 = create_ddraw()))
121
hr = IDirectDraw4_SetCooperativeLevel(ddraw4, window, coop_level);
122
ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
124
memset(&surface_desc, 0, sizeof(surface_desc));
125
surface_desc.dwSize = sizeof(surface_desc);
126
surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
127
surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
128
surface_desc.dwWidth = 640;
129
surface_desc.dwHeight = 480;
131
hr = IDirectDraw4_CreateSurface(ddraw4, &surface_desc, &surface, NULL);
132
ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
134
if (coop_level & DDSCL_NORMAL)
136
IDirectDrawClipper *clipper;
138
hr = IDirectDraw4_CreateClipper(ddraw4, 0, &clipper, NULL);
139
ok(SUCCEEDED(hr), "Failed to create clipper, hr %#x.\n", hr);
140
hr = IDirectDrawClipper_SetHWnd(clipper, 0, window);
141
ok(SUCCEEDED(hr), "Failed to set clipper window, hr %#x.\n", hr);
142
hr = IDirectDrawSurface4_SetClipper(surface, clipper);
143
ok(SUCCEEDED(hr), "Failed to set surface clipper, hr %#x.\n", hr);
144
IDirectDrawClipper_Release(clipper);
147
hr = IDirectDraw4_QueryInterface(ddraw4, &IID_IDirect3D3, (void **)&d3d3);
148
IDirectDraw4_Release(ddraw4);
151
IDirectDrawSurface4_Release(surface);
155
hr = IDirect3D3_CreateDevice(d3d3, &IID_IDirect3DHALDevice, surface, &device, NULL);
156
IDirect3D3_Release(d3d3);
157
IDirectDrawSurface4_Release(surface);
164
static void test_process_vertices(void)
166
IDirect3DVertexBuffer *src_vb, *dst_vb;
167
IDirect3DViewport3 *viewport;
168
D3DVERTEXBUFFERDESC vb_desc;
169
IDirect3DDevice3 *device;
170
struct vec3 *src_data;
171
struct vec4 *dst_data;
178
static D3DMATRIX identity =
180
1.0f, 0.0f, 0.0f, 0.0f,
181
0.0f, 1.0f, 0.0f, 0.0f,
182
0.0f, 0.0f, 1.0f, 0.0f,
183
0.0f, 0.0f, 0.0f, 1.0f,
185
static D3DMATRIX projection =
187
1.0f, 0.0f, 0.0f, 0.0f,
188
0.0f, 1.0f, 0.0f, 0.0f,
189
0.0f, 0.0f, 1.0f, 0.0f,
190
6.0f, 7.0f, 8.0f, 1.0f,
193
window = CreateWindowA("static", "d3d7_test", WS_OVERLAPPEDWINDOW,
194
0, 0, 640, 480, 0, 0, 0, 0);
195
if (!(device = create_device(window, DDSCL_NORMAL)))
197
skip("Failed to create a 3D device, skipping test.\n");
198
DestroyWindow(window);
202
hr = IDirect3DDevice3_GetDirect3D(device, &d3d3);
203
ok(SUCCEEDED(hr), "Failed to get Direct3D3 interface, hr %#x.\n", hr);
205
memset(&vb_desc, 0, sizeof(vb_desc));
206
vb_desc.dwSize = sizeof(vb_desc);
207
vb_desc.dwFVF = D3DFVF_XYZ;
208
vb_desc.dwNumVertices = 3;
209
hr = IDirect3D3_CreateVertexBuffer(d3d3, &vb_desc, &src_vb, 0, NULL);
210
ok(SUCCEEDED(hr), "Failed to create source vertex buffer, hr %#x.\n", hr);
212
hr = IDirect3DVertexBuffer_Lock(src_vb, DDLOCK_WRITEONLY, (void **)&src_data, NULL);
213
ok(SUCCEEDED(hr), "Failed to lock source vertex buffer, hr %#x.\n", hr);
214
src_data[0].x = -1.0f;
215
src_data[0].y = -1.0f;
216
src_data[0].z = -1.0f;
217
src_data[1].x = 0.0f;
218
src_data[1].y = 0.0f;
219
src_data[1].z = 0.0f;
220
src_data[2].x = 1.0f;
221
src_data[2].y = 1.0f;
222
src_data[2].z = 1.0f;
223
hr = IDirect3DVertexBuffer_Unlock(src_vb);
224
ok(SUCCEEDED(hr), "Failed to unlock source vertex buffer, hr %#x.\n", hr);
226
memset(&vb_desc, 0, sizeof(vb_desc));
227
vb_desc.dwSize = sizeof(vb_desc);
228
vb_desc.dwFVF = D3DFVF_XYZRHW;
229
vb_desc.dwNumVertices = 3;
230
hr = IDirect3D3_CreateVertexBuffer(d3d3, &vb_desc, &dst_vb, 0, NULL);
231
ok(SUCCEEDED(hr), "Failed to create destination vertex buffer, hr %#x.\n", hr);
233
hr = IDirect3D3_CreateViewport(d3d3, &viewport, NULL);
234
ok(SUCCEEDED(hr), "Failed to create viewport, hr %#x.\n", hr);
235
hr = IDirect3DDevice3_AddViewport(device, viewport);
236
ok(SUCCEEDED(hr), "Failed to add viewport, hr %#x.\n", hr);
237
vp2.dwSize = sizeof(vp2);
244
vp2.dvClipWidth = 4.0f;
245
vp2.dvClipHeight = 5.0f;
248
hr = IDirect3DViewport3_SetViewport2(viewport, &vp2);
249
ok(SUCCEEDED(hr), "Failed to set viewport data, hr %#x.\n", hr);
250
hr = IDirect3DDevice3_SetCurrentViewport(device, viewport);
251
ok(SUCCEEDED(hr), "Failed to set current viewport, hr %#x.\n", hr);
253
hr = IDirect3DDevice3_SetTransform(device, D3DTRANSFORMSTATE_WORLD, &identity);
254
ok(SUCCEEDED(hr), "Failed to set world transformation, hr %#x.\n", hr);
255
hr = IDirect3DDevice3_SetTransform(device, D3DTRANSFORMSTATE_VIEW, &identity);
256
ok(SUCCEEDED(hr), "Failed to set view transformation, hr %#x.\n", hr);
257
hr = IDirect3DDevice3_SetTransform(device, D3DTRANSFORMSTATE_PROJECTION, &identity);
258
ok(SUCCEEDED(hr), "Failed to set projection transformation, hr %#x.\n", hr);
260
hr = IDirect3DVertexBuffer_ProcessVertices(dst_vb, D3DVOP_TRANSFORM, 0, 3, src_vb, 0, device, 0);
261
ok(SUCCEEDED(hr), "Failed to process vertices, hr %#x.\n", hr);
263
hr = IDirect3DVertexBuffer_Lock(dst_vb, DDLOCK_READONLY, (void **)&dst_data, NULL);
264
ok(SUCCEEDED(hr), "Failed to lock destination vertex buffer, hr %#x.\n", hr);
265
ok(compare_vec4(&dst_data[0], -6.500e+1f, +1.800e+2f, +2.000e-1f, +1.000e+0f, 4096),
266
"Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
267
dst_data[0].x, dst_data[0].y, dst_data[0].z, dst_data[0].w);
268
ok(compare_vec4(&dst_data[1], -4.000e+1f, +1.400e+2f, +4.000e-1f, +1.000e+0f, 4096),
269
"Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
270
dst_data[1].x, dst_data[1].y, dst_data[1].z, dst_data[1].w);
271
ok(compare_vec4(&dst_data[2], -1.500e+1f, +1.000e+2f, +6.000e-1f, +1.000e+0f, 4096),
272
"Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
273
dst_data[2].x, dst_data[2].y, dst_data[2].z, dst_data[2].w);
274
hr = IDirect3DVertexBuffer_Unlock(dst_vb);
275
ok(SUCCEEDED(hr), "Failed to unlock destination vertex buffer, hr %#x.\n", hr);
277
hr = IDirect3DDevice3_MultiplyTransform(device, D3DTRANSFORMSTATE_PROJECTION, &projection);
278
ok(SUCCEEDED(hr), "Failed to set projection transformation, hr %#x.\n", hr);
280
hr = IDirect3DVertexBuffer_ProcessVertices(dst_vb, D3DVOP_TRANSFORM, 0, 3, src_vb, 0, device, 0);
281
ok(SUCCEEDED(hr), "Failed to process vertices, hr %#x.\n", hr);
283
hr = IDirect3DVertexBuffer_Lock(dst_vb, DDLOCK_READONLY, (void **)&dst_data, NULL);
284
ok(SUCCEEDED(hr), "Failed to lock destination vertex buffer, hr %#x.\n", hr);
285
ok(compare_vec4(&dst_data[0], +8.500e+1f, -1.000e+2f, +1.800e+0f, +1.000e+0f, 4096),
286
"Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
287
dst_data[0].x, dst_data[0].y, dst_data[0].z, dst_data[0].w);
288
ok(compare_vec4(&dst_data[1], +1.100e+2f, -1.400e+2f, +2.000e+0f, +1.000e+0f, 4096),
289
"Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
290
dst_data[1].x, dst_data[1].y, dst_data[1].z, dst_data[1].w);
291
ok(compare_vec4(&dst_data[2], +1.350e+2f, -1.800e+2f, +2.200e+0f, +1.000e+0f, 4096),
292
"Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
293
dst_data[2].x, dst_data[2].y, dst_data[2].z, dst_data[2].w);
294
hr = IDirect3DVertexBuffer_Unlock(dst_vb);
295
ok(SUCCEEDED(hr), "Failed to unlock destination vertex buffer, hr %#x.\n", hr);
297
vp2.dwSize = sizeof(vp2);
304
vp2.dvClipWidth = 2.0f;
305
vp2.dvClipHeight = 4.0f;
308
hr = IDirect3DViewport3_SetViewport2(viewport, &vp2);
309
ok(SUCCEEDED(hr), "Failed to set viewport data, hr %#x.\n", hr);
311
hr = IDirect3DVertexBuffer_ProcessVertices(dst_vb, D3DVOP_TRANSFORM, 0, 3, src_vb, 0, device, 0);
312
ok(SUCCEEDED(hr), "Failed to process vertices, hr %#x.\n", hr);
314
hr = IDirect3DVertexBuffer_Lock(dst_vb, DDLOCK_READONLY, (void **)&dst_data, NULL);
315
ok(SUCCEEDED(hr), "Failed to lock destination vertex buffer, hr %#x.\n", hr);
316
ok(compare_vec4(&dst_data[0], +7.500e+1f, +4.000e+1f, -8.000e-1f, +1.000e+0f, 4096),
317
"Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
318
dst_data[0].x, dst_data[0].y, dst_data[0].z, dst_data[0].w);
319
ok(compare_vec4(&dst_data[1], +1.200e+2f, +2.000e+1f, -1.000e+0f, +1.000e+0f, 4096),
320
"Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
321
dst_data[1].x, dst_data[1].y, dst_data[1].z, dst_data[1].w);
322
ok(compare_vec4(&dst_data[2], +1.650e+2f, +0.000e+0f, -1.200e+0f, +1.000e+0f, 4096),
323
"Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
324
dst_data[2].x, dst_data[2].y, dst_data[2].z, dst_data[2].w);
325
hr = IDirect3DVertexBuffer_Unlock(dst_vb);
326
ok(SUCCEEDED(hr), "Failed to unlock destination vertex buffer, hr %#x.\n", hr);
328
vp1.dwSize = sizeof(vp1);
339
hr = IDirect3DViewport3_SetViewport(viewport, &vp1);
340
ok(SUCCEEDED(hr), "Failed to set viewport data, hr %#x.\n", hr);
342
hr = IDirect3DVertexBuffer_ProcessVertices(dst_vb, D3DVOP_TRANSFORM, 0, 3, src_vb, 0, device, 0);
343
ok(SUCCEEDED(hr), "Failed to process vertices, hr %#x.\n", hr);
345
hr = IDirect3DVertexBuffer_Lock(dst_vb, DDLOCK_READONLY, (void **)&dst_data, NULL);
346
ok(SUCCEEDED(hr), "Failed to lock destination vertex buffer, hr %#x.\n", hr);
347
ok(compare_vec4(&dst_data[0], +1.100e+2f, +6.800e+1f, +7.000e+0f, +1.000e+0f, 4096),
348
"Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
349
dst_data[0].x, dst_data[0].y, dst_data[0].z, dst_data[0].w);
350
ok(compare_vec4(&dst_data[1], +1.170e+2f, +6.600e+1f, +8.000e+0f, +1.000e+0f, 4096),
351
"Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
352
dst_data[1].x, dst_data[1].y, dst_data[1].z, dst_data[1].w);
353
ok(compare_vec4(&dst_data[2], +1.240e+2f, +6.400e+1f, +9.000e+0f, +1.000e+0f, 4096),
354
"Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
355
dst_data[2].x, dst_data[2].y, dst_data[2].z, dst_data[2].w);
356
hr = IDirect3DVertexBuffer_Unlock(dst_vb);
357
ok(SUCCEEDED(hr), "Failed to unlock destination vertex buffer, hr %#x.\n", hr);
359
hr = IDirect3DDevice3_DeleteViewport(device, viewport);
360
ok(SUCCEEDED(hr), "Failed to delete viewport, hr %#x.\n", hr);
362
IDirect3DVertexBuffer_Release(dst_vb);
363
IDirect3DVertexBuffer_Release(src_vb);
364
IDirect3DViewport3_Release(viewport);
365
IDirect3D3_Release(d3d3);
366
IDirect3DDevice3_Release(device);
367
DestroyWindow(window);
370
static void test_coop_level_create_device_window(void)
372
HWND focus_window, device_window;
376
focus_window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
377
0, 0, 640, 480, 0, 0, 0, 0);
378
if (!(ddraw = create_ddraw()))
380
skip("Failed to create a ddraw object, skipping test.\n");
381
DestroyWindow(focus_window);
385
hr = IDirectDraw4_SetCooperativeLevel(ddraw, NULL, DDSCL_NORMAL);
386
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
387
device_window = FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
388
ok(!device_window, "Unexpected device window found.\n");
389
hr = IDirectDraw4_SetCooperativeLevel(ddraw, NULL, DDSCL_CREATEDEVICEWINDOW);
390
ok(hr == DDERR_INVALIDPARAMS, "Got unexpected hr %#x.\n", hr);
391
device_window = FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
392
ok(!device_window, "Unexpected device window found.\n");
393
hr = IDirectDraw4_SetCooperativeLevel(ddraw, NULL, DDSCL_CREATEDEVICEWINDOW | DDSCL_NORMAL);
394
ok(hr == DDERR_INVALIDPARAMS, "Got unexpected hr %#x.\n", hr);
395
device_window = FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
396
ok(!device_window, "Unexpected device window found.\n");
397
hr = IDirectDraw4_SetCooperativeLevel(ddraw, NULL, DDSCL_CREATEDEVICEWINDOW | DDSCL_NORMAL | DDSCL_FULLSCREEN);
398
ok(hr == DDERR_INVALIDPARAMS, "Got unexpected hr %#x.\n", hr);
399
device_window = FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
400
ok(!device_window, "Unexpected device window found.\n");
401
hr = IDirectDraw4_SetCooperativeLevel(ddraw, NULL, DDSCL_CREATEDEVICEWINDOW | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
402
ok(hr == DDERR_NOFOCUSWINDOW || broken(hr == DDERR_INVALIDPARAMS), "Got unexpected hr %#x.\n", hr);
403
device_window = FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
404
ok(!device_window, "Unexpected device window found.\n");
406
/* Windows versions before 98 / NT5 don't support DDSCL_CREATEDEVICEWINDOW. */
407
if (broken(hr == DDERR_INVALIDPARAMS))
409
win_skip("DDSCL_CREATEDEVICEWINDOW not supported, skipping test.\n");
410
IDirectDraw4_Release(ddraw);
411
DestroyWindow(focus_window);
415
hr = IDirectDraw4_SetCooperativeLevel(ddraw, NULL, DDSCL_NORMAL);
416
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
417
device_window = FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
418
ok(!device_window, "Unexpected device window found.\n");
419
hr = IDirectDraw4_SetCooperativeLevel(ddraw, focus_window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
420
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
421
device_window = FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
422
ok(!device_window, "Unexpected device window found.\n");
424
hr = IDirectDraw4_SetCooperativeLevel(ddraw, NULL, DDSCL_NORMAL);
425
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
426
device_window = FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
427
ok(!device_window, "Unexpected device window found.\n");
428
hr = IDirectDraw4_SetCooperativeLevel(ddraw, NULL, DDSCL_SETFOCUSWINDOW
429
| DDSCL_CREATEDEVICEWINDOW | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
430
ok(hr == DDERR_NOHWND, "Got unexpected hr %#x.\n", hr);
431
device_window = FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
432
ok(!!device_window, "Device window not found.\n");
434
hr = IDirectDraw4_SetCooperativeLevel(ddraw, NULL, DDSCL_NORMAL);
435
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
436
device_window = FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
437
ok(!device_window, "Unexpected device window found.\n");
438
hr = IDirectDraw4_SetCooperativeLevel(ddraw, focus_window, DDSCL_SETFOCUSWINDOW
439
| DDSCL_CREATEDEVICEWINDOW | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
440
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
441
device_window = FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
442
ok(!!device_window, "Device window not found.\n");
444
hr = IDirectDraw4_SetCooperativeLevel(ddraw, NULL, DDSCL_NORMAL);
445
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
446
device_window = FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
447
ok(!device_window, "Unexpected device window found.\n");
448
hr = IDirectDraw4_SetCooperativeLevel(ddraw, NULL, DDSCL_CREATEDEVICEWINDOW | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
449
ok(hr == DDERR_NOFOCUSWINDOW, "Got unexpected hr %#x.\n", hr);
450
device_window = FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
451
ok(!device_window, "Unexpected device window found.\n");
452
hr = IDirectDraw4_SetCooperativeLevel(ddraw, focus_window, DDSCL_SETFOCUSWINDOW);
453
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
454
device_window = FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
455
ok(!device_window, "Unexpected device window found.\n");
456
hr = IDirectDraw4_SetCooperativeLevel(ddraw, NULL, DDSCL_CREATEDEVICEWINDOW | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
457
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
458
device_window = FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
459
ok(!!device_window, "Device window not found.\n");
461
IDirectDraw4_Release(ddraw);
462
DestroyWindow(focus_window);
465
static void test_clipper_blt(void)
467
IDirectDrawSurface4 *src_surface, *dst_surface;
468
RECT client_rect, src_rect, *rect;
469
IDirectDrawClipper *clipper;
470
DDSURFACEDESC2 surface_desc;
471
unsigned int i, j, x, y;
481
static const D3DCOLOR expected1[] =
483
0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
484
0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
485
0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
486
0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
488
static const D3DCOLOR expected2[] =
490
0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
491
0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
492
0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
493
0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
496
window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
497
10, 10, 640, 480, 0, 0, 0, 0);
498
ShowWindow(window, SW_SHOW);
499
if (!(ddraw = create_ddraw()))
501
skip("Failed to create a ddraw object, skipping test.\n");
502
DestroyWindow(window);
506
ret = GetClientRect(window, &client_rect);
507
ok(ret, "Failed to get client rect.\n");
508
ret = MapWindowPoints(window, NULL, (POINT *)&client_rect, 2);
509
ok(ret, "Failed to map client rect.\n");
511
hr = IDirectDraw4_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
512
ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
514
hr = IDirectDraw4_CreateClipper(ddraw, 0, &clipper, NULL);
515
ok(SUCCEEDED(hr), "Failed to create clipper, hr %#x.\n", hr);
516
hr = IDirectDrawClipper_GetClipList(clipper, NULL, NULL, &ret);
517
ok(hr == DDERR_NOCLIPLIST, "Got unexpected hr %#x.\n", hr);
518
hr = IDirectDrawClipper_SetHWnd(clipper, 0, window);
519
ok(SUCCEEDED(hr), "Failed to set clipper window, hr %#x.\n", hr);
520
hr = IDirectDrawClipper_GetClipList(clipper, NULL, NULL, &ret);
521
ok(SUCCEEDED(hr), "Failed to get clip list size, hr %#x.\n", hr);
522
rgn_data = HeapAlloc(GetProcessHeap(), 0, ret);
523
hr = IDirectDrawClipper_GetClipList(clipper, NULL, rgn_data, &ret);
524
ok(SUCCEEDED(hr), "Failed to get clip list, hr %#x.\n", hr);
525
ok(rgn_data->rdh.dwSize == sizeof(rgn_data->rdh), "Got unexpected structure size %#x.\n", rgn_data->rdh.dwSize);
526
ok(rgn_data->rdh.iType == RDH_RECTANGLES, "Got unexpected type %#x.\n", rgn_data->rdh.iType);
527
ok(rgn_data->rdh.nCount == 1, "Got unexpected count %u.\n", rgn_data->rdh.nCount);
528
ok(rgn_data->rdh.nRgnSize == 16, "Got unexpected region size %u.\n", rgn_data->rdh.nRgnSize);
529
ok(EqualRect(&rgn_data->rdh.rcBound, &client_rect),
530
"Got unexpected bounding rect {%d, %d, %d, %d}, expected {%d, %d, %d, %d}.\n",
531
rgn_data->rdh.rcBound.left, rgn_data->rdh.rcBound.top,
532
rgn_data->rdh.rcBound.right, rgn_data->rdh.rcBound.bottom,
533
client_rect.left, client_rect.top, client_rect.right, client_rect.bottom);
534
rect = (RECT *)&rgn_data->Buffer[0];
535
ok(EqualRect(rect, &client_rect),
536
"Got unexpected clip rect {%d, %d, %d, %d}, expected {%d, %d, %d, %d}.\n",
537
rect->left, rect->top, rect->right, rect->bottom,
538
client_rect.left, client_rect.top, client_rect.right, client_rect.bottom);
539
HeapFree(GetProcessHeap(), 0, rgn_data);
541
r1 = CreateRectRgn(0, 0, 320, 240);
542
ok(!!r1, "Failed to create region.\n");
543
r2 = CreateRectRgn(320, 240, 640, 480);
544
ok(!!r2, "Failed to create region.\n");
545
CombineRgn(r1, r1, r2, RGN_OR);
546
ret = GetRegionData(r1, 0, NULL);
547
rgn_data = HeapAlloc(GetProcessHeap(), 0, ret);
548
ret = GetRegionData(r1, ret, rgn_data);
549
ok(!!ret, "Failed to get region data.\n");
554
hr = IDirectDrawClipper_SetClipList(clipper, rgn_data, 0);
555
ok(hr == DDERR_CLIPPERISUSINGHWND, "Got unexpected hr %#x.\n", hr);
556
hr = IDirectDrawClipper_SetHWnd(clipper, 0, NULL);
557
ok(SUCCEEDED(hr), "Failed to set clipper window, hr %#x.\n", hr);
558
hr = IDirectDrawClipper_SetClipList(clipper, rgn_data, 0);
559
ok(SUCCEEDED(hr), "Failed to set clip list, hr %#x.\n", hr);
561
HeapFree(GetProcessHeap(), 0, rgn_data);
563
memset(&surface_desc, 0, sizeof(surface_desc));
564
surface_desc.dwSize = sizeof(surface_desc);
565
surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
566
surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
567
surface_desc.dwWidth = 640;
568
surface_desc.dwHeight = 480;
569
U4(surface_desc).ddpfPixelFormat.dwSize = sizeof(U4(surface_desc).ddpfPixelFormat);
570
U4(surface_desc).ddpfPixelFormat.dwFlags = DDPF_RGB;
571
U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount = 32;
572
U2(U4(surface_desc).ddpfPixelFormat).dwRBitMask = 0x00ff0000;
573
U3(U4(surface_desc).ddpfPixelFormat).dwGBitMask = 0x0000ff00;
574
U4(U4(surface_desc).ddpfPixelFormat).dwBBitMask = 0x000000ff;
576
hr = IDirectDraw4_CreateSurface(ddraw, &surface_desc, &src_surface, NULL);
577
ok(SUCCEEDED(hr), "Failed to create source surface, hr %#x.\n", hr);
578
hr = IDirectDraw4_CreateSurface(ddraw, &surface_desc, &dst_surface, NULL);
579
ok(SUCCEEDED(hr), "Failed to create destination surface, hr %#x.\n", hr);
581
memset(&fx, 0, sizeof(fx));
582
fx.dwSize = sizeof(fx);
583
hr = IDirectDrawSurface4_Blt(src_surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
584
ok(SUCCEEDED(hr), "Failed to clear source surface, hr %#x.\n", hr);
585
hr = IDirectDrawSurface4_Blt(dst_surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
586
ok(SUCCEEDED(hr), "Failed to clear destination surface, hr %#x.\n", hr);
588
hr = IDirectDrawSurface4_Lock(src_surface, NULL, &surface_desc, DDLOCK_WAIT, NULL);
589
ok(SUCCEEDED(hr), "Failed to lock source surface, hr %#x.\n", hr);
590
((DWORD *)surface_desc.lpSurface)[0] = 0xff0000ff;
591
((DWORD *)surface_desc.lpSurface)[1] = 0xff00ff00;
592
((DWORD *)surface_desc.lpSurface)[2] = 0xffff0000;
593
((DWORD *)surface_desc.lpSurface)[3] = 0xffffffff;
594
hr = IDirectDrawSurface4_Unlock(src_surface, NULL);
595
ok(SUCCEEDED(hr), "Failed to unlock source surface, hr %#x.\n", hr);
597
hr = IDirectDrawSurface4_SetClipper(dst_surface, clipper);
598
ok(SUCCEEDED(hr), "Failed to set clipper, hr %#x.\n", hr);
600
SetRect(&src_rect, 0, 0, 4, 1);
601
hr = IDirectDrawSurface4_Blt(dst_surface, NULL, src_surface, &src_rect, DDBLT_WAIT, NULL);
602
ok(SUCCEEDED(hr), "Failed to blit, hr %#x.\n", hr);
603
for (i = 0; i < 4; ++i)
605
for (j = 0; j < 4; ++j)
607
x = 80 * ((2 * j) + 1);
608
y = 60 * ((2 * i) + 1);
609
color = get_surface_color(dst_surface, x, y);
610
ok(compare_color(color, expected1[i * 4 + j], 1),
611
"Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected1[i * 4 + j], x, y, color);
615
U5(fx).dwFillColor = 0xff0000ff;
616
hr = IDirectDrawSurface4_Blt(dst_surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
617
ok(SUCCEEDED(hr), "Failed to clear destination surface, hr %#x.\n", hr);
618
for (i = 0; i < 4; ++i)
620
for (j = 0; j < 4; ++j)
622
x = 80 * ((2 * j) + 1);
623
y = 60 * ((2 * i) + 1);
624
color = get_surface_color(dst_surface, x, y);
625
ok(compare_color(color, expected2[i * 4 + j], 1),
626
"Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected2[i * 4 + j], x, y, color);
630
hr = IDirectDrawSurface4_BltFast(dst_surface, 0, 0, src_surface, NULL, DDBLTFAST_WAIT);
631
ok(hr == DDERR_BLTFASTCANTCLIP, "Got unexpected hr %#x.\n", hr);
633
hr = IDirectDrawClipper_SetHWnd(clipper, 0, window);
634
ok(SUCCEEDED(hr), "Failed to set clipper window, hr %#x.\n", hr);
635
hr = IDirectDrawClipper_GetClipList(clipper, NULL, NULL, &ret);
636
ok(SUCCEEDED(hr), "Failed to get clip list size, hr %#x.\n", hr);
637
DestroyWindow(window);
638
hr = IDirectDrawClipper_GetClipList(clipper, NULL, NULL, &ret);
639
ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr);
640
hr = IDirectDrawClipper_SetHWnd(clipper, 0, NULL);
641
ok(SUCCEEDED(hr), "Failed to set clipper window, hr %#x.\n", hr);
642
hr = IDirectDrawClipper_GetClipList(clipper, NULL, NULL, &ret);
643
ok(SUCCEEDED(hr), "Failed to get clip list size, hr %#x.\n", hr);
644
hr = IDirectDrawClipper_SetClipList(clipper, NULL, 0);
645
ok(SUCCEEDED(hr), "Failed to set clip list, hr %#x.\n", hr);
646
hr = IDirectDrawClipper_GetClipList(clipper, NULL, NULL, &ret);
647
ok(hr == DDERR_NOCLIPLIST, "Got unexpected hr %#x.\n", hr);
648
hr = IDirectDrawSurface4_Blt(dst_surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
649
ok(hr == DDERR_NOCLIPLIST, "Got unexpected hr %#x.\n", hr);
651
IDirectDrawSurface4_Release(dst_surface);
652
IDirectDrawSurface4_Release(src_surface);
653
IDirectDrawClipper_Release(clipper);
654
IDirectDraw4_Release(ddraw);
659
test_process_vertices();
660
test_coop_level_create_device_window();