Stefan Dösinger : wined3d: Fix IWineGDISurface:: SaveSnapshot.
Alexandre Julliard
julliard at wine.codeweavers.com
Fri May 26 13:55:15 CDT 2006
Module: wine
Branch: refs/heads/master
Commit: 9d5849d9bdf419f5306a1c6c02bce0483ca26e44
URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=9d5849d9bdf419f5306a1c6c02bce0483ca26e44
Author: Stefan Dösinger <stefan at codeweavers.com>
Date: Fri May 26 12:32:52 2006 +0200
wined3d: Fix IWineGDISurface::SaveSnapshot.
---
dlls/wined3d/surface_gdi.c | 124 ++++++++++++++++++++++++++++----------------
1 files changed, 80 insertions(+), 44 deletions(-)
diff --git a/dlls/wined3d/surface_gdi.c b/dlls/wined3d/surface_gdi.c
index c4de656..3b25ff4 100644
--- a/dlls/wined3d/surface_gdi.c
+++ b/dlls/wined3d/surface_gdi.c
@@ -1337,64 +1337,100 @@ IWineGDISurfaceImpl_LoadTexture(IWineD3D
* WINED3D_OK on success
*
*****************************************************************************/
+static int get_shift(DWORD color_mask) {
+ int shift = 0;
+ while (color_mask > 0xFF) {
+ color_mask >>= 1;
+ shift += 1;
+ }
+ while ((color_mask & 0x80) == 0) {
+ color_mask <<= 1;
+ shift -= 1;
+ }
+ return shift;
+}
+
+
HRESULT WINAPI
IWineGDISurfaceImpl_SaveSnapshot(IWineD3DSurface *iface,
const char* filename)
{
FILE* f = NULL;
- UINT i = 0, y = 0;
+ UINT y = 0, x = 0;
IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
- BYTE *textureRow;
- DWORD color;
+ static char *output = NULL;
+ static int size = 0;
+
+ if (This->pow2Width > size) {
+ output = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->pow2Width * 3);
+ size = This->pow2Width;
+ }
+
f = fopen(filename, "w+");
- if (NULL == f)
- {
+ if (NULL == f) {
ERR("opening of %s failed with\n", filename);
return WINED3DERR_INVALIDCALL;
}
- /* Save the dat out to a TGA file because
- * 1: it's an easy raw format,
- * 2: it supports an alpha chanel
- */
- TRACE("(%p) opened %s with format %s\n", This, filename, debug_d3dformat(This->resource.format));
- /* TGA header */
- fputc(0,f);
- fputc(0,f);
- fputc(2,f);
- fputc(0,f);
- fputc(0,f);
- fputc(0,f);
- fputc(0,f);
- fputc(0,f);
- fputc(0,f);
- fputc(0,f);
- fputc(0,f);
- fputc(0,f);
- /* short width*/
- fwrite(&This->currentDesc.Width,2,1,f);
- /* short height */
- fwrite(&This->currentDesc.Height,2,1,f);
- /* format rgba */
- fputc(0x20,f);
- fputc(0x28,f);
- /* raw data */
- /* if the data is upside down if we've fetched it from a back buffer,
- * so it needs flipping again to make it the correct way u
- */
+ fprintf(f, "P6\n%d %d\n255\n", This->pow2Width, This->pow2Height);
- textureRow = This->resource.allocatedMemory;
- for (y = 0 ; y < This->currentDesc.Height; y++) {
- for (i = 0; i < This->currentDesc.Width; i++) {
- color = *((DWORD*)textureRow);
- fputc((color >> 16) & 0xFF, f); /* B */
- fputc((color >> 8) & 0xFF, f); /* G */
- fputc((color >> 0) & 0xFF, f); /* R */
- fputc((color >> 24) & 0xFF, f); /* A */
- textureRow += 4;
+ if (This->resource.format == WINED3DFMT_P8) {
+ unsigned char table[256][3];
+ int i;
+
+ if (This->palette == NULL) {
+ fclose(f);
+ return WINED3DERR_INVALIDCALL;
+ }
+ for (i = 0; i < 256; i++) {
+ table[i][0] = This->palette->palents[i].peRed;
+ table[i][1] = This->palette->palents[i].peGreen;
+ table[i][2] = This->palette->palents[i].peBlue;
+ }
+ for (y = 0; y < This->pow2Height; y++) {
+ unsigned char *src = (unsigned char *) This->resource.allocatedMemory + (y * 1 * IWineD3DSurface_GetPitch(iface));
+ for (x = 0; x < This->pow2Width; x++) {
+ unsigned char color = *src;
+ src += 1;
+
+ output[3 * x + 0] = table[color][0];
+ output[3 * x + 1] = table[color][1];
+ output[3 * x + 2] = table[color][2];
+ }
+ fwrite(output, 3 * This->pow2Width, 1, f);
+ }
+ } else {
+ int red_shift, green_shift, blue_shift, pix_width;
+
+ pix_width = This->bytesPerPixel;
+
+ red_shift = get_shift(get_bitmask_red(This->resource.format));
+ green_shift = get_shift(get_bitmask_green(This->resource.format));
+ blue_shift = get_shift(get_bitmask_blue(This->resource.format));
+
+ for (y = 0; y < This->pow2Height; y++) {
+ unsigned char *src = (unsigned char *) This->resource.allocatedMemory + (y * 1 * IWineD3DSurface_GetPitch(iface));
+ for (x = 0; x < This->pow2Width; x++) {
+ unsigned int color;
+ unsigned int comp;
+ int i;
+
+ color = 0;
+ for (i = 0; i < pix_width; i++) {
+ color |= src[i] << (8 * i);
+ }
+ src += 1 * pix_width;
+
+ comp = color & get_bitmask_red(This->resource.format);
+ output[3 * x + 0] = red_shift > 0 ? comp >> red_shift : comp << -red_shift;
+ comp = color & get_bitmask_green(This->resource.format);
+ output[3 * x + 1] = green_shift > 0 ? comp >> green_shift : comp << -green_shift;
+ comp = color & get_bitmask_blue(This->resource.format);
+ output[3 * x + 2] = blue_shift > 0 ? comp >> blue_shift : comp << -blue_shift;
+ }
+ fwrite(output, 3 * This->pow2Width, 1, f);
}
}
- TRACE("Closing file\n");
fclose(f);
return WINED3D_OK;
}
More information about the wine-cvs
mailing list