Change IVB to an array of 4-float slots
Will fix Halo logo and menu text rendering (once it's visible!) - Remove references to fixed function concepts, since slots might contain anything e.g. don't exclude the 4th component of the slot corresponding to NORMAL in fixed function mode - Use the IVB table directly for simplicity. Copy all table data to the vertex buffer
This commit is contained in:
parent
2397ece059
commit
0453e451f1
|
@ -1177,6 +1177,7 @@ struct X_D3DVertexShader
|
|||
// vertex shader input registers for fixed function vertex shader
|
||||
|
||||
// Name Register number D3DFVF
|
||||
const int X_D3DVSDE_VERTEX = -1; // Xbox extension for Begin/End drawing - equivalent to POSITION
|
||||
const int X_D3DVSDE_POSITION = 0; // Corresponds to X_D3DFVF_XYZ
|
||||
const int X_D3DVSDE_BLENDWEIGHT = 1; // Corresponds to X_D3DFVF_XYZB1? (was X_D3DFVF_XYZRHW?)
|
||||
const int X_D3DVSDE_NORMAL = 2; // Corresponds to X_D3DFVF_NORMAL
|
||||
|
@ -1190,7 +1191,6 @@ const int X_D3DVSDE_TEXCOORD0 = 9; // Corresponds to X_D3DFVF_TEX1 (not X_D3D
|
|||
const int X_D3DVSDE_TEXCOORD1 = 10; // Corresponds to X_D3DFVF_TEX2
|
||||
const int X_D3DVSDE_TEXCOORD2 = 11; // Corresponds to X_D3DFVF_TEX3
|
||||
const int X_D3DVSDE_TEXCOORD3 = 12; // Corresponds to X_D3DFVF_TEX4
|
||||
const int X_D3DVSDE_VERTEX = 0xFFFFFFFF; // Xbox extension for Begin/End drawing (data is a D3DVSDT_FLOAT4)
|
||||
|
||||
//typedef X_D3DVSDE = X_D3DVSDE_POSITION..High(DWORD)-2; // Unique declaration to make overloads possible;
|
||||
|
||||
|
|
|
@ -50,14 +50,11 @@ CxbxVertexBufferConverter VertexBufferConverter = {};
|
|||
|
||||
// Inline vertex buffer emulation
|
||||
xbox::X_D3DPRIMITIVETYPE g_InlineVertexBuffer_PrimitiveType = xbox::X_D3DPT_INVALID;
|
||||
uint32_t g_InlineVertexBuffer_WrittenRegisters = 0; // A bitmask, indicating which registers have been set in g_InlineVertexBuffer_Table
|
||||
xbox::X_VERTEXATTRIBUTEFORMAT g_InlineVertexBuffer_AttributeFormat = {};
|
||||
bool g_InlineVertexBuffer_DeclarationOverride = false;
|
||||
std::vector<D3DIVB> g_InlineVertexBuffer_Table;
|
||||
UINT g_InlineVertexBuffer_TableLength = 0;
|
||||
UINT g_InlineVertexBuffer_TableOffset = 0;
|
||||
FLOAT *g_InlineVertexBuffer_pData = nullptr;
|
||||
UINT g_InlineVertexBuffer_DataSize = 0;
|
||||
|
||||
// Copy of active Xbox D3D Vertex Streams (and strides), set by [D3DDevice|CxbxImpl]_SetStreamSource*
|
||||
xbox::X_STREAMINPUT g_Xbox_SetStreamSource[X_VSH_MAX_STREAMS] = { 0 }; // Note : .Offset member is never set (so always 0)
|
||||
|
@ -69,28 +66,6 @@ bool GetHostRenderTargetDimensions(DWORD* pHostWidth, DWORD* pHostHeight, IDirec
|
|||
uint32_t GetPixelContainerWidth(xbox::X_D3DPixelContainer* pPixelContainer);
|
||||
uint32_t GetPixelContainerHeight(xbox::X_D3DPixelContainer* pPixelContainer);
|
||||
|
||||
struct _D3DIVB &_D3DIVB::operator=(const struct _D3DIVB &Val)
|
||||
{
|
||||
Position.x = Val.Position.x;
|
||||
Position.y = Val.Position.y;
|
||||
Position.z = Val.Position.z;
|
||||
Rhw = Val.Rhw;
|
||||
std::copy(std::begin(Val.Blend), std::end(Val.Blend), std::begin(Blend));
|
||||
Normal.x = Val.Normal.x;
|
||||
Normal.y = Val.Normal.y;
|
||||
Normal.z = Val.Normal.z;
|
||||
Diffuse = Val.Diffuse;
|
||||
Specular = Val.Specular;
|
||||
Fog = Val.Fog;
|
||||
PointSize = Val.PointSize;
|
||||
BackDiffuse = Val.BackDiffuse;
|
||||
BackSpecular = Val.BackSpecular;
|
||||
std::copy(std::begin(Val.TexCoord), std::end(Val.TexCoord), std::begin(TexCoord));
|
||||
std::copy(std::begin(Val.Reg13Up), std::end(Val.Reg13Up), std::begin(Reg13Up));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void CxbxPatchedStream::Activate(CxbxDrawContext *pDrawContext, UINT HostStreamNumber) const
|
||||
{
|
||||
//LOG_INIT // Allows use of DEBUG_D3DRESULT
|
||||
|
@ -716,134 +691,27 @@ void CxbxSetVertexAttribute(int Register, FLOAT a, FLOAT b, FLOAT c, FLOAT d)
|
|||
g_pD3DDevice->SetVertexShaderConstantF(CXBX_D3DVS_CONSTREG_VREGDEFAULTS_BASE + Register, attribute_floats, 1);
|
||||
}
|
||||
|
||||
DWORD Float4ToDWORD(float* floats)
|
||||
{
|
||||
// Inverse of D3DDevice_SetVertexDataColor
|
||||
uint8_t a = uint8_t(floats[0] * 255.0f);
|
||||
uint8_t b = uint8_t(floats[1] * 255.0f);
|
||||
uint8_t c = uint8_t(floats[2] * 255.0f);
|
||||
uint8_t d = uint8_t(floats[3] * 255.0f);
|
||||
uint32_t value = a + (b << 8) + (c << 16) + (d << 24);
|
||||
return value;
|
||||
}
|
||||
|
||||
void CxbxImpl_Begin(xbox::X_D3DPRIMITIVETYPE PrimitiveType)
|
||||
{
|
||||
g_InlineVertexBuffer_PrimitiveType = PrimitiveType;
|
||||
g_InlineVertexBuffer_TableOffset = 0;
|
||||
g_InlineVertexBuffer_WrittenRegisters = 0;
|
||||
}
|
||||
|
||||
void CxbxImpl_End()
|
||||
{
|
||||
using namespace xbox;
|
||||
|
||||
#ifndef FIELD_OFFSET
|
||||
#define FIELD_OFFSET(type, field) ((LONG)(LONG_PTR)&(((type *)0)->field))
|
||||
#endif
|
||||
static const LONG OffsetPerRegister[X_VSH_MAX_ATTRIBUTES] = {
|
||||
/*X_D3DVSDE_POSITION = 0:*/FIELD_OFFSET(D3DIVB, Position),
|
||||
/*X_D3DVSDE_BLENDWEIGHT = 1:*/FIELD_OFFSET(D3DIVB, Blend),
|
||||
/*X_D3DVSDE_NORMAL = 2:*/FIELD_OFFSET(D3DIVB, Normal),
|
||||
/*X_D3DVSDE_DIFFUSE = 3:*/FIELD_OFFSET(D3DIVB, Diffuse),
|
||||
/*X_D3DVSDE_SPECULAR = 4:*/FIELD_OFFSET(D3DIVB, Specular),
|
||||
/*X_D3DVSDE_FOG = 5:*/FIELD_OFFSET(D3DIVB, Fog),
|
||||
/*X_D3DVSDE_POINTSIZE = 6:*/FIELD_OFFSET(D3DIVB, PointSize),
|
||||
/*X_D3DVSDE_BACKDIFFUSE = 7:*/FIELD_OFFSET(D3DIVB, BackDiffuse),
|
||||
/*X_D3DVSDE_BACKSPECULAR = 8:*/FIELD_OFFSET(D3DIVB, BackSpecular),
|
||||
/*X_D3DVSDE_TEXCOORD0 = 9:*/FIELD_OFFSET(D3DIVB, TexCoord[0]),
|
||||
/*X_D3DVSDE_TEXCOORD1 = 10:*/FIELD_OFFSET(D3DIVB, TexCoord[1]),
|
||||
/*X_D3DVSDE_TEXCOORD2 = 11:*/FIELD_OFFSET(D3DIVB, TexCoord[2]),
|
||||
/*X_D3DVSDE_TEXCOORD3 = 12:*/FIELD_OFFSET(D3DIVB, TexCoord[3]),
|
||||
/* 13:*/FIELD_OFFSET(D3DIVB, Reg13Up[0]),
|
||||
/* 14:*/FIELD_OFFSET(D3DIVB, Reg13Up[1]),
|
||||
/* 15:*/FIELD_OFFSET(D3DIVB, Reg13Up[2])
|
||||
};
|
||||
static const LONG FormatPerRegister[X_VSH_MAX_ATTRIBUTES] = {
|
||||
/*X_D3DVSDE_POSITION = 0:*/X_D3DVSDT_FLOAT4,
|
||||
/*X_D3DVSDE_BLENDWEIGHT = 1:*/X_D3DVSDT_FLOAT4,
|
||||
/*X_D3DVSDE_NORMAL = 2:*/X_D3DVSDT_FLOAT3,
|
||||
/*X_D3DVSDE_DIFFUSE = 3:*/X_D3DVSDT_D3DCOLOR,
|
||||
/*X_D3DVSDE_SPECULAR = 4:*/X_D3DVSDT_D3DCOLOR,
|
||||
/*X_D3DVSDE_FOG = 5:*/X_D3DVSDT_FLOAT1,
|
||||
/*X_D3DVSDE_POINTSIZE = 6:*/X_D3DVSDT_FLOAT1,
|
||||
/*X_D3DVSDE_BACKDIFFUSE = 7:*/X_D3DVSDT_D3DCOLOR,
|
||||
/*X_D3DVSDE_BACKSPECULAR = 8:*/X_D3DVSDT_D3DCOLOR,
|
||||
/*X_D3DVSDE_TEXCOORD0 = 9:*/X_D3DVSDT_FLOAT4,
|
||||
/*X_D3DVSDE_TEXCOORD1 = 10:*/X_D3DVSDT_FLOAT4,
|
||||
/*X_D3DVSDE_TEXCOORD2 = 11:*/X_D3DVSDT_FLOAT4,
|
||||
/*X_D3DVSDE_TEXCOORD3 = 12:*/X_D3DVSDT_FLOAT4,
|
||||
/* 13:*/X_D3DVSDT_FLOAT4,
|
||||
/* 14:*/X_D3DVSDT_FLOAT4,
|
||||
/* 15:*/X_D3DVSDT_FLOAT4
|
||||
};
|
||||
static const DWORD SizePerRegister[X_VSH_MAX_ATTRIBUTES] = {
|
||||
/*X_D3DVSDE_POSITION = 0:*/sizeof(float) * 4,
|
||||
/*X_D3DVSDE_BLENDWEIGHT = 1:*/sizeof(float) * 4,
|
||||
/*X_D3DVSDE_NORMAL = 2:*/sizeof(float) * 3,
|
||||
/*X_D3DVSDE_DIFFUSE = 3:*/sizeof(DWORD),
|
||||
/*X_D3DVSDE_SPECULAR = 4:*/sizeof(DWORD),
|
||||
/*X_D3DVSDE_FOG = 5:*/sizeof(float) * 1,
|
||||
/*X_D3DVSDE_POINTSIZE = 6:*/sizeof(float) * 1,
|
||||
/*X_D3DVSDE_BACKDIFFUSE = 7:*/sizeof(DWORD),
|
||||
/*X_D3DVSDE_BACKSPECULAR = 8:*/sizeof(DWORD),
|
||||
/*X_D3DVSDE_TEXCOORD0 = 9:*/sizeof(float) * 4,
|
||||
/*X_D3DVSDE_TEXCOORD1 = 10:*/sizeof(float) * 4,
|
||||
/*X_D3DVSDE_TEXCOORD2 = 11:*/sizeof(float) * 4,
|
||||
/*X_D3DVSDE_TEXCOORD3 = 12:*/sizeof(float) * 4,
|
||||
/* 13:*/sizeof(float) * 4,
|
||||
/* 14:*/sizeof(float) * 4,
|
||||
/* 15:*/sizeof(float) * 4
|
||||
};
|
||||
|
||||
if (g_InlineVertexBuffer_TableOffset <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Compose an Xbox vertex attribute format according to the registers that have been written to :
|
||||
// Compose an Xbox vertex attribute format to pass through all registers
|
||||
UINT uiStride = 0;
|
||||
g_InlineVertexBuffer_AttributeFormat = {};
|
||||
for (int reg = 0; reg < X_VSH_MAX_ATTRIBUTES; reg++) {
|
||||
if (g_InlineVertexBuffer_WrittenRegisters & (1 << reg)) {
|
||||
g_InlineVertexBuffer_AttributeFormat.Slots[reg].Format = FormatPerRegister[reg];
|
||||
g_InlineVertexBuffer_AttributeFormat.Slots[reg].Offset = uiStride;
|
||||
uiStride += SizePerRegister[reg];
|
||||
} else {
|
||||
g_InlineVertexBuffer_AttributeFormat.Slots[reg].Format = X_D3DVSDT_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure the output buffer is big enough
|
||||
UINT NeededSize = g_InlineVertexBuffer_TableOffset * uiStride;
|
||||
if (g_InlineVertexBuffer_DataSize < NeededSize) {
|
||||
g_InlineVertexBuffer_DataSize = NeededSize;
|
||||
if (g_InlineVertexBuffer_pData != nullptr) {
|
||||
free(g_InlineVertexBuffer_pData);
|
||||
}
|
||||
|
||||
g_InlineVertexBuffer_pData = (FLOAT*)malloc(g_InlineVertexBuffer_DataSize);
|
||||
}
|
||||
|
||||
// For each register that ever got written, copy the data over from
|
||||
// g_InlineVertexBuffer_Table to pVertexBufferData, but adjacent
|
||||
// to eachother. This, so that host accepts this as a vertex declaration.
|
||||
// Note, that if we figure out how to draw using vertex buffers that
|
||||
// contain gaps, the following copy is no longer needed, and we could
|
||||
// draw straight from g_InlineVertexBuffer_Table instead!
|
||||
uint8_t* pVertexBufferData = (uint8_t*)g_InlineVertexBuffer_pData;
|
||||
for (unsigned int v = 0; v < g_InlineVertexBuffer_TableOffset; v++) {
|
||||
auto vertex_ptr = (uint8_t*)&(g_InlineVertexBuffer_Table[v]);
|
||||
for (unsigned int reg = 0; reg < X_VSH_MAX_ATTRIBUTES; reg++) {
|
||||
if (g_InlineVertexBuffer_WrittenRegisters & (1 << reg)) {
|
||||
auto source = vertex_ptr + OffsetPerRegister[reg];
|
||||
auto size = SizePerRegister[reg];
|
||||
// Note, that g_InlineVertexBuffer_AttributeFormat is declared with
|
||||
// data types (in g_InlineVertexBuffer_Table ) that are host-compatible,
|
||||
// so we can do a straight copy here, there's no conversion needed :
|
||||
memcpy(pVertexBufferData, source, size);
|
||||
pVertexBufferData += size;
|
||||
}
|
||||
}
|
||||
g_InlineVertexBuffer_AttributeFormat.Slots[reg].Format = X_D3DVSDT_FLOAT4;
|
||||
g_InlineVertexBuffer_AttributeFormat.Slots[reg].Offset = uiStride;
|
||||
uiStride += sizeof(float) * 4;
|
||||
}
|
||||
|
||||
// Arrange for g_InlineVertexBuffer_AttributeFormat to be returned in CxbxGetVertexDeclaration,
|
||||
|
@ -859,7 +727,7 @@ void CxbxImpl_End()
|
|||
|
||||
DrawContext.XboxPrimitiveType = g_InlineVertexBuffer_PrimitiveType;
|
||||
DrawContext.dwVertexCount = g_InlineVertexBuffer_TableOffset;
|
||||
DrawContext.pXboxVertexStreamZeroData = g_InlineVertexBuffer_pData;
|
||||
DrawContext.pXboxVertexStreamZeroData = g_InlineVertexBuffer_Table.data();
|
||||
DrawContext.uiXboxVertexStreamZeroStride = uiStride;
|
||||
|
||||
CxbxDrawPrimitiveUP(DrawContext);
|
||||
|
@ -904,134 +772,34 @@ void CxbxImpl_SetVertexData4f(int Register, FLOAT a, FLOAT b, FLOAT c, FLOAT d)
|
|||
}
|
||||
|
||||
// Is this the initial call after D3DDevice_Begin() ?
|
||||
if (g_InlineVertexBuffer_WrittenRegisters == 0) {
|
||||
if (g_InlineVertexBuffer_TableOffset == 0) {
|
||||
// Read starting values for all inline vertex attributes from HLE NV2A pgraph (converting them to required types) :
|
||||
g_InlineVertexBuffer_Table[0].Position = D3DXVECTOR3(HLE_get_NV2A_vertex_attribute_value_pointer(X_D3DVSDE_POSITION));
|
||||
g_InlineVertexBuffer_Table[0].Rhw = HLE_get_NV2A_vertex_attribute_value_pointer(X_D3DVSDE_POSITION)[3];
|
||||
g_InlineVertexBuffer_Table[0].Blend[0] = HLE_get_NV2A_vertex_attribute_value_pointer(X_D3DVSDE_BLENDWEIGHT)[0];
|
||||
g_InlineVertexBuffer_Table[0].Blend[1] = HLE_get_NV2A_vertex_attribute_value_pointer(X_D3DVSDE_BLENDWEIGHT)[1];
|
||||
g_InlineVertexBuffer_Table[0].Blend[2] = HLE_get_NV2A_vertex_attribute_value_pointer(X_D3DVSDE_BLENDWEIGHT)[2];
|
||||
g_InlineVertexBuffer_Table[0].Blend[3] = HLE_get_NV2A_vertex_attribute_value_pointer(X_D3DVSDE_BLENDWEIGHT)[3];
|
||||
g_InlineVertexBuffer_Table[0].Normal = D3DXVECTOR3(HLE_get_NV2A_vertex_attribute_value_pointer(X_D3DVSDE_NORMAL));
|
||||
g_InlineVertexBuffer_Table[0].Diffuse = Float4ToDWORD(HLE_get_NV2A_vertex_attribute_value_pointer(X_D3DVSDE_DIFFUSE));
|
||||
g_InlineVertexBuffer_Table[0].Specular = Float4ToDWORD(HLE_get_NV2A_vertex_attribute_value_pointer(X_D3DVSDE_SPECULAR));
|
||||
g_InlineVertexBuffer_Table[0].Fog = HLE_get_NV2A_vertex_attribute_value_pointer(X_D3DVSDE_FOG)[0];
|
||||
g_InlineVertexBuffer_Table[0].PointSize = HLE_get_NV2A_vertex_attribute_value_pointer(X_D3DVSDE_POINTSIZE)[0];
|
||||
g_InlineVertexBuffer_Table[0].BackDiffuse = Float4ToDWORD(HLE_get_NV2A_vertex_attribute_value_pointer(X_D3DVSDE_BACKDIFFUSE));
|
||||
g_InlineVertexBuffer_Table[0].BackSpecular = Float4ToDWORD(HLE_get_NV2A_vertex_attribute_value_pointer(X_D3DVSDE_BACKSPECULAR));
|
||||
g_InlineVertexBuffer_Table[0].TexCoord[0] = D3DXVECTOR4(HLE_get_NV2A_vertex_attribute_value_pointer(X_D3DVSDE_TEXCOORD0));
|
||||
g_InlineVertexBuffer_Table[0].TexCoord[1] = D3DXVECTOR4(HLE_get_NV2A_vertex_attribute_value_pointer(X_D3DVSDE_TEXCOORD1));
|
||||
g_InlineVertexBuffer_Table[0].TexCoord[2] = D3DXVECTOR4(HLE_get_NV2A_vertex_attribute_value_pointer(X_D3DVSDE_TEXCOORD2));
|
||||
g_InlineVertexBuffer_Table[0].TexCoord[3] = D3DXVECTOR4(HLE_get_NV2A_vertex_attribute_value_pointer(X_D3DVSDE_TEXCOORD3));
|
||||
g_InlineVertexBuffer_Table[0].Reg13Up[0] = D3DXVECTOR4(HLE_get_NV2A_vertex_attribute_value_pointer(13));
|
||||
g_InlineVertexBuffer_Table[0].Reg13Up[1] = D3DXVECTOR4(HLE_get_NV2A_vertex_attribute_value_pointer(14));
|
||||
g_InlineVertexBuffer_Table[0].Reg13Up[2] = D3DXVECTOR4(HLE_get_NV2A_vertex_attribute_value_pointer(15));
|
||||
for (int i = 0; i < X_VSH_MAX_ATTRIBUTES; i++) {
|
||||
g_InlineVertexBuffer_Table[0].Slots[i] = D3DXVECTOR4(HLE_get_NV2A_vertex_attribute_value_pointer(i));
|
||||
}
|
||||
// Note : Because all members are assigned an initial value, there's no need for a clearing constructor for _D3DIVB!
|
||||
}
|
||||
|
||||
if (Register == X_D3DVSDE_VERTEX)
|
||||
g_InlineVertexBuffer_WrittenRegisters |= (1 << X_D3DVSDE_POSITION);
|
||||
else if (Register < 16)
|
||||
g_InlineVertexBuffer_WrittenRegisters |= (1 << Register);
|
||||
// Write vertex data to the IVB table
|
||||
if (Register >= X_D3DVSDE_VERTEX && Register <= X_VSH_MAX_ATTRIBUTES) {
|
||||
// The slot index is usually the register value, but
|
||||
// VERTEX (-1) maps to POSITION (0)
|
||||
int index = Register;
|
||||
if (Register == X_D3DVSDE_VERTEX)
|
||||
index = X_D3DVSDE_POSITION;
|
||||
|
||||
unsigned o = g_InlineVertexBuffer_TableOffset;
|
||||
unsigned o = g_InlineVertexBuffer_TableOffset;
|
||||
g_InlineVertexBuffer_Table[o].Slots[index] = D3DXVECTOR4(a, b, c, d);
|
||||
|
||||
switch (Register)
|
||||
{
|
||||
case X_D3DVSDE_VERTEX:
|
||||
case X_D3DVSDE_POSITION:
|
||||
{
|
||||
// Note : Setting position signals completion of a vertex
|
||||
g_InlineVertexBuffer_Table[o].Position.x = a;
|
||||
g_InlineVertexBuffer_Table[o].Position.y = b;
|
||||
g_InlineVertexBuffer_Table[o].Position.z = c;
|
||||
g_InlineVertexBuffer_Table[o].Rhw = d;
|
||||
// Start a new vertex
|
||||
g_InlineVertexBuffer_TableOffset++;
|
||||
// Copy all attributes of the prior vertex to the new one, to simulate persistent attribute values
|
||||
g_InlineVertexBuffer_Table[g_InlineVertexBuffer_TableOffset] = g_InlineVertexBuffer_Table[o];
|
||||
break;
|
||||
// Writing to the POSITION slot completes the current vertex
|
||||
if (index == X_D3DVSDE_POSITION) {
|
||||
// Start a new vertex
|
||||
g_InlineVertexBuffer_TableOffset++;
|
||||
// Copy all attributes of the prior vertex to the new one, to simulate persistent attribute values
|
||||
g_InlineVertexBuffer_Table[g_InlineVertexBuffer_TableOffset] = g_InlineVertexBuffer_Table[o];
|
||||
}
|
||||
}
|
||||
|
||||
case X_D3DVSDE_BLENDWEIGHT:
|
||||
{
|
||||
g_InlineVertexBuffer_Table[o].Blend[0] = a;
|
||||
g_InlineVertexBuffer_Table[o].Blend[1] = b;
|
||||
g_InlineVertexBuffer_Table[o].Blend[2] = c;
|
||||
g_InlineVertexBuffer_Table[o].Blend[3] = d;
|
||||
break;
|
||||
}
|
||||
|
||||
case X_D3DVSDE_NORMAL:
|
||||
{
|
||||
g_InlineVertexBuffer_Table[o].Normal.x = a;
|
||||
g_InlineVertexBuffer_Table[o].Normal.y = b;
|
||||
g_InlineVertexBuffer_Table[o].Normal.z = c;
|
||||
break;
|
||||
}
|
||||
|
||||
case X_D3DVSDE_DIFFUSE:
|
||||
{
|
||||
g_InlineVertexBuffer_Table[o].Diffuse = D3DCOLOR_COLORVALUE(a, b, c, d);
|
||||
break;
|
||||
}
|
||||
|
||||
case X_D3DVSDE_SPECULAR:
|
||||
{
|
||||
g_InlineVertexBuffer_Table[o].Specular = D3DCOLOR_COLORVALUE(a, b, c, d);
|
||||
break;
|
||||
}
|
||||
|
||||
case X_D3DVSDE_FOG: // Xbox extension
|
||||
{
|
||||
g_InlineVertexBuffer_Table[o].Fog = a; // TODO : What about the other (b, c and d) arguments?
|
||||
break;
|
||||
}
|
||||
|
||||
case X_D3DVSDE_POINTSIZE:
|
||||
{
|
||||
g_InlineVertexBuffer_Table[o].PointSize = a; // TODO : What about the other (b, c and d) arguments?
|
||||
break;
|
||||
}
|
||||
|
||||
case X_D3DVSDE_BACKDIFFUSE: // Xbox extension
|
||||
{
|
||||
g_InlineVertexBuffer_Table[o].BackDiffuse = D3DCOLOR_COLORVALUE(a, b, c, d);
|
||||
break;
|
||||
}
|
||||
|
||||
case X_D3DVSDE_BACKSPECULAR: // Xbox extension
|
||||
{
|
||||
g_InlineVertexBuffer_Table[o].BackSpecular = D3DCOLOR_COLORVALUE(a, b, c, d);
|
||||
break;
|
||||
}
|
||||
|
||||
case X_D3DVSDE_TEXCOORD0:
|
||||
case X_D3DVSDE_TEXCOORD1:
|
||||
case X_D3DVSDE_TEXCOORD2:
|
||||
case X_D3DVSDE_TEXCOORD3:
|
||||
{
|
||||
unsigned i = Register - X_D3DVSDE_TEXCOORD0;
|
||||
g_InlineVertexBuffer_Table[o].TexCoord[i].x = a;
|
||||
g_InlineVertexBuffer_Table[o].TexCoord[i].y = b;
|
||||
g_InlineVertexBuffer_Table[o].TexCoord[i].z = c;
|
||||
g_InlineVertexBuffer_Table[o].TexCoord[i].w = d;
|
||||
break;
|
||||
}
|
||||
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
{
|
||||
unsigned i = Register - 13;
|
||||
g_InlineVertexBuffer_Table[o].Reg13Up[i].x = a;
|
||||
g_InlineVertexBuffer_Table[o].Reg13Up[i].y = b;
|
||||
g_InlineVertexBuffer_Table[o].Reg13Up[i].z = c;
|
||||
g_InlineVertexBuffer_Table[o].Reg13Up[i].w = d;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
else {
|
||||
EmuLog(LOG_LEVEL::WARNING, "Unknown IVB Register : %d", Register);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
#include <unordered_map>
|
||||
#include <list>
|
||||
#include <array>
|
||||
|
||||
#include "Cxbx.h"
|
||||
|
||||
|
@ -123,23 +124,7 @@ extern xbox::X_D3DPRIMITIVETYPE g_InlineVertexBuffer_PrimitiveType;
|
|||
|
||||
typedef struct _D3DIVB
|
||||
{
|
||||
D3DXVECTOR3 Position; // X_D3DVSDE_POSITION (*) > D3DFVF_XYZ / D3DFVF_XYZRHW
|
||||
FLOAT Rhw; // X_D3DVSDE_VERTEX (*) > D3DFVF_XYZ / D3DFVF_XYZRHW
|
||||
FLOAT Blend[4]; // X_D3DVSDE_BLENDWEIGHT > D3DFVF_XYZB1 (and 3 more up to D3DFVF_XYZB4)
|
||||
D3DXVECTOR3 Normal; // X_D3DVSDE_NORMAL > D3DFVF_NORMAL
|
||||
D3DCOLOR Diffuse; // X_D3DVSDE_DIFFUSE > D3DFVF_DIFFUSE
|
||||
D3DCOLOR Specular; // X_D3DVSDE_SPECULAR > D3DFVF_SPECULAR
|
||||
FLOAT Fog; // X_D3DVSDE_FOG > D3DFVF_FOG unavailable; TODO : How to handle?
|
||||
FLOAT PointSize; // X_D3DVSDE_POINTSIZE > D3DFVF_POINTSIZE unavailable; TODO : How to handle?
|
||||
D3DCOLOR BackDiffuse; // X_D3DVSDE_BACKDIFFUSE > D3DFVF_BACKDIFFUSE unavailable; TODO : How to handle?
|
||||
D3DCOLOR BackSpecular; // X_D3DVSDE_BACKSPECULAR > D3DFVF_BACKSPECULAR unavailable; TODO : How to handle?
|
||||
D3DXVECTOR4 TexCoord[4]; // X_D3DVSDE_TEXCOORD0 > D3DFVF_TEX1, (and 3 more up to D3DFVF_TEX4)
|
||||
D3DXVECTOR4 Reg13Up[3];
|
||||
// (*) X_D3DVSDE_POSITION and X_D3DVSDE_VERTEX both set Position, but Rhw seems optional,
|
||||
// hence, selection for D3DFVF_XYZ or D3DFVF_XYZRHW is rather fuzzy. We DO know that once
|
||||
// D3DFVF_NORMAL is given, D3DFVF_XYZRHW is forbidden (see D3DDevice_SetVertexData4f)
|
||||
|
||||
struct _D3DIVB &operator=(const struct _D3DIVB &Val);
|
||||
std::array<D3DXVECTOR4, 16> Slots;
|
||||
|
||||
} D3DIVB;
|
||||
|
||||
|
|
|
@ -714,7 +714,12 @@ private:
|
|||
case xbox::X_D3DVSDE_TEXCOORD1 /*=10*/: UsageIndex = 1; return D3DDECLUSAGE_TEXCOORD;
|
||||
case xbox::X_D3DVSDE_TEXCOORD2 /*=11*/: UsageIndex = 2; return D3DDECLUSAGE_TEXCOORD;
|
||||
case xbox::X_D3DVSDE_TEXCOORD3 /*=12*/: UsageIndex = 3; return D3DDECLUSAGE_TEXCOORD;
|
||||
default /*13-15*/ :
|
||||
// Unused registers. Assign them a semantic anyway so we don't have to worry about
|
||||
// binding a vertex declaration with them in it
|
||||
case 13: UsageIndex = 4; return D3DDECLUSAGE_TEXCOORD;
|
||||
case 14: UsageIndex = 5; return D3DDECLUSAGE_TEXCOORD;
|
||||
case 15: UsageIndex = 6; return D3DDECLUSAGE_TEXCOORD;
|
||||
default:
|
||||
return D3DDECLUSAGE_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue