crypt32: Fix some test failures on Win9x.
[wine] / dlls / wined3d / wined3d_main.c
1 /*
2  * Direct3D wine internal interface main
3  *
4  * Copyright 2002-2003 The wine-d3d team
5  * Copyright 2002-2003 Raphael Junqueira
6  * Copyright 2004      Jason Edmeades
7  * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23
24 #include "config.h"
25
26 #include "initguid.h"
27 #include "wined3d_private.h"
28
29 WINE_DEFAULT_DEBUG_CHANNEL(wine_d3d);
30
31 int num_lock = 0;
32 void (*wine_tsx11_lock_ptr)(void) = NULL;
33 void (*wine_tsx11_unlock_ptr)(void) = NULL;
34
35
36 /* When updating default value here, make sure to update winecfg as well,
37  * where appropriate. */
38 wined3d_settings_t wined3d_settings = 
39 {
40     VS_HW,          /* Hardware by default */
41     PS_HW,          /* Hardware by default */
42     VBO_HW,         /* Hardware by default */
43     TRUE,           /* Use of GLSL enabled by default */
44     ORM_BACKBUFFER, /* Use the backbuffer to do offscreen rendering */
45     RTL_AUTO,       /* Automatically determine best locking method */
46     0,              /* The default of memory is set in FillGLCaps */
47     NULL,           /* No wine logo by default */
48     FALSE           /* Disable multisampling for now due to Nvidia driver bugs which happens for some users */
49 };
50
51 IWineD3D* WINAPI WineDirect3DCreate(UINT SDKVersion, UINT dxVersion, IUnknown *parent) {
52     IWineD3DImpl* object;
53
54     if (!InitAdapters()) {
55         WARN("Failed to initialize direct3d adapters, Direct3D will not be available\n");
56         if(dxVersion > 7) {
57             ERR("Direct3D%d is not available without opengl\n", dxVersion);
58             return NULL;
59         }
60     }
61
62     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IWineD3DImpl));
63     object->lpVtbl = &IWineD3D_Vtbl;
64     object->dxVersion = dxVersion;
65     object->ref = 1;
66     object->parent = parent;
67
68     TRACE("Created WineD3D object @ %p for d3d%d support\n", object, dxVersion);
69
70     return (IWineD3D *)object;
71 }
72
73 static inline DWORD get_config_key(HKEY defkey, HKEY appkey, const char* name, char* buffer, DWORD size)
74 {
75     if (0 != appkey && !RegQueryValueExA( appkey, name, 0, NULL, (LPBYTE) buffer, &size )) return 0;
76     if (0 != defkey && !RegQueryValueExA( defkey, name, 0, NULL, (LPBYTE) buffer, &size )) return 0;
77     return ERROR_FILE_NOT_FOUND;
78 }
79
80 static void wined3d_do_nothing(void)
81 {
82 }
83
84 /* At process attach */
85 BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
86 {
87     TRACE("WineD3D DLLMain Reason=%d\n", fdwReason);
88     if (fdwReason == DLL_PROCESS_ATTACH)
89     {
90        HMODULE mod;
91        char buffer[MAX_PATH+10];
92        DWORD size = sizeof(buffer);
93        HKEY hkey = 0;
94        HKEY appkey = 0;
95        DWORD len;
96        WNDCLASSA wc;
97
98        /* We need our own window class for a fake window which we use to retrieve GL capabilities */
99        /* We might need CS_OWNDC in the future if we notice strange things on Windows.
100         * Various articles/posts about OpenGL problems on Windows recommend this. */
101        wc.style                = CS_HREDRAW | CS_VREDRAW;
102        wc.lpfnWndProc          = DefWindowProcA;
103        wc.cbClsExtra           = 0;
104        wc.cbWndExtra           = 0;
105        wc.hInstance            = hInstDLL;
106        wc.hIcon                = LoadIconA(NULL, (LPCSTR)IDI_WINLOGO);
107        wc.hCursor              = LoadCursorA(NULL, (LPCSTR)IDC_ARROW);
108        wc.hbrBackground        = NULL;
109        wc.lpszMenuName         = NULL;
110        wc.lpszClassName        = "WineD3D_OpenGL";
111
112        if (!RegisterClassA(&wc) && GetLastError() != ERROR_CLASS_ALREADY_EXISTS)
113        {
114            ERR("Failed to register window class 'WineD3D_OpenGL'!\n");
115            return FALSE;
116        }
117
118        DisableThreadLibraryCalls(hInstDLL);
119
120        mod = GetModuleHandleA( "winex11.drv" );
121        if (mod)
122        {
123            wine_tsx11_lock_ptr   = (void *)GetProcAddress( mod, "wine_tsx11_lock" );
124            wine_tsx11_unlock_ptr = (void *)GetProcAddress( mod, "wine_tsx11_unlock" );
125        }
126        else /* We are most likely on Windows */
127        {
128            wine_tsx11_lock_ptr   = wined3d_do_nothing;
129            wine_tsx11_unlock_ptr = wined3d_do_nothing;
130        }
131        /* @@ Wine registry key: HKCU\Software\Wine\Direct3D */
132        if ( RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\Direct3D", &hkey ) ) hkey = 0;
133
134        len = GetModuleFileNameA( 0, buffer, MAX_PATH );
135        if (len && len < MAX_PATH)
136        {
137             HKEY tmpkey;
138             /* @@ Wine registry key: HKCU\Software\Wine\AppDefaults\app.exe\Direct3D */
139             if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\AppDefaults", &tmpkey ))
140             {
141                 char *p, *appname = buffer;
142                 if ((p = strrchr( appname, '/' ))) appname = p + 1;
143                 if ((p = strrchr( appname, '\\' ))) appname = p + 1;
144                 strcat( appname, "\\Direct3D" );
145                 TRACE("appname = [%s]\n", appname);
146                 if (RegOpenKeyA( tmpkey, appname, &appkey )) appkey = 0;
147                 RegCloseKey( tmpkey );
148             }
149        }
150
151        if ( 0 != hkey || 0 != appkey )
152        {
153             if ( !get_config_key( hkey, appkey, "VertexShaderMode", buffer, size) )
154             {
155                 if (!strcmp(buffer,"none"))
156                 {
157                     TRACE("Disable vertex shaders\n");
158                     wined3d_settings.vs_mode = VS_NONE;
159                 }
160             }
161             if ( !get_config_key( hkey, appkey, "PixelShaderMode", buffer, size) )
162             {
163                 if (!strcmp(buffer,"enabled"))
164                 {
165                     TRACE("Allow pixel shaders\n");
166                     wined3d_settings.ps_mode = PS_HW;
167                 }
168                 if (!strcmp(buffer,"disabled"))
169                 {
170                     TRACE("Disable pixel shaders\n");
171                     wined3d_settings.ps_mode = PS_NONE;
172                 }
173             }
174             if ( !get_config_key( hkey, appkey, "VertexBufferMode", buffer, size) )
175             {
176                 if (!strcmp(buffer,"none"))
177                 {
178                     TRACE("Disable Vertex Buffer Hardware support\n");
179                     wined3d_settings.vbo_mode = VBO_NONE;
180                 }
181                 else if (!strcmp(buffer,"hardware"))
182                 {
183                     TRACE("Allow Vertex Buffer Hardware support\n");
184                     wined3d_settings.vbo_mode = VBO_HW;
185                 }
186             }
187             if ( !get_config_key( hkey, appkey, "UseGLSL", buffer, size) )
188             {
189                 if (!strcmp(buffer,"disabled"))
190                 {
191                     TRACE("Use of GL Shading Language disabled\n");
192                     wined3d_settings.glslRequested = FALSE;
193                 }
194             }
195             if ( !get_config_key( hkey, appkey, "OffscreenRenderingMode", buffer, size) )
196             {
197                 if (!strcmp(buffer,"backbuffer"))
198                 {
199                     TRACE("Using the backbuffer for offscreen rendering\n");
200                     wined3d_settings.offscreen_rendering_mode = ORM_BACKBUFFER;
201                 }
202                 else if (!strcmp(buffer,"pbuffer"))
203                 {
204                     TRACE("Using PBuffers for offscreen rendering\n");
205                     wined3d_settings.offscreen_rendering_mode = ORM_PBUFFER;
206                 }
207                 else if (!strcmp(buffer,"fbo"))
208                 {
209                     TRACE("Using FBOs for offscreen rendering\n");
210                     wined3d_settings.offscreen_rendering_mode = ORM_FBO;
211                 }
212             }
213             if ( !get_config_key( hkey, appkey, "RenderTargetLockMode", buffer, size) )
214             {
215                 if (!strcmp(buffer,"disabled"))
216                 {
217                     TRACE("Disabling render target locking\n");
218                     wined3d_settings.rendertargetlock_mode = RTL_DISABLE;
219                 }
220                 else if (!strcmp(buffer,"readdraw"))
221                 {
222                     TRACE("Using glReadPixels for render target reading and glDrawPixels for writing\n");
223                     wined3d_settings.rendertargetlock_mode = RTL_READDRAW;
224                 }
225                 else if (!strcmp(buffer,"readtex"))
226                 {
227                     TRACE("Using glReadPixels for render target reading and textures for writing\n");
228                     wined3d_settings.rendertargetlock_mode = RTL_READTEX;
229                 }
230                 else if (!strcmp(buffer,"texdraw"))
231                 {
232                     TRACE("Using textures for render target reading and glDrawPixels for writing\n");
233                     wined3d_settings.rendertargetlock_mode = RTL_TEXDRAW;
234                 }
235                 else if (!strcmp(buffer,"textex"))
236                 {
237                     TRACE("Reading render targets via textures and writing via textures\n");
238                     wined3d_settings.rendertargetlock_mode = RTL_TEXTEX;
239                 }
240             }
241             if ( !get_config_key( hkey, appkey, "VideoMemorySize", buffer, size) )
242             {
243                 int TmpVideoMemorySize = atoi(buffer);
244                 if(TmpVideoMemorySize > 0)
245                 {
246                     wined3d_settings.emulated_textureram = TmpVideoMemorySize *1024*1024;
247                     TRACE("Use %iMB = %d byte for emulated_textureram\n",
248                             TmpVideoMemorySize,
249                             wined3d_settings.emulated_textureram);
250                 }
251                 else
252                     ERR("VideoMemorySize is %i but must be >0\n", TmpVideoMemorySize);
253             }
254             if ( !get_config_key( hkey, appkey, "WineLogo", buffer, size) )
255             {
256                 wined3d_settings.logo = HeapAlloc(GetProcessHeap(), 0, strlen(buffer) + 1);
257                 if(wined3d_settings.logo) strcpy(wined3d_settings.logo, buffer);
258             }
259             if ( !get_config_key( hkey, appkey, "Multisampling", buffer, size) )
260             {
261                 if (!strcmp(buffer,"enabled"))
262                 {
263                     TRACE("Allow multisampling\n");
264                     wined3d_settings.allow_multisampling = TRUE;
265                 }
266             }
267        }
268        if (wined3d_settings.vs_mode == VS_HW)
269            TRACE("Allow HW vertex shaders\n");
270        if (wined3d_settings.ps_mode == PS_NONE)
271            TRACE("Disable pixel shaders\n");
272        if (wined3d_settings.vbo_mode == VBO_NONE)
273            TRACE("Disable Vertex Buffer Hardware support\n");
274        if (wined3d_settings.glslRequested)
275            TRACE("If supported by your system, GL Shading Language will be used\n");
276
277        if (appkey) RegCloseKey( appkey );
278        if (hkey) RegCloseKey( hkey );
279     }
280     return TRUE;
281 }