Kill more of the old design.
[reactos.git] / reactos / dll / directx / ddraw / startup.c
1 /* $Id: main.c 21434 2006-04-01 19:12:56Z greatlrd $
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: lib/ddraw/ddraw.c
6 * PURPOSE: DirectDraw Library
7 * PROGRAMMER: Magnus Olsen (greatlrd)
8 *
9 */
10
11 #include <windows.h>
12 #include "rosdraw.h"
13 #include "d3dhal.h"
14
15
16 HRESULT WINAPI
17 StartDirectDraw(LPDIRECTDRAW* iface)
18 {
19 IDirectDrawImpl* This = (IDirectDrawImpl*)iface;
20 DWORD hal_ret;
21 DWORD hel_ret;
22 DEVMODE devmode;
23 HBITMAP hbmp;
24 const UINT bmiSize = sizeof(BITMAPINFOHEADER) + 0x10;
25 UCHAR *pbmiData;
26 BITMAPINFO *pbmi;
27 DWORD *pMasks;
28 DWORD Flags;
29
30 DX_WINDBG_trace();
31
32 RtlZeroMemory(&This->mDDrawGlobal, sizeof(DDRAWI_DIRECTDRAW_GBL));
33
34 /* cObsolete is undoc in msdn it being use in CreateDCA */
35 RtlCopyMemory(&This->mDDrawGlobal.cObsolete,&"DISPLAY",7);
36 RtlCopyMemory(&This->mDDrawGlobal.cDriverName,&"DISPLAY",7);
37
38 /* Same for HEL and HAL */
39 This->mcModeInfos = 1;
40 This->mpModeInfos = (DDHALMODEINFO*) DxHeapMemAlloc(This->mcModeInfos * sizeof(DDHALMODEINFO));
41
42 if (This->mpModeInfos == NULL)
43 {
44 DX_STUB_str("DD_FALSE");
45 return DD_FALSE;
46 }
47
48 EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &devmode);
49
50 This->mpModeInfos[0].dwWidth = devmode.dmPelsWidth;
51 This->mpModeInfos[0].dwHeight = devmode.dmPelsHeight;
52 This->mpModeInfos[0].dwBPP = devmode.dmBitsPerPel;
53 This->mpModeInfos[0].lPitch = (devmode.dmPelsWidth*devmode.dmBitsPerPel)/8;
54 This->mpModeInfos[0].wRefreshRate = (WORD)devmode.dmDisplayFrequency;
55
56 This->hdc = CreateDCW(L"DISPLAY",L"DISPLAY",NULL,NULL);
57
58 if (This->hdc == NULL)
59 {
60 DX_STUB_str("DDERR_OUTOFMEMORY");
61 return DDERR_OUTOFMEMORY ;
62 }
63
64 hbmp = CreateCompatibleBitmap(This->hdc, 1, 1);
65 if (hbmp==NULL)
66 {
67 DxHeapMemFree(This->mpModeInfos);
68 DeleteDC(This->hdc);
69 DX_STUB_str("DDERR_OUTOFMEMORY");
70 return DDERR_OUTOFMEMORY;
71 }
72
73 pbmiData = (UCHAR *) DxHeapMemAlloc(bmiSize);
74 pbmi = (BITMAPINFO*)pbmiData;
75
76 if (pbmiData==NULL)
77 {
78 DxHeapMemFree(This->mpModeInfos);
79 DeleteDC(This->hdc);
80 DeleteObject(hbmp);
81 DX_STUB_str("DDERR_OUTOFMEMORY");
82 return DDERR_OUTOFMEMORY;
83 }
84
85 pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
86 pbmi->bmiHeader.biBitCount = (WORD)devmode.dmBitsPerPel;
87 pbmi->bmiHeader.biCompression = BI_BITFIELDS;
88 pbmi->bmiHeader.biWidth = 1;
89 pbmi->bmiHeader.biHeight = 1;
90
91 GetDIBits(This->hdc, hbmp, 0, 0, NULL, pbmi, 0);
92 DeleteObject(hbmp);
93
94 pMasks = (DWORD*)(pbmiData + sizeof(BITMAPINFOHEADER));
95 This->mpModeInfos[0].dwRBitMask = pMasks[0];
96 This->mpModeInfos[0].dwGBitMask = pMasks[1];
97 This->mpModeInfos[0].dwBBitMask = pMasks[2];
98 This->mpModeInfos[0].dwAlphaBitMask = pMasks[3];
99
100 DxHeapMemFree(pbmiData);
101
102 /* Startup HEL and HAL */
103 RtlZeroMemory(&This->mDDrawGlobal, sizeof(DDRAWI_DIRECTDRAW_GBL));
104 RtlZeroMemory(&This->mHALInfo, sizeof(DDHALINFO));
105 RtlZeroMemory(&This->mCallbacks, sizeof(DDHAL_CALLBACKS));
106
107 This->mDDrawLocal.lpDDCB = &This->mCallbacks;
108 This->mDDrawLocal.lpGbl = &This->mDDrawGlobal;
109 This->mDDrawLocal.dwProcessId = GetCurrentProcessId();
110
111 This->mDDrawGlobal.lpDDCBtmp = &This->mCallbacks;
112 This->mDDrawGlobal.lpExclusiveOwner = &This->mDDrawLocal;
113
114 hal_ret = StartDirectDrawHal(iface);
115 hel_ret = StartDirectDrawHel(iface);
116 if ((hal_ret!=DD_OK) && (hel_ret!=DD_OK))
117 {
118 DX_STUB_str("DDERR_NODIRECTDRAWSUPPORT");
119 return DDERR_NODIRECTDRAWSUPPORT;
120 }
121
122 /*
123 Setup HEL or HAL for DD_CALLBACKS
124 */
125
126 This->mDdCanCreateSurface.lpDD = &This->mDDrawGlobal;
127 This->mDdCreatePalette.lpDD = &This->mDDrawGlobal;
128 This->mDdCreateSurface.lpDD = &This->mDDrawGlobal;
129 This->mDdFlipToGDISurface.lpDD = &This->mDDrawGlobal;
130 This->mDdDestroyDriver.lpDD = &This->mDDrawGlobal;
131 This->mDdGetScanLine.lpDD = &This->mDDrawGlobal;
132 This->mDdSetExclusiveMode.lpDD = &This->mDDrawGlobal;
133 This->mDdSetMode.lpDD = &This->mDDrawGlobal;
134 This->mDdWaitForVerticalBlank.lpDD = &This->mDDrawGlobal;
135 This->mDdSetColorKey.lpDD = &This->mDDrawGlobal;
136
137 if (This->devicetype!=1)
138 {
139 /* both or only hel */
140 This->mDdCanCreateSurface.CanCreateSurface = This->mCallbacks.HELDD.CanCreateSurface;
141 This->mDdCreatePalette.CreatePalette = This->mCallbacks.HELDD.CreatePalette;
142 This->mDdCreateSurface.CreateSurface = This->mCallbacks.HELDD.CreateSurface;
143 This->mDdDestroyDriver.DestroyDriver = This->mCallbacks.HELDD.DestroyDriver;
144 This->mDdFlipToGDISurface.FlipToGDISurface = This->mCallbacks.HELDD.FlipToGDISurface;
145 This->mDdGetScanLine.GetScanLine = This->mCallbacks.HELDD.GetScanLine;
146 This->mDdSetExclusiveMode.SetExclusiveMode = This->mCallbacks.HELDD.SetExclusiveMode;
147 This->mDdSetMode.SetMode = This->mCallbacks.HELDD.SetMode;
148 This->mDdWaitForVerticalBlank.WaitForVerticalBlank = This->mCallbacks.HELDD.WaitForVerticalBlank;
149 // This->mDdSetColorKey.SetColorKey = This->mCallbacks.HELDD.SetColorKey;
150 }
151
152 if (This->devicetype!=2)
153 {
154 Flags = This->mDDrawGlobal.lpDDCBtmp->HALDD.dwFlags;
155 if (Flags & DDHAL_CB32_CANCREATESURFACE)
156 {
157 This->mDdCanCreateSurface.CanCreateSurface = This->mCallbacks.HALDD.CanCreateSurface;
158 }
159
160 if (Flags & DDHAL_CB32_CREATEPALETTE)
161 {
162 This->mDdCreatePalette.CreatePalette = This->mCallbacks.HALDD.CreatePalette;
163 }
164
165 if (Flags & DDHAL_CB32_CREATESURFACE)
166 {
167 This->mDdCreateSurface.CreateSurface = This->mCallbacks.HALDD.CreateSurface;
168 }
169
170 if (Flags & DDHAL_CB32_DESTROYDRIVER)
171 {
172 This->mDdDestroyDriver.DestroyDriver = This->mCallbacks.HALDD.DestroyDriver;
173 }
174
175 if (Flags & DDHAL_CB32_FLIPTOGDISURFACE)
176 {
177 This->mDdFlipToGDISurface.FlipToGDISurface = This->mCallbacks.HALDD.FlipToGDISurface;
178 }
179
180 if (Flags & DDHAL_CB32_GETSCANLINE)
181 {
182 This->mDdGetScanLine.GetScanLine = This->mCallbacks.HALDD.GetScanLine;
183 }
184
185 if (Flags & DDHAL_CB32_SETEXCLUSIVEMODE)
186 {
187 This->mDdSetExclusiveMode.SetExclusiveMode = This->mCallbacks.HALDD.SetExclusiveMode;
188 }
189
190 if (Flags & DDHAL_CB32_SETMODE)
191 {
192 This->mDdSetMode.SetMode = This->mCallbacks.HALDD.SetMode;
193 }
194
195 if (Flags & DDHAL_CB32_WAITFORVERTICALBLANK)
196 {
197 This->mDdWaitForVerticalBlank.WaitForVerticalBlank = This->mCallbacks.HALDD.WaitForVerticalBlank;
198 }
199
200 if (Flags & DDHAL_CB32_SETCOLORKEY)
201 {
202 // This->mDdSetColorKey.SetColorKey = This->mCallbacks.HALDD.SetColorKey;
203 }
204 }
205
206 /*
207 Setup HEL or HAL for SURFACE CALLBACK
208 */
209
210 // FIXME
211
212 /* Setup calback struct so we do not need refill same info again */
213 This->mDdCreateSurface.lpDD = &This->mDDrawGlobal;
214 This->mDdCanCreateSurface.lpDD = &This->mDDrawGlobal;
215
216 return DD_OK;
217 }
218
219
220 HRESULT WINAPI
221 StartDirectDrawHal(LPDIRECTDRAW* iface)
222 {
223 IDirectDrawImpl* This = (IDirectDrawImpl*)iface;
224
225 /* HAL Startup process */
226 BOOL newmode = FALSE;
227
228
229 /*
230 Startup DX HAL step one of three
231 */
232 if (!DdCreateDirectDrawObject(&This->mDDrawGlobal, This->hdc))
233 {
234 DxHeapMemFree(This->mpModeInfos);
235 DeleteDC(This->hdc);
236 return DD_FALSE;
237 }
238
239 // Do not relase HDC it have been map in kernel mode
240 // DeleteDC(hdc);
241
242 if (!DdReenableDirectDrawObject(&This->mDDrawGlobal, &newmode))
243 {
244 DxHeapMemFree(This->mpModeInfos);
245 DeleteDC(This->hdc);
246 return DD_FALSE;
247 }
248
249
250 /*
251 Startup DX HAL step two of three
252 */
253
254 if (!DdQueryDirectDrawObject(&This->mDDrawGlobal,
255 &This->mHALInfo,
256 &This->mCallbacks.HALDD,
257 &This->mCallbacks.HALDDSurface,
258 &This->mCallbacks.HALDDPalette,
259 &This->mD3dCallbacks,
260 &This->mD3dDriverData,
261 &This->mD3dBufferCallbacks,
262 NULL,
263 NULL,
264 NULL))
265 {
266 DxHeapMemFree(This->mpModeInfos);
267 DeleteDC(This->hdc);
268 // FIXME Close DX fristcall and second call
269 return DD_FALSE;
270 }
271
272 This->mcvmList = This->mHALInfo.vmiData.dwNumHeaps;
273 This->mpvmList = (VIDMEM*) DxHeapMemAlloc(sizeof(VIDMEM) * This->mcvmList);
274 if (This->mpvmList == NULL)
275 {
276 DxHeapMemFree(This->mpModeInfos);
277 DeleteDC(This->hdc);
278 // FIXME Close DX fristcall and second call
279 return DD_FALSE;
280 }
281
282 This->mcFourCC = This->mHALInfo.ddCaps.dwNumFourCCCodes;
283 This->mpFourCC = (DWORD *) DxHeapMemAlloc(sizeof(DWORD) * This->mcFourCC);
284 if (This->mpFourCC == NULL)
285 {
286 DxHeapMemFree(This->mpvmList);
287 DxHeapMemFree(This->mpModeInfos);
288 DeleteDC(This->hdc);
289 // FIXME Close DX fristcall and second call
290 return DD_FALSE;
291 }
292
293 This->mcTextures = This->mD3dDriverData.dwNumTextureFormats;
294 This->mpTextures = (DDSURFACEDESC*) DxHeapMemAlloc(sizeof(DDSURFACEDESC) * This->mcTextures);
295 if (This->mpTextures == NULL)
296 {
297 DxHeapMemFree( This->mpFourCC);
298 DxHeapMemFree( This->mpvmList);
299 DxHeapMemFree( This->mpModeInfos);
300 DeleteDC(This->hdc);
301 // FIXME Close DX fristcall and second call
302 return DD_FALSE;
303 }
304
305 This->mHALInfo.vmiData.pvmList = This->mpvmList;
306 This->mHALInfo.lpdwFourCC = This->mpFourCC;
307 This->mD3dDriverData.lpTextureFormats = (DDSURFACEDESC*) This->mpTextures;
308
309 if (!DdQueryDirectDrawObject(
310 &This->mDDrawGlobal,
311 &This->mHALInfo,
312 &This->mCallbacks.HALDD,
313 &This->mCallbacks.HALDDSurface,
314 &This->mCallbacks.HALDDPalette,
315 &This->mD3dCallbacks,
316 &This->mD3dDriverData,
317 &This->mCallbacks.HALDDExeBuf,
318 (DDSURFACEDESC*)This->mpTextures,
319 This->mpFourCC,
320 This->mpvmList))
321
322 {
323 DxHeapMemFree(This->mpTextures);
324 DxHeapMemFree(This->mpFourCC);
325 DxHeapMemFree(This->mpvmList);
326 DxHeapMemFree(This->mpModeInfos);
327 DeleteDC(This->hdc);
328 // FIXME Close DX fristcall and second call
329 return DD_FALSE;
330 }
331
332 /*
333 Copy over from HalInfo to DirectDrawGlobal
334 */
335
336 // this is wrong, cDriverName need be in ASC code not UNICODE
337 //memcpy(mDDrawGlobal.cDriverName, mDisplayAdapter, sizeof(wchar)*MAX_DRIVER_NAME);
338
339 memcpy(&This->mDDrawGlobal.vmiData, &This->mHALInfo.vmiData,sizeof(VIDMEMINFO));
340 memcpy(&This->mDDrawGlobal.ddCaps, &This->mHALInfo.ddCaps,sizeof(DDCORECAPS));
341
342 This->mHALInfo.dwNumModes = This->mcModeInfos;
343 This->mHALInfo.lpModeInfo = This->mpModeInfos;
344 This->mHALInfo.dwMonitorFrequency = This->mpModeInfos[0].wRefreshRate;
345
346 This->mDDrawGlobal.dwMonitorFrequency = This->mHALInfo.dwMonitorFrequency;
347 This->mDDrawGlobal.dwModeIndex = This->mHALInfo.dwModeIndex;
348 This->mDDrawGlobal.dwNumModes = This->mHALInfo.dwNumModes;
349 This->mDDrawGlobal.lpModeInfo = This->mHALInfo.lpModeInfo;
350 This->mDDrawGlobal.hInstance = This->mHALInfo.hInstance;
351
352 This->mDDrawGlobal.lp16DD = &This->mDDrawGlobal;
353
354 //DeleteDC(This->hdc);
355
356 DDHAL_GETDRIVERINFODATA DriverInfo;
357 memset(&DriverInfo,0, sizeof(DDHAL_GETDRIVERINFODATA));
358 DriverInfo.dwSize = sizeof(DDHAL_GETDRIVERINFODATA);
359 DriverInfo.dwContext = This->mDDrawGlobal.hDD;
360
361 /* Get the MiscellaneousCallbacks */
362 DriverInfo.guidInfo = GUID_MiscellaneousCallbacks;
363 DriverInfo.lpvData = &This->mDDrawGlobal.lpDDCBtmp->HALDDMiscellaneous;
364 DriverInfo.dwExpectedSize = sizeof(DDHAL_DDMISCELLANEOUSCALLBACKS);
365 This->mHALInfo.GetDriverInfo(&DriverInfo);
366
367 if (This->mDDrawGlobal.lpDDCBtmp->HALDDMiscellaneous.dwFlags & DDHAL_MISCCB32_GETAVAILDRIVERMEMORY)
368 {
369 This->mDdGetDriverMemory.GetAvailDriverMemory = This->mDDrawGlobal.lpDDCBtmp->HALDDMiscellaneous.GetAvailDriverMemory;
370 }
371
372 /* Setup global surface */
373 /*This->mPrimaryGlobal.dwGlobalFlags = DDRAWISURFGBL_ISGDISURFACE;
374 This->mPrimaryGlobal.lpDD = &This->mDDrawGlobal;
375 This->mPrimaryGlobal.lpDDHandle = &This->mDDrawGlobal;
376 This->mPrimaryGlobal.wWidth = (WORD)This->mpModeInfos[0].dwWidth;
377 This->mPrimaryGlobal.wHeight = (WORD)This->mpModeInfos[0].dwHeight;
378 This->mPrimaryGlobal.lPitch = This->mpModeInfos[0].lPitch;*/
379
380 /* FIXME free it in cleanup */
381 This->mDDrawGlobal.dsList = (LPDDRAWI_DDRAWSURFACE_INT)DxHeapMemAlloc(sizeof(DDRAWI_DDRAWSURFACE_INT));
382 return DD_OK;
383 }
384
385 HRESULT WINAPI
386 StartDirectDrawHel(LPDIRECTDRAW* iface)
387 {
388 IDirectDrawImpl* This = (IDirectDrawImpl*)iface;
389
390 This->HELMemoryAvilable = HEL_GRAPHIC_MEMORY_MAX;
391
392 This->mCallbacks.HELDD.dwFlags = DDHAL_CB32_DESTROYDRIVER;
393 This->mCallbacks.HELDD.DestroyDriver = HelDdDestroyDriver;
394
395 This->mCallbacks.HELDD.dwFlags += DDHAL_CB32_CREATESURFACE;
396 This->mCallbacks.HELDD.CreateSurface = HelDdCreateSurface;
397
398 // DDHAL_CB32_
399 //This->mCallbacks.HELDD.SetColorKey = HelDdSetColorKey;
400
401 This->mCallbacks.HELDD.dwFlags += DDHAL_CB32_SETMODE;
402 This->mCallbacks.HELDD.SetMode = HelDdSetMode;
403
404 This->mCallbacks.HELDD.dwFlags += DDHAL_CB32_WAITFORVERTICALBLANK;
405 This->mCallbacks.HELDD.WaitForVerticalBlank = HelDdWaitForVerticalBlank;
406
407 This->mCallbacks.HELDD.dwFlags += DDHAL_CB32_CANCREATESURFACE;
408 This->mCallbacks.HELDD.CanCreateSurface = HelDdCanCreateSurface;
409
410 This->mCallbacks.HELDD.dwFlags += DDHAL_CB32_CREATEPALETTE;
411 This->mCallbacks.HELDD.CreatePalette = HelDdCreatePalette;
412
413 This->mCallbacks.HELDD.dwFlags += DDHAL_CB32_GETSCANLINE;
414 This->mCallbacks.HELDD.GetScanLine = HelDdGetScanLine;
415
416 This->mCallbacks.HELDD.dwFlags += DDHAL_CB32_SETEXCLUSIVEMODE;
417 This->mCallbacks.HELDD.SetExclusiveMode = HelDdSetExclusiveMode;
418
419 This->mCallbacks.HELDD.dwFlags += DDHAL_CB32_FLIPTOGDISURFACE;
420 This->mCallbacks.HELDD.FlipToGDISurface = HelDdFlipToGDISurface;
421
422 return DD_OK;
423 }
424
425 HRESULT
426 WINAPI
427 Create_DirectDraw (LPGUID pGUID,
428 LPDIRECTDRAW* pIface,
429 REFIID id,
430 BOOL ex)
431 {
432 IDirectDrawImpl* This = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectDrawImpl));
433
434 DX_WINDBG_trace();
435
436 if (This == NULL)
437 {
438 return E_OUTOFMEMORY;
439 }
440
441 ZeroMemory(This,sizeof(IDirectDrawImpl));
442
443 This->lpVtbl = &DirectDraw7_Vtable;
444 This->lpVtbl_v1 = &DDRAW_IDirectDraw_VTable;
445 This->lpVtbl_v2 = &DDRAW_IDirectDraw2_VTable;
446 This->lpVtbl_v4 = &DDRAW_IDirectDraw4_VTable;
447
448 *pIface = (LPDIRECTDRAW)This;
449
450 This->devicetype = 0;
451
452 if (pGUID == (LPGUID) DDCREATE_HARDWAREONLY)
453 {
454 This->devicetype = 1; /* hal only */
455 }
456
457 if (pGUID == (LPGUID) DDCREATE_EMULATIONONLY)
458 {
459 This->devicetype = 2; /* hel only */
460 }
461
462 if(This->lpVtbl->QueryInterface ((LPDIRECTDRAW7)This, id, (void**)&pIface) != S_OK)
463 {
464 return DDERR_INVALIDPARAMS;
465 }
466
467 if (StartDirectDraw((LPDIRECTDRAW*)This) == DD_OK);
468 {
469 return This->lpVtbl->Initialize ((LPDIRECTDRAW7)This, pGUID);
470 }
471
472 return DDERR_INVALIDPARAMS;
473 }
474