Cleanup XbState code: Preparing for bug fixes/improvements
This commit is contained in:
parent
f58d3ce6cf
commit
ed559e5fd6
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<sizeof(unchecked)/sizeof(int);q++)
|
||||
{
|
||||
if(r == unchecked[q])
|
||||
{
|
||||
pass = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(pass)
|
||||
EmuLog(LOG_LEVEL::WARNING, "Unhandled TextureState Change @ %d->%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();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue