d3drm.c 69 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
 *
 * 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
 */

23 24
#include "config.h"
#include "wine/port.h"
25 26 27 28 29

#include "d3drm_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(d3drm);

30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
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 "?";
}

48 49 50 51 52 53 54 55 56 57 58 59 60
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;
}

61 62 63 64 65 66 67 68 69 70 71 72 73
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;
}

74 75 76 77 78 79 80 81 82 83 84 85 86
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;
}

87 88 89 90 91 92 93 94 95 96 97 98 99
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;
}

100 101 102 103 104 105 106 107 108 109 110 111 112
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;
}

113 114 115 116 117 118 119 120 121 122 123 124 125
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;
}

126 127 128 129 130 131 132 133 134 135 136 137 138
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;
}

139 140 141 142 143 144 145 146 147 148 149 150 151
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;
}

152 153 154 155 156 157 158 159 160 161 162 163 164
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;
}

165 166 167 168 169 170 171 172 173 174 175 176 177
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;
}

178 179 180 181 182 183 184 185 186 187 188 189 190
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;
}

191 192
struct d3drm
{
193
    IDirect3DRM IDirect3DRM_iface;
194
    IDirect3DRM2 IDirect3DRM2_iface;
195
    IDirect3DRM3 IDirect3DRM3_iface;
196
    LONG ref1, ref2, ref3, iface_count;
197
};
198

199
static inline struct d3drm *impl_from_IDirect3DRM(IDirect3DRM *iface)
200
{
201
    return CONTAINING_RECORD(iface, struct d3drm, IDirect3DRM_iface);
202 203
}

204
static inline struct d3drm *impl_from_IDirect3DRM2(IDirect3DRM2 *iface)
205
{
206
    return CONTAINING_RECORD(iface, struct d3drm, IDirect3DRM2_iface);
207 208
}

209
static inline struct d3drm *impl_from_IDirect3DRM3(IDirect3DRM3 *iface)
210
{
211
    return CONTAINING_RECORD(iface, struct d3drm, IDirect3DRM3_iface);
212 213
}

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

220
static HRESULT WINAPI d3drm1_QueryInterface(IDirect3DRM *iface, REFIID riid, void **out)
221
{
222
    struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
223

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

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

246
    IUnknown_AddRef((IUnknown *)*out);
247
    return S_OK;
248 249
}

250
static ULONG WINAPI d3drm1_AddRef(IDirect3DRM *iface)
251
{
252
    struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
253
    ULONG refcount = InterlockedIncrement(&d3drm->ref1);
254

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

257 258 259
    if (refcount == 1)
        InterlockedIncrement(&d3drm->iface_count);

260
    return refcount;
261 262
}

263
static ULONG WINAPI d3drm1_Release(IDirect3DRM *iface)
264
{
265
    struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
266
    ULONG refcount = InterlockedDecrement(&d3drm->ref1);
267

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

270 271
    if (!refcount && !InterlockedDecrement(&d3drm->iface_count))
        d3drm_destroy(d3drm);
272

273
    return refcount;
274 275
}

276
static HRESULT WINAPI d3drm1_CreateObject(IDirect3DRM *iface,
Henri Verbeet's avatar
Henri Verbeet committed
277
        REFCLSID clsid, IUnknown *outer, REFIID iid, void **out)
278
{
279 280 281
    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
282
            iface, debugstr_guid(clsid), outer, debugstr_guid(iid), out);
283

284
    return IDirect3DRM3_CreateObject(&d3drm->IDirect3DRM3_iface, clsid, outer, iid, out);
285 286
}

287
static HRESULT WINAPI d3drm1_CreateFrame(IDirect3DRM *iface,
288
        IDirect3DRMFrame *parent_frame, IDirect3DRMFrame **frame)
289
{
290 291 292
    struct d3drm_frame *object;
    HRESULT hr;

293
    TRACE("iface %p, parent_frame %p, frame %p.\n", iface, parent_frame, frame);
294

295 296 297 298 299 300
    if (FAILED(hr = d3drm_frame_create(&object, (IUnknown *)parent_frame, iface)))
        return hr;

    *frame = &object->IDirect3DRMFrame_iface;

    return D3DRM_OK;
301 302
}

303
static HRESULT WINAPI d3drm1_CreateMesh(IDirect3DRM *iface, IDirect3DRMMesh **mesh)
304
{
305
    struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
306

307
    TRACE("iface %p, mesh %p.\n", iface, mesh);
308

309
    return IDirect3DRM3_CreateMesh(&d3drm->IDirect3DRM3_iface, mesh);
310 311
}

312
static HRESULT WINAPI d3drm1_CreateMeshBuilder(IDirect3DRM *iface, IDirect3DRMMeshBuilder **mesh_builder)
313
{
314 315
    struct d3drm *d3drm = impl_from_IDirect3DRM(iface);

316
    TRACE("iface %p, mesh_builder %p.\n", iface, mesh_builder);
317

318
    return IDirect3DRM2_CreateMeshBuilder(&d3drm->IDirect3DRM2_iface, (IDirect3DRMMeshBuilder2 **)mesh_builder);
319 320
}

321
static HRESULT WINAPI d3drm1_CreateFace(IDirect3DRM *iface, IDirect3DRMFace **face)
322
{
323 324 325
    struct d3drm_face *object;
    HRESULT hr;

326
    TRACE("iface %p, face %p.\n", iface, face);
327

328 329 330 331 332 333
    if (FAILED(hr = d3drm_face_create(&object)))
        return hr;

    *face = &object->IDirect3DRMFace_iface;

    return S_OK;
334 335
}

336
static HRESULT WINAPI d3drm1_CreateAnimation(IDirect3DRM *iface, IDirect3DRMAnimation **animation)
337
{
338 339
    struct d3drm_animation *object;
    HRESULT hr;
340

341 342 343 344 345 346 347 348 349 350 351
    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;
352 353
}

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

    return E_NOTIMPL;
}

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

368
    TRACE("iface %p, image %p, texture %p.\n", iface, image, texture);
369

370 371 372 373 374 375
    if (!texture)
        return D3DRMERR_BADVALUE;

    if (FAILED(hr = IDirect3DRM3_CreateTexture(&d3drm->IDirect3DRM3_iface, image, &texture3)))
    {
        *texture = NULL;
376
        return hr;
377
    }
378

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

382
    return hr;
383 384
}

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

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

392
    return IDirect3DRM3_CreateLight(&d3drm->IDirect3DRM3_iface, type, color, light);
393 394
}

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

400 401
    TRACE("iface %p, type %#x, red %.8e, green %.8e, blue %.8e, light %p.\n",
            iface, type, red, green, blue, light);
402

403
    return IDirect3DRM3_CreateLightRGB(&d3drm->IDirect3DRM3_iface, type, red, green, blue, light);
404 405
}

406
static HRESULT WINAPI d3drm1_CreateMaterial(IDirect3DRM *iface,
407
        D3DVALUE power, IDirect3DRMMaterial **material)
408
{
409
    struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
410

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

413
    return IDirect3DRM3_CreateMaterial(&d3drm->IDirect3DRM3_iface, power, (IDirect3DRMMaterial2 **)material);
414 415
}

416
static HRESULT WINAPI d3drm1_CreateDevice(IDirect3DRM *iface,
417
        DWORD width, DWORD height, IDirect3DRMDevice **device)
418
{
419 420
    struct d3drm_device *object;
    HRESULT hr;
421

422
    FIXME("iface %p, width %u, height %u, device %p partial stub!\n", iface, width, height, device);
423

424
    if (FAILED(hr = d3drm_device_create(&object, iface)))
425 426
        return hr;

427
    *device = &object->IDirect3DRMDevice_iface;
428 429

    return D3DRM_OK;
430 431
}

432 433
static HRESULT WINAPI d3drm1_CreateDeviceFromSurface(IDirect3DRM *iface, GUID *guid,
        IDirectDraw *ddraw, IDirectDrawSurface *backbuffer, IDirect3DRMDevice **device)
434
{
435 436
    struct d3drm_device *object;
    HRESULT hr;
437 438

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

441 442 443 444 445 446 447
    if (!device)
        return D3DRMERR_BADVALUE;
    *device = NULL;

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

448
    if (FAILED(hr = d3drm_device_create(&object, iface)))
449 450
        return hr;

451
    if (SUCCEEDED(hr = d3drm_device_init(object, 1, ddraw, backbuffer, TRUE)))
452
        *device = &object->IDirect3DRMDevice_iface;
453 454
    else
        d3drm_device_destroy(object);
455

456
    return hr;
457 458
}

