/tags/JSTUDIO3D_2_5_beta_1/source/Engine/JetEngine/Engine/Drivers/D3DDrv/D3DDRV.CPP

# · C++ · 605 lines · 402 code · 132 blank · 71 comment · 39 complexity · 2bd1ee1e0ae84ba7408c4d9454b3a6d6 MD5 · raw file

  1. /****************************************************************************************/
  2. /* D3DDrv.cpp */
  3. /* */
  4. /* Author: John Pollard */
  5. /* Description: D3D driver */
  6. /* */
  7. /* The contents of this file are subject to the Jet3D Public License */
  8. /* Version 1.01 (the "License"); you may not use this file except in */
  9. /* compliance with the License. You may obtain a copy of the License at */
  10. /* http://www.jet3d.com */
  11. /* */
  12. /* Software distributed under the License is distributed on an "AS IS" */
  13. /* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See */
  14. /* the License for the specific language governing rights and limitations */
  15. /* under the License. */
  16. /* */
  17. /* The Original Code is Jet3D, released December 12, 1999. */
  18. /* Copyright (C) 1996-1999 Eclipse Entertainment, L.L.C. All Rights Reserved */
  19. /* */
  20. /****************************************************************************************/
  21. #include <Windows.h>
  22. #include <ddraw.h>
  23. #include <stdio.h>
  24. #include "D3DDrv.h"
  25. #include "DCommon.h"
  26. #include "d3d_Scene.h"
  27. #include "d3d_Render.h"
  28. #include "D3DCache.h"
  29. #include "D3D_Main.h"
  30. #include "d3d_PCache.h"
  31. #include "d3d_THandle.h"
  32. #include "d3d_GSpan.h"
  33. #include "D3D_fx.h"
  34. DRV_Window D3DDrv_ClientWindow;
  35. static char LastErrorStr[200];
  36. static BOOL ExitHandlerActive = FALSE;
  37. static DRV_EngineSettings EngineSettings;
  38. static jeRDriver_PixelFormat PixelFormat[10];
  39. #define NUM_PIXEL_FORMATS (sizeof(PixelFormats)/sizeof(jeRDriver_PixelFormat))
  40. static HINSTANCE DirectDrawInstance;
  41. static LPDIRECTDRAWCREATE DirectDrawCreateFN;
  42. static LPDIRECTDRAWENUMERATE DirectDrawEnumerateFN;
  43. jeBoolean DRIVERCC DrvShutdown(void);
  44. jeBoolean DRIVERCC ScreenShot(const char *Name);
  45. jeBoolean DRIVERCC DrawDDText(char *text, int x,int y, uint32 color);
  46. jeBoolean DRIVERCC SetFog(float r, float g, float b, float start, float endi, jeBoolean Enable);
  47. //============================================================================================
  48. //============================================================================================
  49. static void D3DDrv_InitStaticsAndGlobals(void)
  50. {
  51. memset(&D3DDrv_ClientWindow, 0, sizeof(D3DDrv_ClientWindow));
  52. //LastError = 0;
  53. memset(LastErrorStr, 0, sizeof(LastErrorStr));
  54. if (DirectDrawInstance != NULL)
  55. FreeLibrary(DirectDrawInstance);
  56. DirectDrawInstance = NULL;
  57. DirectDrawCreateFN = NULL;
  58. DirectDrawEnumerateFN = NULL;
  59. memset(&EngineSettings, 0, sizeof(EngineSettings));
  60. memset(PixelFormat, 0, sizeof(PixelFormat));
  61. }
  62. //============================================================================================
  63. //============================================================================================
  64. /*
  65. This next part is a little ugly thing to let us get the name of certain
  66. Windows functions right for calls to GetProcAddress. This macro lets us
  67. get the right one of DirectDrawEnumerateA vs. DirectDrawEnumerateW in case
  68. someone wants to build the wide char version of this beast.
  69. */
  70. #define MacroStr1(n) #n
  71. #define MacroStr(n) MacroStr1(n)
  72. static HRESULT __stdcall DirectDrawCreateFake( GUID FAR *lpGUID, LPDIRECTDRAW7 FAR *lplpDD, REFIID iid, IUnknown FAR *pUnkOuter )
  73. {
  74. return !DD_OK;
  75. }
  76. static HRESULT __stdcall DirectDrawEnumerateFake( LPDDENUMCALLBACK lpCallback, LPVOID lpContext )
  77. {
  78. return !DD_OK;
  79. }
  80. static BOOL LoadDirectDraw(void)
  81. {
  82. if (DirectDrawInstance)
  83. return TRUE;
  84. DirectDrawInstance = LoadLibrary("ddraw.dll");
  85. DirectDrawCreateFN =(LPDIRECTDRAWCREATE)GetProcAddress(DirectDrawInstance, "DirectDrawCreateEx");
  86. DirectDrawEnumerateFN =(LPDIRECTDRAWENUMERATE)GetProcAddress(DirectDrawInstance, MacroStr(DirectDrawEnumerate));
  87. if (!DirectDrawCreateFN || !DirectDrawEnumerateFN)
  88. {
  89. FreeLibrary(DirectDrawInstance);
  90. DirectDrawInstance = NULL;
  91. DirectDrawCreateFN = DirectDrawCreateFake;
  92. DirectDrawEnumerateFN = DirectDrawEnumerateFake;
  93. return FALSE;
  94. }
  95. return TRUE;
  96. }
  97. LPDIRECTDRAWCREATE D3DDrv_DirectDrawCreate(void)
  98. {
  99. LoadDirectDraw();
  100. return DirectDrawCreateFN;
  101. }
  102. LPDIRECTDRAWENUMERATE D3DDrv_DirectDrawEnumerate(void)
  103. {
  104. LoadDirectDraw();
  105. return DirectDrawEnumerateFN;
  106. }
  107. BOOL DRIVERCC DrvInit(DRV_DriverHook *Hook)
  108. {
  109. RECT WRect;
  110. D3DDrv_InitStaticsAndGlobals();
  111. D3DFx_InitStaticsAndGlobals();
  112. PCache_InitStaticsAndGlobals();
  113. #ifdef USE_SPANS
  114. GSpan_InitStaticsAndGlobals();
  115. #endif
  116. // Start up
  117. if (!D3DMain_InitD3D(Hook->hWnd, Hook->DriverName, Hook->Width, Hook->Height))
  118. {
  119. //SetLastDrvError(DRV_ERROR_INIT_ERROR, "D3D_DrvInit: Could not init driver.\n");
  120. return FALSE;
  121. }
  122. // If they are asking for a window mode, use there hWnd for the size
  123. if (Hook->Width ==-1 && Hook->Height == -1)
  124. {
  125. GetClientRect(Hook->hWnd, &WRect);
  126. Hook->Width = (WRect.right - WRect.left);
  127. Hook->Height = (WRect.bottom - WRect.top);
  128. }
  129. D3DDrv_ClientWindow.Width = Hook->Width;
  130. D3DDrv_ClientWindow.Height = Hook->Height;
  131. D3DDrv_ClientWindow.hWnd = Hook->hWnd;
  132. return TRUE;
  133. }
  134. //============================================================================================
  135. //============================================================================================
  136. BOOL DRIVERCC DrvShutdown(void)
  137. {
  138. D3DMain_ShutdownD3D();
  139. /*
  140. Make sure that we shut down the DLL, and reset things to the faked out
  141. functions. If it needs to be restarted, it will happend automatically.
  142. */
  143. if (DirectDrawInstance)
  144. {
  145. FreeLibrary(DirectDrawInstance);
  146. DirectDrawInstance = NULL;
  147. DirectDrawCreateFN = DirectDrawCreateFake;
  148. DirectDrawEnumerateFN = DirectDrawEnumerateFake;
  149. }
  150. return TRUE;
  151. }
  152. //============================================================================================
  153. // DrvResetAll
  154. //============================================================================================
  155. jeBoolean DRIVERCC DrvResetAll(void)
  156. {
  157. return D3DMain_Reset();
  158. }
  159. //============================================================================================
  160. // EnumPixelFormats
  161. // NOTE: that this function only works after the video mode has been set...
  162. //============================================================================================
  163. jeBoolean DRIVERCC EnumPixelFormats(DRV_ENUM_PFORMAT_CB *Cb, void *Context)
  164. {
  165. int32 i;
  166. jePixelFormat Format3d, Format2d;
  167. uint32 CurrentBpp;
  168. CurrentBpp = D3DInfo.ddsd.ddpfPixelFormat.dwRGBBitCount;
  169. // Setup the 2d surface format
  170. if (CurrentBpp == 32 && D3DInfo.ddSurfFormat.ddpfPixelFormat.dwRGBAlphaBitMask == 0xff000000)
  171. Format2d = JE_PIXELFORMAT_32BIT_ARGB;
  172. else if (CurrentBpp == 32 && D3DInfo.ddSurfFormat.ddpfPixelFormat.dwBBitMask == 0xff)
  173. Format2d = JE_PIXELFORMAT_32BIT_XRGB;
  174. else if (CurrentBpp == 24 && D3DInfo.ddSurfFormat.ddpfPixelFormat.dwBBitMask == 0xff)
  175. Format2d = JE_PIXELFORMAT_24BIT_RGB;
  176. else if (D3DInfo.ddSurfFormat.ddpfPixelFormat.dwGBitMask == (31<<5))
  177. Format2d = JE_PIXELFORMAT_16BIT_555_RGB;
  178. else
  179. Format2d = JE_PIXELFORMAT_16BIT_565_RGB;
  180. // Setup the 3d (Texture) format
  181. if (D3DInfo.ddTexFormat.ddpfPixelFormat.dwGBitMask == (31<<5))
  182. Format3d = JE_PIXELFORMAT_16BIT_555_RGB;
  183. else
  184. Format3d = JE_PIXELFORMAT_16BIT_565_RGB;
  185. // Create the surface formats now
  186. PixelFormat[0].PixelFormat = Format3d; // 3d 565/555 surface
  187. PixelFormat[0].Flags = RDRIVER_PF_3D | RDRIVER_PF_COMBINE_LIGHTMAP;
  188. PixelFormat[1].PixelFormat = JE_PIXELFORMAT_16BIT_4444_ARGB; // 3d 4444 surface
  189. PixelFormat[1].Flags = RDRIVER_PF_3D | RDRIVER_PF_COMBINE_LIGHTMAP | RDRIVER_PF_ALPHA;
  190. PixelFormat[2].PixelFormat = Format2d; // 2d 565/555 surface
  191. PixelFormat[2].Flags = RDRIVER_PF_2D | RDRIVER_PF_CAN_DO_COLORKEY;
  192. PixelFormat[3].PixelFormat = Format3d; // Lightmap 565/555 surface
  193. PixelFormat[3].Flags = RDRIVER_PF_LIGHTMAP;
  194. PixelFormat[4].PixelFormat = JE_PIXELFORMAT_16BIT_1555_ARGB;
  195. PixelFormat[4].Flags = RDRIVER_PF_3D | RDRIVER_PF_COMBINE_LIGHTMAP | RDRIVER_PF_ALPHA;
  196. // Then hand them off to the caller
  197. for (i=0; i<5; i++)
  198. {
  199. if (!Cb(&PixelFormat[i], Context))
  200. return JE_TRUE;
  201. }
  202. return TRUE;
  203. }
  204. //============================================================================================
  205. // SetGamma
  206. //============================================================================================
  207. jeBoolean DRIVERCC SetGamma(float Gamma)
  208. {
  209. return JE_TRUE;
  210. }
  211. //============================================================================================
  212. // GetGamma
  213. //============================================================================================
  214. jeBoolean DRIVERCC GetGamma(float *Gamma)
  215. {
  216. *Gamma = 1.0f;
  217. return JE_TRUE;
  218. }
  219. static jeBoolean DRIVERCC DrvGetDeviceCaps(jeDeviceCaps *DeviceCaps)
  220. {
  221. DeviceCaps->SuggestedDefaultRenderFlags = JE_RENDER_FLAG_BILINEAR_FILTER;
  222. DeviceCaps->CanChangeRenderFlags = 0xFFFFFFFF;
  223. return JE_TRUE;
  224. }
  225. BOOL DRIVERCC EnumSubDrivers2(DRV_ENUM_DRV_CB *Cb, void *Context);
  226. BOOL DRIVERCC EnumModes2(int32 Driver, char *DriverName, DRV_ENUM_MODES_CB *Cb, void *Context);
  227. DRV_Driver D3DDRV =
  228. {
  229. "D3D driver. v"DRV_VMAJS"."DRV_VMINS". Copyright 1999, Eclipse Entertainment; All Rights Reserved.",
  230. DRV_VERSION_MAJOR,
  231. DRV_VERSION_MINOR,
  232. DRV_ERROR_NONE,
  233. NULL,
  234. EnumSubDrivers2,
  235. EnumModes2,
  236. EnumPixelFormats,
  237. DrvGetDeviceCaps,
  238. DrvInit,
  239. DrvShutdown,
  240. DrvResetAll,
  241. D3DMain_UpdateWindow,
  242. D3DMain_SetActive,
  243. THandle_Create,
  244. NULL,
  245. THandle_Destroy,
  246. THandle_Lock,
  247. THandle_UnLock,
  248. NULL, // SetPal
  249. NULL, // GetPal
  250. NULL, // SetAlpha
  251. NULL, // GetAlpha
  252. THandle_GetInfo,
  253. D3DBeginScene,
  254. D3DEndScene,
  255. PCache_BeginBatch,
  256. PCache_EndBatch,
  257. RenderGouraudPoly,
  258. RenderWorldPoly,
  259. RenderMiscTexturePoly,
  260. DrawDecal,
  261. 0,0,0,
  262. &PCache_CacheInfo,
  263. ScreenShot,
  264. SetGamma,
  265. GetGamma,
  266. // BEGIN - Hardware T&L - paradoxnj 4/5/2005
  267. NULL,
  268. NULL,
  269. NULL,
  270. // END - Hardware T&L - paradoxnj 4/5/2005
  271. NULL,
  272. NULL, // Init to NULL, engine SHOULD set this (SetupLightmap)
  273. // KROUER
  274. DrawDDText, // optimized draw text functions
  275. SetFog,
  276. NULL,
  277. NULL,
  278. NULL,
  279. NULL,
  280. NULL,
  281. NULL,
  282. D3DMain_SetRenderState
  283. };
  284. static BOOL DriverHook(DRV_Driver **Driver)
  285. {
  286. // If there is no DirectDraw, bail out right away.
  287. // if (LoadDirectDraw() == FALSE)
  288. // return FALSE;
  289. EngineSettings.CanSupportFlags = (DRV_SUPPORT_ALPHA | DRV_SUPPORT_COLORKEY);
  290. EngineSettings.PreferenceFlags = 0;
  291. D3DDRV.EngineSettings = &EngineSettings;
  292. *Driver = &D3DDRV;
  293. // Make sure the error string ptr is not null, or invalid!!!
  294. D3DDRV.LastErrorStr = LastErrorStr;
  295. SetLastDrvError(DRV_ERROR_NONE, "D3DDrv: No error.");
  296. return TRUE;
  297. }
  298. extern "C" JETAPI void * JETCC jeEngine_D3DDriver(void)
  299. {
  300. return (void *)DriverHook;
  301. }
  302. void SetLastDrvError(int32 Error, char *ErrorStr)
  303. {
  304. //LastError = Error;
  305. if (ErrorStr)
  306. strcpy(LastErrorStr, ErrorStr);
  307. else
  308. LastErrorStr[0] = NULL;
  309. D3DDRV.LastErrorStr = LastErrorStr;
  310. D3DDRV.LastError = Error;
  311. }
  312. //============================================================================================
  313. // D3D Screenshot BMp code
  314. //============================================================================================
  315. #include "Ram.h"
  316. #ifdef BITS16
  317. #define RED(x) ((unsigned short)((x>>11) & 0x1f))
  318. #define GREEN(x) ((unsigned short)((x>>6 ) & 0x1f))
  319. #define BLUE(x) ((unsigned short)((x>>0 ) & 0x1f))
  320. #else
  321. #define RED(x) ((unsigned short)((x>>11) & 0x1f))
  322. #define GREEN(x) ((unsigned short)((x>>5 ) & 63))
  323. #define BLUE(x) ((unsigned short)((x>>0 ) & 0x1f))
  324. #endif
  325. static jeBoolean WriteBMP(unsigned short *ScreenBuffer, int32 Width, int32 Height, int32 Stride, const char *Name)
  326. {
  327. BITMAPFILEHEADER bfh =
  328. {
  329. ((unsigned short)'B' | ((unsigned short)'M' << 8)),
  330. sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFO) + Width * Height * 2,
  331. 0,
  332. 0,
  333. sizeof(BITMAPINFOHEADER)
  334. };
  335. BITMAPINFO bi =
  336. {
  337. {
  338. sizeof(BITMAPINFOHEADER),
  339. Width,
  340. Height,
  341. 1,
  342. 24,
  343. BI_RGB,
  344. 0,
  345. 0,
  346. 0,
  347. 0,
  348. 0
  349. }
  350. };
  351. FILE *out;
  352. int y;
  353. unsigned char *Buff;
  354. Buff = JE_RAM_ALLOCATE_ARRAY(uint8, Width*3);
  355. if (!Buff)
  356. return JE_FALSE;
  357. out = fopen(Name, "wb");
  358. if (!out)
  359. return JE_FALSE;
  360. if (fwrite(&bfh, sizeof(bfh), 1, out) != 1)
  361. return JE_FALSE;
  362. if (fwrite(&bi, sizeof(bi), 1, out) != 1)
  363. return JE_FALSE;
  364. for (y = Height-1; y >= 0; y--)
  365. {
  366. int i;
  367. unsigned short *p;
  368. unsigned char *BuffPtr;
  369. BuffPtr = &Buff[0];
  370. p = &ScreenBuffer[y*Stride];
  371. for (i = 0; i < Width; i++)
  372. {
  373. #ifdef BIT16
  374. unsigned short c;
  375. c = p[i];
  376. c = (RED(c) << 10) + (GREEN(c) << 5) + BLUE(c);
  377. p[i] = c;
  378. #else
  379. #ifdef VER1
  380. char c[3];
  381. c = (char)(GREEN(p[i]) << 2);
  382. fwrite(&c, 1, 1, out);
  383. c = (char)(RED(p[i]) << 3);
  384. fwrite(&c, 1, 1, out);
  385. c = (char)(BLUE(p[i]) << 3);
  386. fwrite(&c, 1, 1, out);
  387. #else
  388. #if 0
  389. char c[3];
  390. c = (char)(BLUE(p[i]) << 3);
  391. fwrite(&c, 1, 1, out);
  392. c = (char)(GREEN(p[i]) << 2);
  393. fwrite(&c, 1, 1, out);
  394. c = (char)(RED(p[i]) << 3);
  395. fwrite(&c, 1, 1, out);
  396. #else
  397. *BuffPtr++ = (char)(BLUE(p[i]) << 3);
  398. *BuffPtr++ = (char)(GREEN(p[i]) << 2);
  399. *BuffPtr++ = (char)(RED(p[i]) << 3);
  400. // fwrite(&c[0], 3, 1, out);
  401. #endif
  402. #endif
  403. #endif
  404. }
  405. fwrite(&Buff[0], Width * 3, 1, out);
  406. #ifdef BIT16
  407. p = &ScreenBuffer[y*Stride];
  408. for (i = 0; i < Width; i++)
  409. fwrite(&p[(i+2)%Width], 2, 1, out);
  410. #endif
  411. }
  412. jeRam_Free(Buff);
  413. if (fclose(out))
  414. return JE_FALSE;
  415. return JE_TRUE;
  416. }
  417. BOOL DRIVERCC ScreenShot(const char *Name)
  418. {
  419. #if 1
  420. int32 Width, Height, Stride;
  421. DDSURFACEDESC2 SurfDesc;
  422. uint16 *Surface;
  423. HRESULT Result;
  424. memset(&SurfDesc, 0, sizeof(DDSURFACEDESC2));
  425. SurfDesc.dwSize = sizeof(DDSURFACEDESC2);
  426. Result = D3DInfo.lpBackBuffer->Lock(NULL, &SurfDesc, DDLOCK_WAIT, NULL);
  427. if (Result != DD_OK)
  428. return JE_FALSE;
  429. Surface = (uint16*)SurfDesc.lpSurface;
  430. Width = SurfDesc.dwWidth;
  431. Height = SurfDesc.dwHeight;
  432. Stride = SurfDesc.lPitch>>1;
  433. if (!WriteBMP(Surface, Width, Height, Stride, Name))
  434. return JE_FALSE;
  435. Result = D3DInfo.lpFrontBuffer->Unlock(NULL);
  436. if (Result != DD_OK)
  437. return JE_FALSE;
  438. #endif
  439. return JE_TRUE;
  440. }
  441. BOOL DRIVERCC SetFog(float r, float g, float b, float start, float endi, jeBoolean enabled)
  442. {
  443. D3DInfo.Fog.R = r;
  444. D3DInfo.Fog.G = g;
  445. D3DInfo.Fog.B = b;
  446. D3DInfo.Fog.Start = start;
  447. D3DInfo.Fog.End = endi;
  448. D3DInfo.Fog.Enabled = enabled;
  449. if(enabled)
  450. {
  451. D3DInfo.lpD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE,true);
  452. D3DInfo.lpD3DDevice->SetRenderState(D3DRENDERSTATE_FOGCOLOR,((DWORD)r<<16)|((DWORD)g<<8)|(DWORD)b);//0x00FFFFFF);//((DWORD)AppInfo.FogR<<16)|((DWORD)AppInfo.FogG<<8)|(DWORD)AppInfo.FogB
  453. D3DInfo.lpD3DDevice->SetRenderState(D3DRENDERSTATE_FOGTABLEMODE, D3DFOG_LINEAR);
  454. D3DInfo.lpD3DDevice->SetRenderState(D3DRENDERSTATE_FOGTABLESTART,*(DWORD*)(&start));
  455. D3DInfo.lpD3DDevice->SetRenderState(D3DRENDERSTATE_FOGTABLEEND, *(DWORD*)(&endi));
  456. D3DInfo.lpD3DDevice->SetRenderState(D3DRENDERSTATE_FOGTABLEDENSITY, (DWORD)0.004f);
  457. }
  458. else
  459. {
  460. D3DInfo.lpD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE,false);
  461. }
  462. return JE_TRUE;
  463. }
  464. jeBoolean DRIVERCC DrawDDText(char *text, int x,int y, uint32 color)
  465. {
  466. HFONT fnt;
  467. fnt = CreateFont(14,0,0,0,0,0,0,0,0,0,0,0,0, "Courier New");
  468. //Draw_Text(text, x,y, RGB(r,g,b),D3DInfo.lpBackBuffer ,fnt);
  469. //Draw_Text(text, x,y, RGB(r,g,b),D3DInfo.lpZBuffer ,fnt);
  470. Draw_Text(text, x,y, (COLORREF)color,D3DInfo.lpBackBuffer ,fnt);
  471. DeleteObject(fnt);
  472. return JE_TRUE;
  473. }