d3drm.c 69.4 KB
Newer Older
1 2 3
/*
 * Implementation of IDirect3DRM Interface
 *
4
 * Copyright 2010, 2012 Christian Costa
5
 * Copyright 2011 André Hentschel
6
 * Copyright 2016 Aaryaman Vasishta
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
 *
 * 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 "d3drm_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(d3drm);

27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
static const char* get_IID_string(const GUID* guid)
{
    if (IsEqualGUID(guid, &IID_IDirect3DRMFrame))
        return "IID_IDirect3DRMFrame";
    else if (IsEqualGUID(guid, &IID_IDirect3DRMFrame2))
        return "IID_IDirect3DRMFrame2";
    else if (IsEqualGUID(guid, &IID_IDirect3DRMFrame3))
        return "IID_IDirect3DRMFrame3";
    else if (IsEqualGUID(guid, &IID_IDirect3DRMMeshBuilder))
        return "IID_IDirect3DRMMeshBuilder";
    else if (IsEqualGUID(guid, &IID_IDirect3DRMMeshBuilder2))
        return "IID_IDirect3DRMMeshBuilder2";
    else if (IsEqualGUID(guid, &IID_IDirect3DRMMeshBuilder3))
        return "IID_IDirect3DRMMeshBuilder3";

    return "?";
}

45 46 47 48 49 50 51 52 53 54 55 56 57
static HRESULT d3drm_create_texture_object(void **object, IDirect3DRM *d3drm)
{
    struct d3drm_texture *texture;
    HRESULT hr;

    if (FAILED(hr = d3drm_texture_create(&texture, d3drm)))
        return hr;

    *object = &texture->IDirect3DRMTexture_iface;

    return hr;
}

58 59 60 61 62 63 64 65 66 67 68 69 70
static HRESULT d3drm_create_device_object(void **object, IDirect3DRM *d3drm)
{
    struct d3drm_device *device;
    HRESULT hr;

    if (FAILED(hr = d3drm_device_create(&device, d3drm)))
        return hr;

    *object = &device->IDirect3DRMDevice_iface;

    return hr;
}

71 72 73 74 75 76 77 78 79 80 81 82 83
static HRESULT d3drm_create_viewport_object(void **object, IDirect3DRM *d3drm)
{
    struct d3drm_viewport *viewport;
    HRESULT hr;

    if (FAILED(hr = d3drm_viewport_create(&viewport, d3drm)))
        return hr;

    *object = &viewport->IDirect3DRMViewport_iface;

    return hr;
}

84 85 86 87 88 89 90 91 92 93 94 95 96
static HRESULT d3drm_create_face_object(void **object, IDirect3DRM *d3drm)
{
    struct d3drm_face *face;
    HRESULT hr;

    if (FAILED(hr = d3drm_face_create(&face)))
        return hr;

    *object = &face->IDirect3DRMFace_iface;

    return hr;
}

97 98 99 100 101 102 103 104 105 106 107 108 109
static HRESULT d3drm_create_mesh_builder_object(void **object, IDirect3DRM *d3drm)
{
    struct d3drm_mesh_builder *mesh_builder;
    HRESULT hr;

    if (FAILED(hr = d3drm_mesh_builder_create(&mesh_builder, d3drm)))
        return hr;

    *object = &mesh_builder->IDirect3DRMMeshBuilder2_iface;

    return hr;
}

110 111 112 113 114 115 116 117 118 119 120 121 122
static HRESULT d3drm_create_frame_object(void **object, IDirect3DRM *d3drm)
{
    struct d3drm_frame *frame;
    HRESULT hr;

    if (FAILED(hr = d3drm_frame_create(&frame, NULL, d3drm)))
        return hr;

    *object = &frame->IDirect3DRMFrame_iface;

    return hr;
}

123 124 125 126 127 128 129 130 131 132 133 134 135
static HRESULT d3drm_create_light_object(void **object, IDirect3DRM *d3drm)
{
    struct d3drm_light *light;
    HRESULT hr;

    if (FAILED(hr = d3drm_light_create(&light, d3drm)))
        return hr;

    *object = &light->IDirect3DRMLight_iface;

    return hr;
}

136 137 138 139 140 141 142 143 144 145 146 147 148
static HRESULT d3drm_create_material_object(void **object, IDirect3DRM *d3drm)
{
    struct d3drm_material *material;
    HRESULT hr;

    if (FAILED(hr = d3drm_material_create(&material, d3drm)))
        return hr;

    *object = &material->IDirect3DRMMaterial2_iface;

    return hr;
}

149 150 151 152 153 154 155 156 157 158 159 160 161
static HRESULT d3drm_create_mesh_object(void **object, IDirect3DRM *d3drm)
{
    struct d3drm_mesh *mesh;
    HRESULT hr;

    if (FAILED(hr = d3drm_mesh_create(&mesh, d3drm)))
        return hr;

    *object = &mesh->IDirect3DRMMesh_iface;

    return hr;
}

162 163 164 165 166 167 168 169 170 171 172 173 174
static HRESULT d3drm_create_animation_object(void **object, IDirect3DRM *d3drm)
{
    struct d3drm_animation *animation;
    HRESULT hr;

    if (FAILED(hr = d3drm_animation_create(&animation, d3drm)))
        return hr;

    *object = &animation->IDirect3DRMAnimation_iface;

    return hr;
}

175 176 177 178 179 180 181 182 183 184 185 186 187
static HRESULT d3drm_create_wrap_object(void **object, IDirect3DRM *d3drm)
{
    struct d3drm_wrap *wrap;
    HRESULT hr;

    if (FAILED(hr = d3drm_wrap_create(&wrap, d3drm)))
        return hr;

    *object = &wrap->IDirect3DRMWrap_iface;

    return hr;
}

188 189
struct d3drm
{
190
    IDirect3DRM IDirect3DRM_iface;
191
    IDirect3DRM2 IDirect3DRM2_iface;
192
    IDirect3DRM3 IDirect3DRM3_iface;
193
    LONG ref1, ref2, ref3, iface_count;
194
};
195

196
static inline struct d3drm *impl_from_IDirect3DRM(IDirect3DRM *iface)
197
{
198
    return CONTAINING_RECORD(iface, struct d3drm, IDirect3DRM_iface);
199 200
}

201
static inline struct d3drm *impl_from_IDirect3DRM2(IDirect3DRM2 *iface)
202
{
203
    return CONTAINING_RECORD(iface, struct d3drm, IDirect3DRM2_iface);
204 205
}

206
static inline struct d3drm *impl_from_IDirect3DRM3(IDirect3DRM3 *iface)
207
{
208
    return CONTAINING_RECORD(iface, struct d3drm, IDirect3DRM3_iface);
209 210
}

211 212
static void d3drm_destroy(struct d3drm *d3drm)
{
213
    heap_free(d3drm);
214 215 216
    TRACE("d3drm object %p is being destroyed.\n", d3drm);
}

217
static HRESULT WINAPI d3drm1_QueryInterface(IDirect3DRM *iface, REFIID riid, void **out)
218
{
219
    struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
220

221
    TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
222

223 224
    if (IsEqualGUID(riid, &IID_IDirect3DRM)
            || IsEqualGUID(riid, &IID_IUnknown))
225
    {
226
        *out = &d3drm->IDirect3DRM_iface;
227
    }
228
    else if (IsEqualGUID(riid, &IID_IDirect3DRM2))
229
    {
230
        *out = &d3drm->IDirect3DRM2_iface;
231
    }
232
    else if (IsEqualGUID(riid, &IID_IDirect3DRM3))
233
    {
234
        *out = &d3drm->IDirect3DRM3_iface;
235
    }
236 237
    else
    {
238
        *out = NULL;
239 240
        WARN("%s not implemented, returning CLASS_E_CLASSNOTAVAILABLE.\n", debugstr_guid(riid));
        return CLASS_E_CLASSNOTAVAILABLE;
241 242
    }

243
    IUnknown_AddRef((IUnknown *)*out);
244
    return S_OK;
245 246
}

247
static ULONG WINAPI d3drm1_AddRef(IDirect3DRM *iface)
248
{
249
    struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
250
    ULONG refcount = InterlockedIncrement(&d3drm->ref1);
251

252
    TRACE("%p increasing refcount to %u.\n", iface, refcount);
253

254 255 256
    if (refcount == 1)
        InterlockedIncrement(&d3drm->iface_count);

257
    return refcount;
258 259
}

260
static ULONG WINAPI d3drm1_Release(IDirect3DRM *iface)
261
{
262
    struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
263
    ULONG refcount = InterlockedDecrement(&d3drm->ref1);
264

265
    TRACE("%p decreasing refcount to %u.\n", iface, refcount);
266

267 268
    if (!refcount && !InterlockedDecrement(&d3drm->iface_count))
        d3drm_destroy(d3drm);
269

270
    return refcount;
271 272
}

273
static HRESULT WINAPI d3drm1_CreateObject(IDirect3DRM *iface,
Henri Verbeet's avatar
Henri Verbeet committed
274
        REFCLSID clsid, IUnknown *outer, REFIID iid, void **out)
275
{
276 277 278
    struct d3drm *d3drm = impl_from_IDirect3DRM(iface);

    TRACE("iface %p, clsid %s, outer %p, iid %s, out %p.\n",
Henri Verbeet's avatar
Henri Verbeet committed
279
            iface, debugstr_guid(clsid), outer, debugstr_guid(iid), out);
280

281
    return IDirect3DRM3_CreateObject(&d3drm->IDirect3DRM3_iface, clsid, outer, iid, out);
282 283
}

284
static HRESULT WINAPI d3drm1_CreateFrame(IDirect3DRM *iface,
285
        IDirect3DRMFrame *parent_frame, IDirect3DRMFrame **frame)
286
{
287 288 289
    struct d3drm_frame *object;
    HRESULT hr;

290
    TRACE("iface %p, parent_frame %p, frame %p.\n", iface, parent_frame, frame);
291

292 293 294 295 296 297
    if (FAILED(hr = d3drm_frame_create(&object, (IUnknown *)parent_frame, iface)))
        return hr;

    *frame = &object->IDirect3DRMFrame_iface;

    return D3DRM_OK;
298 299
}

300
static HRESULT WINAPI d3drm1_CreateMesh(IDirect3DRM *iface, IDirect3DRMMesh **mesh)
301
{
302
    struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
303

304
    TRACE("iface %p, mesh %p.\n", iface, mesh);
305

306
    return IDirect3DRM3_CreateMesh(&d3drm->IDirect3DRM3_iface, mesh);
307 308
}

309
static HRESULT WINAPI d3drm1_CreateMeshBuilder(IDirect3DRM *iface, IDirect3DRMMeshBuilder **mesh_builder)
310
{
311 312
    struct d3drm *d3drm = impl_from_IDirect3DRM(iface);

313
    TRACE("iface %p, mesh_builder %p.\n", iface, mesh_builder);
314

315
    return IDirect3DRM2_CreateMeshBuilder(&d3drm->IDirect3DRM2_iface, (IDirect3DRMMeshBuilder2 **)mesh_builder);
316 317
}

318
static HRESULT WINAPI d3drm1_CreateFace(IDirect3DRM *iface, IDirect3DRMFace **face)
319
{
320 321 322
    struct d3drm_face *object;
    HRESULT hr;

323
    TRACE("iface %p, face %p.\n", iface, face);
324

325 326 327 328 329 330
    if (FAILED(hr = d3drm_face_create(&object)))
        return hr;

    *face = &object->IDirect3DRMFace_iface;

    return S_OK;
331 332
}

333
static HRESULT WINAPI d3drm1_CreateAnimation(IDirect3DRM *iface, IDirect3DRMAnimation **animation)
334
{
335 336
    struct d3drm_animation *object;
    HRESULT hr;
337

338 339 340 341 342 343 344 345 346 347 348
    TRACE("iface %p, animation %p.\n", iface, animation);

    if (!animation)
        return D3DRMERR_BADVALUE;

    if (FAILED(hr = d3drm_animation_create(&object, iface)))
        return hr;

    *animation = &object->IDirect3DRMAnimation_iface;

    return S_OK;
349 350
}

351
static HRESULT WINAPI d3drm1_CreateAnimationSet(IDirect3DRM *iface, IDirect3DRMAnimationSet **set)
352
{
353
    FIXME("iface %p, set %p stub!\n", iface, set);
354 355 356 357

    return E_NOTIMPL;
}

358
static HRESULT WINAPI d3drm1_CreateTexture(IDirect3DRM *iface,
359
        D3DRMIMAGE *image, IDirect3DRMTexture **texture)
360
{
361 362
    struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
    IDirect3DRMTexture3 *texture3;
363 364
    HRESULT hr;

365
    TRACE("iface %p, image %p, texture %p.\n", iface, image, texture);
366

367 368 369 370 371 372
    if (!texture)
        return D3DRMERR_BADVALUE;

    if (FAILED(hr = IDirect3DRM3_CreateTexture(&d3drm->IDirect3DRM3_iface, image, &texture3)))
    {
        *texture = NULL;
373
        return hr;
374
    }
375

376 377
    hr = IDirect3DRMTexture3_QueryInterface(texture3, &IID_IDirect3DRMTexture, (void **)texture);
    IDirect3DRMTexture3_Release(texture3);
378

379
    return hr;
380 381
}

382
static HRESULT WINAPI d3drm1_CreateLight(IDirect3DRM *iface,
383
        D3DRMLIGHTTYPE type, D3DCOLOR color, IDirect3DRMLight **light)
384
{
385
    struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
386

387
    TRACE("iface %p, type %#x, color 0x%08x, light %p.\n", iface, type, color, light);
388

389
    return IDirect3DRM3_CreateLight(&d3drm->IDirect3DRM3_iface, type, color, light);
390 391
}

392
static HRESULT WINAPI d3drm1_CreateLightRGB(IDirect3DRM *iface, D3DRMLIGHTTYPE type,
393
        D3DVALUE red, D3DVALUE green, D3DVALUE blue, IDirect3DRMLight **light)
394
{
395
    struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
396

397 398
    TRACE("iface %p, type %#x, red %.8e, green %.8e, blue %.8e, light %p.\n",
            iface, type, red, green, blue, light);
399

400
    return IDirect3DRM3_CreateLightRGB(&d3drm->IDirect3DRM3_iface, type, red, green, blue, light);
401 402
}

403
static HRESULT WINAPI d3drm1_CreateMaterial(IDirect3DRM *iface,
404
        D3DVALUE power, IDirect3DRMMaterial **material)
405
{
406
    struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
407

408
    TRACE("iface %p, power %.8e, material %p.\n", iface, power, material);
409

410
    return IDirect3DRM3_CreateMaterial(&d3drm->IDirect3DRM3_iface, power, (IDirect3DRMMaterial2 **)material);
411 412
}

413
static HRESULT WINAPI d3drm1_CreateDevice(IDirect3DRM *iface,
414
        DWORD width, DWORD height, IDirect3DRMDevice **device)
415
{
416
    TRACE("iface %p, width %u, height %u, device %p.\n", iface, width, height, device);
417

418 419 420
    if (!device)
        return D3DRMERR_BADVALUE;
    *device = NULL;
421

422
    return D3DRMERR_BADDEVICE;
423 424
}

425 426
static HRESULT WINAPI d3drm1_CreateDeviceFromSurface(IDirect3DRM *iface, GUID *guid,
        IDirectDraw *ddraw, IDirectDrawSurface *backbuffer, IDirect3DRMDevice **device)
427
{
428 429
    struct d3drm_device *object;
    HRESULT hr;
430 431

    TRACE("iface %p, guid %s, ddraw %p, backbuffer %p, device %p.\n",
432
            iface, debugstr_guid(guid), ddraw, backbuffer, device);
433

434 435 436 437 438 439 440
    if (!device)
        return D3DRMERR_BADVALUE;
    *device = NULL;

    if (!backbuffer || !ddraw)
        return D3DRMERR_BADDEVICE;

441
    if (FAILED(hr = d3drm_device_create(&object, iface)))
442 443
        return hr;

444
    if (SUCCEEDED(hr = d3drm_device_init(object, 1, ddraw, backbuffer, TRUE)))
445
        *device = &object->IDirect3DRMDevice_iface;
446 447
    else
        d3drm_device_destroy(object);
448

449
    return hr;
450 451
}

452 453
static HRESULT WINAPI d3drm1_CreateDeviceFromD3D(IDirect3DRM *iface,
        IDirect3D *d3d, IDirect3DDevice *d3d_device, IDirect3DRMDevice **device)
454
{
455 456
    struct d3drm_device *object;
    HRESULT hr;
457
    TRACE("iface %p, d3d %p, d3d_device %p, device %p.\n",
458
            iface, d3d, d3d_device, device);
459

460 461 462 463
    if (!device)
        return D3DRMERR_BADVALUE;
    *device = NULL;

464
    if (FAILED(hr = d3drm_device_create(&object, iface)))
465 466
        return hr;

467
    if (FAILED(hr = IDirect3DRMDevice_InitFromD3D(&object->IDirect3DRMDevice_iface, d3d, d3d_device)))
468 469 470 471
    {
        d3drm_device_destroy(object);
        return hr;
    }
472
    *device = &object->IDirect3DRMDevice_iface;
473 474

    return D3DRM_OK;
475 476
}

477 478 479
static HRESULT WINAPI d3drm1_CreateDeviceFromClipper(IDirect3DRM *iface,
        IDirectDrawClipper *clipper, GUID *guid, int width, int height,
        IDirect3DRMDevice **device)
480
{
481
    struct d3drm_device *object;
482 483
    IDirectDraw *ddraw;
    IDirectDrawSurface *render_target;
484
    HRESULT hr;
485 486

    TRACE("iface %p, clipper %p, guid %s, width %d, height %d, device %p.\n",
487
            iface, clipper, debugstr_guid(guid), width, height, device);
488

489 490 491 492 493 494 495 496 497 498 499
    if (!device)
        return D3DRMERR_BADVALUE;
    *device = NULL;

    if (!clipper || !width || !height)
        return D3DRMERR_BADVALUE;

    hr = DirectDrawCreate(NULL, &ddraw, NULL);
    if (FAILED(hr))
        return hr;

500
    if (FAILED(hr = d3drm_device_create(&object, iface)))
501 502
    {
        IDirectDraw_Release(ddraw);
503
        return hr;
504
    }
505

506 507 508 509 510 511 512
    hr = d3drm_device_create_surfaces_from_clipper(object, ddraw, clipper, width, height, &render_target);
    if (FAILED(hr))
    {
        IDirectDraw_Release(ddraw);
        d3drm_device_destroy(object);
        return hr;
    }
513

514
    hr = d3drm_device_init(object, 1, ddraw, render_target, TRUE);
515 516 517 518 519
    IDirectDraw_Release(ddraw);
    IDirectDrawSurface_Release(render_target);
    if (FAILED(hr))
        d3drm_device_destroy(object);
    else
520
        *device = &object->IDirect3DRMDevice_iface;
521 522

    return hr;
523 524
}

525 526
static HRESULT WINAPI d3drm1_CreateTextureFromSurface(IDirect3DRM *iface,
        IDirectDrawSurface *surface, IDirect3DRMTexture **texture)
527
{
528 529 530
    struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
    IDirect3DRMTexture3 *texture3;
    HRESULT hr;
531

532 533 534 535 536 537 538 539 540 541 542 543 544 545 546
    TRACE("iface %p, surface %p, texture %p.\n", iface, surface, texture);

    if (!texture)
        return D3DRMERR_BADVALUE;

    if (FAILED(hr = IDirect3DRM3_CreateTextureFromSurface(&d3drm->IDirect3DRM3_iface, surface, &texture3)))
    {
        *texture = NULL;
        return hr;
    }

    hr = IDirect3DRMTexture3_QueryInterface(texture3, &IID_IDirect3DRMTexture, (void **)texture);
    IDirect3DRMTexture3_Release(texture3);

    return hr;
547 548
}

549
static HRESULT WINAPI d3drm1_CreateShadow(IDirect3DRM *iface, IDirect3DRMVisual *visual,
550 551
        IDirect3DRMLight *light, D3DVALUE px, D3DVALUE py, D3DVALUE pz, D3DVALUE nx, D3DVALUE ny, D3DVALUE nz,
        IDirect3DRMVisual **shadow)
552
{
553 554
    FIXME("iface %p, visual %p, light %p, px %.8e, py %.8e, pz %.8e, nx %.8e, ny %.8e, nz %.8e, shadow %p stub!\n",
            iface, visual, light, px, py, pz, nx, ny, nz, shadow);
555 556 557 558

    return E_NOTIMPL;
}

559
static HRESULT WINAPI d3drm1_CreateViewport(IDirect3DRM *iface, IDirect3DRMDevice *device,
560
        IDirect3DRMFrame *camera, DWORD x, DWORD y, DWORD width, DWORD height, IDirect3DRMViewport **viewport)
561
{
562
    struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
563 564 565 566
    IDirect3DRMDevice3 *device3;
    IDirect3DRMFrame3 *camera3;
    IDirect3DRMViewport2 *viewport2;
    HRESULT hr;
567

568
    TRACE("iface %p, device %p, camera %p, x %u, y %u, width %u, height %u, viewport %p.\n",
569
            iface, device, camera, x, y, width, height, viewport);
570

571 572
    if (!viewport)
        return D3DRMERR_BADVALUE;
573 574 575 576
    *viewport = NULL;

    if (!device || !camera)
        return D3DRMERR_BADOBJECT;
577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596

    if (FAILED(hr = IDirect3DRMDevice_QueryInterface(device, &IID_IDirect3DRMDevice3, (void **)&device3)))
        return hr;

    if (FAILED(hr = IDirect3DRMFrame_QueryInterface(camera, &IID_IDirect3DRMFrame3, (void **)&camera3)))
    {
        IDirect3DRMDevice3_Release(device3);
        return hr;
    }

    hr = IDirect3DRM3_CreateViewport(&d3drm->IDirect3DRM3_iface, device3, camera3, x, y, width, height, &viewport2);
    IDirect3DRMDevice3_Release(device3);
    IDirect3DRMFrame3_Release(camera3);
    if (FAILED(hr))
        return hr;

    hr = IDirect3DRMViewport2_QueryInterface(viewport2, &IID_IDirect3DRMViewport, (void **)viewport);
    IDirect3DRMViewport2_Release(viewport2);

    return hr;
597 598
}

599
static HRESULT WINAPI d3drm1_CreateWrap(IDirect3DRM *iface, D3DRMWRAPTYPE type, IDirect3DRMFrame *frame,
600 601 602
        D3DVALUE ox, D3DVALUE oy, D3DVALUE oz, D3DVALUE dx, D3DVALUE dy, D3DVALUE dz,
        D3DVALUE ux, D3DVALUE uy, D3DVALUE uz, D3DVALUE ou, D3DVALUE ov, D3DVALUE su, D3DVALUE sv,
        IDirect3DRMWrap **wrap)
603
{
604 605 606
    struct d3drm_wrap *object;
    HRESULT hr;

607
    FIXME("iface %p, type %#x, frame %p, ox %.8e, oy %.8e, oz %.8e, dx %.8e, dy %.8e, dz %.8e, "
608
            "ux %.8e, uy %.8e, uz %.8e, ou %.8e, ov %.8e, su %.8e, sv %.8e, wrap %p, semi-stub.\n",
609
            iface, type, frame, ox, oy, oz, dx, dy, dz, ux, uy, uz, ou, ov, su, sv, wrap);
610

611 612 613 614 615 616 617 618 619
    if (!wrap)
        return D3DRMERR_BADVALUE;

    if (FAILED(hr = d3drm_wrap_create(&object, iface)))
        return hr;

    *wrap = &object->IDirect3DRMWrap_iface;

    return S_OK;
620 621
}

622
static HRESULT WINAPI d3drm1_CreateUserVisual(IDirect3DRM *iface,
623
        D3DRMUSERVISUALCALLBACK cb, void *ctx, IDirect3DRMUserVisual **visual)
624
{
625
    FIXME("iface %p, cb %p, ctx %p visual %p stub!\n", iface, cb, ctx, visual);
626 627 628 629

    return E_NOTIMPL;
}

630
static HRESULT WINAPI d3drm1_LoadTexture(IDirect3DRM *iface,
631
        const char *filename, IDirect3DRMTexture **texture)
632
{
633 634 635
    struct d3drm_texture *object;
    HRESULT hr;

636 637 638 639
    TRACE("iface %p, filename %s, texture %p.\n", iface, debugstr_a(filename), texture);

    if (!texture)
        return D3DRMERR_BADVALUE;
640

641
    if (FAILED(hr = d3drm_texture_create(&object, iface)))
642 643 644
        return hr;

    *texture = &object->IDirect3DRMTexture_iface;
645 646 647 648 649 650 651 652 653
    if (FAILED(hr = IDirect3DRMTexture_InitFromFile(*texture, filename)))
    {
        IDirect3DRMTexture_Release(*texture);
        *texture = NULL;
        if (!filename)
            return D3DRMERR_BADVALUE;

        return hr == D3DRMERR_BADOBJECT ? D3DRMERR_FILENOTFOUND : hr;
    }
654 655

    return D3DRM_OK;
656 657
}

658
static HRESULT WINAPI d3drm1_LoadTextureFromResource(IDirect3DRM *iface,
659
        HRSRC resource, IDirect3DRMTexture **texture)
660
{
661 662 663
    struct d3drm_texture *object;
    HRESULT hr;

664
    FIXME("iface %p, resource %p, texture %p stub!\n", iface, resource, texture);
665

666
    if (FAILED(hr = d3drm_texture_create(&object, iface)))
667 668 669 670 671
        return hr;

    *texture = &object->IDirect3DRMTexture_iface;

    return D3DRM_OK;
672 673
}

674
static HRESULT WINAPI d3drm1_SetSearchPath(IDirect3DRM *iface, const char *path)
675
{
Henri Verbeet's avatar
Henri Verbeet committed
676
    FIXME("iface %p, path %s stub!\n", iface, debugstr_a(path));
677 678 679 680

    return E_NOTIMPL;
}

681
static HRESULT WINAPI d3drm1_AddSearchPath(IDirect3DRM *iface, const char *path)
682
{
Henri Verbeet's avatar
Henri Verbeet committed
683
    FIXME("iface %p, path %s stub!\n", iface, debugstr_a(path));
684 685 686 687

    return E_NOTIMPL;
}

688
static HRESULT WINAPI d3drm1_GetSearchPath(IDirect3DRM *iface, DWORD *size, char *path)
689
{
Henri Verbeet's avatar
Henri Verbeet committed
690
    FIXME("iface %p, size %p, path %p stub!\n", iface, size, path);
691 692 693 694

    return E_NOTIMPL;
}

695
static HRESULT WINAPI d3drm1_SetDefaultTextureColors(IDirect3DRM *iface, DWORD color_count)
696
{
697
    FIXME("iface %p, color_count %u stub!\n", iface, color_count);
698 699 700 701

    return E_NOTIMPL;
}

702
static HRESULT WINAPI d3drm1_SetDefaultTextureShades(IDirect3DRM *iface, DWORD shade_count)
703
{
704
    FIXME("iface %p, shade_count %u stub!\n", iface, shade_count);
705 706 707 708

    return E_NOTIMPL;
}

709
static HRESULT WINAPI d3drm1_GetDevices(IDirect3DRM *iface, IDirect3DRMDeviceArray **array)
710
{
711
    FIXME("iface %p, array %p stub!\n", iface, array);
712 713 714 715

    return E_NOTIMPL;
}

716
static HRESULT WINAPI d3drm1_GetNamedObject(IDirect3DRM *iface,
717
        const char *name, IDirect3DRMObject **object)
718
{
719
    FIXME("iface %p, name %s, object %p stub!\n", iface, debugstr_a(name), object);
720 721 722 723

    return E_NOTIMPL;
}

724
static HRESULT WINAPI d3drm1_EnumerateObjects(IDirect3DRM *iface, D3DRMOBJECTCALLBACK cb, void *ctx)
725
{
Henri Verbeet's avatar
Henri Verbeet committed
726
    FIXME("iface %p, cb %p, ctx %p stub!\n", iface, cb, ctx);
727 728 729 730

    return E_NOTIMPL;
}

731
static HRESULT WINAPI d3drm1_Load(IDirect3DRM *iface, void *source, void *object_id, IID **iids,
732 733
        DWORD iid_count, D3DRMLOADOPTIONS flags, D3DRMLOADCALLBACK load_cb, void *load_ctx,
        D3DRMLOADTEXTURECALLBACK load_tex_cb, void *load_tex_ctx, IDirect3DRMFrame *parent_frame)
734
{
735
    struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
736
    IDirect3DRMFrame3 *parent_frame3 = NULL;
737
    HRESULT hr = D3DRM_OK;
738

739 740 741 742
    TRACE("iface %p, source %p, object_id %p, iids %p, iid_count %u, flags %#x, "
            "load_cb %p, load_ctx %p, load_tex_cb %p, load_tex_ctx %p, parent_frame %p.\n",
            iface, source, object_id, iids, iid_count, flags,
            load_cb, load_ctx, load_tex_cb, load_tex_ctx, parent_frame);
743

744 745
    if (parent_frame)
        hr = IDirect3DRMFrame_QueryInterface(parent_frame, &IID_IDirect3DRMFrame3, (void **)&parent_frame3);
746
    if (SUCCEEDED(hr))
747 748 749 750
        hr = IDirect3DRM3_Load(&d3drm->IDirect3DRM3_iface, source, object_id, iids, iid_count,
                flags, load_cb, load_ctx, load_tex_cb, load_tex_ctx, parent_frame3);
    if (parent_frame3)
        IDirect3DRMFrame3_Release(parent_frame3);
751 752

    return hr;
753 754
}

755
static HRESULT WINAPI d3drm1_Tick(IDirect3DRM *iface, D3DVALUE tick)
756
{
757
    FIXME("iface %p, tick %.8e stub!\n", iface, tick);
758 759 760 761

    return E_NOTIMPL;
}

762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798
static const struct IDirect3DRMVtbl d3drm1_vtbl =
{
    d3drm1_QueryInterface,
    d3drm1_AddRef,
    d3drm1_Release,
    d3drm1_CreateObject,
    d3drm1_CreateFrame,
    d3drm1_CreateMesh,
    d3drm1_CreateMeshBuilder,
    d3drm1_CreateFace,
    d3drm1_CreateAnimation,
    d3drm1_CreateAnimationSet,
    d3drm1_CreateTexture,
    d3drm1_CreateLight,
    d3drm1_CreateLightRGB,
    d3drm1_CreateMaterial,
    d3drm1_CreateDevice,
    d3drm1_CreateDeviceFromSurface,
    d3drm1_CreateDeviceFromD3D,
    d3drm1_CreateDeviceFromClipper,
    d3drm1_CreateTextureFromSurface,
    d3drm1_CreateShadow,
    d3drm1_CreateViewport,
    d3drm1_CreateWrap,
    d3drm1_CreateUserVisual,
    d3drm1_LoadTexture,
    d3drm1_LoadTextureFromResource,
    d3drm1_SetSearchPath,
    d3drm1_AddSearchPath,
    d3drm1_GetSearchPath,
    d3drm1_SetDefaultTextureColors,
    d3drm1_SetDefaultTextureShades,
    d3drm1_GetDevices,
    d3drm1_GetNamedObject,
    d3drm1_EnumerateObjects,
    d3drm1_Load,
    d3drm1_Tick,
799
};
800

801
static HRESULT WINAPI d3drm2_QueryInterface(IDirect3DRM2 *iface, REFIID riid, void **out)
802
{
803 804 805
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);

    return d3drm1_QueryInterface(&d3drm->IDirect3DRM_iface, riid, out);
806 807
}

808
static ULONG WINAPI d3drm2_AddRef(IDirect3DRM2 *iface)
809
{
810
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
811 812 813 814 815 816
    ULONG refcount = InterlockedIncrement(&d3drm->ref2);

    TRACE("%p increasing refcount to %u.\n", iface, refcount);

    if (refcount == 1)
        InterlockedIncrement(&d3drm->iface_count);
817

818
    return refcount;
819 820
}

821
static ULONG WINAPI d3drm2_Release(IDirect3DRM2 *iface)
822
{
823
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
824 825 826
    ULONG refcount = InterlockedDecrement(&d3drm->ref2);

    TRACE("%p decreasing refcount to %u.\n", iface, refcount);
827

828 829 830 831
    if (!refcount && !InterlockedDecrement(&d3drm->iface_count))
        d3drm_destroy(d3drm);

    return refcount;
832 833
}

834
static HRESULT WINAPI d3drm2_CreateObject(IDirect3DRM2 *iface,
Henri Verbeet's avatar
Henri Verbeet committed
835
        REFCLSID clsid, IUnknown *outer, REFIID iid, void **out)
836
{
837 838 839
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);

    TRACE("iface %p, clsid %s, outer %p, iid %s, out %p.\n",
Henri Verbeet's avatar
Henri Verbeet committed
840
            iface, debugstr_guid(clsid), outer, debugstr_guid(iid), out);
841

842
    return IDirect3DRM3_CreateObject(&d3drm->IDirect3DRM3_iface, clsid, outer, iid, out);
843 844
}

845
static HRESULT WINAPI d3drm2_CreateFrame(IDirect3DRM2 *iface,
846
        IDirect3DRMFrame *parent_frame, IDirect3DRMFrame2 **frame)
847
{
848 849 850 851
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
    struct d3drm_frame *object;
    HRESULT hr;

852
    TRACE("iface %p, parent_frame %p, frame %p.\n", iface, parent_frame, frame);
853

854 855 856 857 858 859
    if (FAILED(hr = d3drm_frame_create(&object, (IUnknown *)parent_frame, &d3drm->IDirect3DRM_iface)))
        return hr;

    *frame = &object->IDirect3DRMFrame2_iface;

    return D3DRM_OK;
860 861
}

862
static HRESULT WINAPI d3drm2_CreateMesh(IDirect3DRM2 *iface, IDirect3DRMMesh **mesh)
863
{
864
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
865

866
    TRACE("iface %p, mesh %p.\n", iface, mesh);
867

868
    return IDirect3DRM3_CreateMesh(&d3drm->IDirect3DRM3_iface, mesh);
869 870
}

871
static HRESULT WINAPI d3drm2_CreateMeshBuilder(IDirect3DRM2 *iface, IDirect3DRMMeshBuilder2 **mesh_builder)
872
{
873 874 875 876
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
    struct d3drm_mesh_builder *object;
    HRESULT hr;

877
    TRACE("iface %p, mesh_builder %p.\n", iface, mesh_builder);
878

879 880 881 882 883 884
    if (FAILED(hr = d3drm_mesh_builder_create(&object, &d3drm->IDirect3DRM_iface)))
        return hr;

    *mesh_builder = &object->IDirect3DRMMeshBuilder2_iface;

    return S_OK;
885 886
}

887
static HRESULT WINAPI d3drm2_CreateFace(IDirect3DRM2 *iface, IDirect3DRMFace **face)
888
{
889 890
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);

891
    TRACE("iface %p, face %p.\n", iface, face);
892

893
    return IDirect3DRM_CreateFace(&d3drm->IDirect3DRM_iface, face);
894 895
}

896
static HRESULT WINAPI d3drm2_CreateAnimation(IDirect3DRM2 *iface, IDirect3DRMAnimation **animation)
897
{
898
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
899

900 901 902
    TRACE("iface %p, animation %p.\n", iface, animation);

    return IDirect3DRM_CreateAnimation(&d3drm->IDirect3DRM_iface, animation);
903 904
}

905
static HRESULT WINAPI d3drm2_CreateAnimationSet(IDirect3DRM2 *iface, IDirect3DRMAnimationSet **set)
906
{
907
    FIXME("iface %p, set %p stub!\n", iface, set);
908 909 910 911

    return E_NOTIMPL;
}

912
static HRESULT WINAPI d3drm2_CreateTexture(IDirect3DRM2 *iface,
913
        D3DRMIMAGE *image, IDirect3DRMTexture2 **texture)
914
{
915
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
916
    IDirect3DRMTexture3 *texture3;
917 918
    HRESULT hr;

919
    TRACE("iface %p, image %p, texture %p.\n", iface, image, texture);
920

921 922 923 924 925 926
    if (!texture)
        return D3DRMERR_BADVALUE;

    if (FAILED(hr = IDirect3DRM3_CreateTexture(&d3drm->IDirect3DRM3_iface, image, &texture3)))
    {
        *texture = NULL;
927
        return hr;
928
    }
929

930 931
    hr = IDirect3DRMTexture3_QueryInterface(texture3, &IID_IDirect3DRMTexture2, (void **)texture);
    IDirect3DRMTexture3_Release(texture3);
932

933
    return hr;
934 935
}

936
static HRESULT WINAPI d3drm2_CreateLight(IDirect3DRM2 *iface,
937
        D3DRMLIGHTTYPE type, D3DCOLOR color, IDirect3DRMLight **light)
938
{
939
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
940

941
    TRACE("iface %p, type %#x, color 0x%08x, light %p.\n", iface, type, color, light);
942

943
    return IDirect3DRM3_CreateLight(&d3drm->IDirect3DRM3_iface, type, color, light);
944 945
}

946
static HRESULT WINAPI d3drm2_CreateLightRGB(IDirect3DRM2 *iface, D3DRMLIGHTTYPE type,
947
        D3DVALUE red, D3DVALUE green, D3DVALUE blue, IDirect3DRMLight **light)
948
{
949
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
950

951 952
    TRACE("iface %p, type %#x, red %.8e, green %.8e, blue %.8e, light %p.\n",
            iface, type, red, green, blue, light);
953

954
    return IDirect3DRM3_CreateLightRGB(&d3drm->IDirect3DRM3_iface, type, red, green, blue, light);
955 956
}

957
static HRESULT WINAPI d3drm2_CreateMaterial(IDirect3DRM2 *iface,
958
        D3DVALUE power, IDirect3DRMMaterial **material)
959
{
960
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
961

962
    TRACE("iface %p, power %.8e, material %p.\n", iface, power, material);
963

964
    return IDirect3DRM3_CreateMaterial(&d3drm->IDirect3DRM3_iface, power, (IDirect3DRMMaterial2 **)material);
965 966
}

967
static HRESULT WINAPI d3drm2_CreateDevice(IDirect3DRM2 *iface,
968
        DWORD width, DWORD height, IDirect3DRMDevice2 **device)
969
{
970
    TRACE("iface %p, width %u, height %u, device %p.\n", iface, width, height, device);
971

972 973 974
    if (!device)
        return D3DRMERR_BADVALUE;
    *device = NULL;
975

976
    return D3DRMERR_BADDEVICE;
977 978
}

979 980
static HRESULT WINAPI d3drm2_CreateDeviceFromSurface(IDirect3DRM2 *iface, GUID *guid,
        IDirectDraw *ddraw, IDirectDrawSurface *backbuffer, IDirect3DRMDevice2 **device)
981
{
982 983
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
    IDirect3DRMDevice3 *device3;
984
    HRESULT hr;
985
    TRACE("iface %p, guid %s, ddraw %p, backbuffer %p, device %p.\n",
986
            iface, debugstr_guid(guid), ddraw, backbuffer, device);
987

988 989 990 991
    if (!device)
        return D3DRMERR_BADVALUE;
    *device = NULL;
    hr = IDirect3DRM3_CreateDeviceFromSurface(&d3drm->IDirect3DRM3_iface, guid, ddraw, backbuffer, 0, &device3);
992 993 994
    if (FAILED(hr))
        return hr;

995 996
    hr = IDirect3DRMDevice3_QueryInterface(device3, &IID_IDirect3DRMDevice2, (void**)device);
    IDirect3DRMDevice3_Release(device3);
997

998
    return hr;
999 1000
}

1001
static HRESULT WINAPI d3drm2_CreateDeviceFromD3D(IDirect3DRM2 *iface,
1002
    IDirect3D2 *d3d, IDirect3DDevice2 *d3d_device, IDirect3DRMDevice2 **device)
1003
{
1004
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
1005
    IDirect3DRMDevice3 *device3;
1006
    HRESULT hr;
1007

1008
    TRACE("iface %p, d3d %p, d3d_device %p, device %p.\n",
1009
            iface, d3d, d3d_device, device);
1010

1011 1012 1013
    if (!device)
        return D3DRMERR_BADVALUE;
    *device = NULL;
1014

1015
    hr = IDirect3DRM3_CreateDeviceFromD3D(&d3drm->IDirect3DRM3_iface, d3d, d3d_device, &device3);
1016 1017 1018
    if (FAILED(hr))
        return hr;

1019 1020
    hr = IDirect3DRMDevice3_QueryInterface(device3, &IID_IDirect3DRMDevice2, (void **)device);
    IDirect3DRMDevice3_Release(device3);
1021 1022

    return hr;
1023 1024
}

1025 1026 1027
static HRESULT WINAPI d3drm2_CreateDeviceFromClipper(IDirect3DRM2 *iface,
        IDirectDrawClipper *clipper, GUID *guid, int width, int height,
        IDirect3DRMDevice2 **device)
1028
{
1029 1030
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
    IDirect3DRMDevice3 *device3;
1031
    HRESULT hr;
1032 1033

    TRACE("iface %p, clipper %p, guid %s, width %d, height %d, device %p.\n",
1034
            iface, clipper, debugstr_guid(guid), width, height, device);
1035

1036 1037 1038 1039
    if (!device)
        return D3DRMERR_BADVALUE;
    *device = NULL;
    hr = IDirect3DRM3_CreateDeviceFromClipper(&d3drm->IDirect3DRM3_iface, clipper, guid, width, height, &device3);
1040 1041 1042
    if (FAILED(hr))
        return hr;

1043 1044
    hr = IDirect3DRMDevice3_QueryInterface(device3, &IID_IDirect3DRMDevice2, (void**)device);
    IDirect3DRMDevice3_Release(device3);
1045

1046
    return hr;
1047 1048
}

1049 1050
static HRESULT WINAPI d3drm2_CreateTextureFromSurface(IDirect3DRM2 *iface,
        IDirectDrawSurface *surface, IDirect3DRMTexture2 **texture)
1051
{
1052 1053 1054
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
    IDirect3DRMTexture3 *texture3;
    HRESULT hr;
1055

1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070
    TRACE("iface %p, surface %p, texture %p.\n", iface, surface, texture);

    if (!texture)
        return D3DRMERR_BADVALUE;

    if (FAILED(hr = IDirect3DRM3_CreateTextureFromSurface(&d3drm->IDirect3DRM3_iface, surface, &texture3)))
    {
        *texture = NULL;
        return hr;
    }

    hr = IDirect3DRMTexture3_QueryInterface(texture3, &IID_IDirect3DRMTexture, (void **)texture);
    IDirect3DRMTexture3_Release(texture3);

    return hr;
1071 1072
}

1073
static HRESULT WINAPI d3drm2_CreateShadow(IDirect3DRM2 *iface, IDirect3DRMVisual *visual,
1074 1075
        IDirect3DRMLight *light, D3DVALUE px, D3DVALUE py, D3DVALUE pz, D3DVALUE nx, D3DVALUE ny, D3DVALUE nz,
        IDirect3DRMVisual **shadow)
1076
{
1077 1078
    FIXME("iface %p, visual %p, light %p, px %.8e, py %.8e, pz %.8e, nx %.8e, ny %.8e, nz %.8e, shadow %p stub!\n",
            iface, visual, light, px, py, pz, nx, ny, nz, shadow);
1079 1080 1081 1082

    return E_NOTIMPL;
}

1083
static HRESULT WINAPI d3drm2_CreateViewport(IDirect3DRM2 *iface, IDirect3DRMDevice *device,
1084
        IDirect3DRMFrame *camera, DWORD x, DWORD y, DWORD width, DWORD height, IDirect3DRMViewport **viewport)
1085
{
1086
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
1087 1088 1089
    IDirect3DRMDevice3 *device3;
    IDirect3DRMFrame3 *camera3;
    IDirect3DRMViewport2 *viewport2;
1090 1091
    HRESULT hr;

1092 1093
    TRACE("iface %p, device %p, camera %p, x %u, y %u, width %u, height %u, viewport %p.\n",
          iface, device, camera, x, y, width, height, viewport);
1094

1095 1096
    if (!viewport)
        return D3DRMERR_BADVALUE;
1097 1098 1099 1100
    *viewport = NULL;

    if (!device || !camera)
        return D3DRMERR_BADOBJECT;
1101 1102

    if (FAILED(hr = IDirect3DRMDevice_QueryInterface(device, &IID_IDirect3DRMDevice3, (void **)&device3)))
1103 1104
        return hr;

1105 1106 1107 1108 1109
    if (FAILED(hr = IDirect3DRMFrame_QueryInterface(camera, &IID_IDirect3DRMFrame3, (void **)&camera3)))
    {
        IDirect3DRMDevice3_Release(device3);
        return hr;
    }
1110

1111 1112 1113 1114 1115 1116 1117 1118 1119 1120
    hr = IDirect3DRM3_CreateViewport(&d3drm->IDirect3DRM3_iface, device3, camera3, x, y, width, height, &viewport2);
    IDirect3DRMDevice3_Release(device3);
    IDirect3DRMFrame3_Release(camera3);
    if (FAILED(hr))
        return hr;

    hr = IDirect3DRMViewport2_QueryInterface(viewport2, &IID_IDirect3DRMViewport, (void **)viewport);
    IDirect3DRMViewport2_Release(viewport2);

    return hr;
1121 1122
}

1123
static HRESULT WINAPI d3drm2_CreateWrap(IDirect3DRM2 *iface, D3DRMWRAPTYPE type, IDirect3DRMFrame *frame,
1124 1125 1126
        D3DVALUE ox, D3DVALUE oy, D3DVALUE oz, D3DVALUE dx, D3DVALUE dy, D3DVALUE dz,
        D3DVALUE ux, D3DVALUE uy, D3DVALUE uz, D3DVALUE ou, D3DVALUE ov, D3DVALUE su, D3DVALUE sv,
        IDirect3DRMWrap **wrap)
1127
{
1128 1129 1130 1131
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);

    TRACE("iface %p, type %#x, frame %p, ox %.8e, oy %.8e, oz %.8e, dx %.8e, dy %.8e, dz %.8e, "
            "ux %.8e, uy %.8e, uz %.8e, ou %.8e, ov %.8e, su %.8e, sv %.8e, wrap %p.\n",
1132
            iface, type, frame, ox, oy, oz, dx, dy, dz, ux, uy, uz, ou, ov, su, sv, wrap);
1133

1134 1135
    return IDirect3DRM_CreateWrap(&d3drm->IDirect3DRM_iface, type, frame, ox, oy, oz, dx, dy, dz, ux, uy, uz,
            ou, ov, su, sv, wrap);
1136 1137
}

1138
static HRESULT WINAPI d3drm2_CreateUserVisual(IDirect3DRM2 *iface,
1139
        D3DRMUSERVISUALCALLBACK cb, void *ctx, IDirect3DRMUserVisual **visual)
1140
{
1141
    FIXME("iface %p, cb %p, ctx %p, visual %p stub!\n", iface, cb, ctx, visual);
1142 1143 1144 1145

    return E_NOTIMPL;
}

1146
static HRESULT WINAPI d3drm2_LoadTexture(IDirect3DRM2 *iface,
1147
        const char *filename, IDirect3DRMTexture2 **texture)
1148
{
1149
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
1150
    IDirect3DRMTexture3 *texture3;
1151 1152
    HRESULT hr;

1153
    TRACE("iface %p, filename %s, texture %p.\n", iface, debugstr_a(filename), texture);
1154

1155 1156 1157 1158 1159 1160
    if (!texture)
        return D3DRMERR_BADVALUE;

    if (FAILED(hr = IDirect3DRM3_LoadTexture(&d3drm->IDirect3DRM3_iface, filename, &texture3)))
    {
        *texture = NULL;
1161
        return hr;
1162
    }
1163

1164 1165
    hr = IDirect3DRMTexture3_QueryInterface(texture3, &IID_IDirect3DRMTexture2, (void **)texture);
    IDirect3DRMTexture3_Release(texture3);
1166

1167
    return hr;
1168 1169
}

1170
static HRESULT WINAPI d3drm2_LoadTextureFromResource(IDirect3DRM2 *iface, HMODULE module,
1171
        const char *resource_name, const char *resource_type, IDirect3DRMTexture2 **texture)
1172
{
1173
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
1174 1175 1176
    struct d3drm_texture *object;
    HRESULT hr;

1177 1178
    FIXME("iface %p, resource_name %s, resource_type %s, texture %p stub!\n",
            iface, debugstr_a(resource_name), debugstr_a(resource_type), texture);
1179

1180
    if (FAILED(hr = d3drm_texture_create(&object, &d3drm->IDirect3DRM_iface)))
1181 1182 1183 1184 1185
        return hr;

    *texture = &object->IDirect3DRMTexture2_iface;

    return D3DRM_OK;
1186 1187
}

1188
static HRESULT WINAPI d3drm2_SetSearchPath(IDirect3DRM2 *iface, const char *path)
1189
{
Henri Verbeet's avatar
Henri Verbeet committed
1190
    FIXME("iface %p, path %s stub!\n", iface, debugstr_a(path));
1191 1192 1193 1194

    return E_NOTIMPL;
}

1195
static HRESULT WINAPI d3drm2_AddSearchPath(IDirect3DRM2 *iface, const char *path)
1196
{
Henri Verbeet's avatar
Henri Verbeet committed
1197
    FIXME("iface %p, path %s stub!\n", iface, debugstr_a(path));
1198 1199 1200 1201

    return E_NOTIMPL;
}

1202
static HRESULT WINAPI d3drm2_GetSearchPath(IDirect3DRM2 *iface, DWORD *size, char *path)
1203
{
Henri Verbeet's avatar
Henri Verbeet committed
1204
    FIXME("iface %p, size %p, path %p stub!\n", iface, size, path);
1205 1206 1207 1208

    return E_NOTIMPL;
}

1209
static HRESULT WINAPI d3drm2_SetDefaultTextureColors(IDirect3DRM2 *iface, DWORD color_count)
1210
{
1211
    FIXME("iface %p, color_count %u stub!\n", iface, color_count);
1212 1213 1214 1215

    return E_NOTIMPL;
}

1216
static HRESULT WINAPI d3drm2_SetDefaultTextureShades(IDirect3DRM2 *iface, DWORD shade_count)
1217
{
1218
    FIXME("iface %p, shade_count %u stub!\n", iface, shade_count);
1219 1220 1221 1222

    return E_NOTIMPL;
}

1223
static HRESULT WINAPI d3drm2_GetDevices(IDirect3DRM2 *iface, IDirect3DRMDeviceArray **array)
1224
{
1225
    FIXME("iface %p, array %p stub!\n", iface, array);
1226 1227 1228 1229

    return E_NOTIMPL;
}

1230
static HRESULT WINAPI d3drm2_GetNamedObject(IDirect3DRM2 *iface,
1231
        const char *name, IDirect3DRMObject **object)
1232
{
1233
    FIXME("iface %p, name %s, object %p stub!\n", iface, debugstr_a(name), object);
1234 1235 1236 1237

    return E_NOTIMPL;
}

1238
static HRESULT WINAPI d3drm2_EnumerateObjects(IDirect3DRM2 *iface, D3DRMOBJECTCALLBACK cb, void *ctx)
1239
{
Henri Verbeet's avatar
Henri Verbeet committed
1240
    FIXME("iface %p, cb %p, ctx %p stub!\n", iface, cb, ctx);
1241 1242 1243 1244

    return E_NOTIMPL;
}

1245
static HRESULT WINAPI d3drm2_Load(IDirect3DRM2 *iface, void *source, void *object_id, IID **iids,
1246 1247
        DWORD iid_count, D3DRMLOADOPTIONS flags, D3DRMLOADCALLBACK load_cb, void *load_ctx,
        D3DRMLOADTEXTURECALLBACK load_tex_cb, void *load_tex_ctx, IDirect3DRMFrame *parent_frame)
1248
{
1249
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
1250
    IDirect3DRMFrame3 *parent_frame3 = NULL;
1251
    HRESULT hr = D3DRM_OK;
1252

1253 1254 1255 1256
    TRACE("iface %p, source %p, object_id %p, iids %p, iid_count %u, flags %#x, "
            "load_cb %p, load_ctx %p, load_tex_cb %p, load_tex_ctx %p, parent_frame %p.\n",
            iface, source, object_id, iids, iid_count, flags,
            load_cb, load_ctx, load_tex_cb, load_tex_ctx, parent_frame);
1257

1258 1259
    if (parent_frame)
        hr = IDirect3DRMFrame_QueryInterface(parent_frame, &IID_IDirect3DRMFrame3, (void **)&parent_frame3);
1260
    if (SUCCEEDED(hr))
1261 1262 1263 1264
        hr = IDirect3DRM3_Load(&d3drm->IDirect3DRM3_iface, source, object_id, iids, iid_count,
                flags, load_cb, load_ctx, load_tex_cb, load_tex_ctx, parent_frame3);
    if (parent_frame3)
        IDirect3DRMFrame3_Release(parent_frame3);
1265 1266

    return hr;
1267 1268
}

1269
static HRESULT WINAPI d3drm2_Tick(IDirect3DRM2 *iface, D3DVALUE tick)
1270
{
1271
    FIXME("iface %p, tick %.8e stub!\n", iface, tick);
1272 1273 1274 1275

    return E_NOTIMPL;
}

1276
static HRESULT WINAPI d3drm2_CreateProgressiveMesh(IDirect3DRM2 *iface, IDirect3DRMProgressiveMesh **mesh)
1277
{
1278
    FIXME("iface %p, mesh %p stub!\n", iface, mesh);
1279 1280 1281 1282

    return E_NOTIMPL;
}

1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320
static const struct IDirect3DRM2Vtbl d3drm2_vtbl =
{
    d3drm2_QueryInterface,
    d3drm2_AddRef,
    d3drm2_Release,
    d3drm2_CreateObject,
    d3drm2_CreateFrame,
    d3drm2_CreateMesh,
    d3drm2_CreateMeshBuilder,
    d3drm2_CreateFace,
    d3drm2_CreateAnimation,
    d3drm2_CreateAnimationSet,
    d3drm2_CreateTexture,
    d3drm2_CreateLight,
    d3drm2_CreateLightRGB,
    d3drm2_CreateMaterial,
    d3drm2_CreateDevice,
    d3drm2_CreateDeviceFromSurface,
    d3drm2_CreateDeviceFromD3D,
    d3drm2_CreateDeviceFromClipper,
    d3drm2_CreateTextureFromSurface,
    d3drm2_CreateShadow,
    d3drm2_CreateViewport,
    d3drm2_CreateWrap,
    d3drm2_CreateUserVisual,
    d3drm2_LoadTexture,
    d3drm2_LoadTextureFromResource,
    d3drm2_SetSearchPath,
    d3drm2_AddSearchPath,
    d3drm2_GetSearchPath,
    d3drm2_SetDefaultTextureColors,
    d3drm2_SetDefaultTextureShades,
    d3drm2_GetDevices,
    d3drm2_GetNamedObject,
    d3drm2_EnumerateObjects,
    d3drm2_Load,
    d3drm2_Tick,
    d3drm2_CreateProgressiveMesh,
1321
};
1322

1323
static HRESULT WINAPI d3drm3_QueryInterface(IDirect3DRM3 *iface, REFIID riid, void **out)
1324
{
1325 1326 1327
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);

    return d3drm1_QueryInterface(&d3drm->IDirect3DRM_iface, riid, out);
1328 1329
}

1330
static ULONG WINAPI d3drm3_AddRef(IDirect3DRM3 *iface)
1331
{
1332
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1333 1334 1335 1336 1337 1338
    ULONG refcount = InterlockedIncrement(&d3drm->ref3);

    TRACE("%p increasing refcount to %u.\n", iface, refcount);

    if (refcount == 1)
        InterlockedIncrement(&d3drm->iface_count);
1339

1340
    return refcount;
1341 1342
}

1343
static ULONG WINAPI d3drm3_Release(IDirect3DRM3 *iface)
1344
{
1345
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1346 1347 1348
    ULONG refcount = InterlockedDecrement(&d3drm->ref3);

    TRACE("%p decreasing refcount to %u.\n", iface, refcount);
1349

1350 1351 1352 1353
    if (!refcount && !InterlockedDecrement(&d3drm->iface_count))
        d3drm_destroy(d3drm);

    return refcount;
1354 1355
}

1356
static HRESULT WINAPI d3drm3_CreateObject(IDirect3DRM3 *iface,
Henri Verbeet's avatar
Henri Verbeet committed
1357
        REFCLSID clsid, IUnknown *outer, REFIID iid, void **out)
1358
{
1359
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1360
    IUnknown *object;
1361
    unsigned int i;
1362 1363
    HRESULT hr;

1364 1365 1366 1367 1368 1369 1370 1371
    static const struct
    {
        const CLSID *clsid;
        HRESULT (*create_object)(void **object, IDirect3DRM *d3drm);
    }
    object_table[] =
    {
        {&CLSID_CDirect3DRMTexture, d3drm_create_texture_object},
1372
        {&CLSID_CDirect3DRMDevice, d3drm_create_device_object},
1373
        {&CLSID_CDirect3DRMViewport, d3drm_create_viewport_object},
1374
        {&CLSID_CDirect3DRMFace, d3drm_create_face_object},
1375
        {&CLSID_CDirect3DRMMeshBuilder, d3drm_create_mesh_builder_object},
1376
        {&CLSID_CDirect3DRMFrame, d3drm_create_frame_object},
1377
        {&CLSID_CDirect3DRMLight, d3drm_create_light_object},
1378
        {&CLSID_CDirect3DRMMaterial, d3drm_create_material_object},
1379
        {&CLSID_CDirect3DRMMesh, d3drm_create_mesh_object},
1380
        {&CLSID_CDirect3DRMAnimation, d3drm_create_animation_object},
1381
        {&CLSID_CDirect3DRMWrap, d3drm_create_wrap_object},
1382 1383
    };

1384
    TRACE("iface %p, clsid %s, outer %p, iid %s, out %p.\n",
Henri Verbeet's avatar
Henri Verbeet committed
1385
            iface, debugstr_guid(clsid), outer, debugstr_guid(iid), out);
1386

1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402
    if (!out)
        return D3DRMERR_BADVALUE;

    if (!clsid || !iid)
    {
        *out = NULL;
        return D3DRMERR_BADVALUE;
    }

    if (outer)
    {
        FIXME("COM aggregation for outer IUnknown (%p) not implemented. Returning E_NOTIMPL.\n", outer);
        *out = NULL;
        return E_NOTIMPL;
    }

1403
    for (i = 0; i < ARRAY_SIZE(object_table); ++i)
1404
    {
1405
        if (IsEqualGUID(clsid, object_table[i].clsid))
1406
        {
1407 1408 1409 1410 1411 1412
            if (FAILED(hr = object_table[i].create_object((void **)&object, &d3drm->IDirect3DRM_iface)))
            {
                *out = NULL;
                return hr;
            }
            break;
1413 1414
        }
    }
1415
    if (i == ARRAY_SIZE(object_table))
1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426
    {
        FIXME("%s not implemented. Returning CLASSFACTORY_E_FIRST.\n", debugstr_guid(clsid));
        *out = NULL;
        return CLASSFACTORY_E_FIRST;
    }

    if (FAILED(hr = IUnknown_QueryInterface(object, iid, out)))
        *out = NULL;
    IUnknown_Release(object);

    return hr;
1427 1428
}

1429
static HRESULT WINAPI d3drm3_CreateFrame(IDirect3DRM3 *iface,
1430
        IDirect3DRMFrame3 *parent, IDirect3DRMFrame3 **frame)
1431
{
1432 1433 1434 1435
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
    struct d3drm_frame *object;
    HRESULT hr;

1436
    TRACE("iface %p, parent %p, frame %p.\n", iface, parent, frame);
1437

1438 1439 1440 1441 1442 1443
    if (FAILED(hr = d3drm_frame_create(&object, (IUnknown *)parent, &d3drm->IDirect3DRM_iface)))
        return hr;

    *frame = &object->IDirect3DRMFrame3_iface;

    return D3DRM_OK;
1444 1445
}

1446
static HRESULT WINAPI d3drm3_CreateMesh(IDirect3DRM3 *iface, IDirect3DRMMesh **mesh)
1447
{
1448 1449 1450 1451
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
    struct d3drm_mesh *object;
    HRESULT hr;

1452
    TRACE("iface %p, mesh %p.\n", iface, mesh);
1453

1454 1455 1456 1457 1458 1459
    if (FAILED(hr = d3drm_mesh_create(&object, &d3drm->IDirect3DRM_iface)))
        return hr;

    *mesh = &object->IDirect3DRMMesh_iface;

    return S_OK;
1460 1461
}

1462
static HRESULT WINAPI d3drm3_CreateMeshBuilder(IDirect3DRM3 *iface, IDirect3DRMMeshBuilder3 **mesh_builder)
1463
{
1464 1465 1466 1467
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
    struct d3drm_mesh_builder *object;
    HRESULT hr;

1468
    TRACE("iface %p, mesh_builder %p.\n", iface, mesh_builder);
1469

1470 1471 1472 1473 1474 1475
    if (FAILED(hr = d3drm_mesh_builder_create(&object, &d3drm->IDirect3DRM_iface)))
        return hr;

    *mesh_builder = &object->IDirect3DRMMeshBuilder3_iface;

    return S_OK;
1476 1477
}

1478
static HRESULT WINAPI d3drm3_CreateFace(IDirect3DRM3 *iface, IDirect3DRMFace2 **face)
1479
{
1480 1481 1482 1483
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
    IDirect3DRMFace *face1;
    HRESULT hr;

1484
    TRACE("iface %p, face %p.\n", iface, face);
1485

1486 1487 1488 1489 1490 1491 1492
    if (FAILED(hr = IDirect3DRM_CreateFace(&d3drm->IDirect3DRM_iface, &face1)))
        return hr;

    hr = IDirect3DRMFace_QueryInterface(face1, &IID_IDirect3DRMFace2, (void **)face);
    IDirect3DRMFace_Release(face1);

    return hr;
1493 1494
}

1495
static HRESULT WINAPI d3drm3_CreateAnimation(IDirect3DRM3 *iface, IDirect3DRMAnimation2 **animation)
1496
{
1497 1498 1499
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
    struct d3drm_animation *object;
    HRESULT hr;
1500

1501 1502 1503 1504 1505 1506 1507 1508
    TRACE("iface %p, animation %p.\n", iface, animation);

    if (FAILED(hr = d3drm_animation_create(&object, &d3drm->IDirect3DRM_iface)))
        return hr;

    *animation = &object->IDirect3DRMAnimation2_iface;

    return hr;
1509 1510
}

1511
static HRESULT WINAPI d3drm3_CreateAnimationSet(IDirect3DRM3 *iface, IDirect3DRMAnimationSet2 **set)
1512
{
1513
    FIXME("iface %p, set %p stub!\n", iface, set);
1514 1515 1516 1517

    return E_NOTIMPL;
}

1518
static HRESULT WINAPI d3drm3_CreateTexture(IDirect3DRM3 *iface,
1519
        D3DRMIMAGE *image, IDirect3DRMTexture3 **texture)
1520
{
1521
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1522 1523 1524
    struct d3drm_texture *object;
    HRESULT hr;

1525 1526 1527 1528
    TRACE("iface %p, image %p, texture %p.\n", iface, image, texture);

    if (!texture)
        return D3DRMERR_BADVALUE;
1529

1530
    if (FAILED(hr = d3drm_texture_create(&object, &d3drm->IDirect3DRM_iface)))
1531 1532 1533 1534
        return hr;

    *texture = &object->IDirect3DRMTexture3_iface;

1535 1536 1537 1538 1539 1540 1541
    if (FAILED(IDirect3DRMTexture3_InitFromImage(*texture, image)))
    {
        IDirect3DRMTexture3_Release(*texture);
        *texture = NULL;
        return D3DRMERR_BADVALUE;
    }

1542
    return D3DRM_OK;
1543 1544
}

1545
static HRESULT WINAPI d3drm3_CreateLight(IDirect3DRM3 *iface,
1546
        D3DRMLIGHTTYPE type, D3DCOLOR color, IDirect3DRMLight **light)
1547
{
1548 1549
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
    struct d3drm_light *object;
1550
    HRESULT hr;
1551

1552
    FIXME("iface %p, type %#x, color 0x%08x, light %p partial stub!\n", iface, type, color, light);
1553

1554
    if (SUCCEEDED(hr = d3drm_light_create(&object, &d3drm->IDirect3DRM_iface)))
1555
    {
1556 1557
        IDirect3DRMLight_SetType(&object->IDirect3DRMLight_iface, type);
        IDirect3DRMLight_SetColor(&object->IDirect3DRMLight_iface, color);
1558 1559
    }

1560 1561
    *light = &object->IDirect3DRMLight_iface;

1562
    return hr;
1563 1564
}

1565
static HRESULT WINAPI d3drm3_CreateLightRGB(IDirect3DRM3 *iface, D3DRMLIGHTTYPE type,
1566
        D3DVALUE red, D3DVALUE green, D3DVALUE blue, IDirect3DRMLight **light)
1567
{
1568 1569
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
    struct d3drm_light *object;
1570
    HRESULT hr;
1571

1572 1573
    FIXME("iface %p, type %#x, red %.8e, green %.8e, blue %.8e, light %p partial stub!\n",
            iface, type, red, green, blue, light);
1574

1575
    if (SUCCEEDED(hr = d3drm_light_create(&object, &d3drm->IDirect3DRM_iface)))
1576
    {
1577 1578
        IDirect3DRMLight_SetType(&object->IDirect3DRMLight_iface, type);
        IDirect3DRMLight_SetColorRGB(&object->IDirect3DRMLight_iface, red, green, blue);
1579 1580
    }

1581 1582
    *light = &object->IDirect3DRMLight_iface;

1583
    return hr;
1584 1585
}

1586
static HRESULT WINAPI d3drm3_CreateMaterial(IDirect3DRM3 *iface,
1587
        D3DVALUE power, IDirect3DRMMaterial2 **material)
1588
{
1589 1590
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
    struct d3drm_material *object;
1591
    HRESULT hr;
1592

1593
    TRACE("iface %p, power %.8e, material %p.\n", iface, power, material);
1594

1595 1596 1597 1598
    if (SUCCEEDED(hr = d3drm_material_create(&object, &d3drm->IDirect3DRM_iface)))
        IDirect3DRMMaterial2_SetPower(&object->IDirect3DRMMaterial2_iface, power);

    *material = &object->IDirect3DRMMaterial2_iface;
1599

1600
    return hr;
1601 1602
}

1603
static HRESULT WINAPI d3drm3_CreateDevice(IDirect3DRM3 *iface,
1604
        DWORD width, DWORD height, IDirect3DRMDevice3 **device)
1605
{
1606
    TRACE("iface %p, width %u, height %u, device %p.\n", iface, width, height, device);
1607

1608 1609 1610
    if (!device)
        return D3DRMERR_BADVALUE;
    *device = NULL;
1611

1612
    return D3DRMERR_BADDEVICE;
1613 1614
}

1615
static HRESULT WINAPI d3drm3_CreateDeviceFromSurface(IDirect3DRM3 *iface, GUID *guid,
1616
        IDirectDraw *ddraw, IDirectDrawSurface *backbuffer, DWORD flags, IDirect3DRMDevice3 **device)
1617
{
1618
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1619
    struct d3drm_device *object;
1620
    BOOL use_z_surface;
1621
    HRESULT hr;
1622 1623

    TRACE("iface %p, guid %s, ddraw %p, backbuffer %p, flags %#x, device %p.\n",
1624
            iface, debugstr_guid(guid), ddraw, backbuffer, flags, device);
1625

1626 1627 1628 1629 1630 1631 1632
    if (!device)
        return D3DRMERR_BADVALUE;
    *device = NULL;

    if (!backbuffer || !ddraw)
        return D3DRMERR_BADDEVICE;

1633
    if (FAILED(hr = d3drm_device_create(&object, &d3drm->IDirect3DRM_iface)))
1634 1635
        return hr;

1636
    use_z_surface = !(flags & D3DRMDEVICE_NOZBUFFER);
1637

1638
    if (SUCCEEDED(hr = d3drm_device_init(object, 3, ddraw, backbuffer, use_z_surface)))
1639
        *device = &object->IDirect3DRMDevice3_iface;
1640 1641 1642 1643
    else
        d3drm_device_destroy(object);

    return hr;
1644 1645
}

1646 1647
static HRESULT WINAPI d3drm3_CreateDeviceFromD3D(IDirect3DRM3 *iface,
        IDirect3D2 *d3d, IDirect3DDevice2 *d3d_device, IDirect3DRMDevice3 **device)
1648
{
1649
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1650
    struct d3drm_device *object;
1651
    HRESULT hr;
1652

1653
    TRACE("iface %p, d3d %p, d3d_device %p, device %p.\n",
1654
            iface, d3d, d3d_device, device);
1655

1656 1657 1658 1659
    if (!device)
        return D3DRMERR_BADVALUE;
    *device = NULL;

1660
    if (FAILED(hr = d3drm_device_create(&object, &d3drm->IDirect3DRM_iface)))
1661
        return hr;
1662 1663

    if (FAILED(hr = IDirect3DRMDevice3_InitFromD3D2(&object->IDirect3DRMDevice3_iface, d3d, d3d_device)))
1664
    {
1665
        d3drm_device_destroy(object);
1666 1667
        return hr;
    }
1668
    *device = &object->IDirect3DRMDevice3_iface;
1669

1670
    return D3DRM_OK;
1671 1672
}

1673
static HRESULT WINAPI d3drm3_CreateDeviceFromClipper(IDirect3DRM3 *iface,
1674 1675
        IDirectDrawClipper *clipper, GUID *guid, int width, int height,
        IDirect3DRMDevice3 **device)
1676
{
1677
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1678
    struct d3drm_device *object;
1679 1680
    IDirectDraw *ddraw;
    IDirectDrawSurface *render_target;
1681
    HRESULT hr;
1682 1683

    TRACE("iface %p, clipper %p, guid %s, width %d, height %d, device %p.\n",
1684
            iface, clipper, debugstr_guid(guid), width, height, device);
1685

1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696
    if (!device)
        return D3DRMERR_BADVALUE;
    *device = NULL;

    if (!clipper || !width || !height)
        return D3DRMERR_BADVALUE;

    hr = DirectDrawCreate(NULL, &ddraw, NULL);
    if (FAILED(hr))
        return hr;

1697
    if (FAILED(hr = d3drm_device_create(&object, &d3drm->IDirect3DRM_iface)))
1698 1699
    {
        IDirectDraw_Release(ddraw);
1700
        return hr;
1701
    }
1702

1703 1704 1705 1706 1707 1708 1709
    hr = d3drm_device_create_surfaces_from_clipper(object, ddraw, clipper, width, height, &render_target);
    if (FAILED(hr))
    {
        IDirectDraw_Release(ddraw);
        d3drm_device_destroy(object);
        return hr;
    }
1710

1711
    hr = d3drm_device_init(object, 3, ddraw, render_target, TRUE);
1712 1713 1714 1715 1716
    IDirectDraw_Release(ddraw);
    IDirectDrawSurface_Release(render_target);
    if (FAILED(hr))
        d3drm_device_destroy(object);
    else
1717
        *device = &object->IDirect3DRMDevice3_iface;
1718 1719

    return hr;
1720 1721
}

1722
static HRESULT WINAPI d3drm3_CreateShadow(IDirect3DRM3 *iface, IUnknown *object, IDirect3DRMLight *light,
1723
        D3DVALUE px, D3DVALUE py, D3DVALUE pz, D3DVALUE nx, D3DVALUE ny, D3DVALUE nz, IDirect3DRMShadow2 **shadow)
1724
{
1725 1726
    FIXME("iface %p, object %p, light %p, px %.8e, py %.8e, pz %.8e, nx %.8e, ny %.8e, nz %.8e, shadow %p stub!\n",
            iface, object, light, px, py, pz, nx, ny, nz, shadow);
1727 1728 1729 1730

    return E_NOTIMPL;
}

1731
static HRESULT WINAPI d3drm3_CreateTextureFromSurface(IDirect3DRM3 *iface,
1732
        IDirectDrawSurface *surface, IDirect3DRMTexture3 **texture)
1733
{
1734 1735 1736
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
    struct d3drm_texture *object;
    HRESULT hr;
1737

1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755
    TRACE("iface %p, surface %p, texture %p.\n", iface, surface, texture);

    if (!texture)
        return D3DRMERR_BADVALUE;

    if (FAILED(hr = d3drm_texture_create(&object, &d3drm->IDirect3DRM_iface)))
        return hr;

    *texture = &object->IDirect3DRMTexture3_iface;

    if (FAILED(IDirect3DRMTexture3_InitFromSurface(*texture, surface)))
    {
        IDirect3DRMTexture3_Release(*texture);
        *texture = NULL;
        return D3DRMERR_BADVALUE;
    }

    return D3DRM_OK;
1756 1757
}

1758
static HRESULT WINAPI d3drm3_CreateViewport(IDirect3DRM3 *iface, IDirect3DRMDevice3 *device,
1759
        IDirect3DRMFrame3 *camera, DWORD x, DWORD y, DWORD width, DWORD height, IDirect3DRMViewport2 **viewport)
1760
{
1761 1762 1763 1764
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
    struct d3drm_viewport *object;
    HRESULT hr;

1765
    TRACE("iface %p, device %p, camera %p, x %u, y %u, width %u, height %u, viewport %p.\n",
1766
            iface, device, camera, x, y, width, height, viewport);
1767

1768 1769
    if (!viewport)
        return D3DRMERR_BADVALUE;
1770 1771 1772 1773
    *viewport = NULL;

    if (!device || !camera)
        return D3DRMERR_BADOBJECT;
1774

1775 1776 1777 1778 1779
    if (FAILED(hr = d3drm_viewport_create(&object, &d3drm->IDirect3DRM_iface)))
        return hr;

    *viewport = &object->IDirect3DRMViewport2_iface;

1780 1781 1782 1783 1784 1785 1786
    if (FAILED(hr = IDirect3DRMViewport2_Init(*viewport, device, camera, x, y, width, height)))
    {
        IDirect3DRMViewport2_Release(*viewport);
        *viewport = NULL;
        return D3DRMERR_BADVALUE;
    }

1787
    return D3DRM_OK;
1788 1789
}

1790
static HRESULT WINAPI d3drm3_CreateWrap(IDirect3DRM3 *iface, D3DRMWRAPTYPE type, IDirect3DRMFrame3 *frame,
1791 1792 1793
        D3DVALUE ox, D3DVALUE oy, D3DVALUE oz, D3DVALUE dx, D3DVALUE dy, D3DVALUE dz,
        D3DVALUE ux, D3DVALUE uy, D3DVALUE uz, D3DVALUE ou, D3DVALUE ov, D3DVALUE su, D3DVALUE sv,
        IDirect3DRMWrap **wrap)
1794
{
1795 1796 1797 1798
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
    struct d3drm_wrap *object;
    HRESULT hr;

1799
    FIXME("iface %p, type %#x, frame %p, ox %.8e, oy %.8e, oz %.8e, dx %.8e, dy %.8e, dz %.8e, "
1800
            "ux %.8e, uy %.8e, uz %.8e, ou %.8e, ov %.8e, su %.8e, sv %.8e, wrap %p, semi-stub.\n",
1801
            iface, type, frame, ox, oy, oz, dx, dy, dz, ux, uy, uz, ou, ov, su, sv, wrap);
1802

1803 1804 1805 1806 1807 1808 1809 1810 1811
    if (!wrap)
        return D3DRMERR_BADVALUE;

    if (FAILED(hr = d3drm_wrap_create(&object, &d3drm->IDirect3DRM_iface)))
        return hr;

    *wrap = &object->IDirect3DRMWrap_iface;

    return S_OK;
1812 1813
}

1814
static HRESULT WINAPI d3drm3_CreateUserVisual(IDirect3DRM3 *iface,
1815
        D3DRMUSERVISUALCALLBACK cb, void *ctx, IDirect3DRMUserVisual **visual)
1816
{
1817
    FIXME("iface %p, cb %p, ctx %p, visual %p stub!\n", iface, cb, ctx, visual);
1818 1819 1820 1821

    return E_NOTIMPL;
}

1822
static HRESULT WINAPI d3drm3_LoadTexture(IDirect3DRM3 *iface,
1823
        const char *filename, IDirect3DRMTexture3 **texture)
1824
{
1825
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1826 1827 1828
    struct d3drm_texture *object;
    HRESULT hr;

1829 1830 1831 1832
    TRACE("iface %p, filename %s, texture %p.\n", iface, debugstr_a(filename), texture);

    if (!texture)
        return D3DRMERR_BADVALUE;
1833

1834
    if (FAILED(hr = d3drm_texture_create(&object, &d3drm->IDirect3DRM_iface)))
1835 1836 1837
        return hr;

    *texture = &object->IDirect3DRMTexture3_iface;
1838 1839 1840 1841 1842 1843
    if (FAILED(hr = IDirect3DRMTexture3_InitFromFile(*texture, filename)))
    {
        IDirect3DRMTexture3_Release(*texture);
        *texture = NULL;
        return hr == D3DRMERR_BADOBJECT ? D3DRMERR_FILENOTFOUND : hr;
    }
1844 1845

    return D3DRM_OK;
1846 1847
}

1848
static HRESULT WINAPI d3drm3_LoadTextureFromResource(IDirect3DRM3 *iface, HMODULE module,
1849
        const char *resource_name, const char *resource_type, IDirect3DRMTexture3 **texture)
1850
{
1851
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1852 1853 1854
    struct d3drm_texture *object;
    HRESULT hr;

1855 1856
    FIXME("iface %p, module %p, resource_name %s, resource_type %s, texture %p stub!\n",
            iface, module, debugstr_a(resource_name), debugstr_a(resource_type), texture);
1857

1858
    if (FAILED(hr = d3drm_texture_create(&object, &d3drm->IDirect3DRM_iface)))
1859 1860 1861 1862 1863
        return hr;

    *texture = &object->IDirect3DRMTexture3_iface;

    return D3DRM_OK;
1864 1865
}

1866
static HRESULT WINAPI d3drm3_SetSearchPath(IDirect3DRM3 *iface, const char *path)
1867
{
Henri Verbeet's avatar
Henri Verbeet committed
1868
    FIXME("iface %p, path %s stub!\n", iface, debugstr_a(path));
1869 1870 1871 1872

    return E_NOTIMPL;
}

1873
static HRESULT WINAPI d3drm3_AddSearchPath(IDirect3DRM3 *iface, const char *path)
1874
{
Henri Verbeet's avatar
Henri Verbeet committed
1875
    FIXME("iface %p, path %s stub!\n", iface, debugstr_a(path));
1876 1877 1878 1879

    return E_NOTIMPL;
}

1880
static HRESULT WINAPI d3drm3_GetSearchPath(IDirect3DRM3 *iface, DWORD *size, char *path)
1881
{
Henri Verbeet's avatar
Henri Verbeet committed
1882
    FIXME("iface %p, size %p, path %p stub!\n", iface, size, path);
1883 1884 1885 1886

    return E_NOTIMPL;
}

1887
static HRESULT WINAPI d3drm3_SetDefaultTextureColors(IDirect3DRM3 *iface, DWORD color_count)
1888
{
1889
    FIXME("iface %p, color_count %u stub!\n", iface, color_count);
1890 1891 1892 1893

    return E_NOTIMPL;
}

1894
static HRESULT WINAPI d3drm3_SetDefaultTextureShades(IDirect3DRM3 *iface, DWORD shade_count)
1895
{
1896
    FIXME("iface %p, shade_count %u stub!\n", iface, shade_count);
1897 1898 1899 1900

    return E_NOTIMPL;
}

1901
static HRESULT WINAPI d3drm3_GetDevices(IDirect3DRM3 *iface, IDirect3DRMDeviceArray **array)
1902
{
1903
    FIXME("iface %p, array %p stub!\n", iface, array);
1904 1905 1906 1907

    return E_NOTIMPL;
}

1908
static HRESULT WINAPI d3drm3_GetNamedObject(IDirect3DRM3 *iface,
1909
        const char *name, IDirect3DRMObject **object)
1910
{
1911
    FIXME("iface %p, name %s, object %p stub!\n", iface, debugstr_a(name), object);
1912 1913 1914 1915

    return E_NOTIMPL;
}

1916
static HRESULT WINAPI d3drm3_EnumerateObjects(IDirect3DRM3 *iface, D3DRMOBJECTCALLBACK cb, void *ctx)
1917
{
Henri Verbeet's avatar
Henri Verbeet committed
1918
    FIXME("iface %p, cb %p, ctx %p stub!\n", iface, cb, ctx);
1919 1920 1921 1922

    return E_NOTIMPL;
}

1923 1924
static HRESULT load_data(IDirect3DRM3 *iface, IDirectXFileData *data_object, IID **GUIDs, DWORD nb_GUIDs, D3DRMLOADCALLBACK LoadProc,
                         void *ArgLP, D3DRMLOADTEXTURECALLBACK LoadTextureProc, void *ArgLTP, IDirect3DRMFrame3 *parent_frame)
1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937
{
    HRESULT ret = D3DRMERR_BADOBJECT;
    HRESULT hr;
    const GUID* guid;
    DWORD i;
    BOOL requested = FALSE;

    hr = IDirectXFileData_GetType(data_object, &guid);
    if (hr != DXFILE_OK)
        goto end;

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

1938 1939
    /* Load object only if it is top level and requested or if it is part of another object */

