Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
917d6d6
dkollmann May 14, 2023
e8ff88d
dkollmann May 16, 2023
17ba9b6
Fix comments from pull request
elishacloud May 17, 2023
dbc8e10
Don't override matrix memory, just the pointer
elishacloud May 17, 2023
14632ef
Fix disable lighting and a couple typos
elishacloud May 17, 2023
de8fcbc
Set transform if not set by game
elishacloud May 17, 2023
a0ddc3d
Remove RenderData
elishacloud May 17, 2023
c715c61
Fix default settings
elishacloud May 17, 2023
d7dff14
Fixed that DdrawConvertHomogeneousToWorldUseGameCamera did not actual…
dkollmann May 17, 2023
575bd6f
Remove unneeded matrix assignment
elishacloud May 18, 2023
44d4338
Fix DdrawConvertHomogeneousToWorldUseGameCamera
elishacloud May 18, 2023
f823ec3
Move matrix override code to the end
elishacloud May 18, 2023
e79c204
Fix DdrawConvertHomogeneousToWorldUseGameCamera
elishacloud Jun 6, 2023
153287c
Merge branch 'master' into reverse_xyzrhw_new
elishacloud Jun 20, 2023
1a8607e
Fix merge conflict with main
elishacloud Jun 20, 2023
f82ae80
Minor update
elishacloud Jun 20, 2023
80b12b0
Merge branch 'master' into reverse_xyzrhw_new
elishacloud Jun 26, 2023
fac874b
Fix formatting
elishacloud Jun 26, 2023
8b54596
Fix defaults
elishacloud Jun 26, 2023
48bdfec
Merge remote-tracking branch 'origin/master' into pr/199
elishacloud Jul 13, 2023
3ee34d4
Fix PR to work with master branch changes
elishacloud Jul 13, 2023
5e3d5e4
Merge remote-tracking branch 'origin/master' into pr/199
elishacloud Jul 13, 2023
0d9bb50
Update to make it match master branch
elishacloud Jul 13, 2023
58812be
Merge remote-tracking branch 'origin/master' into pr/199
elishacloud Jul 15, 2023
f5b307d
Merge remote-tracking branch 'origin/master' into pr/199
elishacloud Aug 14, 2023
1ab9a42
Merge branch 'master' into reverse_xyzrhw_new
elishacloud Dec 2, 2023
80dfe72
Include DirectXMath
elishacloud Mar 2, 2024
11e1db3
Merge branch 'master' into reverse_xyzrhw_new
elishacloud Mar 2, 2024
5dec4b8
Merge branch 'master' into reverse_xyzrhw_new
elishacloud Apr 4, 2024
9b92264
Merge branch 'master' into reverse_xyzrhw_new
elishacloud Apr 7, 2024
bf79a6a
Merge branch 'master' into reverse_xyzrhw_new
elishacloud Aug 22, 2024
e84f19c
Merge branch 'master' into reverse_xyzrhw_new
elishacloud Sep 17, 2024
917946e
Merge branch 'master' into reverse_xyzrhw_new
elishacloud Jan 16, 2025
e4bf42c
Merge branch 'master' into reverse_xyzrhw_new
elishacloud Feb 18, 2025
1ff2bc0
Fix issue with merging master branch
elishacloud Mar 4, 2025
6fe14d6
Merge remote-tracking branch 'origin/master' into pr/199
elishacloud Mar 31, 2025
5421628
Merge branch 'master' into reverse_xyzrhw_new
elishacloud Mar 31, 2025
9864712
Fix build merge issues
elishacloud Mar 31, 2025
69e9ae3
Merge branch 'master' into reverse_xyzrhw_new
elishacloud Jun 11, 2025
7c890df
Fix build issue
elishacloud Jun 11, 2025
0c8fb96
Merge branch 'master' into reverse_xyzrhw_new
elishacloud Jul 20, 2025
0c15505
Merge branch 'master' into reverse_xyzrhw_new
elishacloud Sep 29, 2025
e34127f
Fix build issue
elishacloud Sep 29, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions Settings/Settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,16 @@
visit(DdrawOverrideStencilFormat) \
visit(DdrawResolutionHack) \
visit(DdrawUseDirect3D9Ex) \
visit(DdrawConvertHomogeneousW) \
visit(DdrawConvertHomogeneousToWorld) \
visit(DdrawConvertHomogeneousToWorldUseGameCamera) \
visit(DdrawConvertHomogeneousToWorldFOV) \
visit(DdrawConvertHomogeneousToWorldNearPlane) \
visit(DdrawConvertHomogeneousToWorldFarPlane) \
visit(DdrawConvertHomogeneousToWorldDepthOffset) \
visit(DdrawUseNativeResolution) \
visit(DdrawEnableMouseHook) \
visit(DdrawDisableLighting) \
visit(DdrawHookSystem32) \
visit(D3d8HookSystem32) \
visit(D3d9HookSystem32) \
Expand Down Expand Up @@ -209,6 +217,13 @@ 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 DdrawConvertHomogeneousToWorld = false; // Convert primitives back into a world space. Needed for RTX.
bool DdrawConvertHomogeneousToWorldUseGameCamera = false; // Use the game's view matrix instead of replacing it with our own.
float DdrawConvertHomogeneousToWorldFOV = 90.0f; // The field of view of the camera used to reconstruct the original 3D world.
float DdrawConvertHomogeneousToWorldNearPlane = 1.0f; // The near plane of the camera used to reconstruct the original 3D world.
float DdrawConvertHomogeneousToWorldFarPlane = 1000.0f; // The far plane of the camera used to reconstruct the original 3D world.
float DdrawConvertHomogeneousToWorldDepthOffset = 0.0f; // The offset to add to the geometry so it does not clip into the near plane.
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
Expand All @@ -219,6 +234,7 @@ struct CONFIG
DWORD DdrawOverrideRefreshRate = 0; // Force Direct3d9 to use this refresh rate when using Dd7to9
DWORD DdrawOverrideStencilFormat = 0; // Force Direct3d9 to use this AutoStencilFormat when using Dd7to9
bool DdrawEnableMouseHook = true; // Allow to hook into mouse to limit it to the chosen resolution
bool DdrawDisableLighting = false; // Allow to disable lighting
DWORD DdrawHookSystem32 = 0; // Hooks the ddraw.dll file in the Windows System32 folder
DWORD D3d8HookSystem32 = 0; // Hooks the d3d8.dll file in the Windows System32 folder
DWORD D3d9HookSystem32 = 0; // Hooks the d3d9.dll file in the Windows System32 folder
Expand Down
183 changes: 179 additions & 4 deletions ddraw/IDirect3DDeviceX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

