Fix vertex conversion when skip tokens are present in the Xbox vertex declaration.

This commit is contained in:
patrickvl 2019-10-12 16:27:11 +02:00 committed by PatrickvL
parent e5dc2e5e13
commit 6ef5b21144
3 changed files with 66 additions and 32 deletions

View File

@ -437,7 +437,7 @@ void CxbxVertexBufferConverter::ConvertStream
for (UINT uiElement = 0; uiElement < pVertexShaderStreamInfo->NumberOfVertexElements; uiElement++) { for (UINT uiElement = 0; uiElement < pVertexShaderStreamInfo->NumberOfVertexElements; uiElement++) {
FLOAT *pXboxVertexAsFloat = (FLOAT*)pXboxVertexAsByte; FLOAT *pXboxVertexAsFloat = (FLOAT*)pXboxVertexAsByte;
SHORT *pXboxVertexAsShort = (SHORT*)pXboxVertexAsByte; SHORT *pXboxVertexAsShort = (SHORT*)pXboxVertexAsByte;
int XboxElementByteSize = pVertexShaderStreamInfo->VertexElements[uiElement].HostByteSize; const int XboxElementByteSize = pVertexShaderStreamInfo->VertexElements[uiElement].XboxByteSize;
FLOAT *pHostVertexAsFloat = (FLOAT*)pHostVertexAsByte; FLOAT *pHostVertexAsFloat = (FLOAT*)pHostVertexAsByte;
SHORT *pHostVertexAsShort = (SHORT*)pHostVertexAsByte; SHORT *pHostVertexAsShort = (SHORT*)pHostVertexAsByte;
// Dxbx note : The following code handles only the D3DVSDT enums that need conversion; // Dxbx note : The following code handles only the D3DVSDT enums that need conversion;
@ -445,7 +445,6 @@ void CxbxVertexBufferConverter::ConvertStream
switch (pVertexShaderStreamInfo->VertexElements[uiElement].XboxType) { switch (pVertexShaderStreamInfo->VertexElements[uiElement].XboxType) {
case XTL::X_D3DVSDT_NORMSHORT1: { // 0x11: case XTL::X_D3DVSDT_NORMSHORT1: { // 0x11:
// Test-cases : Halo - Combat Evolved // Test-cases : Halo - Combat Evolved
XboxElementByteSize = 1 * sizeof(SHORT);
if (g_D3DCaps.DeclTypes & D3DDTCAPS_SHORT2N) { if (g_D3DCaps.DeclTypes & D3DDTCAPS_SHORT2N) {
// Make it SHORT2N // Make it SHORT2N
pHostVertexAsShort[0] = pXboxVertexAsShort[0]; pHostVertexAsShort[0] = pXboxVertexAsShort[0];
@ -461,11 +460,9 @@ void CxbxVertexBufferConverter::ConvertStream
} }
case XTL::X_D3DVSDT_NORMSHORT2: { // 0x21: case XTL::X_D3DVSDT_NORMSHORT2: { // 0x21:
// Test-cases : Baldur's Gate: Dark Alliance 2, F1 2002, Gun, Halo - Combat Evolved, Scrapland // Test-cases : Baldur's Gate: Dark Alliance 2, F1 2002, Gun, Halo - Combat Evolved, Scrapland
XboxElementByteSize = 2 * sizeof(SHORT);
if (g_D3DCaps.DeclTypes & D3DDTCAPS_SHORT2N) { if (g_D3DCaps.DeclTypes & D3DDTCAPS_SHORT2N) {
// No need for patching when D3D9 supports D3DDECLTYPE_SHORT2N // No need for patching when D3D9 supports D3DDECLTYPE_SHORT2N
// TODO : goto default; // ?? // TODO : goto default; // ??
//assert(XboxElementByteSize == 2 * sizeof(SHORT));
//memcpy(pHostVertexAsByte, pXboxVertexAsByte, XboxElementByteSize); //memcpy(pHostVertexAsByte, pXboxVertexAsByte, XboxElementByteSize);
// Make it SHORT2N // Make it SHORT2N
pHostVertexAsShort[0] = pXboxVertexAsShort[0]; pHostVertexAsShort[0] = pXboxVertexAsShort[0];
@ -481,7 +478,6 @@ void CxbxVertexBufferConverter::ConvertStream
} }
case XTL::X_D3DVSDT_NORMSHORT3: { // 0x31: case XTL::X_D3DVSDT_NORMSHORT3: { // 0x31:
// Test-cases : Cel Damage, Constantine, Destroy All Humans! // Test-cases : Cel Damage, Constantine, Destroy All Humans!
XboxElementByteSize = 3 * sizeof(SHORT);
if (g_D3DCaps.DeclTypes & D3DDTCAPS_SHORT4N) { if (g_D3DCaps.DeclTypes & D3DDTCAPS_SHORT4N) {
// Make it SHORT4N // Make it SHORT4N
pHostVertexAsShort[0] = pXboxVertexAsShort[0]; pHostVertexAsShort[0] = pXboxVertexAsShort[0];
@ -500,11 +496,9 @@ void CxbxVertexBufferConverter::ConvertStream
} }
case XTL::X_D3DVSDT_NORMSHORT4: { // 0x41: case XTL::X_D3DVSDT_NORMSHORT4: { // 0x41:
// Test-cases : Judge Dredd: Dredd vs Death, NHL Hitz 2002, Silent Hill 2, Sneakers, Tony Hawk Pro Skater 4 // Test-cases : Judge Dredd: Dredd vs Death, NHL Hitz 2002, Silent Hill 2, Sneakers, Tony Hawk Pro Skater 4
XboxElementByteSize = 4 * sizeof(SHORT);
if (g_D3DCaps.DeclTypes & D3DDTCAPS_SHORT4N) { if (g_D3DCaps.DeclTypes & D3DDTCAPS_SHORT4N) {
// No need for patching when D3D9 supports D3DDECLTYPE_SHORT4N // No need for patching when D3D9 supports D3DDECLTYPE_SHORT4N
// TODO : goto default; // ?? // TODO : goto default; // ??
//assert(XboxElementByteSize == 4 * sizeof(SHORT));
//memcpy(pHostVertexAsByte, pXboxVertexAsByte, XboxElementByteSize); //memcpy(pHostVertexAsByte, pXboxVertexAsByte, XboxElementByteSize);
// Make it SHORT4N // Make it SHORT4N
pHostVertexAsShort[0] = pXboxVertexAsShort[0]; pHostVertexAsShort[0] = pXboxVertexAsShort[0];
@ -524,7 +518,6 @@ void CxbxVertexBufferConverter::ConvertStream
} }
case XTL::X_D3DVSDT_NORMPACKED3: { // 0x16: case XTL::X_D3DVSDT_NORMPACKED3: { // 0x16:
// Test-cases : Dashboard // Test-cases : Dashboard
XboxElementByteSize = 1 * sizeof(int32_t);
// Make it FLOAT3 // Make it FLOAT3
union { union {
int32_t value; int32_t value;
@ -543,7 +536,6 @@ void CxbxVertexBufferConverter::ConvertStream
break; break;
} }
case XTL::X_D3DVSDT_SHORT1: { // 0x15: case XTL::X_D3DVSDT_SHORT1: { // 0x15:
XboxElementByteSize = 1 * sizeof(SHORT);
// Make it SHORT2 and set the second short to 0 // Make it SHORT2 and set the second short to 0
pHostVertexAsShort[0] = pXboxVertexAsShort[0]; pHostVertexAsShort[0] = pXboxVertexAsShort[0];
pHostVertexAsShort[1] = 0; pHostVertexAsShort[1] = 0;
@ -551,7 +543,6 @@ void CxbxVertexBufferConverter::ConvertStream
} }
case XTL::X_D3DVSDT_SHORT3: { // 0x35: case XTL::X_D3DVSDT_SHORT3: { // 0x35:
// Test-cases : Turok // Test-cases : Turok
XboxElementByteSize = 3 * sizeof(SHORT);
// Make it a SHORT4 and set the fourth short to 1 // Make it a SHORT4 and set the fourth short to 1
pHostVertexAsShort[0] = pXboxVertexAsShort[0]; pHostVertexAsShort[0] = pXboxVertexAsShort[0];
pHostVertexAsShort[1] = pXboxVertexAsShort[1]; pHostVertexAsShort[1] = pXboxVertexAsShort[1];
@ -560,7 +551,6 @@ void CxbxVertexBufferConverter::ConvertStream
break; break;
} }
case XTL::X_D3DVSDT_PBYTE1: { // 0x14: case XTL::X_D3DVSDT_PBYTE1: { // 0x14:
XboxElementByteSize = 1 * sizeof(BYTE);
if (g_D3DCaps.DeclTypes & D3DDTCAPS_UBYTE4N) { if (g_D3DCaps.DeclTypes & D3DDTCAPS_UBYTE4N) {
// Make it UBYTE4N // Make it UBYTE4N
pHostVertexAsByte[0] = pXboxVertexAsByte[0]; pHostVertexAsByte[0] = pXboxVertexAsByte[0];
@ -576,7 +566,6 @@ void CxbxVertexBufferConverter::ConvertStream
break; break;
} }
case XTL::X_D3DVSDT_PBYTE2: { // 0x24: case XTL::X_D3DVSDT_PBYTE2: { // 0x24:
XboxElementByteSize = 2 * sizeof(BYTE);
if (g_D3DCaps.DeclTypes & D3DDTCAPS_UBYTE4N) { if (g_D3DCaps.DeclTypes & D3DDTCAPS_UBYTE4N) {
// Make it UBYTE4N // Make it UBYTE4N
pHostVertexAsByte[0] = pXboxVertexAsByte[0]; pHostVertexAsByte[0] = pXboxVertexAsByte[0];
@ -594,7 +583,6 @@ void CxbxVertexBufferConverter::ConvertStream
} }
case XTL::X_D3DVSDT_PBYTE3: { // 0x34: case XTL::X_D3DVSDT_PBYTE3: { // 0x34:
// Test-cases : Turok // Test-cases : Turok
XboxElementByteSize = 3 * sizeof(BYTE);
if (g_D3DCaps.DeclTypes & D3DDTCAPS_UBYTE4N) { if (g_D3DCaps.DeclTypes & D3DDTCAPS_UBYTE4N) {
// Make it UBYTE4N // Make it UBYTE4N
pHostVertexAsByte[0] = pXboxVertexAsByte[0]; pHostVertexAsByte[0] = pXboxVertexAsByte[0];
@ -613,11 +601,9 @@ void CxbxVertexBufferConverter::ConvertStream
} }
case XTL::X_D3DVSDT_PBYTE4: { // 0x44: case XTL::X_D3DVSDT_PBYTE4: { // 0x44:
// Test-case : Jet Set Radio Future // Test-case : Jet Set Radio Future
XboxElementByteSize = 4 * sizeof(BYTE);
if (g_D3DCaps.DeclTypes & D3DDTCAPS_UBYTE4N) { if (g_D3DCaps.DeclTypes & D3DDTCAPS_UBYTE4N) {
// No need for patching when D3D9 supports D3DDECLTYPE_UBYTE4N // No need for patching when D3D9 supports D3DDECLTYPE_UBYTE4N
// TODO : goto default; // ?? // TODO : goto default; // ??
//assert(XboxElementByteSize == 4 * sizeof(BYTE));
//memcpy(pHostVertexAsByte, pXboxVertexAsByte, XboxElementByteSize); //memcpy(pHostVertexAsByte, pXboxVertexAsByte, XboxElementByteSize);
// Make it UBYTE4N // Make it UBYTE4N
pHostVertexAsByte[0] = pXboxVertexAsByte[0]; pHostVertexAsByte[0] = pXboxVertexAsByte[0];
@ -636,7 +622,6 @@ void CxbxVertexBufferConverter::ConvertStream
break; break;
} }
case XTL::X_D3DVSDT_FLOAT2H: { // 0x72: case XTL::X_D3DVSDT_FLOAT2H: { // 0x72:
XboxElementByteSize = 3 * sizeof(FLOAT);
// Make it FLOAT4 and set the third float to 0.0 // Make it FLOAT4 and set the third float to 0.0
pHostVertexAsFloat[0] = pXboxVertexAsFloat[0]; pHostVertexAsFloat[0] = pXboxVertexAsFloat[0];
pHostVertexAsFloat[1] = pXboxVertexAsFloat[1]; pHostVertexAsFloat[1] = pXboxVertexAsFloat[1];
@ -644,9 +629,10 @@ void CxbxVertexBufferConverter::ConvertStream
pHostVertexAsFloat[3] = pXboxVertexAsFloat[2]; pHostVertexAsFloat[3] = pXboxVertexAsFloat[2];
break; break;
} }
case XTL::X_D3DVSDT_NONE: { // 0x02: // Skip it case XTL::X_D3DVSDT_NONE: { // 0x02:
// Test-case : WWE RAW2 // Test-case : WWE RAW2
LOG_TEST_CASE("X_D3DVSDT_NONE"); LOG_TEST_CASE("X_D3DVSDT_NONE");
// No host element data (but Xbox size can be above zero, when used for X_D3DVSD_MASK_SKIP*
break; break;
} }
default: { default: {

View File

@ -1899,11 +1899,48 @@ private:
} }
} }
void VshConvert_RegisterVertexElement(
UINT XboxVertexElementDataType,
UINT XboxVertexElementByteSize,
UINT HostVertexElementByteSize,
BOOL NeedPatching)
{
CxbxVertexShaderStreamElement* pCurrentElement = &(pCurrentVertexShaderStreamInfo->VertexElements[pCurrentVertexShaderStreamInfo->NumberOfVertexElements]);
pCurrentElement->XboxType = XboxVertexElementDataType;
pCurrentElement->XboxByteSize = XboxVertexElementByteSize;
pCurrentElement->HostByteSize = HostVertexElementByteSize;
pCurrentVertexShaderStreamInfo->NumberOfVertexElements++;
pCurrentVertexShaderStreamInfo->NeedPatch |= NeedPatching;
}
void VshConvert_SkipBytes(int SkipBytesCount)
{
if (SkipBytesCount % sizeof(DWORD)) {
LOG_TEST_CASE("D3DVSD_SKIPBYTES not divisble by 4!");
}
#if 0 // Potential optimization, for now disabled for simplicity :
else {
// Skip size is a whole multiple of 4 bytes;
// Is stream patching not needed up until this element?
if (!pCurrentVertexShaderStreamInfo->NeedPatch) {
// Then we can get away with increasing the host stride,
// which avoids otherwise needless vertex buffer patching :
pCurrentVertexShaderStreamInfo->HostVertexStride += SkipBytesCount;
return;
}
}
#endif
// Register a 'skip' element, so that Xbox data will be skipped
// without increasing host stride - this does require patching :
VshConvert_RegisterVertexElement(XTL::X_D3DVSDT_NONE, SkipBytesCount, /*HostSize=*/0, /*NeedPatching=*/TRUE);
}
void VshConvertToken_STREAMDATA_SKIP(DWORD *pXboxToken) void VshConvertToken_STREAMDATA_SKIP(DWORD *pXboxToken)
{ {
WORD SkipCount = (*pXboxToken & X_D3DVSD_SKIPCOUNTMASK) >> X_D3DVSD_SKIPCOUNTSHIFT; WORD SkipCount = (*pXboxToken & X_D3DVSD_SKIPCOUNTMASK) >> X_D3DVSD_SKIPCOUNTSHIFT;
DbgVshPrintf("\tD3DVSD_SKIP(%d),\n", SkipCount); DbgVshPrintf("\tD3DVSD_SKIP(%d),\n", SkipCount);
pCurrentVertexShaderStreamInfo->HostVertexStride += (SkipCount * sizeof(DWORD)); VshConvert_SkipBytes(SkipCount * sizeof(DWORD));
} }
void VshConvertToken_STREAMDATA_SKIPBYTES(DWORD* pXboxToken) void VshConvertToken_STREAMDATA_SKIPBYTES(DWORD* pXboxToken)
@ -1911,11 +1948,7 @@ private:
WORD SkipBytesCount = (*pXboxToken & X_D3DVSD_SKIPCOUNTMASK) >> X_D3DVSD_SKIPCOUNTSHIFT; WORD SkipBytesCount = (*pXboxToken & X_D3DVSD_SKIPCOUNTMASK) >> X_D3DVSD_SKIPCOUNTSHIFT;
DbgVshPrintf("\tD3DVSD_SKIPBYTES(%d), /* xbox ext. */\n", SkipBytesCount); DbgVshPrintf("\tD3DVSD_SKIPBYTES(%d), /* xbox ext. */\n", SkipBytesCount);
if (SkipBytesCount % sizeof(DWORD)) { VshConvert_SkipBytes(SkipBytesCount);
EmuLog(LOG_LEVEL::WARNING, "D3DVSD_SKIPBYTES can't be converted to D3DVSD_SKIP, not divisble by 4.");
}
pCurrentVertexShaderStreamInfo->HostVertexStride += SkipBytesCount;
} }
void VshConvertToken_STREAMDATA_REG(DWORD *pXboxToken) void VshConvertToken_STREAMDATA_REG(DWORD *pXboxToken)
@ -1945,6 +1978,7 @@ private:
RegVIsPresentInDeclaration[VertexRegister] = true; RegVIsPresentInDeclaration[VertexRegister] = true;
DWORD XboxVertexElementDataType = (*pXboxToken & X_D3DVSD_DATATYPEMASK) >> X_D3DVSD_DATATYPESHIFT; DWORD XboxVertexElementDataType = (*pXboxToken & X_D3DVSD_DATATYPEMASK) >> X_D3DVSD_DATATYPESHIFT;
WORD XboxVertexElementByteSize = 0;
BYTE HostVertexElementDataType = 0; BYTE HostVertexElementDataType = 0;
WORD HostVertexElementByteSize = 0; WORD HostVertexElementByteSize = 0;
@ -1996,6 +2030,7 @@ private:
HostVertexElementDataType = D3DDECLTYPE_FLOAT1; HostVertexElementDataType = D3DDECLTYPE_FLOAT1;
HostVertexElementByteSize = 1 * sizeof(FLOAT); HostVertexElementByteSize = 1 * sizeof(FLOAT);
} }
XboxVertexElementByteSize = 1 * sizeof(XTL::SHORT);
NeedPatching = TRUE; NeedPatching = TRUE;
break; break;
case XTL::X_D3DVSDT_NORMSHORT2: // 0x21: case XTL::X_D3DVSDT_NORMSHORT2: // 0x21:
@ -2010,6 +2045,7 @@ private:
DbgVshPrintf("D3DVSDT_NORMSHORT2 /* xbox ext. */"); DbgVshPrintf("D3DVSDT_NORMSHORT2 /* xbox ext. */");
HostVertexElementDataType = D3DDECLTYPE_FLOAT2; HostVertexElementDataType = D3DDECLTYPE_FLOAT2;
HostVertexElementByteSize = 2 * sizeof(FLOAT); HostVertexElementByteSize = 2 * sizeof(FLOAT);
XboxVertexElementByteSize = 2 * sizeof(XTL::SHORT);
NeedPatching = TRUE; NeedPatching = TRUE;
} }
break; break;
@ -2024,6 +2060,7 @@ private:
HostVertexElementDataType = D3DDECLTYPE_FLOAT3; HostVertexElementDataType = D3DDECLTYPE_FLOAT3;
HostVertexElementByteSize = 3 * sizeof(FLOAT); HostVertexElementByteSize = 3 * sizeof(FLOAT);
} }
XboxVertexElementByteSize = 3 * sizeof(XTL::SHORT);
NeedPatching = TRUE; NeedPatching = TRUE;
break; break;
case XTL::X_D3DVSDT_NORMSHORT4: // 0x41: case XTL::X_D3DVSDT_NORMSHORT4: // 0x41:
@ -2038,6 +2075,7 @@ private:
DbgVshPrintf("D3DVSDT_NORMSHORT4 /* xbox ext. */"); DbgVshPrintf("D3DVSDT_NORMSHORT4 /* xbox ext. */");
HostVertexElementDataType = D3DDECLTYPE_FLOAT4; HostVertexElementDataType = D3DDECLTYPE_FLOAT4;
HostVertexElementByteSize = 4 * sizeof(FLOAT); HostVertexElementByteSize = 4 * sizeof(FLOAT);
XboxVertexElementByteSize = 4 * sizeof(XTL::SHORT);
NeedPatching = TRUE; NeedPatching = TRUE;
} }
break; break;
@ -2045,18 +2083,21 @@ private:
DbgVshPrintf("D3DVSDT_NORMPACKED3 /* xbox ext. */"); DbgVshPrintf("D3DVSDT_NORMPACKED3 /* xbox ext. */");
HostVertexElementDataType = D3DDECLTYPE_FLOAT3; HostVertexElementDataType = D3DDECLTYPE_FLOAT3;
HostVertexElementByteSize = 3 * sizeof(FLOAT); HostVertexElementByteSize = 3 * sizeof(FLOAT);
XboxVertexElementByteSize = 1 * sizeof(XTL::DWORD);
NeedPatching = TRUE; NeedPatching = TRUE;
break; break;
case XTL::X_D3DVSDT_SHORT1: // 0x15: case XTL::X_D3DVSDT_SHORT1: // 0x15:
DbgVshPrintf("D3DVSDT_SHORT1 /* xbox ext. */"); DbgVshPrintf("D3DVSDT_SHORT1 /* xbox ext. */");
HostVertexElementDataType = D3DDECLTYPE_SHORT2; HostVertexElementDataType = D3DDECLTYPE_SHORT2;
HostVertexElementByteSize = 2 * sizeof(SHORT); HostVertexElementByteSize = 2 * sizeof(SHORT);
XboxVertexElementByteSize = 1 * sizeof(XTL::SHORT);
NeedPatching = TRUE; NeedPatching = TRUE;
break; break;
case XTL::X_D3DVSDT_SHORT3: // 0x35: case XTL::X_D3DVSDT_SHORT3: // 0x35:
DbgVshPrintf("D3DVSDT_SHORT3 /* xbox ext. */"); DbgVshPrintf("D3DVSDT_SHORT3 /* xbox ext. */");
HostVertexElementDataType = D3DDECLTYPE_SHORT4; HostVertexElementDataType = D3DDECLTYPE_SHORT4;
HostVertexElementByteSize = 4 * sizeof(SHORT); HostVertexElementByteSize = 4 * sizeof(SHORT);
XboxVertexElementByteSize = 3 * sizeof(XTL::SHORT);
NeedPatching = TRUE; NeedPatching = TRUE;
break; break;
case XTL::X_D3DVSDT_PBYTE1: // 0x14: case XTL::X_D3DVSDT_PBYTE1: // 0x14:
@ -2070,6 +2111,7 @@ private:
HostVertexElementDataType = D3DDECLTYPE_FLOAT1; HostVertexElementDataType = D3DDECLTYPE_FLOAT1;
HostVertexElementByteSize = 1 * sizeof(FLOAT); HostVertexElementByteSize = 1 * sizeof(FLOAT);
} }
XboxVertexElementByteSize = 1 * sizeof(XTL::BYTE);
NeedPatching = TRUE; NeedPatching = TRUE;
break; break;
case XTL::X_D3DVSDT_PBYTE2: // 0x24: case XTL::X_D3DVSDT_PBYTE2: // 0x24:
@ -2083,6 +2125,7 @@ private:
HostVertexElementDataType = D3DDECLTYPE_FLOAT2; HostVertexElementDataType = D3DDECLTYPE_FLOAT2;
HostVertexElementByteSize = 2 * sizeof(FLOAT); HostVertexElementByteSize = 2 * sizeof(FLOAT);
} }
XboxVertexElementByteSize = 2 * sizeof(XTL::BYTE);
NeedPatching = TRUE; NeedPatching = TRUE;
break; break;
case XTL::X_D3DVSDT_PBYTE3: // 0x34: case XTL::X_D3DVSDT_PBYTE3: // 0x34:
@ -2096,6 +2139,7 @@ private:
HostVertexElementDataType = D3DDECLTYPE_FLOAT3; HostVertexElementDataType = D3DDECLTYPE_FLOAT3;
HostVertexElementByteSize = 3 * sizeof(FLOAT); HostVertexElementByteSize = 3 * sizeof(FLOAT);
} }
XboxVertexElementByteSize = 3 * sizeof(XTL::BYTE);
NeedPatching = TRUE; NeedPatching = TRUE;
break; break;
case XTL::X_D3DVSDT_PBYTE4: // 0x44: case XTL::X_D3DVSDT_PBYTE4: // 0x44:
@ -2111,6 +2155,7 @@ private:
DbgVshPrintf("D3DVSDT_PBYTE4 /* xbox ext. */"); DbgVshPrintf("D3DVSDT_PBYTE4 /* xbox ext. */");
HostVertexElementDataType = D3DDECLTYPE_FLOAT4; HostVertexElementDataType = D3DDECLTYPE_FLOAT4;
HostVertexElementByteSize = 4 * sizeof(FLOAT); HostVertexElementByteSize = 4 * sizeof(FLOAT);
XboxVertexElementByteSize = 4 * sizeof(XTL::BYTE);
NeedPatching = TRUE; NeedPatching = TRUE;
} }
break; break;
@ -2118,11 +2163,12 @@ private:
DbgVshPrintf("D3DVSDT_FLOAT2H /* xbox ext. */"); DbgVshPrintf("D3DVSDT_FLOAT2H /* xbox ext. */");
HostVertexElementDataType = D3DDECLTYPE_FLOAT4; HostVertexElementDataType = D3DDECLTYPE_FLOAT4;
HostVertexElementByteSize = 4 * sizeof(FLOAT); HostVertexElementByteSize = 4 * sizeof(FLOAT);
XboxVertexElementByteSize = 3 * sizeof(FLOAT);
NeedPatching = TRUE; NeedPatching = TRUE;
break; break;
case XTL::X_D3DVSDT_NONE: // 0x02: case XTL::X_D3DVSDT_NONE: // 0x02:
DbgVshPrintf("D3DVSDT_NONE /* xbox ext. */"); DbgVshPrintf("D3DVSDT_NONE /* xbox ext. */");
// Ignore token // No host element data, so no patching
break; break;
default: default:
DbgVshPrintf("Unknown data type for D3DVSD_REG: 0x%02X\n", XboxVertexElementDataType); DbgVshPrintf("Unknown data type for D3DVSD_REG: 0x%02X\n", XboxVertexElementDataType);
@ -2134,15 +2180,17 @@ private:
// On X_D3DVSDT_NONE skip this token // On X_D3DVSDT_NONE skip this token
if (XboxVertexElementDataType == XTL::X_D3DVSDT_NONE) if (XboxVertexElementDataType == XTL::X_D3DVSDT_NONE)
{ {
// Xbox elements with X_D3DVSDT_NONE have size zero, so there's no need to register those.
// Note, that for skip tokens, we DO call VshConvert_RegisterVertexElement with a X_D3DVSDT_NONE!
return; return;
} }
// save patching information // save patching information
CxbxVertexShaderStreamElement *pCurrentElement = &(pCurrentVertexShaderStreamInfo->VertexElements[pCurrentVertexShaderStreamInfo->NumberOfVertexElements]); VshConvert_RegisterVertexElement(
pCurrentElement->XboxType = XboxVertexElementDataType; XboxVertexElementDataType,
pCurrentElement->HostByteSize = HostVertexElementByteSize; NeedPatching ? XboxVertexElementByteSize : HostVertexElementByteSize,
pCurrentVertexShaderStreamInfo->NumberOfVertexElements++; HostVertexElementByteSize,
pCurrentVertexShaderStreamInfo->NeedPatch |= NeedPatching; NeedPatching);
pRecompiled->Stream = pCurrentVertexShaderStreamInfo->CurrentStreamNumber; pRecompiled->Stream = pCurrentVertexShaderStreamInfo->CurrentStreamNumber;
pRecompiled->Offset = pCurrentVertexShaderStreamInfo->HostVertexStride; pRecompiled->Offset = pCurrentVertexShaderStreamInfo->HostVertexStride;
@ -2154,7 +2202,6 @@ private:
pRecompiled++; pRecompiled++;
pCurrentVertexShaderStreamInfo->HostVertexStride += HostVertexElementByteSize; pCurrentVertexShaderStreamInfo->HostVertexStride += HostVertexElementByteSize;
} }
void VshConvertToken_STREAMDATA(DWORD *pXboxToken) void VshConvertToken_STREAMDATA(DWORD *pXboxToken)

View File

@ -37,6 +37,7 @@
typedef struct _CxbxVertexShaderStreamElement typedef struct _CxbxVertexShaderStreamElement
{ {
UINT XboxType; // The stream element data types (xbox) UINT XboxType; // The stream element data types (xbox)
UINT XboxByteSize; // The stream element data sizes (xbox)
UINT HostByteSize; // The stream element data sizes (pc) UINT HostByteSize; // The stream element data sizes (pc)
} }
CxbxVertexShaderStreamElement; CxbxVertexShaderStreamElement;