459 460
static HRESULT WINAPI d3drm1_CreateDeviceFromD3D(IDirect3DRM *iface,
        IDirect3D *d3d, IDirect3DDevice *d3d_device, IDirect3DRMDevice **device)
461
{
462 463
    struct d3drm_device *object;
    HRESULT hr;
464
    TRACE("iface %p, d3d %p, d3d_device %p, device %p.\n",
465
            iface, d3d, d3d_device, device);
466

467 468 469 470
    if (!device)
        return D3DRMERR_BADVALUE;
    *device = NULL;

471
    if (FAILED(hr = d3drm_device_create(&object, iface)))
472 473
        return hr;

474
    if (FAILED(hr = IDirect3DRMDevice_InitFromD3D(&object->IDirect3DRMDevice_iface, d3d, d3d_device)))
475 476 477 478
    {
        d3drm_device_destroy(object);
        return hr;
    }
479
    *device = &object->IDirect3DRMDevice_iface;
480 481

    return D3DRM_OK;
482 483
}

484 485 486
static HRESULT WINAPI d3drm1_CreateDeviceFromClipper(IDirect3DRM *iface,
        IDirectDrawClipper *clipper, GUID *guid, int width, int height,
        IDirect3DRMDevice **device)
487
{
488
    struct d3drm_device *object;
489 490
    IDirectDraw *ddraw;
    IDirectDrawSurface *render_target;
491
    HRESULT hr;
492 493

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

496 497 498 499 500 501 502 503 504 505 506
    if (!device)
        return D3DRMERR_BADVALUE;
    *device = NULL;

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

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

507
    if (FAILED(hr = d3drm_device_create(&object, iface)))
508 509
    {
        IDirectDraw_Release(ddraw);
510
        return hr;
511
    }
512

513 514 515 516 517 518 519
    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;
    }
520

521
    hr = d3drm_device_init(object, 1, ddraw, render_target, TRUE);
522 523 524 525 526
    IDirectDraw_Release(ddraw);
    IDirectDrawSurface_Release(render_target);
    if (FAILED(hr))
        d3drm_device_destroy(object);
    else
527
        *device = &object->IDirect3DRMDevice_iface;
528 529

    return hr;
530 531
}

532 533
static HRESULT WINAPI d3drm1_CreateTextureFromSurface(IDirect3DRM *iface,
        IDirectDrawSurface *surface, IDirect3DRMTexture **texture)
534
{
535 536 537
    struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
    IDirect3DRMTexture3 *texture3;
    HRESULT hr;
538

539 540 541 542 543 544 545 546 547 548 549 550 551 552 553
    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;
554 555
}

556
static HRESULT WINAPI d3drm1_CreateShadow(IDirect3DRM *iface, IDirect3DRMVisual *visual,
557 558
        IDirect3DRMLight *light, D3DVALUE px, D3DVALUE py, D3DVALUE pz, D3DVALUE nx, D3DVALUE ny, D3DVALUE nz,
        IDirect3DRMVisual **shadow)
559
{
560 561
    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);
562 563 564 565

    return E_NOTIMPL;
}

566
static HRESULT WINAPI d3drm1_CreateViewport(IDirect3DRM *iface, IDirect3DRMDevice *device,
567
        IDirect3DRMFrame *camera, DWORD x, DWORD y, DWORD width, DWORD height, IDirect3DRMViewport **viewport)
568
{
569
    struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
570 571 572 573
    IDirect3DRMDevice3 *device3;
    IDirect3DRMFrame3 *camera3;
    IDirect3DRMViewport2 *viewport2;
    HRESULT hr;
574

575
    TRACE("iface %p, device %p, camera %p, x %u, y %u, width %u, height %u, viewport %p.\n",
576
            iface, device, camera, x, y, width, height, viewport);
577

578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601
    if (!device || !camera)
        return D3DRMERR_BADOBJECT;
    if (!viewport)
        return D3DRMERR_BADVALUE;

    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;
602 603
}

604
static HRESULT WINAPI d3drm1_CreateWrap(IDirect3DRM *iface, D3DRMWRAPTYPE type, IDirect3DRMFrame *frame,
605 606 607
        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)
608
{
609 610 611
    struct d3drm_wrap *object;
    HRESULT hr;

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

616 617 618 619 620 621 622 623 624
    if (!wrap)
        return D3DRMERR_BADVALUE;

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

    *wrap = &object->IDirect3DRMWrap_iface;

    return S_OK;
625 626
}

627
static HRESULT WINAPI d3drm1_CreateUserVisual(IDirect3DRM *iface,
628
        D3DRMUSERVISUALCALLBACK cb, void *ctx, IDirect3DRMUserVisual **visual)
629
{
630
    FIXME("iface %p, cb %p, ctx %p visual %p stub!\n", iface, cb, ctx, visual);
631 632 633 634

    return E_NOTIMPL;
}

635
static HRESULT WINAPI d3drm1_LoadTexture(IDirect3DRM *iface,
636
        const char *filename, IDirect3DRMTexture **texture)
637
{
638 639 640
    struct d3drm_texture *object;
    HRESULT hr;

641
    FIXME("iface %p, filename %s, texture %p stub!\n", iface, debugstr_a(filename), texture);
642

643
    if (FAILED(hr = d3drm_texture_create(&object, iface)))
644 645 646 647 648
        return hr;

    *texture = &object->IDirect3DRMTexture_iface;

    return D3DRM_OK;
649 650
}

651
static HRESULT WINAPI d3drm1_LoadTextureFromResource(IDirect3DRM *iface,
652
        HRSRC resource, IDirect3DRMTexture **texture)
653
{
654 655 656
    struct d3drm_texture *object;
    HRESULT hr;

657
    FIXME("iface %p, resource %p, texture %p stub!\n", iface, resource, texture);
658

659
    if (FAILED(hr = d3drm_texture_create(&object, iface)))
660 661 662 663 664
        return hr;

    *texture = &object->IDirect3DRMTexture_iface;

    return D3DRM_OK;
665 666
}

667
static HRESULT WINAPI d3drm1_SetSearchPath(IDirect3DRM *iface, const char *path)
668
{
Henri Verbeet's avatar
Henri Verbeet committed
669
    FIXME("iface %p, path %s stub!\n", iface, debugstr_a(path));
670 671 672 673

    return E_NOTIMPL;
}

674
static HRESULT WINAPI d3drm1_AddSearchPath(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_GetSearchPath(IDirect3DRM *iface, DWORD *size, char *path)
682
{
Henri Verbeet's avatar
Henri Verbeet committed
683
    FIXME("iface %p, size %p, path %p stub!\n", iface, size, path);
684 685 686 687

    return E_NOTIMPL;
}

688
static HRESULT WINAPI d3drm1_SetDefaultTextureColors(IDirect3DRM *iface, DWORD color_count)
689
{
690
    FIXME("iface %p, color_count %u stub!\n", iface, color_count);
691 692 693 694

    return E_NOTIMPL;
}

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

    return E_NOTIMPL;
}

702
static HRESULT WINAPI d3drm1_GetDevices(IDirect3DRM *iface, IDirect3DRMDeviceArray **array)
703
{
704
    FIXME("iface %p, array %p stub!\n", iface, array);
705 706 707 708

    return E_NOTIMPL;
}

709
static HRESULT WINAPI d3drm1_GetNamedObject(IDirect3DRM *iface,
710
        const char *name, IDirect3DRMObject **object)
711
{
712
    FIXME("iface %p, name %s, object %p stub!\n", iface, debugstr_a(name), object);
713 714 715 716

    return E_NOTIMPL;
}

717
static HRESULT WINAPI d3drm1_EnumerateObjects(IDirect3DRM *iface, D3DRMOBJECTCALLBACK cb, void *ctx)
718
{
Henri Verbeet's avatar
Henri Verbeet committed
719
    FIXME("iface %p, cb %p, ctx %p stub!\n", iface, cb, ctx);
720 721 722 723

    return E_NOTIMPL;
}

