2 * Copyright 2006, 2012-2013 Stefan Dösinger for CodeWeavers
3 * Copyright 2011 Henri Verbeet for CodeWeavers
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "wine/test.h"
25 static HRESULT (WINAPI
*pDirectDrawCreateEx
)(GUID
*guid
, void **ddraw
, REFIID iid
, IUnknown
*outer_unknown
);
42 struct create_window_thread_param
45 HANDLE window_created
;
46 HANDLE destroy_window
;
50 static BOOL
compare_float(float f
, float g
, unsigned int ulps
)
60 if (abs(x
- y
) > ulps
)
66 static BOOL
compare_vec3(struct vec3
*vec
, float x
, float y
, float z
, unsigned int ulps
)
68 return compare_float(vec
->x
, x
, ulps
)
69 && compare_float(vec
->y
, y
, ulps
)
70 && compare_float(vec
->z
, z
, ulps
);
73 static BOOL
compare_vec4(struct vec4
*vec
, float x
, float y
, float z
, float w
, unsigned int ulps
)
75 return compare_float(vec
->x
, x
, ulps
)
76 && compare_float(vec
->y
, y
, ulps
)
77 && compare_float(vec
->z
, z
, ulps
)
78 && compare_float(vec
->w
, w
, ulps
);
81 static BOOL
compare_color(D3DCOLOR c1
, D3DCOLOR c2
, BYTE max_diff
)
83 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
85 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
87 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
89 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
93 static DWORD WINAPI
create_window_thread_proc(void *param
)
95 struct create_window_thread_param
*p
= param
;
99 p
->window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
100 0, 0, 640, 480, 0, 0, 0, 0);
101 ret
= SetEvent(p
->window_created
);
102 ok(ret
, "SetEvent failed, last error %#x.\n", GetLastError());
108 while (PeekMessage(&msg
, 0, 0, 0, PM_REMOVE
))
109 DispatchMessage(&msg
);
110 res
= WaitForSingleObject(p
->destroy_window
, 100);
111 if (res
== WAIT_OBJECT_0
)
113 if (res
!= WAIT_TIMEOUT
)
115 ok(0, "Wait failed (%#x), last error %#x.\n", res
, GetLastError());
120 DestroyWindow(p
->window
);
125 static void create_window_thread(struct create_window_thread_param
*p
)
129 p
->window_created
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
130 ok(!!p
->window_created
, "CreateEvent failed, last error %#x.\n", GetLastError());
131 p
->destroy_window
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
132 ok(!!p
->destroy_window
, "CreateEvent failed, last error %#x.\n", GetLastError());
133 p
->thread
= CreateThread(NULL
, 0, create_window_thread_proc
, p
, 0, &tid
);
134 ok(!!p
->thread
, "Failed to create thread, last error %#x.\n", GetLastError());
135 res
= WaitForSingleObject(p
->window_created
, INFINITE
);
136 ok(res
== WAIT_OBJECT_0
, "Wait failed (%#x), last error %#x.\n", res
, GetLastError());
139 static void destroy_window_thread(struct create_window_thread_param
*p
)
141 SetEvent(p
->destroy_window
);
142 WaitForSingleObject(p
->thread
, INFINITE
);
143 CloseHandle(p
->destroy_window
);
144 CloseHandle(p
->window_created
);
145 CloseHandle(p
->thread
);
148 static IDirectDrawSurface7
*get_depth_stencil(IDirect3DDevice7
*device
)
150 IDirectDrawSurface7
*rt
, *ret
;
151 DDSCAPS2 caps
= {DDSCAPS_ZBUFFER
, 0, 0, 0};
154 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
155 ok(SUCCEEDED(hr
), "Failed to get the render target, hr %#x.\n", hr
);
156 hr
= IDirectDrawSurface7_GetAttachedSurface(rt
, &caps
, &ret
);
157 ok(SUCCEEDED(hr
) || hr
== DDERR_NOTFOUND
, "Failed to get the z buffer, hr %#x.\n", hr
);
158 IDirectDrawSurface7_Release(rt
);
162 static D3DCOLOR
get_surface_color(IDirectDrawSurface7
*surface
, UINT x
, UINT y
)
164 RECT rect
= {x
, y
, x
+ 1, y
+ 1};
165 DDSURFACEDESC2 surface_desc
;
169 memset(&surface_desc
, 0, sizeof(surface_desc
));
170 surface_desc
.dwSize
= sizeof(surface_desc
);
172 hr
= IDirectDrawSurface7_Lock(surface
, &rect
, &surface_desc
, DDLOCK_READONLY
, NULL
);
173 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
177 color
= *((DWORD
*)surface_desc
.lpSurface
) & 0x00ffffff;
179 hr
= IDirectDrawSurface7_Unlock(surface
, &rect
);
180 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
185 static HRESULT CALLBACK
enum_z_fmt(DDPIXELFORMAT
*format
, void *ctx
)
187 DDPIXELFORMAT
*z_fmt
= ctx
;
189 if (U1(*format
).dwZBufferBitDepth
> U1(*z_fmt
).dwZBufferBitDepth
)
195 static IDirectDraw7
*create_ddraw(void)
199 if (FAILED(pDirectDrawCreateEx(NULL
, (void **)&ddraw
, &IID_IDirectDraw7
, NULL
)))
205 static HRESULT WINAPI
enum_devtype_cb(char *desc_str
, char *name
, D3DDEVICEDESC7
*desc
, void *ctx
)
208 if (IsEqualGUID(&desc
->deviceGUID
, &IID_IDirect3DTnLHalDevice
))
211 return DDENUMRET_CANCEL
;
216 static IDirect3DDevice7
*create_device(HWND window
, DWORD coop_level
)
218 IDirectDrawSurface7
*surface
, *ds
;
219 IDirect3DDevice7
*device
= NULL
;
220 DDSURFACEDESC2 surface_desc
;
226 const GUID
*devtype
= &IID_IDirect3DHALDevice
;
228 if (!(ddraw
= create_ddraw()))
231 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, coop_level
);
232 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
234 memset(&surface_desc
, 0, sizeof(surface_desc
));
235 surface_desc
.dwSize
= sizeof(surface_desc
);
236 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
237 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
238 surface_desc
.dwWidth
= 640;
239 surface_desc
.dwHeight
= 480;
241 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
242 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
244 if (coop_level
& DDSCL_NORMAL
)
246 IDirectDrawClipper
*clipper
;
248 hr
= IDirectDraw7_CreateClipper(ddraw
, 0, &clipper
, NULL
);
249 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
250 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
251 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
252 hr
= IDirectDrawSurface7_SetClipper(surface
, clipper
);
253 ok(SUCCEEDED(hr
), "Failed to set surface clipper, hr %#x.\n", hr
);
254 IDirectDrawClipper_Release(clipper
);
257 hr
= IDirectDraw7_QueryInterface(ddraw
, &IID_IDirect3D7
, (void **)&d3d7
);
258 IDirectDraw7_Release(ddraw
);
261 IDirectDrawSurface7_Release(surface
);
265 hr
= IDirect3D7_EnumDevices(d3d7
, enum_devtype_cb
, &hal_ok
);
266 ok(SUCCEEDED(hr
), "Failed to enumerate devices, hr %#x.\n", hr
);
267 if (hal_ok
) devtype
= &IID_IDirect3DTnLHalDevice
;
269 memset(&z_fmt
, 0, sizeof(z_fmt
));
270 hr
= IDirect3D7_EnumZBufferFormats(d3d7
, devtype
, enum_z_fmt
, &z_fmt
);
271 if (FAILED(hr
) || !z_fmt
.dwSize
)
273 IDirect3D7_Release(d3d7
);
274 IDirectDrawSurface7_Release(surface
);
278 memset(&surface_desc
, 0, sizeof(surface_desc
));
279 surface_desc
.dwSize
= sizeof(surface_desc
);
280 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
281 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
282 U4(surface_desc
).ddpfPixelFormat
= z_fmt
;
283 surface_desc
.dwWidth
= 640;
284 surface_desc
.dwHeight
= 480;
285 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
286 ok(SUCCEEDED(hr
), "Failed to create depth buffer, hr %#x.\n", hr
);
289 IDirect3D7_Release(d3d7
);
290 IDirectDrawSurface7_Release(surface
);
294 hr
= IDirectDrawSurface_AddAttachedSurface(surface
, ds
);
295 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x.\n", hr
);
296 IDirectDrawSurface7_Release(ds
);
299 IDirect3D7_Release(d3d7
);
300 IDirectDrawSurface7_Release(surface
);
304 hr
= IDirect3D7_CreateDevice(d3d7
, devtype
, surface
, &device
);
305 IDirect3D7_Release(d3d7
);
306 IDirectDrawSurface7_Release(surface
);
313 static const UINT
*expect_messages
;
315 static LRESULT CALLBACK
test_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
317 if (expect_messages
&& message
== *expect_messages
)
320 return DefWindowProcA(hwnd
, message
, wparam
, lparam
);
323 /* Set the wndproc back to what ddraw expects it to be, and release the ddraw
324 * interface. This prevents subsequent SetCooperativeLevel() calls on a
325 * different window from failing with DDERR_HWNDALREADYSET. */
326 static void fix_wndproc(HWND window
, LONG_PTR proc
)
331 if (!(ddraw
= create_ddraw()))
334 SetWindowLongPtrA(window
, GWLP_WNDPROC
, proc
);
335 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
336 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
337 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
338 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
340 IDirectDraw7_Release(ddraw
);
343 static void test_process_vertices(void)
345 IDirect3DVertexBuffer7
*src_vb
, *dst_vb1
, *dst_vb2
;
346 D3DVERTEXBUFFERDESC vb_desc
;
347 IDirect3DDevice7
*device
;
348 struct vec4
*dst_data
;
349 struct vec3
*dst_data2
;
350 struct vec3
*src_data
;
356 static D3DMATRIX world
=
358 0.0f
, 1.0f
, 0.0f
, 0.0f
,
359 1.0f
, 0.0f
, 0.0f
, 0.0f
,
360 0.0f
, 0.0f
, 0.0f
, 1.0f
,
361 0.0f
, 1.0f
, 1.0f
, 1.0f
,
363 static D3DMATRIX view
=
365 2.0f
, 0.0f
, 0.0f
, 0.0f
,
366 0.0f
, -1.0f
, 0.0f
, 0.0f
,
367 0.0f
, 0.0f
, 1.0f
, 0.0f
,
368 0.0f
, 0.0f
, 0.0f
, 3.0f
,
370 static D3DMATRIX proj
=
372 1.0f
, 0.0f
, 0.0f
, 1.0f
,
373 0.0f
, 1.0f
, 1.0f
, 0.0f
,
374 0.0f
, 1.0f
, 1.0f
, 0.0f
,
375 1.0f
, 0.0f
, 0.0f
, 1.0f
,
378 window
= CreateWindowA("static", "d3d7_test", WS_OVERLAPPEDWINDOW
,
379 0, 0, 640, 480, 0, 0, 0, 0);
380 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
382 skip("Failed to create a ddraw object, skipping test.\n");
383 DestroyWindow(window
);
387 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d7
);
388 ok(SUCCEEDED(hr
), "Failed to get Direct3D7 interface, hr %#x.\n", hr
);
390 memset(&vb_desc
, 0, sizeof(vb_desc
));
391 vb_desc
.dwSize
= sizeof(vb_desc
);
392 vb_desc
.dwFVF
= D3DFVF_XYZ
;
393 vb_desc
.dwNumVertices
= 4;
394 hr
= IDirect3D7_CreateVertexBuffer(d3d7
, &vb_desc
, &src_vb
, 0);
395 ok(SUCCEEDED(hr
), "Failed to create source vertex buffer, hr %#x.\n", hr
);
397 hr
= IDirect3DVertexBuffer7_Lock(src_vb
, 0, (void **)&src_data
, NULL
);
398 ok(SUCCEEDED(hr
), "Failed to lock source vertex buffer, hr %#x.\n", hr
);
399 src_data
[0].x
= 0.0f
;
400 src_data
[0].y
= 0.0f
;
401 src_data
[0].z
= 0.0f
;
402 src_data
[1].x
= 1.0f
;
403 src_data
[1].y
= 1.0f
;
404 src_data
[1].z
= 1.0f
;
405 src_data
[2].x
= -1.0f
;
406 src_data
[2].y
= -1.0f
;
407 src_data
[2].z
= 0.5f
;
408 src_data
[3].x
= 0.5f
;
409 src_data
[3].y
= -0.5f
;
410 src_data
[3].z
= 0.25f
;
411 hr
= IDirect3DVertexBuffer7_Unlock(src_vb
);
412 ok(SUCCEEDED(hr
), "Failed to unlock source vertex buffer, hr %#x.\n", hr
);
414 memset(&vb_desc
, 0, sizeof(vb_desc
));
415 vb_desc
.dwSize
= sizeof(vb_desc
);
416 vb_desc
.dwFVF
= D3DFVF_XYZRHW
;
417 vb_desc
.dwNumVertices
= 4;
418 /* MSDN says that the last parameter must be 0 - check that. */
419 hr
= IDirect3D7_CreateVertexBuffer(d3d7
, &vb_desc
, &dst_vb1
, 4);
420 ok(SUCCEEDED(hr
), "Failed to create vertex buffer, hr %#x.\n", hr
);
422 memset(&vb_desc
, 0, sizeof(vb_desc
));
423 vb_desc
.dwSize
= sizeof(vb_desc
);
424 vb_desc
.dwFVF
= D3DFVF_XYZ
;
425 vb_desc
.dwNumVertices
= 5;
426 /* MSDN says that the last parameter must be 0 - check that. */
427 hr
= IDirect3D7_CreateVertexBuffer(d3d7
, &vb_desc
, &dst_vb2
, 12345678);
428 ok(SUCCEEDED(hr
), "Failed to create vertex buffer, hr %#x.\n", hr
);
430 memset(&vp
, 0, sizeof(vp
));
437 hr
= IDirect3DDevice7_SetViewport(device
, &vp
);
438 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
440 hr
= IDirect3DVertexBuffer7_ProcessVertices(dst_vb1
, D3DVOP_TRANSFORM
, 0, 4, src_vb
, 0, device
, 0);
441 ok(SUCCEEDED(hr
), "Failed to process vertices, hr %#x.\n", hr
);
442 hr
= IDirect3DVertexBuffer7_ProcessVertices(dst_vb2
, D3DVOP_TRANSFORM
, 0, 4, src_vb
, 0, device
, 0);
443 ok(SUCCEEDED(hr
), "Failed to process vertices, hr %#x.\n", hr
);
445 hr
= IDirect3DVertexBuffer7_Lock(dst_vb1
, 0, (void **)&dst_data
, NULL
);
446 ok(SUCCEEDED(hr
), "Failed to lock destination vertex buffer, hr %#x.\n", hr
);
447 ok(compare_vec4(&dst_data
[0], +1.280e+2f
, +1.280e+2f
, +0.000e+0f
, +1.000e+0f
, 4096),
448 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
449 dst_data
[0].x
, dst_data
[0].y
, dst_data
[0].z
, dst_data
[0].w
);
450 ok(compare_vec4(&dst_data
[1], +1.920e+2f
, +6.400e+1f
, +1.000e+0f
, +1.000e+0f
, 4096),
451 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
452 dst_data
[1].x
, dst_data
[1].y
, dst_data
[1].z
, dst_data
[1].w
);
453 ok(compare_vec4(&dst_data
[2], +6.400e+1f
, +1.920e+2f
, +5.000e-1f
, +1.000e+0f
, 4096),
454 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
455 dst_data
[2].x
, dst_data
[2].y
, dst_data
[2].z
, dst_data
[2].w
);
456 ok(compare_vec4(&dst_data
[3], +1.600e+2f
, +1.600e+2f
, +2.500e-1f
, +1.000e+0f
, 4096),
457 "Got unexpected vertex 3 {%.8e, %.8e, %.8e, %.8e}.\n",
458 dst_data
[3].x
, dst_data
[3].y
, dst_data
[3].z
, dst_data
[3].w
);
459 hr
= IDirect3DVertexBuffer7_Unlock(dst_vb1
);
460 ok(SUCCEEDED(hr
), "Failed to unlock destination vertex buffer, hr %#x.\n", hr
);
462 hr
= IDirect3DVertexBuffer7_Lock(dst_vb2
, 0, (void **)&dst_data2
, NULL
);
463 ok(SUCCEEDED(hr
), "Failed to lock destination vertex buffer, hr %#x.\n", hr
);
464 /* Small thing without much practical meaning, but I stumbled upon it,
465 * so let's check for it: If the output vertex buffer has no RHW value,
466 * the RHW value of the last vertex is written into the next vertex. */
467 ok(compare_vec3(&dst_data2
[4], +1.000e+0f
, +0.000e+0f
, +0.000e+0f
, 4096),
468 "Got unexpected vertex 4 {%.8e, %.8e, %.8e}.\n",
469 dst_data2
[4].x
, dst_data2
[4].y
, dst_data2
[4].z
);
470 hr
= IDirect3DVertexBuffer7_Unlock(dst_vb2
);
471 ok(SUCCEEDED(hr
), "Failed to unlock destination vertex buffer, hr %#x.\n", hr
);
473 /* Try a more complicated viewport, same vertices. */
474 memset(&vp
, 0, sizeof(vp
));
481 hr
= IDirect3DDevice7_SetViewport(device
, &vp
);
482 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
484 hr
= IDirect3DVertexBuffer7_ProcessVertices(dst_vb1
, D3DVOP_TRANSFORM
, 0, 4, src_vb
, 0, device
, 0);
485 ok(SUCCEEDED(hr
), "Failed to process vertices, hr %#x.\n", hr
);
487 hr
= IDirect3DVertexBuffer7_Lock(dst_vb1
, 0, (void **)&dst_data
, NULL
);
488 ok(SUCCEEDED(hr
), "Failed to lock destination vertex buffer, hr %#x.\n", hr
);
489 ok(compare_vec4(&dst_data
[0], +1.330e+2f
, +7.000e+1f
, -2.000e+0f
, +1.000e+0f
, 4096),
490 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
491 dst_data
[0].x
, dst_data
[0].y
, dst_data
[0].z
, dst_data
[0].w
);
492 ok(compare_vec4(&dst_data
[1], +2.560e+2f
, +5.000e+0f
, +4.000e+0f
, +1.000e+0f
, 4096),
493 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
494 dst_data
[1].x
, dst_data
[1].y
, dst_data
[1].z
, dst_data
[1].w
);
495 ok(compare_vec4(&dst_data
[2], +1.000e+1f
, +1.350e+2f
, +1.000e+0f
, +1.000e+0f
, 4096),
496 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
497 dst_data
[2].x
, dst_data
[2].y
, dst_data
[2].z
, dst_data
[2].w
);
498 ok(compare_vec4(&dst_data
[3], +1.945e+2f
, +1.025e+2f
, -5.000e-1f
, +1.000e+0f
, 4096),
499 "Got unexpected vertex 3 {%.8e, %.8e, %.8e, %.8e}.\n",
500 dst_data
[3].x
, dst_data
[3].y
, dst_data
[3].z
, dst_data
[3].w
);
501 hr
= IDirect3DVertexBuffer7_Unlock(dst_vb1
);
502 ok(SUCCEEDED(hr
), "Failed to unlock destination vertex buffer, hr %#x.\n", hr
);
504 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &world
);
505 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
506 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &view
);
507 ok(SUCCEEDED(hr
), "Failed to set view transform, hr %#x.\n", hr
);
508 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &proj
);
509 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#x.\n", hr
);
511 hr
= IDirect3DVertexBuffer7_ProcessVertices(dst_vb1
, D3DVOP_TRANSFORM
, 0, 4, src_vb
, 0, device
, 0);
512 ok(SUCCEEDED(hr
), "Failed to process vertices, hr %#x.\n", hr
);
514 hr
= IDirect3DVertexBuffer7_Lock(dst_vb1
, 0, (void **)&dst_data
, NULL
);
515 ok(SUCCEEDED(hr
), "Failed to lock destination vertex buffer, hr %#x.\n", hr
);
516 ok(compare_vec4(&dst_data
[0], +2.560e+2f
, +7.000e+1f
, -2.000e+0f
, +3.333e-1f
, 4096),
517 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
518 dst_data
[0].x
, dst_data
[0].y
, dst_data
[0].z
, dst_data
[0].w
);
519 ok(compare_vec4(&dst_data
[1], +2.560e+2f
, +7.813e+1f
, -2.750e+0f
, +1.250e-1f
, 4096),
520 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
521 dst_data
[1].x
, dst_data
[1].y
, dst_data
[1].z
, dst_data
[1].w
);
522 ok(compare_vec4(&dst_data
[2], +2.560e+2f
, +4.400e+1f
, +4.000e-1f
, +4.000e-1f
, 4096),
523 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
524 dst_data
[2].x
, dst_data
[2].y
, dst_data
[2].z
, dst_data
[2].w
);
525 ok(compare_vec4(&dst_data
[3], +2.560e+2f
, +8.182e+1f
, -3.091e+0f
, +3.636e-1f
, 4096),
526 "Got unexpected vertex 3 {%.8e, %.8e, %.8e, %.8e}.\n",
527 dst_data
[3].x
, dst_data
[3].y
, dst_data
[3].z
, dst_data
[3].w
);
528 hr
= IDirect3DVertexBuffer7_Unlock(dst_vb1
);
529 ok(SUCCEEDED(hr
), "Failed to unlock destination vertex buffer, hr %#x.\n", hr
);
531 IDirect3DVertexBuffer7_Release(dst_vb2
);
532 IDirect3DVertexBuffer7_Release(dst_vb1
);
533 IDirect3DVertexBuffer7_Release(src_vb
);
534 IDirect3D7_Release(d3d7
);
535 IDirect3DDevice7_Release(device
);
536 DestroyWindow(window
);
539 static void test_coop_level_create_device_window(void)
541 HWND focus_window
, device_window
;
545 focus_window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
546 0, 0, 640, 480, 0, 0, 0, 0);
547 if (!(ddraw
= create_ddraw()))
549 skip("Failed to create a 3D device, skipping test.\n");
550 DestroyWindow(focus_window
);
554 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
555 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
556 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
557 ok(!device_window
, "Unexpected device window found.\n");
558 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
);
559 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
560 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
561 ok(!device_window
, "Unexpected device window found.\n");
562 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_NORMAL
);
563 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
564 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
565 ok(!device_window
, "Unexpected device window found.\n");
566 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
567 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
568 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
569 ok(!device_window
, "Unexpected device window found.\n");
570 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
571 ok(hr
== DDERR_NOFOCUSWINDOW
|| broken(hr
== DDERR_INVALIDPARAMS
), "Got unexpected hr %#x.\n", hr
);
572 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
573 ok(!device_window
, "Unexpected device window found.\n");
575 /* Windows versions before 98 / NT5 don't support DDSCL_CREATEDEVICEWINDOW. */
576 if (broken(hr
== DDERR_INVALIDPARAMS
))
578 win_skip("DDSCL_CREATEDEVICEWINDOW not supported, skipping test.\n");
579 IDirectDraw7_Release(ddraw
);
580 DestroyWindow(focus_window
);
584 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
585 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
586 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
587 ok(!device_window
, "Unexpected device window found.\n");
588 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
589 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
590 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
591 ok(!device_window
, "Unexpected device window found.\n");
593 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
594 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
595 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
596 ok(!device_window
, "Unexpected device window found.\n");
597 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_SETFOCUSWINDOW
598 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
599 ok(hr
== DDERR_NOHWND
, "Got unexpected hr %#x.\n", hr
);
600 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
601 ok(!!device_window
, "Device window not found.\n");
603 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
604 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
605 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
606 ok(!device_window
, "Unexpected device window found.\n");
607 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
608 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
609 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
610 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
611 ok(!!device_window
, "Device window not found.\n");
613 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
614 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
615 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
616 ok(!device_window
, "Unexpected device window found.\n");
617 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
618 ok(hr
== DDERR_NOFOCUSWINDOW
, "Got unexpected hr %#x.\n", hr
);
619 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
620 ok(!device_window
, "Unexpected device window found.\n");
621 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
);
622 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
623 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
624 ok(!device_window
, "Unexpected device window found.\n");
625 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
626 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
627 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
628 ok(!!device_window
, "Device window not found.\n");
630 IDirectDraw7_Release(ddraw
);
631 DestroyWindow(focus_window
);
634 static void test_clipper_blt(void)
636 IDirectDrawSurface7
*src_surface
, *dst_surface
;
637 RECT client_rect
, src_rect
;
638 IDirectDrawClipper
*clipper
;
639 DDSURFACEDESC2 surface_desc
;
640 unsigned int i
, j
, x
, y
;
651 static const DWORD src_data
[] =
653 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
654 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
655 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
657 static const D3DCOLOR expected1
[] =
659 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
660 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
661 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
662 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
664 static const D3DCOLOR expected2
[] =
666 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
667 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
668 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
669 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
672 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
673 10, 10, 640, 480, 0, 0, 0, 0);
674 ShowWindow(window
, SW_SHOW
);
675 if (!(ddraw
= create_ddraw()))
677 skip("Failed to create a ddraw object, skipping test.\n");
678 DestroyWindow(window
);
682 ret
= GetClientRect(window
, &client_rect
);
683 ok(ret
, "Failed to get client rect.\n");
684 ret
= MapWindowPoints(window
, NULL
, (POINT
*)&client_rect
, 2);
685 ok(ret
, "Failed to map client rect.\n");
687 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
688 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
690 hr
= IDirectDraw7_CreateClipper(ddraw
, 0, &clipper
, NULL
);
691 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
692 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
693 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
694 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
695 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
696 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
697 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
698 rgn_data
= HeapAlloc(GetProcessHeap(), 0, ret
);
699 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, rgn_data
, &ret
);
700 ok(SUCCEEDED(hr
), "Failed to get clip list, hr %#x.\n", hr
);
701 ok(rgn_data
->rdh
.dwSize
== sizeof(rgn_data
->rdh
), "Got unexpected structure size %#x.\n", rgn_data
->rdh
.dwSize
);
702 ok(rgn_data
->rdh
.iType
== RDH_RECTANGLES
, "Got unexpected type %#x.\n", rgn_data
->rdh
.iType
);
703 ok(rgn_data
->rdh
.nCount
>= 1, "Got unexpected count %u.\n", rgn_data
->rdh
.nCount
);
704 ok(EqualRect(&rgn_data
->rdh
.rcBound
, &client_rect
),
705 "Got unexpected bounding rect {%d, %d, %d, %d}, expected {%d, %d, %d, %d}.\n",
706 rgn_data
->rdh
.rcBound
.left
, rgn_data
->rdh
.rcBound
.top
,
707 rgn_data
->rdh
.rcBound
.right
, rgn_data
->rdh
.rcBound
.bottom
,
708 client_rect
.left
, client_rect
.top
, client_rect
.right
, client_rect
.bottom
);
709 HeapFree(GetProcessHeap(), 0, rgn_data
);
711 r1
= CreateRectRgn(0, 0, 320, 240);
712 ok(!!r1
, "Failed to create region.\n");
713 r2
= CreateRectRgn(320, 240, 640, 480);
714 ok(!!r2
, "Failed to create region.\n");
715 CombineRgn(r1
, r1
, r2
, RGN_OR
);
716 ret
= GetRegionData(r1
, 0, NULL
);
717 rgn_data
= HeapAlloc(GetProcessHeap(), 0, ret
);
718 ret
= GetRegionData(r1
, ret
, rgn_data
);
719 ok(!!ret
, "Failed to get region data.\n");
724 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
725 ok(hr
== DDERR_CLIPPERISUSINGHWND
, "Got unexpected hr %#x.\n", hr
);
726 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
727 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
728 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
729 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#x.\n", hr
);
731 HeapFree(GetProcessHeap(), 0, rgn_data
);
733 memset(&surface_desc
, 0, sizeof(surface_desc
));
734 surface_desc
.dwSize
= sizeof(surface_desc
);
735 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
736 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
737 surface_desc
.dwWidth
= 640;
738 surface_desc
.dwHeight
= 480;
739 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
740 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
741 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
742 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
743 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
744 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
746 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &src_surface
, NULL
);
747 ok(SUCCEEDED(hr
), "Failed to create source surface, hr %#x.\n", hr
);
748 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &dst_surface
, NULL
);
749 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#x.\n", hr
);
751 memset(&fx
, 0, sizeof(fx
));
752 fx
.dwSize
= sizeof(fx
);
753 hr
= IDirectDrawSurface7_Blt(src_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
754 ok(SUCCEEDED(hr
), "Failed to clear source surface, hr %#x.\n", hr
);
755 hr
= IDirectDrawSurface7_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
756 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#x.\n", hr
);
758 hr
= IDirectDrawSurface7_Lock(src_surface
, NULL
, &surface_desc
, 0, NULL
);
759 ok(SUCCEEDED(hr
), "Failed to lock source surface, hr %#x.\n", hr
);
760 ok(U1(surface_desc
).lPitch
== 2560, "Got unexpected surface pitch %u.\n", U1(surface_desc
).lPitch
);
761 ptr
= surface_desc
.lpSurface
;
762 memcpy(&ptr
[ 0], &src_data
[ 0], 6 * sizeof(DWORD
));
763 memcpy(&ptr
[ 640], &src_data
[ 6], 6 * sizeof(DWORD
));
764 memcpy(&ptr
[1280], &src_data
[12], 6 * sizeof(DWORD
));
765 hr
= IDirectDrawSurface7_Unlock(src_surface
, NULL
);
766 ok(SUCCEEDED(hr
), "Failed to unlock source surface, hr %#x.\n", hr
);
768 hr
= IDirectDrawSurface7_SetClipper(dst_surface
, clipper
);
769 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
771 SetRect(&src_rect
, 1, 1, 5, 2);
772 hr
= IDirectDrawSurface7_Blt(dst_surface
, NULL
, src_surface
, &src_rect
, DDBLT_WAIT
, NULL
);
773 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
774 for (i
= 0; i
< 4; ++i
)
776 for (j
= 0; j
< 4; ++j
)
778 x
= 80 * ((2 * j
) + 1);
779 y
= 60 * ((2 * i
) + 1);
780 color
= get_surface_color(dst_surface
, x
, y
);
781 ok(compare_color(color
, expected1
[i
* 4 + j
], 1),
782 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected1
[i
* 4 + j
], x
, y
, color
);
786 U5(fx
).dwFillColor
= 0xff0000ff;
787 hr
= IDirectDrawSurface7_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
788 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#x.\n", hr
);
789 for (i
= 0; i
< 4; ++i
)
791 for (j
= 0; j
< 4; ++j
)
793 x
= 80 * ((2 * j
) + 1);
794 y
= 60 * ((2 * i
) + 1);
795 color
= get_surface_color(dst_surface
, x
, y
);
796 ok(compare_color(color
, expected2
[i
* 4 + j
], 1),
797 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected2
[i
* 4 + j
], x
, y
, color
);
801 hr
= IDirectDrawSurface7_BltFast(dst_surface
, 0, 0, src_surface
, NULL
, DDBLTFAST_WAIT
);
802 ok(hr
== DDERR_BLTFASTCANTCLIP
, "Got unexpected hr %#x.\n", hr
);
804 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
805 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
806 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
807 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
808 DestroyWindow(window
);
809 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
810 ok(hr
== E_FAIL
, "Got unexpected hr %#x.\n", hr
);
811 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
812 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
813 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
814 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
815 hr
= IDirectDrawClipper_SetClipList(clipper
, NULL
, 0);
816 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#x.\n", hr
);
817 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
818 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
819 hr
= IDirectDrawSurface7_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
820 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
822 IDirectDrawSurface7_Release(dst_surface
);
823 IDirectDrawSurface7_Release(src_surface
);
824 IDirectDrawClipper_Release(clipper
);
825 IDirectDraw7_Release(ddraw
);
828 static void test_coop_level_d3d_state(void)
830 IDirectDrawSurface7
*rt
, *surface
;
831 IDirect3DDevice7
*device
;
839 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
840 0, 0, 640, 480, 0, 0, 0, 0);
841 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
843 skip("Failed to create D3D device, skipping test.\n");
844 DestroyWindow(window
);
848 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
849 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
850 hr
= IDirect3DDevice7_GetRenderState(device
, D3DRENDERSTATE_ZENABLE
, &value
);
851 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
852 ok(!!value
, "Got unexpected z-enable state %#x.\n", value
);
853 hr
= IDirect3DDevice7_GetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, &value
);
854 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
855 ok(!value
, "Got unexpected alpha blend enable state %#x.\n", value
);
856 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
857 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
858 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffff0000, 0.0f
, 0);
859 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
860 color
= get_surface_color(rt
, 320, 240);
861 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
863 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
864 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
865 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
866 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
867 IDirect3D7_Release(d3d
);
868 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
869 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
870 hr
= IDirectDrawSurface7_IsLost(rt
);
871 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
872 hr
= IDirectDraw7_RestoreAllSurfaces(ddraw
);
873 ok(SUCCEEDED(hr
), "Failed to restore surfaces, hr %#x.\n", hr
);
874 IDirectDraw7_Release(ddraw
);
876 hr
= IDirect3DDevice7_GetRenderTarget(device
, &surface
);
877 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
878 ok(surface
== rt
, "Got unexpected surface %p.\n", surface
);
879 hr
= IDirect3DDevice7_GetRenderState(device
, D3DRENDERSTATE_ZENABLE
, &value
);
880 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
881 ok(!!value
, "Got unexpected z-enable state %#x.\n", value
);
882 hr
= IDirect3DDevice7_GetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, &value
);
883 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
884 ok(!!value
, "Got unexpected alpha blend enable state %#x.\n", value
);
885 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff00ff00, 0.0f
, 0);
886 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
887 color
= get_surface_color(rt
, 320, 240);
888 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
890 IDirectDrawSurface7_Release(surface
);
891 IDirectDrawSurface7_Release(rt
);
892 IDirect3DDevice7_Release(device
);
893 DestroyWindow(window
);
896 static void test_surface_interface_mismatch(void)
898 IDirectDraw7
*ddraw
= NULL
;
899 IDirect3D7
*d3d
= NULL
;
900 IDirectDrawSurface7
*surface
= NULL
, *ds
;
901 IDirectDrawSurface3
*surface3
= NULL
;
902 IDirect3DDevice7
*device
= NULL
;
903 DDSURFACEDESC2 surface_desc
;
910 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
911 0, 0, 640, 480, 0, 0, 0, 0);
913 if (!(ddraw
= create_ddraw()))
915 skip("Failed to create a ddraw object, skipping test.\n");
919 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
920 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
922 memset(&surface_desc
, 0, sizeof(surface_desc
));
923 surface_desc
.dwSize
= sizeof(surface_desc
);
924 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
925 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
926 surface_desc
.dwWidth
= 640;
927 surface_desc
.dwHeight
= 480;
929 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
930 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
932 hr
= IDirectDrawSurface7_QueryInterface(surface
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
933 ok(SUCCEEDED(hr
), "Failed to QI IDirectDrawSurface3, hr %#x.\n", hr
);
935 hr
= IDirectDraw7_QueryInterface(ddraw
, &IID_IDirect3D7
, (void **)&d3d
);
938 skip("Failed to get the IDirect3D7 interface, skipping test.\n");
942 memset(&z_fmt
, 0, sizeof(z_fmt
));
943 hr
= IDirect3D7_EnumZBufferFormats(d3d
, &IID_IDirect3DHALDevice
, enum_z_fmt
, &z_fmt
);
944 if (FAILED(hr
) || !z_fmt
.dwSize
)
946 skip("No depth buffer formats available, skipping test.\n");
950 memset(&surface_desc
, 0, sizeof(surface_desc
));
951 surface_desc
.dwSize
= sizeof(surface_desc
);
952 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
953 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
954 U4(surface_desc
).ddpfPixelFormat
= z_fmt
;
955 surface_desc
.dwWidth
= 640;
956 surface_desc
.dwHeight
= 480;
957 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
958 ok(SUCCEEDED(hr
), "Failed to create depth buffer, hr %#x.\n", hr
);
962 /* Using a different surface interface version still works */
963 hr
= IDirectDrawSurface3_AddAttachedSurface(surface3
, (IDirectDrawSurface3
*)ds
);
964 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x.\n", hr
);
965 refcount
= IDirectDrawSurface7_Release(ds
);
966 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
971 hr
= IDirect3D7_CreateDevice(d3d
, &IID_IDirect3DHALDevice
, (IDirectDrawSurface7
*)surface3
, &device
);
972 ok(SUCCEEDED(hr
), "Failed to create d3d device.\n");
976 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffff0000, 0.0f
, 0);
977 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
978 color
= get_surface_color(surface
, 320, 240);
979 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
982 if (surface3
) IDirectDrawSurface3_Release(surface3
);
983 if (surface
) IDirectDrawSurface7_Release(surface
);
984 if (device
) IDirect3DDevice7_Release(device
);
985 if (d3d
) IDirect3D7_Release(d3d
);
986 if (ddraw
) IDirectDraw7_Release(ddraw
);
987 DestroyWindow(window
);
990 static void test_coop_level_threaded(void)
992 struct create_window_thread_param p
;
996 if (!(ddraw
= create_ddraw()))
998 skip("Failed to create a ddraw object, skipping test.\n");
1001 create_window_thread(&p
);
1003 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, p
.window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1004 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
1006 IDirectDraw7_Release(ddraw
);
1007 destroy_window_thread(&p
);
1010 static void test_depth_blit(void)
1012 IDirect3DDevice7
*device
;
1020 { -1.0, 1.0, 0.50f
, 0xff00ff00},
1021 { 1.0, 1.0, 0.50f
, 0xff00ff00},
1022 { -1.0, -1.0, 0.50f
, 0xff00ff00},
1023 { 1.0, -1.0, 0.50f
, 0xff00ff00},
1025 static const D3DCOLOR expected_colors
[4][4] =
1027 {0x00ff0000, 0x00ff0000, 0x0000ff00, 0x0000ff00},
1028 {0x00ff0000, 0x00ff0000, 0x0000ff00, 0x0000ff00},
1029 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1030 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1032 DDSURFACEDESC2 ddsd_new
, ddsd_existing
;
1034 IDirectDrawSurface7
*ds1
, *ds2
, *ds3
, *rt
;
1035 RECT src_rect
, dst_rect
;
1040 IDirectDraw7
*ddraw
;
1044 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1045 0, 0, 640, 480, 0, 0, 0, 0);
1046 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
1048 skip("Failed to create D3D device, skipping test.\n");
1049 DestroyWindow(window
);
1053 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
1054 ok(SUCCEEDED(hr
), "Failed to get Direct3D7 interface, hr %#x.\n", hr
);
1055 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
1056 ok(SUCCEEDED(hr
), "Failed to get DirectDraw7 interface, hr %#x.\n", hr
);
1057 IDirect3D7_Release(d3d
);
1059 ds1
= get_depth_stencil(device
);
1061 memset(&ddsd_new
, 0, sizeof(ddsd_new
));
1062 ddsd_new
.dwSize
= sizeof(ddsd_new
);
1063 memset(&ddsd_existing
, 0, sizeof(ddsd_existing
));
1064 ddsd_existing
.dwSize
= sizeof(ddsd_existing
);
1065 hr
= IDirectDrawSurface7_GetSurfaceDesc(ds1
, &ddsd_existing
);
1066 ddsd_new
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
1067 ddsd_new
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
1068 ddsd_new
.dwWidth
= ddsd_existing
.dwWidth
;
1069 ddsd_new
.dwHeight
= ddsd_existing
.dwHeight
;
1070 U4(ddsd_new
).ddpfPixelFormat
= U4(ddsd_existing
).ddpfPixelFormat
;
1071 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd_new
, &ds2
, NULL
);
1072 ok(SUCCEEDED(hr
), "Failed to create a z buffer, hr %#x.\n", hr
);
1073 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd_new
, &ds3
, NULL
);
1074 ok(SUCCEEDED(hr
), "Failed to create a z buffer, hr %#x.\n", hr
);
1075 IDirectDraw7_Release(ddraw
);
1077 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_TRUE
);
1078 ok(SUCCEEDED(hr
), "Failed to enable z testing, hr %#x.\n", hr
);
1079 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZFUNC
, D3DCMP_LESSEQUAL
);
1080 ok(SUCCEEDED(hr
), "Failed to set the z function, hr %#x.\n", hr
);
1081 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
1082 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
1084 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_ZBUFFER
, 0, 0.0f
, 0);
1085 ok(SUCCEEDED(hr
), "Failed to clear the z buffer, hr %#x.\n", hr
);
1088 SetRect(&src_rect
, 0, 0, 320, 240);
1089 SetRect(&dst_rect
, 0, 0, 320, 240);
1090 hr
= IDirectDrawSurface7_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1091 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1092 /* Different locations. */
1093 SetRect(&src_rect
, 0, 0, 320, 240);
1094 SetRect(&dst_rect
, 320, 240, 640, 480);
1095 hr
= IDirectDrawSurface7_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1096 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1098 SetRect(&src_rect
, 0, 0, 320, 240);
1099 SetRect(&dst_rect
, 0, 0, 640, 480);
1100 hr
= IDirectDrawSurface7_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1101 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1103 SetRect(&src_rect
, 0, 480, 640, 0);
1104 SetRect(&dst_rect
, 0, 0, 640, 480);
1105 hr
= IDirectDrawSurface7_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1106 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
1107 SetRect(&src_rect
, 0, 0, 640, 480);
1108 SetRect(&dst_rect
, 0, 480, 640, 0);
1109 hr
= IDirectDrawSurface7_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1110 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
1111 /* Full, explicit. */
1112 SetRect(&src_rect
, 0, 0, 640, 480);
1113 SetRect(&dst_rect
, 0, 0, 640, 480);
1114 hr
= IDirectDrawSurface7_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1115 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1116 /* Depth -> color blit: Succeeds on Win7 + Radeon HD 5700, fails on WinXP + Radeon X1600 */
1118 /* Depth blit inside a BeginScene / EndScene pair */
1119 hr
= IDirect3DDevice7_BeginScene(device
);
1120 ok(SUCCEEDED(hr
), "Failed to start scene, hr %#x.\n", hr
);
1121 /* From the current depth stencil */
1122 hr
= IDirectDrawSurface7_Blt(ds2
, NULL
, ds1
, NULL
, DDBLT_WAIT
, NULL
);
1123 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1124 /* To the current depth stencil */
1125 hr
= IDirectDrawSurface7_Blt(ds1
, NULL
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1126 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1127 /* Between unbound surfaces */
1128 hr
= IDirectDrawSurface7_Blt(ds3
, NULL
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1129 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1130 hr
= IDirect3DDevice7_EndScene(device
);
1131 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1133 /* Avoid changing the depth stencil, it doesn't work properly on Windows.
1134 * Instead use DDBLT_DEPTHFILL to clear the depth stencil. Unfortunately
1135 * drivers disagree on the meaning of dwFillDepth. Only 0 seems to produce
1136 * a reliable result(z = 0.0) */
1137 memset(&fx
, 0, sizeof(fx
));
1138 fx
.dwSize
= sizeof(fx
);
1139 hr
= IDirectDrawSurface7_Blt(ds2
, NULL
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
1140 ok(SUCCEEDED(hr
), "Failed to clear the source z buffer, hr %#x.\n", hr
);
1142 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_ZBUFFER
| D3DCLEAR_TARGET
, 0xffff0000, 1.0f
, 0);
1143 ok(SUCCEEDED(hr
), "Failed to clear the color and z buffers, hr %#x.\n", hr
);
1144 SetRect(&dst_rect
, 0, 0, 320, 240);
1145 hr
= IDirectDrawSurface7_Blt(ds1
, &dst_rect
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1146 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1147 IDirectDrawSurface7_Release(ds3
);
1148 IDirectDrawSurface7_Release(ds2
);
1149 IDirectDrawSurface7_Release(ds1
);
1151 hr
= IDirect3DDevice7_BeginScene(device
);
1152 ok(SUCCEEDED(hr
), "Failed to start scene, hr %#x.\n", hr
);
1153 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
1155 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1156 hr
= IDirect3DDevice7_EndScene(device
);
1157 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1159 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
1160 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1161 for (i
= 0; i
< 4; ++i
)
1163 for (j
= 0; j
< 4; ++j
)
1165 unsigned int x
= 80 * ((2 * j
) + 1);
1166 unsigned int y
= 60 * ((2 * i
) + 1);
1167 color
= get_surface_color(rt
, x
, y
);
1168 ok(compare_color(color
, expected_colors
[i
][j
], 1),
1169 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors
[i
][j
], x
, y
, color
);
1173 IDirectDrawSurface7_Release(rt
);
1174 IDirect3DDevice7_Release(device
);
1175 DestroyWindow(window
);
1178 static void test_texture_load_ckey(void)
1181 IDirect3DDevice7
*device
;
1182 IDirectDraw7
*ddraw
;
1183 IDirectDrawSurface7
*src
;
1184 IDirectDrawSurface7
*dst
;
1185 DDSURFACEDESC2 ddsd
;
1190 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1191 0, 0, 640, 480, 0, 0, 0, 0);
1192 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
1194 skip("Failed to create D3D device, skipping test.\n");
1195 DestroyWindow(window
);
1199 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
1200 ok(SUCCEEDED(hr
), "Failed to get Direct3D7 interface, hr %#x.\n", hr
);
1201 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
1202 ok(SUCCEEDED(hr
), "Failed to get DirectDraw7 interface, hr %#x.\n", hr
);
1203 IDirect3D7_Release(d3d
);
1205 memset(&ddsd
, 0, sizeof(ddsd
));
1206 ddsd
.dwSize
= sizeof(ddsd
);
1207 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
1208 ddsd
.dwHeight
= 128;
1210 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
;
1211 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &src
, NULL
);
1212 ok(SUCCEEDED(hr
), "Failed to create source texture, hr %#x.\n", hr
);
1213 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1214 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &dst
, NULL
);
1215 ok(SUCCEEDED(hr
), "Failed to create destination texture, hr %#x.\n", hr
);
1217 /* No surface has a color key */
1218 hr
= IDirect3DDevice7_Load(device
, dst
, NULL
, src
, NULL
, 0);
1219 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1220 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0xdeadbeef;
1221 hr
= IDirectDrawSurface7_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1222 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
1223 ok(ckey
.dwColorSpaceLowValue
== 0xdeadbeef, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1224 ok(ckey
.dwColorSpaceHighValue
== 0xdeadbeef, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1226 /* Source surface has a color key */
1227 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0x0000ff00;
1228 hr
= IDirectDrawSurface7_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
1229 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1230 hr
= IDirect3DDevice7_Load(device
, dst
, NULL
, src
, NULL
, 0);
1231 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1232 hr
= IDirectDrawSurface7_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1233 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1234 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1235 ok(ckey
.dwColorSpaceHighValue
== 0x0000ff00, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1237 /* Both surfaces have a color key: Dest ckey is overwritten */
1238 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0x000000ff;
1239 hr
= IDirectDrawSurface7_SetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1240 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1241 hr
= IDirect3DDevice7_Load(device
, dst
, NULL
, src
, NULL
, 0);
1242 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1243 hr
= IDirectDrawSurface7_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1244 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1245 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1246 ok(ckey
.dwColorSpaceHighValue
== 0x0000ff00, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1248 /* Only the destination has a color key: It is deleted. This behavior differs from
1249 * IDirect3DTexture(2)::Load */
1250 hr
= IDirectDrawSurface7_SetColorKey(src
, DDCKEY_SRCBLT
, NULL
);
1251 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1252 hr
= IDirectDrawSurface7_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
1253 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
1254 hr
= IDirect3DDevice7_Load(device
, dst
, NULL
, src
, NULL
, 0);
1255 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1256 hr
= IDirectDrawSurface7_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1257 todo_wine
ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
1259 IDirectDrawSurface7_Release(dst
);
1260 IDirectDrawSurface7_Release(src
);
1261 IDirectDraw7_Release(ddraw
);
1262 IDirect3DDevice7_Release(device
);
1265 static void test_zenable(void)
1269 struct vec4 position
;
1274 {{ 0.0f
, 480.0f
, -0.5f
, 1.0f
}, 0xff00ff00},
1275 {{ 0.0f
, 0.0f
, -0.5f
, 1.0f
}, 0xff00ff00},
1276 {{640.0f
, 480.0f
, 1.5f
, 1.0f
}, 0xff00ff00},
1277 {{640.0f
, 0.0f
, 1.5f
, 1.0f
}, 0xff00ff00},
1279 IDirect3DDevice7
*device
;
1280 IDirectDrawSurface7
*rt
;
1287 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1288 0, 0, 640, 480, 0, 0, 0, 0);
1289 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
1291 skip("Failed to create D3D device, skipping test.\n");
1292 DestroyWindow(window
);
1296 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
1297 ok(SUCCEEDED(hr
), "Failed to disable z-buffering, hr %#x.\n", hr
);
1299 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xffff0000, 0.0f
, 0);
1300 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
1301 hr
= IDirect3DDevice7_BeginScene(device
);
1302 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1303 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
, tquad
, 4, 0);
1304 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1305 hr
= IDirect3DDevice7_EndScene(device
);
1306 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1308 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
1309 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1310 for (i
= 0; i
< 4; ++i
)
1312 for (j
= 0; j
< 4; ++j
)
1314 x
= 80 * ((2 * j
) + 1);
1315 y
= 60 * ((2 * i
) + 1);
1316 color
= get_surface_color(rt
, x
, y
);
1317 ok(compare_color(color
, 0x0000ff00, 1),
1318 "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x
, y
, color
);
1321 IDirectDrawSurface7_Release(rt
);
1323 IDirect3DDevice7_Release(device
);
1324 DestroyWindow(window
);
1327 static void test_ck_rgba(void)
1331 struct vec4 position
;
1332 struct vec2 texcoord
;
1336 {{ 0.0f
, 480.0f
, 0.25f
, 1.0f
}, {0.0f
, 0.0f
}},
1337 {{ 0.0f
, 0.0f
, 0.25f
, 1.0f
}, {0.0f
, 1.0f
}},
1338 {{640.0f
, 480.0f
, 0.25f
, 1.0f
}, {1.0f
, 0.0f
}},
1339 {{640.0f
, 0.0f
, 0.25f
, 1.0f
}, {1.0f
, 1.0f
}},
1340 {{ 0.0f
, 480.0f
, 0.75f
, 1.0f
}, {0.0f
, 0.0f
}},
1341 {{ 0.0f
, 0.0f
, 0.75f
, 1.0f
}, {0.0f
, 1.0f
}},
1342 {{640.0f
, 480.0f
, 0.75f
, 1.0f
}, {1.0f
, 0.0f
}},
1343 {{640.0f
, 0.0f
, 0.75f
, 1.0f
}, {1.0f
, 1.0f
}},
1347 D3DCOLOR fill_color
;
1355 {0xff00ff00, TRUE
, TRUE
, 0x00ff0000, 0x000000ff},
1356 {0xff00ff00, TRUE
, FALSE
, 0x00ff0000, 0x000000ff},
1357 {0xff00ff00, FALSE
, TRUE
, 0x0000ff00, 0x0000ff00},
1358 {0xff00ff00, FALSE
, FALSE
, 0x0000ff00, 0x0000ff00},
1359 {0x7f00ff00, TRUE
, TRUE
, 0x00807f00, 0x00807f00},
1360 {0x7f00ff00, TRUE
, FALSE
, 0x0000ff00, 0x0000ff00},
1361 {0x7f00ff00, FALSE
, TRUE
, 0x00807f00, 0x00807f00},
1362 {0x7f00ff00, FALSE
, FALSE
, 0x0000ff00, 0x0000ff00},
1365 IDirectDrawSurface7
*texture
;
1366 DDSURFACEDESC2 surface_desc
;
1367 IDirect3DDevice7
*device
;
1368 IDirectDrawSurface7
*rt
;
1369 IDirectDraw7
*ddraw
;
1377 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1378 0, 0, 640, 480, 0, 0, 0, 0);
1379 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
1381 skip("Failed to create D3D device, skipping test.\n");
1382 DestroyWindow(window
);
1386 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
1387 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
1388 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
1389 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
1390 IDirect3D7_Release(d3d
);
1392 memset(&surface_desc
, 0, sizeof(surface_desc
));
1393 surface_desc
.dwSize
= sizeof(surface_desc
);
1394 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
1395 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1396 surface_desc
.dwWidth
= 256;
1397 surface_desc
.dwHeight
= 256;
1398 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
1399 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
1400 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
1401 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
1402 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
1403 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
1404 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
1405 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0xff00ff00;
1406 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0xff00ff00;
1407 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &texture
, NULL
);
1408 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#x.\n", hr
);
1410 hr
= IDirect3DDevice7_SetTexture(device
, 0, texture
);
1411 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
1412 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_SRCBLEND
, D3DBLEND_SRCALPHA
);
1413 ok(SUCCEEDED(hr
), "Failed to enable alpha blending, hr %#x.\n", hr
);
1414 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_DESTBLEND
, D3DBLEND_INVSRCALPHA
);
1415 ok(SUCCEEDED(hr
), "Failed to enable alpha blending, hr %#x.\n", hr
);
1417 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
1418 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1420 for (i
= 0; i
< sizeof(tests
) / sizeof(*tests
); ++i
)
1422 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, tests
[i
].color_key
);
1423 ok(SUCCEEDED(hr
), "Failed to enable color keying, hr %#x.\n", hr
);
1424 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, tests
[i
].blend
);
1425 ok(SUCCEEDED(hr
), "Failed to enable alpha blending, hr %#x.\n", hr
);
1427 memset(&fx
, 0, sizeof(fx
));
1428 fx
.dwSize
= sizeof(fx
);
1429 U5(fx
).dwFillColor
= tests
[i
].fill_color
;
1430 hr
= IDirectDrawSurface7_Blt(texture
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1431 ok(SUCCEEDED(hr
), "Failed to fill texture, hr %#x.\n", hr
);
1433 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xffff0000, 1.0f
, 0);
1434 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
1435 hr
= IDirect3DDevice7_BeginScene(device
);
1436 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1437 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZRHW
| D3DFVF_TEX1
, &tquad
[0], 4, 0);
1438 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1439 hr
= IDirect3DDevice7_EndScene(device
);
1440 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1442 color
= get_surface_color(rt
, 320, 240);
1444 todo_wine
ok(compare_color(color
, tests
[i
].result1
, 1), "Expected color 0x%08x for test %u, got 0x%08x.\n",
1445 tests
[i
].result1
, i
, color
);
1447 ok(compare_color(color
, tests
[i
].result1
, 1), "Expected color 0x%08x for test %u, got 0x%08x.\n",
1448 tests
[i
].result1
, i
, color
);
1450 U5(fx
).dwFillColor
= 0xff0000ff;
1451 hr
= IDirectDrawSurface7_Blt(texture
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1452 ok(SUCCEEDED(hr
), "Failed to fill texture, hr %#x.\n", hr
);
1454 hr
= IDirect3DDevice7_BeginScene(device
);
1455 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1456 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZRHW
| D3DFVF_TEX1
, &tquad
[4], 4, 0);
1457 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1458 hr
= IDirect3DDevice7_EndScene(device
);
1459 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1461 /* This tests that fragments that are masked out by the color key are
1462 * discarded, instead of just fully transparent. */
1463 color
= get_surface_color(rt
, 320, 240);
1465 todo_wine
ok(compare_color(color
, tests
[i
].result2
, 1), "Expected color 0x%08x for test %u, got 0x%08x.\n",
1466 tests
[i
].result2
, i
, color
);
1468 ok(compare_color(color
, tests
[i
].result2
, 1), "Expected color 0x%08x for test %u, got 0x%08x.\n",
1469 tests
[i
].result2
, i
, color
);
1472 IDirectDrawSurface7_Release(rt
);
1473 IDirectDrawSurface7_Release(texture
);
1474 IDirectDraw7_Release(ddraw
);
1475 IDirect3DDevice7_Release(device
);
1476 DestroyWindow(window
);
1479 static void test_ck_default(void)
1483 struct vec4 position
;
1484 struct vec2 texcoord
;
1488 {{ 0.0f
, 480.0f
, 0.0f
, 1.0f
}, {0.0f
, 0.0f
}},
1489 {{ 0.0f
, 0.0f
, 0.0f
, 1.0f
}, {0.0f
, 1.0f
}},
1490 {{640.0f
, 480.0f
, 0.0f
, 1.0f
}, {1.0f
, 0.0f
}},
1491 {{640.0f
, 0.0f
, 0.0f
, 1.0f
}, {1.0f
, 1.0f
}},
1493 IDirectDrawSurface7
*surface
, *rt
;
1494 DDSURFACEDESC2 surface_desc
;
1495 IDirect3DDevice7
*device
;
1496 IDirectDraw7
*ddraw
;
1504 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1505 0, 0, 640, 480, 0, 0, 0, 0);
1507 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
1509 skip("Failed to create D3D device, skipping test.\n");
1510 DestroyWindow(window
);
1514 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
1515 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
1516 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
1517 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
1518 IDirect3D7_Release(d3d
);
1520 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
1521 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1523 memset(&surface_desc
, 0, sizeof(surface_desc
));
1524 surface_desc
.dwSize
= sizeof(surface_desc
);
1525 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
1526 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1527 surface_desc
.dwWidth
= 256;
1528 surface_desc
.dwHeight
= 256;
1529 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
1530 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
1531 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
1532 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
1533 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
1534 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
1535 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x000000ff;
1536 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x000000ff;
1537 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1538 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
1539 hr
= IDirect3DDevice7_SetTexture(device
, 0, surface
);
1540 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
1542 memset(&fx
, 0, sizeof(fx
));
1543 fx
.dwSize
= sizeof(fx
);
1544 U5(fx
).dwFillColor
= 0x000000ff;
1545 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1546 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#x.\n", hr
);
1548 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff00ff00, 1.0f
, 0);
1549 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
1550 hr
= IDirect3DDevice7_BeginScene(device
);
1551 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1552 hr
= IDirect3DDevice7_GetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, &value
);
1553 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
1554 ok(!value
, "Got unexpected color keying state %#x.\n", value
);
1555 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZRHW
| D3DFVF_TEX1
, &tquad
[0], 4, 0);
1556 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1557 hr
= IDirect3DDevice7_EndScene(device
);
1558 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1559 color
= get_surface_color(rt
, 320, 240);
1560 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
1562 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff00ff00, 1.0f
, 0);
1563 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
1564 hr
= IDirect3DDevice7_BeginScene(device
);
1565 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1566 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, TRUE
);
1567 ok(SUCCEEDED(hr
), "Failed to enable color keying, hr %#x.\n", hr
);
1568 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZRHW
| D3DFVF_TEX1
, &tquad
[0], 4, 0);
1569 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1570 hr
= IDirect3DDevice7_GetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, &value
);
1571 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
1572 ok(!!value
, "Got unexpected color keying state %#x.\n", value
);
1573 hr
= IDirect3DDevice7_EndScene(device
);
1574 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1575 color
= get_surface_color(rt
, 320, 240);
1576 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
1578 IDirectDrawSurface7_Release(surface
);
1579 IDirectDrawSurface7_Release(rt
);
1580 IDirect3DDevice7_Release(device
);
1581 IDirectDraw7_Release(ddraw
);
1582 DestroyWindow(window
);
1588 REFIID refcount_iid
;
1592 static void test_qi(const char *test_name
, IUnknown
*base_iface
,
1593 REFIID refcount_iid
, const struct qi_test
*tests
, UINT entry_count
)
1595 ULONG refcount
, expected_refcount
;
1596 IUnknown
*iface1
, *iface2
;
1600 for (i
= 0; i
< entry_count
; ++i
)
1602 hr
= IUnknown_QueryInterface(base_iface
, tests
[i
].iid
, (void **)&iface1
);
1603 ok(hr
== tests
[i
].hr
, "Got hr %#x for test \"%s\" %u.\n", hr
, test_name
, i
);
1606 for (j
= 0; j
< entry_count
; ++j
)
1608 hr
= IUnknown_QueryInterface(iface1
, tests
[j
].iid
, (void **)&iface2
);
1609 ok(hr
== tests
[j
].hr
, "Got hr %#x for test \"%s\" %u, %u.\n", hr
, test_name
, i
, j
);
1612 expected_refcount
= 0;
1613 if (IsEqualGUID(refcount_iid
, tests
[j
].refcount_iid
))
1614 ++expected_refcount
;
1615 if (IsEqualGUID(tests
[i
].refcount_iid
, tests
[j
].refcount_iid
))
1616 ++expected_refcount
;
1617 refcount
= IUnknown_Release(iface2
);
1618 ok(refcount
== expected_refcount
, "Got refcount %u for test \"%s\" %u, %u, expected %u.\n",
1619 refcount
, test_name
, i
, j
, expected_refcount
);
1623 expected_refcount
= 0;
1624 if (IsEqualGUID(refcount_iid
, tests
[i
].refcount_iid
))
1625 ++expected_refcount
;
1626 refcount
= IUnknown_Release(iface1
);
1627 ok(refcount
== expected_refcount
, "Got refcount %u for test \"%s\" %u, expected %u.\n",
1628 refcount
, test_name
, i
, expected_refcount
);
1633 static void test_surface_qi(void)
1635 static const struct qi_test tests
[] =
1637 {&IID_IDirect3DTexture2
, NULL
, E_NOINTERFACE
},
1638 {&IID_IDirect3DTexture
, NULL
, E_NOINTERFACE
},
1639 {&IID_IDirectDrawGammaControl
, &IID_IDirectDrawGammaControl
, S_OK
},
1640 {&IID_IDirectDrawColorControl
, NULL
, E_NOINTERFACE
},
1641 {&IID_IDirectDrawSurface7
, &IID_IDirectDrawSurface7
, S_OK
},
1642 {&IID_IDirectDrawSurface4
, &IID_IDirectDrawSurface4
, S_OK
},
1643 {&IID_IDirectDrawSurface3
, &IID_IDirectDrawSurface3
, S_OK
},
1644 {&IID_IDirectDrawSurface2
, &IID_IDirectDrawSurface2
, S_OK
},
1645 {&IID_IDirectDrawSurface
, &IID_IDirectDrawSurface
, S_OK
},
1646 {&IID_IDirect3DDevice7
, NULL
, E_NOINTERFACE
},
1647 {&IID_IDirect3DDevice3
, NULL
, E_NOINTERFACE
},
1648 {&IID_IDirect3DDevice2
, NULL
, E_NOINTERFACE
},
1649 {&IID_IDirect3DDevice
, NULL
, E_NOINTERFACE
},
1650 {&IID_IDirect3DRampDevice
, NULL
, E_NOINTERFACE
},
1651 {&IID_IDirect3DRGBDevice
, NULL
, E_NOINTERFACE
},
1652 {&IID_IDirect3DHALDevice
, NULL
, E_NOINTERFACE
},
1653 {&IID_IDirect3DMMXDevice
, NULL
, E_NOINTERFACE
},
1654 {&IID_IDirect3DRefDevice
, NULL
, E_NOINTERFACE
},
1655 {&IID_IDirect3DTnLHalDevice
, NULL
, E_NOINTERFACE
},
1656 {&IID_IDirect3DNullDevice
, NULL
, E_NOINTERFACE
},
1657 {&IID_IDirect3D7
, NULL
, E_NOINTERFACE
},
1658 {&IID_IDirect3D3
, NULL
, E_NOINTERFACE
},
1659 {&IID_IDirect3D2
, NULL
, E_NOINTERFACE
},
1660 {&IID_IDirect3D
, NULL
, E_NOINTERFACE
},
1661 {&IID_IDirectDraw7
, NULL
, E_NOINTERFACE
},
1662 {&IID_IDirectDraw4
, NULL
, E_NOINTERFACE
},
1663 {&IID_IDirectDraw3
, NULL
, E_NOINTERFACE
},
1664 {&IID_IDirectDraw2
, NULL
, E_NOINTERFACE
},
1665 {&IID_IDirectDraw
, NULL
, E_NOINTERFACE
},
1666 {&IID_IDirect3DLight
, NULL
, E_NOINTERFACE
},
1667 {&IID_IDirect3DMaterial
, NULL
, E_NOINTERFACE
},
1668 {&IID_IDirect3DMaterial2
, NULL
, E_NOINTERFACE
},
1669 {&IID_IDirect3DMaterial3
, NULL
, E_NOINTERFACE
},
1670 {&IID_IDirect3DExecuteBuffer
, NULL
, E_NOINTERFACE
},
1671 {&IID_IDirect3DViewport
, NULL
, E_NOINTERFACE
},
1672 {&IID_IDirect3DViewport2
, NULL
, E_NOINTERFACE
},
1673 {&IID_IDirect3DViewport3
, NULL
, E_NOINTERFACE
},
1674 {&IID_IDirect3DVertexBuffer
, NULL
, E_NOINTERFACE
},
1675 {&IID_IDirect3DVertexBuffer7
, NULL
, E_NOINTERFACE
},
1676 {&IID_IDirectDrawPalette
, NULL
, E_NOINTERFACE
},
1677 {&IID_IDirectDrawClipper
, NULL
, E_NOINTERFACE
},
1678 {&IID_IUnknown
, &IID_IDirectDrawSurface
, S_OK
},
1681 IDirectDrawSurface7
*surface
;
1682 DDSURFACEDESC2 surface_desc
;
1683 IDirect3DDevice7
*device
;
1684 IDirectDraw7
*ddraw
;
1688 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1689 0, 0, 640, 480, 0, 0, 0, 0);
1690 /* Try to create a D3D device to see if the ddraw implementation supports
1691 * D3D. 64-bit ddraw in particular doesn't seem to support D3D, and
1692 * doesn't support e.g. the IDirect3DTexture interfaces. */
1693 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
1695 skip("Failed to create D3D device, skipping test.\n");
1696 DestroyWindow(window
);
1699 IDirect3DDevice_Release(device
);
1700 if (!(ddraw
= create_ddraw()))
1702 skip("Failed to create a ddraw object, skipping test.\n");
1703 DestroyWindow(window
);
1706 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
1707 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
1709 memset(&surface_desc
, 0, sizeof(surface_desc
));
1710 surface_desc
.dwSize
= sizeof(surface_desc
);
1711 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
1712 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1713 surface_desc
.dwWidth
= 512;
1714 surface_desc
.dwHeight
= 512;
1715 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1716 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
1718 test_qi("surface_qi", (IUnknown
*)surface
, &IID_IDirectDrawSurface7
, tests
, sizeof(tests
) / sizeof(*tests
));
1720 IDirectDrawSurface7_Release(surface
);
1721 IDirectDraw7_Release(ddraw
);
1722 DestroyWindow(window
);
1725 static void test_device_qi(void)
1727 static const struct qi_test tests
[] =
1729 {&IID_IDirect3DTexture2
, NULL
, E_NOINTERFACE
},
1730 {&IID_IDirect3DTexture
, NULL
, E_NOINTERFACE
},
1731 {&IID_IDirectDrawGammaControl
, NULL
, E_NOINTERFACE
},
1732 {&IID_IDirectDrawColorControl
, NULL
, E_NOINTERFACE
},
1733 {&IID_IDirectDrawSurface7
, NULL
, E_NOINTERFACE
},
1734 {&IID_IDirectDrawSurface4
, NULL
, E_NOINTERFACE
},
1735 {&IID_IDirectDrawSurface3
, NULL
, E_NOINTERFACE
},
1736 {&IID_IDirectDrawSurface2
, NULL
, E_NOINTERFACE
},
1737 {&IID_IDirectDrawSurface
, NULL
, E_NOINTERFACE
},
1738 {&IID_IDirect3DDevice7
, &IID_IDirect3DDevice7
, S_OK
},
1739 {&IID_IDirect3DDevice3
, NULL
, E_NOINTERFACE
},
1740 {&IID_IDirect3DDevice2
, NULL
, E_NOINTERFACE
},
1741 {&IID_IDirect3DDevice
, NULL
, E_NOINTERFACE
},
1742 {&IID_IDirect3DRampDevice
, NULL
, E_NOINTERFACE
},
1743 {&IID_IDirect3DRGBDevice
, NULL
, E_NOINTERFACE
},
1744 {&IID_IDirect3DHALDevice
, NULL
, E_NOINTERFACE
},
1745 {&IID_IDirect3DMMXDevice
, NULL
, E_NOINTERFACE
},
1746 {&IID_IDirect3DRefDevice
, NULL
, E_NOINTERFACE
},
1747 {&IID_IDirect3DTnLHalDevice
, NULL
, E_NOINTERFACE
},
1748 {&IID_IDirect3DNullDevice
, NULL
, E_NOINTERFACE
},
1749 {&IID_IDirect3D7
, NULL
, E_NOINTERFACE
},
1750 {&IID_IDirect3D3
, NULL
, E_NOINTERFACE
},
1751 {&IID_IDirect3D2
, NULL
, E_NOINTERFACE
},
1752 {&IID_IDirect3D
, NULL
, E_NOINTERFACE
},
1753 {&IID_IDirectDraw7
, NULL
, E_NOINTERFACE
},
1754 {&IID_IDirectDraw4
, NULL
, E_NOINTERFACE
},
1755 {&IID_IDirectDraw3
, NULL
, E_NOINTERFACE
},
1756 {&IID_IDirectDraw2
, NULL
, E_NOINTERFACE
},
1757 {&IID_IDirectDraw
, NULL
, E_NOINTERFACE
},
1758 {&IID_IDirect3DLight
, NULL
, E_NOINTERFACE
},
1759 {&IID_IDirect3DMaterial
, NULL
, E_NOINTERFACE
},
1760 {&IID_IDirect3DMaterial2
, NULL
, E_NOINTERFACE
},
1761 {&IID_IDirect3DMaterial3
, NULL
, E_NOINTERFACE
},
1762 {&IID_IDirect3DExecuteBuffer
, NULL
, E_NOINTERFACE
},
1763 {&IID_IDirect3DViewport
, NULL
, E_NOINTERFACE
},
1764 {&IID_IDirect3DViewport2
, NULL
, E_NOINTERFACE
},
1765 {&IID_IDirect3DViewport3
, NULL
, E_NOINTERFACE
},
1766 {&IID_IDirect3DVertexBuffer
, NULL
, E_NOINTERFACE
},
1767 {&IID_IDirect3DVertexBuffer7
, NULL
, E_NOINTERFACE
},
1768 {&IID_IDirectDrawPalette
, NULL
, E_NOINTERFACE
},
1769 {&IID_IDirectDrawClipper
, NULL
, E_NOINTERFACE
},
1770 {&IID_IUnknown
, &IID_IDirect3DDevice7
, S_OK
},
1773 IDirect3DDevice7
*device
;
1776 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1777 0, 0, 640, 480, 0, 0, 0, 0);
1778 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
1780 skip("Failed to create D3D device, skipping test.\n");
1781 DestroyWindow(window
);
1785 test_qi("device_qi", (IUnknown
*)device
, &IID_IDirect3DDevice7
, tests
, sizeof(tests
) / sizeof(*tests
));
1787 IDirect3DDevice7_Release(device
);
1788 DestroyWindow(window
);
1791 static void test_wndproc(void)
1793 LONG_PTR proc
, ddraw_proc
;
1794 IDirectDraw7
*ddraw
;
1800 static const UINT messages
[] =
1802 WM_WINDOWPOSCHANGING
,
1805 WM_WINDOWPOSCHANGING
,
1811 /* DDSCL_EXCLUSIVE replaces the window's window proc. */
1812 if (!(ddraw
= create_ddraw()))
1814 skip("Failed to create IDirectDraw7 object, skipping tests.\n");
1818 wc
.lpfnWndProc
= test_proc
;
1819 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
1820 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
1822 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test",
1823 WS_MAXIMIZE
| WS_CAPTION
, 0, 0, 640, 480, 0, 0, 0, 0);
1825 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1826 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1827 (LONG_PTR
)test_proc
, proc
);
1828 expect_messages
= messages
;
1829 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1830 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
1831 ok(!*expect_messages
, "Expected message %#x, but didn't receive it.\n", *expect_messages
);
1832 expect_messages
= NULL
;
1833 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1834 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
1835 (LONG_PTR
)test_proc
, proc
);
1836 ref
= IDirectDraw7_Release(ddraw
);
1837 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
1838 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1839 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1840 (LONG_PTR
)test_proc
, proc
);
1842 /* DDSCL_NORMAL doesn't. */
1843 ddraw
= create_ddraw();
1844 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1845 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1846 (LONG_PTR
)test_proc
, proc
);
1847 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
1848 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
1849 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1850 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1851 (LONG_PTR
)test_proc
, proc
);
1852 ref
= IDirectDraw7_Release(ddraw
);
1853 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
1854 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1855 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1856 (LONG_PTR
)test_proc
, proc
);
1858 /* The original window proc is only restored by ddraw if the current
1859 * window proc matches the one ddraw set. This also affects switching
1860 * from DDSCL_NORMAL to DDSCL_EXCLUSIVE. */
1861 ddraw
= create_ddraw();
1862 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1863 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1864 (LONG_PTR
)test_proc
, proc
);
1865 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1866 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
1867 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1868 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
1869 (LONG_PTR
)test_proc
, proc
);
1871 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
1872 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
1873 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1874 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1875 (LONG_PTR
)test_proc
, proc
);
1876 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1877 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
1878 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, (LONG_PTR
)DefWindowProcA
);
1879 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
1880 (LONG_PTR
)test_proc
, proc
);
1881 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
1882 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
1883 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1884 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#lx, got %#lx.\n",
1885 (LONG_PTR
)DefWindowProcA
, proc
);
1886 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1887 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
1888 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, (LONG_PTR
)ddraw_proc
);
1889 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#lx, got %#lx.\n",
1890 (LONG_PTR
)DefWindowProcA
, proc
);
1891 ref
= IDirectDraw7_Release(ddraw
);
1892 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
1893 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1894 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1895 (LONG_PTR
)test_proc
, proc
);
1897 ddraw
= create_ddraw();
1898 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1899 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1900 (LONG_PTR
)test_proc
, proc
);
1901 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1902 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
1903 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, (LONG_PTR
)DefWindowProcA
);
1904 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
1905 (LONG_PTR
)test_proc
, proc
);
1906 ref
= IDirectDraw7_Release(ddraw
);
1907 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
1908 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1909 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#lx, got %#lx.\n",
1910 (LONG_PTR
)DefWindowProcA
, proc
);
1912 fix_wndproc(window
, (LONG_PTR
)test_proc
);
1913 expect_messages
= NULL
;
1914 DestroyWindow(window
);
1915 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
1918 static void test_window_style(void)
1920 LONG style
, exstyle
, tmp
;
1921 RECT fullscreen_rect
, r
;
1922 IDirectDraw7
*ddraw
;
1927 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1928 0, 0, 100, 100, 0, 0, 0, 0);
1929 if (!(ddraw
= create_ddraw()))
1931 skip("Failed to create a ddraw object, skipping test.\n");
1932 DestroyWindow(window
);
1936 style
= GetWindowLongA(window
, GWL_STYLE
);
1937 exstyle
= GetWindowLongA(window
, GWL_EXSTYLE
);
1938 SetRect(&fullscreen_rect
, 0, 0, GetSystemMetrics(SM_CXSCREEN
), GetSystemMetrics(SM_CYSCREEN
));
1940 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1941 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
1943 tmp
= GetWindowLongA(window
, GWL_STYLE
);
1944 todo_wine
ok(tmp
== style
, "Expected window style %#x, got %#x.\n", style
, tmp
);
1945 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
1946 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#x, got %#x.\n", exstyle
, tmp
);
1948 GetWindowRect(window
, &r
);
1949 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
1950 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
1951 r
.left
, r
.top
, r
.right
, r
.bottom
);
1952 GetClientRect(window
, &r
);
1953 todo_wine
ok(!EqualRect(&r
, &fullscreen_rect
), "Client rect and window rect are equal.\n");
1955 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
1956 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
1958 tmp
= GetWindowLongA(window
, GWL_STYLE
);
1959 todo_wine
ok(tmp
== style
, "Expected window style %#x, got %#x.\n", style
, tmp
);
1960 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
1961 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#x, got %#x.\n", exstyle
, tmp
);
1963 ref
= IDirectDraw7_Release(ddraw
);
1964 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
1966 DestroyWindow(window
);
1969 static void test_redundant_mode_set(void)
1971 DDSURFACEDESC2 surface_desc
= {0};
1972 IDirectDraw7
*ddraw
;
1978 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1979 0, 0, 100, 100, 0, 0, 0, 0);
1980 if (!(ddraw
= create_ddraw()))
1982 skip("Failed to create a ddraw object, skipping test.\n");
1983 DestroyWindow(window
);
1987 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1988 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
1990 surface_desc
.dwSize
= sizeof(surface_desc
);
1991 hr
= IDirectDraw7_GetDisplayMode(ddraw
, &surface_desc
);
1992 ok(SUCCEEDED(hr
), "GetDipslayMode failed, hr %#x.\n", hr
);
1994 hr
= IDirectDraw7_SetDisplayMode(ddraw
, surface_desc
.dwWidth
, surface_desc
.dwHeight
,
1995 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
, 0, 0);
1996 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
1998 GetWindowRect(window
, &r
);
2001 SetWindowPos(window
, HWND_TOP
, r
.left
, r
.top
, r
.right
, r
.bottom
, 0);
2002 GetWindowRect(window
, &s
);
2003 ok(EqualRect(&r
, &s
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2004 r
.left
, r
.top
, r
.right
, r
.bottom
,
2005 s
.left
, s
.top
, s
.right
, s
.bottom
);
2007 hr
= IDirectDraw7_SetDisplayMode(ddraw
, surface_desc
.dwWidth
, surface_desc
.dwHeight
,
2008 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
, 0, 0);
2009 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2011 GetWindowRect(window
, &s
);
2012 ok(EqualRect(&r
, &s
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2013 r
.left
, r
.top
, r
.right
, r
.bottom
,
2014 s
.left
, s
.top
, s
.right
, s
.bottom
);
2016 ref
= IDirectDraw7_Release(ddraw
);
2017 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2019 DestroyWindow(window
);
2022 static SIZE screen_size
, screen_size2
;
2024 static LRESULT CALLBACK
mode_set_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
2026 if (message
== WM_SIZE
)
2028 screen_size
.cx
= GetSystemMetrics(SM_CXSCREEN
);
2029 screen_size
.cy
= GetSystemMetrics(SM_CYSCREEN
);
2032 return test_proc(hwnd
, message
, wparam
, lparam
);
2035 static LRESULT CALLBACK
mode_set_proc2(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
2037 if (message
== WM_SIZE
)
2039 screen_size2
.cx
= GetSystemMetrics(SM_CXSCREEN
);
2040 screen_size2
.cy
= GetSystemMetrics(SM_CYSCREEN
);
2043 return test_proc(hwnd
, message
, wparam
, lparam
);
2046 static void test_coop_level_mode_set(void)
2048 IDirectDrawSurface7
*primary
;
2049 RECT fullscreen_rect
, r
, s
;
2050 IDirectDraw7
*ddraw
;
2051 DDSURFACEDESC2 ddsd
;
2053 HWND window
, window2
;
2057 static const UINT exclusive_messages
[] =
2059 WM_WINDOWPOSCHANGING
,
2060 WM_WINDOWPOSCHANGED
,
2066 static const UINT normal_messages
[] =
2072 if (!(ddraw
= create_ddraw()))
2074 skip("Failed to create a ddraw object, skipping test.\n");
2078 wc
.lpfnWndProc
= mode_set_proc
;
2079 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
2080 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
2081 wc
.lpfnWndProc
= mode_set_proc2
;
2082 wc
.lpszClassName
= "ddraw_test_wndproc_wc2";
2083 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
2085 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2086 0, 0, 100, 100, 0, 0, 0, 0);
2087 window2
= CreateWindowA("ddraw_test_wndproc_wc2", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2088 0, 0, 100, 100, 0, 0, 0, 0);
2090 SetRect(&fullscreen_rect
, 0, 0, GetSystemMetrics(SM_CXSCREEN
), GetSystemMetrics(SM_CYSCREEN
));
2091 SetRect(&s
, 0, 0, 640, 480);
2093 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2094 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2096 GetWindowRect(window
, &r
);
2097 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2098 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2099 r
.left
, r
.top
, r
.right
, r
.bottom
);
2101 memset(&ddsd
, 0, sizeof(ddsd
));
2102 ddsd
.dwSize
= sizeof(ddsd
);
2103 ddsd
.dwFlags
= DDSD_CAPS
;
2104 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2106 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2107 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2108 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
2109 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2110 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2111 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2112 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2113 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2115 GetWindowRect(window
, &r
);
2116 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2117 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2118 r
.left
, r
.top
, r
.right
, r
.bottom
);
2120 expect_messages
= exclusive_messages
;
2124 hr
= IDirectDraw7_SetDisplayMode(ddraw
, 640, 480, 32, 0, 0);
2125 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2127 ok(!*expect_messages
, "Expected message %#x, but didn't receive it.\n", *expect_messages
);
2128 expect_messages
= NULL
;
2129 ok(screen_size
.cx
== s
.right
&& screen_size
.cy
== s
.bottom
,
2130 "Expected screen size %ux%u, got %ux%u.\n",
2131 s
.right
, s
.bottom
, screen_size
.cx
, screen_size
.cy
);
2133 GetWindowRect(window
, &r
);
2134 ok(EqualRect(&r
, &s
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2135 s
.left
, s
.top
, s
.right
, s
.bottom
,
2136 r
.left
, r
.top
, r
.right
, r
.bottom
);
2138 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
2139 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2140 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2141 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2142 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2143 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2144 IDirectDrawSurface7_Release(primary
);
2146 memset(&ddsd
, 0, sizeof(ddsd
));
2147 ddsd
.dwSize
= sizeof(ddsd
);
2148 ddsd
.dwFlags
= DDSD_CAPS
;
2149 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2151 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2152 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2153 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
2154 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2155 ok(ddsd
.dwWidth
== s
.right
- s
.left
, "Expected surface width %u, got %u.\n",
2156 s
.right
- s
.left
, ddsd
.dwWidth
);
2157 ok(ddsd
.dwHeight
== s
.bottom
- s
.top
, "Expected surface height %u, got %u.\n",
2158 s
.bottom
- s
.top
, ddsd
.dwHeight
);
2160 GetWindowRect(window
, &r
);
2161 ok(EqualRect(&r
, &s
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2162 s
.left
, s
.top
, s
.right
, s
.bottom
,
2163 r
.left
, r
.top
, r
.right
, r
.bottom
);
2165 expect_messages
= exclusive_messages
;
2169 hr
= IDirectDraw_RestoreDisplayMode(ddraw
);
2170 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
2172 ok(!*expect_messages
, "Expected message %#x, but didn't receive it.\n", *expect_messages
);
2173 expect_messages
= NULL
;
2174 ok(screen_size
.cx
== fullscreen_rect
.right
&& screen_size
.cy
== fullscreen_rect
.bottom
,
2175 "Expected screen size %ux%u, got %ux%u.\n",
2176 fullscreen_rect
.right
, fullscreen_rect
.bottom
, screen_size
.cx
, screen_size
.cy
);
2178 GetWindowRect(window
, &r
);
2179 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2180 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2181 r
.left
, r
.top
, r
.right
, r
.bottom
);
2183 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
2184 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2185 ok(ddsd
.dwWidth
== s
.right
- s
.left
, "Expected surface width %u, got %u.\n",
2186 s
.right
- s
.left
, ddsd
.dwWidth
);
2187 ok(ddsd
.dwHeight
== s
.bottom
- s
.top
, "Expected surface height %u, got %u.\n",
2188 s
.bottom
- s
.top
, ddsd
.dwHeight
);
2189 IDirectDrawSurface7_Release(primary
);
2191 memset(&ddsd
, 0, sizeof(ddsd
));
2192 ddsd
.dwSize
= sizeof(ddsd
);
2193 ddsd
.dwFlags
= DDSD_CAPS
;
2194 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2196 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2197 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2198 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
2199 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2200 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2201 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2202 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2203 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2205 GetWindowRect(window
, &r
);
2206 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2207 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2208 r
.left
, r
.top
, r
.right
, r
.bottom
);
2210 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2211 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2213 GetWindowRect(window
, &r
);
2214 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2215 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2216 r
.left
, r
.top
, r
.right
, r
.bottom
);
2218 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
2219 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2220 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2221 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2222 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2223 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2224 IDirectDrawSurface7_Release(primary
);
2226 memset(&ddsd
, 0, sizeof(ddsd
));
2227 ddsd
.dwSize
= sizeof(ddsd
);
2228 ddsd
.dwFlags
= DDSD_CAPS
;
2229 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2231 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2232 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2233 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
2234 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2235 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2236 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2237 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2238 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2240 GetWindowRect(window
, &r
);
2241 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2242 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2243 r
.left
, r
.top
, r
.right
, r
.bottom
);
2245 expect_messages
= normal_messages
;
2249 hr
= IDirectDraw7_SetDisplayMode(ddraw
, 640, 480, 32, 0, 0);
2250 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2252 ok(!*expect_messages
, "Expected message %#x, but didn't receive it.\n", *expect_messages
);
2253 expect_messages
= NULL
;
2254 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unxpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
2256 GetWindowRect(window
, &r
);
2257 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2258 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2259 r
.left
, r
.top
, r
.right
, r
.bottom
);
2261 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
2262 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2263 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2264 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2265 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2266 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2267 IDirectDrawSurface7_Release(primary
);
2269 memset(&ddsd
, 0, sizeof(ddsd
));
2270 ddsd
.dwSize
= sizeof(ddsd
);
2271 ddsd
.dwFlags
= DDSD_CAPS
;
2272 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2274 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2275 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2276 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
2277 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2278 ok(ddsd
.dwWidth
== s
.right
- s
.left
, "Expected surface width %u, got %u.\n",
2279 s
.right
- s
.left
, ddsd
.dwWidth
);
2280 ok(ddsd
.dwHeight
== s
.bottom
- s
.top
, "Expected surface height %u, got %u.\n",
2281 s
.bottom
- s
.top
, ddsd
.dwHeight
);
2283 GetWindowRect(window
, &r
);
2284 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2285 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2286 r
.left
, r
.top
, r
.right
, r
.bottom
);
2288 expect_messages
= normal_messages
;
2292 hr
= IDirectDraw_RestoreDisplayMode(ddraw
);
2293 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
2295 ok(!*expect_messages
, "Expected message %#x, but didn't receive it.\n", *expect_messages
);
2296 expect_messages
= NULL
;
2297 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unxpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
2299 GetWindowRect(window
, &r
);
2300 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2301 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2302 r
.left
, r
.top
, r
.right
, r
.bottom
);
2304 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
2305 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2306 ok(ddsd
.dwWidth
== s
.right
- s
.left
, "Expected surface width %u, got %u.\n",
2307 s
.right
- s
.left
, ddsd
.dwWidth
);
2308 ok(ddsd
.dwHeight
== s
.bottom
- s
.top
, "Expected surface height %u, got %u.\n",
2309 s
.bottom
- s
.top
, ddsd
.dwHeight
);
2310 IDirectDrawSurface7_Release(primary
);
2312 memset(&ddsd
, 0, sizeof(ddsd
));
2313 ddsd
.dwSize
= sizeof(ddsd
);
2314 ddsd
.dwFlags
= DDSD_CAPS
;
2315 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2317 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2318 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2319 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
2320 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2321 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2322 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2323 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2324 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2326 GetWindowRect(window
, &r
);
2327 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2328 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2329 r
.left
, r
.top
, r
.right
, r
.bottom
);
2331 /* DDSCL_NORMAL | DDSCL_FULLSCREEN behaves the same as just DDSCL_NORMAL.
2332 * Resizing the window on mode changes is a property of DDSCL_EXCLUSIVE,
2333 * not DDSCL_FULLSCREEN. */
2334 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
2335 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2337 GetWindowRect(window
, &r
);
2338 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2339 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2340 r
.left
, r
.top
, r
.right
, r
.bottom
);
2342 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
2343 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2344 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2345 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2346 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2347 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2348 IDirectDrawSurface7_Release(primary
);
2350 memset(&ddsd
, 0, sizeof(ddsd
));
2351 ddsd
.dwSize
= sizeof(ddsd
);
2352 ddsd
.dwFlags
= DDSD_CAPS
;
2353 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2355 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2356 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2357 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
2358 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2359 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2360 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2361 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2362 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2364 GetWindowRect(window
, &r
);
2365 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2366 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2367 r
.left
, r
.top
, r
.right
, r
.bottom
);
2369 expect_messages
= normal_messages
;
2373 hr
= IDirectDraw7_SetDisplayMode(ddraw
, 640, 480, 32, 0, 0);
2374 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2376 ok(!*expect_messages
, "Expected message %#x, but didn't receive it.\n", *expect_messages
);
2377 expect_messages
= NULL
;
2378 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unxpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
2380 GetWindowRect(window
, &r
);
2381 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2382 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2383 r
.left
, r
.top
, r
.right
, r
.bottom
);
2385 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
2386 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2387 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2388 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2389 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2390 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2391 IDirectDrawSurface7_Release(primary
);
2393 memset(&ddsd
, 0, sizeof(ddsd
));
2394 ddsd
.dwSize
= sizeof(ddsd
);
2395 ddsd
.dwFlags
= DDSD_CAPS
;
2396 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2398 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2399 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2400 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
2401 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2402 ok(ddsd
.dwWidth
== s
.right
- s
.left
, "Expected surface width %u, got %u.\n",
2403 s
.right
- s
.left
, ddsd
.dwWidth
);
2404 ok(ddsd
.dwHeight
== s
.bottom
- s
.top
, "Expected surface height %u, got %u.\n",
2405 s
.bottom
- s
.top
, ddsd
.dwHeight
);
2407 GetWindowRect(window
, &r
);
2408 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2409 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2410 r
.left
, r
.top
, r
.right
, r
.bottom
);
2412 expect_messages
= normal_messages
;
2416 hr
= IDirectDraw_RestoreDisplayMode(ddraw
);
2417 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
2419 ok(!*expect_messages
, "Expected message %#x, but didn't receive it.\n", *expect_messages
);
2420 expect_messages
= NULL
;
2421 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unxpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
2423 GetWindowRect(window
, &r
);
2424 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2425 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2426 r
.left
, r
.top
, r
.right
, r
.bottom
);
2428 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
2429 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2430 ok(ddsd
.dwWidth
== s
.right
- s
.left
, "Expected surface width %u, got %u.\n",
2431 s
.right
- s
.left
, ddsd
.dwWidth
);
2432 ok(ddsd
.dwHeight
== s
.bottom
- s
.top
, "Expected surface height %u, got %u.\n",
2433 s
.bottom
- s
.top
, ddsd
.dwHeight
);
2434 IDirectDrawSurface7_Release(primary
);
2436 memset(&ddsd
, 0, sizeof(ddsd
));
2437 ddsd
.dwSize
= sizeof(ddsd
);
2438 ddsd
.dwFlags
= DDSD_CAPS
;
2439 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2441 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2442 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2443 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
2444 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2445 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2446 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2447 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2448 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2449 IDirectDrawSurface7_Release(primary
);
2451 GetWindowRect(window
, &r
);
2452 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2453 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2454 r
.left
, r
.top
, r
.right
, r
.bottom
);
2456 /* Changing the coop level from EXCLUSIVE to NORMAL restores the screen resolution */
2457 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2458 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2459 hr
= IDirectDraw7_SetDisplayMode(ddraw
, 640, 480, 32, 0, 0);
2460 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2462 expect_messages
= exclusive_messages
;
2466 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2467 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2469 ok(!*expect_messages
, "Expected message %#x, but didn't receive it.\n", *expect_messages
);
2470 expect_messages
= NULL
;
2471 ok(screen_size
.cx
== fullscreen_rect
.right
&& screen_size
.cy
== fullscreen_rect
.bottom
,
2472 "Expected screen size %ux%u, got %ux%u.\n",
2473 fullscreen_rect
.right
, fullscreen_rect
.bottom
, screen_size
.cx
, screen_size
.cy
);
2475 GetWindowRect(window
, &r
);
2476 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2477 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2478 r
.left
, r
.top
, r
.right
, r
.bottom
);
2480 memset(&ddsd
, 0, sizeof(ddsd
));
2481 ddsd
.dwSize
= sizeof(ddsd
);
2482 ddsd
.dwFlags
= DDSD_CAPS
;
2483 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2485 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2486 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2487 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
2488 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2489 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2490 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2491 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2492 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2493 IDirectDrawSurface7_Release(primary
);
2495 /* The screen restore is a property of DDSCL_EXCLUSIVE */
2496 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
2497 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2498 hr
= IDirectDraw7_SetDisplayMode(ddraw
, 640, 480, 32, 0, 0);
2499 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2501 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2502 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2504 memset(&ddsd
, 0, sizeof(ddsd
));
2505 ddsd
.dwSize
= sizeof(ddsd
);
2506 ddsd
.dwFlags
= DDSD_CAPS
;
2507 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2509 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2510 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2511 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
2512 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2513 ok(ddsd
.dwWidth
== s
.right
- s
.left
, "Expected surface width %u, got %u.\n",
2514 s
.right
- s
.left
, ddsd
.dwWidth
);
2515 ok(ddsd
.dwHeight
== s
.bottom
- s
.top
, "Expected surface height %u, got %u.\n",
2516 s
.bottom
- s
.top
, ddsd
.dwHeight
);
2517 IDirectDrawSurface7_Release(primary
);
2519 hr
= IDirectDraw_RestoreDisplayMode(ddraw
);
2520 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
2522 /* If the window is changed at the same time, messages are sent to the new window. */
2523 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2524 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2525 hr
= IDirectDraw7_SetDisplayMode(ddraw
, 640, 480, 32, 0, 0);
2526 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2528 expect_messages
= exclusive_messages
;
2531 screen_size2
.cx
= 0;
2532 screen_size2
.cy
= 0;
2534 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
);
2535 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2537 ok(!*expect_messages
, "Expected message %#x, but didn't receive it.\n", *expect_messages
);
2538 expect_messages
= NULL
;
2539 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unxpected screen size %ux%u.\n",
2540 screen_size
.cx
, screen_size
.cy
);
2541 ok(screen_size2
.cx
== fullscreen_rect
.right
&& screen_size2
.cy
== fullscreen_rect
.bottom
,
2542 "Expected screen size 2 %ux%u, got %ux%u.\n",
2543 fullscreen_rect
.right
, fullscreen_rect
.bottom
, screen_size2
.cx
, screen_size2
.cy
);
2545 GetWindowRect(window
, &r
);
2546 ok(EqualRect(&r
, &s
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2547 s
.left
, s
.top
, s
.right
, s
.bottom
,
2548 r
.left
, r
.top
, r
.right
, r
.bottom
);
2549 GetWindowRect(window2
, &r
);
2550 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2551 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2552 r
.left
, r
.top
, r
.right
, r
.bottom
);
2554 memset(&ddsd
, 0, sizeof(ddsd
));
2555 ddsd
.dwSize
= sizeof(ddsd
);
2556 ddsd
.dwFlags
= DDSD_CAPS
;
2557 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2559 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2560 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2561 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
2562 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2563 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2564 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2565 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2566 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2567 IDirectDrawSurface7_Release(primary
);
2569 ref
= IDirectDraw7_Release(ddraw
);
2570 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2572 GetWindowRect(window
, &r
);
2573 ok(EqualRect(&r
, &s
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2574 s
.left
, s
.top
, s
.right
, s
.bottom
,
2575 r
.left
, r
.top
, r
.right
, r
.bottom
);
2577 expect_messages
= NULL
;
2578 DestroyWindow(window
);
2579 DestroyWindow(window2
);
2580 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
2581 UnregisterClassA("ddraw_test_wndproc_wc2", GetModuleHandleA(NULL
));
2584 static void test_coop_level_mode_set_multi(void)
2586 IDirectDraw7
*ddraw1
, *ddraw2
;
2587 UINT orig_w
, orig_h
, w
, h
;
2592 if (!(ddraw1
= create_ddraw()))
2594 skip("Failed to create a ddraw object, skipping test.\n");
2598 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2599 0, 0, 100, 100, 0, 0, 0, 0);
2601 orig_w
= GetSystemMetrics(SM_CXSCREEN
);
2602 orig_h
= GetSystemMetrics(SM_CYSCREEN
);
2604 /* With just a single ddraw object, the display mode is restored on
2606 hr
= IDirectDraw7_SetDisplayMode(ddraw1
, 800, 600, 32, 0, 0);
2607 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2608 w
= GetSystemMetrics(SM_CXSCREEN
);
2609 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
2610 h
= GetSystemMetrics(SM_CYSCREEN
);
2611 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
2613 ref
= IDirectDraw7_Release(ddraw1
);
2614 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2615 w
= GetSystemMetrics(SM_CXSCREEN
);
2616 ok(w
== orig_w
, "Got unexpected screen width %u.\n", w
);
2617 h
= GetSystemMetrics(SM_CYSCREEN
);
2618 ok(h
== orig_h
, "Got unexpected screen height %u.\n", h
);
2620 /* When there are multiple ddraw objects, the display mode is restored to
2621 * the initial mode, before the first SetDisplayMode() call. */
2622 ddraw1
= create_ddraw();
2623 hr
= IDirectDraw7_SetDisplayMode(ddraw1
, 800, 600, 32, 0, 0);
2624 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2625 w
= GetSystemMetrics(SM_CXSCREEN
);
2626 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
2627 h
= GetSystemMetrics(SM_CYSCREEN
);
2628 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
2630 ddraw2
= create_ddraw();
2631 hr
= IDirectDraw7_SetDisplayMode(ddraw2
, 640, 480, 32, 0, 0);
2632 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2633 w
= GetSystemMetrics(SM_CXSCREEN
);
2634 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
2635 h
= GetSystemMetrics(SM_CYSCREEN
);
2636 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
2638 ref
= IDirectDraw7_Release(ddraw2
);
2639 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2640 w
= GetSystemMetrics(SM_CXSCREEN
);
2641 ok(w
== orig_w
, "Got unexpected screen width %u.\n", w
);
2642 h
= GetSystemMetrics(SM_CYSCREEN
);
2643 ok(h
== orig_h
, "Got unexpected screen height %u.\n", h
);
2645 ref
= IDirectDraw7_Release(ddraw1
);
2646 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2647 w
= GetSystemMetrics(SM_CXSCREEN
);
2648 ok(w
== orig_w
, "Got unexpected screen width %u.\n", w
);
2649 h
= GetSystemMetrics(SM_CYSCREEN
);
2650 ok(h
== orig_h
, "Got unexpected screen height %u.\n", h
);
2652 /* Regardless of release ordering. */
2653 ddraw1
= create_ddraw();
2654 hr
= IDirectDraw7_SetDisplayMode(ddraw1
, 800, 600, 32, 0, 0);
2655 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2656 w
= GetSystemMetrics(SM_CXSCREEN
);
2657 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
2658 h
= GetSystemMetrics(SM_CYSCREEN
);
2659 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
2661 ddraw2
= create_ddraw();
2662 hr
= IDirectDraw7_SetDisplayMode(ddraw2
, 640, 480, 32, 0, 0);
2663 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2664 w
= GetSystemMetrics(SM_CXSCREEN
);
2665 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
2666 h
= GetSystemMetrics(SM_CYSCREEN
);
2667 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
2669 ref
= IDirectDraw7_Release(ddraw1
);
2670 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2671 w
= GetSystemMetrics(SM_CXSCREEN
);
2672 ok(w
== orig_w
, "Got unexpected screen width %u.\n", w
);
2673 h
= GetSystemMetrics(SM_CYSCREEN
);
2674 ok(h
== orig_h
, "Got unexpected screen height %u.\n", h
);
2676 ref
= IDirectDraw7_Release(ddraw2
);
2677 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2678 w
= GetSystemMetrics(SM_CXSCREEN
);
2679 ok(w
== orig_w
, "Got unexpected screen width %u.\n", w
);
2680 h
= GetSystemMetrics(SM_CYSCREEN
);
2681 ok(h
== orig_h
, "Got unexpected screen height %u.\n", h
);
2683 /* But only for ddraw objects that called SetDisplayMode(). */
2684 ddraw1
= create_ddraw();
2685 ddraw2
= create_ddraw();
2686 hr
= IDirectDraw7_SetDisplayMode(ddraw2
, 640, 480, 32, 0, 0);
2687 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2688 w
= GetSystemMetrics(SM_CXSCREEN
);
2689 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
2690 h
= GetSystemMetrics(SM_CYSCREEN
);
2691 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
2693 ref
= IDirectDraw7_Release(ddraw1
);
2694 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2695 w
= GetSystemMetrics(SM_CXSCREEN
);
2696 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
2697 h
= GetSystemMetrics(SM_CYSCREEN
);
2698 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
2700 ref
= IDirectDraw7_Release(ddraw2
);
2701 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2702 w
= GetSystemMetrics(SM_CXSCREEN
);
2703 ok(w
== orig_w
, "Got unexpected screen width %u.\n", w
);
2704 h
= GetSystemMetrics(SM_CYSCREEN
);
2705 ok(h
== orig_h
, "Got unexpected screen height %u.\n", h
);
2707 /* If there's a ddraw object that's currently in exclusive mode, it blocks
2708 * restoring the display mode. */
2709 ddraw1
= create_ddraw();
2710 hr
= IDirectDraw7_SetDisplayMode(ddraw1
, 800, 600, 32, 0, 0);
2711 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2712 w
= GetSystemMetrics(SM_CXSCREEN
);
2713 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
2714 h
= GetSystemMetrics(SM_CYSCREEN
);
2715 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
2717 ddraw2
= create_ddraw();
2718 hr
= IDirectDraw7_SetDisplayMode(ddraw2
, 640, 480, 32, 0, 0);
2719 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2720 w
= GetSystemMetrics(SM_CXSCREEN
);
2721 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
2722 h
= GetSystemMetrics(SM_CYSCREEN
);
2723 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
2725 hr
= IDirectDraw7_SetCooperativeLevel(ddraw2
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2726 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2728 ref
= IDirectDraw7_Release(ddraw1
);
2729 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2730 w
= GetSystemMetrics(SM_CXSCREEN
);
2731 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
2732 h
= GetSystemMetrics(SM_CYSCREEN
);
2733 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
2735 ref
= IDirectDraw7_Release(ddraw2
);
2736 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2737 w
= GetSystemMetrics(SM_CXSCREEN
);
2738 ok(w
== orig_w
, "Got unexpected screen width %u.\n", w
);
2739 h
= GetSystemMetrics(SM_CYSCREEN
);
2740 ok(h
== orig_h
, "Got unexpected screen height %u.\n", h
);
2742 /* Exclusive mode blocks mode setting on other ddraw objects in general. */
2743 ddraw1
= create_ddraw();
2744 hr
= IDirectDraw7_SetDisplayMode(ddraw1
, 800, 600, 32, 0, 0);
2745 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2746 w
= GetSystemMetrics(SM_CXSCREEN
);
2747 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
2748 h
= GetSystemMetrics(SM_CYSCREEN
);
2749 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
2751 hr
= IDirectDraw7_SetCooperativeLevel(ddraw1
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2752 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2754 ddraw2
= create_ddraw();
2755 hr
= IDirectDraw7_SetDisplayMode(ddraw2
, 640, 480, 32, 0, 0);
2756 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
2758 ref
= IDirectDraw7_Release(ddraw1
);
2759 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2760 w
= GetSystemMetrics(SM_CXSCREEN
);
2761 ok(w
== orig_w
, "Got unexpected screen width %u.\n", w
);
2762 h
= GetSystemMetrics(SM_CYSCREEN
);
2763 ok(h
== orig_h
, "Got unexpected screen height %u.\n", h
);
2765 ref
= IDirectDraw7_Release(ddraw2
);
2766 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2767 w
= GetSystemMetrics(SM_CXSCREEN
);
2768 ok(w
== orig_w
, "Got unexpected screen width %u.\n", w
);
2769 h
= GetSystemMetrics(SM_CYSCREEN
);
2770 ok(h
== orig_h
, "Got unexpected screen height %u.\n", h
);
2772 DestroyWindow(window
);
2775 static void test_initialize(void)
2777 IDirectDraw7
*ddraw
;
2780 if (!(ddraw
= create_ddraw()))
2782 skip("Failed to create a ddraw object, skipping test.\n");
2786 hr
= IDirectDraw7_Initialize(ddraw
, NULL
);
2787 ok(hr
== DDERR_ALREADYINITIALIZED
, "Initialize returned hr %#x.\n", hr
);
2788 IDirectDraw7_Release(ddraw
);
2791 hr
= CoCreateInstance(&CLSID_DirectDraw
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDirectDraw7
, (void **)&ddraw
);
2792 ok(SUCCEEDED(hr
), "Failed to create IDirectDraw7 instance, hr %#x.\n", hr
);
2793 hr
= IDirectDraw7_Initialize(ddraw
, NULL
);
2794 ok(hr
== DD_OK
, "Initialize returned hr %#x, expected DD_OK.\n", hr
);
2795 hr
= IDirectDraw7_Initialize(ddraw
, NULL
);
2796 ok(hr
== DDERR_ALREADYINITIALIZED
, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr
);
2797 IDirectDraw7_Release(ddraw
);
2801 static void test_coop_level_surf_create(void)
2803 IDirectDrawSurface7
*surface
;
2804 IDirectDraw7
*ddraw
;
2805 DDSURFACEDESC2 ddsd
;
2808 if (!(ddraw
= create_ddraw()))
2810 skip("Failed to create a ddraw object, skipping test.\n");
2814 memset(&ddsd
, 0, sizeof(ddsd
));
2815 ddsd
.dwSize
= sizeof(ddsd
);
2816 ddsd
.dwFlags
= DDSD_CAPS
;
2817 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2818 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
2819 ok(hr
== DDERR_NOCOOPERATIVELEVELSET
, "Surface creation returned hr %#x.\n", hr
);
2821 IDirectDraw7_Release(ddraw
);
2824 static void test_vb_discard(void)
2826 static const struct vec4 quad
[] =
2828 { 0.0f
, 480.0f
, 0.0f
, 1.0f
},
2829 { 0.0f
, 0.0f
, 0.0f
, 1.0f
},
2830 {640.0f
, 480.0f
, 0.0f
, 1.0f
},
2831 {640.0f
, 0.0f
, 0.0f
, 1.0f
},
2834 IDirect3DDevice7
*device
;
2836 IDirect3DVertexBuffer7
*buffer
;
2839 D3DVERTEXBUFFERDESC desc
;
2841 static const unsigned int vbsize
= 16;
2844 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2845 0, 0, 640, 480, 0, 0, 0, 0);
2847 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
2849 skip("Failed to create D3D device, skipping test.\n");
2850 DestroyWindow(window
);
2854 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
2855 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
2857 memset(&desc
, 0, sizeof(desc
));
2858 desc
.dwSize
= sizeof(desc
);
2859 desc
.dwCaps
= D3DVBCAPS_WRITEONLY
;
2860 desc
.dwFVF
= D3DFVF_XYZRHW
;
2861 desc
.dwNumVertices
= vbsize
;
2862 hr
= IDirect3D7_CreateVertexBuffer(d3d
, &desc
, &buffer
, 0);
2863 ok(SUCCEEDED(hr
), "Failed to create vertex buffer, hr %#x.\n", hr
);
2865 hr
= IDirect3DVertexBuffer7_Lock(buffer
, DDLOCK_DISCARDCONTENTS
, (void **)&data
, NULL
);
2866 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
2867 memcpy(data
, quad
, sizeof(quad
));
2868 hr
= IDirect3DVertexBuffer7_Unlock(buffer
);
2869 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
2871 hr
= IDirect3DDevice7_BeginScene(device
);
2872 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
2873 hr
= IDirect3DDevice7_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, buffer
, 0, 4, 0);
2874 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2875 hr
= IDirect3DDevice7_EndScene(device
);
2876 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
2878 hr
= IDirect3DVertexBuffer7_Lock(buffer
, DDLOCK_DISCARDCONTENTS
, (void **)&data
, NULL
);
2879 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
2880 memset(data
, 0xaa, sizeof(struct vec4
) * vbsize
);
2881 hr
= IDirect3DVertexBuffer7_Unlock(buffer
);
2882 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
2884 hr
= IDirect3DVertexBuffer7_Lock(buffer
, DDLOCK_DISCARDCONTENTS
, (void **)&data
, NULL
);
2885 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
2886 for (i
= 0; i
< sizeof(struct vec4
) * vbsize
; i
++)
2888 if (data
[i
] != 0xaa)
2890 ok(FALSE
, "Vertex buffer data byte %u is 0x%02x, expected 0xaa\n", i
, data
[i
]);
2894 hr
= IDirect3DVertexBuffer7_Unlock(buffer
);
2895 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
2897 IDirect3DVertexBuffer7_Release(buffer
);
2898 IDirect3D7_Release(d3d
);
2899 IDirect3DDevice7_Release(device
);
2900 DestroyWindow(window
);
2903 static void test_coop_level_multi_window(void)
2905 HWND window1
, window2
;
2906 IDirectDraw7
*ddraw
;
2909 window1
= CreateWindowA("static", "ddraw_test1", WS_OVERLAPPEDWINDOW
,
2910 0, 0, 640, 480, 0, 0, 0, 0);
2911 window2
= CreateWindowA("static", "ddraw_test2", WS_OVERLAPPEDWINDOW
,
2912 0, 0, 640, 480, 0, 0, 0, 0);
2913 if (!(ddraw
= create_ddraw()))
2915 skip("Failed to create a ddraw object, skipping test.\n");
2916 DestroyWindow(window2
);
2917 DestroyWindow(window1
);
2921 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
);
2922 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
2923 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
);
2924 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
2925 ok(IsWindow(window1
), "Window 1 was destroyed.\n");
2926 ok(IsWindow(window2
), "Window 2 was destroyed.\n");
2928 IDirectDraw7_Release(ddraw
);
2929 DestroyWindow(window2
);
2930 DestroyWindow(window1
);
2933 static void test_draw_strided(void)
2935 static struct vec3 position
[] =
2942 static DWORD diffuse
[] =
2944 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
2946 static WORD indices
[] =
2951 IDirectDrawSurface7
*rt
;
2952 IDirect3DDevice7
*device
;
2956 D3DDRAWPRIMITIVESTRIDEDDATA strided
;
2958 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2959 0, 0, 640, 480, 0, 0, 0, 0);
2961 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
2963 skip("Failed to create D3D device, skipping test.\n");
2964 DestroyWindow(window
);
2968 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
2969 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
2971 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
2972 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
2973 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x00000000, 1.0f
, 0);
2974 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
2975 hr
= IDirect3DDevice7_BeginScene(device
);
2976 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
2978 memset(&strided
, 0x55, sizeof(strided
));
2979 strided
.position
.lpvData
= position
;
2980 strided
.position
.dwStride
= sizeof(*position
);
2981 strided
.diffuse
.lpvData
= diffuse
;
2982 strided
.diffuse
.dwStride
= sizeof(*diffuse
);
2983 hr
= IDirect3DDevice7_DrawIndexedPrimitiveStrided(device
, D3DPT_TRIANGLELIST
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
2984 &strided
, 4, indices
, 6, 0);
2985 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2987 hr
= IDirect3DDevice7_EndScene(device
);
2988 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
2990 color
= get_surface_color(rt
, 320, 240);
2991 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
2993 IDirectDrawSurface7_Release(rt
);
2994 IDirect3DDevice7_Release(device
);
2995 DestroyWindow(window
);
2998 static void test_clear_rect_count(void)
3000 IDirectDrawSurface7
*rt
;
3001 IDirect3DDevice7
*device
;
3005 D3DRECT rect
= {{0}, {0}, {640}, {480}};
3007 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
3008 0, 0, 640, 480, 0, 0, 0, 0);
3009 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
3011 skip("Failed to create D3D device, skipping test.\n");
3012 DestroyWindow(window
);
3016 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
3017 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
3019 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x00ffffff, 1.0f
, 0);
3020 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
3021 hr
= IDirect3DDevice7_Clear(device
, 0, &rect
, D3DCLEAR_TARGET
, 0x00ff0000, 1.0f
, 0);
3022 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
3024 color
= get_surface_color(rt
, 320, 240);
3025 ok(compare_color(color
, 0x00ffffff, 1),
3026 "Clear with count = 0, rect != NULL has color %#08x.\n", color
);
3028 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x00ffffff, 1.0f
, 0);
3029 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
3030 hr
= IDirect3DDevice7_Clear(device
, 1, NULL
, D3DCLEAR_TARGET
, 0x0000ff00, 1.0f
, 0);
3031 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
3033 color
= get_surface_color(rt
, 320, 240);
3034 ok(compare_color(color
, 0x0000ff00, 1),
3035 "Clear with count = 1, rect = NULL has color %#08x.\n", color
);
3037 IDirectDrawSurface7_Release(rt
);
3038 IDirect3DDevice7_Release(device
);
3039 DestroyWindow(window
);
3042 static BOOL
test_mode_restored(IDirectDraw7
*ddraw
, HWND window
)
3044 DDSURFACEDESC2 ddsd1
, ddsd2
;
3047 memset(&ddsd1
, 0, sizeof(ddsd1
));
3048 ddsd1
.dwSize
= sizeof(ddsd1
);
3049 hr
= IDirectDraw7_GetDisplayMode(ddraw
, &ddsd1
);
3050 ok(SUCCEEDED(hr
), "GetDisplayMode failed, hr %#x.\n", hr
);
3052 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3053 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3054 hr
= IDirectDraw7_SetDisplayMode(ddraw
, 640, 480, 32, 0, 0);
3055 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
3056 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3057 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3059 memset(&ddsd2
, 0, sizeof(ddsd2
));
3060 ddsd2
.dwSize
= sizeof(ddsd2
);
3061 hr
= IDirectDraw7_GetDisplayMode(ddraw
, &ddsd2
);
3062 ok(SUCCEEDED(hr
), "GetDisplayMode failed, hr %#x.\n", hr
);
3063 hr
= IDirectDraw7_RestoreDisplayMode(ddraw
);
3064 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
3066 return ddsd1
.dwWidth
== ddsd2
.dwWidth
&& ddsd1
.dwHeight
== ddsd2
.dwHeight
;
3069 static void test_coop_level_versions(void)
3075 IDirectDrawSurface
*surface
;
3076 IDirectDraw7
*ddraw7
;
3079 window
= CreateWindowA("static", "ddraw_test1", WS_OVERLAPPEDWINDOW
,
3080 0, 0, 640, 480, 0, 0, 0, 0);
3082 if (!(ddraw7
= create_ddraw()))
3084 /* Newly created ddraw objects restore the mode on ddraw2+::SetCooperativeLevel(NORMAL) */
3085 restored
= test_mode_restored(ddraw7
, window
);
3086 ok(restored
, "Display mode not restored in new ddraw object\n");
3088 /* A failing ddraw1::SetCooperativeLevel call does not have an effect */
3089 hr
= IDirectDraw7_QueryInterface(ddraw7
, &IID_IDirectDraw
, (void **)&ddraw
);
3090 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
3092 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
3093 ok(FAILED(hr
), "SetCooperativeLevel returned %#x, expected failure.\n", hr
);
3094 restored
= test_mode_restored(ddraw7
, window
);
3095 ok(restored
, "Display mode not restored after bad ddraw1::SetCooperativeLevel call\n");
3097 /* A successful one does */
3098 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
3099 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3100 restored
= test_mode_restored(ddraw7
, window
);
3101 ok(!restored
, "Display mode restored after good ddraw1::SetCooperativeLevel call\n");
3103 IDirectDraw_Release(ddraw
);
3104 IDirectDraw7_Release(ddraw7
);
3106 if (!(ddraw7
= create_ddraw()))
3108 hr
= IDirectDraw7_QueryInterface(ddraw7
, &IID_IDirectDraw
, (void **)&ddraw
);
3109 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
3111 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_SETFOCUSWINDOW
);
3112 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3113 restored
= test_mode_restored(ddraw7
, window
);
3114 ok(!restored
, "Display mode restored after ddraw1::SetCooperativeLevel(SETFOCUSWINDOW) call\n");
3116 IDirectDraw_Release(ddraw
);
3117 IDirectDraw7_Release(ddraw7
);
3119 /* A failing call does not restore the ddraw2+ behavior */
3120 if (!(ddraw7
= create_ddraw()))
3122 hr
= IDirectDraw7_QueryInterface(ddraw7
, &IID_IDirectDraw
, (void **)&ddraw
);
3123 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
3125 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
3126 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3127 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
3128 ok(FAILED(hr
), "SetCooperativeLevel returned %#x, expected failure.\n", hr
);
3129 restored
= test_mode_restored(ddraw7
, window
);
3130 ok(!restored
, "Display mode restored after good-bad ddraw1::SetCooperativeLevel() call sequence\n");
3132 IDirectDraw_Release(ddraw
);
3133 IDirectDraw7_Release(ddraw7
);
3135 /* Neither does a sequence of successful calls with the new interface */
3136 if (!(ddraw7
= create_ddraw()))
3138 hr
= IDirectDraw7_QueryInterface(ddraw7
, &IID_IDirectDraw
, (void **)&ddraw
);
3139 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
3141 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
3142 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3143 hr
= IDirectDraw7_SetCooperativeLevel(ddraw7
, window
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
3144 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3145 hr
= IDirectDraw7_SetCooperativeLevel(ddraw7
, window
, DDSCL_NORMAL
);
3146 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3148 restored
= test_mode_restored(ddraw7
, window
);
3149 ok(!restored
, "Display mode restored after ddraw1-ddraw7 SetCooperativeLevel() call sequence\n");
3150 IDirectDraw_Release(ddraw
);
3151 IDirectDraw7_Release(ddraw7
);
3153 /* ddraw1::CreateSurface does not triger the ddraw1 behavior */
3154 if (!(ddraw7
= create_ddraw()))
3156 hr
= IDirectDraw7_QueryInterface(ddraw7
, &IID_IDirectDraw
, (void **)&ddraw
);
3157 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
3159 hr
= IDirectDraw7_SetCooperativeLevel(ddraw7
, window
, DDSCL_NORMAL
);
3160 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3162 memset(&ddsd
, 0, sizeof(ddsd
));
3163 ddsd
.dwSize
= sizeof(ddsd
);
3164 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
3165 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
3166 ddsd
.dwWidth
= ddsd
.dwHeight
= 8;
3167 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
3168 ok(SUCCEEDED(hr
), "CreateSurface failed, hr %#x.\n", hr
);
3169 IDirectDrawSurface_Release(surface
);
3170 restored
= test_mode_restored(ddraw7
, window
);
3171 ok(restored
, "Display mode not restored after ddraw1::CreateSurface() call\n");
3173 IDirectDraw_Release(ddraw
);
3174 IDirectDraw7_Release(ddraw7
);
3177 DestroyWindow(window
);
3180 static void test_fog_special(void)
3184 struct vec3 position
;
3189 {{ -1.0f
, 1.0f
, 0.0f
}, 0xff00ff00},
3190 {{ 1.0f
, 1.0f
, 1.0f
}, 0xff00ff00},
3191 {{ -1.0f
, -1.0f
, 0.0f
}, 0xff00ff00},
3192 {{ 1.0f
, -1.0f
, 1.0f
}, 0xff00ff00},
3196 DWORD vertexmode
, tablemode
;
3197 D3DCOLOR color_left
, color_right
;
3201 {D3DFOG_LINEAR
, D3DFOG_NONE
, 0x00ff0000, 0x00ff0000},
3202 {D3DFOG_NONE
, D3DFOG_LINEAR
, 0x0000ff00, 0x00ff0000},
3213 IDirect3DDevice7
*device
;
3214 IDirectDrawSurface7
*rt
;
3216 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
3217 0, 0, 640, 480, 0, 0, 0, 0);
3219 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
3221 skip("Failed to create D3D device, skipping test.\n");
3222 DestroyWindow(window
);
3226 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
3227 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
3229 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, TRUE
);
3230 ok(SUCCEEDED(hr
), "Failed to enable fog, hr %#x.\n", hr
);
3231 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGCOLOR
, 0xffff0000);
3232 ok(SUCCEEDED(hr
), "Failed to set fog color, hr %#x.\n", hr
);
3233 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
3234 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
3235 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
3236 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
3239 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGSTART
, conv
.d
);
3240 ok(SUCCEEDED(hr
), "Failed to set fog start, hr %#x.\n", hr
);
3241 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGEND
, conv
.d
);
3242 ok(SUCCEEDED(hr
), "Failed to set fog end, hr %#x.\n", hr
);
3244 for (i
= 0; i
< sizeof(tests
) / sizeof(*tests
); i
++)
3246 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x000000ff, 1.0f
, 0);
3247 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
3249 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGVERTEXMODE
, tests
[i
].vertexmode
);
3250 ok(SUCCEEDED(hr
), "Failed to set fogvertexmode, hr %#x.\n", hr
);
3251 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGTABLEMODE
, tests
[i
].tablemode
);
3252 ok(SUCCEEDED(hr
), "Failed to set fogtablemode, hr %#x.\n", hr
);
3254 hr
= IDirect3DDevice7_BeginScene(device
);
3255 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
3256 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
, quad
, 4, 0);
3257 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
3258 hr
= IDirect3DDevice7_EndScene(device
);
3259 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
3261 color
= get_surface_color(rt
, 310, 240);
3262 ok(compare_color(color
, tests
[i
].color_left
, 1),
3263 "Expected left color 0x%08x, got 0x%08x, case %u.\n", tests
[i
].color_left
, color
, i
);
3264 color
= get_surface_color(rt
, 330, 240);
3265 ok(compare_color(color
, tests
[i
].color_right
, 1),
3266 "Expected right color 0x%08x, got 0x%08x, case %u.\n", tests
[i
].color_right
, color
, i
);
3269 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
3270 ok(SUCCEEDED(hr
), "Failed to disable fog, hr %#x.\n", hr
);
3272 IDirectDrawSurface7_Release(rt
);
3273 IDirect3DDevice7_Release(device
);
3274 DestroyWindow(window
);
3279 HMODULE module
= GetModuleHandleA("ddraw.dll");
3281 if (!(pDirectDrawCreateEx
= (void *)GetProcAddress(module
, "DirectDrawCreateEx")))
3283 win_skip("DirectDrawCreateEx not available, skipping tests.\n");
3287 test_process_vertices();
3288 test_coop_level_create_device_window();
3290 test_coop_level_d3d_state();
3291 test_surface_interface_mismatch();
3292 test_coop_level_threaded();
3294 test_texture_load_ckey();
3301 test_window_style();
3302 test_redundant_mode_set();
3303 test_coop_level_mode_set();
3304 test_coop_level_mode_set_multi();
3306 test_coop_level_surf_create();
3308 test_coop_level_multi_window();
3309 test_draw_strided();
3310 test_clear_rect_count();
3311 test_coop_level_versions();