From 36074d9fd53b6416f9e0fc14070158b710cf48aa Mon Sep 17 00:00:00 2001 From: Ian Curtis Date: Mon, 30 May 2016 13:25:00 +0000 Subject: [PATCH] Y texture offsets are just 5 bits. Texture coordinate wrap around happens in the same texture sheet, not into the next one. Fixes various texturing bugs in sega rally. --- Src/Graphics/New3D/Model.cpp | 8 ++++---- Src/Graphics/New3D/Model.h | 5 +++-- Src/Graphics/New3D/New3D.cpp | 28 +++++++++++++++++++++++++--- Src/Graphics/New3D/New3D.h | 2 ++ 4 files changed, 34 insertions(+), 9 deletions(-) diff --git a/Src/Graphics/New3D/Model.cpp b/Src/Graphics/New3D/Model.cpp index ee9eae3..c2ab778 100644 --- a/Src/Graphics/New3D/Model.cpp +++ b/Src/Graphics/New3D/Model.cpp @@ -6,7 +6,7 @@ NodeAttributes::NodeAttributes() { currentTexOffsetX = 0; currentTexOffsetY = 0; - currentTexOffset = 0; + page = 0; } bool NodeAttributes::Push() @@ -20,7 +20,7 @@ bool NodeAttributes::Push() return false; } - na.texOffset = currentTexOffset; + na.page = page; na.texOffsetX = currentTexOffsetX; na.texOffsetY = currentTexOffsetY; @@ -35,7 +35,7 @@ bool NodeAttributes::Pop() return false; // check for underflow } - currentTexOffset = m_vecAttribs.back().texOffset; + page = m_vecAttribs.back().page; currentTexOffsetX = m_vecAttribs.back().texOffsetX; currentTexOffsetY = m_vecAttribs.back().texOffsetY; @@ -51,7 +51,7 @@ bool NodeAttributes::StackLimit() void NodeAttributes::Reset() { - currentTexOffset = 0; + page = 0; currentTexOffsetX = 0; currentTexOffsetY = 0; m_vecAttribs.clear(); diff --git a/Src/Graphics/New3D/Model.h b/Src/Graphics/New3D/Model.h index 71c360d..2f442f0 100644 --- a/Src/Graphics/New3D/Model.h +++ b/Src/Graphics/New3D/Model.h @@ -80,6 +80,7 @@ struct Model // texture offsets for model int textureOffsetX = 0; int textureOffsetY = 0; + int page = 0; //matrices float modelMat[16]; @@ -112,7 +113,7 @@ public: int currentTexOffsetX; int currentTexOffsetY; - int currentTexOffset; // raw value + int page; private: @@ -120,7 +121,7 @@ private: { int texOffsetX; int texOffsetY; - int texOffset; + int page; }; std::vector m_vecAttribs; }; diff --git a/Src/Graphics/New3D/New3D.cpp b/Src/Graphics/New3D/New3D.cpp index e8bc099..44553f3 100644 --- a/Src/Graphics/New3D/New3D.cpp +++ b/Src/Graphics/New3D/New3D.cpp @@ -128,7 +128,11 @@ void CNew3D::RenderScene(int priority, bool alpha) } if (mesh.textured) { - auto tex1 = m_texSheet.BindTexture(m_textureRAM, mesh.format, mesh.mirrorU, mesh.mirrorV, mesh.x + m.textureOffsetX, mesh.y + m.textureOffsetY, mesh.width, mesh.height); + + int x, y; + CalcTexOffset(m.textureOffsetX, m.textureOffsetY, m.page, mesh.x, mesh.y, x, y); + + auto tex1 = m_texSheet.BindTexture(m_textureRAM, mesh.format, mesh.mirrorU, mesh.mirrorV, x, y, mesh.width, mesh.height); if (tex1) { tex1->BindTexture(); tex1->SetWrapMode(mesh.mirrorU, mesh.mirrorV); @@ -315,6 +319,7 @@ bool CNew3D::DrawModel(UINT32 modelAddr) // update texture offsets m->textureOffsetX = m_nodeAttribs.currentTexOffsetX; m->textureOffsetY = m_nodeAttribs.currentTexOffsetY; + m->page = m_nodeAttribs.page; if (!cached) { CacheModel(m, modelAddress); @@ -368,13 +373,13 @@ void CNew3D::DescendCullingNode(UINT32 addr) if (!m_offset) // Step 1.5+ { tx = 32 * ((node[0x02] >> 7) & 0x3F); - ty = 32 * (node[0x02] & 0x3F) + ((node[0x02] & 0x4000) ? 1024 : 0); // TODO: 5 or 6 bits for Y coord? + ty = 32 * (node[0x02] & 0x1F); // apply texture offsets, else retain current ones if ((node[0x02] & 0x8000)) { m_nodeAttribs.currentTexOffsetX = tx; m_nodeAttribs.currentTexOffsetY = ty; - m_nodeAttribs.currentTexOffset = node[0x02] & 0x7FFF; + m_nodeAttribs.page = (node[0x02] & 0x4000) >> 14; } } @@ -1153,5 +1158,22 @@ bool CNew3D::IsVROMModel(UINT32 modelAddr) return modelAddr >= 0x100000; } +void CNew3D::CalcTexOffset(int offX, int offY, int page, int x, int y, int& newX, int& newY) +{ + newX = (x + offX) & 2047; // wrap around 2048, shouldn't be required + + int oldPage = y / 1024; + + y -= (oldPage * 1024); // remove page from tex y + + // calc newY with wrap around, wraps around in the same sheet, not into another memory sheet + + newY = (y + offY) & 1023; + + // add page to Y + + newY += ((oldPage + page) & 1) * 1024; // max page 0-1 +} + } // New3D diff --git a/Src/Graphics/New3D/New3D.h b/Src/Graphics/New3D/New3D.h index f1dae85..110e88e 100644 --- a/Src/Graphics/New3D/New3D.h +++ b/Src/Graphics/New3D/New3D.h @@ -176,6 +176,8 @@ private: bool IsDynamicModel(UINT32 *data); // check if the model has a colour palette bool IsVROMModel(UINT32 modelAddr); + void CalcTexOffset(int offX, int offY, int page, int x, int y, int& newX, int& newY); + /* * Data