meshbuilder.c 30 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
/*
 * Implementation of IDirect3DRMMeshBuilder Interface
 *
 * Copyright 2010 Christian Costa
 *
 * This file contains the (internal) driver registration functions,
 * driver enumeration APIs and DirectDraw creation functions.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "wine/debug.h"

#define COBJMACROS

#include "winbase.h"
#include "wingdi.h"
30
#include "dxfile.h"
31
#include "rmxfguid.h"
32 33 34 35 36

#include "d3drm_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(d3drm);

37 38 39 40 41
typedef struct {
    D3DVALUE u;
    D3DVALUE v;
} Coords2d;

42
typedef struct {
43
    IDirect3DRMMeshBuilder IDirect3DRMMeshBuilder_iface;
44
    LONG ref;
45 46 47 48 49 50 51
    DWORD nb_vertices;
    D3DVECTOR* pVertices;
    DWORD nb_normals;
    D3DVECTOR* pNormals;
    DWORD nb_faces;
    DWORD face_data_size;
    LPVOID pFaceData;
52 53
    DWORD nb_coords2d;
    Coords2d* pCoords2d;
54 55
} IDirect3DRMMeshBuilderImpl;

56 57 58 59 60 61
typedef struct {
    WORD major;
    WORD minor;
    DWORD flags;
} Header;

62 63
static const struct IDirect3DRMMeshBuilderVtbl Direct3DRMMeshBuilder_Vtbl;

64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284
static char templates[] = {
"xof 0302txt 0064"
"template Header"
"{"
"<3D82AB43-62DA-11CF-AB39-0020AF71E433>"
"WORD major;"
"WORD minor;"
"DWORD flags;"
"}"
"template Vector"
"{"
"<3D82AB5E-62DA-11CF-AB39-0020AF71E433>"
"FLOAT x;"
"FLOAT y;"
"FLOAT z;"
"}"
"template Coords2d"
"{"
"<F6F23F44-7686-11CF-8F52-0040333594A3>"
"FLOAT u;"
"FLOAT v;"
"}"
"template Matrix4x4"
"{"
"<F6F23F45-7686-11CF-8F52-0040333594A3>"
"array FLOAT matrix[16];"
"}"
"template ColorRGBA"
"{"
"<35FF44E0-6C7C-11CF-8F52-0040333594A3>"
"FLOAT red;"
"FLOAT green;"
"FLOAT blue;"
"FLOAT alpha;"
"}"
"template ColorRGB"
"{"
"<D3E16E81-7835-11CF-8F52-0040333594A3>"
"FLOAT red;"
"FLOAT green;"
"FLOAT blue;"
"}"
"template IndexedColor"
"{"
"<1630B820-7842-11CF-8F52-0040333594A3>"
"DWORD index;"
"ColorRGBA indexColor;"
"}"
"template Boolean"
"{"
"<537DA6A0-CA37-11D0-941C-0080C80CFA7B>"
"DWORD truefalse;"
"}"
"template Boolean2d"
"{"
"<4885AE63-78E8-11CF-8F52-0040333594A3>"
"Boolean u;"
"Boolean v;"
"}"
"template MaterialWrap"
"{"
"<4885AE60-78E8-11CF-8F52-0040333594A3>"
"Boolean u;"
"Boolean v;"
"}"
"template TextureFilename"
"{"
"<A42790E1-7810-11CF-8F52-0040333594A3>"
"STRING filename;"
"}"
"template Material"
"{"
"<3D82AB4D-62DA-11CF-AB39-0020AF71E433>"
"ColorRGBA faceColor;"
"FLOAT power;"
"ColorRGB specularColor;"
"ColorRGB emissiveColor;"
"[...]"
"}"
"template MeshFace"
"{"
"<3D82AB5F-62DA-11CF-AB39-0020AF71E433>"
"DWORD nFaceVertexIndices;"
"array DWORD faceVertexIndices[nFaceVertexIndices];"
"}"
"template MeshFaceWraps"
"{"
"<ED1EC5C0-C0A8-11D0-941C-0080C80CFA7B>"
"DWORD nFaceWrapValues;"
"array Boolean2d faceWrapValues[nFaceWrapValues];"
"}"
"template MeshTextureCoords"
"{"
"<F6F23F40-7686-11CF-8F52-0040333594A3>"
"DWORD nTextureCoords;"
"array Coords2d textureCoords[nTextureCoords];"
"}"
"template MeshMaterialList"
"{"
"<F6F23F42-7686-11CF-8F52-0040333594A3>"
"DWORD nMaterials;"
"DWORD nFaceIndexes;"
"array DWORD faceIndexes[nFaceIndexes];"
"[Material]"
"}"
"template MeshNormals"
"{"
"<F6F23F43-7686-11CF-8F52-0040333594A3>"
"DWORD nNormals;"
"array Vector normals[nNormals];"
"DWORD nFaceNormals;"
"array MeshFace faceNormals[nFaceNormals];"
"}"
"template MeshVertexColors"
"{"
"<1630B821-7842-11CF-8F52-0040333594A3>"
"DWORD nVertexColors;"
"array IndexedColor vertexColors[nVertexColors];"
"}"
"template Mesh"
"{"
"<3D82AB44-62DA-11CF-AB39-0020AF71E433>"
"DWORD nVertices;"
"array Vector vertices[nVertices];"
"DWORD nFaces;"
"array MeshFace faces[nFaces];"
"[...]"
"}"
"template FrameTransformMatrix"
"{"
"<F6F23F41-7686-11CF-8F52-0040333594A3>"
"Matrix4x4 frameMatrix;"
"}"
"template Frame"
"{"
"<3D82AB46-62DA-11CF-AB39-0020AF71E433>"
"[...]"
"}"
"template FloatKeys"
"{"
"<10DD46A9-775B-11CF-8F52-0040333594A3>"
"DWORD nValues;"
"array FLOAT values[nValues];"
"}"
"template TimedFloatKeys"
"{"
"<F406B180-7B3B-11CF-8F52-0040333594A3>"
"DWORD time;"
"FloatKeys tfkeys;"
"}"
"template AnimationKey"
"{"
"<10DD46A8-775B-11CF-8F52-0040333594A3>"
"DWORD keyType;"
"DWORD nKeys;"
"array TimedFloatKeys keys[nKeys];"
"}"
"template AnimationOptions"
"{"
"<E2BF56C0-840F-11CF-8F52-0040333594A3>"
"DWORD openclosed;"
"DWORD positionquality;"
"}"
"template Animation"
"{"
"<3D82AB4F-62DA-11CF-AB39-0020AF71E433>"
"[...]"
"}"
"template AnimationSet"
"{"
"<3D82AB50-62DA-11CF-AB39-0020AF71E433>"
"[Animation]"
"}"
"template InlineData"
"{"
"<3A23EEA0-94B1-11D0-AB39-0020AF71E433>"
"[BINARY]"
"}"
"template Url"
"{"
"<3A23EEA1-94B1-11D0-AB39-0020AF71E433>"
"DWORD nUrls;"
"array STRING urls[nUrls];"
"}"
"template ProgressiveMesh"
"{"
"<8A63C360-997D-11D0-941C-0080C80CFA7B>"
"[Url,InlineData]"
"}"
"template Guid"
"{"
"<A42790E0-7810-11CF-8F52-0040333594A3>"
"DWORD data1;"
"WORD data2;"
"WORD data3;"
"array UCHAR data4[8];"
"}"
"template StringProperty"
"{"
"<7F0F21E0-BFE1-11D1-82C0-00A0C9697271>"
"STRING key;"
"STRING value;"
"}"
"template PropertyBag"
"{"
"<7F0F21E1-BFE1-11D1-82C0-00A0C9697271>"
"[StringProperty]"
"}"
"template ExternalVisual"
"{"
"<98116AA0-BDBA-11D1-82C0-00A0C9697271>"
"Guid guidExternalVisual;"
"[...]"
"}"
"template RightHanded"
"{"
"<7F5D5EA0-D53A-11D1-82C0-00A0C9697271>"
"DWORD bRightHanded;"
"}"
};

285 286 287 288 289
static inline IDirect3DRMMeshBuilderImpl *impl_from_IDirect3DRMMeshBuilder(IDirect3DRMMeshBuilder *iface)
{
    return CONTAINING_RECORD(iface, IDirect3DRMMeshBuilderImpl, IDirect3DRMMeshBuilder_iface);
}

290 291 292 293 294 295 296 297 298 299 300 301 302
HRESULT Direct3DRMMeshBuilder_create(LPDIRECT3DRMMESHBUILDER* ppMeshBuilder)
{
    IDirect3DRMMeshBuilderImpl* object;

    TRACE("(%p)\n", ppMeshBuilder);

    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DRMMeshBuilderImpl));
    if (!object)
    {
        ERR("Out of memory\n");
        return E_OUTOFMEMORY;
    }

303
    object->IDirect3DRMMeshBuilder_iface.lpVtbl = &Direct3DRMMeshBuilder_Vtbl;
304 305 306 307 308 309 310 311 312 313
    object->ref = 1;

    *ppMeshBuilder = (IDirect3DRMMeshBuilder*)object;

    return S_OK;
}

/*** IUnknown methods ***/
static HRESULT WINAPI IDirect3DRMMeshBuilderImpl_QueryInterface(IDirect3DRMMeshBuilder* iface, REFIID riid, void** ppvObject)
{
314
    IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder(iface);
315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331

    TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid), ppvObject);

    if (IsEqualGUID(riid, &IID_IUnknown) ||
        IsEqualGUID(riid, &IID_IDirect3DRMMeshBuilder))
    {
        IClassFactory_AddRef(iface);
        *ppvObject = This;
        return S_OK;
    }

    ERR("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
    return E_NOINTERFACE;
}