1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952
    if (IsEqualGUID(guid, &TID_D3DRMMesh))
    {
        TRACE("Found TID_D3DRMMesh\n");

        for (i = 0; i < nb_GUIDs; i++)
            if (IsEqualGUID(GUIDs[i], &IID_IDirect3DRMMeshBuilder) ||
                IsEqualGUID(GUIDs[i], &IID_IDirect3DRMMeshBuilder2) ||
                IsEqualGUID(GUIDs[i], &IID_IDirect3DRMMeshBuilder3))
            {
                requested = TRUE;
                break;
            }

1953
        if (requested || parent_frame)
1954
        {
1955
            IDirect3DRMMeshBuilder3 *meshbuilder;
1956

1957
            TRACE("Load mesh data\n");
1958 1959 1960 1961

            hr = IDirect3DRM3_CreateMeshBuilder(iface, &meshbuilder);
            if (SUCCEEDED(hr))
            {
1962
                hr = load_mesh_data(meshbuilder, data_object, LoadTextureProc, ArgLTP);
1963 1964
                if (SUCCEEDED(hr))
                {
1965 1966
                    /* Only top level objects are notified */
                    if (!parent_frame)
1967
                    {
1968 1969 1970 1971 1972
                        IDirect3DRMObject *object;

                        hr = IDirect3DRMMeshBuilder3_QueryInterface(meshbuilder, GUIDs[i], (void**)&object);
                        if (SUCCEEDED(hr))
                        {
1973
                            LoadProc(object, GUIDs[i], ArgLP);
1974 1975 1976 1977 1978 1979
                            IDirect3DRMObject_Release(object);
                        }
                    }
                    else
                    {
                        IDirect3DRMFrame3_AddVisual(parent_frame, (IUnknown*)meshbuilder);
1980
                    }
1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001
                }
                IDirect3DRMMeshBuilder3_Release(meshbuilder);
            }

            if (FAILED(hr))
                ERR("Cannot process mesh\n");
        }
    }
    else if (IsEqualGUID(guid, &TID_D3DRMFrame))
    {
        TRACE("Found TID_D3DRMFrame\n");

        for (i = 0; i < nb_GUIDs; i++)
            if (IsEqualGUID(GUIDs[i], &IID_IDirect3DRMFrame) ||
                IsEqualGUID(GUIDs[i], &IID_IDirect3DRMFrame2) ||
                IsEqualGUID(GUIDs[i], &IID_IDirect3DRMFrame3))
            {
                requested = TRUE;
                break;
            }

2002
        if (requested || parent_frame)
2003
        {
2004
            IDirect3DRMFrame3 *frame;
2005

2006
            TRACE("Load frame data\n");
2007

2008
            hr = IDirect3DRM3_CreateFrame(iface, parent_frame, &frame);
2009 2010
            if (SUCCEEDED(hr))
            {
2011
                IDirectXFileObject *child;
2012

2013
                while (SUCCEEDED(hr = IDirectXFileData_GetNextObject(data_object, &child)))
2014
                {
2015 2016 2017
                    IDirectXFileData *data;
                    IDirectXFileDataReference *reference;
                    IDirectXFileBinary *binary;
2018

2019 2020
                    if (SUCCEEDED(IDirectXFileObject_QueryInterface(child,
                            &IID_IDirectXFileBinary, (void **)&binary)))
2021
                    {
2022 2023
                        FIXME("Binary Object not supported yet\n");
                        IDirectXFileBinary_Release(binary);
2024
                    }
2025 2026
                    else if (SUCCEEDED(IDirectXFileObject_QueryInterface(child,
                            &IID_IDirectXFileData, (void **)&data)))
2027
                    {
2028 2029 2030
                        TRACE("Found Data Object\n");
                        hr = load_data(iface, data, GUIDs, nb_GUIDs, LoadProc, ArgLP, LoadTextureProc, ArgLTP, frame);
                        IDirectXFileData_Release(data);
2031
                    }
2032 2033
                    else if (SUCCEEDED(IDirectXFileObject_QueryInterface(child,
                            &IID_IDirectXFileDataReference, (void **)&reference)))
2034 2035 2036 2037 2038 2039 2040
                    {
                        TRACE("Found Data Object Reference\n");
                        IDirectXFileDataReference_Resolve(reference, &data);
                        hr = load_data(iface, data, GUIDs, nb_GUIDs, LoadProc, ArgLP, LoadTextureProc, ArgLTP, frame);
                        IDirectXFileData_Release(data);
                        IDirectXFileDataReference_Release(reference);
                    }
2041
                    IDirectXFileObject_Release(child);
2042
                }
2043

2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058
                if (hr != DXFILEERR_NOMOREOBJECTS)
                {
                    IDirect3DRMFrame3_Release(frame);
                    goto end;
                }
                hr = S_OK;

                /* Only top level objects are notified */
                if (!parent_frame)
                {
                    IDirect3DRMObject *object;

                    hr = IDirect3DRMFrame3_QueryInterface(frame, GUIDs[i], (void**)&object);
                    if (SUCCEEDED(hr))
                    {
2059
                        LoadProc(object, GUIDs[i], ArgLP);
2060 2061
                        IDirect3DRMObject_Release(object);
                    }
2062 2063 2064 2065 2066 2067 2068 2069 2070 2071
                }
                IDirect3DRMFrame3_Release(frame);
            }

            if (FAILED(hr))
                ERR("Cannot process frame\n");
        }
    }
    else if (IsEqualGUID(guid, &TID_D3DRMMaterial))
    {
2072 2073 2074
        TRACE("Found TID_D3DRMMaterial\n");

        /* Cannot be requested so nothing to do */
2075
    }
