ReactOS  0.4.14-dev-115-g4576127
d3drm.c
Go to the documentation of this file.
1 /*
2  * Copyright 2010, 2012 Christian Costa
3  * Copyright 2012 AndrĂ© Hentschel
4  * Copyright 2011-2014 Henri Verbeet for CodeWeavers
5  * Copyright 2014-2015 Aaryaman Vasishta
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21 
22 #include <limits.h>
23 
24 #define COBJMACROS
25 #include <d3d.h>
26 #include <initguid.h>
27 #include <d3drm.h>
28 #include <d3drmwin.h>
29 
30 #include "wine/test.h"
31 
32 #define CHECK_REFCOUNT(obj,rc) \
33  { \
34  int rc_new = rc; \
35  int count = get_refcount( (IUnknown *)obj ); \
36  ok(count == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, count); \
37  }
38 
39 static ULONG get_refcount(IUnknown *object)
40 {
41  IUnknown_AddRef( object );
42  return IUnknown_Release( object );
43 }
44 
45 static BOOL compare_float(float f, float g, unsigned int ulps)
46 {
47  int x = *(int *)&f;
48  int y = *(int *)&g;
49 
50  if (x < 0)
51  x = INT_MIN - x;
52  if (y < 0)
53  y = INT_MIN - y;
54 
55  if (abs(x - y) > ulps)
56  return FALSE;
57 
58  return TRUE;
59 }
60 
61 #define check_vector(a, b, c, d, e) check_vector_(__LINE__, a, b, c, d, e)
62 static void check_vector_(unsigned int line, const D3DVECTOR *v, float x, float y, float z, unsigned int ulps)
63 {
64  BOOL ret = compare_float(U1(v)->x, x, ulps)
65  && compare_float(U2(v)->y, y, ulps)
66  && compare_float(U3(v)->z, z, ulps);
67 
68  ok_(__FILE__, line)(ret, "Got unexpected vector {%.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e}.\n",
69  U1(v)->x, U2(v)->y, U3(v)->z, x, y, z);
70 }
71 
72 #define vector_eq(a, b) vector_eq_(__LINE__, a, b)
73 static void vector_eq_(unsigned int line, const D3DVECTOR *left, const D3DVECTOR *right)
74 {
75  check_vector_(line, left, U1(right)->x, U2(right)->y, U3(right)->z, 0);
76 }
77 
79  { 1.0f, 0.0f, 0.0f, 0.0f },
80  { 0.0f, 1.0f, 0.0f, 0.0f },
81  { 0.0f, 0.0f, 1.0f, 0.0f },
82  { 0.0f, 0.0f, 0.0f, 1.0f }
83 };
84 
85 static HWND create_window(void)
86 {
87  RECT r = {0, 0, 640, 480};
88 
90 
91  return CreateWindowA("static", "d3drm_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
92  CW_USEDEFAULT, CW_USEDEFAULT, r.right - r.left, r.bottom - r.top, NULL, NULL, NULL, NULL);
93 }
94 
95 #define test_class_name(a, b) test_class_name_(__LINE__, a, b)
96 static void test_class_name_(unsigned int line, IDirect3DRMObject *object, const char *name)
97 {
98  char cname[64] = {0};
99  DWORD size, size2;
100  HRESULT hr;
101 
102  hr = IDirect3DRMObject_GetClassName(object, NULL, cname);
103  ok_(__FILE__, line)(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
105  ok_(__FILE__, line)(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
106 
107  size = 0;
109  ok_(__FILE__, line)(hr == D3DRM_OK, "Failed to get classname size, hr %#x.\n", hr);
110  ok_(__FILE__, line)(size == strlen(name) + 1, "wrong size: %u\n", size);
111 
112  size = size2 = !!*name;
113  hr = IDirect3DRMObject_GetClassName(object, &size, cname);
114  ok_(__FILE__, line)(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
115  ok_(__FILE__, line)(size == size2, "Got size %u.\n", size);
116 
117  size = sizeof(cname);
118  hr = IDirect3DRMObject_GetClassName(object, &size, cname);
119  ok_(__FILE__, line)(hr == D3DRM_OK, "Failed to get classname, hr %#x.\n", hr);
120  ok_(__FILE__, line)(size == strlen(name) + 1, "wrong size: %u\n", size);
121  ok_(__FILE__, line)(!strcmp(cname, name), "Expected cname to be \"%s\", but got \"%s\".\n", name, cname);
122 
123  size = strlen(name) + 1;
124  hr = IDirect3DRMObject_GetClassName(object, &size, cname);
125  ok_(__FILE__, line)(hr == D3DRM_OK, "Failed to get classname, hr %#x.\n", hr);
126  ok_(__FILE__, line)(size == strlen(name) + 1, "wrong size: %u\n", size);
127  ok_(__FILE__, line)(!strcmp(cname, name), "Expected cname to be \"%s\", but got \"%s\".\n", name, cname);
128 
129  size = strlen(name);
130  strcpy(cname, "XXX");
131  hr = IDirect3DRMObject_GetClassName(object, &size, cname);
132  ok_(__FILE__, line)(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
133  ok_(__FILE__, line)(size == strlen(name), "Wrong classname size: %u.\n", size);
134  ok_(__FILE__, line)(!strcmp(cname, "XXX"), "Expected unchanged buffer, but got \"%s\".\n", cname);
135 }
136 
137 #define test_object_name(a) test_object_name_(__LINE__, a)
138 static void test_object_name_(unsigned int line, IDirect3DRMObject *object)
139 {
140  char name[64] = {0};
141  HRESULT hr;
142  DWORD size;
143 
145  ok_(__FILE__, line)(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
146 
147  name[0] = 0x1f;
149  ok_(__FILE__, line)(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
150  ok_(__FILE__, line)(name[0] == 0x1f, "Unexpected buffer contents, %#x.\n", name[0]);
151 
152  /* Name is not set yet. */
153  size = 100;
154  hr = IDirect3DRMObject_GetName(object, &size, NULL);
155  ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to get name size, hr %#x.\n", hr);
156  ok_(__FILE__, line)(size == 0, "Unexpected size %u.\n", size);
157 
158  size = sizeof(name);
159  name[0] = 0x1f;
160  hr = IDirect3DRMObject_GetName(object, &size, name);
161  ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to get name size, hr %#x.\n", hr);
162  ok_(__FILE__, line)(size == 0, "Unexpected size %u.\n", size);
163  ok_(__FILE__, line)(name[0] == 0, "Unexpected name \"%s\".\n", name);
164 
165  size = 0;
166  name[0] = 0x1f;
167  hr = IDirect3DRMObject_GetName(object, &size, name);
168  ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to get name size, hr %#x.\n", hr);
169  ok_(__FILE__, line)(size == 0, "Unexpected size %u.\n", size);
170  ok_(__FILE__, line)(name[0] == 0x1f, "Unexpected name \"%s\".\n", name);
171 
172  hr = IDirect3DRMObject_SetName(object, NULL);
173  ok_(__FILE__, line)(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
174 
175  hr = IDirect3DRMObject_SetName(object, "name");
176  ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to set a name, hr %#x.\n", hr);
177 
178  size = 0;
179  hr = IDirect3DRMObject_GetName(object, &size, NULL);
180  ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to get name size, hr %#x.\n", hr);
181  ok_(__FILE__, line)(size == strlen("name") + 1, "Unexpected size %u.\n", size);
182 
183  size = strlen("name") + 1;
184  hr = IDirect3DRMObject_GetName(object, &size, name);
185  ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to get name size, hr %#x.\n", hr);
186  ok_(__FILE__, line)(size == strlen("name") + 1, "Unexpected size %u.\n", size);
187  ok_(__FILE__, line)(!strcmp(name, "name"), "Unexpected name \"%s\".\n", name);
188 
189  size = 2;
190  name[0] = 0x1f;
191  hr = IDirect3DRMObject_GetName(object, &size, name);
192  ok_(__FILE__, line)(hr == E_INVALIDARG, "Failed to get object name, hr %#x.\n", hr);
193  ok_(__FILE__, line)(size == 2, "Unexpected size %u.\n", size);
194  ok_(__FILE__, line)(name[0] == 0x1f, "Got unexpected name \"%s\".\n", name);
195 
196  hr = IDirect3DRMObject_SetName(object, NULL);
197  ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to set object name, hr %#x.\n", hr);
198 
199  size = 1;
200  hr = IDirect3DRMObject_GetName(object, &size, NULL);
201  ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to get name size, hr %#x.\n", hr);
202  ok_(__FILE__, line)(size == 0, "Unexpected size %u.\n", size);
203 
204  size = 1;
205  name[0] = 0x1f;
206  hr = IDirect3DRMObject_GetName(object, &size, name);
207  ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to get name size, hr %#x.\n", hr);
208  ok_(__FILE__, line)(size == 0, "Unexpected size %u.\n", size);
209  ok_(__FILE__, line)(name[0] == 0, "Got unexpected name \"%s\".\n", name);
210 }
211 
212 static char data_bad_version[] =
213 "xof 0302txt 0064\n"
214 "Header Object\n"
215 "{\n"
216 "1; 2; 3;\n"
217 "}\n";
218 
219 static char data_no_mesh[] =
220 "xof 0302txt 0064\n"
221 "Header Object\n"
222 "{\n"
223 "1; 0; 1;\n"
224 "}\n";
225 
226 static char data_ok[] =
227 "xof 0302txt 0064\n"
228 "Header Object\n"
229 "{\n"
230 "1; 0; 1;\n"
231 "}\n"
232 "Mesh Object\n"
233 "{\n"
234 "4;\n"
235 "1.0; 0.0; 0.0;,\n"
236 "0.0; 1.0; 0.0;,\n"
237 "0.0; 0.0; 1.0;,\n"
238 "1.0; 1.0; 1.0;;\n"
239 "3;\n"
240 "3; 0, 1, 2;,\n"
241 "3; 1, 2, 3;,\n"
242 "3; 3, 1, 2;;\n"
243 "}\n";
244 
245 static char data_full[] =
246 "xof 0302txt 0064\n"
247 "Header { 1; 0; 1; }\n"
248 "Mesh {\n"
249 " 3;\n"
250 " 0.1; 0.2; 0.3;,\n"
251 " 0.4; 0.5; 0.6;,\n"
252 " 0.7; 0.8; 0.9;;\n"
253 " 1;\n"
254 " 3; 0, 1, 2;;\n"
255 " MeshMaterialList {\n"
256 " 1; 1; 0;\n"
257 " Material {\n"
258 " 0.0; 1.0; 0.0; 1.0;;\n"
259 " 30.0;\n"
260 " 1.0; 0.0; 0.0;;\n"
261 " 0.5; 0.5; 0.5;;\n"
262 " TextureFileName {\n"
263 " \"Texture.bmp\";\n"
264 " }\n"
265 " }\n"
266 " }\n"
267 " MeshNormals {\n"
268 " 3;\n"
269 " 1.1; 1.2; 1.3;,\n"
270 " 1.4; 1.5; 1.6;,\n"
271 " 1.7; 1.8; 1.9;;\n"
272 " 1;"
273 " 3; 0, 1, 2;;\n"
274 " }\n"
275 " MeshTextureCoords {\n"
276 " 3;\n"
277 " 0.13; 0.17;,\n"
278 " 0.23; 0.27;,\n"
279 " 0.33; 0.37;;\n"
280 " }\n"
281 "}\n";
282 
283 static char data_d3drm_load[] =
284 "xof 0302txt 0064\n"
285 "Header Object\n"
286 "{\n"
287 "1; 0; 1;\n"
288 "}\n"
289 "Mesh Object1\n"
290 "{\n"
291 " 1;\n"
292 " 0.1; 0.2; 0.3;,\n"
293 " 1;\n"
294 " 3; 0, 1, 2;;\n"
295 "}\n"
296 "Mesh Object2\n"
297 "{\n"
298 " 1;\n"
299 " 0.1; 0.2; 0.3;,\n"
300 " 1;\n"
301 " 3; 0, 1, 2;;\n"
302 "}\n"
303 "Frame Scene\n"
304 "{\n"
305 " {Object1}\n"
306 " {Object2}\n"
307 "}\n"
308 "Material\n"
309 "{\n"
310 " 0.1, 0.2, 0.3, 0.4;;\n"
311 " 0.5;\n"
312 " 0.6, 0.7, 0.8;;\n"
313 " 0.9, 1.0, 1.1;;\n"
314 "}\n";
315 
317 "xof 0302txt 0064\n"
318 "Header { 1; 0; 1; }\n"
319 "Frame {\n"
320 " Mesh mesh1 {\n"
321 " 5;\n"
322 " 0.1; 0.2; 0.3;,\n"
323 " 0.4; 0.5; 0.6;,\n"
324 " 0.7; 0.8; 0.9;,\n"
325 " 1.1; 1.2; 1.3;,\n"
326 " 1.4; 1.5; 1.6;;\n"
327 " 6;\n"
328 " 3; 0, 1, 2;,\n"
329 " 3; 0, 2, 1;,\n"
330 " 3; 1, 2, 3;,\n"
331 " 3; 1, 3, 2;,\n"
332 " 3; 2, 3, 4;,\n"
333 " 3; 2, 4, 3;;\n"
334 " MeshMaterialList {\n"
335 " 3; 6; 0, 1, 1, 2, 2, 2;\n"
336 " Material mat1 {\n"
337 " 1.0; 0.0; 0.0; 0.1;;\n"
338 " 10.0;\n"
339 " 0.11; 0.12; 0.13;;\n"
340 " 0.14; 0.15; 0.16;;\n"
341 " }\n"
342 " Material mat2 {\n"
343 " 0.0; 1.0; 0.0; 0.2;;\n"
344 " 20.0;\n"
345 " 0.21; 0.22; 0.23;;\n"
346 " 0.24; 0.25; 0.26;;\n"
347 " }\n"
348 " Material mat3 {\n"
349 " 0.0; 0.0; 1.0; 0.3;;\n"
350 " 30.0;\n"
351 " 0.31; 0.32; 0.33;;\n"
352 " 0.34; 0.35; 0.36;;\n"
353 " }\n"
354 " }\n"
355 " }\n"
356 "}\n";
357 
358 static void test_MeshBuilder(void)
359 {
360  HRESULT hr;
361  IDirect3DRM *d3drm;
362  IDirect3DRMMeshBuilder *pMeshBuilder;
363  IDirect3DRMMeshBuilder3 *meshbuilder3;
364  IDirect3DRMMesh *mesh;
366  int val;
367  DWORD val1, val2, val3;
368  D3DVALUE valu, valv;
369  D3DVECTOR v[3];
370  D3DVECTOR n[4];
371  DWORD f[8];
372  char name[10];
373  DWORD size;
374  D3DCOLOR color;
375  IUnknown *unk;
376 
378  ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x)\n", hr);
379 
380  hr = IDirect3DRM_CreateMeshBuilder(d3drm, &pMeshBuilder);
381  ok(hr == D3DRM_OK, "Cannot get IDirect3DRMMeshBuilder interface (hr = %x)\n", hr);
382 
383  hr = IDirect3DRMMeshBuilder_QueryInterface(pMeshBuilder, &IID_IDirect3DRMObject, (void **)&unk);
384  ok(SUCCEEDED(hr), "Failed to get IDirect3DRMObject, %#x.\n", hr);
385  ok(unk == (IUnknown *)pMeshBuilder, "Unexpected interface pointer.\n");
386  IUnknown_Release(unk);
387 
388  hr = IDirect3DRMMeshBuilder_QueryInterface(pMeshBuilder, &IID_IDirect3DRMVisual, (void **)&unk);
389  ok(SUCCEEDED(hr), "Failed to get IDirect3DRMVisual, %#x.\n", hr);
390  ok(unk == (IUnknown *)pMeshBuilder, "Unexpected interface pointer.\n");
391  IUnknown_Release(unk);
392 
393  hr = IDirect3DRMMeshBuilder_QueryInterface(pMeshBuilder, &IID_IDirect3DRMMeshBuilder3, (void **)&meshbuilder3);
394  ok(SUCCEEDED(hr), "Failed to get IDirect3DRMMeshBuilder3, %#x.\n", hr);
395 
396  hr = IDirect3DRMMeshBuilder3_QueryInterface(meshbuilder3, &IID_IDirect3DRMObject, (void **)&unk);
397  ok(SUCCEEDED(hr), "Failed to get IDirect3DRMObject, %#x.\n", hr);
398  ok(unk == (IUnknown *)pMeshBuilder, "Unexpected interface pointer.\n");
399  IUnknown_Release(unk);
400 
401  hr = IDirect3DRMMeshBuilder3_QueryInterface(meshbuilder3, &IID_IDirect3DRMVisual, (void **)&unk);
402  ok(SUCCEEDED(hr), "Failed to get IDirect3DRMVisual, %#x.\n", hr);
403  ok(unk == (IUnknown *)pMeshBuilder, "Unexpected interface pointer.\n");
404  IUnknown_Release(unk);
405 
406  IDirect3DRMMeshBuilder3_Release(meshbuilder3);
407 
408  test_class_name((IDirect3DRMObject *)pMeshBuilder, "Builder");
409  test_object_name((IDirect3DRMObject *)pMeshBuilder);
410 
411  info.lpMemory = data_bad_version;
412  info.dSize = strlen(data_bad_version);
414  ok(hr == D3DRMERR_BADFILE, "Should have returned D3DRMERR_BADFILE (hr = %x)\n", hr);
415 
416  info.lpMemory = data_no_mesh;
417  info.dSize = strlen(data_no_mesh);
419  ok(hr == D3DRMERR_NOTFOUND, "Should have returned D3DRMERR_NOTFOUND (hr = %x)\n", hr);
420 
421  info.lpMemory = data_ok;
422  info.dSize = strlen(data_ok);
424  ok(hr == D3DRM_OK, "Cannot load mesh data (hr = %x)\n", hr);
425 
426  size = sizeof(name);
427  hr = IDirect3DRMMeshBuilder_GetName(pMeshBuilder, &size, name);
428  ok(hr == D3DRM_OK, "IDirect3DRMMeshBuilder_GetName returned hr = %x\n", hr);
429  ok(!strcmp(name, "Object"), "Retrieved name '%s' instead of 'Object'\n", name);
430  size = strlen("Object"); /* No space for null character */
431  hr = IDirect3DRMMeshBuilder_GetName(pMeshBuilder, &size, name);
432  ok(hr == E_INVALIDARG, "IDirect3DRMMeshBuilder_GetName returned hr = %x\n", hr);
433  hr = IDirect3DRMMeshBuilder_SetName(pMeshBuilder, NULL);
434  ok(hr == D3DRM_OK, "IDirect3DRMMeshBuilder_SetName returned hr = %x\n", hr);
435  size = sizeof(name);
436  hr = IDirect3DRMMeshBuilder_GetName(pMeshBuilder, &size, name);
437  ok(hr == D3DRM_OK, "IDirect3DRMMeshBuilder_GetName returned hr = %x\n", hr);
438  ok(size == 0, "Size should be 0 instead of %u\n", size);
439  hr = IDirect3DRMMeshBuilder_SetName(pMeshBuilder, "");
440  ok(hr == D3DRM_OK, "IDirect3DRMMeshBuilder_SetName returned hr = %x\n", hr);
441  size = sizeof(name);
442  hr = IDirect3DRMMeshBuilder_GetName(pMeshBuilder, &size, name);
443  ok(hr == D3DRM_OK, "IDirect3DRMMeshBuilder_GetName returned hr = %x\n", hr);
444  ok(!strcmp(name, ""), "Retrieved name '%s' instead of ''\n", name);
445 
447  ok(val == 4, "Wrong number of vertices %d (must be 4)\n", val);
448 
450  ok(val == 3, "Wrong number of faces %d (must be 3)\n", val);
451 
452  hr = IDirect3DRMMeshBuilder_GetVertices(pMeshBuilder, &val1, NULL, &val2, NULL, &val3, NULL);
453  ok(hr == D3DRM_OK, "Cannot get vertices information (hr = %x)\n", hr);
454  ok(val1 == 4, "Wrong number of vertices %d (must be 4)\n", val1);
455  ok(val2 == 4, "Wrong number of normals %d (must be 4)\n", val2);
456  ok(val3 == 22, "Wrong number of face data bytes %d (must be 22)\n", val3);
457 
458  /* Check that Load method generated default normals */
459  hr = IDirect3DRMMeshBuilder_GetVertices(pMeshBuilder, NULL, NULL, &val2, n, NULL, NULL);
460  ok(hr == D3DRM_OK, "Cannot get vertices information (hr = %x)\n", hr);
461  check_vector(&n[0], 0.577350f, 0.577350f, 0.577350f, 32);
462  check_vector(&n[1], -0.229416f, 0.688247f, 0.688247f, 32);
463  check_vector(&n[2], -0.229416f, 0.688247f, 0.688247f, 32);
464  check_vector(&n[3], -0.577350f, 0.577350f, 0.577350f, 32);
465 
466  /* Check that Load method generated default texture coordinates (0.0f, 0.0f) for each vertex */
467  valu = 1.23f;
468  valv = 3.21f;
469  hr = IDirect3DRMMeshBuilder_GetTextureCoordinates(pMeshBuilder, 0, &valu, &valv);
470  ok(hr == D3DRM_OK, "Cannot get texture coordinates (hr = %x)\n", hr);
471  ok(valu == 0.0f, "Wrong coordinate %f (must be 0.0)\n", valu);
472  ok(valv == 0.0f, "Wrong coordinate %f (must be 0.0)\n", valv);
473  valu = 1.23f;
474  valv = 3.21f;
475  hr = IDirect3DRMMeshBuilder_GetTextureCoordinates(pMeshBuilder, 1, &valu, &valv);
476  ok(hr == D3DRM_OK, "Cannot get texture coordinates (hr = %x)\n", hr);
477  ok(valu == 0.0f, "Wrong coordinate %f (must be 0.0)\n", valu);
478  ok(valv == 0.0f, "Wrong coordinate %f (must be 0.0)\n", valv);
479  valu = 1.23f;
480  valv = 3.21f;
481  hr = IDirect3DRMMeshBuilder_GetTextureCoordinates(pMeshBuilder, 2, &valu, &valv);
482  ok(hr == D3DRM_OK, "Cannot get texture coordinates (hr = %x)\n", hr);
483  ok(valu == 0.0f, "Wrong coordinate %f (must be 0.0)\n", valu);
484  ok(valv == 0.0f, "Wrong coordinate %f (must be 0.0)\n", valv);
485  valu = 1.23f;
486  valv = 3.21f;
487  hr = IDirect3DRMMeshBuilder_GetTextureCoordinates(pMeshBuilder, 3, &valu, &valv);
488  ok(hr == D3DRM_OK, "Cannot get texture coordinates (hr = %x)\n", hr);
489  ok(valu == 0.0f, "Wrong coordinate %f (must be 0.0)\n", valu);
490  ok(valv == 0.0f, "Wrong coordinate %f (must be 0.0)\n", valv);
491  hr = IDirect3DRMMeshBuilder_GetTextureCoordinates(pMeshBuilder, 4, &valu, &valv);
492  ok(hr == D3DRMERR_BADVALUE, "Should fail and return D3DRM_BADVALUE (hr = %x)\n", hr);
493 
494  valu = 1.23f;
495  valv = 3.21f;
496  hr = IDirect3DRMMeshBuilder_SetTextureCoordinates(pMeshBuilder, 0, valu, valv);
497  ok(hr == D3DRM_OK, "Cannot set texture coordinates (hr = %x)\n", hr);
498  hr = IDirect3DRMMeshBuilder_SetTextureCoordinates(pMeshBuilder, 4, valu, valv);
499  ok(hr == D3DRMERR_BADVALUE, "Should fail and return D3DRM_BADVALUE (hr = %x)\n", hr);
500 
501  valu = 0.0f;
502  valv = 0.0f;
503  hr = IDirect3DRMMeshBuilder_GetTextureCoordinates(pMeshBuilder, 0, &valu, &valv);
504  ok(hr == D3DRM_OK, "Cannot get texture coordinates (hr = %x)\n", hr);
505  ok(valu == 1.23f, "Wrong coordinate %f (must be 1.23)\n", valu);
506  ok(valv == 3.21f, "Wrong coordinate %f (must be 3.21)\n", valv);
507 
508  IDirect3DRMMeshBuilder_Release(pMeshBuilder);
509 
510  hr = IDirect3DRM_CreateMeshBuilder(d3drm, &pMeshBuilder);
511  ok(hr == D3DRM_OK, "Cannot get IDirect3DRMMeshBuilder interface (hr = %x)\n", hr);
512 
513  /* No group in mesh when mesh builder is not loaded */
514  hr = IDirect3DRMMeshBuilder_CreateMesh(pMeshBuilder, &mesh);
515  ok(hr == D3DRM_OK, "CreateMesh failed returning hr = %x\n", hr);
516  if (hr == D3DRM_OK)
517  {
518  DWORD nb_groups;
519 
520  nb_groups = IDirect3DRMMesh_GetGroupCount(mesh);
521  ok(nb_groups == 0, "GetCroupCount returned %u\n", nb_groups);
522 
524  }
525 
526  info.lpMemory = data_full;
527  info.dSize = strlen(data_full);
529  ok(hr == D3DRM_OK, "Cannot load mesh data (hr = %x)\n", hr);
530 
532  ok(val == 3, "Wrong number of vertices %d (must be 3)\n", val);
533 
535  ok(val == 1, "Wrong number of faces %d (must be 1)\n", val);
536 
537  /* Check no buffer size and too small buffer size errors */
538  val1 = 1; val2 = 3; val3 = 8;
539  hr = IDirect3DRMMeshBuilder_GetVertices(pMeshBuilder, &val1, v, &val2, n, &val3, f);
540  ok(hr == D3DRMERR_BADVALUE, "IDirect3DRMMeshBuilder_GetVertices returned %#x\n", hr);
541  hr = IDirect3DRMMeshBuilder_GetVertices(pMeshBuilder, NULL, v, &val2, n, &val3, f);
542  ok(hr == D3DRMERR_BADVALUE, "IDirect3DRMMeshBuilder_GetVertices returned %#x\n", hr);
543  val1 = 3; val2 = 1; val3 = 8;
544  hr = IDirect3DRMMeshBuilder_GetVertices(pMeshBuilder, &val1, v, &val2, n, &val3, f);
545  ok(hr == D3DRMERR_BADVALUE, "IDirect3DRMMeshBuilder_GetVertices returned %#x\n", hr);
546  hr = IDirect3DRMMeshBuilder_GetVertices(pMeshBuilder, &val1, v, NULL, n, &val3, f);
547  ok(hr == D3DRMERR_BADVALUE, "IDirect3DRMMeshBuilder_GetVertices returned %#x\n", hr);
548  val1 = 3; val2 = 3; val3 = 1;
549  hr = IDirect3DRMMeshBuilder_GetVertices(pMeshBuilder, &val1, v, &val2, n, &val3, f);
550  ok(hr == D3DRMERR_BADVALUE, "IDirect3DRMMeshBuilder_GetVertices returned %#x\n", hr);
551  hr = IDirect3DRMMeshBuilder_GetVertices(pMeshBuilder, &val1, v, &val2, n, NULL, f);
552  ok(hr == D3DRMERR_BADVALUE, "IDirect3DRMMeshBuilder_GetVertices returned %#x\n", hr);
553 
554  val1 = 3; val2 = 3; val3 = 8;
555  hr = IDirect3DRMMeshBuilder_GetVertices(pMeshBuilder, &val1, v, &val2, n, &val3, f);
556  ok(hr == D3DRM_OK, "Cannot get vertices information (hr = %x)\n", hr);
557  ok(val1 == 3, "Wrong number of vertices %d (must be 3)\n", val1);
558  ok(val2 == 3, "Wrong number of normals %d (must be 3)\n", val2);
559  ok(val3 == 8, "Wrong number of face data bytes %d (must be 8)\n", val3);
560  check_vector(&v[0], 0.1f, 0.2f, 0.3f, 32);
561  check_vector(&v[1], 0.4f, 0.5f, 0.6f, 32);
562  check_vector(&v[2], 0.7f, 0.8f, 0.9f, 32);
563  check_vector(&n[0], 1.1f, 1.2f, 1.3f, 32);
564  check_vector(&n[1], 1.4f, 1.5f, 1.6f, 32);
565  check_vector(&n[2], 1.7f, 1.8f, 1.9f, 32);
566  ok(f[0] == 3 , "Wrong component f[0] = %d (expected 3)\n", f[0]);
567  ok(f[1] == 0 , "Wrong component f[1] = %d (expected 0)\n", f[1]);
568  ok(f[2] == 0 , "Wrong component f[2] = %d (expected 0)\n", f[2]);
569  ok(f[3] == 1 , "Wrong component f[3] = %d (expected 1)\n", f[3]);
570  ok(f[4] == 1 , "Wrong component f[4] = %d (expected 1)\n", f[4]);
571  ok(f[5] == 2 , "Wrong component f[5] = %d (expected 2)\n", f[5]);
572  ok(f[6] == 2 , "Wrong component f[6] = %d (expected 2)\n", f[6]);
573  ok(f[7] == 0 , "Wrong component f[7] = %d (expected 0)\n", f[7]);
574 
575  hr = IDirect3DRMMeshBuilder_CreateMesh(pMeshBuilder, &mesh);
576  ok(hr == D3DRM_OK, "CreateMesh failed returning hr = %x\n", hr);
577  if (hr == D3DRM_OK)
578  {
579  DWORD nb_groups;
580  unsigned nb_vertices, nb_faces, nb_face_vertices;
581  DWORD data_size;
582  IDirect3DRMMaterial *material = (IDirect3DRMMaterial *)0xdeadbeef;
583  IDirect3DRMTexture *texture = (IDirect3DRMTexture *)0xdeadbeef;
584  D3DVALUE values[3];
585 
586  nb_groups = IDirect3DRMMesh_GetGroupCount(mesh);
587  ok(nb_groups == 1, "GetCroupCount returned %u\n", nb_groups);
588  hr = IDirect3DRMMesh_GetGroup(mesh, 1, &nb_vertices, &nb_faces, &nb_face_vertices, &data_size, NULL);
589  ok(hr == D3DRMERR_BADVALUE, "GetCroup returned hr = %x\n", hr);
590  hr = IDirect3DRMMesh_GetGroup(mesh, 0, &nb_vertices, &nb_faces, &nb_face_vertices, &data_size, NULL);
591  ok(hr == D3DRM_OK, "GetCroup failed returning hr = %x\n", hr);
592  ok(nb_vertices == 3, "Wrong number of vertices %u (must be 3)\n", nb_vertices);
593  ok(nb_faces == 1, "Wrong number of faces %u (must be 1)\n", nb_faces);
594  ok(nb_face_vertices == 3, "Wrong number of vertices per face %u (must be 3)\n", nb_face_vertices);
595  ok(data_size == 3, "Wrong number of face data bytes %u (must be 3)\n", data_size);
597  ok(color == 0xff00ff00, "Wrong color returned %#x instead of %#x\n", color, 0xff00ff00);
599  ok(hr == D3DRM_OK, "GetCroupTexture failed returning hr = %x\n", hr);
600  ok(texture == NULL, "No texture should be present\n");
601  hr = IDirect3DRMMesh_GetGroupMaterial(mesh, 0, &material);
602  ok(hr == D3DRM_OK, "GetCroupMaterial failed returning hr = %x\n", hr);
603  ok(material != NULL, "No material present\n");
604  hr = IDirect3DRMMaterial_GetEmissive(material, &values[0], &values[1], &values[2]);
605  ok(hr == D3DRM_OK, "Failed to get emissive color, hr %#x.\n", hr);
606  ok(values[0] == 0.5f, "Got unexpected red component %.8e.\n", values[0]);
607  ok(values[1] == 0.5f, "Got unexpected green component %.8e.\n", values[1]);
608  ok(values[2] == 0.5f, "Got unexpected blue component %.8e.\n", values[2]);
609  hr = IDirect3DRMMaterial_GetSpecular(material, &values[0], &values[1], &values[2]);
610  ok(hr == D3DRM_OK, "Failed to get specular color, hr %#x.\n", hr);
611  ok(values[0] == 1.0f, "Got unexpected red component %.8e.\n", values[0]);
612  ok(values[1] == 0.0f, "Got unexpected green component %.8e.\n", values[1]);
613  ok(values[2] == 0.0f, "Got unexpected blue component %.8e.\n", values[2]);
614  values[0] = IDirect3DRMMaterial_GetPower(material);
615  ok(values[0] == 30.0f, "Got unexpected power value %.8e.\n", values[0]);
616  IDirect3DRMMaterial_Release(material);
617 
619  }
620 
621  hr = IDirect3DRMMeshBuilder_Scale(pMeshBuilder, 2, 3 ,4);
622  ok(hr == D3DRM_OK, "Scale failed returning hr = %x\n", hr);
623 
624  hr = IDirect3DRMMeshBuilder_GetVertices(pMeshBuilder, &val1, v, &val2, n, &val3, f);
625  ok(hr == D3DRM_OK, "Cannot get vertices information (hr = %x)\n", hr);
626  ok(val2 == 3, "Wrong number of normals %d (must be 3)\n", val2);
627  ok(val1 == 3, "Wrong number of vertices %d (must be 3)\n", val1);
628 
629  check_vector(&v[0], 0.1f * 2, 0.2f * 3, 0.3f * 4, 32);
630  check_vector(&v[1], 0.4f * 2, 0.5f * 3, 0.6f * 4, 32);
631  check_vector(&v[2], 0.7f * 2, 0.8f * 3, 0.9f * 4, 32);
632  /* Normals are not affected by Scale */
633  check_vector(&n[0], 1.1f, 1.2f, 1.3f, 32);
634  check_vector(&n[1], 1.4f, 1.5f, 1.6f, 32);
635  check_vector(&n[2], 1.7f, 1.8f, 1.9f, 32);
636 
637  IDirect3DRMMeshBuilder_Release(pMeshBuilder);
638 
640 }
641 
642 static void test_MeshBuilder3(void)
643 {
644  HRESULT hr;
645  IDirect3DRM *d3drm;
646  IDirect3DRM3 *d3drm3;
647  IDirect3DRMMeshBuilder3 *pMeshBuilder3;
649  int val;
650  DWORD val1;
651  D3DVALUE valu, valv;
652 
654  ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x)\n", hr);
655 
656  if (FAILED(hr = IDirect3DRM_QueryInterface(d3drm, &IID_IDirect3DRM3, (void **)&d3drm3)))
657  {
658  win_skip("Cannot get IDirect3DRM3 interface (hr = %x), skipping tests\n", hr);
660  return;
661  }
662 
663  hr = IDirect3DRM3_CreateMeshBuilder(d3drm3, &pMeshBuilder3);
664  ok(hr == D3DRM_OK, "Cannot get IDirect3DRMMeshBuilder3 interface (hr = %x)\n", hr);
665 
666  test_class_name((IDirect3DRMObject *)pMeshBuilder3, "Builder");
667  test_object_name((IDirect3DRMObject *)pMeshBuilder3);
668 
669  info.lpMemory = data_bad_version;
670  info.dSize = strlen(data_bad_version);
672  ok(hr == D3DRMERR_BADFILE, "Should have returned D3DRMERR_BADFILE (hr = %x)\n", hr);
673 
674  info.lpMemory = data_no_mesh;
675  info.dSize = strlen(data_no_mesh);
677  ok(hr == D3DRMERR_NOTFOUND, "Should have returned D3DRMERR_NOTFOUND (hr = %x)\n", hr);
678 
679  info.lpMemory = data_ok;
680  info.dSize = strlen(data_ok);
682  ok(hr == D3DRM_OK, "Cannot load mesh data (hr = %x)\n", hr);
683 
685  ok(val == 4, "Wrong number of vertices %d (must be 4)\n", val);
686 
687  val = IDirect3DRMMeshBuilder3_GetFaceCount(pMeshBuilder3);
688  ok(val == 3, "Wrong number of faces %d (must be 3)\n", val);
689 
690  hr = IDirect3DRMMeshBuilder3_GetVertices(pMeshBuilder3, 0, &val1, NULL);
691  ok(hr == D3DRM_OK, "Cannot get vertices information (hr = %x)\n", hr);
692  ok(val1 == 4, "Wrong number of vertices %d (must be 4)\n", val1);
693 
694  /* Check that Load method generated default texture coordinates (0.0f, 0.0f) for each vertex */
695  valu = 1.23f;
696  valv = 3.21f;
697  hr = IDirect3DRMMeshBuilder3_GetTextureCoordinates(pMeshBuilder3, 0, &valu, &valv);
698  ok(hr == D3DRM_OK, "Cannot get texture coordinates (hr = %x)\n", hr);
699  ok(valu == 0.0f, "Wrong coordinate %f (must be 0.0)\n", valu);
700  ok(valv == 0.0f, "Wrong coordinate %f (must be 0.0)\n", valv);
701  valu = 1.23f;
702  valv = 3.21f;
703  hr = IDirect3DRMMeshBuilder3_GetTextureCoordinates(pMeshBuilder3, 1, &valu, &valv);
704  ok(hr == D3DRM_OK, "Cannot get texture coordinates (hr = %x)\n", hr);
705  ok(valu == 0.0f, "Wrong coordinate %f (must be 0.0)\n", valu);
706  ok(valv == 0.0f, "Wrong coordinate %f (must be 0.0)\n", valv);
707  valu = 1.23f;
708  valv = 3.21f;
709  hr = IDirect3DRMMeshBuilder3_GetTextureCoordinates(pMeshBuilder3, 2, &valu, &valv);
710  ok(hr == D3DRM_OK, "Cannot get texture coordinates (hr = %x)\n", hr);
711  ok(valu == 0.0f, "Wrong coordinate %f (must be 0.0)\n", valu);
712  ok(valv == 0.0f, "Wrong coordinate %f (must be 0.0)\n", valv);
713  valu = 1.23f;
714  valv = 3.21f;
715  hr = IDirect3DRMMeshBuilder3_GetTextureCoordinates(pMeshBuilder3, 3, &valu, &valv);
716  ok(hr == D3DRM_OK, "Cannot get texture coordinates (hr = %x)\n", hr);
717  ok(valu == 0.0f, "Wrong coordinate %f (must be 0.0)\n", valu);
718  ok(valv == 0.0f, "Wrong coordinate %f (must be 0.0)\n", valv);
719  hr = IDirect3DRMMeshBuilder3_GetTextureCoordinates(pMeshBuilder3, 4, &valu, &valv);
720  ok(hr == D3DRMERR_BADVALUE, "Should fail and return D3DRM_BADVALUE (hr = %x)\n", hr);
721 
722  valu = 1.23f;
723  valv = 3.21f;
724  hr = IDirect3DRMMeshBuilder3_SetTextureCoordinates(pMeshBuilder3, 0, valu, valv);
725  ok(hr == D3DRM_OK, "Cannot set texture coordinates (hr = %x)\n", hr);
726  hr = IDirect3DRMMeshBuilder3_SetTextureCoordinates(pMeshBuilder3, 4, valu, valv);
727  ok(hr == D3DRMERR_BADVALUE, "Should fail and return D3DRM_BADVALUE (hr = %x)\n", hr);
728 
729  valu = 0.0f;
730  valv = 0.0f;
731  hr = IDirect3DRMMeshBuilder3_GetTextureCoordinates(pMeshBuilder3, 0, &valu, &valv);
732  ok(hr == D3DRM_OK, "Cannot get texture coordinates (hr = %x)\n", hr);
733  ok(valu == 1.23f, "Wrong coordinate %f (must be 1.23)\n", valu);
734  ok(valv == 3.21f, "Wrong coordinate %f (must be 3.21)\n", valv);
735 
736  IDirect3DRMMeshBuilder3_Release(pMeshBuilder3);
737  IDirect3DRM3_Release(d3drm3);
739 }
740 
741 static void test_Mesh(void)
742 {
743  HRESULT hr;
744  IDirect3DRM *d3drm;
745  IDirect3DRMMesh *mesh;
746  IUnknown *unk;
747 
749  ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x)\n", hr);
750 
751  hr = IDirect3DRM_CreateMesh(d3drm, &mesh);
752  ok(hr == D3DRM_OK, "Cannot get IDirect3DRMMesh interface (hr = %x)\n", hr);
753 
754  test_class_name((IDirect3DRMObject *)mesh, "Mesh");
755  test_object_name((IDirect3DRMObject *)mesh);
756 
757  hr = IDirect3DRMMesh_QueryInterface(mesh, &IID_IDirect3DRMObject, (void **)&unk);
758  ok(SUCCEEDED(hr), "Failed to get IDirect3DRMObject, %#x.\n", hr);
759  IUnknown_Release(unk);
760 
761  hr = IDirect3DRMMesh_QueryInterface(mesh, &IID_IDirect3DRMVisual, (void **)&unk);
762  ok(SUCCEEDED(hr), "Failed to get IDirect3DRMVisual, %#x.\n", hr);
763  IUnknown_Release(unk);
764 
766 
768 }
769 
770 static void test_Face(void)
771 {
772  HRESULT hr;
773  IDirect3DRM *d3drm;
774  IDirect3DRM2 *d3drm2;
775  IDirect3DRM3 *d3drm3;
776  IDirect3DRMMeshBuilder2 *MeshBuilder2;
777  IDirect3DRMMeshBuilder3 *MeshBuilder3;
778  IDirect3DRMFace *face1;
779  IDirect3DRMObject *obj;
780  IDirect3DRMFace2 *face2;
781  IDirect3DRMFaceArray *array1;
783  D3DVECTOR v1[4], n1[4], v2[4], n2[4];
784  D3DCOLOR color;
785  DWORD count;
786  int icount;
787 
789  ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x)\n", hr);
790 
791  hr = IDirect3DRM_CreateFace(d3drm, &face1);
792  ok(hr == D3DRM_OK, "Cannot get IDirect3DRMFace interface (hr = %x)\n", hr);
793  if (FAILED(hr))
794  {
795  skip("Cannot get IDirect3DRMFace interface (hr = %x), skipping tests\n", hr);
797  return;
798  }
799 
800  hr = IDirect3DRMFace_QueryInterface(face1, &IID_IDirect3DRMObject, (void **)&obj);
801  ok(SUCCEEDED(hr), "Failed to get IDirect3DRMObject, %#x.\n", hr);
802  ok(obj == (IDirect3DRMObject *)face1, "Unexpected interface pointer.\n");
804 
805  test_class_name((IDirect3DRMObject *)face1, "Face");
806  test_object_name((IDirect3DRMObject *)face1);
807 
808  icount = IDirect3DRMFace_GetVertexCount(face1);
809  ok(!icount, "wrong VertexCount: %i\n", icount);
810 
812 
813  if (FAILED(hr = IDirect3DRM_QueryInterface(d3drm, &IID_IDirect3DRM2, (void **)&d3drm2)))
814  {
815  win_skip("Cannot get IDirect3DRM2 interface (hr = %x), skipping tests\n", hr);
817  return;
818  }
819 
820  hr = IDirect3DRM2_CreateMeshBuilder(d3drm2, &MeshBuilder2);
821  ok(hr == D3DRM_OK, "Cannot get IDirect3DRMMeshBuilder2 interface (hr = %x)\n", hr);
822 
823  icount = IDirect3DRMMeshBuilder2_GetFaceCount(MeshBuilder2);
824  ok(!icount, "wrong FaceCount: %i\n", icount);
825 
826  array1 = NULL;
827  hr = IDirect3DRMMeshBuilder2_GetFaces(MeshBuilder2, &array1);
828  todo_wine
829  ok(hr == D3DRM_OK, "Cannot get FaceArray (hr = %x)\n", hr);
830 
831  hr = IDirect3DRMMeshBuilder2_CreateFace(MeshBuilder2, &face1);
832  ok(hr == D3DRM_OK, "Cannot get IDirect3DRMFace interface (hr = %x)\n", hr);
833 
834  icount = IDirect3DRMMeshBuilder2_GetFaceCount(MeshBuilder2);
835  todo_wine
836  ok(icount == 1, "wrong FaceCount: %i\n", icount);
837 
838  array1 = NULL;
839  hr = IDirect3DRMMeshBuilder2_GetFaces(MeshBuilder2, &array1);
840  todo_wine
841  ok(hr == D3DRM_OK, "Cannot get FaceArray (hr = %x)\n", hr);
842  todo_wine
843  ok(array1 != NULL, "pArray = %p\n", array1);
844  if (array1)
845  {
846  IDirect3DRMFace *face;
848  ok(count == 1, "count = %u\n", count);
849  hr = IDirect3DRMFaceArray_GetElement(array1, 0, &face);
850  ok(hr == D3DRM_OK, "Cannot get face (hr = %x)\n", hr);
853  }
854 
855  icount = IDirect3DRMFace_GetVertexCount(face1);
856  ok(!icount, "wrong VertexCount: %i\n", icount);
857 
859  IDirect3DRMMeshBuilder2_Release(MeshBuilder2);
860 
861  if (FAILED(hr = IDirect3DRM_QueryInterface(d3drm, &IID_IDirect3DRM3, (void **)&d3drm3)))
862  {
863  win_skip("Cannot get IDirect3DRM3 interface (hr = %x), skipping tests\n", hr);
865  return;
866  }
867 
868  hr = IDirect3DRM3_CreateMeshBuilder(d3drm3, &MeshBuilder3);
869  ok(hr == D3DRM_OK, "Cannot get IDirect3DRMMeshBuilder3 interface (hr = %x)\n", hr);
870 
871  icount = IDirect3DRMMeshBuilder3_GetFaceCount(MeshBuilder3);
872  ok(!icount, "wrong FaceCount: %i\n", icount);
873 
874  hr = IDirect3DRMMeshBuilder3_CreateFace(MeshBuilder3, &face2);
875  ok(hr == D3DRM_OK, "Cannot get IDirect3DRMFace2 interface (hr = %x)\n", hr);
876 
877  hr = IDirect3DRMFace2_QueryInterface(face2, &IID_IDirect3DRMObject, (void **)&obj);
878  ok(SUCCEEDED(hr), "Failed to get IDirect3DRMObject, %#x.\n", hr);
879 
880  hr = IDirect3DRMFace2_QueryInterface(face2, &IID_IDirect3DRMFace, (void **)&face1);
881  ok(SUCCEEDED(hr), "Failed to get IDirect3DRMObject, %#x.\n", hr);
882  ok(obj == (IDirect3DRMObject *)face1, "Unexpected interface pointer.\n");
883 
886 
887  test_class_name((IDirect3DRMObject *)face2, "Face");
888  test_object_name((IDirect3DRMObject *)face2);
889 
890  icount = IDirect3DRMMeshBuilder3_GetFaceCount(MeshBuilder3);
891  todo_wine
892  ok(icount == 1, "wrong FaceCount: %i\n", icount);
893 
894  array1 = NULL;
895  hr = IDirect3DRMMeshBuilder3_GetFaces(MeshBuilder3, &array1);
896  todo_wine
897  ok(hr == D3DRM_OK, "Cannot get FaceArray (hr = %x)\n", hr);
898  todo_wine
899  ok(array1 != NULL, "pArray = %p\n", array1);
900  if (array1)
901  {
902  IDirect3DRMFace *face;
904  ok(count == 1, "count = %u\n", count);
905  hr = IDirect3DRMFaceArray_GetElement(array1, 0, &face);
906  ok(hr == D3DRM_OK, "Cannot get face (hr = %x)\n", hr);
909  }
910 
911  icount = IDirect3DRMFace2_GetVertexCount(face2);
912  ok(!icount, "wrong VertexCount: %i\n", icount);
913 
914  info.lpMemory = data_ok;
915  info.dSize = strlen(data_ok);
917  ok(hr == D3DRM_OK, "Cannot load mesh data (hr = %x)\n", hr);
918 
919  icount = IDirect3DRMMeshBuilder3_GetVertexCount(MeshBuilder3);
920  ok(icount == 4, "Wrong number of vertices %d (must be 4)\n", icount);
921 
922  icount = IDirect3DRMMeshBuilder3_GetNormalCount(MeshBuilder3);
923  ok(icount == 4, "Wrong number of normals %d (must be 4)\n", icount);
924 
925  icount = IDirect3DRMMeshBuilder3_GetFaceCount(MeshBuilder3);
926  todo_wine
927  ok(icount == 4, "Wrong number of faces %d (must be 4)\n", icount);
928 
929  count = 4;
930  hr = IDirect3DRMMeshBuilder3_GetVertices(MeshBuilder3, 0, &count, v1);
931  ok(hr == D3DRM_OK, "Cannot get vertices information (hr = %x)\n", hr);
932  ok(count == 4, "Wrong number of vertices %d (must be 4)\n", count);
933 
934  hr = IDirect3DRMMeshBuilder3_GetNormals(MeshBuilder3, 0, &count, n1);
935  ok(hr == D3DRM_OK, "Cannot get normals information (hr = %x)\n", hr);
936  ok(count == 4, "Wrong number of normals %d (must be 4)\n", count);
937 
938  array1 = NULL;
939  hr = IDirect3DRMMeshBuilder3_GetFaces(MeshBuilder3, &array1);
940  todo_wine
941  ok(hr == D3DRM_OK, "Cannot get FaceArray (hr = %x)\n", hr);
942  todo_wine
943  ok(array1 != NULL, "pArray = %p\n", array1);
944  if (array1)
945  {
946  IDirect3DRMFace *face;
948  ok(count == 4, "count = %u\n", count);
949  hr = IDirect3DRMFaceArray_GetElement(array1, 1, &face);
950  ok(hr == D3DRM_OK, "Cannot get face (hr = %x)\n", hr);
952  ok(hr == D3DRM_OK, "Cannot get vertices information (hr = %x)\n", hr);
953  ok(count == 3, "Wrong number of vertices %d (must be 3)\n", count);
954 
955  vector_eq(&v1[0], &v2[0]);
956  vector_eq(&v1[1], &v2[1]);
957  vector_eq(&v1[2], &v2[2]);
958 
959  vector_eq(&n1[0], &n2[0]);
960  vector_eq(&n1[1], &n2[1]);
961  vector_eq(&n1[2], &n2[2]);
962 
965  }
966 
967  /* Setting face color. */
968  hr = IDirect3DRMFace2_SetColor(face2, 0x1f180587);
969  ok(SUCCEEDED(hr), "Failed to set face color, hr %#x.\n", hr);
971  ok(color == 0x1f180587, "Unexpected color %8x.\n", color);
972 
973  hr = IDirect3DRMFace2_SetColorRGB(face2, 0.5f, 0.5f, 0.5f);
974  ok(SUCCEEDED(hr), "Failed to set color, hr %#x.\n", hr);
976  ok(color == 0xff7f7f7f, "Unexpected color %8x.\n", color);
977 
979  IDirect3DRMMeshBuilder3_Release(MeshBuilder3);
980  IDirect3DRM3_Release(d3drm3);
981  IDirect3DRM2_Release(d3drm2);
983 }
984 
985 static void test_Frame(void)
986 {
987  HRESULT hr;
988  IDirect3DRM *d3drm;
989  IDirect3DRMFrame *pFrameC;
990  IDirect3DRMFrame *pFrameP1;
991  IDirect3DRMFrame *pFrameP2;
992  IDirect3DRMFrame *pFrameTmp;
993  IDirect3DRMFrame *scene_frame;
994  IDirect3DRMFrameArray *frame_array;
995  IDirect3DRMMeshBuilder *mesh_builder;
996  IDirect3DRMVisual *visual1;
997  IDirect3DRMVisual *visual_tmp;
998  IDirect3DRMVisualArray *visual_array;
999  IDirect3DRMLight *light1;
1000  IDirect3DRMLight *light_tmp;
1001  IDirect3DRMLightArray *light_array;
1002  IDirect3DRMFrame3 *frame3;
1003  DWORD count, options;
1004  ULONG ref, ref2;
1005  D3DCOLOR color;
1006 
1008  ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x)\n", hr);
1009 
1011  hr = IDirect3DRM_CreateFrame(d3drm, NULL, &pFrameC);
1012  ok(hr == D3DRM_OK, "Cannot get IDirect3DRMFrame interface (hr = %x)\n", hr);
1013  CHECK_REFCOUNT(pFrameC, 1);
1015  ok(ref2 > ref, "Expected d3drm object to be referenced.\n");
1016 
1017  test_class_name((IDirect3DRMObject *)pFrameC, "Frame");
1018  test_object_name((IDirect3DRMObject *)pFrameC);
1019 
1020  hr = IDirect3DRMFrame_GetParent(pFrameC, NULL);
1021  ok(hr == D3DRMERR_BADVALUE, "Should fail and return D3DRM_BADVALUE (hr = %x)\n", hr);
1022  pFrameTmp = (void*)0xdeadbeef;
1023  hr = IDirect3DRMFrame_GetParent(pFrameC, &pFrameTmp);
1024  ok(hr == D3DRM_OK, "Cannot get parent frame (hr = %x)\n", hr);
1025  ok(pFrameTmp == NULL, "pFrameTmp = %p\n", pFrameTmp);
1026  CHECK_REFCOUNT(pFrameC, 1);
1027 
1028  frame_array = NULL;
1029  hr = IDirect3DRMFrame_GetChildren(pFrameC, &frame_array);
1030  ok(hr == D3DRM_OK, "Cannot get children (hr = %x)\n", hr);
1031  ok(!!frame_array, "frame_array = %p\n", frame_array);
1032  if (frame_array)
1033  {
1034  count = IDirect3DRMFrameArray_GetSize(frame_array);
1035  ok(count == 0, "count = %u\n", count);
1036  hr = IDirect3DRMFrameArray_GetElement(frame_array, 0, &pFrameTmp);
1037  ok(hr == D3DRMERR_BADVALUE, "Should have returned D3DRMERR_BADVALUE (hr = %x)\n", hr);
1038  ok(pFrameTmp == NULL, "pFrameTmp = %p\n", pFrameTmp);
1039  IDirect3DRMFrameArray_Release(frame_array);
1040  }
1041 
1042  hr = IDirect3DRM_CreateFrame(d3drm, NULL, &pFrameP1);
1043  ok(hr == D3DRM_OK, "Cannot get IDirect3DRMFrame interface (hr = %x)\n", hr);
1044 
1045  /* GetParent with NULL pointer */
1046  hr = IDirect3DRMFrame_GetParent(pFrameP1, NULL);
1047  ok(hr == D3DRMERR_BADVALUE, "Should have returned D3DRMERR_BADVALUE (hr = %x)\n", hr);
1048  CHECK_REFCOUNT(pFrameP1, 1);
1049 
1050  /* [Add/Delete]Child with NULL pointer */
1051  hr = IDirect3DRMFrame_AddChild(pFrameP1, NULL);
1052  ok(hr == D3DRMERR_BADOBJECT, "Should have returned D3DRMERR_BADOBJECT (hr = %x)\n", hr);
1053  CHECK_REFCOUNT(pFrameP1, 1);
1054 
1055  hr = IDirect3DRMFrame_DeleteChild(pFrameP1, NULL);
1056  ok(hr == D3DRMERR_BADOBJECT, "Should have returned D3DRMERR_BADOBJECT (hr = %x)\n", hr);
1057  CHECK_REFCOUNT(pFrameP1, 1);
1058 
1059  /* Add child to first parent */
1060  pFrameTmp = (void*)0xdeadbeef;
1061  hr = IDirect3DRMFrame_GetParent(pFrameP1, &pFrameTmp);
1062  ok(hr == D3DRM_OK, "Cannot get parent frame (hr = %x)\n", hr);
1063  ok(pFrameTmp == NULL, "pFrameTmp = %p\n", pFrameTmp);
1064 
1065  hr = IDirect3DRMFrame_AddChild(pFrameP1, pFrameC);
1066  ok(hr == D3DRM_OK, "Cannot add child frame (hr = %x)\n", hr);
1067  CHECK_REFCOUNT(pFrameP1, 1);
1068  CHECK_REFCOUNT(pFrameC, 2);
1069 
1070  hr = IDirect3DRMFrame_GetScene(pFrameC, NULL);
1071  ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
1072  hr = IDirect3DRMFrame_GetScene(pFrameC, &scene_frame);
1073  ok(SUCCEEDED(hr), "Cannot get scene (hr == %#x).\n", hr);
1074  ok(scene_frame == pFrameP1, "Expected scene frame == %p, got %p.\n", pFrameP1, scene_frame);
1075  CHECK_REFCOUNT(pFrameP1, 2);
1076  IDirect3DRMFrame_Release(scene_frame);
1077  hr = IDirect3DRMFrame_GetScene(pFrameP1, &scene_frame);
1078  ok(SUCCEEDED(hr), "Cannot get scene (hr == %#x).\n", hr);
1079  ok(scene_frame == pFrameP1, "Expected scene frame == %p, got %p.\n", pFrameP1, scene_frame);
1080  CHECK_REFCOUNT(pFrameP1, 2);
1081  IDirect3DRMFrame_Release(scene_frame);
1082 
1083  frame_array = NULL;
1084  hr = IDirect3DRMFrame_GetChildren(pFrameP1, &frame_array);
1085  ok(hr == D3DRM_OK, "Cannot get children (hr = %x)\n", hr);
1086  /* In some older version of d3drm, creating IDirect3DRMFrameArray object with GetChildren does not increment refcount of children frames */
1087  ok((get_refcount((IUnknown*)pFrameC) == 3) || broken(get_refcount((IUnknown*)pFrameC) == 2),
1088  "Invalid refcount. Expected 3 (or 2) got %d\n", get_refcount((IUnknown*)pFrameC));
1089  if (frame_array)
1090  {
1091  count = IDirect3DRMFrameArray_GetSize(frame_array);
1092  ok(count == 1, "count = %u\n", count);
1093  hr = IDirect3DRMFrameArray_GetElement(frame_array, 0, &pFrameTmp);
1094  ok(hr == D3DRM_OK, "Cannot get element (hr = %x)\n", hr);
1095  ok(pFrameTmp == pFrameC, "pFrameTmp = %p\n", pFrameTmp);
1096  ok((get_refcount((IUnknown*)pFrameC) == 4) || broken(get_refcount((IUnknown*)pFrameC) == 3),
1097  "Invalid refcount. Expected 4 (or 3) got %d\n", get_refcount((IUnknown*)pFrameC));
1098  IDirect3DRMFrame_Release(pFrameTmp);
1099  ok((get_refcount((IUnknown*)pFrameC) == 3) || broken(get_refcount((IUnknown*)pFrameC) == 2),
1100  "Invalid refcount. Expected 3 (or 2) got %d\n", get_refcount((IUnknown*)pFrameC));
1101  IDirect3DRMFrameArray_Release(frame_array);
1102  CHECK_REFCOUNT(pFrameC, 2);
1103  }
1104 
1105  pFrameTmp = (void*)0xdeadbeef;
1106  hr = IDirect3DRMFrame_GetParent(pFrameC, &pFrameTmp);
1107  ok(hr == D3DRM_OK, "Cannot get parent frame (hr = %x)\n", hr);
1108  ok(pFrameTmp == pFrameP1, "pFrameTmp = %p\n", pFrameTmp);
1109  CHECK_REFCOUNT(pFrameP1, 2);
1110  IDirect3DRMFrame_Release(pFrameTmp);
1111  CHECK_REFCOUNT(pFrameP1, 1);
1112 
1113  /* Add child to second parent */
1114  hr = IDirect3DRM_CreateFrame(d3drm, NULL, &pFrameP2);
1115  ok(hr == D3DRM_OK, "Cannot get IDirect3DRMFrame interface (hr = %x)\n", hr);
1116 
1117  hr = IDirect3DRMFrame_AddChild(pFrameP2, pFrameC);
1118  ok(hr == D3DRM_OK, "Cannot add child frame (hr = %x)\n", hr);
1119  CHECK_REFCOUNT(pFrameC, 2);
1120 
1121  frame_array = NULL;
1122  hr = IDirect3DRMFrame_GetChildren(pFrameP2, &frame_array);
1123  ok(hr == D3DRM_OK, "Cannot get children (hr = %x)\n", hr);
1124  if (frame_array)
1125  {
1126  count = IDirect3DRMFrameArray_GetSize(frame_array);
1127  ok(count == 1, "count = %u\n", count);
1128  hr = IDirect3DRMFrameArray_GetElement(frame_array, 0, &pFrameTmp);
1129  ok(hr == D3DRM_OK, "Cannot get element (hr = %x)\n", hr);
1130  ok(pFrameTmp == pFrameC, "pFrameTmp = %p\n", pFrameTmp);
1131  IDirect3DRMFrame_Release(pFrameTmp);
1132  IDirect3DRMFrameArray_Release(frame_array);
1133  }
1134 
1135  frame_array = NULL;
1136  hr = IDirect3DRMFrame_GetChildren(pFrameP1, &frame_array);
1137  ok(hr == D3DRM_OK, "Cannot get children (hr = %x)\n", hr);
1138  if (frame_array)
1139  {
1140  count = IDirect3DRMFrameArray_GetSize(frame_array);
1141  ok(count == 0, "count = %u\n", count);
1142  pFrameTmp = (void*)0xdeadbeef;
1143  hr = IDirect3DRMFrameArray_GetElement(frame_array, 0, &pFrameTmp);
1144  ok(hr == D3DRMERR_BADVALUE, "Should have returned D3DRMERR_BADVALUE (hr = %x)\n", hr);
1145  ok(pFrameTmp == NULL, "pFrameTmp = %p\n", pFrameTmp);
1146  IDirect3DRMFrameArray_Release(frame_array);
1147  }
1148  hr = IDirect3DRMFrame_GetScene(pFrameC, &scene_frame);
1149  ok(SUCCEEDED(hr), "Cannot get scene (hr == %#x).\n", hr);
1150  ok(scene_frame == pFrameP2, "Expected scene frame == %p, got %p.\n", pFrameP2, scene_frame);
1151  CHECK_REFCOUNT(pFrameP2, 2);
1152  IDirect3DRMFrame_Release(scene_frame);
1153  hr = IDirect3DRMFrame_GetScene(pFrameP2, &scene_frame);
1154  ok(SUCCEEDED(hr), "Cannot get scene (hr == %#x).\n", hr);
1155  ok(scene_frame == pFrameP2, "Expected scene frame == %p, got %p.\n", pFrameP2, scene_frame);
1156  CHECK_REFCOUNT(pFrameP2, 2);
1157  IDirect3DRMFrame_Release(scene_frame);
1158 
1159  pFrameTmp = (void*)0xdeadbeef;
1160  hr = IDirect3DRMFrame_GetParent(pFrameC, &pFrameTmp);
1161  ok(hr == D3DRM_OK, "Cannot get parent frame (hr = %x)\n", hr);
1162  ok(pFrameTmp == pFrameP2, "pFrameTmp = %p\n", pFrameTmp);
1163  CHECK_REFCOUNT(pFrameP2, 2);
1164  CHECK_REFCOUNT(pFrameC, 2);
1165  IDirect3DRMFrame_Release(pFrameTmp);
1166  CHECK_REFCOUNT(pFrameP2, 1);
1167 
1168  /* Add child again */
1169  hr = IDirect3DRMFrame_AddChild(pFrameP2, pFrameC);
1170  ok(hr == D3DRM_OK, "Cannot add child frame (hr = %x)\n", hr);
1171  CHECK_REFCOUNT(pFrameC, 2);
1172 
1173  frame_array = NULL;
1174  hr = IDirect3DRMFrame_GetChildren(pFrameP2, &frame_array);
1175  ok(hr == D3DRM_OK, "Cannot get children (hr = %x)\n", hr);
1176  if (frame_array)
1177  {
1178  count = IDirect3DRMFrameArray_GetSize(frame_array);
1179  ok(count == 1, "count = %u\n", count);
1180  hr = IDirect3DRMFrameArray_GetElement(frame_array, 0, &pFrameTmp);
1181  ok(hr == D3DRM_OK, "Cannot get element (hr = %x)\n", hr);
1182  ok(pFrameTmp == pFrameC, "pFrameTmp = %p\n", pFrameTmp);
1183  IDirect3DRMFrame_Release(pFrameTmp);
1184  IDirect3DRMFrameArray_Release(frame_array);
1185  }
1186 
1187  /* Delete child */
1188  hr = IDirect3DRMFrame_DeleteChild(pFrameP2, pFrameC);
1189  ok(hr == D3DRM_OK, "Cannot delete child frame (hr = %x)\n", hr);
1190  CHECK_REFCOUNT(pFrameC, 1);
1191 
1192  frame_array = NULL;
1193  hr = IDirect3DRMFrame_GetChildren(pFrameP2, &frame_array);
1194  ok(hr == D3DRM_OK, "Cannot get children (hr = %x)\n", hr);
1195  if (frame_array)
1196  {
1197  count = IDirect3DRMFrameArray_GetSize(frame_array);
1198  ok(count == 0, "count = %u\n", count);
1199  pFrameTmp = (void*)0xdeadbeef;
1200  hr = IDirect3DRMFrameArray_GetElement(frame_array, 0, &pFrameTmp);
1201  ok(hr == D3DRMERR_BADVALUE, "Should have returned D3DRMERR_BADVALUE (hr = %x)\n", hr);
1202  ok(pFrameTmp == NULL, "pFrameTmp = %p\n", pFrameTmp);
1203  IDirect3DRMFrameArray_Release(frame_array);
1204  }
1205 
1206  pFrameTmp = (void*)0xdeadbeef;
1207  hr = IDirect3DRMFrame_GetParent(pFrameC, &pFrameTmp);
1208  ok(hr == D3DRM_OK, "Cannot get parent frame (hr = %x)\n", hr);
1209  ok(pFrameTmp == NULL, "pFrameTmp = %p\n", pFrameTmp);
1210 
1211  /* Add two children */
1212  hr = IDirect3DRMFrame_AddChild(pFrameP2, pFrameC);
1213  ok(hr == D3DRM_OK, "Cannot add child frame (hr = %x)\n", hr);
1214  CHECK_REFCOUNT(pFrameC, 2);
1215 
1216  hr = IDirect3DRMFrame_AddChild(pFrameP2, pFrameP1);
1217  ok(hr == D3DRM_OK, "Cannot add child frame (hr = %x)\n", hr);
1218  CHECK_REFCOUNT(pFrameP1, 2);
1219 
1220  frame_array = NULL;
1221  hr = IDirect3DRMFrame_GetChildren(pFrameP2, &frame_array);
1222  ok(hr == D3DRM_OK, "Cannot get children (hr = %x)\n", hr);
1223  if (frame_array)
1224  {
1225  count = IDirect3DRMFrameArray_GetSize(frame_array);
1226  ok(count == 2, "count = %u\n", count);
1227  hr = IDirect3DRMFrameArray_GetElement(frame_array, 0, &pFrameTmp);
1228  ok(hr == D3DRM_OK, "Cannot get element (hr = %x)\n", hr);
1229  ok(pFrameTmp == pFrameC, "pFrameTmp = %p\n", pFrameTmp);
1230  IDirect3DRMFrame_Release(pFrameTmp);
1231  hr = IDirect3DRMFrameArray_GetElement(frame_array, 1, &pFrameTmp);
1232  ok(hr == D3DRM_OK, "Cannot get element (hr = %x)\n", hr);
1233  ok(pFrameTmp == pFrameP1, "pFrameTmp = %p\n", pFrameTmp);
1234  IDirect3DRMFrame_Release(pFrameTmp);
1235  IDirect3DRMFrameArray_Release(frame_array);
1236  }
1237 
1238  /* [Add/Delete]Visual with NULL pointer */
1239  hr = IDirect3DRMFrame_AddVisual(pFrameP1, NULL);
1240  ok(hr == D3DRMERR_BADOBJECT, "Should have returned D3DRMERR_BADOBJECT (hr = %x)\n", hr);
1241  CHECK_REFCOUNT(pFrameP1, 2);
1242 
1243  hr = IDirect3DRMFrame_DeleteVisual(pFrameP1, NULL);
1244  ok(hr == D3DRMERR_BADOBJECT, "Should have returned D3DRMERR_BADOBJECT (hr = %x)\n", hr);
1245  CHECK_REFCOUNT(pFrameP1, 2);
1246 
1247  /* Create Visual */
1249  ok(hr == D3DRM_OK, "Cannot get IDirect3DRMMeshBuilder interface (hr = %x)\n", hr);
1250  visual1 = (IDirect3DRMVisual *)mesh_builder;
1251 
1252  /* Add Visual to first parent */
1253  hr = IDirect3DRMFrame_AddVisual(pFrameP1, visual1);
1254  ok(hr == D3DRM_OK, "Cannot add visual (hr = %x)\n", hr);
1255  CHECK_REFCOUNT(pFrameP1, 2);
1256  CHECK_REFCOUNT(visual1, 2);
1257 
1258  visual_array = NULL;
1259  hr = IDirect3DRMFrame_GetVisuals(pFrameP1, &visual_array);
1260  ok(hr == D3DRM_OK, "Cannot get visuals (hr = %x)\n", hr);
1261  if (visual_array)
1262  {
1263  count = IDirect3DRMVisualArray_GetSize(visual_array);
1264  ok(count == 1, "count = %u\n", count);
1265  hr = IDirect3DRMVisualArray_GetElement(visual_array, 0, &visual_tmp);
1266  ok(hr == D3DRM_OK, "Cannot get element (hr = %x)\n", hr);
1267  ok(visual_tmp == visual1, "visual_tmp = %p\n", visual_tmp);
1268  IDirect3DRMVisual_Release(visual_tmp);
1269  IDirect3DRMVisualArray_Release(visual_array);
1270  }
1271 
1272  /* Delete Visual */
1273  hr = IDirect3DRMFrame_DeleteVisual(pFrameP1, visual1);
1274  ok(hr == D3DRM_OK, "Cannot delete visual (hr = %x)\n", hr);
1275  CHECK_REFCOUNT(pFrameP1, 2);
1277 
1278  /* [Add/Delete]Light with NULL pointer */
1279  hr = IDirect3DRMFrame_AddLight(pFrameP1, NULL);
1280  ok(hr == D3DRMERR_BADOBJECT, "Should have returned D3DRMERR_BADOBJECT (hr = %x)\n", hr);
1281  CHECK_REFCOUNT(pFrameP1, 2);
1282 
1283  hr = IDirect3DRMFrame_DeleteLight(pFrameP1, NULL);
1284  ok(hr == D3DRMERR_BADOBJECT, "Should have returned D3DRMERR_BADOBJECT (hr = %x)\n", hr);
1285  CHECK_REFCOUNT(pFrameP1, 2);
1286 
1287  /* Create Light */
1288  hr = IDirect3DRM_CreateLightRGB(d3drm, D3DRMLIGHT_SPOT, 0.1, 0.2, 0.3, &light1);
1289  ok(hr == D3DRM_OK, "Cannot get IDirect3DRMLight interface (hr = %x)\n", hr);
1290 
1291  /* Add Light to first parent */
1292  hr = IDirect3DRMFrame_AddLight(pFrameP1, light1);
1293  ok(hr == D3DRM_OK, "Cannot add light (hr = %x)\n", hr);
1294  CHECK_REFCOUNT(pFrameP1, 2);
1295  CHECK_REFCOUNT(light1, 2);
1296 
1297  light_array = NULL;
1298  hr = IDirect3DRMFrame_GetLights(pFrameP1, &light_array);
1299  ok(hr == D3DRM_OK, "Cannot get lights (hr = %x)\n", hr);
1300  if (light_array)
1301  {
1302  count = IDirect3DRMLightArray_GetSize(light_array);
1303  ok(count == 1, "count = %u\n", count);
1304  hr = IDirect3DRMLightArray_GetElement(light_array, 0, &light_tmp);
1305  ok(hr == D3DRM_OK, "Cannot get element (hr = %x)\n", hr);
1306  ok(light_tmp == light1, "light_tmp = %p\n", light_tmp);
1307  IDirect3DRMLight_Release(light_tmp);
1308  IDirect3DRMLightArray_Release(light_array);
1309  }
1310 
1311  /* Delete Light */
1312  hr = IDirect3DRMFrame_DeleteLight(pFrameP1, light1);
1313  ok(hr == D3DRM_OK, "Cannot delete light (hr = %x)\n", hr);
1314  CHECK_REFCOUNT(pFrameP1, 2);
1315  IDirect3DRMLight_Release(light1);
1316 
1317  /* Test SceneBackground on first parent */
1319  ok(color == 0xff000000, "wrong color (%x)\n", color);
1320 
1321  hr = IDirect3DRMFrame_SetSceneBackground(pFrameP1, 0xff180587);
1322  ok(hr == D3DRM_OK, "Cannot set color (hr = %x)\n", hr);
1324  ok(color == 0xff180587, "wrong color (%x)\n", color);
1325 
1326  hr = IDirect3DRMFrame_SetSceneBackgroundRGB(pFrameP1, 0.5, 0.5, 0.5);
1327  ok(hr == D3DRM_OK, "Cannot set color (hr = %x)\n", hr);
1329  ok(color == 0xff7f7f7f, "wrong color (%x)\n", color);
1330 
1331  /* Traversal options. */
1332  hr = IDirect3DRMFrame_QueryInterface(pFrameP2, &IID_IDirect3DRMFrame3, (void **)&frame3);
1333  ok(SUCCEEDED(hr), "Failed to get IDirect3DRMFrame3 interface, hr %#x.\n", hr);
1334 
1336  ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#x.\n", hr);
1337 
1338  options = 0;
1340  ok(SUCCEEDED(hr), "Failed to get traversal options, hr %#x.\n", hr);
1341  ok(options == (D3DRMFRAME_RENDERENABLE | D3DRMFRAME_PICKENABLE), "Unexpected default options %#x.\n", options);
1342 
1344  ok(SUCCEEDED(hr), "Unexpected hr %#x.\n", hr);
1345 
1346  hr = IDirect3DRMFrame3_SetTraversalOptions(frame3, 0xf0000000);
1347  ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#x.\n", hr);
1348 
1350  ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#x.\n", hr);
1351 
1352  options = 0xf;
1354  ok(SUCCEEDED(hr), "Failed to get traversal options, hr %#x.\n", hr);
1355  ok(options == 0, "Unexpected traversal options %#x.\n", options);
1356 
1358  ok(SUCCEEDED(hr), "Failed to set traversal options, hr %#x.\n", hr);
1359 
1360  options = 0;
1362  ok(SUCCEEDED(hr), "Failed to get traversal options, hr %#x.\n", hr);
1363  ok(options == D3DRMFRAME_PICKENABLE, "Unexpected traversal options %#x.\n", options);
1364 
1365  IDirect3DRMFrame3_Release(frame3);
1366 
1367  /* Cleanup */
1368  IDirect3DRMFrame_Release(pFrameP2);
1369  CHECK_REFCOUNT(pFrameC, 1);
1370  CHECK_REFCOUNT(pFrameP1, 1);
1371 
1372  IDirect3DRMFrame_Release(pFrameC);
1373  IDirect3DRMFrame_Release(pFrameP1);
1374 
1376 }
1377 
1379 {
1380  IDirect3DRMObject *obj;
1381  unsigned int test_idx;
1382  int called;
1383 };
1384 
1386 {
1387  void *callback;
1388  void *context;
1389 } corder[3], d3drm_corder[3];
1390 
1391 static void CDECL destroy_callback(IDirect3DRMObject *obj, void *arg)
1392 {
1393  struct destroy_context *ctxt = arg;
1394  ok(ctxt->called == 1 || ctxt->called == 2, "got called counter %d\n", ctxt->called);
1395  ok(obj == ctxt->obj, "called with %p, expected %p\n", obj, ctxt->obj);
1396  d3drm_corder[ctxt->called].callback = &destroy_callback;
1397  d3drm_corder[ctxt->called++].context = ctxt;
1398 }
1399 
1400 static void CDECL destroy_callback1(IDirect3DRMObject *obj, void *arg)
1401 {
1402  struct destroy_context *ctxt = (struct destroy_context*)arg;
1403  ok(ctxt->called == 0, "got called counter %d\n", ctxt->called);
1404  ok(obj == ctxt->obj, "called with %p, expected %p\n", obj, ctxt->obj);
1405  d3drm_corder[ctxt->called].callback = &destroy_callback1;
1406  d3drm_corder[ctxt->called++].context = ctxt;
1407 }
1408 
1409 static void test_destroy_callback(unsigned int test_idx, REFCLSID clsid, REFIID iid)
1410 {
1411  struct destroy_context context;
1412  IDirect3DRMObject *obj;
1413  IUnknown *unknown;
1414  IDirect3DRM *d3drm;
1415  HRESULT hr;
1416  int i;
1417 
1419  ok(SUCCEEDED(hr), "Test %u: Cannot get IDirect3DRM interface (hr = %x).\n", test_idx, hr);
1420 
1421  hr = IDirect3DRM_CreateObject(d3drm, clsid, NULL, iid, (void **)&unknown);
1422  ok(hr == D3DRM_OK, "Test %u: Cannot get IDirect3DRMObject interface (hr = %x).\n", test_idx, hr);
1423  hr = IUnknown_QueryInterface(unknown, &IID_IDirect3DRMObject, (void**)&obj);
1424  ok(hr == D3DRM_OK, "Test %u: expected D3DRM_OK (hr = %x).\n", test_idx, hr);
1425  IUnknown_Release(unknown);
1426 
1427  context.called = 0;
1428  context.test_idx = test_idx;
1429  context.obj = obj;
1430 
1432  ok(hr == D3DRMERR_BADVALUE, "Test %u: expected D3DRMERR_BADVALUE (hr = %x).\n", test_idx, hr);
1433 
1435  ok(hr == D3DRM_OK, "Test %u: expected D3DRM_OK (hr = %x).\n", test_idx, hr);
1436  corder[2].callback = &destroy_callback;
1437  corder[2].context = &context;
1438 
1439  /* same callback added twice */
1441  ok(hr == D3DRM_OK, "Test %u: expected D3DRM_OK (hr = %x).\n", test_idx, hr);
1442  corder[1].callback = &destroy_callback;
1443  corder[1].context = &context;
1444 
1446  ok(hr == D3DRM_OK, "Test %u: expected D3DRM_OK (hr = %x).\n", test_idx, hr);
1447 
1449  ok(hr == D3DRM_OK, "Test %u: expected D3DRM_OK (hr = %x).\n", test_idx, hr);
1450 
1451  /* add one more */
1453  ok(hr == D3DRM_OK, "Test %u: expected D3DRM_OK (hr = %x).\n", test_idx, hr);
1454  corder[0].callback = &destroy_callback1;
1455  corder[0].context = &context;
1456 
1458  ok(hr == D3DRMERR_BADVALUE, "Test %u: expected D3DRM_BADVALUE (hr = %x).\n", test_idx, hr);
1459 
1460  context.called = 0;
1462  ok(context.called == 3, "Test %u: got %d, expected 3.\n", test_idx, context.called);
1463  for (i = 0; i < context.called; i++)
1464  {
1467  "Expected callback = %p, context = %p. Got callback = %p, context = %p.\n", d3drm_corder[i].callback,
1469  }
1470 
1471  /* test this pattern - add cb1, add cb2, add cb1, delete cb1 */
1472  hr = IDirect3DRM_CreateObject(d3drm, clsid, NULL, iid, (void **)&unknown);
1473  ok(hr == D3DRM_OK, "Test %u: Cannot get IDirect3DRMObject interface (hr = %x).\n", test_idx, hr);
1474  hr = IUnknown_QueryInterface(unknown, &IID_IDirect3DRMObject, (void**)&obj);
1475  ok(hr == D3DRM_OK, "Test %u: expected D3DRM_OK (hr = %x).\n", test_idx, hr);
1476  IUnknown_Release(unknown);
1477 
1479  ok(hr == D3DRM_OK, "Test %u: expected D3DRM_OK (hr = %x).\n", test_idx, hr);
1480  corder[1].callback = &destroy_callback;
1481  corder[1].context = &context;
1482 
1484  ok(hr == D3DRM_OK, "Test %u: expected D3DRM_OK (hr = %x).\n", test_idx, hr);
1485  corder[0].callback = &destroy_callback1;
1486  corder[0].context = &context;
1487 
1489  ok(hr == D3DRM_OK, "Test %u: expected D3DRM_OK (hr = %x).\n", test_idx, hr);
1490 
1492  ok(hr == D3DRM_OK, "Test %u: expected D3DRM_OK (hr = %x).\n", test_idx, hr);
1493 
1494  context.called = 0;
1495  hr = IDirect3DRMObject_QueryInterface(obj, &IID_IDirect3DRMObject, (void**)&context.obj);
1496  ok(hr == D3DRM_OK, "Test %u: expected D3DRM_OK (hr = %x).\n", test_idx, hr);
1498  IUnknown_Release(unknown);
1499  ok(context.called == 2, "Test %u: got %d, expected 2.\n", test_idx, context.called);
1500  for (i = 0; i < context.called; i++)
1501  {
1504  "Expected callback = %p, context = %p. Got callback = %p, context = %p.\n", d3drm_corder[i].callback,
1506  }
1507 
1509 }
1510 
1511 static void test_object(void)
1512 {
1513  static const struct
1514  {
1515  REFCLSID clsid;
1516  REFIID iid;
1517  BOOL takes_d3drm_ref;
1518  }
1519  tests[] =
1520  {
1521  { &CLSID_CDirect3DRMDevice, &IID_IDirect3DRMDevice },
1522  { &CLSID_CDirect3DRMDevice, &IID_IDirect3DRMDevice2 },
1523  { &CLSID_CDirect3DRMDevice, &IID_IDirect3DRMDevice3 },
1524  { &CLSID_CDirect3DRMDevice, &IID_IDirect3DRMWinDevice },
1525  { &CLSID_CDirect3DRMTexture, &IID_IDirect3DRMTexture },
1526  { &CLSID_CDirect3DRMTexture, &IID_IDirect3DRMTexture2 },
1527  { &CLSID_CDirect3DRMTexture, &IID_IDirect3DRMTexture3 },
1528  { &CLSID_CDirect3DRMViewport, &IID_IDirect3DRMViewport },
1529  { &CLSID_CDirect3DRMViewport, &IID_IDirect3DRMViewport2 },
1530  { &CLSID_CDirect3DRMFace, &IID_IDirect3DRMFace },
1531  { &CLSID_CDirect3DRMFace, &IID_IDirect3DRMFace2 },
1532  { &CLSID_CDirect3DRMMeshBuilder, &IID_IDirect3DRMMeshBuilder, TRUE },
1533  { &CLSID_CDirect3DRMMeshBuilder, &IID_IDirect3DRMMeshBuilder2, TRUE },
1534  { &CLSID_CDirect3DRMMeshBuilder, &IID_IDirect3DRMMeshBuilder3, TRUE },
1535  { &CLSID_CDirect3DRMFrame, &IID_IDirect3DRMFrame, TRUE },
1536  { &CLSID_CDirect3DRMFrame, &IID_IDirect3DRMFrame2, TRUE },
1537  { &CLSID_CDirect3DRMFrame, &IID_IDirect3DRMFrame3, TRUE },
1538  { &CLSID_CDirect3DRMLight, &IID_IDirect3DRMLight, TRUE },
1539  { &CLSID_CDirect3DRMMaterial, &IID_IDirect3DRMMaterial, TRUE },
1540  { &CLSID_CDirect3DRMMaterial, &IID_IDirect3DRMMaterial2, TRUE },
1541  { &CLSID_CDirect3DRMMesh, &IID_IDirect3DRMMesh, TRUE },
1542  { &CLSID_CDirect3DRMAnimation, &IID_IDirect3DRMAnimation, TRUE },
1543  { &CLSID_CDirect3DRMAnimation, &IID_IDirect3DRMAnimation2, TRUE },
1544  { &CLSID_CDirect3DRMWrap, &IID_IDirect3DRMWrap },
1545  };
1546  IDirect3DRM *d3drm1;
1547  IDirect3DRM2 *d3drm2;
1548  IDirect3DRM3 *d3drm3;
1549  IUnknown *unknown = (IUnknown *)0xdeadbeef;
1550  HRESULT hr;
1551  ULONG ref1, ref2, ref3, ref4;
1552  int i;
1553 
1554  hr = Direct3DRMCreate(&d3drm1);
1555  ok(SUCCEEDED(hr), "Cannot get IDirect3DRM interface (hr = %#x).\n", hr);
1556  ref1 = get_refcount((IUnknown *)d3drm1);
1557  hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM2, (void **)&d3drm2);
1558  ok(SUCCEEDED(hr), "Cannot get IDirect3DRM2 interface (hr = %#x).\n", hr);
1559  hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM3, (void **)&d3drm3);
1560  ok(SUCCEEDED(hr), "Cannot get IDirect3DRM3 interface (hr = %#x).\n", hr);
1561 
1562  hr = IDirect3DRM_CreateObject(d3drm1, &CLSID_DirectDraw, NULL, &IID_IDirectDraw, (void **)&unknown);
1563  ok(hr == CLASSFACTORY_E_FIRST, "Expected hr == CLASSFACTORY_E_FIRST, got %#x.\n", hr);
1564  ok(!unknown, "Expected object returned == NULL, got %p.\n", unknown);
1565 
1566  for (i = 0; i < ARRAY_SIZE(tests); ++i)
1567  {
1568  unknown = (IUnknown *)0xdeadbeef;
1569  hr = IDirect3DRM_CreateObject(d3drm1, NULL, NULL, tests[i].iid, (void **)&unknown);
1570  ok(hr == D3DRMERR_BADVALUE, "Test %u: expected hr == D3DRMERR_BADVALUE, got %#x.\n", i, hr);
1571  ok(!unknown, "Expected object returned == NULL, got %p.\n", unknown);
1572  unknown = (IUnknown *)0xdeadbeef;
1573  hr = IDirect3DRM_CreateObject(d3drm1, tests[i].clsid, NULL, NULL, (void **)&unknown);
1574  ok(hr == D3DRMERR_BADVALUE, "Test %u: expected hr == D3DRMERR_BADVALUE, got %#x.\n", i, hr);
1575  ok(!unknown, "Expected object returned == NULL, got %p.\n", unknown);
1577  ok(hr == D3DRMERR_BADVALUE, "Test %u: expected hr == D3DRMERR_BADVALUE, got %#x.\n", i, hr);
1578 
1579  hr = IDirect3DRM_CreateObject(d3drm1, tests[i].clsid, NULL, tests[i].iid, (void **)&unknown);
1580  ok(SUCCEEDED(hr), "Test %u: expected hr == D3DRM_OK, got %#x.\n", i, hr);
1581  if (SUCCEEDED(hr))
1582  {
1583  ref2 = get_refcount((IUnknown *)d3drm1);
1584  if (tests[i].takes_d3drm_ref)
1585  ok(ref2 > ref1, "Test %u: expected ref2 > ref1, got ref1 = %u, ref2 = %u.\n", i, ref1, ref2);
1586  else
1587  ok(ref2 == ref1, "Test %u: expected ref2 == ref1, got ref1 = %u, ref2 = %u.\n", i, ref1, ref2);
1588 
1589  ref3 = get_refcount((IUnknown *)d3drm2);
1590  ok(ref3 == ref1, "Test %u: expected ref3 == ref1, got ref1 = %u, ref3 = %u.\n", i, ref1, ref3);
1591  ref4 = get_refcount((IUnknown *)d3drm3);
1592  ok(ref4 == ref1, "Test %u: expected ref4 == ref1, got ref1 = %u, ref4 = %u.\n", i, ref1, ref4);
1593  IUnknown_Release(unknown);
1594  ref2 = get_refcount((IUnknown *)d3drm1);
1595  ok(ref2 == ref1, "Test %u: expected ref2 == ref1, got ref1 = %u, ref2 = %u.\n", i, ref1, ref2);
1596  ref3 = get_refcount((IUnknown *)d3drm2);
1597  ok(ref3 == ref1, "Test %u: expected ref3 == ref1, got ref1 = %u, ref3 = %u.\n", i, ref1, ref3);
1598  ref4 = get_refcount((IUnknown *)d3drm3);
1599  ok(ref4 == ref1, "Test %u: expected ref4 == ref1, got ref1 = %u, ref4 = %u.\n", i, ref1, ref4);
1600 
1601  /* test Add/Destroy callbacks */
1603 
1604  hr = IDirect3DRM2_CreateObject(d3drm2, tests[i].clsid, NULL, tests[i].iid, (void **)&unknown);
1605  ok(SUCCEEDED(hr), "Test %u: expected hr == D3DRM_OK, got %#x.\n", i, hr);
1606  ref2 = get_refcount((IUnknown *)d3drm1);
1607  if (tests[i].takes_d3drm_ref)
1608  ok(ref2 > ref1, "Test %u: expected ref2 > ref1, got ref1 = %u, ref2 = %u.\n", i, ref1, ref2);
1609  else
1610  ok(ref2 == ref1, "Test %u: expected ref2 == ref1, got ref1 = %u, ref2 = %u.\n", i, ref1, ref2);
1611  ref3 = get_refcount((IUnknown *)d3drm2);
1612  ok(ref3 == ref1, "Test %u: expected ref3 == ref1, got ref1 = %u, ref3 = %u.\n", i, ref1, ref3);
1613  ref4 = get_refcount((IUnknown *)d3drm3);
1614  ok(ref4 == ref1, "Test %u: expected ref4 == ref1, got ref1 = %u, ref4 = %u.\n", i, ref1, ref4);
1615  IUnknown_Release(unknown);
1616  ref2 = get_refcount((IUnknown *)d3drm1);
1617  ok(ref2 == ref1, "Test %u: expected ref2 == ref1, got ref1 = %u, ref2 = %u.\n", i, ref1, ref2);
1618  ref3 = get_refcount((IUnknown *)d3drm2);
1619  ok(ref3 == ref1, "Test %u: expected ref3 == ref1, got ref1 = %u, ref3 = %u.\n", i, ref1, ref3);
1620  ref4 = get_refcount((IUnknown *)d3drm3);
1621  ok(ref4 == ref1, "Test %u: expected ref4 == ref1, got ref1 = %u, ref4 = %u.\n", i, ref1, ref4);
1622 
1623  hr = IDirect3DRM3_CreateObject(d3drm3, tests[i].clsid, NULL, tests[i].iid, (void **)&unknown);
1624  ok(SUCCEEDED(hr), "Test %u: expected hr == D3DRM_OK, got %#x.\n", i, hr);
1625  ref2 = get_refcount((IUnknown *)d3drm1);
1626  if (tests[i].takes_d3drm_ref)
1627  ok(ref2 > ref1, "Test %u: expected ref2 > ref1, got ref1 = %u, ref2 = %u.\n", i, ref1, ref2);
1628  else
1629  ok(ref2 == ref1, "Test %u: expected ref2 == ref1, got ref1 = %u, ref2 = %u.\n", i, ref1, ref2);
1630  ref3 = get_refcount((IUnknown *)d3drm2);
1631  ok(ref3 == ref1, "Test %u: expected ref3 == ref1, got ref1 = %u, ref3 = %u.\n", i, ref1, ref3);
1632  ref4 = get_refcount((IUnknown *)d3drm3);
1633  ok(ref4 == ref1, "Test %u: expected ref4 == ref1, got ref1 = %u, ref4 = %u.\n", i, ref1, ref4);
1634  IUnknown_Release(unknown);
1635  ref2 = get_refcount((IUnknown *)d3drm1);
1636  ok(ref2 == ref1, "Test %u: expected ref2 == ref1, got ref1 = %u, ref2 = %u.\n", i, ref1, ref2);
1637  ref3 = get_refcount((IUnknown *)d3drm2);
1638  ok(ref3 == ref1, "Test %u: expected ref3 == ref1, got ref1 = %u, ref3 = %u.\n", i, ref1, ref3);
1639  ref4 = get_refcount((IUnknown *)d3drm3);
1640  ok(ref4 == ref1, "Test %u: expected ref4 == ref1, got ref1 = %u, ref4 = %u.\n", i, ref1, ref4);
1641  }
1642  }
1643 
1644  IDirect3DRM_Release(d3drm1);
1645  IDirect3DRM2_Release(d3drm2);
1646  IDirect3DRM3_Release(d3drm3);
1647 }
1648 
1649 static void test_Viewport(void)
1650 {
1651  IDirectDrawClipper *clipper;
1652  HRESULT hr;
1653  IDirect3DRM *d3drm1;
1654  IDirect3DRM2 *d3drm2;
1655  IDirect3DRM3 *d3drm3;
1656  IDirect3DRMDevice *device1, *d3drm_device1;
1657  IDirect3DRMDevice3 *device3, *d3drm_device3;
1658  IDirect3DRMFrame *frame;
1659  IDirect3DRMFrame3 *frame3;
1660  IDirect3DRMViewport *viewport;
1661  IDirect3DRMViewport2 *viewport2;
1662  IDirect3DViewport *d3d_viewport;
1663  D3DVIEWPORT vp;
1664  D3DVALUE expected_val;
1665  IDirect3DRMObject *obj, *obj2;
1666  GUID driver;
1667  HWND window;
1668  RECT rc;
1669  DWORD data, ref1, ref2, ref3, ref4;
1670  DWORD initial_ref1, initial_ref2, initial_ref3, device_ref, frame_ref, frame_ref2, viewport_ref;
1671 
1672  window = create_window();
1673  GetClientRect(window, &rc);
1674 
1675  hr = Direct3DRMCreate(&d3drm1);
1676  ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x)\n", hr);
1677  hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM2, (void **)&d3drm2);
1678  ok(SUCCEEDED(hr), "Cannot get IDirect3DRM2 interface (hr = %#x).\n", hr);
1679  hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM3, (void **)&d3drm3);
1680  ok(SUCCEEDED(hr), "Cannot get IDirect3DRM3 interface (hr = %#x).\n", hr);
1681  initial_ref1 = get_refcount((IUnknown *)d3drm1);
1682  initial_ref2 = get_refcount((IUnknown *)d3drm2);
1683  initial_ref3 = get_refcount((IUnknown *)d3drm3);
1684 
1685  hr = DirectDrawCreateClipper(0, &clipper, NULL);
1686  ok(hr == DD_OK, "Cannot get IDirectDrawClipper interface (hr = %x)\n", hr);
1687 
1688  hr = IDirectDrawClipper_SetHWnd(clipper, 0, window);
1689  ok(hr == DD_OK, "Cannot set HWnd to Clipper (hr = %x)\n", hr);
1690 
1691  memcpy(&driver, &IID_IDirect3DRGBDevice, sizeof(GUID));
1692  hr = IDirect3DRM3_CreateDeviceFromClipper(d3drm3, clipper, &driver, rc.right, rc.bottom, &device3);
1693  ok(hr == D3DRM_OK, "Cannot get IDirect3DRMDevice interface (hr = %x)\n", hr);
1694  hr = IDirect3DRMDevice3_QueryInterface(device3, &IID_IDirect3DRMDevice, (void **)&device1);
1695  ok(SUCCEEDED(hr), "Cannot get IDirect3DRMDevice interface (hr = %#x).\n", hr);
1696 
1697  hr = IDirect3DRM_CreateFrame(d3drm1, NULL, &frame);
1698  ok(hr == D3DRM_OK, "Cannot get IDirect3DRMFrame interface (hr = %x)\n", hr);
1699  hr = IDirect3DRM3_CreateFrame(d3drm3, NULL, &frame3);
1700  ok(SUCCEEDED(hr), "Cannot get IDirect3DRMFrame3 interface (hr = %x).\n", hr);
1701 
1702  ref1 = get_refcount((IUnknown *)d3drm1);
1703  ref2 = get_refcount((IUnknown *)d3drm2);
1704  ref3 = get_refcount((IUnknown *)d3drm3);
1705  device_ref = get_refcount((IUnknown *)device1);
1706  frame_ref = get_refcount((IUnknown *)frame);
1707 
1708  hr = IDirect3DRM_CreateViewport(d3drm1, device1, frame, 0, 0, 0, 0, &viewport);
1709  ok(SUCCEEDED(hr), "Cannot get IDirect3DRMViewport interface (hr = %#x)\n", hr);
1710  ref4 = get_refcount((IUnknown *)d3drm1);
1711  ok(ref4 > ref1, "Expected ref4 > ref1, got ref1 = %u, ref4 = %u.\n", ref1, ref4);
1712  ref4 = get_refcount((IUnknown *)d3drm2);
1713  ok(ref4 == ref2, "Expected ref4 == ref2, got ref2 = %u, ref4 = %u.\n", ref2, ref4);
1714  ref4 = get_refcount((IUnknown *)d3drm3);
1715  ok(ref4 == ref3, "Expected ref4 == ref3, got ref3 = %u, ref4 = %u.\n", ref3, ref4);
1716  ref4 = get_refcount((IUnknown *)device1);
1717  ok(ref4 == device_ref, "Expected ref4 == device_ref, got device_ref = %u, ref4 = %u.\n", device_ref, ref4);
1718  ref4 = get_refcount((IUnknown *)frame);
1719  ok(ref4 > frame_ref, "Expected ref4 > frame_ref, got frame_ref = %u, ref4 = %u.\n", frame_ref, ref4);
1720 
1721  hr = IDirect3DRMViewport_GetDevice(viewport, &d3drm_device1);
1722  ok(SUCCEEDED(hr), "Cannot get IDirect3DRMDevice interface (hr = %x)\n", hr);
1723  ok(device1 == d3drm_device1, "Expected device returned = %p, got %p.\n", device1, d3drm_device1);
1724  IDirect3DRMDevice_Release(d3drm_device1);
1725 
1726  IDirect3DRMViewport_Release(viewport);
1727  ref4 = get_refcount((IUnknown *)d3drm1);
1728  ok(ref4 == ref1, "Expected ref4 == ref1, got ref1 = %u, ref4 = %u.\n", ref1, ref4);
1729  ref4 = get_refcount((IUnknown *)d3drm2);
1730  ok(ref4 == ref2, "Expected ref4 == ref2, got ref2 = %u, ref4 = %u.\n", ref2, ref4);
1731  ref4 = get_refcount((IUnknown *)d3drm3);
1732  ok(ref4 == ref3, "Expected ref4 == ref3, got ref3 = %u, ref4 = %u.\n", ref3, ref4);
1733  ref4 = get_refcount((IUnknown *)device1);
1734  ok(ref4 == device_ref, "Expected ref4 == device_ref, got device_ref = %u, ref4 = %u.\n", device_ref, ref4);
1735  ref4 = get_refcount((IUnknown *)frame);
1736  ok(ref4 == frame_ref, "Expected ref4 == frame_ref, got frame_ref = %u, ref4 = %u.\n", frame_ref, ref4);
1737 
1738  hr = IDirect3DRM2_CreateViewport(d3drm2, device1, frame, 0, 0, 0, 0, &viewport);
1739  ok(SUCCEEDED(hr), "Cannot get IDirect3DRMViewport interface (hr = %#x)\n", hr);
1740  ref4 = get_refcount((IUnknown *)d3drm1);
1741  ok(ref4 > ref1, "Expected ref4 > ref1, got ref1 = %u, ref4 = %u.\n", ref1, ref4);
1742  ref4 = get_refcount((IUnknown *)d3drm2);
1743  ok(ref4 == ref2, "Expected ref4 == ref2, got ref2 = %u, ref4 = %u.\n", ref2, ref4);
1744  ref4 = get_refcount((IUnknown *)d3drm3);
1745  ok(ref4 == ref3, "Expected ref4 == ref3, got ref3 = %u, ref4 = %u.\n", ref3, ref4);
1746  ref4 = get_refcount((IUnknown *)device1);
1747  ok(ref4 == device_ref, "Expected ref4 == device_ref, got device_ref = %u, ref4 = %u.\n", device_ref, ref4);
1748  ref4 = get_refcount((IUnknown *)frame);
1749  ok(ref4 > frame_ref, "Expected ref4 > frame_ref, got frame_ref = %u, ref4 = %u.\n", frame_ref, ref4);
1750 
1751  hr = IDirect3DRMViewport_GetDevice(viewport, &d3drm_device1);
1752  ok(SUCCEEDED(hr), "Cannot get IDirect3DRMDevice interface (hr = %x)\n", hr);
1753  ok(device1 == d3drm_device1, "Expected device returned = %p, got %p.\n", device1, d3drm_device1);
1754  IDirect3DRMDevice_Release(d3drm_device1);
1755 
1756  IDirect3DRMViewport_Release(viewport);
1757  ref4 = get_refcount((IUnknown *)d3drm1);
1758  ok(ref4 == ref1, "Expected ref4 == ref1, got ref1 = %u, ref4 = %u.\n", ref1, ref4);
1759  ref4 = get_refcount((IUnknown *)d3drm2);
1760  ok(ref4 == ref2, "Expected ref4 == ref2, got ref2 = %u, ref4 = %u.\n", ref2, ref4);
1761  ref4 = get_refcount((IUnknown *)d3drm3);
1762  ok(ref4 == ref3, "Expected ref4 == ref3, got ref3 = %u, ref4 = %u.\n", ref3, ref4);
1763  ref4 = get_refcount((IUnknown *)device1);
1764  ok(ref4 == device_ref, "Expected ref4 == device_ref, got device_ref = %u, ref4 = %u.\n", device_ref, ref4);
1765  ref4 = get_refcount((IUnknown *)frame);
1766  ok(ref4 == frame_ref, "Expected ref4 == frame_ref, got frame_ref = %u, ref4 = %u.\n", frame_ref, ref4);
1767 
1768  device_ref = get_refcount((IUnknown *)device3);
1769  frame_ref2 = get_refcount((IUnknown *)frame3);
1770 
1771  hr = IDirect3DRM3_CreateViewport(d3drm3, device3, frame3, 0, 0, 0, 0, &viewport2);
1772  ok(SUCCEEDED(hr), "Cannot get IDirect3DRMViewport2 interface (hr = %#x)\n", hr);
1773  ref4 = get_refcount((IUnknown *)d3drm1);
1774  ok(ref4 > ref1, "Expected ref4 > ref1, got ref1 = %u, ref4 = %u.\n", ref1, ref4);
1775  ref4 = get_refcount((IUnknown *)d3drm2);
1776  ok(ref4 == ref2, "Expected ref4 == ref2, got ref2 = %u, ref4 = %u.\n", ref2, ref4);
1777  ref4 = get_refcount((IUnknown *)d3drm3);
1778  ok(ref4 == ref3, "Expected ref4 == ref3, got ref3 = %u, ref4 = %u.\n", ref3, ref4);
1779  ref4 = get_refcount((IUnknown *)device3);
1780  ok(ref4 == device_ref, "Expected ref4 == device_ref, got device_ref = %u, ref4 = %u.\n", device_ref, ref4);
1781  ref4 = get_refcount((IUnknown *)frame3);
1782  ok(ref4 > frame_ref2, "Expected ref4 > frame_ref2, got frame_ref2 = %u, ref4 = %u.\n", frame_ref2, ref4);
1783 
1784  hr = IDirect3DRMViewport2_GetDevice(viewport2, &d3drm_device3);
1785  ok(SUCCEEDED(hr), "Cannot get IDirect3DRMDevice3 interface (hr = %x)\n", hr);
1786  ok(device3 == d3drm_device3, "Expected device returned = %p, got %p.\n", device3, d3drm_device3);
1787  IDirect3DRMDevice3_Release(d3drm_device3);
1788 
1789  IDirect3DRMViewport2_Release(viewport2);
1790  ref4 = get_refcount((IUnknown *)d3drm1);
1791  ok(ref4 == ref1, "Expected ref4 == ref1, got ref1 = %u, ref4 = %u.\n", ref1, ref4);
1792  ref4 = get_refcount((IUnknown *)d3drm2);
1793  ok(ref4 == ref2, "Expected ref4 == ref2, got ref2 = %u, ref4 = %u.\n", ref2, ref4);
1794  ref4 = get_refcount((IUnknown *)d3drm3);
1795  ok(ref4 == ref3, "Expected ref4 == ref3, got ref3 = %u, ref4 = %u.\n", ref3, ref4);
1796  ref4 = get_refcount((IUnknown *)device3);
1797  ok(ref4 == device_ref, "Expected ref4 == device_ref, got device_ref = %u, ref4 = %u.\n", device_ref, ref4);
1798  ref4 = get_refcount((IUnknown *)frame3);
1799  ok(ref4 == frame_ref2, "Expected ref4 == frame_ref2, got frame_ref2 = %u, ref4 = %u.\n", frame_ref2, ref4);
1800 
1801  /* Test all failures together */
1802  hr = IDirect3DRM_CreateViewport(d3drm1, NULL, frame, rc.left, rc.top, rc.right, rc.bottom, &viewport);
1803  ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
1804  hr = IDirect3DRM_CreateViewport(d3drm1, device1, NULL, rc.left, rc.top, rc.right, rc.bottom, &viewport);
1805  ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
1806  hr = IDirect3DRM_CreateViewport(d3drm1, device1, frame, rc.left, rc.top, rc.right + 1, rc.bottom + 1, &viewport);
1807  ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
1808  hr = IDirect3DRM_CreateViewport(d3drm1, device1, frame, rc.left, rc.top, rc.right + 1, rc.bottom, &viewport);
1809  ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
1810  hr = IDirect3DRM_CreateViewport(d3drm1, device1, frame, rc.left, rc.top, rc.right, rc.bottom + 1, &viewport);
1811  ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
1812  hr = IDirect3DRM_CreateViewport(d3drm1, device1, frame, rc.left, rc.top, rc.right, rc.bottom, NULL);
1813  ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
1814 
1815  hr = IDirect3DRM2_CreateViewport(d3drm2, NULL, frame, rc.left, rc.top, rc.right, rc.bottom, &viewport);
1816  ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
1817  hr = IDirect3DRM2_CreateViewport(d3drm2, device1, NULL, rc.left, rc.top, rc.right, rc.bottom, &viewport);
1818  ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
1819  hr = IDirect3DRM2_CreateViewport(d3drm2, device1, frame, rc.left, rc.top, rc.right + 1, rc.bottom + 1, &viewport);
1820  ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
1821  hr = IDirect3DRM2_CreateViewport(d3drm2, device1, frame, rc.left, rc.top, rc.right + 1, rc.bottom, &viewport);
1822  ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
1823  hr = IDirect3DRM2_CreateViewport(d3drm2, device1, frame, rc.left, rc.top, rc.right, rc.bottom + 1, &viewport);
1824  ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
1825  hr = IDirect3DRM2_CreateViewport(d3drm2, device1, frame, rc.left, rc.top, rc.right, rc.bottom, NULL);
1826  ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
1827 
1828  hr = IDirect3DRM3_CreateViewport(d3drm3, NULL, frame3, rc.left, rc.top, rc.right, rc.bottom, &viewport2);
1829  ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
1830  hr = IDirect3DRM3_CreateViewport(d3drm3, device3, NULL, rc.left, rc.top, rc.right, rc.bottom, &viewport2);
1831  ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
1832  hr = IDirect3DRM3_CreateViewport(d3drm3, device3, frame3, rc.left, rc.top, rc.right + 1, rc.bottom + 1, &viewport2);
1833  ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
1834  hr = IDirect3DRM3_CreateViewport(d3drm3, device3, frame3, rc.left, rc.top, rc.right + 1, rc.bottom, &viewport2);
1835  ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
1836  hr = IDirect3DRM3_CreateViewport(d3drm3, device3, frame3, rc.left, rc.top, rc.right, rc.bottom + 1, &viewport2);
1837  ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
1838  hr = IDirect3DRM3_CreateViewport(d3drm3, device3, frame3, rc.left, rc.top, rc.right, rc.bottom, NULL);
1839  ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
1840 
1841  hr = IDirect3DRM2_CreateViewport(d3drm2, device1, frame, rc.left, rc.top, rc.right, rc.bottom, &viewport);
1842  ok(hr == D3DRM_OK, "Cannot get IDirect3DRMViewport interface (hr = %#x)\n", hr);
1844  ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport interface (hr = %#x).\n", hr);
1845  viewport_ref = get_refcount((IUnknown *)d3d_viewport);
1847  ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport interface (hr = %#x).\n", hr);
1848  ref4 = get_refcount((IUnknown *)d3d_viewport);
1849  ok(ref4 > viewport_ref, "Expected ref4 > viewport_ref, got ref4 = %u, viewport_ref = %u.\n", ref4, viewport_ref);
1851  ref4 = get_refcount((IUnknown *)d3d_viewport);
1852  ok(ref4 == viewport_ref, "Expected ref4 == viewport_ref, got ref4 = %u, viewport_ref = %u.\n", ref4, viewport_ref);
1854 
1856  ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport interface (hr = %#x).\n", hr);
1857  vp.dwSize = sizeof(vp);
1859  ok(SUCCEEDED(hr), "Cannot get D3DVIEWPORT struct (hr = %#x).\n", hr);
1860  ok(vp.dwWidth == rc.right, "Expected viewport width = %u, got %u.\n", rc.right, vp.dwWidth);
1861  ok(vp.dwHeight == rc.bottom, "Expected viewport height = %u, got %u.\n", rc.bottom, vp.dwHeight);
1862  ok(vp.dwX == rc.left, "Expected viewport X position = %u, got %u.\n", rc.left, vp.dwX);
1863  ok(vp.dwY == rc.top, "Expected viewport Y position = %u, got %u.\n", rc.top, vp.dwY);
1864  expected_val = (rc.right > rc.bottom) ? (rc.right / 2.0f) : (rc.bottom / 2.0f);
1865  ok(vp.dvScaleX == expected_val, "Expected dvScaleX = %f, got %f.\n", expected_val, vp.dvScaleX);
1866  ok(vp.dvScaleY == expected_val, "Expected dvScaleY = %f, got %f.\n", expected_val, vp.dvScaleY);
1867  expected_val = vp.dwWidth / (2.0f * vp.dvScaleX);
1868  ok(vp.dvMaxX == expected_val, "Expected dvMaxX = %f, got %f.\n", expected_val, vp.dvMaxX);
1869  expected_val = vp.dwHeight / (2.0f * vp.dvScaleY);
1870  ok(vp.dvMaxY == expected_val, "Expected dvMaxY = %f, got %f.\n", expected_val, vp.dvMaxY);
1872  IDirect3DRMViewport_Release(viewport);
1873 
1874  hr = IDirect3DRM3_CreateViewport(d3drm3, device3, frame3, rc.left, rc.top, rc.right, rc.bottom, &viewport2);
1875  ok(hr == D3DRM_OK, "Cannot get IDirect3DRMViewport2 interface (hr = %#x)\n", hr);
1877  ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport interface (hr = %#x).\n", hr);
1878  viewport_ref = get_refcount((IUnknown *)d3d_viewport);
1880  ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport interface (hr = %#x).\n", hr);
1881  ref4 = get_refcount((IUnknown *)d3d_viewport);
1882  ok(ref4 > viewport_ref, "Expected ref4 > viewport_ref, got ref4 = %u, viewport_ref = %u.\n", ref4, viewport_ref);
1884  ref4 = get_refcount((IUnknown *)d3d_viewport);
1885  ok(ref4 == viewport_ref, "Expected ref4 == viewport_ref, got ref4 = %u, viewport_ref = %u.\n", ref4, viewport_ref);
1887 
1889  ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport interface (hr = %#x).\n", hr);
1890  vp.dwSize = sizeof(vp);
1892  ok(SUCCEEDED(hr), "Cannot get D3DVIEWPORT struct (hr = %#x).\n", hr);
1893  ok(vp.dwWidth == rc.right, "Expected viewport width = %u, got %u.\n", rc.right, vp.dwWidth);
1894  ok(vp.dwHeight == rc.bottom, "Expected viewport height = %u, got %u.\n", rc.bottom, vp.dwHeight);
1895  ok(vp.dwX == rc.left, "Expected viewport X position = %u, got %u.\n", rc.left, vp.dwX);
1896  ok(vp.dwY == rc.top, "Expected viewport Y position = %u, got %u.\n", rc.top, vp.dwY);
1897  expected_val = (rc.right > rc.bottom) ? (rc.right / 2.0f) : (rc.bottom / 2.0f);
1898  ok(vp.dvScaleX == expected_val, "Expected dvScaleX = %f, got %f.\n", expected_val, vp.dvScaleX);
1899  ok(vp.dvScaleY == expected_val, "Expected dvScaleY = %f, got %f.\n", expected_val, vp.dvScaleY);
1900  expected_val = vp.dwWidth / (2.0f * vp.dvScaleX);
1901  ok(vp.dvMaxX == expected_val, "Expected dvMaxX = %f, got %f.\n", expected_val, vp.dvMaxX);
1902  expected_val = vp.dwHeight / (2.0f * vp.dvScaleY);
1903  ok(vp.dvMaxY == expected_val, "Expected dvMaxY = %f, got %f.\n", expected_val, vp.dvMaxY);
1905  IDirect3DRMViewport2_Release(viewport2);
1906 
1907  hr = IDirect3DRM_CreateViewport(d3drm1, device1, frame, rc.left, rc.top, rc.right, rc.bottom, &viewport);
1908  ok(hr == D3DRM_OK, "Cannot get IDirect3DRMViewport interface (hr = %x)\n", hr);
1910  ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport interface (hr = %#x).\n", hr);
1911  viewport_ref = get_refcount((IUnknown *)d3d_viewport);
1913  ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport interface (hr = %#x).\n", hr);
1914  ref4 = get_refcount((IUnknown *)d3d_viewport);
1915  ok(ref4 > viewport_ref, "Expected ref4 > viewport_ref, got ref4 = %u, viewport_ref = %u.\n", ref4, viewport_ref);
1917  ref4 = get_refcount((IUnknown *)d3d_viewport);
1918  ok(ref4 == viewport_ref, "Expected ref4 == viewport_ref, got ref4 = %u, viewport_ref = %u.\n", ref4, viewport_ref);
1920 
1922  ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport interface (hr = %#x).\n", hr);
1923  vp.dwSize = sizeof(vp);
1925  ok(SUCCEEDED(hr), "Cannot get D3DVIEWPORT struct (hr = %#x).\n", hr);
1926  ok(vp.dwWidth == rc.right, "Expected viewport width = %u, got %u.\n", rc.right, vp.dwWidth);
1927  ok(vp.dwHeight == rc.bottom, "Expected viewport height = %u, got %u.\n", rc.bottom, vp.dwHeight);
1928  ok(vp.dwX == rc.left, "Expected viewport X position = %u, got %u.\n", rc.left, vp.dwX);
1929  ok(vp.dwY == rc.top, "Expected viewport Y position = %u, got %u.\n", rc.top, vp.dwY);
1930  expected_val = (rc.right > rc.bottom) ? (rc.right / 2.0f) : (rc.bottom / 2.0f);
1931  ok(vp.dvScaleX == expected_val, "Expected dvScaleX = %f, got %f.\n", expected_val, vp.dvScaleX);
1932  ok(vp.dvScaleY == expected_val, "Expected dvScaleY = %f, got %f.\n", expected_val, vp.dvScaleY);
1933  expected_val = vp.dwWidth / (2.0f * vp.dvScaleX);
1934  ok(vp.dvMaxX == expected_val, "Expected dvMaxX = %f, got %f.\n", expected_val, vp.dvMaxX);
1935  expected_val = vp.dwHeight / (2.0f * vp.dvScaleY);
1936  ok(vp.dvMaxY == expected_val, "Expected dvMaxY = %f, got %f.\n", expected_val, vp.dvMaxY);
1938 
1939  hr = IDirect3DRMViewport_QueryInterface(viewport, &IID_IDirect3DRMObject, (void**)&obj);
1940  ok(hr == D3DRM_OK, "expected D3DRM_OK (hr = %x)\n", hr);
1941  ok((IDirect3DRMObject*)viewport == obj, "got object pointer %p, expected %p\n", obj, viewport);
1942 
1943  hr = IDirect3DRMViewport_QueryInterface(viewport, &IID_IDirect3DRMViewport2, (void**)&viewport2);
1944  ok(hr == D3DRM_OK, "expected D3DRM_OK (hr = %x)\n", hr);
1945 
1946  hr = IDirect3DRMViewport2_QueryInterface(viewport2, &IID_IDirect3DRMObject, (void**)&obj2);
1947  ok(hr == D3DRM_OK, "expected D3DRM_OK (hr = %x)\n", hr);
1948  ok(obj == obj2, "got object pointer %p, expected %p\n", obj2, obj);
1949  ok((IUnknown*)viewport != (IUnknown*)viewport2, "got viewport1 %p, viewport2 %p\n", viewport, viewport2);
1950 
1951  IDirect3DRMViewport2_Release(viewport2);
1954 
1955  test_class_name((IDirect3DRMObject *)viewport, "Viewport");
1956  test_object_name((IDirect3DRMObject *)viewport);
1957 
1958  /* AppData */
1959  hr = IDirect3DRMViewport_SetAppData(viewport, 0);
1960  ok(hr == D3DRM_OK, "expected D3DRM_OK (hr = %x)\n", hr);
1961 
1962  hr = IDirect3DRMViewport_SetAppData(viewport, 0);
1963  ok(hr == D3DRM_OK, "expected D3DRM_OK (hr = %x)\n", hr);
1964 
1965  hr = IDirect3DRMViewport_SetAppData(viewport, 1);
1966  ok(hr == D3DRM_OK, "expected D3DRM_OK (hr = %x)\n", hr);
1967 
1968  hr = IDirect3DRMViewport_SetAppData(viewport, 1);
1969  ok(hr == D3DRM_OK, "expected D3DRM_OK (hr = %x)\n", hr);
1970 
1971  hr = IDirect3DRMViewport_QueryInterface(viewport, &IID_IDirect3DRMViewport2, (void**)&viewport2);
1972  ok(hr == D3DRM_OK, "expected D3DRM_OK (hr = %x)\n", hr);
1973 
1975  ok(data == 1, "got %x\n", data);
1976  IDirect3DRMViewport2_Release(viewport2);
1977  IDirect3DRMViewport_Release(viewport);
1978 
1979  /* IDirect3DRMViewport*::Init tests */
1980  ref1 = get_refcount((IUnknown *)d3drm1);
1981  ref2 = get_refcount((IUnknown *)d3drm2);
1982  ref3 = get_refcount((IUnknown *)d3drm3);
1983  hr = IDirect3DRM_CreateObject(d3drm1, &CLSID_CDirect3DRMViewport, NULL, &IID_IDirect3DRMViewport,
1984  (void **)&viewport);
1985  ok(SUCCEEDED(hr), "Cannot get IDirect3DRMViewport interface (hr = %#x).\n", hr);
1986  ref4 = get_refcount((IUnknown *)d3drm1);
1987  ok(ref4 == ref1, "Expected ref4 == ref1, got ref1 = %u, ref4 = %u.\n", ref1, ref4);
1988  ref4 = get_refcount((IUnknown *)d3drm2);
1989  ok(ref4 == ref2, "Expected ref4 == ref2, got ref2 = %u, ref4 = %u.\n", ref2, ref4);
1990  ref4 = get_refcount((IUnknown *)d3drm3);
1991  ok(ref4 == ref3, "Expected ref4 == ref3, got ref3 = %u, ref4 = %u.\n", ref3, ref4);
1992 
1994  ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
1995  hr = IDirect3DRMViewport_GetDevice(viewport, &d3drm_device1);
1996  ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
1997 
1998  /* Test all failures together */
1999  hr = IDirect3DRMViewport_Init(viewport, NULL, frame, rc.left, rc.top, rc.right, rc.bottom);
2000  ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2001  hr = IDirect3DRMViewport_Init(viewport, device1, NULL, rc.left, rc.top, rc.right, rc.bottom);
2002  ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2003  hr = IDirect3DRMViewport_Init(viewport, device1, frame, rc.left, rc.top, rc.right + 1, rc.bottom + 1);
2004  ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2005  hr = IDirect3DRMViewport_Init(viewport, device1, frame, rc.left, rc.top, rc.right + 1, rc.bottom);
2006  ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2007  hr = IDirect3DRMViewport_Init(viewport, device1, frame, rc.left, rc.top, rc.right, rc.bottom + 1);
2008  ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2009 
2010  device_ref = get_refcount((IUnknown *)device1);
2011  frame_ref = get_refcount((IUnknown *)frame);
2012  hr = IDirect3DRMViewport_Init(viewport, device1, frame, rc.left, rc.top, rc.right, rc.bottom);
2013  ok(SUCCEEDED(hr), "Cannot initialize IDirect3DRMViewport interface (hr = %#x).\n", hr);
2014  ref4 = get_refcount((IUnknown *)d3drm1);
2015  ok(ref4 > ref1, "Expected ref4 > ref1, got ref1 = %u, ref4 = %u.\n", ref1, ref4);
2016  ref4 = get_refcount((IUnknown *)d3drm2);
2017  ok(ref4 == ref2, "Expected ref4 == ref2, got ref2 = %u, ref4 = %u.\n", ref2, ref4);
2018  ref4 = get_refcount((IUnknown *)d3drm3);
2019  ok(ref4 == ref3, "Expected ref4 == ref3, got ref3 = %u, ref4 = %u.\n", ref3, ref4);
2020  ref4 = get_refcount((IUnknown *)device1);
2021  ok(ref4 == device_ref, "Expected ref4 == device_ref, got device_ref = %u, ref4 = %u.\n", device_ref, ref4);
2022  ref4 = get_refcount((IUnknown *)frame);
2023  ok(ref4 > frame_ref, "Expected ref4 > frame_ref, got frame_ref = %u, ref4 = %u.\n", frame_ref, ref4);
2024 
2025  hr = IDirect3DRMViewport_GetDevice(viewport, &d3drm_device1);
2026  ok(SUCCEEDED(hr), "Cannot get IDirect3DRMDevice3 interface (hr = %x)\n", hr);
2027  ok(device1 == d3drm_device1, "Expected device returned = %p, got %p.\n", device3, d3drm_device3);
2028  IDirect3DRMDevice_Release(d3drm_device1);
2029 
2031  ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport interface (hr = %#x).\n", hr);
2032  viewport_ref = get_refcount((IUnknown *)d3d_viewport);
2034  ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport interface (hr = %#x).\n", hr);
2035  ref4 = get_refcount((IUnknown *)d3d_viewport);
2036  ok(ref4 > viewport_ref, "Expected ref4 > viewport_ref, got ref4 = %u, viewport_ref = %u.\n", ref4, viewport_ref);
2038  ref4 = get_refcount((IUnknown *)d3d_viewport);
2039  ok(ref4 == viewport_ref, "Expected ref4 == viewport_ref, got ref4 = %u, viewport_ref = %u.\n", ref4, viewport_ref);
2041 
2043  ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport interface (hr = %#x).\n", hr);
2044  vp.dwSize = sizeof(vp);
2046  ok(SUCCEEDED(hr), "Cannot get D3DVIEWPORT struct (hr = %#x).\n", hr);
2047  ok(vp.dwWidth == rc.right, "Expected viewport width = %u, got %u.\n", rc.right, vp.dwWidth);
2048  ok(vp.dwHeight == rc.bottom, "Expected viewport height = %u, got %u.\n", rc.bottom, vp.dwHeight);
2049  ok(vp.dwX == rc.left, "Expected viewport X position = %u, got %u.\n", rc.left, vp.dwX);
2050  ok(vp.dwY == rc.top, "Expected viewport Y position = %u, got %u.\n", rc.top, vp.dwY);
2051  expected_val = (rc.right > rc.bottom) ? (rc.right / 2.0f) : (rc.bottom / 2.0f);
2052  ok(vp.dvScaleX == expected_val, "Expected dvScaleX = %f, got %f.\n", expected_val, vp.dvScaleX);
2053  ok(vp.dvScaleY == expected_val, "Expected dvScaleY = %f, got %f.\n", expected_val, vp.dvScaleY);
2054  expected_val = vp.dwWidth / (2.0f * vp.dvScaleX);
2055  ok(vp.dvMaxX == expected_val, "Expected dvMaxX = %f, got %f.\n", expected_val, vp.dvMaxX);
2056  expected_val = vp.dwHeight / (2.0f * vp.dvScaleY);
2057  ok(vp.dvMaxY == expected_val, "Expected dvMaxY = %f, got %f.\n", expected_val, vp.dvMaxY);
2059 
2060  hr = IDirect3DRMViewport_Init(viewport, device1, frame, rc.left, rc.top, rc.right, rc.bottom);
2061  ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2062 
2063  IDirect3DRMViewport_Release(viewport);
2064  ref4 = get_refcount((IUnknown *)d3drm1);
2065  todo_wine ok(ref4 > ref1, "Expected ref4 > ref1, got ref1 = %u, ref4 = %u.\n", ref1, ref4);
2066  ref4 = get_refcount((IUnknown *)d3drm2);
2067  ok(ref4 == ref2, "Expected ref4 == ref2, got ref2 = %u, ref4 = %u.\n", ref2, ref4);
2068  ref4 = get_refcount((IUnknown *)d3drm3);
2069  ok(ref4 == ref3, "Expected ref4 == ref3, got ref3 = %u, ref4 = %u.\n", ref3, ref4);
2070  ref4 = get_refcount((IUnknown *)device1);
2071  ok(ref4 == device_ref, "Expected ref4 == device_ref, got device_ref = %u, ref4 = %u.\n", device_ref, ref4);
2072  ref4 = get_refcount((IUnknown *)frame);
2073  todo_wine ok(ref4 > frame_ref, "Expected ref4 > frame_ref, got frame_ref = %u, ref4 = %u.\n", frame_ref, ref4);
2074 
2075  ref1 = get_refcount((IUnknown *)d3drm1);
2076  ref2 = get_refcount((IUnknown *)d3drm2);
2077  ref3 = get_refcount((IUnknown *)d3drm3);
2078  hr = IDirect3DRM3_CreateObject(d3drm2, &CLSID_CDirect3DRMViewport, NULL, &IID_IDirect3DRMViewport2,
2079  (void **)&viewport2);
2080  ok(SUCCEEDED(hr), "Cannot get IDirect3DRMViewport2 interface (hr = %#x).\n", hr);
2081  ref4 = get_refcount((IUnknown *)d3drm1);
2082  ok(ref4 == ref1, "Expected ref4 == ref1, got ref1 = %u, ref4 = %u.\n", ref1, ref4);
2083  ref4 = get_refcount((IUnknown *)d3drm2);
2084  ok(ref4 == ref2, "Expected ref4 == ref2, got ref2 = %u, ref4 = %u.\n", ref2, ref4);
2085  ref4 = get_refcount((IUnknown *)d3drm3);
2086  ok(ref4 == ref3, "Expected ref4 == ref3, got ref3 = %u, ref4 = %u.\n", ref3, ref4);
2087 
2089  ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2090  hr = IDirect3DRMViewport2_GetDevice(viewport2, &d3drm_device3);
2091  ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2092 
2093  hr = IDirect3DRMViewport2_Init(viewport2, NULL, frame3, rc.left, rc.top, rc.right, rc.bottom);
2094  ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2095  hr = IDirect3DRMViewport2_Init(viewport2, device3, NULL, rc.left, rc.top, rc.right, rc.bottom);
2096  ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2097  hr = IDirect3DRMViewport2_Init(viewport2, device3, frame3, rc.left, rc.top, rc.right + 1, rc.bottom + 1);
2098  ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2099  hr = IDirect3DRMViewport2_Init(viewport2, device3, frame3, rc.left, rc.top, rc.right + 1, rc.bottom);
2100  ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2101  hr = IDirect3DRMViewport2_Init(viewport2, device3, frame3, rc.left, rc.top, rc.right, rc.bottom + 1);
2102  ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2103 
2104  device_ref = get_refcount((IUnknown *)device3);
2105  frame_ref2 = get_refcount((IUnknown *)frame3);
2106  hr = IDirect3DRMViewport2_Init(viewport2, device3, frame3, rc.left, rc.top, rc.right, rc.bottom);
2107  ok(SUCCEEDED(hr), "Cannot initialize IDirect3DRMViewport2 interface (hr = %#x).\n", hr);
2108  ref4 = get_refcount((IUnknown *)device3);
2109  ok(ref4 == device_ref, "Expected ref4 == device_ref, got device_ref = %u, ref4 = %u.\n", device_ref, ref4);
2110  ref4 = get_refcount((IUnknown *)frame3);
2111  ok(ref4 > frame_ref2, "Expected ref4 > frame_ref2, got frame_ref2 = %u, ref4 = %u.\n", frame_ref2, ref4);
2112 
2113  hr = IDirect3DRMViewport2_GetDevice(viewport2, &d3drm_device3);
2114  ok(SUCCEEDED(hr), "Cannot get IDirect3DRMDevice3 interface (hr = %x)\n", hr);
2115  ok(device3 == d3drm_device3, "Expected device returned = %p, got %p.\n", device3, d3drm_device3);
2116  IDirect3DRMDevice3_Release(d3drm_device3);
2117 
2119  ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport interface (hr = %#x).\n", hr);
2120  viewport_ref = get_refcount((IUnknown *)d3d_viewport);
2122  ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport interface (hr = %#x).\n", hr);
2123  ref4 = get_refcount((IUnknown *)d3d_viewport);
2124  ok(ref4 > viewport_ref, "Expected ref4 > viewport_ref, got ref4 = %u, viewport_ref = %u.\n", ref4, viewport_ref);
2126  ref4 = get_refcount((IUnknown *)d3d_viewport);
2127  ok(ref4 == viewport_ref, "Expected ref4 == viewport_ref, got ref4 = %u, viewport_ref = %u.\n", ref4, viewport_ref);
2129 
2131  ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport interface (hr = %#x).\n", hr);
2132  vp.dwSize = sizeof(vp);
2134  ok(SUCCEEDED(hr), "Cannot get D3DVIEWPORT struct (hr = %#x).\n", hr);
2135  ok(vp.dwWidth == rc.right, "Expected viewport width = %u, got %u.\n", rc.right, vp.dwWidth);
2136  ok(vp.dwHeight == rc.bottom, "Expected viewport height = %u, got %u.\n", rc.bottom, vp.dwHeight);
2137  ok(vp.dwX == rc.left, "Expected viewport X position = %u, got %u.\n", rc.left, vp.dwX);
2138  ok(vp.dwY == rc.top, "Expected viewport Y position = %u, got %u.\n", rc.top, vp.dwY);
2139  expected_val = (rc.right > rc.bottom) ? (rc.right / 2.0f) : (rc.bottom / 2.0f);
2140  ok(vp.dvScaleX == expected_val, "Expected dvScaleX = %f, got %f.\n", expected_val, vp.dvScaleX);
2141  ok(vp.dvScaleY == expected_val, "Expected dvScaleY = %f, got %f.\n", expected_val, vp.dvScaleY);
2142  expected_val = vp.dwWidth / (2.0f * vp.dvScaleX);
2143  ok(vp.dvMaxX == expected_val, "Expected dvMaxX = %f, got %f.\n", expected_val, vp.dvMaxX);
2144  expected_val = vp.dwHeight / (2.0f * vp.dvScaleY);
2145  ok(vp.dvMaxY == expected_val, "Expected dvMaxY = %f, got %f.\n", expected_val, vp.dvMaxY);
2147 
2148  hr = IDirect3DRMViewport2_Init(viewport2, device3, frame3, rc.left, rc.top, rc.right, rc.bottom);
2149  ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2150 
2151  IDirect3DRMViewport2_Release(viewport2);
2152  ref4 = get_refcount((IUnknown *)d3drm1);
2153  todo_wine ok(ref4 > ref1, "Expected ref4 > ref1, got ref1 = %u, ref4 = %u.\n", ref1, ref4);
2154  ref4 = get_refcount((IUnknown *)d3drm2);
2155  ok(ref4 == ref2, "Expected ref4 == ref2, got ref2 = %u, ref4 = %u.\n", ref2, ref4);
2156  ref4 = get_refcount((IUnknown *)d3drm3);
2157  ok(ref4 == ref3, "Expected ref4 == ref3, got ref3 = %u, ref4 = %u.\n", ref3, ref4);
2158  ref4 = get_refcount((IUnknown *)device3);
2159  ok(ref4 == device_ref, "Expected ref4 == device_ref, got device_ref = %u, ref4 = %u.\n", device_ref, ref4);
2160  ref4 = get_refcount((IUnknown *)frame3);
2161  todo_wine ok(ref4 > frame_ref2, "Expected ref4 > frame_ref2, got frame_ref2 = %u, ref4 = %u.\n", frame_ref2, ref4);
2162 
2163  IDirect3DRMDevice3_Release(device3);
2164  IDirect3DRMDevice_Release(device1);
2165  ref4 = get_refcount((IUnknown *)d3drm1);
2166  ok(ref4 > initial_ref1, "Expected ref4 > initial_ref1, got initial_ref1 = %u, ref4 = %u.\n", initial_ref1, ref4);
2167  ref4 = get_refcount((IUnknown *)d3drm2);
2168  ok(ref4 == initial_ref2, "Expected ref4 == initial_ref2, got initial_ref2 = %u, ref4 = %u.\n", initial_ref2, ref4);
2169  ref4 = get_refcount((IUnknown *)d3drm3);
2170  ok(ref4 == initial_ref3, "Expected ref4 == initial_ref3, got initial_ref3 = %u, ref4 = %u.\n", initial_ref3, ref4);
2171  ref4 = get_refcount((IUnknown *)frame);
2172  ok(ref4 == frame_ref, "Expected ref4 == frame_ref, got frame_ref = %u, ref4 = %u.\n", frame_ref, ref4);
2173  ref4 = get_refcount((IUnknown *)frame3);
2174  ok(ref4 == frame_ref2, "Expected ref4 == frame_ref2, got frame_ref2 = %u, ref4 = %u.\n", frame_ref2, ref4);
2175 
2176  IDirect3DRMFrame3_Release(frame3);
2177  ref4 = get_refcount((IUnknown *)d3drm1);
2178  ok(ref4 > initial_ref1, "Expected ref4 > initial_ref1, got initial_ref1 = %u, ref4 = %u.\n", initial_ref1, ref4);
2179  ref4 = get_refcount((IUnknown *)d3drm2);
2180  ok(ref4 == initial_ref2, "Expected ref4 == initial_ref2, got initial_ref2 = %u, ref4 = %u.\n", initial_ref2, ref4);
2181  ref4 = get_refcount((IUnknown *)d3drm3);
2182  ok(ref4 == initial_ref3, "Expected ref4 == initial_ref3, got initial_ref3 = %u, ref4 = %u.\n", initial_ref3, ref4);
2183 
2184  IDirect3DRMFrame_Release(frame);
2185  ref4 = get_refcount((IUnknown *)d3drm1);
2186  ok(ref4 == initial_ref1, "Expected ref4 == initial_ref1, got initial_ref1 = %u, ref4 = %u.\n", initial_ref1, ref4);
2187  ref4 = get_refcount((IUnknown *)d3drm2);
2188  ok(ref4 == initial_ref2, "Expected ref4 == initial_ref2, got initial_ref2 = %u, ref4 = %u.\n", initial_ref2, ref4);
2189  ref4 = get_refcount((IUnknown *)d3drm3);
2190  ok(ref4 == initial_ref3, "Expected ref4 == initial_ref3, got initial_ref3 = %u, ref4 = %u.\n", initial_ref3, ref4);
2191  IDirectDrawClipper_Release(clipper);
2192 
2193  IDirect3DRM3_Release(d3drm3);
2194  IDirect3DRM2_Release(d3drm2);
2195  IDirect3DRM_Release(d3drm1);
2197 }
2198 
2199 static void test_Light(void)
2200 {
2201  IDirect3DRMObject *object;
2202  HRESULT hr;
2203  IDirect3DRM *d3drm;
2204  IDirect3DRMLight *light;
2206  D3DCOLOR color;
2207 
2209  ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x)\n", hr);
2210 
2212  ok(hr == D3DRM_OK, "Cannot get IDirect3DRMLight interface (hr = %x)\n", hr);
2213 
2214  hr = IDirect3DRMLight_QueryInterface(light, &IID_IDirect3DRMObject, (void **)&object);
2215  ok(SUCCEEDED(hr), "Failed to get IDirect3DRMObject, hr %#x.\n", hr);
2216  IDirect3DRMObject_Release(object);
2217 
2218  test_class_name((IDirect3DRMObject *)light, "Light");
2219  test_object_name((IDirect3DRMObject *)light);
2220 
2222  ok(type == D3DRMLIGHT_SPOT, "wrong type (%u)\n", type);
2223 
2225  ok(color == 0xff7f7f7f, "wrong color (%x)\n", color);
2226 
2228  ok(hr == D3DRM_OK, "Cannot set type (hr = %x)\n", hr);
2230  ok(type == D3DRMLIGHT_POINT, "wrong type (%u)\n", type);
2231 
2232  hr = IDirect3DRMLight_SetColor(light, 0xff180587);
2233  ok(hr == D3DRM_OK, "Cannot set color (hr = %x)\n", hr);
2235  ok(color == 0xff180587, "wrong color (%x)\n", color);
2236 
2237  hr = IDirect3DRMLight_SetColorRGB(light, 0.5, 0.5, 0.5);
2238  ok(hr == D3DRM_OK, "Cannot set color (hr = %x)\n", hr);
2240  ok(color == 0xff7f7f7f, "wrong color (%x)\n", color);
2241 
2243 
2245 }
2246 
2247 static void test_Material2(void)
2248 {
2249  HRESULT hr;
2250  IDirect3DRM *d3drm;
2251  IDirect3DRM3 *d3drm3;
2252  IDirect3DRMMaterial2 *material2;
2253  D3DVALUE r, g, b;
2254 
2256  ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x)\n", hr);
2257 
2258  if (FAILED(hr = IDirect3DRM_QueryInterface(d3drm, &IID_IDirect3DRM3, (void **)&d3drm3)))
2259  {
2260  win_skip("Cannot get IDirect3DRM3 interface (hr = %x), skipping tests\n", hr);
2262  return;
2263  }
2264 
2265  hr = IDirect3DRM3_CreateMaterial(d3drm3, 18.5f, &material2);
2266  ok(hr == D3DRM_OK, "Cannot get IDirect3DRMMaterial2 interface (hr = %x)\n", hr);
2267 
2268  test_class_name((IDirect3DRMObject *)material2, "Material");
2269  test_object_name((IDirect3DRMObject *)material2);
2270 
2271  r = IDirect3DRMMaterial2_GetPower(material2);
2272  ok(r == 18.5f, "wrong power (%f)\n", r);
2273 
2274  hr = IDirect3DRMMaterial2_GetEmissive(material2, &r, &g, &b);
2275  ok(hr == D3DRM_OK, "Cannot get emissive (hr = %x)\n", hr);
2276  ok(r == 0.0f && g == 0.0f && b == 0.0f, "wrong emissive r=%f g=%f b=%f, expected r=0.0 g=0.0 b=0.0\n", r, g, b);
2277 
2278  hr = IDirect3DRMMaterial2_GetSpecular(material2, &r, &g, &b);
2279  ok(hr == D3DRM_OK, "Cannot get emissive (hr = %x)\n", hr);
2280  ok(r == 1.0f && g == 1.0f && b == 1.0f, "wrong specular r=%f g=%f b=%f, expected r=1.0 g=1.0 b=1.0\n", r, g, b);
2281 
2282  hr = IDirect3DRMMaterial2_GetAmbient(material2, &r, &g, &b);
2283  ok(hr == D3DRM_OK, "Cannot get emissive (hr = %x)\n", hr);
2284  ok(r == 0.0f && g == 0.0f && b == 0.0f, "wrong ambient r=%f g=%f b=%f, expected r=0.0 g=0.0 b=0.0\n", r, g, b);
2285 
2286  hr = IDirect3DRMMaterial2_SetPower(material2, 5.87f);
2287  ok(hr == D3DRM_OK, "Cannot set power (hr = %x)\n", hr);
2288  r = IDirect3DRMMaterial2_GetPower(material2);
2289  ok(r == 5.87f, "wrong power (%f)\n", r);
2290 
2291  hr = IDirect3DRMMaterial2_SetEmissive(material2, 0.5f, 0.5f, 0.5f);
2292  ok(hr == D3DRM_OK, "Cannot set emissive (hr = %x)\n", hr);
2293  hr = IDirect3DRMMaterial2_GetEmissive(material2, &r, &g, &b);
2294  ok(hr == D3DRM_OK, "Cannot get emissive (hr = %x)\n", hr);
2295  ok(r == 0.5f && g == 0.5f && b == 0.5f, "wrong emissive r=%f g=%f b=%f, expected r=0.5 g=0.5 b=0.5\n", r, g, b);
2296 
2297  hr = IDirect3DRMMaterial2_SetSpecular(material2, 0.6f, 0.6f, 0.6f);
2298  ok(hr == D3DRM_OK, "Cannot set specular (hr = %x)\n", hr);
2299  hr = IDirect3DRMMaterial2_GetSpecular(material2, &r, &g, &b);
2300  ok(hr == D3DRM_OK, "Cannot get specular (hr = %x)\n", hr);
2301  ok(r == 0.6f && g == 0.6f && b == 0.6f, "wrong specular r=%f g=%f b=%f, expected r=0.6 g=0.6 b=0.6\n", r, g, b);
2302 
2303  hr = IDirect3DRMMaterial2_SetAmbient(material2, 0.7f, 0.7f, 0.7f);
2304  ok(hr == D3DRM_OK, "Cannot set ambient (hr = %x)\n", hr);
2305  hr = IDirect3DRMMaterial2_GetAmbient(material2, &r, &g, &b);
2306  ok(hr == D3DRM_OK, "Cannot get ambient (hr = %x)\n", hr);
2307  ok(r == 0.7f && g == 0.7f && b == 0.7f, "wrong ambient r=%f g=%f b=%f, expected r=0.7 g=0.7 b=0.7\n", r, g, b);
2308 
2309  IDirect3DRMMaterial2_Release(material2);
2310 
2311  IDirect3DRM3_Release(d3drm3);
2313 }
2314 
2315 static void test_Texture(void)
2316 {
2317  HRESULT hr;
2318  IDirect3DRM *d3drm1;
2319  IDirect3DRM2 *d3drm2;
2320  IDirect3DRM3 *d3drm3;
2321  IDirect3DRMTexture *texture1;
2322  IDirect3DRMTexture2 *texture2;
2323  IDirect3DRMTexture3 *texture3;
2324  IDirectDrawSurface *surface;
2325 
2326  D3DRMIMAGE initimg =
2327  {
2328  2, 2, 1, 1, 32,
2329  TRUE, 2 * sizeof(DWORD), NULL, NULL,
2330  0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000, 0, NULL
2331  },
2332  testimg =
2333  {
2334  0, 0, 0, 0, 0,
2335  TRUE, 0, (void *)0xcafebabe, NULL,
2336  0x000000ff, 0x0000ff00, 0x00ff0000, 0, 0, NULL
2337  },
2338  *d3drm_img = NULL;
2339 
2340  DWORD pixel[4] = { 20000, 30000, 10000, 0 };
2341  ULONG ref1, ref2, ref3, ref4;
2342 
2343  hr = Direct3DRMCreate(&d3drm1);
2344  ok(SUCCEEDED(hr), "Cannot get IDirect3DRM interface (hr = %x)\n", hr);
2345  ref1 = get_refcount((IUnknown *)d3drm1);
2346 
2347  hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM2, (void **)&d3drm2);
2348  ok(SUCCEEDED(hr), "Cannot get IDirect3DRM2 interface (hr = %x).\n", hr);
2349 
2350  hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM3, (void **)&d3drm3);
2351  ok(SUCCEEDED(hr), "Cannot get IDirect3DRM3 interface (hr = %x).\n", hr);
2352 
2353  /* Test NULL params */
2354  texture1 = (IDirect3DRMTexture *)0xdeadbeef;
2355  hr = IDirect3DRM_CreateTexture(d3drm1, NULL, &texture1);
2356  ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
2357  ok(!texture1, "Expected texture returned == NULL, got %p.\n", texture1);
2358  hr = IDirect3DRM_CreateTexture(d3drm1, NULL, NULL);
2359  ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
2360 
2361  texture2 = (IDirect3DRMTexture2 *)0xdeadbeef;
2362  hr = IDirect3DRM2_CreateTexture(d3drm2, NULL, &texture2);
2363  ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
2364  ok(!texture2, "Expected texture returned == NULL, got %p.\n", texture2);
2365  hr = IDirect3DRM2_CreateTexture(d3drm2, NULL, NULL);
2366  ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
2367 
2368  texture3 = (IDirect3DRMTexture3 *)0xdeadbeef;
2369  hr = IDirect3DRM3_CreateTexture(d3drm3, NULL, &texture3);
2370  ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
2371  ok(!texture3, "Expected texture returned == NULL, got %p.\n", texture3);
2372  hr = IDirect3DRM3_CreateTexture(d3drm3, NULL, NULL);
2373  ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
2374 
2375  /* Tests for validation of D3DRMIMAGE struct */
2376  hr = IDirect3DRM_CreateTexture(d3drm1, &testimg, &texture1);
2377  ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture interface (hr = %#x)\n", hr);
2378  hr = IDirect3DRM2_CreateTexture(d3drm2, &testimg, &texture2);
2379  ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture2 interface (hr = %#x)\n", hr);
2380  hr = IDirect3DRM3_CreateTexture(d3drm3, &testimg, &texture3);
2381  ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture3 interface (hr = %#x)\n", hr);
2382  IDirect3DRMTexture_Release(texture1);
2383  IDirect3DRMTexture2_Release(texture2);
2384  IDirect3DRMTexture3_Release(texture3);
2385 
2386  testimg.rgb = 0;
2387  testimg.palette = (void *)0xdeadbeef;
2388  testimg.palette_size = 0x39;
2389  hr = IDirect3DRM_CreateTexture(d3drm1, &testimg, &texture1);
2390  ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture interface (hr = %#x)\n", hr);
2391  hr = IDirect3DRM2_CreateTexture(d3drm2, &testimg, &texture2);
2392  ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture2 interface (hr = %#x)\n", hr);
2393  hr = IDirect3DRM3_CreateTexture(d3drm3, &testimg, &texture3);
2394  ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture3 interface (hr = %#x)\n", hr);
2395  IDirect3DRMTexture_Release(texture1);
2396  IDirect3DRMTexture2_Release(texture2);
2397  IDirect3DRMTexture3_Release(texture3);
2398 
2399  initimg.rgb = 0;
2400  texture1 = (IDirect3DRMTexture *)0xdeadbeef;
2401  hr = IDirect3DRM_CreateTexture(d3drm1, &initimg, &texture1);
2402  ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
2403  ok(!texture1, "Expected texture == NULL, got %p.\n", texture1);
2404  texture2 = (IDirect3DRMTexture2 *)0xdeadbeef;
2405  hr = IDirect3DRM2_CreateTexture(d3drm2, &initimg, &texture2);
2406  ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
2407  ok(!texture2, "Expected texture == NULL, got %p.\n", texture2);
2408  texture3 = (IDirect3DRMTexture3 *)0xdeadbeef;
2409  hr = IDirect3DRM3_CreateTexture(d3drm3, &initimg, &texture3);
2410  ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
2411  ok(!texture3, "Expected texture == NULL, got %p.\n", texture3);
2412  initimg.rgb = 1;
2413  initimg.red_mask = 0;
2414  hr = IDirect3DRM_CreateTexture(d3drm1, &initimg, &texture1);
2415  ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
2416  hr = IDirect3DRM2_CreateTexture(d3drm2, &initimg, &texture2);
2417  ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
2418  hr = IDirect3DRM3_CreateTexture(d3drm3, &initimg, &texture3);
2419  ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
2420  initimg.red_mask = 0x000000ff;
2421  initimg.green_mask = 0;
2422  hr = IDirect3DRM_CreateTexture(d3drm1, &initimg, &texture1);
2423  ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
2424  hr = IDirect3DRM2_CreateTexture(d3drm2, &initimg, &texture2);
2425  ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
2426  hr = IDirect3DRM3_CreateTexture(d3drm3, &initimg, &texture3);
2427  ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
2428  initimg.green_mask = 0x0000ff00;
2429  initimg.blue_mask = 0;
2430  hr = IDirect3DRM_CreateTexture(d3drm1, &initimg, &texture1);
2431  ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
2432  hr = IDirect3DRM2_CreateTexture(d3drm2, &initimg, &texture2);
2433  ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
2434  hr = IDirect3DRM3_CreateTexture(d3drm3, &initimg, &texture3);
2435  ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
2436  initimg.blue_mask = 0x00ff0000;
2437  initimg.buffer1 = NULL;
2438  hr = IDirect3DRM_CreateTexture(d3drm1, &initimg, &texture1);
2439  ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
2440  hr = IDirect3DRM2_CreateTexture(d3drm2, &initimg, &texture2);
2441  ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
2442  hr = IDirect3DRM3_CreateTexture(d3drm3, &initimg, &texture3);
2443  ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
2444 
2445  initimg.buffer1 = &pixel;
2446  hr = IDirect3DRM_CreateTexture(d3drm1, &initimg, &texture1);
2447  ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture interface (hr = %#x)\n", hr);
2448  ref2 = get_refcount((IUnknown *)d3drm1);
2449  ok(ref2 > ref1, "expected ref2 > ref1, got ref1 = %u , ref2 = %u.\n", ref1, ref2);
2450  ref3 = get_refcount((IUnknown *)d3drm2);
2451  ok(ref3 == ref1, "expected ref3 == ref1, got ref1 = %u , ref3 = %u.\n", ref1, ref3);
2452  ref4 = get_refcount((IUnknown *)d3drm3);
2453  ok(ref4 == ref1, "expected ref4 == ref1, got ref1 = %u , ref4 = %u.\n", ref1, ref4);
2454  hr = IDirect3DRM2_CreateTexture(d3drm2, &initimg, &texture2);
2455  ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture2 interface (hr = %#x)\n", hr);
2456  ref2 = get_refcount((IUnknown *)d3drm1);
2457  ok(ref2 > ref1 + 1, "expected ref2 > (ref1 + 1), got ref1 = %u , ref2 = %u.\n", ref1, ref2);
2458  ref3 = get_refcount((IUnknown *)d3drm2);
2459  ok(ref3 == ref1, "expected ref3 == ref1, got ref1 = %u , ref3 = %u.\n", ref1, ref3);
2460  ref4 = get_refcount((IUnknown *)d3drm3);
2461  ok(ref4 == ref1, "expected ref4 == ref1, got ref1 = %u , ref4 = %u.\n", ref1, ref4);
2462  hr = IDirect3DRM3_CreateTexture(d3drm3, &initimg, &texture3);
2463  ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture3 interface (hr = %#x)\n", hr);
2464  ref2 = get_refcount((IUnknown *)d3drm1);
2465  ok(ref2 > ref1 + 2, "expected ref2 > (ref1 + 2), got ref1 = %u , ref2 = %u.\n", ref1, ref2);
2466  ref3 = get_refcount((IUnknown *)d3drm2);
2467  ok(ref3 == ref1, "expected ref3 == ref1, got ref1 = %u , ref3 = %u.\n", ref1, ref3);
2468  ref4 = get_refcount((IUnknown *)d3drm3);
2469  ok(ref4 == ref1, "expected ref4 == ref1, got ref1 = %u , ref4 = %u.\n", ref1, ref4);
2470 
2471  /* Created from image, GetSurface() does not work. */
2472  hr = IDirect3DRMTexture3_GetSurface(texture3, 0, NULL);
2473  ok(hr == D3DRMERR_BADVALUE, "GetSurface() expected to fail, %#x\n", hr);
2474 
2475  hr = IDirect3DRMTexture3_GetSurface(texture3, 0, &surface);
2476  ok(hr == D3DRMERR_NOTCREATEDFROMDDS, "GetSurface() expected to fail, %#x\n", hr);
2477 
2478  /* Test all failures together */
2479  test_class_name((IDirect3DRMObject *)texture1, "Texture");
2480  test_class_name((IDirect3DRMObject *)texture2, "Texture");
2481  test_class_name((IDirect3DRMObject *)texture3, "Texture");
2482  test_object_name((IDirect3DRMObject *)texture1);
2483  test_object_name((IDirect3DRMObject *)texture2);
2484  test_object_name((IDirect3DRMObject *)texture3);
2485 
2486  d3drm_img = IDirect3DRMTexture_GetImage(texture1);
2487  ok(!!d3drm_img, "Failed to get image.\n");
2488  ok(d3drm_img == &initimg, "Expected image returned == %p, got %p.\n", &initimg, d3drm_img);
2489 
2490  IDirect3DRMTexture_Release(texture1);
2491  ref2 = get_refcount((IUnknown *)d3drm1);
2492  ok(ref2 - 2 == ref1, "expected (ref2 - 2) == ref1, got ref1 = %u, ref2 = %u.\n", ref1, ref2);
2493  ref3 = get_refcount((IUnknown *)d3drm2);
2494  ok(ref3 == ref1, "expected ref3 == ref1, got ref1 = %u, ref3 = %u.\n", ref1, ref3);
2495  ref4 = get_refcount((IUnknown *)d3drm3);
2496  ok(ref4 == ref1, "expected ref4 == ref1, got ref1 = %u, ref4 = %u.\n", ref1, ref4);
2497 
2498  d3drm_img = NULL;
2499  d3drm_img = IDirect3DRMTexture2_GetImage(texture2);
2500  ok(!!d3drm_img, "Failed to get image.\n");
2501  ok(d3drm_img == &initimg, "Expected image returned == %p, got %p.\n", &initimg, d3drm_img);
2502 
2503  IDirect3DRMTexture2_Release(texture2);
2504  ref2 = get_refcount((IUnknown *)d3drm1);
2505  ok(ref2 - 1 == ref1, "expected (ref2 - 1) == ref1, got ref1 = %u, ref2 = %u.\n", ref1, ref2);
2506  ref3 = get_refcount((IUnknown *)d3drm2);
2507  ok(ref3 == ref1, "expected ref3 == ref1, got ref1 = %u, ref3 = %u.\n", ref1, ref3);
2508  ref4 = get_refcount((IUnknown *)d3drm3);
2509  ok(ref4 == ref1, "expected ref4 == ref1, got ref1 = %u, ref4 = %u.\n", ref1, ref4);
2510 
2511  d3drm_img = NULL;
2512  d3drm_img = IDirect3DRMTexture3_GetImage(texture3);
2513  ok(!!d3drm_img, "Failed to get image.\n");
2514  ok(d3drm_img == &initimg, "Expected image returned == %p, got %p.\n", &initimg, d3drm_img);
2515 
2516  IDirect3DRMTexture3_Release(texture3);
2517  ref2 = get_refcount((IUnknown *)d3drm1);
2518  ok(ref2 == ref1, "expected ref2 == ref1, got ref1 = %u, ref2 = %u.\n", ref1, ref2);
2519  ref3 = get_refcount((IUnknown *)d3drm2);
2520  ok(ref3 == ref1, "expected ref3 == ref1, got ref1 = %u, ref3 = %u.\n", ref1, ref3);
2521  ref4 = get_refcount((IUnknown *)d3drm3);
2522  ok(ref4 == ref1, "expected ref4 == ref1, got ref1 = %u, ref4 = %u.\n", ref1, ref4);
2523 
2524  /* InitFromImage tests */
2525  /* Tests for validation of D3DRMIMAGE struct */
2526  testimg.rgb = 1;
2527  testimg.palette = NULL;
2528  testimg.palette_size = 0;
2529  hr = IDirect3DRM2_CreateObject(d3drm2, &CLSID_CDirect3DRMTexture, NULL, &IID_IDirect3DRMTexture2,
2530  (void **)&texture2);
2531  ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture2 interface (hr = %#x).\n", hr);
2532  hr = IDirect3DRM3_CreateObject(d3drm3, &CLSID_CDirect3DRMTexture, NULL, &IID_IDirect3DRMTexture3,
2533  (void **)&texture3);
2534  ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture3 interface (hr = %#x).\n", hr);
2535  hr = IDirect3DRMTexture2_InitFromImage(texture2, &testimg);
2536  ok(SUCCEEDED(hr), "Cannot initialize IDirect3DRMTexture2 interface (hr = %#x)\n", hr);
2537  hr = IDirect3DRMTexture3_InitFromImage(texture3, &testimg);
2538  ok(SUCCEEDED(hr), "Cannot initialize IDirect3DRMTexture3 interface (hr = %#x)\n", hr);
2539  IDirect3DRMTexture2_Release(texture2);
2540  IDirect3DRMTexture3_Release(texture3);
2541 
2542  testimg.rgb = 0;
2543  testimg.palette = (void *)0xdeadbeef;
2544  testimg.palette_size = 0x39;
2545  hr = IDirect3DRM2_CreateObject(d3drm2, &CLSID_CDirect3DRMTexture, NULL, &IID_IDirect3DRMTexture2,
2546  (void **)&texture2);
2547  ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture2 interface (hr = %#x).\n", hr);
2548  hr = IDirect3DRM3_CreateObject(d3drm3, &CLSID_CDirect3DRMTexture, NULL, &IID_IDirect3DRMTexture3,
2549  (void **)&texture3);
2550  ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture3 interface (hr = %#x).\n", hr);
2551  hr = IDirect3DRMTexture2_InitFromImage(texture2, &testimg);
2552  ok(SUCCEEDED(hr), "Cannot initialize IDirect3DRMTexture2 interface (hr = %#x)\n", hr);
2553  hr = IDirect3DRMTexture3_InitFromImage(texture3, &testimg);
2554  ok(SUCCEEDED(hr), "Cannot initialize IDirect3DRMTexture3 interface (hr = %#x)\n", hr);
2555  IDirect3DRMTexture2_Release(texture2);
2556  IDirect3DRMTexture3_Release(texture3);
2557 
2558  hr = IDirect3DRM2_CreateObject(d3drm2, &CLSID_CDirect3DRMTexture, NULL, &IID_IDirect3DRMTexture2,
2559  (void **)&texture2);
2560  ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture2 interface (hr = %#x).\n", hr);
2561  ref2 = get_refcount((IUnknown *)texture2);
2563  ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2564  ref3 = get_refcount((IUnknown *)texture2);
2565  ok(ref3 == ref2, "expected ref3 == ref2, got ref2 = %u , ref3 = %u.\n", ref2, ref3);
2566 
2567  hr = IDirect3DRM3_CreateObject(d3drm3, &CLSID_CDirect3DRMTexture, NULL, &IID_IDirect3DRMTexture3,
2568  (void **)&texture3);
2569  ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture3 interface (hr = %#x).\n", hr);
2570  ref2 = get_refcount((IUnknown *)texture3);
2572  ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2573  ref3 = get_refcount((IUnknown *)texture3);
2574  ok(ref3 == ref2, "expected ref3 == ref2, got ref2 = %u , ref3 = %u.\n", ref2, ref3);
2575 
2576  initimg.rgb = 0;
2577  hr = IDirect3DRMTexture2_InitFromImage(texture2, &initimg);
2578  ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2579  hr = IDirect3DRMTexture3_InitFromImage(texture3, &initimg);
2580  ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2581  initimg.rgb = 1;
2582  initimg.red_mask = 0;
2583  hr = IDirect3DRMTexture2_InitFromImage(texture2, &initimg);
2584  ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2585  hr = IDirect3DRMTexture3_InitFromImage(texture3, &initimg);
2586  ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2587  initimg.red_mask = 0x000000ff;
2588  initimg.green_mask = 0;
2589  hr = IDirect3DRMTexture2_InitFromImage(texture2, &initimg);
2590  ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2591  hr = IDirect3DRMTexture3_InitFromImage(texture3, &initimg);
2592  ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2593  initimg.green_mask = 0x0000ff00;
2594  initimg.blue_mask = 0;
2595  hr = IDirect3DRMTexture2_InitFromImage(texture2, &initimg);
2596  ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2597  hr = IDirect3DRMTexture3_InitFromImage(texture3, &initimg);
2598  ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2599  initimg.blue_mask = 0x00ff0000;
2600  initimg.buffer1 = NULL;
2601  hr = IDirect3DRMTexture2_InitFromImage(texture2, &initimg);
2602  ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2603  hr = IDirect3DRMTexture3_InitFromImage(texture3, &initimg);
2604  ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2605  initimg.buffer1 = &pixel;
2606 
2607  d3drm_img = NULL;
2608  hr = IDirect3DRMTexture2_InitFromImage(texture2, &initimg);
2609  ok(SUCCEEDED(hr), "Cannot initialize IDirect3DRMTexture2 from image (hr = %#x).\n", hr);
2610  ref2 = get_refcount((IUnknown *)d3drm1);
2611  ok(ref2 > ref1, "expected ref2 > ref1, got ref1 = %u , ref2 = %u.\n", ref1, ref2);
2612  ref3 = get_refcount((IUnknown *)d3drm2);
2613  ok(ref3 == ref1, "expected ref3 == ref1, got ref1 = %u , ref3 = %u.\n", ref1, ref3);
2614  ref4 = get_refcount((IUnknown *)d3drm3);
2615  ok(ref4 == ref1, "expected ref4 == ref1, got ref1 = %u , ref4 = %u.\n", ref1, ref4);
2616 
2617  hr = IDirect3DRMTexture2_InitFromImage(texture2, &initimg);
2618  ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2619  /* Release leaked reference to d3drm1 */
2620  IDirect3DRM_Release(d3drm1);
2621 
2622  d3drm_img = IDirect3DRMTexture2_GetImage(texture2);
2623  ok(!!d3drm_img, "Failed to get image.\n");
2624  ok(d3drm_img == &initimg, "Expected image returned == %p, got %p.\n", &initimg, d3drm_img);
2625  IDirect3DRMTexture2_Release(texture2);
2626  ref2 = get_refcount((IUnknown *)d3drm1);
2627  ok(ref2 == ref1, "expected ref2 == ref1, got ref1 = %u, ref2 = %u.\n", ref1, ref2);
2628  ref3 = get_refcount((IUnknown *)d3drm2);
2629  ok(ref3 == ref1, "expected ref3 == ref1, got ref1 = %u, ref3 = %u.\n", ref1, ref3);
2630  ref4 = get_refcount((IUnknown *)d3drm3);
2631  ok(ref4 == ref1, "expected ref4 == ref1, got ref1 = %u, ref4 = %u.\n", ref1, ref4);
2632 
2633  d3drm_img = NULL;
2634  hr = IDirect3DRMTexture3_InitFromImage(texture3, &initimg);
2635  ok(SUCCEEDED(hr), "Cannot initialize IDirect3DRMTexture3 from image (hr = %#x).\n", hr);
2636  ref2 = get_refcount((IUnknown *)d3drm1);
2637  ok(ref2 > ref1, "expected ref2 > ref1, got ref1 = %u , ref2 = %u.\n", ref1, ref2);
2638  ref3 = get_refcount((IUnknown *)d3drm2);
2639  ok(ref3 == ref1, "expected ref3 == ref1, got ref1 = %u , ref3 = %u.\n", ref1, ref3);
2640  ref4 = get_refcount((IUnknown *)d3drm3);
2641  ok(ref4 == ref1, "expected ref4 == ref1, got ref1 = %u , ref4 = %u.\n", ref1, ref4);
2642 
2643  hr = IDirect3DRMTexture3_InitFromImage(texture3, &initimg);
2644  ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2645  IDirect3DRM_Release(d3drm1);
2646 
2647  d3drm_img = IDirect3DRMTexture3_GetImage(texture3);
2648  ok(!!d3drm_img, "Failed to get image.\n");
2649  ok(d3drm_img == &initimg, "Expected image returned == %p, got %p.\n", &initimg, d3drm_img);
2650  IDirect3DRMTexture3_Release(texture3);
2651  ref2 = get_refcount((IUnknown *)d3drm1);
2652  ok(ref2 == ref1, "expected ref2 == ref1, got ref1 = %u, ref2 = %u.\n", ref1, ref2);
2653  ref3 = get_refcount((IUnknown *)d3drm2);
2654  ok(ref3 == ref1, "expected ref3 == ref1, got ref1 = %u, ref3 = %u.\n", ref1, ref3);
2655  ref4 = get_refcount((IUnknown *)d3drm3);
2656  ok(ref4 == ref1, "expected ref4 == ref1, got ref1 = %u, ref4 = %u.\n", ref1, ref4);
2657 
2658  IDirect3DRM3_Release(d3drm3);
2659  IDirect3DRM2_Release(d3drm2);
2660  IDirect3DRM_Release(d3drm1);
2661 }
2662 
2663 static void test_Device(void)
2664 {
2665  IDirectDrawClipper *pClipper;
2666  HRESULT hr;
2667  IDirect3DRM *d3drm;
2668  IDirect3DRMDevice *device;
2669  IDirect3DRMWinDevice *win_device;
2670  GUID driver;
2671  HWND window;
2672  RECT rc;
2673 
2674  window = create_window();
2675  GetClientRect(window, &rc);
2676 
2678  ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x)\n", hr);
2679 
2680  hr = DirectDrawCreateClipper(0, &pClipper, NULL);
2681  ok(hr == DD_OK, "Cannot get IDirectDrawClipper interface (hr = %x)\n", hr);
2682 
2683  hr = IDirectDrawClipper_SetHWnd(pClipper, 0, window);
2684  ok(hr == DD_OK, "Cannot set HWnd to Clipper (hr = %x)\n", hr);
2685 
2686  memcpy(&driver, &IID_IDirect3DRGBDevice, sizeof(GUID));
2688  ok(hr == D3DRM_OK, "Cannot get IDirect3DRMDevice interface (hr = %x)\n", hr);
2689 
2690  test_class_name((IDirect3DRMObject *)device, "Device");
2691  test_object_name((IDirect3DRMObject *)device);
2692 
2693  /* WinDevice */
2694  if (FAILED(hr = IDirect3DRMDevice_QueryInterface(device, &IID_IDirect3DRMWinDevice, (void **)&win_device)))
2695  {
2696  win_skip("Cannot get IDirect3DRMWinDevice interface (hr = %x), skipping tests\n", hr);
2697  goto cleanup;
2698  }
2699 
2700  test_class_name((IDirect3DRMObject *)win_device, "Device");
2701  test_object_name((IDirect3DRMObject *)win_device);
2702  IDirect3DRMWinDevice_Release(win_device);
2703 
2704 cleanup:
2706  IDirectDrawClipper_Release(pClipper);
2707 
2710 }
2711 
2712 static void test_frame_transform(void)
2713 {
2714  HRESULT hr;
2715  IDirect3DRM *d3drm;
2716  IDirect3DRMFrame *frame;
2718 
2720  ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x)\n", hr);
2721 
2722  hr = IDirect3DRM_CreateFrame(d3drm, NULL, &frame);
2723  ok(hr == D3DRM_OK, "Cannot get IDirect3DRMFrame interface (hr = %x)\n", hr);
2724 
2726  ok(hr == D3DRM_OK, "IDirect3DRMFrame_GetTransform returned hr = %x\n", hr);
2727  ok(!memcmp(matrix, identity, sizeof(D3DRMMATRIX4D)), "Returned matrix is not identity\n");
2728 
2729  IDirect3DRMFrame_Release(frame);
2731 }
2732 
2733 static int nb_objects = 0;
2734 static const GUID* refiids[] =
2735 {
2736  &IID_IDirect3DRMMeshBuilder,
2737  &IID_IDirect3DRMMeshBuilder,
2738  &IID_IDirect3DRMFrame,
2739  &IID_IDirect3DRMMaterial /* Not taken into account and not notified */
2740 };
2741 
2742 static void __cdecl object_load_callback(IDirect3DRMObject *object, REFIID objectguid, void *arg)
2743 {
2744  ok(object != NULL, "Arg 1 should not be null\n");
2745  ok(IsEqualGUID(objectguid, refiids[nb_objects]), "Arg 2 is incorrect\n");
2746  ok(arg == (void *)0xdeadbeef, "Arg 3 should be 0xdeadbeef (got %p)\n", arg);
2747  nb_objects++;
2748 }
2749 
2750 static void test_d3drm_load(void)
2751 {
2752  HRESULT hr;
2753  IDirect3DRM *d3drm;
2755  const GUID* req_refiids[] = { &IID_IDirect3DRMMeshBuilder, &IID_IDirect3DRMFrame, &IID_IDirect3DRMMaterial };
2756 
2758  ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x)\n", hr);
2759 
2760  info.lpMemory = data_d3drm_load;
2761  info.dSize = strlen(data_d3drm_load);
2762  hr = IDirect3DRM_Load(d3drm, &info, NULL, (GUID **)req_refiids, 3, D3DRMLOAD_FROMMEMORY,
2763  object_load_callback, (void *)0xdeadbeef, NULL, NULL, NULL);
2764  ok(hr == D3DRM_OK, "Cannot load data (hr = %x)\n", hr);
2765  ok(nb_objects == 3, "Should have loaded 3 objects (got %d)\n", nb_objects);
2766 
2768 }
2769 
2770 IDirect3DRMMeshBuilder *mesh_builder = NULL;
2771 
2772 static void __cdecl object_load_callback_frame(IDirect3DRMObject *object, REFIID object_guid, void *arg)
2773 {
2774  HRESULT hr;
2775  IDirect3DRMFrame *frame;
2776  IDirect3DRMVisualArray *array;
2777  IDirect3DRMVisual *visual;
2778  ULONG size;
2779  char name[128];
2780 
2781  hr = IDirect3DRMObject_QueryInterface(object, &IID_IDirect3DRMFrame, (void**)&frame);
2782  ok(hr == D3DRM_OK, "IDirect3DRMObject_QueryInterface returned %x\n", hr);
2783 
2785  ok(hr == D3DRM_OK, "IDirect3DRMFrame_GetVisuals returned %x\n", hr);
2786 
2788  ok(size == 1, "Wrong size %u returned, expected 1\n", size);
2789 
2791  ok(hr == D3DRM_OK, "IDirect3DRMVisualArray_GetElement returned %x\n", hr);
2792 
2793  hr = IDirect3DRMVisual_QueryInterface(visual, &IID_IDirect3DRMMeshBuilder, (void**)&mesh_builder);
2794  ok(hr == D3DRM_OK, "IDirect3DRMVisualArray_GetSize returned %x\n", hr);
2795 
2796  size = sizeof(name);
2798  ok(hr == D3DRM_OK, "IDirect3DRMMeshBuilder_GetName returned %x\n", hr);
2799  ok(!strcmp(name, "mesh1"), "Wrong name %s, expected mesh1\n", name);
2800 
2801  IDirect3DRMVisual_Release(visual);
2803  IDirect3DRMFrame_Release(frame);
2804 }
2805 
2806 struct {
2812  float power;
2813  float specular[3];
2814  float emissive[3];
2815 } groups[3] = {
2816  { 4, 3, 3, 9, 0x4c0000ff, 30.0f, { 0.31f, 0.32f, 0.33f }, { 0.34f, 0.35f, 0.36f } },
2817  { 4, 2, 3, 6, 0x3300ff00, 20.0f, { 0.21f, 0.22f, 0.23f }, { 0.24f, 0.25f, 0.26f } },
2818  { 3, 1, 3, 3, 0x19ff0000, 10.0f, { 0.11f, 0.12f, 0.13f }, { 0.14f, 0.15f, 0.16f } }
2819 };
2820 
2821 static void test_frame_mesh_materials(void)
2822 {
2823  HRESULT hr;
2824  IDirect3DRM *d3drm;
2826  const GUID *req_refiids[] = { &IID_IDirect3DRMFrame };
2827  IDirect3DRMMesh *mesh;
2828  ULONG size;
2829  IDirect3DRMMaterial *material;
2830  IDirect3DRMTexture *texture;
2831  int i;
2832 
2834  ok(hr == D3DRM_OK, "Direct3DRMCreate returned %x\n", hr);
2835 
2836  info.lpMemory = data_frame_mesh_materials;
2838  hr = IDirect3DRM_Load(d3drm, &info, NULL, (GUID**)req_refiids, 1, D3DRMLOAD_FROMMEMORY, object_load_callback_frame, (void*)0xdeadbeef, NULL, NULL, NULL);
2839  ok(hr == D3DRM_OK, "Cannot load data (hr = %x)\n", hr);
2840 
2842  ok(hr == D3DRM_OK, "IDirect3DRMMeshBuilder_CreateMesh returned %x\n", hr);
2843 
2845  ok(size == 3, "Wrong size %u returned, expected 3\n", size);
2846 
2847  for (i = 0; i < size; i++)
2848  {
2850  D3DCOLOR color;
2853 
2855  ok(hr == D3DRM_OK, "Group %d: IDirect3DRMMesh_GetGroup returned %x\n", i, hr);
2856  ok(vertex_count == groups[i].vertex_count, "Group %d: Wrong vertex count %d, expected %d\n", i, vertex_count, groups[i].vertex_count);
2857  ok(face_count == groups[i].face_count, "Group %d: Wrong face count %d; expected %d\n", i, face_count, groups[i].face_count);
2858  ok(vertex_per_face == groups[i].vertex_per_face, "Group %d: Wrong vertex per face %d, expected %d\n", i, vertex_per_face, groups[i].vertex_per_face);
2859  ok(face_data_size == groups[i].face_data_size, "Group %d: Wrong face data size %d, expected %d\n", i, face_data_size, groups[i].face_data_size);
2860 
2862  ok(color == groups[i].color, "Group %d: Wrong color %x, expected %x\n", i, color, groups[i].color);
2863 
2864  hr = IDirect3DRMMesh_GetGroupMaterial(mesh, i, &material);
2865  ok(hr == D3DRM_OK, "Group %d: IDirect3DRMMesh_GetGroupMaterial returned %x\n", i, hr);
2866  ok(material != NULL, "Group %d: No material\n", i);
2867  power = IDirect3DRMMaterial_GetPower(material);
2868  ok(power == groups[i].power, "Group %d: Wrong power %f, expected %f\n", i, power, groups[i].power);
2869  hr = IDirect3DRMMaterial_GetSpecular(material, &red, &green, &blue);
2870  ok(hr == D3DRM_OK, "Group %d: IDirect3DRMMaterial_GetSpecular returned %x\n", i, hr);
2871  ok(red == groups[i].specular[0], "Group %d: Wrong specular red %f, expected %f\n", i, red, groups[i].specular[0]);
2872  ok(green == groups[i].specular[1], "Group %d: Wrong specular green %f, pD3DRMexpected %f\n", i, green, groups[i].specular[1]);
2873  ok(blue == groups[i].specular[2], "Group %d: Wrong specular blue %f, expected %f\n", i, blue, groups[i].specular[2]);
2874  hr = IDirect3DRMMaterial_GetEmissive(material, &red, &green, &blue);
2875  ok(hr == D3DRM_OK, "Group %d: IDirect3DRMMaterial_GetEmissive returned %x\n", i, hr);
2876  ok(red == groups[i].emissive[0], "Group %d: Wrong emissive red %f, expected %f\n", i, red, groups[i].emissive[0]);
2877  ok(green == groups[i].emissive[1], "Group %d: Wrong emissive green %f, expected %f\n", i, green, groups[i].emissive[1]);
2878  ok(blue == groups[i].emissive[2], "Group %d: Wrong emissive blue %f, expected %f\n", i, blue, groups[i].emissive[2]);
2879 
2881  ok(hr == D3DRM_OK, "Group %d: IDirect3DRMMesh_GetGroupTexture returned %x\n", i, hr);
2882  ok(!texture, "Group %d: Unexpected texture\n", i);
2883 
2884  if (material)
2885  IDirect3DRMMaterial_Release(material);
2886  if (texture)
2888  }
2889 
2893 }
2894 
2895 struct qi_test
2896 {
2901 };
2902 
2903 static void test_qi(const char *test_name, IUnknown *base_iface,
2904  REFIID refcount_iid, const struct qi_test *tests, UINT entry_count)
2905 {
2906  ULONG refcount, expected_refcount;
2907  IUnknown *iface1, *iface2;
2908  HRESULT hr;
2909  UINT i, j;
2910 
2911  for (i = 0; i < entry_count; ++i)
2912  {
2913  hr = IUnknown_QueryInterface(base_iface, tests[i].iid, (void **)&iface1);
2914  ok(hr == tests[i].hr, "Got hr %#x for test \"%s\" %u.\n", hr, test_name, i);
2915  if (SUCCEEDED(hr))
2916  {
2917  for (j = 0; j < entry_count; ++j)
2918  {
2919  hr = IUnknown_QueryInterface(iface1, tests[j].iid, (void **)&iface2);
2920  ok(hr == tests[j].hr, "Got hr %#x for test \"%s\" %u, %u.\n", hr, test_name, i, j);
2921  if (SUCCEEDED(hr))
2922  {
2923  expected_refcount = 0;
2924  if (IsEqualGUID(refcount_iid, tests[j].refcount_iid))
2925  ++expected_refcount;
2926  if (IsEqualGUID(tests[i].refcount_iid, tests[j].refcount_iid))
2927  ++expected_refcount;
2928  refcount = IUnknown_Release(iface2);
2929  ok(refcount == expected_refcount, "Got refcount %u for test \"%s\" %u, %u, expected %u.\n",
2930  refcount, test_name, i, j, expected_refcount);
2931  if (tests[i].vtable_iid && tests[j].vtable_iid && IsEqualGUID(tests[i].vtable_iid, tests[j].vtable_iid))
2932  ok(iface1 == iface2,
2933  "Expected iface1 == iface2 for test \"%s\" %u, %u. Got iface1 = %p, iface 2 = %p.\n",
2934  test_name, i, j, iface1, iface2);
2935  else if (tests[i].vtable_iid && tests[j].vtable_iid)
2936  ok(iface1 != iface2,
2937  "Expected iface1 != iface2 for test \"%s\" %u, %u. Got iface1 == iface2 == %p.\n",
2938  test_name, i, j, iface1);
2939  }
2940  }
2941 
2942  expected_refcount = 0;
2943  if (IsEqualGUID(refcount_iid, tests[i].refcount_iid))
2944  ++expected_refcount;
2945  refcount = IUnknown_Release(iface1);
2946  ok(refcount == expected_refcount, "Got refcount %u for test \"%s\" %u, expected %u.\n",
2947  refcount, test_name, i, expected_refcount);
2948  }
2949  }
2950 }
2951 
2952 static void test_d3drm_qi(void)
2953 {
2954  static const struct qi_test tests[] =
2955  {
2956  { &IID_IDirect3DRM3, &IID_IDirect3DRM3, &IID_IDirect3DRM3, S_OK },
2957  { &IID_IDirect3DRM2, &IID_IDirect3DRM2, &IID_IDirect3DRM2, S_OK },
2958  { &IID_IDirect3DRM, &IID_IDirect3DRM, &IID_IDirect3DRM, S_OK },
2959  { &IID_IDirect3DRMDevice, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
2960  { &IID_IDirect3DRMObject, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
2961  { &IID_IDirect3DRMObject2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
2962  { &IID_IDirect3DRMDevice2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
2963  { &IID_IDirect3DRMDevice3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
2964  { &IID_IDirect3DRMViewport, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
2965  { &IID_IDirect3DRMViewport2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
2966  { &IID_IDirect3DRMFrame, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
2967  { &IID_IDirect3DRMFrame2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
2968  { &IID_IDirect3DRMFrame3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
2969  { &IID_IDirect3DRMVisual, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
2970  { &IID_IDirect3DRMMesh, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
2971  { &IID_IDirect3DRMMeshBuilder, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
2972  { &IID_IDirect3DRMMeshBuilder2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
2973  { &IID_IDirect3DRMMeshBuilder3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
2974  { &IID_IDirect3DRMFace, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
2975  { &IID_IDirect3DRMFace2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
2976  { &IID_IDirect3DRMLight, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
2977  { &IID_IDirect3DRMTexture, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
2978  { &IID_IDirect3DRMTexture2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
2979  { &IID_IDirect3DRMTexture3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
2980  { &IID_IDirect3DRMWrap, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
2981  { &IID_IDirect3DRMMaterial, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
2982  { &IID_IDirect3DRMMaterial2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
2983  { &IID_IDirect3DRMAnimation, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
2984  { &IID_IDirect3DRMAnimation2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
2985  { &IID_IDirect3DRMAnimationSet, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
2986  { &IID_IDirect3DRMAnimationSet2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
2987  { &IID_IDirect3DRMObjectArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
2988  { &IID_IDirect3DRMDeviceArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
2989  { &IID_IDirect3DRMViewportArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
2990  { &IID_IDirect3DRMFrameArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
2991  { &IID_IDirect3DRMVisualArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
2992  { &IID_IDirect3DRMLightArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
2993  { &IID_IDirect3DRMPickedArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
2994  { &IID_IDirect3DRMFaceArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
2995  { &IID_IDirect3DRMAnimationArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
2996  { &IID_IDirect3DRMUserVisual, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
2997  { &IID_IDirect3DRMShadow, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
2998  { &IID_IDirect3DRMShadow2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
2999  { &IID_IDirect3DRMInterpolator, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3000  { &IID_IDirect3DRMProgressiveMesh, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3001  { &IID_IDirect3DRMPicked2Array, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3002  { &IID_IDirect3DRMClippedVisual, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3003  { &IID_IDirectDrawClipper, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3004  { &IID_IDirectDrawSurface7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3005  { &IID_IDirectDrawSurface4, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3006  { &IID_IDirectDrawSurface3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3007  { &IID_IDirectDrawSurface2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3008  { &IID_IDirectDrawSurface, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3009  { &IID_IDirect3DDevice7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3010  { &IID_IDirect3DDevice3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3011  { &IID_IDirect3DDevice2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3012  { &IID_IDirect3DDevice, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3013  { &IID_IDirect3D7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3014  { &IID_IDirect3D3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3015  { &IID_IDirect3D2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3016  { &IID_IDirect3D, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3017  { &IID_IDirectDraw7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3018  { &IID_IDirectDraw4, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3019  { &IID_IDirectDraw3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3020  { &IID_IDirectDraw2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3021  { &IID_IDirectDraw, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3022  { &IID_IDirect3DLight, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3023  { &IID_IUnknown, &IID_IDirect3DRM, &IID_IDirect3DRM, S_OK },
3024  };
3025  HRESULT hr;
3026  IDirect3DRM *d3drm;
3027 
3029  ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x)\n", hr);
3030 
3031  test_qi("d3drm_qi", (IUnknown *)d3drm, &IID_IDirect3DRM, tests, ARRAY_SIZE(tests));
3032 
3034 }
3035 
3036 static void test_frame_qi(void)
3037 {
3038  static const struct qi_test tests[] =
3039  {
3040  { &IID_IDirect3DRMFrame3, &IID_IUnknown, &IID_IDirect3DRMFrame3, S_OK },
3041  { &IID_IDirect3DRMFrame2, &IID_IUnknown, &IID_IDirect3DRMFrame2, S_OK },
3042  { &IID_IDirect3DRMFrame, &IID_IUnknown, &IID_IDirect3DRMFrame, S_OK },
3043  { &IID_IDirect3DRM, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3044  { &IID_IDirect3DRMDevice, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3045  { &IID_IDirect3DRMObject, &IID_IUnknown, &IID_IDirect3DRMFrame, S_OK },
3046  { &IID_IDirect3DRMDevice2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3047  { &IID_IDirect3DRMDevice3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3048  { &IID_IDirect3DRMViewport, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3049  { &IID_IDirect3DRMViewport2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3050  { &IID_IDirect3DRM3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3051  { &IID_IDirect3DRM2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3052  { &IID_IDirect3DRMVisual, &IID_IUnknown, &IID_IDirect3DRMFrame, S_OK },
3053  { &IID_IDirect3DRMMesh, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3054  { &IID_IDirect3DRMMeshBuilder, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3055  { &IID_IDirect3DRMMeshBuilder2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3056  { &IID_IDirect3DRMMeshBuilder3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3057  { &IID_IDirect3DRMFace, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3058  { &IID_IDirect3DRMFace2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3059  { &IID_IDirect3DRMLight, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3060  { &IID_IDirect3DRMTexture, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3061  { &IID_IDirect3DRMTexture2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3062  { &IID_IDirect3DRMTexture3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3063  { &IID_IDirect3DRMWrap, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3064  { &IID_IDirect3DRMMaterial, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3065  { &IID_IDirect3DRMMaterial2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3066  { &IID_IDirect3DRMAnimation, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3067  { &IID_IDirect3DRMAnimation2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3068  { &IID_IDirect3DRMAnimationSet, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3069  { &IID_IDirect3DRMAnimationSet2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3070  { &IID_IDirect3DRMObjectArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3071  { &IID_IDirect3DRMDeviceArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3072  { &IID_IDirect3DRMViewportArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3073  { &IID_IDirect3DRMFrameArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3074  { &IID_IDirect3DRMVisualArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3075  { &IID_IDirect3DRMLightArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3076  { &IID_IDirect3DRMPickedArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3077  { &IID_IDirect3DRMFaceArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3078  { &IID_IDirect3DRMAnimationArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3079  { &IID_IDirect3DRMUserVisual, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3080  { &IID_IDirect3DRMShadow, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3081  { &IID_IDirect3DRMShadow2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3082  { &IID_IDirect3DRMInterpolator, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3083  { &IID_IDirect3DRMProgressiveMesh, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3084  { &IID_IDirect3DRMPicked2Array, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3085  { &IID_IDirect3DRMClippedVisual, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3086  { &IID_IDirectDrawClipper, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3087  { &IID_IDirectDrawSurface7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3088  { &IID_IDirectDrawSurface4, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3089  { &IID_IDirectDrawSurface3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3090  { &IID_IDirectDrawSurface2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3091  { &IID_IDirectDrawSurface, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3092  { &IID_IDirect3DDevice7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3093  { &IID_IDirect3DDevice3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3094  { &IID_IDirect3DDevice2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3095  { &IID_IDirect3DDevice, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3096  { &IID_IDirect3D7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3097  { &IID_IDirect3D3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3098  { &IID_IDirect3D2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3099  { &IID_IDirect3D, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3100  { &IID_IDirectDraw7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3101  { &IID_IDirectDraw4, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3102  { &IID_IDirectDraw3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3103  { &IID_IDirectDraw2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3104  { &IID_IDirectDraw, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3105  { &IID_IDirect3DLight, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3107  };
3108  HRESULT hr;
3109  IDirect3DRM *d3drm1;
3110  IDirect3DRM2 *d3drm2;
3111  IDirect3DRM3 *d3drm3;
3112  IDirect3DRMFrame *frame1;
3113  IDirect3DRMFrame2 *frame2;
3114  IDirect3DRMFrame3 *frame3;
3115  IUnknown *unknown;
3116 
3117  hr = Direct3DRMCreate(&d3drm1);
3118  ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x)\n", hr);
3119 
3120  hr = IDirect3DRM_CreateFrame(d3drm1, NULL, &frame1);
3121  ok(hr == D3DRM_OK, "Failed to create frame1 (hr = %x)\n", hr);
3122  hr = IDirect3DRMFrame_QueryInterface(frame1, &IID_IUnknown, (void **)&unknown);
3123  ok(hr == D3DRM_OK, "Failed to create IUnknown from frame1 (hr = %x)\n", hr);
3124  IDirect3DRMFrame_Release(frame1);
3125  test_qi("frame1_qi", unknown, &IID_IUnknown, tests, ARRAY_SIZE(tests));
3126  IUnknown_Release(unknown);
3127 
3128  hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM2, (void **)&d3drm2);
3129  ok(hr == D3DRM_OK, "Cannot get IDirect3DRM2 interface (hr = %x).\n", hr);
3130  hr = IDirect3DRM2_CreateFrame(d3drm2, NULL, &frame2);
3131  ok(hr == D3DRM_OK, "Failed to create frame2 (hr = %x)\n", hr);
3133  ok(hr == D3DRM_OK, "Failed to create IUnknown from frame2 (hr = %x)\n", hr);
3134  IDirect3DRMFrame2_Release(frame2);
3135  test_qi("frame2_qi", unknown, &IID_IUnknown, tests, ARRAY_SIZE(tests));
3136  IUnknown_Release(unknown);
3137 
3138  hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM3, (void **)&d3drm3);
3139  ok(hr == D3DRM_OK, "Cannot get IDirect3DRM3 interface (hr = %x).\n", hr);
3140  hr = IDirect3DRM3_CreateFrame(d3drm3, NULL, &frame3);
3141  ok(hr == D3DRM_OK, "Failed to create frame3 (hr = %x)\n", hr);
3143  ok(hr == D3DRM_OK, "Failed to create IUnknown from frame3 (hr = %x)\n", hr);
3144  IDirect3DRMFrame3_Release(frame3);
3145  test_qi("frame3_qi", unknown, &IID_IUnknown, tests, ARRAY_SIZE(tests));
3146  IUnknown_Release(unknown);
3147 
3148  IDirect3DRM3_Release(d3drm3);
3149  IDirect3DRM2_Release(d3drm2);
3150  IDirect3DRM_Release(d3drm1);
3151 }
3152 
3153 static void test_device_qi(void)
3154 {
3155  static const struct qi_test tests[] =
3156  {
3157  { &IID_IDirect3DRM3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3158  { &IID_IDirect3DRM2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3159  { &IID_IDirect3DRM, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3160  { &IID_IDirect3DRMDevice, &IID_IUnknown, &IID_IDirect3DRMDevice, S_OK, },
3161  { &IID_IDirect3DRMDevice2, &IID_IUnknown, &IID_IDirect3DRMDevice2, S_OK, },
3162  { &IID_IDirect3DRMDevice3, &IID_IUnknown, &IID_IDirect3DRMDevice3, S_OK, },
3163  { &IID_IDirect3DRMWinDevice, &IID_IUnknown, &IID_IDirect3DRMWinDevice,