Closed elishacloud closed 7 years ago
Nice work! As for the zbias to depthbias mapping - I choose the same mapping a few years ago - see https://github.com/PatrickvL/Dxbx/blob/master/Source/Delphi/src/DxbxKrnl/EmuD3D8/uConvert.pas#L436 this might contain other mappings that could be useful for this project (although to be honest, these weren't tested thoroughly, so I'm not 100% sure those mappings in there are entirely correct, but at least it's a reference that can be looked at, right?)
Yes, changing D3DRS_ZBIAS
to D3DRS_DEPTHBIAS
may not be a perfect change. However if you look at Direct3DDevice8::GetRenderState
it appears that this is what d3d8to9 is expecting. There are other ways of handling this also. Take a look at the comments here and here.
It seems that the Boris/ENBSeries converter does something similar to what d3d8to9 does. Here is what ENBSeries does:
case D3DRS_ZBIAS:
Biased = static_cast<FLOAT>(Value) * -0.0f;
Value = *reinterpret_cast<const DWORD *>(&Biased);
State = D3DRS_DEPTHBIAS;
SetRenderState(State, Value);
break;
Whereas d3d8to9 does this:
case D3DRS_ZBIAS:
Biased = static_cast<FLOAT>(Value) * -0.000005f;
Value = *reinterpret_cast<const DWORD *>(&Biased);
State = D3DRS_DEPTHBIAS;
SetRenderState(State, Value);
break;
I am not quite sure which one is better. All five games I tested showed the same results no matter which one of these methods I used. So I took the simplest path.
As far as the fix for CreateVertexShader
, I did notice that d3d8to9 will initialize all three registers: 'oD', 'oT' and 'r'. However the ENBSeries only initializes the 'oT' registers. I did not see a need to initialize the 'oD' and 'r' registers but I left them there as it seemed to work. Though I wonder if initializing these other two registers are really needed.
There was a game (the first Max Payne I think) that would only write to certain components of some registers, leaving the rest uninitialized. Passing that code to the D3DX assembler would fail with an error, which is why the initialization happens. I don't know if this works even if c0
is not declared, since it's a constant either way. But it probably will, so I guess it's OK.
I tested both Max Payne and Max Payne 2.
Max Payne fails both with and without this change and never calls CreateVertexShader
. Something weird is happening with Max Payne because it appears that all APIs are already hooked and it won't launch if I try to attach a debugger to it or run it with PIX. I cannot get Max Payne to work with d3d8to9 even with older versions of d3d8to9.
Max Payne 2 seems to run fine with d3d8to9 with this change.
Let me know if there is some other issue with this change. It seems to work fine on all the games I have tested.
Alright. Looks good then.
CreateVertexShader
to fix missing textures in some games such as Hitman 2 Silent Assassin and Indiana Jones and the Emperor's Tomb.CopyRects
,CreateVertexShader
,GetVertexShaderDeclaration
andCreatePixelShader
. RemovedE_FAIL
andE_NOTIMPL
and replaced them withD3DERR_INVALIDCALL
. These Direct3D APIs don't listE_FAIL
andE_NOTIMPL
as supported return values in the Microsoft documentation.SetRenderState
to call the correctD3DRENDERSTATETYPE
whenD3DRS_ZBIAS
is used.