2076 2077 2078 2079
    else if (IsEqualGUID(guid, &TID_D3DRMFrameTransformMatrix))
    {
        TRACE("Found TID_D3DRMFrameTransformMatrix\n");

2080
        /* Cannot be requested */
2081 2082
        if (parent_frame)
        {
2083
            D3DRMMATRIX4D *matrix;
2084 2085 2086 2087
            DWORD size;

            TRACE("Load Frame Transform Matrix data\n");

2088
            hr = IDirectXFileData_GetData(data_object, NULL, &size, (void**)&matrix);
2089 2090 2091
            if ((hr != DXFILE_OK) || (size != sizeof(matrix)))
                goto end;

2092
            hr = IDirect3DRMFrame3_AddTransform(parent_frame, D3DRMCOMBINE_REPLACE, *matrix);
2093 2094 2095 2096
            if (FAILED(hr))
                goto end;
        }
    }
2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108
    else
    {
        FIXME("Found unknown TID %s\n", debugstr_guid(guid));
    }

    ret = D3DRM_OK;

end:

    return ret;
}

2109
static HRESULT WINAPI d3drm3_Load(IDirect3DRM3 *iface, void *source, void *object_id, IID **iids,
2110 2111
        DWORD iid_count, D3DRMLOADOPTIONS flags, D3DRMLOADCALLBACK load_cb, void *load_ctx,
        D3DRMLOADTEXTURECALLBACK load_tex_cb, void *load_tex_ctx, IDirect3DRMFrame3 *parent_frame)
