From: Yuri Hérouard yuri.herouard@gmail.com
--- dlls/ddraw/tests/ddraw1.c | 148 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+)
diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c index e62d9283aaa..fc546856c65 100644 --- a/dlls/ddraw/tests/ddraw1.c +++ b/dlls/ddraw/tests/ddraw1.c @@ -9582,6 +9582,153 @@ done: DestroyWindow(window); }
+static void test_stretched_blit(void) +{ + IDirectDrawSurface *surface1, *surface2, *surface3; + DDSURFACEDESC surface_desc; + IDirectDraw *ddraw; + HRESULT hr; + IDirect3DDevice *device; + ULONG color1, color2, color, refcount; + HWND window; + RECT rect; + BYTE* pSurface, *buffer; + color1 = 0xffffffff; + color2 = 0x00000000; + window = create_window(); + ddraw = create_ddraw(); + ok(!!ddraw, "Failed to create a ddraw object.\n"); + if (!(device = create_device(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN))) + { + skip("Failed to create a 3D device.\n"); + IDirectDraw_Release(ddraw); + DestroyWindow(window); + return; + } + hr = IDirect3DDevice_QueryInterface(device, &IID_IDirectDrawSurface, (void **)&surface1); + ok(SUCCEEDED(hr), "Failed to get render target, hr %#lx.\n", hr); + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + surface_desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS; + surface_desc.dwWidth = 640; + surface_desc.dwHeight = 480; + surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; + hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &surface1, NULL); + ok(SUCCEEDED(hr), "Failed to create surface, hr %#lx.\n", hr); + hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &surface2, NULL); + ok(SUCCEEDED(hr), "Failed to create surface, hr %#lx.\n", hr); + hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &surface3, NULL); + ok(SUCCEEDED(hr), "Failed to create surface, hr %#lx.\n", hr); + + //Setting 1px checkerboard texture + hr = IDirectDrawSurface_Lock(surface1, NULL, &surface_desc, DDLOCK_WAIT, NULL); + ok(SUCCEEDED(hr), "Failed to lock surface, hr %#lx.\n", hr); + pSurface = (BYTE*)surface_desc.lpSurface; + for (int row = 0; row < 480; row++) + { + buffer = pSurface + row*surface_desc.lPitch; + for (int col = 0; col < 640; col++) + { + ((DWORD *)buffer)[col] = (row % 2 == 0) == (col % 2 == 0) ? color1 : color2; + } + } + hr = IDirectDrawSurface_Unlock(surface1, 0); + ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#lx.\n", hr); + +#define CHECK_BLITTED_TEXTURE(surface_ptr, expected_color) \ +do { \ +BOOL color_ok = TRUE; \ +hr = IDirectDrawSurface_Lock(surface_ptr, NULL, &surface_desc, DDLOCK_WAIT, NULL); \ +ok(SUCCEEDED(hr), "Failed to lock surface, hr %#lx.\n", hr); \ +pSurface = (BYTE*)surface_desc.lpSurface; \ +for (int row = 0; row < surface_desc.dwHeight; row++) \ +{ \ + for (int col = 0; col < surface_desc.dwWidth; col++) \ + { \ + buffer = pSurface + row*surface_desc.lPitch; \ + color = ((DWORD *)buffer)[col]; \ + if (color != expected_color) \ + { \ + color_ok = FALSE; \ + break; \ + } \ + if(!color_ok) break; \ + } \ +} \ +ok(color_ok, "Blitted texture color is incorrect.\n"); \ +hr = IDirectDrawSurface_Unlock(surface_ptr, 0); \ +ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#lx.\n", hr); \ +} while(0) + + rect.bottom = 240; + rect.right = 640; + rect.left = 0; + rect.top = 0; + hr = IDirectDrawSurface_Blt(surface2, NULL, surface1, &rect, DDBLT_WAIT, NULL); + ok(SUCCEEDED(hr), "Failed to blit, hr %#lx.\n", hr); + + //Checking that dst is a 2px vertical checkerboard + CHECK_BLITTED_TEXTURE(surface2, ((row % 4 < 2) == (col % 2 == 0) ? color1 : color2)); + + rect.bottom = 480; + rect.right = 320; + rect.left = 0; + rect.top = 0; + hr = IDirectDrawSurface_Blt(surface2, NULL, surface1, &rect, DDBLT_WAIT, NULL); + ok(SUCCEEDED(hr), "Failed to blit, hr %#lx.\n", hr); + + //Checking that dst is a 2px horizontal checkerboard + CHECK_BLITTED_TEXTURE(surface2, ((row % 2 == 0) == (col % 4 < 2) ? color1 : color2)); + + rect.bottom = 240; + rect.right = 320; + rect.left = 0; + rect.top = 0; + hr = IDirectDrawSurface_Blt(surface3, NULL, surface1, &rect, DDBLT_WAIT, NULL); + ok(SUCCEEDED(hr), "Failed to blit, hr %#lx.\n", hr); + + //Checking that src is a 4px checkerboard + CHECK_BLITTED_TEXTURE(surface3, ((row % 4 < 2) == (col % 4 < 2) ? color1 : color2)); + + rect.bottom = 240; + rect.right = 320; + rect.left = 0; + rect.top = 0; + //Blitting surface to itself ! Both axis stretched + hr = IDirectDrawSurface_Blt(surface1, NULL, surface1, &rect, DDBLT_WAIT, NULL); + ok(SUCCEEDED(hr), "Failed to blit, hr %#lx.\n", hr); + + //Checking that src is a 4px checkerboard + CHECK_BLITTED_TEXTURE(surface1, ((row % 4 < 2) == (col % 4 < 2) ? color1 : color2)); + + rect.bottom = 240; + rect.right = 640; + rect.left = 0; + rect.top = 0; + //Blitting surface to itself ! Vertical stretch + hr = IDirectDrawSurface_Blt(surface2, NULL, surface2, &rect, DDBLT_WAIT, NULL); + ok(SUCCEEDED(hr), "Failed to blit, hr %#lx.\n", hr); + + //Checking that src is a 4px checkerboard + CHECK_BLITTED_TEXTURE(surface2, ((row % 4 < 2) == (col % 4 < 2) ? color1 : color2)); + + rect.bottom = 480; + rect.right = 320; + rect.left = 0; + rect.top = 0; + //Blitting surface to itself ! Horizontal stretch + hr = IDirectDrawSurface_Blt(surface3, NULL, surface3, &rect, DDBLT_WAIT, NULL); + ok(SUCCEEDED(hr), "Failed to blit, hr %#lx.\n", hr); + + //Checking that src is a 2x4 px checkerboard + CHECK_BLITTED_TEXTURE(surface3, ((row % 4 < 2) == (col % 8 < 4) ? color1 : color2)); + + refcount = IDirectDraw_Release(ddraw); + ok(!refcount, "Unexpected refcount %lu.\n", refcount); + if (window) DestroyWindow(window); +#undef CHECK_BLITTED_TEXTURE +} + static void test_colorkey_precision(void) { static D3DTLVERTEX quad[] = @@ -16242,4 +16389,5 @@ START_TEST(ddraw1) test_multiple_devices(); test_sysmem_x_channel(); test_yuv_blit(); + test_stretched_blit(); }