diff --git a/source/d3d8to9_device.cpp b/source/d3d8to9_device.cpp index 30e9b73..718ea7f 100644 --- a/source/d3d8to9_device.cpp +++ b/source/d3d8to9_device.cpp @@ -787,13 +787,14 @@ HRESULT STDMETHODCALLTYPE Direct3DDevice8::SetRenderState(D3DRENDERSTATETYPE Sta switch (static_cast(State)) { - case D3DRS_LINEPATTERN: case D3DRS_ZVISIBLE: - case D3DRS_EDGEANTIALIAS: - case D3DRS_PATCHSEGMENTS: return D3DERR_INVALIDCALL; + case D3DRS_PATCHSEGMENTS: + case D3DRS_LINEPATTERN: case D3DRS_SOFTWAREVERTEXPROCESSING: return D3D_OK; + case D3DRS_EDGEANTIALIAS: + return ProxyInterface->SetRenderState(D3DRS_ANTIALIASEDLINEENABLE, Value); case D3DRS_CLIPPLANEENABLE: hr = ProxyInterface->SetRenderState(State, Value); if (SUCCEEDED(hr)) @@ -821,10 +822,13 @@ HRESULT STDMETHODCALLTYPE Direct3DDevice8::GetRenderState(D3DRENDERSTATETYPE Sta switch (static_cast(State)) { - case D3DRS_LINEPATTERN: case D3DRS_ZVISIBLE: - case D3DRS_EDGEANTIALIAS: return D3DERR_INVALIDCALL; + case D3DRS_LINEPATTERN: + *pValue = 0; + return D3D_OK; + case D3DRS_EDGEANTIALIAS: + return ProxyInterface->GetRenderState(D3DRS_ANTIALIASEDLINEENABLE, pValue); case D3DRS_ZBIAS: hr = ProxyInterface->GetRenderState(D3DRS_DEPTHBIAS, pValue); *pValue = static_cast(*reinterpret_cast(pValue) * -500000.0f); @@ -1463,6 +1467,19 @@ HRESULT STDMETHODCALLTYPE Direct3DDevice8::CreateVertexShader(const DWORD *pDecl } } + // Vertex shader must minimally write all four components (xyzw) of oPos output register. (fix error X5350) + if (std::regex_search(SourceCode, std::regex(" ([a-z2-4]*) oPos\\.")) && !std::regex_search(SourceCode, std::regex(" ([a-z2-4]*) oPos,"))) + { + bool xReg = std::regex_search(SourceCode, std::regex(" ([a-z2-4]*) oPos\\.[y|z|w]*x")); + bool yReg = std::regex_search(SourceCode, std::regex(" ([a-z2-4]*) oPos\\.[x|z|w]*y")); + bool zReg = std::regex_search(SourceCode, std::regex(" ([a-z2-4]*) oPos\\.[x|y|w]*z")); + bool wReg = std::regex_search(SourceCode, std::regex(" ([a-z2-4]*) oPos\\.[x|y|z]*w")); + if (!xReg || !yReg || !zReg || !wReg) + { + SourceCode = std::regex_replace(SourceCode, std::regex(" ([a-z2-4]*) (oPos\\.[x|y|z|w]*,) ([^\\n]*)\\n"), " $1 oPos, $3 /* removed oPos swizzles */\n"); + } + } + #ifndef D3D8TO9NOLOG LOG << "> Dumping translated shader assembly:" << std::endl << std::endl << SourceCode << std::endl; #endif diff --git a/source/d3d8types.cpp b/source/d3d8types.cpp index a51293d..0966bed 100644 --- a/source/d3d8types.cpp +++ b/source/d3d8types.cpp @@ -64,7 +64,6 @@ static UINT CalcTextureSize(UINT Width, UINT Height, UINT Depth, D3DFORMAT Forma return ((Width + 3) >> 2) * ((Height + 3) >> 2) * 16; } } - void ConvertCaps(D3DCAPS9 &Input, D3DCAPS8 &Output) { CopyMemory(&Output, &Input, sizeof(Output)); @@ -82,7 +81,6 @@ void ConvertCaps(D3DCAPS9 &Input, D3DCAPS8 &Output) // D3D8 can only handle up to 256 for MaxVertexShaderConst Output.MaxVertexShaderConst = min(256, Input.MaxVertexShaderConst); } - void ConvertVolumeDesc(D3DVOLUME_DESC &Input, D3DVOLUME_DESC8 &Output) { Output.Format = Input.Format; @@ -104,14 +102,7 @@ void ConvertSurfaceDesc(D3DSURFACE_DESC &Input, D3DSURFACE_DESC8 &Output) Output.MultiSampleType = Input.MultiSampleType; Output.Width = Input.Width; Output.Height = Input.Height; - - // Check for D3DMULTISAMPLE_NONMASKABLE and change it to D3DMULTISAMPLE_NONE for best D3D8 compatibility. - if (Output.MultiSampleType == D3DMULTISAMPLE_NONMASKABLE) - { - Output.MultiSampleType = D3DMULTISAMPLE_NONE; - } } - void ConvertPresentParameters(D3DPRESENT_PARAMETERS8 &Input, D3DPRESENT_PARAMETERS &Output) { Output.BackBufferWidth = Input.BackBufferWidth; @@ -136,13 +127,19 @@ void ConvertPresentParameters(D3DPRESENT_PARAMETERS8 &Input, D3DPRESENT_PARAMETE } // D3DPRESENT_RATE_UNLIMITED is no longer supported in D3D9 - if (Output.PresentationInterval == D3DPRESENT_RATE_UNLIMITED) + if (Output.FullScreen_RefreshRateInHz == D3DPRESENT_RATE_UNLIMITED) + { + Output.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; + } + + // Windowed mode should always present immediately + if (Output.Windowed) { Output.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; } - // D3DPRESENT_INTERVAL_DEFAULT is defined as zero and is equivalent to D3DPRESENT_INTERVAL_ONE in D3D9 - if (Output.PresentationInterval == D3DPRESENT_INTERVAL_DEFAULT) + // Fulscreen mode defaults to D3DPRESENT_INTERVAL_ONE + if (!Output.Windowed && Output.PresentationInterval == D3DPRESENT_INTERVAL_DEFAULT) { Output.PresentationInterval = D3DPRESENT_INTERVAL_ONE; } @@ -150,8 +147,11 @@ void ConvertPresentParameters(D3DPRESENT_PARAMETERS8 &Input, D3DPRESENT_PARAMETE // D3DSWAPEFFECT_COPY_VSYNC is no longer supported in D3D9 if (Output.SwapEffect == D3DSWAPEFFECT_COPY_VSYNC) { - Output.PresentationInterval = D3DPRESENT_INTERVAL_ONE; Output.SwapEffect = D3DSWAPEFFECT_COPY; + if (!Output.Windowed && Output.PresentationInterval == D3DPRESENT_INTERVAL_IMMEDIATE) + { + Output.PresentationInterval = D3DPRESENT_INTERVAL_ONE; + } } } void ConvertAdapterIdentifier(D3DADAPTER_IDENTIFIER9 &Input, D3DADAPTER_IDENTIFIER8 &Output)