static ULONG WINAPI IDirect3DRMMeshBuilderImpl_AddRef(IDirect3DRMMeshBuilder* iface)
{
332
    IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder(iface);
333 334 335 336 337 338 339 340

    TRACE("(%p)\n", This);

    return InterlockedIncrement(&This->ref);
}

static ULONG WINAPI IDirect3DRMMeshBuilderImpl_Release(IDirect3DRMMeshBuilder* iface)
{
341
    IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder(iface);
342 343 344 345 346
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p)\n", This);

    if (!ref)
347 348 349 350
    {
        HeapFree(GetProcessHeap(), 0, This->pVertices);
        HeapFree(GetProcessHeap(), 0, This->pNormals);
        HeapFree(GetProcessHeap(), 0, This->pFaceData);
351
        HeapFree(GetProcessHeap(), 0, This);
352
    }
353 354 355 356 357 358 359

    return ref;
}

/*** IDirect3DRMObject methods ***/
static HRESULT WINAPI IDirect3DRMMeshBuilderImpl_Clone(IDirect3DRMMeshBuilder* iface, LPUNKNOWN pUnkOuter, REFIID riid, LPVOID *ppvObj)
{
360
    IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder(iface);
361 362 363 364 365 366 367 368

    FIXME("(%p)->(%p,%s,%p): stub\n", This, pUnkOuter, debugstr_guid(riid), ppvObj);

    return E_NOTIMPL;
}

