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"
22 static BOOL
compare_color(D3DCOLOR c1
, D3DCOLOR c2
, BYTE max_diff
)
24 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
26 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
28 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
30 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
34 static D3DCOLOR
get_surface_color(IDirectDrawSurface
*surface
, UINT x
, UINT y
)
36 RECT rect
= {x
, y
, x
+ 1, y
+ 1};
37 DDSURFACEDESC surface_desc
;
41 memset(&surface_desc
, 0, sizeof(surface_desc
));
42 surface_desc
.dwSize
= sizeof(surface_desc
);
44 hr
= IDirectDrawSurface_Lock(surface
, &rect
, &surface_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
45 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
49 color
= *((DWORD
*)surface_desc
.lpSurface
) & 0x00ffffff;
51 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
52 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
57 static HRESULT CALLBACK
enum_z_fmt(GUID
*guid
, char *description
, char *name
,
58 D3DDEVICEDESC
*hal_desc
, D3DDEVICEDESC
*hel_desc
, void *ctx
)
62 if (!IsEqualGUID(&IID_IDirect3DHALDevice
, guid
))
65 if (hal_desc
->dwDeviceZBufferBitDepth
& DDBD_32
)
67 else if (hal_desc
->dwDeviceZBufferBitDepth
& DDBD_24
)
69 else if (hal_desc
->dwDeviceZBufferBitDepth
& DDBD_16
)
75 static IDirectDraw2
*create_ddraw(void)
81 if (FAILED(DirectDrawCreate(NULL
, &ddraw1
, NULL
)))
84 hr
= IDirectDraw_QueryInterface(ddraw1
, &IID_IDirectDraw2
, (void **)&ddraw2
);
85 IDirectDraw_Release(ddraw1
);
92 static IDirect3DDevice2
*create_device(IDirectDraw2
*ddraw
, HWND window
, DWORD coop_level
)
94 IDirectDrawSurface
*surface
, *ds
;
95 IDirect3DDevice2
*device
= NULL
;
96 DDSURFACEDESC surface_desc
;
101 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, coop_level
);
102 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
104 memset(&surface_desc
, 0, sizeof(surface_desc
));
105 surface_desc
.dwSize
= sizeof(surface_desc
);
106 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
107 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
108 surface_desc
.dwWidth
= 640;
109 surface_desc
.dwHeight
= 480;
111 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
112 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
114 if (coop_level
& DDSCL_NORMAL
)
116 IDirectDrawClipper
*clipper
;
118 hr
= IDirectDraw2_CreateClipper(ddraw
, 0, &clipper
, NULL
);
119 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
120 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
121 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
122 hr
= IDirectDrawSurface_SetClipper(surface
, clipper
);
123 ok(SUCCEEDED(hr
), "Failed to set surface clipper, hr %#x.\n", hr
);
124 IDirectDrawClipper_Release(clipper
);
127 hr
= IDirectDraw2_QueryInterface(ddraw
, &IID_IDirect3D2
, (void **)&d3d
);
130 IDirectDrawSurface_Release(surface
);
134 hr
= IDirect3D2_EnumDevices(d3d
, enum_z_fmt
, &z_depth
);
135 ok(SUCCEEDED(hr
), "Failed to enumerate z-formats, hr %#x.\n", hr
);
136 if (FAILED(hr
) || !z_depth
)
138 IDirect3D2_Release(d3d
);
139 IDirectDrawSurface_Release(surface
);
143 memset(&surface_desc
, 0, sizeof(surface_desc
));
144 surface_desc
.dwSize
= sizeof(surface_desc
);
145 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_ZBUFFERBITDEPTH
| DDSD_WIDTH
| DDSD_HEIGHT
;
146 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
147 surface_desc
.dwZBufferBitDepth
= z_depth
;
148 surface_desc
.dwWidth
= 640;
149 surface_desc
.dwHeight
= 480;
150 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
151 ok(SUCCEEDED(hr
), "Failed to create depth buffer, hr %#x.\n", hr
);
154 IDirect3D2_Release(d3d
);
155 IDirectDrawSurface_Release(surface
);
159 hr
= IDirectDrawSurface_AddAttachedSurface(surface
, ds
);
160 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x.\n", hr
);
161 IDirectDrawSurface_Release(ds
);
164 IDirect3D2_Release(d3d
);
165 IDirectDrawSurface_Release(surface
);
169 hr
= IDirect3D2_CreateDevice(d3d
, &IID_IDirect3DHALDevice
, surface
, &device
);
170 IDirect3D2_Release(d3d
);
171 IDirectDrawSurface_Release(surface
);
178 static HRESULT CALLBACK
restore_callback(IDirectDrawSurface
*surface
, DDSURFACEDESC
*desc
, void *context
)
180 HRESULT hr
= IDirectDrawSurface_Restore(surface
);
181 ok(SUCCEEDED(hr
), "Failed to restore surface, hr %#x.\n", hr
);
182 IDirectDrawSurface_Release(surface
);
187 static HRESULT
restore_surfaces(IDirectDraw2
*ddraw
)
189 return IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_ALL
| DDENUMSURFACES_DOESEXIST
,
190 NULL
, NULL
, restore_callback
);
193 static void test_coop_level_create_device_window(void)
195 HWND focus_window
, device_window
;
199 focus_window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
200 0, 0, 640, 480, 0, 0, 0, 0);
201 if (!(ddraw
= create_ddraw()))
203 skip("Failed to create a ddraw object, skipping test.\n");
204 DestroyWindow(focus_window
);
208 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
209 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
210 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
211 ok(!device_window
, "Unexpected device window found.\n");
212 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
);
213 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
214 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
215 ok(!device_window
, "Unexpected device window found.\n");
216 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_NORMAL
);
217 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
218 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
219 ok(!device_window
, "Unexpected device window found.\n");
220 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
221 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
222 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
223 ok(!device_window
, "Unexpected device window found.\n");
224 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
225 ok(hr
== DDERR_NOFOCUSWINDOW
|| broken(hr
== DDERR_INVALIDPARAMS
), "Got unexpected hr %#x.\n", hr
);
226 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
227 ok(!device_window
, "Unexpected device window found.\n");
229 /* Windows versions before 98 / NT5 don't support DDSCL_CREATEDEVICEWINDOW. */
230 if (broken(hr
== DDERR_INVALIDPARAMS
))
232 win_skip("DDSCL_CREATEDEVICEWINDOW not supported, skipping test.\n");
233 IDirectDraw2_Release(ddraw
);
234 DestroyWindow(focus_window
);
238 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
239 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
240 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
241 ok(!device_window
, "Unexpected device window found.\n");
242 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
243 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
244 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
245 ok(!device_window
, "Unexpected device window found.\n");
247 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
248 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
249 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
250 ok(!device_window
, "Unexpected device window found.\n");
251 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_SETFOCUSWINDOW
252 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
253 ok(hr
== DDERR_NOHWND
, "Got unexpected hr %#x.\n", hr
);
254 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
255 ok(!!device_window
, "Device window not found.\n");
257 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
258 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
259 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
260 ok(!device_window
, "Unexpected device window found.\n");
261 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
262 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
263 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
264 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
265 ok(!!device_window
, "Device window not found.\n");
267 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
268 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
269 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
270 ok(!device_window
, "Unexpected device window found.\n");
271 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
272 ok(hr
== DDERR_NOFOCUSWINDOW
, "Got unexpected hr %#x.\n", hr
);
273 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
274 ok(!device_window
, "Unexpected device window found.\n");
275 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
);
276 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
277 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
278 ok(!device_window
, "Unexpected device window found.\n");
279 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
280 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
281 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
282 ok(!!device_window
, "Device window not found.\n");
284 IDirectDraw2_Release(ddraw
);
285 DestroyWindow(focus_window
);
288 static void test_clipper_blt(void)
290 IDirectDrawSurface
*src_surface
, *dst_surface
;
291 RECT client_rect
, src_rect
, *rect
;
292 IDirectDrawClipper
*clipper
;
293 DDSURFACEDESC surface_desc
;
294 unsigned int i
, j
, x
, y
;
305 static const DWORD src_data
[] =
307 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
308 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
309 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
311 static const D3DCOLOR expected1
[] =
313 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
314 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
315 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
316 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
318 static const D3DCOLOR expected2
[] =
320 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
321 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
322 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
323 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
326 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
327 10, 10, 640, 480, 0, 0, 0, 0);
328 ShowWindow(window
, SW_SHOW
);
329 if (!(ddraw
= create_ddraw()))
331 skip("Failed to create a ddraw object, skipping test.\n");
332 DestroyWindow(window
);
336 ret
= GetClientRect(window
, &client_rect
);
337 ok(ret
, "Failed to get client rect.\n");
338 ret
= MapWindowPoints(window
, NULL
, (POINT
*)&client_rect
, 2);
339 ok(ret
, "Failed to map client rect.\n");
341 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
342 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
344 hr
= IDirectDraw2_CreateClipper(ddraw
, 0, &clipper
, NULL
);
345 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
346 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
347 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
348 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
349 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
350 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
351 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
352 rgn_data
= HeapAlloc(GetProcessHeap(), 0, ret
);
353 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, rgn_data
, &ret
);
354 ok(SUCCEEDED(hr
), "Failed to get clip list, hr %#x.\n", hr
);
355 ok(rgn_data
->rdh
.dwSize
== sizeof(rgn_data
->rdh
), "Got unexpected structure size %#x.\n", rgn_data
->rdh
.dwSize
);
356 ok(rgn_data
->rdh
.iType
== RDH_RECTANGLES
, "Got unexpected type %#x.\n", rgn_data
->rdh
.iType
);
357 ok(rgn_data
->rdh
.nCount
== 1, "Got unexpected count %u.\n", rgn_data
->rdh
.nCount
);
358 ok(rgn_data
->rdh
.nRgnSize
== 16 || broken(rgn_data
->rdh
.nRgnSize
== 168 /* NT4 */),
359 "Got unexpected region size %u.\n", rgn_data
->rdh
.nRgnSize
);
360 ok(EqualRect(&rgn_data
->rdh
.rcBound
, &client_rect
),
361 "Got unexpected bounding rect {%d, %d, %d, %d}, expected {%d, %d, %d, %d}.\n",
362 rgn_data
->rdh
.rcBound
.left
, rgn_data
->rdh
.rcBound
.top
,
363 rgn_data
->rdh
.rcBound
.right
, rgn_data
->rdh
.rcBound
.bottom
,
364 client_rect
.left
, client_rect
.top
, client_rect
.right
, client_rect
.bottom
);
365 rect
= (RECT
*)&rgn_data
->Buffer
[0];
366 ok(EqualRect(rect
, &client_rect
),
367 "Got unexpected clip rect {%d, %d, %d, %d}, expected {%d, %d, %d, %d}.\n",
368 rect
->left
, rect
->top
, rect
->right
, rect
->bottom
,
369 client_rect
.left
, client_rect
.top
, client_rect
.right
, client_rect
.bottom
);
370 HeapFree(GetProcessHeap(), 0, rgn_data
);
372 r1
= CreateRectRgn(0, 0, 320, 240);
373 ok(!!r1
, "Failed to create region.\n");
374 r2
= CreateRectRgn(320, 240, 640, 480);
375 ok(!!r2
, "Failed to create region.\n");
376 CombineRgn(r1
, r1
, r2
, RGN_OR
);
377 ret
= GetRegionData(r1
, 0, NULL
);
378 rgn_data
= HeapAlloc(GetProcessHeap(), 0, ret
);
379 ret
= GetRegionData(r1
, ret
, rgn_data
);
380 ok(!!ret
, "Failed to get region data.\n");
385 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
386 ok(hr
== DDERR_CLIPPERISUSINGHWND
, "Got unexpected hr %#x.\n", hr
);
387 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
388 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
389 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
390 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#x.\n", hr
);
392 HeapFree(GetProcessHeap(), 0, rgn_data
);
394 memset(&surface_desc
, 0, sizeof(surface_desc
));
395 surface_desc
.dwSize
= sizeof(surface_desc
);
396 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
397 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
398 surface_desc
.dwWidth
= 640;
399 surface_desc
.dwHeight
= 480;
400 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
401 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
402 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
403 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
404 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
405 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
407 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &src_surface
, NULL
);
408 ok(SUCCEEDED(hr
), "Failed to create source surface, hr %#x.\n", hr
);
409 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &dst_surface
, NULL
);
410 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#x.\n", hr
);
412 memset(&fx
, 0, sizeof(fx
));
413 fx
.dwSize
= sizeof(fx
);
414 hr
= IDirectDrawSurface_Blt(src_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
415 ok(SUCCEEDED(hr
), "Failed to clear source surface, hr %#x.\n", hr
);
416 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
417 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#x.\n", hr
);
419 hr
= IDirectDrawSurface_Lock(src_surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
420 ok(SUCCEEDED(hr
), "Failed to lock source surface, hr %#x.\n", hr
);
421 ok(surface_desc
.lPitch
== 2560, "Got unexpected surface pitch %u.\n", surface_desc
.lPitch
);
422 ptr
= surface_desc
.lpSurface
;
423 memcpy(&ptr
[ 0], &src_data
[ 0], 6 * sizeof(DWORD
));
424 memcpy(&ptr
[ 640], &src_data
[ 6], 6 * sizeof(DWORD
));
425 memcpy(&ptr
[1280], &src_data
[12], 6 * sizeof(DWORD
));
426 hr
= IDirectDrawSurface_Unlock(src_surface
, NULL
);
427 ok(SUCCEEDED(hr
), "Failed to unlock source surface, hr %#x.\n", hr
);
429 hr
= IDirectDrawSurface_SetClipper(dst_surface
, clipper
);
430 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
432 SetRect(&src_rect
, 1, 1, 5, 2);
433 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, src_surface
, &src_rect
, DDBLT_WAIT
, NULL
);
434 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
435 for (i
= 0; i
< 4; ++i
)
437 for (j
= 0; j
< 4; ++j
)
439 x
= 80 * ((2 * j
) + 1);
440 y
= 60 * ((2 * i
) + 1);
441 color
= get_surface_color(dst_surface
, x
, y
);
442 ok(compare_color(color
, expected1
[i
* 4 + j
], 1),
443 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected1
[i
* 4 + j
], x
, y
, color
);
447 U5(fx
).dwFillColor
= 0xff0000ff;
448 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
449 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#x.\n", hr
);
450 for (i
= 0; i
< 4; ++i
)
452 for (j
= 0; j
< 4; ++j
)
454 x
= 80 * ((2 * j
) + 1);
455 y
= 60 * ((2 * i
) + 1);
456 color
= get_surface_color(dst_surface
, x
, y
);
457 ok(compare_color(color
, expected2
[i
* 4 + j
], 1),
458 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected2
[i
* 4 + j
], x
, y
, color
);
462 hr
= IDirectDrawSurface_BltFast(dst_surface
, 0, 0, src_surface
, NULL
, DDBLTFAST_WAIT
);
463 ok(hr
== DDERR_BLTFASTCANTCLIP
|| broken(hr
== E_NOTIMPL
/* NT4 */), "Got unexpected hr %#x.\n", hr
);
465 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
466 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
467 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
468 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
469 DestroyWindow(window
);
470 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
471 ok(hr
== E_FAIL
, "Got unexpected hr %#x.\n", hr
);
472 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
473 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
474 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
475 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
476 hr
= IDirectDrawClipper_SetClipList(clipper
, NULL
, 0);
477 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#x.\n", hr
);
478 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
479 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
480 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
481 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
483 IDirectDrawSurface_Release(dst_surface
);
484 IDirectDrawSurface_Release(src_surface
);
485 IDirectDrawClipper_Release(clipper
);
486 IDirectDraw2_Release(ddraw
);
489 static void test_coop_level_d3d_state(void)
491 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
492 D3DMATERIALHANDLE background_handle
;
493 IDirectDrawSurface
*rt
, *surface
;
494 IDirect3DMaterial2
*background
;
495 IDirect3DViewport2
*viewport
;
496 IDirect3DDevice2
*device
;
497 D3DMATERIAL material
;
506 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
507 0, 0, 640, 480, 0, 0, 0, 0);
508 if (!(ddraw
= create_ddraw()))
510 skip("Failed to create ddraw object, skipping test.\n");
511 DestroyWindow(window
);
514 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
516 skip("Failed to create D3D device, skipping test.\n");
517 IDirectDraw2_Release(ddraw
);
518 DestroyWindow(window
);
522 hr
= IDirect3DDevice2_GetDirect3D(device
, &d3d
);
523 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
524 hr
= IDirect3D2_CreateViewport(d3d
, &viewport
, NULL
);
525 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#x.\n", hr
);
526 hr
= IDirect3D2_CreateMaterial(d3d
, &background
, NULL
);
527 ok(SUCCEEDED(hr
), "Failed to create material, hr %#x.\n", hr
);
528 IDirect3D2_Release(d3d
);
530 hr
= IDirect3DDevice2_AddViewport(device
, viewport
);
531 ok(SUCCEEDED(hr
), "Failed to add viewport, hr %#x.\n", hr
);
532 memset(&vp
, 0, sizeof(vp
));
533 vp
.dwSize
= sizeof(vp
);
540 vp
.dvClipWidth
= 2.0f
;
541 vp
.dvClipHeight
= 2.0f
;
544 hr
= IDirect3DViewport2_SetViewport2(viewport
, &vp
);
545 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
547 memset(&material
, 0, sizeof(material
));
548 material
.dwSize
= sizeof(material
);
549 U1(U(material
).diffuse
).r
= 1.0f
;
550 U2(U(material
).diffuse
).g
= 0.0f
;
551 U3(U(material
).diffuse
).b
= 0.0f
;
552 U4(U(material
).diffuse
).a
= 1.0f
;
553 hr
= IDirect3DMaterial2_SetMaterial(background
, &material
);
554 ok(SUCCEEDED(hr
), "Failed to set material data, hr %#x.\n", hr
);
555 hr
= IDirect3DMaterial2_GetHandle(background
, device
, &background_handle
);
556 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#x.\n", hr
);
557 hr
= IDirect3DViewport2_SetBackground(viewport
, background_handle
);
558 ok(SUCCEEDED(hr
), "Failed to set viewport background, hr %#x.\n", hr
);
560 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
561 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
562 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_ZENABLE
, &value
);
563 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
564 ok(!!value
, "Got unexpected z-enable state %#x.\n", value
);
565 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, &value
);
566 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
567 ok(!value
, "Got unexpected alpha blend enable state %#x.\n", value
);
568 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
569 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
570 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
571 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
572 color
= get_surface_color(rt
, 320, 240);
573 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
575 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
576 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
577 hr
= IDirectDrawSurface_IsLost(rt
);
578 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
579 hr
= restore_surfaces(ddraw
);
580 ok(SUCCEEDED(hr
), "Failed to restore surfaces, hr %#x.\n", hr
);
582 memset(&material
, 0, sizeof(material
));
583 material
.dwSize
= sizeof(material
);
584 U1(U(material
).diffuse
).r
= 0.0f
;
585 U2(U(material
).diffuse
).g
= 1.0f
;
586 U3(U(material
).diffuse
).b
= 0.0f
;
587 U4(U(material
).diffuse
).a
= 1.0f
;
588 hr
= IDirect3DMaterial2_SetMaterial(background
, &material
);
589 ok(SUCCEEDED(hr
), "Failed to set material data, hr %#x.\n", hr
);
591 hr
= IDirect3DDevice2_GetRenderTarget(device
, &surface
);
592 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
593 ok(surface
== rt
, "Got unexpected surface %p.\n", surface
);
594 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_ZENABLE
, &value
);
595 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
596 todo_wine
ok(!!value
, "Got unexpected z-enable state %#x.\n", value
);
597 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, &value
);
598 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
599 todo_wine
ok(!!value
, "Got unexpected alpha blend enable state %#x.\n", value
);
600 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
601 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
602 color
= get_surface_color(rt
, 320, 240);
603 todo_wine
ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
605 hr
= IDirect3DDevice2_DeleteViewport(device
, viewport
);
606 ok(SUCCEEDED(hr
), "Failed to delete viewport, hr %#x.\n", hr
);
607 IDirect3DMaterial2_Release(background
);
608 IDirect3DViewport2_Release(viewport
);
609 IDirectDrawSurface_Release(surface
);
610 IDirectDrawSurface_Release(rt
);
611 IDirect3DDevice2_Release(device
);
612 IDirectDraw2_Release(ddraw
);
613 DestroyWindow(window
);
618 test_coop_level_create_device_window();
620 test_coop_level_d3d_state();