Legacy engine: Culling node texture Y offset is only 5 bits (fixes Sega Rally 2 initials decal)

This commit is contained in:
Bart Trzynadlowski 2016-05-29 20:49:28 +00:00
parent 2ee0d9018e
commit d1f49675b1
3 changed files with 30 additions and 13 deletions

View file

@ -692,7 +692,7 @@ void CLegacy3D::DescendCullingNode(UINT32 addr)
if (!offset) // Step 1.5+
{
int tx = 32*((node[0x02]>>7)&0x3F);
int ty = 32*(node[0x02]&0x3F) + ((node[0x02]&0x4000)?1024:0); // TODO: 5 or 6 bits for Y coord?
int ty = 32*(node[0x02]&0x1F) + ((node[0x02]&0x4000)?1024:0); // 5 bits for Y coordinate, else Sega Rally 2 initials decal breaks
if ((node[0x02]&0x8000)) // apply texture offsets, else retain current ones
{
texOffsetXY[0] = (GLfloat) tx;
@ -837,6 +837,10 @@ void CLegacy3D::RenderViewport(UINT32 addr, int pri)
if (nextAddr != 0x01000000)
RenderViewport(nextAddr, pri);
// Skip disabled viewports
//if ((vpnode[0] & 0x20) != 0)
// return;
// If the priority doesn't match, do not process
int curPri = (vpnode[0x00] >> 3) & 3; // viewport priority
if (curPri != pri)

View file

@ -373,6 +373,8 @@ private:
void DrawDisplayList(ModelCache *Cache, POLY_STATE state);
bool AppendDisplayList(ModelCache *Cache, bool isViewport, const struct VBORef *Model);
void ClearDisplayList(ModelCache *Cache);
int GetTextureBaseX(const Poly *P) const;
int GetTextureBaseY(const Poly *P) const;
bool InsertPolygon(ModelCache *cache, const Poly *p);
void InsertVertex(ModelCache *cache, const Vertex *v, const Poly *p, float normFlip);
struct VBORef *BeginModel(ModelCache *cache);

View file

@ -451,6 +451,19 @@ void CLegacy3D::ClearDisplayList(ModelCache *Cache)
Vertices are copied in batches sorted by state when the model is complete.
******************************************************************************/
int CLegacy3D::GetTextureBaseX(const Poly *P) const
{
int x = ((P->header[4] & 0x1F) << 1) | ((P->header[5] >> 7) & 1);
return (32 * x + int(texOffsetXY[0])) & 2047;
}
int CLegacy3D::GetTextureBaseY(const Poly *P) const
{
int texPage = (P->header[4] & 0x40) << 4; // 1024 or 0
int y = P->header[5] & 0x1F;
return (32 * y + texPage + int(texOffsetXY[1])) & 2047;
}
// Inserts a vertex into the local vertex buffer, incrementing both the local and VBO pointers. The normal is scaled by normFlip.
void CLegacy3D::InsertVertex(ModelCache *Cache, const Vertex *V, const Poly *P, float normFlip)
{
@ -459,11 +472,10 @@ void CLegacy3D::InsertVertex(ModelCache *Cache, const Vertex *V, const Poly *P,
unsigned texFormat = (P->header[6]>>7)&7;
GLfloat texWidth = (GLfloat) (32<<((P->header[3]>>3)&7));
GLfloat texHeight = (GLfloat) (32<<((P->header[3]>>0)&7));
int texPage = (P->header[4]&0x40) ? 1024 : 0; // treat texture page as Y coordinate
TexSheet *texSheet = fmtToTexSheet[texFormat]; // get X&Y offset of texture sheet within texture map
GLfloat texBaseX = (GLfloat) (texSheet->xOffset + (((32*(((P->header[4]&0x1F)<<1)|((P->header[5]>>7)&1))) + (int)texOffsetXY[0])&2047));
GLfloat texBaseY = (GLfloat) (texSheet->yOffset + (((32*(P->header[5]&0x1F)+texPage) + (int)texOffsetXY[1])&2047));
TexSheet *texSheet = fmtToTexSheet[texFormat]; // get X, Y offset of texture sheet within texture map
GLfloat texBaseX = texSheet->xOffset + GetTextureBaseX(P);
GLfloat texBaseY = texSheet->yOffset + GetTextureBaseY(P);
/*
* Lighting and Color Modulation:
*
@ -1010,13 +1022,12 @@ struct VBORef *CLegacy3D::CacheModel(ModelCache *Cache, int lutIdx, UINT16 texOf
P.numVerts = (P.header[0]&0x40)?4:3;
// Texture data
int texEnable = P.header[6]&0x400;
int texFormat = (P.header[6]>>7)&7;
int texWidth = (32<<((P.header[3]>>3)&7));
int texHeight = (32<<((P.header[3]>>0)&7));
int texPage = (P.header[4]&0x40) ? 1024 : 0; // treat texture page as Y coordinate
int texBaseX = ((32*(((P.header[4]&0x1F)<<1)|((P.header[5]>>7)&1))) + (int)texOffsetXY[0]) & 2047;
int texBaseY = ((32*(P.header[5]&0x1F)+texPage) + (int)texOffsetXY[1]) & 2047;
int texEnable = P.header[6]&0x400;
int texFormat = (P.header[6]>>7)&7;
int texWidth = (32<<((P.header[3]>>3)&7));
int texHeight = (32<<((P.header[3]>>0)&7));
int texBaseX = GetTextureBaseX(&P);
int texBaseY = GetTextureBaseY(&P);
GLfloat uvScale = (P.header[1]&0x40)?1.0f:(1.0f/8.0f);
// Determine whether this is an alpha polygon (TODO: when testing textures, test if texturing enabled? Might not matter)