static HRESULT WINAPI IDirect3DRMMeshBuilderImpl_AddDestroyCallback(IDirect3DRMMeshBuilder* iface, D3DRMOBJECTCALLBACK cb, LPVOID argument)
{
369
    IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder(iface);
370 371 372 373 374 375 376 377

    FIXME("(%p)->(%p,%p): stub\n", This, cb, argument);

    return E_NOTIMPL;
}

static HRESULT WINAPI IDirect3DRMMeshBuilderImpl_DeleteDestroyCallback(IDirect3DRMMeshBuilder* iface, D3DRMOBJECTCALLBACK cb, LPVOID argument)
{
378
    IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder(iface);
379 380 381 382 383 384 385 386

    FIXME("(%p)->(%p,%p): stub\n", This, cb, argument);

    return E_NOTIMPL;
}

static HRESULT WINAPI IDirect3DRMMeshBuilderImpl_SetAppData(IDirect3DRMMeshBuilder* iface, DWORD data)
{
387
    IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder(iface);
388 389 390 391 392 393 394 395

    FIXME("(%p)->(%u): stub\n", This, data);

    return E_NOTIMPL;
}

static DWORD WINAPI IDirect3DRMMeshBuilderImpl_GetAppData(IDirect3DRMMeshBuilder* iface)
{
396
    IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder(iface);
397 398 399 400 401 402 403 404

    FIXME("(%p)->(): stub\n", This);

    return 0;
}

static HRESULT WINAPI IDirect3DRMMeshBuilderImpl_SetName(IDirect3DRMMeshBuilder* iface, LPCSTR pName)
{
405
    IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder(iface);
406 407 408 409 410 411 412 413

    FIXME("(%p)->(%s): stub\n", This, pName);

    return E_NOTIMPL;
}

static HRESULT WINAPI IDirect3DRMMeshBuilderImpl_GetName(IDirect3DRMMeshBuilder* iface, LPDWORD lpdwSize, LPSTR lpName)
{
414
    IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder(iface);
415 416 417 418 419 420 421 422

    FIXME("(%p)->(%p,%p): stub\n", This, lpdwSize, lpName);

    return E_NOTIMPL;
}

static HRESULT WINAPI IDirect3DRMMeshBuilderImpl_GetClassName(IDirect3DRMMeshBuilder* iface, LPDWORD lpdwSize, LPSTR lpName)
{
423
    IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder(iface);
424 425 426 427 428 429 430 431 432

    FIXME("(%p)->(%p,%p): stub\n", This, lpdwSize, lpName);

    return E_NOTIMPL;
}

