surface_base.c revision 9a0dee30f5bea4fb02c0e836cd9689822e4645d1
/*
* IWineD3DSurface Implementation of management(non-rendering) functions
*
* Copyright 1998 Lionel Ulmer
* Copyright 2000-2001 TransGaming Technologies Inc.
* Copyright 2002-2005 Jason Edmeades
* Copyright 2002-2003 Raphael Junqueira
* Copyright 2004 Christian Costa
* Copyright 2005 Oliver Stieber
* Copyright 2006-2008 Stefan Dösinger for CodeWeavers
* Copyright 2007 Henri Verbeet
* Copyright 2006-2007 Roderick Colenbrander
* Copyright 2009 Henri Verbeet for CodeWeavers
*
* 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
*/
/*
* Sun LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
* other than GPL or LGPL is available it will apply instead, Sun elects to use only
* the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
* a choice of LGPL license versions is made available with the language indicating
* that LGPLv2 or any later version may be used, or where a choice of which version
* of the LGPL is applied is otherwise unspecified.
*/
#include "config.h"
#include "wined3d_private.h"
/* See also float_16_to_32() in wined3d_private.h */
static inline unsigned short float_32_to_16(const float *in)
{
int exp = 0;
unsigned int mantissa;
unsigned short ret;
/* Deal with special numbers */
do
{
exp--;
do
{
tmp /= 2.0f;
exp++;
}
} else if(exp <= 0) {
/* exp == 0: Non-normalized mantissa. Returns 0x0000 (=0.0) for too small numbers */
while(exp <= 0) {
exp++;
}
} else {
}
return ret;
}
/* Do NOT define GLINFO_LOCATION in this file. THIS CODE MUST NOT USE IT */
/* *******************************************
IWineD3DSurface IUnknown parts follow
******************************************* */
HRESULT WINAPI IWineD3DBaseSurfaceImpl_QueryInterface(IWineD3DSurface *iface, REFIID riid, LPVOID *ppobj)
{
/* Warn ,but be nice about things */
return S_OK;
}
return E_NOINTERFACE;
}
return ref;
}
/* ****************************************************
IWineD3DSurface IWineD3DResource parts follow
**************************************************** */
HRESULT WINAPI IWineD3DBaseSurfaceImpl_SetPrivateData(IWineD3DSurface *iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) {
}
HRESULT WINAPI IWineD3DBaseSurfaceImpl_GetPrivateData(IWineD3DSurface *iface, REFGUID refguid, void* pData, DWORD* pSizeOfData) {
}
}
}
}
}
}
/* ******************************************************
IWineD3DSurface IWineD3DSurface parts follow
****************************************************** */
HRESULT WINAPI IWineD3DBaseSurfaceImpl_GetContainer(IWineD3DSurface* iface, REFIID riid, void** ppContainer) {
IWineD3DBase *container = 0;
if (!ppContainer) {
ERR("Called without a valid ppContainer.\n");
}
/* Standalone surfaces return the device as container. */
TRACE("Relaying to QueryInterface\n");
}
HRESULT WINAPI IWineD3DBaseSurfaceImpl_GetDesc(IWineD3DSurface *iface, WINED3DSURFACE_DESC *pDesc) {
return WINED3D_OK;
}
{
switch (Flags)
{
case WINEDDGBS_CANBLT:
case WINEDDGBS_ISBLTDONE:
return WINED3D_OK;
default:
return WINED3DERR_INVALIDCALL;
}
}
/* XXX: DDERR_INVALIDSURFACETYPE */
switch (Flags) {
case WINEDDGFS_CANFLIP:
case WINEDDGFS_ISFLIPDONE:
return WINED3D_OK;
default:
return WINED3DERR_INVALIDCALL;
}
}
/* D3D8 and 9 loose full devices, ddraw only surfaces */
}
/* So far we don't lose anything :) */
return WINED3D_OK;
}
TRACE("Nop palette change\n");
return WINED3D_OK;
}
}
return IWineD3DSurface_RealizePalette(iface);
}
else return WINED3D_OK;
}
HRESULT WINAPI IWineD3DBaseSurfaceImpl_SetColorKey(IWineD3DSurface *iface, DWORD Flags, const WINEDDCOLORKEY *CKey)
{
if ((Flags & WINEDDCKEY_COLORSPACE) != 0) {
return WINED3DERR_INVALIDCALL;
}
/* Dirtify the surface, but only if a key was changed */
if(CKey) {
switch (Flags & ~WINEDDCKEY_COLORSPACE) {
case WINEDDCKEY_DESTBLT:
break;
case WINEDDCKEY_DESTOVERLAY:
break;
case WINEDDCKEY_SRCOVERLAY:
break;
case WINEDDCKEY_SRCBLT:
break;
}
}
else {
switch (Flags & ~WINEDDCKEY_COLORSPACE) {
case WINEDDCKEY_DESTBLT:
break;
case WINEDDCKEY_DESTOVERLAY:
break;
case WINEDDCKEY_SRCOVERLAY:
break;
case WINEDDCKEY_SRCBLT:
break;
}
}
return WINED3D_OK;
}
return WINED3D_OK;
}
{
/* Since compressed formats are block based, pitch means the amount of
* bytes to the next row of block rather than the next row of pixels. */
UINT row_block_count = (This->currentDesc.Width + format_desc->block_width - 1) / format_desc->block_width;
}
else
{
}
return ret;
}
LONG w, h;
{
return WINEDDERR_NOTAOVERLAYSURFACE;
}
return WINED3D_OK;
}
HRESULT WINAPI IWineD3DBaseSurfaceImpl_GetOverlayPosition(IWineD3DSurface *iface, LONG *X, LONG *Y) {
{
return WINEDDERR_NOTAOVERLAYSURFACE;
}
*X = 0; *Y = 0;
} else {
hr = WINED3D_OK;
}
return hr;
}
HRESULT WINAPI IWineD3DBaseSurfaceImpl_UpdateOverlayZOrder(IWineD3DSurface *iface, DWORD Flags, IWineD3DSurface *Ref) {
{
return WINEDDERR_NOTAOVERLAYSURFACE;
}
return WINED3D_OK;
}
{
{
return WINEDDERR_NOTAOVERLAYSURFACE;
} else if(!DstSurface) {
return WINED3DERR_INVALIDCALL;
}
if(SrcRect) {
} else {
}
if(DstRect) {
} else {
}
}
if(Flags & WINEDDOVER_SHOW) {
}
} else if(Flags & WINEDDOVER_HIDE) {
/* tests show that the rectangles are erased on hide */
}
return WINED3D_OK;
}
{
return WINED3D_OK;
}
HRESULT WINAPI IWineD3DBaseSurfaceImpl_GetClipper(IWineD3DSurface *iface, IWineD3DClipper **clipper)
{
if(*clipper) {
}
return WINED3D_OK;
}
HRESULT WINAPI IWineD3DBaseSurfaceImpl_SetContainer(IWineD3DSurface *iface, IWineD3DBase *container) {
/* We can't keep a reference to the container, since the container already keeps a reference to us. */
return WINED3D_OK;
}
{
return WINED3DERR_INVALIDCALL;
}
return WINED3D_OK;
}
int extraline = 0;
{
return WINED3DERR_INVALIDCALL;
}
switch (format_desc->byte_count)
{
case 2:
case 4:
/* Allocate extra space to store the RGB bit masks. */
b_info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 3 * sizeof(DWORD));
break;
case 3:
break;
default:
/* Allocate extra space for a palette. */
break;
}
if (!b_info)
return E_OUTOFMEMORY;
/* Some apps access the surface in via DWORDs, and do not take the necessary care at the end of the
* surface. So we need at least extra 4 bytes at the end of the surface. Check against the page size,
* if the last page used for the surface has at least 4 spare bytes we're safe, otherwise
* add an extra line to the dib section
*/
extraline = 1;
TRACE("Adding an extra line to the dib section\n");
}
/* TODO: Is there a nicer way to force a specific alignment? (8 byte for ddraw) */
b_info->bmiHeader.biSizeImage = ( This->currentDesc.Height + extraline) * IWineD3DSurface_GetPitch(iface);
/* Get the bit masks */
{
case WINED3DFMT_B8G8R8_UNORM:
break;
case WINED3DFMT_B2G3R3_UNORM:
case WINED3DFMT_B5G6R5_UNORM:
usage = 0;
break;
default:
/* Don't know palette */
usage = 0;
break;
}
if (ddc == 0) {
return HRESULT_FROM_WIN32(GetLastError());
}
TRACE("Creating a DIB section with size %dx%dx%d, size=%d\n", b_info->bmiHeader.biWidth, b_info->bmiHeader.biHeight, b_info->bmiHeader.biBitCount, b_info->bmiHeader.biSizeImage);
This->dib.DIBsection = CreateDIBSection(ddc, b_info, usage, &This->dib.bitmap_data, 0 /* Handle */, 0 /* Offset */);
ERR("CreateDIBSection failed!\n");
return HRESULT_FROM_WIN32(GetLastError());
}
/* copy the existing surface to the dib section */
memcpy(This->dib.bitmap_data, This->resource.allocatedMemory, This->currentDesc.Height * IWineD3DSurface_GetPitch(iface));
} else {
/* This is to make LockRect read the gl Texture although memory is allocated */
}
/* Now allocate a HDC */
FALSE);
return WINED3D_OK;
}
static void convert_r32_float_r16_float(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out,
unsigned int w, unsigned int h)
{
unsigned int x, y;
const float *src_f;
unsigned short *dst_s;
for(y = 0; y < h; y++) {
for(x = 0; x < w; x++) {
}
}
}
{
static const unsigned char convert_5to8[] =
{
0x00, 0x08, 0x10, 0x19, 0x21, 0x29, 0x31, 0x3a,
0x42, 0x4a, 0x52, 0x5a, 0x63, 0x6b, 0x73, 0x7b,
0x84, 0x8c, 0x94, 0x9c, 0xa5, 0xad, 0xb5, 0xbd,
0xc5, 0xce, 0xd6, 0xde, 0xe6, 0xef, 0xf7, 0xff,
};
static const unsigned char convert_6to8[] =
{
0x00, 0x04, 0x08, 0x0c, 0x10, 0x14, 0x18, 0x1c,
0x20, 0x24, 0x28, 0x2d, 0x31, 0x35, 0x39, 0x3d,
0x41, 0x45, 0x49, 0x4d, 0x51, 0x55, 0x59, 0x5d,
0x61, 0x65, 0x69, 0x6d, 0x71, 0x75, 0x79, 0x7d,
0x82, 0x86, 0x8a, 0x8e, 0x92, 0x96, 0x9a, 0x9e,
0xa2, 0xa6, 0xaa, 0xae, 0xb2, 0xb6, 0xba, 0xbe,
0xc2, 0xc6, 0xca, 0xce, 0xd2, 0xd7, 0xdb, 0xdf,
0xe3, 0xe7, 0xeb, 0xef, 0xf3, 0xf7, 0xfb, 0xff,
};
unsigned int x, y;
for (y = 0; y < h; ++y)
{
for (x = 0; x < w; ++x)
{
dst_line[x] = 0xff000000
}
}
}
{
unsigned int x, y;
for (y = 0; y < h; ++y)
{
for (x = 0; x < w; ++x)
{
}
}
}
static inline BYTE cliptobyte(int x)
{
}
{
unsigned int x, y;
for (y = 0; y < h; ++y)
{
for (x = 0; x < w; ++x)
{
/* YUV to RGB conversion formulas from http://en.wikipedia.org/wiki/YUV:
* C = Y - 16; D = U - 128; E = V - 128;
* R = cliptobyte((298 * C + 409 * E + 128) >> 8);
* G = cliptobyte((298 * C - 100 * D - 208 * E + 128) >> 8);
* B = cliptobyte((298 * C + 516 * D + 128) >> 8);
* Two adjacent YUY2 pixels are stored as four bytes: Y0 U Y1 V .
* U and V are shared between the pixels.
*/
if (!(x & 1)) /* for every even pixel, read new U and V */
{
}
dst_line[x] = 0xff000000
/* Scale RGB values to 0..255 range,
* then clip them if still not in range (may be negative),
* then shift them within DWORD if necessary.
*/
src_line += 2;
}
}
}
struct d3dfmt_convertor_desc {
void (*convert)(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h);
};
static const struct d3dfmt_convertor_desc convertors[] =
{
};
static inline const struct d3dfmt_convertor_desc *find_convertor(WINED3DFORMAT from, WINED3DFORMAT to)
{
unsigned int i;
for(i = 0; i < (sizeof(convertors) / sizeof(convertors[0])); i++) {
return &convertors[i];
}
}
return NULL;
}
/*****************************************************************************
* surface_convert_format
*
* Creates a duplicate of a surface in a different format. Is used by Blt to
* blit between surfaces with different formats
*
* Parameters
* source: Source surface
* fmt: Requested destination format
*
*****************************************************************************/
static IWineD3DSurfaceImpl *surface_convert_format(IWineD3DSurfaceImpl *source, WINED3DFORMAT to_fmt) {
const struct d3dfmt_convertor_desc *conv;
if(!conv) {
FIXME("Cannot find a conversion function from format %s to %s\n",
return NULL;
}
#ifdef VBOXWDDM
#else
#endif
if(!ret) {
ERR("Failed to create a destination surface for conversion\n");
return NULL;
}
ERR("Failed to lock the source surface\n");
return NULL;
}
ERR("Failed to lock the dest surface\n");
return NULL;
}
return (IWineD3DSurfaceImpl *) ret;
}
/*****************************************************************************
* _Blt_ColorFill
*
* Helper function that fills a memory area with a specific color
*
* Params:
* buf: memory address to start filling at
* width, height: Dimensions of the area to fill
* bpp: Bit depth of the surface
* lPitch: pitch of the surface
* color: Color to fill with
*
*****************************************************************************/
static HRESULT
{
int x, y;
/* Do first row */
#define COLORFILL_ROW(type) \
{ \
for (x = 0; x < width; x++) \
break; \
}
switch(bpp)
{
case 3:
{
for (x = 0; x < width; x++,d+=3)
{
d[0] = (color ) & 0xFF;
}
break;
}
default:
return WINED3DERR_NOTAVAILABLE;
}
/* Now copy first row */
for (y = 1; y < height; y++)
{
}
return WINED3D_OK;
}
/*****************************************************************************
* IWineD3DSurface::Blt, SW emulation version
*
* Performs blits to a surface, eigher from a source of source-less blts
* This is the main functionality of DirectDraw
*
* Params:
* DestRect: Destination rectangle to write to
* SrcSurface: Source surface, can be NULL
* SrcRect: Source rectangle
*****************************************************************************/
HRESULT WINAPI IWineD3DBaseSurfaceImpl_Blt(IWineD3DSurface *iface, const RECT *DestRect, IWineD3DSurface *SrcSurface,
{
int x, y;
if (TRACE_ON(d3d_surface))
{
#if 0
TRACE("\tflags: ");
if (Flags & WINEDDBLT_DDFX)
{
TRACE("\tblitfx: ");
}
#endif
}
{
WARN(" Surface is busy, returning DDERR_SURFACEBUSY\n");
return WINEDDERR_SURFACEBUSY;
}
/* Can happen when d3d9 apps do a StretchRect call which isn't handled in gl */
FIXME("Filters not supported in software blit\n");
}
/* First check for the validity of source / destination rectangles. This was
* verified using a test application + by MSDN.
*/
{
WARN("Application gave us bad source rectangle for Blt.\n");
return WINEDDERR_INVALIDRECT;
}
/* For the Destination rect, it can be out of bounds on the condition that a clipper
* is set for the given surface.
*/
{
WARN("Application gave us bad destination rectangle for Blt without a clipper set.\n");
return WINEDDERR_INVALIDRECT;
}
/* Now handle negative values in the rectangles. Warning: only supported for now
in the 'simple' cases (ie not in any stretching / rotation cases).
First, the case where nothing is to be done.
*/
{
TRACE("Nothing to be done !\n");
return WINED3D_OK;
}
if (DestRect)
{
}
else
{
}
if (SrcRect)
{
}
else
{
if (Src)
{
}
else
{
}
}
/* The easy case : the source-less blits.... */
{
}
else if (DestRect)
{
/* Only handle clipping on the destination rectangle */
if (clip_vert || clip_horiz)
{
/* Now check if this is a special case or not... */
(Flags & WINEDDBLT_DDFX))
{
WARN("Out of screen rectangle in special case. Not handled right now.\n");
return WINED3D_OK;
}
if (clip_horiz)
{
{
}
}
if (clip_vert)
{
{
}
{
}
}
/* And check if after clipping something is still to be done... */
{
TRACE("Nothing to be done after clipping !\n");
return WINED3D_OK;
}
}
}
{
}
else
{
if (Src)
{
{
if(!Src) {
/* The conv function writes a FIXME */
WARN("Cannot convert source surface format to dest format\n");
goto release;
}
}
}
else
{
}
if (DestRect)
else
}
{
{
goto release;
}
}
else
if (Flags & WINEDDBLT_WAIT)
{
Flags &= ~WINEDDBLT_WAIT;
}
if (Flags & WINEDDBLT_ASYNC)
{
if (!displayed)
FIXME("Can't handle WINEDDBLT_ASYNC flag right now.\n");
Flags &= ~WINEDDBLT_ASYNC;
}
if (Flags & WINEDDBLT_DONOTWAIT)
{
/* WINEDDBLT_DONOTWAIT appeared in DX7 */
if (!displayed)
FIXME("Can't handle WINEDDBLT_DONOTWAIT flag right now.\n");
Flags &= ~WINEDDBLT_DONOTWAIT;
}
/* First, all the 'source-less' blits */
if (Flags & WINEDDBLT_COLORFILL)
{
Flags &= ~WINEDDBLT_COLORFILL;
}
if (Flags & WINEDDBLT_DEPTHFILL)
{
FIXME("DDBLT_DEPTHFILL needs to be implemented!\n");
}
if (Flags & WINEDDBLT_ROP)
{
/* Catch some degenerate cases here */
{
case BLACKNESS:
break;
case 0xAA0029: /* No-op */
break;
case WHITENESS:
break;
case SRCCOPY: /* well, we do that below ? */
break;
default:
goto error;
}
Flags &= ~WINEDDBLT_ROP;
}
if (Flags & WINEDDBLT_DDROPS)
{
}
/* Now the 'with source' blits */
if (Src)
{
goto release;
if (!Flags)
{
/* No effects, we can cheat here */
{
{
/* No stretching in either direction. This needs to be as
* fast as possible */
/* check for overlapping surfaces */
{
/* no overlap, or dst above src, so copy from top downwards */
for (y = 0; y < dstheight; y++)
{
}
}
{
for (y = 0; y < dstheight; y++)
{
}
}
else /* src and dst overlapping on the same line, use memmove */
{
for (y = 0; y < dstheight; y++)
{
}
}
} else {
/* Stretching in Y direction only */
}
}
}
else
{
/* Stretching in X direction */
int last_sy = -1;
{
{
/* this sourcerow is the same as last sourcerow -
* copy already stretched row
*/
}
else
{
#define STRETCH_ROW(type) { \
d[x] = s[sx >> 16]; \
break; }
switch(bpp)
{
case 3:
{
const BYTE *s;
{
d[0] = (pixel )&0xff;
d+=3;
}
break;
}
default:
goto error;
}
}
}
}
}
else
{
if (Flags & (WINEDDBLT_KEYSRC | WINEDDBLT_KEYDEST | WINEDDBLT_KEYSRCOVERRIDE | WINEDDBLT_KEYDESTOVERRIDE))
{
/* The color keying flags are checked for correctness in ddraw */
if (Flags & WINEDDBLT_KEYSRC)
{
}
else if (Flags & WINEDDBLT_KEYSRCOVERRIDE)
{
}
if (Flags & WINEDDBLT_KEYDEST)
{
/* Destination color keys are taken from the source surface ! */
}
else if (Flags & WINEDDBLT_KEYDESTOVERRIDE)
{
}
if(bpp == 1)
{
keymask = 0xff;
}
else
{
| sEntry->green_mask
}
Flags &= ~(WINEDDBLT_KEYSRC | WINEDDBLT_KEYDEST | WINEDDBLT_KEYSRCOVERRIDE | WINEDDBLT_KEYDESTOVERRIDE);
}
if (Flags & WINEDDBLT_DDFX)
{
{
/* I don't think we need to do anything about this flag */
WARN("Flags=DDBLT_DDFX nothing done for WINEDDBLTFX_ARITHSTRETCHY\n");
}
{
tmp = dBottomRight;
dBottomLeft = tmp;
}
{
dBottomLeft = tmp;
dBottomRight = tmp;
}
{
/* I don't think we need to do anything about this flag */
WARN("Flags=DDBLT_DDFX nothing done for WINEDDBLTFX_NOTEARING\n");
}
{
tmp = dBottomRight;
tmp = dBottomLeft;
}
{
}
{
dBottomLeft = tmp;
}
{
/* I don't think we need to do anything about this flag */
WARN("Flags=WINEDDBLT_DDFX nothing done for WINEDDBLTFX_ZBUFFERBASEDEST\n");
}
Flags &= ~(WINEDDBLT_DDFX);
}
#define COPY_COLORKEY_FX(type) { \
const type *s; \
dx = d; \
} \
} \
} \
break; }
switch (bpp) {
case 3:
{
const BYTE *s;
{
dx = d;
{
{
}
}
d += dstyinc;
}
break;
}
default:
FIXME("%s color-keyed blit not implemented for bpp %d!\n",
goto error;
}
}
}
{
}
/* Release the converted surface if any */
return ret;
}
/*****************************************************************************
* IWineD3DSurface::BltFast, SW emulation version
*
* This is the software implementation of BltFast, as used by GDI surfaces
* and as a fallback for OpenGL surfaces. This code is taken from the old
* DirectDraw code, and was originally written by TransGaming.
*
* Params:
* dstx:
* dsty:
* Source: Source surface to copy from
* rsrc: Source rectangle
* trans: Some Flags
*
* Returns:
* WINED3D_OK on success
*
*****************************************************************************/
{
int bpp, w, h, x, y;
if (TRACE_ON(d3d_surface))
{
if (rsrc)
{
}
else
{
TRACE(" srcrect: NULL\n");
}
}
{
WARN(" Surface is busy, returning DDERR_SURFACEBUSY\n");
return WINEDDERR_SURFACEBUSY;
}
if (!rsrc)
{
WARN("rsrc is NULL!\n");
}
/* Check source rect for validity. Copied from normal Blt. Fixes Baldur's Gate.*/
{
WARN("Application gave us bad source rectangle for BltFast.\n");
return WINEDDERR_INVALIDRECT;
}
if (h <= 0) return WINEDDERR_INVALIDRECT;
if (w <= 0) return WINEDDERR_INVALIDRECT;
/* Now compute the locking rectangle... */
/* We need to lock the surfaces, or we won't get refreshes when done. */
{
int pitch;
/* Lock the union of the two rectangles */
/* Since slock was originally copied from this surface's description, we can just reuse it */
}
else
{
}
/* Handle compressed surfaces first... */
{
TRACE("compressed -> compressed copy\n");
if (trans)
FIXME("trans arg not supported when a compressed surface is involved\n");
FIXME("offset for destination surface is not supported\n");
{
FIXME("compressed -> compressed copy only supported for the same type of surface\n");
goto error;
}
for (y = 0; y < h; y += dEntry->block_height)
{
}
goto error;
}
{
/* TODO: Use the libtxc_dxtn.so shared library to do
* software decompression
*/
ERR("Software decompression not supported.\n");
goto error;
}
{
/* For some 8-bit formats like L8 and P8 color masks don't make sense */
mask = 0xff;
TRACE("Color keyed copy\n");
if (trans & WINEDDBLTFAST_SRCCOLORKEY)
{
}
else
{
/* I'm not sure if this is correct */
FIXME("WINEDDBLTFAST_DESTCOLORKEY not fully supported yet.\n");
}
#define COPYBOX_COLORKEY(type) { \
for (y = 0; y < h; y++) { \
for (x = 0; x < w; x++) { \
tmp = s[x]; \
} \
} \
break; \
}
switch (bpp) {
case 3:
{
const BYTE *s;
BYTE *d;
s = sbuf;
d = dbuf;
for (y = 0; y < h; y++)
{
for (x = 0; x < w * 3; x += 3)
{
{
d[x + 0] = s[x + 0];
d[x + 1] = s[x + 1];
d[x + 2] = s[x + 2];
}
}
}
break;
}
default:
goto error;
}
TRACE("Copy Done\n");
}
else
{
TRACE("NO color key copy\n");
/* Handle overlapping surfaces */
{
}
else
{
}
for (y = 0; y < h; y++)
{
/* This is pretty easy, a line for line memcpy */
}
TRACE("Copy done\n");
}
{
}
else
{
}
return ret;
}
HRESULT WINAPI IWineD3DBaseSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags)
{
TRACE("(%p) : rect@%p flags(%08x), output lockedRect@%p, memory@%p\n",
{
TRACE("Locked Rect (%p) = l %d, t %d, r %d, b %d\n",
}
else
{
TRACE("Lock Rect (%p) = l %d, t %d, r %d, b %d\n",
{
/* Compressed textures are block based, so calculate the offset of
* the block that contains the top-left pixel of the locked rectangle. */
}
else
{
}
}
/* No dirtifying is needed for this surface implementation */
return WINED3D_OK;
}
ERR("Should not be called on base texture\n");
}
/* TODO: think about moving this down to resource? */
{
/* This should only be called for sysmem textures, it may be a good idea
* to extend this to all pools at some point in the future */
{
}
}