Don't open device if already open.
[wine] / dlls / ddraw / tests / dsurface.c
1 /*
2  * Unit tests for (a few) ddraw surface functions
3  *
4  * Copyright (C) 2005 Antoine Chavasse (a.chavasse@gmail.com)
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include <assert.h>
22 #include "wine/test.h"
23 #include "ddraw.h"
24
25 #ifdef NONAMELESSUNION
26 # define U(x)  (x).u
27 # define U2(x) (x).u2
28 #else
29 # define U(x)  (x)
30 # define U2(x) (x)
31 #endif
32
33 static LPDIRECTDRAW lpDD = NULL;
34
35 static void CreateDirectDraw()
36 {
37     HRESULT rc;
38
39     rc = DirectDrawCreate(NULL, &lpDD, NULL);
40     ok(rc==DD_OK,"DirectDrawCreate returned: %lx\n",rc);
41
42     rc = IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
43     ok(rc==DD_OK,"SetCooperativeLevel returned: %lx\n",rc);
44 }
45
46
47 static void ReleaseDirectDraw()
48 {
49     if( lpDD != NULL )
50     {
51         IDirectDraw_Release(lpDD);
52         lpDD = NULL;
53     }
54 }
55
56 static void MipMapCreationTest()
57 {
58     LPDIRECTDRAWSURFACE lpDDSMipMapTest;
59     DDSURFACEDESC ddsd;
60     HRESULT rc;
61
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;
69     ddsd.dwWidth = 128;
70     ddsd.dwHeight = 32;
71     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
72     ok(rc==DD_OK,"CreateSurface returned: %lx\n",rc);
73
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: %lx\n",rc);
79     ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
80         "GetSurfaceDesc returned no mipmapcount.\n");
81     ok(U2(ddsd).dwMipMapCount == 3, "Incorrect mipmap count: %ld.\n",
82         U2(ddsd).dwMipMapCount);
83
84     /* Destroy the surface. */
85     IDirectDrawSurface_Release(lpDDSMipMapTest);
86
87
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;
95     ddsd.dwWidth = 128;
96     ddsd.dwHeight = 32;
97     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
98     ok(rc==DD_OK,"CreateSurface returned: %lx\n",rc);
99
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: %lx\n",rc);
105     ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
106         "GetSurfaceDesc returned no mipmapcount.\n");
107     ok(U2(ddsd).dwMipMapCount == 1, "Incorrect mipmap count: %ld.\n",
108         U2(ddsd).dwMipMapCount);
109
110
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
115        created.
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;
121     ddsd.dwWidth = 128;
122     ddsd.dwHeight = 32;
123     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
124     ok(rc==DD_OK,"CreateSurface returned: %lx\n",rc);
125
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: %lx\n",rc);
131     ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
132         "GetSurfaceDesc returned no mipmapcount.\n");
133     ok(U2(ddsd).dwMipMapCount == 6, "Incorrect mipmap count: %ld.\n",
134         U2(ddsd).dwMipMapCount);
135
136
137     /* Fourth mipmap creation test: same as above with a different texture
138        size.
139        The purpose is to verify that the number of generated mipmaps is
140        dependant 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;
145     ddsd.dwWidth = 32;
146     ddsd.dwHeight = 64;
147     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
148     ok(rc==DD_OK,"CreateSurface returned: %lx\n",rc);
149
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: %lx\n",rc);
155     ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
156         "GetSurfaceDesc returned no mipmapcount.\n");
157     ok(U2(ddsd).dwMipMapCount == 6, "Incorrect mipmap count: %ld.\n",
158         U2(ddsd).dwMipMapCount);
159
160     /* Destroy the surface. */
161     IDirectDrawSurface_Release(lpDDSMipMapTest);
162 }
163
164
165 START_TEST(dsurface)
166 {
167     CreateDirectDraw();
168     MipMapCreationTest();
169     ReleaseDirectDraw();
170 }