[PATCH] d3dx9: Add a rudimentary D3DXLoadSurfaceFromMemory implementation (only supports copying an A8R8G8B8 surface to an A8R8G8B8 one)

Tony Wasserka tony.wasserka at freenet.de
Wed Jul 15 09:29:07 CDT 2009


---
 dlls/d3dx9_36/surface.c       |   47 ++++++++++++++++++++++++++++++++++++++--
 dlls/d3dx9_36/tests/texture.c |   10 +++-----
 2 files changed, 48 insertions(+), 9 deletions(-)

diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c
index 0bee7c8..e0aad21 100644
--- a/dlls/d3dx9_36/surface.c
+++ b/dlls/d3dx9_36/surface.c
@@ -350,7 +350,8 @@ HRESULT WINAPI D3DXLoadSurfaceFromResourceW(LPDIRECT3DSURFACE9 pDestSurface,
  *            E_FAIL, if SrcFormat is D3DFMT_UNKNOWN or the dimensions of pSrcRect are invalid
  *
  * NOTES
- *   pSrcRect specifies the dimensions of the source data
+ *   pSrcRect specifies the dimensions of the source data;
+ *   negative values for pSrcRect are allowed as we're only looking at the width and height anyways.
  *
  */
 HRESULT WINAPI D3DXLoadSurfaceFromMemory(LPDIRECT3DSURFACE9 pDestSurface,
@@ -364,11 +365,51 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(LPDIRECT3DSURFACE9 pDestSurface,
                                          DWORD dwFilter,
                                          D3DCOLOR Colorkey)
 {
-    TRACE("stub\n");
+    D3DSURFACE_DESC SurfDesc;
+    D3DLOCKED_RECT LockRect;
+    POINT SrcSize, DestSize;
+    HRESULT hr;
+    UINT x, y;
+    DWORD *pSrcPtr, *pDestPtr;
+    TRACE("(void)\n");
 
     if( !pDestSurface || !pSrcMemory || !pSrcRect ) return D3DERR_INVALIDCALL;
     if(SrcFormat == D3DFMT_UNKNOWN || pSrcRect->left >= pSrcRect->right || pSrcRect->top >= pSrcRect->bottom) return E_FAIL;
-    return E_NOTIMPL;
+
+    IDirect3DSurface9_GetDesc(pDestSurface, &SurfDesc);
+    if(SrcFormat != D3DFMT_A8R8G8B8 || SurfDesc.Format != D3DFMT_A8R8G8B8 || dwFilter != D3DX_FILTER_NONE) return E_NOTIMPL;
+
+    SrcSize.x = pSrcRect->right - pSrcRect->left;
+    SrcSize.y = pSrcRect->bottom - pSrcRect->top;
+    if( !pDestRect ) {
+        DestSize.x = SurfDesc.Width;
+        DestSize.y = SurfDesc.Height;
+    } else {
+        DestSize.x = pDestRect->right - pDestRect->left;
+        DestSize.y = pDestRect->bottom - pDestRect->top;
+    }
+
+    hr = IDirect3DSurface9_LockRect(pDestSurface, &LockRect, pDestRect, 0);
+    if(FAILED(hr)) return D3DXERR_INVALIDDATA;
+
+    pSrcPtr = (DWORD*)pSrcMemory;
+    pDestPtr = LockRect.pBits;
+    for(y = 0;y < DestSize.y;y++) {
+        if(y >= SrcSize.y) break;
+
+        pSrcPtr = (DWORD*)((BYTE*)pSrcMemory + y * SrcPitch);
+        pDestPtr = (DWORD*)((BYTE*)LockRect.pBits + y * LockRect.Pitch);
+        for(x = 0;x < DestSize.x;x++) {
+            if(x >= SrcSize.x) break;
+
+            *pDestPtr = (*pSrcPtr != Colorkey) ? (*pSrcPtr) : 0;
+            pDestPtr++;
+            pSrcPtr++;
+        }
+    }
+
+    IDirect3DSurface9_UnlockRect(pDestSurface);
+    return D3D_OK;
 }
 
 /************************************************************
diff --git a/dlls/d3dx9_36/tests/texture.c b/dlls/d3dx9_36/tests/texture.c
index 7f10e2d..2a717cb 100644
--- a/dlls/d3dx9_36/tests/texture.c
+++ b/dlls/d3dx9_36/tests/texture.c
@@ -303,13 +303,11 @@ static void test_D3DXLoadSurface(IDirect3DDevice9 *device)
     /* D3DXLoadSurfaceFromMemory */
     SetRect(&rect, 0, 0, 2, 2);
 
-    todo_wine {
-        hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata, D3DFMT_A8R8G8B8, sizeof(pixdata), NULL, &rect, D3DX_DEFAULT, 0);
-        ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
+    hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata, D3DFMT_A8R8G8B8, sizeof(pixdata), NULL, &rect, D3DX_FILTER_NONE, 0);
+    ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
 
-        hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata, D3DFMT_A8R8G8B8, 0, NULL, &rect, D3DX_DEFAULT, 0);
-        ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
-    }
+    hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata, D3DFMT_A8R8G8B8, 0, NULL, &rect, D3DX_FILTER_NONE, 0);
+    ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
 
     hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, NULL, D3DFMT_A8R8G8B8, sizeof(pixdata), NULL, &rect, D3DX_DEFAULT, 0);
     ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
-- 
1.6.0.2


--------------040600000302010909050300--



More information about the wine-patches mailing list