2112
{
2113
    DXFILELOADOPTIONS load_options;
2114
    IDirectXFile *file = NULL;
2115
    IDirectXFileEnumObject *enum_object = NULL;
2116
    IDirectXFileData *data = NULL;
2117 2118 2119
    HRESULT hr;
    const GUID* pGuid;
    DWORD size;
2120
    struct d3drm_file_header *header;
2121 2122 2123
    HRESULT ret = D3DRMERR_BADOBJECT;
    DWORD i;

2124 2125 2126 2127
    TRACE("iface %p, source %p, object_id %p, iids %p, iid_count %u, flags %#x, "
            "load_cb %p, load_ctx %p, load_tex_cb %p, load_tex_ctx %p, parent_frame %p.\n",
            iface, source, object_id, iids, iid_count, flags,
            load_cb, load_ctx, load_tex_cb, load_tex_ctx, parent_frame);
2128

2129
    TRACE("Looking for GUIDs:\n");
2130 2131
    for (i = 0; i < iid_count; ++i)
        TRACE("- %s (%s)\n", debugstr_guid(iids[i]), get_IID_string(iids[i]));
2132

2133
    if (flags == D3DRMLOAD_FROMMEMORY)
2134 2135 2136
    {
        load_options = DXFILELOAD_FROMMEMORY;
    }
2137
    else if (flags == D3DRMLOAD_FROMFILE)
2138 2139
    {
        load_options = DXFILELOAD_FROMFILE;
2140
        TRACE("Loading from file %s\n", debugstr_a(source));
2141 2142 2143
    }
    else
    {
2144
        FIXME("Load options %#x not supported yet.\n", flags);
2145 2146 2147
        return E_NOTIMPL;
    }

2148
    hr = DirectXFileCreate(&file);
2149 2150 2151
    if (hr != DXFILE_OK)
        goto end;

2152
    hr = IDirectXFile_RegisterTemplates(file, templates, strlen(templates));
2153 2154 2155
    if (hr != DXFILE_OK)
        goto end;

2156
    hr = IDirectXFile_CreateEnumObject(file, source, load_options, &enum_object);
2157 2158 2159
    if (hr != DXFILE_OK)
        goto end;

2160
    hr = IDirectXFileEnumObject_GetNextDataObject(enum_object, &data);
2161 2162 2163
    if (hr != DXFILE_OK)
        goto end;

2164
    hr = IDirectXFileData_GetType(data, &pGuid);
2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175
    if (hr != DXFILE_OK)
        goto end;

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

    if (!IsEqualGUID(pGuid, &TID_DXFILEHeader))
    {
        ret = D3DRMERR_BADFILE;
        goto end;
    }

2176 2177
    hr = IDirectXFileData_GetData(data, NULL, &size, (void **)&header);
    if ((hr != DXFILE_OK) || (size != sizeof(*header)))
2178 2179
        goto end;

2180
    TRACE("Version is %u.%u, flags %#x.\n", header->major, header->minor, header->flags);
2181 2182

    /* Version must be 1.0.x */
2183
    if ((header->major != 1) || (header->minor != 0))
2184 2185 2186 2187 2188
    {
        ret = D3DRMERR_BADFILE;
        goto end;
    }

2189 2190
    IDirectXFileData_Release(data);
    data = NULL;
2191 2192 2193

    while (1)
    {
2194
        hr = IDirectXFileEnumObject_GetNextDataObject(enum_object, &data);
2195 2196 2197 2198 2199 2200 2201
        if (hr == DXFILEERR_NOMOREOBJECTS)
        {
            TRACE("No more object\n");
            break;
        }
        else if (hr != DXFILE_OK)
        {
2202
            ret = D3DRMERR_BADFILE;
2203 2204 2205
            goto end;
        }

2206
        ret = load_data(iface, data, iids, iid_count, load_cb, load_ctx, load_tex_cb, load_tex_ctx, parent_frame);
2207
        if (ret != D3DRM_OK)
2208 2209
            goto end;

2210 2211
        IDirectXFileData_Release(data);
        data = NULL;
2212 2213 2214 2215 2216
    }

    ret = D3DRM_OK;

end:
2217 2218
    if (data)
        IDirectXFileData_Release(data);
2219 2220
    if (enum_object)
        IDirectXFileEnumObject_Release(enum_object);
2221 2222
    if (file)
        IDirectXFile_Release(file);
2223 2224

    return ret;
2225 2226
}