/*** IDirect3DRMMeshBuilder methods ***/
static HRESULT WINAPI IDirect3DRMMeshBuilderImpl_Load(IDirect3DRMMeshBuilder* iface, LPVOID filename, LPVOID name, D3DRMLOADOPTIONS loadflags, D3DRMLOADTEXTURECALLBACK cb, LPVOID pArg)
{
433
    IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder(iface);
434 435 436 437
    DXFILELOADOPTIONS load_options;
    LPDIRECTXFILE pDXFile = NULL;
    LPDIRECTXFILEENUMOBJECT pEnumObject = NULL;
    LPDIRECTXFILEDATA pData = NULL;
438 439
    LPDIRECTXFILEOBJECT pObject = NULL;
    LPDIRECTXFILEDATA pData2 = NULL;
440
    const GUID* pGuid;
441 442
    DWORD size;
    Header* pHeader;
443
    LPBYTE ptr;
444 445
    HRESULT hr;
    HRESULT ret = D3DRMERR_BADOBJECT;
446

447
    FIXME("(%p)->(%p,%p,%x,%p,%p): partial stub\n", This, filename, name, loadflags, cb, pArg);
448

449 450 451 452 453 454 455
    /* First free allocated buffers of previous mesh data */
    HeapFree(GetProcessHeap(), 0, This->pVertices);
    This->pVertices = NULL;
    HeapFree(GetProcessHeap(), 0, This->pNormals);
    This->pNormals = NULL;
    HeapFree(GetProcessHeap(), 0, This->pFaceData);
    This->pFaceData = NULL;
456 457
    HeapFree(GetProcessHeap(), 0, This->pCoords2d);
    This->pCoords2d = NULL;
458

459 460 461 462 463 464 465 466 467 468 469 470 471 472
    if (loadflags == D3DRMLOAD_FROMMEMORY)
    {
        load_options = DXFILELOAD_FROMMEMORY;
    }
    else
    {
        FIXME("Load options %d not supported yet\n", loadflags);
        return E_NOTIMPL;
    }

    hr = DirectXFileCreate(&pDXFile);
    if (hr != DXFILE_OK)
        goto end;

473
    hr = IDirectXFile_RegisterTemplates(pDXFile, templates, strlen(templates));
474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490
    if (hr != DXFILE_OK)
        goto end;

    hr = IDirectXFile_CreateEnumObject(pDXFile, filename, load_options, &pEnumObject);
    if (hr != DXFILE_OK)
        goto end;

    hr = IDirectXFileEnumObject_GetNextDataObject(pEnumObject, &pData);
    if (hr != DXFILE_OK)
        goto end;

    hr = IDirectXFileData_GetType(pData, &pGuid);
    if (hr != DXFILE_OK)
        goto end;

    TRACE("Found object type whose GUID = %s\n", debugstr_guid(pGuid));

491
    if (!IsEqualGUID(pGuid, &TID_DXFILEHeader))
492 493 494 495 496
    {
        ret = D3DRMERR_BADFILE;
        goto end;
    }

497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525
    hr = IDirectXFileData_GetData(pData, NULL, &size, (void**)&pHeader);
    if ((hr != DXFILE_OK) || (size != sizeof(Header)))
        goto end;

    TRACE("Version is %d %d %d\n", pHeader->major, pHeader->minor, pHeader->flags);

    /* Version must be 1.0.x */
    if ((pHeader->major != 1) || (pHeader->minor != 0))
    {
        ret = D3DRMERR_BADFILE;
        goto end;
    }

    IDirectXFileData_Release(pData);
    pData = NULL;

    hr = IDirectXFileEnumObject_GetNextDataObject(pEnumObject, &pData);
    if (hr != DXFILE_OK)
    {
        ret = D3DRMERR_NOTFOUND;
        goto end;
    }

    hr = IDirectXFileData_GetType(pData, &pGuid);
    if (hr != DXFILE_OK)
        goto end;

    TRACE("Found object type whose GUID = %s\n", debugstr_guid(pGuid));

526
    if (!IsEqualGUID(pGuid, &TID_D3DRMMesh))
527 528 529 530 531
    {
        ret = D3DRMERR_NOTFOUND;
        goto end;
    }

532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547
    hr = IDirectXFileData_GetData(pData, NULL, &size, (void**)&ptr);
    if (hr != DXFILE_OK)
        goto end;

    This->nb_vertices = *(DWORD*)ptr;
    This->nb_faces = *(DWORD*)(ptr + sizeof(DWORD) + This->nb_vertices * sizeof(D3DVECTOR));
    This->face_data_size = size - sizeof(DWORD) - This->nb_vertices * sizeof(D3DVECTOR) - sizeof(DWORD);

    TRACE("Mesh: nb_vertices = %d, nb_faces = %d, face_data_size = %d\n", This->nb_vertices, This->nb_faces, This->face_data_size);

    This->pVertices = HeapAlloc(GetProcessHeap(), 0, This->nb_vertices * sizeof(D3DVECTOR));
    memcpy(This->pVertices, ptr + sizeof(DWORD), This->nb_vertices * sizeof(D3DVECTOR));

    This->pFaceData = HeapAlloc(GetProcessHeap(), 0, This->face_data_size);
    memcpy(This->pFaceData, ptr + sizeof(DWORD) + This->nb_vertices * sizeof(D3DVECTOR) + sizeof(DWORD), This->face_data_size);

548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570
    while (1)
    {
        hr =  IDirectXFileData_GetNextObject(pData, &pObject);
        if (hr == DXFILEERR_NOMOREOBJECTS)
        {
	    FIXME("no more object\n");
            break;
        }
        if (hr != DXFILE_OK)
           goto end;

            hr = IDirectXFileObject_QueryInterface(pObject, &IID_IDirectXFileData, (void**)&pData2);
        IDirectXFileObject_Release(pObject);
        if (hr != DXFILE_OK)
            goto end;

        hr = IDirectXFileData_GetType(pData2, &pGuid);
        if (hr != DXFILE_OK)
        {
            IDirectXFileData_Release(pData2);
            goto end;
        }

571
        FIXME("Found object type whose GUID = %s\n", debugstr_guid(pGuid));
572

573
        if (!IsEqualGUID(pGuid, &TID_D3DRMMeshNormals))
574 575 576 577 578 579 580 581 582 583 584 585 586 587 588
        {
            DWORD tmp;

            hr = IDirectXFileData_GetData(pData, NULL, &size, (void**)&ptr);
            if (hr != DXFILE_OK)
                goto end;

            This->nb_normals = *(DWORD*)ptr;
            tmp = *(DWORD*)(ptr + sizeof(DWORD) + This->nb_normals * sizeof(D3DVECTOR));

            FIXME("MeshNormals: nb_normals = %d, nb_faces_normals = %d\n", This->nb_normals, tmp);

            This->pNormals = HeapAlloc(GetProcessHeap(), 0, This->nb_normals * sizeof(D3DVECTOR));
            memcpy(This->pNormals, ptr + sizeof(DWORD), This->nb_normals * sizeof(D3DVECTOR));
        }
589
        else if(!IsEqualGUID(pGuid, &TID_D3DRMMeshTextureCoords))
590 591 592 593 594 595 596 597 598 599 600 601 602
        {
            hr = IDirectXFileData_GetData(pData, NULL, &size, (void**)&ptr);
            if (hr != DXFILE_OK)
                goto end;

            This->nb_coords2d = *(DWORD*)ptr;

            FIXME("MeshTextureCoords: nb_coords2d = %d\n", This->nb_coords2d);

            This->pCoords2d = HeapAlloc(GetProcessHeap(), 0, This->nb_coords2d * sizeof(Coords2d));
            memcpy(This->pCoords2d, ptr + sizeof(DWORD), This->nb_coords2d * sizeof(Coords2d));

        }
603
        else if(!IsEqualGUID(pGuid, &TID_D3DRMMeshMaterialList))
604 605 606 607 608 609 610 611 612 613 614
        {
            FIXME("MeshMaterialList not supported yet, ignoring...\n");
        }
	else
        {
            FIXME("Unknown GUID %s, ignoring...\n", debugstr_guid(pGuid));
        }

        IDirectXFileData_Release(pData2);
    }

615 616 617 618 619 620 621 622 623 624
    ret = D3DRM_OK;

end:
    if (pData)
        IDirectXFileData_Release(pData);
    if (pEnumObject)
        IDirectXFileEnumObject_Release(pEnumObject);
    if (pDXFile)
        IDirectXFile_Release(pDXFile);

625
    if (ret != D3DRM_OK)
626 627 628 629 630 631
    {
        /* Clean mesh data */
        This->nb_vertices = 0;
        This->nb_normals = 0;
        This->nb_faces = 0;
        This->face_data_size = 0;
632
        This->nb_coords2d = 0;
633 634 635 636 637 638
        HeapFree(GetProcessHeap(), 0, This->pVertices);
        This->pVertices = NULL;
        HeapFree(GetProcessHeap(), 0, This->pNormals);
        This->pNormals = NULL;
        HeapFree(GetProcessHeap(), 0, This->pFaceData);
        This->pFaceData = NULL;
639 640
        HeapFree(GetProcessHeap(), 0, This->pCoords2d);
        This->pCoords2d = NULL;
641 642
    }

643
    return ret;
644 645 646 647
}

