[PATCH 1/5] ddraw/tests: Add some clipper tests.
Henri Verbeet
hverbeet at codeweavers.com
Wed Jan 4 16:34:52 CST 2012
---
dlls/ddraw/tests/ddraw1.c | 217 +++++++++++++++++++++++++++++++++++++++++++++
dlls/ddraw/tests/ddraw2.c | 217 +++++++++++++++++++++++++++++++++++++++++++++
dlls/ddraw/tests/ddraw4.c | 216 ++++++++++++++++++++++++++++++++++++++++++++
dlls/ddraw/tests/ddraw7.c | 216 ++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 866 insertions(+), 0 deletions(-)
diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c
index 54a1569..ebcb4e6 100644
--- a/dlls/ddraw/tests/ddraw1.c
+++ b/dlls/ddraw/tests/ddraw1.c
@@ -19,6 +19,41 @@
#include "wine/test.h"
#include "d3d.h"
+static BOOL compare_color(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
+{
+ if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
+ c1 >>= 8; c2 >>= 8;
+ if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
+ c1 >>= 8; c2 >>= 8;
+ if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
+ c1 >>= 8; c2 >>= 8;
+ if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
+ return TRUE;
+}
+
+static D3DCOLOR get_surface_color(IDirectDrawSurface *surface, UINT x, UINT y)
+{
+ RECT rect = {x, y, x + 1, y + 1};
+ DDSURFACEDESC surface_desc;
+ D3DCOLOR color;
+ HRESULT hr;
+
+ memset(&surface_desc, 0, sizeof(surface_desc));
+ surface_desc.dwSize = sizeof(surface_desc);
+
+ hr = IDirectDrawSurface_Lock(surface, &rect, &surface_desc, DDLOCK_READONLY | DDLOCK_WAIT, NULL);
+ ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
+ if (FAILED(hr))
+ return 0xdeadbeef;
+
+ color = *((DWORD *)surface_desc.lpSurface) & 0x00ffffff;
+
+ hr = IDirectDrawSurface_Unlock(surface, NULL);
+ ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
+
+ return color;
+}
+
static IDirectDraw *create_ddraw(void)
{
IDirectDraw *ddraw;
@@ -124,7 +159,189 @@ static void test_coop_level_create_device_window(void)
DestroyWindow(focus_window);
}
+static void test_clipper_blt(void)
+{
+ IDirectDrawSurface *src_surface, *dst_surface;
+ RECT client_rect, src_rect, *rect;
+ IDirectDrawClipper *clipper;
+ DDSURFACEDESC surface_desc;
+ unsigned int i, j, x, y;
+ IDirectDraw *ddraw;
+ RGNDATA *rgn_data;
+ D3DCOLOR color;
+ HRGN r1, r2;
+ HWND window;
+ DDBLTFX fx;
+ HRESULT hr;
+ DWORD ret;
+
+ static const D3DCOLOR expected1[] =
+ {
+ 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
+ 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
+ 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
+ };
+ static const D3DCOLOR expected2[] =
+ {
+ 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
+ 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
+ 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
+ };
+
+ window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
+ 10, 10, 640, 480, 0, 0, 0, 0);
+ ShowWindow(window, SW_SHOW);
+ if (!(ddraw = create_ddraw()))
+ {
+ skip("Failed to create a ddraw object, skipping test.\n");
+ DestroyWindow(window);
+ return;
+ }
+
+ ret = GetClientRect(window, &client_rect);
+ ok(ret, "Failed to get client rect.\n");
+ ret = MapWindowPoints(window, NULL, (POINT *)&client_rect, 2);
+ ok(ret, "Failed to map client rect.\n");
+
+ hr = IDirectDraw_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
+ ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
+
+ hr = IDirectDraw_CreateClipper(ddraw, 0, &clipper, NULL);
+ ok(SUCCEEDED(hr), "Failed to create clipper, hr %#x.\n", hr);
+ hr = IDirectDrawClipper_SetHWnd(clipper, 0, window);
+ ok(SUCCEEDED(hr), "Failed to set clipper window, hr %#x.\n", hr);
+ hr = IDirectDrawClipper_GetClipList(clipper, NULL, NULL, &ret);
+ ok(SUCCEEDED(hr), "Failed to get clip list size, hr %#x.\n", hr);
+ rgn_data = HeapAlloc(GetProcessHeap(), 0, ret);
+ hr = IDirectDrawClipper_GetClipList(clipper, NULL, rgn_data, &ret);
+ ok(SUCCEEDED(hr), "Failed to get clip list, hr %#x.\n", hr);
+ ok(rgn_data->rdh.dwSize == sizeof(rgn_data->rdh), "Got unexpected structure size %#x.\n", rgn_data->rdh.dwSize);
+ ok(rgn_data->rdh.iType == RDH_RECTANGLES, "Got unexpected type %#x.\n", rgn_data->rdh.iType);
+ ok(rgn_data->rdh.nCount == 1, "Got unexpected count %u.\n", rgn_data->rdh.nCount);
+ ok(rgn_data->rdh.nRgnSize == 16 || broken(rgn_data->rdh.nRgnSize == 168 /* NT4 */),
+ "Got unexpected region size %u.\n", rgn_data->rdh.nRgnSize);
+ todo_wine ok(EqualRect(&rgn_data->rdh.rcBound, &client_rect),
+ "Got unexpected bounding rect {%d, %d, %d, %d}, expected {%d, %d, %d, %d}.\n",
+ rgn_data->rdh.rcBound.left, rgn_data->rdh.rcBound.top,
+ rgn_data->rdh.rcBound.right, rgn_data->rdh.rcBound.bottom,
+ client_rect.left, client_rect.top, client_rect.right, client_rect.bottom);
+ rect = (RECT *)&rgn_data->Buffer[0];
+ todo_wine ok(EqualRect(rect, &client_rect),
+ "Got unexpected clip rect {%d, %d, %d, %d}, expected {%d, %d, %d, %d}.\n",
+ rect->left, rect->top, rect->right, rect->bottom,
+ client_rect.left, client_rect.top, client_rect.right, client_rect.bottom);
+ HeapFree(GetProcessHeap(), 0, rgn_data);
+
+ r1 = CreateRectRgn(0, 0, 320, 240);
+ ok(!!r1, "Failed to create region.\n");
+ r2 = CreateRectRgn(320, 240, 640, 480);
+ ok(!!r2, "Failed to create region.\n");
+ CombineRgn(r1, r1, r2, RGN_OR);
+ ret = GetRegionData(r1, 0, NULL);
+ rgn_data = HeapAlloc(GetProcessHeap(), 0, ret);
+ ret = GetRegionData(r1, ret, rgn_data);
+ ok(!!ret, "Failed to get region data.\n");
+
+ DeleteObject(r2);
+ DeleteObject(r1);
+
+ hr = IDirectDrawClipper_SetClipList(clipper, rgn_data, 0);
+ todo_wine ok(hr == DDERR_CLIPPERISUSINGHWND, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawClipper_SetHWnd(clipper, 0, NULL);
+ ok(SUCCEEDED(hr), "Failed to set clipper window, hr %#x.\n", hr);
+ hr = IDirectDrawClipper_SetClipList(clipper, rgn_data, 0);
+ ok(SUCCEEDED(hr), "Failed to set clip list, hr %#x.\n", hr);
+
+ HeapFree(GetProcessHeap(), 0, rgn_data);
+
+ memset(&surface_desc, 0, sizeof(surface_desc));
+ surface_desc.dwSize = sizeof(surface_desc);
+ surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
+ surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
+ surface_desc.dwWidth = 640;
+ surface_desc.dwHeight = 480;
+ surface_desc.ddpfPixelFormat.dwSize = sizeof(surface_desc.ddpfPixelFormat);
+ surface_desc.ddpfPixelFormat.dwFlags = DDPF_RGB;
+ U1(surface_desc.ddpfPixelFormat).dwRGBBitCount = 32;
+ U2(surface_desc.ddpfPixelFormat).dwRBitMask = 0x00ff0000;
+ U3(surface_desc.ddpfPixelFormat).dwGBitMask = 0x0000ff00;
+ U4(surface_desc.ddpfPixelFormat).dwBBitMask = 0x000000ff;
+
+ hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &src_surface, NULL);
+ ok(SUCCEEDED(hr), "Failed to create source surface, hr %#x.\n", hr);
+ hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &dst_surface, NULL);
+ ok(SUCCEEDED(hr), "Failed to create destination surface, hr %#x.\n", hr);
+
+ memset(&fx, 0, sizeof(fx));
+ fx.dwSize = sizeof(fx);
+ hr = IDirectDrawSurface_Blt(src_surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
+ ok(SUCCEEDED(hr), "Failed to clear source surface, hr %#x.\n", hr);
+ hr = IDirectDrawSurface_Blt(dst_surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
+ ok(SUCCEEDED(hr), "Failed to clear destination surface, hr %#x.\n", hr);
+
+ hr = IDirectDrawSurface_Lock(src_surface, NULL, &surface_desc, 0, NULL);
+ ok(SUCCEEDED(hr), "Failed to lock source surface, hr %#x.\n", hr);
+ ((DWORD *)surface_desc.lpSurface)[0] = 0xff0000ff;
+ ((DWORD *)surface_desc.lpSurface)[1] = 0xff00ff00;
+ ((DWORD *)surface_desc.lpSurface)[2] = 0xffff0000;
+ ((DWORD *)surface_desc.lpSurface)[3] = 0xffffffff;
+ hr = IDirectDrawSurface_Unlock(src_surface, NULL);
+ ok(SUCCEEDED(hr), "Failed to unlock source surface, hr %#x.\n", hr);
+
+ hr = IDirectDrawSurface_SetClipper(dst_surface, clipper);
+ ok(SUCCEEDED(hr), "Failed to set clipper, hr %#x.\n", hr);
+
+ SetRect(&src_rect, 0, 0, 4, 1);
+ hr = IDirectDrawSurface_Blt(dst_surface, NULL, src_surface, &src_rect, DDBLT_WAIT, NULL);
+ todo_wine ok(SUCCEEDED(hr), "Failed to blit, hr %#x.\n", hr);
+ for (i = 0; i < 4; ++i)
+ {
+ for (j = 0; j < 4; ++j)
+ {
+ x = 80 * ((2 * j) + 1);
+ y = 60 * ((2 * i) + 1);
+ color = get_surface_color(dst_surface, x, y);
+ if ((i < 2 && j < 2) || (i >= 2 && j >= 2))
+ todo_wine ok(compare_color(color, expected1[i * 4 + j], 1),
+ "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected1[i * 4 + j], x, y, color);
+ else
+ ok(compare_color(color, expected1[i * 4 + j], 1),
+ "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected1[i * 4 + j], x, y, color);
+ }
+ }
+
+ U5(fx).dwFillColor = 0xff0000ff;
+ hr = IDirectDrawSurface_Blt(dst_surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
+ todo_wine ok(SUCCEEDED(hr), "Failed to clear destination surface, hr %#x.\n", hr);
+ for (i = 0; i < 4; ++i)
+ {
+ for (j = 0; j < 4; ++j)
+ {
+ x = 80 * ((2 * j) + 1);
+ y = 60 * ((2 * i) + 1);
+ color = get_surface_color(dst_surface, x, y);
+ if ((i < 2 && j < 2) || (i >= 2 && j >= 2))
+ todo_wine ok(compare_color(color, expected2[i * 4 + j], 1),
+ "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected2[i * 4 + j], x, y, color);
+ else
+ ok(compare_color(color, expected2[i * 4 + j], 1),
+ "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected2[i * 4 + j], x, y, color);
+ }
+ }
+
+ hr = IDirectDrawSurface_BltFast(dst_surface, 0, 0, src_surface, NULL, DDBLTFAST_WAIT);
+ todo_wine ok(hr == DDERR_BLTFASTCANTCLIP || broken(hr == E_NOTIMPL /* NT4 */), "Got unexpected hr %#x.\n", hr);
+
+ IDirectDrawSurface_Release(dst_surface);
+ IDirectDrawSurface_Release(src_surface);
+ IDirectDrawClipper_Release(clipper);
+ IDirectDraw_Release(ddraw);
+}
+
START_TEST(ddraw1)
{
test_coop_level_create_device_window();
+ test_clipper_blt();
}
diff --git a/dlls/ddraw/tests/ddraw2.c b/dlls/ddraw/tests/ddraw2.c
index 1af341e..64595c8 100644
--- a/dlls/ddraw/tests/ddraw2.c
+++ b/dlls/ddraw/tests/ddraw2.c
@@ -19,6 +19,41 @@
#include "wine/test.h"
#include "d3d.h"
+static BOOL compare_color(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
+{
+ if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
+ c1 >>= 8; c2 >>= 8;
+ if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
+ c1 >>= 8; c2 >>= 8;
+ if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
+ c1 >>= 8; c2 >>= 8;
+ if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
+ return TRUE;
+}
+
+static D3DCOLOR get_surface_color(IDirectDrawSurface *surface, UINT x, UINT y)
+{
+ RECT rect = {x, y, x + 1, y + 1};
+ DDSURFACEDESC surface_desc;
+ D3DCOLOR color;
+ HRESULT hr;
+
+ memset(&surface_desc, 0, sizeof(surface_desc));
+ surface_desc.dwSize = sizeof(surface_desc);
+
+ hr = IDirectDrawSurface_Lock(surface, &rect, &surface_desc, DDLOCK_READONLY | DDLOCK_WAIT, NULL);
+ ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
+ if (FAILED(hr))
+ return 0xdeadbeef;
+
+ color = *((DWORD *)surface_desc.lpSurface) & 0x00ffffff;
+
+ hr = IDirectDrawSurface_Unlock(surface, NULL);
+ ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
+
+ return color;
+}
+
static IDirectDraw2 *create_ddraw(void)
{
IDirectDraw2 *ddraw2;
@@ -131,7 +166,189 @@ static void test_coop_level_create_device_window(void)
DestroyWindow(focus_window);
}
+static void test_clipper_blt(void)
+{
+ IDirectDrawSurface *src_surface, *dst_surface;
+ RECT client_rect, src_rect, *rect;
+ IDirectDrawClipper *clipper;
+ DDSURFACEDESC surface_desc;
+ unsigned int i, j, x, y;
+ IDirectDraw2 *ddraw;
+ RGNDATA *rgn_data;
+ D3DCOLOR color;
+ HRGN r1, r2;
+ HWND window;
+ DDBLTFX fx;
+ HRESULT hr;
+ DWORD ret;
+
+ static const D3DCOLOR expected1[] =
+ {
+ 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
+ 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
+ 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
+ };
+ static const D3DCOLOR expected2[] =
+ {
+ 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
+ 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
+ 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
+ };
+
+ window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
+ 10, 10, 640, 480, 0, 0, 0, 0);
+ ShowWindow(window, SW_SHOW);
+ if (!(ddraw = create_ddraw()))
+ {
+ skip("Failed to create a ddraw object, skipping test.\n");
+ DestroyWindow(window);
+ return;
+ }
+
+ ret = GetClientRect(window, &client_rect);
+ ok(ret, "Failed to get client rect.\n");
+ ret = MapWindowPoints(window, NULL, (POINT *)&client_rect, 2);
+ ok(ret, "Failed to map client rect.\n");
+
+ hr = IDirectDraw2_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
+ ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
+
+ hr = IDirectDraw2_CreateClipper(ddraw, 0, &clipper, NULL);
+ ok(SUCCEEDED(hr), "Failed to create clipper, hr %#x.\n", hr);
+ hr = IDirectDrawClipper_SetHWnd(clipper, 0, window);
+ ok(SUCCEEDED(hr), "Failed to set clipper window, hr %#x.\n", hr);
+ hr = IDirectDrawClipper_GetClipList(clipper, NULL, NULL, &ret);
+ ok(SUCCEEDED(hr), "Failed to get clip list size, hr %#x.\n", hr);
+ rgn_data = HeapAlloc(GetProcessHeap(), 0, ret);
+ hr = IDirectDrawClipper_GetClipList(clipper, NULL, rgn_data, &ret);
+ ok(SUCCEEDED(hr), "Failed to get clip list, hr %#x.\n", hr);
+ ok(rgn_data->rdh.dwSize == sizeof(rgn_data->rdh), "Got unexpected structure size %#x.\n", rgn_data->rdh.dwSize);
+ ok(rgn_data->rdh.iType == RDH_RECTANGLES, "Got unexpected type %#x.\n", rgn_data->rdh.iType);
+ ok(rgn_data->rdh.nCount == 1, "Got unexpected count %u.\n", rgn_data->rdh.nCount);
+ ok(rgn_data->rdh.nRgnSize == 16 || broken(rgn_data->rdh.nRgnSize == 168 /* NT4 */),
+ "Got unexpected region size %u.\n", rgn_data->rdh.nRgnSize);
+ todo_wine ok(EqualRect(&rgn_data->rdh.rcBound, &client_rect),
+ "Got unexpected bounding rect {%d, %d, %d, %d}, expected {%d, %d, %d, %d}.\n",
+ rgn_data->rdh.rcBound.left, rgn_data->rdh.rcBound.top,
+ rgn_data->rdh.rcBound.right, rgn_data->rdh.rcBound.bottom,
+ client_rect.left, client_rect.top, client_rect.right, client_rect.bottom);
+ rect = (RECT *)&rgn_data->Buffer[0];
+ todo_wine ok(EqualRect(rect, &client_rect),
+ "Got unexpected clip rect {%d, %d, %d, %d}, expected {%d, %d, %d, %d}.\n",
+ rect->left, rect->top, rect->right, rect->bottom,
+ client_rect.left, client_rect.top, client_rect.right, client_rect.bottom);
+ HeapFree(GetProcessHeap(), 0, rgn_data);
+
+ r1 = CreateRectRgn(0, 0, 320, 240);
+ ok(!!r1, "Failed to create region.\n");
+ r2 = CreateRectRgn(320, 240, 640, 480);
+ ok(!!r2, "Failed to create region.\n");
+ CombineRgn(r1, r1, r2, RGN_OR);
+ ret = GetRegionData(r1, 0, NULL);
+ rgn_data = HeapAlloc(GetProcessHeap(), 0, ret);
+ ret = GetRegionData(r1, ret, rgn_data);
+ ok(!!ret, "Failed to get region data.\n");
+
+ DeleteObject(r2);
+ DeleteObject(r1);
+
+ hr = IDirectDrawClipper_SetClipList(clipper, rgn_data, 0);
+ todo_wine ok(hr == DDERR_CLIPPERISUSINGHWND, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawClipper_SetHWnd(clipper, 0, NULL);
+ ok(SUCCEEDED(hr), "Failed to set clipper window, hr %#x.\n", hr);
+ hr = IDirectDrawClipper_SetClipList(clipper, rgn_data, 0);
+ ok(SUCCEEDED(hr), "Failed to set clip list, hr %#x.\n", hr);
+
+ HeapFree(GetProcessHeap(), 0, rgn_data);
+
+ memset(&surface_desc, 0, sizeof(surface_desc));
+ surface_desc.dwSize = sizeof(surface_desc);
+ surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
+ surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
+ surface_desc.dwWidth = 640;
+ surface_desc.dwHeight = 480;
+ surface_desc.ddpfPixelFormat.dwSize = sizeof(surface_desc.ddpfPixelFormat);
+ surface_desc.ddpfPixelFormat.dwFlags = DDPF_RGB;
+ U1(surface_desc.ddpfPixelFormat).dwRGBBitCount = 32;
+ U2(surface_desc.ddpfPixelFormat).dwRBitMask = 0x00ff0000;
+ U3(surface_desc.ddpfPixelFormat).dwGBitMask = 0x0000ff00;
+ U4(surface_desc.ddpfPixelFormat).dwBBitMask = 0x000000ff;
+
+ hr = IDirectDraw2_CreateSurface(ddraw, &surface_desc, &src_surface, NULL);
+ ok(SUCCEEDED(hr), "Failed to create source surface, hr %#x.\n", hr);
+ hr = IDirectDraw2_CreateSurface(ddraw, &surface_desc, &dst_surface, NULL);
+ ok(SUCCEEDED(hr), "Failed to create destination surface, hr %#x.\n", hr);
+
+ memset(&fx, 0, sizeof(fx));
+ fx.dwSize = sizeof(fx);
+ hr = IDirectDrawSurface_Blt(src_surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
+ ok(SUCCEEDED(hr), "Failed to clear source surface, hr %#x.\n", hr);
+ hr = IDirectDrawSurface_Blt(dst_surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
+ ok(SUCCEEDED(hr), "Failed to clear destination surface, hr %#x.\n", hr);
+
+ hr = IDirectDrawSurface_Lock(src_surface, NULL, &surface_desc, 0, NULL);
+ ok(SUCCEEDED(hr), "Failed to lock source surface, hr %#x.\n", hr);
+ ((DWORD *)surface_desc.lpSurface)[0] = 0xff0000ff;
+ ((DWORD *)surface_desc.lpSurface)[1] = 0xff00ff00;
+ ((DWORD *)surface_desc.lpSurface)[2] = 0xffff0000;
+ ((DWORD *)surface_desc.lpSurface)[3] = 0xffffffff;
+ hr = IDirectDrawSurface_Unlock(src_surface, NULL);
+ ok(SUCCEEDED(hr), "Failed to unlock source surface, hr %#x.\n", hr);
+
+ hr = IDirectDrawSurface_SetClipper(dst_surface, clipper);
+ ok(SUCCEEDED(hr), "Failed to set clipper, hr %#x.\n", hr);
+
+ SetRect(&src_rect, 0, 0, 4, 1);
+ hr = IDirectDrawSurface_Blt(dst_surface, NULL, src_surface, &src_rect, DDBLT_WAIT, NULL);
+ todo_wine ok(SUCCEEDED(hr), "Failed to blit, hr %#x.\n", hr);
+ for (i = 0; i < 4; ++i)
+ {
+ for (j = 0; j < 4; ++j)
+ {
+ x = 80 * ((2 * j) + 1);
+ y = 60 * ((2 * i) + 1);
+ color = get_surface_color(dst_surface, x, y);
+ if ((i < 2 && j < 2) || (i >= 2 && j >= 2))
+ todo_wine ok(compare_color(color, expected1[i * 4 + j], 1),
+ "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected1[i * 4 + j], x, y, color);
+ else
+ ok(compare_color(color, expected1[i * 4 + j], 1),
+ "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected1[i * 4 + j], x, y, color);
+ }
+ }
+
+ U5(fx).dwFillColor = 0xff0000ff;
+ hr = IDirectDrawSurface_Blt(dst_surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
+ todo_wine ok(SUCCEEDED(hr), "Failed to clear destination surface, hr %#x.\n", hr);
+ for (i = 0; i < 4; ++i)
+ {
+ for (j = 0; j < 4; ++j)
+ {
+ x = 80 * ((2 * j) + 1);
+ y = 60 * ((2 * i) + 1);
+ color = get_surface_color(dst_surface, x, y);
+ if ((i < 2 && j < 2) || (i >= 2 && j >= 2))
+ todo_wine ok(compare_color(color, expected2[i * 4 + j], 1),
+ "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected2[i * 4 + j], x, y, color);
+ else
+ ok(compare_color(color, expected2[i * 4 + j], 1),
+ "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected2[i * 4 + j], x, y, color);
+ }
+ }
+
+ hr = IDirectDrawSurface_BltFast(dst_surface, 0, 0, src_surface, NULL, DDBLTFAST_WAIT);
+ todo_wine ok(hr == DDERR_BLTFASTCANTCLIP || broken(hr == E_NOTIMPL /* NT4 */), "Got unexpected hr %#x.\n", hr);
+
+ IDirectDrawSurface_Release(dst_surface);
+ IDirectDrawSurface_Release(src_surface);
+ IDirectDrawClipper_Release(clipper);
+ IDirectDraw2_Release(ddraw);
+}
+
START_TEST(ddraw2)
{
test_coop_level_create_device_window();
+ test_clipper_blt();
}
diff --git a/dlls/ddraw/tests/ddraw4.c b/dlls/ddraw/tests/ddraw4.c
index 680c6ac..184ce54 100644
--- a/dlls/ddraw/tests/ddraw4.c
+++ b/dlls/ddraw/tests/ddraw4.c
@@ -54,6 +54,41 @@ static BOOL compare_vec4(struct vec4 *vec, float x, float y, float z, float w, u
&& compare_float(vec->w, w, ulps);
}
+static BOOL compare_color(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
+{
+ if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
+ c1 >>= 8; c2 >>= 8;
+ if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
+ c1 >>= 8; c2 >>= 8;
+ if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
+ c1 >>= 8; c2 >>= 8;
+ if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
+ return TRUE;
+}
+
+static D3DCOLOR get_surface_color(IDirectDrawSurface4 *surface, UINT x, UINT y)
+{
+ RECT rect = {x, y, x + 1, y + 1};
+ DDSURFACEDESC2 surface_desc;
+ D3DCOLOR color;
+ HRESULT hr;
+
+ memset(&surface_desc, 0, sizeof(surface_desc));
+ surface_desc.dwSize = sizeof(surface_desc);
+
+ hr = IDirectDrawSurface4_Lock(surface, &rect, &surface_desc, DDLOCK_READONLY | DDLOCK_WAIT, NULL);
+ ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
+ if (FAILED(hr))
+ return 0xdeadbeef;
+
+ color = *((DWORD *)surface_desc.lpSurface) & 0x00ffffff;
+
+ hr = IDirectDrawSurface4_Unlock(surface, &rect);
+ ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
+
+ return color;
+}
+
static IDirectDraw4 *create_ddraw(void)
{
IDirectDraw4 *ddraw4;
@@ -427,8 +462,189 @@ static void test_coop_level_create_device_window(void)
DestroyWindow(focus_window);
}
+static void test_clipper_blt(void)
+{
+ IDirectDrawSurface4 *src_surface, *dst_surface;
+ RECT client_rect, src_rect, *rect;
+ IDirectDrawClipper *clipper;
+ DDSURFACEDESC2 surface_desc;
+ unsigned int i, j, x, y;
+ IDirectDraw4 *ddraw;
+ RGNDATA *rgn_data;
+ D3DCOLOR color;
+ HRGN r1, r2;
+ HWND window;
+ DDBLTFX fx;
+ HRESULT hr;
+ DWORD ret;
+
+ static const D3DCOLOR expected1[] =
+ {
+ 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
+ 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
+ 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
+ };
+ static const D3DCOLOR expected2[] =
+ {
+ 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
+ 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
+ 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
+ };
+
+ window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
+ 10, 10, 640, 480, 0, 0, 0, 0);
+ ShowWindow(window, SW_SHOW);
+ if (!(ddraw = create_ddraw()))
+ {
+ skip("Failed to create a ddraw object, skipping test.\n");
+ DestroyWindow(window);
+ return;
+ }
+
+ ret = GetClientRect(window, &client_rect);
+ ok(ret, "Failed to get client rect.\n");
+ ret = MapWindowPoints(window, NULL, (POINT *)&client_rect, 2);
+ ok(ret, "Failed to map client rect.\n");
+
+ hr = IDirectDraw4_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
+ ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
+
+ hr = IDirectDraw4_CreateClipper(ddraw, 0, &clipper, NULL);
+ ok(SUCCEEDED(hr), "Failed to create clipper, hr %#x.\n", hr);
+ hr = IDirectDrawClipper_SetHWnd(clipper, 0, window);
+ ok(SUCCEEDED(hr), "Failed to set clipper window, hr %#x.\n", hr);
+ hr = IDirectDrawClipper_GetClipList(clipper, NULL, NULL, &ret);
+ ok(SUCCEEDED(hr), "Failed to get clip list size, hr %#x.\n", hr);
+ rgn_data = HeapAlloc(GetProcessHeap(), 0, ret);
+ hr = IDirectDrawClipper_GetClipList(clipper, NULL, rgn_data, &ret);
+ ok(SUCCEEDED(hr), "Failed to get clip list, hr %#x.\n", hr);
+ ok(rgn_data->rdh.dwSize == sizeof(rgn_data->rdh), "Got unexpected structure size %#x.\n", rgn_data->rdh.dwSize);
+ ok(rgn_data->rdh.iType == RDH_RECTANGLES, "Got unexpected type %#x.\n", rgn_data->rdh.iType);
+ ok(rgn_data->rdh.nCount == 1, "Got unexpected count %u.\n", rgn_data->rdh.nCount);
+ ok(rgn_data->rdh.nRgnSize == 16, "Got unexpected region size %u.\n", rgn_data->rdh.nRgnSize);
+ todo_wine ok(EqualRect(&rgn_data->rdh.rcBound, &client_rect),
+ "Got unexpected bounding rect {%d, %d, %d, %d}, expected {%d, %d, %d, %d}.\n",
+ rgn_data->rdh.rcBound.left, rgn_data->rdh.rcBound.top,
+ rgn_data->rdh.rcBound.right, rgn_data->rdh.rcBound.bottom,
+ client_rect.left, client_rect.top, client_rect.right, client_rect.bottom);
+ rect = (RECT *)&rgn_data->Buffer[0];
+ todo_wine ok(EqualRect(rect, &client_rect),
+ "Got unexpected clip rect {%d, %d, %d, %d}, expected {%d, %d, %d, %d}.\n",
+ rect->left, rect->top, rect->right, rect->bottom,
+ client_rect.left, client_rect.top, client_rect.right, client_rect.bottom);
+ HeapFree(GetProcessHeap(), 0, rgn_data);
+
+ r1 = CreateRectRgn(0, 0, 320, 240);
+ ok(!!r1, "Failed to create region.\n");
+ r2 = CreateRectRgn(320, 240, 640, 480);
+ ok(!!r2, "Failed to create region.\n");
+ CombineRgn(r1, r1, r2, RGN_OR);
+ ret = GetRegionData(r1, 0, NULL);
+ rgn_data = HeapAlloc(GetProcessHeap(), 0, ret);
+ ret = GetRegionData(r1, ret, rgn_data);
+ ok(!!ret, "Failed to get region data.\n");
+
+ DeleteObject(r2);
+ DeleteObject(r1);
+
+ hr = IDirectDrawClipper_SetClipList(clipper, rgn_data, 0);
+ todo_wine ok(hr == DDERR_CLIPPERISUSINGHWND, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawClipper_SetHWnd(clipper, 0, NULL);
+ ok(SUCCEEDED(hr), "Failed to set clipper window, hr %#x.\n", hr);
+ hr = IDirectDrawClipper_SetClipList(clipper, rgn_data, 0);
+ ok(SUCCEEDED(hr), "Failed to set clip list, hr %#x.\n", hr);
+
+ HeapFree(GetProcessHeap(), 0, rgn_data);
+
+ memset(&surface_desc, 0, sizeof(surface_desc));
+ surface_desc.dwSize = sizeof(surface_desc);
+ surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
+ surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
+ surface_desc.dwWidth = 640;
+ surface_desc.dwHeight = 480;
+ surface_desc.ddpfPixelFormat.dwSize = sizeof(surface_desc.ddpfPixelFormat);
+ surface_desc.ddpfPixelFormat.dwFlags = DDPF_RGB;
+ U1(surface_desc.ddpfPixelFormat).dwRGBBitCount = 32;
+ U2(surface_desc.ddpfPixelFormat).dwRBitMask = 0x00ff0000;
+ U3(surface_desc.ddpfPixelFormat).dwGBitMask = 0x0000ff00;
+ U4(surface_desc.ddpfPixelFormat).dwBBitMask = 0x000000ff;
+
+ hr = IDirectDraw4_CreateSurface(ddraw, &surface_desc, &src_surface, NULL);
+ ok(SUCCEEDED(hr), "Failed to create source surface, hr %#x.\n", hr);
+ hr = IDirectDraw4_CreateSurface(ddraw, &surface_desc, &dst_surface, NULL);
+ ok(SUCCEEDED(hr), "Failed to create destination surface, hr %#x.\n", hr);
+
+ memset(&fx, 0, sizeof(fx));
+ fx.dwSize = sizeof(fx);
+ hr = IDirectDrawSurface4_Blt(src_surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
+ ok(SUCCEEDED(hr), "Failed to clear source surface, hr %#x.\n", hr);
+ hr = IDirectDrawSurface4_Blt(dst_surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
+ ok(SUCCEEDED(hr), "Failed to clear destination surface, hr %#x.\n", hr);
+
+ hr = IDirectDrawSurface4_Lock(src_surface, NULL, &surface_desc, 0, NULL);
+ ok(SUCCEEDED(hr), "Failed to lock source surface, hr %#x.\n", hr);
+ ((DWORD *)surface_desc.lpSurface)[0] = 0xff0000ff;
+ ((DWORD *)surface_desc.lpSurface)[1] = 0xff00ff00;
+ ((DWORD *)surface_desc.lpSurface)[2] = 0xffff0000;
+ ((DWORD *)surface_desc.lpSurface)[3] = 0xffffffff;
+ hr = IDirectDrawSurface4_Unlock(src_surface, NULL);
+ ok(SUCCEEDED(hr), "Failed to unlock source surface, hr %#x.\n", hr);
+
+ hr = IDirectDrawSurface4_SetClipper(dst_surface, clipper);
+ ok(SUCCEEDED(hr), "Failed to set clipper, hr %#x.\n", hr);
+
+ SetRect(&src_rect, 0, 0, 4, 1);
+ hr = IDirectDrawSurface4_Blt(dst_surface, NULL, src_surface, &src_rect, DDBLT_WAIT, NULL);
+ todo_wine ok(SUCCEEDED(hr), "Failed to blit, hr %#x.\n", hr);
+ for (i = 0; i < 4; ++i)
+ {
+ for (j = 0; j < 4; ++j)
+ {
+ x = 80 * ((2 * j) + 1);
+ y = 60 * ((2 * i) + 1);
+ color = get_surface_color(dst_surface, x, y);
+ if ((i < 2 && j < 2) || (i >= 2 && j >= 2))
+ todo_wine ok(compare_color(color, expected1[i * 4 + j], 1),
+ "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected1[i * 4 + j], x, y, color);
+ else
+ ok(compare_color(color, expected1[i * 4 + j], 1),
+ "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected1[i * 4 + j], x, y, color);
+ }
+ }
+
+ U5(fx).dwFillColor = 0xff0000ff;
+ hr = IDirectDrawSurface4_Blt(dst_surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
+ todo_wine ok(SUCCEEDED(hr), "Failed to clear destination surface, hr %#x.\n", hr);
+ for (i = 0; i < 4; ++i)
+ {
+ for (j = 0; j < 4; ++j)
+ {
+ x = 80 * ((2 * j) + 1);
+ y = 60 * ((2 * i) + 1);
+ color = get_surface_color(dst_surface, x, y);
+ if ((i < 2 && j < 2) || (i >= 2 && j >= 2))
+ todo_wine ok(compare_color(color, expected2[i * 4 + j], 1),
+ "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected2[i * 4 + j], x, y, color);
+ else
+ ok(compare_color(color, expected2[i * 4 + j], 1),
+ "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected2[i * 4 + j], x, y, color);
+ }
+ }
+
+ hr = IDirectDrawSurface4_BltFast(dst_surface, 0, 0, src_surface, NULL, DDBLTFAST_WAIT);
+ todo_wine ok(hr == DDERR_BLTFASTCANTCLIP, "Got unexpected hr %#x.\n", hr);
+
+ IDirectDrawSurface4_Release(dst_surface);
+ IDirectDrawSurface4_Release(src_surface);
+ IDirectDrawClipper_Release(clipper);
+ IDirectDraw4_Release(ddraw);
+}
+
START_TEST(ddraw4)
{
test_process_vertices();
test_coop_level_create_device_window();
+ test_clipper_blt();
}
diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c
index 89974e9..d5ef2e3 100644
--- a/dlls/ddraw/tests/ddraw7.c
+++ b/dlls/ddraw/tests/ddraw7.c
@@ -64,6 +64,41 @@ static BOOL compare_vec4(struct vec4 *vec, float x, float y, float z, float w, u
&& compare_float(vec->w, w, ulps);
}
+static BOOL compare_color(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
+{
+ if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
+ c1 >>= 8; c2 >>= 8;
+ if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
+ c1 >>= 8; c2 >>= 8;
+ if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
+ c1 >>= 8; c2 >>= 8;
+ if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
+ return TRUE;
+}
+
+static D3DCOLOR get_surface_color(IDirectDrawSurface7 *surface, UINT x, UINT y)
+{
+ RECT rect = {x, y, x + 1, y + 1};
+ DDSURFACEDESC2 surface_desc;
+ D3DCOLOR color;
+ HRESULT hr;
+
+ memset(&surface_desc, 0, sizeof(surface_desc));
+ surface_desc.dwSize = sizeof(surface_desc);
+
+ hr = IDirectDrawSurface7_Lock(surface, &rect, &surface_desc, DDLOCK_READONLY | DDLOCK_WAIT, NULL);
+ ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
+ if (FAILED(hr))
+ return 0xdeadbeef;
+
+ color = *((DWORD *)surface_desc.lpSurface) & 0x00ffffff;
+
+ hr = IDirectDrawSurface7_Unlock(surface, &rect);
+ ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
+
+ return color;
+}
+
static IDirectDraw7 *create_ddraw(void)
{
IDirectDraw7 *ddraw;
@@ -420,6 +455,186 @@ static void test_coop_level_create_device_window(void)
DestroyWindow(focus_window);
}
+static void test_clipper_blt(void)
+{
+ IDirectDrawSurface7 *src_surface, *dst_surface;
+ RECT client_rect, src_rect, *rect;
+ IDirectDrawClipper *clipper;
+ DDSURFACEDESC2 surface_desc;
+ unsigned int i, j, x, y;
+ IDirectDraw7 *ddraw;
+ RGNDATA *rgn_data;
+ D3DCOLOR color;
+ HRGN r1, r2;
+ HWND window;
+ DDBLTFX fx;
+ HRESULT hr;
+ DWORD ret;
+
+ static const D3DCOLOR expected1[] =
+ {
+ 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
+ 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
+ 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
+ };
+ static const D3DCOLOR expected2[] =
+ {
+ 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
+ 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
+ 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
+ };
+
+ window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
+ 10, 10, 640, 480, 0, 0, 0, 0);
+ ShowWindow(window, SW_SHOW);
+ if (!(ddraw = create_ddraw()))
+ {
+ skip("Failed to create a ddraw object, skipping test.\n");
+ DestroyWindow(window);
+ return;
+ }
+
+ ret = GetClientRect(window, &client_rect);
+ ok(ret, "Failed to get client rect.\n");
+ ret = MapWindowPoints(window, NULL, (POINT *)&client_rect, 2);
+ ok(ret, "Failed to map client rect.\n");
+
+ hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
+ ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
+
+ hr = IDirectDraw7_CreateClipper(ddraw, 0, &clipper, NULL);
+ ok(SUCCEEDED(hr), "Failed to create clipper, hr %#x.\n", hr);
+ hr = IDirectDrawClipper_SetHWnd(clipper, 0, window);
+ ok(SUCCEEDED(hr), "Failed to set clipper window, hr %#x.\n", hr);
+ hr = IDirectDrawClipper_GetClipList(clipper, NULL, NULL, &ret);
+ ok(SUCCEEDED(hr), "Failed to get clip list size, hr %#x.\n", hr);
+ rgn_data = HeapAlloc(GetProcessHeap(), 0, ret);
+ hr = IDirectDrawClipper_GetClipList(clipper, NULL, rgn_data, &ret);
+ ok(SUCCEEDED(hr), "Failed to get clip list, hr %#x.\n", hr);
+ ok(rgn_data->rdh.dwSize == sizeof(rgn_data->rdh), "Got unexpected structure size %#x.\n", rgn_data->rdh.dwSize);
+ ok(rgn_data->rdh.iType == RDH_RECTANGLES, "Got unexpected type %#x.\n", rgn_data->rdh.iType);
+ ok(rgn_data->rdh.nCount == 1, "Got unexpected count %u.\n", rgn_data->rdh.nCount);
+ ok(rgn_data->rdh.nRgnSize == 16, "Got unexpected region size %u.\n", rgn_data->rdh.nRgnSize);
+ todo_wine ok(EqualRect(&rgn_data->rdh.rcBound, &client_rect),
+ "Got unexpected bounding rect {%d, %d, %d, %d}, expected {%d, %d, %d, %d}.\n",
+ rgn_data->rdh.rcBound.left, rgn_data->rdh.rcBound.top,
+ rgn_data->rdh.rcBound.right, rgn_data->rdh.rcBound.bottom,
+ client_rect.left, client_rect.top, client_rect.right, client_rect.bottom);
+ rect = (RECT *)&rgn_data->Buffer[0];
+ todo_wine ok(EqualRect(rect, &client_rect),
+ "Got unexpected clip rect {%d, %d, %d, %d}, expected {%d, %d, %d, %d}.\n",
+ rect->left, rect->top, rect->right, rect->bottom,
+ client_rect.left, client_rect.top, client_rect.right, client_rect.bottom);
+ HeapFree(GetProcessHeap(), 0, rgn_data);
+
+ r1 = CreateRectRgn(0, 0, 320, 240);
+ ok(!!r1, "Failed to create region.\n");
+ r2 = CreateRectRgn(320, 240, 640, 480);
+ ok(!!r2, "Failed to create region.\n");
+ CombineRgn(r1, r1, r2, RGN_OR);
+ ret = GetRegionData(r1, 0, NULL);
+ rgn_data = HeapAlloc(GetProcessHeap(), 0, ret);
+ ret = GetRegionData(r1, ret, rgn_data);
+ ok(!!ret, "Failed to get region data.\n");
+
+ DeleteObject(r2);
+ DeleteObject(r1);
+
+ hr = IDirectDrawClipper_SetClipList(clipper, rgn_data, 0);
+ todo_wine ok(hr == DDERR_CLIPPERISUSINGHWND, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawClipper_SetHWnd(clipper, 0, NULL);
+ ok(SUCCEEDED(hr), "Failed to set clipper window, hr %#x.\n", hr);
+ hr = IDirectDrawClipper_SetClipList(clipper, rgn_data, 0);
+ ok(SUCCEEDED(hr), "Failed to set clip list, hr %#x.\n", hr);
+
+ HeapFree(GetProcessHeap(), 0, rgn_data);
+
+ memset(&surface_desc, 0, sizeof(surface_desc));
+ surface_desc.dwSize = sizeof(surface_desc);
+ surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
+ surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
+ surface_desc.dwWidth = 640;
+ surface_desc.dwHeight = 480;
+ surface_desc.ddpfPixelFormat.dwSize = sizeof(surface_desc.ddpfPixelFormat);
+ surface_desc.ddpfPixelFormat.dwFlags = DDPF_RGB;
+ U1(surface_desc.ddpfPixelFormat).dwRGBBitCount = 32;
+ U2(surface_desc.ddpfPixelFormat).dwRBitMask = 0x00ff0000;
+ U3(surface_desc.ddpfPixelFormat).dwGBitMask = 0x0000ff00;
+ U4(surface_desc.ddpfPixelFormat).dwBBitMask = 0x000000ff;
+
+ hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &src_surface, NULL);
+ ok(SUCCEEDED(hr), "Failed to create source surface, hr %#x.\n", hr);
+ hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &dst_surface, NULL);
+ ok(SUCCEEDED(hr), "Failed to create destination surface, hr %#x.\n", hr);
+
+ memset(&fx, 0, sizeof(fx));
+ fx.dwSize = sizeof(fx);
+ hr = IDirectDrawSurface7_Blt(src_surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
+ ok(SUCCEEDED(hr), "Failed to clear source surface, hr %#x.\n", hr);
+ hr = IDirectDrawSurface7_Blt(dst_surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
+ ok(SUCCEEDED(hr), "Failed to clear destination surface, hr %#x.\n", hr);
+
+ hr = IDirectDrawSurface7_Lock(src_surface, NULL, &surface_desc, 0, NULL);
+ ok(SUCCEEDED(hr), "Failed to lock source surface, hr %#x.\n", hr);
+ ((DWORD *)surface_desc.lpSurface)[0] = 0xff0000ff;
+ ((DWORD *)surface_desc.lpSurface)[1] = 0xff00ff00;
+ ((DWORD *)surface_desc.lpSurface)[2] = 0xffff0000;
+ ((DWORD *)surface_desc.lpSurface)[3] = 0xffffffff;
+ hr = IDirectDrawSurface7_Unlock(src_surface, NULL);
+ ok(SUCCEEDED(hr), "Failed to unlock source surface, hr %#x.\n", hr);
+
+ hr = IDirectDrawSurface7_SetClipper(dst_surface, clipper);
+ ok(SUCCEEDED(hr), "Failed to set clipper, hr %#x.\n", hr);
+
+ SetRect(&src_rect, 0, 0, 4, 1);
+ hr = IDirectDrawSurface7_Blt(dst_surface, NULL, src_surface, &src_rect, DDBLT_WAIT, NULL);
+ todo_wine ok(SUCCEEDED(hr), "Failed to blit, hr %#x.\n", hr);
+ for (i = 0; i < 4; ++i)
+ {
+ for (j = 0; j < 4; ++j)
+ {
+ x = 80 * ((2 * j) + 1);
+ y = 60 * ((2 * i) + 1);
+ color = get_surface_color(dst_surface, x, y);
+ if ((i < 2 && j < 2) || (i >= 2 && j >= 2))
+ todo_wine ok(compare_color(color, expected1[i * 4 + j], 1),
+ "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected1[i * 4 + j], x, y, color);
+ else
+ ok(compare_color(color, expected1[i * 4 + j], 1),
+ "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected1[i * 4 + j], x, y, color);
+ }
+ }
+
+ U5(fx).dwFillColor = 0xff0000ff;
+ hr = IDirectDrawSurface7_Blt(dst_surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
+ todo_wine ok(SUCCEEDED(hr), "Failed to clear destination surface, hr %#x.\n", hr);
+ for (i = 0; i < 4; ++i)
+ {
+ for (j = 0; j < 4; ++j)
+ {
+ x = 80 * ((2 * j) + 1);
+ y = 60 * ((2 * i) + 1);
+ color = get_surface_color(dst_surface, x, y);
+ if ((i < 2 && j < 2) || (i >= 2 && j >= 2))
+ todo_wine ok(compare_color(color, expected2[i * 4 + j], 1),
+ "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected2[i * 4 + j], x, y, color);
+ else
+ ok(compare_color(color, expected2[i * 4 + j], 1),
+ "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected2[i * 4 + j], x, y, color);
+ }
+ }
+
+ hr = IDirectDrawSurface7_BltFast(dst_surface, 0, 0, src_surface, NULL, DDBLTFAST_WAIT);
+ todo_wine ok(hr == DDERR_BLTFASTCANTCLIP, "Got unexpected hr %#x.\n", hr);
+
+ IDirectDrawSurface7_Release(dst_surface);
+ IDirectDrawSurface7_Release(src_surface);
+ IDirectDrawClipper_Release(clipper);
+ IDirectDraw7_Release(ddraw);
+}
+
START_TEST(ddraw7)
{
HMODULE module = GetModuleHandleA("ddraw.dll");
@@ -432,4 +647,5 @@ START_TEST(ddraw7)
test_process_vertices();
test_coop_level_create_device_window();
+ test_clipper_blt();
}
--
1.7.3.4
More information about the wine-patches
mailing list