diff --git a/dlls/ddraw/Makefile.in b/dlls/ddraw/Makefile.in index b9711a19f6c..ba571c6fb05 100644 --- a/dlls/ddraw/Makefile.in +++ b/dlls/ddraw/Makefile.in @@ -18,7 +18,6 @@ C_SRCS = \ parent.c \ regsvr.c \ surface.c \ - texture.c \ utils.c \ vertexbuffer.c \ viewport.c diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c index e69630ba3bd..8f23ab1f7df 100644 --- a/dlls/ddraw/surface.c +++ b/dlls/ddraw/surface.c @@ -166,6 +166,20 @@ static HRESULT WINAPI ddraw_gamma_control_QueryInterface(IDirectDrawGammaControl return ddraw_surface7_QueryInterface((IDirectDrawSurface7 *)surface_from_gamma_control(iface), riid, object); } +static HRESULT WINAPI d3d_texture2_QueryInterface(IDirect3DTexture2 *iface, REFIID riid, void **object) +{ + TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); + + return ddraw_surface7_QueryInterface((IDirectDrawSurface7 *)surface_from_texture2(iface), riid, object); +} + +static HRESULT WINAPI d3d_texture1_QueryInterface(IDirect3DTexture *iface, REFIID riid, void **object) +{ + TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); + + return ddraw_surface7_QueryInterface((IDirectDrawSurface7 *)surface_from_texture1(iface), riid, object); +} + /***************************************************************************** * IDirectDrawSurface7::AddRef * @@ -205,6 +219,20 @@ static ULONG WINAPI ddraw_gamma_control_AddRef(IDirectDrawGammaControl *iface) return ddraw_surface7_AddRef((IDirectDrawSurface7 *)surface_from_gamma_control(iface)); } +static ULONG WINAPI d3d_texture2_AddRef(IDirect3DTexture2 *iface) +{ + TRACE("iface %p.\n", iface); + + return ddraw_surface7_AddRef((IDirectDrawSurface7 *)surface_from_texture2(iface)); +} + +static ULONG WINAPI d3d_texture1_AddRef(IDirect3DTexture *iface) +{ + TRACE("iface %p.\n", iface); + + return ddraw_surface7_AddRef((IDirectDrawSurface7 *)surface_from_texture1(iface)); +} + /***************************************************************************** * ddraw_surface_destroy * @@ -447,6 +475,20 @@ static ULONG WINAPI ddraw_gamma_control_Release(IDirectDrawGammaControl *iface) return ddraw_surface7_Release((IDirectDrawSurface7 *)surface_from_gamma_control(iface)); } +static ULONG WINAPI d3d_texture2_Release(IDirect3DTexture2 *iface) +{ + TRACE("iface %p.\n", iface); + + return ddraw_surface7_Release((IDirectDrawSurface7 *)surface_from_texture2(iface)); +} + +static ULONG WINAPI d3d_texture1_Release(IDirect3DTexture *iface) +{ + TRACE("iface %p.\n", iface); + + return ddraw_surface7_Release((IDirectDrawSurface7 *)surface_from_texture1(iface)); +} + /***************************************************************************** * IDirectDrawSurface7::GetAttachedSurface * @@ -1934,6 +1976,26 @@ static HRESULT WINAPI ddraw_surface3_Initialize(IDirectDrawSurface3 *iface, ddraw, (DDSURFACEDESC2 *)surface_desc); } +/***************************************************************************** + * IDirect3DTexture1::Initialize + * + * The sdk says it's not implemented + * + * Params: + * ? + * + * Returns + * DDERR_UNSUPPORTED + * + *****************************************************************************/ +static HRESULT WINAPI d3d_texture1_Initialize(IDirect3DTexture *iface, + IDirect3DDevice *device, IDirectDrawSurface *surface) +{ + TRACE("iface %p, device %p, surface %p.\n", iface, device, surface); + + return DDERR_UNSUPPORTED; /* Unchecked */ +} + /***************************************************************************** * IDirectDrawSurface7::IsLost * @@ -2985,6 +3047,320 @@ static HRESULT WINAPI ddraw_gamma_control_SetGammaRamp(IDirectDrawGammaControl * return DD_OK; } +/***************************************************************************** + * IDirect3DTexture2::PaletteChanged + * + * Informs the texture about a palette change + * + * Params: + * start: Start index of the change + * count: The number of changed entries + * + * Returns + * D3D_OK, because it's a stub + * + *****************************************************************************/ +static HRESULT WINAPI d3d_texture2_PaletteChanged(IDirect3DTexture2 *iface, DWORD start, DWORD count) +{ + FIXME("iface %p, start %u, count %u stub!\n", iface, start, count); + + return D3D_OK; +} + +static HRESULT WINAPI d3d_texture1_PaletteChanged(IDirect3DTexture *iface, DWORD start, DWORD count) +{ + IDirectDrawSurfaceImpl *surface = surface_from_texture1(iface); + + TRACE("iface %p, start %u, count %u.\n", iface, start, count); + + return d3d_texture2_PaletteChanged((IDirect3DTexture2 *)&surface->IDirect3DTexture2_vtbl, start, count); +} + +/***************************************************************************** + * IDirect3DTexture::Unload + * + * DX5 SDK: "The IDirect3DTexture2::Unload method is not implemented + * + * + * Returns: + * DDERR_UNSUPPORTED + * + *****************************************************************************/ +static HRESULT WINAPI d3d_texture1_Unload(IDirect3DTexture *iface) +{ + WARN("iface %p. Not implemented.\n", iface); + + return DDERR_UNSUPPORTED; +} + +/***************************************************************************** + * IDirect3DTexture2::GetHandle + * + * Returns handle for the texture. At the moment, the interface + * to the IWineD3DTexture is used. + * + * Params: + * device: Device this handle is assigned to + * handle: Address to store the handle at. + * + * Returns: + * D3D_OK + * + *****************************************************************************/ +static HRESULT WINAPI d3d_texture2_GetHandle(IDirect3DTexture2 *iface, + IDirect3DDevice2 *device, D3DTEXTUREHANDLE *handle) +{ + IDirectDrawSurfaceImpl *surface = surface_from_texture2(iface); + + TRACE("iface %p, device %p, handle %p.\n", iface, device, handle); + + EnterCriticalSection(&ddraw_cs); + + if (!surface->Handle) + { + DWORD h = ddraw_allocate_handle(&device_from_device2(device)->handle_table, surface, DDRAW_HANDLE_SURFACE); + if (h == DDRAW_INVALID_HANDLE) + { + ERR("Failed to allocate a texture handle.\n"); + LeaveCriticalSection(&ddraw_cs); + return DDERR_OUTOFMEMORY; + } + + surface->Handle = h + 1; + } + + TRACE("Returning handle %08x.\n", surface->Handle); + *handle = surface->Handle; + + LeaveCriticalSection(&ddraw_cs); + + return D3D_OK; +} + +static HRESULT WINAPI d3d_texture1_GetHandle(IDirect3DTexture *iface, + IDirect3DDevice *device, D3DTEXTUREHANDLE *handle) +{ + IDirect3DTexture2 *texture2 = (IDirect3DTexture2 *)&surface_from_texture1(iface)->IDirect3DTexture2_vtbl; + IDirect3DDevice2 *device2 = (IDirect3DDevice2 *)&device_from_device1(device)->IDirect3DDevice2_vtbl; + + TRACE("iface %p, device %p, handle %p.\n", iface, device, handle); + + return d3d_texture2_GetHandle(texture2, device2, handle); +} + +/***************************************************************************** + * 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 *surface) +{ + /* Now go down the mipmap chain to the next surface */ + static DDSCAPS2 mipmap_caps = { DDSCAPS_MIPMAP | DDSCAPS_TEXTURE, 0, 0, 0 }; + IDirectDrawSurface7 *next_level; + HRESULT hr; + + hr = ddraw_surface7_GetAttachedSurface((IDirectDrawSurface7 *)surface, &mipmap_caps, &next_level); + if (FAILED(hr)) return NULL; + + ddraw_surface7_Release(next_level); + + return (IDirectDrawSurfaceImpl *)next_level; +} + +/***************************************************************************** + * 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: + * src_texture: Address of the texture to load + * + * Returns: + * D3D_OK on success + * D3DERR_TEXTURE_LOAD_FAILED. + * + *****************************************************************************/ +static HRESULT WINAPI d3d_texture2_Load(IDirect3DTexture2 *iface, IDirect3DTexture2 *src_texture) +{ + IDirectDrawSurfaceImpl *dst_surface = surface_from_texture2(iface); + IDirectDrawSurfaceImpl *src_surface = surface_from_texture2(src_texture); + HRESULT hr; + + TRACE("iface %p, src_texture %p.\n", iface, src_texture); + + if (src_surface == dst_surface) + { + TRACE("copying surface %p to surface %p, why?\n", src_surface, dst_surface); + return D3D_OK; + } + + EnterCriticalSection(&ddraw_cs); + + if (((src_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) + != (dst_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP)) + || (src_surface->surface_desc.u2.dwMipMapCount != dst_surface->surface_desc.u2.dwMipMapCount)) + { + ERR("Trying to load surfaces with different mip-map counts.\n"); + } + + for (;;) + { + IWineD3DPalette *wined3d_dst_pal, *wined3d_src_pal; + IDirectDrawPalette *dst_pal = NULL, *src_pal = NULL; + DDSURFACEDESC *src_desc, *dst_desc; + + TRACE("Copying surface %p to surface %p (mipmap level %d).\n", + src_surface, dst_surface, src_surface->mipmap_level); + + /* Suppress the ALLOCONLOAD flag */ + dst_surface->surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_ALLOCONLOAD; + + /* Get the palettes */ + hr = IWineD3DSurface_GetPalette(dst_surface->WineD3DSurface, &wined3d_dst_pal); + if (FAILED(hr)) + { + ERR("Failed to get destination palette, hr %#x.\n", hr); + LeaveCriticalSection(&ddraw_cs); + return D3DERR_TEXTURE_LOAD_FAILED; + } + if (wined3d_dst_pal) + { + hr = IWineD3DPalette_GetParent(wined3d_dst_pal, (IUnknown **)&dst_pal); + if (FAILED(hr)) + { + ERR("Failed to get destination palette parent, hr %#x.\n", hr); + LeaveCriticalSection(&ddraw_cs); + return D3DERR_TEXTURE_LOAD_FAILED; + } + } + + hr = IWineD3DSurface_GetPalette(src_surface->WineD3DSurface, &wined3d_src_pal); + if (FAILED(hr)) + { + ERR("Failed to get source palette, hr %#x.\n", hr); + LeaveCriticalSection(&ddraw_cs); + return D3DERR_TEXTURE_LOAD_FAILED; + } + if (wined3d_src_pal) + { + hr = IWineD3DPalette_GetParent(wined3d_src_pal, (IUnknown **)&src_pal); + if (FAILED(hr)) + { + ERR("Failed to get source palette parent, hr %#x.\n", hr); + if (dst_pal) IDirectDrawPalette_Release(dst_pal); + LeaveCriticalSection(&ddraw_cs); + return D3DERR_TEXTURE_LOAD_FAILED; + } + } + + if (src_pal) + { + PALETTEENTRY palent[256]; + + if (!dst_pal) + { + IDirectDrawPalette_Release(src_pal); + LeaveCriticalSection(&ddraw_cs); + return DDERR_NOPALETTEATTACHED; + } + IDirectDrawPalette_GetEntries(src_pal, 0, 0, 256, palent); + IDirectDrawPalette_SetEntries(dst_pal, 0, 0, 256, palent); + } + + if (dst_pal) IDirectDrawPalette_Release(dst_pal); + if (src_pal) IDirectDrawPalette_Release(src_pal); + + /* Copy one surface on the other */ + dst_desc = (DDSURFACEDESC *)&(dst_surface->surface_desc); + src_desc = (DDSURFACEDESC *)&(src_surface->surface_desc); + + if ((src_desc->dwWidth != dst_desc->dwWidth) || (src_desc->dwHeight != dst_desc->dwHeight)) + { + /* Should also check for same pixel format, u1.lPitch, ... */ + ERR("Error in surface sizes.\n"); + LeaveCriticalSection(&ddraw_cs); + return D3DERR_TEXTURE_LOAD_FAILED; + } + else + { + WINED3DLOCKED_RECT src_rect, dst_rect; + + /* Copy also the ColorKeying stuff */ + if (src_desc->dwFlags & DDSD_CKSRCBLT) + { + dst_desc->dwFlags |= DDSD_CKSRCBLT; + dst_desc->ddckCKSrcBlt.dwColorSpaceLowValue = src_desc->ddckCKSrcBlt.dwColorSpaceLowValue; + dst_desc->ddckCKSrcBlt.dwColorSpaceHighValue = src_desc->ddckCKSrcBlt.dwColorSpaceHighValue; + } + + /* Copy the main memory texture into the surface that corresponds + * to the OpenGL texture object. */ + + hr = IWineD3DSurface_LockRect(src_surface->WineD3DSurface, &src_rect, NULL, 0); + if (FAILED(hr)) + { + ERR("Failed to lock source surface, hr %#x.\n", hr); + LeaveCriticalSection(&ddraw_cs); + return D3DERR_TEXTURE_LOAD_FAILED; + } + + hr = IWineD3DSurface_LockRect(dst_surface->WineD3DSurface, &dst_rect, NULL, 0); + if (FAILED(hr)) + { + ERR("Failed to lock destination surface, hr %#x.\n", hr); + IWineD3DSurface_UnlockRect(src_surface->WineD3DSurface); + LeaveCriticalSection(&ddraw_cs); + return D3DERR_TEXTURE_LOAD_FAILED; + } + + if (dst_surface->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) + memcpy(dst_rect.pBits, src_rect.pBits, src_surface->surface_desc.u1.dwLinearSize); + else + memcpy(dst_rect.pBits, src_rect.pBits, src_rect.Pitch * src_desc->dwHeight); + + IWineD3DSurface_UnlockRect(src_surface->WineD3DSurface); + IWineD3DSurface_UnlockRect(dst_surface->WineD3DSurface); + } + + if (src_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) + src_surface = get_sub_mimaplevel(src_surface); + else + src_surface = NULL; + + if (dst_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) + dst_surface = get_sub_mimaplevel(dst_surface); + else + dst_surface = NULL; + + if (!src_surface || !dst_surface) + { + if (src_surface != dst_surface) + ERR("Loading surface with different mipmap structure.\n"); + break; + } + } + + LeaveCriticalSection(&ddraw_cs); + + return hr; +} + +static HRESULT WINAPI d3d_texture1_Load(IDirect3DTexture *iface, IDirect3DTexture *src_texture) +{ + TRACE("iface %p, src_texture %p.\n", iface, src_texture); + + return d3d_texture2_Load((IDirect3DTexture2 *)&surface_from_texture1(iface)->IDirect3DTexture2_vtbl, + src_texture ? (IDirect3DTexture2 *)&surface_from_texture1(src_texture)->IDirect3DTexture2_vtbl : NULL); +} + /***************************************************************************** * The VTable *****************************************************************************/ @@ -3104,3 +3480,25 @@ const IDirectDrawGammaControlVtbl IDirectDrawGammaControl_Vtbl = ddraw_gamma_control_GetGammaRamp, ddraw_gamma_control_SetGammaRamp, }; + +const IDirect3DTexture2Vtbl IDirect3DTexture2_Vtbl = +{ + d3d_texture2_QueryInterface, + d3d_texture2_AddRef, + d3d_texture2_Release, + d3d_texture2_GetHandle, + d3d_texture2_PaletteChanged, + d3d_texture2_Load, +}; + +const IDirect3DTextureVtbl IDirect3DTexture1_Vtbl = +{ + d3d_texture1_QueryInterface, + d3d_texture1_AddRef, + d3d_texture1_Release, + d3d_texture1_Initialize, + d3d_texture1_GetHandle, + d3d_texture1_PaletteChanged, + d3d_texture1_Load, + d3d_texture1_Unload, +}; diff --git a/dlls/ddraw/texture.c b/dlls/ddraw/texture.c deleted file mode 100644 index 2fc5d5076ed..00000000000 --- a/dlls/ddraw/texture.c +++ /dev/null @@ -1,501 +0,0 @@ -/* Direct3D Texture - * Copyright (c) 1998 Lionel ULMER - * Copyright (c) 2006 Stefan DÖSINGER - * - * This file contains the implementation of interface Direct3DTexture2. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" -#include "wine/port.h" - -#include -#include -#include -#include - -#define COBJMACROS -#define NONAMELESSUNION - -#include "windef.h" -#include "winbase.h" -#include "winerror.h" -#include "wingdi.h" -#include "wine/exception.h" - -#include "ddraw.h" -#include "d3d.h" - -#include "ddraw_private.h" -#include "wine/debug.h" - -WINE_DEFAULT_DEBUG_CHANNEL(d3d7); -WINE_DECLARE_DEBUG_CHANNEL(ddraw_thunk); - -/***************************************************************************** - * IUnknown interfaces. They are thunks to IDirectDrawSurface7 - *****************************************************************************/ -static HRESULT WINAPI -Thunk_IDirect3DTextureImpl_2_QueryInterface(IDirect3DTexture2 *iface, - REFIID riid, - void **obj) -{ - IDirectDrawSurfaceImpl *This = surface_from_texture2(iface); - TRACE("(%p)->(%s,%p) thunking to IDirectDrawSurface7 interface.\n", This, debugstr_guid(riid), obj); - return IDirectDrawSurface7_QueryInterface((IDirectDrawSurface7 *)This, riid, obj); -} - -static HRESULT WINAPI -Thunk_IDirect3DTextureImpl_1_QueryInterface(IDirect3DTexture *iface, - REFIID riid, - void **obj) -{ - IDirectDrawSurfaceImpl *This = surface_from_texture1(iface); - TRACE("(%p)->(%s,%p) thunking to IDirectDrawSurface7 interface.\n", This, debugstr_guid(riid), obj); - - return IDirectDrawSurface7_QueryInterface((IDirectDrawSurface7 *)This, riid, obj); -} - -static ULONG WINAPI -Thunk_IDirect3DTextureImpl_2_AddRef(IDirect3DTexture2 *iface) -{ - IDirectDrawSurfaceImpl *This = surface_from_texture2(iface); - TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", This); - - return IDirectDrawSurface7_AddRef((IDirectDrawSurface7 *)This); -} - -static ULONG WINAPI -Thunk_IDirect3DTextureImpl_1_AddRef(IDirect3DTexture *iface) -{ - IDirectDrawSurfaceImpl *This = surface_from_texture1(iface); - TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", This); - - return IDirectDrawSurface7_AddRef((IDirectDrawSurface7 *)This); -} - -static ULONG WINAPI -Thunk_IDirect3DTextureImpl_2_Release(IDirect3DTexture2 *iface) -{ - IDirectDrawSurfaceImpl *This = surface_from_texture2(iface); - TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", This); - - return IDirectDrawSurface7_Release((IDirectDrawSurface7 *)This); -} - - -static ULONG WINAPI -Thunk_IDirect3DTextureImpl_1_Release(IDirect3DTexture *iface) -{ - IDirectDrawSurfaceImpl *This = surface_from_texture1(iface); - TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", This); - - return IDirectDrawSurface7_Release((IDirectDrawSurface7 *)This); -} - -/***************************************************************************** - * IDirect3DTexture interface - *****************************************************************************/ - -/***************************************************************************** - * 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) -{ - TRACE("(%p)->(%p,%p) Not implemented\n", iface, Direct3DDevice, DDSurface); - return DDERR_UNSUPPORTED; /* Unchecked */ -} - -/***************************************************************************** - * IDirect3DTexture2::PaletteChanged - * - * Informs the texture about a palette change - * - * Params: - * Start: Start index of the change - * Count: The number of changed entries - * - * Returns - * D3D_OK, because it's a stub - * - *****************************************************************************/ -static HRESULT WINAPI -IDirect3DTextureImpl_PaletteChanged(IDirect3DTexture2 *iface, - DWORD Start, - DWORD Count) -{ - IDirectDrawSurfaceImpl *This = surface_from_texture2(iface); - FIXME("(%p)->(%08x,%08x): stub!\n", This, Start, Count); - return D3D_OK; -} - -static HRESULT WINAPI -Thunk_IDirect3DTextureImpl_1_PaletteChanged(IDirect3DTexture *iface, - DWORD Start, - DWORD Count) -{ - IDirectDrawSurfaceImpl *This = surface_from_texture1(iface); - TRACE("(%p)->(%08x,%08x) thunking to IDirect3DTexture2 interface.\n", This, Start, Count); - - return IDirect3DTexture2_PaletteChanged((IDirect3DTexture2 *)&This->IDirect3DTexture2_vtbl, Start, Count); -} - - -/***************************************************************************** - * IDirect3DTexture::Unload - * - * DX5 SDK: "The IDirect3DTexture2::Unload method is not implemented - * - * - * Returns: - * DDERR_UNSUPPORTED - * - *****************************************************************************/ -static HRESULT WINAPI -IDirect3DTextureImpl_1_Unload(IDirect3DTexture *iface) -{ - IDirectDrawSurfaceImpl *This = surface_from_texture1(iface); - TRACE("(%p)->(): not implemented!\n", This); - return DDERR_UNSUPPORTED; -} - -/***************************************************************************** - * 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) -{ - IDirectDrawSurfaceImpl *This = surface_from_texture2(iface); - IDirect3DDeviceImpl *d3d = device_from_device2(Direct3DDevice2); - - TRACE("(%p)->(%p,%p)\n", This, d3d, lpHandle); - - EnterCriticalSection(&ddraw_cs); - if(!This->Handle) - { - DWORD h = ddraw_allocate_handle(&d3d->handle_table, This, DDRAW_HANDLE_SURFACE); - if (h == DDRAW_INVALID_HANDLE) - { - ERR("Failed to allocate a texture handle.\n"); - LeaveCriticalSection(&ddraw_cs); - return DDERR_OUTOFMEMORY; - } - - This->Handle = h + 1; - } - *lpHandle = This->Handle; - - TRACE(" returning handle %08x.\n", *lpHandle); - - LeaveCriticalSection(&ddraw_cs); - return D3D_OK; -} - -static HRESULT WINAPI -Thunk_IDirect3DTextureImpl_1_GetHandle(IDirect3DTexture *iface, - LPDIRECT3DDEVICE lpDirect3DDevice, - LPD3DTEXTUREHANDLE lpHandle) -{ - IDirectDrawSurfaceImpl *This = surface_from_texture1(iface); - IDirect3DDeviceImpl *d3d = device_from_device1(lpDirect3DDevice); - IDirect3DTexture2 *d3d_texture2 = (IDirect3DTexture2 *)&This->IDirect3DTexture2_vtbl; - IDirect3DDevice2 *d3d_device2 = (IDirect3DDevice2 *)&d3d->IDirect3DDevice2_vtbl; - - TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DTexture2 interface.\n", This, d3d, lpHandle); - - return IDirect3DTexture2_GetHandle(d3d_texture2, d3d_device2, lpHandle); -} - - -/***************************************************************************** - * 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 DDSCAPS2 mipmap_caps = { DDSCAPS_MIPMAP | DDSCAPS_TEXTURE, 0, 0, 0 }; - LPDIRECTDRAWSURFACE7 next_level; - IDirectDrawSurfaceImpl *surf_ptr; - HRESULT hr; - - hr = IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7 *)tex_ptr, &mipmap_caps, &next_level); - if (FAILED(hr)) return NULL; - - surf_ptr = (IDirectDrawSurfaceImpl *)next_level; - IDirectDrawSurface7_Release(next_level); - - return surf_ptr; -} - -/***************************************************************************** - * 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) -{ - IDirectDrawSurfaceImpl *This = surface_from_texture2(iface); - IDirectDrawSurfaceImpl *src_ptr = surface_from_texture2(D3DTexture2); - HRESULT ret_value = D3D_OK; - if(src_ptr == This) - { - TRACE("copying surface %p to surface %p, why?\n", src_ptr, This); - return ret_value; - } - - TRACE("(%p)->(%p)\n", This, src_ptr); - EnterCriticalSection(&ddraw_cs); - - 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) - { - IWineD3DPalette *wine_pal, *wine_pal_src; - IDirectDrawPalette *pal = NULL, *pal_src = NULL; - DDSURFACEDESC *src_d, *dst_d; - - TRACE(" copying surface %p to surface %p (mipmap level %d)\n", src_ptr, This, src_ptr->mipmap_level); - - /* 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"); - LeaveCriticalSection(&ddraw_cs); - 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"); - LeaveCriticalSection(&ddraw_cs); - return D3DERR_TEXTURE_LOAD_FAILED; - } - } - - ret_value = IWineD3DSurface_GetPalette(src_ptr->WineD3DSurface, &wine_pal_src); - if( ret_value != D3D_OK) - { - ERR("IWineD3DSurface::GetPalette failed! This is unexpected\n"); - LeaveCriticalSection(&ddraw_cs); - 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"); - if (pal) IDirectDrawPalette_Release(pal); - LeaveCriticalSection(&ddraw_cs); - return D3DERR_TEXTURE_LOAD_FAILED; - } - } - - if (pal_src != NULL) - { - PALETTEENTRY palent[256]; - - if (pal == NULL) - { - IDirectDrawPalette_Release(pal_src); - LeaveCriticalSection(&ddraw_cs); - return DDERR_NOPALETTEATTACHED; - } - IDirectDrawPalette_GetEntries(pal_src, 0, 0, 256, palent); - IDirectDrawPalette_SetEntries(pal, 0, 0, 256, palent); - } - - if (pal) IDirectDrawPalette_Release(pal); - if (pal_src) IDirectDrawPalette_Release(pal_src); - - /* 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"); - LeaveCriticalSection(&ddraw_cs); - 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); - LeaveCriticalSection(&ddraw_cs); - 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); - LeaveCriticalSection(&ddraw_cs); - 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; - } - } - - LeaveCriticalSection(&ddraw_cs); - return ret_value; -} - -static HRESULT WINAPI -Thunk_IDirect3DTextureImpl_1_Load(IDirect3DTexture *iface, - IDirect3DTexture *D3DTexture) -{ - IDirectDrawSurfaceImpl *This = surface_from_texture1(iface); - IDirectDrawSurfaceImpl *Texture = surface_from_texture1(D3DTexture); - TRACE("(%p)->(%p) thunking to IDirect3DTexture2 interface.\n", This, Texture); - - return IDirect3DTexture2_Load((IDirect3DTexture2 *)&This->IDirect3DTexture2_vtbl, - D3DTexture ? (IDirect3DTexture2 *)&surface_from_texture1(D3DTexture)->IDirect3DTexture2_vtbl : NULL); -} - -/***************************************************************************** - * The VTables - *****************************************************************************/ -const IDirect3DTexture2Vtbl IDirect3DTexture2_Vtbl = -{ - Thunk_IDirect3DTextureImpl_2_QueryInterface, - Thunk_IDirect3DTextureImpl_2_AddRef, - Thunk_IDirect3DTextureImpl_2_Release, - IDirect3DTextureImpl_GetHandle, - IDirect3DTextureImpl_PaletteChanged, - IDirect3DTextureImpl_Load, -}; - - -const IDirect3DTextureVtbl IDirect3DTexture1_Vtbl = -{ - Thunk_IDirect3DTextureImpl_1_QueryInterface, - Thunk_IDirect3DTextureImpl_1_AddRef, - Thunk_IDirect3DTextureImpl_1_Release, - IDirect3DTextureImpl_1_Initialize, - Thunk_IDirect3DTextureImpl_1_GetHandle, - Thunk_IDirect3DTextureImpl_1_PaletteChanged, - Thunk_IDirect3DTextureImpl_1_Load, - IDirect3DTextureImpl_1_Unload, -};