Matteo Bruni : d3dx9: Add color key support to D3DXLoadSurfaceFromMemory.
Alexandre Julliard
julliard at winehq.org
Mon Nov 15 13:28:48 CST 2010
Module: wine
Branch: master
Commit: 0b4969f841abc269bc6cfcf68285857891fd4beb
URL: http://source.winehq.org/git/wine.git/?a=commit;h=0b4969f841abc269bc6cfcf68285857891fd4beb
Author: Matteo Bruni <mbruni at codeweavers.com>
Date: Thu Nov 11 22:13:06 2010 +0100
d3dx9: Add color key support to D3DXLoadSurfaceFromMemory.
---
dlls/d3dx9_36/surface.c | 60 +++++++++++++++++++++++++++++++++++++++--------
1 files changed, 50 insertions(+), 10 deletions(-)
diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c
index e9af051..48cd2c2 100644
--- a/dlls/d3dx9_36/surface.c
+++ b/dlls/d3dx9_36/surface.c
@@ -642,11 +642,14 @@ static void make_argb_color(CONST struct argb_conversion_info *info, CONST DWORD
* Pixels outsize the source rect are blacked out.
* Works only for ARGB formats with 1 - 4 bytes per pixel.
*/
-static void copy_simple_data(CONST BYTE *src, UINT srcpitch, POINT srcsize, CONST PixelFormatDesc *srcformat,
- BYTE *dest, UINT destpitch, POINT destsize, CONST PixelFormatDesc *destformat)
+static void copy_simple_data(CONST BYTE *src, UINT srcpitch, POINT srcsize,
+ CONST PixelFormatDesc *srcformat,
+ BYTE *dest, UINT destpitch, POINT destsize,
+ CONST PixelFormatDesc *destformat,
+ D3DCOLOR colorkey)
{
- struct argb_conversion_info conv_info;
- DWORD channels[4];
+ struct argb_conversion_info conv_info, ck_conv_info;
+ DWORD channels[4], pixel;
UINT minwidth, minheight;
UINT x, y;
@@ -656,6 +659,14 @@ static void copy_simple_data(CONST BYTE *src, UINT srcpitch, POINT srcsize, C
minwidth = (srcsize.x < destsize.x) ? srcsize.x : destsize.x;
minheight = (srcsize.y < destsize.y) ? srcsize.y : destsize.y;
+ if(colorkey) {
+ /* color keys are always represented in D3DFMT_A8R8G8B8 format */
+ const PixelFormatDesc *ckformatdesc;
+
+ ckformatdesc = get_format_info(D3DFMT_A8R8G8B8);
+ init_argb_conversion_info(srcformat, ckformatdesc, &ck_conv_info);
+ }
+
for(y = 0;y < minheight;y++) {
const BYTE *srcptr = src + y * srcpitch;
BYTE *destptr = dest + y * destpitch;
@@ -666,6 +677,14 @@ static void copy_simple_data(CONST BYTE *src, UINT srcpitch, POINT srcsize, C
/* recombine the components */
if(destformat->type == FORMAT_ARGB) make_argb_color(&conv_info, channels, (DWORD*)destptr);
+ if(colorkey) {
+ get_relevant_argb_components(&ck_conv_info, *(const DWORD*)srcptr, channels);
+ make_argb_color(&ck_conv_info, channels, &pixel);
+ if(pixel == colorkey)
+ /* make this pixel transparent */
+ *(DWORD *)destptr &= ~conv_info.destmask[0];
+ }
+
srcptr += srcformat->bytes_per_pixel;
destptr += destformat->bytes_per_pixel;
}
@@ -685,17 +704,28 @@ static void copy_simple_data(CONST BYTE *src, UINT srcpitch, POINT srcsize, C
* using a point filter.
* Works only for ARGB formats with 1 - 4 bytes per pixel.
*/
-static void point_filter_simple_data(CONST BYTE *src, UINT srcpitch, POINT srcsize, CONST PixelFormatDesc *srcformat,
- BYTE *dest, UINT destpitch, POINT destsize, CONST PixelFormatDesc *destformat)
+static void point_filter_simple_data(CONST BYTE *src, UINT srcpitch, POINT srcsize,
+ CONST PixelFormatDesc *srcformat,
+ BYTE *dest, UINT destpitch, POINT destsize,
+ CONST PixelFormatDesc *destformat,
+ D3DCOLOR colorkey)
{
- struct argb_conversion_info conv_info;
- DWORD channels[4];
+ struct argb_conversion_info conv_info, ck_conv_info;
+ DWORD channels[4], pixel;
UINT x, y;
ZeroMemory(channels, sizeof(channels));
init_argb_conversion_info(srcformat, destformat, &conv_info);
+ if(colorkey) {
+ /* color keys are always represented in D3DFMT_A8R8G8B8 format */
+ const PixelFormatDesc *ckformatdesc;
+
+ ckformatdesc = get_format_info(D3DFMT_A8R8G8B8);
+ init_argb_conversion_info(srcformat, ckformatdesc, &ck_conv_info);
+ }
+
for(y = 0;y < destsize.y;y++) {
BYTE *destptr = dest + y * destpitch;
const BYTE *bufptr = src + srcpitch * (y * srcsize.y / destsize.y);
@@ -709,6 +739,14 @@ static void point_filter_simple_data(CONST BYTE *src, UINT srcpitch, POINT sr
/* recombine the components */
if(destformat->type == FORMAT_ARGB) make_argb_color(&conv_info, channels, (DWORD*)destptr);
+ if(colorkey) {
+ get_relevant_argb_components(&ck_conv_info, *(const DWORD*)srcptr, channels);
+ make_argb_color(&ck_conv_info, channels, &pixel);
+ if(pixel == colorkey)
+ /* make this pixel transparent */
+ *(DWORD *)destptr &= ~conv_info.destmask[0];
+ }
+
destptr += destformat->bytes_per_pixel;
}
}
@@ -797,11 +835,13 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(LPDIRECT3DSURFACE9 pDestSurface,
if((dwFilter & 0xF) == D3DX_FILTER_NONE) {
copy_simple_data(pSrcMemory, SrcPitch, srcsize, srcformatdesc,
- lockrect.pBits, lockrect.Pitch, destsize, destformatdesc);
+ lockrect.pBits, lockrect.Pitch, destsize, destformatdesc,
+ Colorkey);
} else /*if((dwFilter & 0xF) == D3DX_FILTER_POINT) */ {
/* always apply a point filter until D3DX_FILTER_LINEAR, D3DX_FILTER_TRIANGLE and D3DX_FILTER_BOX are implemented */
point_filter_simple_data(pSrcMemory, SrcPitch, srcsize, srcformatdesc,
- lockrect.pBits, lockrect.Pitch, destsize, destformatdesc);
+ lockrect.pBits, lockrect.Pitch, destsize, destformatdesc,
+ Colorkey);
}
IDirect3DSurface9_UnlockRect(pDestSurface);
More information about the wine-cvs
mailing list