/*** IUnknown methods ***/ static HRESULT WINAPI IDirect3DRMImpl_QueryInterface(IDirect3DRM* iface, REFIID riid, void** ppvObject) { IDirect3DRMImpl *This = impl_from_IDirect3DRM(iface); TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ppvObject); *ppvObject = NULL; if(IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IDirect3DRM)) { *ppvObject = &This->IDirect3DRM_iface; } else if(IsEqualGUID(riid, &IID_IDirect3DRM2)) { *ppvObject = &This->IDirect3DRM2_iface; } else if(IsEqualGUID(riid, &IID_IDirect3DRM3)) { *ppvObject = &This->IDirect3DRM3_iface; } else { FIXME("interface %s not implemented\n", debugstr_guid(riid)); return E_NOINTERFACE; } IDirect3DRM_AddRef(iface); return S_OK; }
static HRESULT d3drm_device_set_ddraw_device_d3d(struct d3drm_device *device, IDirect3D *d3d, IDirect3DDevice *d3d_device) { IDirectDraw *ddraw; IDirectDrawSurface *surface; IDirect3DDevice2 *d3d_device2 = NULL; DDSURFACEDESC desc; HRESULT hr; /* AddRef these interfaces beforehand for the intentional leak on reinitialization. */ if (FAILED(hr = IDirect3D_QueryInterface(d3d, &IID_IDirectDraw, (void **)&ddraw))) return hr; IDirect3DRM_AddRef(device->d3drm); IDirect3DDevice_AddRef(d3d_device); /* Fetch render target and get width/height from there */ if (FAILED(hr = IDirect3DDevice_QueryInterface(d3d_device, &IID_IDirectDrawSurface, (void **)&surface))) { if (FAILED(hr = IDirect3DDevice_QueryInterface(d3d_device, &IID_IDirect3DDevice2, (void **)&d3d_device2))) return hr; hr = IDirect3DDevice2_GetRenderTarget(d3d_device2, &surface); IDirect3DDevice2_Release(d3d_device2); if (FAILED(hr)) return hr; } if (device->ddraw) { if (d3d_device2) IDirectDrawSurface_Release(surface); return D3DRMERR_BADOBJECT; } desc.dwSize = sizeof(desc); hr = IDirectDrawSurface_GetSurfaceDesc(surface, &desc); if (FAILED(hr)) { IDirectDrawSurface_Release(surface); return hr; } device->ddraw = ddraw; device->width = desc.dwWidth; device->height = desc.dwHeight; device->device = d3d_device; device->render_target = surface; return hr; }
static HRESULT WINAPI d3drm_texture3_InitFromImage(IDirect3DRMTexture3 *iface, D3DRMIMAGE *image) { struct d3drm_texture *texture = impl_from_IDirect3DRMTexture3(iface); TRACE("iface %p, image %p.\n", iface, image); if (!d3drm_validate_image(image)) return D3DRMERR_BADOBJECT; /* d3drm intentionally leaks a reference to IDirect3DRM here if texture has already been initialized. */ IDirect3DRM_AddRef(texture->d3drm); if (texture->image) return D3DRMERR_BADOBJECT; texture->image = image; return D3DRM_OK; }
static ULONG WINAPI IDirect3DRM3Impl_AddRef(IDirect3DRM3* iface) { IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface); return IDirect3DRM_AddRef(&This->IDirect3DRM_iface); }
HRESULT d3drm_device_init(struct d3drm_device *device, UINT version, IDirectDraw *ddraw, IDirectDrawSurface *surface, BOOL create_z_surface) { DDSCAPS caps = { DDSCAPS_ZBUFFER }; IDirectDrawSurface *ds = NULL; IDirect3DDevice *device1 = NULL; IDirect3DDevice2 *device2 = NULL; IDirect3D2 *d3d2 = NULL; DDSURFACEDESC desc, surface_desc; HRESULT hr; device->ddraw = ddraw; IDirectDraw_AddRef(ddraw); IDirect3DRM_AddRef(device->d3drm); device->render_target = surface; IDirectDrawSurface_AddRef(surface); desc.dwSize = sizeof(desc); hr = IDirectDrawSurface_GetSurfaceDesc(surface, &desc); if (FAILED(hr)) return hr; if (!(desc.ddsCaps.dwCaps & DDSCAPS_3DDEVICE)) return DDERR_INVALIDCAPS; hr = IDirectDrawSurface_GetAttachedSurface(surface, &caps, &ds); if (SUCCEEDED(hr)) { create_z_surface = FALSE; IDirectDrawSurface_Release(ds); ds = NULL; } if (create_z_surface) { memset(&surface_desc, 0, sizeof(surface_desc)); surface_desc.dwSize = sizeof(surface_desc); surface_desc.dwFlags = DDSD_CAPS | DDSD_ZBUFFERBITDEPTH | DDSD_WIDTH | DDSD_HEIGHT; surface_desc.ddsCaps.dwCaps = DDSCAPS_ZBUFFER; surface_desc.u2.dwZBufferBitDepth = 16; surface_desc.dwWidth = desc.dwWidth; surface_desc.dwHeight = desc.dwHeight; hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &ds, NULL); if (FAILED(hr)) return hr; hr = IDirectDrawSurface_AddAttachedSurface(surface, ds); IDirectDrawSurface_Release(ds); if (FAILED(hr)) return hr; } if (version == 1) hr = IDirectDrawSurface_QueryInterface(surface, &IID_IDirect3DRGBDevice, (void **)&device1); else { IDirectDraw_QueryInterface(ddraw, &IID_IDirect3D2, (void**)&d3d2); hr = IDirect3D2_CreateDevice(d3d2, &IID_IDirect3DRGBDevice, surface, &device2); IDirect3D2_Release(d3d2); } if (FAILED(hr)) { IDirectDrawSurface_DeleteAttachedSurface(surface, 0, ds); return hr; } if (version != 1) { hr = IDirect3DDevice2_QueryInterface(device2, &IID_IDirect3DDevice, (void**)&device1); IDirect3DDevice2_Release(device2); if (FAILED(hr)) { IDirectDrawSurface_DeleteAttachedSurface(surface, 0, ds); return hr; } } device->device = device1; device->width = desc.dwWidth; device->height = desc.dwHeight; return hr; }