static HRESULT WINAPI IDirect3DRMMeshBuilderImpl_Save(IDirect3DRMMeshBuilder* iface, const char *filename, D3DRMXOFFORMAT format, D3DRMSAVEOPTIONS save)
{
648
    IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder(iface);
649 650 651 652 653 654 655 656

    FIXME("(%p)->(%s,%d,%d): stub\n", This, filename, format, save);

    return E_NOTIMPL;
}

static HRESULT WINAPI IDirect3DRMMeshBuilderImpl_Scale(IDirect3DRMMeshBuilder* iface, D3DVALUE sx, D3DVALUE sy, D3DVALUE sz)
{
657
    IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder(iface);
658 659 660 661 662 663 664 665

    FIXME("(%p)->(%f,%f,%f): stub\n", This, sx, sy, sz);

    return E_NOTIMPL;
}

static HRESULT WINAPI IDirect3DRMMeshBuilderImpl_Translate(IDirect3DRMMeshBuilder* iface, D3DVALUE tx, D3DVALUE ty, D3DVALUE tz)
{
666
    IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder(iface);
667 668 669 670 671 672 673 674

    FIXME("(%p)->(%f,%f,%f): stub\n", This, tx, ty, tz);

    return E_NOTIMPL;
}

static HRESULT WINAPI IDirect3DRMMeshBuilderImpl_SetColorSource(IDirect3DRMMeshBuilder* iface, D3DRMCOLORSOURCE color)
{
675
    IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder(iface);
676 677 678 679 680 681 682 683

    FIXME("(%p)->(%x): stub\n", This, color);

    return E_NOTIMPL;
}

static HRESULT WINAPI IDirect3DRMMeshBuilderImpl_GetBox(IDirect3DRMMeshBuilder* iface, D3DRMBOX *pBox)
{
684
    IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder(iface);
685 686 687 688 689 690 691 692

    FIXME("(%p)->(%p): stub\n", This, pBox);

    return E_NOTIMPL;
}

static HRESULT WINAPI IDirect3DRMMeshBuilderImpl_GenerateNormals(IDirect3DRMMeshBuilder* iface)
{
693
    IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder(iface);
694 695 696 697 698 699 700 701

    FIXME("(%p)->(): stub\n", This);

    return E_NOTIMPL;
}

static D3DRMCOLORSOURCE WINAPI IDirect3DRMMeshBuilderImpl_GetColorSource(IDirect3DRMMeshBuilder* iface)
{
702
    IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder(iface);
703 704 705 706 707 708 709 710

    FIXME("(%p)->(): stub\n", This);

    return E_NOTIMPL;
}

static HRESULT WINAPI IDirect3DRMMeshBuilderImpl_AddMesh(IDirect3DRMMeshBuilder* iface, LPDIRECT3DRMMESH pMesh)
{
711
    IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder(iface);
712 713 714 715 716 717 718 719

    FIXME("(%p)->(%p): stub\n", This, pMesh);

    return E_NOTIMPL;
}

