1 /* $Id: main.c 21434 2006-04-01 19:12:56Z greatlrd $
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)
17 StartDirectDraw(LPDIRECTDRAW
* iface
)
19 IDirectDrawImpl
* This
= (IDirectDrawImpl
*)iface
;
24 const UINT bmiSize
= sizeof(BITMAPINFOHEADER
) + 0x10;
32 RtlZeroMemory(&This
->mDDrawGlobal
, sizeof(DDRAWI_DIRECTDRAW_GBL
));
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);
38 /* Same for HEL and HAL */
39 This
->mcModeInfos
= 1;
40 This
->mpModeInfos
= (DDHALMODEINFO
*) DxHeapMemAlloc(This
->mcModeInfos
* sizeof(DDHALMODEINFO
));
42 if (This
->mpModeInfos
== NULL
)
44 DX_STUB_str("DD_FALSE");
48 EnumDisplaySettings(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
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
;
56 if ( This
->devicetype
<3 )
58 /* Create HDC for default, hal and hel driver */
59 This
->hdc
= CreateDCW(L
"DISPLAY",L
"DISPLAY",NULL
,NULL
);
63 /* FIXME : need getting driver from the GUID that have been pass in from
64 the register. we do not support that yet
70 if (This
->hdc
== NULL
)
72 DX_STUB_str("DDERR_OUTOFMEMORY");
73 return DDERR_OUTOFMEMORY
;
76 hbmp
= CreateCompatibleBitmap(This
->hdc
, 1, 1);
79 DxHeapMemFree(This
->mpModeInfos
);
81 DX_STUB_str("DDERR_OUTOFMEMORY");
82 return DDERR_OUTOFMEMORY
;
85 pbmiData
= (UCHAR
*) DxHeapMemAlloc(bmiSize
);
86 pbmi
= (BITMAPINFO
*)pbmiData
;
90 DxHeapMemFree(This
->mpModeInfos
);
93 DX_STUB_str("DDERR_OUTOFMEMORY");
94 return DDERR_OUTOFMEMORY
;
97 pbmi
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
98 pbmi
->bmiHeader
.biBitCount
= (WORD
)devmode
.dmBitsPerPel
;
99 pbmi
->bmiHeader
.biCompression
= BI_BITFIELDS
;
100 pbmi
->bmiHeader
.biWidth
= 1;
101 pbmi
->bmiHeader
.biHeight
= 1;
103 GetDIBits(This
->hdc
, hbmp
, 0, 0, NULL
, pbmi
, 0);
106 pMasks
= (DWORD
*)(pbmiData
+ sizeof(BITMAPINFOHEADER
));
107 This
->mpModeInfos
[0].dwRBitMask
= pMasks
[0];
108 This
->mpModeInfos
[0].dwGBitMask
= pMasks
[1];
109 This
->mpModeInfos
[0].dwBBitMask
= pMasks
[2];
110 This
->mpModeInfos
[0].dwAlphaBitMask
= pMasks
[3];
112 DxHeapMemFree(pbmiData
);
114 /* Startup HEL and HAL */
115 RtlZeroMemory(&This
->mDDrawGlobal
, sizeof(DDRAWI_DIRECTDRAW_GBL
));
116 RtlZeroMemory(&This
->mHALInfo
, sizeof(DDHALINFO
));
117 RtlZeroMemory(&This
->mCallbacks
, sizeof(DDHAL_CALLBACKS
));
119 This
->mDDrawLocal
.lpDDCB
= &This
->mCallbacks
;
120 This
->mDDrawLocal
.lpGbl
= &This
->mDDrawGlobal
;
121 This
->mDDrawLocal
.dwProcessId
= GetCurrentProcessId();
123 This
->mDDrawGlobal
.lpDDCBtmp
= &This
->mCallbacks
;
124 This
->mDDrawGlobal
.lpExclusiveOwner
= &This
->mDDrawLocal
;
126 hal_ret
= StartDirectDrawHal(iface
);
127 hel_ret
= StartDirectDrawHel(iface
);
128 if ((hal_ret
!=DD_OK
) && (hel_ret
!=DD_OK
))
130 DX_STUB_str("DDERR_NODIRECTDRAWSUPPORT");
131 return DDERR_NODIRECTDRAWSUPPORT
;
135 Setup HEL or HAL for DD_CALLBACKS
138 This
->mDdCanCreateSurface
.lpDD
= &This
->mDDrawGlobal
;
139 This
->mDdCreatePalette
.lpDD
= &This
->mDDrawGlobal
;
140 This
->mDdCreateSurface
.lpDD
= &This
->mDDrawGlobal
;
141 This
->mDdFlipToGDISurface
.lpDD
= &This
->mDDrawGlobal
;
142 This
->mDdDestroyDriver
.lpDD
= &This
->mDDrawGlobal
;
143 This
->mDdGetScanLine
.lpDD
= &This
->mDDrawGlobal
;
144 This
->mDdSetExclusiveMode
.lpDD
= &This
->mDDrawGlobal
;
145 This
->mDdSetMode
.lpDD
= &This
->mDDrawGlobal
;
146 This
->mDdWaitForVerticalBlank
.lpDD
= &This
->mDDrawGlobal
;
147 This
->mDdSetColorKey
.lpDD
= &This
->mDDrawGlobal
;
149 if (This
->devicetype
!=1)
151 /* both or only hel */
152 This
->mDdCanCreateSurface
.CanCreateSurface
= This
->mCallbacks
.HELDD
.CanCreateSurface
;
153 This
->mDdCreatePalette
.CreatePalette
= This
->mCallbacks
.HELDD
.CreatePalette
;
154 This
->mDdCreateSurface
.CreateSurface
= This
->mCallbacks
.HELDD
.CreateSurface
;
155 This
->mDdDestroyDriver
.DestroyDriver
= This
->mCallbacks
.HELDD
.DestroyDriver
;
156 This
->mDdFlipToGDISurface
.FlipToGDISurface
= This
->mCallbacks
.HELDD
.FlipToGDISurface
;
157 This
->mDdGetScanLine
.GetScanLine
= This
->mCallbacks
.HELDD
.GetScanLine
;
158 This
->mDdSetExclusiveMode
.SetExclusiveMode
= This
->mCallbacks
.HELDD
.SetExclusiveMode
;
159 This
->mDdSetMode
.SetMode
= This
->mCallbacks
.HELDD
.SetMode
;
160 This
->mDdWaitForVerticalBlank
.WaitForVerticalBlank
= This
->mCallbacks
.HELDD
.WaitForVerticalBlank
;
161 // This->mDdSetColorKey.SetColorKey = This->mCallbacks.HELDD.SetColorKey;
164 if (This
->devicetype
!=2)
166 Flags
= This
->mDDrawGlobal
.lpDDCBtmp
->HALDD
.dwFlags
;
167 if (Flags
& DDHAL_CB32_CANCREATESURFACE
)
169 This
->mDdCanCreateSurface
.CanCreateSurface
= This
->mCallbacks
.HALDD
.CanCreateSurface
;
172 if (Flags
& DDHAL_CB32_CREATEPALETTE
)
174 This
->mDdCreatePalette
.CreatePalette
= This
->mCallbacks
.HALDD
.CreatePalette
;
177 if (Flags
& DDHAL_CB32_CREATESURFACE
)
179 This
->mDdCreateSurface
.CreateSurface
= This
->mCallbacks
.HALDD
.CreateSurface
;
182 if (Flags
& DDHAL_CB32_DESTROYDRIVER
)
184 This
->mDdDestroyDriver
.DestroyDriver
= This
->mCallbacks
.HALDD
.DestroyDriver
;
187 if (Flags
& DDHAL_CB32_FLIPTOGDISURFACE
)
189 This
->mDdFlipToGDISurface
.FlipToGDISurface
= This
->mCallbacks
.HALDD
.FlipToGDISurface
;
192 if (Flags
& DDHAL_CB32_GETSCANLINE
)
194 This
->mDdGetScanLine
.GetScanLine
= This
->mCallbacks
.HALDD
.GetScanLine
;
197 if (Flags
& DDHAL_CB32_SETEXCLUSIVEMODE
)
199 This
->mDdSetExclusiveMode
.SetExclusiveMode
= This
->mCallbacks
.HALDD
.SetExclusiveMode
;
202 if (Flags
& DDHAL_CB32_SETMODE
)
204 This
->mDdSetMode
.SetMode
= This
->mCallbacks
.HALDD
.SetMode
;
207 if (Flags
& DDHAL_CB32_WAITFORVERTICALBLANK
)
209 This
->mDdWaitForVerticalBlank
.WaitForVerticalBlank
= This
->mCallbacks
.HALDD
.WaitForVerticalBlank
;
212 if (Flags
& DDHAL_CB32_SETCOLORKEY
)
214 // This->mDdSetColorKey.SetColorKey = This->mCallbacks.HALDD.SetColorKey;
219 Setup HEL or HAL for SURFACE CALLBACK
224 /* Setup calback struct so we do not need refill same info again */
225 This
->mDdCreateSurface
.lpDD
= &This
->mDDrawGlobal
;
226 This
->mDdCanCreateSurface
.lpDD
= &This
->mDDrawGlobal
;
228 This
->mDDrawLocal
.lpGbl
= &This
->mDDrawGlobal
;
234 StartDirectDrawHal(LPDIRECTDRAW
* iface
)
236 IDirectDrawImpl
* This
= (IDirectDrawImpl
*)iface
;
237 DDHAL_GETDRIVERINFODATA DriverInfo
;
239 /* HAL Startup process */
240 BOOL newmode
= FALSE
;
244 Startup DX HAL step one of three
246 if (!DdCreateDirectDrawObject(&This
->mDDrawGlobal
, This
->hdc
))
248 DxHeapMemFree(This
->mpModeInfos
);
253 // Do not relase HDC it have been map in kernel mode
256 if (!DdReenableDirectDrawObject(&This
->mDDrawGlobal
, &newmode
))
258 DxHeapMemFree(This
->mpModeInfos
);
265 Startup DX HAL step two of three
268 if (!DdQueryDirectDrawObject(&This
->mDDrawGlobal
,
270 &This
->mCallbacks
.HALDD
,
271 &This
->mCallbacks
.HALDDSurface
,
272 &This
->mCallbacks
.HALDDPalette
,
273 &This
->mD3dCallbacks
,
274 &This
->mD3dDriverData
,
275 &This
->mD3dBufferCallbacks
,
280 DxHeapMemFree(This
->mpModeInfos
);
282 // FIXME Close DX fristcall and second call
286 This
->mcvmList
= This
->mHALInfo
.vmiData
.dwNumHeaps
;
287 This
->mpvmList
= (VIDMEM
*) DxHeapMemAlloc(sizeof(VIDMEM
) * This
->mcvmList
);
288 if (This
->mpvmList
== NULL
)
290 DxHeapMemFree(This
->mpModeInfos
);
292 // FIXME Close DX fristcall and second call
296 This
->mcFourCC
= This
->mHALInfo
.ddCaps
.dwNumFourCCCodes
;
297 This
->mpFourCC
= (DWORD
*) DxHeapMemAlloc(sizeof(DWORD
) * This
->mcFourCC
);
298 if (This
->mpFourCC
== NULL
)
300 DxHeapMemFree(This
->mpvmList
);
301 DxHeapMemFree(This
->mpModeInfos
);
303 // FIXME Close DX fristcall and second call
307 This
->mcTextures
= This
->mD3dDriverData
.dwNumTextureFormats
;
308 This
->mpTextures
= (DDSURFACEDESC
*) DxHeapMemAlloc(sizeof(DDSURFACEDESC
) * This
->mcTextures
);
309 if (This
->mpTextures
== NULL
)
311 DxHeapMemFree( This
->mpFourCC
);
312 DxHeapMemFree( This
->mpvmList
);
313 DxHeapMemFree( This
->mpModeInfos
);
315 // FIXME Close DX fristcall and second call
319 This
->mHALInfo
.vmiData
.pvmList
= This
->mpvmList
;
320 This
->mHALInfo
.lpdwFourCC
= This
->mpFourCC
;
321 This
->mD3dDriverData
.lpTextureFormats
= (DDSURFACEDESC
*) This
->mpTextures
;
323 if (!DdQueryDirectDrawObject(
326 &This
->mCallbacks
.HALDD
,
327 &This
->mCallbacks
.HALDDSurface
,
328 &This
->mCallbacks
.HALDDPalette
,
329 &This
->mD3dCallbacks
,
330 &This
->mD3dDriverData
,
331 &This
->mCallbacks
.HALDDExeBuf
,
332 (DDSURFACEDESC
*)This
->mpTextures
,
337 DxHeapMemFree(This
->mpTextures
);
338 DxHeapMemFree(This
->mpFourCC
);
339 DxHeapMemFree(This
->mpvmList
);
340 DxHeapMemFree(This
->mpModeInfos
);
342 // FIXME Close DX fristcall and second call
347 Copy over from HalInfo to DirectDrawGlobal
350 // this is wrong, cDriverName need be in ASC code not UNICODE
351 //memcpy(mDDrawGlobal.cDriverName, mDisplayAdapter, sizeof(wchar)*MAX_DRIVER_NAME);
353 memcpy(&This
->mDDrawGlobal
.vmiData
, &This
->mHALInfo
.vmiData
,sizeof(VIDMEMINFO
));
354 memcpy(&This
->mDDrawGlobal
.ddCaps
, &This
->mHALInfo
.ddCaps
,sizeof(DDCORECAPS
));
356 This
->mHALInfo
.dwNumModes
= This
->mcModeInfos
;
357 This
->mHALInfo
.lpModeInfo
= This
->mpModeInfos
;
358 This
->mHALInfo
.dwMonitorFrequency
= This
->mpModeInfos
[0].wRefreshRate
;
360 This
->mDDrawGlobal
.dwMonitorFrequency
= This
->mHALInfo
.dwMonitorFrequency
;
361 This
->mDDrawGlobal
.dwModeIndex
= This
->mHALInfo
.dwModeIndex
;
362 This
->mDDrawGlobal
.dwNumModes
= This
->mHALInfo
.dwNumModes
;
363 This
->mDDrawGlobal
.lpModeInfo
= This
->mHALInfo
.lpModeInfo
;
364 This
->mDDrawGlobal
.hInstance
= This
->mHALInfo
.hInstance
;
366 This
->mDDrawGlobal
.lp16DD
= &This
->mDDrawGlobal
;
368 //DeleteDC(This->hdc);
371 memset(&DriverInfo
,0, sizeof(DDHAL_GETDRIVERINFODATA
));
372 DriverInfo
.dwSize
= sizeof(DDHAL_GETDRIVERINFODATA
);
373 DriverInfo
.dwContext
= This
->mDDrawGlobal
.hDD
;
375 /* Get the MiscellaneousCallbacks */
376 DriverInfo
.guidInfo
= GUID_MiscellaneousCallbacks
;
377 DriverInfo
.lpvData
= &This
->mDDrawGlobal
.lpDDCBtmp
->HALDDMiscellaneous
;
378 DriverInfo
.dwExpectedSize
= sizeof(DDHAL_DDMISCELLANEOUSCALLBACKS
);
379 This
->mHALInfo
.GetDriverInfo(&DriverInfo
);
381 /* Setup global surface */
382 /*This->mPrimaryGlobal.dwGlobalFlags = DDRAWISURFGBL_ISGDISURFACE;
383 This->mPrimaryGlobal.lpDD = &This->mDDrawGlobal;
384 This->mPrimaryGlobal.lpDDHandle = &This->mDDrawGlobal;
385 This->mPrimaryGlobal.wWidth = (WORD)This->mpModeInfos[0].dwWidth;
386 This->mPrimaryGlobal.wHeight = (WORD)This->mpModeInfos[0].dwHeight;
387 This->mPrimaryGlobal.lPitch = This->mpModeInfos[0].lPitch;*/
389 /* FIXME free it in cleanup */
390 // This->mDDrawGlobal.dsList = (LPDDRAWI_DDRAWSURFACE_INT)DxHeapMemAlloc(sizeof(DDRAWI_DDRAWSURFACE_INT));
395 StartDirectDrawHel(LPDIRECTDRAW
* iface
)
397 IDirectDrawImpl
* This
= (IDirectDrawImpl
*)iface
;
399 This
->HELMemoryAvilable
= HEL_GRAPHIC_MEMORY_MAX
;
401 This
->mCallbacks
.HELDD
.dwFlags
= DDHAL_CB32_DESTROYDRIVER
;
402 This
->mCallbacks
.HELDD
.DestroyDriver
= HelDdDestroyDriver
;
404 This
->mCallbacks
.HELDD
.dwFlags
+= DDHAL_CB32_CREATESURFACE
;
405 This
->mCallbacks
.HELDD
.CreateSurface
= HelDdCreateSurface
;
408 //This->mCallbacks.HELDD.SetColorKey = HelDdSetColorKey;
410 This
->mCallbacks
.HELDD
.dwFlags
+= DDHAL_CB32_SETMODE
;
411 This
->mCallbacks
.HELDD
.SetMode
= HelDdSetMode
;
413 This
->mCallbacks
.HELDD
.dwFlags
+= DDHAL_CB32_WAITFORVERTICALBLANK
;
414 This
->mCallbacks
.HELDD
.WaitForVerticalBlank
= HelDdWaitForVerticalBlank
;
416 This
->mCallbacks
.HELDD
.dwFlags
+= DDHAL_CB32_CANCREATESURFACE
;
417 This
->mCallbacks
.HELDD
.CanCreateSurface
= HelDdCanCreateSurface
;
419 This
->mCallbacks
.HELDD
.dwFlags
+= DDHAL_CB32_CREATEPALETTE
;
420 This
->mCallbacks
.HELDD
.CreatePalette
= HelDdCreatePalette
;
422 This
->mCallbacks
.HELDD
.dwFlags
+= DDHAL_CB32_GETSCANLINE
;
423 This
->mCallbacks
.HELDD
.GetScanLine
= HelDdGetScanLine
;
425 This
->mCallbacks
.HELDD
.dwFlags
+= DDHAL_CB32_SETEXCLUSIVEMODE
;
426 This
->mCallbacks
.HELDD
.SetExclusiveMode
= HelDdSetExclusiveMode
;
428 This
->mCallbacks
.HELDD
.dwFlags
+= DDHAL_CB32_FLIPTOGDISURFACE
;
429 This
->mCallbacks
.HELDD
.FlipToGDISurface
= HelDdFlipToGDISurface
;
436 Create_DirectDraw (LPGUID pGUID
,
437 LPDIRECTDRAW
* pIface
,
441 IDirectDrawImpl
* This
;
445 //AcquireDDThreadLock();
447 This
= (IDirectDrawImpl
*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectDrawImpl
));
452 ReleaseDDThreadLock();
453 return E_OUTOFMEMORY
;
457 ZeroMemory(This
,sizeof(IDirectDrawImpl
));
459 This
->lpVtbl
= &DirectDraw7_Vtable
;
460 This
->lpVtbl_v1
= &DDRAW_IDirectDraw_VTable
;
461 This
->lpVtbl_v2
= &DDRAW_IDirectDraw2_VTable
;
462 This
->lpVtbl_v4
= &DDRAW_IDirectDraw4_VTable
;
464 *pIface
= (LPDIRECTDRAW
)This
;
468 This
->devicetype
= 0; /* both hal and hel default driver "DISPLAY" */
470 else if (pGUID
== (LPGUID
) DDCREATE_HARDWAREONLY
)
472 This
->devicetype
= 1; /* hal only default driver "DISPLAY" */
475 else if (pGUID
== (LPGUID
) DDCREATE_EMULATIONONLY
)
477 This
->devicetype
= 2; /* hel only default driver "DISPLAY" */
481 This
->devicetype
= 3; /* Read from the register which driver it should be */
485 if(This
->lpVtbl
->QueryInterface ((LPDIRECTDRAW7
)This
, id
, (void**)&pIface
) != S_OK
)
487 ReleaseDDThreadLock();
488 return DDERR_INVALIDPARAMS
;
491 if (StartDirectDraw((LPDIRECTDRAW
*)This
) == DD_OK
);
493 //ReleaseDDThreadLock();
494 return This
->lpVtbl
->Initialize ((LPDIRECTDRAW7
)This
, pGUID
);
497 //ReleaseDDThreadLock();
498 return DDERR_INVALIDPARAMS
;