Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2169 lines
82 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 1994-1995 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: ddcreate.c
  6. * Content: DirectDraw create object.
  7. * History:
  8. * Date By Reason
  9. * ==== == ======
  10. * 31-dec-94 craige initial implementation
  11. * 13-jan-95 craige re-worked to updated spec + ongoing work
  12. * 21-jan-95 craige made 32-bit + ongoing work
  13. * 13-feb-94 craige allow 32-bit callbacks
  14. * 21-feb-95 craige disconnect anyone who forgot to do it themselves
  15. * 27-feb-95 craige new sync. macros
  16. * 06-mar-95 craige HEL integration
  17. * 08-mar-95 craige new APIs
  18. * 11-mar-95 craige palette stuff
  19. * 15-mar-95 craige more HEL integration
  20. * 19-mar-95 craige use HRESULTs, process termination cleanup fixes
  21. * 27-mar-95 craige linear or rectangular vidmem
  22. * 28-mar-95 craige removed Get/SetColorKey, added FlipToGDISurface
  23. * 29-mar-95 craige reorg to only call driver once per creation, and
  24. * to allow driver to load us first
  25. * 01-apr-95 craige happy fun joy updated header file
  26. * 06-apr-95 craige fill in free video memory
  27. * 09-apr-95 craige fixed deadlock situation with a process having a lock
  28. * on the primary surface while another process starts
  29. * 12-apr-95 craige bug when driver object freed (extra leave csect)
  30. * 13-apr-95 craige EricEng's little contribution to our being late
  31. * 15-apr-95 craige fail load if no DD components present
  32. * 06-may-95 craige use driver-level csects only
  33. * 09-may-95 craige escape call to get 32-bit DLL
  34. * 12-may-95 craige added DirectDrawEnumerate; use GUIDs in DirectDrawCreate
  35. * 14-may-95 craige call DoneExclusiveMode during CurrentProcessCleanup
  36. * 15-may-95 craige restore display mode on a per-process basis
  37. * 19-may-95 craige memory leak on mode change
  38. * 23-may-95 craige added Flush, GetBatchLimit, SetBatchLimit
  39. * 24-may-95 craige plugged another memory leak; allow fourcc codes &
  40. * number of vmem heaps to change
  41. * 26-may-95 craige somebody freed the vmem heaps and then tried to
  42. * free the surfaces!
  43. * 28-may-95 craige unicode support; make sure blt means at least srccopy
  44. * 05-jun-95 craige removed GetVersion, FreeAllSurfaces, DefWindowProc;
  45. * change GarbageCollect to Compact
  46. * 06-jun-95 craige call RestoreDisplayMode
  47. * 07-jun-95 craige removed DCLIST
  48. * 12-jun-95 craige new process list stuff
  49. * 16-jun-95 craige new surface structure
  50. * 18-jun-95 craige specify pitch for rectangular memory; deadlock
  51. * with MemAlloc16 if we don't take the DLL lock
  52. * 25-jun-95 craige one ddraw mutex
  53. * 26-jun-95 craige reorganized surface structure
  54. * 27-jun-95 craige replaced batch limit/flush stuff with BltBatch
  55. * 28-jun-95 craige ENTER_DDRAW at very start of fns
  56. * 02-jul-95 craige new registry format
  57. * 03-jul-95 craige YEEHAW: new driver struct; SEH
  58. * 06-jul-95 craige RemoveFromDriverList was screwing up links
  59. * 07-jul-95 craige added pdevice stuff
  60. * 08-jul-95 craige call InvalidateAllSurfaces
  61. * 10-jul-95 craige support SetOverlayPosition
  62. * 11-jul-95 craige validate pdevice is from a dibeng mini driver;
  63. * fail aggregation calls; one ddraw object/process
  64. * 13-jul-95 craige ENTER_DDRAW is now the win16 lock; need to
  65. * leave Win16 lock while doing ExtEscape calls
  66. * 14-jul-95 craige allow driver to specify heap is already allocated
  67. * 15-jul-95 craige invalid HDC set in emulation only
  68. * 18-jul-95 craige need to initialize dwPreferredMode
  69. * 20-jul-95 craige internal reorg to prevent thunking during modeset
  70. * 20-jul-95 toddla zero DDHALINFO before thunking in case nobody home.
  71. * 22-jul-95 craige emulation only needs to initialize correctly
  72. * 29-jul-95 toddla added DEBUG code to clear driver caps
  73. * 31-jul-95 toddla added DD_HAL_VERSION
  74. * 31-jul-95 craige set DDCAPS_BANKSWITCHED
  75. * 01-aug-95 toddla added dwPDevice to DDRAWI_DIRECTDRAW_GBL
  76. * 10-aug-95 craige validate alignment fields
  77. * 13-aug-95 craige check DD_HAL_VERSION & set DDCAPS2_CERTIFIED
  78. * 21-aug-95 craige mode X support
  79. * 27-aug-95 craige bug 738: use GUID instead of IID
  80. * 05-sep-95 craige bug 814
  81. * 08-sep-95 craige bug 845: reset driver callbacks every time
  82. * 09-sep-95 craige bug 949: don't allow ddraw to run in 4bpp
  83. * bug 951: NULL out fn tables at reset
  84. * 10-sep-95 toddla dont allow DirectDrawCreate to work for < 8bpp mode.
  85. * 10-sep-95 toddla added Message box when DirectDrawCreate fails
  86. * 20-sep-95 craige made primary display desc. a string resource
  87. * 21-sep-95 craige bug 1215: let ddraw16 know about certified for modex
  88. * 21-nov-95 colinmc made Direct3D a queryable interface off DirectDraw
  89. * 27-nov-95 colinmc new member to return available vram of a given type
  90. * (defined by DDSCAPS)
  91. * 05-dec-95 colinmc changed DDSCAPS_TEXTUREMAP => DDSCAPS_TEXTURE for
  92. * consitency with Direct3D
  93. * 09-dec-95 colinmc execute buffer support
  94. * 15-dec-95 colinmc fixed bug setting HAL up for execute buffers
  95. * 25-dec-95 craige added InternalDirectDrawCreate for ClassFactory work
  96. * 31-dec-95 craige more ClassFactory work
  97. * 04-jan-96 kylej add driver interface structures
  98. * 22-jan-96 jeffno NT driver conversation in createSurface.
  99. * Since vidmem ptrs can legally be 0 for kernel, added
  100. * DDRAWISURFACEGBL_ISGDISURFACE and use that to find gdi
  101. * 02-feb-96 kylej Move HAL function pointers to local object
  102. * 28-feb-96 kylej Change DDHALINFO structure
  103. * 02-mar-96 colinmc Repulsive hack to support interim drivers
  104. * 06-mar-96 kylej init HEL even with non-display drivers
  105. * 13-mar-96 craige Bug 7528: hw that doesn't have modex
  106. * 13-mar-96 jeffno Dynamic mode switch support for NT
  107. * Register process IDs with NT kernel stuff
  108. * 16-mar-96 colinmc Callback tables now initialized in dllmain
  109. * 18-mar-96 colinmc Bug 13545: Independent clippers cleanup
  110. * 22-mar-96 colinmc Bug 13316: uninitialized interfaces
  111. * 23-mar-96 colinmc Bug 12252: Direct3D not cleaned up properly on crash
  112. * 14-apr-96 colinmc Bug 17736: No driver notification of flip to GDI
  113. * 16-apr-96 colinmc Bug 17921: Remove interim driver support
  114. * 19-apr-96 colinmc Bug 18059: New caps bit to indicate that driver
  115. * can't interleave 2D and 3D operations during scene
  116. * rendering
  117. * 11-may-96 colinmc Bug 22293: Now validate GUID passed to DirectDraw
  118. * Create in retail as well as debug
  119. * 16-may-96 colinmc Bug 23215: Not checking for a mode index of -1
  120. * on driver initialization
  121. * 27-may-96 kylej Bug 24595: Set Certified bit after call to
  122. * FakeDDCreateDriverObject.
  123. * 26-jun-96 colinmc Bug 2041: DirectDraw needs time bomb
  124. * 22-jul-96 colinmc Work Item: Minimal stackable driver support
  125. * 23-aug-96 craige registry entries for sw only and modex only
  126. * 31-aug-96 colinmc Removed erroneous time bomb
  127. * 03-sep-96 craige App compatibilty stuff
  128. * 01-oct-96 ketand added GetAvailVidMem entrypoint for driver callbacks
  129. * 05-sep-96 colinmc Work Item: Removing the restriction on taking Win16
  130. * lock on VRAM surfaces (not including the primary)
  131. * 10-oct-96 colinmc Refinements of the Win16 locking stuff
  132. * 12-oct-96 colinmc Improvements to Win16 locking code to reduce virtual
  133. * memory usage
  134. * 15-oct-96 toddla support multimonitor
  135. * 09-nov-96 colinmc Fixed problem with old and new drivers not working
  136. * with DirectDraw
  137. * 17-nov-96 colinmc Added ability to use PrintScrn key to snapshot
  138. * DirectDraw applications.
  139. * 08-dec-96 colinmc Initial AGP support
  140. * 21-jan-97 ketand Added a rectMonitor to lpDD_gbl to allow for correct clipping
  141. * on multi-monitor systems.
  142. * 25-jan-97 nwilt Instance GUID in GetDriverInfo struct
  143. * Query for D3DCallbacks2 w/no deps on D3D
  144. * 27-jan-97 colinmc Fixed problem with multi-mon on emulated displays
  145. * 27-jan-97 ketand Multi-mon. Remove bad globals; pass them explicitly. Fix ATTENTIONs.
  146. * 29-jan-97 smac Removed old ring 0 code
  147. * 30-jan-97 colinmc Work item 4125: Add time bomb for beta
  148. * 30-jan-97 jeffno Allow surfaces wider than the primary
  149. * 30-jan-97 ketand Only enumerate secondaries for multi-mon systems.
  150. * 01-feb-97 colinmc Bug 5457: Fixed Win16 lock problem causing hang
  151. * with mutliple AMovie instances on old cards
  152. * 07-feb-97 ketand Zero DisplayDevice struct between calls to EnumDisplayDevices.
  153. * Fix memory leak w.r.t. GetAndValidateNewHalInfo
  154. * 24-feb-97 ketand Update Rects whenever a display change occurs.
  155. * 24-feb-97 ketand Add a dwContext to GetDriverInfoData
  156. * 03-mar-97 smac Added kernel mode interface
  157. * 03-mar-97 jeffno Work item: Extended surface memory alignment
  158. * 08-mar-97 colinmc Added support for DMA style AGP usage
  159. * 11-mar-97 jeffno Asynchronous DMA support
  160. * 11-mar-97 nwilt Fail driver create if driver exports some DrawPrimitive
  161. * exports without exporting all of them.
  162. * 13-mar-97 colinmc Bug 6533: Pass uncached flag to VMM correctly
  163. * 20-mar-97 nwilt #6625 and D3D extended caps
  164. * 24-mar-97 jeffno Optimized Surfaces
  165. * 13-may-97 colinmc AGP support on OSR 2.1 systems
  166. * 26-may-97 nwilt Fail driver create if driver sets D3DDEVCAPS_DRAWPRIMTLVERTEX
  167. * without exporting the callbacks.
  168. * 31-jul-97 jvanaken Bug 7093: Ensure unique HDC for each process/driver pair
  169. * in a multimonitor system.
  170. * 16-sep-97 jeffno DirectDrawEnumerateEx
  171. * 30-sep-97 jeffno IDirectDraw4
  172. * 31-oct-97 johnstep Persistent-content surfaces for Windows 9x
  173. * 05-nov-97 jvanaken Support for master sprite list in SetSpriteDisplayList
  174. *
  175. ***************************************************************************/
  176. extern "C" {
  177. #include "ddrawpr.h"
  178. #ifdef WINNT
  179. #include "ddrawgdi.h"
  180. #define BUILD_DDDDK
  181. #include "d3dhal.h"
  182. #endif
  183. #ifdef WIN95
  184. #include "d3dhal.h"
  185. #endif
  186. } // extern C
  187. #include "pixel.hpp"
  188. #ifdef DEBUG
  189. #define static
  190. #endif
  191. #undef DPF_MODNAME
  192. #define DPF_MODNAME "DirectDrawObjectCreate"
  193. #define DISPLAY_STR "display"
  194. #define D3DFORMAT_OP_BACKBUFFER 0x00000020L
  195. char g_szPrimaryDisplay[MAX_DRIVER_NAME] = "";
  196. void getPrimaryDisplayName(void);
  197. #ifndef WIN16_SEPARATE
  198. #ifdef WIN95
  199. CRITICAL_SECTION ddcCS = {0};
  200. #define ENTER_CSDDC() EnterCriticalSection(&ddcCS)
  201. #define LEAVE_CSDDC() LeaveCriticalSection(&ddcCS)
  202. #else
  203. #define ENTER_CSDDC()
  204. #define LEAVE_CSDDC()
  205. #endif
  206. #else
  207. #define ENTER_CSDDC()
  208. #define LEAVE_CSDDC()
  209. #endif
  210. /*
  211. * DISPLAY_DEVICEA
  212. *
  213. * define a local copy of the structures and constants needed
  214. * to call EnumDisplayDevices
  215. *
  216. */
  217. #ifndef DISPLAY_DEVICE_ATTACHED_TO_DESKTOP
  218. #define DISPLAY_DEVICE_ATTACHED_TO_DESKTOP 0x00000001
  219. #define DISPLAY_DEVICE_MULTI_DRIVER 0x00000002
  220. #define DISPLAY_DEVICE_PRIMARY_DEVICE 0x00000004
  221. #define DISPLAY_DEVICE_MIRRORING_DRIVER 0x00000008
  222. #define DISPLAY_DEVICE_VGA 0x00000010
  223. typedef struct {
  224. DWORD cb;
  225. CHAR DeviceName[MAX_DRIVER_NAME];
  226. CHAR DeviceString[128];
  227. DWORD StateFlags;
  228. } DISPLAY_DEVICEA;
  229. #endif
  230. #undef DPF_MODNAME
  231. #define DPF_MODNAME "MakeDX8Caps"
  232. void
  233. MakeDX8Caps( D3DCAPS8 *pCaps8,
  234. const D3D8_GLOBALDRIVERDATA* pGblDrvData,
  235. const D3DHAL_D3DEXTENDEDCAPS* pExtCaps )
  236. {
  237. // we shouldn't memset pCaps8 as members like Caps, Caps2, Caps3 (dwSVCaps) and
  238. // CursorCaps are already set by Thunk layer
  239. pCaps8->DevCaps = pGblDrvData->hwCaps.dwDevCaps;
  240. pCaps8->PrimitiveMiscCaps = pGblDrvData->hwCaps.dpcTriCaps.dwMiscCaps;
  241. pCaps8->RasterCaps = pGblDrvData->hwCaps.dpcTriCaps.dwRasterCaps;
  242. pCaps8->ZCmpCaps = pGblDrvData->hwCaps.dpcTriCaps.dwZCmpCaps;
  243. pCaps8->SrcBlendCaps = pGblDrvData->hwCaps.dpcTriCaps.dwSrcBlendCaps;
  244. pCaps8->DestBlendCaps = pGblDrvData->hwCaps.dpcTriCaps.dwDestBlendCaps;
  245. pCaps8->AlphaCmpCaps = pGblDrvData->hwCaps.dpcTriCaps.dwAlphaCmpCaps;
  246. pCaps8->ShadeCaps = pGblDrvData->hwCaps.dpcTriCaps.dwShadeCaps;
  247. pCaps8->TextureCaps = pGblDrvData->hwCaps.dpcTriCaps.dwTextureCaps;
  248. pCaps8->TextureFilterCaps = pGblDrvData->hwCaps.dpcTriCaps.dwTextureFilterCaps;
  249. // Adjust the texture filter caps for the legacy drivers that
  250. // set only the legacy texture filter caps and not the newer ones.
  251. if ((pCaps8->TextureFilterCaps & (D3DPTFILTERCAPS_MINFPOINT |
  252. D3DPTFILTERCAPS_MAGFPOINT |
  253. D3DPTFILTERCAPS_MIPFPOINT |
  254. D3DPTFILTERCAPS_MINFLINEAR |
  255. D3DPTFILTERCAPS_MAGFLINEAR |
  256. D3DPTFILTERCAPS_MIPFLINEAR)) == 0)
  257. {
  258. if (pCaps8->TextureFilterCaps & D3DPTFILTERCAPS_NEAREST)
  259. {
  260. pCaps8->TextureFilterCaps |= (D3DPTFILTERCAPS_MINFPOINT |
  261. D3DPTFILTERCAPS_MAGFPOINT);
  262. }
  263. if (pCaps8->TextureFilterCaps & D3DPTFILTERCAPS_LINEAR)
  264. {
  265. pCaps8->TextureFilterCaps |= (D3DPTFILTERCAPS_MINFLINEAR |
  266. D3DPTFILTERCAPS_MAGFLINEAR);
  267. }
  268. if (pCaps8->TextureFilterCaps & D3DPTFILTERCAPS_MIPNEAREST)
  269. {
  270. pCaps8->TextureFilterCaps |= (D3DPTFILTERCAPS_MINFPOINT |
  271. D3DPTFILTERCAPS_MAGFPOINT |
  272. D3DPTFILTERCAPS_MIPFPOINT);
  273. }
  274. if (pCaps8->TextureFilterCaps & D3DPTFILTERCAPS_MIPLINEAR)
  275. {
  276. pCaps8->TextureFilterCaps |= (D3DPTFILTERCAPS_MINFLINEAR |
  277. D3DPTFILTERCAPS_MAGFLINEAR |
  278. D3DPTFILTERCAPS_MIPFPOINT);
  279. }
  280. if (pCaps8->TextureFilterCaps & D3DPTFILTERCAPS_LINEARMIPNEAREST)
  281. {
  282. pCaps8->TextureFilterCaps |= (D3DPTFILTERCAPS_MINFPOINT |
  283. D3DPTFILTERCAPS_MAGFPOINT |
  284. D3DPTFILTERCAPS_MIPFLINEAR);
  285. }
  286. if (pCaps8->TextureFilterCaps & D3DPTFILTERCAPS_LINEARMIPLINEAR)
  287. {
  288. pCaps8->TextureFilterCaps |= (D3DPTFILTERCAPS_MINFLINEAR |
  289. D3DPTFILTERCAPS_MAGFLINEAR |
  290. D3DPTFILTERCAPS_MIPFLINEAR);
  291. }
  292. }
  293. pCaps8->TextureAddressCaps = pGblDrvData->hwCaps.dpcTriCaps.dwTextureAddressCaps;
  294. // Set the cube-texture filter caps only if the device supports
  295. // cubemaps.
  296. if (pCaps8->TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
  297. {
  298. pCaps8->CubeTextureFilterCaps = pGblDrvData->hwCaps.dpcTriCaps.dwTextureFilterCaps;
  299. }
  300. const D3DPRIMCAPS* pTC = &pGblDrvData->hwCaps.dpcTriCaps;
  301. const D3DPRIMCAPS* pLC = &pGblDrvData->hwCaps.dpcLineCaps;
  302. if (pLC->dwTextureCaps) pCaps8->LineCaps |= D3DLINECAPS_TEXTURE ;
  303. if (pLC->dwZCmpCaps == pTC->dwZCmpCaps)
  304. pCaps8->LineCaps |= D3DLINECAPS_ZTEST;
  305. if ( (pLC->dwSrcBlendCaps == pTC->dwSrcBlendCaps) &&
  306. (pLC->dwDestBlendCaps == pTC->dwDestBlendCaps) )
  307. pCaps8->LineCaps |= D3DLINECAPS_BLEND;
  308. if (pLC->dwAlphaCmpCaps == pTC->dwAlphaCmpCaps)
  309. pCaps8->LineCaps |= D3DLINECAPS_ALPHACMP;
  310. if (pLC->dwRasterCaps & (D3DPRASTERCAPS_FOGVERTEX|D3DPRASTERCAPS_FOGTABLE))
  311. pCaps8->LineCaps |= D3DLINECAPS_FOG;
  312. if( pExtCaps->dwMaxTextureWidth == 0 )
  313. pCaps8->MaxTextureWidth = 256;
  314. else
  315. pCaps8->MaxTextureWidth = pExtCaps->dwMaxTextureWidth;
  316. if( pExtCaps->dwMaxTextureHeight == 0 )
  317. pCaps8->MaxTextureHeight = 256;
  318. else
  319. pCaps8->MaxTextureHeight = pExtCaps->dwMaxTextureHeight;
  320. pCaps8->MaxTextureRepeat = pExtCaps->dwMaxTextureRepeat;
  321. pCaps8->MaxTextureAspectRatio = pExtCaps->dwMaxTextureAspectRatio;
  322. pCaps8->MaxAnisotropy = pExtCaps->dwMaxAnisotropy;
  323. pCaps8->MaxVertexW = pExtCaps->dvMaxVertexW;
  324. pCaps8->GuardBandLeft = pExtCaps->dvGuardBandLeft;
  325. pCaps8->GuardBandTop = pExtCaps->dvGuardBandTop;
  326. pCaps8->GuardBandRight = pExtCaps->dvGuardBandRight;
  327. pCaps8->GuardBandBottom = pExtCaps->dvGuardBandBottom;
  328. pCaps8->ExtentsAdjust = pExtCaps->dvExtentsAdjust;
  329. pCaps8->StencilCaps = pExtCaps->dwStencilCaps;
  330. pCaps8->FVFCaps = pExtCaps->dwFVFCaps;
  331. pCaps8->TextureOpCaps = pExtCaps->dwTextureOpCaps;
  332. pCaps8->MaxTextureBlendStages = pExtCaps->wMaxTextureBlendStages;
  333. pCaps8->MaxSimultaneousTextures = pExtCaps->wMaxSimultaneousTextures;
  334. pCaps8->VertexProcessingCaps = pExtCaps->dwVertexProcessingCaps;
  335. pCaps8->MaxActiveLights = pExtCaps->dwMaxActiveLights;
  336. pCaps8->MaxUserClipPlanes = pExtCaps->wMaxUserClipPlanes;
  337. pCaps8->MaxVertexBlendMatrices = pExtCaps->wMaxVertexBlendMatrices;
  338. if (pCaps8->MaxVertexBlendMatrices == 1)
  339. pCaps8->MaxVertexBlendMatrices = 0;
  340. //
  341. // Stuff in the DX8 caps that cannot be reported by the pre DX8 drivers
  342. //
  343. pCaps8->MaxPointSize = 0;
  344. pCaps8->MaxPrimitiveCount = 0xffff;
  345. pCaps8->MaxVertexIndex = 0xffff;
  346. pCaps8->MaxStreams = 0;
  347. pCaps8->MaxStreamStride = 255;
  348. pCaps8->MaxVertexBlendMatrixIndex = 0;
  349. pCaps8->MaxVolumeExtent = 0;
  350. // Format is 8.8 in bottom of DWORD
  351. pCaps8->VertexShaderVersion = D3DVS_VERSION(0,0);
  352. pCaps8->MaxVertexShaderConst = 0;
  353. pCaps8->PixelShaderVersion = D3DPS_VERSION(0,0);
  354. pCaps8->MaxPixelShaderValue = 1.0f;
  355. } // MakeDX8Caps
  356. /*
  357. * xxxEnumDisplayDevices
  358. *
  359. * wrapper around the new Win32 API EnumDisplayDevices
  360. * uses GetProcAddress() so we run on Win95.
  361. *
  362. * this function exists in NT 4.0 and Win97 (Memphis) but not Win95
  363. *
  364. */
  365. BOOL xxxEnumDisplayDevicesA(LPVOID lpUnused, DWORD iDevice, DISPLAY_DEVICEA *pdd, DWORD dwFlags)
  366. {
  367. HMODULE h = GetModuleHandle("USER32");
  368. BOOL (WINAPI *pfnEnumDisplayDevices)(LPVOID, DWORD, DISPLAY_DEVICEA *, DWORD);
  369. *((void **)&pfnEnumDisplayDevices) = GetProcAddress(h,"EnumDisplayDevicesA");
  370. //
  371. // NT 4.0 had a EnumDisplayDevicesA but it does not have the same
  372. // number of params, so ignore it unless a GetMonitorInfoA exists too.
  373. //
  374. if (GetProcAddress(h,"GetMonitorInfoA") == NULL)
  375. pfnEnumDisplayDevices = NULL;
  376. if (pfnEnumDisplayDevices)
  377. {
  378. return (*pfnEnumDisplayDevices)(lpUnused, iDevice, pdd, dwFlags);
  379. }
  380. //else we emulate the function for 95, NT4:
  381. if (iDevice > 0)
  382. return FALSE;
  383. pdd->StateFlags = DISPLAY_DEVICE_PRIMARY_DEVICE;
  384. lstrcpy(pdd->DeviceName, DISPLAY_STR);
  385. LoadString(g_hModule, IDS_PRIMARYDISPLAY, pdd->DeviceString, sizeof(pdd->DeviceString));
  386. return TRUE;
  387. }
  388. // Multi-monitor defines; these are wrong in the TRANGO tree;
  389. // so I need to define them here explicitly. When we move to
  390. // something that matches Memphis/NT5 then we can remove these
  391. #undef SM_XVIRTUALSCREEN
  392. #undef SM_YVIRTUALSCREEN
  393. #undef SM_CXVIRTUALSCREEN
  394. #undef SM_CYVIRTUALSCREEN
  395. #undef SM_CMONITORS
  396. #define SM_XVIRTUALSCREEN 76
  397. #define SM_YVIRTUALSCREEN 77
  398. #define SM_CXVIRTUALSCREEN 78
  399. #define SM_CYVIRTUALSCREEN 79
  400. #define SM_CMONITORS 80
  401. #ifndef ENUM_CURRENT_SETTINGS
  402. #define ENUM_CURRENT_SETTINGS ((DWORD)-1)
  403. #endif
  404. #ifdef WINNT
  405. // This function gets the device rect by calling GetMonitorInfo.
  406. // On Win98, we got this by calling EnumDisplaySettings, but this
  407. // doesn't work on NT5 and reading the documentation, it never
  408. // indicates that it should work, so we'll just do it the documented
  409. // way.
  410. HRESULT GetNTDeviceRect(LPSTR pDriverName, LPRECT lpRect)
  411. {
  412. MONITORINFO MonInfo;
  413. HMONITOR hMon;
  414. MonInfo.cbSize = sizeof(MONITORINFO);
  415. if (_stricmp(pDriverName, DISPLAY_STR) == 0)
  416. {
  417. hMon = GetMonitorFromDeviceName(g_szPrimaryDisplay);
  418. }
  419. else
  420. {
  421. hMon = GetMonitorFromDeviceName(pDriverName);
  422. }
  423. if (hMon != NULL)
  424. {
  425. if (GetMonitorInfo(hMon, &MonInfo) != 0)
  426. {
  427. CopyMemory(lpRect, &MonInfo.rcMonitor, sizeof(RECT));
  428. return S_OK;
  429. }
  430. }
  431. return E_FAIL;
  432. }
  433. #endif
  434. /*
  435. * IsVGADevice()
  436. *
  437. * determine if the passed device name is a VGA
  438. *
  439. */
  440. BOOL IsVGADevice(LPSTR szDevice)
  441. {
  442. //
  443. // assume "DISPLAY" and "DISPLAY1" are VGA devices
  444. //
  445. if ((_stricmp(szDevice, DISPLAY_STR) == 0) ||
  446. ((szDevice[0] == '\\') &&
  447. (szDevice[1] == '\\') &&
  448. (szDevice[2] == '.')))
  449. {
  450. return TRUE;
  451. }
  452. return FALSE;
  453. }
  454. /*
  455. * This function is currently only used in NT
  456. */
  457. #ifdef WINNT
  458. BOOL GetDDStereoMode(LPDDRAWI_DIRECTDRAW_GBL pdrv,
  459. DWORD dwWidth,
  460. DWORD dwHeight,
  461. DWORD dwBpp,
  462. DWORD dwRefreshRate)
  463. {
  464. DDHAL_GETDRIVERINFODATA gdidata;
  465. HRESULT hres;
  466. DDSTEREOMODE ddStereoMode;
  467. DDASSERT(pdrv != NULL);
  468. /*
  469. * If driver does not support GetDriverInfo callback, it also
  470. * has no extended capabilities to report, so we're done.
  471. */
  472. if (!VALIDEX_CODE_PTR (pdrv->pGetDriverInfo))
  473. {
  474. return FALSE;
  475. }
  476. /*
  477. * The mode can't be stereo if the driver doesn't support it...
  478. */
  479. if (0 == (pdrv->ddCaps.dwCaps2 & DDCAPS2_STEREO))
  480. {
  481. return FALSE;
  482. }
  483. ZeroMemory(&ddStereoMode, sizeof(DDSTEREOMODE));
  484. ddStereoMode.dwSize=sizeof(DDSTEREOMODE);
  485. ddStereoMode.dwWidth=dwWidth;
  486. ddStereoMode.dwHeight=dwHeight;
  487. ddStereoMode.dwBpp=dwBpp;
  488. ddStereoMode.dwRefreshRate=dwRefreshRate;
  489. ddStereoMode.bSupported = TRUE;
  490. /*
  491. * Get the actual driver data
  492. */
  493. memset(&gdidata, 0, sizeof(gdidata));
  494. gdidata.dwSize = sizeof(gdidata);
  495. gdidata.dwFlags = 0;
  496. gdidata.guidInfo = GUID_DDStereoMode;
  497. gdidata.dwExpectedSize = sizeof(DDSTEREOMODE);
  498. gdidata.lpvData = &ddStereoMode;
  499. gdidata.ddRVal = E_FAIL;
  500. // Pass a context variable so that the driver
  501. // knows which instance of itself to use
  502. // w.r.t. this function. These are different
  503. // values on Win95 and NT.
  504. #ifdef WIN95
  505. gdidata.dwContext = pdrv->dwReserved3;
  506. #else
  507. gdidata.dwContext = pdrv->hDD;
  508. #endif
  509. return TRUE;
  510. } /* GetDDStereoMode */
  511. #endif //WINNT
  512. /*
  513. * doneDC
  514. */
  515. void DD_DoneDC(HDC hdc_dd)
  516. {
  517. if (hdc_dd != NULL)
  518. {
  519. DPF(5, "DeleteDC 0x%x", hdc_dd);
  520. DeleteDC(hdc_dd);
  521. hdc_dd = NULL;
  522. }
  523. } /* doneDC */
  524. #undef DPF_MODNAME
  525. #define DPF_MODNAME "DirectDrawCreate"
  526. /*
  527. * createDC
  528. *
  529. * create a new DC given a device name.
  530. * doneDC() should be called to free DC
  531. *
  532. * the following are valid for device names:
  533. *
  534. * DISPLAY - the main display device via CreateDC("DISPLAY", ...)
  535. * this is the normal case.
  536. *
  537. * foobar - the foobar.drv via CreateDC("foobar", ...)
  538. * used for secondary displays listed in the registry
  539. *
  540. * \\.\DisplayX - display device X via CreateDC(NULL,"\\.\DisplayX",...)
  541. * used on Memphis and NT5 for secondary displays
  542. *
  543. */
  544. HDC DD_CreateDC(LPSTR pdrvname)
  545. {
  546. HDC hdc;
  547. UINT u;
  548. DDASSERT(pdrvname != NULL);
  549. #ifdef DEBUG
  550. if (pdrvname[0] == 0)
  551. {
  552. DPF(3, "createDC() empty string!!!");
  553. DebugBreak();
  554. return NULL;
  555. }
  556. #endif
  557. #if defined(NT_FIX) || defined(WIN95)
  558. u = SetErrorMode(SEM_NOOPENFILEERRORBOX);
  559. #endif
  560. #ifdef WINNT
  561. /*
  562. * Note that DirectDraw refers to the driver for the primary monitor
  563. * in a multimon system as "display", but NT uses "display" to refer
  564. * to the desktop as a whole. To handle this mismatch, we store
  565. * NT's name for the primary monitor's driver in g_szPrimaryDisplay
  566. * and substitute this name in place of "display" in our calls to NT.
  567. */
  568. if (GetSystemMetrics(SM_CMONITORS) > 1)
  569. {
  570. if ((_stricmp(pdrvname, DISPLAY_STR) == 0))
  571. {
  572. if (g_szPrimaryDisplay[0] == '\0')
  573. {
  574. getPrimaryDisplayName();
  575. }
  576. pdrvname = g_szPrimaryDisplay;
  577. }
  578. }
  579. #endif //WINNT
  580. DPF(5, "createDC(%s)", pdrvname);
  581. if (pdrvname[0] == '\\' && pdrvname[1] == '\\' && pdrvname[2] == '.')
  582. hdc = CreateDC(NULL, pdrvname, NULL, NULL);
  583. else
  584. hdc = CreateDC(pdrvname, NULL, NULL, NULL);
  585. #if defined(NT_FIX) || defined(WIN95) //fix this error mode stuff
  586. SetErrorMode(u);
  587. #endif
  588. if (hdc == NULL)
  589. {
  590. DPF(3, "createDC(%s) FAILED!", pdrvname);
  591. }
  592. return hdc;
  593. } /* createDC */
  594. /*****************************Private*Routine******************************\
  595. * DdConvertFromOldFormat
  596. *
  597. * History:
  598. * 13-Nov-1999 -by- Scott MacDonald [smac]
  599. * Wrote it.
  600. \**************************************************************************/
  601. #undef DPF_MODNAME
  602. #define DPF_MODNAME "ConvertFromOldFormat"
  603. void ConvertFromOldFormat(LPDDPIXELFORMAT pOldFormat, D3DFORMAT *pNewFormat)
  604. {
  605. *pNewFormat = D3DFMT_UNKNOWN;
  606. if (pOldFormat->dwFlags & DDPF_FOURCC)
  607. {
  608. *pNewFormat = (D3DFORMAT) pOldFormat->dwFourCC;
  609. }
  610. else if (pOldFormat->dwFlags == DDPF_RGB)
  611. {
  612. switch (pOldFormat->dwRGBBitCount)
  613. {
  614. case 8:
  615. if ((pOldFormat->dwRBitMask == 0x000000e0) &&
  616. (pOldFormat->dwGBitMask == 0x0000001c) &&
  617. (pOldFormat->dwBBitMask == 0x00000003))
  618. {
  619. *pNewFormat = D3DFMT_R3G3B2;
  620. }
  621. else
  622. {
  623. *pNewFormat = D3DFMT_P8;
  624. }
  625. break;
  626. case 16:
  627. if ((pOldFormat->dwRBitMask == 0x0000f800) &&
  628. (pOldFormat->dwGBitMask == 0x000007e0) &&
  629. (pOldFormat->dwBBitMask == 0x0000001f))
  630. {
  631. *pNewFormat = D3DFMT_R5G6B5;
  632. }
  633. else if ((pOldFormat->dwRBitMask == 0x00007c00) &&
  634. (pOldFormat->dwGBitMask == 0x000003e0) &&
  635. (pOldFormat->dwBBitMask == 0x0000001f))
  636. {
  637. *pNewFormat = D3DFMT_X1R5G5B5;
  638. }
  639. else if ((pOldFormat->dwRBitMask == 0x00000f00) &&
  640. (pOldFormat->dwGBitMask == 0x000000f0) &&
  641. (pOldFormat->dwBBitMask == 0x0000000f))
  642. {
  643. *pNewFormat = D3DFMT_X4R4G4B4;
  644. }
  645. break;
  646. case 24:
  647. if ((pOldFormat->dwRBitMask == 0x00ff0000) &&
  648. (pOldFormat->dwGBitMask == 0x0000ff00) &&
  649. (pOldFormat->dwBBitMask == 0x000000ff))
  650. {
  651. *pNewFormat = D3DFMT_R8G8B8;
  652. }
  653. break;
  654. case 32:
  655. if ((pOldFormat->dwRBitMask == 0x00ff0000) &&
  656. (pOldFormat->dwGBitMask == 0x0000ff00) &&
  657. (pOldFormat->dwBBitMask == 0x000000ff))
  658. {
  659. *pNewFormat = D3DFMT_X8R8G8B8;
  660. }
  661. break;
  662. }
  663. }
  664. else if (pOldFormat->dwFlags == (DDPF_RGB | DDPF_ALPHAPIXELS))
  665. {
  666. switch (pOldFormat->dwRGBBitCount)
  667. {
  668. case 16:
  669. if ((pOldFormat->dwRGBAlphaBitMask == 0x0000FF00) &&
  670. (pOldFormat->dwRBitMask == 0x000000e0) &&
  671. (pOldFormat->dwGBitMask == 0x0000001c) &&
  672. (pOldFormat->dwBBitMask == 0x00000003))
  673. {
  674. *pNewFormat = D3DFMT_A8R3G3B2;
  675. }
  676. else if ((pOldFormat->dwRGBAlphaBitMask == 0x0000f000) &&
  677. (pOldFormat->dwRBitMask == 0x00000f00) &&
  678. (pOldFormat->dwGBitMask == 0x000000f0) &&
  679. (pOldFormat->dwBBitMask == 0x0000000f))
  680. {
  681. *pNewFormat = D3DFMT_A4R4G4B4;
  682. }
  683. else if ((pOldFormat->dwRGBAlphaBitMask == 0x0000FF00) &&
  684. (pOldFormat->dwRBitMask == 0x00000f00) &&
  685. (pOldFormat->dwGBitMask == 0x000000f0) &&
  686. (pOldFormat->dwBBitMask == 0x0000000f))
  687. {
  688. *pNewFormat = D3DFMT_A4R4G4B4;
  689. }
  690. else if ((pOldFormat->dwRGBAlphaBitMask == 0x00008000) &&
  691. (pOldFormat->dwRBitMask == 0x00007c00) &&
  692. (pOldFormat->dwGBitMask == 0x000003e0) &&
  693. (pOldFormat->dwBBitMask == 0x0000001f))
  694. {
  695. *pNewFormat = D3DFMT_A1R5G5B5;
  696. }
  697. break;
  698. case 32:
  699. if ((pOldFormat->dwRGBAlphaBitMask == 0xff000000) &&
  700. (pOldFormat->dwRBitMask == 0x00ff0000) &&
  701. (pOldFormat->dwGBitMask == 0x0000ff00) &&
  702. (pOldFormat->dwBBitMask == 0x000000ff))
  703. {
  704. *pNewFormat = D3DFMT_A8R8G8B8;
  705. }
  706. break;
  707. }
  708. }
  709. #if 0
  710. // We don't convert the old representation of A8 to
  711. // the new format because there are some existing DX7 drivers
  712. // that expose the old format but don't implement it correctly
  713. // or completely. We've seen Blt failures, and Rendering failures.
  714. // So this becomes a DX8+ only feature; in which case
  715. // we will get a new-style format from the driver.
  716. // MB43799
  717. else if (pOldFormat->dwFlags == DDPF_ALPHA)
  718. {
  719. if (pOldFormat->dwAlphaBitDepth == 8)
  720. {
  721. *pNewFormat = D3DFMT_A8;
  722. }
  723. }
  724. #endif
  725. else if (pOldFormat->dwFlags & (DDPF_PALETTEINDEXED8 | DDPF_RGB))
  726. {
  727. switch (pOldFormat->dwRGBBitCount)
  728. {
  729. case 8:
  730. if (pOldFormat->dwFlags == (DDPF_PALETTEINDEXED8 | DDPF_RGB))
  731. {
  732. *pNewFormat = D3DFMT_P8;
  733. }
  734. break;
  735. case 16:
  736. if (pOldFormat->dwFlags == (DDPF_PALETTEINDEXED8 |
  737. DDPF_RGB |
  738. DDPF_ALPHAPIXELS) &&
  739. pOldFormat->dwRGBAlphaBitMask == 0xFF00)
  740. {
  741. *pNewFormat = D3DFMT_A8P8;
  742. }
  743. break;
  744. }
  745. }
  746. else if (pOldFormat->dwFlags == DDPF_ZBUFFER)
  747. {
  748. switch (pOldFormat->dwZBufferBitDepth)
  749. {
  750. case 32:
  751. if (pOldFormat->dwZBitMask == 0xffffffff)
  752. {
  753. *pNewFormat = D3DFMT_D32;
  754. }
  755. else if (pOldFormat->dwZBitMask == 0x00FFFFFF)
  756. {
  757. *pNewFormat = D3DFMT_X8D24;
  758. }
  759. else if (pOldFormat->dwZBitMask == 0xFFFFFF00)
  760. {
  761. *pNewFormat = D3DFMT_D24X8;
  762. }
  763. break;
  764. case 16:
  765. if (pOldFormat->dwZBitMask == 0xffff)
  766. {
  767. *pNewFormat = D3DFMT_D16_LOCKABLE;
  768. }
  769. break;
  770. }
  771. }
  772. else if (pOldFormat->dwFlags == (DDPF_ZBUFFER | DDPF_STENCILBUFFER))
  773. {
  774. switch (pOldFormat->dwZBufferBitDepth)
  775. {
  776. case 32:
  777. if ((pOldFormat->dwZBitMask == 0xffffff00) &&
  778. (pOldFormat->dwStencilBitMask == 0x000000ff) &&
  779. (pOldFormat->dwStencilBitDepth == 8))
  780. {
  781. *pNewFormat = D3DFMT_D24S8;
  782. }
  783. else if ((pOldFormat->dwZBitMask == 0x00ffffff) &&
  784. (pOldFormat->dwStencilBitMask == 0xff000000) &&
  785. (pOldFormat->dwStencilBitDepth == 8))
  786. {
  787. *pNewFormat = D3DFMT_S8D24;
  788. }
  789. else if ((pOldFormat->dwZBitMask == 0xffffff00) &&
  790. (pOldFormat->dwStencilBitMask == 0x0000000f) &&
  791. (pOldFormat->dwStencilBitDepth == 4))
  792. {
  793. *pNewFormat = D3DFMT_D24X4S4;
  794. }
  795. else if ((pOldFormat->dwZBitMask == 0x00ffffff) &&
  796. (pOldFormat->dwStencilBitMask == 0x0f000000) &&
  797. (pOldFormat->dwStencilBitDepth == 4))
  798. {
  799. *pNewFormat = D3DFMT_X4S4D24;
  800. }
  801. break;
  802. case 16:
  803. if ((pOldFormat->dwZBitMask == 0xfffe) &&
  804. (pOldFormat->dwStencilBitMask == 0x0001) &&
  805. (pOldFormat->dwStencilBitDepth == 1))
  806. {
  807. *pNewFormat = D3DFMT_D15S1;
  808. }
  809. else if ((pOldFormat->dwZBitMask == 0x7fff) &&
  810. (pOldFormat->dwStencilBitMask == 0x8000) &&
  811. (pOldFormat->dwStencilBitDepth == 1))
  812. {
  813. *pNewFormat = D3DFMT_S1D15;
  814. }
  815. break;
  816. }
  817. }
  818. else if (pOldFormat->dwFlags == DDPF_LUMINANCE)
  819. {
  820. switch (pOldFormat->dwLuminanceBitCount)
  821. {
  822. case 8:
  823. if (pOldFormat->dwLuminanceBitMask == 0xFF)
  824. {
  825. *pNewFormat = D3DFMT_L8;
  826. }
  827. break;
  828. }
  829. }
  830. else if (pOldFormat->dwFlags == (DDPF_LUMINANCE | DDPF_ALPHAPIXELS))
  831. {
  832. switch (pOldFormat->dwLuminanceBitCount)
  833. {
  834. case 8:
  835. if (pOldFormat->dwLuminanceBitMask == 0x0F &&
  836. pOldFormat->dwLuminanceAlphaBitMask == 0xF0)
  837. {
  838. *pNewFormat = D3DFMT_A4L4;
  839. }
  840. case 16:
  841. if (pOldFormat->dwLuminanceBitMask == 0x00FF &&
  842. pOldFormat->dwLuminanceAlphaBitMask == 0xFF00)
  843. {
  844. *pNewFormat = D3DFMT_A8L8;
  845. }
  846. break;
  847. }
  848. }
  849. else if (pOldFormat->dwFlags == DDPF_BUMPDUDV)
  850. {
  851. switch (pOldFormat->dwBumpBitCount)
  852. {
  853. case 16:
  854. if (pOldFormat->dwBumpDuBitMask == 0xFF &&
  855. pOldFormat->dwBumpDvBitMask == 0xFF00)
  856. {
  857. *pNewFormat = D3DFMT_V8U8;
  858. }
  859. break;
  860. }
  861. }
  862. else if (pOldFormat->dwFlags == (DDPF_BUMPDUDV | DDPF_BUMPLUMINANCE))
  863. {
  864. switch (pOldFormat->dwBumpBitCount)
  865. {
  866. case 16:
  867. if (pOldFormat->dwBumpDuBitMask == 0x001F &&
  868. pOldFormat->dwBumpDvBitMask == 0x03E0 &&
  869. pOldFormat->dwBumpLuminanceBitMask == 0xFC00)
  870. {
  871. *pNewFormat = D3DFMT_L6V5U5;
  872. }
  873. break;
  874. case 32:
  875. if (pOldFormat->dwBumpDuBitMask == 0x0000FF &&
  876. pOldFormat->dwBumpDvBitMask == 0x00FF00 &&
  877. pOldFormat->dwBumpLuminanceBitMask == 0xFF0000)
  878. {
  879. *pNewFormat = D3DFMT_X8L8V8U8;
  880. }
  881. break;
  882. }
  883. }
  884. }
  885. /*
  886. * FetchDirectDrawData
  887. *
  888. * Go get new HAL info...
  889. */
  890. void FetchDirectDrawData(
  891. PD3D8_DEVICEDATA pBaseData,
  892. void* pInitFunction,
  893. D3DFORMAT Unknown16,
  894. DDSURFACEDESC* pHalOpList,
  895. DWORD NumHalOps)
  896. {
  897. BOOL bNewMode;
  898. BOOL bRetVal;
  899. UINT i=0;
  900. BOOL bAlreadyAnOpList = FALSE;
  901. LPDDPIXELFORMAT pZStencilFormatList=0;
  902. DDSURFACEDESC *pTextureList=0;
  903. D3D8_GLOBALDRIVERDATA D3DGlobalDriverData;
  904. D3DHAL_D3DEXTENDEDCAPS D3DExtendedCaps;
  905. BOOL bBackbuffersExist = FALSE;
  906. BOOL bReset = FALSE;
  907. ZeroMemory( &D3DGlobalDriverData, sizeof(D3DGlobalDriverData) );
  908. ZeroMemory( &D3DExtendedCaps, sizeof(D3DExtendedCaps) );
  909. if (pBaseData->hDD == NULL)
  910. {
  911. #ifdef WINNT
  912. D3D8CreateDirectDrawObject(pBaseData->hDC,
  913. pBaseData->DriverName,
  914. &pBaseData->hDD,
  915. pBaseData->DeviceType,
  916. &pBaseData->hLibrary,
  917. pInitFunction);
  918. #else
  919. D3D8CreateDirectDrawObject(&pBaseData->Guid,
  920. pBaseData->DriverName,
  921. &pBaseData->hDD,
  922. pBaseData->DeviceType,
  923. &pBaseData->hLibrary,
  924. pInitFunction);
  925. #endif
  926. if (pBaseData->hDD == NULL)
  927. {
  928. #ifdef WINNT
  929. DPF(1, "****DirectDraw/Direct3D DRIVER DISABLING ERROR****:NT Kernel mode would not create driver object... Failing over to emulation");
  930. #endif
  931. goto ErrorExit;
  932. }
  933. }
  934. else
  935. {
  936. // If we already have 3D caps, then we are resetting
  937. if ((pBaseData->DriverData.dwFlags & DDIFLAG_D3DCAPS8) &&
  938. (pBaseData->DriverData.D3DCaps.DevCaps != 0))
  939. {
  940. bReset = TRUE;
  941. }
  942. }
  943. // Now we can get the driver info...
  944. // The first call returns the amount of space we need to allocate for the
  945. // texture and z/stencil lists
  946. UINT cTextureFormats;
  947. UINT cZStencilFormats;
  948. if (bReset)
  949. {
  950. // If we are ressting, we do not want to rebuild all of the caps, the
  951. // format list, etc., but we still need to call the thunk layer because
  952. // on NT this resets the kernel.
  953. D3D8_DRIVERCAPS TempData;
  954. D3D8_CALLBACKS TempCallbacks;
  955. if (!D3D8ReenableDirectDrawObject(pBaseData->hDD,&bNewMode) ||
  956. !D3D8QueryDirectDrawObject(pBaseData->hDD,
  957. &TempData,
  958. &TempCallbacks,
  959. pBaseData->DriverName,
  960. pBaseData->hLibrary,
  961. &D3DGlobalDriverData,
  962. &D3DExtendedCaps,
  963. NULL,
  964. NULL,
  965. &cTextureFormats,
  966. &cZStencilFormats))
  967. {
  968. goto ErrorExit;
  969. }
  970. pBaseData->DriverData.DisplayWidth = TempData.DisplayWidth;
  971. pBaseData->DriverData.DisplayHeight = TempData.DisplayHeight;
  972. pBaseData->DriverData.DisplayFormatWithAlpha = TempData.DisplayFormatWithAlpha;
  973. pBaseData->DriverData.DisplayFormatWithoutAlpha = TempData.DisplayFormatWithoutAlpha;
  974. pBaseData->DriverData.DisplayFrequency = TempData.DisplayFrequency;
  975. }
  976. else
  977. {
  978. MemFree (pBaseData->DriverData.pGDD8SupportedFormatOps);
  979. pBaseData->DriverData.pGDD8SupportedFormatOps = NULL;
  980. if (!D3D8ReenableDirectDrawObject(pBaseData->hDD,&bNewMode) ||
  981. !D3D8QueryDirectDrawObject(pBaseData->hDD,
  982. &pBaseData->DriverData,
  983. &pBaseData->Callbacks,
  984. pBaseData->DriverName,
  985. pBaseData->hLibrary,
  986. &D3DGlobalDriverData,
  987. &D3DExtendedCaps,
  988. NULL,
  989. NULL,
  990. &cTextureFormats,
  991. &cZStencilFormats))
  992. {
  993. DPF(1, "****Direct3D DRIVER DISABLING ERROR****:First call to DdQueryDirectDrawObject failed!");
  994. D3D8DeleteDirectDrawObject(pBaseData->hDD);
  995. pBaseData->hDD = NULL;
  996. goto ErrorExit;
  997. }
  998. // First we make space for the formats
  999. // let's do memalloc for pTextureList just once, 3 extra for possible backbuffers
  1000. // 3 extra for D3DFORMAT_OP_SAME_FORMAT_RENDERTARGET
  1001. pTextureList = (DDSURFACEDESC *) MemAlloc ((cTextureFormats+ cZStencilFormats + 6) * sizeof (*pTextureList));
  1002. if (pTextureList == NULL)
  1003. {
  1004. DPF_ERR("****Direct3D DRIVER DISABLING ERROR****:Unable to allocate memory for texture formats!");
  1005. D3D8DeleteDirectDrawObject(pBaseData->hDD);
  1006. pBaseData->hDD = NULL;
  1007. goto ErrorExit;
  1008. }
  1009. if (cZStencilFormats > 0)
  1010. {
  1011. pZStencilFormatList = (DDPIXELFORMAT *) MemAlloc (cZStencilFormats * sizeof (*pZStencilFormatList));
  1012. if (pZStencilFormatList == NULL)
  1013. {
  1014. DPF_ERR("****Direct3D DRIVER DISABLING ERROR****:Unable to allocate memory for Z/Stencil formats!");
  1015. D3D8DeleteDirectDrawObject(pBaseData->hDD);
  1016. pBaseData->hDD = NULL;
  1017. goto ErrorExit;
  1018. }
  1019. }
  1020. //Now that we've allocated space for the texture and z/stencil lists, we can go get em.
  1021. if (!D3D8QueryDirectDrawObject(pBaseData->hDD,
  1022. &pBaseData->DriverData,
  1023. &pBaseData->Callbacks,
  1024. pBaseData->DriverName,
  1025. pBaseData->hLibrary,
  1026. &D3DGlobalDriverData,
  1027. &D3DExtendedCaps,
  1028. pTextureList,
  1029. pZStencilFormatList,
  1030. &cTextureFormats,
  1031. &cZStencilFormats))
  1032. {
  1033. DPF_ERR("****Direct3D DRIVER DISABLING ERROR****:Second call to DdQueryDirectDrawObject failed!");
  1034. D3D8DeleteDirectDrawObject(pBaseData->hDD);
  1035. pBaseData->hDD = NULL;
  1036. goto ErrorExit;
  1037. }
  1038. // If no D3DCAPS8 was reported by the thunk layer, then the driver
  1039. // must be a pre-DX8 driver. We must sew together the
  1040. // D3DGlobalDriverData and the ExtendedCaps (which have to be reported).
  1041. // Note: The thunk layer already has plugged in the DDraw Caps such
  1042. // as the Caps, Caps2 and Caps3 (dwSVCaps).
  1043. if( (pBaseData->DriverData.dwFlags & DDIFLAG_D3DCAPS8) == 0 )
  1044. {
  1045. MakeDX8Caps( &pBaseData->DriverData.D3DCaps,
  1046. &D3DGlobalDriverData,
  1047. &D3DExtendedCaps );
  1048. pBaseData->DriverData.dwFlags |= DDIFLAG_D3DCAPS8;
  1049. }
  1050. else
  1051. {
  1052. // They reported the DX8 caps.
  1053. // Internally we check MaxPointSize if it is zero or not
  1054. // to determine if PointSprites are supported or not. So if a DX8 driver said 1.0
  1055. // set it to Zero
  1056. if (pBaseData->DriverData.D3DCaps.MaxPointSize == 1.0)
  1057. {
  1058. pBaseData->DriverData.D3DCaps.MaxPointSize = 0;
  1059. }
  1060. }
  1061. // There are some legacy caps that are reported by the drivers that
  1062. // we dont want the applications to see. Should weed them out here.
  1063. pBaseData->DriverData.D3DCaps.PrimitiveMiscCaps &= ~(D3DPMISCCAPS_MASKPLANES |
  1064. D3DPMISCCAPS_CONFORMANT);
  1065. pBaseData->DriverData.D3DCaps.DevCaps &= ~(D3DDEVCAPS_FLOATTLVERTEX |
  1066. D3DDEVCAPS_SORTINCREASINGZ | D3DDEVCAPS_SORTDECREASINGZ |
  1067. D3DDEVCAPS_SORTEXACT);
  1068. pBaseData->DriverData.D3DCaps.TextureCaps &= ~(D3DPTEXTURECAPS_TRANSPARENCY |
  1069. D3DPTEXTURECAPS_BORDER | D3DPTEXTURECAPS_COLORKEYBLEND);
  1070. pBaseData->DriverData.D3DCaps.VertexProcessingCaps &= ~(D3DVTXPCAPS_VERTEXFOG);
  1071. pBaseData->DriverData.D3DCaps.RasterCaps &= ~(D3DPRASTERCAPS_SUBPIXEL |
  1072. D3DPRASTERCAPS_SUBPIXELX | D3DPRASTERCAPS_STIPPLE |
  1073. D3DPRASTERCAPS_ANTIALIASSORTDEPENDENT |
  1074. D3DPRASTERCAPS_ANTIALIASSORTINDEPENDENT |
  1075. D3DPRASTERCAPS_TRANSLUCENTSORTINDEPENDENT);
  1076. pBaseData->DriverData.D3DCaps.ShadeCaps &= ~(D3DPSHADECAPS_COLORFLATMONO |
  1077. D3DPSHADECAPS_COLORFLATRGB | D3DPSHADECAPS_COLORGOURAUDMONO |
  1078. D3DPSHADECAPS_COLORPHONGMONO | D3DPSHADECAPS_COLORPHONGRGB |
  1079. D3DPSHADECAPS_SPECULARFLATMONO | D3DPSHADECAPS_SPECULARFLATRGB |
  1080. D3DPSHADECAPS_SPECULARGOURAUDMONO | D3DPSHADECAPS_SPECULARPHONGMONO |
  1081. D3DPSHADECAPS_SPECULARPHONGRGB | D3DPSHADECAPS_ALPHAFLATBLEND |
  1082. D3DPSHADECAPS_ALPHAFLATSTIPPLED | D3DPSHADECAPS_ALPHAGOURAUDSTIPPLED |
  1083. D3DPSHADECAPS_ALPHAPHONGBLEND | D3DPSHADECAPS_ALPHAPHONGSTIPPLED |
  1084. D3DPSHADECAPS_FOGFLAT | D3DPSHADECAPS_FOGPHONG);
  1085. // Now we generate the list of supported ops from the texture format
  1086. // list and z/stencil list.
  1087. //
  1088. // A DX7 or older driver will return to us a simple list of pixel formats.
  1089. // We will take this list and convert it into a list of supported
  1090. // texture formats in the DX8 style. To that we will append any
  1091. // z/stencil formats.
  1092. //
  1093. // First step in generating supported op lists: see if the list is
  1094. // already a DX8 style format list. If it is (i.e. if any
  1095. // entries are DDPF_D3DFORMAT, then all we need to do is
  1096. // yank out the old-style entries (drivers are allowed to
  1097. // keep both so they can run against old runtimes).
  1098. for (i = 0; i < cTextureFormats; i++)
  1099. {
  1100. if (pTextureList[i].ddpfPixelFormat.dwFlags == DDPF_D3DFORMAT)
  1101. {
  1102. bAlreadyAnOpList = TRUE;
  1103. break;
  1104. }
  1105. }
  1106. if (bAlreadyAnOpList)
  1107. {
  1108. // mmmmm.... dx8 driver. We'll ignore its Z/stencil list because
  1109. // such a driver is supposed to put additional op entries in the
  1110. // "texture" list (i.e. the op list) for its z/stencil formats
  1111. // Now all we have to do is ZAP all the old-style entries.
  1112. for (i = 0; i < (INT)cTextureFormats; i++)
  1113. {
  1114. if (pTextureList[i].ddpfPixelFormat.dwFlags != DDPF_D3DFORMAT && i < (INT)cTextureFormats)
  1115. {
  1116. // ha! zap that evil old-style entry!
  1117. // (scroll the remainder of the list down
  1118. // to squish this entry)
  1119. DDASSERT(cTextureFormats > 0); //after all, we're in a for loop.
  1120. if (i < (INT)(cTextureFormats - 1))
  1121. {
  1122. memcpy(pTextureList + i,
  1123. pTextureList + i + 1,
  1124. sizeof(*pTextureList)*(cTextureFormats - i - 1));
  1125. }
  1126. cTextureFormats--;
  1127. i--;
  1128. }
  1129. }
  1130. // TODO: Remove this as soon as we think that drivers have caught up to
  1131. // our OP LIST changes.
  1132. for (i = 0; i < cTextureFormats; i++)
  1133. {
  1134. if (pTextureList[i].ddpfPixelFormat.dwOperations & D3DFORMAT_OP_BACKBUFFER)
  1135. {
  1136. pTextureList[i].ddpfPixelFormat.dwOperations &= ~D3DFORMAT_OP_BACKBUFFER;
  1137. pTextureList[i].ddpfPixelFormat.dwOperations |= D3DFORMAT_OP_3DACCELERATION;
  1138. if (pBaseData->DeviceType == D3DDEVTYPE_HAL)
  1139. {
  1140. pTextureList[i].ddpfPixelFormat.dwOperations |= D3DFORMAT_OP_DISPLAYMODE;
  1141. }
  1142. }
  1143. }
  1144. // If it's a SW driver, we've got a lot of extra work to do.
  1145. if ((pBaseData->DeviceType == D3DDEVTYPE_REF) ||
  1146. (pBaseData->DeviceType == D3DDEVTYPE_SW))
  1147. {
  1148. // First, make sure that the SW driver didn't erroneuously report any
  1149. // D3DFORMAT_OP_DISPLAYMODE entries.
  1150. for (i = 0; i < cTextureFormats; i++)
  1151. {
  1152. if (pTextureList[i].ddpfPixelFormat.dwOperations & D3DFORMAT_OP_DISPLAYMODE)
  1153. {
  1154. DPF_ERR("*****The SW driver is disabled because it claims to support D3DFORMAT_OP_DISPLAYMODE*****");
  1155. D3D8DeleteDirectDrawObject(pBaseData->hDD);
  1156. pBaseData->hDD = NULL;
  1157. goto ErrorExit;
  1158. }
  1159. }
  1160. // Now for the hard part. The HAL reports which display modes
  1161. // it can support, and the SW driver reports which display
  1162. // modes it can accelerate. We need to prune the SW list so
  1163. // that it matches the HW list.
  1164. for (i = 0; i < cTextureFormats; i++)
  1165. {
  1166. if (pTextureList[i].ddpfPixelFormat.dwOperations & D3DFORMAT_OP_3DACCELERATION)
  1167. {
  1168. // Does the HAL support this mode?
  1169. if (IsSupportedOp ((D3DFORMAT) pTextureList[i].ddpfPixelFormat.dwFourCC,
  1170. pHalOpList,
  1171. NumHalOps,
  1172. D3DFORMAT_OP_DISPLAYMODE))
  1173. {
  1174. pTextureList[i].ddpfPixelFormat.dwOperations |= D3DFORMAT_OP_DISPLAYMODE;
  1175. }
  1176. else
  1177. {
  1178. pTextureList[i].ddpfPixelFormat.dwOperations &= ~D3DFORMAT_OP_3DACCELERATION;
  1179. }
  1180. }
  1181. }
  1182. }
  1183. // since we found one op-style entry, we shouldn't have
  1184. // killed them all
  1185. DDASSERT(cTextureFormats);
  1186. }
  1187. else
  1188. {
  1189. // Hmmm.. yucky non DX8 driver! Better go through its texture list
  1190. // and turn it into an op list
  1191. INT i;
  1192. for(i=0; i< (INT)cTextureFormats; i++)
  1193. {
  1194. // we proved this above:
  1195. DDASSERT(pTextureList[i].ddpfPixelFormat.dwFlags != DDPF_D3DFORMAT);
  1196. D3DFORMAT NewFormat;
  1197. ConvertFromOldFormat(&pTextureList[i].ddpfPixelFormat, &NewFormat );
  1198. if (NewFormat != D3DFMT_UNKNOWN) // we succeeded the conversion
  1199. {
  1200. pTextureList[i].ddpfPixelFormat.dwFourCC = (DWORD) NewFormat;
  1201. pTextureList[i].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT;
  1202. pTextureList[i].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_TEXTURE;
  1203. if (pBaseData->DriverData.D3DCaps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
  1204. {
  1205. // It is assumed that any texture format works for cubes
  1206. pTextureList[i].ddpfPixelFormat.dwOperations |=
  1207. D3DFORMAT_OP_CUBETEXTURE;
  1208. if (NewFormat == D3DFMT_X1R5G5B5 ||
  1209. NewFormat == D3DFMT_R5G6B5 ||
  1210. NewFormat == D3DFMT_A8R8G8B8 ||
  1211. NewFormat == D3DFMT_X8R8G8B8)
  1212. {
  1213. // For these three formats, we assume
  1214. // all cube-map hw supports rendering to them.
  1215. //
  1216. // Testing indicates that these formats don't work
  1217. // well if they are in bitdepth other than the primary;
  1218. // so we only specify that the RT aspect of these
  1219. // formats work if they are basically the same
  1220. // as the primary.
  1221. pTextureList[i].ddpfPixelFormat.dwOperations |=
  1222. D3DFORMAT_OP_SAME_FORMAT_UP_TO_ALPHA_RENDERTARGET;
  1223. }
  1224. }
  1225. // If they can support render target textures, add those flags in now
  1226. DWORD RTBit = D3DFORMAT_OP_SAME_FORMAT_UP_TO_ALPHA_RENDERTARGET;
  1227. if (pBaseData->DriverData.KnownDriverFlags & KNOWN_CANMISMATCHRT)
  1228. {
  1229. RTBit = D3DFORMAT_OP_OFFSCREEN_RENDERTARGET;
  1230. }
  1231. if ((NewFormat == D3DFMT_X1R5G5B5) &&
  1232. (pBaseData->DriverData.KnownDriverFlags & KNOWN_RTTEXTURE_X1R5G5B5))
  1233. {
  1234. pTextureList[i].ddpfPixelFormat.dwOperations |= RTBit;
  1235. }
  1236. else if ((NewFormat == D3DFMT_R5G6B5) &&
  1237. (pBaseData->DriverData.KnownDriverFlags & KNOWN_RTTEXTURE_R5G6B5))
  1238. {
  1239. pTextureList[i].ddpfPixelFormat.dwOperations |= RTBit;
  1240. }
  1241. else if ((NewFormat == D3DFMT_X8R8G8B8) &&
  1242. (pBaseData->DriverData.KnownDriverFlags & KNOWN_RTTEXTURE_X8R8G8B8))
  1243. {
  1244. pTextureList[i].ddpfPixelFormat.dwOperations |= RTBit;
  1245. }
  1246. else if ((NewFormat == D3DFMT_A8R8G8B8) &&
  1247. (pBaseData->DriverData.KnownDriverFlags & KNOWN_RTTEXTURE_A8R8G8B8))
  1248. {
  1249. pTextureList[i].ddpfPixelFormat.dwOperations |= RTBit;
  1250. }
  1251. else if ((NewFormat == D3DFMT_A1R5G5B5) &&
  1252. (pBaseData->DriverData.KnownDriverFlags & KNOWN_RTTEXTURE_A1R5G5B5))
  1253. {
  1254. pTextureList[i].ddpfPixelFormat.dwOperations |= RTBit;
  1255. }
  1256. else if ((NewFormat == D3DFMT_A4R4G4B4) &&
  1257. (pBaseData->DriverData.KnownDriverFlags & KNOWN_RTTEXTURE_A4R4G4B4))
  1258. {
  1259. pTextureList[i].ddpfPixelFormat.dwOperations |= RTBit;
  1260. }
  1261. pTextureList[i].ddpfPixelFormat.dwPrivateFormatBitCount = 0;
  1262. pTextureList[i].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0;
  1263. pTextureList[i].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = 0;
  1264. }
  1265. else
  1266. {
  1267. DPF(3,"This driver exposes an unrecognized DX7- style texture format");
  1268. // and we eat it up:
  1269. // (scroll the remainder of the list down to
  1270. // squish this entry)
  1271. DDASSERT(cTextureFormats>0); //after all, we're in a for loop.
  1272. if (i < (INT)(cTextureFormats - 1))
  1273. {
  1274. memcpy(pTextureList + i,
  1275. pTextureList + i + 1,
  1276. sizeof(*pTextureList)*(cTextureFormats - i - 1));
  1277. }
  1278. cTextureFormats--;
  1279. i--;
  1280. }
  1281. }
  1282. //And laboriously tack on the z/stencil formats. Phew.
  1283. for (i = 0; i < (INT)cZStencilFormats; i++)
  1284. {
  1285. DDASSERT(pZStencilFormatList);
  1286. //we proved this above:
  1287. DDASSERT(pZStencilFormatList[i].dwFlags != DDPF_D3DFORMAT);
  1288. D3DFORMAT NewFormat;
  1289. ConvertFromOldFormat(&pZStencilFormatList[i], &NewFormat);
  1290. if (NewFormat != D3DFMT_UNKNOWN) //we succeeded the conversion
  1291. {
  1292. // Room for these elements was allocated above...
  1293. pTextureList[cTextureFormats].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT;
  1294. pTextureList[cTextureFormats].ddpfPixelFormat.dwFourCC = (DWORD) NewFormat;
  1295. pTextureList[cTextureFormats].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_ZSTENCIL;
  1296. pTextureList[cTextureFormats].ddpfPixelFormat.dwPrivateFormatBitCount = 0;
  1297. pTextureList[cTextureFormats].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0;
  1298. pTextureList[cTextureFormats].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = 0;
  1299. // See if part is "known good" i.e. it can mix-and-match
  1300. // ZBuffer and RT formats
  1301. if (pBaseData->DriverData.KnownDriverFlags & KNOWN_ZSTENCILDEPTH)
  1302. {
  1303. pTextureList[cTextureFormats].ddpfPixelFormat.dwOperations
  1304. |= D3DFORMAT_OP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH;
  1305. }
  1306. // If part successfully supports lockable 16-bit zbuffer tests
  1307. // then we allow D16_LOCKABLE through; else we only expose D3DFMT_D16
  1308. if (NewFormat == D3DFMT_D16_LOCKABLE)
  1309. {
  1310. if (!(pBaseData->DriverData.KnownDriverFlags & KNOWN_D16_LOCKABLE))
  1311. {
  1312. pTextureList[cTextureFormats].ddpfPixelFormat.dwFourCC = (DWORD) D3DFMT_D16;
  1313. }
  1314. }
  1315. cTextureFormats++;
  1316. }
  1317. else
  1318. {
  1319. DPF(3,"This driver exposes an unrecognized DX6 style Z/Stencil format");
  1320. }
  1321. }
  1322. // Now we need to add in off-screen render target formats for this Non-DX8 driver.
  1323. // DX8 doesn't allow back buffers to be used as textures, so we add
  1324. // a whole new entry to the op list for each supported back buffer
  1325. // format (i.e. don't go searching for any existing texturable format
  1326. // entry that matches and OR in the RT op).
  1327. //
  1328. //If the format is a back-buffer format, we assume it can be rendered when in the same
  1329. //display mode. Note the presence of this entry in the format op list doesn't imply
  1330. //necessarily that the device can render in that depth. CheckDeviceFormat could still
  1331. //fail for modes of that format... This gives us license to blindly add the formats
  1332. //here before we really know what set of back buffer formats the device can do.
  1333. //(Note only display devices are given this boost, since voodoos don't run windowed)
  1334. if (pBaseData->dwFlags & DD_DISPLAYDRV)
  1335. {
  1336. pTextureList[cTextureFormats].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT;
  1337. pTextureList[cTextureFormats].ddpfPixelFormat.dwFourCC = (DWORD) Unknown16;
  1338. pTextureList[cTextureFormats].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_SAME_FORMAT_RENDERTARGET;
  1339. pTextureList[cTextureFormats].ddpfPixelFormat.dwPrivateFormatBitCount = 0;
  1340. pTextureList[cTextureFormats].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0;
  1341. pTextureList[cTextureFormats].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = 0;
  1342. cTextureFormats ++;
  1343. pTextureList[cTextureFormats].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT;
  1344. pTextureList[cTextureFormats].ddpfPixelFormat.dwFourCC = (DWORD) D3DFMT_X8R8G8B8;
  1345. pTextureList[cTextureFormats].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_SAME_FORMAT_RENDERTARGET;
  1346. pTextureList[cTextureFormats].ddpfPixelFormat.dwPrivateFormatBitCount = 0;
  1347. pTextureList[cTextureFormats].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0;
  1348. pTextureList[cTextureFormats].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = 0;
  1349. cTextureFormats ++;
  1350. }
  1351. else
  1352. {
  1353. // Voodood 2 hack - The V2 doesn't really support offscreen
  1354. // render targets, but we need to add a 565 RT anyway or else
  1355. // our op list won't create the device.
  1356. // CONSIDER: Adding an internal OP flag indicating that this format
  1357. // should NOT succeed in a call to CreateRenderTarget.
  1358. pTextureList[cTextureFormats].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT;
  1359. pTextureList[cTextureFormats].ddpfPixelFormat.dwFourCC = (DWORD) Unknown16;
  1360. pTextureList[cTextureFormats].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_SAME_FORMAT_RENDERTARGET;
  1361. pTextureList[cTextureFormats].ddpfPixelFormat.dwPrivateFormatBitCount = 0;
  1362. pTextureList[cTextureFormats].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0;
  1363. pTextureList[cTextureFormats].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = 0;
  1364. cTextureFormats ++;
  1365. }
  1366. // Now add in the supported display modes
  1367. if (D3DGlobalDriverData.hwCaps.dwDeviceRenderBitDepth & DDBD_16)
  1368. {
  1369. pTextureList[cTextureFormats].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT;
  1370. pTextureList[cTextureFormats].ddpfPixelFormat.dwFourCC = (DWORD) Unknown16;
  1371. pTextureList[cTextureFormats].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_DISPLAYMODE|D3DFORMAT_OP_3DACCELERATION;
  1372. pTextureList[cTextureFormats].ddpfPixelFormat.dwPrivateFormatBitCount = 0;
  1373. pTextureList[cTextureFormats].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0;
  1374. pTextureList[cTextureFormats].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = 0;
  1375. cTextureFormats++;
  1376. }
  1377. if (D3DGlobalDriverData.hwCaps.dwDeviceRenderBitDepth & DDBD_24)
  1378. {
  1379. pTextureList[cTextureFormats].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT;
  1380. pTextureList[cTextureFormats].ddpfPixelFormat.dwFourCC = (DWORD) D3DFMT_R8G8B8;
  1381. pTextureList[cTextureFormats].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_DISPLAYMODE|D3DFORMAT_OP_3DACCELERATION;
  1382. pTextureList[cTextureFormats].ddpfPixelFormat.dwPrivateFormatBitCount = 0;
  1383. pTextureList[cTextureFormats].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0;
  1384. pTextureList[cTextureFormats].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = 0;
  1385. cTextureFormats++;
  1386. }
  1387. if (D3DGlobalDriverData.hwCaps.dwDeviceRenderBitDepth & DDBD_32)
  1388. {
  1389. pTextureList[cTextureFormats].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT;
  1390. pTextureList[cTextureFormats].ddpfPixelFormat.dwFourCC = (DWORD) D3DFMT_X8R8G8B8;
  1391. pTextureList[cTextureFormats].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_DISPLAYMODE|D3DFORMAT_OP_3DACCELERATION;
  1392. pTextureList[cTextureFormats].ddpfPixelFormat.dwPrivateFormatBitCount = 0;
  1393. pTextureList[cTextureFormats].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0;
  1394. pTextureList[cTextureFormats].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = 0;
  1395. cTextureFormats++;
  1396. }
  1397. // This is a hack for those really, really old drivers that don't
  1398. // support any D3D at all. We will fill in 16 and 32bpp modes, but remove
  1399. // the 32bpp mode later if we can't find it in the mode table.
  1400. if ((D3DGlobalDriverData.hwCaps.dwDeviceRenderBitDepth == 0)
  1401. #ifdef WIN95
  1402. && (pBaseData->DriverData.D3DCaps.Caps & DDCAPS_BLT)
  1403. && !(pBaseData->DriverData.D3DCaps.Caps & DDCAPS_NOHARDWARE)
  1404. #endif
  1405. )
  1406. {
  1407. pTextureList[cTextureFormats].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT;
  1408. pTextureList[cTextureFormats].ddpfPixelFormat.dwFourCC = (DWORD) Unknown16;
  1409. pTextureList[cTextureFormats].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_DISPLAYMODE;
  1410. pTextureList[cTextureFormats].ddpfPixelFormat.dwPrivateFormatBitCount = 0;
  1411. pTextureList[cTextureFormats].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0;
  1412. pTextureList[cTextureFormats].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = 0;
  1413. cTextureFormats++;
  1414. pTextureList[cTextureFormats].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT;
  1415. pTextureList[cTextureFormats].ddpfPixelFormat.dwFourCC = (DWORD) D3DFMT_X8R8G8B8;
  1416. pTextureList[cTextureFormats].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_DISPLAYMODE;
  1417. pTextureList[cTextureFormats].ddpfPixelFormat.dwPrivateFormatBitCount = 0;
  1418. pTextureList[cTextureFormats].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0;
  1419. pTextureList[cTextureFormats].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = 0;
  1420. cTextureFormats++;
  1421. }
  1422. }
  1423. // As a final pass we infer operations as necessary. If we have an
  1424. // general operation that implies other specific operations; then we
  1425. // turn on the bits of those specific operations. This is better
  1426. // than relying on the driver to get everything right; because it lets us
  1427. // add more specific operations in future releases without breaking
  1428. // old releases.
  1429. for (i = 0; i < cTextureFormats; i++)
  1430. {
  1431. DWORD *pdwOperations = &(pTextureList[i].ddpfPixelFormat.dwOperations);
  1432. // Off-screen RT means truly mode-independent
  1433. if ((*pdwOperations) & D3DFORMAT_OP_OFFSCREEN_RENDERTARGET)
  1434. {
  1435. (*pdwOperations) |= D3DFORMAT_OP_SAME_FORMAT_UP_TO_ALPHA_RENDERTARGET;
  1436. (*pdwOperations) |= D3DFORMAT_OP_SAME_FORMAT_RENDERTARGET;
  1437. }
  1438. // Same except for alpha means exact same is good too
  1439. if ((*pdwOperations) & D3DFORMAT_OP_SAME_FORMAT_UP_TO_ALPHA_RENDERTARGET)
  1440. {
  1441. (*pdwOperations) |= D3DFORMAT_OP_SAME_FORMAT_RENDERTARGET;
  1442. }
  1443. // Color Independent Z implies that forced Z matching is ok too.
  1444. if ((*pdwOperations) & D3DFORMAT_OP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH)
  1445. {
  1446. (*pdwOperations) |= D3DFORMAT_OP_ZSTENCIL;
  1447. }
  1448. }
  1449. // Now we make a final pass to verify that they driver did gave us an
  1450. // OP list that makes sense. The OP list rules are:
  1451. //
  1452. // 1. Only One Endian-ness for any DS format is allowed i.e. D15S1 OR
  1453. // S1D15, not both independent of other bits.
  1454. // 2. A list should only include D3DFORMAT_OP_DISPLAYMODE for exactly
  1455. // one 16bpp format (i.e. shouldn�t enumerate 5:5:5 and 5:6:5).
  1456. // 3. A list should not any alpha formats with D3DFORMAT_OP_DISPLAYMODE
  1457. // or D3DFORMAT_OP_3DACCEL set.
  1458. // 4. Make sure no mode has OP_3DACCEL set that doesn�t also have
  1459. // OP_DISPLAYMODE set.
  1460. //
  1461. // We also register IHV formats with CPixel.
  1462. //
  1463. BOOL BadOpList = FALSE;
  1464. for (i = 0; i < cTextureFormats; i++)
  1465. {
  1466. if ((pTextureList[i].ddpfPixelFormat.dwOperations & D3DFORMAT_OP_PIXELSIZE) &&
  1467. pTextureList[i].ddpfPixelFormat.dwPrivateFormatBitCount != 0)
  1468. {
  1469. CPixel::Register((D3DFORMAT)pTextureList[i].ddpfPixelFormat.dwFourCC, pTextureList[i].ddpfPixelFormat.dwPrivateFormatBitCount);
  1470. }
  1471. if ((pTextureList[i].ddpfPixelFormat.dwOperations & D3DFORMAT_OP_3DACCELERATION) &&
  1472. !(pTextureList[i].ddpfPixelFormat.dwOperations & D3DFORMAT_OP_DISPLAYMODE))
  1473. {
  1474. DPF_ERR("***Driver disabled because it reported a format with D3DFORMAT_OP_3DACCELERATION without D3DFORMAT_OP_DISPLAYMODE");
  1475. BadOpList = TRUE;
  1476. }
  1477. if ((pTextureList[i].ddpfPixelFormat.dwOperations & D3DFORMAT_OP_3DACCELERATION) &&
  1478. ((pTextureList[i].ddpfPixelFormat.dwFourCC == (DWORD) D3DFMT_A8R8G8B8) ||
  1479. (pTextureList[i].ddpfPixelFormat.dwFourCC == (DWORD) D3DFMT_A1R5G5B5)))
  1480. {
  1481. DPF_ERR("***Driver disabled because it reported an alpha format with D3DFORMAT_OP_3DACCELERATION");
  1482. BadOpList = TRUE;
  1483. }
  1484. if ((pTextureList[i].ddpfPixelFormat.dwOperations & D3DFORMAT_OP_DISPLAYMODE) &&
  1485. (pTextureList[i].ddpfPixelFormat.dwFourCC == (DWORD) D3DFMT_R5G6B5))
  1486. {
  1487. if (IsSupportedOp (D3DFMT_X1R5G5B5, pTextureList, cTextureFormats, D3DFORMAT_OP_DISPLAYMODE))
  1488. {
  1489. DPF_ERR("***Driver disabled because it reported both D3DFMT_R5G6B5 and D3DFMT_X1R5G5B5 as a display mode");
  1490. BadOpList = TRUE;
  1491. }
  1492. }
  1493. if (pTextureList[i].ddpfPixelFormat.dwFourCC == (DWORD) D3DFMT_D15S1)
  1494. {
  1495. if (IsSupportedOp (D3DFMT_S1D15, pTextureList, cTextureFormats, 0))
  1496. {
  1497. DPF_ERR("***Driver disabled because it reported both D3DFMT_D15S1 and D3DFMT_S1D15");
  1498. BadOpList = TRUE;
  1499. }
  1500. }
  1501. else if (pTextureList[i].ddpfPixelFormat.dwFourCC == (DWORD) D3DFMT_D24S8)
  1502. {
  1503. if (IsSupportedOp (D3DFMT_S8D24, pTextureList, cTextureFormats, 0))
  1504. {
  1505. DPF_ERR("***Driver disabled because it reported both D3DFMT_D24S8 and D3DFMT_S8D24");
  1506. BadOpList = TRUE;
  1507. }
  1508. }
  1509. else if (pTextureList[i].ddpfPixelFormat.dwFourCC == (DWORD) D3DFMT_D24X8)
  1510. {
  1511. if (IsSupportedOp (D3DFMT_X8D24, pTextureList, cTextureFormats, 0))
  1512. {
  1513. DPF_ERR("***Driver disabled because it reported both D3DFMT_D24X8 and D3DFMT_X8D24");
  1514. BadOpList = TRUE;
  1515. }
  1516. }
  1517. else if (pTextureList[i].ddpfPixelFormat.dwFourCC == (DWORD) D3DFMT_D24X4S4)
  1518. {
  1519. if (IsSupportedOp (D3DFMT_X4S4D24, pTextureList, cTextureFormats, 0))
  1520. {
  1521. DPF_ERR("***Driver disabled because it reported both D3DFMT_D24X4S4 and D3DFMT_X4S4D24");
  1522. BadOpList = TRUE;
  1523. }
  1524. }
  1525. }
  1526. if (BadOpList)
  1527. {
  1528. D3D8DeleteDirectDrawObject(pBaseData->hDD);
  1529. pBaseData->hDD = NULL;
  1530. goto ErrorExit;
  1531. }
  1532. // and now we assign the texture list to its place in the driver data
  1533. pBaseData->DriverData.pGDD8SupportedFormatOps = pTextureList;
  1534. if (pTextureList != NULL)
  1535. {
  1536. pTextureList = NULL; //so it won't be freed later
  1537. pBaseData->DriverData.GDD8NumSupportedFormatOps = cTextureFormats;
  1538. }
  1539. else
  1540. {
  1541. pBaseData->DriverData.GDD8NumSupportedFormatOps = 0;
  1542. }
  1543. if (!(pBaseData->DriverData.D3DCaps.Caps2 & DDCAPS2_NONLOCALVIDMEM))
  1544. {
  1545. if (pBaseData->DriverData.D3DCaps.DevCaps & D3DDEVCAPS_TEXTURENONLOCALVIDMEM)
  1546. { //some drivers(Riva128 on PCI) incorrectly sets D3DDEVCAPS_TEXTURENONLOCALVIDMEM
  1547. DPF(1, "driver set D3DDEVCAPS_TEXTURENONLOCALVIDMEM w/o DDCAPS2_NONLOCALVIDMEM:turning off D3DDEVCAPS_TEXTURENONLOCALVIDMEM");
  1548. pBaseData->DriverData.D3DCaps.DevCaps &= ~D3DDEVCAPS_TEXTURENONLOCALVIDMEM;
  1549. }
  1550. }
  1551. // For pre-DX8, we have some munging of caps that is necessary
  1552. if (pBaseData->DriverData.D3DCaps.MaxStreams == 0)
  1553. {
  1554. DWORD *pdwTextureCaps = &pBaseData->DriverData.D3DCaps.TextureCaps;
  1555. if (*pdwTextureCaps & D3DPTEXTURECAPS_CUBEMAP)
  1556. {
  1557. if (pBaseData->DriverData.KnownDriverFlags & KNOWN_MIPPEDCUBEMAPS)
  1558. {
  1559. *pdwTextureCaps |= D3DPTEXTURECAPS_MIPCUBEMAP;
  1560. }
  1561. else
  1562. {
  1563. // Turn off Mip filter flags since this is card doesnt support a mipped cubemap.
  1564. pBaseData->DriverData.D3DCaps.CubeTextureFilterCaps &= ~(D3DPTFILTERCAPS_MIPFPOINT |
  1565. D3DPTFILTERCAPS_MIPFLINEAR);
  1566. }
  1567. // Also we need to specify that cube-maps must
  1568. // be power-of-two
  1569. *pdwTextureCaps |= D3DPTEXTURECAPS_CUBEMAP_POW2;
  1570. }
  1571. // We need to determine the part can support mipmaps...
  1572. if (pBaseData->DriverData.D3DCaps.TextureFilterCaps &
  1573. (D3DPTFILTERCAPS_MIPNEAREST |
  1574. D3DPTFILTERCAPS_MIPLINEAR |
  1575. D3DPTFILTERCAPS_LINEARMIPNEAREST |
  1576. D3DPTFILTERCAPS_LINEARMIPLINEAR |
  1577. D3DPTFILTERCAPS_MIPFPOINT |
  1578. D3DPTFILTERCAPS_MIPFLINEAR))
  1579. {
  1580. *pdwTextureCaps |= D3DPTEXTURECAPS_MIPMAP;
  1581. }
  1582. else
  1583. {
  1584. DPF(3, "Device doesn't support mip-maps");
  1585. }
  1586. }
  1587. // We disable driver-management for pre-dx8 parts because
  1588. // the semantics for driver-management are now different
  1589. // for dx8; and hence we can't use old driver's logic.
  1590. pBaseData->DriverData.D3DCaps.Caps2 &= ~DDCAPS2_CANMANAGETEXTURE;
  1591. // For HW that needs separate banks of texture memory; we
  1592. // disable multi-texturing. This is done because we don't want to
  1593. // have an API that puts the burden on the application to specifically
  1594. // code for this case.
  1595. if (pBaseData->DriverData.D3DCaps.DevCaps & D3DDEVCAPS_SEPARATETEXTUREMEMORIES)
  1596. {
  1597. pBaseData->DriverData.D3DCaps.MaxSimultaneousTextures = 1;
  1598. // Turn off this flag.
  1599. pBaseData->DriverData.D3DCaps.DevCaps &= ~D3DDEVCAPS_SEPARATETEXTUREMEMORIES;
  1600. }
  1601. }
  1602. ErrorExit:
  1603. if (NULL != pTextureList)
  1604. MemFree(pTextureList);
  1605. // It was only temporary, having now been merged into the supported op list.
  1606. if (NULL != pZStencilFormatList)
  1607. MemFree(pZStencilFormatList);
  1608. return;
  1609. } /* FetchDirectDrawData */
  1610. /*
  1611. * DirectDrawSupported
  1612. */
  1613. BOOL DirectDrawSupported(void)
  1614. {
  1615. HDC hdc;
  1616. unsigned u;
  1617. hdc = GetDC(NULL);
  1618. u = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
  1619. ReleaseDC(NULL, hdc);
  1620. if (u < 8)
  1621. {
  1622. return FALSE;
  1623. }
  1624. return TRUE;
  1625. } /* DirectDrawSupported */
  1626. // Utility function that tells us if there is more than
  1627. // one display device in the system. (We count all devices,
  1628. // regardless of whether they are attached to the desktop.)
  1629. BOOL IsMultiMonitor(void)
  1630. {
  1631. int i, n;
  1632. // Each loop below enumerates one display device.
  1633. for (i = 0, n = 0; ; i++)
  1634. {
  1635. DISPLAY_DEVICEA dd;
  1636. // Zero the memory of the DISPLAY_DEVICE struct between calls to
  1637. // EnumDisplayDevices
  1638. ZeroMemory(&dd, sizeof(dd));
  1639. dd.cb = sizeof(dd);
  1640. if (!xxxEnumDisplayDevicesA(NULL, i, &dd, 0))
  1641. {
  1642. break; // no more devices to enumerate
  1643. }
  1644. if (dd.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER)
  1645. {
  1646. continue; // not a real hardware display driver
  1647. }
  1648. // We're just trying to count the number of display devices in the
  1649. // system and see if there is more than one.
  1650. if (++n > 1)
  1651. {
  1652. return TRUE; // multiple display devices
  1653. }
  1654. }
  1655. return FALSE; // single display device
  1656. }
  1657. BOOL fDoesGDI(HDC hdc)
  1658. {
  1659. //
  1660. // the 3Dfx driver always return 1 to every thing
  1661. // verify GetNearest() color works.
  1662. //
  1663. BOOL b = GetNearestColor(hdc, 0x000000) == 0x000000 &&
  1664. GetNearestColor(hdc, 0xFFFFFF) == 0xFFFFFF;
  1665. if (b)
  1666. {
  1667. DPF(3,"Driver is a GDI driver");
  1668. }
  1669. return b;
  1670. }
  1671. /*
  1672. * Functions to dynamically link against exports we need in user32 on
  1673. * older OSes
  1674. */
  1675. //These statics will be per-process, cuz it's outside the shared section
  1676. typedef BOOL (WINAPI * LPENUMMONITORS) (HDC, LPRECT, MONITORENUMPROC, LPARAM);
  1677. typedef BOOL (WINAPI * LPGETMONINFO) (HMONITOR, MONITORINFO *);
  1678. typedef BOOL (WINAPI * LPISDEBUG) (void);
  1679. static LPISDEBUG pIsDebuggerPresent = 0;
  1680. static LPENUMMONITORS pEnumMonitors = 0;
  1681. static LPGETMONINFO pGetMonitorInfo = 0;
  1682. static BOOL bTriedToGetProcAlready = FALSE;
  1683. BOOL DynamicLinkToOS(void)
  1684. {
  1685. if (1) //!pEnumMonitors)
  1686. {
  1687. HMODULE hUser32;
  1688. HMODULE hKernel32;
  1689. if (0) //bTriedToGetProcAlready)
  1690. return FALSE;
  1691. bTriedToGetProcAlready = TRUE;
  1692. hUser32 = GetModuleHandle(TEXT("USER32"));
  1693. pEnumMonitors = (LPENUMMONITORS) GetProcAddress(hUser32,"EnumDisplayMonitors");
  1694. pGetMonitorInfo = (LPGETMONINFO) GetProcAddress(hUser32,"GetMonitorInfoA");
  1695. hKernel32 = GetModuleHandle(TEXT("KERNEL32"));
  1696. pIsDebuggerPresent = (LPISDEBUG) GetProcAddress(hKernel32,"IsDebuggerPresent");
  1697. if (!pEnumMonitors || !pGetMonitorInfo || !pIsDebuggerPresent)
  1698. {
  1699. DPF(3,"Failed to get proc addresses");
  1700. return FALSE;
  1701. }
  1702. }
  1703. DDASSERT(pEnumMonitors);
  1704. DDASSERT(pGetMonitorInfo);
  1705. DDASSERT(pEnumMonitors);
  1706. return TRUE;
  1707. }
  1708. BOOL InternalGetMonitorInfo(HMONITOR hMon, MONITORINFO *lpInfo)
  1709. {
  1710. DynamicLinkToOS();
  1711. if (!pGetMonitorInfo)
  1712. return FALSE;
  1713. return pGetMonitorInfo(hMon, lpInfo);
  1714. }
  1715. typedef struct
  1716. {
  1717. LPSTR pName;
  1718. HMONITOR hMon;
  1719. } CALLBACKSTRUCT, * LPCALLBACKSTRUCT;
  1720. BOOL InternalEnumMonitors(MONITORENUMPROC proc, LPCALLBACKSTRUCT lp)
  1721. {
  1722. DynamicLinkToOS();
  1723. if (!pEnumMonitors)
  1724. return FALSE;
  1725. pEnumMonitors(NULL,NULL,proc,(LPARAM)lp);
  1726. return TRUE;
  1727. }
  1728. /*
  1729. * InternalIsDebuggerPresent
  1730. * A little helper so that this runtime runs against older OSes
  1731. */
  1732. BOOL InternalIsDebuggerPresent(void)
  1733. {
  1734. DynamicLinkToOS();
  1735. if (!pIsDebuggerPresent)
  1736. return FALSE;
  1737. return pIsDebuggerPresent();
  1738. }
  1739. //
  1740. // getPrimaryDisplayName
  1741. //
  1742. void getPrimaryDisplayName(void)
  1743. {
  1744. DISPLAY_DEVICE dd;
  1745. int i;
  1746. ZeroMemory(&dd, sizeof dd);
  1747. dd.cb = sizeof dd;
  1748. for (i = 0; xxxEnumDisplayDevicesA(NULL, i, &dd, 0); ++i)
  1749. {
  1750. if (dd.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
  1751. {
  1752. lstrcpyn(g_szPrimaryDisplay, dd.DeviceName, sizeof g_szPrimaryDisplay);
  1753. return;
  1754. }
  1755. }
  1756. lstrcpy(g_szPrimaryDisplay, DISPLAY_STR);
  1757. }
  1758. /*
  1759. * InternalDirectDrawCreate
  1760. */
  1761. HRESULT InternalDirectDrawCreate(
  1762. PD3D8_DEVICEDATA* ppBaseData,
  1763. PADAPTERINFO pDeviceInfo,
  1764. D3DDEVTYPE DeviceType,
  1765. VOID* pInitFunction,
  1766. D3DFORMAT Unknown16,
  1767. DDSURFACEDESC* pHalOpList,
  1768. DWORD NumHalOps)
  1769. {
  1770. int rc;
  1771. HDC hdc_dd;
  1772. HKEY hkey;
  1773. ULONG_PTR hDD;
  1774. PD3D8_DEVICEDATA pBaseData;
  1775. *ppBaseData = (PD3D8_DEVICEDATA) NULL;
  1776. /*
  1777. * check for < 8 bpp and disallow.
  1778. */
  1779. if (!DirectDrawSupported())
  1780. {
  1781. DPF_ERR("DDraw and Direct3D are not supported in less than 8bpp modes. Creating Device fails.");
  1782. return D3DERR_NOTAVAILABLE;
  1783. }
  1784. ENTER_CSDDC();
  1785. hdc_dd = NULL;
  1786. hDD = 0;
  1787. //
  1788. // Get the primary display name, which will usually be something like
  1789. // \\.\Display1 and in some cases may be \\.\Display1\Unit0. We only
  1790. // do this one time, and store it globally. On Win98, the global name
  1791. // will be shared between all processes, and on NT5, each process will
  1792. // have its own copy. Also, note that the primary device name may change
  1793. // on NT5; we need to look into this.
  1794. //
  1795. if (g_szPrimaryDisplay[0] == '\0')
  1796. {
  1797. getPrimaryDisplayName();
  1798. }
  1799. // Create the object and get all of the data.
  1800. hdc_dd = DD_CreateDC(pDeviceInfo->DeviceName);
  1801. if (hdc_dd == NULL)
  1802. {
  1803. DPF_ERR("Could not create driver, CreateDC failed! Creating Device fails.");
  1804. LEAVE_CSDDC();
  1805. return E_OUTOFMEMORY;
  1806. }
  1807. // Create the driver object
  1808. pBaseData = (PD3D8_DEVICEDATA) MemAlloc (sizeof (D3D8_DEVICEDATA));
  1809. if (pBaseData == NULL)
  1810. {
  1811. DPF_ERR("Insufficient system memory! Creating Device fails. ");
  1812. DD_DoneDC(hdc_dd);
  1813. LEAVE_CSDDC();
  1814. return E_OUTOFMEMORY;
  1815. }
  1816. ZeroMemory( pBaseData, sizeof(D3D8_DEVICEDATA) );
  1817. strcpy(pBaseData->DriverName, pDeviceInfo->DeviceName);
  1818. pBaseData->hDC = hdc_dd;
  1819. pBaseData->Guid = pDeviceInfo->Guid;
  1820. pBaseData->DeviceType = DeviceType;
  1821. // Even if it's not a display driver, it may still be a GDI driver
  1822. if (hdc_dd != NULL)
  1823. {
  1824. if (pDeviceInfo->bIsDisplay)
  1825. {
  1826. pBaseData->dwFlags |= DD_DISPLAYDRV;
  1827. }
  1828. else if (fDoesGDI(hdc_dd))
  1829. {
  1830. pBaseData->dwFlags |= DD_GDIDRV;
  1831. }
  1832. }
  1833. // Get all of the driver caps and callbacks
  1834. FetchDirectDrawData(pBaseData,
  1835. pInitFunction,
  1836. Unknown16,
  1837. pHalOpList,
  1838. NumHalOps);
  1839. if (pBaseData->hDD == NULL)
  1840. {
  1841. DDASSERT(NULL == pBaseData->DriverData.pGDD8SupportedFormatOps);
  1842. DD_DoneDC(hdc_dd);
  1843. MemFree(pBaseData);
  1844. LEAVE_CSDDC();
  1845. return D3DERR_NOTAVAILABLE;
  1846. }
  1847. *ppBaseData = pBaseData;
  1848. LEAVE_CSDDC();
  1849. return S_OK;
  1850. } /* InternalDirectDrawCreate */
  1851. /*
  1852. * InternalDirectDrawRelease
  1853. */
  1854. HRESULT InternalDirectDrawRelease(PD3D8_DEVICEDATA pBaseData)
  1855. {
  1856. D3D8DeleteDirectDrawObject(pBaseData->hDD);
  1857. DD_DoneDC(pBaseData->hDC);
  1858. MemFree(pBaseData->DriverData.pGDD8SupportedFormatOps);
  1859. MemFree(pBaseData);
  1860. return S_OK;
  1861. } /* InternalDirectDrawRelease */
  1862. BOOL CALLBACK MonitorEnumProc(HMONITOR hMon, HDC hdc, LPRECT lpr, LPARAM lParam)
  1863. {
  1864. MONITORINFOEX mix;
  1865. MONITORINFO mi;
  1866. LPCALLBACKSTRUCT lpcb = (LPCALLBACKSTRUCT) lParam;
  1867. mi.cbSize = sizeof(mi);
  1868. if (!InternalGetMonitorInfo(hMon,&mi))
  1869. return FALSE;
  1870. mix.cbSize = sizeof(mix);
  1871. if (!InternalGetMonitorInfo(hMon,(MONITORINFO*) &mix))
  1872. return FALSE;
  1873. if (!strcmp(lpcb->pName,(LPSTR)mix.szDevice))
  1874. {
  1875. //Found it!!
  1876. lpcb->hMon = hMon;
  1877. return FALSE;
  1878. }
  1879. return TRUE;
  1880. }
  1881. /*
  1882. * GetMonitorFromDeviceName
  1883. */
  1884. HMONITOR GetMonitorFromDeviceName(LPSTR szName)
  1885. {
  1886. CALLBACKSTRUCT cbs;
  1887. cbs.pName = szName;
  1888. cbs.hMon = NULL;
  1889. if (!InternalEnumMonitors(MonitorEnumProc, &cbs))
  1890. return NULL;
  1891. return cbs.hMon;
  1892. }
  1893. /*
  1894. * these are exported... temp. hack for non-Win95
  1895. */
  1896. #ifndef WIN95
  1897. void DDAPI thk3216_ThunkData32(void)
  1898. {
  1899. }
  1900. void DDAPI thk1632_ThunkData32(void)
  1901. {
  1902. }
  1903. DWORD DDAPI DDGetPID(void)
  1904. {
  1905. return 0;
  1906. }
  1907. int DDAPI DDGetRequest(void)
  1908. {
  1909. return 0;
  1910. }
  1911. BOOL DDAPI DDGetDCInfo(LPSTR fname)
  1912. {
  1913. return 0;
  1914. }
  1915. #ifdef POSTPONED
  1916. BOOL DDAPI DD32_HandleExternalModeChange(LPDEVMODE pModeInfo)
  1917. {
  1918. return FALSE;
  1919. }
  1920. #endif
  1921. #endif