static HRESULT WINAPI Thunk_IDirect3DVertexBufferImpl_1_ProcessVertices(IDirect3DVertexBuffer *iface, DWORD VertexOp, DWORD DestIndex, DWORD Count, IDirect3DVertexBuffer *SrcBuffer, DWORD SrcIndex, IDirect3DDevice3 *D3DDevice, DWORD Flags) { ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, iface); IDirect3DVertexBufferImpl *Src = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, SrcBuffer); IDirect3DDeviceImpl *D3D = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice3, D3DDevice); TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%08x,%p,%08x,%p,%08x) thunking to IDirect3DVertexBuffer7 interface.\n", This, VertexOp, DestIndex, Count, Src, SrcIndex, D3D, Flags); return IDirect3DVertexBuffer7_ProcessVertices(ICOM_INTERFACE(This, IDirect3DVertexBuffer7), VertexOp, DestIndex, Count, ICOM_INTERFACE(Src, IDirect3DVertexBuffer7), SrcIndex, ICOM_INTERFACE(D3D, IDirect3DDevice7), Flags); }
/***************************************************************************** * IDirect3DTexture1::Initialize * * The sdk says it's not implemented * * Params: * ? * * Returns * DDERR_UNSUPPORTED * *****************************************************************************/ static HRESULT WINAPI IDirect3DTextureImpl_1_Initialize(IDirect3DTexture *iface, IDirect3DDevice *Direct3DDevice, IDirectDrawSurface *DDSurface) { ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture, iface); IDirect3DDeviceImpl *d3d = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice, Direct3DDevice); IDirectDrawSurfaceImpl *surf = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface3, DDSurface); TRACE("(%p)->(%p,%p) Not implemented\n", This, d3d, surf); return DDERR_UNSUPPORTED; /* Unchecked */ }
/***************************************************************************** * IDirect3DViewport3::SetViewport2 * * Sets the viewport from a D3DVIEWPORT2 structure * * Params: * lpData: Viewport to set * * Returns: * D3D_OK on success * *****************************************************************************/ static HRESULT WINAPI IDirect3DViewportImpl_SetViewport2(IDirect3DViewport3 *iface, D3DVIEWPORT2 *lpData) { ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface); LPDIRECT3DVIEWPORT3 current_viewport; TRACE("(%p/%p)->(%p)\n", This, iface, lpData); if (TRACE_ON(d3d7)) { TRACE(" getting D3DVIEWPORT2 :\n"); _dump_D3DVIEWPORT2(lpData); } EnterCriticalSection(&ddraw_cs); This->use_vp2 = 1; memset(&(This->viewports.vp2), 0, sizeof(This->viewports.vp2)); memcpy(&(This->viewports.vp2), lpData, lpData->dwSize); if (This->active_device) { IDirect3DDevice3_GetCurrentViewport(ICOM_INTERFACE(This->active_device, IDirect3DDevice3), ¤t_viewport); if (current_viewport) { if (ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, current_viewport) == This) This->activate(This, FALSE); IDirect3DViewport3_Release(current_viewport); } } LeaveCriticalSection(&ddraw_cs); return D3D_OK; }
/***************************************************************************** * IDirect3DViewport3::DeleteLight * * Deletes a light from the viewports' light list * * Params: * lpDirect3DLight: Light to delete * * Returns: * D3D_OK on success * DDERR_INVALIDPARAMS if the light wasn't found * *****************************************************************************/ static HRESULT WINAPI IDirect3DViewportImpl_DeleteLight(IDirect3DViewport3 *iface, IDirect3DLight *lpDirect3DLight) { ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface); IDirect3DLightImpl *lpDirect3DLightImpl = ICOM_OBJECT(IDirect3DLightImpl, IDirect3DLight, lpDirect3DLight); IDirect3DLightImpl *cur_light, *prev_light = NULL; TRACE("(%p)->(%p)\n", This, lpDirect3DLight); EnterCriticalSection(&ddraw_cs); cur_light = This->lights; while (cur_light != NULL) { if (cur_light == lpDirect3DLightImpl) { lpDirect3DLightImpl->desactivate(lpDirect3DLightImpl); if (prev_light == NULL) This->lights = cur_light->next; else prev_light->next = cur_light->next; /* Detach the light to the viewport */ cur_light->active_viewport = NULL; This->num_lights--; This->map_lights &= ~(1<<lpDirect3DLightImpl->dwLightIndex); LeaveCriticalSection(&ddraw_cs); return D3D_OK; } prev_light = cur_light; cur_light = cur_light->next; } LeaveCriticalSection(&ddraw_cs); return DDERR_INVALIDPARAMS; }
/***************************************************************************** * IDirect3DTexture2::GetHandle * * Returns handle for the texture. At the moment, the interface * to the IWineD3DTexture is used. * * Params: * Direct3DDevice2: Device this handle is assigned to * Handle: Address to store the handle at. * * Returns: * D3D_OK * *****************************************************************************/ static HRESULT WINAPI IDirect3DTextureImpl_GetHandle(IDirect3DTexture2 *iface, IDirect3DDevice2 *Direct3DDevice2, D3DTEXTUREHANDLE *lpHandle) { ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface); IDirect3DDeviceImpl *d3d = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice2, Direct3DDevice2); TRACE("(%p)->(%p,%p)\n", This, d3d, lpHandle); if(!This->Handle) { This->Handle = IDirect3DDeviceImpl_CreateHandle(d3d); if(This->Handle) { d3d->Handles[This->Handle - 1].ptr = This; d3d->Handles[This->Handle - 1].type = DDrawHandle_Texture; } } *lpHandle = This->Handle; TRACE(" returning handle %08lx.\n", *lpHandle); return D3D_OK; }
/***************************************************************************** * IDirect3DLight::Initialize * * Initializes the interface. This implementation is a no-op, because * initialization takes place at creation time * * Params: * Direct3D: Pointer to an IDirect3D interface. * * Returns: * D3D_OK * *****************************************************************************/ static HRESULT WINAPI IDirect3DLightImpl_Initialize(IDirect3DLight *iface, IDirect3D *lpDirect3D) { ICOM_THIS_FROM(IDirect3DLightImpl, IDirect3DLight, iface); IDirectDrawImpl *d3d = ICOM_OBJECT(IDirectDrawImpl, IDirect3D, lpDirect3D); TRACE("(%p)->(%p) no-op...\n", This, d3d); return D3D_OK; }
static HRESULT WINAPI Thunk_IDirect3DTextureImpl_1_Load(IDirect3DTexture *iface, IDirect3DTexture *D3DTexture) { ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture, iface); IDirectDrawSurfaceImpl *Texture = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture, D3DTexture); TRACE("(%p)->(%p) thunking to IDirect3DTexture2 interface.\n", This, Texture); return IDirect3DTexture2_Load(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirect3DTexture2, iface), COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirect3DTexture2, D3DTexture)); }
/***************************************************************************** * IDirect3DViewport3::Clear * * Clears the render target and / or the z buffer * * Params: * dwCount: The amount of rectangles to clear. If 0, the whole buffer is * cleared * lpRects: Pointer to the array of rectangles. If NULL, Count must be 0 * dwFlags: D3DCLEAR_ZBUFFER and / or D3DCLEAR_TARGET * * Returns: * D3D_OK on success * D3DERR_VIEWPORTHASNODEVICE if there's no active device * The return value of IDirect3DDevice7::Clear * *****************************************************************************/ static HRESULT WINAPI IDirect3DViewportImpl_Clear(IDirect3DViewport3 *iface, DWORD dwCount, D3DRECT *lpRects, DWORD dwFlags) { ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface); DWORD color = 0x00000000; HRESULT hr; LPDIRECT3DVIEWPORT3 current_viewport; TRACE("(%p/%p)->(%08x,%p,%08x)\n", This, iface, dwCount, lpRects, dwFlags); if (This->active_device == NULL) { ERR(" Trying to clear a viewport not attached to a device !\n"); return D3DERR_VIEWPORTHASNODEVICE; } EnterCriticalSection(&ddraw_cs); if (dwFlags & D3DCLEAR_TARGET) { if (This->background == NULL) { ERR(" Trying to clear the color buffer without background material !\n"); } else { color = ((int) ((This->background->mat.u.diffuse.u1.r) * 255) << 16) | ((int) ((This->background->mat.u.diffuse.u2.g) * 255) << 8) | ((int) ((This->background->mat.u.diffuse.u3.b) * 255) << 0) | ((int) ((This->background->mat.u.diffuse.u4.a) * 255) << 24); } } /* Need to temporarily activate viewport to clear it. Previously active one will be restored afterwards. */ This->activate(This, TRUE); hr = IDirect3DDevice7_Clear(ICOM_INTERFACE(This->active_device, IDirect3DDevice7), dwCount, lpRects, dwFlags & (D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET), color, 1.0, 0x00000000); IDirect3DDevice3_GetCurrentViewport(ICOM_INTERFACE(This->active_device, IDirect3DDevice3), ¤t_viewport); if(current_viewport) { IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, current_viewport); vp->activate(vp, TRUE); IDirect3DViewport3_Release(current_viewport); } LeaveCriticalSection(&ddraw_cs); return hr; }
static HRESULT WINAPI Thunk_IDirect3DVertexBufferImpl_1_Optimize(IDirect3DVertexBuffer *iface, IDirect3DDevice3 *D3DDevice, DWORD Flags) { ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, iface); IDirect3DDeviceImpl *D3D = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice3, D3DDevice); TRACE_(ddraw_thunk)("(%p)->(%p,%08x) thunking to IDirect3DVertexBuffer7 interface.\n", This, D3D, Flags); return IDirect3DVertexBuffer7_Optimize(ICOM_INTERFACE(This, IDirect3DVertexBuffer7), ICOM_INTERFACE(D3D, IDirect3DDevice7), Flags); }
static HRESULT WINAPI Thunk_IDirect3DTextureImpl_1_GetHandle(IDirect3DTexture *iface, LPDIRECT3DDEVICE lpDirect3DDevice, LPD3DTEXTUREHANDLE lpHandle) { ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture, iface); IDirect3DDeviceImpl *d3d = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice, lpDirect3DDevice); TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DTexture2 interface.\n", This, d3d, lpHandle); return IDirect3DTexture2_GetHandle(ICOM_INTERFACE(This, IDirect3DTexture2), ICOM_INTERFACE(d3d, IDirect3DDevice2), lpHandle); }
/***************************************************************************** * IDirect3DVertexBuffer7::ProcessVerticesStrided * * This method processes untransformed strided vertices into a processed * or optimized vertex buffer. * * For more details on the parameters, see * IDirect3DVertexBuffer7::ProcessVertices * * Params: * VertexOp: Operations to perform * DestIndex: Destination index to write the vertices to * Count: Number of input vertices * StrideData: Array containing the input vertices * VertexTypeDesc: Vertex Description or source index????????? * D3DDevice: IDirect3DDevice7 to use for processing * Flags: Can be D3DPV_DONOTCOPYDATA to avoid copying unmodified vertices * * Returns * D3D_OK on success, or DDERR_* * *****************************************************************************/ static HRESULT WINAPI IDirect3DVertexBufferImpl_ProcessVerticesStrided(IDirect3DVertexBuffer7 *iface, DWORD VertexOp, DWORD DestIndex, DWORD Count, D3DDRAWPRIMITIVESTRIDEDDATA *StrideData, DWORD VertexTypeDesc, IDirect3DDevice7 *D3DDevice, DWORD Flags) { ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface); IDirect3DDeviceImpl *D3D = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice7, D3DDevice); FIXME("(%p)->(%08x,%08x,%08x,%p,%08x,%p,%08x): stub!\n", This, VertexOp, DestIndex, Count, StrideData, VertexTypeDesc, D3D, Flags); return DD_OK; }
/***************************************************************************** * get_sub_mimaplevel * * Helper function that returns the next mipmap level * * tex_ptr: Surface of which to return the next level * *****************************************************************************/ static IDirectDrawSurfaceImpl * get_sub_mimaplevel(IDirectDrawSurfaceImpl *tex_ptr) { /* Now go down the mipmap chain to the next surface */ static const DDSCAPS2 mipmap_caps = { DDSCAPS_MIPMAP | DDSCAPS_TEXTURE, 0, 0, 0 }; LPDIRECTDRAWSURFACE7 next_level; IDirectDrawSurfaceImpl *surf_ptr; HRESULT hr; hr = IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(tex_ptr, IDirectDrawSurface7), (DDSCAPS2 *) &mipmap_caps, &next_level); if (FAILED(hr)) return NULL; surf_ptr = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, next_level); IDirectDrawSurface7_Release(next_level); return surf_ptr; }
/***************************************************************************** * IDirect3DVertexBuffer7::Optimize * * Converts an unoptimized vertex buffer into an optimized buffer * * Params: * D3DDevice: Device for which this buffer is optimized * Flags: Not used, should be set to 0 * * Returns * D3D_OK, because it's a stub * *****************************************************************************/ static HRESULT WINAPI IDirect3DVertexBufferImpl_Optimize(IDirect3DVertexBuffer7 *iface, IDirect3DDevice7 *D3DDevice, DWORD Flags) { ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface); IDirect3DDeviceImpl *D3D = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice7, D3DDevice); FIXME("(%p)->(%p,%08x): stub!\n", This, D3D, Flags); /* We could forward this call to WineD3D and take advantage * of it once we use OpenGL vertex buffers */ EnterCriticalSection(&ddraw_cs); This->Caps |= D3DVBCAPS_OPTIMIZED; LeaveCriticalSection(&ddraw_cs); return DD_OK; }
/***************************************************************************** * IDirect3DViewport3::AddLight * * Adds an light to the viewport * * Params: * lpDirect3DLight: Interface of the light to add * * Returns: * D3D_OK on success * DDERR_INVALIDPARAMS if Direct3DLight is NULL * DDERR_INVALIDPARAMS if there are 8 lights or more * *****************************************************************************/ static HRESULT WINAPI IDirect3DViewportImpl_AddLight(IDirect3DViewport3 *iface, IDirect3DLight *lpDirect3DLight) { ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface); IDirect3DLightImpl *lpDirect3DLightImpl = ICOM_OBJECT(IDirect3DLightImpl, IDirect3DLight, lpDirect3DLight); DWORD i = 0; DWORD map = This->map_lights; TRACE("(%p)->(%p)\n", This, lpDirect3DLight); EnterCriticalSection(&ddraw_cs); if (This->num_lights >= 8) { LeaveCriticalSection(&ddraw_cs); return DDERR_INVALIDPARAMS; } /* Find a light number and update both light and viewports objects accordingly */ while(map&1) { map>>=1; i++; } lpDirect3DLightImpl->dwLightIndex = i; This->num_lights++; This->map_lights |= 1<<i; /* Add the light in the 'linked' chain */ lpDirect3DLightImpl->next = This->lights; This->lights = lpDirect3DLightImpl; /* Attach the light to the viewport */ lpDirect3DLightImpl->active_viewport = This; /* If active, activate the light */ if (This->active_device != NULL) { lpDirect3DLightImpl->activate(lpDirect3DLightImpl); } LeaveCriticalSection(&ddraw_cs); return D3D_OK; }
/***************************************************************************** * IDirect3DViewport3::Clear2 * * Another clearing method * * Params: * Count: Number of rectangles to clear * Rects: Rectangle array to clear * Flags: Some flags :) * Color: Color to fill the render target with * Z: Value to fill the depth buffer with * Stencil: Value to fill the stencil bits with * * Returns: * *****************************************************************************/ static HRESULT WINAPI IDirect3DViewportImpl_Clear2(IDirect3DViewport3 *iface, DWORD dwCount, LPD3DRECT lpRects, DWORD dwFlags, DWORD dwColor, D3DVALUE dvZ, DWORD dwStencil) { ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface); HRESULT hr; LPDIRECT3DVIEWPORT3 current_viewport; TRACE("(%p)->(%08x,%p,%08x,%08x,%f,%08x)\n", This, dwCount, lpRects, dwFlags, dwColor, dvZ, dwStencil); EnterCriticalSection(&ddraw_cs); if (This->active_device == NULL) { ERR(" Trying to clear a viewport not attached to a device !\n"); LeaveCriticalSection(&ddraw_cs); return D3DERR_VIEWPORTHASNODEVICE; } /* Need to temporarily activate viewport to clear it. Previously active one will be restored afterwards. */ This->activate(This, TRUE); hr = IDirect3DDevice7_Clear(ICOM_INTERFACE(This->active_device, IDirect3DDevice7), dwCount, lpRects, dwFlags, dwColor, dvZ, dwStencil); IDirect3DDevice3_GetCurrentViewport(ICOM_INTERFACE(This->active_device, IDirect3DDevice3), ¤t_viewport); if(current_viewport) { IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, current_viewport); vp->activate(vp, TRUE); IDirect3DViewport3_Release(current_viewport); } LeaveCriticalSection(&ddraw_cs); return hr; }
/***************************************************************************** * IDirect3DViewport3::SetViewport * * Sets the viewport information for this interface * * Params: * lpData: Viewport to set * * Returns: * D3D_OK on success * DDERR_INVALIDPARAMS if Data is NULL * *****************************************************************************/ static HRESULT WINAPI IDirect3DViewportImpl_SetViewport(IDirect3DViewport3 *iface, D3DVIEWPORT *lpData) { ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface); LPDIRECT3DVIEWPORT3 current_viewport; TRACE("(%p/%p)->(%p)\n", This, iface, lpData); if (TRACE_ON(d3d7)) { TRACE(" getting D3DVIEWPORT :\n"); _dump_D3DVIEWPORT(lpData); } EnterCriticalSection(&ddraw_cs); This->use_vp2 = 0; memset(&(This->viewports.vp1), 0, sizeof(This->viewports.vp1)); memcpy(&(This->viewports.vp1), lpData, lpData->dwSize); /* Tests on two games show that these values are never used properly so override them with proper ones :-) */ This->viewports.vp1.dvMinZ = 0.0; This->viewports.vp1.dvMaxZ = 1.0; if (This->active_device) { IDirect3DDevice3_GetCurrentViewport(ICOM_INTERFACE(This->active_device, IDirect3DDevice3), ¤t_viewport); if (current_viewport) { if (ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, current_viewport) == This) This->activate(This, FALSE); IDirect3DViewport3_Release(current_viewport); } } LeaveCriticalSection(&ddraw_cs); return DD_OK; }
/***************************************************************************** * IDirect3DTexture2::Load * * Loads a texture created with the DDSCAPS_ALLOCONLOAD * * This function isn't relayed to WineD3D because the whole interface is * implemented in DDraw only. For speed improvements a implementation which * takes OpenGL more into account could be placed into WineD3D. * * Params: * D3DTexture2: Address of the texture to load * * Returns: * D3D_OK on success * D3DERR_TEXTURE_LOAD_FAILED. * *****************************************************************************/ static HRESULT WINAPI IDirect3DTextureImpl_Load(IDirect3DTexture2 *iface, IDirect3DTexture2 *D3DTexture2) { ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface); IDirectDrawSurfaceImpl *src_ptr = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture2, D3DTexture2); IWineD3DPalette *wine_pal, *wine_pal_src; IDirectDrawPalette *pal = NULL, *pal_src = NULL; IDirectDrawPaletteImpl *pal_impl, *pal_impl_src; HRESULT ret_value = D3D_OK; TRACE("(%p)->(%p)\n", This, src_ptr); if (((src_ptr->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) != (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP)) || (src_ptr->surface_desc.u2.dwMipMapCount != This->surface_desc.u2.dwMipMapCount)) { ERR("Trying to load surfaces with different mip-map counts !\n"); } while(1) { DDSURFACEDESC *src_d, *dst_d; TRACE(" copying surface %p to surface %p (mipmap level %d)\n", src_ptr, This, src_ptr->mipmap_level); if ( This->surface_desc.ddsCaps.dwCaps & DDSCAPS_ALLOCONLOAD ) /* If the surface is not allocated and its location is not yet specified, force it to video memory */ if ( !(This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_SYSTEMMEMORY|DDSCAPS_VIDEOMEMORY)) ) This->surface_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY; /* Suppress the ALLOCONLOAD flag */ This->surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_ALLOCONLOAD; /* Get the palettes */ ret_value = IWineD3DSurface_GetPalette(This->WineD3DSurface, &wine_pal); if( ret_value != D3D_OK) { ERR("IWineD3DSurface::GetPalette failed! This is unexpected\n"); return D3DERR_TEXTURE_LOAD_FAILED; } if(wine_pal) { ret_value = IWineD3DPalette_GetParent(wine_pal, (IUnknown **) &pal); if(ret_value != D3D_OK) { ERR("IWineD3DPalette::GetParent failed! This is unexpected\n"); return D3DERR_TEXTURE_LOAD_FAILED; } pal_impl = ICOM_OBJECT(IDirectDrawPaletteImpl, IDirectDrawPalette, pal); } else { pal_impl = NULL; } ret_value = IWineD3DSurface_GetPalette(src_ptr->WineD3DSurface, &wine_pal_src); if( ret_value != D3D_OK) { ERR("IWineD3DSurface::GetPalette failed! This is unexpected\n"); return D3DERR_TEXTURE_LOAD_FAILED; } if(wine_pal_src) { ret_value = IWineD3DPalette_GetParent(wine_pal_src, (IUnknown **) &pal_src); if(ret_value != D3D_OK) { ERR("IWineD3DPalette::GetParent failed! This is unexpected\n"); return D3DERR_TEXTURE_LOAD_FAILED; } pal_impl_src = ICOM_OBJECT(IDirectDrawPaletteImpl, IDirectDrawPalette, pal_src); } else { pal_impl_src = NULL; } /* After seeing some logs, not sure at all about this... */ if (pal_impl == NULL) { IWineD3DSurface_SetPalette(This->WineD3DSurface, wine_pal); if (pal_impl_src != NULL) IDirectDrawPalette_AddRef(ICOM_INTERFACE(pal_impl_src, IDirectDrawPalette)); } else { if (pal_impl_src != NULL) { PALETTEENTRY palent[256]; IDirectDrawPalette_GetEntries(ICOM_INTERFACE(pal_impl_src, IDirectDrawPalette), 0, 0, 256, palent); IDirectDrawPalette_SetEntries(ICOM_INTERFACE(pal_impl, IDirectDrawPalette), 0, 0, 256, palent); } } /* Copy one surface on the other */ dst_d = (DDSURFACEDESC *)&(This->surface_desc); src_d = (DDSURFACEDESC *)&(src_ptr->surface_desc); if ((src_d->dwWidth != dst_d->dwWidth) || (src_d->dwHeight != dst_d->dwHeight)) { /* Should also check for same pixel format, u1.lPitch, ... */ ERR("Error in surface sizes\n"); return D3DERR_TEXTURE_LOAD_FAILED; } else { WINED3DLOCKED_RECT pSrcRect, pDstRect; /* LPDIRECT3DDEVICE2 d3dd = (LPDIRECT3DDEVICE2) This->D3Ddevice; */ /* I should put a macro for the calculus of bpp */ /* Copy also the ColorKeying stuff */ if (src_d->dwFlags & DDSD_CKSRCBLT) { dst_d->dwFlags |= DDSD_CKSRCBLT; dst_d->ddckCKSrcBlt.dwColorSpaceLowValue = src_d->ddckCKSrcBlt.dwColorSpaceLowValue; dst_d->ddckCKSrcBlt.dwColorSpaceHighValue = src_d->ddckCKSrcBlt.dwColorSpaceHighValue; } /* Copy the main memory texture into the surface that corresponds to the OpenGL texture object. */ ret_value = IWineD3DSurface_LockRect(src_ptr->WineD3DSurface, &pSrcRect, NULL, 0); if(ret_value != D3D_OK) { ERR(" (%p) Locking the source surface failed\n", This); return D3DERR_TEXTURE_LOAD_FAILED; } ret_value = IWineD3DSurface_LockRect(This->WineD3DSurface, &pDstRect, NULL, 0); if(ret_value != D3D_OK) { ERR(" (%p) Locking the destination surface failed\n", This); IWineD3DSurface_UnlockRect(src_ptr->WineD3DSurface); return D3DERR_TEXTURE_LOAD_FAILED; } if (This->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) memcpy(pDstRect.pBits, pSrcRect.pBits, src_ptr->surface_desc.u1.dwLinearSize); else memcpy(pDstRect.pBits, pSrcRect.pBits, pSrcRect.Pitch * src_d->dwHeight); IWineD3DSurface_UnlockRect(src_ptr->WineD3DSurface); IWineD3DSurface_UnlockRect(This->WineD3DSurface); } if (src_ptr->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) { src_ptr = get_sub_mimaplevel(src_ptr); } else { src_ptr = NULL; } if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) { This = get_sub_mimaplevel(This); } else { This = NULL; } if ((src_ptr == NULL) || (This == NULL)) { if (src_ptr != This) { ERR(" Loading surface with different mipmap structure !!!\n"); } break; } } return ret_value; }
/***************************************************************************** * IDirect3DVertexBuffer7::ProcessVertices * * Processes untransformed Vertices into a transformed or optimized vertex * buffer. It can also perform other operations, such as lighting or clipping * * Params * VertexOp: Operation(s) to perform: D3DVOP_CLIP, _EXTENTS, _LIGHT, _TRANSFORM * DestIndex: Index in the destination buffer(This), where the vertices are * placed * Count: Number of Vertices in the Source buffer to process * SrcBuffer: Source vertex buffer * SrcIndex: Index of the first vertex in the src buffer to process * D3DDevice: Device to use for transformation * Flags: 0 for default, D3DPV_DONOTCOPYDATA to prevent copying * unchaned vertices * * Returns: * D3D_OK on success * DDERR_INVALIDPARAMS If D3DVOP_TRANSFORM wasn't passed * *****************************************************************************/ static HRESULT WINAPI IDirect3DVertexBufferImpl_ProcessVertices(IDirect3DVertexBuffer7 *iface, DWORD VertexOp, DWORD DestIndex, DWORD Count, IDirect3DVertexBuffer7 *SrcBuffer, DWORD SrcIndex, IDirect3DDevice7 *D3DDevice, DWORD Flags) { ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface); IDirect3DVertexBufferImpl *Src = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, SrcBuffer); IDirect3DDeviceImpl *D3D = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice7, D3DDevice); BOOL oldClip, doClip; HRESULT hr; WINED3DVERTEXBUFFER_DESC Desc; TRACE("(%p)->(%08x,%d,%d,%p,%d,%p,%08x)\n", This, VertexOp, DestIndex, Count, Src, SrcIndex, D3D, Flags); /* Vertex operations: * D3DVOP_CLIP: Clips vertices outside the viewing frustrum. Needs clipping information * in the vertex buffer (Buffer may not be created with D3DVBCAPS_DONOTCLIP) * D3DVOP_EXTENTS: Causes the screen extents to be updated when rendering the vertices * D3DVOP_LIGHT: Lights the vertices * D3DVOP_TRANSFORM: Transform the vertices. This flag is necessary * * WineD3D only transforms and clips the vertices by now, so EXTENTS and LIGHT * are not implemented. Clipping is disabled ATM, because of unsure conditions. */ if( !(VertexOp & D3DVOP_TRANSFORM) ) return DDERR_INVALIDPARAMS; EnterCriticalSection(&ddraw_cs); /* WineD3D doesn't know d3d7 vertex operation, it uses * render states instead. Set the render states according to * the vertex ops */ doClip = VertexOp & D3DVOP_CLIP ? TRUE : FALSE; IWineD3DDevice_GetRenderState(D3D->wineD3DDevice, WINED3DRS_CLIPPING, (DWORD *) &oldClip); if(doClip != oldClip) { IWineD3DDevice_SetRenderState(D3D->wineD3DDevice, WINED3DRS_CLIPPING, doClip); } IWineD3DVertexBuffer_GetDesc(Src->wineD3DVertexBuffer, &Desc); IWineD3DDevice_SetStreamSource(D3D->wineD3DDevice, 0, /* Stream No */ Src->wineD3DVertexBuffer, 0, /* Offset */ get_flexible_vertex_size(Desc.FVF)); IWineD3DDevice_SetVertexDeclaration(D3D->wineD3DDevice, Src->wineD3DVertexDeclaration); hr = IWineD3DDevice_ProcessVertices(D3D->wineD3DDevice, SrcIndex, DestIndex, Count, This->wineD3DVertexBuffer, NULL /* Output vdecl */, Flags); /* Restore the states if needed */ if(doClip != oldClip) IWineD3DDevice_SetRenderState(D3D->wineD3DDevice, WINED3DRS_CLIPPING, oldClip); LeaveCriticalSection(&ddraw_cs); return hr; }