static HRESULT WINAPI IDirect3DRMMeshBuilderImpl_AddMeshBuilder(IDirect3DRMMeshBuilder* iface, LPDIRECT3DRMMESHBUILDER pMeshBuilder)
{
720
    IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder(iface);
721 722 723 724 725 726 727 728

    FIXME("(%p)->(%p): stub\n", This, pMeshBuilder);

    return E_NOTIMPL;
}

static HRESULT WINAPI IDirect3DRMMeshBuilderImpl_AddFrame(IDirect3DRMMeshBuilder* iface, LPDIRECT3DRMFRAME pFrame)
{
729
    IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder(iface);
730 731 732 733 734 735 736 737

    FIXME("(%p)->(%p): stub\n", This, pFrame);

    return E_NOTIMPL;
}

static HRESULT WINAPI IDirect3DRMMeshBuilderImpl_AddFace(IDirect3DRMMeshBuilder* iface, LPDIRECT3DRMFACE pFace)
{
738
    IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder(iface);
739 740 741 742 743 744 745 746

    FIXME("(%p)->(%p): stub\n", This, pFace);

    return E_NOTIMPL;
}

static HRESULT WINAPI IDirect3DRMMeshBuilderImpl_AddFaces(IDirect3DRMMeshBuilder* iface, DWORD vcount, D3DVECTOR *vertices, DWORD ncount, D3DVECTOR *normals, DWORD *data, LPDIRECT3DRMFACEARRAY* pFaceArray)
{
747
    IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder(iface);
748 749 750 751 752 753 754 755

    FIXME("(%p)->(%d,%p,%d,%p,%p,%p): stub\n", This, vcount, vertices, ncount, normals, data, pFaceArray);

    return E_NOTIMPL;
}

static HRESULT WINAPI IDirect3DRMMeshBuilderImpl_ReserveSpace(IDirect3DRMMeshBuilder* iface, DWORD vertex_Count, DWORD normal_count, DWORD face_count)
{
756
    IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder(iface);
757 758 759 760 761 762 763 764

    FIXME("(%p)->(%d,%d,%d): stub\n", This, vertex_Count, normal_count, face_count);

    return E_NOTIMPL;
}

static HRESULT WINAPI IDirect3DRMMeshBuilderImpl_SetColorRGB(IDirect3DRMMeshBuilder* iface, D3DVALUE red, D3DVALUE green, D3DVALUE blue)
{
765
    IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder(iface);
766 767 768 769 770 771 772 773

    FIXME("(%p)->(%f,%f,%f): stub\n", This, red, green, blue);

    return E_NOTIMPL;
}

static HRESULT WINAPI IDirect3DRMMeshBuilderImpl_SetColor(IDirect3DRMMeshBuilder* iface, D3DCOLOR color)
{
774
    IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder(iface);
775 776 777 778 779 780 781 782

    FIXME("(%p)->(%x): stub\n", This, color);

    return E_NOTIMPL;
}

static HRESULT WINAPI IDirect3DRMMeshBuilderImpl_SetTexture(IDirect3DRMMeshBuilder* iface, LPDIRECT3DRMTEXTURE pTexture)
{
783
    IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder(iface);
784 785 786 787 788 789 790 791

    FIXME("(%p)->(%p): stub\n", This, pTexture);

    return E_NOTIMPL;
}

static HRESULT WINAPI IDirect3DRMMeshBuilderImpl_SetMaterial(IDirect3DRMMeshBuilder* iface, LPDIRECT3DRMMATERIAL pMaterial)
{
792
    IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder(iface);
793 794 795 796 797 798 799 800

    FIXME("(%p)->(%p): stub\n", This, pMaterial);

    return E_NOTIMPL;
}

static HRESULT WINAPI IDirect3DRMMeshBuilderImpl_SetTextureTopology(IDirect3DRMMeshBuilder* iface, BOOL wrap_u, BOOL wrap_v)
{
801
    IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder(iface);
802 803 804 805 806 807 808 809

    FIXME("(%p)->(%d,%d): stub\n", This, wrap_u, wrap_v);

    return E_NOTIMPL;
}

static HRESULT WINAPI IDirect3DRMMeshBuilderImpl_SetQuality(IDirect3DRMMeshBuilder* iface, D3DRMRENDERQUALITY quality)
{
810
    IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder(iface);
811 812 813 814 815 816 817 818

    FIXME("(%p)->(%d): stub\n", This, quality);

    return E_NOTIMPL;
}

static HRESULT WINAPI IDirect3DRMMeshBuilderImpl_SetPerspective(IDirect3DRMMeshBuilder* iface, BOOL enable)
{
819
    IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder(iface);
820 821 822 823 824 825 826 827

    FIXME("(%p)->(%d): stub\n", This, enable);

    return E_NOTIMPL;
}

static HRESULT WINAPI IDirect3DRMMeshBuilderImpl_SetVertex(IDirect3DRMMeshBuilder* iface, DWORD index, D3DVALUE x, D3DVALUE y, D3DVALUE z)
{
828
    IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder(iface);
829 830 831 832 833 834 835 836

    FIXME("(%p)->(%f,%f,%f): stub\n", This, x, y, z);

    return E_NOTIMPL;
}

