mirror of
https://github.com/RetroDECK/Supermodel.git
synced 2024-11-26 15:45:41 +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
|
@ -1026,9 +1026,7 @@ void CNew3D::SetMeshValues(SortingMesh *currentMesh, PolyHeader &ph)
|
||||||
|
|
||||||
void CNew3D::CacheModel(Model *m, const UINT32 *data)
|
void CNew3D::CacheModel(Model *m, const UINT32 *data)
|
||||||
{
|
{
|
||||||
Vertex prev[4];
|
|
||||||
UINT16 texCoords[4][2];
|
UINT16 texCoords[4][2];
|
||||||
UINT16 prevTexCoords[4][2];
|
|
||||||
PolyHeader ph;
|
PolyHeader ph;
|
||||||
UINT64 lastHash = -1;
|
UINT64 lastHash = -1;
|
||||||
SortingMesh* currentMesh = nullptr;
|
SortingMesh* currentMesh = nullptr;
|
||||||
|
@ -1086,10 +1084,10 @@ void CNew3D::CacheModel(Model *m, const UINT32 *data)
|
||||||
{
|
{
|
||||||
if (ph.SharedVertex(i))
|
if (ph.SharedVertex(i))
|
||||||
{
|
{
|
||||||
p.v[j] = prev[i];
|
p.v[j] = m_prev[i];
|
||||||
|
|
||||||
texCoords[j][0] = prevTexCoords[i][0];
|
texCoords[j][0] = m_prevTexCoords[i][0];
|
||||||
texCoords[j][1] = prevTexCoords[i][1];
|
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
|
//check if we need to recalc tex coords - will only happen if tex tiles are different + sharing vertices
|
||||||
if (hash != lastHash) {
|
if (hash != lastHash) {
|
||||||
|
@ -1178,7 +1176,8 @@ void CNew3D::CacheModel(Model *m, const UINT32 *data)
|
||||||
p.v[j].fixedShade = shade;
|
p.v[j].fixedShade = shade;
|
||||||
}
|
}
|
||||||
|
|
||||||
float texU, texV = 0;
|
float texU = 0;
|
||||||
|
float texV = 0;
|
||||||
|
|
||||||
// tex coords
|
// tex coords
|
||||||
if (currentMesh->textured) {
|
if (currentMesh->textured) {
|
||||||
|
@ -1233,9 +1232,9 @@ void CNew3D::CacheModel(Model *m, const UINT32 *data)
|
||||||
|
|
||||||
// Copy current vertices into previous vertex array
|
// Copy current vertices into previous vertex array
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
prev[i] = p.v[i];
|
m_prev[i] = p.v[i];
|
||||||
prevTexCoords[i][0] = texCoords[i][0];
|
m_prevTexCoords[i][0] = texCoords[i][0];
|
||||||
prevTexCoords[i][1] = texCoords[i][1];
|
m_prevTexCoords[i][1] = texCoords[i][1];
|
||||||
}
|
}
|
||||||
|
|
||||||
} while (ph.NextPoly());
|
} while (ph.NextPoly());
|
||||||
|
|
|
@ -250,6 +250,9 @@ private:
|
||||||
NodeAttributes m_nodeAttribs;
|
NodeAttributes m_nodeAttribs;
|
||||||
Mat4 m_modelMat; // current modelview matrix
|
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<Node> m_nodes; // this represents the entire render frame
|
||||||
std::vector<Poly> m_polyBufferRam; // dynamic polys
|
std::vector<Poly> m_polyBufferRam; // dynamic polys
|
||||||
std::vector<Poly> m_polyBufferRom; // rom polys
|
std::vector<Poly> m_polyBufferRom; // rom polys
|
||||||
|
|
Loading…
Reference in a new issue