diff --git a/Settings/Settings.h b/Settings/Settings.h index 0ef68a40..cc1b1cdf 100644 --- a/Settings/Settings.h +++ b/Settings/Settings.h @@ -43,6 +43,7 @@ visit(DdrawOverrideStencilFormat) \ visit(DdrawResolutionHack) \ visit(DdrawUseDirect3D9Ex) \ + visit(DdrawConvertHomogeneousW) \ visit(DdrawUseNativeResolution) \ visit(DdrawEnableMouseHook) \ visit(DdrawHookSystem32) \ @@ -209,6 +210,7 @@ struct CONFIG bool DdrawIntegerScalingClamp = false; // Scales the screen by an integer value to help preserve video quality bool DdrawMaintainAspectRatio = false; // Keeps the current DirectDraw aspect ratio when overriding the game's resolution bool DdrawUseDirect3D9Ex = false; // Use Direct3D9Ex extensions for Dd7to9 + bool DdrawConvertHomogeneousW = false; // Convert primites using D3DFVF_XYZRHW to D3DFVF_XYZW. bool DdrawUseNativeResolution = false; // Uses the current screen resolution for Dd7to9 DWORD DdrawClippedWidth = 0; // Used to scaled Direct3d9 to use this width when using Dd7to9 DWORD DdrawClippedHeight = 0; // Used to scaled Direct3d9 to use this height when using Dd7to9 diff --git a/ddraw/IDirect3DDeviceX.cpp b/ddraw/IDirect3DDeviceX.cpp index e8fb8ffb..b8c24671 100644 --- a/ddraw/IDirect3DDeviceX.cpp +++ b/ddraw/IDirect3DDeviceX.cpp @@ -338,6 +338,28 @@ HRESULT m_IDirect3DDeviceX::SetTransform(D3DTRANSFORMSTATETYPE dtstTransformStat break; } + if (Config.DdrawConvertHomogeneousW) + { + if (dtstTransformStateType == D3DTS_VIEW) + { + D3DVIEWPORT9 Viewport9; + if (SUCCEEDED((*d3d9Device)->GetViewport(&Viewport9))) + { + ZeroMemory(lpD3DMatrix, sizeof(_D3DMATRIX)); + lpD3DMatrix->_11 = 2.0f / (float)Viewport9.Width; + lpD3DMatrix->_22 = -2.0f / (float)Viewport9.Height; + lpD3DMatrix->_33 = 1.0f; + lpD3DMatrix->_41 = -1.0f; // translate X + lpD3DMatrix->_42 = 1.0f; // translate Y + lpD3DMatrix->_44 = 1.0f; + } + } + else + { + return D3D_OK; + } + } + HRESULT hr = (*d3d9Device)->SetTransform(dtstTransformStateType, lpD3DMatrix); if (SUCCEEDED(hr)) @@ -1943,6 +1965,28 @@ HRESULT m_IDirect3DDeviceX::SetRenderState(D3DRENDERSTATETYPE dwRenderStateType, if (Config.Dd7to9) { + if(Config.DdrawConvertHomogeneousW) + { + // ReSharper disable once CppIncompleteSwitchStatement + switch(dwRenderStateType) + { + case D3DRS_CULLMODE: + //dwRenderState = D3DCULL_NONE; + break; + + case D3DRS_LIGHTING: + dwRenderState = FALSE; + break; + + case D3DRS_CLIPPLANEENABLE: + //dwRenderState = 0; + break; + + default: + break; + } + } + // Check for device interface if (FAILED(CheckInterface(__FUNCTION__, true))) { @@ -2352,6 +2396,26 @@ HRESULT m_IDirect3DDeviceX::DrawIndexedPrimitive(D3DPRIMITIVETYPE dptPrimitiveTy } else { + const UINT stride = GetVertexStride(dwVertexTypeDesc); + + // Handle PositionT + if((dwVertexTypeDesc & D3DFVF_XYZRHW) != 0 && Config.DdrawConvertHomogeneousW) + { + UINT8 *vertex = (UINT8*)lpVertices; + + for (UINT x = 0; x < dwVertexCount; x++) + { + float *pos = (float*) vertex; + + pos[3] = 1.0f; + + vertex += stride; + } + + // Update the FVF + dwVertexTypeDesc = (dwVertexTypeDesc & ~D3DFVF_XYZRHW) | D3DFVF_XYZW; + } + // Set fixed function vertex type (*d3d9Device)->SetFVF(dwVertexTypeDesc);