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.

This commit is contained in:
Ian Curtis 2016-05-30 13:25:00 +00:00
parent d1f49675b1
commit 36074d9fd5
4 changed files with 34 additions and 9 deletions

View file

@ -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();

View file

@ -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<NodeAttribs> m_vecAttribs;
};

View file

@ -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

View file

@ -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