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