d3drm: Avoid LPDIRECT3DRMVISUAL.
[wine] / dlls / d3drm / tests / d3drm.c
1 /*
2  * Copyright 2010, 2012 Christian Costa
3  * Copyright 2012 AndrĂ© Hentschel
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18  */
19
20 #define COBJMACROS
21 #include <d3drm.h>
22 #include <initguid.h>
23 #include <d3drmwin.h>
24
25 #include "wine/test.h"
26
27 static HMODULE d3drm_handle = 0;
28
29 static HRESULT (WINAPI * pDirect3DRMCreate)(IDirect3DRM **d3drm);
30
31 #define CHECK_REFCOUNT(obj,rc) \
32     { \
33         int rc_new = rc; \
34         int count = get_refcount( (IUnknown *)obj ); \
35         ok(count == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, count); \
36     }
37
38 #define D3DRM_GET_PROC(func) \
39     p ## func = (void*)GetProcAddress(d3drm_handle, #func); \
40     if(!p ## func) { \
41       trace("GetProcAddress(%s) failed\n", #func); \
42       FreeLibrary(d3drm_handle); \
43       return FALSE; \
44     }
45
46 static BOOL InitFunctionPtrs(void)
47 {
48     d3drm_handle = LoadLibraryA("d3drm.dll");
49
50     if(!d3drm_handle)
51     {
52         skip("Could not load d3drm.dll\n");
53         return FALSE;
54     }
55
56     D3DRM_GET_PROC(Direct3DRMCreate)
57
58     return TRUE;
59 }
60
61 static int get_refcount(IUnknown *object)
62 {
63     IUnknown_AddRef( object );
64     return IUnknown_Release( object );
65 }
66
67 static BOOL match_float(float a, float b)
68 {
69     return (a - b) < 0.000001f;
70 }
71
72 static D3DRMMATRIX4D identity = {
73     { 1.0f, 0.0f, 0.0f, 0.0f },
74     { 0.0f, 1.0f, 0.0f, 0.0f },
75     { 0.0f, 0.0f, 1.0f, 0.0f },
76     { 0.0f, 0.0f, 0.0f, 1.0f }
77 };
78
79 static char data_bad_version[] =
80 "xof 0302txt 0064\n"
81 "Header Object\n"
82 "{\n"
83 "1; 2; 3;\n"
84 "}\n";
85
86 static char data_no_mesh[] =
87 "xof 0302txt 0064\n"
88 "Header Object\n"
89 "{\n"
90 "1; 0; 1;\n"
91 "}\n";
92
93 static char data_ok[] =
94 "xof 0302txt 0064\n"
95 "Header Object\n"
96 "{\n"
97 "1; 0; 1;\n"
98 "}\n"
99 "Mesh Object\n"
100 "{\n"
101 "4;\n"
102 "1.0; 0.0; 0.0;,\n"
103 "0.0; 1.0; 0.0;,\n"
104 "0.0; 0.0; 1.0;,\n"
105 "1.0; 1.0; 1.0;;\n"
106 "3;\n"
107 "3; 0, 1, 2;,\n"
108 "3; 1, 2, 3;,\n"
109 "3; 3, 1, 2;;\n"
110 "}\n";
111
112 static char data_full[] =
113 "xof 0302txt 0064\n"
114 "Header { 1; 0; 1; }\n"
115 "Mesh {\n"
116 " 3;\n"
117 " 0.1; 0.2; 0.3;,\n"
118 " 0.4; 0.5; 0.6;,\n"
119 " 0.7; 0.8; 0.9;;\n"
120 " 1;\n"
121 " 3; 0, 1, 2;;\n"
122 " MeshMaterialList {\n"
123 "  1; 1; 0;\n"
124 "  Material {\n"
125 "   0.0; 1.0; 0.0; 1.0;;\n"
126 "   30.0;\n"
127 "   1.0; 0.0; 0.0;;\n"
128 "   0.5; 0.5; 0.5;;\n"
129 "   TextureFileName {\n"
130 "    \"Texture.bmp\";\n"
131 "   }\n"
132 "  }\n"
133 " }\n"
134 " MeshNormals {\n"
135 "  3;\n"
136 "  1.1; 1.2; 1.3;,\n"
137 "  1.4; 1.5; 1.6;,\n"
138 "  1.7; 1.8; 1.9;;\n"
139 "  1;"
140 "  3; 0, 1, 2;;\n"
141 " }\n"
142 " MeshTextureCoords {\n"
143 "  3;\n"
144 "  0.13; 0.17;,\n"
145 "  0.23; 0.27;,\n"
146 "  0.33; 0.37;;\n"
147 " }\n"
148 "}\n";
149
150 static char data_d3drm_load[] =
151 "xof 0302txt 0064\n"
152 "Header Object\n"
153 "{\n"
154 "1; 0; 1;\n"
155 "}\n"
156 "Mesh Object1\n"
157 "{\n"
158 " 1;\n"
159 " 0.1; 0.2; 0.3;,\n"
160 " 1;\n"
161 " 3; 0, 1, 2;;\n"
162 "}\n"
163 "Mesh Object2\n"
164 "{\n"
165 " 1;\n"
166 " 0.1; 0.2; 0.3;,\n"
167 " 1;\n"
168 " 3; 0, 1, 2;;\n"
169 "}\n"
170 "Frame Scene\n"
171 "{\n"
172 " {Object1}\n"
173 " {Object2}\n"
174 "}\n"
175 "Material\n"
176 "{\n"
177 " 0.1, 0.2, 0.3, 0.4;;\n"
178 " 0.5;\n"
179 " 0.6, 0.7, 0.8;;\n"
180 " 0.9, 1.0, 1.1;;\n"
181 "}\n";
182
183 static char data_frame_mesh_materials[] =
184 "xof 0302txt 0064\n"
185 "Header { 1; 0; 1; }\n"
186 "Frame {\n"
187 " Mesh mesh1 {\n"
188 "  5;\n"
189 "  0.1; 0.2; 0.3;,\n"
190 "  0.4; 0.5; 0.6;,\n"
191 "  0.7; 0.8; 0.9;,\n"
192 "  1.1; 1.2; 1.3;,\n"
193 "  1.4; 1.5; 1.6;;\n"
194 "  6;\n"
195 "  3; 0, 1, 2;,\n"
196 "  3; 0, 2, 1;,\n"
197 "  3; 1, 2, 3;,\n"
198 "  3; 1, 3, 2;,\n"
199 "  3; 2, 3, 4;,\n"
200 "  3; 2, 4, 3;;\n"
201 "  MeshMaterialList {\n"
202 "   3; 6; 0, 1, 1, 2, 2, 2;\n"
203 "   Material mat1 {\n"
204 "    1.0; 0.0; 0.0; 0.1;;\n"
205 "    10.0;\n"
206 "    0.11; 0.12; 0.13;;\n"
207 "    0.14; 0.15; 0.16;;\n"
208 "   }\n"
209 "   Material mat2 {\n"
210 "    0.0; 1.0; 0.0; 0.2;;\n"
211 "    20.0;\n"
212 "    0.21; 0.22; 0.23;;\n"
213 "    0.24; 0.25; 0.26;;\n"
214 "   }\n"
215 "   Material mat3 {\n"
216 "    0.0; 0.0; 1.0; 0.3;;\n"
217 "    30.0;\n"
218 "    0.31; 0.32; 0.33;;\n"
219 "    0.34; 0.35; 0.36;;\n"
220 "   }\n"
221 "  }\n"
222 " }\n"
223 "}\n";
224
225 static void test_MeshBuilder(void)
226 {
227     HRESULT hr;
228     IDirect3DRM *d3drm;
229     LPDIRECT3DRMMESHBUILDER pMeshBuilder;
230     LPDIRECT3DRMMESH mesh;
231     D3DRMLOADMEMORY info;
232     int val;
233     DWORD val1, val2, val3;
234     D3DVALUE valu, valv;
235     D3DVECTOR v[3];
236     D3DVECTOR n[4];
237     DWORD f[8];
238     char name[10];
239     DWORD size;
240     D3DCOLOR color;
241     CHAR cname[64] = {0};
242
243     hr = pDirect3DRMCreate(&d3drm);
244     ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x)\n", hr);
245
246     hr = IDirect3DRM_CreateMeshBuilder(d3drm, &pMeshBuilder);
247     ok(hr == D3DRM_OK, "Cannot get IDirect3DRMMeshBuilder interface (hr = %x)\n", hr);
248
249     hr = IDirect3DRMMeshBuilder_GetClassName(pMeshBuilder, NULL, cname);
250     ok(hr == E_INVALIDARG, "GetClassName failed with %x\n", hr);
251     hr = IDirect3DRMMeshBuilder_GetClassName(pMeshBuilder, NULL, NULL);
252     ok(hr == E_INVALIDARG, "GetClassName failed with %x\n", hr);
253     size = 1;
254     hr = IDirect3DRMMeshBuilder_GetClassName(pMeshBuilder, &size, cname);
255     ok(hr == E_INVALIDARG, "GetClassName failed with %x\n", hr);
256     size = sizeof(cname);
257     hr = IDirect3DRMMeshBuilder_GetClassName(pMeshBuilder, &size, cname);
258     ok(hr == D3DRM_OK, "Cannot get classname (hr = %x)\n", hr);
259     ok(size == sizeof("Builder"), "wrong size: %u\n", size);
260     ok(!strcmp(cname, "Builder"), "Expected cname to be \"Builder\", but got \"%s\"\n", cname);
261
262     info.lpMemory = data_bad_version;
263     info.dSize = strlen(data_bad_version);
264     hr = IDirect3DRMMeshBuilder_Load(pMeshBuilder, &info, NULL, D3DRMLOAD_FROMMEMORY, NULL, NULL);
265     ok(hr == D3DRMERR_BADFILE, "Should have returned D3DRMERR_BADFILE (hr = %x)\n", hr);
266
267     info.lpMemory = data_no_mesh;
268     info.dSize = strlen(data_no_mesh);
269     hr = IDirect3DRMMeshBuilder_Load(pMeshBuilder, &info, NULL, D3DRMLOAD_FROMMEMORY, NULL, NULL);
270     ok(hr == D3DRMERR_NOTFOUND, "Should have returned D3DRMERR_NOTFOUND (hr = %x)\n", hr);
271
272     info.lpMemory = data_ok;
273     info.dSize = strlen(data_ok);
274     hr = IDirect3DRMMeshBuilder_Load(pMeshBuilder, &info, NULL, D3DRMLOAD_FROMMEMORY, NULL, NULL);
275     ok(hr == D3DRM_OK, "Cannot load mesh data (hr = %x)\n", hr);
276
277     size = sizeof(name);
278     hr = IDirect3DRMMeshBuilder_GetName(pMeshBuilder, &size, name);
279     ok(hr == D3DRM_OK, "IDirect3DRMMeshBuilder_GetName returned hr = %x\n", hr);
280     ok(!strcmp(name, "Object"), "Retrieved name '%s' instead of 'Object'\n", name);
281     size = strlen("Object"); /* No space for null character */
282     hr = IDirect3DRMMeshBuilder_GetName(pMeshBuilder, &size, name);
283     ok(hr == E_INVALIDARG, "IDirect3DRMMeshBuilder_GetName returned hr = %x\n", hr);
284     hr = IDirect3DRMMeshBuilder_SetName(pMeshBuilder, NULL);
285     ok(hr == D3DRM_OK, "IDirect3DRMMeshBuilder_SetName returned hr = %x\n", hr);
286     size = sizeof(name);
287     hr = IDirect3DRMMeshBuilder_GetName(pMeshBuilder, &size, name);
288     ok(hr == D3DRM_OK, "IDirect3DRMMeshBuilder_GetName returned hr = %x\n", hr);
289     ok(size == 0, "Size should be 0 instead of %u\n", size);
290     hr = IDirect3DRMMeshBuilder_SetName(pMeshBuilder, "");
291     ok(hr == D3DRM_OK, "IDirect3DRMMeshBuilder_SetName returned hr = %x\n", hr);
292     size = sizeof(name);
293     hr = IDirect3DRMMeshBuilder_GetName(pMeshBuilder, &size, name);
294     ok(hr == D3DRM_OK, "IDirect3DRMMeshBuilder_GetName returned hr = %x\n", hr);
295     ok(!strcmp(name, ""), "Retrieved name '%s' instead of ''\n", name);
296
297     val = IDirect3DRMMeshBuilder_GetVertexCount(pMeshBuilder);
298     ok(val == 4, "Wrong number of vertices %d (must be 4)\n", val);
299
300     val = IDirect3DRMMeshBuilder_GetFaceCount(pMeshBuilder);
301     ok(val == 3, "Wrong number of faces %d (must be 3)\n", val);
302
303     hr = IDirect3DRMMeshBuilder_GetVertices(pMeshBuilder, &val1, NULL, &val2, NULL, &val3, NULL);
304     ok(hr == D3DRM_OK, "Cannot get vertices information (hr = %x)\n", hr);
305     ok(val1 == 4, "Wrong number of vertices %d (must be 4)\n", val1);
306     ok(val2 == 4, "Wrong number of normals %d (must be 4)\n", val2);
307     ok(val3 == 22, "Wrong number of face data bytes %d (must be 22)\n", val3);
308
309     /* Check that Load method generated default normals */
310     hr = IDirect3DRMMeshBuilder_GetVertices(pMeshBuilder, NULL, NULL, &val2, n, NULL, NULL);
311     ok(hr == D3DRM_OK, "Cannot get vertices information (hr = %x)\n", hr);
312     ok(match_float(U1(n[0]).x, 0.577350f),  "Wrong component n[0].x = %f (expected %f)\n", U1(n[0]).x, 0.577350f);
313     ok(match_float(U2(n[0]).y, 0.577350f),  "Wrong component n[0].y = %f (expected %f)\n", U2(n[0]).y, 0.577350f);
314     ok(match_float(U3(n[0]).z, 0.577350f),  "Wrong component n[0].z = %f (expected %f)\n", U3(n[0]).z, 0.577350f);
315     ok(match_float(U1(n[1]).x, -0.229416f), "Wrong component n[1].x = %f (expected %f)\n", U1(n[1]).x, -0.229416f);
316     ok(match_float(U2(n[1]).y, 0.688247f),  "Wrong component n[1].y = %f (expected %f)\n", U2(n[1]).y, 0.688247f);
317     ok(match_float(U3(n[1]).z, 0.688247f),  "Wrong component n[1].z = %f (expected %f)\n", U3(n[1]).z, 0.688247f);
318     ok(match_float(U1(n[2]).x, -0.229416f), "Wrong component n[2].x = %f (expected %f)\n", U1(n[2]).x, -0.229416f);
319     ok(match_float(U2(n[2]).y, 0.688247f),  "Wrong component n[2].y = %f (expected %f)\n", U2(n[2]).y, 0.688247f);
320     ok(match_float(U3(n[2]).z, 0.688247f),  "Wrong component n[2].z = %f (expected %f)\n", U3(n[2]).z, 0.688247f);
321     ok(match_float(U1(n[3]).x, -0.577350f), "Wrong component n[3].x = %f (expected %f)\n", U1(n[3]).x, -0.577350f);
322     ok(match_float(U2(n[3]).y, 0.577350f),  "Wrong component n[3].y = %f (expected %f)\n", U2(n[3]).y, 0.577350f);
323     ok(match_float(U3(n[3]).z, 0.577350f),  "Wrong component n[3].z = %f (expected %f)\n", U3(n[3]).z, 0.577350f);
324
325     /* Check that Load method generated default texture coordinates (0.0f, 0.0f) for each vertex */
326     valu = 1.23f;
327     valv = 3.21f;
328     hr = IDirect3DRMMeshBuilder_GetTextureCoordinates(pMeshBuilder, 0, &valu, &valv);
329     ok(hr == D3DRM_OK, "Cannot get texture coordinates (hr = %x)\n", hr);
330     ok(valu == 0.0f, "Wrong coordinate %f (must be 0.0)\n", valu);
331     ok(valv == 0.0f, "Wrong coordinate %f (must be 0.0)\n", valv);
332     valu = 1.23f;
333     valv = 3.21f;
334     hr = IDirect3DRMMeshBuilder_GetTextureCoordinates(pMeshBuilder, 1, &valu, &valv);
335     ok(hr == D3DRM_OK, "Cannot get texture coordinates (hr = %x)\n", hr);
336     ok(valu == 0.0f, "Wrong coordinate %f (must be 0.0)\n", valu);
337     ok(valv == 0.0f, "Wrong coordinate %f (must be 0.0)\n", valv);
338     valu = 1.23f;
339     valv = 3.21f;
340     hr = IDirect3DRMMeshBuilder_GetTextureCoordinates(pMeshBuilder, 2, &valu, &valv);
341     ok(hr == D3DRM_OK, "Cannot get texture coordinates (hr = %x)\n", hr);
342     ok(valu == 0.0f, "Wrong coordinate %f (must be 0.0)\n", valu);
343     ok(valv == 0.0f, "Wrong coordinate %f (must be 0.0)\n", valv);
344     valu = 1.23f;
345     valv = 3.21f;
346     hr = IDirect3DRMMeshBuilder_GetTextureCoordinates(pMeshBuilder, 3, &valu, &valv);
347     ok(hr == D3DRM_OK, "Cannot get texture coordinates (hr = %x)\n", hr);
348     ok(valu == 0.0f, "Wrong coordinate %f (must be 0.0)\n", valu);
349     ok(valv == 0.0f, "Wrong coordinate %f (must be 0.0)\n", valv);
350     hr = IDirect3DRMMeshBuilder_GetTextureCoordinates(pMeshBuilder, 4, &valu, &valv);
351     ok(hr == D3DRMERR_BADVALUE, "Should fail and return D3DRM_BADVALUE (hr = %x)\n", hr);
352
353     valu = 1.23f;
354     valv = 3.21f;
355     hr = IDirect3DRMMeshBuilder_SetTextureCoordinates(pMeshBuilder, 0, valu, valv);
356     ok(hr == D3DRM_OK, "Cannot set texture coordinates (hr = %x)\n", hr);
357     hr = IDirect3DRMMeshBuilder_SetTextureCoordinates(pMeshBuilder, 4, valu, valv);
358     ok(hr == D3DRMERR_BADVALUE, "Should fail and return D3DRM_BADVALUE (hr = %x)\n", hr);
359
360     valu = 0.0f;
361     valv = 0.0f;
362     hr = IDirect3DRMMeshBuilder_GetTextureCoordinates(pMeshBuilder, 0, &valu, &valv);
363     ok(hr == D3DRM_OK, "Cannot get texture coordinates (hr = %x)\n", hr);
364     ok(valu == 1.23f, "Wrong coordinate %f (must be 1.23)\n", valu);
365     ok(valv == 3.21f, "Wrong coordinate %f (must be 3.21)\n", valv);
366
367     IDirect3DRMMeshBuilder_Release(pMeshBuilder);
368
369     hr = IDirect3DRM_CreateMeshBuilder(d3drm, &pMeshBuilder);
370     ok(hr == D3DRM_OK, "Cannot get IDirect3DRMMeshBuilder interface (hr = %x)\n", hr);
371
372     /* No group in mesh when mesh builder is not loaded */
373     hr = IDirect3DRMMeshBuilder_CreateMesh(pMeshBuilder, &mesh);
374     ok(hr == D3DRM_OK, "CreateMesh failed returning hr = %x\n", hr);
375     if (hr == D3DRM_OK)
376     {
377         DWORD nb_groups;
378
379         nb_groups = IDirect3DRMMesh_GetGroupCount(mesh);
380         ok(nb_groups == 0, "GetCroupCount returned %u\n", nb_groups);
381
382         IDirect3DRMMesh_Release(mesh);
383     }
384
385     info.lpMemory = data_full;
386     info.dSize = strlen(data_full);
387     hr = IDirect3DRMMeshBuilder_Load(pMeshBuilder, &info, NULL, D3DRMLOAD_FROMMEMORY, NULL, NULL);
388     ok(hr == D3DRM_OK, "Cannot load mesh data (hr = %x)\n", hr);
389
390     val = IDirect3DRMMeshBuilder_GetVertexCount(pMeshBuilder);
391     ok(val == 3, "Wrong number of vertices %d (must be 3)\n", val);
392
393     val = IDirect3DRMMeshBuilder_GetFaceCount(pMeshBuilder);
394     ok(val == 1, "Wrong number of faces %d (must be 1)\n", val);
395
396     /* Check no buffer size and too small buffer size errors */
397     val1 = 1; val2 = 3; val3 = 8;
398     hr = IDirect3DRMMeshBuilder_GetVertices(pMeshBuilder, &val1, v, &val2, n, &val3, f);
399     ok(hr == D3DRMERR_BADVALUE, "IDirect3DRMMeshBuilder_GetVertices returned %#x\n", hr);
400     hr = IDirect3DRMMeshBuilder_GetVertices(pMeshBuilder, NULL, v, &val2, n, &val3, f);
401     ok(hr == D3DRMERR_BADVALUE, "IDirect3DRMMeshBuilder_GetVertices returned %#x\n", hr);
402     val1 = 3; val2 = 1; val3 = 8;
403     hr = IDirect3DRMMeshBuilder_GetVertices(pMeshBuilder, &val1, v, &val2, n, &val3, f);
404     ok(hr == D3DRMERR_BADVALUE, "IDirect3DRMMeshBuilder_GetVertices returned %#x\n", hr);
405     hr = IDirect3DRMMeshBuilder_GetVertices(pMeshBuilder, &val1, v, NULL, n, &val3, f);
406     ok(hr == D3DRMERR_BADVALUE, "IDirect3DRMMeshBuilder_GetVertices returned %#x\n", hr);
407     val1 = 3; val2 = 3; val3 = 1;
408     hr = IDirect3DRMMeshBuilder_GetVertices(pMeshBuilder, &val1, v, &val2, n, &val3, f);
409     ok(hr == D3DRMERR_BADVALUE, "IDirect3DRMMeshBuilder_GetVertices returned %#x\n", hr);
410     hr = IDirect3DRMMeshBuilder_GetVertices(pMeshBuilder, &val1, v, &val2, n, NULL, f);
411     ok(hr == D3DRMERR_BADVALUE, "IDirect3DRMMeshBuilder_GetVertices returned %#x\n", hr);
412
413     val1 = 3; val2 = 3; val3 = 8;
414     hr = IDirect3DRMMeshBuilder_GetVertices(pMeshBuilder, &val1, v, &val2, n, &val3, f);
415     ok(hr == D3DRM_OK, "Cannot get vertices information (hr = %x)\n", hr);
416     ok(val1 == 3, "Wrong number of vertices %d (must be 3)\n", val1);
417     ok(val2 == 3, "Wrong number of normals %d (must be 3)\n", val2);
418     ok(val3 == 8, "Wrong number of face data bytes %d (must be 8)\n", val3);
419     ok(U1(v[0]).x == 0.1f, "Wrong component v[0].x = %f (expected 0.1)\n", U1(v[0]).x);
420     ok(U2(v[0]).y == 0.2f, "Wrong component v[0].y = %f (expected 0.2)\n", U2(v[0]).y);
421     ok(U3(v[0]).z == 0.3f, "Wrong component v[0].z = %f (expected 0.3)\n", U3(v[0]).z);
422     ok(U1(v[1]).x == 0.4f, "Wrong component v[1].x = %f (expected 0.4)\n", U1(v[1]).x);
423     ok(U2(v[1]).y == 0.5f, "Wrong component v[1].y = %f (expected 0.5)\n", U2(v[1]).y);
424     ok(U3(v[1]).z == 0.6f, "Wrong component v[1].z = %f (expected 0.6)\n", U3(v[1]).z);
425     ok(U1(v[2]).x == 0.7f, "Wrong component v[2].x = %f (expected 0.7)\n", U1(v[2]).x);
426     ok(U2(v[2]).y == 0.8f, "Wrong component v[2].y = %f (expected 0.8)\n", U2(v[2]).y);
427     ok(U3(v[2]).z == 0.9f, "Wrong component v[2].z = %f (expected 0.9)\n", U3(v[2]).z);
428     ok(U1(n[0]).x == 1.1f, "Wrong component n[0].x = %f (expected 1.1)\n", U1(n[0]).x);
429     ok(U2(n[0]).y == 1.2f, "Wrong component n[0].y = %f (expected 1.2)\n", U2(n[0]).y);
430     ok(U3(n[0]).z == 1.3f, "Wrong component n[0].z = %f (expected 1.3)\n", U3(n[0]).z);
431     ok(U1(n[1]).x == 1.4f, "Wrong component n[1].x = %f (expected 1.4)\n", U1(n[1]).x);
432     ok(U2(n[1]).y == 1.5f, "Wrong component n[1].y = %f (expected 1.5)\n", U2(n[1]).y);
433     ok(U3(n[1]).z == 1.6f, "Wrong component n[1].z = %f (expected 1.6)\n", U3(n[1]).z);
434     ok(U1(n[2]).x == 1.7f, "Wrong component n[2].x = %f (expected 1.7)\n", U1(n[2]).x);
435     ok(U2(n[2]).y == 1.8f, "Wrong component n[2].y = %f (expected 1.8)\n", U2(n[2]).y);
436     ok(U3(n[2]).z == 1.9f, "Wrong component n[2].z = %f (expected 1.9)\n", U3(n[2]).z);
437     ok(f[0] == 3 , "Wrong component f[0] = %d (expected 3)\n", f[0]);
438     ok(f[1] == 0 , "Wrong component f[1] = %d (expected 0)\n", f[1]);
439     ok(f[2] == 0 , "Wrong component f[2] = %d (expected 0)\n", f[2]);
440     ok(f[3] == 1 , "Wrong component f[3] = %d (expected 1)\n", f[3]);
441     ok(f[4] == 1 , "Wrong component f[4] = %d (expected 1)\n", f[4]);
442     ok(f[5] == 2 , "Wrong component f[5] = %d (expected 2)\n", f[5]);
443     ok(f[6] == 2 , "Wrong component f[6] = %d (expected 2)\n", f[6]);
444     ok(f[7] == 0 , "Wrong component f[7] = %d (expected 0)\n", f[7]);
445
446     hr = IDirect3DRMMeshBuilder_CreateMesh(pMeshBuilder, &mesh);
447     ok(hr == D3DRM_OK, "CreateMesh failed returning hr = %x\n", hr);
448     if (hr == D3DRM_OK)
449     {
450         DWORD nb_groups;
451         unsigned nb_vertices, nb_faces, nb_face_vertices;
452         DWORD data_size;
453         LPDIRECT3DRMMATERIAL material = (LPDIRECT3DRMMATERIAL)0xdeadbeef;
454         LPDIRECT3DRMTEXTURE texture = (LPDIRECT3DRMTEXTURE)0xdeadbeef;
455         D3DVALUE values[3];
456
457         nb_groups = IDirect3DRMMesh_GetGroupCount(mesh);
458         ok(nb_groups == 1, "GetCroupCount returned %u\n", nb_groups);
459         hr = IDirect3DRMMesh_GetGroup(mesh, 1, &nb_vertices, &nb_faces, &nb_face_vertices, &data_size, NULL);
460         ok(hr == D3DRMERR_BADVALUE, "GetCroup returned hr = %x\n", hr);
461         hr = IDirect3DRMMesh_GetGroup(mesh, 0, &nb_vertices, &nb_faces, &nb_face_vertices, &data_size, NULL);
462         ok(hr == D3DRM_OK, "GetCroup failed returning hr = %x\n", hr);
463         ok(nb_vertices == 3, "Wrong number of vertices %u (must be 3)\n", nb_vertices);
464         ok(nb_faces == 1, "Wrong number of faces %u (must be 1)\n", nb_faces);
465         ok(nb_face_vertices == 3, "Wrong number of vertices per face %u (must be 3)\n", nb_face_vertices);
466         ok(data_size == 3, "Wrong number of face data bytes %u (must be 3)\n", data_size);
467         color = IDirect3DRMMesh_GetGroupColor(mesh, 0);
468         ok(color == 0xff00ff00, "Wrong color returned %#x instead of %#x\n", color, 0xff00ff00);
469         hr = IDirect3DRMMesh_GetGroupTexture(mesh, 0, &texture);
470         ok(hr == D3DRM_OK, "GetCroupTexture failed returning hr = %x\n", hr);
471         ok(texture == NULL, "No texture should be present\n");
472         hr = IDirect3DRMMesh_GetGroupMaterial(mesh, 0, &material);
473         ok(hr == D3DRM_OK, "GetCroupMaterial failed returning hr = %x\n", hr);
474         ok(material != NULL, "No material present\n");
475         if ((hr == D3DRM_OK) && material)
476         {
477             hr = IDirect3DRMMaterial_GetEmissive(material, &values[0], &values[1], &values[2]);
478             ok(hr == D3DRM_OK, "GetMaterialEmissive failed returning hr = %x\n", hr);
479             ok(values[0] == 0.5f, "Emissive red component should be %f instead of %f\n", 0.5f, values[0]);
480             ok(values[1] == 0.5f, "Emissive green component should be %f instead of %f\n", 0.5f, values[1]);
481             ok(values[2] == 0.5f, "Emissive blue component should be %f instead of %f\n", 0.5f, values[2]);
482             hr = IDirect3DRMMaterial_GetSpecular(material, &values[0], &values[1], &values[2]);
483             ok(hr == D3DRM_OK, "GetMaterialEmissive failed returning hr = %x\n", hr);
484             ok(values[0] == 1.0f, "Specular red component should be %f instead of %f\n", 1.0f, values[0]);
485             ok(values[1] == 0.0f, "Specular green component should be %f instead of %f\n", 0.0f, values[1]);
486             ok(values[2] == 0.0f, "Specular blue component should be %f instead of %f\n", 0.0f, values[2]);
487             values[0] = IDirect3DRMMaterial_GetPower(material);
488             ok(values[0] == 30.0f, "Power value should be %f instead of %f\n", 30.0f, values[0]);
489         }
490
491         IDirect3DRMMesh_Release(mesh);
492     }
493
494     hr = IDirect3DRMMeshBuilder_Scale(pMeshBuilder, 2, 3 ,4);
495     ok(hr == D3DRM_OK, "Scale failed returning hr = %x\n", hr);
496
497     hr = IDirect3DRMMeshBuilder_GetVertices(pMeshBuilder, &val1, v, &val2, n, &val3, f);
498     ok(hr == D3DRM_OK, "Cannot get vertices information (hr = %x)\n", hr);
499     ok(val2 == 3, "Wrong number of normals %d (must be 3)\n", val2);
500     ok(val1 == 3, "Wrong number of vertices %d (must be 3)\n", val1);
501     ok(U1(v[0]).x == 0.1f*2, "Wrong component v[0].x = %f (expected %f)\n", U1(v[0]).x, 0.1f*2);
502     ok(U2(v[0]).y == 0.2f*3, "Wrong component v[0].y = %f (expected %f)\n", U2(v[0]).y, 0.2f*3);
503     ok(U3(v[0]).z == 0.3f*4, "Wrong component v[0].z = %f (expected %f)\n", U3(v[0]).z, 0.3f*4);
504     ok(U1(v[1]).x == 0.4f*2, "Wrong component v[1].x = %f (expected %f)\n", U1(v[1]).x, 0.4f*2);
505     ok(U2(v[1]).y == 0.5f*3, "Wrong component v[1].y = %f (expected %f)\n", U2(v[1]).y, 0.5f*3);
506     ok(U3(v[1]).z == 0.6f*4, "Wrong component v[1].z = %f (expected %f)\n", U3(v[1]).z, 0.6f*4);
507     ok(U1(v[2]).x == 0.7f*2, "Wrong component v[2].x = %f (expected %f)\n", U1(v[2]).x, 0.7f*2);
508     ok(U2(v[2]).y == 0.8f*3, "Wrong component v[2].y = %f (expected %f)\n", U2(v[2]).y, 0.8f*3);
509     ok(U3(v[2]).z == 0.9f*4, "Wrong component v[2].z = %f (expected %f)\n", U3(v[2]).z, 0.9f*4);
510     /* Normals are not affected by Scale */
511     ok(U1(n[0]).x == 1.1f, "Wrong component n[0].x = %f (expected %f)\n", U1(n[0]).x, 1.1f);
512     ok(U2(n[0]).y == 1.2f, "Wrong component n[0].y = %f (expected %f)\n", U2(n[0]).y, 1.2f);
513     ok(U3(n[0]).z == 1.3f, "Wrong component n[0].z = %f (expected %f)\n", U3(n[0]).z, 1.3f);
514     ok(U1(n[1]).x == 1.4f, "Wrong component n[1].x = %f (expected %f)\n", U1(n[1]).x, 1.4f);
515     ok(U2(n[1]).y == 1.5f, "Wrong component n[1].y = %f (expected %f)\n", U2(n[1]).y, 1.5f);
516     ok(U3(n[1]).z == 1.6f, "Wrong component n[1].z = %f (expected %f)\n", U3(n[1]).z, 1.6f);
517     ok(U1(n[2]).x == 1.7f, "Wrong component n[2].x = %f (expected %f)\n", U1(n[2]).x, 1.7f);
518     ok(U2(n[2]).y == 1.8f, "Wrong component n[2].y = %f (expected %f)\n", U2(n[2]).y, 1.8f);
519     ok(U3(n[2]).z == 1.9f, "Wrong component n[2].z = %f (expected %f)\n", U3(n[2]).z, 1.9f);
520
521     IDirect3DRMMeshBuilder_Release(pMeshBuilder);
522
523     IDirect3DRM_Release(d3drm);
524 }
525
526 static void test_MeshBuilder3(void)
527 {
528     HRESULT hr;
529     IDirect3DRM *d3drm;
530     IDirect3DRM3 *d3drm3;
531     LPDIRECT3DRMMESHBUILDER3 pMeshBuilder3;
532     D3DRMLOADMEMORY info;
533     int val;
534     DWORD val1;
535     D3DVALUE valu, valv;
536     DWORD size;
537     CHAR cname[64] = {0};
538
539     hr = pDirect3DRMCreate(&d3drm);
540     ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x)\n", hr);
541
542     if (FAILED(hr = IDirect3DRM_QueryInterface(d3drm, &IID_IDirect3DRM3, (void **)&d3drm3)))
543     {
544         win_skip("Cannot get IDirect3DRM3 interface (hr = %x), skipping tests\n", hr);
545         IDirect3DRM_Release(d3drm);
546         return;
547     }
548
549     hr = IDirect3DRM3_CreateMeshBuilder(d3drm3, &pMeshBuilder3);
550     ok(hr == D3DRM_OK, "Cannot get IDirect3DRMMeshBuilder3 interface (hr = %x)\n", hr);
551
552     hr = IDirect3DRMMeshBuilder3_GetClassName(pMeshBuilder3, NULL, cname);
553     ok(hr == E_INVALIDARG, "GetClassName failed with %x\n", hr);
554     hr = IDirect3DRMMeshBuilder3_GetClassName(pMeshBuilder3, NULL, NULL);
555     ok(hr == E_INVALIDARG, "GetClassName failed with %x\n", hr);
556     size = 1;
557     hr = IDirect3DRMMeshBuilder3_GetClassName(pMeshBuilder3, &size, cname);
558     ok(hr == E_INVALIDARG, "GetClassName failed with %x\n", hr);
559     size = sizeof(cname);
560     hr = IDirect3DRMMeshBuilder3_GetClassName(pMeshBuilder3, &size, cname);
561     ok(hr == D3DRM_OK, "Cannot get classname (hr = %x)\n", hr);
562     ok(size == sizeof("Builder"), "wrong size: %u\n", size);
563     ok(!strcmp(cname, "Builder"), "Expected cname to be \"Builder\", but got \"%s\"\n", cname);
564
565     info.lpMemory = data_bad_version;
566     info.dSize = strlen(data_bad_version);
567     hr = IDirect3DRMMeshBuilder3_Load(pMeshBuilder3, &info, NULL, D3DRMLOAD_FROMMEMORY, NULL, NULL);
568     ok(hr == D3DRMERR_BADFILE, "Should have returned D3DRMERR_BADFILE (hr = %x)\n", hr);
569
570     info.lpMemory = data_no_mesh;
571     info.dSize = strlen(data_no_mesh);
572     hr = IDirect3DRMMeshBuilder3_Load(pMeshBuilder3, &info, NULL, D3DRMLOAD_FROMMEMORY, NULL, NULL);
573     ok(hr == D3DRMERR_NOTFOUND, "Should have returned D3DRMERR_NOTFOUND (hr = %x)\n", hr);
574
575     info.lpMemory = data_ok;
576     info.dSize = strlen(data_ok);
577     hr = IDirect3DRMMeshBuilder3_Load(pMeshBuilder3, &info, NULL, D3DRMLOAD_FROMMEMORY, NULL, NULL);
578     ok(hr == D3DRM_OK, "Cannot load mesh data (hr = %x)\n", hr);
579
580     val = IDirect3DRMMeshBuilder3_GetVertexCount(pMeshBuilder3);
581     ok(val == 4, "Wrong number of vertices %d (must be 4)\n", val);
582
583     val = IDirect3DRMMeshBuilder3_GetFaceCount(pMeshBuilder3);
584     ok(val == 3, "Wrong number of faces %d (must be 3)\n", val);
585
586     hr = IDirect3DRMMeshBuilder3_GetVertices(pMeshBuilder3, 0, &val1, NULL);
587     ok(hr == D3DRM_OK, "Cannot get vertices information (hr = %x)\n", hr);
588     ok(val1 == 4, "Wrong number of vertices %d (must be 4)\n", val1);
589
590     /* Check that Load method generated default texture coordinates (0.0f, 0.0f) for each vertex */
591     valu = 1.23f;
592     valv = 3.21f;
593     hr = IDirect3DRMMeshBuilder3_GetTextureCoordinates(pMeshBuilder3, 0, &valu, &valv);
594     ok(hr == D3DRM_OK, "Cannot get texture coordinates (hr = %x)\n", hr);
595     ok(valu == 0.0f, "Wrong coordinate %f (must be 0.0)\n", valu);
596     ok(valv == 0.0f, "Wrong coordinate %f (must be 0.0)\n", valv);
597     valu = 1.23f;
598     valv = 3.21f;
599     hr = IDirect3DRMMeshBuilder3_GetTextureCoordinates(pMeshBuilder3, 1, &valu, &valv);
600     ok(hr == D3DRM_OK, "Cannot get texture coordinates (hr = %x)\n", hr);
601     ok(valu == 0.0f, "Wrong coordinate %f (must be 0.0)\n", valu);
602     ok(valv == 0.0f, "Wrong coordinate %f (must be 0.0)\n", valv);
603     valu = 1.23f;
604     valv = 3.21f;
605     hr = IDirect3DRMMeshBuilder3_GetTextureCoordinates(pMeshBuilder3, 2, &valu, &valv);
606     ok(hr == D3DRM_OK, "Cannot get texture coordinates (hr = %x)\n", hr);
607     ok(valu == 0.0f, "Wrong coordinate %f (must be 0.0)\n", valu);
608     ok(valv == 0.0f, "Wrong coordinate %f (must be 0.0)\n", valv);
609     valu = 1.23f;
610     valv = 3.21f;
611     hr = IDirect3DRMMeshBuilder3_GetTextureCoordinates(pMeshBuilder3, 3, &valu, &valv);
612     ok(hr == D3DRM_OK, "Cannot get texture coordinates (hr = %x)\n", hr);
613     ok(valu == 0.0f, "Wrong coordinate %f (must be 0.0)\n", valu);
614     ok(valv == 0.0f, "Wrong coordinate %f (must be 0.0)\n", valv);
615     hr = IDirect3DRMMeshBuilder3_GetTextureCoordinates(pMeshBuilder3, 4, &valu, &valv);
616     ok(hr == D3DRMERR_BADVALUE, "Should fail and return D3DRM_BADVALUE (hr = %x)\n", hr);
617
618     valu = 1.23f;
619     valv = 3.21f;
620     hr = IDirect3DRMMeshBuilder3_SetTextureCoordinates(pMeshBuilder3, 0, valu, valv);
621     ok(hr == D3DRM_OK, "Cannot set texture coordinates (hr = %x)\n", hr);
622     hr = IDirect3DRMMeshBuilder3_SetTextureCoordinates(pMeshBuilder3, 4, valu, valv);
623     ok(hr == D3DRMERR_BADVALUE, "Should fail and return D3DRM_BADVALUE (hr = %x)\n", hr);
624
625     valu = 0.0f;
626     valv = 0.0f;
627     hr = IDirect3DRMMeshBuilder3_GetTextureCoordinates(pMeshBuilder3, 0, &valu, &valv);
628     ok(hr == D3DRM_OK, "Cannot get texture coordinates (hr = %x)\n", hr);
629     ok(valu == 1.23f, "Wrong coordinate %f (must be 1.23)\n", valu);
630     ok(valv == 3.21f, "Wrong coordinate %f (must be 3.21)\n", valv);
631
632     IDirect3DRMMeshBuilder3_Release(pMeshBuilder3);
633     IDirect3DRM3_Release(d3drm3);
634     IDirect3DRM_Release(d3drm);
635 }
636
637 static void test_Mesh(void)
638 {
639     HRESULT hr;
640     IDirect3DRM *d3drm;
641     LPDIRECT3DRMMESH pMesh;
642     DWORD size;
643     CHAR cname[64] = {0};
644
645     hr = pDirect3DRMCreate(&d3drm);
646     ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x)\n", hr);
647
648     hr = IDirect3DRM_CreateMesh(d3drm, &pMesh);
649     ok(hr == D3DRM_OK, "Cannot get IDirect3DRMMesh interface (hr = %x)\n", hr);
650
651     hr = IDirect3DRMMesh_GetClassName(pMesh, NULL, cname);
652     ok(hr == E_INVALIDARG, "GetClassName failed with %x\n", hr);
653     hr = IDirect3DRMMesh_GetClassName(pMesh, NULL, NULL);
654     ok(hr == E_INVALIDARG, "GetClassName failed with %x\n", hr);
655     size = 1;
656     hr = IDirect3DRMMesh_GetClassName(pMesh, &size, cname);
657     ok(hr == E_INVALIDARG, "GetClassName failed with %x\n", hr);
658     size = sizeof(cname);
659     hr = IDirect3DRMMesh_GetClassName(pMesh, &size, cname);
660     ok(hr == D3DRM_OK, "Cannot get classname (hr = %x)\n", hr);
661     ok(size == sizeof("Mesh"), "wrong size: %u\n", size);
662     ok(!strcmp(cname, "Mesh"), "Expected cname to be \"Mesh\", but got \"%s\"\n", cname);
663
664     IDirect3DRMMesh_Release(pMesh);
665
666     IDirect3DRM_Release(d3drm);
667 }
668
669 static void test_Frame(void)
670 {
671     HRESULT hr;
672     IDirect3DRM *d3drm;
673     IDirect3DRMFrame *pFrameC;
674     IDirect3DRMFrame *pFrameP1;
675     IDirect3DRMFrame *pFrameP2;
676     IDirect3DRMFrame *pFrameTmp;
677     LPDIRECT3DRMFRAMEARRAY pArray;
678     LPDIRECT3DRMMESHBUILDER pMeshBuilder;
679     IDirect3DRMVisual *visual1;
680     IDirect3DRMVisual *visual_tmp;
681     LPDIRECT3DRMVISUALARRAY pVisualArray;
682     LPDIRECT3DRMLIGHT pLight1;
683     LPDIRECT3DRMLIGHT pLightTmp;
684     LPDIRECT3DRMLIGHTARRAY pLightArray;
685     D3DCOLOR color;
686     DWORD count;
687     CHAR cname[64] = {0};
688
689     hr = pDirect3DRMCreate(&d3drm);
690     ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x)\n", hr);
691
692     hr = IDirect3DRM_CreateFrame(d3drm, NULL, &pFrameC);
693     ok(hr == D3DRM_OK, "Cannot get IDirect3DRMFrame interface (hr = %x)\n", hr);
694     CHECK_REFCOUNT(pFrameC, 1);
695
696     hr = IDirect3DRMFrame_GetClassName(pFrameC, NULL, cname);
697     ok(hr == E_INVALIDARG, "GetClassName failed with %x\n", hr);
698     hr = IDirect3DRMFrame_GetClassName(pFrameC, NULL, NULL);
699     ok(hr == E_INVALIDARG, "GetClassName failed with %x\n", hr);
700     count = 1;
701     hr = IDirect3DRMFrame_GetClassName(pFrameC, &count, cname);
702     ok(hr == E_INVALIDARG, "GetClassName failed with %x\n", hr);
703     count = sizeof(cname);
704     hr = IDirect3DRMFrame_GetClassName(pFrameC, &count, cname);
705     ok(hr == D3DRM_OK, "Cannot get classname (hr = %x)\n", hr);
706     ok(count == sizeof("Frame"), "wrong size: %u\n", count);
707     ok(!strcmp(cname, "Frame"), "Expected cname to be \"Frame\", but got \"%s\"\n", cname);
708
709     hr = IDirect3DRMFrame_GetParent(pFrameC, NULL);
710     ok(hr == D3DRMERR_BADVALUE, "Should fail and return D3DRM_BADVALUE (hr = %x)\n", hr);
711     pFrameTmp = (void*)0xdeadbeef;
712     hr = IDirect3DRMFrame_GetParent(pFrameC, &pFrameTmp);
713     ok(hr == D3DRM_OK, "Cannot get parent frame (hr = %x)\n", hr);
714     ok(pFrameTmp == NULL, "pFrameTmp = %p\n", pFrameTmp);
715     CHECK_REFCOUNT(pFrameC, 1);
716
717     pArray = NULL;
718     hr = IDirect3DRMFrame_GetChildren(pFrameC, &pArray);
719     ok(hr == D3DRM_OK, "Cannot get children (hr = %x)\n", hr);
720     ok(pArray != NULL, "pArray = %p\n", pArray);
721     if (pArray)
722     {
723         count = IDirect3DRMFrameArray_GetSize(pArray);
724         ok(count == 0, "count = %u\n", count);
725         hr = IDirect3DRMFrameArray_GetElement(pArray, 0, &pFrameTmp);
726         ok(hr == D3DRMERR_BADVALUE, "Should have returned D3DRMERR_BADVALUE (hr = %x)\n", hr);
727         ok(pFrameTmp == NULL, "pFrameTmp = %p\n", pFrameTmp);
728         IDirect3DRMFrameArray_Release(pArray);
729     }
730
731     hr = IDirect3DRM_CreateFrame(d3drm, NULL, &pFrameP1);
732     ok(hr == D3DRM_OK, "Cannot get IDirect3DRMFrame interface (hr = %x)\n", hr);
733
734     /* GetParent with NULL pointer */
735     hr = IDirect3DRMFrame_GetParent(pFrameP1, NULL);
736     ok(hr == D3DRMERR_BADVALUE, "Should have returned D3DRMERR_BADVALUE (hr = %x)\n", hr);
737     CHECK_REFCOUNT(pFrameP1, 1);
738
739     /* [Add/Delete]Child with NULL pointer */
740     hr = IDirect3DRMFrame_AddChild(pFrameP1, NULL);
741     ok(hr == D3DRMERR_BADOBJECT, "Should have returned D3DRMERR_BADOBJECT (hr = %x)\n", hr);
742     CHECK_REFCOUNT(pFrameP1, 1);
743
744     hr = IDirect3DRMFrame_DeleteChild(pFrameP1, NULL);
745     ok(hr == D3DRMERR_BADOBJECT, "Should have returned D3DRMERR_BADOBJECT (hr = %x)\n", hr);
746     CHECK_REFCOUNT(pFrameP1, 1);
747
748     /* Add child to first parent */
749     pFrameTmp = (void*)0xdeadbeef;
750     hr = IDirect3DRMFrame_GetParent(pFrameP1, &pFrameTmp);
751     ok(hr == D3DRM_OK, "Cannot get parent frame (hr = %x)\n", hr);
752     ok(pFrameTmp == NULL, "pFrameTmp = %p\n", pFrameTmp);
753
754     hr = IDirect3DRMFrame_AddChild(pFrameP1, pFrameC);
755     ok(hr == D3DRM_OK, "Cannot add child frame (hr = %x)\n", hr);
756     CHECK_REFCOUNT(pFrameP1, 1);
757     CHECK_REFCOUNT(pFrameC, 2);
758
759     pArray = NULL;
760     hr = IDirect3DRMFrame_GetChildren(pFrameP1, &pArray);
761     ok(hr == D3DRM_OK, "Cannot get children (hr = %x)\n", hr);
762     /* In some older version of d3drm, creating IDirect3DRMFrameArray object with GetChildren does not increment refcount of children frames */
763     ok((get_refcount((IUnknown*)pFrameC) == 3) || broken(get_refcount((IUnknown*)pFrameC) == 2),
764             "Invalid refcount. Expected 3 (or 2) got %d\n", get_refcount((IUnknown*)pFrameC));
765     if (pArray)
766     {
767         count = IDirect3DRMFrameArray_GetSize(pArray);
768         ok(count == 1, "count = %u\n", count);
769         hr = IDirect3DRMFrameArray_GetElement(pArray, 0, &pFrameTmp);
770         ok(hr == D3DRM_OK, "Cannot get element (hr = %x)\n", hr);
771         ok(pFrameTmp == pFrameC, "pFrameTmp = %p\n", pFrameTmp);
772         ok((get_refcount((IUnknown*)pFrameC) == 4) || broken(get_refcount((IUnknown*)pFrameC) == 3),
773                 "Invalid refcount. Expected 4 (or 3) got %d\n", get_refcount((IUnknown*)pFrameC));
774         IDirect3DRMFrame_Release(pFrameTmp);
775         ok((get_refcount((IUnknown*)pFrameC) == 3) || broken(get_refcount((IUnknown*)pFrameC) == 2),
776                 "Invalid refcount. Expected 3 (or 2) got %d\n", get_refcount((IUnknown*)pFrameC));
777         IDirect3DRMFrameArray_Release(pArray);
778         CHECK_REFCOUNT(pFrameC, 2);
779     }
780
781     pFrameTmp = (void*)0xdeadbeef;
782     hr = IDirect3DRMFrame_GetParent(pFrameC, &pFrameTmp);
783     ok(hr == D3DRM_OK, "Cannot get parent frame (hr = %x)\n", hr);
784     ok(pFrameTmp == pFrameP1, "pFrameTmp = %p\n", pFrameTmp);
785     CHECK_REFCOUNT(pFrameP1, 2);
786
787     /* Add child to second parent */
788     hr = IDirect3DRM_CreateFrame(d3drm, NULL, &pFrameP2);
789     ok(hr == D3DRM_OK, "Cannot get IDirect3DRMFrame interface (hr = %x)\n", hr);
790
791     hr = IDirect3DRMFrame_AddChild(pFrameP2, pFrameC);
792     ok(hr == D3DRM_OK, "Cannot add child frame (hr = %x)\n", hr);
793     CHECK_REFCOUNT(pFrameC, 2);
794
795     pArray = NULL;
796     hr = IDirect3DRMFrame_GetChildren(pFrameP2, &pArray);
797     ok(hr == D3DRM_OK, "Cannot get children (hr = %x)\n", hr);
798     if (pArray)
799     {
800         count = IDirect3DRMFrameArray_GetSize(pArray);
801         ok(count == 1, "count = %u\n", count);
802         hr = IDirect3DRMFrameArray_GetElement(pArray, 0, &pFrameTmp);
803         ok(hr == D3DRM_OK, "Cannot get element (hr = %x)\n", hr);
804         ok(pFrameTmp == pFrameC, "pFrameTmp = %p\n", pFrameTmp);
805         IDirect3DRMFrame_Release(pFrameTmp);
806         IDirect3DRMFrameArray_Release(pArray);
807     }
808
809     pArray = NULL;
810     hr = IDirect3DRMFrame_GetChildren(pFrameP1, &pArray);
811     ok(hr == D3DRM_OK, "Cannot get children (hr = %x)\n", hr);
812     if (pArray)
813     {
814         count = IDirect3DRMFrameArray_GetSize(pArray);
815         ok(count == 0, "count = %u\n", count);
816         pFrameTmp = (void*)0xdeadbeef;
817         hr = IDirect3DRMFrameArray_GetElement(pArray, 0, &pFrameTmp);
818         ok(hr == D3DRMERR_BADVALUE, "Should have returned D3DRMERR_BADVALUE (hr = %x)\n", hr);
819         ok(pFrameTmp == NULL, "pFrameTmp = %p\n", pFrameTmp);
820         IDirect3DRMFrameArray_Release(pArray);
821     }
822
823     pFrameTmp = (void*)0xdeadbeef;
824     hr = IDirect3DRMFrame_GetParent(pFrameC, &pFrameTmp);
825     ok(hr == D3DRM_OK, "Cannot get parent frame (hr = %x)\n", hr);
826     ok(pFrameTmp == pFrameP2, "pFrameTmp = %p\n", pFrameTmp);
827     CHECK_REFCOUNT(pFrameP2, 2);
828     CHECK_REFCOUNT(pFrameC, 2);
829
830     /* Add child again */
831     hr = IDirect3DRMFrame_AddChild(pFrameP2, pFrameC);
832     ok(hr == D3DRM_OK, "Cannot add child frame (hr = %x)\n", hr);
833     CHECK_REFCOUNT(pFrameC, 2);
834
835     pArray = NULL;
836     hr = IDirect3DRMFrame_GetChildren(pFrameP2, &pArray);
837     ok(hr == D3DRM_OK, "Cannot get children (hr = %x)\n", hr);
838     if (pArray)
839     {
840         count = IDirect3DRMFrameArray_GetSize(pArray);
841         ok(count == 1, "count = %u\n", count);
842         hr = IDirect3DRMFrameArray_GetElement(pArray, 0, &pFrameTmp);
843         ok(hr == D3DRM_OK, "Cannot get element (hr = %x)\n", hr);
844         ok(pFrameTmp == pFrameC, "pFrameTmp = %p\n", pFrameTmp);
845         IDirect3DRMFrame_Release(pFrameTmp);
846         IDirect3DRMFrameArray_Release(pArray);
847     }
848
849     /* Delete child */
850     hr = IDirect3DRMFrame_DeleteChild(pFrameP2, pFrameC);
851     ok(hr == D3DRM_OK, "Cannot delete child frame (hr = %x)\n", hr);
852     CHECK_REFCOUNT(pFrameC, 1);
853
854     pArray = NULL;
855     hr = IDirect3DRMFrame_GetChildren(pFrameP2, &pArray);
856     ok(hr == D3DRM_OK, "Cannot get children (hr = %x)\n", hr);
857     if (pArray)
858     {
859         count = IDirect3DRMFrameArray_GetSize(pArray);
860         ok(count == 0, "count = %u\n", count);
861         pFrameTmp = (void*)0xdeadbeef;
862         hr = IDirect3DRMFrameArray_GetElement(pArray, 0, &pFrameTmp);
863         ok(hr == D3DRMERR_BADVALUE, "Should have returned D3DRMERR_BADVALUE (hr = %x)\n", hr);
864         ok(pFrameTmp == NULL, "pFrameTmp = %p\n", pFrameTmp);
865         IDirect3DRMFrameArray_Release(pArray);
866     }
867
868     pFrameTmp = (void*)0xdeadbeef;
869     hr = IDirect3DRMFrame_GetParent(pFrameC, &pFrameTmp);
870     ok(hr == D3DRM_OK, "Cannot get parent frame (hr = %x)\n", hr);
871     ok(pFrameTmp == NULL, "pFrameTmp = %p\n", pFrameTmp);
872
873     /* Add two children */
874     hr = IDirect3DRMFrame_AddChild(pFrameP2, pFrameC);
875     ok(hr == D3DRM_OK, "Cannot add child frame (hr = %x)\n", hr);
876     CHECK_REFCOUNT(pFrameC, 2);
877
878     hr = IDirect3DRMFrame_AddChild(pFrameP2, pFrameP1);
879     ok(hr == D3DRM_OK, "Cannot add child frame (hr = %x)\n", hr);
880     CHECK_REFCOUNT(pFrameP1, 3);
881
882     pArray = NULL;
883     hr = IDirect3DRMFrame_GetChildren(pFrameP2, &pArray);
884     ok(hr == D3DRM_OK, "Cannot get children (hr = %x)\n", hr);
885     if (pArray)
886     {
887         count = IDirect3DRMFrameArray_GetSize(pArray);
888         ok(count == 2, "count = %u\n", count);
889         hr = IDirect3DRMFrameArray_GetElement(pArray, 0, &pFrameTmp);
890         ok(hr == D3DRM_OK, "Cannot get element (hr = %x)\n", hr);
891         ok(pFrameTmp == pFrameC, "pFrameTmp = %p\n", pFrameTmp);
892         IDirect3DRMFrame_Release(pFrameTmp);
893         hr = IDirect3DRMFrameArray_GetElement(pArray, 1, &pFrameTmp);
894         ok(hr == D3DRM_OK, "Cannot get element (hr = %x)\n", hr);
895         ok(pFrameTmp == pFrameP1, "pFrameTmp = %p\n", pFrameTmp);
896         IDirect3DRMFrame_Release(pFrameTmp);
897         IDirect3DRMFrameArray_Release(pArray);
898     }
899
900     /* [Add/Delete]Visual with NULL pointer */
901     hr = IDirect3DRMFrame_AddVisual(pFrameP1, NULL);
902     ok(hr == D3DRMERR_BADOBJECT, "Should have returned D3DRMERR_BADOBJECT (hr = %x)\n", hr);
903     CHECK_REFCOUNT(pFrameP1, 3);
904
905     hr = IDirect3DRMFrame_DeleteVisual(pFrameP1, NULL);
906     ok(hr == D3DRMERR_BADOBJECT, "Should have returned D3DRMERR_BADOBJECT (hr = %x)\n", hr);
907     CHECK_REFCOUNT(pFrameP1, 3);
908
909     /* Create Visual */
910     hr = IDirect3DRM_CreateMeshBuilder(d3drm, &pMeshBuilder);
911     ok(hr == D3DRM_OK, "Cannot get IDirect3DRMMeshBuilder interface (hr = %x)\n", hr);
912     visual1 = (IDirect3DRMVisual *)pMeshBuilder;
913
914     /* Add Visual to first parent */
915     hr = IDirect3DRMFrame_AddVisual(pFrameP1, visual1);
916     ok(hr == D3DRM_OK, "Cannot add visual (hr = %x)\n", hr);
917     CHECK_REFCOUNT(pFrameP1, 3);
918     CHECK_REFCOUNT(visual1, 2);
919
920     pVisualArray = NULL;
921     hr = IDirect3DRMFrame_GetVisuals(pFrameP1, &pVisualArray);
922     ok(hr == D3DRM_OK, "Cannot get visuals (hr = %x)\n", hr);
923     if (pVisualArray)
924     {
925         count = IDirect3DRMVisualArray_GetSize(pVisualArray);
926         ok(count == 1, "count = %u\n", count);
927         hr = IDirect3DRMVisualArray_GetElement(pVisualArray, 0, &visual_tmp);
928         ok(hr == D3DRM_OK, "Cannot get element (hr = %x)\n", hr);
929         ok(visual_tmp == visual1, "visual_tmp = %p\n", visual_tmp);
930         IDirect3DRMVisual_Release(visual_tmp);
931         IDirect3DRMVisualArray_Release(pVisualArray);
932     }
933
934     /* Delete Visual */
935     hr = IDirect3DRMFrame_DeleteVisual(pFrameP1, visual1);
936     ok(hr == D3DRM_OK, "Cannot delete visual (hr = %x)\n", hr);
937     CHECK_REFCOUNT(pFrameP1, 3);
938     IDirect3DRMMeshBuilder_Release(pMeshBuilder);
939
940     /* [Add/Delete]Light with NULL pointer */
941     hr = IDirect3DRMFrame_AddLight(pFrameP1, NULL);
942     ok(hr == D3DRMERR_BADOBJECT, "Should have returned D3DRMERR_BADOBJECT (hr = %x)\n", hr);
943     CHECK_REFCOUNT(pFrameP1, 3);
944
945     hr = IDirect3DRMFrame_DeleteLight(pFrameP1, NULL);
946     ok(hr == D3DRMERR_BADOBJECT, "Should have returned D3DRMERR_BADOBJECT (hr = %x)\n", hr);
947     CHECK_REFCOUNT(pFrameP1, 3);
948
949     /* Create Light */
950     hr = IDirect3DRM_CreateLightRGB(d3drm, D3DRMLIGHT_SPOT, 0.1, 0.2, 0.3, &pLight1);
951     ok(hr == D3DRM_OK, "Cannot get IDirect3DRMLight interface (hr = %x)\n", hr);
952
953     /* Add Light to first parent */
954     hr = IDirect3DRMFrame_AddLight(pFrameP1, pLight1);
955     ok(hr == D3DRM_OK, "Cannot add light (hr = %x)\n", hr);
956     CHECK_REFCOUNT(pFrameP1, 3);
957     CHECK_REFCOUNT(pLight1, 2);
958
959     pLightArray = NULL;
960     hr = IDirect3DRMFrame_GetLights(pFrameP1, &pLightArray);
961     ok(hr == D3DRM_OK, "Cannot get lights (hr = %x)\n", hr);
962     if (pLightArray)
963     {
964         count = IDirect3DRMLightArray_GetSize(pLightArray);
965         ok(count == 1, "count = %u\n", count);
966         hr = IDirect3DRMLightArray_GetElement(pLightArray, 0, &pLightTmp);
967         ok(hr == D3DRM_OK, "Cannot get element (hr = %x)\n", hr);
968         ok(pLightTmp == pLight1, "pLightTmp = %p\n", pLightTmp);
969         IDirect3DRMLight_Release(pLightTmp);
970         IDirect3DRMLightArray_Release(pLightArray);
971     }
972
973     /* Delete Light */
974     hr = IDirect3DRMFrame_DeleteLight(pFrameP1, pLight1);
975     ok(hr == D3DRM_OK, "Cannot delete light (hr = %x)\n", hr);
976     CHECK_REFCOUNT(pFrameP1, 3);
977     IDirect3DRMLight_Release(pLight1);
978
979     /* Test SceneBackground on first parent */
980     color = IDirect3DRMFrame_GetSceneBackground(pFrameP1);
981     ok(color == 0xff000000, "wrong color (%x)\n", color);
982
983     hr = IDirect3DRMFrame_SetSceneBackground(pFrameP1, 0xff180587);
984     ok(hr == D3DRM_OK, "Cannot set color (hr = %x)\n", hr);
985     color = IDirect3DRMFrame_GetSceneBackground(pFrameP1);
986     ok(color == 0xff180587, "wrong color (%x)\n", color);
987
988     hr = IDirect3DRMFrame_SetSceneBackgroundRGB(pFrameP1, 0.5, 0.5, 0.5);
989     ok(hr == D3DRM_OK, "Cannot set color (hr = %x)\n", hr);
990     color = IDirect3DRMFrame_GetSceneBackground(pFrameP1);
991     ok(color == 0xff7f7f7f, "wrong color (%x)\n", color);
992
993     /* Cleanup */
994     IDirect3DRMFrame_Release(pFrameP2);
995     CHECK_REFCOUNT(pFrameC, 2);
996     CHECK_REFCOUNT(pFrameP1, 3);
997
998     IDirect3DRMFrame_Release(pFrameC);
999     IDirect3DRMFrame_Release(pFrameP1);
1000
1001     IDirect3DRM_Release(d3drm);
1002 }
1003
1004 static void test_Viewport(void)
1005 {
1006     IDirectDrawClipper *pClipper;
1007     HRESULT hr;
1008     IDirect3DRM *d3drm;
1009     IDirect3DRMDevice *device;
1010     IDirect3DRMFrame *frame;
1011     IDirect3DRMViewport *viewport;
1012     GUID driver;
1013     HWND window;
1014     RECT rc;
1015     DWORD size;
1016     CHAR cname[64] = {0};
1017
1018     window = CreateWindowA("static", "d3drm_test", WS_OVERLAPPEDWINDOW, 0, 0, 300, 200, 0, 0, 0, 0);
1019     GetClientRect(window, &rc);
1020
1021     hr = pDirect3DRMCreate(&d3drm);
1022     ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x)\n", hr);
1023
1024     hr = DirectDrawCreateClipper(0, &pClipper, NULL);
1025     ok(hr == DD_OK, "Cannot get IDirectDrawClipper interface (hr = %x)\n", hr);
1026
1027     hr = IDirectDrawClipper_SetHWnd(pClipper, 0, window);
1028     ok(hr == DD_OK, "Cannot set HWnd to Clipper (hr = %x)\n", hr);
1029
1030     memcpy(&driver, &IID_IDirect3DRGBDevice, sizeof(GUID));
1031     hr = IDirect3DRM3_CreateDeviceFromClipper(d3drm, pClipper, &driver, rc.right, rc.bottom, &device);
1032     ok(hr == D3DRM_OK, "Cannot get IDirect3DRMDevice interface (hr = %x)\n", hr);
1033
1034     hr = IDirect3DRM_CreateFrame(d3drm, NULL, &frame);
1035     ok(hr == D3DRM_OK, "Cannot get IDirect3DRMFrame interface (hr = %x)\n", hr);
1036
1037     hr = IDirect3DRM_CreateViewport(d3drm, device, frame, rc.left, rc.top, rc.right, rc.bottom, &viewport);
1038     ok(hr == D3DRM_OK, "Cannot get IDirect3DRMViewport interface (hr = %x)\n", hr);
1039
1040     hr = IDirect3DRMViewport_GetClassName(viewport, NULL, cname);
1041     ok(hr == E_INVALIDARG, "GetClassName failed with %x\n", hr);
1042     hr = IDirect3DRMViewport_GetClassName(viewport, NULL, NULL);
1043     ok(hr == E_INVALIDARG, "GetClassName failed with %x\n", hr);
1044     size = 1;
1045     hr = IDirect3DRMViewport_GetClassName(viewport, &size, cname);
1046     ok(hr == E_INVALIDARG, "GetClassName failed with %x\n", hr);
1047     size = sizeof(cname);
1048     hr = IDirect3DRMViewport_GetClassName(viewport, &size, cname);
1049     ok(hr == D3DRM_OK, "Cannot get classname (hr = %x)\n", hr);
1050     ok(size == sizeof("Viewport"), "wrong size: %u\n", size);
1051     ok(!strcmp(cname, "Viewport"), "Expected cname to be \"Viewport\", but got \"%s\"\n", cname);
1052
1053     IDirect3DRMViewport_Release(viewport);
1054     IDirect3DRMFrame_Release(frame);
1055     IDirect3DRMDevice_Release(device);
1056     IDirectDrawClipper_Release(pClipper);
1057
1058     IDirect3DRM_Release(d3drm);
1059     DestroyWindow(window);
1060 }
1061
1062 static void test_Light(void)
1063 {
1064     HRESULT hr;
1065     IDirect3DRM *d3drm;
1066     LPDIRECT3DRMLIGHT pLight;
1067     D3DRMLIGHTTYPE type;
1068     D3DCOLOR color;
1069     DWORD size;
1070     CHAR cname[64] = {0};
1071
1072     hr = pDirect3DRMCreate(&d3drm);
1073     ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x)\n", hr);
1074
1075     hr = IDirect3DRM_CreateLightRGB(d3drm, D3DRMLIGHT_SPOT, 0.5, 0.5, 0.5, &pLight);
1076     ok(hr == D3DRM_OK, "Cannot get IDirect3DRMLight interface (hr = %x)\n", hr);
1077
1078     hr = IDirect3DRMLight_GetClassName(pLight, NULL, cname);
1079     ok(hr == E_INVALIDARG, "GetClassName failed with %x\n", hr);
1080     hr = IDirect3DRMLight_GetClassName(pLight, NULL, NULL);
1081     ok(hr == E_INVALIDARG, "GetClassName failed with %x\n", hr);
1082     size = 1;
1083     hr = IDirect3DRMLight_GetClassName(pLight, &size, cname);
1084     ok(hr == E_INVALIDARG, "GetClassName failed with %x\n", hr);
1085     size = sizeof(cname);
1086     hr = IDirect3DRMLight_GetClassName(pLight, &size, cname);
1087     ok(hr == D3DRM_OK, "Cannot get classname (hr = %x)\n", hr);
1088     ok(size == sizeof("Light"), "wrong size: %u\n", size);
1089     ok(!strcmp(cname, "Light"), "Expected cname to be \"Light\", but got \"%s\"\n", cname);
1090
1091     type = IDirect3DRMLight_GetType(pLight);
1092     ok(type == D3DRMLIGHT_SPOT, "wrong type (%u)\n", type);
1093
1094     color = IDirect3DRMLight_GetColor(pLight);
1095     ok(color == 0xff7f7f7f, "wrong color (%x)\n", color);
1096
1097     hr = IDirect3DRMLight_SetType(pLight, D3DRMLIGHT_POINT);
1098     ok(hr == D3DRM_OK, "Cannot set type (hr = %x)\n", hr);
1099     type = IDirect3DRMLight_GetType(pLight);
1100     ok(type == D3DRMLIGHT_POINT, "wrong type (%u)\n", type);
1101
1102     hr = IDirect3DRMLight_SetColor(pLight, 0xff180587);
1103     ok(hr == D3DRM_OK, "Cannot set color (hr = %x)\n", hr);
1104     color = IDirect3DRMLight_GetColor(pLight);
1105     ok(color == 0xff180587, "wrong color (%x)\n", color);
1106
1107     hr = IDirect3DRMLight_SetColorRGB(pLight, 0.5, 0.5, 0.5);
1108     ok(hr == D3DRM_OK, "Cannot set color (hr = %x)\n", hr);
1109     color = IDirect3DRMLight_GetColor(pLight);
1110     ok(color == 0xff7f7f7f, "wrong color (%x)\n", color);
1111
1112     IDirect3DRMLight_Release(pLight);
1113
1114     IDirect3DRM_Release(d3drm);
1115 }
1116
1117 static void test_Material2(void)
1118 {
1119     HRESULT hr;
1120     IDirect3DRM *d3drm;
1121     IDirect3DRM3 *d3drm3;
1122     LPDIRECT3DRMMATERIAL2 pMaterial2;
1123     D3DVALUE r, g, b;
1124     DWORD size;
1125     CHAR cname[64] = {0};
1126
1127     hr = pDirect3DRMCreate(&d3drm);
1128     ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x)\n", hr);
1129
1130     if (FAILED(hr = IDirect3DRM_QueryInterface(d3drm, &IID_IDirect3DRM3, (void **)&d3drm3)))
1131     {
1132         win_skip("Cannot get IDirect3DRM3 interface (hr = %x), skipping tests\n", hr);
1133         IDirect3DRM_Release(d3drm);
1134         return;
1135     }
1136
1137     hr = IDirect3DRM3_CreateMaterial(d3drm3, 18.5f, &pMaterial2);
1138     ok(hr == D3DRM_OK, "Cannot get IDirect3DRMMaterial2 interface (hr = %x)\n", hr);
1139
1140     hr = IDirect3DRMMaterial2_GetClassName(pMaterial2, NULL, cname);
1141     ok(hr == E_INVALIDARG, "GetClassName failed with %x\n", hr);
1142     hr = IDirect3DRMMaterial2_GetClassName(pMaterial2, NULL, NULL);
1143     ok(hr == E_INVALIDARG, "GetClassName failed with %x\n", hr);
1144     size = 1;
1145     hr = IDirect3DRMMaterial2_GetClassName(pMaterial2, &size, cname);
1146     ok(hr == E_INVALIDARG, "GetClassName failed with %x\n", hr);
1147     size = sizeof(cname);
1148     hr = IDirect3DRMMaterial2_GetClassName(pMaterial2, &size, cname);
1149     ok(hr == D3DRM_OK, "Cannot get classname (hr = %x)\n", hr);
1150     ok(size == sizeof("Material"), "wrong size: %u\n", size);
1151     ok(!strcmp(cname, "Material"), "Expected cname to be \"Material\", but got \"%s\"\n", cname);
1152
1153     r = IDirect3DRMMaterial2_GetPower(pMaterial2);
1154     ok(r == 18.5f, "wrong power (%f)\n", r);
1155
1156     hr = IDirect3DRMMaterial2_GetEmissive(pMaterial2, &r, &g, &b);
1157     ok(hr == D3DRM_OK, "Cannot get emissive (hr = %x)\n", hr);
1158     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);
1159
1160     hr = IDirect3DRMMaterial2_GetSpecular(pMaterial2, &r, &g, &b);
1161     ok(hr == D3DRM_OK, "Cannot get emissive (hr = %x)\n", hr);
1162     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);
1163
1164     hr = IDirect3DRMMaterial2_GetAmbient(pMaterial2, &r, &g, &b);
1165     ok(hr == D3DRM_OK, "Cannot get emissive (hr = %x)\n", hr);
1166     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);
1167
1168     hr = IDirect3DRMMaterial2_SetPower(pMaterial2, 5.87f);
1169     ok(hr == D3DRM_OK, "Cannot set power (hr = %x)\n", hr);
1170     r = IDirect3DRMMaterial2_GetPower(pMaterial2);
1171     ok(r == 5.87f, "wrong power (%f)\n", r);
1172
1173     hr = IDirect3DRMMaterial2_SetEmissive(pMaterial2, 0.5f, 0.5f, 0.5f);
1174     ok(hr == D3DRM_OK, "Cannot set emissive (hr = %x)\n", hr);
1175     hr = IDirect3DRMMaterial2_GetEmissive(pMaterial2, &r, &g, &b);
1176     ok(hr == D3DRM_OK, "Cannot get emissive (hr = %x)\n", hr);
1177     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);
1178
1179     hr = IDirect3DRMMaterial2_SetSpecular(pMaterial2, 0.6f, 0.6f, 0.6f);
1180     ok(hr == D3DRM_OK, "Cannot set specular (hr = %x)\n", hr);
1181     hr = IDirect3DRMMaterial2_GetSpecular(pMaterial2, &r, &g, &b);
1182     ok(hr == D3DRM_OK, "Cannot get specular (hr = %x)\n", hr);
1183     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);
1184
1185     hr = IDirect3DRMMaterial2_SetAmbient(pMaterial2, 0.7f, 0.7f, 0.7f);
1186     ok(hr == D3DRM_OK, "Cannot set ambient (hr = %x)\n", hr);
1187     hr = IDirect3DRMMaterial2_GetAmbient(pMaterial2, &r, &g, &b);
1188     ok(hr == D3DRM_OK, "Cannot get ambient (hr = %x)\n", hr);
1189     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);
1190
1191     IDirect3DRMMaterial2_Release(pMaterial2);
1192
1193     IDirect3DRM3_Release(d3drm3);
1194     IDirect3DRM_Release(d3drm);
1195 }
1196
1197 static void test_Texture(void)
1198 {
1199     HRESULT hr;
1200     IDirect3DRM *d3drm;
1201     LPDIRECT3DRMTEXTURE pTexture;
1202     D3DRMIMAGE initimg = {
1203         2, 2, 1, 1, 32,
1204         TRUE, 2 * sizeof(DWORD), NULL, NULL,
1205         0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000, 0, NULL
1206     };
1207     DWORD pixel[4] = { 20000, 30000, 10000, 0 };
1208     DWORD size;
1209     CHAR cname[64] = {0};
1210
1211     hr = pDirect3DRMCreate(&d3drm);
1212     ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x)\n", hr);
1213
1214     initimg.buffer1 = &pixel;
1215     hr = IDirect3DRM_CreateTexture(d3drm, &initimg, &pTexture);
1216     ok(hr == D3DRM_OK, "Cannot get IDirect3DRMTexture interface (hr = %x)\n", hr);
1217
1218     hr = IDirect3DRMTexture_GetClassName(pTexture, NULL, cname);
1219     ok(hr == E_INVALIDARG, "GetClassName failed with %x\n", hr);
1220     hr = IDirect3DRMTexture_GetClassName(pTexture, NULL, NULL);
1221     ok(hr == E_INVALIDARG, "GetClassName failed with %x\n", hr);
1222     size = 1;
1223     hr = IDirect3DRMTexture_GetClassName(pTexture, &size, cname);
1224     ok(hr == E_INVALIDARG, "GetClassName failed with %x\n", hr);
1225     size = sizeof(cname);
1226     hr = IDirect3DRMTexture_GetClassName(pTexture, &size, cname);
1227     ok(hr == D3DRM_OK, "Cannot get classname (hr = %x)\n", hr);
1228     ok(size == sizeof("Texture"), "wrong size: %u\n", size);
1229     ok(!strcmp(cname, "Texture"), "Expected cname to be \"Texture\", but got \"%s\"\n", cname);
1230
1231     IDirect3DRMTexture_Release(pTexture);
1232
1233     IDirect3DRM_Release(d3drm);
1234 }
1235
1236 static void test_Device(void)
1237 {
1238     IDirectDrawClipper *pClipper;
1239     HRESULT hr;
1240     IDirect3DRM *d3drm;
1241     IDirect3DRMDevice *device;
1242     LPDIRECT3DRMWINDEVICE pWinDevice;
1243     GUID driver;
1244     HWND window;
1245     RECT rc;
1246     DWORD size;
1247     CHAR cname[64] = {0};
1248
1249     window = CreateWindowA("static", "d3drm_test", WS_OVERLAPPEDWINDOW, 0, 0, 300, 200, 0, 0, 0, 0);
1250     GetClientRect(window, &rc);
1251
1252     hr = pDirect3DRMCreate(&d3drm);
1253     ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x)\n", hr);
1254
1255     hr = DirectDrawCreateClipper(0, &pClipper, NULL);
1256     ok(hr == DD_OK, "Cannot get IDirectDrawClipper interface (hr = %x)\n", hr);
1257
1258     hr = IDirectDrawClipper_SetHWnd(pClipper, 0, window);
1259     ok(hr == DD_OK, "Cannot set HWnd to Clipper (hr = %x)\n", hr);
1260
1261     memcpy(&driver, &IID_IDirect3DRGBDevice, sizeof(GUID));
1262     hr = IDirect3DRM3_CreateDeviceFromClipper(d3drm, pClipper, &driver, rc.right, rc.bottom, &device);
1263     ok(hr == D3DRM_OK, "Cannot get IDirect3DRMDevice interface (hr = %x)\n", hr);
1264
1265     hr = IDirect3DRMDevice_GetClassName(device, NULL, cname);
1266     ok(hr == E_INVALIDARG, "GetClassName failed with %x\n", hr);
1267     hr = IDirect3DRMDevice_GetClassName(device, NULL, NULL);
1268     ok(hr == E_INVALIDARG, "GetClassName failed with %x\n", hr);
1269     size = 1;
1270     hr = IDirect3DRMDevice_GetClassName(device, &size, cname);
1271     ok(hr == E_INVALIDARG, "GetClassName failed with %x\n", hr);
1272     size = sizeof(cname);
1273     hr = IDirect3DRMDevice_GetClassName(device, &size, cname);
1274     ok(hr == D3DRM_OK, "Cannot get classname (hr = %x)\n", hr);
1275     ok(size == sizeof("Device"), "wrong size: %u\n", size);
1276     ok(!strcmp(cname, "Device"), "Expected cname to be \"Device\", but got \"%s\"\n", cname);
1277
1278     /* WinDevice */
1279     hr = IDirect3DRMDevice_QueryInterface(device, &IID_IDirect3DRMWinDevice, (LPVOID*)&pWinDevice);
1280     if (FAILED(hr))
1281     {
1282         win_skip("Cannot get IDirect3DRMWinDevice interface (hr = %x), skipping tests\n", hr);
1283         goto cleanup;
1284     }
1285
1286     hr = IDirect3DRMWinDevice_GetClassName(pWinDevice, NULL, cname);
1287     ok(hr == E_INVALIDARG, "GetClassName failed with %x\n", hr);
1288     hr = IDirect3DRMWinDevice_GetClassName(pWinDevice, NULL, NULL);
1289     ok(hr == E_INVALIDARG, "GetClassName failed with %x\n", hr);
1290     size = 1;
1291     hr = IDirect3DRMWinDevice_GetClassName(pWinDevice, &size, cname);
1292     ok(hr == E_INVALIDARG, "GetClassName failed with %x\n", hr);
1293     size = sizeof(cname);
1294     hr = IDirect3DRMWinDevice_GetClassName(pWinDevice, &size, cname);
1295     ok(hr == D3DRM_OK, "Cannot get classname (hr = %x)\n", hr);
1296     ok(size == sizeof("Device"), "wrong size: %u\n", size);
1297     ok(!strcmp(cname, "Device"), "Expected cname to be \"Device\", but got \"%s\"\n", cname);
1298
1299     IDirect3DRMWinDevice_Release(pWinDevice);
1300
1301 cleanup:
1302     IDirect3DRMDevice_Release(device);
1303     IDirectDrawClipper_Release(pClipper);
1304
1305     IDirect3DRM_Release(d3drm);
1306     DestroyWindow(window);
1307 }
1308
1309 static void test_frame_transform(void)
1310 {
1311     HRESULT hr;
1312     IDirect3DRM *d3drm;
1313     IDirect3DRMFrame *frame;
1314     D3DRMMATRIX4D matrix;
1315
1316     hr = pDirect3DRMCreate(&d3drm);
1317     ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x)\n", hr);
1318
1319     hr = IDirect3DRM_CreateFrame(d3drm, NULL, &frame);
1320     ok(hr == D3DRM_OK, "Cannot get IDirect3DRMFrame interface (hr = %x)\n", hr);
1321
1322     hr = IDirect3DRMFrame_GetTransform(frame, matrix);
1323     ok(hr == D3DRM_OK, "IDirect3DRMFrame_GetTransform returned hr = %x\n", hr);
1324     ok(!memcmp(matrix, identity, sizeof(D3DRMMATRIX4D)), "Returned matrix is not identity\n");
1325
1326     IDirect3DRM_Release(d3drm);
1327 }
1328
1329 static int nb_objects = 0;
1330 static const GUID* refiids[] =
1331 {
1332     &IID_IDirect3DRMMeshBuilder,
1333     &IID_IDirect3DRMMeshBuilder,
1334     &IID_IDirect3DRMFrame,
1335     &IID_IDirect3DRMMaterial /* Not taken into account and not notified */
1336 };
1337
1338 static void __cdecl object_load_callback(IDirect3DRMObject *object, REFIID objectguid, LPVOID arg)
1339 {
1340     ok(object != NULL, "Arg 1 should not be null\n");
1341     ok(IsEqualGUID(objectguid, refiids[nb_objects]), "Arg 2 is incorrect\n");
1342     ok(arg == (LPVOID)0xdeadbeef, "Arg 3 should be 0xdeadbeef (got %p)\n", arg);
1343     nb_objects++;
1344 }
1345
1346 static void test_d3drm_load(void)
1347 {
1348     HRESULT hr;
1349     IDirect3DRM *d3drm;
1350     D3DRMLOADMEMORY info;
1351     const GUID* req_refiids[] = { &IID_IDirect3DRMMeshBuilder, &IID_IDirect3DRMFrame, &IID_IDirect3DRMMaterial };
1352
1353     hr = pDirect3DRMCreate(&d3drm);
1354     ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x)\n", hr);
1355
1356     info.lpMemory = data_d3drm_load;
1357     info.dSize = strlen(data_d3drm_load);
1358     hr = IDirect3DRM_Load(d3drm, &info, NULL, (GUID **)req_refiids, 3, D3DRMLOAD_FROMMEMORY,
1359             object_load_callback, (void *)0xdeadbeef, NULL, NULL, NULL);
1360     ok(hr == D3DRM_OK, "Cannot load data (hr = %x)\n", hr);
1361     ok(nb_objects == 3, "Should have loaded 3 objects (got %d)\n", nb_objects);
1362
1363     IDirect3DRM_Release(d3drm);
1364 }
1365
1366 IDirect3DRMMeshBuilder *mesh_builder = NULL;
1367
1368 static void __cdecl object_load_callback_frame(IDirect3DRMObject *object, REFIID object_guid, void *arg)
1369 {
1370     HRESULT hr;
1371     IDirect3DRMFrame *frame;
1372     IDirect3DRMVisualArray *array;
1373     IDirect3DRMVisual *visual;
1374     ULONG size;
1375     char name[128];
1376
1377     hr = IDirect3DRMObject_QueryInterface(object, &IID_IDirect3DRMFrame, (void**)&frame);
1378     ok(hr == D3DRM_OK, "IDirect3DRMObject_QueryInterface returned %x\n", hr);
1379
1380     hr = IDirect3DRMFrame_GetVisuals(frame, &array);
1381     ok(hr == D3DRM_OK, "IDirect3DRMFrame_GetVisuals returned %x\n", hr);
1382
1383     size = IDirect3DRMVisualArray_GetSize(array);
1384     ok(size == 1, "Wrong size %u returned, expected 1\n", size);
1385
1386     hr = IDirect3DRMVisualArray_GetElement(array, 0, &visual);
1387     ok(hr == D3DRM_OK, "IDirect3DRMVisualArray_GetElement returned %x\n", hr);
1388
1389     hr = IDirect3DRMVisual_QueryInterface(visual, &IID_IDirect3DRMMeshBuilder, (void**)&mesh_builder);
1390     ok(hr == D3DRM_OK, "IDirect3DRMVisualArray_GetSize returned %x\n", hr);
1391
1392     size = sizeof(name);
1393     hr = IDirect3DRMMeshBuilder_GetName(mesh_builder, &size, name);
1394     ok(hr == D3DRM_OK, "IDirect3DRMMeshBuilder_GetName returned %x\n", hr);
1395     ok(!strcmp(name, "mesh1"), "Wrong name %s, expected mesh1\n", name);
1396
1397     IDirect3DRMVisual_Release(visual);
1398     IDirect3DRMVisualArray_Release(array);
1399     IDirect3DRMFrame_Release(frame);
1400 }
1401
1402 struct {
1403     int vertex_count;
1404     int face_count;
1405     int vertex_per_face;
1406     int face_data_size;
1407     DWORD color;
1408     float power;
1409     float specular[3];
1410     float emissive[3];
1411 } groups[3] = {
1412     { 4, 3, 3, 9, 0x4c0000ff, 30.0f, { 0.31f, 0.32f, 0.33f }, { 0.34f, 0.35f, 0.36f } },
1413     { 4, 2, 3, 6, 0x3300ff00, 20.0f, { 0.21f, 0.22f, 0.23f }, { 0.24f, 0.25f, 0.26f } },
1414     { 3, 1, 3, 3, 0x19ff0000, 10.0f, { 0.11f, 0.12f, 0.13f }, { 0.14f, 0.15f, 0.16f } }
1415 };
1416
1417 static void test_frame_mesh_materials(void)
1418 {
1419     HRESULT hr;
1420     IDirect3DRM *d3drm;
1421     D3DRMLOADMEMORY info;
1422     const GUID *req_refiids[] = { &IID_IDirect3DRMFrame };
1423     IDirect3DRMMesh *mesh;
1424     ULONG size;
1425     IDirect3DRMMaterial *material;
1426     IDirect3DRMTexture *texture;
1427     int i;
1428
1429     hr = pDirect3DRMCreate(&d3drm);
1430     ok(hr == D3DRM_OK, "Direct3DRMCreate returned %x\n", hr);
1431
1432     info.lpMemory = data_frame_mesh_materials;
1433     info.dSize = strlen(data_frame_mesh_materials);
1434     hr = IDirect3DRM_Load(d3drm, &info, NULL, (GUID**)req_refiids, 1, D3DRMLOAD_FROMMEMORY, object_load_callback_frame, (void*)0xdeadbeef, NULL, NULL, NULL);
1435     ok(hr == D3DRM_OK, "Cannot load data (hr = %x)\n", hr);
1436
1437     hr = IDirect3DRMMeshBuilder_CreateMesh(mesh_builder, &mesh);
1438     ok(hr == D3DRM_OK, "IDirect3DRMMeshBuilder_CreateMesh returned %x\n", hr);
1439
1440     size = IDirect3DRMMesh_GetGroupCount(mesh);
1441     ok(size == 3, "Wrong size %u returned, expected 3\n", size);
1442
1443     for (i = 0; i < size; i++)
1444     {
1445         D3DVALUE red, green, blue, power;
1446         D3DCOLOR color;
1447         unsigned vertex_count, face_count, vertex_per_face;
1448         DWORD face_data_size;
1449
1450         hr = IDirect3DRMMesh_GetGroup(mesh, i, &vertex_count, &face_count, &vertex_per_face, &face_data_size, NULL);
1451         ok(hr == D3DRM_OK, "Group %d: IDirect3DRMMesh_GetGroup returned %x\n", i, hr);
1452         ok(vertex_count == groups[i].vertex_count, "Group %d: Wrong vertex count %d, expected %d\n", i, vertex_count, groups[i].vertex_count);
1453         ok(face_count == groups[i].face_count, "Group %d: Wrong face count %d; expected %d\n", i, face_count, groups[i].face_count);
1454         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);
1455         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);
1456
1457         color = IDirect3DRMMesh_GetGroupColor(mesh, i);
1458         ok(color == groups[i].color, "Group %d: Wrong color %x, expected %x\n", i, color, groups[i].color);
1459
1460         hr = IDirect3DRMMesh_GetGroupMaterial(mesh, i, &material);
1461         ok(hr == D3DRM_OK, "Group %d: IDirect3DRMMesh_GetGroupMaterial returned %x\n", i, hr);
1462         ok(material != NULL, "Group %d: No material\n", i);
1463         power = IDirect3DRMMaterial_GetPower(material);
1464         ok(power == groups[i].power, "Group %d: Wrong power %f, expected %f\n", i, power,  groups[i].power);
1465         hr = IDirect3DRMMaterial_GetSpecular(material, &red, &green, &blue);
1466         ok(hr == D3DRM_OK, "Group %d: IDirect3DRMMaterial_GetSpecular returned %x\n", i, hr);
1467         ok(red == groups[i].specular[0], "Group %d: Wrong specular red %f, expected %f\n", i, red, groups[i].specular[0]);
1468         ok(green == groups[i].specular[1], "Group %d: Wrong specular green %f, pD3DRMexpected %f\n", i, green, groups[i].specular[1]);
1469         ok(blue == groups[i].specular[2], "Group %d: Wrong specular blue %f, expected %f\n", i, blue, groups[i].specular[2]);
1470         hr = IDirect3DRMMaterial_GetEmissive(material, &red, &green, &blue);
1471         ok(hr == D3DRM_OK, "Group %d: IDirect3DRMMaterial_GetEmissive returned %x\n", i, hr);
1472         ok(red == groups[i].emissive[0], "Group %d: Wrong emissive red %f, expected %f\n", i, red, groups[i].emissive[0]);
1473         ok(green == groups[i].emissive[1], "Group %d: Wrong emissive green %f, expected %f\n", i, green, groups[i].emissive[1]);
1474         ok(blue == groups[i].emissive[2], "Group %d: Wrong emissive blue %f, expected %f\n", i, blue, groups[i].emissive[2]);
1475
1476         hr = IDirect3DRMMesh_GetGroupTexture(mesh, i, &texture);
1477         ok(hr == D3DRM_OK, "Group %d: IDirect3DRMMesh_GetGroupTexture returned %x\n", i, hr);
1478         ok(!texture, "Group %d: Unexpected texture\n", i);
1479
1480         if (material)
1481             IDirect3DRMMaterial_Release(material);
1482         if (texture)
1483             IDirect3DRMTexture_Release(texture);
1484     }
1485
1486     IDirect3DRMMesh_Release(mesh);
1487     IDirect3DRMMeshBuilder_Release(mesh_builder);
1488     IDirect3DRM_Release(d3drm);
1489 }
1490
1491 START_TEST(d3drm)
1492 {
1493     if (!InitFunctionPtrs())
1494         return;
1495
1496     test_MeshBuilder();
1497     test_MeshBuilder3();
1498     test_Mesh();
1499     test_Frame();
1500     test_Device();
1501     test_Viewport();
1502     test_Light();
1503     test_Material2();
1504     test_Texture();
1505     test_frame_transform();
1506     test_d3drm_load();
1507     test_frame_mesh_materials();
1508
1509     FreeLibrary(d3drm_handle);
1510 }