PageRenderTime 59ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 1ms

/tags/jet3d_dev_msvc2003/source/Engine/JetEngine/Engine/Drivers/D3D9Drv/Direct3D9Driver.cpp

#
C++ | 1692 lines | 1261 code | 309 blank | 122 comment | 299 complexity | 775853f1ae59b266c97387ae4c047d8d MD5 | raw file
  1. #include <assert.h>
  2. #include "Direct3D9Driver.h"
  3. #include "pixelformat.h"
  4. #include "D3D9TextureMgr.h"
  5. #include "PolyCache.h"
  6. #include "D3D9Log.h"
  7. #include "jeLight.h"
  8. /*#ifdef _DEBUG
  9. #pragma comment(lib, "Jet3Dd.lib")
  10. #else
  11. #pragma comment(lib, "Jet3D.lib")
  12. #endif*/
  13. #pragma comment(lib, "d3d9.lib")
  14. #pragma comment(lib, "d3dx9.lib")
  15. #define MAX_LIGHTS 8
  16. //#define PERFORMANCE_DEBUG
  17. #define USE_TEXT_CACHE
  18. #define USE_DECAL_CACHE
  19. jeRDriver_PixelFormat PixelFormat[10];
  20. DRV_EngineSettings EngineSettings;
  21. HWND hWnd;
  22. IDirect3D9 *pD3D = NULL;
  23. IDirect3DDevice9 *pDevice = NULL;
  24. float localgamma;
  25. D3DPRESENT_PARAMETERS d3dpp;
  26. D3DCAPS9 g_Caps;
  27. bool CanDoAntiAlias = false;
  28. bool CanDoShaders = false;
  29. bool CanDoAnisotropic = false;
  30. D3DLIGHT9 g_Lights[MAX_LIGHTS];
  31. D3DDISPLAYMODE old_mode;
  32. ID3DXSprite *pSprite = NULL;
  33. ID3DXFont *pFont = NULL;
  34. PolyCache *g_pPolyCache = NULL;
  35. #define JE_FONT_NORMAL 0x00000001
  36. #define JE_FONT_BOLD 0x00000002
  37. RGB_LUT Lut1;
  38. typedef struct jeFont
  39. {
  40. ID3DXFont *pFont;
  41. } jeFont;
  42. static jeBoolean PrepPolyVerts(jeTLVertex *Pnts, int32 NumPoints, jeRDriver_Layer *Layers, int32 NumLayers,void *LMapCBContext);
  43. static void FillLMapSurface(jeTLVertex *Pnts,int32 NumPoints,jeTexture *THandle, jeRDriver_LMapCBInfo *Info, int32 LNum);
  44. //inline DWORD FtoDW( FLOAT f ) { return *((DWORD*)&f); }
  45. inline DWORD FtoDW(float f)
  46. {
  47. DWORD d;
  48. _asm
  49. {
  50. fld f
  51. lea eax, [d]
  52. fistp dword ptr[eax]
  53. }
  54. return d;
  55. }
  56. void jeXForm3d_ToD3DMatrix(jeXForm3d *XForm, D3DMATRIX *mat)
  57. {
  58. mat->_11 = XForm->AX;
  59. mat->_12 = XForm->AY;
  60. mat->_13 = XForm->AZ;
  61. mat->_14 = 0.0f;
  62. mat->_21 = XForm->BX;
  63. mat->_22 = XForm->BY;
  64. mat->_23 = XForm->BZ;
  65. mat->_24 = 0.0f;
  66. mat->_31 = XForm->CX;
  67. mat->_32 = XForm->CY;
  68. mat->_33 = XForm->CZ;
  69. mat->_34 = 0.0f;
  70. mat->_41 = XForm->Translation.X;
  71. mat->_42 = XForm->Translation.Y;
  72. mat->_43 = XForm->Translation.Z;
  73. mat->_44 = 1.0f;
  74. }
  75. void D3DMatrix_ToXForm3d(D3DMATRIX *mat, jeXForm3d *XForm)
  76. {
  77. XForm->AX = mat->_11;
  78. XForm->AY = mat->_12;
  79. XForm->AZ = mat->_13;
  80. XForm->BX = mat->_21;
  81. XForm->BY = mat->_22;
  82. XForm->BZ = mat->_23;
  83. XForm->CX = mat->_31;
  84. XForm->CY = mat->_32;
  85. XForm->CZ = mat->_33;
  86. XForm->Translation.X = mat->_41;
  87. XForm->Translation.Y = mat->_42;
  88. XForm->Translation.Z = mat->_43;
  89. }
  90. jeBoolean DRIVERCC D3D9Drv_EnumSubDrivers(DRV_ENUM_DRV_CB *Cb, void *Context)
  91. {
  92. if (LOG_LEVEL > 1)
  93. D3D9Log::GetPtr()->Printf("Function Call: EnumSubDrivers()");
  94. else
  95. REPORT("Function Call: EnumSubDrivers()");
  96. Cb(1, "Direct3D 9 Driver", Context);
  97. return TRUE;
  98. }
  99. jeBoolean DRIVERCC D3D9Drv_EnumModes(S32 Driver, char *DriverName, DRV_ENUM_MODES_CB *Cb, void *Context)
  100. {
  101. HRESULT hres;
  102. D3DFORMAT fmt[] = { D3DFMT_X8R8G8B8, D3DFMT_R5G6B5 };
  103. int32 y = 0, numModes = 0;
  104. if (LOG_LEVEL > 1)
  105. D3D9Log::GetPtr()->Printf("Function Call: EnumModes()");
  106. else
  107. REPORT("Function Call: EnumModes()");
  108. for (int32 x = 0; x < 2; x++)
  109. {
  110. int32 modecount = pD3D->GetAdapterModeCount(D3DADAPTER_DEFAULT, fmt[x]);
  111. for (y = 0; y < modecount; y++)
  112. {
  113. D3DDISPLAYMODE mode;
  114. hres = pD3D->EnumAdapterModes(D3DADAPTER_DEFAULT, fmt[x], y, &mode);
  115. if (FAILED(hres))
  116. {
  117. D3D9Log::GetPtr()->Printf("ERROR: Could not enumerate display modes!!");
  118. return FALSE;
  119. }
  120. if (mode.Width <= 2048 && mode.Height <= 1024 && mode.RefreshRate == 60)
  121. {
  122. char modename[32];
  123. int32 bpp;
  124. if (mode.Format == D3DFMT_X8R8G8B8)
  125. bpp = 32;
  126. else if (mode.Format == D3DFMT_R5G6B5)
  127. bpp = 16;
  128. else
  129. bpp = 0;
  130. sprintf(modename, "%dx%dx%d", mode.Width, mode.Height, bpp);
  131. Cb(y, modename, mode.Width, mode.Height, bpp, Context);
  132. numModes++;
  133. }
  134. }
  135. }
  136. Cb(numModes, "WindowMode", -1, -1, -1, Context);
  137. return TRUE;
  138. }
  139. jeBoolean DRIVERCC D3D9Drv_Init(DRV_DriverHook *hook)
  140. {
  141. HRESULT hres;
  142. //D3DPRESENT_PARAMETERS d3dpp;
  143. int32 bpp;
  144. int32 dummy;
  145. const char *modename = NULL;
  146. int w, h;
  147. if (LOG_LEVEL > 1)
  148. D3D9Log::GetPtr()->Printf("Function Call: Init()");
  149. else
  150. REPORT("Function Call: Init()");
  151. if (pDevice != NULL)
  152. {
  153. SAFE_RELEASE(pDevice);
  154. }
  155. pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &old_mode);
  156. ZeroMemory(&d3dpp, sizeof(D3DPRESENT_PARAMETERS));
  157. sscanf(hook->ModeName, "%dx%dx%d", &w, &h, &bpp);
  158. if (hook->Width == -1 && hook->Height == -1)
  159. {
  160. RECT r;
  161. GetClientRect(hook->hWnd, &r);
  162. d3dpp.BackBufferWidth = r.right - r.left;
  163. d3dpp.BackBufferHeight = r.bottom - r.top;
  164. d3dpp.BackBufferFormat = old_mode.Format;
  165. d3dpp.Windowed = TRUE;
  166. }
  167. else
  168. {
  169. d3dpp.BackBufferWidth = hook->Width;
  170. d3dpp.BackBufferHeight = hook->Height;
  171. d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
  172. if(bpp==32)
  173. d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
  174. else
  175. d3dpp.BackBufferFormat = D3DFMT_R5G6B5;
  176. d3dpp.FullScreen_RefreshRateInHz = 60;
  177. d3dpp.Windowed = FALSE;
  178. }
  179. sscanf(hook->ModeName,"%dx%dx%d",&dummy,&dummy,&bpp);
  180. d3dpp.BackBufferCount = 1;
  181. d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
  182. d3dpp.hDeviceWindow = hook->hWnd;
  183. d3dpp.EnableAutoDepthStencil = TRUE;
  184. d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
  185. d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
  186. hres = pD3D->CheckDeviceMultiSampleType(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3dpp.BackBufferFormat, d3dpp.Windowed, D3DMULTISAMPLE_2_SAMPLES, NULL);
  187. if (FAILED(hres))
  188. {
  189. D3D9Log::GetPtr()->Printf("Feature Request: Full Scene Anti-Aliasing OFF");
  190. CanDoAntiAlias = false;
  191. }
  192. else
  193. {
  194. D3D9Log::GetPtr()->Printf("Feature Request: Full Scene Anti-Aliasing ON");
  195. CanDoAntiAlias = true;
  196. }
  197. if (!CanDoAntiAlias)
  198. d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
  199. else
  200. d3dpp.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
  201. d3dpp.MultiSampleQuality = 0;
  202. d3dpp.Flags = 0;
  203. #ifndef PERFORMANCE_DEBUG
  204. hres = pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hook->hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &pDevice);
  205. if (FAILED(hres))
  206. {
  207. hres = pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hook->hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice);
  208. if (FAILED(hres))
  209. {
  210. hres = pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_SW, hook->hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice);
  211. if (FAILED(hres))
  212. {
  213. hres = pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, hook->hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice);
  214. if (FAILED(hres))
  215. {
  216. if (hres == D3DERR_DEVICELOST)
  217. D3D9Log::GetPtr()->Printf("ERROR: Device Lost!!");
  218. else if (hres == D3DERR_INVALIDCALL)
  219. D3D9Log::GetPtr()->Printf("ERROR: Invalid Call!!");
  220. else if (hres == D3DERR_NOTAVAILABLE)
  221. D3D9Log::GetPtr()->Printf("ERROR: Not Available!!");
  222. else if (hres == D3DERR_OUTOFVIDEOMEMORY)
  223. D3D9Log::GetPtr()->Printf("ERROR: Out of video memory!!");
  224. else
  225. D3D9Log::GetPtr()->Printf("ERROR: Unknown error!!");
  226. return FALSE;
  227. }
  228. else
  229. D3D9Log::GetPtr()->Printf("DEVICE: Created using REF/SW");
  230. }
  231. else
  232. D3D9Log::GetPtr()->Printf("DEVICE: Created using SW/SW");
  233. }
  234. else
  235. D3D9Log::GetPtr()->Printf("DEVICE: Created using HW/SW");
  236. }
  237. else
  238. D3D9Log::GetPtr()->Printf("DEVICE: Created using HW/HW");
  239. #else
  240. hres = pD3D->CreateDevice(pD3D->GetAdapterCount()-1, D3DDEVTYPE_REF, hook->hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &pDevice);
  241. if (FAILED(hres))
  242. {
  243. if (hres == D3DERR_DEVICELOST)
  244. D3D9Log::GetPtr()->Printf("ERROR: Device Lost!!");
  245. else if (hres == D3DERR_INVALIDCALL)
  246. D3D9Log::GetPtr()->Printf("ERROR: Invalid Call!!");
  247. else if (hres == D3DERR_NOTAVAILABLE)
  248. D3D9Log::GetPtr()->Printf("ERROR: Not Available!!");
  249. else if (hres == D3DERR_OUTOFVIDEOMEMORY)
  250. D3D9Log::GetPtr()->Printf("ERROR: Out of video memory!!");
  251. else
  252. D3D9Log::GetPtr()->Printf("ERROR: Unknown error!!");
  253. return FALSE;
  254. }
  255. #endif
  256. pDevice->GetDeviceCaps(&g_Caps);
  257. if (g_Caps.RasterCaps & D3DPRASTERCAPS_ANISOTROPY)
  258. {
  259. D3D9Log::GetPtr()->Printf("Feature Request: Anisotropic Filtering ON");
  260. CanDoAnisotropic = true;
  261. }
  262. else
  263. D3D9Log::GetPtr()->Printf("Feature Request: Anisotropic Filtering OFF");
  264. if ((g_Caps.VertexShaderVersion >= D3DVS_VERSION(1, 1)) && (g_Caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)))
  265. {
  266. D3D9Log::GetPtr()->Printf("Feature Request: Vertex and Pixel Shaders ON");
  267. CanDoShaders = true;
  268. }
  269. else
  270. D3D9Log::GetPtr()->Printf("Feature Request: Vertex and Pixel Shaders OFF");
  271. if (CanDoAntiAlias)
  272. pDevice->SetRenderState( D3DRS_MULTISAMPLEANTIALIAS, TRUE);
  273. pDevice->SetRenderState( D3DRS_SHADEMODE, D3DSHADE_GOURAUD );
  274. pDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE);
  275. pDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
  276. pDevice->SetRenderState( D3DRS_ZENABLE, D3DZB_TRUE );
  277. pDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE );
  278. g_pPolyCache = new PolyCache();
  279. if (!g_pPolyCache)
  280. {
  281. D3D9Log::GetPtr()->Printf("ERROR: Could not create poly cache!!");
  282. return FALSE;
  283. }
  284. if (!g_pPolyCache->Initialize(pDevice))
  285. {
  286. D3D9Log::GetPtr()->Printf("ERROR: Could not initialize poly cache!!");
  287. return FALSE;
  288. }
  289. D3DXMATRIX matProj;
  290. D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f, 1.0f, 4000.0f );
  291. pDevice->SetTransform( D3DTS_PROJECTION, &matProj );
  292. localgamma = 1.0f;
  293. BuildRGBGammaTables(1);
  294. if (FAILED(D3DXCreateSprite(pDevice, &pSprite)))
  295. {
  296. D3D9Log::GetPtr()->Printf("ERROR: Could not create sprite interface!!");
  297. return FALSE;
  298. }
  299. D3DXCreateFont(pDevice, 18, 0, FW_BOLD, 0, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, TEXT("Arial"), &pFont);
  300. if (LOG_LEVEL > 1)
  301. D3D9Log::GetPtr()->Printf("DEBUG: Initialization successful");
  302. else
  303. REPORT("DEBUG: Initialization complete...");
  304. return TRUE;
  305. }
  306. jeBoolean DRIVERCC D3D9Drv_Shutdown(void)
  307. {
  308. if (LOG_LEVEL > 1)
  309. D3D9Log::GetPtr()->Printf("Function Call: Shutdown()");
  310. else
  311. REPORT("Function Call: Shutdown()");
  312. SAFE_RELEASE(pFont);
  313. SAFE_DELETE(g_pPolyCache);
  314. D3D9_THandle_Shutdown();
  315. SAFE_RELEASE(pDevice);
  316. SAFE_RELEASE(pD3D);
  317. D3D9Log::GetPtr()->Printf("Shutdown complete...");
  318. D3D9Log::GetPtr()->Shutdown();
  319. D3D9Log::Singleton = NULL;
  320. // SAFE_DELETE(D3D9Log::GetPtr());
  321. return TRUE;
  322. }
  323. /*jeRDriver_PixelFormat PFormats[] =
  324. {
  325. { JE_PIXELFORMAT_32BIT_ARGB, RDRIVER_PF_3D | RDRIVER_PF_COMBINE_LIGHTMAP },
  326. { JE_PIXELFORMAT_24BIT_RGB, RDRIVER_PF_2D | RDRIVER_PF_CAN_DO_COLORKEY },
  327. { JE_PIXELFORMAT_24BIT_RGB, RDRIVER_PF_LIGHTMAP }
  328. };
  329. #define NUM_PIXEL_FORMATS (sizeof(PFormats) / sizeof(jeRDriver_PixelFormat))
  330. jeBoolean DRIVERCC D3D9Drv_EnumPixelFormats(DRV_ENUM_PFORMAT_CB *Cb, void *Context)
  331. {
  332. if (LOG_LEVEL > 1)
  333. D3D9Log::GetPtr()->Printf("Function Call: EnumPixelFormats()");
  334. else
  335. REPORT("Function Call: EnumPixelFormats()");
  336. for (int i = 0; i < NUM_PIXEL_FORMATS; i++)
  337. {
  338. if (!Cb(&PFormats[i], Context))
  339. {
  340. D3D9Log::GetPtr()->Printf("ERROR: Cannot enumerate pixel formats!!");
  341. return JE_FALSE;
  342. }
  343. }
  344. return JE_TRUE;
  345. }*/
  346. jeBoolean DRIVERCC D3D9Drv_EnumPixelFormats(DRV_ENUM_PFORMAT_CB *Cb, void *Context)
  347. {
  348. int32 i;
  349. jePixelFormat Format3d, Format2d;
  350. uint32 CurrentBpp;
  351. D3DDISPLAYMODE mode;
  352. pDevice->GetDisplayMode(0, &mode);
  353. if (mode.Format == D3DFMT_X8R8G8B8 || mode.Format == D3DFMT_A8R8G8B8 || mode.Format == D3DFMT_A2R10G10B10)
  354. CurrentBpp = 32;
  355. else if (mode.Format == D3DFMT_R5G6B5 || mode.Format == D3DFMT_A1R5G5B5 || mode.Format == D3DFMT_X1R5G5B5)
  356. CurrentBpp = 16;
  357. // Setup the 2d surface format
  358. if (CurrentBpp == 32 && mode.Format == D3DFMT_A8R8G8B8)
  359. Format2d = JE_PIXELFORMAT_32BIT_ARGB;
  360. else if (CurrentBpp == 32 && mode.Format == D3DFMT_X8R8G8B8)
  361. Format2d = JE_PIXELFORMAT_32BIT_XRGB;
  362. else if (CurrentBpp == 16 && mode.Format == D3DFMT_A1R5G5B5)
  363. Format2d = JE_PIXELFORMAT_16BIT_1555_ARGB;
  364. else if (CurrentBpp == 16 && mode.Format == D3DFMT_R5G6B5)
  365. Format2d = JE_PIXELFORMAT_16BIT_565_RGB;
  366. else
  367. Format2d = JE_PIXELFORMAT_16BIT_555_RGB;
  368. // Setup the 3d (Texture) format
  369. //if (mode.Format == D3DFMT_R5G6B5)
  370. // Format3d = JE_PIXELFORMAT_16BIT_555_RGB;
  371. //else
  372. Format3d = JE_PIXELFORMAT_16BIT_565_RGB;
  373. // Create the surface formats now
  374. PixelFormat[0].PixelFormat = Format3d; // 3d 565/555 surface
  375. PixelFormat[0].Flags = RDRIVER_PF_3D | RDRIVER_PF_COMBINE_LIGHTMAP;
  376. PixelFormat[1].PixelFormat = JE_PIXELFORMAT_16BIT_4444_ARGB; // 3d 4444 surface
  377. PixelFormat[1].Flags = RDRIVER_PF_3D | RDRIVER_PF_COMBINE_LIGHTMAP | RDRIVER_PF_ALPHA;
  378. PixelFormat[2].PixelFormat = Format2d; // 2d 565/555 surface
  379. PixelFormat[2].Flags = RDRIVER_PF_2D | RDRIVER_PF_CAN_DO_COLORKEY;
  380. PixelFormat[3].PixelFormat = Format3d; // Lightmap 565/555 surface
  381. PixelFormat[3].Flags = RDRIVER_PF_LIGHTMAP;
  382. PixelFormat[4].PixelFormat = JE_PIXELFORMAT_16BIT_1555_ARGB;
  383. PixelFormat[4].Flags = RDRIVER_PF_3D | RDRIVER_PF_COMBINE_LIGHTMAP | RDRIVER_PF_ALPHA;
  384. // Then hand them off to the caller
  385. for (i=0; i<5; i++)
  386. {
  387. if (!Cb(&PixelFormat[i], Context))
  388. return JE_TRUE;
  389. }
  390. return TRUE;
  391. }
  392. jeBoolean DRIVERCC D3D9Drv_GetDeviceCaps(jeDeviceCaps *DeviceCaps)
  393. {
  394. if (LOG_LEVEL > 1)
  395. D3D9Log::GetPtr()->Printf("Function Call: GetDeviceCaps()");
  396. else
  397. REPORT("Function Call: GetDeviceCaps()");
  398. DeviceCaps->SuggestedDefaultRenderFlags = JE_RENDER_FLAG_BILINEAR_FILTER;
  399. DeviceCaps->CanChangeRenderFlags = 0xFFFFFFFF;
  400. return JE_TRUE;
  401. }
  402. jeBoolean DRIVERCC D3D9Drv_SetGamma(float gamma)
  403. {
  404. if (LOG_LEVEL > 1)
  405. D3D9Log::GetPtr()->Printf("Function Call: SetGamma()");
  406. else
  407. REPORT("Function Call: SetGamma()");
  408. localgamma=gamma;
  409. BuildRGBGammaTables(gamma);
  410. return JE_TRUE;
  411. }
  412. jeBoolean DRIVERCC D3D9Drv_GetGamma(float *gamma)
  413. {
  414. if (LOG_LEVEL > 1)
  415. D3D9Log::GetPtr()->Printf("Function Call: GetGamma()");
  416. else
  417. REPORT("Function Call: GetGamma()");
  418. *gamma = localgamma;
  419. return JE_TRUE;
  420. }
  421. jeBoolean DRIVERCC D3D9Drv_Reset()
  422. {
  423. if (LOG_LEVEL > 1)
  424. D3D9Log::GetPtr()->Printf("Function Call: Reset()");
  425. else
  426. REPORT("Function Call: Reset()");
  427. D3D9_THandle_Shutdown();
  428. g_pPolyCache->Shutdown();
  429. D3D9_THandle_Startup();
  430. g_pPolyCache->Initialize(pDevice);
  431. return TRUE;
  432. }
  433. jeBoolean DRIVERCC D3D9Drv_UpdateWindow()
  434. {
  435. RECT r;
  436. if (LOG_LEVEL > 1)
  437. D3D9Log::GetPtr()->Printf("Function Call: UpdateWindow()");
  438. else
  439. REPORT("Function Call: UpdateWindow()");
  440. GetClientRect(hWnd, &r);
  441. if (d3dpp.Windowed == TRUE)
  442. {
  443. d3dpp.BackBufferWidth = r.right - r.left;
  444. d3dpp.BackBufferHeight = r.bottom - r.top;
  445. pDevice->Reset(&d3dpp);
  446. }
  447. return TRUE;
  448. }
  449. jeBoolean DRIVERCC D3D9Drv_SetActive(jeBoolean Active)
  450. {
  451. if (LOG_LEVEL > 1)
  452. D3D9Log::GetPtr()->Printf("Function Call: SetActive()");
  453. else
  454. REPORT("Function Call: SetActive()");
  455. Active;
  456. return TRUE;
  457. }
  458. jeBoolean DRIVERCC D3D9Drv_BeginScene(jeBoolean Clear, jeBoolean ClearZ, RECT *WorldRect, jeBoolean Wireframe)
  459. {
  460. HRESULT hres;
  461. if (LOG_LEVEL > 1)
  462. D3D9Log::GetPtr()->Printf("Function Call: BeginScene()");
  463. else
  464. REPORT("Function Call: BeginScene()");
  465. if (Clear)
  466. {
  467. g_D3D9Drv.NumRenderedPolys=0;
  468. pDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0f, 0L );
  469. }
  470. if(ClearZ)
  471. {
  472. pDevice->Clear( 0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1.0f, 0L );
  473. }
  474. if (Wireframe)
  475. pDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
  476. else
  477. pDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
  478. hres = pDevice->BeginScene();
  479. if (FAILED(hres))
  480. {
  481. D3D9Log::GetPtr()->Printf("ERROR: Could not begin scene!!");
  482. return JE_FALSE;
  483. }
  484. return JE_TRUE;
  485. }
  486. jeBoolean DRIVERCC D3D9Drv_EndScene()
  487. {
  488. HRESULT hres;
  489. if (LOG_LEVEL > 1)
  490. D3D9Log::GetPtr()->Printf("Function Call: EndScene()");
  491. else
  492. REPORT("Function Call: EndScene()");
  493. if (!g_pPolyCache->Flush())
  494. {
  495. D3D9Log::GetPtr()->Printf("ERROR: Failed to flush poly cache!!");
  496. return JE_FALSE;
  497. }
  498. hres = pDevice->EndScene();
  499. if (FAILED(hres))
  500. {
  501. D3D9Log::GetPtr()->Printf("ERROR: Could not end scene!!");
  502. return JE_FALSE;
  503. }
  504. hres = pDevice->Present(NULL, NULL, NULL, NULL);
  505. if (FAILED(hres))
  506. {
  507. D3D9Log::GetPtr()->Printf("ERROR: Could not present scene!!");
  508. return JE_FALSE;
  509. }
  510. for (int32 i = 0; i < MAX_LIGHTS; i++)
  511. {
  512. pDevice->LightEnable(i, FALSE);
  513. //pDevice->SetLight(i, NULL);
  514. ZeroMemory(&g_Lights[i], sizeof(D3DLIGHT9));
  515. }
  516. return JE_TRUE;
  517. }
  518. jeBoolean DRIVERCC D3D9Drv_BeginBatch()
  519. {
  520. if (LOG_LEVEL > 1)
  521. D3D9Log::GetPtr()->Printf("Function Call: BeginBatch()");
  522. else
  523. REPORT("Function Call: BeginBatch()");
  524. return JE_TRUE;
  525. }
  526. jeBoolean DRIVERCC D3D9Drv_EndBatch()
  527. {
  528. if (LOG_LEVEL > 1)
  529. D3D9Log::GetPtr()->Printf("Function Call: EndBatch()");
  530. else
  531. REPORT("Function Call: EndBatch()");
  532. return JE_TRUE;
  533. }
  534. jeBoolean DRIVERCC D3D9Drv_RenderGouraudPoly(jeTLVertex *Pnts, int32 NumPoints, uint32 Flags)
  535. {
  536. if (LOG_LEVEL > 1)
  537. D3D9Log::GetPtr()->Printf("Function Call: RenderGouraudPoly()");
  538. else
  539. REPORT("Function Call: RenderGouraudPoly()");
  540. if (!g_pPolyCache)
  541. {
  542. D3D9Log::GetPtr()->Printf("ERROR: Poly cache not initialized!!");
  543. return JE_FALSE;
  544. }
  545. return g_pPolyCache->AddGouraudPoly(Pnts, NumPoints, Flags);
  546. }
  547. jeBoolean DRIVERCC D3D9Drv_RenderWorldPoly(jeTLVertex *Pnts, int32 NumPoints, jeRDriver_Layer *Layers, int32 NumLayers, void *LMapCBContext, uint32 Flags)
  548. {
  549. if (LOG_LEVEL > 1)
  550. D3D9Log::GetPtr()->Printf("Function Call: RenderWorldPoly()");
  551. else
  552. REPORT("Function Call: RenderWorldPoly()");
  553. if (!g_pPolyCache)
  554. {
  555. D3D9Log::GetPtr()->Printf("ERROR: Poly cache not initialized!!");
  556. return JE_FALSE;
  557. }
  558. return g_pPolyCache->AddWorldPoly(Pnts, NumPoints, Layers, NumLayers, LMapCBContext, Flags);
  559. }
  560. /*
  561. typedef struct
  562. {
  563. float x, y, z, pad; // screen points
  564. float r, g, b, a; // color
  565. float u, v, pad1,pad2; // Uv's
  566. float sr, sg, sb, pad3; // specular color
  567. } jeTLVertex; // 64 bytes
  568. #define JE_RENDER_FLAG_ALPHA (1<<0) // Alpha in the vertices are valid
  569. #define JE_RENDER_FLAG_SPECULAR (1<<1) // Specular in the vertices are valid
  570. #define JE_RENDER_FLAG_COLORKEY (1<<2) // Texture format has color key on the poly being rendered
  571. #define JE_RENDER_FLAG_CLAMP_UV (1<<3) // Clamp U and V in BOTH directions
  572. #define JE_RENDER_FLAG_COUNTER_CLOCKWISE (1<<4) // Winding of poly will be counter-clockwise
  573. #define JE_RENDER_FLAG_NO_ZTEST (1<<5) // No ZTest should be performed
  574. #define JE_RENDER_FLAG_NO_ZWRITE (1<<6) // No ZWrites should be performed
  575. #define JE_RENDER_FLAG_STEST (1<<7) // Span test should be performed (if set, polys should be front to back)
  576. #define JE_RENDER_FLAG_SWRITE (1<<8) // Spans should be written to the sbuffer
  577. #define JE_RENDER_FLAG_FLUSHBATCH (1<<9) // Flushes the current batch of polys (if any), and the current poly
  578. #define JE_RENDER_FLAG_BILINEAR_FILTER (1<<10) // Enable bilinear filtering
  579. */
  580. jeBoolean DRIVERCC D3D9Drv_RenderMiscTexturePoly(jeTLVertex *Pnts, int32 NumPoints, jeRDriver_Layer *Layers, int32 NumLayers, uint32 Flags)
  581. {
  582. if (LOG_LEVEL > 1)
  583. D3D9Log::GetPtr()->Printf("Function Call: RenderMiscTexturePoly()");
  584. else
  585. REPORT("Function Call: RenderMiscTexturePoly()");
  586. if (!g_pPolyCache)
  587. {
  588. D3D9Log::GetPtr()->Printf("ERROR: Poly cache not initialized!!");
  589. return JE_FALSE;
  590. }
  591. return g_pPolyCache->AddMiscTexturePoly(Pnts, NumPoints, Layers, NumLayers, Flags);
  592. }
  593. jeBoolean DRIVERCC D3D9Drv_DrawDecal(jeTexture *Handle, RECT *SrcRect, int32 x, int32 y)
  594. {
  595. HRESULT hres;
  596. if (LOG_LEVEL > 1)
  597. D3D9Log::GetPtr()->Printf("Function Call: DrawDecal()");
  598. else
  599. REPORT("Function Call: DrawDecal()");
  600. #ifndef USE_DECAL_CACHE
  601. hres = pSprite->Begin(D3DXSPRITE_ALPHABLEND);
  602. if (FAILED(hres))
  603. {
  604. D3D9Log::GetPtr()->Printf("ERROR: Could not begin sprite frame!!");
  605. return JE_FALSE;
  606. }
  607. hres = pSprite->Draw(Handle->pTexture, NULL, NULL, &D3DXVECTOR3((float)x, (float)y, 1.0f), D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,1.0f));
  608. if (FAILED(hres))
  609. {
  610. D3D9Log::GetPtr()->Printf("ERROR: Could not draw sprite!!");
  611. return JE_FALSE;
  612. }
  613. hres = pSprite->End();
  614. if (FAILED(hres))
  615. {
  616. D3D9Log::GetPtr()->Printf("ERROR: Could not end sprite frame!!");
  617. return JE_FALSE;
  618. }
  619. return JE_TRUE;
  620. #else
  621. return g_pPolyCache->AddDecal(Handle, SrcRect, x, y);
  622. #endif
  623. }
  624. jeBoolean DRIVERCC D3D9Drv_Screenshot(const char *filename)
  625. {
  626. HRESULT hres;
  627. IDirect3DSurface9 *pSurface = NULL;
  628. D3DDISPLAYMODE dmode;
  629. if (LOG_LEVEL > 1)
  630. D3D9Log::GetPtr()->Printf("Function Call: Screenshot()");
  631. else
  632. REPORT("Function Call: Screenshot()");
  633. hres = pDevice->GetDisplayMode(0, &dmode);
  634. if (FAILED(hres))
  635. {
  636. D3D9Log::GetPtr()->Printf("ERROR: Could not get display mode!!");
  637. return JE_FALSE;
  638. }
  639. hres = pDevice->CreateOffscreenPlainSurface(dmode.Width, dmode.Height, dmode.Format, D3DPOOL_SYSTEMMEM, &pSurface, NULL);
  640. if (FAILED(hres))
  641. {
  642. D3D9Log::GetPtr()->Printf("ERROR: Could not create offscreen plain surface!!");
  643. return JE_FALSE;
  644. }
  645. hres = pDevice->GetFrontBufferData(0, pSurface);
  646. if (FAILED(hres))
  647. {
  648. D3D9Log::GetPtr()->Printf("ERROR: Could not get front buffer data!!");
  649. pSurface->Release();
  650. pSurface = NULL;
  651. return JE_FALSE;
  652. }
  653. hres = D3DXSaveSurfaceToFile(filename, D3DXIFF_BMP, pSurface, NULL, NULL);
  654. if (FAILED(hres))
  655. {
  656. D3D9Log::GetPtr()->Printf("ERROR: Could not save screenshot!!");
  657. pSurface->Release();
  658. pSurface = NULL;
  659. return JE_FALSE;
  660. }
  661. pSurface->Release();
  662. pSurface = NULL;
  663. return JE_TRUE;
  664. }
  665. uint32 DRIVERCC D3D9Drv_CreateStaticMesh(jeHWVertex *Points, int32 NumPoints, jeRDriver_Layer *Layers, int32 NumLayers, uint32 Flags)
  666. {
  667. uint32 id;
  668. if (LOG_LEVEL > 1)
  669. D3D9Log::GetPtr()->Printf("Function Call: CreateStaticMesh()");
  670. else
  671. REPORT("Function Call: CreateStaticMesh()");
  672. if (!g_pPolyCache)
  673. {
  674. D3D9Log::GetPtr()->Printf("ERROR: No poly cache!!");
  675. return 0;
  676. }
  677. id = g_pPolyCache->AddStaticBuffer(Points, NumPoints, Layers, NumLayers, Flags);
  678. return id;
  679. }
  680. jeBoolean DRIVERCC D3D9Drv_RemoveStaticMesh(uint32 id)
  681. {
  682. if (LOG_LEVEL > 1)
  683. D3D9Log::GetPtr()->Printf("Function Call: RemoveStaticMesh()");
  684. else
  685. REPORT("Function Call: RemoveStaticMesh()");
  686. if (!g_pPolyCache)
  687. {
  688. D3D9Log::GetPtr()->Printf("ERROR: No poly cache!!");
  689. return JE_FALSE;
  690. }
  691. return g_pPolyCache->RemoveStaticBuffer(id);
  692. }
  693. jeBoolean DRIVERCC D3D9Drv_RenderStaticMesh(uint32 id, int32 StartVertex, int32 NumPolys, jeXForm3d *XForm)
  694. {
  695. if (LOG_LEVEL > 1)
  696. D3D9Log::GetPtr()->Printf("Function Call: RenderStaticMesh()");
  697. else
  698. REPORT("Function Call: RenderStaticMesh()");
  699. if (!g_pPolyCache)
  700. {
  701. D3D9Log::GetPtr()->Printf("ERROR: No poly cache!!");
  702. return JE_FALSE;
  703. }
  704. return g_pPolyCache->RenderStaticBuffer(id, StartVertex, NumPolys, XForm);
  705. }
  706. jeBoolean DRIVERCC D3D9Drv_SetMatrix(uint32 Type, jeXForm3d *Matrix)
  707. {
  708. D3DTRANSFORMSTATETYPE t;
  709. D3DMATRIX out;
  710. if (LOG_LEVEL > 1)
  711. D3D9Log::GetPtr()->Printf("Function Call: SetMatrix()");
  712. else
  713. REPORT("Function Call: SetMatrix()");
  714. switch (Type)
  715. {
  716. case JE_XFORM_TYPE_WORLD:
  717. {
  718. t = D3DTS_WORLD;
  719. break;
  720. }
  721. case JE_XFORM_TYPE_VIEW:
  722. {
  723. t = D3DTS_VIEW;
  724. break;
  725. }
  726. case JE_XFORM_TYPE_PROJECTION:
  727. {
  728. t = D3DTS_PROJECTION;
  729. break;
  730. }
  731. default:
  732. return JE_FALSE;
  733. }
  734. jeXForm3d_ToD3DMatrix(Matrix, &out);
  735. pDevice->SetTransform(t, &out);
  736. return JE_TRUE;
  737. }
  738. jeBoolean DRIVERCC D3D9Drv_GetMatrix(uint32 Type, jeXForm3d *Matrix)
  739. {
  740. D3DTRANSFORMSTATETYPE t;
  741. D3DMATRIX out;
  742. if (LOG_LEVEL > 1)
  743. D3D9Log::GetPtr()->Printf("Function Call: GetMatrix()");
  744. else
  745. REPORT("Function Call: GetMatrix()");
  746. switch (Type)
  747. {
  748. case JE_XFORM_TYPE_WORLD:
  749. {
  750. t = D3DTS_WORLD;
  751. break;
  752. }
  753. case JE_XFORM_TYPE_VIEW:
  754. {
  755. t = D3DTS_VIEW;
  756. break;
  757. }
  758. case JE_XFORM_TYPE_PROJECTION:
  759. {
  760. t = D3DTS_PROJECTION;
  761. break;
  762. }
  763. default:
  764. return JE_FALSE;
  765. }
  766. pDevice->GetTransform(t, &out);
  767. D3DMatrix_ToXForm3d(&out, Matrix);
  768. return JE_TRUE;
  769. }
  770. jeBoolean DRIVERCC D3D9Drv_SetCamera(jeCamera *Camera)
  771. {
  772. if (LOG_LEVEL > 1)
  773. D3D9Log::GetPtr()->Printf("Function Call: SetCamera()");
  774. else
  775. REPORT("Function Call: SetCamera()");
  776. return JE_TRUE;
  777. }
  778. jeFont * DRIVERCC D3D9Drv_CreateFont(int32 Height, int32 Width, uint32 Weight, jeBoolean Italic, const char *facename)
  779. {
  780. jeFont *font = NULL;
  781. HRESULT hres;
  782. uint32 w;
  783. if (LOG_LEVEL > 1)
  784. D3D9Log::GetPtr()->Printf("Function Call: CreateFont()");
  785. else
  786. REPORT("Function Call: EnumSubDrivers()");
  787. if (Weight == JE_FONT_BOLD)
  788. w = FW_BOLD;
  789. else
  790. w = 0;
  791. font = new jeFont;
  792. if (!font)
  793. {
  794. D3D9Log::GetPtr()->Printf("ERROR: Out of memory!!");
  795. return NULL;
  796. }
  797. hres = D3DXCreateFont(pDevice, Height, Width, Weight, 0, Italic, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, TEXT(facename), &font->pFont);
  798. if (FAILED(hres))
  799. {
  800. D3D9Log::GetPtr()->Printf("ERROR: Could not create font!!");
  801. delete font;
  802. font = NULL;
  803. return NULL;
  804. }
  805. return font;
  806. }
  807. jeBoolean DRIVERCC D3D9Drv_DrawFont(jeFont *Font, int32 x, int32 y, uint32 Color, const char *text)
  808. {
  809. RECT r;
  810. if (LOG_LEVEL > 1)
  811. D3D9Log::GetPtr()->Printf("Function Call: DrawFont()");
  812. pDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
  813. pDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
  814. SetRect(&r, x, y, 0, 0);
  815. if (FAILED(Font->pFont->DrawText(NULL, text, (int)strlen(text), &r, DT_NOCLIP, Color)))
  816. {
  817. D3D9Log::GetPtr()->Printf("ERROR: Could not draw font!!");
  818. return JE_FALSE;
  819. }
  820. pDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
  821. pDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
  822. return JE_TRUE;
  823. }
  824. jeBoolean DRIVERCC D3D9Drv_DestroyFont(jeFont **Font)
  825. {
  826. if (LOG_LEVEL > 1)
  827. D3D9Log::GetPtr()->Printf("Function Call: DestroyFont()");
  828. else
  829. REPORT("Function Call: DestroyFont()");
  830. (*Font)->pFont->Release();
  831. (*Font)->pFont = NULL;
  832. delete (*Font);
  833. (*Font) = NULL;
  834. return JE_TRUE;
  835. }
  836. jeBoolean DRIVERCC D3D9Drv_SetRenderState(uint32 state, uint32 value)
  837. {
  838. HRESULT hres;
  839. DWORD val;
  840. if (LOG_LEVEL > 1)
  841. D3D9Log::GetPtr()->Printf("Function Call: SetRenderState()");
  842. else
  843. REPORT("Function Call: SetRenderState()");
  844. switch (state)
  845. {
  846. case JE_RENDERSTATE_ENABLE_ZBUFFER:
  847. {
  848. if ((jeBoolean)value == JE_TRUE)
  849. val = D3DZB_TRUE;
  850. else
  851. val = D3DZB_FALSE;
  852. hres = pDevice->SetRenderState(D3DRS_ZENABLE, val);
  853. break;
  854. }
  855. case JE_RENDERSTATE_ENABLE_ZWRITES:
  856. {
  857. if ((jeBoolean)value == JE_TRUE)
  858. val = TRUE;
  859. else
  860. val = FALSE;
  861. hres = pDevice->SetRenderState(D3DRS_ZWRITEENABLE, val);
  862. break;
  863. }
  864. case JE_RENDERSTATE_ENABLE_ALPHABLENDING:
  865. {
  866. if ((jeBoolean)value == JE_TRUE)
  867. val = TRUE;
  868. else
  869. val = FALSE;
  870. hres = pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, val);
  871. break;
  872. }
  873. case JE_RENDERSTATE_ENABLE_ALPHATESTING:
  874. {
  875. if ((jeBoolean)value == JE_TRUE)
  876. val = TRUE;
  877. else
  878. val = FALSE;
  879. hres = pDevice->SetRenderState(D3DRS_ALPHATESTENABLE, val);
  880. break;
  881. }
  882. case JE_RENDERSTATE_ALPHAREF:
  883. {
  884. hres = pDevice->SetRenderState(D3DRS_ALPHAREF, value);
  885. break;
  886. }
  887. case JE_RENDERSTATE_ALPHAFUNC:
  888. case JE_RENDERSTATE_DEPTHFUNC:
  889. case JE_RENDERSTATE_STENCILFUNC:
  890. {
  891. D3DCMPFUNC func;
  892. D3DRENDERSTATETYPE st;
  893. if (value == JE_CMP_NEVER)
  894. func = D3DCMP_NEVER;
  895. else if (value == JE_CMP_LESS)
  896. func = D3DCMP_LESS;
  897. else if (value == JE_CMP_EQUAL)
  898. func = D3DCMP_EQUAL;
  899. else if (value == JE_CMP_LEQUAL)
  900. func = D3DCMP_LESSEQUAL;
  901. else if (value == JE_CMP_GREATER)
  902. func = D3DCMP_GREATER;
  903. else if (value == JE_CMP_GEQUAL)
  904. func = D3DCMP_GREATEREQUAL;
  905. else if (value == JE_CMP_NEQUAL)
  906. func = D3DCMP_NOTEQUAL;
  907. else if (value == JE_CMP_ALWAYS)
  908. func = D3DCMP_ALWAYS;
  909. if (state == JE_RENDERSTATE_ALPHAFUNC)
  910. st = D3DRS_ALPHAFUNC;
  911. else if (state == JE_RENDERSTATE_DEPTHFUNC)
  912. st = D3DRS_ZFUNC;
  913. else if (state == JE_RENDERSTATE_STENCILFUNC)
  914. st = D3DRS_STENCILFUNC;
  915. hres = pDevice->SetRenderState(st, func);
  916. break;
  917. }
  918. case JE_RENDERSTATE_FILLMODE:
  919. {
  920. D3DFILLMODE fm;
  921. if (value == JE_FILL_POINT)
  922. fm = D3DFILL_POINT;
  923. else if (value == JE_FILL_WIREFRAME)
  924. fm = D3DFILL_WIREFRAME;
  925. else if (value == JE_FILL_SOLID)
  926. fm = D3DFILL_SOLID;
  927. hres = pDevice->SetRenderState(D3DRS_FILLMODE, fm);
  928. break;
  929. }
  930. case JE_RENDERSTATE_SHADEMODE:
  931. {
  932. D3DSHADEMODE sm;
  933. if (value == JE_SHADE_FLAT)
  934. sm = D3DSHADE_FLAT;
  935. else if (value == JE_SHADE_GOURAUD)
  936. sm = D3DSHADE_GOURAUD;
  937. else if (value == JE_SHADE_PHONG)
  938. sm = D3DSHADE_PHONG;
  939. hres = pDevice->SetRenderState(D3DRS_SHADEMODE, sm);
  940. break;
  941. }
  942. case JE_RENDERSTATE_CULLMODE:
  943. {
  944. D3DCULL cm;
  945. if (value == JE_CULL_NONE)
  946. cm = D3DCULL_NONE;
  947. else if (value == JE_CULL_CW)
  948. cm = D3DCULL_CW;
  949. else if (value == JE_CULL_CCW)
  950. cm = D3DCULL_CCW;
  951. hres = pDevice->SetRenderState(D3DRS_CULLMODE, cm);
  952. break;
  953. }
  954. case JE_RENDERSTATE_ENABLE_FOG:
  955. {
  956. if ((jeBoolean)value == JE_TRUE)
  957. val = TRUE;
  958. else
  959. val = FALSE;
  960. hres = pDevice->SetRenderState(D3DRS_FOGENABLE, val);
  961. break;
  962. }
  963. case JE_RENDERSTATE_FOGCOLOR:
  964. {
  965. hres = pDevice->SetRenderState(D3DRS_FOGCOLOR, value);
  966. break;
  967. }
  968. case JE_RENDERSTATE_FOGSTART:
  969. {
  970. hres = pDevice->SetRenderState(D3DRS_FOGSTART, value);
  971. break;
  972. }
  973. case JE_RENDERSTATE_FOGEND:
  974. {
  975. hres = pDevice->SetRenderState(D3DRS_FOGEND, value);
  976. break;
  977. }
  978. case JE_RENDERSTATE_HWLIGHTINGENABLE:
  979. {
  980. if ((jeBoolean)value == JE_TRUE)
  981. val = TRUE;
  982. else
  983. val = FALSE;
  984. hres = pDevice->SetRenderState(D3DRS_LIGHTING, val);
  985. break;
  986. }
  987. case JE_RENDERSTATE_AMBIENTLIGHT:
  988. {
  989. hres = pDevice->SetRenderState(D3DRS_AMBIENT, value);
  990. break;
  991. }
  992. case JE_RENDERSTATE_ENABLE_STENCIL:
  993. {
  994. if ((jeBoolean)value == JE_TRUE)
  995. val = TRUE;
  996. else
  997. val = FALSE;
  998. hres = pDevice->SetRenderState(D3DRS_STENCILENABLE, val);
  999. break;
  1000. }
  1001. case JE_RENDERSTATE_STENCILREF:
  1002. {
  1003. hres = pDevice->SetRenderState(D3DRS_STENCILREF, value);
  1004. break;
  1005. }
  1006. case JE_RENDERSTATE_STENCILMASK:
  1007. {
  1008. hres = pDevice->SetRenderState(D3DRS_STENCILMASK, value);
  1009. break;
  1010. }
  1011. case JE_RENDERSTATE_STENCILWRITEMASK:
  1012. {
  1013. hres = pDevice->SetRenderState(D3DRS_STENCILWRITEMASK, value);
  1014. break;
  1015. }
  1016. case JE_RENDERSTATE_STENCILFAIL:
  1017. case JE_RENDERSTATE_STENCILZFAIL:
  1018. {
  1019. D3DSTENCILOP so;
  1020. D3DRENDERSTATETYPE rs;
  1021. if (state == JE_RENDERSTATE_STENCILFAIL)
  1022. rs = D3DRS_STENCILFAIL;
  1023. else if (state == JE_RENDERSTATE_STENCILZFAIL)
  1024. rs = D3DRS_STENCILZFAIL;
  1025. else if (state == JE_RENDERSTATE_STENCILPASS)
  1026. rs = D3DRS_STENCILPASS;
  1027. if (value == JE_STENCILOP_KEEP)
  1028. so = D3DSTENCILOP_KEEP;
  1029. else if (value == JE_STENCILOP_ZERO)
  1030. so = D3DSTENCILOP_ZERO;
  1031. else if (value == JE_STENCILOP_REPLACE)
  1032. so = D3DSTENCILOP_REPLACE;
  1033. else if (value == JE_STENCILOP_INCRWRAP)
  1034. so = D3DSTENCILOP_INCRSAT;
  1035. else if (value == JE_STENCILOP_DECRWRAP)
  1036. so = D3DSTENCILOP_DECRSAT;
  1037. else if (value == JE_STENCILOP_INVERT)
  1038. so = D3DSTENCILOP_INVERT;
  1039. else if (value == JE_STENCILOP_INCR)
  1040. so = D3DSTENCILOP_INCR;
  1041. else if (value == JE_STENCILOP_DECR)
  1042. so = D3DSTENCILOP_DECR;
  1043. hres = pDevice->SetRenderState(rs, so);
  1044. break;
  1045. }
  1046. }
  1047. if (FAILED(hres))
  1048. {
  1049. D3D9Log::GetPtr()->Printf("ERROR: Could not set render state!!");
  1050. return JE_FALSE;
  1051. }
  1052. return JE_TRUE;
  1053. }
  1054. jeBoolean DRIVERCC D3D9Drv_DrawText(char *text, int x, int y, uint32 color)
  1055. {
  1056. RECT r;
  1057. if (LOG_LEVEL > 1)
  1058. D3D9Log::GetPtr()->Printf("Function Call: DrawText()");
  1059. else
  1060. REPORT("Function Call: DrawText()");
  1061. #ifndef USE_TEXT_CACHE
  1062. SetRect(&r, x, y, 0, 0);
  1063. if (FAILED(pFont->DrawText(NULL, text, (int)strlen(text), &r, DT_NOCLIP, color)))
  1064. return JE_FALSE;
  1065. return JE_TRUE;
  1066. #else
  1067. return g_pPolyCache->AddText(text, x, y, color);
  1068. #endif
  1069. }
  1070. DRV_Driver g_D3D9Drv = {
  1071. "Direct3D 9 Driver. Copyright 2004-2006, Paradox Software",
  1072. DRV_VERSION_MAJOR,
  1073. DRV_VERSION_MINOR,
  1074. // Error handling hooks set by driver
  1075. DRV_ERROR_NONE,
  1076. NULL,
  1077. // Enum Modes/Drivers
  1078. D3D9Drv_EnumSubDrivers,
  1079. D3D9Drv_EnumModes,
  1080. D3D9Drv_EnumPixelFormats,
  1081. // Device Caps
  1082. D3D9Drv_GetDeviceCaps,
  1083. // Init/DeInit functions
  1084. D3D9Drv_Init,
  1085. D3D9Drv_Shutdown,
  1086. D3D9Drv_Reset,
  1087. NULL,
  1088. D3D9Drv_SetActive,
  1089. // Create/Destroy texture functions
  1090. D3D9_THandle_Create,
  1091. D3D9_THandle_CreateFromFile,
  1092. D3D9_THandle_Destroy,
  1093. // Texture manipulation functions
  1094. D3D9_THandle_Lock,
  1095. D3D9_THandle_Unlock,
  1096. // Palette access functions
  1097. NULL,
  1098. NULL,
  1099. // Palette access functions
  1100. NULL,
  1101. NULL,
  1102. D3D9_THandle_GetInfo,
  1103. // Scene management functions
  1104. D3D9Drv_BeginScene,
  1105. D3D9Drv_EndScene,
  1106. D3D9Drv_BeginBatch,
  1107. D3D9Drv_EndBatch,
  1108. // Render functions
  1109. D3D9Drv_RenderGouraudPoly,
  1110. D3D9Drv_RenderWorldPoly,
  1111. D3D9Drv_RenderMiscTexturePoly,
  1112. //Decal functions
  1113. D3D9Drv_DrawDecal,
  1114. 0,
  1115. 0,
  1116. 0,
  1117. NULL,
  1118. D3D9Drv_Screenshot,
  1119. D3D9Drv_SetGamma,
  1120. D3D9Drv_GetGamma,
  1121. // BEGIN - Hardware T&L - paradoxnj 4/5/2005
  1122. D3D9Drv_SetMatrix,
  1123. D3D9Drv_GetMatrix,
  1124. NULL,
  1125. // END - Hardware T&L - paradoxnj 4/5/2005
  1126. NULL,
  1127. NULL,
  1128. D3D9Drv_DrawText,
  1129. NULL,
  1130. D3D9Drv_CreateStaticMesh,
  1131. D3D9Drv_RemoveStaticMesh,
  1132. D3D9Drv_RenderStaticMesh,
  1133. D3D9Drv_CreateFont,
  1134. D3D9Drv_DrawFont,
  1135. D3D9Drv_DestroyFont,
  1136. D3D9Drv_SetRenderState,
  1137. // Vertex Buffer
  1138. // NULL,
  1139. // NULL,
  1140. // NULL,
  1141. // NULL
  1142. };
  1143. extern "C" BOOL DriverHook(DRV_Driver **Driver)
  1144. {
  1145. if (LOG_LEVEL > 1)
  1146. D3D9Log::GetPtr()->Printf("Function Call: DriverHook()");
  1147. pD3D = Direct3DCreate9(D3D_SDK_VERSION);
  1148. if (!pD3D)
  1149. {
  1150. D3D9Log::GetPtr()->Printf("ERROR: Could not create Direct3D object!!");
  1151. return FALSE;
  1152. }
  1153. D3D9_THandle_Startup();
  1154. EngineSettings.CanSupportFlags = (DRV_SUPPORT_ALPHA | DRV_SUPPORT_COLORKEY);
  1155. EngineSettings.PreferenceFlags = 0;
  1156. g_D3D9Drv.EngineSettings = &EngineSettings;
  1157. *Driver = &g_D3D9Drv;
  1158. return TRUE;
  1159. }
  1160. //====================================================================================
  1161. // PrepPolyVerts
  1162. //====================================================================================
  1163. static jeBoolean PrepPolyVerts(jeTLVertex *Pnts, int32 NumPoints, jeRDriver_Layer *Layers, int32 NumLayers,void *LMapCBContext)
  1164. {
  1165. float InvScale, u, v;
  1166. float ShiftU, ShiftV, ScaleU, ScaleV;
  1167. jeTLVertex *TempVerts,*pTVerts, *pVerts;
  1168. //float du, dv, dx, dy, MipScale;
  1169. int32 j;
  1170. // D3DSURFACE_DESC desc;
  1171. float InvScale2, ShiftU2, ShiftV2;
  1172. jeRDriver_Layer *LMapLayer;
  1173. jeRDriver_Layer *TexLayer;
  1174. TempVerts = (jeTLVertex*)malloc(sizeof(jeTLVertex)*NumPoints);
  1175. memcpy(TempVerts,Pnts,sizeof(jeTLVertex)*NumPoints);
  1176. pTVerts = &TempVerts[0];
  1177. // Set up shifts and scaled for texture uv's
  1178. TexLayer = &Layers[0];
  1179. LMapLayer = &Layers[1];
  1180. // Normalize UV's using Texture Size
  1181. InvScale = 1.0f / (float)((1<<TexLayer->THandle->Log));
  1182. ShiftU = TexLayer->ShiftU;
  1183. ShiftV = TexLayer->ShiftV;
  1184. ScaleU = (1.0f/(TexLayer->ScaleU));
  1185. ScaleV = (1.0f/(TexLayer->ScaleV));
  1186. if(NumLayers>1)
  1187. {
  1188. // Set up shifts and scaled for lightmap uv's
  1189. ShiftU2 = (float)-LMapLayer->ShiftU + 8.0f;
  1190. ShiftV2 = (float)-LMapLayer->ShiftV + 8.0f;
  1191. InvScale2 = 1.0f/(float)((1<<LMapLayer->THandle->Log)<<4);
  1192. }
  1193. pVerts = &Pnts[0];
  1194. for (j=0; j<NumPoints; j++)
  1195. {
  1196. u = pTVerts->u*ScaleU+ShiftU;
  1197. v = pTVerts->v*ScaleV+ShiftV;
  1198. pVerts->u = u * InvScale;
  1199. pVerts->v = v * InvScale;
  1200. if(NumLayers>1)
  1201. {
  1202. u = pTVerts->u + ShiftU2;
  1203. v = pTVerts->v + ShiftV2;
  1204. pVerts->pad1 =u * InvScale2;
  1205. pVerts->pad2 =v * InvScale2;
  1206. }
  1207. // pVerts->color = pTVerts->Color;
  1208. pTVerts++;
  1209. pVerts++;
  1210. }
  1211. free(TempVerts);
  1212. return TRUE;
  1213. }
  1214. //=====================================================================================
  1215. // Log2
  1216. // Return the log of a size
  1217. //=====================================================================================
  1218. uint32 Log2(uint32 P2)
  1219. {
  1220. uint32 p = 0;
  1221. int32 i = 0;
  1222. for (i = P2; i > 0; i>>=1)
  1223. p++;
  1224. return (p-1);
  1225. }
  1226. //=====================================================================================
  1227. // SnapToPower2
  1228. // Snaps a number to a power of 2
  1229. //=====================================================================================
  1230. int32 SnapToPower2(int32 Width)
  1231. {
  1232. if (Width <= 1) return 1;
  1233. else if (Width <= 2) return 2;
  1234. else if (Width <= 4) return 4;
  1235. else if (Width <= 8) return 8;
  1236. else if (Width <= 16) return 16;
  1237. else if (Width <= 32) return 32;
  1238. else if (Width <= 64) return 64;
  1239. else if (Width <= 128) return 128;
  1240. else if (Width <= 256) return 256;
  1241. else if (Width <= 512) return 512;
  1242. else if (Width <= 1024) return 1024;
  1243. else if (Width <= 2048) return 2048;
  1244. else
  1245. return -1;
  1246. }
  1247. //=====================================================================================
  1248. // Return the max log of a (power of 2) width and height
  1249. //=====================================================================================
  1250. int32 GetLog(int32 Width, int32 Height)
  1251. {
  1252. int32 LWidth = SnapToPower2(max(Width, Height));
  1253. return Log2(LWidth);
  1254. }
  1255. //=====================================================================================
  1256. // FillLMapSurface
  1257. //=====================================================================================
  1258. static void FillLMapSurface(jeTLVertex *Pnts,int32 NumPoints,jeTexture *THandle, jeRDriver_LMapCBInfo *Info, int32 LNum)
  1259. {
  1260. U16 *pTempBits,*pTempBits2;
  1261. int32 w, h, Width, Height, Size;
  1262. U8 *pBitPtr;
  1263. RGB_LUT *Lut;
  1264. int32 Extra;
  1265. //U8 PrevR,PrevG,PrevB;
  1266. pBitPtr = (U8*)Info->RGBLight[LNum];
  1267. Width = THandle->Width;
  1268. Height = THandle->Height;
  1269. Size = THandle->Log;
  1270. Lut = &Lut1;
  1271. D3D9_THandle_Lock(THandle, 0, (void**)&pTempBits);
  1272. pTempBits2=pTempBits;
  1273. Extra = (THandle->stride-THandle->Width);
  1274. for (h=0; h< Height; h++)
  1275. {
  1276. for (w=0; w< Width; w++)
  1277. {
  1278. U8 R, G, B;
  1279. U16 Color;
  1280. R = *pBitPtr++;
  1281. G = *pBitPtr++;
  1282. B = *pBitPtr++;
  1283. Color = (U16)((Lut->R[R] | Lut->G[G] | Lut->B[B])&0xFFFF);
  1284. *((U16*)pTempBits) = Color;
  1285. ((U16*)pTempBits)++;
  1286. }
  1287. pTempBits += Extra;
  1288. }
  1289. D3D9_THandle_Unlock(THandle, 0);
  1290. }
  1291. void BuildRGBGammaTables(float Gamma)
  1292. {
  1293. int32 i, Val;
  1294. int32 GammaTable[256];
  1295. DWORD R_Left, G_Left, B_Left; //, A_Left;
  1296. DWORD R_Right, G_Right, B_Right; //, A_Right;
  1297. if (Gamma == 1.0)
  1298. {
  1299. {
  1300. for (i=0 ; i<256 ; i++)
  1301. GammaTable[i] = i;
  1302. }
  1303. }
  1304. else for (i=0 ; i<256 ; i++)
  1305. {
  1306. float Ratio = (i+0.5f)/255.5f;
  1307. float RGB = (float)(255.0 * pow((double)Ratio, 1.0/(double)Gamma) + 0.5);
  1308. if (RGB < 0.0f)
  1309. RGB = 0.0f;
  1310. if (RGB > 255.0f)
  1311. RGB = 255.0f;
  1312. GammaTable[i] = (int32)RGB;
  1313. }
  1314. for (i=0; i< 256; i++)
  1315. {
  1316. Val = GammaTable[i];
  1317. R_Left = 11;
  1318. G_Left = 5;
  1319. B_Left = 0;
  1320. //A_Left = PixelMask.A_Shift;
  1321. R_Right = 3;
  1322. G_Right = 2;
  1323. B_Right = 3;
  1324. //A_Right = 8 - PixelMask.A_Width;
  1325. Val = GammaTable[i];
  1326. Lut1.R[i] = (((uint32)Val >> R_Right) << R_Left) & 0xF800;
  1327. Lut1.G[i] = (((uint32)Val >> G_Right) << G_Left) & 0x7E0;
  1328. Lut1.B[i] = (((uint32)Val >> B_Right) << B_Left) & 0x1F;
  1329. //D3DInfo.Lut1.A[i] = (((uint32) i >> A_Right) << A_Left) & 0x00;
  1330. //Lut1.R[i] = (i<<11) & 0xF800;
  1331. //Lut1.G[i] = (i<<5) & 0x7E0;
  1332. //Lut1.B[i] = (i) & 0x1F;
  1333. }
  1334. }
  1335. void * JETCC jeEngine_D3D9Driver(void)
  1336. {
  1337. return (void*)DriverHook;
  1338. }
  1339. jeBoolean DRIVERCC D3D9Drv_SetLight(int32 Index, jeLight *Light, jeBoolean Enable)
  1340. {
  1341. HRESULT hres;
  1342. jeVec3d Pos, Color;
  1343. float Radius, Brightness;
  1344. uint32 Flags;
  1345. assert(Index < 8 && Index >= 0);
  1346. ZeroMemory(&g_Lights[Index], sizeof(D3DLIGHT9));
  1347. jeLight_GetAttributes(Light, &Pos, &Color, &Radius, &Brightness, &Flags);
  1348. if (Flags & JE_LIGHT_FLAG_SUN)
  1349. g_Lights[Index].Type = D3DLIGHT_DIRECTIONAL;
  1350. else if (Flags & JE_LIGHT_FLAG_SPOTLIGHT)
  1351. g_Lights[Index].Type = D3DLIGHT_SPOT;
  1352. else
  1353. g_Lights[Index].Type = D3DLIGHT_POINT;
  1354. g_Lights[Index].Diffuse.r = Color.X / 255.0f;
  1355. g_Lights[Index].Diffuse.g = Color.Y / 255.0f;
  1356. g_Lights[Index].Diffuse.b = Color.Z / 255.0f;
  1357. g_Lights[Index].Diffuse.a = 0.0f;
  1358. //g_Lights[Index].Diffuse = g_Lights[Index].Ambient;
  1359. /*switch (g_Lights[Index].Type)
  1360. {
  1361. case D3DLIGHT_POINT:
  1362. {*/
  1363. g_Lights[Index].Range = Radius;
  1364. //g_Lights[Index].Attenuation0 = Brightness;
  1365. //break;
  1366. /*}
  1367. }*/
  1368. g_Lights[Index].Position.x = Pos.X;
  1369. g_Lights[Index].Position.y = Pos.Y;
  1370. g_Lights[Index].Position.z = Pos.Z;
  1371. hres = pDevice->SetLight(Index, &g_Lights[Index]);
  1372. if (FAILED(hres))
  1373. return JE_FALSE;
  1374. hres = pDevice->LightEnable(Index, Enable);
  1375. if (FAILED(hres))
  1376. return JE_FALSE;
  1377. return JE_TRUE;
  1378. }