724
static HRESULT WINAPI d3drm1_Load(IDirect3DRM *iface, void *source, void *object_id, IID **iids,
725 726
        DWORD iid_count, D3DRMLOADOPTIONS flags, D3DRMLOADCALLBACK load_cb, void *load_ctx,
        D3DRMLOADTEXTURECALLBACK load_tex_cb, void *load_tex_ctx, IDirect3DRMFrame *parent_frame)
727
{
728
    struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
729
    IDirect3DRMFrame3 *parent_frame3 = NULL;
730
    HRESULT hr = D3DRM_OK;
731

732 733 734 735
    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);
736

737 738
    if (parent_frame)
        hr = IDirect3DRMFrame_QueryInterface(parent_frame, &IID_IDirect3DRMFrame3, (void **)&parent_frame3);
739
    if (SUCCEEDED(hr))
740 741 742 743
        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);
744 745

    return hr;
746 747
}

748
static HRESULT WINAPI d3drm1_Tick(IDirect3DRM *iface, D3DVALUE tick)
749
{
750
    FIXME("iface %p, tick %.8e stub!\n", iface, tick);
751 752 753 754

    return E_NOTIMPL;
}

755 756 757 758 759 760 761 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
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,
792
};
793

794
static HRESULT WINAPI d3drm2_QueryInterface(IDirect3DRM2 *iface, REFIID riid, void **out)
795
{
796 797 798
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);

    return d3drm1_QueryInterface(&d3drm->IDirect3DRM_iface, riid, out);
799 800
}

801
static ULONG WINAPI d3drm2_AddRef(IDirect3DRM2 *iface)
802
{
803
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
804 805 806 807 808 809
    ULONG refcount = InterlockedIncrement(&d3drm->ref2);

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

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

811
    return refcount;
812 813
}

814
static ULONG WINAPI d3drm2_Release(IDirect3DRM2 *iface)
815
{
816
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
817 818 819
    ULONG refcount = InterlockedDecrement(&d3drm->ref2);

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

821 822 823 824
    if (!refcount && !InterlockedDecrement(&d3drm->iface_count))
        d3drm_destroy(d3drm);

    return refcount;
825 826
}

827
static HRESULT WINAPI d3drm2_CreateObject(IDirect3DRM2 *iface,
Henri Verbeet's avatar
Henri Verbeet committed
828
        REFCLSID clsid, IUnknown *outer, REFIID iid, void **out)
829
{
830 831 832
    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
833
            iface, debugstr_guid(clsid), outer, debugstr_guid(iid), out);
834

835
    return IDirect3DRM3_CreateObject(&d3drm->IDirect3DRM3_iface, clsid, outer, iid, out);
836 837
}

838
static HRESULT WINAPI d3drm2_CreateFrame(IDirect3DRM2 *iface,
839
        IDirect3DRMFrame *parent_frame, IDirect3DRMFrame2 **frame)
840
{
841 842 843 844
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
    struct d3drm_frame *object;
    HRESULT hr;

845
    TRACE("iface %p, parent_frame %p, frame %p.\n", iface, parent_frame, frame);
846

847 848 849 850 851 852
    if (FAILED(hr = d3drm_frame_create(&object, (IUnknown *)parent_frame, &d3drm->IDirect3DRM_iface)))
        return hr;

    *frame = &object->IDirect3DRMFrame2_iface;

    return D3DRM_OK;
853 854
}

855
static HRESULT WINAPI d3drm2_CreateMesh(IDirect3DRM2 *iface, IDirect3DRMMesh **mesh)
856
{
857
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
858

859
    TRACE("iface %p, mesh %p.\n", iface, mesh);
860

861
    return IDirect3DRM3_CreateMesh(&d3drm->IDirect3DRM3_iface, mesh);
862 863
}

864
static HRESULT WINAPI d3drm2_CreateMeshBuilder(IDirect3DRM2 *iface, IDirect3DRMMeshBuilder2 **mesh_builder)
865
{
866 867 868 869
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
    struct d3drm_mesh_builder *object;
    HRESULT hr;

870
    TRACE("iface %p, mesh_builder %p.\n", iface, mesh_builder);
871

872 873 874 875 876 877
    if (FAILED(hr = d3drm_mesh_builder_create(&object, &d3drm->IDirect3DRM_iface)))
        return hr;

    *mesh_builder = &object->IDirect3DRMMeshBuilder2_iface;

    return S_OK;
878 879
}

880
static HRESULT WINAPI d3drm2_CreateFace(IDirect3DRM2 *iface, IDirect3DRMFace **face)
881
{
882 883
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);

884
    TRACE("iface %p, face %p.\n", iface, face);
885

886
    return IDirect3DRM_CreateFace(&d3drm->IDirect3DRM_iface, face);
887 888
}

889
static HRESULT WINAPI d3drm2_CreateAnimation(IDirect3DRM2 *iface, IDirect3DRMAnimation **animation)
890
{
891
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
892

893 894 895
    TRACE("iface %p, animation %p.\n", iface, animation);

    return IDirect3DRM_CreateAnimation(&d3drm->IDirect3DRM_iface, animation);
896 897
}

898
static HRESULT WINAPI d3drm2_CreateAnimationSet(IDirect3DRM2 *iface, IDirect3DRMAnimationSet **set)
899
{
900
    FIXME("iface %p, set %p stub!\n", iface, set);
901 902 903 904

    return E_NOTIMPL;
}

905
static HRESULT WINAPI d3drm2_CreateTexture(IDirect3DRM2 *iface,
906
        D3DRMIMAGE *image, IDirect3DRMTexture2 **texture)
907
{
908
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
909
    IDirect3DRMTexture3 *texture3;
910 911
    HRESULT hr;

912
    TRACE("iface %p, image %p, texture %p.\n", iface, image, texture);
913

914 915 916 917 918 919
    if (!texture)
        return D3DRMERR_BADVALUE;

    if (FAILED(hr = IDirect3DRM3_CreateTexture(&d3drm->IDirect3DRM3_iface, image, &texture3)))
    {
        *texture = NULL;
920
        return hr;
921
    }
922

923 924
    hr = IDirect3DRMTexture3_QueryInterface(texture3, &IID_IDirect3DRMTexture2, (void **)texture);
    IDirect3DRMTexture3_Release(texture3);
925

926
    return hr;
927 928
}

929
static HRESULT WINAPI d3drm2_CreateLight(IDirect3DRM2 *iface,
930
        D3DRMLIGHTTYPE type, D3DCOLOR color, IDirect3DRMLight **light)
931
{
932
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
933

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

936
    return IDirect3DRM3_CreateLight(&d3drm->IDirect3DRM3_iface, type, color, light);
937 938
}

939
static HRESULT WINAPI d3drm2_CreateLightRGB(IDirect3DRM2 *iface, D3DRMLIGHTTYPE type,
940
        D3DVALUE red, D3DVALUE green, D3DVALUE blue, IDirect3DRMLight **light)
941
{
942
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
943

944 945
    TRACE("iface %p, type %#x, red %.8e, green %.8e, blue %.8e, light %p.\n",
            iface, type, red, green, blue, light);
946

947
    return IDirect3DRM3_CreateLightRGB(&d3drm->IDirect3DRM3_iface, type, red, green, blue, light);
948 949
}

950
static HRESULT WINAPI d3drm2_CreateMaterial(IDirect3DRM2 *iface,
951
        D3DVALUE power, IDirect3DRMMaterial **material)
952
{
953
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
954

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

957
    return IDirect3DRM3_CreateMaterial(&d3drm->IDirect3DRM3_iface, power, (IDirect3DRMMaterial2 **)material);
958 959
}

960
static HRESULT WINAPI d3drm2_CreateDevice(IDirect3DRM2 *iface,
961
        DWORD width, DWORD height, IDirect3DRMDevice2 **device)
962
{
963
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
964 965
    struct d3drm_device *object;
    HRESULT hr;
966

967 968
    FIXME("iface %p, width %u, height %u, device %p partial stub!\n", iface, width, height, device);

969
    if (FAILED(hr = d3drm_device_create(&object, &d3drm->IDirect3DRM_iface)))
970
        return hr;
971

972
    *device = &object->IDirect3DRMDevice2_iface;
973 974

    return D3DRM_OK;
975 976
}

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

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

993 994
    hr = IDirect3DRMDevice3_QueryInterface(device3, &IID_IDirect3DRMDevice2, (void**)device);
    IDirect3DRMDevice3_Release(device3);
995

996
    return hr;
997 998
}

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

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

