ddraw: Fix DirectDrawSurface::QueryInterface crash.
[wine/multimedia.git] / dlls / ddraw / tests / dsurface.c
blobe1e0c9330912f99f593d7432f6b13036e57f87dc
1 /*
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include <assert.h>
24 #include "wine/test.h"
25 #include "ddraw.h"
27 static LPDIRECTDRAW lpDD = NULL;
29 static void CreateDirectDraw(void)
31 HRESULT rc;
33 rc = DirectDrawCreate(NULL, &lpDD, NULL);
34 ok(rc==DD_OK,"DirectDrawCreate returned: %lx\n",rc);
36 rc = IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
37 ok(rc==DD_OK,"SetCooperativeLevel returned: %lx\n",rc);
41 static void ReleaseDirectDraw(void)
43 if( lpDD != NULL )
45 IDirectDraw_Release(lpDD);
46 lpDD = NULL;
50 static void MipMapCreationTest(void)
52 LPDIRECTDRAWSURFACE lpDDSMipMapTest;
53 DDSURFACEDESC ddsd;
54 HRESULT rc;
56 /* First mipmap creation test: create a surface with DDSCAPS_COMPLEX,
57 DDSCAPS_MIPMAP, and DDSD_MIPMAPCOUNT. This create the number of
58 requested mipmap levels. */
59 ddsd.dwSize = sizeof(ddsd);
60 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
61 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
62 U2(ddsd).dwMipMapCount = 3;
63 ddsd.dwWidth = 128;
64 ddsd.dwHeight = 32;
65 rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
66 ok(rc==DD_OK,"CreateSurface returned: %lx\n",rc);
68 /* Check the number of created mipmaps */
69 memset(&ddsd, 0, sizeof(DDSURFACEDESC));
70 ddsd.dwSize = sizeof(ddsd);
71 rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd);
72 ok(rc==DD_OK,"GetSurfaceDesc returned: %lx\n",rc);
73 ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
74 "GetSurfaceDesc returned no mipmapcount.\n");
75 ok(U2(ddsd).dwMipMapCount == 3, "Incorrect mipmap count: %ld.\n",
76 U2(ddsd).dwMipMapCount);
78 /* Destroy the surface. */
79 IDirectDrawSurface_Release(lpDDSMipMapTest);
82 /* Second mipmap creation test: create a surface without a mipmap
83 count, with DDSCAPS_MIPMAP and without DDSCAPS_COMPLEX.
84 This creates a single mipmap level. */
85 memset(&ddsd, 0, sizeof(DDSURFACEDESC));
86 ddsd.dwSize = sizeof(ddsd);
87 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
88 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
89 ddsd.dwWidth = 128;
90 ddsd.dwHeight = 32;
91 rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
92 ok(rc==DD_OK,"CreateSurface returned: %lx\n",rc);
94 /* Check the number of created mipmaps */
95 memset(&ddsd, 0, sizeof(DDSURFACEDESC));
96 ddsd.dwSize = sizeof(ddsd);
97 rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd);
98 ok(rc==DD_OK,"GetSurfaceDesc returned: %lx\n",rc);
99 ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
100 "GetSurfaceDesc returned no mipmapcount.\n");
101 ok(U2(ddsd).dwMipMapCount == 1, "Incorrect mipmap count: %ld.\n",
102 U2(ddsd).dwMipMapCount);
105 /* Third mipmap creation test: create a surface with DDSCAPS_MIPMAP,
106 DDSCAPS_COMPLEX and without DDSD_MIPMAPCOUNT.
107 It's an undocumented features where a chain of mipmaps, starting from
108 he specified size and down to the smallest size, is automatically
109 created.
110 Anarchy Online needs this feature to work. */
111 memset(&ddsd, 0, sizeof(DDSURFACEDESC));
112 ddsd.dwSize = sizeof(ddsd);
113 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
114 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
115 ddsd.dwWidth = 128;
116 ddsd.dwHeight = 32;
117 rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
118 ok(rc==DD_OK,"CreateSurface returned: %lx\n",rc);
120 /* Check the number of created mipmaps */
121 memset(&ddsd, 0, sizeof(DDSURFACEDESC));
122 ddsd.dwSize = sizeof(ddsd);
123 rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd);
124 ok(rc==DD_OK,"GetSurfaceDesc returned: %lx\n",rc);
125 ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
126 "GetSurfaceDesc returned no mipmapcount.\n");
127 ok(U2(ddsd).dwMipMapCount == 6, "Incorrect mipmap count: %ld.\n",
128 U2(ddsd).dwMipMapCount);
131 /* Fourth mipmap creation test: same as above with a different texture
132 size.
133 The purpose is to verify that the number of generated mipmaps is
134 dependent on the smallest dimension. */
135 memset(&ddsd, 0, sizeof(DDSURFACEDESC));
136 ddsd.dwSize = sizeof(ddsd);
137 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
138 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
139 ddsd.dwWidth = 32;
140 ddsd.dwHeight = 64;
141 rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
142 ok(rc==DD_OK,"CreateSurface returned: %lx\n",rc);
144 /* Check the number of created mipmaps */
145 memset(&ddsd, 0, sizeof(DDSURFACEDESC));
146 ddsd.dwSize = sizeof(ddsd);
147 rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd);
148 ok(rc==DD_OK,"GetSurfaceDesc returned: %lx\n",rc);
149 ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
150 "GetSurfaceDesc returned no mipmapcount.\n");
151 ok(U2(ddsd).dwMipMapCount == 6, "Incorrect mipmap count: %ld.\n",
152 U2(ddsd).dwMipMapCount);
154 /* Destroy the surface. */
155 IDirectDrawSurface_Release(lpDDSMipMapTest);
158 static void SrcColorKey32BlitTest(void)
160 LPDIRECTDRAWSURFACE lpSrc;
161 LPDIRECTDRAWSURFACE lpDst;
162 DDSURFACEDESC ddsd;
163 DDSURFACEDESC ddsd2;
164 LPDWORD lpData;
165 HRESULT rc;
167 ddsd2.dwSize = sizeof(ddsd2);
168 ddsd2.ddpfPixelFormat.dwSize = sizeof(ddsd2.ddpfPixelFormat);
170 ddsd.dwSize = sizeof(ddsd);
171 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
172 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
173 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
174 ddsd.dwWidth = 800;
175 ddsd.dwHeight = 600;
176 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
177 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
178 U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xFF0000;
179 U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x00FF00;
180 U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x0000FF;
181 rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDst, NULL);
182 ok(rc==DD_OK,"CreateSurface returned: %lx\n",rc);
184 ddsd.dwFlags |= DDSD_CKSRCBLT;
185 ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0xFF00FF;
186 ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0xFF00FF;
187 rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpSrc, NULL);
188 ok(rc==DD_OK,"CreateSurface returned: %lx\n",rc);
190 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
191 ok(rc==DD_OK,"Lock returned: %lx\n",rc);
192 lpData = (LPDWORD)ddsd2.lpSurface;
193 lpData[0] = 0xCCCCCCCC;
194 lpData[1] = 0xCCCCCCCC;
195 lpData[2] = 0xCCCCCCCC;
196 lpData[3] = 0xCCCCCCCC;
197 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
198 ok(rc==DD_OK,"Unlock returned: %lx\n",rc);
200 rc = IDirectDrawSurface_Lock(lpSrc, NULL, &ddsd2, DDLOCK_WAIT, NULL);
201 ok(rc==DD_OK,"Lock returned: %lx\n",rc);
202 lpData = (LPDWORD)ddsd2.lpSurface;
203 lpData[0] = 0x77010203;
204 lpData[1] = 0x00010203;
205 lpData[2] = 0x77FF00FF;
206 lpData[3] = 0x00FF00FF;
207 rc = IDirectDrawSurface_Unlock(lpSrc, NULL);
208 ok(rc==DD_OK,"Unlock returned: %lx\n",rc);
210 IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRC, NULL);
212 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
213 ok(rc==DD_OK,"Lock returned: %lx\n",rc);
214 lpData = (LPDWORD)ddsd2.lpSurface;
215 ok((lpData[0]==0x77010203)&&(lpData[1]==0x00010203)&&(lpData[2]==0xCCCCCCCC)&&(lpData[3]==0xCCCCCCCC),
216 "Destination data after blitting is not correct\n");
217 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
218 ok(rc==DD_OK,"Unlock returned: %lx\n",rc);
220 IDirectDrawSurface_Release(lpSrc);
221 IDirectDrawSurface_Release(lpDst);
224 static void QueryInterface(void)
226 LPDIRECTDRAWSURFACE dsurface;
227 DDSURFACEDESC surface;
228 LPVOID object;
229 HRESULT ret;
231 /* Create a surface */
232 ZeroMemory(&surface, sizeof(surface));
233 surface.dwSize = sizeof(surface);
234 surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
235 surface.dwHeight = 10;
236 surface.dwWidth = 10;
237 ret = IDirectDraw_CreateSurface(lpDD, &surface, &dsurface, NULL);
238 if(ret != DD_OK)
240 ok(FALSE, "IDirectDraw::CreateSurface failed with error %lx\n", ret);
241 return;
244 /* Call IUnkown::QueryInterface */
245 ret = IDirectDrawSurface_QueryInterface(dsurface, 0, &object);
246 ok(ret == DDERR_INVALIDPARAMS, "IDirectDrawSurface::QueryInterface returned %lx\n", ret);
248 IDirectDrawSurface_Release(dsurface);
251 START_TEST(dsurface)
253 CreateDirectDraw();
254 MipMapCreationTest();
255 SrcColorKey32BlitTest();
256 QueryInterface();
257 ReleaseDirectDraw();