2 * Unit tests for (a few) ddraw surface functions
4 * Copyright (C) 2005 Antoine Chavasse (a.chavasse@gmail.com)
5 * Copyright (C) 2005 Christian Costa
6 * Copyright 2005 Ivan Leo Puoti
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #include "wine/test.h"
27 static LPDIRECTDRAW lpDD = NULL;
29 static BOOL CreateDirectDraw(void)
33 rc = DirectDrawCreate(NULL, &lpDD, NULL);
34 ok(rc==DD_OK || rc==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %x\n", rc);
36 trace("DirectDrawCreateEx() failed with an error %x\n", rc);
40 rc = IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
41 ok(rc==DD_OK,"SetCooperativeLevel returned: %x\n",rc);
47 static void ReleaseDirectDraw(void)
51 IDirectDraw_Release(lpDD);
56 static void MipMapCreationTest(void)
58 LPDIRECTDRAWSURFACE lpDDSMipMapTest;
62 /* First mipmap creation test: create a surface with DDSCAPS_COMPLEX,
63 DDSCAPS_MIPMAP, and DDSD_MIPMAPCOUNT. This create the number of
64 requested mipmap levels. */
65 ddsd.dwSize = sizeof(ddsd);
66 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
67 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
68 U2(ddsd).dwMipMapCount = 3;
71 rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
72 ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
74 /* Check the number of created mipmaps */
75 memset(&ddsd, 0, sizeof(DDSURFACEDESC));
76 ddsd.dwSize = sizeof(ddsd);
77 rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd);
78 ok(rc==DD_OK,"GetSurfaceDesc returned: %x\n",rc);
79 ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
80 "GetSurfaceDesc returned no mipmapcount.\n");
81 ok(U2(ddsd).dwMipMapCount == 3, "Incorrect mipmap count: %d.\n",
82 U2(ddsd).dwMipMapCount);
84 /* Destroy the surface. */
85 IDirectDrawSurface_Release(lpDDSMipMapTest);
88 /* Second mipmap creation test: create a surface without a mipmap
89 count, with DDSCAPS_MIPMAP and without DDSCAPS_COMPLEX.
90 This creates a single mipmap level. */
91 memset(&ddsd, 0, sizeof(DDSURFACEDESC));
92 ddsd.dwSize = sizeof(ddsd);
93 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
94 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
97 rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
98 ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
100 /* Check the number of created mipmaps */
101 memset(&ddsd, 0, sizeof(DDSURFACEDESC));
102 ddsd.dwSize = sizeof(ddsd);
103 rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd);
104 ok(rc==DD_OK,"GetSurfaceDesc returned: %x\n",rc);
105 ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
106 "GetSurfaceDesc returned no mipmapcount.\n");
107 ok(U2(ddsd).dwMipMapCount == 1, "Incorrect mipmap count: %d.\n",
108 U2(ddsd).dwMipMapCount);
111 /* Third mipmap creation test: create a surface with DDSCAPS_MIPMAP,
112 DDSCAPS_COMPLEX and without DDSD_MIPMAPCOUNT.
113 It's an undocumented features where a chain of mipmaps, starting from
114 he specified size and down to the smallest size, is automatically
116 Anarchy Online needs this feature to work. */
117 memset(&ddsd, 0, sizeof(DDSURFACEDESC));
118 ddsd.dwSize = sizeof(ddsd);
119 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
120 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
123 rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
124 ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
126 /* Check the number of created mipmaps */
127 memset(&ddsd, 0, sizeof(DDSURFACEDESC));
128 ddsd.dwSize = sizeof(ddsd);
129 rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd);
130 ok(rc==DD_OK,"GetSurfaceDesc returned: %x\n",rc);
131 ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
132 "GetSurfaceDesc returned no mipmapcount.\n");
133 ok(U2(ddsd).dwMipMapCount == 6, "Incorrect mipmap count: %d.\n",
134 U2(ddsd).dwMipMapCount);
137 /* Fourth mipmap creation test: same as above with a different texture
139 The purpose is to verify that the number of generated mipmaps is
140 dependent on the smallest dimension. */
141 memset(&ddsd, 0, sizeof(DDSURFACEDESC));
142 ddsd.dwSize = sizeof(ddsd);
143 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
144 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
147 rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
148 ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
150 /* Check the number of created mipmaps */
151 memset(&ddsd, 0, sizeof(DDSURFACEDESC));
152 ddsd.dwSize = sizeof(ddsd);
153 rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd);
154 ok(rc==DD_OK,"GetSurfaceDesc returned: %x\n",rc);
155 ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
156 "GetSurfaceDesc returned no mipmapcount.\n");
157 ok(U2(ddsd).dwMipMapCount == 6, "Incorrect mipmap count: %d.\n",
158 U2(ddsd).dwMipMapCount);
160 /* Destroy the surface. */
161 IDirectDrawSurface_Release(lpDDSMipMapTest);
164 static void SrcColorKey32BlitTest(void)
166 LPDIRECTDRAWSURFACE lpSrc;
167 LPDIRECTDRAWSURFACE lpDst;
170 DDCOLORKEY DDColorKey;
174 ddsd2.dwSize = sizeof(ddsd2);
175 ddsd2.ddpfPixelFormat.dwSize = sizeof(ddsd2.ddpfPixelFormat);
177 ddsd.dwSize = sizeof(ddsd);
178 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
179 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
180 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
183 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
184 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
185 U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xFF0000;
186 U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x00FF00;
187 U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x0000FF;
188 rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDst, NULL);
189 ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
191 ddsd.dwFlags |= DDSD_CKSRCBLT;
192 ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0xFF00FF;
193 ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0xFF00FF;
194 rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpSrc, NULL);
195 ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
197 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
198 ok(rc==DD_OK,"Lock returned: %x\n",rc);
199 lpData = (LPDWORD)ddsd2.lpSurface;
200 lpData[0] = 0xCCCCCCCC;
201 lpData[1] = 0xCCCCCCCC;
202 lpData[2] = 0xCCCCCCCC;
203 lpData[3] = 0xCCCCCCCC;
204 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
205 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
207 rc = IDirectDrawSurface_Lock(lpSrc, NULL, &ddsd2, DDLOCK_WAIT, NULL);
208 ok(rc==DD_OK,"Lock returned: %x\n",rc);
209 lpData = (LPDWORD)ddsd2.lpSurface;
210 lpData[0] = 0x77010203;
211 lpData[1] = 0x00010203;
212 lpData[2] = 0x77FF00FF;
213 lpData[3] = 0x00FF00FF;
214 rc = IDirectDrawSurface_Unlock(lpSrc, NULL);
215 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
217 IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRC, NULL);
219 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
220 ok(rc==DD_OK,"Lock returned: %x\n",rc);
221 lpData = (LPDWORD)ddsd2.lpSurface;
222 ok((lpData[0]==0x77010203)&&(lpData[1]==0x00010203)&&(lpData[2]==0xCCCCCCCC)&&(lpData[3]==0xCCCCCCCC),
223 "Destination data after blitting is not correct\n");
224 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
225 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
227 /* Also test SetColorKey */
228 IDirectDrawSurface_GetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
229 ok(DDColorKey.dwColorSpaceLowValue == 0xFF00FF && DDColorKey.dwColorSpaceHighValue == 0xFF00FF,
230 "GetColorKey does not return the colorkey used at surface creation\n");
232 DDColorKey.dwColorSpaceLowValue = 0x00FF00;
233 DDColorKey.dwColorSpaceHighValue = 0x00FF00;
234 IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
236 DDColorKey.dwColorSpaceLowValue = 0;
237 DDColorKey.dwColorSpaceHighValue = 0;
238 IDirectDrawSurface_GetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
239 ok(DDColorKey.dwColorSpaceLowValue == 0x00FF00 && DDColorKey.dwColorSpaceHighValue == 0x00FF00,
240 "GetColorKey does not return the colorkey set with SetColorKey\n");
242 ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0;
243 ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0;
244 IDirectDrawSurface_GetSurfaceDesc(lpSrc, &ddsd);
245 ok(ddsd.ddckCKSrcBlt.dwColorSpaceLowValue == 0x00FF00 && ddsd.ddckCKSrcBlt.dwColorSpaceHighValue == 0x00FF00,
246 "GetSurfaceDesc does not return the colorkey set with SetColorKey\n");
248 IDirectDrawSurface_Release(lpSrc);
249 IDirectDrawSurface_Release(lpDst);
252 static void QueryInterface(void)
254 LPDIRECTDRAWSURFACE dsurface;
255 DDSURFACEDESC surface;
259 /* Create a surface */
260 ZeroMemory(&surface, sizeof(surface));
261 surface.dwSize = sizeof(surface);
262 surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
263 surface.dwHeight = 10;
264 surface.dwWidth = 10;
265 ret = IDirectDraw_CreateSurface(lpDD, &surface, &dsurface, NULL);
268 ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
272 /* Call IUnknown::QueryInterface */
273 ret = IDirectDrawSurface_QueryInterface(dsurface, 0, &object);
274 ok(ret == DDERR_INVALIDPARAMS, "IDirectDrawSurface::QueryInterface returned %x\n", ret);
276 IDirectDrawSurface_Release(dsurface);
281 if (!CreateDirectDraw())
283 MipMapCreationTest();
284 SrcColorKey32BlitTest();