mirror of
https://github.com/RetroDECK/Supermodel.git
synced 2024-11-22 13:55:38 +00:00
Sega bass fishing is starting some off the meshes with a shared vertex. Without having a previous vertex to share with, the values were just uninitialised and junk. The hardware itself seems to hold the value from the previous mesh, and sega bass fishing relies on this undefined behaviour to function correctly. Storing the cached vertices as member variables instead of locally to the function means it holds the values from the last mesh, and uses those values instead of random garbage.
This commit is contained in:
parent
c1c2dedcfa
commit
e4f5f0bcaf
|
@ -23,12 +23,12 @@ CNew3D::CNew3D(const Util::Config::Node &config, std::string gameName)
|
|||
m_cullingRAMHi = nullptr;
|
||||
m_polyRAM = nullptr;
|
||||
m_vrom = nullptr;
|
||||
m_textureRAM = nullptr;
|
||||
m_sunClamp = true;
|
||||
m_shadeIsSigned = true;
|
||||
}
|
||||
|
||||
CNew3D::~CNew3D()
|
||||
m_textureRAM = nullptr;
|
||||
m_sunClamp = true;
|
||||
m_shadeIsSigned = true;
|
||||
}
|
||||
|
||||
CNew3D::~CNew3D()
|
||||
{
|
||||
m_vbo.Destroy();
|
||||
}
|
||||
|
@ -1026,9 +1026,7 @@ void CNew3D::SetMeshValues(SortingMesh *currentMesh, PolyHeader &ph)
|
|||
|
||||
void CNew3D::CacheModel(Model *m, const UINT32 *data)
|
||||
{
|
||||
Vertex prev[4];
|
||||
UINT16 texCoords[4][2];
|
||||
UINT16 prevTexCoords[4][2];
|
||||
PolyHeader ph;
|
||||
UINT64 lastHash = -1;
|
||||
SortingMesh* currentMesh = nullptr;
|
||||
|
@ -1086,10 +1084,10 @@ void CNew3D::CacheModel(Model *m, const UINT32 *data)
|
|||
{
|
||||
if (ph.SharedVertex(i))
|
||||
{
|
||||
p.v[j] = prev[i];
|
||||
p.v[j] = m_prev[i];
|
||||
|
||||
texCoords[j][0] = prevTexCoords[i][0];
|
||||
texCoords[j][1] = prevTexCoords[i][1];
|
||||
texCoords[j][0] = m_prevTexCoords[i][0];
|
||||
texCoords[j][1] = m_prevTexCoords[i][1];
|
||||
|
||||
//check if we need to recalc tex coords - will only happen if tex tiles are different + sharing vertices
|
||||
if (hash != lastHash) {
|
||||
|
@ -1178,7 +1176,8 @@ void CNew3D::CacheModel(Model *m, const UINT32 *data)
|
|||
p.v[j].fixedShade = shade;
|
||||
}
|
||||
|
||||
float texU, texV = 0;
|
||||
float texU = 0;
|
||||
float texV = 0;
|
||||
|
||||
// tex coords
|
||||
if (currentMesh->textured) {
|
||||
|
@ -1233,9 +1232,9 @@ void CNew3D::CacheModel(Model *m, const UINT32 *data)
|
|||
|
||||
// Copy current vertices into previous vertex array
|
||||
for (i = 0; i < 4; i++) {
|
||||
prev[i] = p.v[i];
|
||||
prevTexCoords[i][0] = texCoords[i][0];
|
||||
prevTexCoords[i][1] = texCoords[i][1];
|
||||
m_prev[i] = p.v[i];
|
||||
m_prevTexCoords[i][0] = texCoords[i][0];
|
||||
m_prevTexCoords[i][1] = texCoords[i][1];
|
||||
}
|
||||
|
||||
} while (ph.NextPoly());
|
||||
|
@ -1659,10 +1658,10 @@ void CNew3D::SetSunClamp(bool enable)
|
|||
{
|
||||
m_sunClamp = enable;
|
||||
}
|
||||
|
||||
void CNew3D::SetSignedShade(bool enable)
|
||||
{
|
||||
m_shadeIsSigned = enable;
|
||||
}
|
||||
|
||||
|
||||
void CNew3D::SetSignedShade(bool enable)
|
||||
{
|
||||
m_shadeIsSigned = enable;
|
||||
}
|
||||
|
||||
} // New3D
|
||||
|
|
|
@ -250,6 +250,9 @@ private:
|
|||
NodeAttributes m_nodeAttribs;
|
||||
Mat4 m_modelMat; // current modelview matrix
|
||||
|
||||
Vertex m_prev[4]; // these are class variables because sega bass fishing starts meshes with shared vertices from the previous one
|
||||
UINT16 m_prevTexCoords[4][2]; // basically relying on undefined behavour
|
||||
|
||||
std::vector<Node> m_nodes; // this represents the entire render frame
|
||||
std::vector<Poly> m_polyBufferRam; // dynamic polys
|
||||
std::vector<Poly> m_polyBufferRom; // rom polys
|
||||
|
|
Loading…
Reference in a new issue