static HRESULT WINAPI IDirect3DRMMeshBuilderImpl_SetNormal(IDirect3DRMMeshBuilder* iface, DWORD index, D3DVALUE x, D3DVALUE y, D3DVALUE z)
{
837
    IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder(iface);
838 839 840 841 842 843 844 845

    FIXME("(%p)->(%f,%f,%f): stub\n", This, x, y, z);

    return E_NOTIMPL;
}

static HRESULT WINAPI IDirect3DRMMeshBuilderImpl_SetTextureCoordinates(IDirect3DRMMeshBuilder* iface, DWORD index, D3DVALUE u, D3DVALUE v)
{
846
    IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder(iface);
847 848 849 850 851 852 853 854

    FIXME("(%p)->(%f,%f): stub\n", This, u, v);

    return E_NOTIMPL;
}

static HRESULT WINAPI IDirect3DRMMeshBuilderImpl_SetVertexColor(IDirect3DRMMeshBuilder* iface, DWORD index, D3DCOLOR color)
{
855
    IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder(iface);
856 857 858 859 860 861 862 863

    FIXME("(%p)->(%d,%x): stub\n", This, index, color);

    return E_NOTIMPL;
}

static HRESULT WINAPI IDirect3DRMMeshBuilderImpl_SetVertexColorRGB(IDirect3DRMMeshBuilder* iface, DWORD index, D3DVALUE red, D3DVALUE green, D3DVALUE blue)
{
864
    IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder(iface);
865 866 867 868 869 870 871 872

    FIXME("(%p)->(%d,%f,%f,%f): stub\n", This, index, red, green, blue);

    return E_NOTIMPL;
}

static HRESULT WINAPI IDirect3DRMMeshBuilderImpl_GetFaces(IDirect3DRMMeshBuilder* iface, LPDIRECT3DRMFACEARRAY* pFaceArray)
{
873
    IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder(iface);
874 875 876 877 878 879 880 881

    FIXME("(%p)->(%p): stub\n", This, pFaceArray);

    return E_NOTIMPL;
}

static HRESULT WINAPI IDirect3DRMMeshBuilderImpl_GetVertices(IDirect3DRMMeshBuilder* iface, DWORD *vcount, D3DVECTOR *vertices, DWORD *ncount, D3DVECTOR *normals, DWORD *face_data_size, DWORD *face_data)
{
882
    IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder(iface);
883

884
    TRACE("(%p)->(%p,%p,%p,%p,%p,%p)\n", This, vcount, vertices, ncount, normals, face_data_size, face_data);
885

886 887 888 889 890 891 892 893 894 895 896 897 898 899
    if (vcount)
        *vcount = This->nb_vertices;
    if (vertices && This->nb_vertices)
        memcpy(vertices, This->pVertices, This->nb_vertices * sizeof(D3DVECTOR));
    if (ncount)
        *ncount = This->nb_normals;
    if (normals && This->nb_normals)
        memcpy(normals, This->pNormals, This->nb_normals * sizeof(D3DVECTOR));
    if (face_data_size)
        *face_data_size = This->face_data_size;
    if (face_data && This->face_data_size)
        memcpy(face_data, This->pFaceData, This->face_data_size);

    return D3DRM_OK;
900 901 902 903
}

static HRESULT WINAPI IDirect3DRMMeshBuilderImpl_GetTextureCoordinates(IDirect3DRMMeshBuilder* iface, DWORD index, D3DVALUE *u, D3DVALUE *v)
{
904
    IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder(iface);
905 906 907

    FIXME("(%p)->(%d,%p,%p): stub\n", This, index, u, v);

908 909 910 911 912 913 914
    if (index >= This->nb_coords2d)
        return D3DRMERR_NOTFOUND;

    *u = This->pCoords2d[index].u;
    *v = This->pCoords2d[index].v;

    return D3DRM_OK;
915 916 917 918
}

static int WINAPI IDirect3DRMMeshBuilderImpl_AddVertex(IDirect3DRMMeshBuilder* iface, D3DVALUE x, D3DVALUE y, D3DVALUE z)
{
919
    IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder(iface);
920 921 922 923 924 925 926 927

    FIXME("(%p)->(%f,%f,%f): stub\n", This, x, y, z);

    return 0;
}

static int WINAPI IDirect3DRMMeshBuilderImpl_AddNormal(IDirect3DRMMeshBuilder* iface, D3DVALUE x, D3DVALUE y, D3DVALUE z)
{
928
    IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder(iface);
929 930 931 932 933 934 935 936

    FIXME("(%p)->(%f,%f,%f): stub\n", This, x, y, z);

    return 0;
}

static HRESULT WINAPI IDirect3DRMMeshBuilderImpl_CreateFace(IDirect3DRMMeshBuilder* iface, LPDIRECT3DRMFACE* ppFace)
{
937
    IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder(iface);
938 939 940 941 942 943 944 945

    FIXME("(%p)->(%p): stub\n", This, ppFace);

    return E_NOTIMPL;
}

static D3DRMRENDERQUALITY WINAPI IDirect3DRMMeshBuilderImpl_GetQuality(IDirect3DRMMeshBuilder* iface)
{
946
    IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder(iface);
947 948 949 950 951 952 953 954

    FIXME("(%p)->(): stub\n", This);

    return 0;
}