#include "ddraw.h"
#include <d3dhal.h>
#include <DirectXMath.h>

// Enable for testing only
//#define ENABLE_DEBUGOVERLAY
Expand Down Expand Up @@ -338,15 +339,95 @@ HRESULT m_IDirect3DDeviceX::SetTransform(D3DTRANSFORMSTATETYPE dtstTransformStat
break;
}

HRESULT hr = (*d3d9Device)->SetTransform(dtstTransformStateType, lpD3DMatrix);

if (SUCCEEDED(hr))
_D3DMATRIX view;
if (Config.DdrawConvertHomogeneousW)
{
#ifdef ENABLE_DEBUGOVERLAY
// Set the original matrix
DOverlay.SetTransform(dtstTransformStateType, lpD3DMatrix);
#endif

if (dtstTransformStateType == D3DTS_VIEW)
{
D3DVIEWPORT9 Viewport9;
if (SUCCEEDED((*d3d9Device)->GetViewport(&Viewport9)))
{
const float width = (float)Viewport9.Width;
const float height = (float)Viewport9.Height;
const float ratio = width / height;

// Replace the matrix with one that handles D3DFVF_XYZRHW geometry
ZeroMemory(&view, sizeof(_D3DMATRIX));
view._11 = 2.0f / width;
view._22 = -2.0f / height;
view._33 = 1.0f;
view._41 = -1.0f; // translate X
view._42 = 1.0f; // translate Y
view._44 = 1.0f;

// Override original matrix pointer
lpD3DMatrix = &view;

if (Config.DdrawConvertHomogeneousToWorld)
{
DirectX::XMVECTOR position, direction;
if (Config.DdrawConvertHomogeneousToWorldUseGameCamera)
{
// To reconstruct the 3D world, we need to know where the camera is and where it is looking
position = DirectX::XMVectorSet(lpD3DMatrix->_41, lpD3DMatrix->_42, lpD3DMatrix->_43, lpD3DMatrix->_44);
direction = DirectX::XMVectorSet(lpD3DMatrix->_31, lpD3DMatrix->_32, lpD3DMatrix->_33, lpD3DMatrix->_34);
}
else
{
const float cameradir = 1.0f;

position = DirectX::XMVectorSet(0.0f, 0.0f, -cameradir, 0.0f);
direction = DirectX::XMVectorSet(0.0f, 0.0f, cameradir, 0.0f);
}

// Store the original matrix so it can be restored
std::memcpy(&RenderData.DdrawConvertHomogeneousToWorld_ViewMatrixOriginal, &view, sizeof(_D3DMATRIX));

// The Black & White matrix is an ortho camera, so create a perspective one matching the game
const float fov = Config.DdrawConvertHomogeneousToWorldFOV;
const float nearplane = Config.DdrawConvertHomogeneousToWorldNearPlane;
const float farplane = Config.DdrawConvertHomogeneousToWorldFarPlane;
DirectX::XMMATRIX proj = DirectX::XMMatrixPerspectiveFovLH(fov * (3.14159265359f / 180.0f), ratio, nearplane, farplane);

DirectX::XMStoreFloat4x4((DirectX::XMFLOAT4X4*)&RenderData.DdrawConvertHomogeneousToWorld_ProjectionMatrix, proj);

DirectX::XMVECTOR up = DirectX::XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
DirectX::XMMATRIX viewMatrix = DirectX::XMMatrixLookToLH(position, direction, up);

// Store the 3D view matrix so it can be set later
DirectX::XMStoreFloat4x4((DirectX::XMFLOAT4X4*)&RenderData.DdrawConvertHomogeneousToWorld_ViewMatrix, viewMatrix);

// Store the view inverse matrix of the game, so we can transform the geometry with it
DirectX::XMMATRIX toViewSpace = DirectX::XMLoadFloat4x4((DirectX::XMFLOAT4X4*)lpD3DMatrix);
DirectX::XMMATRIX vp = DirectX::XMMatrixMultiply(viewMatrix, proj);
DirectX::XMMATRIX vpinv = DirectX::XMMatrixInverse(nullptr, vp);

DirectX::XMMATRIX depthoffset = DirectX::XMMatrixTranslation(0.0f, 0.0f, Config.DdrawConvertHomogeneousToWorldDepthOffset);

RenderData.DdrawConvertHomogeneousToWorld_ViewMatrixInverse = DirectX::XMMatrixMultiply(depthoffset, DirectX::XMMatrixMultiply(toViewSpace, vpinv));
}
}
}
else
{
return D3D_OK;
}
}

