GSState.cpp
上传用户:xjjlds
上传日期:2015-12-05
资源大小:22823k
文件大小:41k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. /* 
  2.  * Copyright (C) 2003-2005 Gabest
  3.  * http://www.gabest.org
  4.  *
  5.  *  This Program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2, or (at your option)
  8.  *  any later version.
  9.  *   
  10.  *  This Program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13.  *  GNU General Public License for more details.
  14.  *   
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with GNU Make; see the file COPYING.  If not, write to
  17.  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
  18.  *  http://www.gnu.org/copyleft/gpl.html
  19.  *
  20.  */
  21. #include "StdAfx.h"
  22. #include "GSState.h"
  23. #include "GSdx9.h"
  24. #include "GSUtil.h"
  25. #include "resource.h"
  26. //
  27. // GSState
  28. //
  29. GSState::GSState(int w, int h, HWND hWnd, HRESULT& hr) 
  30. : m_hWnd(hWnd)
  31. , m_width(w)
  32. , m_height(h)
  33. , m_sfp(NULL)
  34. , m_fp(NULL)
  35. , m_iOSD(1)
  36. , m_nVSync(0)
  37. {
  38. hr = E_FAIL;
  39. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  40.     CWinApp* pApp = AfxGetApp();
  41. m_v.RGBAQ.Q = m_q = 1.0f;
  42. memset(m_path, 0, sizeof(m_path));
  43. m_de.PRMODECONT.AC = 1;
  44. m_pPRIM = &m_de.PRIM;
  45. m_PRIM = 8;
  46. m_pCSRr = &m_rs.CSRr;
  47. m_fpGSirq = NULL;
  48. m_ctxt = &m_de.CTXT[0];
  49. m_pTrBuff = (BYTE*)_aligned_malloc(1024*1024*4, 16);
  50. m_nTrBytes = 0;
  51. for(int i = 0; i < countof(m_fpGIFPackedRegHandlers); i++)
  52. m_fpGIFPackedRegHandlers[i] = &GSState::GIFPackedRegHandlerNull;
  53. m_fpGIFPackedRegHandlers[GIF_REG_PRIM] = &GSState::GIFPackedRegHandlerPRIM;
  54. m_fpGIFPackedRegHandlers[GIF_REG_RGBA] = &GSState::GIFPackedRegHandlerRGBA;
  55. m_fpGIFPackedRegHandlers[GIF_REG_STQ] = &GSState::GIFPackedRegHandlerSTQ;
  56. m_fpGIFPackedRegHandlers[GIF_REG_UV] = &GSState::GIFPackedRegHandlerUV;
  57. m_fpGIFPackedRegHandlers[GIF_REG_XYZF2] = &GSState::GIFPackedRegHandlerXYZF2;
  58. m_fpGIFPackedRegHandlers[GIF_REG_XYZ2] = &GSState::GIFPackedRegHandlerXYZ2;
  59. m_fpGIFPackedRegHandlers[GIF_REG_TEX0_1] = &GSState::GIFPackedRegHandlerTEX0_1;
  60. m_fpGIFPackedRegHandlers[GIF_REG_TEX0_2] = &GSState::GIFPackedRegHandlerTEX0_2;
  61. m_fpGIFPackedRegHandlers[GIF_REG_CLAMP_1] = &GSState::GIFPackedRegHandlerCLAMP_1;
  62. m_fpGIFPackedRegHandlers[GIF_REG_CLAMP_2] = &GSState::GIFPackedRegHandlerCLAMP_2;
  63. m_fpGIFPackedRegHandlers[GIF_REG_FOG] = &GSState::GIFPackedRegHandlerFOG;
  64. m_fpGIFPackedRegHandlers[GIF_REG_XYZF3] = &GSState::GIFPackedRegHandlerXYZF3;
  65. m_fpGIFPackedRegHandlers[GIF_REG_XYZ3] = &GSState::GIFPackedRegHandlerXYZ3;
  66. m_fpGIFPackedRegHandlers[GIF_REG_A_D] = &GSState::GIFPackedRegHandlerA_D;
  67. m_fpGIFPackedRegHandlers[GIF_REG_NOP] = &GSState::GIFPackedRegHandlerNOP;
  68. for(int i = 0; i < countof(m_fpGIFRegHandlers); i++)
  69. m_fpGIFRegHandlers[i] = &GSState::GIFRegHandlerNull;
  70. m_fpGIFRegHandlers[GIF_A_D_REG_PRIM] = &GSState::GIFRegHandlerPRIM;
  71. m_fpGIFRegHandlers[GIF_A_D_REG_RGBAQ] = &GSState::GIFRegHandlerRGBAQ;
  72. m_fpGIFRegHandlers[GIF_A_D_REG_ST] = &GSState::GIFRegHandlerST;
  73. m_fpGIFRegHandlers[GIF_A_D_REG_UV] = &GSState::GIFRegHandlerUV;
  74. m_fpGIFRegHandlers[GIF_A_D_REG_XYZF2] = &GSState::GIFRegHandlerXYZF2;
  75. m_fpGIFRegHandlers[GIF_A_D_REG_XYZ2] = &GSState::GIFRegHandlerXYZ2;
  76. m_fpGIFRegHandlers[GIF_A_D_REG_TEX0_1] = &GSState::GIFRegHandlerTEX0_1;
  77. m_fpGIFRegHandlers[GIF_A_D_REG_TEX0_2] = &GSState::GIFRegHandlerTEX0_2;
  78. m_fpGIFRegHandlers[GIF_A_D_REG_CLAMP_1] = &GSState::GIFRegHandlerCLAMP_1;
  79. m_fpGIFRegHandlers[GIF_A_D_REG_CLAMP_2] = &GSState::GIFRegHandlerCLAMP_2;
  80. m_fpGIFRegHandlers[GIF_A_D_REG_FOG] = &GSState::GIFRegHandlerFOG;
  81. m_fpGIFRegHandlers[GIF_A_D_REG_XYZF3] = &GSState::GIFRegHandlerXYZF3;
  82. m_fpGIFRegHandlers[GIF_A_D_REG_XYZ3] = &GSState::GIFRegHandlerXYZ3;
  83. m_fpGIFRegHandlers[GIF_A_D_REG_NOP] = &GSState::GIFRegHandlerNOP;
  84. m_fpGIFRegHandlers[GIF_A_D_REG_TEX1_1] = &GSState::GIFRegHandlerTEX1_1;
  85. m_fpGIFRegHandlers[GIF_A_D_REG_TEX1_2] = &GSState::GIFRegHandlerTEX1_2;
  86. m_fpGIFRegHandlers[GIF_A_D_REG_TEX2_1] = &GSState::GIFRegHandlerTEX2_1;
  87. m_fpGIFRegHandlers[GIF_A_D_REG_TEX2_2] = &GSState::GIFRegHandlerTEX2_2;
  88. m_fpGIFRegHandlers[GIF_A_D_REG_XYOFFSET_1] = &GSState::GIFRegHandlerXYOFFSET_1;
  89. m_fpGIFRegHandlers[GIF_A_D_REG_XYOFFSET_2] = &GSState::GIFRegHandlerXYOFFSET_2;
  90. m_fpGIFRegHandlers[GIF_A_D_REG_PRMODECONT] = &GSState::GIFRegHandlerPRMODECONT;
  91. m_fpGIFRegHandlers[GIF_A_D_REG_PRMODE] = &GSState::GIFRegHandlerPRMODE;
  92. m_fpGIFRegHandlers[GIF_A_D_REG_TEXCLUT] = &GSState::GIFRegHandlerTEXCLUT;
  93. m_fpGIFRegHandlers[GIF_A_D_REG_SCANMSK] = &GSState::GIFRegHandlerSCANMSK;
  94. m_fpGIFRegHandlers[GIF_A_D_REG_MIPTBP1_1] = &GSState::GIFRegHandlerMIPTBP1_1;
  95. m_fpGIFRegHandlers[GIF_A_D_REG_MIPTBP1_2] = &GSState::GIFRegHandlerMIPTBP1_2;
  96. m_fpGIFRegHandlers[GIF_A_D_REG_MIPTBP2_1] = &GSState::GIFRegHandlerMIPTBP2_1;
  97. m_fpGIFRegHandlers[GIF_A_D_REG_MIPTBP2_2] = &GSState::GIFRegHandlerMIPTBP2_2;
  98. m_fpGIFRegHandlers[GIF_A_D_REG_TEXA] = &GSState::GIFRegHandlerTEXA;
  99. m_fpGIFRegHandlers[GIF_A_D_REG_FOGCOL] = &GSState::GIFRegHandlerFOGCOL;
  100. m_fpGIFRegHandlers[GIF_A_D_REG_TEXFLUSH] = &GSState::GIFRegHandlerTEXFLUSH;
  101. m_fpGIFRegHandlers[GIF_A_D_REG_SCISSOR_1] = &GSState::GIFRegHandlerSCISSOR_1;
  102. m_fpGIFRegHandlers[GIF_A_D_REG_SCISSOR_2] = &GSState::GIFRegHandlerSCISSOR_2;
  103. m_fpGIFRegHandlers[GIF_A_D_REG_ALPHA_1] = &GSState::GIFRegHandlerALPHA_1;
  104. m_fpGIFRegHandlers[GIF_A_D_REG_ALPHA_2] = &GSState::GIFRegHandlerALPHA_2;
  105. m_fpGIFRegHandlers[GIF_A_D_REG_DIMX] = &GSState::GIFRegHandlerDIMX;
  106. m_fpGIFRegHandlers[GIF_A_D_REG_DTHE] = &GSState::GIFRegHandlerDTHE;
  107. m_fpGIFRegHandlers[GIF_A_D_REG_COLCLAMP] = &GSState::GIFRegHandlerCOLCLAMP;
  108. m_fpGIFRegHandlers[GIF_A_D_REG_TEST_1] = &GSState::GIFRegHandlerTEST_1;
  109. m_fpGIFRegHandlers[GIF_A_D_REG_TEST_2] = &GSState::GIFRegHandlerTEST_2;
  110. m_fpGIFRegHandlers[GIF_A_D_REG_PABE] = &GSState::GIFRegHandlerPABE;
  111. m_fpGIFRegHandlers[GIF_A_D_REG_FBA_1] = &GSState::GIFRegHandlerFBA_1;
  112. m_fpGIFRegHandlers[GIF_A_D_REG_FBA_2] = &GSState::GIFRegHandlerFBA_2;
  113. m_fpGIFRegHandlers[GIF_A_D_REG_FRAME_1] = &GSState::GIFRegHandlerFRAME_1;
  114. m_fpGIFRegHandlers[GIF_A_D_REG_FRAME_2] = &GSState::GIFRegHandlerFRAME_2;
  115. m_fpGIFRegHandlers[GIF_A_D_REG_ZBUF_1] = &GSState::GIFRegHandlerZBUF_1;
  116. m_fpGIFRegHandlers[GIF_A_D_REG_ZBUF_2] = &GSState::GIFRegHandlerZBUF_2;
  117. m_fpGIFRegHandlers[GIF_A_D_REG_BITBLTBUF] = &GSState::GIFRegHandlerBITBLTBUF;
  118. m_fpGIFRegHandlers[GIF_A_D_REG_TRXPOS] = &GSState::GIFRegHandlerTRXPOS;
  119. m_fpGIFRegHandlers[GIF_A_D_REG_TRXREG] = &GSState::GIFRegHandlerTRXREG;
  120. m_fpGIFRegHandlers[GIF_A_D_REG_TRXDIR] = &GSState::GIFRegHandlerTRXDIR;
  121. m_fpGIFRegHandlers[GIF_A_D_REG_HWREG] = &GSState::GIFRegHandlerHWREG;
  122. m_fpGIFRegHandlers[GIF_A_D_REG_SIGNAL] = &GSState::GIFRegHandlerSIGNAL;
  123. m_fpGIFRegHandlers[GIF_A_D_REG_FINISH] = &GSState::GIFRegHandlerFINISH;
  124. m_fpGIFRegHandlers[GIF_A_D_REG_LABEL] = &GSState::GIFRegHandlerLABEL;
  125. // DD
  126. CComPtr<IDirectDraw7> pDD; 
  127. if(FAILED(DirectDrawCreateEx(0, (void**)&pDD, IID_IDirectDraw7, 0)))
  128. return;
  129. m_ddcaps.dwSize = sizeof(DDCAPS); 
  130. if(FAILED(pDD->GetCaps(&m_ddcaps, NULL)))
  131. return;
  132. pDD = NULL;
  133. // D3D
  134. if(!(m_pD3D = Direct3DCreate9(D3D_SDK_VERSION))
  135. && !(m_pD3D = Direct3DCreate9(D3D9b_SDK_VERSION)))
  136. return;
  137. ZeroMemory(&m_caps, sizeof(m_caps));
  138. m_pD3D->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_X, &m_caps);
  139. m_fmtDepthStencil = 
  140. IsDepthFormatOk(m_pD3D, D3DFMT_D32, D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8) ? D3DFMT_D32 :
  141. IsDepthFormatOk(m_pD3D, D3DFMT_D24X8, D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8) ? D3DFMT_D24X8 :
  142. D3DFMT_D16;
  143. // D3D Device
  144. if(FAILED(ResetDevice(true)))
  145. return;
  146. // Shaders
  147. DWORD PixelShaderVersion = pApp->GetProfileInt(_T("Settings"), _T("PixelShaderVersion2"), D3DPS_VERSION(2, 0));
  148. if(PixelShaderVersion > m_caps.PixelShaderVersion)
  149. {
  150. CString str;
  151. str.Format(_T("Supported pixel shader version is too low!nnSupported: %d.%dnSelected: %d.%d"),
  152. D3DSHADER_VERSION_MAJOR(m_caps.PixelShaderVersion), D3DSHADER_VERSION_MINOR(m_caps.PixelShaderVersion),
  153. D3DSHADER_VERSION_MAJOR(PixelShaderVersion), D3DSHADER_VERSION_MINOR(PixelShaderVersion));
  154. AfxMessageBox(str);
  155. m_pD3DDev = NULL;
  156. return;
  157. }
  158. m_caps.PixelShaderVersion = min(PixelShaderVersion, m_caps.PixelShaderVersion);
  159. static const TCHAR* hlsl_tfx[] = 
  160. {
  161. _T("main_tfx0_32"), _T("main_tfx1_32"), _T("main_tfx2_32"), _T("main_tfx3_32"),
  162. _T("main_tfx0_24"), _T("main_tfx1_24"), _T("main_tfx2_24"), _T("main_tfx3_24"),
  163. _T("main_tfx0_24AEM"), _T("main_tfx1_24AEM"), _T("main_tfx2_24AEM"), _T("main_tfx3_24AEM"),
  164. _T("main_tfx0_16"), _T("main_tfx1_16"), _T("main_tfx2_16"), _T("main_tfx3_16"), 
  165. _T("main_tfx0_16AEM"), _T("main_tfx1_16AEM"), _T("main_tfx2_16AEM"), _T("main_tfx3_16AEM"), 
  166. _T("main_tfx0_8P_pt"), _T("main_tfx1_8P_pt"), _T("main_tfx2_8P_pt"), _T("main_tfx3_8P_pt"), 
  167. _T("main_tfx0_8P_ln"), _T("main_tfx1_8P_ln"), _T("main_tfx2_8P_ln"), _T("main_tfx3_8P_ln"), 
  168. _T("main_tfx0_8HP_pt"), _T("main_tfx1_8HP_pt"), _T("main_tfx2_8HP_pt"), _T("main_tfx3_8HP_pt"), 
  169. _T("main_tfx0_8HP_ln"), _T("main_tfx1_8HP_ln"), _T("main_tfx2_8HP_ln"), _T("main_tfx3_8HP_ln"),
  170. _T("main_notfx"), 
  171. _T("main_8PTo32"),
  172. };
  173. // ps_3_0
  174. if(m_caps.PixelShaderVersion >= D3DPS_VERSION(3, 0))
  175. {
  176. for(int i = 0; i < countof(hlsl_tfx); i++)
  177. {
  178. if(m_pHLSLTFX[i]) continue;
  179. CompileShaderFromResource(m_pD3DDev, IDR_HLSL_TFX, hlsl_tfx[i], _T("ps_3_0"),
  180. D3DXSHADER_AVOID_FLOW_CONTROL|D3DXSHADER_PARTIALPRECISION, &m_pHLSLTFX[i]);
  181. }
  182. for(int i = 0; i < 3; i++)
  183. {
  184. if(m_pHLSLMerge[i]) continue;
  185. CString main;
  186. main.Format(_T("main%d"), i);
  187. CompileShaderFromResource(m_pD3DDev, IDR_HLSL_MERGE, main, _T("ps_3_0"), 
  188. D3DXSHADER_AVOID_FLOW_CONTROL|D3DXSHADER_PARTIALPRECISION, &m_pHLSLMerge[i]);
  189. }
  190. }
  191. // ps_2_0
  192. if(m_caps.PixelShaderVersion >= D3DPS_VERSION(2, 0))
  193. {
  194. for(int i = 0; i < countof(hlsl_tfx); i++)
  195. {
  196. if(m_pHLSLTFX[i]) continue;
  197. CompileShaderFromResource(m_pD3DDev, IDR_HLSL_TFX, hlsl_tfx[i], _T("ps_2_0"), 
  198. D3DXSHADER_PARTIALPRECISION, &m_pHLSLTFX[i]);
  199. }
  200. for(int i = 0; i < 3; i++)
  201. {
  202. if(m_pHLSLMerge[i]) continue;
  203. CString main;
  204. main.Format(_T("main%d"), i);
  205. CompileShaderFromResource(m_pD3DDev, IDR_HLSL_MERGE, main, _T("ps_2_0"), 
  206. D3DXSHADER_PARTIALPRECISION, &m_pHLSLMerge[i]);
  207. }
  208. }
  209. // ps_1_1 + ps_1_4
  210. if(m_caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
  211. {
  212. static const UINT nShaderIDs[] = 
  213. {
  214. IDR_PS11_TFX000, IDR_PS11_TFX010, IDR_PS11_TFX011, 
  215. IDR_PS11_TFX1x0, IDR_PS11_TFX1x1,
  216. IDR_PS11_TFX200, IDR_PS11_TFX210, IDR_PS11_TFX211,
  217. IDR_PS11_TFX300, IDR_PS11_TFX310, IDR_PS11_TFX311,
  218. IDR_PS11_TFX4xx,
  219. IDR_PS11_EN11, IDR_PS11_EN01, IDR_PS11_EN10, IDR_PS11_EN00,
  220. IDR_PS14_EN11, IDR_PS14_EN01, IDR_PS14_EN10, IDR_PS14_EN00
  221. };
  222. for(int i = 0; i < countof(nShaderIDs); i++)
  223. {
  224. if(m_pPixelShaders[i]) continue;
  225. AssembleShaderFromResource(m_pD3DDev, nShaderIDs[i], 0, &m_pPixelShaders[i]);
  226. }
  227. if(!m_pHLSLRedBlue)
  228. {
  229. CompileShaderFromResource(m_pD3DDev, IDR_HLSL_RB, _T("main"), _T("ps_1_1"), 
  230. D3DXSHADER_PARTIALPRECISION, &m_pHLSLRedBlue);
  231. }
  232. }
  233. //
  234. m_strDefaultTitle.ReleaseBufferSetLength(GetWindowText(m_hWnd, m_strDefaultTitle.GetBuffer(256), 256));
  235. m_fEnablePalettizedTextures = !!pApp->GetProfileInt(_T("Settings"), _T("fEnablePalettizedTextures"), FALSE);
  236. //
  237. m_pRefClock = new CBaseReferenceClock(_T("RefClock"), NULL, &hr);
  238. //
  239. hr = S_OK;
  240. Reset();
  241. #if defined(DEBUG_LOG) || defined(DEBUG_LOG2)
  242. ::DeleteFile(_T("g:\gs.txt"));
  243. m_fp = _tfopen(_T("g:\gs.txt"), _T("at"));
  244. #endif
  245. // m_pCSRr->REV = 0x20;
  246. /*
  247. GSLocalMemory lm;
  248. int w = 512, h = 512;
  249. for(int y = 0; y < h; y++)
  250. {
  251. for(int x = 0; x < w; x++)
  252. {
  253. lm.writePixel24(x, y, (x * 255 / w) | ((y * 255 / h) << 8), 0x500, 8);
  254. }
  255. }
  256. for(int i = 16; i > 0; i--)
  257. {
  258. CString fn;
  259. fn.Format(_T("g:/%02d.bmp"), i);
  260. lm.SaveBMP(m_pD3DDev, fn, 0x500, i, PSM_PSMCT24, i*64, 512);
  261. }
  262. */
  263. }
  264. GSState::~GSState()
  265. {
  266. Reset();
  267. _aligned_free(m_pTrBuff);
  268. if(m_sfp) fclose(m_sfp);
  269. if(m_fp) fclose(m_fp);
  270. }
  271. HRESULT GSState::ResetDevice(bool fForceWindowed)
  272. {
  273. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  274. HMODULE hModule = AfxGetResourceHandle();
  275.     CWinApp* pApp = AfxGetApp();
  276. HRESULT hr;
  277. if(!m_pD3D)
  278. return E_FAIL;
  279. m_pOrgRenderTarget = NULL;
  280. m_pTmpRenderTarget = NULL;
  281. m_pD3DXFont = NULL;
  282. ZeroMemory(&m_d3dpp, sizeof(m_d3dpp));
  283. m_d3dpp.Windowed = TRUE;
  284. m_d3dpp.hDeviceWindow = m_hWnd;
  285. m_d3dpp.SwapEffect = /*D3DSWAPEFFECT_COPY*/D3DSWAPEFFECT_DISCARD/*D3DSWAPEFFECT_FLIP*/;
  286. m_d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
  287. m_d3dpp.BackBufferWidth = m_width;
  288. m_d3dpp.BackBufferHeight = m_height;
  289. //m_d3dpp.BackBufferCount = 3;
  290. m_d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
  291. if(!!pApp->GetProfileInt(_T("Settings"), _T("fEnableTvOut"), FALSE))
  292. m_d3dpp.Flags |= D3DPRESENTFLAG_VIDEO;
  293. int ModeWidth = pApp->GetProfileInt(_T("Settings"), _T("ModeWidth"), 0);
  294. int ModeHeight = pApp->GetProfileInt(_T("Settings"), _T("ModeHeight"), 0);
  295. int ModeRefreshRate = pApp->GetProfileInt(_T("Settings"), _T("ModeRefreshRate"), 0);
  296. if(!fForceWindowed && ModeWidth > 0 && ModeHeight > 0 && ModeRefreshRate >= 0)
  297. {
  298. m_d3dpp.Windowed = FALSE;
  299. m_d3dpp.BackBufferWidth = ModeWidth;
  300. m_d3dpp.BackBufferHeight = ModeHeight;
  301. m_d3dpp.FullScreen_RefreshRateInHz = ModeRefreshRate;
  302. m_d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
  303. ::SetWindowLong(m_hWnd, GWL_STYLE, ::GetWindowLong(m_hWnd, GWL_STYLE) & ~(WS_CAPTION|WS_THICKFRAME));
  304. ::SetWindowPos(m_hWnd, NULL, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
  305. ::SetMenu(m_hWnd, NULL);
  306. m_iOSD = 0;
  307. }
  308. if(!m_pD3DDev)
  309. {
  310. if(FAILED(hr = m_pD3D->CreateDevice(
  311. // m_pD3D->GetAdapterCount()-1, D3DDEVTYPE_REF,
  312. D3DADAPTER_DEFAULT, D3DDEVTYPE_X, 
  313. m_hWnd,
  314. m_caps.VertexProcessingCaps ? D3DCREATE_HARDWARE_VERTEXPROCESSING : D3DCREATE_SOFTWARE_VERTEXPROCESSING, 
  315. &m_d3dpp, &m_pD3DDev)))
  316. return hr;
  317. }
  318. else
  319. {
  320. if(FAILED(hr = m_pD3DDev->Reset(&m_d3dpp)))
  321. {
  322. if(D3DERR_DEVICELOST == hr)
  323. {
  324. Sleep(1000);
  325. if(FAILED(hr = m_pD3DDev->Reset(&m_d3dpp)))
  326. return hr;
  327. }
  328. else
  329. {
  330. return hr;
  331. }
  332. }
  333. }
  334. CComPtr<IDirect3DSurface9> pBackBuff;
  335. hr = m_pD3DDev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuff);
  336. ZeroMemory(&m_bd, sizeof(m_bd));
  337. pBackBuff->GetDesc(&m_bd);
  338. hr = m_pD3DDev->Clear(0, NULL, D3DCLEAR_TARGET, 0, 1.0f, 0);
  339.     hr = m_pD3DDev->GetRenderTarget(0, &m_pOrgRenderTarget);
  340. if(m_caps.PixelShaderVersion >= D3DPS_VERSION(1, 1) && m_caps.PixelShaderVersion <= D3DPS_VERSION(1, 3)
  341. && m_pHLSLRedBlue)
  342. {
  343. hr = m_pD3DDev->CreateTexture(
  344. m_bd.Width, m_bd.Height, 0, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, 
  345. D3DPOOL_DEFAULT, &m_pTmpRenderTarget, NULL);
  346. }
  347. D3DXFONT_DESC fd;
  348. memset(&fd, 0, sizeof(fd));
  349. _tcscpy(fd.FaceName, _T("Arial"));
  350. fd.Height = -(int)(sqrt((float)m_bd.Height) * 0.7);
  351. hr = D3DXCreateFontIndirect(m_pD3DDev, &fd, &m_pD3DXFont);
  352.     hr = m_pD3DDev->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
  353.     hr = m_pD3DDev->SetRenderState(D3DRS_LIGHTING, FALSE);
  354. m_texfilter = (D3DTEXTUREFILTERTYPE)pApp->GetProfileInt(_T("Settings"), _T("TexFilter"), D3DTEXF_LINEAR);
  355. for(int i = 0; i < 8; i++)
  356. {
  357. hr = m_pD3DDev->SetSamplerState(i, D3DSAMP_MAGFILTER, m_texfilter);
  358. hr = m_pD3DDev->SetSamplerState(i, D3DSAMP_MINFILTER, m_texfilter);
  359. // hr = m_pD3DDev->SetSamplerState(i, D3DSAMP_MIPFILTER, m_texfilter);
  360. hr = m_pD3DDev->SetSamplerState(i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
  361. hr = m_pD3DDev->SetSamplerState(i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
  362. }
  363. hr = m_pD3DDev->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE);
  364. hr = m_pD3DDev->SetRenderState(D3DRS_BLENDOPALPHA, D3DBLENDOP_ADD);
  365. hr = m_pD3DDev->SetRenderState(D3DRS_SRCBLENDALPHA, D3DBLEND_ONE);
  366. hr = m_pD3DDev->SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_ZERO);
  367. return S_OK;
  368. }
  369. UINT32 GSState::Freeze(freezeData* fd, bool fSizeOnly)
  370. {
  371. int size = sizeof(m_version)
  372. + sizeof(m_de) + sizeof(m_rs) + sizeof(m_v) 
  373. + sizeof(m_x) + sizeof(m_y) + 1024*1024*4
  374. + sizeof(m_path) + sizeof(m_q)
  375. /*+ sizeof(m_vl)*/;
  376. if(fSizeOnly)
  377. {
  378. fd->size = size;
  379. return 0;
  380. }
  381. else if(!fd->data || fd->size < size)
  382. {
  383. return -1;
  384. }
  385. FlushWriteTransfer();
  386. FlushPrimInternal();
  387. BYTE* data = fd->data;
  388. memcpy(data, &m_version, sizeof(m_version)); data += sizeof(m_version);
  389. memcpy(data, &m_de, sizeof(m_de)); data += sizeof(m_de);
  390. memcpy(data, &m_rs, sizeof(m_rs)); data += sizeof(m_rs);
  391. memcpy(data, &m_v, sizeof(m_v)); data += sizeof(m_v);
  392. memcpy(data, &m_x, sizeof(m_x)); data += sizeof(m_x);
  393. memcpy(data, &m_y, sizeof(m_y)); data += sizeof(m_y);
  394. memcpy(data, m_lm.GetVM(), 1024*1024*4); data += 1024*1024*4;
  395. memcpy(data, m_path, sizeof(m_path)); data += sizeof(m_path);
  396. memcpy(data, &m_q, sizeof(m_q)); data += sizeof(m_q);
  397. // memcpy(data, &m_vl, sizeof(m_vl)); data += sizeof(m_vl);
  398. return 0;
  399. }
  400. UINT32 GSState::Defrost(const freezeData* fd)
  401. {
  402. if(!fd || !fd->data || fd->size == 0) 
  403. return -1;
  404. int size = sizeof(m_version)
  405. + sizeof(m_de) + sizeof(m_rs) + sizeof(m_v) 
  406. + sizeof(m_x) + sizeof(m_y) + 1024*1024*4
  407. + sizeof(m_path)
  408. + sizeof(m_q)
  409. /*+ sizeof(m_vl)*/;
  410. if(fd->size != size) 
  411. return -1;
  412. BYTE* data = fd->data;
  413. int version = 0;
  414. memcpy(&version, data, sizeof(version)); data += sizeof(version);
  415. if(m_version != version) return -1;
  416. FlushPrimInternal();
  417. memcpy(&m_de, data, sizeof(m_de)); data += sizeof(m_de);
  418. memcpy(&m_rs, data, sizeof(m_rs)); data += sizeof(m_rs);
  419. memcpy(&m_v, data, sizeof(m_v)); data += sizeof(m_v);
  420. memcpy(&m_x, data, sizeof(m_x)); data += sizeof(m_x);
  421. memcpy(&m_y, data, sizeof(m_y)); data += sizeof(m_y);
  422. memcpy(m_lm.GetVM(), data, 1024*1024*4); data += 1024*1024*4;
  423. memcpy(&m_path, data, sizeof(m_path)); data += sizeof(m_path);
  424. memcpy(&m_q, data, sizeof(m_q)); data += sizeof(m_q);
  425. // memcpy(&m_vl, data, sizeof(m_vl)); data += sizeof(m_vl);
  426. m_pPRIM = !m_de.PRMODECONT.AC ? (GIFRegPRIM*)&m_de.PRMODE : &m_de.PRIM;
  427. m_ctxt = &m_de.CTXT[m_pPRIM->CTXT];
  428. m_de.CTXT[0].ftbl = &GSLocalMemory::m_psmtbl[m_de.CTXT[0].FRAME.PSM];
  429. m_de.CTXT[0].ztbl = &GSLocalMemory::m_psmtbl[m_de.CTXT[0].ZBUF.PSM];
  430. m_de.CTXT[0].ttbl = &GSLocalMemory::m_psmtbl[m_de.CTXT[0].TEX0.PSM];
  431. m_de.CTXT[1].ftbl = &GSLocalMemory::m_psmtbl[m_de.CTXT[1].FRAME.PSM];
  432. m_de.CTXT[1].ztbl = &GSLocalMemory::m_psmtbl[m_de.CTXT[1].ZBUF.PSM];
  433. m_de.CTXT[1].ttbl = &GSLocalMemory::m_psmtbl[m_de.CTXT[1].TEX0.PSM];
  434. return 0;
  435. }
  436. void GSState::Write(GS_REG mem, GSReg* r, UINT64 mask)
  437. {
  438. ASSERT(r);
  439. GSPerfMonAutoTimer at(m_perfmon);
  440. #ifdef ENABLE_CAPTURE_STATE
  441. if(m_sfp)
  442. {
  443. fputc(ST_WRITE, m_sfp);
  444. fwrite(&mem, 4, 1, m_sfp);
  445. fwrite(r, 8, 1, m_sfp);
  446. fwrite(&mask, 8, 1, m_sfp);
  447. }
  448. #endif
  449. #define AssignReg(reg) m_rs.##reg##.i64 = (r->i64 & mask) | (m_rs.##reg##.i64 & ~mask);
  450. switch(mem)
  451. {
  452. case GS_PMODE:
  453. AssignReg(PMODE);
  454. LOG(_T("Write(GS_PMODE, EN1=%x EN2=%x CRTMD=%x MMOD=%x AMOD=%x SLBG=%x ALP=%x)n"), 
  455. r->PMODE.EN1,
  456. r->PMODE.EN2,
  457. r->PMODE.CRTMD,
  458. r->PMODE.MMOD,
  459. r->PMODE.AMOD,
  460. r->PMODE.SLBG,
  461. r->PMODE.ALP);
  462. break;
  463. case GS_SMODE1:
  464. AssignReg(SMODE1);
  465. LOG(_T("Write(GS_SMODE1, CMOD=%x)n"), 
  466. r->SMODE1.CMOD);
  467. break;
  468. case GS_SMODE2:
  469. AssignReg(SMODE2);
  470. LOG(_T("Write(GS_SMODE2, INT=%x FFMD=%x DPMS=%x)n"), 
  471. r->SMODE2.INT,
  472. r->SMODE2.FFMD,
  473. r->SMODE2.DPMS);
  474. break;
  475. case GS_SRFSH:
  476. LOG(_T("Write(GS_SRFSH, %016I64x)n"), r->i64);
  477. break;
  478. case GS_SYNCH1:
  479. LOG(_T("Write(GS_SYNCH1, %016I64x)n"), r->i64);
  480. break;
  481. case GS_SYNCH2:
  482. LOG(_T("Write(GS_SYNCH2, %016I64x)n"), r->i64);
  483. break;
  484. case GS_SYNCV:
  485. LOG(_T("Write(GS_SYNCV, %016I64x)n"), r->i64);
  486. break;
  487. case GS_DISPFB1:
  488. AssignReg(DISPFB[0]);
  489. LOG(_T("Write(GS_DISPFB1, FBP=%x FBW=%d PSM=%x DBX=%x DBY=%x)n"), 
  490. r->DISPFB.FBP<<5,
  491. r->DISPFB.FBW*64,
  492. r->DISPFB.PSM,
  493. r->DISPFB.DBX,
  494. r->DISPFB.DBY);
  495. break;
  496. case GS_DISPLAY1:
  497. AssignReg(DISPLAY[0]);
  498. LOG(_T("Write(GS_DISPLAY1, DX=%x DY=%x MAGH=%x MAGV=%x DW=%x DH=%x)n"),
  499. r->DISPLAY.DX,
  500. r->DISPLAY.DY,
  501. r->DISPLAY.MAGH,
  502. r->DISPLAY.MAGV,
  503. r->DISPLAY.DW,
  504. r->DISPLAY.DH);
  505. break;
  506. case GS_DISPFB2:
  507. AssignReg(DISPFB[1]);
  508. LOG(_T("Write(GS_DISPFB2, FBP=%x FBW=%d PSM=%x DBX=%x DBY=%x)n"), 
  509. r->DISPFB.FBP<<5,
  510. r->DISPFB.FBW*64,
  511. r->DISPFB.PSM,
  512. r->DISPFB.DBX,
  513. r->DISPFB.DBY);
  514. break;
  515. case GS_DISPLAY2:
  516. AssignReg(DISPLAY[1]);
  517. LOG(_T("Write(GS_DISPLAY2, DX=%x DY=%x MAGH=%x MAGV=%x DW=%x DH=%x)n"),
  518. r->DISPLAY.DX,
  519. r->DISPLAY.DY,
  520. r->DISPLAY.MAGH,
  521. r->DISPLAY.MAGV,
  522. r->DISPLAY.DW,
  523. r->DISPLAY.DH);
  524. break;
  525. case GS_EXTBUF:
  526. AssignReg(EXTBUF);
  527. LOG(_T("Write(GS_EXTBUF, EXBP=%x EXBW=%x FBIN=%x WFFMD=%x EMODA=%x EMODC=%x WDX=%x WDY=%x)n"),
  528. r->EXTBUF.EXBP,
  529. r->EXTBUF.EXBW,
  530. r->EXTBUF.FBIN,
  531. r->EXTBUF.WFFMD,
  532. r->EXTBUF.EMODA,
  533. r->EXTBUF.EMODC,
  534. r->EXTBUF.WDX,
  535. r->EXTBUF.WDY);
  536. break;
  537. case GS_EXTDATA:
  538. AssignReg(EXTDATA);
  539. LOG(_T("Write(GS_EXTDATA, SX=%x SY=%x SMPH=%x SMPV=%x WW=%x WH=%x)n"), 
  540. r->EXTDATA.SX,
  541. r->EXTDATA.SY,
  542. r->EXTDATA.SMPH,
  543. r->EXTDATA.SMPV,
  544. r->EXTDATA.WW,
  545. r->EXTDATA.WH);
  546. break;
  547. case GS_EXTWRITE:
  548. AssignReg(EXTWRITE);
  549. LOG(_T("Write(GS_EXTWRITE, WRITE=%x)n"),
  550. r->EXTWRITE.WRITE);
  551. break;
  552. case GS_BGCOLOR:
  553. AssignReg(BGCOLOR);
  554. LOG(_T("Write(GS_BGCOLOR, R=%x G=%x B=%x)n"),
  555. r->BGCOLOR.R,
  556. r->BGCOLOR.G,
  557. r->BGCOLOR.B);
  558. break;
  559. case GS_CSR:
  560. AssignReg(CSRw);
  561. LOG(_T("Write(GS_CSR, SIGNAL=%x FINISH=%x HSINT=%x VSINT=%x EDWINT=%x ZERO1=%x ZERO2=%x FLUSH=%x RESET=%x NFIELD=%x FIELD=%x FIFO=%x REV=%x ID=%x)n"),
  562. r->CSR.SIGNAL,
  563. r->CSR.FINISH,
  564. r->CSR.HSINT,
  565. r->CSR.VSINT,
  566. r->CSR.EDWINT,
  567. r->CSR.ZERO1,
  568. r->CSR.ZERO2,
  569. r->CSR.FLUSH,
  570. r->CSR.RESET,
  571. r->CSR.NFIELD,
  572. r->CSR.FIELD,
  573. r->CSR.FIFO,
  574. r->CSR.REV,
  575. r->CSR.ID);
  576. if(m_rs.CSRw.SIGNAL) m_pCSRr->SIGNAL = 0;
  577. if(m_rs.CSRw.FINISH) m_pCSRr->FINISH = 0;
  578. if(m_rs.CSRw.RESET) Reset();
  579. break;
  580. case GS_IMR:
  581. AssignReg(IMR);
  582. LOG(_T("Write(GS_IMR, _PAD1=%x SIGMSK=%x FINISHMSK=%x HSMSK=%x VSMSK=%x EDWMSK=%x)n"),
  583. r->IMR._PAD1,
  584. r->IMR.SIGMSK,
  585. r->IMR.FINISHMSK,
  586. r->IMR.HSMSK,
  587. r->IMR.VSMSK,
  588. r->IMR.EDWMSK);
  589. break;
  590. case GS_BUSDIR:
  591. AssignReg(BUSDIR);
  592. LOG(_T("Write(GS_BUSDIR, DIR=%x)n"),
  593. r->BUSDIR.DIR);
  594. break;
  595. case GS_SIGLBLID:
  596. AssignReg(SIGLBLID);
  597. LOG(_T("Write(GS_SIGLBLID, SIGID=%x LBLID=%x)n"),
  598. r->SIGLBLID.SIGID,
  599. r->SIGLBLID.LBLID);
  600. break;
  601. default:
  602. LOG(_T("*** WARNING *** Write(?????????, %016I64x)n"), r->i64);
  603. ASSERT(0);
  604. break;
  605. }
  606. m_nVSync = 0;
  607. }
  608. UINT64 GSState::Read(GS_REG mem)
  609. {
  610. if(mem == GS_CSR)
  611. return m_pCSRr->i64;
  612. GSPerfMonAutoTimer at(m_perfmon);
  613. GSReg* r = NULL;
  614. switch(mem)
  615. {
  616. case GS_CSR:
  617. r = reinterpret_cast<GSReg*>(m_pCSRr);
  618. LOG(_T("Read(GS_CSR, SIGNAL=%x FINISH=%x HSINT=%x VSINT=%x EDWINT=%x ZERO1=%x ZERO2=%x FLUSH=%x RESET=%x NFIELD=%x FIELD=%x FIFO=%x REV=%x ID=%x)n"),
  619. r->CSR.SIGNAL,
  620. r->CSR.FINISH,
  621. r->CSR.HSINT,
  622. r->CSR.VSINT,
  623. r->CSR.EDWINT,
  624. r->CSR.ZERO1,
  625. r->CSR.ZERO2,
  626. r->CSR.FLUSH,
  627. r->CSR.RESET,
  628. r->CSR.NFIELD,
  629. r->CSR.FIELD,
  630. r->CSR.FIFO,
  631. r->CSR.REV,
  632. r->CSR.ID);
  633. break;
  634. case GS_SIGLBLID:
  635. r = reinterpret_cast<GSReg*>(&m_rs.SIGLBLID);
  636. LOG(_T("Read(GS_SIGLBLID, SIGID=%x LBLID=%x)n"),
  637. r->SIGLBLID.SIGID,
  638. r->SIGLBLID.LBLID);
  639. break;
  640. case GS_UNKNOWN:
  641. LOG(_T("*** WARNING *** Read(%08x)n"), mem);
  642. return m_pCSRr->FIELD << 13;
  643. break;
  644. default:
  645. LOG(_T("*** WARNING *** Read(%08x)n"), mem);
  646. ASSERT(0);
  647. break;
  648. }
  649. return r ? r->i64 : 0;
  650. }
  651. void GSState::ReadFIFO(BYTE* pMem)
  652. {
  653. GSPerfMonAutoTimer at(m_perfmon);
  654. FlushWriteTransfer();
  655. LOG(_T("*** WARNING *** ReadFIFO(%08x)n"), pMem);
  656. ReadTransfer(pMem, 16);
  657. }
  658. __declspec(align(16)) static BYTE tr1_buff[0x4000];
  659. void GSState::Transfer1(BYTE* pMem, UINT32 addr)
  660. {
  661. // GSPerfMonAutoTimer at(m_perfmon);
  662. LOG(_T("Transfer1(%08x, %d)n"), pMem, addr);
  663. // TODO: this is too cheap...
  664. addr &= 0x3fff;
  665. memcpy(tr1_buff, pMem + addr, 0x4000 - addr);
  666. memcpy(tr1_buff + 0x4000 - addr, pMem, addr);
  667. /*
  668. if((m_tag).NLOOP
  669. && ((GIFTag*)tr1_buff)->NLOOP == 8 && ((GIFTag*)tr1_buff)->PRIM == 0x5b
  670. && ((GIFTag*)tr1_buff)->NREG == 9 && ((GIFTag*)tr1_buff)->REGS == 0x0000000412412412ui64)
  671. {
  672. ASSERT(0);
  673. }
  674. */
  675. ASSERT(m_path[1].m_tag.NLOOP == 0 && m_path[2].m_tag.NLOOP == 0);
  676. Transfer(tr1_buff, -1, m_path[0]);
  677. }
  678. void GSState::Transfer2(BYTE* pMem, UINT32 size)
  679. {
  680. ASSERT(m_path[0].m_tag.NLOOP == 0 && m_path[2].m_tag.NLOOP == 0);
  681. Transfer(pMem, size, m_path[1]);
  682. }
  683. void GSState::Transfer3(BYTE* pMem, UINT32 size)
  684. {
  685. ASSERT(m_path[0].m_tag.NLOOP == 0 && m_path[1].m_tag.NLOOP == 0);
  686. Transfer(pMem, size, m_path[2]);
  687. }
  688. void GSState::Transfer(BYTE* pMem, UINT32 size, GIFPath& path)
  689. {
  690. GSPerfMonAutoTimer at(m_perfmon);
  691. BYTE* pMemOrg = pMem;
  692. UINT32 sizeOrg = size;
  693. while(size > 0)
  694. {
  695. LOG(_T("Transfer(%08x, %d) STARTn"), pMem, size);
  696. bool fEOP = false;
  697. if(path.m_tag.NLOOP == 0)
  698. {
  699. path.m_tag = *(GIFTag*)pMem;
  700. path.m_nreg = 0;
  701. m_q = 1.0f;
  702. /*
  703. LOG(_T("GIFTag NLOOP=%x EOP=%x PRE=%x PRIM=%x FLG=%x NREG=%x REGS=%xn"), 
  704. m_tag.NLOOP,
  705. m_tag.EOP,
  706. m_tag.PRE,
  707. m_tag.PRIM,
  708. m_tag.FLG,
  709. m_tag.NREG,
  710. m_tag.REGS);
  711. */
  712. pMem += sizeof(GIFTag);
  713. size--;
  714. if(path.m_tag.PRE)
  715. {
  716. LOG(_T("PRE "));
  717. GIFReg r;
  718. r.i64 = path.m_tag.PRIM;
  719. (this->*m_fpGIFRegHandlers[GIF_A_D_REG_PRIM])(&r);
  720. }
  721. if(path.m_tag.EOP)
  722. {
  723. LOG(_T("EOPn"));
  724. fEOP = true;
  725. }
  726. else if(path.m_tag.NLOOP == 0)
  727. {
  728. LOG(_T("*** WARNING *** m_tag.NLOOP == 0 && EOP == 0n"));
  729. fEOP = true;
  730. // ASSERT(0);
  731. }
  732. }
  733. UINT32 size_msb = size & (1<<31);
  734. switch(path.m_tag.FLG)
  735. {
  736. case GIF_FLG_PACKED:
  737. for(GIFPackedReg* r = (GIFPackedReg*)pMem; path.m_tag.NLOOP > 0 && size > 0; r++, size--, pMem += sizeof(GIFPackedReg))
  738. {
  739. DWORD reg = GET_GIF_REG(path.m_tag, path.m_nreg);
  740. (this->*m_fpGIFPackedRegHandlers[reg])(r);
  741. if((path.m_nreg = (path.m_nreg+1)&0xf) == path.m_tag.NREG) {path.m_nreg = 0; path.m_tag.NLOOP--;}
  742. }
  743. break;
  744. case GIF_FLG_REGLIST:
  745. size *= 2;
  746. for(GIFReg* r = (GIFReg*)pMem; path.m_tag.NLOOP > 0 && size > 0; r++, size--, pMem += sizeof(GIFReg))
  747. {
  748. DWORD reg = GET_GIF_REG(path.m_tag, path.m_nreg);
  749. (this->*m_fpGIFRegHandlers[reg])(r);
  750. if((path.m_nreg = (path.m_nreg+1)&0xf) == path.m_tag.NREG) {path.m_nreg = 0; path.m_tag.NLOOP--;}
  751. }
  752. if(size&1) pMem += sizeof(GIFReg);
  753. size /= 2;
  754. size |= size_msb; // a bit lame :P
  755. break;
  756. case GIF_FLG_IMAGE2:
  757. LOG(_T("*** WARNING **** Unexpected GIFTag flagn"));
  758. path.m_tag.NLOOP = 0;
  759. break;
  760. ASSERT(0);
  761. case GIF_FLG_IMAGE:
  762. {
  763. int len = min(size, path.m_tag.NLOOP);
  764. //ASSERT(!(len&3));
  765. switch(m_rs.TRXDIR.XDIR)
  766. {
  767. case 0:
  768. WriteTransfer(pMem, len*16);
  769. break;
  770. case 1: 
  771. ReadTransfer(pMem, len*16);
  772. break;
  773. case 2: 
  774. //MoveTransfer();
  775. break;
  776. case 3: 
  777. ASSERT(0);
  778. break;
  779. default: 
  780. __assume(0);
  781. }
  782. pMem += len*16;
  783. path.m_tag.NLOOP -= len;
  784. size -= len;
  785. }
  786. break;
  787. default: 
  788. __assume(0);
  789. }
  790. LOG(_T("Transfer(%08x, %d) ENDn"), pMem, size);
  791. if(fEOP && (INT32)size <= 0)
  792. {
  793. break;
  794. }
  795. }
  796. #ifdef ENABLE_CAPTURE_STATE
  797. if(m_sfp)
  798. {
  799. fputc(ST_TRANSFER, m_sfp);
  800. fwrite(&sizeOrg, 4, 1, m_sfp);
  801. UINT32 len = (UINT32)(pMem - pMemOrg);
  802. fwrite(&len, 4, 1, m_sfp);
  803. fwrite(pMemOrg, len, 1, m_sfp);
  804. }
  805. #endif
  806. }
  807. UINT32 GSState::MakeSnapshot(char* path)
  808. {
  809. GSPerfMonAutoTimer at(m_perfmon);
  810. CString fn;
  811. fn.Format(_T("%sgsdx9_%s.bmp"), CString(path), CTime::GetCurrentTime().Format(_T("%Y%m%d%H%M%S")));
  812. return D3DXSaveSurfaceToFile(fn, D3DXIFF_BMP, m_pOrgRenderTarget, NULL, NULL);
  813. }
  814. void GSState::Capture()
  815. {
  816. GSPerfMonAutoTimer at(m_perfmon);
  817. if(!m_capture.IsCapturing()) m_capture.BeginCapture(m_pD3DDev, m_rs.GetFPS());
  818. else m_capture.EndCapture();
  819. }
  820. void GSState::ToggleOSD()
  821. {
  822. if(m_d3dpp.Windowed)
  823. {
  824. if(m_iOSD == 1) SetWindowText(m_hWnd, m_strDefaultTitle);
  825. m_iOSD = ++m_iOSD % 3;
  826. }
  827. else
  828. {
  829. m_iOSD = m_iOSD ? 0 : 2;
  830. }
  831. }
  832. void GSState::CaptureState(CString fn)
  833. {
  834. #ifdef ENABLE_CAPTURE_STATE
  835. if(!m_sfp) m_sfp = !fn.IsEmpty() ? _tfopen(fn, _T("wb")) : NULL;
  836. #endif
  837. }
  838. void GSState::VSync()
  839. {
  840. GSPerfMonAutoTimer at(m_perfmon);
  841. LOG(_T("VSync(%d)n"), m_perfmon.GetFrame());
  842. #ifdef ENABLE_CAPTURE_STATE
  843. if(m_sfp) fputc(ST_VSYNC, m_sfp);
  844. #endif
  845. FlushPrimInternal();
  846. Flip();
  847. EndFrame();
  848. }
  849. void GSState::Reset()
  850. {
  851. GSPerfMonAutoTimer at(m_perfmon);
  852. memset(&m_de, 0, sizeof(m_de));
  853. memset(&m_rs, 0, sizeof(m_rs));
  854. memset(m_path, 0, sizeof(m_path));
  855. memset(&m_v, 0, sizeof(m_v));
  856. // m_de.PRMODECONT.AC = 1;
  857. // m_pPRIM = &m_de.PRIM;
  858. m_PRIM = 8;
  859. m_ctxt = &m_de.CTXT[0];
  860. m_de.CTXT[0].ftbl = &GSLocalMemory::m_psmtbl[m_de.CTXT[0].FRAME.PSM];
  861. m_de.CTXT[0].ztbl = &GSLocalMemory::m_psmtbl[m_de.CTXT[0].ZBUF.PSM];
  862. m_de.CTXT[0].ttbl = &GSLocalMemory::m_psmtbl[m_de.CTXT[0].TEX0.PSM];
  863. m_de.CTXT[1].ftbl = &GSLocalMemory::m_psmtbl[m_de.CTXT[1].FRAME.PSM];
  864. m_de.CTXT[1].ztbl = &GSLocalMemory::m_psmtbl[m_de.CTXT[1].ZBUF.PSM];
  865. m_de.CTXT[1].ttbl = &GSLocalMemory::m_psmtbl[m_de.CTXT[1].TEX0.PSM];
  866. if(m_pD3DDev) m_pD3DDev->Clear(0, NULL, D3DCLEAR_TARGET/*|D3DCLEAR_ZBUFFER|D3DCLEAR_STENCIL*/, 0, 1.0f, 0);
  867. }
  868. void GSState::FinishFlip(FlipInfo rt[2])
  869. {
  870. HRESULT hr;
  871. bool fEN[2];
  872. CRect src[2];
  873. for(int i = 0; i < countof(fEN); i++)
  874. {
  875. fEN[i] = m_rs.IsEnabled(i) && rt[i].pRT;
  876. if(fEN[i])
  877. {
  878. CRect r = m_rs.GetDispRect(i);
  879. src[i] = CRect(
  880. (int)(rt[i].scale.x * r.left),
  881. (int)(rt[i].scale.y * r.top),
  882. (int)(rt[i].scale.x * r.right),
  883. (int)(rt[i].scale.y * r.bottom));
  884. if(m_rs.SMODE2.INT && m_rs.SMODE2.FFMD)
  885. src[i].bottom /= 2;
  886. }
  887. else
  888. {
  889. rt[i].rd.Width = rt[i].rd.Height = 1; // to avoid div by zero below
  890. }
  891. }
  892. CRect dst(0, 0, m_bd.Width, m_bd.Height);
  893. struct
  894. {
  895. float x, y, z, rhw;
  896. float tu1, tv1;
  897. float tu2, tv2;
  898. }
  899. pVertices[] =
  900. {
  901. {(float)dst.left, (float)dst.top, 0.5f, 2.0f, 
  902. (float)src[0].left / rt[0].rd.Width, (float)src[0].top / rt[0].rd.Height, 
  903. (float)src[1].left / rt[1].rd.Width, (float)src[1].top / rt[1].rd.Height},
  904. {(float)dst.right, (float)dst.top, 0.5f, 2.0f, 
  905. (float)src[0].right / rt[0].rd.Width, (float)src[0].top / rt[0].rd.Height, 
  906. (float)src[1].right / rt[1].rd.Width, (float)src[1].top / rt[1].rd.Height},
  907. {(float)dst.left, (float)dst.bottom, 0.5f, 2.0f, 
  908. (float)src[0].left / rt[0].rd.Width, (float)src[0].bottom / rt[0].rd.Height, 
  909. (float)src[1].left / rt[1].rd.Width, (float)src[1].bottom / rt[1].rd.Height},
  910. {(float)dst.right, (float)dst.bottom, 0.5f, 2.0f, 
  911. (float)src[0].right / rt[0].rd.Width, (float)src[0].bottom / rt[0].rd.Height, 
  912. (float)src[1].right / rt[1].rd.Width, (float)src[1].bottom / rt[1].rd.Height},
  913. };
  914. /*
  915. if(m_rs.SMODE2.INT)
  916. {
  917. if(!m_rs.SMODE2.FFMD)
  918. {
  919. // m_pCSRr->FIELD = 1 - m_pCSRr->FIELD;
  920. }
  921. else if(!m_pCSRr->FIELD)
  922. {
  923. // if(m_pCSRr->FIELD == 0) m_pCSRr->FIELD = 1; // FIXME: might stop a few games, but this is the only way to stop shaking the bios or sfae
  924. for(int i = 0; i < countof(pVertices); i++)
  925. {
  926. pVertices[i].tv1 += rt[0].scale.y*0.5f / rt[0].rd.Height;
  927. pVertices[i].tv2 += rt[1].scale.y*0.5f / rt[1].rd.Height;
  928. }
  929. }
  930. }
  931. */
  932. // FIXME: sw mode / poolmaster + funslower
  933. // if(m_nVSync > 1 || m_pCSRr->FIELD == 0)
  934. {
  935. m_pCSRr->FIELD = 1 - m_pCSRr->FIELD; 
  936. m_nVSync = 0;
  937. }
  938. m_nVSync++;
  939. if(m_pCSRr->FIELD && m_rs.SMODE2.INT /*&& m_rs.SMODE2.FFMD*/)
  940. {
  941. for(int i = 0; i < countof(pVertices); i++)
  942. {
  943. pVertices[i].tv1 += rt[0].scale.y*0.5f / rt[0].rd.Height;
  944. pVertices[i].tv2 += rt[1].scale.y*0.5f / rt[1].rd.Height;
  945. }
  946. }
  947. hr = m_pD3DDev->SetRenderState(D3DRS_ZENABLE, FALSE);
  948.     hr = m_pD3DDev->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
  949. hr = m_pD3DDev->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); 
  950. hr = m_pD3DDev->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
  951. hr = m_pD3DDev->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RGBA);
  952. hr = m_pD3DDev->SetTexture(0, rt[0].pRT);
  953. hr = m_pD3DDev->SetTexture(1, rt[1].pRT);
  954. hr = m_pD3DDev->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
  955. hr = m_pD3DDev->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1);
  956. hr = m_pD3DDev->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
  957. hr = m_pD3DDev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
  958. hr = m_pD3DDev->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
  959. hr = m_pD3DDev->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
  960. hr = m_pD3DDev->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
  961. hr = m_pD3DDev->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
  962. hr = m_pD3DDev->SetSamplerState(1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
  963. hr = m_pD3DDev->SetSamplerState(1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
  964. IDirect3DPixelShader9* pPixelShader = NULL;
  965. if(!pPixelShader && m_caps.PixelShaderVersion >= D3DPS_VERSION(2, 0) && m_pHLSLMerge[PS_M32])
  966. {
  967. pPixelShader = m_pHLSLMerge[PS_M32];
  968. }
  969. if(!pPixelShader && m_caps.PixelShaderVersion >= D3DPS_VERSION(1, 4))
  970. {
  971. if(fEN[0] && fEN[1]) // RAO1 + RAO2
  972. {
  973. pPixelShader = m_pPixelShaders[PS14_EN11];
  974. }
  975. else if(fEN[0]) // RAO1
  976. {
  977. pPixelShader = m_pPixelShaders[PS14_EN10];
  978. }
  979. else if(fEN[1]) // RAO2
  980. {
  981. pPixelShader = m_pPixelShaders[PS14_EN01];
  982. }
  983. }
  984. if(!pPixelShader && m_caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
  985. {
  986. if(fEN[0] && fEN[1]) // RAO1 + RAO2
  987. {
  988. pPixelShader = m_pPixelShaders[PS11_EN11];
  989. }
  990. else if(fEN[0]) // RAO1
  991. {
  992. pPixelShader = m_pPixelShaders[PS11_EN10];
  993. }
  994. else if(fEN[1]) // RAO2
  995. {
  996. pPixelShader = m_pPixelShaders[PS11_EN01];
  997. }
  998. }
  999. if(!pPixelShader)
  1000. {
  1001. int stage = 0;
  1002. hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
  1003. hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_COLORARG1, D3DTA_TEXTURE);
  1004. hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
  1005. stage++;
  1006. if(fEN[0] && fEN[1]) // RAO1 + RAO2
  1007. {
  1008. if(m_rs.PMODE.ALP < 0xff)
  1009. {
  1010. hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_COLOROP, D3DTOP_LERP);
  1011. hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_COLORARG1, D3DTA_CURRENT);
  1012. hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_COLORARG2, m_rs.PMODE.SLBG ? D3DTA_CONSTANT : D3DTA_TEXTURE);
  1013. hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_COLORARG0, D3DTA_ALPHAREPLICATE|(m_rs.PMODE.MMOD ? D3DTA_CONSTANT : D3DTA_TEXTURE));
  1014. hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
  1015. hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_CONSTANT, D3DCOLOR_ARGB(m_rs.PMODE.ALP, m_rs.BGCOLOR.R, m_rs.BGCOLOR.G, m_rs.BGCOLOR.B));
  1016. stage++;
  1017. }
  1018. }
  1019. else if(fEN[0]) // RAO1
  1020. {
  1021. if(m_rs.PMODE.ALP < 0xff)
  1022. {
  1023. hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_COLOROP, D3DTOP_MODULATE);
  1024. hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_COLORARG1, D3DTA_CURRENT);
  1025. hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_COLORARG2, D3DTA_ALPHAREPLICATE|(m_rs.PMODE.MMOD ? D3DTA_CONSTANT : D3DTA_TEXTURE));
  1026. hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
  1027. hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_CONSTANT, D3DCOLOR_ARGB(m_rs.PMODE.ALP, 0, 0, 0));
  1028. stage++;
  1029. }
  1030. }
  1031. else if(fEN[1]) // RAO2
  1032. {
  1033. hr = m_pD3DDev->SetTexture(0, rt[1].pRT);
  1034. hr = m_pD3DDev->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 1);
  1035. // FIXME
  1036. hr = m_pD3DDev->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
  1037. for(int i = 0; i < countof(pVertices); i++)
  1038. {
  1039. pVertices[i].tu1 = pVertices[i].tu2;
  1040. pVertices[i].tv1 = pVertices[i].tv2;
  1041. }
  1042. }
  1043. hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_COLOROP, D3DTOP_DISABLE);
  1044. hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
  1045. }
  1046. if(pPixelShader)
  1047. {
  1048. const float c[] = 
  1049. {
  1050. (float)m_rs.BGCOLOR.B / 255, (float)m_rs.BGCOLOR.G / 255, (float)m_rs.BGCOLOR.R / 255, (float)m_rs.PMODE.ALP / 255,
  1051. (float)m_rs.PMODE.AMOD - 0.1f, (float)m_rs.IsEnabled(0), (float)m_rs.IsEnabled(1), (float)m_rs.PMODE.MMOD - 0.1f,
  1052. (float)m_de.TEXA.AEM, (float)m_de.TEXA.TA0 / 255, (float)m_de.TEXA.TA1 / 255, (float)m_rs.PMODE.SLBG - 0.1f
  1053. };
  1054. hr = m_pD3DDev->SetPixelShaderConstantF(0, c, countof(c)/4);
  1055. }
  1056. if(fEN[0] || fEN[1])
  1057. {
  1058. if(m_pTmpRenderTarget && m_pHLSLRedBlue)
  1059. {
  1060. CComPtr<IDirect3DSurface9> pSurf;
  1061. hr = m_pTmpRenderTarget->GetSurfaceLevel(0, &pSurf);
  1062. hr = m_pD3DDev->SetRenderTarget(0, pSurf);
  1063. }
  1064. else
  1065. {
  1066. hr = m_pD3DDev->SetRenderTarget(0, m_pOrgRenderTarget);
  1067. }
  1068. hr = m_pD3DDev->BeginScene();
  1069. hr = m_pD3DDev->SetPixelShader(pPixelShader);
  1070. hr = m_pD3DDev->SetFVF(D3DFVF_XYZRHW|D3DFVF_TEX2);
  1071. hr = m_pD3DDev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, pVertices, sizeof(pVertices[0]));
  1072. int w, h;
  1073. CComPtr<IDirect3DSurface9> pRTSurf;
  1074. if(m_capture.BeginFrame(w, h, &pRTSurf))
  1075. {
  1076. pVertices[0].x = pVertices[0].y = pVertices[2].x = pVertices[1].y = 0;
  1077. pVertices[1].x = pVertices[3].x = (float)w;
  1078. pVertices[2].y = pVertices[3].y = (float)h;
  1079. for(int i = 0; i < countof(pVertices); i++) {pVertices[i].x -= 0.5; pVertices[i].y -= 0.5;}
  1080. hr = m_pD3DDev->SetRenderTarget(0, pRTSurf);
  1081. hr = m_pD3DDev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, pVertices, sizeof(pVertices[0]));
  1082. m_capture.EndFrame();
  1083. }
  1084. hr = m_pD3DDev->EndScene();
  1085. if(m_pTmpRenderTarget && m_pHLSLRedBlue)
  1086. {
  1087. hr = m_pD3DDev->SetRenderTarget(0, m_pOrgRenderTarget);
  1088. hr = m_pD3DDev->SetTexture(0, m_pTmpRenderTarget);
  1089. hr = m_pD3DDev->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
  1090. hr = m_pD3DDev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
  1091. hr = m_pD3DDev->SetPixelShader(m_pHLSLRedBlue);
  1092. struct
  1093. {
  1094. float x, y, z, rhw;
  1095. float tu, tv;
  1096. }
  1097. pVertices[] =
  1098. {
  1099. {0, 0, 0.5f, 2.0f, 0, 0},
  1100. {(float)m_bd.Width, 0, 0.5f, 2.0f, 1, 0},
  1101. {0, (float)m_bd.Height, 0.5f, 2.0f, 0, 1},
  1102. {(float)m_bd.Width, (float)m_bd.Height, 0.5f, 2.0f, 1, 1},
  1103. };
  1104. hr = m_pD3DDev->BeginScene();
  1105. hr = m_pD3DDev->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1);
  1106. hr = m_pD3DDev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, pVertices, sizeof(pVertices[0]));
  1107. hr = m_pD3DDev->EndScene();
  1108. }
  1109. }
  1110. //
  1111. m_perfmon.IncCounter(GSPerfMon::c_frame);
  1112. static CString s_stats;
  1113. if(!(m_perfmon.GetFrame()&15)) 
  1114. {
  1115. s_stats = m_perfmon.ToString(m_rs.GetFPS());
  1116. // stats.Format(_T("%s - %.2f MB"), CString(stats), 1.0f*m_pD3DDev->GetAvailableTextureMem()/1024/1024);
  1117. if(m_iOSD == 1)
  1118. {
  1119. SetWindowText(m_hWnd, s_stats);
  1120. }
  1121. }
  1122. if(m_iOSD == 2)
  1123. {
  1124. CString str;
  1125. str.Format(
  1126. _T("n")
  1127. _T("SMODE2.INT=%d, SMODE2.FFMD=%d, XYOFFSET.OFY=%.2f, CSR.FIELD=%dn")
  1128. _T("[%c] DBX=%d, DBY=%d, DW=%d, DH=%d | [%c] DBX=%d, DBY=%d, DW=%d, DH=%dn"),
  1129. m_rs.SMODE2.INT, m_rs.SMODE2.FFMD, (float)m_ctxt->XYOFFSET.OFY / 16, m_pCSRr->FIELD,
  1130. fEN[0] ? 'o' : 'x', m_rs.DISPFB[0].DBX, m_rs.DISPFB[0].DBY, m_rs.DISPLAY[0].DW + 1, m_rs.DISPLAY[0].DH + 1,
  1131. fEN[1] ? 'o' : 'x', m_rs.DISPFB[1].DBX, m_rs.DISPFB[1].DBY, m_rs.DISPLAY[1].DW + 1, m_rs.DISPLAY[1].DH + 1);
  1132. str = s_stats + str;
  1133. hr = m_pD3DDev->BeginScene();
  1134. CRect r = dst;
  1135. D3DCOLOR c = D3DCOLOR_ARGB(255, 0, 255, 0);
  1136. if(m_pD3DXFont->DrawText(NULL, str, -1, &r, DT_CALCRECT|DT_LEFT|DT_WORDBREAK, c))
  1137. m_pD3DXFont->DrawText(NULL, str, -1, &r, DT_LEFT|DT_WORDBREAK, c);
  1138. hr = m_pD3DDev->EndScene();
  1139. }
  1140. /*
  1141. // this suxx
  1142. REFERENCE_TIME rtTimePerFrame = 10000000i64 / m_rs.GetFPS();
  1143. REFERENCE_TIME rtNow = 0;
  1144. hr = m_pRefClock->GetTime(&rtNow);
  1145. DWORD_PTR dwAdviseCookie = 0;
  1146. hr = m_pRefClock->AdviseTime((rtNow / rtTimePerFrame + 1) * rtTimePerFrame, 0, (HEVENT)(HANDLE)m_evVSync, &dwAdviseCookie);
  1147. if(!m_evVSync.Wait((DWORD)(rtTimePerFrame / 10000))) hr = m_pRefClock->Unadvise(dwAdviseCookie);
  1148. */
  1149. //
  1150. hr = m_pD3DDev->Present(NULL, NULL, NULL, NULL);
  1151. }
  1152. void GSState::FlushPrimInternal()
  1153. {
  1154. FlushWriteTransfer();
  1155. FlushPrim();
  1156. }