From ed559e5fd63e91094b2bf1724d13f41229a72f3f Mon Sep 17 00:00:00 2001 From: Luke Usher Date: Wed, 3 Apr 2019 11:47:32 +0100 Subject: [PATCH 01/12] Cleanup XbState code: Preparing for bug fixes/improvements --- src/core/hle/D3D8/XbConvert.h | 6 +- src/core/hle/D3D8/XbD3D8Types.h | 8 + src/core/hle/D3D8/XbState.cpp | 627 ++++++++++++++++---------------- 3 files changed, 315 insertions(+), 326 deletions(-) diff --git a/src/core/hle/D3D8/XbConvert.h b/src/core/hle/D3D8/XbConvert.h index bcadab69d..47913a73c 100644 --- a/src/core/hle/D3D8/XbConvert.h +++ b/src/core/hle/D3D8/XbConvert.h @@ -156,10 +156,8 @@ inline D3DBLEND EmuXB2PC_D3DBLEND(X_D3DBLEND Value) case 0x306: return D3DBLEND_DESTCOLOR; case 0x307: return D3DBLEND_INVDESTCOLOR; case 0x308: return D3DBLEND_SRCALPHASAT; - // Unsupported (on host) Xbox Extensions - // TODO: Find a way to implement these: Xbox sets a constant blend colour using D3DRS_BLENDCOLOR - case 0x8001: EmuLogEx(LOG_PREFIX_D3DCVT, LOG_LEVEL::WARNING, "Unsupported Xbox D3DBlend Extension: D3DBLEND_CONSTANTCOLOR"); return D3DBLEND_ONE; - case 0x8002: EmuLogEx(LOG_PREFIX_D3DCVT, LOG_LEVEL::WARNING, "Unsupported Xbox D3DBlend Extension: D3DBLEND_INVCONSTANTCOLOR "); return D3DBLEND_ONE; + case 0x8001:return D3DBLEND_BLENDFACTOR; + case 0x8002:return D3DBLEND_INVBLENDFACTOR; case 0x8003: EmuLogEx(LOG_PREFIX_D3DCVT, LOG_LEVEL::WARNING, "Unsupported Xbox D3DBlend Extension: D3DBLEND_CONSTANTALPHA"); return D3DBLEND_ONE; case 0x8004: EmuLogEx(LOG_PREFIX_D3DCVT, LOG_LEVEL::WARNING, "Unsupported Xbox D3DBlend Extension: D3DBLEND_INVCONSTANTALPHA"); return D3DBLEND_ONE; } diff --git a/src/core/hle/D3D8/XbD3D8Types.h b/src/core/hle/D3D8/XbD3D8Types.h index fa39911c9..4abc57430 100644 --- a/src/core/hle/D3D8/XbD3D8Types.h +++ b/src/core/hle/D3D8/XbD3D8Types.h @@ -1041,6 +1041,14 @@ constexpr DWORD X_D3DTADDRESS_CLAMP = 3; constexpr DWORD X_D3DTADDRESS_BORDER = 4; constexpr DWORD X_D3DTADDRESS_CLAMPTOEDGE = 5; +// X_D3DTEXTUREFILTERTYPE Values +constexpr DWORD X_D3DTEXF_NONE = 0; +constexpr DWORD X_D3DTEXF_POINT = 1; +constexpr DWORD X_D3DTEXF_LINEAR = 2; +constexpr DWORD X_D3DTEXF_ANISOTROPIC = 3; +constexpr DWORD X_D3DTEXF_QUINCUNX = 4; // Xbox extension +constexpr DWORD X_D3DTEXF_GAUSSIANCUBIC = 5; + // X_D3DCLEAR values : constexpr DWORD X_D3DCLEAR_ZBUFFER = 0x00000001; constexpr DWORD X_D3DCLEAR_STENCIL = 0x00000002; diff --git a/src/core/hle/D3D8/XbState.cpp b/src/core/hle/D3D8/XbState.cpp index 500c9ac0d..e8386d051 100644 --- a/src/core/hle/D3D8/XbState.cpp +++ b/src/core/hle/D3D8/XbState.cpp @@ -38,346 +38,329 @@ extern uint32_t g_BuildVersion; #include "core\hle\Intercept.hpp" // For g_SymbolAddresses -// ****************************************************************** -// * patch: UpdateDeferredStates -// ****************************************************************** -void XTL::EmuUpdateDeferredStates() +void VerifyAndFixEmuDeferredRenderStateOffset() { - using namespace XTL; - - // Verify that EmuD3DDeferredRenderState is correct, if not, we can programatically correct it - // We should also flag up a warning so this can be fixed upstream in XboxSymbolDatabase! - // This is made possible by the registration of D3DRS_CULLMODE by XboxSymbolDatabase - static bool verifiedRenderStateOffset = false; - if (!verifiedRenderStateOffset) { - DWORD CullModeOffset = g_SymbolAddresses["D3DRS_CULLMODE"]; - - // If we found a valid CullMode offset, verify the symbol location - if (CullModeOffset != 0) { - // Calculate index of D3DRS_CULLMODE for this XDK. We start counting from the first deferred state (D3DRS_FOGENABLE) - DWORD CullModeIndex = 0; - for (int i = X_D3DRS_FOGENABLE; i < X_D3DRS_CULLMODE; i++) { - if (DxbxRenderStateInfo[i].V <= g_BuildVersion) { - CullModeIndex++; - } - } - - // If the offset was incorrect, calculate the correct offset, log it, and fix it - if ((DWORD)(&EmuD3DDeferredRenderState[CullModeIndex]) != CullModeOffset) { - DWORD CorrectOffset = CullModeOffset - (CullModeIndex * sizeof(DWORD)); - EmuLog(LOG_LEVEL::WARNING, "EmuD3DDeferredRenderState returned by XboxSymbolDatabase (0x%08X) was incorrect. Correcting to be 0x%08X.\nPlease file an issue with the XbSymbolDatabase project", EmuD3DDeferredRenderState, CorrectOffset); - EmuD3DDeferredRenderState = (DWORD*)CorrectOffset; - } - } else { - EmuLog(LOG_LEVEL::WARNING, "D3DRS_CULLMODE could not be found. Please update the XbSymbolDatabase submodule"); - } - - verifiedRenderStateOffset = true; - } - - // Certain D3DRS values need to be checked on each Draw[Indexed]Vertices - if(EmuD3DDeferredRenderState != 0) - { - // Loop through all deferred render states - for (unsigned int RenderState = X_D3DRS_FOGENABLE; RenderState <= X_D3DRS_PATCHSEGMENTS; RenderState++) { - // If this render state does not have a PC counterpart, skip it - if (DxbxRenderStateInfo[RenderState].PC == 0) { - continue; - } - - uint8_t index = RenderState - X_D3DRS_FOGENABLE; - // Some render states require special handling to convert to host, but most can be mapped 1:1 - // We use a switch/case to handle the special states - switch (RenderState) { - case X_D3DRS_WRAP0: { - ::DWORD dwConv = 0; - - dwConv |= (XTL::EmuD3DDeferredRenderState[index] & 0x00000010) ? D3DWRAP_U : 0; - dwConv |= (XTL::EmuD3DDeferredRenderState[index] & 0x00001000) ? D3DWRAP_V : 0; - dwConv |= (XTL::EmuD3DDeferredRenderState[index] & 0x00100000) ? D3DWRAP_W : 0; - - g_pD3DDevice->SetRenderState(D3DRS_WRAP0, dwConv); - } break; - case X_D3DRS_WRAP1: { - ::DWORD dwConv = 0; - - dwConv |= (XTL::EmuD3DDeferredRenderState[index] & 0x00000010) ? D3DWRAP_U : 0; - dwConv |= (XTL::EmuD3DDeferredRenderState[index] & 0x00001000) ? D3DWRAP_V : 0; - dwConv |= (XTL::EmuD3DDeferredRenderState[index] & 0x00100000) ? D3DWRAP_W : 0; - - g_pD3DDevice->SetRenderState(D3DRS_WRAP1, dwConv); - } break; - default: - g_pD3DDevice->SetRenderState(DxbxRenderStateInfo[RenderState].PC, EmuD3DDeferredRenderState[index]); - break; - } - } + // Verify that EmuD3DDeferredRenderState is correct, if not, we can programatically correct it + // We should also flag up a warning so this can be fixed upstream in XboxSymbolDatabase! + // This is made possible by the registration of D3DRS_CULLMODE by XboxSymbolDatabase + static bool verifiedRenderStateOffset = false; + if (verifiedRenderStateOffset) { + return; } - // For below XDK 3948, the actual D3DTSS flags have different values. - int Adjust1 = (g_BuildVersion <= 3948) ? 12 : 0; - int Adjust2 = (g_BuildVersion <= 3948) ? 10 : 0; + verifiedRenderStateOffset = true; - // Certain D3DTS values need to be checked on each Draw[Indexed]Vertices - if(EmuD3DDeferredTextureState != 0) - { - for(int v=0;v<4;v++) - { - ::DWORD *pCur = &EmuD3DDeferredTextureState[v*32]; + DWORD CullModeOffset = g_SymbolAddresses["D3DRS_CULLMODE"]; - if(pCur[0+Adjust2] != X_D3DTSS_UNK) - { - if(pCur[0+Adjust2] == 5) - EmuLog(LOG_LEVEL::WARNING, "ClampToEdge is unsupported (temporarily)"); - else - g_pD3DDevice->SetSamplerState(v, D3DSAMP_ADDRESSU, pCur[0 + Adjust2]); + // If we found a valid CullMode offset, verify the symbol location + if (CullModeOffset == 0) { + EmuLog(LOG_LEVEL::WARNING, "D3DRS_CULLMODE could not be found. Please update the XbSymbolDatabase submodule"); + return; + } + + // Calculate index of D3DRS_CULLMODE for this XDK. We start counting from the first deferred state (D3DRS_FOGENABLE) + DWORD CullModeIndex = 0; + for (int i = XTL::X_D3DRS_FOGENABLE; i < XTL::X_D3DRS_CULLMODE; i++) { + if (XTL::DxbxRenderStateInfo[i].V <= g_BuildVersion) { + CullModeIndex++; + } + } + + // If the offset was incorrect, calculate the correct offset, log it, and fix it + if ((DWORD)(&XTL::EmuD3DDeferredRenderState[CullModeIndex]) != CullModeOffset) { + DWORD CorrectOffset = CullModeOffset - (CullModeIndex * sizeof(DWORD)); + EmuLog(LOG_LEVEL::WARNING, "EmuD3DDeferredRenderState returned by XboxSymbolDatabase (0x%08X) was incorrect. Correcting to be 0x%08X.\nPlease file an issue with the XbSymbolDatabase project", XTL::EmuD3DDeferredRenderState, CorrectOffset); + XTL::EmuD3DDeferredRenderState = (DWORD*)CorrectOffset; + } +} + +void UpdateDeferredRenderStates() +{ + // Certain D3DRS values need to be checked on each Draw[Indexed]Vertices + if (XTL::EmuD3DDeferredRenderState != 0) { + // Loop through all deferred render states + for (unsigned int RenderState = XTL::X_D3DRS_FOGENABLE; RenderState <= XTL::X_D3DRS_PATCHSEGMENTS; RenderState++) { + // If this render state does not have a PC counterpart, skip it + if (XTL::DxbxRenderStateInfo[RenderState].PC == 0) { + continue; } - if(pCur[1+Adjust2] != X_D3DTSS_UNK) - { - if(pCur[1+Adjust2] == 5) - EmuLog(LOG_LEVEL::WARNING, "ClampToEdge is unsupported (temporarily)"); - else - g_pD3DDevice->SetSamplerState(v, D3DSAMP_ADDRESSV, pCur[1 + Adjust2]); + uint8_t index = RenderState - XTL::X_D3DRS_FOGENABLE; + // Some render states require special handling to convert to host, but most can be mapped 1:1 + // We use a switch/case to handle the special states + switch (RenderState) { + case XTL::X_D3DRS_WRAP0: { + ::DWORD dwConv = 0; + + dwConv |= (XTL::EmuD3DDeferredRenderState[index] & 0x00000010) ? D3DWRAP_U : 0; + dwConv |= (XTL::EmuD3DDeferredRenderState[index] & 0x00001000) ? D3DWRAP_V : 0; + dwConv |= (XTL::EmuD3DDeferredRenderState[index] & 0x00100000) ? D3DWRAP_W : 0; + + g_pD3DDevice->SetRenderState(XTL::D3DRS_WRAP0, dwConv); + } break; + case XTL::X_D3DRS_WRAP1: { + ::DWORD dwConv = 0; + + dwConv |= (XTL::EmuD3DDeferredRenderState[index] & 0x00000010) ? D3DWRAP_U : 0; + dwConv |= (XTL::EmuD3DDeferredRenderState[index] & 0x00001000) ? D3DWRAP_V : 0; + dwConv |= (XTL::EmuD3DDeferredRenderState[index] & 0x00100000) ? D3DWRAP_W : 0; + + g_pD3DDevice->SetRenderState(XTL::D3DRS_WRAP1, dwConv); + } break; + default: + g_pD3DDevice->SetRenderState(XTL::DxbxRenderStateInfo[RenderState].PC, XTL::EmuD3DDeferredRenderState[index]); + break; } + } + } +} - if(pCur[2+Adjust2] != X_D3DTSS_UNK) - { - if(pCur[2+Adjust2] == 5) - EmuLog(LOG_LEVEL::WARNING, "ClampToEdge is unsupported (temporarily)"); - else - g_pD3DDevice->SetSamplerState(v, D3DSAMP_ADDRESSW, pCur[2 + Adjust2]); - } - - if(pCur[3+Adjust2] != X_D3DTSS_UNK) - { - if(pCur[3+Adjust2] == 4) - EmuLog(LOG_LEVEL::WARNING, "QuinCunx is unsupported (temporarily)"); - else - g_pD3DDevice->SetSamplerState(v, D3DSAMP_MAGFILTER, pCur[3 + Adjust2]); - } - - if(pCur[4+Adjust2] != X_D3DTSS_UNK) - { - if(pCur[4+Adjust2] == 4) - EmuLog(LOG_LEVEL::WARNING, "QuinCunx is unsupported (temporarily)"); - else - g_pD3DDevice->SetSamplerState(v, D3DSAMP_MINFILTER, pCur[4 + Adjust2]); - } - - if(pCur[5+Adjust2] != X_D3DTSS_UNK) - { - if(pCur[5+Adjust2] == 4) - EmuLog(LOG_LEVEL::WARNING, "QuinCunx is unsupported (temporarily)"); - else - g_pD3DDevice->SetSamplerState(v, D3DSAMP_MIPFILTER, pCur[5 + Adjust2]); - } - - if(pCur[6+Adjust2] != X_D3DTSS_UNK) - g_pD3DDevice->SetSamplerState(v, D3DSAMP_MIPMAPLODBIAS, pCur[6 + Adjust2]); - - if(pCur[7+Adjust2] != X_D3DTSS_UNK) - g_pD3DDevice->SetSamplerState(v, D3DSAMP_MAXMIPLEVEL, pCur[7 + Adjust2]); - - if(pCur[8+Adjust2] != X_D3DTSS_UNK) - g_pD3DDevice->SetSamplerState(v, D3DSAMP_MAXANISOTROPY, pCur[8 + Adjust2]); - - if(pCur[12-Adjust1] != X_D3DTSS_UNK) - { - // TODO: This would be better split into it's own function, or a lookup array - switch (pCur[12 - Adjust1]) - { - case X_D3DTOP_DISABLE: - g_pD3DDevice->SetTextureStageState(v, D3DTSS_COLOROP, D3DTOP_DISABLE); - break; - case X_D3DTOP_SELECTARG1: - g_pD3DDevice->SetTextureStageState(v, D3DTSS_COLOROP, D3DTOP_SELECTARG1); - break; - case X_D3DTOP_SELECTARG2: - g_pD3DDevice->SetTextureStageState(v, D3DTSS_COLOROP, D3DTOP_SELECTARG2); - break; - case X_D3DTOP_MODULATE: - g_pD3DDevice->SetTextureStageState(v, D3DTSS_COLOROP, D3DTOP_MODULATE); - break; - case X_D3DTOP_MODULATE2X: - g_pD3DDevice->SetTextureStageState(v, D3DTSS_COLOROP, D3DTOP_MODULATE2X); - break; - case X_D3DTOP_MODULATE4X: - g_pD3DDevice->SetTextureStageState(v, D3DTSS_COLOROP, D3DTOP_MODULATE4X); - break; - case X_D3DTOP_ADD: - g_pD3DDevice->SetTextureStageState(v, D3DTSS_COLOROP, D3DTOP_ADD); - break; - case X_D3DTOP_ADDSIGNED: - g_pD3DDevice->SetTextureStageState(v, D3DTSS_COLOROP, D3DTOP_ADDSIGNED); - break; - case X_D3DTOP_ADDSIGNED2X: - g_pD3DDevice->SetTextureStageState(v, D3DTSS_COLOROP, D3DTOP_ADDSIGNED2X); - break; - case X_D3DTOP_SUBTRACT: - g_pD3DDevice->SetTextureStageState(v, D3DTSS_COLOROP, D3DTOP_SUBTRACT); - break; - case X_D3DTOP_ADDSMOOTH: - g_pD3DDevice->SetTextureStageState(v, D3DTSS_COLOROP, D3DTOP_ADDSMOOTH); - break; - case X_D3DTOP_BLENDDIFFUSEALPHA: - g_pD3DDevice->SetTextureStageState(v, D3DTSS_COLOROP, D3DTOP_BLENDDIFFUSEALPHA); - break; - case X_D3DTOP_BLENDCURRENTALPHA: - g_pD3DDevice->SetTextureStageState(v, D3DTSS_COLOROP, D3DTOP_BLENDCURRENTALPHA); - break; - case X_D3DTOP_BLENDTEXTUREALPHA: - g_pD3DDevice->SetTextureStageState(v, D3DTSS_COLOROP, D3DTOP_BLENDTEXTUREALPHA); - break; - case X_D3DTOP_BLENDFACTORALPHA: - g_pD3DDevice->SetTextureStageState(v, D3DTSS_COLOROP, D3DTOP_BLENDFACTORALPHA); - break; - case X_D3DTOP_BLENDTEXTUREALPHAPM: - g_pD3DDevice->SetTextureStageState(v, D3DTSS_COLOROP, D3DTOP_BLENDTEXTUREALPHAPM); - break; - case X_D3DTOP_PREMODULATE: - g_pD3DDevice->SetTextureStageState(v, D3DTSS_COLOROP, D3DTOP_PREMODULATE); - break; - case X_D3DTOP_MODULATEALPHA_ADDCOLOR: - g_pD3DDevice->SetTextureStageState(v, D3DTSS_COLOROP, D3DTOP_MODULATEALPHA_ADDCOLOR); - break; - case X_D3DTOP_MODULATECOLOR_ADDALPHA: - g_pD3DDevice->SetTextureStageState(v, D3DTSS_COLOROP, D3DTOP_MODULATECOLOR_ADDALPHA); - break; - case X_D3DTOP_MODULATEINVALPHA_ADDCOLOR: - g_pD3DDevice->SetTextureStageState(v, D3DTSS_COLOROP, D3DTOP_MODULATEINVALPHA_ADDCOLOR); - break; - case X_D3DTOP_MODULATEINVCOLOR_ADDALPHA: - g_pD3DDevice->SetTextureStageState(v, D3DTSS_COLOROP, D3DTOP_MODULATEINVCOLOR_ADDALPHA); - break; - case X_D3DTOP_DOTPRODUCT3: - g_pD3DDevice->SetTextureStageState(v, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3); - break; - case X_D3DTOP_MULTIPLYADD: - g_pD3DDevice->SetTextureStageState(v, D3DTSS_COLOROP, D3DTOP_MULTIPLYADD); - break; - case X_D3DTOP_LERP: - g_pD3DDevice->SetTextureStageState(v, D3DTSS_COLOROP, D3DTOP_LERP); - break; - case X_D3DTOP_BUMPENVMAP: - g_pD3DDevice->SetTextureStageState(v, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP); - break; - case X_D3DTOP_BUMPENVMAPLUMINANCE: - g_pD3DDevice->SetTextureStageState(v, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE); - break; - default: - EmuLog(LOG_LEVEL::WARNING, "(Temporarily) Unsupported D3DTSS_COLOROP Value (%d)", pCur[12 - Adjust1]); - break; - } - } - - if(pCur[13-Adjust1] != X_D3DTSS_UNK) - g_pD3DDevice->SetTextureStageState(v, D3DTSS_COLORARG0, pCur[13-Adjust1]); - - if(pCur[14-Adjust1] != X_D3DTSS_UNK) - g_pD3DDevice->SetTextureStageState(v, D3DTSS_COLORARG1, pCur[14-Adjust1]); - - if(pCur[15-Adjust1] != X_D3DTSS_UNK) - g_pD3DDevice->SetTextureStageState(v, D3DTSS_COLORARG2, pCur[15-Adjust1]); - - // TODO: Use a lookup table, this is not always a 1:1 map (same as D3DTSS_COLOROP) - if(pCur[16-Adjust1] != X_D3DTSS_UNK) - { - if(pCur[16-Adjust1] > 12 && pCur[16-Adjust1] != 14 && pCur[16-Adjust1] != 13) - EmuLog(LOG_LEVEL::WARNING, "(Temporarily) Unsupported D3DTSS_ALPHAOP Value (%d)", pCur[16-Adjust1]); - else - if( pCur[16-Adjust1] == 14 ) - g_pD3DDevice->SetTextureStageState(v, D3DTSS_ALPHAOP, D3DTOP_BLENDTEXTUREALPHA); - if( pCur[16-Adjust1] == 15 ) - g_pD3DDevice->SetTextureStageState(v, D3DTSS_ALPHAOP, D3DTOP_BLENDFACTORALPHA); - if( pCur[16-Adjust1] == 13 ) - g_pD3DDevice->SetTextureStageState(v, D3DTSS_ALPHAOP, D3DTOP_BLENDCURRENTALPHA); - else - g_pD3DDevice->SetTextureStageState(v, D3DTSS_ALPHAOP, pCur[16-Adjust1]); - } - - if(pCur[17-Adjust1] != X_D3DTSS_UNK) - g_pD3DDevice->SetTextureStageState(v, D3DTSS_ALPHAARG0, pCur[17-Adjust1]); - - if(pCur[18-Adjust1] != X_D3DTSS_UNK) - g_pD3DDevice->SetTextureStageState(v, D3DTSS_ALPHAARG1, pCur[18-Adjust1]); - - if(pCur[19-Adjust1] != X_D3DTSS_UNK) - g_pD3DDevice->SetTextureStageState(v, D3DTSS_ALPHAARG2, pCur[19-Adjust1]); - - if(pCur[20-Adjust1] != X_D3DTSS_UNK) - g_pD3DDevice->SetTextureStageState(v, D3DTSS_RESULTARG, pCur[20-Adjust1]); - - if(pCur[21-Adjust1] != X_D3DTSS_UNK) - g_pD3DDevice->SetTextureStageState(v, D3DTSS_TEXTURETRANSFORMFLAGS, pCur[21-Adjust1]); - - /*if(pCur[29] != X_D3DTSS_UNK) // This is NOT a deferred texture state! - g_pD3DDevice->SetSamplerState(v, D3DSAMP_BORDERCOLOR, pCur[29]); - */ - - /** To check for unhandled texture stage state changes - for(int r=0;r<32;r++) - { - static const int unchecked[] = - { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 29, 30, 31 - }; - - if(pCur[r] != X_D3DTSS_UNK) - { - bool pass = true; - - for(int q=0;q%d", v, r); - } - } - //**/ +DWORD GetDeferredTextureStateFromIndex(DWORD State) +{ + // On early XDKs, we need to shuffle the values around a little + // TODO: Verify which XDK version this change occurred at + if (g_BuildVersion <= 3948) { + // Values range 0-9 (D3DTSS_COLOROP to D3DTSS_TEXTURETRANSFORMFLAGS) become 12-21 + if (State <= 9) { + return State + 12; } - // if point sprites are enabled, copy stage 3 over to 0 - if(EmuD3DDeferredRenderState[26] == TRUE) - { - // pCur = Texture Stage 3 States - ::DWORD *pCur = &EmuD3DDeferredTextureState[2*32]; + // All Remaining values 10-21 (D3DTSS_ADDRESSU to D3DTSS_ALPHAKILL) become 0-11 + return State - 10; + } - IDirect3DBaseTexture *pTexture; + // On later XDKs, the mapping is identical to our representation + return State; +} - // set the point sprites texture - g_pD3DDevice->GetTexture(3, &pTexture); - g_pD3DDevice->SetTexture(0, pTexture); +void UpdateDeferredTextureStates() +{ + // Iterate through all deferred texture states/stages + for (int Stage = 0; Stage < XTL::X_D3DTS_STAGECOUNT; Stage++) { + for (int StateIndex = XTL::X_D3DTSS_DEFERRED_FIRST; StateIndex <= XTL::X_D3DTSS_DEFERRED_LAST; StateIndex++) { + // Read the value of the current stage/state from the Xbox data structure + DWORD Value = XTL::EmuD3DDeferredTextureState[(Stage * XTL::X_D3DTS_STAGESIZE) + StateIndex]; - // disable all other stages - g_pD3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); - g_pD3DDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + // Convert the index of the current state to an index that we can use + // This handles the case when XDKs have different state values + DWORD State = GetDeferredTextureStateFromIndex(StateIndex); - // in that case we have to copy over the stage by hand - for(int v=0;v<30;v++) - { - if(pCur[v] != X_D3DTSS_UNK) - { - ::DWORD dwValue; + switch (State) { + case XTL::X_D3DTSS_ADDRESSU: case XTL::X_D3DTSS_ADDRESSV: case XTL::X_D3DTSS_ADDRESSW: + if (Value == XTL::X_D3DTADDRESS_CLAMPTOEDGE) { + EmuLog(LOG_LEVEL::WARNING, "ClampToEdge is unsupported"); + break; + } - // For Direct3D9, everything below X_D3DSAMP_MAXANISOTROPY needs to call GetSamplerState / SetSamplerState : - if (v <= X_D3DTSS_MAXANISOTROPY) { - g_pD3DDevice->GetSamplerState(3, (D3DSAMPLERSTATETYPE)v, &dwValue); - g_pD3DDevice->SetSamplerState(0, (D3DSAMPLERSTATETYPE)v, dwValue); - } - else - { - g_pD3DDevice->GetTextureStageState(3, (D3DTEXTURESTAGESTATETYPE)v, &dwValue); - g_pD3DDevice->SetTextureStageState(0, (D3DTEXTURESTAGESTATETYPE)v, dwValue); - } + // These states match the PC counterpart IDs + g_pD3DDevice->SetSamplerState(Stage, (XTL::D3DSAMPLERSTATETYPE)State, Value); + break; + case XTL::X_D3DTSS_MAGFILTER: case XTL::X_D3DTSS_MINFILTER: case XTL::X_D3DTSS_MIPFILTER: + if (Value == XTL::X_D3DTEXF_QUINCUNX) { + EmuLog(LOG_LEVEL::WARNING, "QuinCunx is unsupported"); + break; + } + + // These states (when incremented by 2) match the PC counterpart IDs + g_pD3DDevice->SetSamplerState(Stage, (XTL::D3DSAMPLERSTATETYPE)(State + 2), Value); + break; + case XTL::X_D3DTSS_MIPMAPLODBIAS: + g_pD3DDevice->SetSamplerState(Stage, XTL::D3DSAMP_MIPMAPLODBIAS, Value); + break; + case XTL::X_D3DTSS_MAXMIPLEVEL: + g_pD3DDevice->SetSamplerState(Stage, XTL::D3DSAMP_MAXMIPLEVEL, Value); + break; + case XTL::X_D3DTSS_MAXANISOTROPY: + g_pD3DDevice->SetSamplerState(Stage, XTL::D3DSAMP_MAXANISOTROPY, Value); + break; + case XTL::X_D3DTSS_COLORKEYOP: // Xbox ext + // Logging Disabled: Causes Dashboard to slow down massively + //EmuLog(LOG_LEVEL::WARNING, "D3DTSS_COLORKEYOP is unsupported"); + break; + case XTL::X_D3DTSS_COLORSIGN: // Xbox ext + // Logging Disabled: Causes Dashboard to slow down massively + //EmuLog(LOG_LEVEL::WARNING, "D3DTSS_COLORSIGN is unsupported"); + break; + case XTL::X_D3DTSS_ALPHAKILL: // Xbox ext + // Logging Disabled: Causes Dashboard to slow down massively + //EmuLog(LOG_LEVEL::WARNING, "D3DTSS_ALPHAKILL is unsupported"); + break; + case XTL::X_D3DTSS_COLOROP: + // TODO: This would be better split into it's own function, or a lookup array + switch (Value) { + case XTL::X_D3DTOP_DISABLE: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_DISABLE); + break; + case XTL::X_D3DTOP_SELECTARG1: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_SELECTARG1); + break; + case XTL::X_D3DTOP_SELECTARG2: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_SELECTARG2); + break; + case XTL::X_D3DTOP_MODULATE: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_MODULATE); + break; + case XTL::X_D3DTOP_MODULATE2X: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_MODULATE2X); + break; + case XTL::X_D3DTOP_MODULATE4X: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_MODULATE4X); + break; + case XTL::X_D3DTOP_ADD: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_ADD); + break; + case XTL::X_D3DTOP_ADDSIGNED: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_ADDSIGNED); + break; + case XTL::X_D3DTOP_ADDSIGNED2X: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_ADDSIGNED2X); + break; + case XTL::X_D3DTOP_SUBTRACT: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_SUBTRACT); + break; + case XTL::X_D3DTOP_ADDSMOOTH: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_ADDSMOOTH); + break; + case XTL::X_D3DTOP_BLENDDIFFUSEALPHA: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_BLENDDIFFUSEALPHA); + break; + case XTL::X_D3DTOP_BLENDCURRENTALPHA: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_BLENDCURRENTALPHA); + break; + case XTL::X_D3DTOP_BLENDTEXTUREALPHA: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_BLENDTEXTUREALPHA); + break; + case XTL::X_D3DTOP_BLENDFACTORALPHA: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_BLENDFACTORALPHA); + break; + case XTL::X_D3DTOP_BLENDTEXTUREALPHAPM: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_BLENDTEXTUREALPHAPM); + break; + case XTL::X_D3DTOP_PREMODULATE: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_PREMODULATE); + break; + case XTL::X_D3DTOP_MODULATEALPHA_ADDCOLOR: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_MODULATEALPHA_ADDCOLOR); + break; + case XTL::X_D3DTOP_MODULATECOLOR_ADDALPHA: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_MODULATECOLOR_ADDALPHA); + break; + case XTL::X_D3DTOP_MODULATEINVALPHA_ADDCOLOR: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_MODULATEINVALPHA_ADDCOLOR); + break; + case XTL::X_D3DTOP_MODULATEINVCOLOR_ADDALPHA: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_MODULATEINVCOLOR_ADDALPHA); + break; + case XTL::X_D3DTOP_DOTPRODUCT3: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_DOTPRODUCT3); + break; + case XTL::X_D3DTOP_MULTIPLYADD: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_MULTIPLYADD); + break; + case XTL::X_D3DTOP_LERP: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_LERP); + break; + case XTL::X_D3DTOP_BUMPENVMAP: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_BUMPENVMAP); + break; + case XTL::X_D3DTOP_BUMPENVMAPLUMINANCE: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_BUMPENVMAPLUMINANCE); + break; + default: + EmuLog(LOG_LEVEL::WARNING, "Unsupported D3DTSS_COLOROP Value (%d)", Value); + break; + } + break; + case XTL::X_D3DTSS_COLORARG0: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLORARG0, Value); + break; + case XTL::X_D3DTSS_COLORARG1: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLORARG1, Value); + break; + case XTL::X_D3DTSS_COLORARG2: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLORARG2, Value); + break; + case XTL::X_D3DTSS_ALPHAOP: + // TODO: Use a lookup table, this is not always a 1:1 map (same as D3DTSS_COLOROP) + if (Value != X_D3DTSS_UNK) { + if (Value > XTL::X_D3DTOP_BLENDDIFFUSEALPHA && Value != XTL::X_D3DTOP_BLENDTEXTUREALPHA && Value != XTL::X_D3DTOP_BLENDCURRENTALPHA) { + EmuLog(LOG_LEVEL::WARNING, "Unsupported D3DTSS_ALPHAOP Value (%d)", Value); + } else if (Value == XTL::X_D3DTOP_BLENDTEXTUREALPHA) { + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_BLENDTEXTUREALPHA); + } + + if (Value == XTL::X_D3DTOP_BLENDFACTORALPHA) { + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_BLENDFACTORALPHA); + } + + if (Value == XTL::X_D3DTOP_BLENDCURRENTALPHA) { + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_BLENDCURRENTALPHA); + } else { + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, Value); + } + } + break; + case XTL::X_D3DTSS_ALPHAARG0: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAARG0, Value); + break; + case XTL::X_D3DTSS_ALPHAARG1: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAARG1, Value); + break; + case XTL::X_D3DTSS_ALPHAARG2: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAARG2, Value); + break; + case XTL::X_D3DTSS_RESULTARG: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_RESULTARG, Value); + break; + case XTL::X_D3DTSS_TEXTURETRANSFORMFLAGS: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_TEXTURETRANSFORMFLAGS, Value); + break; + default: + EmuLog(LOG_LEVEL::WARNING, "Unkown Xbox D3DTSS Value: %d", State); + break; + } + } + } + + // if point sprites are enabled, copy stage 3 over to 0 + // TODO: Verify/Fix this, it doesn't seem right (It calls host functions using Xbox indexes) + if (XTL::EmuD3DDeferredRenderState[XTL::X_D3DRS_POINTSPRITEENABLE - XTL::X_D3DRS_FOGENABLE] == TRUE) { + // Get a pointer to Stage 3 + DWORD *pCur = &XTL::EmuD3DDeferredTextureState[2 * XTL::X_D3DTS_STAGESIZE]; + + XTL::IDirect3DBaseTexture *pTexture; + + // set the point sprites texture + g_pD3DDevice->GetTexture(3, &pTexture); + g_pD3DDevice->SetTexture(0, pTexture); + + // disable all other stages + g_pD3DDevice->SetTextureStageState(1, XTL::D3DTSS_COLOROP, XTL::D3DTOP_DISABLE); + g_pD3DDevice->SetTextureStageState(1, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_DISABLE); + + for (int v = 0; v < 30; v++) { + if (pCur[v] != X_D3DTSS_UNK) { + DWORD dwValue = 0; + + // For Direct3D9, everything below X_D3DSAMP_MAXANISOTROPY needs to call GetSamplerState / SetSamplerState : + if (v <= XTL::X_D3DTSS_MAXANISOTROPY) { + g_pD3DDevice->GetSamplerState(3, (XTL::D3DSAMPLERSTATETYPE)v, &dwValue); + g_pD3DDevice->SetSamplerState(0, (XTL::D3DSAMPLERSTATETYPE)v, dwValue); + } else { + g_pD3DDevice->GetTextureStageState(3, (XTL::D3DTEXTURESTAGESTATETYPE)v, &dwValue); + g_pD3DDevice->SetTextureStageState(0, (XTL::D3DTEXTURESTAGESTATETYPE)v, dwValue); } } } } } + +// ****************************************************************** +// * patch: UpdateDeferredStates +// ****************************************************************** +void XTL::EmuUpdateDeferredStates() +{ + VerifyAndFixEmuDeferredRenderStateOffset(); + UpdateDeferredRenderStates(); + UpdateDeferredTextureStates(); +} From f6c2544c2281cc019441ed12638c93c7f012d878 Mon Sep 17 00:00:00 2001 From: Luke Usher Date: Wed, 3 Apr 2019 12:03:36 +0100 Subject: [PATCH 02/12] Slightly better way of handling Point Sprites in XbState --- src/core/hle/D3D8/XbState.cpp | 43 +++++++++++++++++------------------ 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/src/core/hle/D3D8/XbState.cpp b/src/core/hle/D3D8/XbState.cpp index e8386d051..6f5558150 100644 --- a/src/core/hle/D3D8/XbState.cpp +++ b/src/core/hle/D3D8/XbState.cpp @@ -136,14 +136,31 @@ DWORD GetDeferredTextureStateFromIndex(DWORD State) void UpdateDeferredTextureStates() { // Iterate through all deferred texture states/stages - for (int Stage = 0; Stage < XTL::X_D3DTS_STAGECOUNT; Stage++) { + + // Track if we need to overwrite state 0 with 3 because of Point Sprites + bool pointSpriteOverride = false; + if (XTL::EmuD3DDeferredRenderState[XTL::X_D3DRS_POINTSPRITEENABLE - XTL::X_D3DRS_FOGENABLE] == TRUE) { + pointSpriteOverride = true; + } + + for (int StageIndex = 0; StageIndex < XTL::X_D3DTS_STAGECOUNT; StageIndex++) { for (int StateIndex = XTL::X_D3DTSS_DEFERRED_FIRST; StateIndex <= XTL::X_D3DTSS_DEFERRED_LAST; StateIndex++) { // Read the value of the current stage/state from the Xbox data structure - DWORD Value = XTL::EmuD3DDeferredTextureState[(Stage * XTL::X_D3DTS_STAGESIZE) + StateIndex]; - + DWORD Value = XTL::EmuD3DDeferredTextureState[(StageIndex * XTL::X_D3DTS_STAGESIZE) + StateIndex]; + // Convert the index of the current state to an index that we can use // This handles the case when XDKs have different state values DWORD State = GetDeferredTextureStateFromIndex(StateIndex); + DWORD Stage = StageIndex; + + // If point sprites are enabled, we need to overwrite our existing state 0 with State 3 also + if (pointSpriteOverride && Stage == 3) { + Stage = 0; + + // Make sure we only do this once + pointSpriteOverride = false; + StageIndex--; // Force Stage 3 to repeat, without this hack next time + } switch (State) { case XTL::X_D3DTSS_ADDRESSU: case XTL::X_D3DTSS_ADDRESSV: case XTL::X_D3DTSS_ADDRESSW: @@ -322,12 +339,7 @@ void UpdateDeferredTextureStates() } } - // if point sprites are enabled, copy stage 3 over to 0 - // TODO: Verify/Fix this, it doesn't seem right (It calls host functions using Xbox indexes) if (XTL::EmuD3DDeferredRenderState[XTL::X_D3DRS_POINTSPRITEENABLE - XTL::X_D3DRS_FOGENABLE] == TRUE) { - // Get a pointer to Stage 3 - DWORD *pCur = &XTL::EmuD3DDeferredTextureState[2 * XTL::X_D3DTS_STAGESIZE]; - XTL::IDirect3DBaseTexture *pTexture; // set the point sprites texture @@ -338,20 +350,7 @@ void UpdateDeferredTextureStates() g_pD3DDevice->SetTextureStageState(1, XTL::D3DTSS_COLOROP, XTL::D3DTOP_DISABLE); g_pD3DDevice->SetTextureStageState(1, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_DISABLE); - for (int v = 0; v < 30; v++) { - if (pCur[v] != X_D3DTSS_UNK) { - DWORD dwValue = 0; - - // For Direct3D9, everything below X_D3DSAMP_MAXANISOTROPY needs to call GetSamplerState / SetSamplerState : - if (v <= XTL::X_D3DTSS_MAXANISOTROPY) { - g_pD3DDevice->GetSamplerState(3, (XTL::D3DSAMPLERSTATETYPE)v, &dwValue); - g_pD3DDevice->SetSamplerState(0, (XTL::D3DSAMPLERSTATETYPE)v, dwValue); - } else { - g_pD3DDevice->GetTextureStageState(3, (XTL::D3DTEXTURESTAGESTATETYPE)v, &dwValue); - g_pD3DDevice->SetTextureStageState(0, (XTL::D3DTEXTURESTAGESTATETYPE)v, dwValue); - } - } - } + // no need to actually copy here, since it was handled in the loop above } } From 11daaac408ab5206e747d1c9ad43859590836d37 Mon Sep 17 00:00:00 2001 From: Luke Usher Date: Thu, 4 Apr 2019 14:32:15 +0100 Subject: [PATCH 03/12] Remove EmuD3DRenderStateSimpleEncoded, use DxbxRenderStateInfo instead This code is easier to maintain, easier to extend, and removes more legacy cruft from original Cxbx. --- src/core/hle/D3D8/Direct3D9/Direct3D9.cpp | 336 +++++++++------------- src/core/hle/D3D8/XbConvert.cpp | 95 ------ src/core/hle/D3D8/XbConvert.h | 1 - 3 files changed, 140 insertions(+), 292 deletions(-) diff --git a/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp b/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp index e7680e5c7..8fcbd1180 100644 --- a/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp +++ b/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp @@ -6006,213 +6006,157 @@ VOID __fastcall XTL::EMUPATCH(D3DDevice_SetRenderState_Simple) ( DWORD Method, DWORD Value -) + ) { - LOG_FUNC_BEGIN - LOG_FUNC_ARG(Method) - LOG_FUNC_ARG(Value) - LOG_FUNC_END; + LOG_FUNC_BEGIN + LOG_FUNC_ARG(Method) + LOG_FUNC_ARG(Value) + LOG_FUNC_END; - XB_trampoline(VOID, __fastcall, D3DDevice_SetRenderState_Simple, (DWORD, DWORD)); - XB_D3DDevice_SetRenderState_Simple(Method, Value); + XB_trampoline(VOID, __fastcall, D3DDevice_SetRenderState_Simple, (DWORD, DWORD)); + XB_D3DDevice_SetRenderState_Simple(Method, Value); - // Special Case: Handle PixelShader related Render States - // TODO: Port over EmuMappedD3DRenderState and related code from Dxbx or Wip_LessVertexPatching - // After this, we don't need to do this part anymore - switch (Method & 0x00001FFC) { - case NV2A_RC_IN_ALPHA(0): TemporaryPixelShaderRenderStates[X_D3DRS_PSALPHAINPUTS0] = Value; return; - case NV2A_RC_IN_ALPHA(1): TemporaryPixelShaderRenderStates[X_D3DRS_PSALPHAINPUTS1] = Value; return; - case NV2A_RC_IN_ALPHA(2): TemporaryPixelShaderRenderStates[X_D3DRS_PSALPHAINPUTS2] = Value; return; - case NV2A_RC_IN_ALPHA(3): TemporaryPixelShaderRenderStates[X_D3DRS_PSALPHAINPUTS3] = Value; return; - case NV2A_RC_IN_ALPHA(4): TemporaryPixelShaderRenderStates[X_D3DRS_PSALPHAINPUTS4] = Value; return; - case NV2A_RC_IN_ALPHA(5): TemporaryPixelShaderRenderStates[X_D3DRS_PSALPHAINPUTS5] = Value; return; - case NV2A_RC_IN_ALPHA(6): TemporaryPixelShaderRenderStates[X_D3DRS_PSALPHAINPUTS6] = Value; return; - case NV2A_RC_IN_ALPHA(7): TemporaryPixelShaderRenderStates[X_D3DRS_PSALPHAINPUTS7] = Value; return; - case NV2A_RC_FINAL0: TemporaryPixelShaderRenderStates[X_D3DRS_PSFINALCOMBINERINPUTSABCD] = Value; return; - case NV2A_RC_FINAL1: TemporaryPixelShaderRenderStates[X_D3DRS_PSFINALCOMBINERINPUTSEFG] = Value; return; - case NV2A_RC_CONSTANT_COLOR0(0): TemporaryPixelShaderRenderStates[X_D3DRS_PSCONSTANT0_0] = Value; return; - case NV2A_RC_CONSTANT_COLOR0(1): TemporaryPixelShaderRenderStates[X_D3DRS_PSCONSTANT0_1] = Value; return; - case NV2A_RC_CONSTANT_COLOR0(2): TemporaryPixelShaderRenderStates[X_D3DRS_PSCONSTANT0_2] = Value; return; - case NV2A_RC_CONSTANT_COLOR0(3): TemporaryPixelShaderRenderStates[X_D3DRS_PSCONSTANT0_3] = Value; return; - case NV2A_RC_CONSTANT_COLOR0(4): TemporaryPixelShaderRenderStates[X_D3DRS_PSCONSTANT0_4] = Value; return; - case NV2A_RC_CONSTANT_COLOR0(5): TemporaryPixelShaderRenderStates[X_D3DRS_PSCONSTANT0_5] = Value; return; - case NV2A_RC_CONSTANT_COLOR0(6): TemporaryPixelShaderRenderStates[X_D3DRS_PSCONSTANT0_6] = Value; return; - case NV2A_RC_CONSTANT_COLOR0(7): TemporaryPixelShaderRenderStates[X_D3DRS_PSCONSTANT0_7] = Value; return; - case NV2A_RC_CONSTANT_COLOR1(0): TemporaryPixelShaderRenderStates[X_D3DRS_PSCONSTANT1_0] = Value; return; - case NV2A_RC_CONSTANT_COLOR1(1): TemporaryPixelShaderRenderStates[X_D3DRS_PSCONSTANT1_1] = Value; return; - case NV2A_RC_CONSTANT_COLOR1(2): TemporaryPixelShaderRenderStates[X_D3DRS_PSCONSTANT1_2] = Value; return; - case NV2A_RC_CONSTANT_COLOR1(3): TemporaryPixelShaderRenderStates[X_D3DRS_PSCONSTANT1_3] = Value; return; - case NV2A_RC_CONSTANT_COLOR1(4): TemporaryPixelShaderRenderStates[X_D3DRS_PSCONSTANT1_4] = Value; return; - case NV2A_RC_CONSTANT_COLOR1(5): TemporaryPixelShaderRenderStates[X_D3DRS_PSCONSTANT1_5] = Value; return; - case NV2A_RC_CONSTANT_COLOR1(6): TemporaryPixelShaderRenderStates[X_D3DRS_PSCONSTANT1_6] = Value; return; - case NV2A_RC_CONSTANT_COLOR1(7): TemporaryPixelShaderRenderStates[X_D3DRS_PSCONSTANT1_7] = Value; return; - case NV2A_RC_OUT_ALPHA(0): TemporaryPixelShaderRenderStates[X_D3DRS_PSALPHAOUTPUTS0] = Value; return; - case NV2A_RC_OUT_ALPHA(1): TemporaryPixelShaderRenderStates[X_D3DRS_PSALPHAOUTPUTS1] = Value; return; - case NV2A_RC_OUT_ALPHA(2): TemporaryPixelShaderRenderStates[X_D3DRS_PSALPHAOUTPUTS2] = Value; return; - case NV2A_RC_OUT_ALPHA(3): TemporaryPixelShaderRenderStates[X_D3DRS_PSALPHAOUTPUTS3] = Value; return; - case NV2A_RC_OUT_ALPHA(4): TemporaryPixelShaderRenderStates[X_D3DRS_PSALPHAOUTPUTS4] = Value; return; - case NV2A_RC_OUT_ALPHA(5): TemporaryPixelShaderRenderStates[X_D3DRS_PSALPHAOUTPUTS5] = Value; return; - case NV2A_RC_OUT_ALPHA(6): TemporaryPixelShaderRenderStates[X_D3DRS_PSALPHAOUTPUTS6] = Value; return; - case NV2A_RC_OUT_ALPHA(7): TemporaryPixelShaderRenderStates[X_D3DRS_PSALPHAOUTPUTS7] = Value; return; - case NV2A_RC_IN_RGB(0): TemporaryPixelShaderRenderStates[X_D3DRS_PSRGBINPUTS0] = Value; return; - case NV2A_RC_IN_RGB(1): TemporaryPixelShaderRenderStates[X_D3DRS_PSRGBINPUTS1] = Value; return; - case NV2A_RC_IN_RGB(2): TemporaryPixelShaderRenderStates[X_D3DRS_PSRGBINPUTS2] = Value; return; - case NV2A_RC_IN_RGB(3): TemporaryPixelShaderRenderStates[X_D3DRS_PSRGBINPUTS3] = Value; return; - case NV2A_RC_IN_RGB(4): TemporaryPixelShaderRenderStates[X_D3DRS_PSRGBINPUTS4] = Value; return; - case NV2A_RC_IN_RGB(5): TemporaryPixelShaderRenderStates[X_D3DRS_PSRGBINPUTS5] = Value; return; - case NV2A_RC_IN_RGB(6): TemporaryPixelShaderRenderStates[X_D3DRS_PSRGBINPUTS6] = Value; return; - case NV2A_RC_IN_RGB(7): TemporaryPixelShaderRenderStates[X_D3DRS_PSRGBINPUTS7] = Value; return; - case NV2A_TX_SHADER_CULL_MODE: TemporaryPixelShaderRenderStates[X_D3DRS_PSCOMPAREMODE] = Value; return; - case NV2A_RC_COLOR0: TemporaryPixelShaderRenderStates[X_D3DRS_PSFINALCOMBINERCONSTANT0] = Value; return; - case NV2A_RC_COLOR1: TemporaryPixelShaderRenderStates[X_D3DRS_PSFINALCOMBINERCONSTANT1] = Value; return; - case NV2A_RC_OUT_RGB(0): TemporaryPixelShaderRenderStates[X_D3DRS_PSRGBOUTPUTS0] = Value; return; - case NV2A_RC_OUT_RGB(1): TemporaryPixelShaderRenderStates[X_D3DRS_PSRGBOUTPUTS1] = Value; return; - case NV2A_RC_OUT_RGB(2): TemporaryPixelShaderRenderStates[X_D3DRS_PSRGBOUTPUTS2] = Value; return; - case NV2A_RC_OUT_RGB(3): TemporaryPixelShaderRenderStates[X_D3DRS_PSRGBOUTPUTS3] = Value; return; - case NV2A_RC_OUT_RGB(4): TemporaryPixelShaderRenderStates[X_D3DRS_PSRGBOUTPUTS4] = Value; return; - case NV2A_RC_OUT_RGB(5): TemporaryPixelShaderRenderStates[X_D3DRS_PSRGBOUTPUTS5] = Value; return; - case NV2A_RC_OUT_RGB(6): TemporaryPixelShaderRenderStates[X_D3DRS_PSRGBOUTPUTS6] = Value; return; - case NV2A_RC_OUT_RGB(7): TemporaryPixelShaderRenderStates[X_D3DRS_PSRGBOUTPUTS7] = Value; return; - case NV2A_RC_ENABLE: TemporaryPixelShaderRenderStates[X_D3DRS_PSCOMBINERCOUNT] = Value; return; - case NV2A_NOP: TemporaryPixelShaderRenderStates[X_D3DRS_PS_RESERVED] = Value; return; // Dxbx note : This takes the slot of X_D3DPIXELSHADERDEF.PSTextureModes, set by D3DDevice_SetRenderState_LogicOp? - case NV2A_TX_SHADER_DOTMAPPING: TemporaryPixelShaderRenderStates[X_D3DRS_PSDOTMAPPING] = Value; return; - case NV2A_TX_SHADER_PREVIOUS: TemporaryPixelShaderRenderStates[X_D3DRS_PSINPUTTEXTURE] = Value; return; - } + // Special Case: Handle PixelShader related Render States + // TODO: Port over EmuMappedD3DRenderState and related code from Dxbx or Wip_LessVertexPatching + // After this, we don't need to do this part anymore + switch (Method & 0x00001FFC) { + case NV2A_RC_IN_ALPHA(0): TemporaryPixelShaderRenderStates[X_D3DRS_PSALPHAINPUTS0] = Value; return; + case NV2A_RC_IN_ALPHA(1): TemporaryPixelShaderRenderStates[X_D3DRS_PSALPHAINPUTS1] = Value; return; + case NV2A_RC_IN_ALPHA(2): TemporaryPixelShaderRenderStates[X_D3DRS_PSALPHAINPUTS2] = Value; return; + case NV2A_RC_IN_ALPHA(3): TemporaryPixelShaderRenderStates[X_D3DRS_PSALPHAINPUTS3] = Value; return; + case NV2A_RC_IN_ALPHA(4): TemporaryPixelShaderRenderStates[X_D3DRS_PSALPHAINPUTS4] = Value; return; + case NV2A_RC_IN_ALPHA(5): TemporaryPixelShaderRenderStates[X_D3DRS_PSALPHAINPUTS5] = Value; return; + case NV2A_RC_IN_ALPHA(6): TemporaryPixelShaderRenderStates[X_D3DRS_PSALPHAINPUTS6] = Value; return; + case NV2A_RC_IN_ALPHA(7): TemporaryPixelShaderRenderStates[X_D3DRS_PSALPHAINPUTS7] = Value; return; + case NV2A_RC_FINAL0: TemporaryPixelShaderRenderStates[X_D3DRS_PSFINALCOMBINERINPUTSABCD] = Value; return; + case NV2A_RC_FINAL1: TemporaryPixelShaderRenderStates[X_D3DRS_PSFINALCOMBINERINPUTSEFG] = Value; return; + case NV2A_RC_CONSTANT_COLOR0(0): TemporaryPixelShaderRenderStates[X_D3DRS_PSCONSTANT0_0] = Value; return; + case NV2A_RC_CONSTANT_COLOR0(1): TemporaryPixelShaderRenderStates[X_D3DRS_PSCONSTANT0_1] = Value; return; + case NV2A_RC_CONSTANT_COLOR0(2): TemporaryPixelShaderRenderStates[X_D3DRS_PSCONSTANT0_2] = Value; return; + case NV2A_RC_CONSTANT_COLOR0(3): TemporaryPixelShaderRenderStates[X_D3DRS_PSCONSTANT0_3] = Value; return; + case NV2A_RC_CONSTANT_COLOR0(4): TemporaryPixelShaderRenderStates[X_D3DRS_PSCONSTANT0_4] = Value; return; + case NV2A_RC_CONSTANT_COLOR0(5): TemporaryPixelShaderRenderStates[X_D3DRS_PSCONSTANT0_5] = Value; return; + case NV2A_RC_CONSTANT_COLOR0(6): TemporaryPixelShaderRenderStates[X_D3DRS_PSCONSTANT0_6] = Value; return; + case NV2A_RC_CONSTANT_COLOR0(7): TemporaryPixelShaderRenderStates[X_D3DRS_PSCONSTANT0_7] = Value; return; + case NV2A_RC_CONSTANT_COLOR1(0): TemporaryPixelShaderRenderStates[X_D3DRS_PSCONSTANT1_0] = Value; return; + case NV2A_RC_CONSTANT_COLOR1(1): TemporaryPixelShaderRenderStates[X_D3DRS_PSCONSTANT1_1] = Value; return; + case NV2A_RC_CONSTANT_COLOR1(2): TemporaryPixelShaderRenderStates[X_D3DRS_PSCONSTANT1_2] = Value; return; + case NV2A_RC_CONSTANT_COLOR1(3): TemporaryPixelShaderRenderStates[X_D3DRS_PSCONSTANT1_3] = Value; return; + case NV2A_RC_CONSTANT_COLOR1(4): TemporaryPixelShaderRenderStates[X_D3DRS_PSCONSTANT1_4] = Value; return; + case NV2A_RC_CONSTANT_COLOR1(5): TemporaryPixelShaderRenderStates[X_D3DRS_PSCONSTANT1_5] = Value; return; + case NV2A_RC_CONSTANT_COLOR1(6): TemporaryPixelShaderRenderStates[X_D3DRS_PSCONSTANT1_6] = Value; return; + case NV2A_RC_CONSTANT_COLOR1(7): TemporaryPixelShaderRenderStates[X_D3DRS_PSCONSTANT1_7] = Value; return; + case NV2A_RC_OUT_ALPHA(0): TemporaryPixelShaderRenderStates[X_D3DRS_PSALPHAOUTPUTS0] = Value; return; + case NV2A_RC_OUT_ALPHA(1): TemporaryPixelShaderRenderStates[X_D3DRS_PSALPHAOUTPUTS1] = Value; return; + case NV2A_RC_OUT_ALPHA(2): TemporaryPixelShaderRenderStates[X_D3DRS_PSALPHAOUTPUTS2] = Value; return; + case NV2A_RC_OUT_ALPHA(3): TemporaryPixelShaderRenderStates[X_D3DRS_PSALPHAOUTPUTS3] = Value; return; + case NV2A_RC_OUT_ALPHA(4): TemporaryPixelShaderRenderStates[X_D3DRS_PSALPHAOUTPUTS4] = Value; return; + case NV2A_RC_OUT_ALPHA(5): TemporaryPixelShaderRenderStates[X_D3DRS_PSALPHAOUTPUTS5] = Value; return; + case NV2A_RC_OUT_ALPHA(6): TemporaryPixelShaderRenderStates[X_D3DRS_PSALPHAOUTPUTS6] = Value; return; + case NV2A_RC_OUT_ALPHA(7): TemporaryPixelShaderRenderStates[X_D3DRS_PSALPHAOUTPUTS7] = Value; return; + case NV2A_RC_IN_RGB(0): TemporaryPixelShaderRenderStates[X_D3DRS_PSRGBINPUTS0] = Value; return; + case NV2A_RC_IN_RGB(1): TemporaryPixelShaderRenderStates[X_D3DRS_PSRGBINPUTS1] = Value; return; + case NV2A_RC_IN_RGB(2): TemporaryPixelShaderRenderStates[X_D3DRS_PSRGBINPUTS2] = Value; return; + case NV2A_RC_IN_RGB(3): TemporaryPixelShaderRenderStates[X_D3DRS_PSRGBINPUTS3] = Value; return; + case NV2A_RC_IN_RGB(4): TemporaryPixelShaderRenderStates[X_D3DRS_PSRGBINPUTS4] = Value; return; + case NV2A_RC_IN_RGB(5): TemporaryPixelShaderRenderStates[X_D3DRS_PSRGBINPUTS5] = Value; return; + case NV2A_RC_IN_RGB(6): TemporaryPixelShaderRenderStates[X_D3DRS_PSRGBINPUTS6] = Value; return; + case NV2A_RC_IN_RGB(7): TemporaryPixelShaderRenderStates[X_D3DRS_PSRGBINPUTS7] = Value; return; + case NV2A_TX_SHADER_CULL_MODE: TemporaryPixelShaderRenderStates[X_D3DRS_PSCOMPAREMODE] = Value; return; + case NV2A_RC_COLOR0: TemporaryPixelShaderRenderStates[X_D3DRS_PSFINALCOMBINERCONSTANT0] = Value; return; + case NV2A_RC_COLOR1: TemporaryPixelShaderRenderStates[X_D3DRS_PSFINALCOMBINERCONSTANT1] = Value; return; + case NV2A_RC_OUT_RGB(0): TemporaryPixelShaderRenderStates[X_D3DRS_PSRGBOUTPUTS0] = Value; return; + case NV2A_RC_OUT_RGB(1): TemporaryPixelShaderRenderStates[X_D3DRS_PSRGBOUTPUTS1] = Value; return; + case NV2A_RC_OUT_RGB(2): TemporaryPixelShaderRenderStates[X_D3DRS_PSRGBOUTPUTS2] = Value; return; + case NV2A_RC_OUT_RGB(3): TemporaryPixelShaderRenderStates[X_D3DRS_PSRGBOUTPUTS3] = Value; return; + case NV2A_RC_OUT_RGB(4): TemporaryPixelShaderRenderStates[X_D3DRS_PSRGBOUTPUTS4] = Value; return; + case NV2A_RC_OUT_RGB(5): TemporaryPixelShaderRenderStates[X_D3DRS_PSRGBOUTPUTS5] = Value; return; + case NV2A_RC_OUT_RGB(6): TemporaryPixelShaderRenderStates[X_D3DRS_PSRGBOUTPUTS6] = Value; return; + case NV2A_RC_OUT_RGB(7): TemporaryPixelShaderRenderStates[X_D3DRS_PSRGBOUTPUTS7] = Value; return; + case NV2A_RC_ENABLE: TemporaryPixelShaderRenderStates[X_D3DRS_PSCOMBINERCOUNT] = Value; return; + case NV2A_NOP: TemporaryPixelShaderRenderStates[X_D3DRS_PS_RESERVED] = Value; return; // Dxbx note : This takes the slot of X_D3DPIXELSHADERDEF.PSTextureModes, set by D3DDevice_SetRenderState_LogicOp? + case NV2A_TX_SHADER_DOTMAPPING: TemporaryPixelShaderRenderStates[X_D3DRS_PSDOTMAPPING] = Value; return; + case NV2A_TX_SHADER_PREVIOUS: TemporaryPixelShaderRenderStates[X_D3DRS_PSINPUTTEXTURE] = Value; return; + } - // Fallback to non-shader render state handling - int State = -1; + // Fetch the RenderState conversion info for the given input + int XboxRenderStateIndex = -1; + for (int i = 0; i <= X_D3DRS_DONOTCULLUNCOMPRESSED; i++) { + if (DxbxRenderStateInfo[i].M == (Method & 0x00001FFC)) { + XboxRenderStateIndex = i; + } + } - // Todo: make this faster and more elegant - for (int v = 0; v<174; v++) - { - if (EmuD3DRenderStateSimpleEncoded[v] == Method) - { - State = v; - break; - } - } + // If we could not map it, log and return + if (XboxRenderStateIndex == -1) { + EmuLog(LOG_LEVEL::WARNING, "RenderState_Simple(0x%.08X (%s), 0x%.08X) could not be found in RenderState table", Method, DxbxRenderStateInfo[XboxRenderStateIndex].S, Value); + return; + } - if (State == -1) { - // Attempt to determine renderstate name for unsupported types - std::string name = "Unknown"; - for (int i = 0; i <= X_D3DRS_DONOTCULLUNCOMPRESSED; i++) { - if (DxbxRenderStateInfo[i].M == (Method & 0x00001FFC)) { - name = DxbxRenderStateInfo[i].S; - break; - } - } + DBG_PRINTF("RenderState_Simple: %s = 0x%08X", DxbxRenderStateInfo[XboxRenderStateIndex].S, Value); - EmuLog(LOG_LEVEL::WARNING, "RenderState_Simple(0x%.08X (%s), 0x%.08X) is unsupported!", Method, name.c_str(), Value); - } - else - { - switch(State) - { - case D3DRS_COLORWRITEENABLE: - { - DWORD OrigValue = Value; + // Perform Conversion + switch (XboxRenderStateIndex) { + case X_D3DRS_COLORWRITEENABLE: { + DWORD OrigValue = Value; + Value = 0; - Value = 0; - - if(OrigValue & (1L<<16)) - Value |= D3DCOLORWRITEENABLE_RED; - if(OrigValue & (1L<<8)) - Value |= D3DCOLORWRITEENABLE_GREEN; - if(OrigValue & (1L<<0)) - Value |= D3DCOLORWRITEENABLE_BLUE; - if(OrigValue & (1L<<24)) - Value |= D3DCOLORWRITEENABLE_ALPHA; - - DBG_PRINTF("D3DRS_COLORWRITEENABLE := 0x%.08X\n", Value); + if (OrigValue & (1L << 16)) { + Value |= D3DCOLORWRITEENABLE_RED; } + + if (OrigValue & (1L << 8)) { + Value |= D3DCOLORWRITEENABLE_GREEN; + } + + if (OrigValue & (1L << 0)) { + Value |= D3DCOLORWRITEENABLE_BLUE; + } + + if (OrigValue & (1L << 24)) { + Value |= D3DCOLORWRITEENABLE_ALPHA; + } + } break; + case X_D3DRS_SHADEMODE: + Value = EmuXB2PC_D3DSHADEMODE(Value); break; + case X_D3DRS_BLENDOP: + Value = EmuXB2PC_D3DBLENDOP(Value); + break; + case X_D3DRS_SRCBLEND: + case X_D3DRS_DESTBLEND: + Value = EmuXB2PC_D3DBLEND(Value); + break; + case X_D3DRS_ZFUNC: + case X_D3DRS_ALPHAFUNC: + case X_D3DRS_STENCILFUNC: + Value = EmuXB2PC_D3DCMPFUNC(Value); + break; + case X_D3DRS_STENCILZFAIL: + case X_D3DRS_STENCILPASS: + Value = EmuXB2PC_D3DSTENCILOP(Value); + break; + case X_D3DRS_SWATHWIDTH: + // X_D3DRS_SWATHWIDTH safely ignored as it has no visible behavior: + // It simply changes the fill-rate for performance tweaking + // Just log and return + EmuLog(LOG_LEVEL::DEBUG, "RenderState_Simple(0x%.08X (%s), 0x%.08X) was ignored!", Method, DxbxRenderStateInfo[XboxRenderStateIndex].S, Value); + return; + case X_D3DRS_ALPHATESTENABLE: case X_D3DRS_ALPHABLENDENABLE: + case X_D3DRS_ALPHAREF: case X_D3DRS_ZWRITEENABLE: + case X_D3DRS_DITHERENABLE: case X_D3DRS_STENCILREF: + case X_D3DRS_STENCILMASK: case X_D3DRS_STENCILWRITEMASK: + // These render states require no conversion, so we simply + // allow SetRenderState to be called with no changes + break; + default: + // RenderState is unsupported/unimplemented, report and return + EmuLog(LOG_LEVEL::WARNING, "RenderState_Simple(0x%.08X (%s), 0x%.08X) is unsupported!", Method, DxbxRenderStateInfo[XboxRenderStateIndex].S, Value); + return; + } - case D3DRS_SHADEMODE: - Value = EmuXB2PC_D3DSHADEMODE(Value); - DBG_PRINTF("D3DRS_SHADEMODE := 0x%.08X\n", Value); - break; - - case D3DRS_BLENDOP: - Value = EmuXB2PC_D3DBLENDOP(Value); - DBG_PRINTF("D3DRS_BLENDOP := 0x%.08X\n", Value); - break; - - case D3DRS_SRCBLEND: - Value = EmuXB2PC_D3DBLEND(Value); - DBG_PRINTF("D3DRS_SRCBLEND := 0x%.08X\n", Value); - break; - - case D3DRS_DESTBLEND: - Value = EmuXB2PC_D3DBLEND(Value); - DBG_PRINTF("D3DRS_DESTBLEND := 0x%.08X\n", Value); - break; - - case D3DRS_ZFUNC: - Value = EmuXB2PC_D3DCMPFUNC(Value); - DBG_PRINTF("D3DRS_ZFUNC := 0x%.08X\n", Value); - break; - - case D3DRS_ALPHAFUNC: - Value = EmuXB2PC_D3DCMPFUNC(Value); - DBG_PRINTF("D3DRS_ALPHAFUNC := 0x%.08X\n", Value); - break; - - case D3DRS_ALPHATESTENABLE: - DBG_PRINTF("D3DRS_ALPHATESTENABLE := 0x%.08X\n", Value); - break; - - case D3DRS_ALPHABLENDENABLE: - DBG_PRINTF("D3DRS_ALPHABLENDENABLE := 0x%.08X\n", Value); - break; - - case D3DRS_ALPHAREF: - DBG_PRINTF("D3DRS_ALPHAREF := %lf\n", DWtoF(Value)); - break; - - case D3DRS_ZWRITEENABLE: - DBG_PRINTF("D3DRS_ZWRITEENABLE := 0x%.08X\n", Value); - break; - - case D3DRS_DITHERENABLE: - DBG_PRINTF("D3DRS_DITHERENABLE := 0x%.08X\n", Value); - break; - - case D3DRS_STENCILZFAIL: - Value = EmuXB2PC_D3DSTENCILOP(Value); - DBG_PRINTF("D3DRS_STENCILZFAIL := 0x%.08X\n", Value); - break; - - case D3DRS_STENCILPASS: - Value = EmuXB2PC_D3DSTENCILOP(Value); - DBG_PRINTF("D3DRS_STENCILPASS := 0x%.08X\n", Value); - break; - - case D3DRS_STENCILFUNC: - Value = EmuXB2PC_D3DCMPFUNC(Value); - DBG_PRINTF("D3DRS_STENCILFUNC := 0x%.08X\n", Value); - break; - - case D3DRS_STENCILREF: - DBG_PRINTF("D3DRS_STENCILREF := 0x%.08X\n", Value); - break; - - case D3DRS_STENCILMASK: - DBG_PRINTF("D3DRS_STENCILMASK := 0x%.08X\n", Value); - break; - - case D3DRS_STENCILWRITEMASK: - DBG_PRINTF("D3DRS_STENCILWRITEMASK := 0x%.08X\n", Value); - break; - - default: - CxbxKrnlCleanup("Unsupported RenderState (0x%.08X)", State); - break; - }; - - // TODO: verify these params as you add support for them! - HRESULT hRet = g_pD3DDevice->SetRenderState((D3DRENDERSTATETYPE)State, Value); - DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetRenderState"); - } + HRESULT hRet = g_pD3DDevice->SetRenderState((D3DRENDERSTATETYPE)(DxbxRenderStateInfo[XboxRenderStateIndex].PC), Value); + DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetRenderState"); } // ****************************************************************** diff --git a/src/core/hle/D3D8/XbConvert.cpp b/src/core/hle/D3D8/XbConvert.cpp index 0e67afe97..37607f784 100644 --- a/src/core/hle/D3D8/XbConvert.cpp +++ b/src/core/hle/D3D8/XbConvert.cpp @@ -1215,101 +1215,6 @@ XTL::D3DPRIMITIVETYPE XTL::EmuPrimitiveTypeLookup[] = /* D3DPT_MAX = 11, */ (XTL::D3DPRIMITIVETYPE)11 }; -// render state conversion table -CONST DWORD XTL::EmuD3DRenderStateSimpleEncoded[174] = -{ - // WARNING: This lookup table strongly binds us to an SDK with these - // specific #define values for D3DRS_*. Make VERY sure that you have - // the correct lookup values; - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 0 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 2 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 4 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 6 - X_D3DRSSE_UNK, 0x0004037c, // 8 - , D3DRS_SHADEMODE - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 10 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 12 - 0x0004035c, 0x00040300, // 14 - D3DRS_ZWRITEENABLE, D3DRS_ALPHATESTENABLE - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 16 - X_D3DRSSE_UNK, 0x00040344, // 18 - , D3DRS_SRCBLEND - 0x00040348, X_D3DRSSE_UNK, // 20 - D3DRS_DESTBLEND - X_D3DRSSE_UNK, 0x00040354, // 22 - , D3DRS_ZFUNC - 0x00040340, 0x0004033c, // 24 - D3DRS_ALPHAREF, D3DRS_ALPHAFUNC - 0x00040310, 0x00040304, // 26 - D3DRS_DITHERENABLE, D3DRS_ALPHABLENDENABLE - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 28 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 30 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 32 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 34 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 36 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 38 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 40 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 42 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 44 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 46 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 48 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 50 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 52 - 0x00040374, 0x00040378, // 54 - D3DRS_STENCILZFAIL, D3DRS_STENCILPASS - 0x00040364, 0x00040368, // 56 - D3DRS_STENCILFUNC, D3DRS_STENCILREF - 0x0004036c, 0x00040360, // 58 - D3DRS_STENCILMASK, D3DRS_STENCILWRITEMASK - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 60 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 62 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 64 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 66 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 68 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 70 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 72 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 74 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 76 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 78 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 80 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 82 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 84 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 86 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 88 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 90 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 92 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 94 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 96 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 98 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 100 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 102 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 104 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 106 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 108 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 110 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 112 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 114 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 116 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 118 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 120 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 122 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 124 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 126 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 128 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 130 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 132 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 134 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 136 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 138 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 140 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 142 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 144 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 146 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 148 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 150 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 152 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 154 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 156 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 158 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 160 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 162 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 164 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 166 - 0x00040358, X_D3DRSSE_UNK, // 168 - D3DRS_COLORWRITEENABLE - X_D3DRSSE_UNK, 0x00040350, // 170 - X_D3DRSSE_UNK, X_D3DRSSE_UNK, // 172 -}; - void XTL::EmuUnswizzleBox ( CONST PVOID pSrcBuff, diff --git a/src/core/hle/D3D8/XbConvert.h b/src/core/hle/D3D8/XbConvert.h index 47913a73c..01e46a7db 100644 --- a/src/core/hle/D3D8/XbConvert.h +++ b/src/core/hle/D3D8/XbConvert.h @@ -35,7 +35,6 @@ // simple render state encoding lookup table #define X_D3DRSSE_UNK 0x7fffffff -extern CONST DWORD EmuD3DRenderStateSimpleEncoded[174]; typedef void(*FormatToARGBRow)(const uint8_t* src, uint8_t* dst_argb, int width); From 21377baf93f44de8159729558156d66e17d3c3b2 Mon Sep 17 00:00:00 2001 From: Luke Usher Date: Thu, 4 Apr 2019 20:00:58 +0100 Subject: [PATCH 04/12] Fix broken/incorrect X_D3DTSS_ALPHAOP values. Fixes broken cloth polygons in Dead or Alive 3. --- src/core/hle/D3D8/XbState.cpp | 98 +++++++++++++++++++++++++++++------ 1 file changed, 83 insertions(+), 15 deletions(-) diff --git a/src/core/hle/D3D8/XbState.cpp b/src/core/hle/D3D8/XbState.cpp index 6f5558150..fe617acb7 100644 --- a/src/core/hle/D3D8/XbState.cpp +++ b/src/core/hle/D3D8/XbState.cpp @@ -300,21 +300,89 @@ void UpdateDeferredTextureStates() case XTL::X_D3DTSS_ALPHAOP: // TODO: Use a lookup table, this is not always a 1:1 map (same as D3DTSS_COLOROP) if (Value != X_D3DTSS_UNK) { - if (Value > XTL::X_D3DTOP_BLENDDIFFUSEALPHA && Value != XTL::X_D3DTOP_BLENDTEXTUREALPHA && Value != XTL::X_D3DTOP_BLENDCURRENTALPHA) { - EmuLog(LOG_LEVEL::WARNING, "Unsupported D3DTSS_ALPHAOP Value (%d)", Value); - } else if (Value == XTL::X_D3DTOP_BLENDTEXTUREALPHA) { - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_BLENDTEXTUREALPHA); - } - - if (Value == XTL::X_D3DTOP_BLENDFACTORALPHA) { - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_BLENDFACTORALPHA); - } - - if (Value == XTL::X_D3DTOP_BLENDCURRENTALPHA) { - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_BLENDCURRENTALPHA); - } else { - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, Value); - } + switch (Value) { + case XTL::X_D3DTOP_DISABLE: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_DISABLE); + break; + case XTL::X_D3DTOP_SELECTARG1: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_SELECTARG1); + break; + case XTL::X_D3DTOP_SELECTARG2: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_SELECTARG2); + break; + case XTL::X_D3DTOP_MODULATE: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_MODULATE); + break; + case XTL::X_D3DTOP_MODULATE2X: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_MODULATE2X); + break; + case XTL::X_D3DTOP_MODULATE4X: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_MODULATE4X); + break; + case XTL::X_D3DTOP_ADD: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_ADD); + break; + case XTL::X_D3DTOP_ADDSIGNED: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_ADDSIGNED); + break; + case XTL::X_D3DTOP_ADDSIGNED2X: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_ADDSIGNED2X); + break; + case XTL::X_D3DTOP_SUBTRACT: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_SUBTRACT); + break; + case XTL::X_D3DTOP_ADDSMOOTH: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_ADDSMOOTH); + break; + case XTL::X_D3DTOP_BLENDDIFFUSEALPHA: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_BLENDDIFFUSEALPHA); + break; + case XTL::X_D3DTOP_BLENDTEXTUREALPHA: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_BLENDTEXTUREALPHA); + break; + case XTL::X_D3DTOP_BLENDFACTORALPHA: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_BLENDFACTORALPHA); + break; + case XTL::X_D3DTOP_BLENDTEXTUREALPHAPM: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_BLENDTEXTUREALPHAPM); + break; + case XTL::X_D3DTOP_BLENDCURRENTALPHA: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_BLENDCURRENTALPHA); + break; + case XTL::X_D3DTOP_PREMODULATE: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_PREMODULATE); + break; + case XTL::X_D3DTOP_MODULATEALPHA_ADDCOLOR: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_MODULATEALPHA_ADDCOLOR); + break; + case XTL::X_D3DTOP_MODULATECOLOR_ADDALPHA: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_MODULATECOLOR_ADDALPHA); + break; + case XTL::X_D3DTOP_MODULATEINVALPHA_ADDCOLOR: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_MODULATEINVALPHA_ADDCOLOR); + break; + case XTL::X_D3DTOP_MODULATEINVCOLOR_ADDALPHA: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_MODULATEINVCOLOR_ADDALPHA); + break; + case XTL::X_D3DTOP_DOTPRODUCT3: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_DOTPRODUCT3); + break; + case XTL::X_D3DTOP_MULTIPLYADD: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_MULTIPLYADD); + break; + case XTL::X_D3DTOP_LERP: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_LERP); + break; + case XTL::X_D3DTOP_BUMPENVMAP: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_BUMPENVMAP); + break; + case XTL::X_D3DTOP_BUMPENVMAPLUMINANCE: + g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_BUMPENVMAPLUMINANCE); + break; + default: + EmuLog(LOG_LEVEL::WARNING, "Unsupported D3DTSS_ALPHAOP Value (%d)", Value); + break; + } } break; case XTL::X_D3DTSS_ALPHAARG0: From c37fe2595ea81eed2e93b0722c0007a1f8652309 Mon Sep 17 00:00:00 2001 From: Luke Usher Date: Fri, 5 Apr 2019 09:42:30 +0100 Subject: [PATCH 05/12] Fix broken textures caused by off-by-one error (solve regressions) --- src/core/hle/D3D8/XbState.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/hle/D3D8/XbState.cpp b/src/core/hle/D3D8/XbState.cpp index fe617acb7..21b58a67f 100644 --- a/src/core/hle/D3D8/XbState.cpp +++ b/src/core/hle/D3D8/XbState.cpp @@ -170,7 +170,7 @@ void UpdateDeferredTextureStates() } // These states match the PC counterpart IDs - g_pD3DDevice->SetSamplerState(Stage, (XTL::D3DSAMPLERSTATETYPE)State, Value); + g_pD3DDevice->SetSamplerState(Stage, (XTL::D3DSAMPLERSTATETYPE)(State + 1), Value); break; case XTL::X_D3DTSS_MAGFILTER: case XTL::X_D3DTSS_MINFILTER: case XTL::X_D3DTSS_MIPFILTER: if (Value == XTL::X_D3DTEXF_QUINCUNX) { From 9897c8daebaa7a132de40e9b5e456e798128d51a Mon Sep 17 00:00:00 2001 From: Luke Usher Date: Fri, 5 Apr 2019 09:44:54 +0100 Subject: [PATCH 06/12] Explicitly map RenderState values Prevents incorrect mappings from going accidentally un-noticed Also implements X_D3DRS_WRAP2/X_D3DRS_WRAP3, as well as D3DWRAPCOORD_3 which were previously ignored. --- src/core/hle/D3D8/XbState.cpp | 88 ++++++++++++++++++++++++----------- 1 file changed, 60 insertions(+), 28 deletions(-) diff --git a/src/core/hle/D3D8/XbState.cpp b/src/core/hle/D3D8/XbState.cpp index 21b58a67f..d6bc53b24 100644 --- a/src/core/hle/D3D8/XbState.cpp +++ b/src/core/hle/D3D8/XbState.cpp @@ -79,38 +79,70 @@ void UpdateDeferredRenderStates() // Certain D3DRS values need to be checked on each Draw[Indexed]Vertices if (XTL::EmuD3DDeferredRenderState != 0) { // Loop through all deferred render states - for (unsigned int RenderState = XTL::X_D3DRS_FOGENABLE; RenderState <= XTL::X_D3DRS_PATCHSEGMENTS; RenderState++) { - // If this render state does not have a PC counterpart, skip it + for (unsigned int RenderState = XTL::X_D3DRS_FOGENABLE; RenderState <= XTL::X_D3DRS_PRESENTATIONINTERVAL; RenderState++) { + uint8_t index = RenderState - XTL::X_D3DRS_FOGENABLE; + DWORD Value = XTL::EmuD3DDeferredRenderState[index]; + + // Convert from Xbox Data Formats to PC + switch (RenderState) { + case XTL::X_D3DRS_FOGENABLE: + case XTL::X_D3DRS_FOGTABLEMODE: + case XTL::X_D3DRS_FOGSTART: + case XTL::X_D3DRS_FOGEND: + case XTL::X_D3DRS_FOGDENSITY: + case XTL::X_D3DRS_RANGEFOGENABLE: + case XTL::X_D3DRS_LIGHTING: + case XTL::X_D3DRS_SPECULARENABLE: + case XTL::X_D3DRS_LOCALVIEWER: + case XTL::X_D3DRS_COLORVERTEX: + case XTL::X_D3DRS_SPECULARMATERIALSOURCE: + case XTL::X_D3DRS_DIFFUSEMATERIALSOURCE: + case XTL::X_D3DRS_AMBIENTMATERIALSOURCE: + case XTL::X_D3DRS_EMISSIVEMATERIALSOURCE: + case XTL::X_D3DRS_AMBIENT: + case XTL::X_D3DRS_POINTSIZE: + case XTL::X_D3DRS_POINTSIZE_MIN: + case XTL::X_D3DRS_POINTSPRITEENABLE: + case XTL::X_D3DRS_POINTSCALEENABLE: + case XTL::X_D3DRS_POINTSCALE_A: + case XTL::X_D3DRS_POINTSCALE_B: + case XTL::X_D3DRS_POINTSCALE_C: + case XTL::X_D3DRS_POINTSIZE_MAX: + case XTL::X_D3DRS_PATCHEDGESTYLE: + case XTL::X_D3DRS_PATCHSEGMENTS: + // These render states require no conversion, so we can use them as-is + break; + case XTL::X_D3DRS_BACKSPECULARMATERIALSOURCE: + case XTL::X_D3DRS_BACKDIFFUSEMATERIALSOURCE: + case XTL::X_D3DRS_BACKAMBIENTMATERIALSOURCE: + case XTL::X_D3DRS_BACKEMISSIVEMATERIALSOURCE: + case XTL::X_D3DRS_BACKAMBIENT: + case XTL::X_D3DRS_SWAPFILTER: + case XTL::X_D3DRS_PRESENTATIONINTERVAL: + // These render states are unsupported by the host, so we skip them entirely + continue; + case XTL::X_D3DRS_WRAP0: + case XTL::X_D3DRS_WRAP1: + case XTL::X_D3DRS_WRAP2: + case XTL::X_D3DRS_WRAP3: { + DWORD OldValue = Value; + Value = 0; + + Value |= (OldValue & 0x00000010) ? D3DWRAPCOORD_0 : 0; + Value |= (OldValue & 0x00001000) ? D3DWRAPCOORD_1 : 0; + Value |= (OldValue & 0x00100000) ? D3DWRAPCOORD_2 : 0; + Value |= (OldValue & 0x01000000) ? D3DWRAPCOORD_3 : 0; + } break; + default: + EmuLog(LOG_LEVEL::WARNING, "Unimplemented Deferred Render State: %s", XTL::DxbxRenderStateInfo[RenderState].S); + continue; + } + if (XTL::DxbxRenderStateInfo[RenderState].PC == 0) { continue; } - uint8_t index = RenderState - XTL::X_D3DRS_FOGENABLE; - // Some render states require special handling to convert to host, but most can be mapped 1:1 - // We use a switch/case to handle the special states - switch (RenderState) { - case XTL::X_D3DRS_WRAP0: { - ::DWORD dwConv = 0; - - dwConv |= (XTL::EmuD3DDeferredRenderState[index] & 0x00000010) ? D3DWRAP_U : 0; - dwConv |= (XTL::EmuD3DDeferredRenderState[index] & 0x00001000) ? D3DWRAP_V : 0; - dwConv |= (XTL::EmuD3DDeferredRenderState[index] & 0x00100000) ? D3DWRAP_W : 0; - - g_pD3DDevice->SetRenderState(XTL::D3DRS_WRAP0, dwConv); - } break; - case XTL::X_D3DRS_WRAP1: { - ::DWORD dwConv = 0; - - dwConv |= (XTL::EmuD3DDeferredRenderState[index] & 0x00000010) ? D3DWRAP_U : 0; - dwConv |= (XTL::EmuD3DDeferredRenderState[index] & 0x00001000) ? D3DWRAP_V : 0; - dwConv |= (XTL::EmuD3DDeferredRenderState[index] & 0x00100000) ? D3DWRAP_W : 0; - - g_pD3DDevice->SetRenderState(XTL::D3DRS_WRAP1, dwConv); - } break; - default: - g_pD3DDevice->SetRenderState(XTL::DxbxRenderStateInfo[RenderState].PC, XTL::EmuD3DDeferredRenderState[index]); - break; - } + g_pD3DDevice->SetRenderState(XTL::DxbxRenderStateInfo[RenderState].PC, Value); } } } From a4741d5c3ef2eb4aef8b28c849c591c38876f163 Mon Sep 17 00:00:00 2001 From: Luke Usher Date: Fri, 5 Apr 2019 10:48:23 +0100 Subject: [PATCH 07/12] Fix issue where Portable Mode would still default to AppData for EmuDisk --- src/common/Settings.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/common/Settings.cpp b/src/common/Settings.cpp index 82515ecb8..43bc7c203 100644 --- a/src/common/Settings.cpp +++ b/src/common/Settings.cpp @@ -195,10 +195,12 @@ bool Settings::Init() int iRet = MessageBox(nullptr, szSettings_save_user_option_message, "Cxbx-Reloaded", MB_YESNOCANCEL | MB_ICONQUESTION); if (iRet == IDYES) { - saveFile = GenerateExecDirectoryStr(); + saveFile = GenerateExecDirectoryStr(); + m_gui.DataStorageToggle = CXBX_DATA_EXECDIR; } else if (iRet == IDNO){ - saveFile = GenerateUserProfileDirectoryStr(); + saveFile = GenerateUserProfileDirectoryStr(); + m_gui.DataStorageToggle = CXBX_DATA_APPDATA; if (saveFile.size() == 0) { return false; } @@ -221,7 +223,7 @@ bool Settings::Init() saveFile.append(szSettings_settings_file); // Call LoadConfig, this will load the config, applying defaults for any missing fields - bRet = LoadConfig(); + bRet = LoadConfig(); if (!bRet) { MessageBox(nullptr, szSettings_setup_error, "Cxbx-Reloaded", MB_OK); @@ -293,7 +295,7 @@ bool Settings::LoadConfig() m_gui.szCxbxDebugFile = si_data; } - m_gui.DataStorageToggle = m_si.GetLongValue(section_gui, sect_gui_keys.DataStorageToggle, /*Default=*/CXBX_DATA_APPDATA); + m_gui.DataStorageToggle = m_si.GetLongValue(section_gui, sect_gui_keys.DataStorageToggle, /*Default=*/m_gui.DataStorageToggle); si_data = m_si.GetValue(section_gui, sect_gui_keys.DataCustomLocation, /*Default=*/nullptr); // Fallback to null string if value is empty or contains a bigger string. if (si_data == nullptr || std::strlen(si_data) >= MAX_PATH) { From 2d8f5124daa298278e001c083a96dad6346f1f9f Mon Sep 17 00:00:00 2001 From: Luke Usher Date: Fri, 5 Apr 2019 14:30:00 +0100 Subject: [PATCH 08/12] Improve mappings of D3DTOP values for earlier XDKs TODO: Verify when the values changed, it must be somewhere between 3911 and 4361 but where? --- src/core/hle/D3D8/XbState.cpp | 74 +++++++++++++++++++++++++++++------ 1 file changed, 62 insertions(+), 12 deletions(-) diff --git a/src/core/hle/D3D8/XbState.cpp b/src/core/hle/D3D8/XbState.cpp index d6bc53b24..b8d194581 100644 --- a/src/core/hle/D3D8/XbState.cpp +++ b/src/core/hle/D3D8/XbState.cpp @@ -165,6 +165,53 @@ DWORD GetDeferredTextureStateFromIndex(DWORD State) return State; } +DWORD Map3911ToCxbxD3DTOP(DWORD Value) +{ + switch (Value) { + case 1: return XTL::X_D3DTOP_DISABLE; + case 2: return XTL::X_D3DTOP_SELECTARG1; + case 3: return XTL::X_D3DTOP_SELECTARG2; + case 4: return XTL::X_D3DTOP_MODULATE; + case 5: return XTL::X_D3DTOP_MODULATE2X; + case 6: return XTL::X_D3DTOP_MODULATE4X; + case 7: return XTL::X_D3DTOP_ADD; + case 8: return XTL::X_D3DTOP_ADDSIGNED; + case 9: return XTL::X_D3DTOP_ADDSIGNED2X; + case 10: return XTL::X_D3DTOP_SUBTRACT; + case 11: return XTL::X_D3DTOP_ADDSMOOTH; + case 12: return XTL::X_D3DTOP_BLENDDIFFUSEALPHA; + case 13: return XTL::X_D3DTOP_BLENDTEXTUREALPHA; + case 14: return XTL::X_D3DTOP_BLENDFACTORALPHA; + case 15: return XTL::X_D3DTOP_BLENDTEXTUREALPHAPM; + case 16: return XTL::X_D3DTOP_BLENDCURRENTALPHA; + case 17: return XTL::X_D3DTOP_PREMODULATE; + case 18: return XTL::X_D3DTOP_MODULATEALPHA_ADDCOLOR; + case 19: return XTL::X_D3DTOP_MODULATECOLOR_ADDALPHA; + case 20: return XTL::X_D3DTOP_MODULATEINVALPHA_ADDCOLOR; + case 21: return XTL::X_D3DTOP_MODULATEINVCOLOR_ADDALPHA; + case 22: return XTL::X_D3DTOP_BUMPENVMAP; + case 23: return XTL::X_D3DTOP_BUMPENVMAPLUMINANCE; + case 24: return XTL::X_D3DTOP_DOTPRODUCT3; + case 25: return XTL::X_D3DTOP_MULTIPLYADD; + case 26: return XTL::X_D3DTOP_LERP; + } + + EmuLog(LOG_LEVEL::WARNING, "Unknown X_D3DTOP Value"); + return Value; +} + +DWORD TranslateXDKSpecificD3DTOP(DWORD Value) +{ + if (g_BuildVersion >= 4361) { + // For these XDKs, the mapping has been confirmed to match our internal mapping + return Value; + } + + // TODO: Did these values change after 3911 but before 4361? + // For now, assume they didn't and use the 3911 mappings + return Map3911ToCxbxD3DTOP(Value); +} + void UpdateDeferredTextureStates() { // Iterate through all deferred texture states/stages @@ -176,6 +223,13 @@ void UpdateDeferredTextureStates() } for (int StageIndex = 0; StageIndex < XTL::X_D3DTS_STAGECOUNT; StageIndex++) { + DWORD Stage = StageIndex; + + // If point sprites are enabled, we need to overwrite our existing state 0 with State 3 also + if (pointSpriteOverride && Stage == 3) { + Stage = 0; + } + for (int StateIndex = XTL::X_D3DTSS_DEFERRED_FIRST; StateIndex <= XTL::X_D3DTSS_DEFERRED_LAST; StateIndex++) { // Read the value of the current stage/state from the Xbox data structure DWORD Value = XTL::EmuD3DDeferredTextureState[(StageIndex * XTL::X_D3DTS_STAGESIZE) + StateIndex]; @@ -183,16 +237,7 @@ void UpdateDeferredTextureStates() // Convert the index of the current state to an index that we can use // This handles the case when XDKs have different state values DWORD State = GetDeferredTextureStateFromIndex(StateIndex); - DWORD Stage = StageIndex; - // If point sprites are enabled, we need to overwrite our existing state 0 with State 3 also - if (pointSpriteOverride && Stage == 3) { - Stage = 0; - - // Make sure we only do this once - pointSpriteOverride = false; - StageIndex--; // Force Stage 3 to repeat, without this hack next time - } switch (State) { case XTL::X_D3DTSS_ADDRESSU: case XTL::X_D3DTSS_ADDRESSV: case XTL::X_D3DTSS_ADDRESSW: @@ -235,8 +280,7 @@ void UpdateDeferredTextureStates() //EmuLog(LOG_LEVEL::WARNING, "D3DTSS_ALPHAKILL is unsupported"); break; case XTL::X_D3DTSS_COLOROP: - // TODO: This would be better split into it's own function, or a lookup array - switch (Value) { + switch (TranslateXDKSpecificD3DTOP(Value)) { case XTL::X_D3DTOP_DISABLE: g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_DISABLE); break; @@ -332,7 +376,7 @@ void UpdateDeferredTextureStates() case XTL::X_D3DTSS_ALPHAOP: // TODO: Use a lookup table, this is not always a 1:1 map (same as D3DTSS_COLOROP) if (Value != X_D3DTSS_UNK) { - switch (Value) { + switch (TranslateXDKSpecificD3DTOP(Value)) { case XTL::X_D3DTOP_DISABLE: g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_DISABLE); break; @@ -437,6 +481,12 @@ void UpdateDeferredTextureStates() break; } } + + // Make sure we only do this once + if (pointSpriteOverride && Stage == 3) { + pointSpriteOverride = false; + StageIndex--; // Force Stage 3 to repeat, without this hack next time + } } if (XTL::EmuD3DDeferredRenderState[XTL::X_D3DRS_POINTSPRITEENABLE - XTL::X_D3DRS_FOGENABLE] == TRUE) { From 67569172cb9375c0fe4ec792253af7b6cc018a43 Mon Sep 17 00:00:00 2001 From: Luke Usher Date: Fri, 5 Apr 2019 14:45:00 +0100 Subject: [PATCH 09/12] More point sprite tweaks --- src/core/hle/D3D8/XbState.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/core/hle/D3D8/XbState.cpp b/src/core/hle/D3D8/XbState.cpp index b8d194581..4c2c44a1c 100644 --- a/src/core/hle/D3D8/XbState.cpp +++ b/src/core/hle/D3D8/XbState.cpp @@ -223,12 +223,8 @@ void UpdateDeferredTextureStates() } for (int StageIndex = 0; StageIndex < XTL::X_D3DTS_STAGECOUNT; StageIndex++) { - DWORD Stage = StageIndex; - // If point sprites are enabled, we need to overwrite our existing state 0 with State 3 also - if (pointSpriteOverride && Stage == 3) { - Stage = 0; - } + DWORD Stage = (pointSpriteOverride && StageIndex == 3) ? 0 : StageIndex; for (int StateIndex = XTL::X_D3DTSS_DEFERRED_FIRST; StateIndex <= XTL::X_D3DTSS_DEFERRED_LAST; StateIndex++) { // Read the value of the current stage/state from the Xbox data structure @@ -483,9 +479,8 @@ void UpdateDeferredTextureStates() } // Make sure we only do this once - if (pointSpriteOverride && Stage == 3) { + if (pointSpriteOverride && StageIndex == 3) { pointSpriteOverride = false; - StageIndex--; // Force Stage 3 to repeat, without this hack next time } } From 04b311ec8c0bcab23efa3ab2b80334c2fe95750e Mon Sep 17 00:00:00 2001 From: Luke Usher Date: Fri, 5 Apr 2019 15:09:21 +0100 Subject: [PATCH 10/12] Restore StageIndex-- --- src/core/hle/D3D8/XbState.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/hle/D3D8/XbState.cpp b/src/core/hle/D3D8/XbState.cpp index 4c2c44a1c..8a4e124cd 100644 --- a/src/core/hle/D3D8/XbState.cpp +++ b/src/core/hle/D3D8/XbState.cpp @@ -234,7 +234,6 @@ void UpdateDeferredTextureStates() // This handles the case when XDKs have different state values DWORD State = GetDeferredTextureStateFromIndex(StateIndex); - switch (State) { case XTL::X_D3DTSS_ADDRESSU: case XTL::X_D3DTSS_ADDRESSV: case XTL::X_D3DTSS_ADDRESSW: if (Value == XTL::X_D3DTADDRESS_CLAMPTOEDGE) { @@ -481,6 +480,7 @@ void UpdateDeferredTextureStates() // Make sure we only do this once if (pointSpriteOverride && StageIndex == 3) { pointSpriteOverride = false; + StageIndex--; } } From 372de28d7b0f437c7a4667703675fa084c1e38f8 Mon Sep 17 00:00:00 2001 From: Luke Usher Date: Sat, 6 Apr 2019 14:07:43 +0100 Subject: [PATCH 11/12] Reduce D3DTOP >= 4361 exception to >= 4134: Fixes DOA3 PAL --- src/core/hle/D3D8/XbState.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/core/hle/D3D8/XbState.cpp b/src/core/hle/D3D8/XbState.cpp index 8a4e124cd..4cb1011b9 100644 --- a/src/core/hle/D3D8/XbState.cpp +++ b/src/core/hle/D3D8/XbState.cpp @@ -201,14 +201,15 @@ DWORD Map3911ToCxbxD3DTOP(DWORD Value) } DWORD TranslateXDKSpecificD3DTOP(DWORD Value) -{ - if (g_BuildVersion >= 4361) { +{ + // TODO: Determine when exactly these values changed + // So far, 4134 is the earliest version we've seen using these mappings + // But this may change + if (g_BuildVersion >= 4134) { // For these XDKs, the mapping has been confirmed to match our internal mapping return Value; } - // TODO: Did these values change after 3911 but before 4361? - // For now, assume they didn't and use the 3911 mappings return Map3911ToCxbxD3DTOP(Value); } From a0e8bb897345f55732cd4d8d451cd3c233375be3 Mon Sep 17 00:00:00 2001 From: Luke Usher Date: Sun, 7 Apr 2019 09:21:11 +0100 Subject: [PATCH 12/12] Feedback --- src/core/hle/D3D8/Direct3D9/Direct3D9.cpp | 1 + src/core/hle/D3D8/XbConvert.h | 4 +- src/core/hle/D3D8/XbState.cpp | 150 +++++++++++----------- 3 files changed, 79 insertions(+), 76 deletions(-) diff --git a/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp b/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp index 8fcbd1180..c71b55b7d 100644 --- a/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp +++ b/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp @@ -6084,6 +6084,7 @@ VOID __fastcall XTL::EMUPATCH(D3DDevice_SetRenderState_Simple) for (int i = 0; i <= X_D3DRS_DONOTCULLUNCOMPRESSED; i++) { if (DxbxRenderStateInfo[i].M == (Method & 0x00001FFC)) { XboxRenderStateIndex = i; + break; } } diff --git a/src/core/hle/D3D8/XbConvert.h b/src/core/hle/D3D8/XbConvert.h index 01e46a7db..e7afacb3e 100644 --- a/src/core/hle/D3D8/XbConvert.h +++ b/src/core/hle/D3D8/XbConvert.h @@ -155,8 +155,8 @@ inline D3DBLEND EmuXB2PC_D3DBLEND(X_D3DBLEND Value) case 0x306: return D3DBLEND_DESTCOLOR; case 0x307: return D3DBLEND_INVDESTCOLOR; case 0x308: return D3DBLEND_SRCALPHASAT; - case 0x8001:return D3DBLEND_BLENDFACTOR; - case 0x8002:return D3DBLEND_INVBLENDFACTOR; + case 0x8001:return D3DBLEND_BLENDFACTOR; // Maps Xbox D3DBLEND_CONSTANTCOLOR + case 0x8002:return D3DBLEND_INVBLENDFACTOR; // Maps Xbox D3DBLEND_INVCONSTANTCOLOR case 0x8003: EmuLogEx(LOG_PREFIX_D3DCVT, LOG_LEVEL::WARNING, "Unsupported Xbox D3DBlend Extension: D3DBLEND_CONSTANTALPHA"); return D3DBLEND_ONE; case 0x8004: EmuLogEx(LOG_PREFIX_D3DCVT, LOG_LEVEL::WARNING, "Unsupported Xbox D3DBlend Extension: D3DBLEND_INVCONSTANTALPHA"); return D3DBLEND_ONE; } diff --git a/src/core/hle/D3D8/XbState.cpp b/src/core/hle/D3D8/XbState.cpp index 4cb1011b9..b7e31c317 100644 --- a/src/core/hle/D3D8/XbState.cpp +++ b/src/core/hle/D3D8/XbState.cpp @@ -217,25 +217,27 @@ void UpdateDeferredTextureStates() { // Iterate through all deferred texture states/stages - // Track if we need to overwrite state 0 with 3 because of Point Sprites + // Track if we need to overwrite state 0 with 3 because of Point Sprites + // The Xbox NV2A uses only Stage 3 for point-sprites, so we emulate this + // by mapping Stage 3 to Stage 0, and disabling all stages > 0 bool pointSpriteOverride = false; if (XTL::EmuD3DDeferredRenderState[XTL::X_D3DRS_POINTSPRITEENABLE - XTL::X_D3DRS_FOGENABLE] == TRUE) { pointSpriteOverride = true; } - for (int StageIndex = 0; StageIndex < XTL::X_D3DTS_STAGECOUNT; StageIndex++) { + for (int XboxStage = 0; XboxStage < XTL::X_D3DTS_STAGECOUNT; XboxStage++) { // If point sprites are enabled, we need to overwrite our existing state 0 with State 3 also - DWORD Stage = (pointSpriteOverride && StageIndex == 3) ? 0 : StageIndex; + DWORD HostStage = (pointSpriteOverride && XboxStage == 3) ? 0 : XboxStage; for (int StateIndex = XTL::X_D3DTSS_DEFERRED_FIRST; StateIndex <= XTL::X_D3DTSS_DEFERRED_LAST; StateIndex++) { // Read the value of the current stage/state from the Xbox data structure - DWORD Value = XTL::EmuD3DDeferredTextureState[(StageIndex * XTL::X_D3DTS_STAGESIZE) + StateIndex]; + DWORD Value = XTL::EmuD3DDeferredTextureState[(XboxStage * XTL::X_D3DTS_STAGESIZE) + StateIndex]; // Convert the index of the current state to an index that we can use // This handles the case when XDKs have different state values - DWORD State = GetDeferredTextureStateFromIndex(StateIndex); + DWORD XboxState = GetDeferredTextureStateFromIndex(StateIndex); - switch (State) { + switch (XboxState) { case XTL::X_D3DTSS_ADDRESSU: case XTL::X_D3DTSS_ADDRESSV: case XTL::X_D3DTSS_ADDRESSW: if (Value == XTL::X_D3DTADDRESS_CLAMPTOEDGE) { EmuLog(LOG_LEVEL::WARNING, "ClampToEdge is unsupported"); @@ -243,7 +245,7 @@ void UpdateDeferredTextureStates() } // These states match the PC counterpart IDs - g_pD3DDevice->SetSamplerState(Stage, (XTL::D3DSAMPLERSTATETYPE)(State + 1), Value); + g_pD3DDevice->SetSamplerState(HostStage, (XTL::D3DSAMPLERSTATETYPE)(XboxState + 1), Value); break; case XTL::X_D3DTSS_MAGFILTER: case XTL::X_D3DTSS_MINFILTER: case XTL::X_D3DTSS_MIPFILTER: if (Value == XTL::X_D3DTEXF_QUINCUNX) { @@ -252,16 +254,16 @@ void UpdateDeferredTextureStates() } // These states (when incremented by 2) match the PC counterpart IDs - g_pD3DDevice->SetSamplerState(Stage, (XTL::D3DSAMPLERSTATETYPE)(State + 2), Value); + g_pD3DDevice->SetSamplerState(HostStage, (XTL::D3DSAMPLERSTATETYPE)(XboxState + 2), Value); break; case XTL::X_D3DTSS_MIPMAPLODBIAS: - g_pD3DDevice->SetSamplerState(Stage, XTL::D3DSAMP_MIPMAPLODBIAS, Value); + g_pD3DDevice->SetSamplerState(HostStage, XTL::D3DSAMP_MIPMAPLODBIAS, Value); break; case XTL::X_D3DTSS_MAXMIPLEVEL: - g_pD3DDevice->SetSamplerState(Stage, XTL::D3DSAMP_MAXMIPLEVEL, Value); + g_pD3DDevice->SetSamplerState(HostStage, XTL::D3DSAMP_MAXMIPLEVEL, Value); break; case XTL::X_D3DTSS_MAXANISOTROPY: - g_pD3DDevice->SetSamplerState(Stage, XTL::D3DSAMP_MAXANISOTROPY, Value); + g_pD3DDevice->SetSamplerState(HostStage, XTL::D3DSAMP_MAXANISOTROPY, Value); break; case XTL::X_D3DTSS_COLORKEYOP: // Xbox ext // Logging Disabled: Causes Dashboard to slow down massively @@ -278,82 +280,82 @@ void UpdateDeferredTextureStates() case XTL::X_D3DTSS_COLOROP: switch (TranslateXDKSpecificD3DTOP(Value)) { case XTL::X_D3DTOP_DISABLE: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_DISABLE); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_DISABLE); break; case XTL::X_D3DTOP_SELECTARG1: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_SELECTARG1); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_SELECTARG1); break; case XTL::X_D3DTOP_SELECTARG2: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_SELECTARG2); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_SELECTARG2); break; case XTL::X_D3DTOP_MODULATE: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_MODULATE); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_MODULATE); break; case XTL::X_D3DTOP_MODULATE2X: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_MODULATE2X); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_MODULATE2X); break; case XTL::X_D3DTOP_MODULATE4X: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_MODULATE4X); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_MODULATE4X); break; case XTL::X_D3DTOP_ADD: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_ADD); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_ADD); break; case XTL::X_D3DTOP_ADDSIGNED: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_ADDSIGNED); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_ADDSIGNED); break; case XTL::X_D3DTOP_ADDSIGNED2X: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_ADDSIGNED2X); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_ADDSIGNED2X); break; case XTL::X_D3DTOP_SUBTRACT: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_SUBTRACT); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_SUBTRACT); break; case XTL::X_D3DTOP_ADDSMOOTH: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_ADDSMOOTH); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_ADDSMOOTH); break; case XTL::X_D3DTOP_BLENDDIFFUSEALPHA: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_BLENDDIFFUSEALPHA); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_BLENDDIFFUSEALPHA); break; case XTL::X_D3DTOP_BLENDCURRENTALPHA: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_BLENDCURRENTALPHA); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_BLENDCURRENTALPHA); break; case XTL::X_D3DTOP_BLENDTEXTUREALPHA: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_BLENDTEXTUREALPHA); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_BLENDTEXTUREALPHA); break; case XTL::X_D3DTOP_BLENDFACTORALPHA: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_BLENDFACTORALPHA); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_BLENDFACTORALPHA); break; case XTL::X_D3DTOP_BLENDTEXTUREALPHAPM: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_BLENDTEXTUREALPHAPM); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_BLENDTEXTUREALPHAPM); break; case XTL::X_D3DTOP_PREMODULATE: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_PREMODULATE); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_PREMODULATE); break; case XTL::X_D3DTOP_MODULATEALPHA_ADDCOLOR: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_MODULATEALPHA_ADDCOLOR); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_MODULATEALPHA_ADDCOLOR); break; case XTL::X_D3DTOP_MODULATECOLOR_ADDALPHA: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_MODULATECOLOR_ADDALPHA); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_MODULATECOLOR_ADDALPHA); break; case XTL::X_D3DTOP_MODULATEINVALPHA_ADDCOLOR: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_MODULATEINVALPHA_ADDCOLOR); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_MODULATEINVALPHA_ADDCOLOR); break; case XTL::X_D3DTOP_MODULATEINVCOLOR_ADDALPHA: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_MODULATEINVCOLOR_ADDALPHA); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_MODULATEINVCOLOR_ADDALPHA); break; case XTL::X_D3DTOP_DOTPRODUCT3: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_DOTPRODUCT3); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_DOTPRODUCT3); break; case XTL::X_D3DTOP_MULTIPLYADD: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_MULTIPLYADD); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_MULTIPLYADD); break; case XTL::X_D3DTOP_LERP: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_LERP); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_LERP); break; case XTL::X_D3DTOP_BUMPENVMAP: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_BUMPENVMAP); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_BUMPENVMAP); break; case XTL::X_D3DTOP_BUMPENVMAPLUMINANCE: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_BUMPENVMAPLUMINANCE); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_COLOROP, XTL::D3DTOP_BUMPENVMAPLUMINANCE); break; default: EmuLog(LOG_LEVEL::WARNING, "Unsupported D3DTSS_COLOROP Value (%d)", Value); @@ -361,95 +363,95 @@ void UpdateDeferredTextureStates() } break; case XTL::X_D3DTSS_COLORARG0: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLORARG0, Value); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_COLORARG0, Value); break; case XTL::X_D3DTSS_COLORARG1: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLORARG1, Value); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_COLORARG1, Value); break; case XTL::X_D3DTSS_COLORARG2: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_COLORARG2, Value); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_COLORARG2, Value); break; case XTL::X_D3DTSS_ALPHAOP: // TODO: Use a lookup table, this is not always a 1:1 map (same as D3DTSS_COLOROP) if (Value != X_D3DTSS_UNK) { switch (TranslateXDKSpecificD3DTOP(Value)) { case XTL::X_D3DTOP_DISABLE: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_DISABLE); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_DISABLE); break; case XTL::X_D3DTOP_SELECTARG1: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_SELECTARG1); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_SELECTARG1); break; case XTL::X_D3DTOP_SELECTARG2: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_SELECTARG2); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_SELECTARG2); break; case XTL::X_D3DTOP_MODULATE: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_MODULATE); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_MODULATE); break; case XTL::X_D3DTOP_MODULATE2X: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_MODULATE2X); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_MODULATE2X); break; case XTL::X_D3DTOP_MODULATE4X: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_MODULATE4X); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_MODULATE4X); break; case XTL::X_D3DTOP_ADD: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_ADD); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_ADD); break; case XTL::X_D3DTOP_ADDSIGNED: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_ADDSIGNED); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_ADDSIGNED); break; case XTL::X_D3DTOP_ADDSIGNED2X: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_ADDSIGNED2X); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_ADDSIGNED2X); break; case XTL::X_D3DTOP_SUBTRACT: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_SUBTRACT); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_SUBTRACT); break; case XTL::X_D3DTOP_ADDSMOOTH: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_ADDSMOOTH); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_ADDSMOOTH); break; case XTL::X_D3DTOP_BLENDDIFFUSEALPHA: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_BLENDDIFFUSEALPHA); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_BLENDDIFFUSEALPHA); break; case XTL::X_D3DTOP_BLENDTEXTUREALPHA: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_BLENDTEXTUREALPHA); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_BLENDTEXTUREALPHA); break; case XTL::X_D3DTOP_BLENDFACTORALPHA: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_BLENDFACTORALPHA); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_BLENDFACTORALPHA); break; case XTL::X_D3DTOP_BLENDTEXTUREALPHAPM: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_BLENDTEXTUREALPHAPM); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_BLENDTEXTUREALPHAPM); break; case XTL::X_D3DTOP_BLENDCURRENTALPHA: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_BLENDCURRENTALPHA); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_BLENDCURRENTALPHA); break; case XTL::X_D3DTOP_PREMODULATE: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_PREMODULATE); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_PREMODULATE); break; case XTL::X_D3DTOP_MODULATEALPHA_ADDCOLOR: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_MODULATEALPHA_ADDCOLOR); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_MODULATEALPHA_ADDCOLOR); break; case XTL::X_D3DTOP_MODULATECOLOR_ADDALPHA: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_MODULATECOLOR_ADDALPHA); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_MODULATECOLOR_ADDALPHA); break; case XTL::X_D3DTOP_MODULATEINVALPHA_ADDCOLOR: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_MODULATEINVALPHA_ADDCOLOR); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_MODULATEINVALPHA_ADDCOLOR); break; case XTL::X_D3DTOP_MODULATEINVCOLOR_ADDALPHA: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_MODULATEINVCOLOR_ADDALPHA); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_MODULATEINVCOLOR_ADDALPHA); break; case XTL::X_D3DTOP_DOTPRODUCT3: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_DOTPRODUCT3); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_DOTPRODUCT3); break; case XTL::X_D3DTOP_MULTIPLYADD: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_MULTIPLYADD); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_MULTIPLYADD); break; case XTL::X_D3DTOP_LERP: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_LERP); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_LERP); break; case XTL::X_D3DTOP_BUMPENVMAP: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_BUMPENVMAP); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_BUMPENVMAP); break; case XTL::X_D3DTOP_BUMPENVMAPLUMINANCE: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_BUMPENVMAPLUMINANCE); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_ALPHAOP, XTL::D3DTOP_BUMPENVMAPLUMINANCE); break; default: EmuLog(LOG_LEVEL::WARNING, "Unsupported D3DTSS_ALPHAOP Value (%d)", Value); @@ -458,30 +460,30 @@ void UpdateDeferredTextureStates() } break; case XTL::X_D3DTSS_ALPHAARG0: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAARG0, Value); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_ALPHAARG0, Value); break; case XTL::X_D3DTSS_ALPHAARG1: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAARG1, Value); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_ALPHAARG1, Value); break; case XTL::X_D3DTSS_ALPHAARG2: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_ALPHAARG2, Value); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_ALPHAARG2, Value); break; case XTL::X_D3DTSS_RESULTARG: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_RESULTARG, Value); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_RESULTARG, Value); break; case XTL::X_D3DTSS_TEXTURETRANSFORMFLAGS: - g_pD3DDevice->SetTextureStageState(Stage, XTL::D3DTSS_TEXTURETRANSFORMFLAGS, Value); + g_pD3DDevice->SetTextureStageState(HostStage, XTL::D3DTSS_TEXTURETRANSFORMFLAGS, Value); break; default: - EmuLog(LOG_LEVEL::WARNING, "Unkown Xbox D3DTSS Value: %d", State); + EmuLog(LOG_LEVEL::WARNING, "Unkown Xbox D3DTSS Value: %d", XboxState); break; } } // Make sure we only do this once - if (pointSpriteOverride && StageIndex == 3) { + if (pointSpriteOverride && XboxStage == 3) { pointSpriteOverride = false; - StageIndex--; + XboxStage--; } }