2227
static HRESULT WINAPI d3drm3_Tick(IDirect3DRM3 *iface, D3DVALUE tick)
2228
{
2229
    FIXME("iface %p, tick %.8e stub!\n", iface, tick);
2230 2231 2232 2233

    return E_NOTIMPL;
}

2234
static HRESULT WINAPI d3drm3_CreateProgressiveMesh(IDirect3DRM3 *iface, IDirect3DRMProgressiveMesh **mesh)
2235
{
2236
    FIXME("iface %p, mesh %p stub!\n", iface, mesh);
2237 2238 2239 2240

    return E_NOTIMPL;
}

2241
static HRESULT WINAPI d3drm3_RegisterClient(IDirect3DRM3 *iface, REFGUID guid, DWORD *id)
2242
{
Henri Verbeet's avatar
Henri Verbeet committed
2243
    FIXME("iface %p, guid %s, id %p stub!\n", iface, debugstr_guid(guid), id);
2244 2245 2246 2247

    return E_NOTIMPL;
}

2248
static HRESULT WINAPI d3drm3_UnregisterClient(IDirect3DRM3 *iface, REFGUID guid)
2249
{
2250
    FIXME("iface %p, guid %s stub!\n", iface, debugstr_guid(guid));
2251 2252 2253 2254

    return E_NOTIMPL;
}