1009 1010 1011
    if (!device)
        return D3DRMERR_BADVALUE;
    *device = NULL;
1012

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

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

    return hr;
1021 1022
}

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

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

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

1041 1042
    hr = IDirect3DRMDevice3_QueryInterface(device3, &IID_IDirect3DRMDevice2, (void**)device);
    IDirect3DRMDevice3_Release(device3);
1043

1044
    return hr;
1045 1046
}

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

1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068
    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;
1069 1070
}

1071
static HRESULT WINAPI d3drm2_CreateShadow(IDirect3DRM2 *iface, IDirect3DRMVisual *visual,
1072 1073
        IDirect3DRMLight *light, D3DVALUE px, D3DVALUE py, D3DVALUE pz, D3DVALUE nx, D3DVALUE ny, D3DVALUE nz,
        IDirect3DRMVisual **shadow)
1074
{
1075 1076
    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);
1077 1078 1079 1080

    return E_NOTIMPL;
}

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

1090 1091
    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);
1092

1093 1094 1095 1096 1097 1098
    if (!device || !camera)
        return D3DRMERR_BADOBJECT;
    if (!viewport)
        return D3DRMERR_BADVALUE;

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

1101 1102 1103 1104 1105
    if (FAILED(hr = IDirect3DRMFrame_QueryInterface(camera, &IID_IDirect3DRMFrame3, (void **)&camera3)))
    {
        IDirect3DRMDevice3_Release(device3);
        return hr;
    }
1106

1107 1108 1109 1110 1111 1112 1113 1114 1115 1116
    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;
1117 1118
}

1119
static HRESULT WINAPI d3drm2_CreateWrap(IDirect3DRM2 *iface, D3DRMWRAPTYPE type, IDirect3DRMFrame *frame,
1120 1121 1122
        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)
1123
{
1124 1125 1126 1127
    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",
1128
            iface, type, frame, ox, oy, oz, dx, dy, dz, ux, uy, uz, ou, ov, su, sv, wrap);
1129

1130 1131
    return IDirect3DRM_CreateWrap(&d3drm->IDirect3DRM_iface, type, frame, ox, oy, oz, dx, dy, dz, ux, uy, uz,
            ou, ov, su, sv, wrap);
1132 1133
}

1134
static HRESULT WINAPI d3drm2_CreateUserVisual(IDirect3DRM2 *iface,
1135
        D3DRMUSERVISUALCALLBACK cb, void *ctx, IDirect3DRMUserVisual **visual)
1136
{
1137
    FIXME("iface %p, cb %p, ctx %p, visual %p stub!\n", iface, cb, ctx, visual);
1138 1139 1140 1141

    return E_NOTIMPL;
}

1142
static HRESULT WINAPI d3drm2_LoadTexture(IDirect3DRM2 *iface,
1143
        const char *filename, IDirect3DRMTexture2 **texture)
1144
{
1145
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
1146 1147 1148
    struct d3drm_texture *object;
    HRESULT hr;

1149
    FIXME("iface %p, filename %s, texture %p stub!\n", iface, debugstr_a(filename), texture);
1150

1151
    if (FAILED(hr = d3drm_texture_create(&object, &d3drm->IDirect3DRM_iface)))
1152 1153 1154 1155
        return hr;

    *texture = &object->IDirect3DRMTexture2_iface;

1156
    return hr;
1157 1158
}

1159
static HRESULT WINAPI d3drm2_LoadTextureFromResource(IDirect3DRM2 *iface, HMODULE module,
1160
        const char *resource_name, const char *resource_type, IDirect3DRMTexture2 **texture)
1161
{
1162
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
1163 1164 1165
    struct d3drm_texture *object;
    HRESULT hr;

1166 1167
    FIXME("iface %p, resource_name %s, resource_type %s, texture %p stub!\n",
            iface, debugstr_a(resource_name), debugstr_a(resource_type), texture);
1168

1169
    if (FAILED(hr = d3drm_texture_create(&object, &d3drm->IDirect3DRM_iface)))
1170 1171 1172 1173 1174
        return hr;

    *texture = &object->IDirect3DRMTexture2_iface;

    return D3DRM_OK;
1175 1176
}

1177
static HRESULT WINAPI d3drm2_SetSearchPath(IDirect3DRM2 *iface, const char *path)
1178
{
Henri Verbeet's avatar
Henri Verbeet committed
1179
    FIXME("iface %p, path %s stub!\n", iface, debugstr_a(path));
1180 1181 1182 1183

    return E_NOTIMPL;
}

1184
static HRESULT WINAPI d3drm2_AddSearchPath(IDirect3DRM2 *iface, const char *path)
1185
{
Henri Verbeet's avatar
Henri Verbeet committed
1186
    FIXME("iface %p, path %s stub!\n", iface, debugstr_a(path));
1187 1188 1189 1190

    return E_NOTIMPL;
}

1191
static HRESULT WINAPI d3drm2_GetSearchPath(IDirect3DRM2 *iface, DWORD *size, char *path)
1192
{
Henri Verbeet's avatar
Henri Verbeet committed
1193
    FIXME("iface %p, size %p, path %p stub!\n", iface, size, path);
1194 1195 1196 1197

    return E_NOTIMPL;
}

1198
static HRESULT WINAPI d3drm2_SetDefaultTextureColors(IDirect3DRM2 *iface, DWORD color_count)
1199
{
1200
    FIXME("iface %p, color_count %u stub!\n", iface, color_count);
1201 1202 1203 1204

    return E_NOTIMPL;
}

1205
static HRESULT WINAPI d3drm2_SetDefaultTextureShades(IDirect3DRM2 *iface, DWORD shade_count)
1206
{
1207
    FIXME("iface %p, shade_count %u stub!\n", iface, shade_count);
1208 1209 1210 1211

    return E_NOTIMPL;
}

1212
static HRESULT WINAPI d3drm2_GetDevices(IDirect3DRM2 *iface, IDirect3DRMDeviceArray **array)
1213
{
1214
    FIXME("iface %p, array %p stub!\n", iface, array);
1215 1216 1217 1218

    return E_NOTIMPL;
}

1219
static HRESULT WINAPI d3drm2_GetNamedObject(IDirect3DRM2 *iface,
1220
        const char *name, IDirect3DRMObject **object)
1221
{
1222
    FIXME("iface %p, name %s, object %p stub!\n", iface, debugstr_a(name), object);
1223 1224 1225 1226

    return E_NOTIMPL;
}

1227
static HRESULT WINAPI d3drm2_EnumerateObjects(IDirect3DRM2 *iface, D3DRMOBJECTCALLBACK cb, void *ctx)
1228
{
Henri Verbeet's avatar
Henri Verbeet committed
1229
    FIXME("iface %p, cb %p, ctx %p stub!\n", iface, cb, ctx);
1230 1231 1232 1233

    return E_NOTIMPL;
}

1234
static HRESULT WINAPI d3drm2_Load(IDirect3DRM2 *iface, void *source, void *object_id, IID **iids,
1235 1236
        DWORD iid_count, D3DRMLOADOPTIONS flags, D3DRMLOADCALLBACK load_cb, void *load_ctx,
        D3DRMLOADTEXTURECALLBACK load_tex_cb, void *load_tex_ctx, IDirect3DRMFrame *parent_frame)
1237
{
1238
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
1239
    IDirect3DRMFrame3 *parent_frame3 = NULL;
1240
    HRESULT hr = D3DRM_OK;
1241

1242 1243 1244 1245
    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);
1246

1247 1248
    if (parent_frame)
        hr = IDirect3DRMFrame_QueryInterface(parent_frame, &IID_IDirect3DRMFrame3, (void **)&parent_frame3);
1249
    if (SUCCEEDED(hr))
1250 1251 1252 1253
        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);
1254 1255

    return hr;
1256 1257
}

1258
static HRESULT WINAPI d3drm2_Tick(IDirect3DRM2 *iface, D3DVALUE tick)
1259
{
1260
    FIXME("iface %p, tick %.8e stub!\n", iface, tick);
1261 1262 1263 1264

    return E_NOTIMPL;
}

1265
static HRESULT WINAPI d3drm2_CreateProgressiveMesh(IDirect3DRM2 *iface, IDirect3DRMProgressiveMesh **mesh)
1266
{
1267
    FIXME("iface %p, mesh %p stub!\n", iface, mesh);
1268 1269 1270 1271

    return E_NOTIMPL;
}

