On Mon, Jul 14, 2008 at 02:51:42AM +0400, Victor Eremin wrote: > > Converter function supports conversion between most of > "unsigned color" argb/xrgb surface formats (like D3DFMT_A8R8G8B8, > D3DFMT_A8R3G3B2, and so on), and between "luminosity" color formats > (D3DFMT_L8, etc), excluding D3DFMT_A16R16G16B16, D3DFMT_A8P8, > D3DFMT_P8 and D3DFMT_A1. > > Conversion from rgba to luminosity (and vice versa) is not currently > implemented. > > The patch removes "Cannot find coverter" FIXMEs from "Ancient Evil" and > "Stranded 2" games. > > Patch also fixes water glitches in "Stranded 2" game.
I've attached my pixel conversion function which uses the table in utils.c. Hope you find it useful although I haven't really polished it.
/* Counts the number of leading zeros in a mask, returns 0 if the mask is zero. */ static unsigned int count_zeros(unsigned int mask) { unsigned int count; if (!mask) return 0; for (count = 0; !(mask & 1); ++count) { mask >>= 1; } return count; } /* Scales a value masked by one mask to another. */ static DWORD convert_channel(DWORD src, DWORD srcmask, DWORD dstmask) { src = src & srcmask; src >>= count_zeros(srcmask); src *= (dstmask >> count_zeros(dstmask)) / (srcmask >> count_zeros(srcmask)); src <<= count_zeros(dstmask); return src; } static DWORD get_mask(DWORD value, DWORD mask) { return (value & mask) >> count_zeros(mask); } static DWORD put_mask(DWORD value, DWORD mask) { return (value << count_zeros(mask)) & mask; } /* MSDN states that the default value is 1 for missing channels; and that * D3DFMT_A8 is the exception where the missing channels are 0. * * I assume 1 means 1 in every bit. */ static DWORD convert_pixel(DWORD srcword, const StaticPixelFormatDesc* srcentry, const StaticPixelFormatDesc* dstentry) { DWORD pixel = 0; if (srcentry->alphaMask && dstentry->alphaMask) pixel |= convert_channel(srcword, srcentry->alphaMask, dstentry->alphaMask); else pixel |= dstentry->alphaMask; if (srcentry->redMask && dstentry->redMask) pixel |= convert_channel(srcword, srcentry->redMask, dstentry->redMask); else pixel |= dstentry->redMask; if (srcentry->greenMask && dstentry->greenMask) pixel |= convert_channel(srcword, srcentry->greenMask, dstentry->greenMask); else pixel |= dstentry->greenMask; if (srcentry->blueMask && dstentry->blueMask) pixel |= convert_channel(srcword, srcentry->blueMask, dstentry->blueMask); else pixel |= dstentry->blueMask; return pixel; } DWORD convert_pixelformat(DWORD pixel, WINED3DFORMAT srcformat, WINED3DFORMAT dstformat) { const StaticPixelFormatDesc* srcentry = getFormatDescEntry(srcformat, NULL, NULL); const StaticPixelFormatDesc* dstentry = getFormatDescEntry(dstformat, NULL, NULL); if (!srcentry) { FIXME("Unsupported pixelformat.\n"); return 0; } if (!dstentry) { FIXME("Unsupported pixelformat.\n"); return 0; } return convert_pixel(pixel, srcentry, dstentry); } static UINT get_pixel(const LPCVOID data, UINT bpp, const RECT* const rect, UINT pitch, UINT x, UINT y) { DWORD pixel = 0; memcpy(&pixel, (char*)data + (rect->top + y) * pitch + (rect->left + x) * bpp, bpp); return pixel; }