Ejemplo n.º 1
0
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);
}
Ejemplo n.º 2
0
/*****************************************************************************
 * 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 */
}
Ejemplo n.º 3
0
/*****************************************************************************
 * 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), &current_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;
}
Ejemplo n.º 4
0
/*****************************************************************************
 * 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;
}
Ejemplo n.º 5
0
/*****************************************************************************
 * 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;
}
Ejemplo n.º 6
0
/*****************************************************************************
 * 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;
}
Ejemplo n.º 7
0
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));
}
Ejemplo n.º 8
0
/*****************************************************************************
 * 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), &current_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;
}
Ejemplo n.º 9
0
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);
}
Ejemplo n.º 10
0
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);
}
Ejemplo n.º 11
0
/*****************************************************************************
 * 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;
}
Ejemplo n.º 12
0
/*****************************************************************************
 * 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;
}
Ejemplo n.º 13
0
/*****************************************************************************
 * 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;
}
Ejemplo n.º 14
0
/*****************************************************************************
 * 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;
}
Ejemplo n.º 15
0
/*****************************************************************************
 * 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), &current_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;
}
Ejemplo n.º 16
0
/*****************************************************************************
 * 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), &current_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;
}
Ejemplo n.º 17
0
/*****************************************************************************
 * 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;
}
Ejemplo n.º 18
0
/*****************************************************************************
 * 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;
}