2255
static HRESULT WINAPI d3drm3_CreateClippedVisual(IDirect3DRM3 *iface,
2256
        IDirect3DRMVisual *visual, IDirect3DRMClippedVisual **clipped_visual)
2257
{
2258
    FIXME("iface %p, visual %p, clipped_visual %p stub!\n", iface, visual, clipped_visual);
2259 2260 2261 2262

    return E_NOTIMPL;
}

2263
static HRESULT WINAPI d3drm3_SetOptions(IDirect3DRM3 *iface, DWORD flags)
2264
{
2265
    FIXME("iface %p, flags %#x stub!\n", iface, flags);
2266 2267 2268 2269

    return E_NOTIMPL;
}

2270
static HRESULT WINAPI d3drm3_GetOptions(IDirect3DRM3 *iface, DWORD *flags)
2271
{
Henri Verbeet's avatar
Henri Verbeet committed
2272
    FIXME("iface %p, flags %p stub!\n", iface, flags);
2273 2274 2275 2276

    return E_NOTIMPL;
}

2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319
static const struct IDirect3DRM3Vtbl d3drm3_vtbl =
{
    d3drm3_QueryInterface,
    d3drm3_AddRef,
    d3drm3_Release,
    d3drm3_CreateObject,
    d3drm3_CreateFrame,
    d3drm3_CreateMesh,
    d3drm3_CreateMeshBuilder,
    d3drm3_CreateFace,
    d3drm3_CreateAnimation,
    d3drm3_CreateAnimationSet,
    d3drm3_CreateTexture,
    d3drm3_CreateLight,
    d3drm3_CreateLightRGB,
    d3drm3_CreateMaterial,
    d3drm3_CreateDevice,
    d3drm3_CreateDeviceFromSurface,
    d3drm3_CreateDeviceFromD3D,
    d3drm3_CreateDeviceFromClipper,
    d3drm3_CreateTextureFromSurface,
    d3drm3_CreateShadow,
    d3drm3_CreateViewport,
    d3drm3_CreateWrap,
    d3drm3_CreateUserVisual,
    d3drm3_LoadTexture,
    d3drm3_LoadTextureFromResource,
    d3drm3_SetSearchPath,
    d3drm3_AddSearchPath,
    d3drm3_GetSearchPath,
    d3drm3_SetDefaultTextureColors,
    d3drm3_SetDefaultTextureShades,
    d3drm3_GetDevices,
    d3drm3_GetNamedObject,
    d3drm3_EnumerateObjects,
    d3drm3_Load,
    d3drm3_Tick,
    d3drm3_CreateProgressiveMesh,
    d3drm3_RegisterClient,
    d3drm3_UnregisterClient,
    d3drm3_CreateClippedVisual,
    d3drm3_SetOptions,
    d3drm3_GetOptions,
2320
};
2321

2322
HRESULT WINAPI Direct3DRMCreate(IDirect3DRM **d3drm)
2323
{
2324
    struct d3drm *object;
2325

2326
    TRACE("d3drm %p.\n", d3drm);
2327

2328
    if (!(object = heap_alloc_zero(sizeof(*object))))
2329 2330
        return E_OUTOFMEMORY;

2331 2332 2333
    object->IDirect3DRM_iface.lpVtbl = &d3drm1_vtbl;
    object->IDirect3DRM2_iface.lpVtbl = &d3drm2_vtbl;
    object->IDirect3DRM3_iface.lpVtbl = &d3drm3_vtbl;
2334 2335
    object->ref1 = 1;
    object->iface_count = 1;
2336

2337
    *d3drm = &object->IDirect3DRM_iface;
2338 2339 2340

    return S_OK;
}
2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355

HRESULT WINAPI DllCanUnloadNow(void)
{
    return S_FALSE;
}

HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv)
{
    TRACE("(%s, %s, %p): stub\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);

    if(!ppv)
        return E_INVALIDARG;

    return CLASS_E_CLASSNOTAVAILABLE;
}