HRESULT hr = (*d3d9Device)->SetTransform(dtstTransformStateType, lpD3DMatrix);

#ifdef ENABLE_DEBUGOVERLAY
if (SUCCEEDED(hr) && !Config.DdrawConvertHomogeneousW)
{
DOverlay.SetTransform(dtstTransformStateType, lpD3DMatrix);
}
#endif

return hr;
}

Expand Down Expand Up @@ -2050,6 +2131,12 @@ HRESULT m_IDirect3DDeviceX::SetRenderState(D3DRENDERSTATETYPE dwRenderStateType,
dwRenderStateType = D3DRS_DEPTHBIAS;
break;
}
case D3DRS_LIGHTING:
if (Config.DdrawDisableLighting)
{
dwRenderState = FALSE;
}
break;
case D3DRENDERSTATE_TEXTUREPERSPECTIVE:
return D3D_OK; // As long as the device's D3DPTEXTURECAPS_PERSPECTIVE is enabled, the correction will be applied automatically.
case D3DRENDERSTATE_LINEPATTERN:
Expand Down Expand Up @@ -2453,11 +2540,99 @@ HRESULT m_IDirect3DDeviceX::DrawIndexedPrimitive(D3DPRIMITIVETYPE dptPrimitiveTy
}
else
{
const UINT stride = GetVertexStride(dwVertexTypeDesc);

// Handle PositionT
if (Config.DdrawConvertHomogeneousW && (dwVertexTypeDesc & 0x0E) == D3DFVF_XYZRHW)
{
D3DFVF_XYZB1;
if (!Config.DdrawConvertHomogeneousToWorld)
{
/*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;
}
else
{
const UINT targetStride = stride - sizeof(float);
const UINT restSize = stride - sizeof(float) * 4;

RenderData.DdrawConvertHomogeneousToWorld_IntermediateGeometry.resize(targetStride * dwVertexCount);

UINT8 *sourceVertex = (UINT8*)lpVertices;
UINT8 *targetVertex = (UINT8*)RenderData.DdrawConvertHomogeneousToWorld_IntermediateGeometry.data();

lpVertices = targetVertex;

for (UINT x = 0; x < dwVertexCount; x++)
{
// Transform the vertices into world space
float *srcpos = (float*) sourceVertex;
float *trgtpos = (float*) targetVertex;

DirectX::XMVECTOR xpos = DirectX::XMVectorSet(srcpos[0], srcpos[1], srcpos[2], srcpos[3]);

DirectX::XMVECTOR xpos_global = DirectX::XMVector3TransformCoord(xpos, RenderData.DdrawConvertHomogeneousToWorld_ViewMatrixInverse);

xpos_global = DirectX::XMVectorDivide(xpos_global, DirectX::XMVectorSplatW(xpos_global));

trgtpos[0] = DirectX::XMVectorGetX(xpos_global);
trgtpos[1] = DirectX::XMVectorGetY(xpos_global);
trgtpos[2] = DirectX::XMVectorGetZ(xpos_global);

// Copy the rest
std::memcpy(targetVertex + sizeof(float) * 3, sourceVertex + sizeof(float) * 4, restSize);

// Move to next vertex
sourceVertex += stride;
targetVertex += targetStride;
}

// Set transform
(*d3d9Device)->SetTransform(D3DTS_VIEW, &RenderData.DdrawConvertHomogeneousToWorld_ViewMatrix);
(*d3d9Device)->SetTransform(D3DTS_PROJECTION, &RenderData.DdrawConvertHomogeneousToWorld_ProjectionMatrix);

// Update the FVF
const DWORD newVertexTypeDesc = (dwVertexTypeDesc & ~D3DFVF_XYZRHW) | D3DFVF_XYZ;

// Set fixed function vertex type
(*d3d9Device)->SetFVF(newVertexTypeDesc);

// Draw indexed primitive UP
hr = (*d3d9Device)->DrawIndexedPrimitiveUP(dptPrimitiveType, 0, dwVertexCount, GetNumberOfPrimitives(dptPrimitiveType, dwIndexCount), lpIndices, D3DFMT_INDEX16, lpVertices, targetStride);

// Restore transform
_D3DMATRIX identityMatrix;
ZeroMemory(&identityMatrix, sizeof(_D3DMATRIX));
identityMatrix._11 = 1.0f;
identityMatrix._22 = 1.0f;
identityMatrix._33 = 1.0f;

(*d3d9Device)->SetTransform(D3DTS_VIEW, &RenderData.DdrawConvertHomogeneousToWorld_ViewMatrixOriginal);
(*d3d9Device)->SetTransform(D3DTS_PROJECTION, &identityMatrix);

// Handle dwFlags
UnSetDrawFlags(rsClipping, rsLighting, rsExtents, newVertexTypeDesc, dwFlags, DirectXVersion);

return hr;
}
}

// Set fixed function vertex type
(*d3d9Device)->SetFVF(dwVertexTypeDesc);

// Draw indexed primitive UP
hr = (*d3d9Device)->DrawIndexedPrimitiveUP(dptPrimitiveType, 0, dwVertexCount, GetNumberOfPrimitives(dptPrimitiveType, dwIndexCount), lpIndices, D3DFMT_INDEX16, lpVertices, GetVertexStride(dwVertexTypeDesc));
hr = (*d3d9Device)->DrawIndexedPrimitiveUP(dptPrimitiveType, 0, dwVertexCount, GetNumberOfPrimitives(dptPrimitiveType, dwIndexCount), lpIndices, D3DFMT_INDEX16, lpVertices, stride);
}

// Handle dwFlags
Expand Down
4 changes: 4 additions & 0 deletions ddraw/IDirect3DDeviceX.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include "IDirectDrawX.h"
#include "RenderData.h"

class m_IDirect3DDeviceX : public IUnknown, public AddressLookupTableDdrawObject
{
Expand All @@ -27,6 +28,9 @@ class m_IDirect3DDeviceX : public IUnknown, public AddressLookupTableDdrawObject
// SetTexture array
LPDIRECTDRAWSURFACE7 AttachedTexture[8] = {};

// The data used for rendering
RenderData RenderData;

// Wrapper interface functions
inline REFIID GetWrapperType(DWORD DirectXVersion)
{
Expand Down
37 changes: 37 additions & 0 deletions ddraw/RenderData.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#pragma once

#include <d3d9types.h>
#include <DirectXMath.h>
#include <vector>

class RenderData
{
public:

// Store the projection matrix used to transform the geometry on the gpu
_D3DMATRIX DdrawConvertHomogeneousToWorld_ProjectionMatrix;

// Store the view matrix used to transform the geometry on the gpu
_D3DMATRIX DdrawConvertHomogeneousToWorld_ViewMatrix;

// Store the original view matrix, so we can restore it
_D3DMATRIX DdrawConvertHomogeneousToWorld_ViewMatrixOriginal;

// Store the inverse view matrix to transform the geometry on the cpu
DirectX::XMMATRIX DdrawConvertHomogeneousToWorld_ViewMatrixInverse;

// Intermediate buffer for the geometry conversion
std::vector<uint8_t> DdrawConvertHomogeneousToWorld_IntermediateGeometry;

RenderData()
{
ZeroMemory(&DdrawConvertHomogeneousToWorld_ViewMatrix, sizeof(_D3DMATRIX));
DdrawConvertHomogeneousToWorld_ViewMatrix._11 = 1.0f;
DdrawConvertHomogeneousToWorld_ViewMatrix._22 = 1.0f;
DdrawConvertHomogeneousToWorld_ViewMatrix._33 = 1.0f;
DdrawConvertHomogeneousToWorld_ViewMatrix._44 = 1.0f;

std::memcpy(&DdrawConvertHomogeneousToWorld_ProjectionMatrix, &DdrawConvertHomogeneousToWorld_ViewMatrix, sizeof(_D3DMATRIX));
std::memcpy(&DdrawConvertHomogeneousToWorld_ViewMatrixOriginal, &DdrawConvertHomogeneousToWorld_ViewMatrix, sizeof(_D3DMATRIX));
}
};
1 change: 1 addition & 0 deletions dxwrapper.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,7 @@ cmd /q /c "cd /D ""$(ProjectDir)d3d8\"" &amp;&amp; del build.bat"</Command>
<ClInclude Include="ddraw\IDirectDrawGammaControl.h" />
<ClInclude Include="ddraw\IDirectDrawPalette.h" />
<ClInclude Include="ddraw\IDirectDrawX.h" />
<ClInclude Include="ddraw\RenderData.h" />
<ClInclude Include="ddraw\Versions\IDirect3D.h" />
<ClInclude Include="ddraw\Versions\IDirect3D2.h" />
<ClInclude Include="ddraw\Versions\IDirect3D3.h" />
Expand Down
5 changes: 4 additions & 1 deletion dxwrapper.vcxproj.filters
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="DDrawCompat">
Expand Down Expand Up @@ -1868,6 +1868,9 @@
<ClInclude Include="ddraw\DebugOverlay.h">
<Filter>ddraw</Filter>
</ClInclude>
<ClInclude Include="ddraw\RenderData.h">
<Filter>ddraw</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Dllmain\BuildNo.rc">
Expand Down