d3drm: Fix leakage of pData2 on error.
[wine] / dlls / d3drm / meshbuilder.c
1 /*
2  * Implementation of IDirect3DRMMeshBuilder2 Interface
3  *
4  * Copyright 2010 Christian Costa
5  * Copyright 2011 AndrĂ© Hentschel
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 "wine/debug.h"
23
24 #define COBJMACROS
25
26 #include "winbase.h"
27 #include "wingdi.h"
28 #include "dxfile.h"
29 #include "rmxfguid.h"
30
31 #include "d3drm_private.h"
32
33 WINE_DEFAULT_DEBUG_CHANNEL(d3drm);
34
35 typedef struct {
36     D3DVALUE u;
37     D3DVALUE v;
38 } Coords2d;
39
40 typedef struct {
41     IDirect3DRMMeshBuilder2 IDirect3DRMMeshBuilder2_iface;
42     IDirect3DRMMeshBuilder3 IDirect3DRMMeshBuilder3_iface;
43     LONG ref;
44     DWORD nb_vertices;
45     D3DVECTOR* pVertices;
46     DWORD nb_normals;
47     D3DVECTOR* pNormals;
48     DWORD nb_faces;
49     DWORD face_data_size;
50     LPVOID pFaceData;
51     DWORD nb_coords2d;
52     Coords2d* pCoords2d;
53 } IDirect3DRMMeshBuilderImpl;
54
55 typedef struct {
56     WORD major;
57     WORD minor;
58     DWORD flags;
59 } Header;
60
61 static char templates[] = {
62 "xof 0302txt 0064"
63 "template Header"
64 "{"
65 "<3D82AB43-62DA-11CF-AB39-0020AF71E433>"
66 "WORD major;"
67 "WORD minor;"
68 "DWORD flags;"
69 "}"
70 "template Vector"
71 "{"
72 "<3D82AB5E-62DA-11CF-AB39-0020AF71E433>"
73 "FLOAT x;"
74 "FLOAT y;"
75 "FLOAT z;"
76 "}"
77 "template Coords2d"
78 "{"
79 "<F6F23F44-7686-11CF-8F52-0040333594A3>"
80 "FLOAT u;"
81 "FLOAT v;"
82 "}"
83 "template Matrix4x4"
84 "{"
85 "<F6F23F45-7686-11CF-8F52-0040333594A3>"
86 "array FLOAT matrix[16];"
87 "}"
88 "template ColorRGBA"
89 "{"
90 "<35FF44E0-6C7C-11CF-8F52-0040333594A3>"
91 "FLOAT red;"
92 "FLOAT green;"
93 "FLOAT blue;"
94 "FLOAT alpha;"
95 "}"
96 "template ColorRGB"
97 "{"
98 "<D3E16E81-7835-11CF-8F52-0040333594A3>"
99 "FLOAT red;"
100 "FLOAT green;"
101 "FLOAT blue;"
102 "}"
103 "template IndexedColor"
104 "{"
105 "<1630B820-7842-11CF-8F52-0040333594A3>"
106 "DWORD index;"
107 "ColorRGBA indexColor;"
108 "}"
109 "template Boolean"
110 "{"
111 "<537DA6A0-CA37-11D0-941C-0080C80CFA7B>"
112 "DWORD truefalse;"
113 "}"
114 "template Boolean2d"
115 "{"
116 "<4885AE63-78E8-11CF-8F52-0040333594A3>"
117 "Boolean u;"
118 "Boolean v;"
119 "}"
120 "template MaterialWrap"
121 "{"
122 "<4885AE60-78E8-11CF-8F52-0040333594A3>"
123 "Boolean u;"
124 "Boolean v;"
125 "}"
126 "template TextureFilename"
127 "{"
128 "<A42790E1-7810-11CF-8F52-0040333594A3>"
129 "STRING filename;"
130 "}"
131 "template Material"
132 "{"
133 "<3D82AB4D-62DA-11CF-AB39-0020AF71E433>"
134 "ColorRGBA faceColor;"
135 "FLOAT power;"
136 "ColorRGB specularColor;"
137 "ColorRGB emissiveColor;"
138 "[...]"
139 "}"
140 "template MeshFace"
141 "{"
142 "<3D82AB5F-62DA-11CF-AB39-0020AF71E433>"
143 "DWORD nFaceVertexIndices;"
144 "array DWORD faceVertexIndices[nFaceVertexIndices];"
145 "}"
146 "template MeshFaceWraps"
147 "{"
148 "<ED1EC5C0-C0A8-11D0-941C-0080C80CFA7B>"
149 "DWORD nFaceWrapValues;"
150 "array Boolean2d faceWrapValues[nFaceWrapValues];"
151 "}"
152 "template MeshTextureCoords"
153 "{"
154 "<F6F23F40-7686-11CF-8F52-0040333594A3>"
155 "DWORD nTextureCoords;"
156 "array Coords2d textureCoords[nTextureCoords];"
157 "}"
158 "template MeshMaterialList"
159 "{"
160 "<F6F23F42-7686-11CF-8F52-0040333594A3>"
161 "DWORD nMaterials;"
162 "DWORD nFaceIndexes;"
163 "array DWORD faceIndexes[nFaceIndexes];"
164 "[Material]"
165 "}"
166 "template MeshNormals"
167 "{"
168 "<F6F23F43-7686-11CF-8F52-0040333594A3>"
169 "DWORD nNormals;"
170 "array Vector normals[nNormals];"
171 "DWORD nFaceNormals;"
172 "array MeshFace faceNormals[nFaceNormals];"
173 "}"
174 "template MeshVertexColors"
175 "{"
176 "<1630B821-7842-11CF-8F52-0040333594A3>"
177 "DWORD nVertexColors;"
178 "array IndexedColor vertexColors[nVertexColors];"
179 "}"
180 "template Mesh"
181 "{"
182 "<3D82AB44-62DA-11CF-AB39-0020AF71E433>"
183 "DWORD nVertices;"
184 "array Vector vertices[nVertices];"
185 "DWORD nFaces;"
186 "array MeshFace faces[nFaces];"
187 "[...]"
188 "}"
189 "template FrameTransformMatrix"
190 "{"
191 "<F6F23F41-7686-11CF-8F52-0040333594A3>"
192 "Matrix4x4 frameMatrix;"
193 "}"
194 "template Frame"
195 "{"
196 "<3D82AB46-62DA-11CF-AB39-0020AF71E433>"
197 "[...]"
198 "}"
199 "template FloatKeys"
200 "{"
201 "<10DD46A9-775B-11CF-8F52-0040333594A3>"
202 "DWORD nValues;"
203 "array FLOAT values[nValues];"
204 "}"
205 "template TimedFloatKeys"
206 "{"
207 "<F406B180-7B3B-11CF-8F52-0040333594A3>"
208 "DWORD time;"
209 "FloatKeys tfkeys;"
210 "}"
211 "template AnimationKey"
212 "{"
213 "<10DD46A8-775B-11CF-8F52-0040333594A3>"
214 "DWORD keyType;"
215 "DWORD nKeys;"
216 "array TimedFloatKeys keys[nKeys];"
217 "}"
218 "template AnimationOptions"
219 "{"
220 "<E2BF56C0-840F-11CF-8F52-0040333594A3>"
221 "DWORD openclosed;"
222 "DWORD positionquality;"
223 "}"
224 "template Animation"
225 "{"
226 "<3D82AB4F-62DA-11CF-AB39-0020AF71E433>"
227 "[...]"
228 "}"
229 "template AnimationSet"
230 "{"
231 "<3D82AB50-62DA-11CF-AB39-0020AF71E433>"
232 "[Animation]"
233 "}"
234 "template InlineData"
235 "{"
236 "<3A23EEA0-94B1-11D0-AB39-0020AF71E433>"
237 "[BINARY]"
238 "}"
239 "template Url"
240 "{"
241 "<3A23EEA1-94B1-11D0-AB39-0020AF71E433>"
242 "DWORD nUrls;"
243 "array STRING urls[nUrls];"
244 "}"
245 "template ProgressiveMesh"
246 "{"
247 "<8A63C360-997D-11D0-941C-0080C80CFA7B>"
248 "[Url,InlineData]"
249 "}"
250 "template Guid"
251 "{"
252 "<A42790E0-7810-11CF-8F52-0040333594A3>"
253 "DWORD data1;"
254 "WORD data2;"
255 "WORD data3;"
256 "array UCHAR data4[8];"
257 "}"
258 "template StringProperty"
259 "{"
260 "<7F0F21E0-BFE1-11D1-82C0-00A0C9697271>"
261 "STRING key;"
262 "STRING value;"
263 "}"
264 "template PropertyBag"
265 "{"
266 "<7F0F21E1-BFE1-11D1-82C0-00A0C9697271>"
267 "[StringProperty]"
268 "}"
269 "template ExternalVisual"
270 "{"
271 "<98116AA0-BDBA-11D1-82C0-00A0C9697271>"
272 "Guid guidExternalVisual;"
273 "[...]"
274 "}"
275 "template RightHanded"
276 "{"
277 "<7F5D5EA0-D53A-11D1-82C0-00A0C9697271>"
278 "DWORD bRightHanded;"
279 "}"
280 };
281
282 static inline IDirect3DRMMeshBuilderImpl *impl_from_IDirect3DRMMeshBuilder2(IDirect3DRMMeshBuilder2 *iface)
283 {
284     return CONTAINING_RECORD(iface, IDirect3DRMMeshBuilderImpl, IDirect3DRMMeshBuilder2_iface);
285 }
286
287 static inline IDirect3DRMMeshBuilderImpl *impl_from_IDirect3DRMMeshBuilder3(IDirect3DRMMeshBuilder3 *iface)
288 {
289     return CONTAINING_RECORD(iface, IDirect3DRMMeshBuilderImpl, IDirect3DRMMeshBuilder3_iface);
290 }
291
292 /*** IUnknown methods ***/
293 static HRESULT WINAPI IDirect3DRMMeshBuilder2Impl_QueryInterface(IDirect3DRMMeshBuilder2* iface,
294                                                                  REFIID riid, void** ppvObject)
295 {
296     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
297
298     TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid), ppvObject);
299
300     *ppvObject = NULL;
301
302     if(IsEqualGUID(riid, &IID_IUnknown) ||
303        IsEqualGUID(riid, &IID_IDirect3DRMMeshBuilder) ||
304        IsEqualGUID(riid, &IID_IDirect3DRMMeshBuilder2))
305     {
306         *ppvObject = &This->IDirect3DRMMeshBuilder2_iface;
307     }
308     else if(IsEqualGUID(riid, &IID_IDirect3DRMMeshBuilder3))
309     {
310         *ppvObject = &This->IDirect3DRMMeshBuilder3_iface;
311     }
312     else
313     {
314         FIXME("interface %s not implemented\n", debugstr_guid(riid));
315         return E_NOINTERFACE;
316     }
317
318     IDirect3DRMMeshBuilder_AddRef(iface);
319     return S_OK;
320 }
321
322 static ULONG WINAPI IDirect3DRMMeshBuilder2Impl_AddRef(IDirect3DRMMeshBuilder2* iface)
323 {
324     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
325
326     TRACE("(%p)\n", This);
327
328     return InterlockedIncrement(&This->ref);
329 }
330
331 static ULONG WINAPI IDirect3DRMMeshBuilder2Impl_Release(IDirect3DRMMeshBuilder2* iface)
332 {
333     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
334     ULONG ref = InterlockedDecrement(&This->ref);
335
336     TRACE("(%p)\n", This);
337
338     if (!ref)
339     {
340         HeapFree(GetProcessHeap(), 0, This->pVertices);
341         HeapFree(GetProcessHeap(), 0, This->pNormals);
342         HeapFree(GetProcessHeap(), 0, This->pFaceData);
343         HeapFree(GetProcessHeap(), 0, This->pCoords2d);
344         HeapFree(GetProcessHeap(), 0, This);
345     }
346
347     return ref;
348 }
349
350 /*** IDirect3DRMObject methods ***/
351 static HRESULT WINAPI IDirect3DRMMeshBuilder2Impl_Clone(IDirect3DRMMeshBuilder2* iface,
352                                                         LPUNKNOWN pUnkOuter, REFIID riid,
353                                                         LPVOID *ppvObj)
354 {
355     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
356
357     FIXME("(%p)->(%p,%s,%p): stub\n", This, pUnkOuter, debugstr_guid(riid), ppvObj);
358
359     return E_NOTIMPL;
360 }
361
362 static HRESULT WINAPI IDirect3DRMMeshBuilder2Impl_AddDestroyCallback(IDirect3DRMMeshBuilder2* iface,
363                                                                      D3DRMOBJECTCALLBACK cb,
364                                                                      LPVOID argument)
365 {
366     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
367
368     FIXME("(%p)->(%p,%p): stub\n", This, cb, argument);
369
370     return E_NOTIMPL;
371 }
372
373 static HRESULT WINAPI IDirect3DRMMeshBuilder2Impl_DeleteDestroyCallback(IDirect3DRMMeshBuilder2* iface,
374                                                                         D3DRMOBJECTCALLBACK cb,
375                                                                         LPVOID argument)
376 {
377     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
378
379     FIXME("(%p)->(%p,%p): stub\n", This, cb, argument);
380
381     return E_NOTIMPL;
382 }
383
384 static HRESULT WINAPI IDirect3DRMMeshBuilder2Impl_SetAppData(IDirect3DRMMeshBuilder2* iface,
385                                                              DWORD data)
386 {
387     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
388
389     FIXME("(%p)->(%u): stub\n", This, data);
390
391     return E_NOTIMPL;
392 }
393
394 static DWORD WINAPI IDirect3DRMMeshBuilder2Impl_GetAppData(IDirect3DRMMeshBuilder2* iface)
395 {
396     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
397
398     FIXME("(%p)->(): stub\n", This);
399
400     return 0;
401 }
402
403 static HRESULT WINAPI IDirect3DRMMeshBuilder2Impl_SetName(IDirect3DRMMeshBuilder2* iface,
404                                                           LPCSTR pName)
405 {
406     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
407
408     FIXME("(%p)->(%s): stub\n", This, pName);
409
410     return E_NOTIMPL;
411 }
412
413 static HRESULT WINAPI IDirect3DRMMeshBuilder2Impl_GetName(IDirect3DRMMeshBuilder2* iface,
414                                                           LPDWORD lpdwSize, LPSTR lpName)
415 {
416     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
417
418     FIXME("(%p)->(%p,%p): stub\n", This, lpdwSize, lpName);
419
420     return E_NOTIMPL;
421 }
422
423 static HRESULT WINAPI IDirect3DRMMeshBuilder2Impl_GetClassName(IDirect3DRMMeshBuilder2* iface,
424                                                                LPDWORD lpdwSize, LPSTR lpName)
425 {
426     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
427
428     FIXME("(%p)->(%p,%p): stub\n", This, lpdwSize, lpName);
429
430     return E_NOTIMPL;
431 }
432
433 /*** IDirect3DRMMeshBuilder2 methods ***/
434 static HRESULT WINAPI IDirect3DRMMeshBuilder2Impl_Load(IDirect3DRMMeshBuilder2* iface,
435                                                        LPVOID filename, LPVOID name,
436                                                        D3DRMLOADOPTIONS loadflags,
437                                                        D3DRMLOADTEXTURECALLBACK cb, LPVOID arg)
438 {
439     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
440
441     TRACE("(%p)->(%p,%p,%x,%p,%p): partial stub\n", This, filename, name, loadflags, cb, arg);
442
443     return IDirect3DRMMeshBuilder3_Load(&This->IDirect3DRMMeshBuilder3_iface, filename, name,
444                                         loadflags, (D3DRMLOADTEXTURE3CALLBACK)cb, arg);
445 }
446
447 static HRESULT WINAPI IDirect3DRMMeshBuilder2Impl_Save(IDirect3DRMMeshBuilder2* iface,
448                                                        const char *filename, D3DRMXOFFORMAT format,
449                                                        D3DRMSAVEOPTIONS save)
450 {
451     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
452
453     FIXME("(%p)->(%s,%d,%d): stub\n", This, filename, format, save);
454
455     return E_NOTIMPL;
456 }
457
458 static HRESULT WINAPI IDirect3DRMMeshBuilder2Impl_Scale(IDirect3DRMMeshBuilder2* iface,
459                                                         D3DVALUE sx, D3DVALUE sy, D3DVALUE sz)
460 {
461     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
462
463     FIXME("(%p)->(%f,%f,%f): stub\n", This, sx, sy, sz);
464
465     return E_NOTIMPL;
466 }
467
468 static HRESULT WINAPI IDirect3DRMMeshBuilder2Impl_Translate(IDirect3DRMMeshBuilder2* iface,
469                                                             D3DVALUE tx, D3DVALUE ty, D3DVALUE tz)
470 {
471     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
472
473     FIXME("(%p)->(%f,%f,%f): stub\n", This, tx, ty, tz);
474
475     return E_NOTIMPL;
476 }
477
478 static HRESULT WINAPI IDirect3DRMMeshBuilder2Impl_SetColorSource(IDirect3DRMMeshBuilder2* iface,
479                                                                  D3DRMCOLORSOURCE color)
480 {
481     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
482
483     FIXME("(%p)->(%x): stub\n", This, color);
484
485     return E_NOTIMPL;
486 }
487
488 static HRESULT WINAPI IDirect3DRMMeshBuilder2Impl_GetBox(IDirect3DRMMeshBuilder2* iface,
489                                                          D3DRMBOX *pBox)
490 {
491     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
492
493     FIXME("(%p)->(%p): stub\n", This, pBox);
494
495     return E_NOTIMPL;
496 }
497
498 static HRESULT WINAPI IDirect3DRMMeshBuilder2Impl_GenerateNormals(IDirect3DRMMeshBuilder2* iface)
499 {
500     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
501
502     FIXME("(%p)->(): stub\n", This);
503
504     return E_NOTIMPL;
505 }
506
507 static D3DRMCOLORSOURCE WINAPI IDirect3DRMMeshBuilder2Impl_GetColorSource(IDirect3DRMMeshBuilder2* iface)
508 {
509     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
510
511     FIXME("(%p)->(): stub\n", This);
512
513     return E_NOTIMPL;
514 }
515
516 static HRESULT WINAPI IDirect3DRMMeshBuilder2Impl_AddMesh(IDirect3DRMMeshBuilder2* iface,
517                                                           LPDIRECT3DRMMESH pMesh)
518 {
519     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
520
521     FIXME("(%p)->(%p): stub\n", This, pMesh);
522
523     return E_NOTIMPL;
524 }
525
526 static HRESULT WINAPI IDirect3DRMMeshBuilder2Impl_AddMeshBuilder(IDirect3DRMMeshBuilder2* iface,
527                                                                  LPDIRECT3DRMMESHBUILDER pMeshBuilder)
528 {
529     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
530
531     FIXME("(%p)->(%p): stub\n", This, pMeshBuilder);
532
533     return E_NOTIMPL;
534 }
535
536 static HRESULT WINAPI IDirect3DRMMeshBuilder2Impl_AddFrame(IDirect3DRMMeshBuilder2* iface,
537                                                            LPDIRECT3DRMFRAME pFrame)
538 {
539     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
540
541     FIXME("(%p)->(%p): stub\n", This, pFrame);
542
543     return E_NOTIMPL;
544 }
545
546 static HRESULT WINAPI IDirect3DRMMeshBuilder2Impl_AddFace(IDirect3DRMMeshBuilder2* iface,
547                                                           LPDIRECT3DRMFACE pFace)
548 {
549     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
550
551     FIXME("(%p)->(%p): stub\n", This, pFace);
552
553     return E_NOTIMPL;
554 }
555
556 static HRESULT WINAPI IDirect3DRMMeshBuilder2Impl_AddFaces(IDirect3DRMMeshBuilder2* iface,
557                                                            DWORD vcount, D3DVECTOR *vertices,
558                                                            DWORD ncount, D3DVECTOR *normals,
559                                                            DWORD *data,
560                                                            LPDIRECT3DRMFACEARRAY* pFaceArray)
561 {
562     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
563
564     FIXME("(%p)->(%d,%p,%d,%p,%p,%p): stub\n", This, vcount, vertices, ncount, normals, data, pFaceArray);
565
566     return E_NOTIMPL;
567 }
568
569 static HRESULT WINAPI IDirect3DRMMeshBuilder2Impl_ReserveSpace(IDirect3DRMMeshBuilder2* iface,
570                                                                DWORD vertex_Count,
571                                                                DWORD normal_count,
572                                                                DWORD face_count)
573 {
574     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
575
576     FIXME("(%p)->(%d,%d,%d): stub\n", This, vertex_Count, normal_count, face_count);
577
578     return E_NOTIMPL;
579 }
580
581 static HRESULT WINAPI IDirect3DRMMeshBuilder2Impl_SetColorRGB(IDirect3DRMMeshBuilder2* iface,
582                                                               D3DVALUE red, D3DVALUE green,
583                                                               D3DVALUE blue)
584 {
585     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
586
587     FIXME("(%p)->(%f,%f,%f): stub\n", This, red, green, blue);
588
589     return E_NOTIMPL;
590 }
591
592 static HRESULT WINAPI IDirect3DRMMeshBuilder2Impl_SetColor(IDirect3DRMMeshBuilder2* iface,
593                                                            D3DCOLOR color)
594 {
595     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
596
597     FIXME("(%p)->(%x): stub\n", This, color);
598
599     return E_NOTIMPL;
600 }
601
602 static HRESULT WINAPI IDirect3DRMMeshBuilder2Impl_SetTexture(IDirect3DRMMeshBuilder2* iface,
603                                                              LPDIRECT3DRMTEXTURE pTexture)
604 {
605     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
606
607     FIXME("(%p)->(%p): stub\n", This, pTexture);
608
609     return E_NOTIMPL;
610 }
611
612 static HRESULT WINAPI IDirect3DRMMeshBuilder2Impl_SetMaterial(IDirect3DRMMeshBuilder2* iface,
613                                                               LPDIRECT3DRMMATERIAL pMaterial)
614 {
615     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
616
617     FIXME("(%p)->(%p): stub\n", This, pMaterial);
618
619     return E_NOTIMPL;
620 }
621
622 static HRESULT WINAPI IDirect3DRMMeshBuilder2Impl_SetTextureTopology(IDirect3DRMMeshBuilder2* iface,
623                                                                      BOOL wrap_u, BOOL wrap_v)
624 {
625     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
626
627     FIXME("(%p)->(%d,%d): stub\n", This, wrap_u, wrap_v);
628
629     return E_NOTIMPL;
630 }
631
632 static HRESULT WINAPI IDirect3DRMMeshBuilder2Impl_SetQuality(IDirect3DRMMeshBuilder2* iface,
633                                                              D3DRMRENDERQUALITY quality)
634 {
635     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
636
637     FIXME("(%p)->(%d): stub\n", This, quality);
638
639     return E_NOTIMPL;
640 }
641
642 static HRESULT WINAPI IDirect3DRMMeshBuilder2Impl_SetPerspective(IDirect3DRMMeshBuilder2* iface,
643                                                                  BOOL enable)
644 {
645     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
646
647     FIXME("(%p)->(%d): stub\n", This, enable);
648
649     return E_NOTIMPL;
650 }
651
652 static HRESULT WINAPI IDirect3DRMMeshBuilder2Impl_SetVertex(IDirect3DRMMeshBuilder2* iface,
653                                                             DWORD index,
654                                                             D3DVALUE x, D3DVALUE y, D3DVALUE z)
655 {
656     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
657
658     FIXME("(%p)->(%f,%f,%f): stub\n", This, x, y, z);
659
660     return E_NOTIMPL;
661 }
662
663 static HRESULT WINAPI IDirect3DRMMeshBuilder2Impl_SetNormal(IDirect3DRMMeshBuilder2* iface,
664                                                             DWORD index,
665                                                             D3DVALUE x, D3DVALUE y, D3DVALUE z)
666 {
667     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
668
669     FIXME("(%p)->(%f,%f,%f): stub\n", This, x, y, z);
670
671     return E_NOTIMPL;
672 }
673
674 static HRESULT WINAPI IDirect3DRMMeshBuilder2Impl_SetTextureCoordinates(IDirect3DRMMeshBuilder2* iface,
675                                                                         DWORD index,
676                                                                         D3DVALUE u, D3DVALUE v)
677 {
678     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
679
680     FIXME("(%p)->(%f,%f): stub\n", This, u, v);
681
682     return E_NOTIMPL;
683 }
684
685 static HRESULT WINAPI IDirect3DRMMeshBuilder2Impl_SetVertexColor(IDirect3DRMMeshBuilder2* iface,
686                                                                  DWORD index, D3DCOLOR color)
687 {
688     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
689
690     FIXME("(%p)->(%d,%x): stub\n", This, index, color);
691
692     return E_NOTIMPL;
693 }
694
695 static HRESULT WINAPI IDirect3DRMMeshBuilder2Impl_SetVertexColorRGB(IDirect3DRMMeshBuilder2* iface,
696                                                                     DWORD index, D3DVALUE red,
697                                                                     D3DVALUE green, D3DVALUE blue)
698 {
699     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
700
701     FIXME("(%p)->(%d,%f,%f,%f): stub\n", This, index, red, green, blue);
702
703     return E_NOTIMPL;
704 }
705
706 static HRESULT WINAPI IDirect3DRMMeshBuilder2Impl_GetFaces(IDirect3DRMMeshBuilder2* iface,
707                                                            LPDIRECT3DRMFACEARRAY* pFaceArray)
708 {
709     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
710
711     FIXME("(%p)->(%p): stub\n", This, pFaceArray);
712
713     return E_NOTIMPL;
714 }
715
716 static HRESULT WINAPI IDirect3DRMMeshBuilder2Impl_GetVertices(IDirect3DRMMeshBuilder2* iface,
717                                                               DWORD *vcount, D3DVECTOR *vertices,
718                                                               DWORD *ncount, D3DVECTOR *normals,
719                                                               DWORD *face_data_size,
720                                                               DWORD *face_data)
721 {
722     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
723
724     TRACE("(%p)->(%p,%p,%p,%p,%p,%p)\n", This, vcount, vertices, ncount, normals, face_data_size, face_data);
725
726     if (vcount)
727         *vcount = This->nb_vertices;
728     if (vertices && This->nb_vertices)
729         memcpy(vertices, This->pVertices, This->nb_vertices * sizeof(D3DVECTOR));
730     if (ncount)
731         *ncount = This->nb_normals;
732     if (normals && This->nb_normals)
733         memcpy(normals, This->pNormals, This->nb_normals * sizeof(D3DVECTOR));
734     if (face_data_size)
735         *face_data_size = This->face_data_size;
736     if (face_data && This->face_data_size)
737         memcpy(face_data, This->pFaceData, This->face_data_size);
738
739     return D3DRM_OK;
740 }
741
742 static HRESULT WINAPI IDirect3DRMMeshBuilder2Impl_GetTextureCoordinates(IDirect3DRMMeshBuilder2* iface,
743                                                                         DWORD index,
744                                                                         D3DVALUE *u, D3DVALUE *v)
745 {
746     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
747
748     TRACE("(%p)->(%d,%p,%p)\n", This, index, u, v);
749
750     return IDirect3DRMMeshBuilder3_GetTextureCoordinates(&This->IDirect3DRMMeshBuilder3_iface,
751                                                          index, u, v);
752 }
753
754 static int WINAPI IDirect3DRMMeshBuilder2Impl_AddVertex(IDirect3DRMMeshBuilder2* iface,
755                                                         D3DVALUE x, D3DVALUE y, D3DVALUE z)
756 {
757     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
758
759     FIXME("(%p)->(%f,%f,%f): stub\n", This, x, y, z);
760
761     return 0;
762 }
763
764 static int WINAPI IDirect3DRMMeshBuilder2Impl_AddNormal(IDirect3DRMMeshBuilder2* iface,
765                                                         D3DVALUE x, D3DVALUE y, D3DVALUE z)
766 {
767     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
768
769     FIXME("(%p)->(%f,%f,%f): stub\n", This, x, y, z);
770
771     return 0;
772 }
773
774 static HRESULT WINAPI IDirect3DRMMeshBuilder2Impl_CreateFace(IDirect3DRMMeshBuilder2* iface,
775                                                              LPDIRECT3DRMFACE* ppFace)
776 {
777     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
778
779     FIXME("(%p)->(%p): stub\n", This, ppFace);
780
781     return E_NOTIMPL;
782 }
783
784 static D3DRMRENDERQUALITY WINAPI IDirect3DRMMeshBuilder2Impl_GetQuality(IDirect3DRMMeshBuilder2* iface)
785 {
786     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
787
788     FIXME("(%p)->(): stub\n", This);
789
790     return 0;
791 }
792
793 static BOOL WINAPI IDirect3DRMMeshBuilder2Impl_GetPerspective(IDirect3DRMMeshBuilder2* iface)
794 {
795     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
796
797     FIXME("(%p)->(): stub\n", This);
798
799     return FALSE;
800 }
801
802 static int WINAPI IDirect3DRMMeshBuilder2Impl_GetFaceCount(IDirect3DRMMeshBuilder2* iface)
803 {
804     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
805
806     TRACE("(%p)->()\n", This);
807
808     return This->nb_faces;
809 }
810
811 static int WINAPI IDirect3DRMMeshBuilder2Impl_GetVertexCount(IDirect3DRMMeshBuilder2* iface)
812 {
813     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
814
815     TRACE("(%p)->()\n", This);
816
817     return This->nb_vertices;
818 }
819
820 static D3DCOLOR WINAPI IDirect3DRMMeshBuilder2Impl_GetVertexColor(IDirect3DRMMeshBuilder2* iface,
821                                                                   DWORD index)
822 {
823     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
824
825     FIXME("(%p)->(%d): stub\n", This, index);
826
827     return 0;
828 }
829
830 static HRESULT WINAPI IDirect3DRMMeshBuilder2Impl_CreateMesh(IDirect3DRMMeshBuilder2* iface,
831                                                              LPDIRECT3DRMMESH* ppMesh)
832 {
833     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
834
835     FIXME("(%p)->(%p): stub\n", This, ppMesh);
836
837     return E_NOTIMPL;
838 }
839
840 static HRESULT WINAPI IDirect3DRMMeshBuilder2Impl_GenerateNormals2(IDirect3DRMMeshBuilder2* iface,
841                                                                    D3DVALUE crease, DWORD dwFlags)
842 {
843     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
844
845     FIXME("(%p)->(%f,%u): stub\n", This, crease, dwFlags);
846
847     return E_NOTIMPL;
848 }
849
850 static HRESULT WINAPI IDirect3DRMMeshBuilder2Impl_GetFace(IDirect3DRMMeshBuilder2* iface,
851                                                           DWORD index, LPDIRECT3DRMFACE* ppFace)
852 {
853     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder2(iface);
854
855     FIXME("(%p)->(%u,%p): stub\n", This, index, ppFace);
856
857     return E_NOTIMPL;
858 }
859
860 static const struct IDirect3DRMMeshBuilder2Vtbl Direct3DRMMeshBuilder2_Vtbl =
861 {
862     /*** IUnknown methods ***/
863     IDirect3DRMMeshBuilder2Impl_QueryInterface,
864     IDirect3DRMMeshBuilder2Impl_AddRef,
865     IDirect3DRMMeshBuilder2Impl_Release,
866     /*** IDirect3DRMObject methods ***/
867     IDirect3DRMMeshBuilder2Impl_Clone,
868     IDirect3DRMMeshBuilder2Impl_AddDestroyCallback,
869     IDirect3DRMMeshBuilder2Impl_DeleteDestroyCallback,
870     IDirect3DRMMeshBuilder2Impl_SetAppData,
871     IDirect3DRMMeshBuilder2Impl_GetAppData,
872     IDirect3DRMMeshBuilder2Impl_SetName,
873     IDirect3DRMMeshBuilder2Impl_GetName,
874     IDirect3DRMMeshBuilder2Impl_GetClassName,
875     /*** IDirect3DRMMeshBuilder methods ***/
876     IDirect3DRMMeshBuilder2Impl_Load,
877     IDirect3DRMMeshBuilder2Impl_Save,
878     IDirect3DRMMeshBuilder2Impl_Scale,
879     IDirect3DRMMeshBuilder2Impl_Translate,
880     IDirect3DRMMeshBuilder2Impl_SetColorSource,
881     IDirect3DRMMeshBuilder2Impl_GetBox,
882     IDirect3DRMMeshBuilder2Impl_GenerateNormals,
883     IDirect3DRMMeshBuilder2Impl_GetColorSource,
884     IDirect3DRMMeshBuilder2Impl_AddMesh,
885     IDirect3DRMMeshBuilder2Impl_AddMeshBuilder,
886     IDirect3DRMMeshBuilder2Impl_AddFrame,
887     IDirect3DRMMeshBuilder2Impl_AddFace,
888     IDirect3DRMMeshBuilder2Impl_AddFaces,
889     IDirect3DRMMeshBuilder2Impl_ReserveSpace,
890     IDirect3DRMMeshBuilder2Impl_SetColorRGB,
891     IDirect3DRMMeshBuilder2Impl_SetColor,
892     IDirect3DRMMeshBuilder2Impl_SetTexture,
893     IDirect3DRMMeshBuilder2Impl_SetMaterial,
894     IDirect3DRMMeshBuilder2Impl_SetTextureTopology,
895     IDirect3DRMMeshBuilder2Impl_SetQuality,
896     IDirect3DRMMeshBuilder2Impl_SetPerspective,
897     IDirect3DRMMeshBuilder2Impl_SetVertex,
898     IDirect3DRMMeshBuilder2Impl_SetNormal,
899     IDirect3DRMMeshBuilder2Impl_SetTextureCoordinates,
900     IDirect3DRMMeshBuilder2Impl_SetVertexColor,
901     IDirect3DRMMeshBuilder2Impl_SetVertexColorRGB,
902     IDirect3DRMMeshBuilder2Impl_GetFaces,
903     IDirect3DRMMeshBuilder2Impl_GetVertices,
904     IDirect3DRMMeshBuilder2Impl_GetTextureCoordinates,
905     IDirect3DRMMeshBuilder2Impl_AddVertex,
906     IDirect3DRMMeshBuilder2Impl_AddNormal,
907     IDirect3DRMMeshBuilder2Impl_CreateFace,
908     IDirect3DRMMeshBuilder2Impl_GetQuality,
909     IDirect3DRMMeshBuilder2Impl_GetPerspective,
910     IDirect3DRMMeshBuilder2Impl_GetFaceCount,
911     IDirect3DRMMeshBuilder2Impl_GetVertexCount,
912     IDirect3DRMMeshBuilder2Impl_GetVertexColor,
913     IDirect3DRMMeshBuilder2Impl_CreateMesh,
914     /*** IDirect3DRMMeshBuilder2 methods ***/
915     IDirect3DRMMeshBuilder2Impl_GenerateNormals2,
916     IDirect3DRMMeshBuilder2Impl_GetFace
917 };
918
919
920 /*** IUnknown methods ***/
921 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_QueryInterface(IDirect3DRMMeshBuilder3* iface,
922                                                                  REFIID riid, void** ppvObject)
923 {
924     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
925     return IDirect3DRMMeshBuilder2_QueryInterface(&This->IDirect3DRMMeshBuilder2_iface, riid, ppvObject);
926 }
927
928 static ULONG WINAPI IDirect3DRMMeshBuilder3Impl_AddRef(IDirect3DRMMeshBuilder3* iface)
929 {
930     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
931     return IDirect3DRMMeshBuilder2_AddRef(&This->IDirect3DRMMeshBuilder2_iface);
932 }
933
934 static ULONG WINAPI IDirect3DRMMeshBuilder3Impl_Release(IDirect3DRMMeshBuilder3* iface)
935 {
936     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
937     return IDirect3DRMMeshBuilder2_Release(&This->IDirect3DRMMeshBuilder2_iface);
938 }
939
940 /*** IDirect3DRMObject methods ***/
941 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_Clone(IDirect3DRMMeshBuilder3* iface,
942                                                         LPUNKNOWN pUnkOuter, REFIID riid,
943                                                         LPVOID *ppvObj)
944 {
945     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
946
947     FIXME("(%p)->(%p,%s,%p): stub\n", This, pUnkOuter, debugstr_guid(riid), ppvObj);
948
949     return E_NOTIMPL;
950 }
951
952 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_AddDestroyCallback(IDirect3DRMMeshBuilder3* iface,
953                                                                      D3DRMOBJECTCALLBACK cb,
954                                                                      LPVOID argument)
955 {
956     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
957
958     FIXME("(%p)->(%p,%p): stub\n", This, cb, argument);
959
960     return E_NOTIMPL;
961 }
962
963 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_DeleteDestroyCallback(IDirect3DRMMeshBuilder3* iface,
964                                                                         D3DRMOBJECTCALLBACK cb,
965                                                                         LPVOID argument)
966 {
967     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
968
969     FIXME("(%p)->(%p,%p): stub\n", This, cb, argument);
970
971     return E_NOTIMPL;
972 }
973
974 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_SetAppData(IDirect3DRMMeshBuilder3* iface,
975                                                              DWORD data)
976 {
977     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
978
979     FIXME("(%p)->(%u): stub\n", This, data);
980
981     return E_NOTIMPL;
982 }
983
984 static DWORD WINAPI IDirect3DRMMeshBuilder3Impl_GetAppData(IDirect3DRMMeshBuilder3* iface)
985 {
986     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
987
988     FIXME("(%p)->(): stub\n", This);
989
990     return 0;
991 }
992
993 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_SetName(IDirect3DRMMeshBuilder3* iface,
994                                                           LPCSTR pName)
995 {
996     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
997
998     FIXME("(%p)->(%s): stub\n", This, pName);
999
1000     return E_NOTIMPL;
1001 }
1002
1003 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_GetName(IDirect3DRMMeshBuilder3* iface,
1004                                                           LPDWORD lpdwSize, LPSTR lpName)
1005 {
1006     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1007
1008     FIXME("(%p)->(%p,%p): stub\n", This, lpdwSize, lpName);
1009
1010     return E_NOTIMPL;
1011 }
1012
1013 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_GetClassName(IDirect3DRMMeshBuilder3* iface,
1014                                                                LPDWORD lpdwSize, LPSTR lpName)
1015 {
1016     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1017
1018     FIXME("(%p)->(%p,%p): stub\n", This, lpdwSize, lpName);
1019
1020     return E_NOTIMPL;
1021 }
1022
1023 /*** IDirect3DRMMeshBuilder3 methods ***/
1024 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_Load(IDirect3DRMMeshBuilder3* iface,
1025                                                        LPVOID filename, LPVOID name,
1026                                                        D3DRMLOADOPTIONS loadflags,
1027                                                        D3DRMLOADTEXTURE3CALLBACK cb, LPVOID arg)
1028 {
1029     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1030     DXFILELOADOPTIONS load_options;
1031     LPDIRECTXFILE pDXFile = NULL;
1032     LPDIRECTXFILEENUMOBJECT pEnumObject = NULL;
1033     LPDIRECTXFILEDATA pData = NULL;
1034     LPDIRECTXFILEOBJECT pObject = NULL;
1035     LPDIRECTXFILEDATA pData2 = NULL;
1036     const GUID* pGuid;
1037     DWORD size;
1038     Header* pHeader;
1039     LPBYTE ptr;
1040     HRESULT hr;
1041     HRESULT ret = D3DRMERR_BADOBJECT;
1042
1043     FIXME("(%p)->(%p,%p,%x,%p,%p): partial stub\n", This, filename, name, loadflags, cb, arg);
1044
1045     /* First free allocated buffers of previous mesh data */
1046     HeapFree(GetProcessHeap(), 0, This->pVertices);
1047     This->pVertices = NULL;
1048     HeapFree(GetProcessHeap(), 0, This->pNormals);
1049     This->pNormals = NULL;
1050     HeapFree(GetProcessHeap(), 0, This->pFaceData);
1051     This->pFaceData = NULL;
1052     HeapFree(GetProcessHeap(), 0, This->pCoords2d);
1053     This->pCoords2d = NULL;
1054
1055     if (loadflags == D3DRMLOAD_FROMMEMORY)
1056     {
1057         load_options = DXFILELOAD_FROMMEMORY;
1058     }
1059     else
1060     {
1061         FIXME("Load options %d not supported yet\n", loadflags);
1062         return E_NOTIMPL;
1063     }
1064
1065     hr = DirectXFileCreate(&pDXFile);
1066     if (hr != DXFILE_OK)
1067         goto end;
1068
1069     hr = IDirectXFile_RegisterTemplates(pDXFile, templates, strlen(templates));
1070     if (hr != DXFILE_OK)
1071         goto end;
1072
1073     hr = IDirectXFile_CreateEnumObject(pDXFile, filename, load_options, &pEnumObject);
1074     if (hr != DXFILE_OK)
1075         goto end;
1076
1077     hr = IDirectXFileEnumObject_GetNextDataObject(pEnumObject, &pData);
1078     if (hr != DXFILE_OK)
1079         goto end;
1080
1081     hr = IDirectXFileData_GetType(pData, &pGuid);
1082     if (hr != DXFILE_OK)
1083         goto end;
1084
1085     TRACE("Found object type whose GUID = %s\n", debugstr_guid(pGuid));
1086
1087     if (!IsEqualGUID(pGuid, &TID_DXFILEHeader))
1088     {
1089         ret = D3DRMERR_BADFILE;
1090         goto end;
1091     }
1092
1093     hr = IDirectXFileData_GetData(pData, NULL, &size, (void**)&pHeader);
1094     if ((hr != DXFILE_OK) || (size != sizeof(Header)))
1095         goto end;
1096
1097     TRACE("Version is %d %d %d\n", pHeader->major, pHeader->minor, pHeader->flags);
1098
1099     /* Version must be 1.0.x */
1100     if ((pHeader->major != 1) || (pHeader->minor != 0))
1101     {
1102         ret = D3DRMERR_BADFILE;
1103         goto end;
1104     }
1105
1106     IDirectXFileData_Release(pData);
1107     pData = NULL;
1108
1109     hr = IDirectXFileEnumObject_GetNextDataObject(pEnumObject, &pData);
1110     if (hr != DXFILE_OK)
1111     {
1112         ret = D3DRMERR_NOTFOUND;
1113         goto end;
1114     }
1115
1116     hr = IDirectXFileData_GetType(pData, &pGuid);
1117     if (hr != DXFILE_OK)
1118         goto end;
1119
1120     TRACE("Found object type whose GUID = %s\n", debugstr_guid(pGuid));
1121
1122     if (!IsEqualGUID(pGuid, &TID_D3DRMMesh))
1123     {
1124         ret = D3DRMERR_NOTFOUND;
1125         goto end;
1126     }
1127
1128     hr = IDirectXFileData_GetData(pData, NULL, &size, (void**)&ptr);
1129     if (hr != DXFILE_OK)
1130         goto end;
1131
1132     This->nb_vertices = *(DWORD*)ptr;
1133     This->nb_faces = *(DWORD*)(ptr + sizeof(DWORD) + This->nb_vertices * sizeof(D3DVECTOR));
1134     This->face_data_size = size - sizeof(DWORD) - This->nb_vertices * sizeof(D3DVECTOR) - sizeof(DWORD);
1135
1136     TRACE("Mesh: nb_vertices = %d, nb_faces = %d, face_data_size = %d\n", This->nb_vertices, This->nb_faces, This->face_data_size);
1137
1138     This->pVertices = HeapAlloc(GetProcessHeap(), 0, This->nb_vertices * sizeof(D3DVECTOR));
1139     memcpy(This->pVertices, ptr + sizeof(DWORD), This->nb_vertices * sizeof(D3DVECTOR));
1140
1141     This->pFaceData = HeapAlloc(GetProcessHeap(), 0, This->face_data_size);
1142     memcpy(This->pFaceData, ptr + sizeof(DWORD) + This->nb_vertices * sizeof(D3DVECTOR) + sizeof(DWORD), This->face_data_size);
1143
1144     while (1)
1145     {
1146         hr =  IDirectXFileData_GetNextObject(pData, &pObject);
1147         if (hr == DXFILEERR_NOMOREOBJECTS)
1148         {
1149             TRACE("No more object\n");
1150             break;
1151         }
1152         if (hr != DXFILE_OK)
1153            goto end;
1154
1155             hr = IDirectXFileObject_QueryInterface(pObject, &IID_IDirectXFileData, (void**)&pData2);
1156         IDirectXFileObject_Release(pObject);
1157         if (hr != DXFILE_OK)
1158             goto end;
1159
1160         hr = IDirectXFileData_GetType(pData2, &pGuid);
1161         if (hr != DXFILE_OK)
1162             goto end;
1163
1164         TRACE("Found object type whose GUID = %s\n", debugstr_guid(pGuid));
1165
1166         if (!IsEqualGUID(pGuid, &TID_D3DRMMeshNormals))
1167         {
1168             DWORD tmp;
1169
1170             hr = IDirectXFileData_GetData(pData, NULL, &size, (void**)&ptr);
1171             if (hr != DXFILE_OK)
1172                 goto end;
1173
1174             This->nb_normals = *(DWORD*)ptr;
1175             tmp = *(DWORD*)(ptr + sizeof(DWORD) + This->nb_normals * sizeof(D3DVECTOR));
1176
1177             TRACE("MeshNormals: nb_normals = %d, nb_faces_normals = %d\n", This->nb_normals, tmp);
1178
1179             This->pNormals = HeapAlloc(GetProcessHeap(), 0, This->nb_normals * sizeof(D3DVECTOR));
1180             memcpy(This->pNormals, ptr + sizeof(DWORD), This->nb_normals * sizeof(D3DVECTOR));
1181         }
1182         else if(!IsEqualGUID(pGuid, &TID_D3DRMMeshTextureCoords))
1183         {
1184             hr = IDirectXFileData_GetData(pData, NULL, &size, (void**)&ptr);
1185             if (hr != DXFILE_OK)
1186                 goto end;
1187
1188             This->nb_coords2d = *(DWORD*)ptr;
1189
1190             TRACE("MeshTextureCoords: nb_coords2d = %d\n", This->nb_coords2d);
1191
1192             This->pCoords2d = HeapAlloc(GetProcessHeap(), 0, This->nb_coords2d * sizeof(Coords2d));
1193             memcpy(This->pCoords2d, ptr + sizeof(DWORD), This->nb_coords2d * sizeof(Coords2d));
1194
1195         }
1196         else if(!IsEqualGUID(pGuid, &TID_D3DRMMeshMaterialList))
1197         {
1198             FIXME("MeshMaterialList not supported yet, ignoring...\n");
1199         }
1200         else
1201         {
1202             FIXME("Unknown GUID %s, ignoring...\n", debugstr_guid(pGuid));
1203         }
1204
1205         IDirectXFileData_Release(pData2);
1206         pData2 = NULL;
1207     }
1208
1209     ret = D3DRM_OK;
1210
1211 end:
1212     if (pData2)
1213         IDirectXFileData_Release(pData2);
1214     if (pData)
1215         IDirectXFileData_Release(pData);
1216     if (pEnumObject)
1217         IDirectXFileEnumObject_Release(pEnumObject);
1218     if (pDXFile)
1219         IDirectXFile_Release(pDXFile);
1220
1221     if (ret != D3DRM_OK)
1222     {
1223         /* Clean mesh data */
1224         This->nb_vertices = 0;
1225         This->nb_normals = 0;
1226         This->nb_faces = 0;
1227         This->face_data_size = 0;
1228         This->nb_coords2d = 0;
1229         HeapFree(GetProcessHeap(), 0, This->pVertices);
1230         This->pVertices = NULL;
1231         HeapFree(GetProcessHeap(), 0, This->pNormals);
1232         This->pNormals = NULL;
1233         HeapFree(GetProcessHeap(), 0, This->pFaceData);
1234         This->pFaceData = NULL;
1235         HeapFree(GetProcessHeap(), 0, This->pCoords2d);
1236         This->pCoords2d = NULL;
1237     }
1238
1239     return ret;
1240 }
1241
1242 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_Save(IDirect3DRMMeshBuilder3* iface,
1243                                                        const char* filename, D3DRMXOFFORMAT format,
1244                                                        D3DRMSAVEOPTIONS save)
1245 {
1246     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1247
1248     FIXME("(%p)->(%s,%d,%d): stub\n", This, filename, format, save);
1249
1250     return E_NOTIMPL;
1251 }
1252
1253 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_Scale(IDirect3DRMMeshBuilder3* iface,
1254                                                         D3DVALUE sx, D3DVALUE sy, D3DVALUE sz)
1255 {
1256     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1257
1258     FIXME("(%p)->(%f,%f,%f): stub\n", This, sx, sy, sz);
1259
1260     return E_NOTIMPL;
1261 }
1262
1263 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_Translate(IDirect3DRMMeshBuilder3* iface,
1264                                                             D3DVALUE tx, D3DVALUE ty, D3DVALUE tz)
1265 {
1266     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1267
1268     FIXME("(%p)->(%f,%f,%f): stub\n", This, tx, ty, tz);
1269
1270     return E_NOTIMPL;
1271 }
1272
1273 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_SetColorSource(IDirect3DRMMeshBuilder3* iface,
1274                                                                  D3DRMCOLORSOURCE color)
1275 {
1276     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1277
1278     FIXME("(%p)->(%x): stub\n", This, color);
1279
1280     return E_NOTIMPL;
1281 }
1282
1283 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_GetBox(IDirect3DRMMeshBuilder3* iface,
1284                                                          D3DRMBOX* box)
1285 {
1286     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1287
1288     FIXME("(%p)->(%p): stub\n", This, box);
1289
1290     return E_NOTIMPL;
1291 }
1292
1293 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_GenerateNormals(IDirect3DRMMeshBuilder3* iface,
1294                                                                   D3DVALUE crease, DWORD flags)
1295 {
1296     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1297
1298     FIXME("(%p)->(%f,%u): stub\n", This, crease, flags);
1299
1300     return E_NOTIMPL;
1301 }
1302
1303 static D3DRMCOLORSOURCE WINAPI IDirect3DRMMeshBuilder3Impl_GetColorSource(IDirect3DRMMeshBuilder3* iface)
1304 {
1305     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1306
1307     FIXME("(%p)->(): stub\n", This);
1308
1309     return E_NOTIMPL;
1310 }
1311
1312 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_AddMesh(IDirect3DRMMeshBuilder3* iface,
1313                                                           LPDIRECT3DRMMESH Mesh)
1314 {
1315     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1316
1317     FIXME("(%p)->(%p): stub\n", This, Mesh);
1318
1319     return E_NOTIMPL;
1320 }
1321
1322 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_AddMeshBuilder(IDirect3DRMMeshBuilder3* iface,
1323                                                                  LPDIRECT3DRMMESHBUILDER3 MeshBuilder,
1324                                                                  DWORD flags)
1325 {
1326     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1327
1328     FIXME("(%p)->(%p,%u): stub\n", This, MeshBuilder, flags);
1329
1330     return E_NOTIMPL;
1331 }
1332
1333 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_AddFrame(IDirect3DRMMeshBuilder3* iface,
1334                                                            LPDIRECT3DRMFRAME3 Frame)
1335 {
1336     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1337
1338     FIXME("(%p)->(%p): stub\n", This, Frame);
1339
1340     return E_NOTIMPL;
1341 }
1342
1343 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_AddFace(IDirect3DRMMeshBuilder3* iface,
1344                                                           LPDIRECT3DRMFACE2 Face)
1345 {
1346     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1347
1348     FIXME("(%p)->(%p): stub\n", This, Face);
1349
1350     return E_NOTIMPL;
1351 }
1352
1353 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_AddFaces(IDirect3DRMMeshBuilder3* iface,
1354                                                            DWORD vcount, D3DVECTOR* vertices,
1355                                                            DWORD ncount, D3DVECTOR* normals,
1356                                                            DWORD* data,
1357                                                            LPDIRECT3DRMFACEARRAY* FaceArray)
1358 {
1359     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1360
1361     FIXME("(%p)->(%d,%p,%d,%p,%p,%p): stub\n", This, vcount, vertices, ncount,
1362           normals, data, FaceArray);
1363
1364     return E_NOTIMPL;
1365 }
1366
1367 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_ReserveSpace(IDirect3DRMMeshBuilder3* iface,
1368                                                                DWORD vertex_Count,
1369                                                                DWORD normal_count,
1370                                                                DWORD face_count)
1371 {
1372     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1373
1374     FIXME("(%p)->(%d,%d,%d): stub\n", This, vertex_Count, normal_count, face_count);
1375
1376     return E_NOTIMPL;
1377 }
1378
1379 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_SetColorRGB(IDirect3DRMMeshBuilder3* iface,
1380                                                               D3DVALUE red, D3DVALUE green,
1381                                                               D3DVALUE blue)
1382 {
1383     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1384
1385     FIXME("(%p)->(%f,%f,%f): stub\n", This, red, green, blue);
1386
1387     return E_NOTIMPL;
1388 }
1389
1390 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_SetColor(IDirect3DRMMeshBuilder3* iface,
1391                                                            D3DCOLOR color)
1392 {
1393     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1394
1395     FIXME("(%p)->(%x): stub\n", This, color);
1396
1397     return E_NOTIMPL;
1398 }
1399
1400 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_SetTexture(IDirect3DRMMeshBuilder3* iface,
1401                                                              LPDIRECT3DRMTEXTURE3 texture)
1402 {
1403     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1404
1405     FIXME("(%p)->(%p): stub\n", This, texture);
1406
1407     return E_NOTIMPL;
1408 }
1409
1410 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_SetMaterial(IDirect3DRMMeshBuilder3* iface,
1411                                                               LPDIRECT3DRMMATERIAL2 material)
1412 {
1413     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1414
1415     FIXME("(%p)->(%p): stub\n", This, material);
1416
1417     return E_NOTIMPL;
1418 }
1419
1420 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_SetTextureTopology(IDirect3DRMMeshBuilder3* iface,
1421                                                                      BOOL wrap_u, BOOL wrap_v)
1422 {
1423     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1424
1425     FIXME("(%p)->(%d,%d): stub\n", This, wrap_u, wrap_v);
1426
1427     return E_NOTIMPL;
1428 }
1429
1430 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_SetQuality(IDirect3DRMMeshBuilder3* iface,
1431                                                              D3DRMRENDERQUALITY quality)
1432 {
1433     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1434
1435     FIXME("(%p)->(%d): stub\n", This, quality);
1436
1437     return E_NOTIMPL;
1438 }
1439
1440 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_SetPerspective(IDirect3DRMMeshBuilder3* iface,
1441                                                                  BOOL enable)
1442 {
1443     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1444
1445     FIXME("(%p)->(%d): stub\n", This, enable);
1446
1447     return E_NOTIMPL;
1448 }
1449
1450 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_SetVertex(IDirect3DRMMeshBuilder3* iface,
1451                                                             DWORD index,
1452                                                             D3DVALUE x, D3DVALUE y, D3DVALUE z)
1453 {
1454     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1455
1456     FIXME("(%p)->(%f,%f,%f): stub\n", This, x, y, z);
1457
1458     return E_NOTIMPL;
1459 }
1460
1461 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_SetNormal(IDirect3DRMMeshBuilder3* iface,
1462                                                             DWORD index,
1463                                                             D3DVALUE x, D3DVALUE y, D3DVALUE z)
1464 {
1465     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1466
1467     FIXME("(%p)->(%f,%f,%f): stub\n", This, x, y, z);
1468
1469     return E_NOTIMPL;
1470 }
1471
1472 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_SetTextureCoordinates(IDirect3DRMMeshBuilder3* iface,
1473                                                                         DWORD index, D3DVALUE u,
1474                                                                         D3DVALUE v)
1475 {
1476     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1477
1478     FIXME("(%p)->(%f,%f): stub\n", This, u, v);
1479
1480     return E_NOTIMPL;
1481 }
1482
1483 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_SetVertexColor(IDirect3DRMMeshBuilder3* iface,
1484                                                                  DWORD index, D3DCOLOR color)
1485 {
1486     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1487
1488     FIXME("(%p)->(%d,%x): stub\n", This, index, color);
1489
1490     return E_NOTIMPL;
1491 }
1492
1493 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_SetVertexColorRGB(IDirect3DRMMeshBuilder3* iface,
1494                                                                     DWORD index,
1495                                                                     D3DVALUE red, D3DVALUE green,
1496                                                                     D3DVALUE blue)
1497 {
1498     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1499
1500     FIXME("(%p)->(%d,%f,%f,%f): stub\n", This, index, red, green, blue);
1501
1502     return E_NOTIMPL;
1503 }
1504
1505 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_GetFaces(IDirect3DRMMeshBuilder3* iface,
1506                                                            LPDIRECT3DRMFACEARRAY* FaceArray)
1507 {
1508     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1509
1510     FIXME("(%p)->(%p): stub\n", This, FaceArray);
1511
1512     return E_NOTIMPL;
1513 }
1514
1515 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_GetGeometry(IDirect3DRMMeshBuilder3* iface,
1516                                                               DWORD* vcount, D3DVECTOR* vertices,
1517                                                               DWORD* ncount, D3DVECTOR* normals,
1518                                                               DWORD* face_data_size,
1519                                                               DWORD* face_data)
1520 {
1521     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1522
1523     FIXME("(%p)->(%p,%p,%p,%p,%p,%p): stub\n", This, vcount, vertices, ncount, normals,
1524           face_data_size, face_data);
1525
1526     return E_NOTIMPL;
1527 }
1528
1529 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_GetTextureCoordinates(IDirect3DRMMeshBuilder3* iface,
1530                                                                         DWORD index, D3DVALUE* u,
1531                                                                         D3DVALUE* v)
1532 {
1533     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1534
1535     TRACE("(%p)->(%d,%p,%p)\n", This, index, u, v);
1536
1537     if (index >= This->nb_coords2d)
1538         return D3DRMERR_NOTFOUND;
1539
1540     *u = This->pCoords2d[index].u;
1541     *v = This->pCoords2d[index].v;
1542
1543     return D3DRM_OK;
1544 }
1545
1546
1547 static int WINAPI IDirect3DRMMeshBuilder3Impl_AddVertex(IDirect3DRMMeshBuilder3* iface,
1548                                                         D3DVALUE x, D3DVALUE y, D3DVALUE z)
1549 {
1550     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1551
1552     FIXME("(%p)->(%f,%f,%f): stub\n", This, x, y, z);
1553
1554     return 0;
1555 }
1556
1557 static int WINAPI IDirect3DRMMeshBuilder3Impl_AddNormal(IDirect3DRMMeshBuilder3* iface,
1558                                                         D3DVALUE x, D3DVALUE y, D3DVALUE z)
1559 {
1560     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1561
1562     FIXME("(%p)->(%f,%f,%f): stub\n", This, x, y, z);
1563
1564     return 0;
1565 }
1566
1567 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_CreateFace(IDirect3DRMMeshBuilder3* iface,
1568                                                              LPDIRECT3DRMFACE2* Face)
1569 {
1570     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1571
1572     FIXME("(%p)->(%p): stub\n", This, Face);
1573
1574     return E_NOTIMPL;
1575 }
1576
1577 static D3DRMRENDERQUALITY WINAPI IDirect3DRMMeshBuilder3Impl_GetQuality(IDirect3DRMMeshBuilder3* iface)
1578 {
1579     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1580
1581     FIXME("(%p)->(): stub\n", This);
1582
1583     return 0;
1584 }
1585
1586 static BOOL WINAPI IDirect3DRMMeshBuilder3Impl_GetPerspective(IDirect3DRMMeshBuilder3* iface)
1587 {
1588     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1589
1590     FIXME("(%p)->(): stub\n", This);
1591
1592     return FALSE;
1593 }
1594
1595 static int WINAPI IDirect3DRMMeshBuilder3Impl_GetFaceCount(IDirect3DRMMeshBuilder3* iface)
1596 {
1597     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1598
1599     TRACE("(%p)->()\n", This);
1600
1601     return This->nb_faces;
1602 }
1603
1604 static int WINAPI IDirect3DRMMeshBuilder3Impl_GetVertexCount(IDirect3DRMMeshBuilder3* iface)
1605 {
1606     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1607
1608     TRACE("(%p)->()\n", This);
1609
1610     return This->nb_vertices;
1611 }
1612
1613 static D3DCOLOR WINAPI IDirect3DRMMeshBuilder3Impl_GetVertexColor(IDirect3DRMMeshBuilder3* iface,
1614                                                                   DWORD index)
1615 {
1616     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1617
1618     FIXME("(%p)->(%d): stub\n", This, index);
1619
1620     return 0;
1621 }
1622
1623 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_CreateMesh(IDirect3DRMMeshBuilder3* iface,
1624                                                              LPDIRECT3DRMMESH* Mesh)
1625 {
1626     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1627
1628     FIXME("(%p)->(%p): stub\n", This, Mesh);
1629
1630     return E_NOTIMPL;
1631 }
1632
1633 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_GetFace(IDirect3DRMMeshBuilder3* iface,
1634                                                           DWORD index, LPDIRECT3DRMFACE2* Face)
1635 {
1636     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1637
1638     FIXME("(%p)->(%u,%p): stub\n", This, index, Face);
1639
1640     return E_NOTIMPL;
1641 }
1642
1643 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_GetVertex(IDirect3DRMMeshBuilder3* iface,
1644                                                             DWORD index, LPD3DVECTOR vector)
1645 {
1646     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1647
1648     FIXME("(%p)->(%u,%p): stub\n", This, index, vector);
1649
1650     return E_NOTIMPL;
1651 }
1652
1653 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_GetNormal(IDirect3DRMMeshBuilder3* iface,
1654                                                             DWORD index, LPD3DVECTOR vector)
1655 {
1656     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1657
1658     FIXME("(%p)->(%u,%p): stub\n", This, index, vector);
1659
1660     return E_NOTIMPL;
1661 }
1662
1663 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_DeleteVertices(IDirect3DRMMeshBuilder3* iface,
1664                                                                  DWORD IndexFirst, DWORD count)
1665 {
1666     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1667
1668     FIXME("(%p)->(%u,%u): stub\n", This, IndexFirst, count);
1669
1670     return E_NOTIMPL;
1671 }
1672
1673 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_DeleteNormals(IDirect3DRMMeshBuilder3* iface,
1674                                                                 DWORD IndexFirst, DWORD count)
1675 {
1676     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1677
1678     FIXME("(%p)->(%u,%u): stub\n", This, IndexFirst, count);
1679
1680     return E_NOTIMPL;
1681 }
1682
1683 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_DeleteFace(IDirect3DRMMeshBuilder3* iface,
1684                                                              LPDIRECT3DRMFACE2 Face)
1685 {
1686     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1687
1688     FIXME("(%p)->(%p): stub\n", This, Face);
1689
1690     return E_NOTIMPL;
1691 }
1692
1693 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_Empty(IDirect3DRMMeshBuilder3* iface, DWORD flags)
1694 {
1695     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1696
1697     FIXME("(%p)->(%u): stub\n", This, flags);
1698
1699     return E_NOTIMPL;
1700 }
1701
1702 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_Optimize(IDirect3DRMMeshBuilder3* iface,
1703                                                            DWORD flags)
1704 {
1705     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1706
1707     FIXME("(%p)->(%u): stub\n", This, flags);
1708
1709     return E_NOTIMPL;
1710 }
1711
1712 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_AddFacesIndexed(IDirect3DRMMeshBuilder3* iface,
1713                                                                   DWORD flags, DWORD* indices,
1714                                                                   DWORD* IndexFirst, DWORD* count)
1715 {
1716     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1717
1718     FIXME("(%p)->(%u,%p,%p,%p): stub\n", This, flags, indices, IndexFirst, count);
1719
1720     return E_NOTIMPL;
1721 }
1722
1723 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_CreateSubMesh(IDirect3DRMMeshBuilder3* iface,
1724                                                                 LPUNKNOWN *unkwn)
1725 {
1726     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1727
1728     FIXME("(%p)->(%p): stub\n", This, unkwn);
1729
1730     return E_NOTIMPL;
1731 }
1732
1733 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_GetParentMesh(IDirect3DRMMeshBuilder3* iface,
1734                                                                 DWORD flags, LPUNKNOWN *unkwn)
1735 {
1736     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1737
1738     FIXME("(%p)->(%u,%p): stub\n", This, flags, unkwn);
1739
1740     return E_NOTIMPL;
1741 }
1742
1743 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_GetSubMeshes(IDirect3DRMMeshBuilder3* iface,
1744                                                                LPDWORD count, LPUNKNOWN *unkwn)
1745 {
1746     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1747
1748     FIXME("(%p)->(%p,%p): stub\n", This, count, unkwn);
1749
1750     return E_NOTIMPL;
1751 }
1752
1753 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_DeleteSubMesh(IDirect3DRMMeshBuilder3* iface,
1754                                                                 LPUNKNOWN unkwn)
1755 {
1756     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1757
1758     FIXME("(%p)->(%p): stub\n", This, unkwn);
1759
1760     return E_NOTIMPL;
1761 }
1762
1763 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_Enable(IDirect3DRMMeshBuilder3* iface,
1764                                                          DWORD index)
1765 {
1766     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1767
1768     FIXME("(%p)->(%u): stub\n", This, index);
1769
1770     return E_NOTIMPL;
1771 }
1772
1773 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_GetEnable(IDirect3DRMMeshBuilder3* iface,
1774                                                             DWORD* indices)
1775 {
1776     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1777
1778     FIXME("(%p)->(%p): stub\n", This, indices);
1779
1780     return E_NOTIMPL;
1781 }
1782
1783 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_AddTriangles(IDirect3DRMMeshBuilder3* iface,
1784                                                                DWORD flags, DWORD format,
1785                                                                DWORD VertexCount, LPVOID data)
1786 {
1787     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1788
1789     FIXME("(%p)->(%u,%u,%u,%p): stub\n", This, flags, format, VertexCount, data);
1790
1791     return E_NOTIMPL;
1792 }
1793
1794 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_SetVertices(IDirect3DRMMeshBuilder3* iface,
1795                                                               DWORD IndexFirst, DWORD count,
1796                                                               LPD3DVECTOR vector)
1797 {
1798     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1799
1800     FIXME("(%p)->(%u,%u,%p): stub\n", This, IndexFirst, count, vector);
1801
1802     return E_NOTIMPL;
1803 }
1804
1805 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_GetVertices(IDirect3DRMMeshBuilder3* iface,
1806                                                               DWORD IndexFirst, LPDWORD vcount,
1807                                                               LPD3DVECTOR vertices)
1808 {
1809     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1810     DWORD count = This->nb_vertices - IndexFirst;
1811
1812     TRACE("(%p)->(%u,%p,%p)\n", This, IndexFirst, vcount, vertices);
1813
1814     if (vcount)
1815         *vcount = count;
1816     if (vertices && This->nb_vertices)
1817         memcpy(vertices, This->pVertices + IndexFirst, count * sizeof(D3DVECTOR));
1818
1819     return D3DRM_OK;
1820 }
1821
1822 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_SetNormals(IDirect3DRMMeshBuilder3* iface,
1823                                                              DWORD IndexFirst, DWORD count,
1824                                                              LPD3DVECTOR vector)
1825 {
1826     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1827
1828     FIXME("(%p)->(%u,%u,%p): stub\n", This, IndexFirst, count, vector);
1829
1830     return E_NOTIMPL;
1831 }
1832
1833 static HRESULT WINAPI IDirect3DRMMeshBuilder3Impl_GetNormals(IDirect3DRMMeshBuilder3* iface,
1834                                                              DWORD IndexFirst, LPDWORD count,
1835                                                              LPD3DVECTOR vector)
1836 {
1837     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1838
1839     FIXME("(%p)->(%u,%p,%p): stub\n", This, IndexFirst, count, vector);
1840
1841     return E_NOTIMPL;
1842 }
1843
1844 static int WINAPI IDirect3DRMMeshBuilder3Impl_GetNormalCount(IDirect3DRMMeshBuilder3* iface)
1845 {
1846     IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder3(iface);
1847
1848     FIXME("(%p)->(): stub\n", This);
1849
1850     return E_NOTIMPL;
1851 }
1852
1853 static const struct IDirect3DRMMeshBuilder3Vtbl Direct3DRMMeshBuilder3_Vtbl =
1854 {
1855     /*** IUnknown methods ***/
1856     IDirect3DRMMeshBuilder3Impl_QueryInterface,
1857     IDirect3DRMMeshBuilder3Impl_AddRef,
1858     IDirect3DRMMeshBuilder3Impl_Release,
1859     /*** IDirect3DRMObject methods ***/
1860     IDirect3DRMMeshBuilder3Impl_Clone,
1861     IDirect3DRMMeshBuilder3Impl_AddDestroyCallback,
1862     IDirect3DRMMeshBuilder3Impl_DeleteDestroyCallback,
1863     IDirect3DRMMeshBuilder3Impl_SetAppData,
1864     IDirect3DRMMeshBuilder3Impl_GetAppData,
1865     IDirect3DRMMeshBuilder3Impl_SetName,
1866     IDirect3DRMMeshBuilder3Impl_GetName,
1867     IDirect3DRMMeshBuilder3Impl_GetClassName,
1868     /*** IDirect3DRMMeshBuilder3 methods ***/
1869     IDirect3DRMMeshBuilder3Impl_Load,
1870     IDirect3DRMMeshBuilder3Impl_Save,
1871     IDirect3DRMMeshBuilder3Impl_Scale,
1872     IDirect3DRMMeshBuilder3Impl_Translate,
1873     IDirect3DRMMeshBuilder3Impl_SetColorSource,
1874     IDirect3DRMMeshBuilder3Impl_GetBox,
1875     IDirect3DRMMeshBuilder3Impl_GenerateNormals,
1876     IDirect3DRMMeshBuilder3Impl_GetColorSource,
1877     IDirect3DRMMeshBuilder3Impl_AddMesh,
1878     IDirect3DRMMeshBuilder3Impl_AddMeshBuilder,
1879     IDirect3DRMMeshBuilder3Impl_AddFrame,
1880     IDirect3DRMMeshBuilder3Impl_AddFace,
1881     IDirect3DRMMeshBuilder3Impl_AddFaces,
1882     IDirect3DRMMeshBuilder3Impl_ReserveSpace,
1883     IDirect3DRMMeshBuilder3Impl_SetColorRGB,
1884     IDirect3DRMMeshBuilder3Impl_SetColor,
1885     IDirect3DRMMeshBuilder3Impl_SetTexture,
1886     IDirect3DRMMeshBuilder3Impl_SetMaterial,
1887     IDirect3DRMMeshBuilder3Impl_SetTextureTopology,
1888     IDirect3DRMMeshBuilder3Impl_SetQuality,
1889     IDirect3DRMMeshBuilder3Impl_SetPerspective,
1890     IDirect3DRMMeshBuilder3Impl_SetVertex,
1891     IDirect3DRMMeshBuilder3Impl_SetNormal,
1892     IDirect3DRMMeshBuilder3Impl_SetTextureCoordinates,
1893     IDirect3DRMMeshBuilder3Impl_SetVertexColor,
1894     IDirect3DRMMeshBuilder3Impl_SetVertexColorRGB,
1895     IDirect3DRMMeshBuilder3Impl_GetFaces,
1896     IDirect3DRMMeshBuilder3Impl_GetGeometry,
1897     IDirect3DRMMeshBuilder3Impl_GetTextureCoordinates,
1898     IDirect3DRMMeshBuilder3Impl_AddVertex,
1899     IDirect3DRMMeshBuilder3Impl_AddNormal,
1900     IDirect3DRMMeshBuilder3Impl_CreateFace,
1901     IDirect3DRMMeshBuilder3Impl_GetQuality,
1902     IDirect3DRMMeshBuilder3Impl_GetPerspective,
1903     IDirect3DRMMeshBuilder3Impl_GetFaceCount,
1904     IDirect3DRMMeshBuilder3Impl_GetVertexCount,
1905     IDirect3DRMMeshBuilder3Impl_GetVertexColor,
1906     IDirect3DRMMeshBuilder3Impl_CreateMesh,
1907     IDirect3DRMMeshBuilder3Impl_GetFace,
1908     IDirect3DRMMeshBuilder3Impl_GetVertex,
1909     IDirect3DRMMeshBuilder3Impl_GetNormal,
1910     IDirect3DRMMeshBuilder3Impl_DeleteVertices,
1911     IDirect3DRMMeshBuilder3Impl_DeleteNormals,
1912     IDirect3DRMMeshBuilder3Impl_DeleteFace,
1913     IDirect3DRMMeshBuilder3Impl_Empty,
1914     IDirect3DRMMeshBuilder3Impl_Optimize,
1915     IDirect3DRMMeshBuilder3Impl_AddFacesIndexed,
1916     IDirect3DRMMeshBuilder3Impl_CreateSubMesh,
1917     IDirect3DRMMeshBuilder3Impl_GetParentMesh,
1918     IDirect3DRMMeshBuilder3Impl_GetSubMeshes,
1919     IDirect3DRMMeshBuilder3Impl_DeleteSubMesh,
1920     IDirect3DRMMeshBuilder3Impl_Enable,
1921     IDirect3DRMMeshBuilder3Impl_GetEnable,
1922     IDirect3DRMMeshBuilder3Impl_AddTriangles,
1923     IDirect3DRMMeshBuilder3Impl_SetVertices,
1924     IDirect3DRMMeshBuilder3Impl_GetVertices,
1925     IDirect3DRMMeshBuilder3Impl_SetNormals,
1926     IDirect3DRMMeshBuilder3Impl_GetNormals,
1927     IDirect3DRMMeshBuilder3Impl_GetNormalCount
1928 };
1929
1930 HRESULT Direct3DRMMeshBuilder_create(REFIID riid, IUnknown** ppObj)
1931 {
1932     IDirect3DRMMeshBuilderImpl* object;
1933
1934     TRACE("(%p)\n", ppObj);
1935
1936     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DRMMeshBuilderImpl));
1937     if (!object)
1938     {
1939         ERR("Out of memory\n");
1940         return E_OUTOFMEMORY;
1941     }
1942
1943     object->IDirect3DRMMeshBuilder2_iface.lpVtbl = &Direct3DRMMeshBuilder2_Vtbl;
1944     object->IDirect3DRMMeshBuilder3_iface.lpVtbl = &Direct3DRMMeshBuilder3_Vtbl;
1945     object->ref = 1;
1946
1947     if (IsEqualGUID(riid, &IID_IDirect3DRMMeshBuilder3))
1948         *ppObj = (IUnknown*)&object->IDirect3DRMMeshBuilder3_iface;
1949     else
1950         *ppObj = (IUnknown*)&object->IDirect3DRMMeshBuilder2_iface;
1951
1952     return S_OK;
1953 }