Convert D3DSHADEMODE from Xbox to PC.

Improved inline vertex buffer handling.

Support all Xbox primitives in VertexBuffer. Quads and convex polygons are rendered by using triangles, wireframe renderering and flat shading colors will thus not be emulated correctly. Indexed meshes will still fail on patched primitives (quad list and line loop) due to lack of index buffer patching.

New D3D8 5849 OOVPAs.
- IDirect3DDevice8::DrawIndexedVerticesUP
- Reuse IDirect3DResource8::IsBusy from 4361
This commit is contained in:
Daniel Stien 2008-09-06 23:33:44 +00:00
parent 2dcf87aed2
commit df0153d9d5
6 changed files with 320 additions and 486 deletions

View File

@ -3482,9 +3482,6 @@ HRESULT WINAPI XTL::EmuIDirect3DDevice8_Begin
");\n", ");\n",
GetCurrentThreadId(), PrimitiveType); GetCurrentThreadId(), PrimitiveType);
if((PrimitiveType != X_D3DPT_TRIANGLEFAN) && (PrimitiveType != X_D3DPT_QUADSTRIP) && (PrimitiveType != X_D3DPT_QUADLIST))
CxbxKrnlCleanup("EmuIDirect3DDevice8_Begin does not support primitive : %d", PrimitiveType);
g_IVBPrimitiveType = PrimitiveType; g_IVBPrimitiveType = PrimitiveType;
if(g_IVBTable == 0) if(g_IVBTable == 0)
@ -3597,6 +3594,8 @@ HRESULT WINAPI XTL::EmuIDirect3DDevice8_SetVertexData4f
switch(Register) switch(Register)
{ {
// TODO: Blend weight.
case 0: // D3DVSDE_POSITION case 0: // D3DVSDE_POSITION
{ {
int o = g_IVBTblOffs; int o = g_IVBTblOffs;
@ -3612,6 +3611,20 @@ HRESULT WINAPI XTL::EmuIDirect3DDevice8_SetVertexData4f
} }
break; break;
case 2: // D3DVSDE_NORMAL
{
int o = g_IVBTblOffs;
g_IVBTable[o].Normal.x = a;
g_IVBTable[o].Normal.y = b;
g_IVBTable[o].Normal.z = c;
g_IVBTblOffs++;
g_IVBFVF |= D3DFVF_NORMAL;
}
break;
case 3: // D3DVSDE_DIFFUSE case 3: // D3DVSDE_DIFFUSE
{ {
int o = g_IVBTblOffs; int o = g_IVBTblOffs;
@ -3707,6 +3720,10 @@ HRESULT WINAPI XTL::EmuIDirect3DDevice8_SetVertexData4f
g_IVBTable[o].Position.z = c; g_IVBTable[o].Position.z = c;
g_IVBTable[o].Rhw = d; g_IVBTable[o].Rhw = d;
// Copy current color to next vertex
g_IVBTable[o+1].dwDiffuse = g_IVBTable[o].dwDiffuse;
g_IVBTable[o+1].dwSpecular = g_IVBTable[o].dwSpecular;
g_IVBTblOffs++; g_IVBTblOffs++;
g_IVBFVF |= D3DFVF_XYZRHW; g_IVBFVF |= D3DFVF_XYZRHW;
@ -6149,7 +6166,7 @@ VOID __fastcall XTL::EmuIDirect3DDevice8_SetRenderState_Simple
break; break;
case D3DRS_SHADEMODE: case D3DRS_SHADEMODE:
Value = Value & 0x03; Value = EmuXB2PC_D3DSHADEMODE(Value);
DbgPrintf("D3DRS_SHADEMODE := 0x%.08X\n", Value); DbgPrintf("D3DRS_SHADEMODE := 0x%.08X\n", Value);
break; break;
@ -6962,19 +6979,10 @@ VOID WINAPI XTL::EmuIDirect3DDevice8_DrawVertices
EmuUpdateDeferredStates(); EmuUpdateDeferredStates();
if( (PrimitiveType == X_D3DPT_QUADSTRIP) || (PrimitiveType == X_D3DPT_POLYGON) )
EmuWarning("Unsupported PrimitiveType! (%d)", (DWORD)PrimitiveType);
UINT PrimitiveCount = EmuD3DVertex2PrimitiveCount(PrimitiveType, VertexCount);
// Convert from Xbox to PC enumeration
D3DPRIMITIVETYPE PCPrimitiveType = EmuPrimitiveType(PrimitiveType);
VertexPatchDesc VPDesc; VertexPatchDesc VPDesc;
VPDesc.dwVertexCount = VertexCount;
VPDesc.PrimitiveType = PrimitiveType; VPDesc.PrimitiveType = PrimitiveType;
VPDesc.dwPrimitiveCount = PrimitiveCount; VPDesc.dwVertexCount = VertexCount;
VPDesc.dwOffset = StartVertex; VPDesc.dwOffset = StartVertex;
VPDesc.pVertexStreamZeroData = 0; VPDesc.pVertexStreamZeroData = 0;
VPDesc.uiVertexStreamZeroStride = 0; VPDesc.uiVertexStreamZeroStride = 0;
@ -6987,24 +6995,17 @@ VOID WINAPI XTL::EmuIDirect3DDevice8_DrawVertices
if(IsValidCurrentShader()) if(IsValidCurrentShader())
{ {
#ifdef _DEBUG_TRACK_VB #ifdef _DEBUG_TRACK_VB
if(g_bVBSkipStream) if(!g_bVBSkipStream)
{
g_pD3DDevice8->DrawPrimitive
(
PCPrimitiveType,
StartVertex,
0
);
}
else
{ {
#endif #endif
g_pD3DDevice8->DrawPrimitive g_pD3DDevice8->DrawPrimitive
( (
PCPrimitiveType, EmuPrimitiveType(VPDesc.PrimitiveType),
StartVertex, StartVertex,
VPDesc.dwPrimitiveCount VPDesc.dwPrimitiveCount
); );
#ifdef _DEBUG_TRACK_VB #ifdef _DEBUG_TRACK_VB
} }
#endif #endif
@ -7042,79 +7043,10 @@ VOID WINAPI XTL::EmuIDirect3DDevice8_DrawVerticesUP
EmuUpdateDeferredStates(); EmuUpdateDeferredStates();
if( (PrimitiveType == X_D3DPT_QUADSTRIP) || (PrimitiveType == X_D3DPT_POLYGON) )
CxbxKrnlCleanup("Unsupported PrimitiveType! (%d)", (DWORD)PrimitiveType);
/*
// DEBUG
{
static FLOAT fixer[] =
{
0.0f, 0.0f, 1.0f,
0.0f, 480.0f, 1.0f,
640.0f, 0.0f, 1.0f,
640.0f, 480.0f, 1.0f,
};
DWORD *pdwVB = (DWORD*)pVertexStreamZeroData;
for(uint r=0;r<VertexCount;r++)
{
pdwVB[0] = FtoDW(fixer[r*3+0]);
pdwVB[1] = FtoDW(fixer[r*3+1]);
pdwVB[2] = FtoDW(fixer[r*3+2]);
pdwVB[5] = 0xFFFFFFFF;
FLOAT px = DWtoF(pdwVB[0]);
FLOAT py = DWtoF(pdwVB[1]);
FLOAT pz = DWtoF(pdwVB[2]);
FLOAT rhw = DWtoF(pdwVB[3]);
DWORD dwDiffuse = pdwVB[5];
DWORD dwSpecular = pdwVB[4];
FLOAT tx = DWtoF(pdwVB[6]);
FLOAT ty = DWtoF(pdwVB[7]);
//D3DFVF_POSITION_MASK
printf("%.02d XYZ : {%.08f, %.08f, %.08f}\n", r, px, py, pz);
printf("%.02d RHW : %f\n", r, rhw);
printf("%.02d dwDiffuse : 0x%.08X\n", r, dwDiffuse);
printf("%.02d dwSpecular : 0x%.08X\n", r, dwSpecular);
printf("%.02d Tex1 : {%.08f, %.08f}\n", r, tx, ty);
printf("\n");
pdwVB += (VertexStreamZeroStride/4);
}
}
//*/
/*
IDirect3DBaseTexture8 *pTexture = 0;
g_pD3DDevice8->GetTexture(0, &pTexture);
if(pTexture != NULL)
{
static int dwDumpTexture = 0;
char szBuffer[255];
sprintf(szBuffer, "C:\\Aaron\\Textures\\Texture-Active%.03d.bmp", dwDumpTexture++);
D3DXSaveTextureToFile(szBuffer, D3DXIFF_BMP, pTexture, NULL);
}
//*/
UINT PrimitiveCount = EmuD3DVertex2PrimitiveCount(PrimitiveType, VertexCount);
// Convert from Xbox to PC enumeration
D3DPRIMITIVETYPE PCPrimitiveType = EmuPrimitiveType(PrimitiveType);
VertexPatchDesc VPDesc; VertexPatchDesc VPDesc;
VPDesc.dwVertexCount = VertexCount;
VPDesc.PrimitiveType = PrimitiveType; VPDesc.PrimitiveType = PrimitiveType;
VPDesc.dwPrimitiveCount = PrimitiveCount; VPDesc.dwVertexCount = VertexCount;
VPDesc.dwOffset = 0; VPDesc.dwOffset = 0;
VPDesc.pVertexStreamZeroData = pVertexStreamZeroData; VPDesc.pVertexStreamZeroData = pVertexStreamZeroData;
VPDesc.uiVertexStreamZeroStride = VertexStreamZeroStride; VPDesc.uiVertexStreamZeroStride = VertexStreamZeroStride;
@ -7133,7 +7065,7 @@ VOID WINAPI XTL::EmuIDirect3DDevice8_DrawVerticesUP
g_pD3DDevice8->DrawPrimitiveUP g_pD3DDevice8->DrawPrimitiveUP
( (
PCPrimitiveType, EmuPrimitiveType(VPDesc.PrimitiveType),
VPDesc.dwPrimitiveCount, VPDesc.dwPrimitiveCount,
VPDesc.pVertexStreamZeroData, VPDesc.pVertexStreamZeroData,
VPDesc.uiVertexStreamZeroStride VPDesc.uiVertexStreamZeroStride
@ -7206,19 +7138,13 @@ HRESULT WINAPI XTL::EmuIDirect3DDevice8_DrawIndexedVertices
EmuUpdateDeferredStates(); EmuUpdateDeferredStates();
if( (PrimitiveType == X_D3DPT_QUADLIST) || (PrimitiveType == X_D3DPT_QUADSTRIP) || (PrimitiveType == X_D3DPT_POLYGON) ) if( (PrimitiveType == X_D3DPT_LINELOOP) || (PrimitiveType == X_D3DPT_QUADLIST) )
EmuWarning("Unsupported PrimitiveType! (%d)", (DWORD)PrimitiveType); EmuWarning("Unsupported PrimitiveType! (%d)", (DWORD)PrimitiveType);
UINT PrimitiveCount = EmuD3DVertex2PrimitiveCount(PrimitiveType, VertexCount);
// Convert from Xbox to PC enumeration
D3DPRIMITIVETYPE PCPrimitiveType = EmuPrimitiveType(PrimitiveType);
VertexPatchDesc VPDesc; VertexPatchDesc VPDesc;
VPDesc.dwVertexCount = VertexCount;
VPDesc.PrimitiveType = PrimitiveType; VPDesc.PrimitiveType = PrimitiveType;
VPDesc.dwPrimitiveCount = PrimitiveCount; VPDesc.dwVertexCount = VertexCount;
VPDesc.dwOffset = 0; VPDesc.dwOffset = 0;
VPDesc.pVertexStreamZeroData = 0; VPDesc.pVertexStreamZeroData = 0;
VPDesc.uiVertexStreamZeroStride = 0; VPDesc.uiVertexStreamZeroStride = 0;
@ -7287,7 +7213,7 @@ HRESULT WINAPI XTL::EmuIDirect3DDevice8_DrawIndexedVertices
{ {
g_pD3DDevice8->DrawIndexedPrimitive g_pD3DDevice8->DrawIndexedPrimitive
( (
PCPrimitiveType, 0, uiNumVertices, uiStartIndex, VPDesc.dwPrimitiveCount EmuPrimitiveType(VPDesc.PrimitiveType), 0, uiNumVertices, uiStartIndex, VPDesc.dwPrimitiveCount
); );
} }
@ -7338,19 +7264,13 @@ VOID WINAPI XTL::EmuIDirect3DDevice8_DrawIndexedVerticesUP
EmuUpdateDeferredStates(); EmuUpdateDeferredStates();
if( (PrimitiveType == X_D3DPT_QUADLIST) || (PrimitiveType == X_D3DPT_QUADSTRIP) || (PrimitiveType == X_D3DPT_POLYGON) ) if( (PrimitiveType == X_D3DPT_LINELOOP) || (PrimitiveType == X_D3DPT_QUADLIST) )
EmuWarning("Unsupported PrimitiveType! (%d)", (DWORD)PrimitiveType); EmuWarning("Unsupported PrimitiveType! (%d)", (DWORD)PrimitiveType);
UINT PrimitiveCount = EmuD3DVertex2PrimitiveCount(PrimitiveType, VertexCount);
// Convert from Xbox to PC enumeration
D3DPRIMITIVETYPE PCPrimitiveType = EmuPrimitiveType(PrimitiveType);
VertexPatchDesc VPDesc; VertexPatchDesc VPDesc;
VPDesc.dwVertexCount = VertexCount;
VPDesc.PrimitiveType = PrimitiveType; VPDesc.PrimitiveType = PrimitiveType;
VPDesc.dwPrimitiveCount = PrimitiveCount; VPDesc.dwVertexCount = VertexCount;
VPDesc.dwOffset = 0; VPDesc.dwOffset = 0;
VPDesc.pVertexStreamZeroData = pVertexStreamZeroData; VPDesc.pVertexStreamZeroData = pVertexStreamZeroData;
VPDesc.uiVertexStreamZeroStride = VertexStreamZeroStride; VPDesc.uiVertexStreamZeroStride = VertexStreamZeroStride;
@ -7369,7 +7289,7 @@ VOID WINAPI XTL::EmuIDirect3DDevice8_DrawIndexedVerticesUP
{ {
g_pD3DDevice8->DrawIndexedPrimitiveUP g_pD3DDevice8->DrawIndexedPrimitiveUP
( (
PCPrimitiveType, 0, VertexCount, VPDesc.dwPrimitiveCount, pIndexData, D3DFMT_INDEX16, VPDesc.pVertexStreamZeroData, VPDesc.uiVertexStreamZeroStride EmuPrimitiveType(VPDesc.PrimitiveType), 0, VPDesc.dwVertexCount, VPDesc.dwPrimitiveCount, pIndexData, D3DFMT_INDEX16, VPDesc.pVertexStreamZeroData, VPDesc.uiVertexStreamZeroStride
); );
} }

View File

@ -247,17 +247,17 @@ DWORD XTL::EmuXB2PC_D3DLock(DWORD Flags)
// lookup table for converting vertex count to primitive count // lookup table for converting vertex count to primitive count
UINT XTL::EmuD3DVertexToPrimitive[11][2] = UINT XTL::EmuD3DVertexToPrimitive[11][2] =
{ {
{0, 0}, {0, 0}, // NULL
{1, 0}, {1, 0}, // X_D3DPT_POINTLIST
{2, 0}, {2, 0}, // X_D3DPT_LINELIST
{1, 1}, {1, 1}, // X_D3DPT_LINELOOP
{1, 1}, {1, 1}, // X_D3DPT_LINESTRIP
{3, 0}, {3, 0}, // X_D3DPT_TRIANGLELIST
{1, 2}, {1, 2}, // X_D3DPT_TRIANGLESTRIP
{1, 2}, {1, 2}, // X_D3DPT_TRIANGLEFAN
{4, 0}, {4, 0}, // X_D3DPT_QUADLIST
{2, 2}, {2, 2}, // X_D3DPT_QUADSTRIP
{0, 0}, {1, 0}, // X_D3DPT_POLYGON
}; };
// conversion table for xbox->pc primitive types // conversion table for xbox->pc primitive types
@ -272,8 +272,8 @@ XTL::D3DPRIMITIVETYPE XTL::EmuPrimitiveTypeLookup[] =
/* D3DPT_TRIANGLESTRIP = 6, */ XTL::D3DPT_TRIANGLESTRIP, /* D3DPT_TRIANGLESTRIP = 6, */ XTL::D3DPT_TRIANGLESTRIP,
/* D3DPT_TRIANGLEFAN = 7, */ XTL::D3DPT_TRIANGLEFAN, /* D3DPT_TRIANGLEFAN = 7, */ XTL::D3DPT_TRIANGLEFAN,
/* D3DPT_QUADLIST = 8, Xbox */ XTL::D3DPT_TRIANGLELIST, /* D3DPT_QUADLIST = 8, Xbox */ XTL::D3DPT_TRIANGLELIST,
/* D3DPT_QUADSTRIP = 9, Xbox */ XTL::D3DPT_TRIANGLELIST, /* D3DPT_QUADSTRIP = 9, Xbox */ XTL::D3DPT_TRIANGLESTRIP,
/* D3DPT_POLYGON = 10, Xbox */ XTL::D3DPT_TRIANGLELIST, /* D3DPT_POLYGON = 10, Xbox */ XTL::D3DPT_TRIANGLEFAN,
/* D3DPT_MAX = 11, */ (XTL::D3DPRIMITIVETYPE)11 /* D3DPT_MAX = 11, */ (XTL::D3DPRIMITIVETYPE)11
}; };

View File

@ -123,6 +123,12 @@ inline D3DFILLMODE EmuXB2PC_D3DFILLMODE(X_D3DFILLMODE Value)
return (D3DFILLMODE)((Value & 0xF) + 1); return (D3DFILLMODE)((Value & 0xF) + 1);
} }
// convert from xbox to pc shade modes
inline D3DSHADEMODE EmuXB2PC_D3DSHADEMODE(X_D3DSHADEMODE Value)
{
return (D3DSHADEMODE)((Value & 0x3) + 1);
}
// table used for vertex->primitive count conversion // table used for vertex->primitive count conversion
extern UINT EmuD3DVertexToPrimitive[11][2]; extern UINT EmuD3DVertexToPrimitive[11][2];

View File

@ -849,9 +849,40 @@ bool XTL::VertexPatcher::PatchPrimitive(VertexPatchDesc *pPatchDesc,
UINT uiStream) UINT uiStream)
{ {
PATCHEDSTREAM *pStream = &m_pStreams[uiStream]; PATCHEDSTREAM *pStream = &m_pStreams[uiStream];
// only quad and listloop are currently supported
if((pPatchDesc->PrimitiveType != X_D3DPT_QUADLIST) && (pPatchDesc->PrimitiveType != X_D3DPT_LINELOOP)) if((pPatchDesc->PrimitiveType) < 1 || (pPatchDesc->PrimitiveType >= X_D3DPT_MAX))
{
CxbxKrnlCleanup("Unknown primitive type: 0x%.02X\n", pPatchDesc->PrimitiveType);
}
// Unsupported primitives that don't need deep patching.
switch(pPatchDesc->PrimitiveType)
{
// Quad strip is just like a triangle strip, but requires two
// vertices per primitive.
case X_D3DPT_QUADSTRIP:
pPatchDesc->dwVertexCount -= pPatchDesc->dwVertexCount % 2;
pPatchDesc->PrimitiveType = X_D3DPT_TRIANGLESTRIP;
break;
// Convex polygon is the same as a triangle fan.
case X_D3DPT_POLYGON:
pPatchDesc->PrimitiveType = X_D3DPT_TRIANGLEFAN;
break;
}
pPatchDesc->dwPrimitiveCount = EmuD3DVertex2PrimitiveCount(pPatchDesc->PrimitiveType, pPatchDesc->dwVertexCount);
// Skip primitives that don't need further patching.
switch(pPatchDesc->PrimitiveType)
{
case X_D3DPT_QUADLIST:
case X_D3DPT_LINELOOP:
break;
default:
return false; return false;
}
if(pPatchDesc->pVertexStreamZeroData && uiStream > 0) if(pPatchDesc->pVertexStreamZeroData && uiStream > 0)
{ {
@ -876,7 +907,13 @@ bool XTL::VertexPatcher::PatchPrimitive(VertexPatchDesc *pPatchDesc,
{ {
g_pD3DDevice8->GetStreamSource(0, &pStream->pOriginalStream, &pStream->uiOrigStride); g_pD3DDevice8->GetStreamSource(0, &pStream->pOriginalStream, &pStream->uiOrigStride);
pStream->uiNewStride = pStream->uiOrigStride; // The stride is still the same pStream->uiNewStride = pStream->uiOrigStride; // The stride is still the same
}
else
{
pStream->uiOrigStride = pPatchDesc->uiVertexStreamZeroStride;
}
// Quad list
if(pPatchDesc->PrimitiveType == X_D3DPT_QUADLIST) if(pPatchDesc->PrimitiveType == X_D3DPT_QUADLIST)
{ {
pPatchDesc->dwPrimitiveCount *= 2; pPatchDesc->dwPrimitiveCount *= 2;
@ -885,7 +922,7 @@ bool XTL::VertexPatcher::PatchPrimitive(VertexPatchDesc *pPatchDesc,
dwOriginalSize = pPatchDesc->dwPrimitiveCount * pStream->uiOrigStride * 2; dwOriginalSize = pPatchDesc->dwPrimitiveCount * pStream->uiOrigStride * 2;
dwNewSize = pPatchDesc->dwPrimitiveCount * pStream->uiOrigStride * 3; dwNewSize = pPatchDesc->dwPrimitiveCount * pStream->uiOrigStride * 3;
} }
// LineLoop // Line loop
else if(pPatchDesc->PrimitiveType == X_D3DPT_LINELOOP) else if(pPatchDesc->PrimitiveType == X_D3DPT_LINELOOP)
{ {
pPatchDesc->dwPrimitiveCount += 1; pPatchDesc->dwPrimitiveCount += 1;
@ -895,6 +932,8 @@ bool XTL::VertexPatcher::PatchPrimitive(VertexPatchDesc *pPatchDesc,
dwNewSize = pPatchDesc->dwPrimitiveCount * pStream->uiOrigStride + pStream->uiOrigStride; dwNewSize = pPatchDesc->dwPrimitiveCount * pStream->uiOrigStride + pStream->uiOrigStride;
} }
if(pPatchDesc->pVertexStreamZeroData == 0)
{
// Retrieve the original buffer size // Retrieve the original buffer size
{ {
XTL::D3DVERTEXBUFFER_DESC Desc; XTL::D3DVERTEXBUFFER_DESC Desc;
@ -926,25 +965,6 @@ bool XTL::VertexPatcher::PatchPrimitive(VertexPatchDesc *pPatchDesc,
} }
else else
{ {
pStream->uiOrigStride = pPatchDesc->uiVertexStreamZeroStride;
if(pPatchDesc->PrimitiveType == X_D3DPT_QUADLIST)
{
pPatchDesc->dwPrimitiveCount *= 2;
// This is a list of sqares/rectangles, so we convert it to a list of triangles
dwOriginalSize = pPatchDesc->dwPrimitiveCount * pStream->uiOrigStride * 2;
dwNewSize = pPatchDesc->dwPrimitiveCount * pStream->uiOrigStride * 3;
}
else if(pPatchDesc->PrimitiveType == X_D3DPT_LINELOOP) // LineLoop
{
pPatchDesc->dwPrimitiveCount += 1;
// We will add exactly one more line
dwOriginalSize = pPatchDesc->dwPrimitiveCount * pStream->uiOrigStride;
dwNewSize = pPatchDesc->dwPrimitiveCount * pStream->uiOrigStride + pStream->uiOrigStride;
}
dwOriginalSizeWR = dwOriginalSize; dwOriginalSizeWR = dwOriginalSize;
dwNewSizeWR = dwNewSize; dwNewSizeWR = dwNewSize;
@ -963,7 +983,7 @@ bool XTL::VertexPatcher::PatchPrimitive(VertexPatchDesc *pPatchDesc,
&pOrigVertexData[pPatchDesc->dwOffset+dwOriginalSize], &pOrigVertexData[pPatchDesc->dwOffset+dwOriginalSize],
dwOriginalSizeWR - pPatchDesc->dwOffset - dwOriginalSize); dwOriginalSizeWR - pPatchDesc->dwOffset - dwOriginalSize);
// Quad // Quad list
if(pPatchDesc->PrimitiveType == X_D3DPT_QUADLIST) if(pPatchDesc->PrimitiveType == X_D3DPT_QUADLIST)
{ {
uint08 *pPatch1 = &pPatchedVertexData[pPatchDesc->dwOffset * pStream->uiOrigStride]; uint08 *pPatch1 = &pPatchedVertexData[pPatchDesc->dwOffset * pStream->uiOrigStride];
@ -1003,7 +1023,7 @@ bool XTL::VertexPatcher::PatchPrimitive(VertexPatchDesc *pPatchDesc,
} }
} }
} }
// LineLoop // Line loop
else if(pPatchDesc->PrimitiveType == X_D3DPT_LINELOOP) else if(pPatchDesc->PrimitiveType == X_D3DPT_LINELOOP)
{ {
memcpy(&pPatchedVertexData[pPatchDesc->dwOffset], &pOrigVertexData[pPatchDesc->dwOffset], dwOriginalSize); memcpy(&pPatchedVertexData[pPatchDesc->dwOffset], &pOrigVertexData[pPatchDesc->dwOffset], dwOriginalSize);
@ -1098,118 +1118,45 @@ bool XTL::VertexPatcher::Restore()
VOID XTL::EmuFlushIVB() VOID XTL::EmuFlushIVB()
{ {
if(g_IVBPrimitiveType == X_D3DPT_TRIANGLEFAN)
{
XTL::EmuUpdateDeferredStates(); XTL::EmuUpdateDeferredStates();
DWORD *pdwVB = (DWORD*)g_IVBTable; DWORD *pdwVB = (DWORD*)g_IVBTable;
UINT uiStride = 0; UINT uiStride = 0;
// Parse IVB table with current FVF shader if possible.
bool bFVF = !VshHandleIsVertexShader(g_CurrentVertexShader);
DWORD dwCurFVF;
if(bFVF && ((g_CurrentVertexShader & D3DFVF_POSITION_MASK) != D3DFVF_XYZRHW))
{
dwCurFVF = g_CurrentVertexShader;
}
else
{
dwCurFVF = g_IVBFVF;
}
DbgPrintf("g_IVBTblOffs := %d\n", g_IVBTblOffs); DbgPrintf("g_IVBTblOffs := %d\n", g_IVBTblOffs);
// TEMP DEBUGGING
/*
g_IVBTable[0].TexCoord1.x = 0.0f;
g_IVBTable[0].TexCoord1.y = 0.0f;
g_IVBTable[1].TexCoord1.x = 1.0f;
g_IVBTable[1].TexCoord1.y = 0.0f;
g_IVBTable[2].TexCoord1.x = 1.0f;
g_IVBTable[2].TexCoord1.y = 1.0f;
g_IVBTable[3].TexCoord1.x = 0.0f;
g_IVBTable[3].TexCoord1.y = 1.0f;
g_IVBTable[0].TexCoord2.x = 0.0f;
g_IVBTable[0].TexCoord2.y = 0.0f;
g_IVBTable[1].TexCoord2.x = 1.0f;
g_IVBTable[1].TexCoord2.y = 0.0f;
g_IVBTable[2].TexCoord2.x = 1.0f;
g_IVBTable[2].TexCoord2.y = 1.0f;
g_IVBTable[3].TexCoord2.x = 0.0f;
g_IVBTable[3].TexCoord2.y = 1.0f;
g_IVBTable[0].TexCoord3.x = 0.0f;
g_IVBTable[0].TexCoord3.y = 0.0f;
g_IVBTable[1].TexCoord3.x = 1.0f;
g_IVBTable[1].TexCoord3.y = 0.0f;
g_IVBTable[2].TexCoord3.x = 1.0f;
g_IVBTable[2].TexCoord3.y = 1.0f;
g_IVBTable[3].TexCoord3.x = 0.0f;
g_IVBTable[3].TexCoord3.y = 1.0f;
g_IVBTable[0].TexCoord4.x = 0.0f;
g_IVBTable[0].TexCoord4.y = 0.0f;
g_IVBTable[1].TexCoord4.x = 1.0f;
g_IVBTable[1].TexCoord4.y = 0.0f;
g_IVBTable[2].TexCoord4.x = 1.0f;
g_IVBTable[2].TexCoord4.y = 1.0f;
g_IVBTable[3].TexCoord4.x = 0.0f;
g_IVBTable[3].TexCoord4.y = 1.0f;
//*/
/*
static IDirect3DTexture8 *pDummyTexture[4] = {0, 0, 0, 0};
for(int Stage=0;Stage<4;Stage++)
{
if(pDummyTexture[Stage] == 0)
{
if(Stage == 0)
{
if(D3DXCreateTextureFromFile(g_pD3DDevice8, "C:\\dummy1.bmp", &pDummyTexture[Stage]) != D3D_OK)
CxbxKrnlCleanup("Could not create dummy texture!");
}
else if(Stage == 1)
{
if(D3DXCreateTextureFromFile(g_pD3DDevice8, "C:\\dummy2.bmp", &pDummyTexture[Stage]) != D3D_OK)
CxbxKrnlCleanup("Could not create dummy texture!");
}
}
g_pD3DDevice8->SetTexture(Stage, pDummyTexture[Stage]);
}
/*
g_pD3DDevice8->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_BLENDDIFFUSEALPHA);
g_pD3DDevice8->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
g_pD3DDevice8->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_SPECULAR);
g_pD3DDevice8->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
g_pD3DDevice8->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
*/
/*
g_pD3DDevice8->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
g_pD3DDevice8->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
g_pD3DDevice8->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
g_pD3DDevice8->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
g_pD3DDevice8->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
g_pD3DDevice8->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
g_pD3DDevice8->SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
g_pD3DDevice8->SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
g_pD3DDevice8->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
g_pD3DDevice8->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
g_pD3DDevice8->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
g_pD3DDevice8->SetTextureStageState(2, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
g_pD3DDevice8->SetTextureStageState(2, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
g_pD3DDevice8->SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_DISABLE);
g_pD3DDevice8->SetTextureStageState(2, D3DTSS_COLORARG1, D3DTA_TEXTURE);
g_pD3DDevice8->SetTextureStageState(2, D3DTSS_COLORARG2, D3DTA_CURRENT);
g_pD3DDevice8->SetTextureStageState(3, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
g_pD3DDevice8->SetTextureStageState(3, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
g_pD3DDevice8->SetTextureStageState(3, D3DTSS_COLOROP, D3DTOP_DISABLE);
g_pD3DDevice8->SetTextureStageState(3, D3DTSS_COLORARG1, D3DTA_TEXTURE);
g_pD3DDevice8->SetTextureStageState(3, D3DTSS_COLORARG2, D3DTA_CURRENT);
g_pD3DDevice8->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
g_pD3DDevice8->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_SRCCOLOR);
g_pD3DDevice8->SetRenderState(D3DRS_AMBIENT, RGB(255,255,255));
g_pD3DDevice8->SetRenderState(D3DRS_LIGHTING, FALSE);
g_pD3DDevice8->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
g_pD3DDevice8->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
//*/
for(uint v=0;v<g_IVBTblOffs;v++) for(uint v=0;v<g_IVBTblOffs;v++)
{ {
DWORD dwPos = g_IVBFVF & D3DFVF_POSITION_MASK; DWORD dwPos = dwCurFVF & D3DFVF_POSITION_MASK;
if(dwPos == D3DFVF_XYZRHW) if(dwPos == D3DFVF_XYZ)
{
*(FLOAT*)pdwVB++ = g_IVBTable[v].Position.x;
*(FLOAT*)pdwVB++ = g_IVBTable[v].Position.y;
*(FLOAT*)pdwVB++ = g_IVBTable[v].Position.z;
if(v == 0)
{
uiStride += (sizeof(FLOAT)*3);
}
DbgPrintf("IVB Position := {%f, %f, %f}\n", g_IVBTable[v].Position.x, g_IVBTable[v].Position.y, g_IVBTable[v].Position.z);
}
else if(dwPos == D3DFVF_XYZRHW)
{ {
*(FLOAT*)pdwVB++ = g_IVBTable[v].Position.x; *(FLOAT*)pdwVB++ = g_IVBTable[v].Position.x;
*(FLOAT*)pdwVB++ = g_IVBTable[v].Position.y; *(FLOAT*)pdwVB++ = g_IVBTable[v].Position.y;
@ -1221,14 +1168,30 @@ VOID XTL::EmuFlushIVB()
uiStride += (sizeof(FLOAT)*4); uiStride += (sizeof(FLOAT)*4);
} }
DbgPrintf("IVB Position := {%f, %f, %f}\n", g_IVBTable[v].Position.x, g_IVBTable[v].Position.y, g_IVBTable[v].Position.z); DbgPrintf("IVB Position := {%f, %f, %f, %f}\n", g_IVBTable[v].Position.x, g_IVBTable[v].Position.y, g_IVBTable[v].Position.z, g_IVBTable[v].Position.z, g_IVBTable[v].Rhw);
} }
else else
{ {
CxbxKrnlCleanup("Unsupported Position Mask (FVF := 0x%.08X)", g_IVBFVF); CxbxKrnlCleanup("Unsupported Position Mask (FVF := 0x%.08X)", g_IVBFVF);
} }
if(g_IVBFVF & D3DFVF_DIFFUSE) if(dwPos == D3DFVF_NORMAL)
{
*(FLOAT*)pdwVB++ = g_IVBTable[v].Normal.x;
*(FLOAT*)pdwVB++ = g_IVBTable[v].Normal.y;
*(FLOAT*)pdwVB++ = g_IVBTable[v].Normal.z;
if(v == 0)
{
uiStride += (sizeof(FLOAT)*3);
}
DbgPrintf("IVB Normal := {%f, %f, %f}\n", g_IVBTable[v].Normal.x, g_IVBTable[v].Normal.y, g_IVBTable[v].Normal.z);
}
if(dwCurFVF & D3DFVF_DIFFUSE)
{ {
*(DWORD*)pdwVB++ = g_IVBTable[v].dwDiffuse; *(DWORD*)pdwVB++ = g_IVBTable[v].dwDiffuse;
@ -1240,9 +1203,9 @@ VOID XTL::EmuFlushIVB()
DbgPrintf("IVB Diffuse := 0x%.08X\n", g_IVBTable[v].dwDiffuse); DbgPrintf("IVB Diffuse := 0x%.08X\n", g_IVBTable[v].dwDiffuse);
} }
if(g_IVBFVF & D3DFVF_SPECULAR) if(dwCurFVF & D3DFVF_SPECULAR)
{ {
*(DWORD*)pdwVB++ = g_IVBTable[v].dwDiffuse; *(DWORD*)pdwVB++ = g_IVBTable[v].dwSpecular;
if(v == 0) if(v == 0)
{ {
@ -1252,7 +1215,7 @@ VOID XTL::EmuFlushIVB()
DbgPrintf("IVB Specular := 0x%.08X\n", g_IVBTable[v].dwSpecular); DbgPrintf("IVB Specular := 0x%.08X\n", g_IVBTable[v].dwSpecular);
} }
DWORD dwTexN = (g_IVBFVF & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT; DWORD dwTexN = (dwCurFVF & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT;
if(dwTexN >= 1) if(dwTexN >= 1)
{ {
@ -1307,137 +1270,38 @@ VOID XTL::EmuFlushIVB()
} }
} }
g_pD3DDevice8->SetVertexShader(g_IVBFVF);
g_pD3DDevice8->SetPixelShader(NULL);
// patch buffer
UINT PrimitiveCount = EmuD3DVertex2PrimitiveCount(g_IVBPrimitiveType, g_IVBTblOffs);
VertexPatchDesc VPDesc; VertexPatchDesc VPDesc;
VPDesc.PrimitiveType = g_IVBPrimitiveType;
VPDesc.dwVertexCount = g_IVBTblOffs; VPDesc.dwVertexCount = g_IVBTblOffs;
VPDesc.PrimitiveType = g_IVBPrimitiveType;
VPDesc.dwPrimitiveCount = PrimitiveCount;
VPDesc.dwOffset = 0; VPDesc.dwOffset = 0;
VPDesc.pVertexStreamZeroData = g_IVBTable; VPDesc.pVertexStreamZeroData = g_IVBTable;
VPDesc.uiVertexStreamZeroStride = uiStride; VPDesc.uiVertexStreamZeroStride = uiStride;
// TODO: Set the current shader and let the patcher handle it.. VPDesc.hVertexShader = g_CurrentVertexShader;
VPDesc.hVertexShader = g_IVBFVF;
VertexPatcher VertPatch; VertexPatcher VertPatch;
bool bPatched = VertPatch.Apply(&VPDesc); bool bPatched = VertPatch.Apply(&VPDesc);
/* if(bFVF)
IDirect3DBaseTexture8 *pTexture = 0;
g_pD3DDevice8->GetTexture(0, &pTexture);
if(pTexture != NULL)
{ {
static int dwDumpTexture = 0; g_pD3DDevice8->SetVertexShader(dwCurFVF);
char szBuffer[255];
sprintf(szBuffer, "C:\\Aaron\\Textures\\Texture-Active%.03d (0x%.08X).bmp", dwDumpTexture++, pTexture);
D3DXSaveTextureToFile(szBuffer, D3DXIFF_BMP, pTexture, NULL);
} }
//*/
//EmuUpdateActiveTexture();
g_pD3DDevice8->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, VPDesc.dwPrimitiveCount, VPDesc.pVertexStreamZeroData, VPDesc.uiVertexStreamZeroStride); g_pD3DDevice8->DrawPrimitiveUP(
EmuPrimitiveType(VPDesc.PrimitiveType),
VPDesc.dwPrimitiveCount,
VPDesc.pVertexStreamZeroData,
VPDesc.uiVertexStreamZeroStride);
if(bFVF)
{
g_pD3DDevice8->SetVertexShader(g_CurrentVertexShader);
}
VertPatch.Restore(); VertPatch.Restore();
g_IVBTblOffs = 0; g_IVBTblOffs = 0;
}
else if((g_IVBPrimitiveType == X_D3DPT_QUADLIST) && (g_IVBTblOffs == 4))
{
XTL::EmuUpdateDeferredStates();
DWORD *pdwVB = (DWORD*)g_IVBTable;
UINT uiStride = 0;
for(int v=0;v<4;v++)
{
DWORD dwPos = g_IVBFVF & D3DFVF_POSITION_MASK;
if(dwPos == D3DFVF_XYZ)
{
*(FLOAT*)pdwVB++ = g_IVBTable[v].Position.x;
*(FLOAT*)pdwVB++ = g_IVBTable[v].Position.y;
*(FLOAT*)pdwVB++ = g_IVBTable[v].Position.z;
if(v == 0)
{
uiStride += (sizeof(FLOAT)*3);
}
DbgPrintf("IVB Position := {%f, %f, %f}\n", g_IVBTable[v].Position.x, g_IVBTable[v].Position.y, g_IVBTable[v].Position.z);
}
else
{
CxbxKrnlCleanup("Unsupported Position Mask (FVF := 0x%.08X)", g_IVBFVF);
}
if(g_IVBFVF & D3DFVF_DIFFUSE)
{
*(DWORD*)pdwVB++ = g_IVBTable[v].dwDiffuse;
if(v == 0)
{
uiStride += sizeof(DWORD);
}
DbgPrintf("IVB Diffuse := 0x%.08X\n", g_IVBTable[v].dwDiffuse);
}
DWORD dwTexN = (g_IVBFVF & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT;
if(dwTexN >= 1)
{
*(FLOAT*)pdwVB++ = g_IVBTable[v].TexCoord1.x;
*(FLOAT*)pdwVB++ = g_IVBTable[v].TexCoord1.y;
if(v == 0)
{
uiStride += sizeof(FLOAT)*2;
}
DbgPrintf("IVB TexCoord1 := {%f, %f}\n", g_IVBTable[v].TexCoord1.x, g_IVBTable[v].TexCoord1.y);
}
}
g_pD3DDevice8->SetVertexShader(g_IVBFVF);
g_pD3DDevice8->SetPixelShader(NULL);
// patch buffer
UINT PrimitiveCount = EmuD3DVertex2PrimitiveCount(g_IVBPrimitiveType, 4);
VertexPatchDesc VPDesc;
VPDesc.dwVertexCount = 4;
VPDesc.PrimitiveType = g_IVBPrimitiveType;
VPDesc.dwPrimitiveCount = PrimitiveCount;
VPDesc.dwOffset = 0;
VPDesc.pVertexStreamZeroData = g_IVBTable;
VPDesc.uiVertexStreamZeroStride = uiStride;
// TODO: Set the current shader and let the patcher handle it..
VPDesc.hVertexShader = g_IVBFVF;
VertexPatcher VertPatch;
bool bPatched = VertPatch.Apply(&VPDesc);
g_pD3DDevice8->DrawPrimitiveUP(D3DPT_TRIANGLELIST, VPDesc.dwPrimitiveCount, VPDesc.pVertexStreamZeroData, VPDesc.uiVertexStreamZeroStride);
VertPatch.Restore();
// ignore
g_IVBTblOffs = 0;
}
return; return;
} }

View File

@ -46,6 +46,7 @@ typedef DWORD X_D3DBLENDOP;
typedef DWORD X_D3DBLEND; typedef DWORD X_D3DBLEND;
typedef DWORD X_D3DCMPFUNC; typedef DWORD X_D3DCMPFUNC;
typedef DWORD X_D3DFILLMODE; typedef DWORD X_D3DFILLMODE;
typedef DWORD X_D3DSHADEMODE;
typedef DWORD X_D3DTEXTURESTAGESTATETYPE; typedef DWORD X_D3DTEXTURESTAGESTATETYPE;
// Primitives supported by draw-primitive API // Primitives supported by draw-primitive API

View File

@ -325,6 +325,29 @@ SOOVPA<8> IDirect3DDevice8_DrawIndexedVertices_1_0_5849 =
} }
}; };
// ******************************************************************
// * IDirect3DDevice8_DrawIndexedVerticesUP
// ******************************************************************
SOOVPA<8> IDirect3DDevice8_DrawIndexedVerticesUP_1_0_5849 =
{
0, // Large == 0
8, // Count == 8
-1, // XRef Not Saved
0, // XRef Not Used
{
{ 0x1F, 0x05 },
{ 0x3A, 0x89 },
{ 0x64, 0xF0 },
{ 0x73, 0x13 },
{ 0x94, 0xAF },
{ 0xAB, 0x12 },
{ 0xE4, 0xDB },
{ 0xFF, 0x0C },
}
};
// ****************************************************************** // ******************************************************************
// * IDirect3DDevice8_SetMaterial // * IDirect3DDevice8_SetMaterial
// ****************************************************************** // ******************************************************************
@ -1249,6 +1272,16 @@ OOVPATable D3D8_1_0_5849[] =
"EmuIDirect3DDevice8_DrawIndexedVertices" "EmuIDirect3DDevice8_DrawIndexedVertices"
#endif #endif
}, },
// IDirect3DDevice8::DrawIndexedVerticesUP
{
(OOVPA*)&IDirect3DDevice8_DrawIndexedVerticesUP_1_0_5849,
XTL::EmuIDirect3DDevice8_DrawIndexedVerticesUP,
#ifdef _DEBUG_TRACE
"EmuIDirect3DDevice8_DrawIndexedVerticesUP"
#endif
},
// IDirect3DDevice8::SetMaterial // IDirect3DDevice8::SetMaterial
{ {
(OOVPA*)&IDirect3DDevice8_SetMaterial_1_0_5849, (OOVPA*)&IDirect3DDevice8_SetMaterial_1_0_5849,
@ -1299,6 +1332,16 @@ OOVPATable D3D8_1_0_5849[] =
"EmuIDirect3DResource8_Release" "EmuIDirect3DResource8_Release"
#endif #endif
}, },
// IDirect3DResource8::IsBusy (* unchanged since 4361 *)
{
(OOVPA*)&IDirect3DResource8_IsBusy_1_0_4361,
XTL::EmuIDirect3DResource8_IsBusy,
#ifdef _DEBUG_TRACE
"EmuIDirect3DResource8_IsBusy"
#endif
},
// IDirect3DSurface8::GetDesc (* unchanged since 4361 *) // IDirect3DSurface8::GetDesc (* unchanged since 4361 *)
{ {
(OOVPA*)&IDirect3DSurface8_GetDesc_1_0_4361, (OOVPA*)&IDirect3DSurface8_GetDesc_1_0_4361,