1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 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
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,
1310
};
1311

1312
static HRESULT WINAPI d3drm3_QueryInterface(IDirect3DRM3 *iface, REFIID riid, void **out)
1313
{
1314 1315 1316
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);

    return d3drm1_QueryInterface(&d3drm->IDirect3DRM_iface, riid, out);
1317 1318
}

1319
static ULONG WINAPI d3drm3_AddRef(IDirect3DRM3 *iface)
1320
{
1321
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1322 1323 1324 1325 1326 1327
    ULONG refcount = InterlockedIncrement(&d3drm->ref3);

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

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

1329
    return refcount;
1330 1331
}

1332
static ULONG WINAPI d3drm3_Release(IDirect3DRM3 *iface)
1333
{
1334
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1335 1336 1337
    ULONG refcount = InterlockedDecrement(&d3drm->ref3);

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

1339 1340 1341 1342
    if (!refcount && !InterlockedDecrement(&d3drm->iface_count))
        d3drm_destroy(d3drm);

    return refcount;
1343 1344
}

1345
static HRESULT WINAPI d3drm3_CreateObject(IDirect3DRM3 *iface,
Henri Verbeet's avatar
Henri Verbeet committed
1346
        REFCLSID clsid, IUnknown *outer, REFIID iid, void **out)
1347
{
1348
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1349
    IUnknown *object;
1350
    unsigned int i;
1351 1352
    HRESULT hr;

1353 1354 1355 1356 1357 1358 1359 1360
    static const struct
    {
        const CLSID *clsid;
        HRESULT (*create_object)(void **object, IDirect3DRM *d3drm);
    }
    object_table[] =
    {
        {&CLSID_CDirect3DRMTexture, d3drm_create_texture_object},
1361
        {&CLSID_CDirect3DRMDevice, d3drm_create_device_object},
1362
        {&CLSID_CDirect3DRMViewport, d3drm_create_viewport_object},
1363
        {&CLSID_CDirect3DRMFace, d3drm_create_face_object},
1364
        {&CLSID_CDirect3DRMMeshBuilder, d3drm_create_mesh_builder_object},
1365
        {&CLSID_CDirect3DRMFrame, d3drm_create_frame_object},
1366
        {&CLSID_CDirect3DRMLight, d3drm_create_light_object},
1367
        {&CLSID_CDirect3DRMMaterial, d3drm_create_material_object},
1368
        {&CLSID_CDirect3DRMMesh, d3drm_create_mesh_object},
1369
        {&CLSID_CDirect3DRMAnimation, d3drm_create_animation_object},
1370
        {&CLSID_CDirect3DRMWrap, d3drm_create_wrap_object},
1371 1372
    };

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

1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391
    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;
    }

1392
    for (i = 0; i < ARRAY_SIZE(object_table); ++i)
1393
    {
1394
        if (IsEqualGUID(clsid, object_table[i].clsid))
1395
        {
1396 1397 1398 1399 1400 1401
            if (FAILED(hr = object_table[i].create_object((void **)&object, &d3drm->IDirect3DRM_iface)))
            {
                *out = NULL;
                return hr;
            }
            break;
1402 1403
        }
    }
1404
    if (i == ARRAY_SIZE(object_table))
1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415
    {
        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;
1416 1417
}

1418
static HRESULT WINAPI d3drm3_CreateFrame(IDirect3DRM3 *iface,
1419
        IDirect3DRMFrame3 *parent, IDirect3DRMFrame3 **frame)
1420
{
1421 1422 1423 1424
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
    struct d3drm_frame *object;
    HRESULT hr;

1425
    TRACE("iface %p, parent %p, frame %p.\n", iface, parent, frame);
1426

1427 1428 1429 1430 1431 1432
    if (FAILED(hr = d3drm_frame_create(&object, (IUnknown *)parent, &d3drm->IDirect3DRM_iface)))
        return hr;

    *frame = &object->IDirect3DRMFrame3_iface;

    return D3DRM_OK;
1433 1434
}

1435
static HRESULT WINAPI d3drm3_CreateMesh(IDirect3DRM3 *iface, IDirect3DRMMesh **mesh)
1436
{
1437 1438 1439 1440
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
    struct d3drm_mesh *object;
    HRESULT hr;

1441
    TRACE("iface %p, mesh %p.\n", iface, mesh);
1442

1443 1444 1445 1446 1447 1448
    if (FAILED(hr = d3drm_mesh_create(&object, &d3drm->IDirect3DRM_iface)))
        return hr;

    *mesh = &object->IDirect3DRMMesh_iface;

    return S_OK;
1449 1450
}

1451
static HRESULT WINAPI d3drm3_CreateMeshBuilder(IDirect3DRM3 *iface, IDirect3DRMMeshBuilder3 **mesh_builder)
1452
{
1453 1454 1455 1456
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
    struct d3drm_mesh_builder *object;
    HRESULT hr;

1457
    TRACE("iface %p, mesh_builder %p.\n", iface, mesh_builder);
1458

1459 1460 1461 1462 1463 1464
    if (FAILED(hr = d3drm_mesh_builder_create(&object, &d3drm->IDirect3DRM_iface)))
        return hr;

    *mesh_builder = &object->IDirect3DRMMeshBuilder3_iface;

    return S_OK;
1465 1466
}

1467
static HRESULT WINAPI d3drm3_CreateFace(IDirect3DRM3 *iface, IDirect3DRMFace2 **face)
1468
{
1469 1470 1471 1472
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
    IDirect3DRMFace *face1;
    HRESULT hr;

1473
    TRACE("iface %p, face %p.\n", iface, face);
1474

1475 1476 1477 1478 1479 1480 1481
    if (FAILED(hr = IDirect3DRM_CreateFace(&d3drm->IDirect3DRM_iface, &face1)))
        return hr;

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

    return hr;
1482 1483
}

1484
static HRESULT WINAPI d3drm3_CreateAnimation(IDirect3DRM3 *iface, IDirect3DRMAnimation2 **animation)
1485
{
1486 1487 1488
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
    struct d3drm_animation *object;
    HRESULT hr;
1489

1490 1491 1492 1493 1494 1495 1496 1497
    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;
1498 1499
}

1500
static HRESULT WINAPI d3drm3_CreateAnimationSet(IDirect3DRM3 *iface, IDirect3DRMAnimationSet2 **set)
1501
{
1502
    FIXME("iface %p, set %p stub!\n", iface, set);
1503 1504 1505 1506

    return E_NOTIMPL;
}

1507
static HRESULT WINAPI d3drm3_CreateTexture(IDirect3DRM3 *iface,
1508
        D3DRMIMAGE *image, IDirect3DRMTexture3 **texture)
1509
{
1510
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1511 1512 1513
    struct d3drm_texture *object;
    HRESULT hr;

1514 1515 1516 1517
    TRACE("iface %p, image %p, texture %p.\n", iface, image, texture);

    if (!texture)
        return D3DRMERR_BADVALUE;
1518

1519
    if (FAILED(hr = d3drm_texture_create(&object, &d3drm->IDirect3DRM_iface)))
1520 1521 1522 1523
        return hr;

    *texture = &object->IDirect3DRMTexture3_iface;

1524 1525 1526 1527 1528 1529 1530
    if (FAILED(IDirect3DRMTexture3_InitFromImage(*texture, image)))
    {
        IDirect3DRMTexture3_Release(*texture);
        *texture = NULL;
        return D3DRMERR_BADVALUE;
    }

1531
    return D3DRM_OK;
1532 1533
}

1534
static HRESULT WINAPI d3drm3_CreateLight(IDirect3DRM3 *iface,
1535
        D3DRMLIGHTTYPE type, D3DCOLOR color, IDirect3DRMLight **light)
1536
{
1537 1538
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
    struct d3drm_light *object;
1539
    HRESULT hr;
1540

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

1543
    if (SUCCEEDED(hr = d3drm_light_create(&object, &d3drm->IDirect3DRM_iface)))
1544
    {
1545 1546
        IDirect3DRMLight_SetType(&object->IDirect3DRMLight_iface, type);
        IDirect3DRMLight_SetColor(&object->IDirect3DRMLight_iface, color);
1547 1548
    }

1549 1550
    *light = &object->IDirect3DRMLight_iface;

1551
    return hr;
1552 1553
}