static BOOL WINAPI IDirect3DRMMeshBuilderImpl_GetPerspective(IDirect3DRMMeshBuilder* iface)
{
955
    IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder(iface);
956 957 958 959 960 961 962 963

    FIXME("(%p)->(): stub\n", This);

    return FALSE;
}

static int WINAPI IDirect3DRMMeshBuilderImpl_GetFaceCount(IDirect3DRMMeshBuilder* iface)
{
964
    IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder(iface);
965

966
    TRACE("(%p)->()\n", This);
967

968
    return This->nb_faces;
969 970 971 972
}

static int WINAPI IDirect3DRMMeshBuilderImpl_GetVertexCount(IDirect3DRMMeshBuilder* iface)
{
973
    IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder(iface);
974

975
    TRACE("(%p)->()\n", This);
976

977
    return This->nb_vertices;
978 979 980 981
}

static D3DCOLOR WINAPI IDirect3DRMMeshBuilderImpl_GetVertexColor(IDirect3DRMMeshBuilder* iface, DWORD index)
{
982
    IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder(iface);
983 984 985 986 987 988 989 990

    FIXME("(%p)->(%d): stub\n", This, index);

    return 0;
}

static HRESULT WINAPI IDirect3DRMMeshBuilderImpl_CreateMesh(IDirect3DRMMeshBuilder* iface, LPDIRECT3DRMMESH* ppMesh)
{
991
    IDirect3DRMMeshBuilderImpl *This = impl_from_IDirect3DRMMeshBuilder(iface);
992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052

    FIXME("(%p)->(%p): stub\n", This, ppMesh);

    return E_NOTIMPL;
}

static const struct IDirect3DRMMeshBuilderVtbl Direct3DRMMeshBuilder_Vtbl =
{
    /*** IUnknown methods ***/
    IDirect3DRMMeshBuilderImpl_QueryInterface,
    IDirect3DRMMeshBuilderImpl_AddRef,
    IDirect3DRMMeshBuilderImpl_Release,
    /*** IDirect3DRMObject methods ***/
    IDirect3DRMMeshBuilderImpl_Clone,
    IDirect3DRMMeshBuilderImpl_AddDestroyCallback,
    IDirect3DRMMeshBuilderImpl_DeleteDestroyCallback,
    IDirect3DRMMeshBuilderImpl_SetAppData,
    IDirect3DRMMeshBuilderImpl_GetAppData,
    IDirect3DRMMeshBuilderImpl_SetName,
    IDirect3DRMMeshBuilderImpl_GetName,
    IDirect3DRMMeshBuilderImpl_GetClassName,
    /*** IDirect3DRMMeshBuilder methods ***/
    IDirect3DRMMeshBuilderImpl_Load,
    IDirect3DRMMeshBuilderImpl_Save,
    IDirect3DRMMeshBuilderImpl_Scale,
    IDirect3DRMMeshBuilderImpl_Translate,
    IDirect3DRMMeshBuilderImpl_SetColorSource,
    IDirect3DRMMeshBuilderImpl_GetBox,
    IDirect3DRMMeshBuilderImpl_GenerateNormals,
    IDirect3DRMMeshBuilderImpl_GetColorSource,
    IDirect3DRMMeshBuilderImpl_AddMesh,
    IDirect3DRMMeshBuilderImpl_AddMeshBuilder,
    IDirect3DRMMeshBuilderImpl_AddFrame,
    IDirect3DRMMeshBuilderImpl_AddFace,
    IDirect3DRMMeshBuilderImpl_AddFaces,
    IDirect3DRMMeshBuilderImpl_ReserveSpace,
    IDirect3DRMMeshBuilderImpl_SetColorRGB,
    IDirect3DRMMeshBuilderImpl_SetColor,
    IDirect3DRMMeshBuilderImpl_SetTexture,
    IDirect3DRMMeshBuilderImpl_SetMaterial,
    IDirect3DRMMeshBuilderImpl_SetTextureTopology,
    IDirect3DRMMeshBuilderImpl_SetQuality,
    IDirect3DRMMeshBuilderImpl_SetPerspective,
    IDirect3DRMMeshBuilderImpl_SetVertex,
    IDirect3DRMMeshBuilderImpl_SetNormal,
    IDirect3DRMMeshBuilderImpl_SetTextureCoordinates,
    IDirect3DRMMeshBuilderImpl_SetVertexColor,
    IDirect3DRMMeshBuilderImpl_SetVertexColorRGB,
    IDirect3DRMMeshBuilderImpl_GetFaces,
    IDirect3DRMMeshBuilderImpl_GetVertices,
    IDirect3DRMMeshBuilderImpl_GetTextureCoordinates,
    IDirect3DRMMeshBuilderImpl_AddVertex,
    IDirect3DRMMeshBuilderImpl_AddNormal,
    IDirect3DRMMeshBuilderImpl_CreateFace,
    IDirect3DRMMeshBuilderImpl_GetQuality,
    IDirect3DRMMeshBuilderImpl_GetPerspective,
    IDirect3DRMMeshBuilderImpl_GetFaceCount,
    IDirect3DRMMeshBuilderImpl_GetVertexCount,
    IDirect3DRMMeshBuilderImpl_GetVertexColor,
    IDirect3DRMMeshBuilderImpl_CreateMesh
};