surface_base.c revision 589fd26cedb2b4ebbed14f2964cad03cc8ebbca2
/*
* 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
*
* 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"
#include <assert.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.0;
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_GetDevice(IWineD3DSurface *iface, IWineD3DDevice** ppDevice) {
}
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. */
} else {
}
TRACE("Relaying to QueryInterface\n");
}
HRESULT WINAPI IWineD3DBaseSurfaceImpl_GetDesc(IWineD3DSurface *iface, WINED3DSURFACE_DESC *pDesc) {
if(pDesc->MultiSampleQuality != NULL) *(pDesc->MultiSampleQuality) = This->currentDesc.MultiSampleQuality;
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;
}
/* DXTn formats don't have exact pitches as they are to the new row of blocks,
where each block is 4x4 pixels, 8 bytes (dxt1) and 16 bytes (dxt2/3/4/5)
ie pitch = (width/4) * bytes per block */
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;
}
if (format == WINED3DFMT_UNKNOWN) {
} else if (format == WINED3DFMT_DXT1) {
/* DXT1 is half byte per pixel */
This->resource.size = ((max(This->pow2Width, 4) * format_desc->byte_count) * max(This->pow2Height, 4)) >> 1;
This->resource.size = ((max(This->pow2Width, 4) * format_desc->byte_count) * max(This->pow2Height, 4));
} else {
This->resource.size = ((This->pow2Width * format_desc->byte_count) + alignment - 1) & ~(alignment - 1);
}
return WINED3D_OK;
}
int extraline = 0;
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_R8G8B8:
break;
case WINED3DFMT_X1R5G5B5:
case WINED3DFMT_A1R5G5B5:
case WINED3DFMT_A4R4G4B4:
case WINED3DFMT_X4R4G4B4:
case WINED3DFMT_R3G3B2:
case WINED3DFMT_A8R3G3B2:
case WINED3DFMT_X8B8G8R8:
case WINED3DFMT_A2R10G10B10:
case WINED3DFMT_R5G6B5:
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
}
}
}
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;
}
0 /* MultiSampleQuality */, IWineD3DSurface_GetImplType((IWineD3DSurface *) source), NULL /* parent */);
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 first the FOURCC surfaces... */
{
TRACE("Fourcc -> Fourcc copy\n");
if (trans)
FIXME("trans arg not supported when a FOURCC surface is involved\n");
FIXME("offset for destination surface is not supported\n");
{
FIXME("FOURCC->FOURCC copy only supported for the same type of surface\n");
goto error;
}
{
block_width = 4;
block_height = 4;
block_byte_size = 8;
}
{
block_width = 4;
block_height = 4;
block_byte_size = 16;
}
else
{
block_width = 1;
block_height = 1;
}
for (y = 0; y < h; y += block_height)
{
}
goto error;
}
{
/* TODO: Use the libtxc_dxtn.so shared library to do
* software decompression
*/
ERR("DXTC decompression not supported by now\n");
goto error;
}
{
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",
/* DXTn textures are based on compressed blocks of 4x4 pixels, each
* 16 bytes large (8 bytes in case of DXT1). Because of that Pitch has
* slightly different meaning compared to regular textures. For DXTn
* textures Pitch is the size of a row of blocks, 4 high and "width"
* long. The x offset is calculated differently as well, since moving 4
* pixels to the right actually moves an entire 4x4 block to right, ie
* 16 bytes (8 in case of DXT1). */
{
pLockedRect->pBits = This->resource.allocatedMemory + (pLockedRect->Pitch * pRect->top / 4) + (pRect->left * 2);
}
{
pLockedRect->pBits = This->resource.allocatedMemory + (pLockedRect->Pitch * pRect->top / 4) + (pRect->left * 4);
}
else
{
}
}
/* No dirtifying is needed for this surface implementation */
return WINED3D_OK;
}
ERR("Should not be called on base texture\n");
return;
}
/* 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 */
{
}
}