1554
static HRESULT WINAPI d3drm3_CreateLightRGB(IDirect3DRM3 *iface, D3DRMLIGHTTYPE type,
1555
        D3DVALUE red, D3DVALUE green, D3DVALUE blue, IDirect3DRMLight **light)
1556
{
1557 1558
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
    struct d3drm_light *object;
1559
    HRESULT hr;
1560

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

1564
    if (SUCCEEDED(hr = d3drm_light_create(&object, &d3drm->IDirect3DRM_iface)))
1565
    {
1566 1567
        IDirect3DRMLight_SetType(&object->IDirect3DRMLight_iface, type);
        IDirect3DRMLight_SetColorRGB(&object->IDirect3DRMLight_iface, red, green, blue);
1568 1569
    }

1570 1571
    *light = &object->IDirect3DRMLight_iface;

1572
    return hr;
1573 1574
}

1575
static HRESULT WINAPI d3drm3_CreateMaterial(IDirect3DRM3 *iface,
1576
        D3DVALUE power, IDirect3DRMMaterial2 **material)
1577
{
1578 1579
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
    struct d3drm_material *object;
1580
    HRESULT hr;
1581

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

1584 1585 1586 1587
    if (SUCCEEDED(hr = d3drm_material_create(&object, &d3drm->IDirect3DRM_iface)))
        IDirect3DRMMaterial2_SetPower(&object->IDirect3DRMMaterial2_iface, power);

    *material = &object->IDirect3DRMMaterial2_iface;
1588

1589
    return hr;
1590 1591
}

1592
static HRESULT WINAPI d3drm3_CreateDevice(IDirect3DRM3 *iface,
1593
        DWORD width, DWORD height, IDirect3DRMDevice3 **device)
1594
{
1595
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1596 1597
    struct d3drm_device *object;
    HRESULT hr;
1598

1599
    FIXME("iface %p, width %u, height %u, device %p partial stub!\n", iface, width, height, device);
1600

1601
    if (FAILED(hr = d3drm_device_create(&object, &d3drm->IDirect3DRM_iface)))
1602 1603
        return hr;

1604
    *device = &object->IDirect3DRMDevice3_iface;
1605 1606

    return D3DRM_OK;
1607 1608
}

1609
static HRESULT WINAPI d3drm3_CreateDeviceFromSurface(IDirect3DRM3 *iface, GUID *guid,
1610
        IDirectDraw *ddraw, IDirectDrawSurface *backbuffer, DWORD flags, IDirect3DRMDevice3 **device)
1611
{
1612
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1613
    struct d3drm_device *object;
1614
    BOOL use_z_surface;
1615
    HRESULT hr;
1616 1617

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

1620 1621 1622 1623 1624 1625 1626
    if (!device)
        return D3DRMERR_BADVALUE;
    *device = NULL;

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

1627
    if (FAILED(hr = d3drm_device_create(&object, &d3drm->IDirect3DRM_iface)))
1628 1629
        return hr;

1630
    use_z_surface = !(flags & D3DRMDEVICE_NOZBUFFER);
1631

1632
    if (SUCCEEDED(hr = d3drm_device_init(object, 3, ddraw, backbuffer, use_z_surface)))
1633
        *device = &object->IDirect3DRMDevice3_iface;
1634 1635 1636 1637
    else
        d3drm_device_destroy(object);

    return hr;
1638 1639
}

1640 1641
static HRESULT WINAPI d3drm3_CreateDeviceFromD3D(IDirect3DRM3 *iface,
        IDirect3D2 *d3d, IDirect3DDevice2 *d3d_device, IDirect3DRMDevice3 **device)
1642
{
1643
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1644
    struct d3drm_device *object;
1645
    HRESULT hr;
1646

1647
    TRACE("iface %p, d3d %p, d3d_device %p, device %p.\n",
1648
            iface, d3d, d3d_device, device);
1649

1650 1651 1652 1653
    if (!device)
        return D3DRMERR_BADVALUE;
    *device = NULL;

1654
    if (FAILED(hr = d3drm_device_create(&object, &d3drm->IDirect3DRM_iface)))
1655
        return hr;
1656 1657

    if (FAILED(hr = IDirect3DRMDevice3_InitFromD3D2(&object->IDirect3DRMDevice3_iface, d3d, d3d_device)))
1658
    {
1659
        d3drm_device_destroy(object);
1660 1661
        return hr;
    }
1662
    *device = &object->IDirect3DRMDevice3_iface;
1663

1664
    return D3DRM_OK;
1665 1666
}

1667
static HRESULT WINAPI d3drm3_CreateDeviceFromClipper(IDirect3DRM3 *iface,
1668 1669
        IDirectDrawClipper *clipper, GUID *guid, int width, int height,
        IDirect3DRMDevice3 **device)
1670
{
1671
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1672
    struct d3drm_device *object;
1673 1674
    IDirectDraw *ddraw;
    IDirectDrawSurface *render_target;
1675
    HRESULT hr;
1676 1677

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

1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690
    if (!device)
        return D3DRMERR_BADVALUE;
    *device = NULL;

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

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

1691
    if (FAILED(hr = d3drm_device_create(&object, &d3drm->IDirect3DRM_iface)))
1692 1693
    {
        IDirectDraw_Release(ddraw);
1694
        return hr;
1695
    }
1696

1697 1698 1699 1700 1701 1702 1703
    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;
    }
1704

1705
    hr = d3drm_device_init(object, 3, ddraw, render_target, TRUE);
1706 1707 1708 1709 1710
    IDirectDraw_Release(ddraw);
    IDirectDrawSurface_Release(render_target);
    if (FAILED(hr))
        d3drm_device_destroy(object);
    else
1711
        *device = &object->IDirect3DRMDevice3_iface;
1712 1713

    return hr;
1714 1715
}

1716
static HRESULT WINAPI d3drm3_CreateShadow(IDirect3DRM3 *iface, IUnknown *object, IDirect3DRMLight *light,
1717
        D3DVALUE px, D3DVALUE py, D3DVALUE pz, D3DVALUE nx, D3DVALUE ny, D3DVALUE nz, IDirect3DRMShadow2 **shadow)
1718
{
1719 1720
    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);
1721 1722 1723 1724

    return E_NOTIMPL;
}

1725
static HRESULT WINAPI d3drm3_CreateTextureFromSurface(IDirect3DRM3 *iface,
1726
        IDirectDrawSurface *surface, IDirect3DRMTexture3 **texture)
1727
{
1728 1729 1730
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
    struct d3drm_texture *object;
    HRESULT hr;
1731

1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749
    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;
1750 1751
}

1752
static HRESULT WINAPI d3drm3_CreateViewport(IDirect3DRM3 *iface, IDirect3DRMDevice3 *device,
1753
        IDirect3DRMFrame3 *camera, DWORD x, DWORD y, DWORD width, DWORD height, IDirect3DRMViewport2 **viewport)
1754
{
1755 1756 1757 1758
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
    struct d3drm_viewport *object;
    HRESULT hr;

1759
    TRACE("iface %p, device %p, camera %p, x %u, y %u, width %u, height %u, viewport %p.\n",
1760
            iface, device, camera, x, y, width, height, viewport);
1761

1762 1763 1764 1765 1766
    if (!device || !camera)
        return D3DRMERR_BADOBJECT;
    if (!viewport)
        return D3DRMERR_BADVALUE;

1767 1768 1769 1770 1771
    if (FAILED(hr = d3drm_viewport_create(&object, &d3drm->IDirect3DRM_iface)))
        return hr;

    *viewport = &object->IDirect3DRMViewport2_iface;

1772 1773 1774 1775 1776 1777 1778
    if (FAILED(hr = IDirect3DRMViewport2_Init(*viewport, device, camera, x, y, width, height)))
    {
        IDirect3DRMViewport2_Release(*viewport);
        *viewport = NULL;
        return D3DRMERR_BADVALUE;
    }

1779
    return D3DRM_OK;
1780 1781
}

1782
static HRESULT WINAPI d3drm3_CreateWrap(IDirect3DRM3 *iface, D3DRMWRAPTYPE type, IDirect3DRMFrame3 *frame,
1783 1784 1785
        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)
1786
{
1787 1788 1789 1790
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
    struct d3drm_wrap *object;
    HRESULT hr;

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

1795 1796 1797 1798 1799 1800 1801 1802 1803
    if (!wrap)
        return D3DRMERR_BADVALUE;

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

    *wrap = &object->IDirect3DRMWrap_iface;

    return S_OK;
1804 1805
}

1806
static HRESULT WINAPI d3drm3_CreateUserVisual(IDirect3DRM3 *iface,
1807
        D3DRMUSERVISUALCALLBACK cb, void *ctx, IDirect3DRMUserVisual **visual)
1808
{
1809
    FIXME("iface %p, cb %p, ctx %p, visual %p stub!\n", iface, cb, ctx, visual);
1810 1811 1812 1813

    return E_NOTIMPL;
}

1814
static HRESULT WINAPI d3drm3_LoadTexture(IDirect3DRM3 *iface,
1815
        const char *filename, IDirect3DRMTexture3 **texture)
1816
{
1817
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1818 1819 1820
    struct d3drm_texture *object;
    HRESULT hr;

1821
    FIXME("iface %p, filename %s, texture %p stub!\n", iface, debugstr_a(filename), texture);
1822

1823
    if (FAILED(hr = d3drm_texture_create(&object, &d3drm->IDirect3DRM_iface)))
1824 1825 1826 1827 1828
        return hr;

    *texture = &object->IDirect3DRMTexture3_iface;

    return D3DRM_OK;
1829 1830
}

1831
static HRESULT WINAPI d3drm3_LoadTextureFromResource(IDirect3DRM3 *iface, HMODULE module,
1832
        const char *resource_name, const char *resource_type, IDirect3DRMTexture3 **texture)
1833
{
1834
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1835 1836 1837
    struct d3drm_texture *object;
    HRESULT hr;

1838 1839
    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);
1840

1841
    if (FAILED(hr = d3drm_texture_create(&object, &d3drm->IDirect3DRM_iface)))
1842 1843 1844 1845 1846
        return hr;

    *texture = &object->IDirect3DRMTexture3_iface;

    return D3DRM_OK;
1847 1848
}

1849
static HRESULT WINAPI d3drm3_SetSearchPath(IDirect3DRM3 *iface, const char *path)
1850
{
Henri Verbeet's avatar
Henri Verbeet committed
1851
    FIXME("iface %p, path %s stub!\n", iface, debugstr_a(path));
1852 1853 1854 1855

    return E_NOTIMPL;
}

1856
static HRESULT WINAPI d3drm3_AddSearchPath(IDirect3DRM3 *iface, const char *path)
1857
{
Henri Verbeet's avatar
Henri Verbeet committed
1858
    FIXME("iface %p, path %s stub!\n", iface, debugstr_a(path));
1859 1860 1861 1862

    return E_NOTIMPL;
}

1863
static HRESULT WINAPI d3drm3_GetSearchPath(IDirect3DRM3 *iface, DWORD *size, char *path)
1864
{
Henri Verbeet's avatar
Henri Verbeet committed
1865
    FIXME("iface %p, size %p, path %p stub!\n", iface, size, path);
1866 1867 1868 1869

    return E_NOTIMPL;
}

1870
static HRESULT WINAPI d3drm3_SetDefaultTextureColors(IDirect3DRM3 *iface, DWORD color_count)
1871
{
1872
    FIXME("iface %p, color_count %u stub!\n", iface, color_count);
1873 1874 1875 1876

    return E_NOTIMPL;
}

1877
static HRESULT WINAPI d3drm3_SetDefaultTextureShades(IDirect3DRM3 *iface, DWORD shade_count)
1878
{
1879
    FIXME("iface %p, shade_count %u stub!\n", iface, shade_count);
1880 1881 1882 1883

    return E_NOTIMPL;
}

1884
static HRESULT WINAPI d3drm3_GetDevices(IDirect3DRM3 *iface, IDirect3DRMDeviceArray **array)
1885
{
1886
    FIXME("iface %p, array %p stub!\n", iface, array);
1887 1888 1889 1890

    return E_NOTIMPL;
}

1891
static HRESULT WINAPI d3drm3_GetNamedObject(IDirect3DRM3 *iface,
1892
        const char *name, IDirect3DRMObject **object)
1893
{
1894
    FIXME("iface %p, name %s, object %p stub!\n", iface, debugstr_a(name), object);
1895 1896 1897 1898

    return E_NOTIMPL;
}

1899
static HRESULT WINAPI d3drm3_EnumerateObjects(IDirect3DRM3 *iface, D3DRMOBJECTCALLBACK cb, void *ctx)
1900
{
Henri Verbeet's avatar
Henri Verbeet committed
1901
    FIXME("iface %p, cb %p, ctx %p stub!\n", iface, cb, ctx);
1902 1903 1904 1905

    return E_NOTIMPL;
}

1906 1907
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)
1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920
{
    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));

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

1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935
    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;
            }

1936
        if (requested || parent_frame)
1937
        {
1938
            IDirect3DRMMeshBuilder3 *meshbuilder;
1939

1940
            TRACE("Load mesh data\n");
1941 1942 1943 1944

            hr = IDirect3DRM3_CreateMeshBuilder(iface, &meshbuilder);
            if (SUCCEEDED(hr))
            {
1945
                hr = load_mesh_data(meshbuilder, data_object, LoadTextureProc, ArgLTP);
1946 1947
                if (SUCCEEDED(hr))
                {
1948 1949
                    /* Only top level objects are notified */
                    if (!parent_frame)
1950
                    {
1951 1952 1953 1954 1955
                        IDirect3DRMObject *object;

                        hr = IDirect3DRMMeshBuilder3_QueryInterface(meshbuilder, GUIDs[i], (void**)&object);
                        if (SUCCEEDED(hr))
                        {
1956
                            LoadProc(object, GUIDs[i], ArgLP);
1957 1958 1959 1960 1961 1962
                            IDirect3DRMObject_Release(object);
                        }
                    }
                    else
                    {
                        IDirect3DRMFrame3_AddVisual(parent_frame, (IUnknown*)meshbuilder);
1963
                    }
1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984
                }
                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;
            }

1985
        if (requested || parent_frame)
1986
        {
1987
            IDirect3DRMFrame3 *frame;
1988

1989
            TRACE("Load frame data\n");
1990

1991
            hr = IDirect3DRM3_CreateFrame(iface, parent_frame, &frame);
1992 1993
            if (SUCCEEDED(hr))
            {
1994
                IDirectXFileObject *child;
1995

1996
                while (SUCCEEDED(hr = IDirectXFileData_GetNextObject(data_object, &child)))
1997
                {
1998 1999 2000
                    IDirectXFileData *data;
                    IDirectXFileDataReference *reference;
                    IDirectXFileBinary *binary;
2001

2002 2003
                    if (SUCCEEDED(IDirectXFileObject_QueryInterface(child,
                            &IID_IDirectXFileBinary, (void **)&binary)))
2004
                    {
2005 2006
                        FIXME("Binary Object not supported yet\n");
                        IDirectXFileBinary_Release(binary);
2007
                    }
2008 2009
                    else if (SUCCEEDED(IDirectXFileObject_QueryInterface(child,
                            &IID_IDirectXFileData, (void **)&data)))
2010
                    {
2011 2012 2013
                        TRACE("Found Data Object\n");
                        hr = load_data(iface, data, GUIDs, nb_GUIDs, LoadProc, ArgLP, LoadTextureProc, ArgLTP, frame);
                        IDirectXFileData_Release(data);
2014
                    }
2015 2016
                    else if (SUCCEEDED(IDirectXFileObject_QueryInterface(child,
                            &IID_IDirectXFileDataReference, (void **)&reference)))
2017 2018 2019 2020 2021 2022 2023
                    {
                        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);
                    }
2024
                    IDirectXFileObject_Release(child);
2025
                }
2026

2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041
                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))
                    {
2042
                        LoadProc(object, GUIDs[i], ArgLP);
2043 2044
                        IDirect3DRMObject_Release(object);
                    }
2045 2046 2047 2048 2049 2050 2051 2052 2053 2054
                }
                IDirect3DRMFrame3_Release(frame);
            }

            if (FAILED(hr))
                ERR("Cannot process frame\n");
        }
    }
    else if (IsEqualGUID(guid, &TID_D3DRMMaterial))
    {
2055 2056 2057
        TRACE("Found TID_D3DRMMaterial\n");

        /* Cannot be requested so nothing to do */
2058
    }
2059 2060 2061 2062
    else if (IsEqualGUID(guid, &TID_D3DRMFrameTransformMatrix))
    {
        TRACE("Found TID_D3DRMFrameTransformMatrix\n");

2063
        /* Cannot be requested */
2064 2065
        if (parent_frame)
        {
2066
            D3DRMMATRIX4D *matrix;
2067 2068 2069 2070
            DWORD size;

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

2071
            hr = IDirectXFileData_GetData(data_object, NULL, &size, (void**)&matrix);
2072 2073 2074
            if ((hr != DXFILE_OK) || (size != sizeof(matrix)))
                goto end;

2075
            hr = IDirect3DRMFrame3_AddTransform(parent_frame, D3DRMCOMBINE_REPLACE, *matrix);
2076 2077 2078 2079
            if (FAILED(hr))
                goto end;
        }
    }
2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091
    else
    {
        FIXME("Found unknown TID %s\n", debugstr_guid(guid));
    }

    ret = D3DRM_OK;

end:

    return ret;
}

2092
static HRESULT WINAPI d3drm3_Load(IDirect3DRM3 *iface, void *source, void *object_id, IID **iids,
2093 2094
        DWORD iid_count, D3DRMLOADOPTIONS flags, D3DRMLOADCALLBACK load_cb, void *load_ctx,
        D3DRMLOADTEXTURECALLBACK load_tex_cb, void *load_tex_ctx, IDirect3DRMFrame3 *parent_frame)
2095
{
2096
    DXFILELOADOPTIONS load_options;
2097
    IDirectXFile *file = NULL;
2098
    IDirectXFileEnumObject *enum_object = NULL;
2099
    IDirectXFileData *data = NULL;
2100 2101 2102
    HRESULT hr;
    const GUID* pGuid;
    DWORD size;
2103
    struct d3drm_file_header *header;
2104 2105 2106
    HRESULT ret = D3DRMERR_BADOBJECT;
    DWORD i;

2107 2108 2109 2110
    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);
2111

2112
    TRACE("Looking for GUIDs:\n");
2113 2114
    for (i = 0; i < iid_count; ++i)
        TRACE("- %s (%s)\n", debugstr_guid(iids[i]), get_IID_string(iids[i]));
2115

2116
    if (flags == D3DRMLOAD_FROMMEMORY)
2117 2118 2119
    {
        load_options = DXFILELOAD_FROMMEMORY;
    }
2120
    else if (flags == D3DRMLOAD_FROMFILE)
2121 2122
    {
        load_options = DXFILELOAD_FROMFILE;
2123
        TRACE("Loading from file %s\n", debugstr_a(source));
2124 2125 2126
    }
    else
    {
2127
        FIXME("Load options %#x not supported yet.\n", flags);
2128 2129 2130
        return E_NOTIMPL;
    }

2131
    hr = DirectXFileCreate(&file);
2132 2133 2134
    if (hr != DXFILE_OK)
        goto end;

2135
    hr = IDirectXFile_RegisterTemplates(file, templates, strlen(templates));
2136 2137 2138
    if (hr != DXFILE_OK)
        goto end;

2139
    hr = IDirectXFile_CreateEnumObject(file, source, load_options, &enum_object);
2140 2141 2142
    if (hr != DXFILE_OK)
        goto end;

2143
    hr = IDirectXFileEnumObject_GetNextDataObject(enum_object, &data);
2144 2145 2146
    if (hr != DXFILE_OK)
        goto end;

2147
    hr = IDirectXFileData_GetType(data, &pGuid);
2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158
    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;
    }

2159 2160
    hr = IDirectXFileData_GetData(data, NULL, &size, (void **)&header);
    if ((hr != DXFILE_OK) || (size != sizeof(*header)))
2161 2162
        goto end;

2163
    TRACE("Version is %u.%u, flags %#x.\n", header->major, header->minor, header->flags);
2164 2165

    /* Version must be 1.0.x */
2166
    if ((header->major != 1) || (header->minor != 0))
2167 2168 2169 2170 2171
    {
        ret = D3DRMERR_BADFILE;
        goto end;
    }

2172 2173
    IDirectXFileData_Release(data);
    data = NULL;
2174 2175 2176

    while (1)
    {
2177
        hr = IDirectXFileEnumObject_GetNextDataObject(enum_object, &data);
2178 2179 2180 2181 2182 2183 2184
        if (hr == DXFILEERR_NOMOREOBJECTS)
        {
            TRACE("No more object\n");
            break;
        }
        else if (hr != DXFILE_OK)
        {
2185
            ret = D3DRMERR_BADFILE;
2186 2187 2188
            goto end;
        }

2189
        ret = load_data(iface, data, iids, iid_count, load_cb, load_ctx, load_tex_cb, load_tex_ctx, parent_frame);
2190
        if (ret != D3DRM_OK)
2191 2192
            goto end;

2193 2194
        IDirectXFileData_Release(data);
        data = NULL;
2195 2196 2197 2198 2199
    }

    ret = D3DRM_OK;

end:
2200 2201
    if (data)
        IDirectXFileData_Release(data);
2202 2203
    if (enum_object)
        IDirectXFileEnumObject_Release(enum_object);
2204 2205
    if (file)
        IDirectXFile_Release(file);
2206 2207

    return ret;
2208 2209
}

2210
static HRESULT WINAPI d3drm3_Tick(IDirect3DRM3 *iface, D3DVALUE tick)
2211
{
2212
    FIXME("iface %p, tick %.8e stub!\n", iface, tick);
2213 2214 2215 2216

    return E_NOTIMPL;
}

2217
static HRESULT WINAPI d3drm3_CreateProgressiveMesh(IDirect3DRM3 *iface, IDirect3DRMProgressiveMesh **mesh)
2218
{
2219
    FIXME("iface %p, mesh %p stub!\n", iface, mesh);
2220 2221 2222 2223

    return E_NOTIMPL;
}

2224
static HRESULT WINAPI d3drm3_RegisterClient(IDirect3DRM3 *iface, REFGUID guid, DWORD *id)
2225
{
Henri Verbeet's avatar
Henri Verbeet committed
2226
    FIXME("iface %p, guid %s, id %p stub!\n", iface, debugstr_guid(guid), id);
2227 2228 2229 2230

    return E_NOTIMPL;
}

2231
static HRESULT WINAPI d3drm3_UnregisterClient(IDirect3DRM3 *iface, REFGUID guid)
2232
{
2233
    FIXME("iface %p, guid %s stub!\n", iface, debugstr_guid(guid));
2234 2235 2236 2237

    return E_NOTIMPL;
}

2238
static HRESULT WINAPI d3drm3_CreateClippedVisual(IDirect3DRM3 *iface,
2239
        IDirect3DRMVisual *visual, IDirect3DRMClippedVisual **clipped_visual)
2240
{
2241
    FIXME("iface %p, visual %p, clipped_visual %p stub!\n", iface, visual, clipped_visual);
2242 2243 2244 2245

    return E_NOTIMPL;
}

2246
static HRESULT WINAPI d3drm3_SetOptions(IDirect3DRM3 *iface, DWORD flags)
2247
{
2248
    FIXME("iface %p, flags %#x stub!\n", iface, flags);
2249 2250 2251 2252

    return E_NOTIMPL;
}

2253
static HRESULT WINAPI d3drm3_GetOptions(IDirect3DRM3 *iface, DWORD *flags)
2254
{
Henri Verbeet's avatar
Henri Verbeet committed
2255
    FIXME("iface %p, flags %p stub!\n", iface, flags);
2256 2257 2258 2259

    return E_NOTIMPL;
}

2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 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
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,
2303
};
2304

2305
HRESULT WINAPI Direct3DRMCreate(IDirect3DRM **d3drm)
2306
{
2307
    struct d3drm *object;
2308

2309
    TRACE("d3drm %p.\n", d3drm);
2310

2311
    if (!(object = heap_alloc_zero(sizeof(*object))))
2312 2313
        return E_OUTOFMEMORY;

2314 2315 2316
    object->IDirect3DRM_iface.lpVtbl = &d3drm1_vtbl;
    object->IDirect3DRM2_iface.lpVtbl = &d3drm2_vtbl;
    object->IDirect3DRM3_iface.lpVtbl = &d3drm3_vtbl;
2317 2318
    object->ref1 = 1;
    object->iface_count = 1;
2319

2320
    *d3drm = &object->IDirect3DRM_iface;
2321 2322 2323

    return S_OK;
}
2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338

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;
}