fix lighting behavior with normals that overflow

This commit is contained in:
StapleButter 2017-05-03 23:54:31 +02:00
parent 9e622dcc66
commit 7c1443b973
1 changed files with 6 additions and 6 deletions

View File

@ -976,10 +976,6 @@ void SubmitVertex()
s32 CalculateLighting() s32 CalculateLighting()
{ {
// TODO: this requires matrix mode 2, apparently
// hardware seems to read garbage when matrix mode isn't 2
// also, non-normal normals seem to be treated as zero? or overflow to negative?
if ((TexParam >> 30) == 2) if ((TexParam >> 30) == 2)
{ {
TexCoords[0] = RawTexCoords[0] + (((s64)Normal[0]*TexMatrix[0] + (s64)Normal[1]*TexMatrix[4] + (s64)Normal[2]*TexMatrix[8]) >> 21); TexCoords[0] = RawTexCoords[0] + (((s64)Normal[0]*TexMatrix[0] + (s64)Normal[1]*TexMatrix[4] + (s64)Normal[2]*TexMatrix[8]) >> 21);
@ -1001,6 +997,11 @@ s32 CalculateLighting()
if (!(CurPolygonAttr & (1<<i))) if (!(CurPolygonAttr & (1<<i)))
continue; continue;
// overflow handling (for example, if the normal length is >1)
// according to some hardware tests
// * diffuse level is saturated to 255
// * shininess level mirrors back to 0 and is ANDed with 0xFF, that before being squared
s32 difflevel = (-(LightDirection[i][0]*normaltrans[0] + s32 difflevel = (-(LightDirection[i][0]*normaltrans[0] +
LightDirection[i][1]*normaltrans[1] + LightDirection[i][1]*normaltrans[1] +
LightDirection[i][2]*normaltrans[2])) >> 10; LightDirection[i][2]*normaltrans[2])) >> 10;
@ -1011,9 +1012,9 @@ s32 CalculateLighting()
(LightDirection[i][1]>>1)*normaltrans[1] + (LightDirection[i][1]>>1)*normaltrans[1] +
((LightDirection[i][2]-0x200)>>1)*normaltrans[2]) >> 10); ((LightDirection[i][2]-0x200)>>1)*normaltrans[2]) >> 10);
if (shinelevel < 0) shinelevel = 0; if (shinelevel < 0) shinelevel = 0;
else if (shinelevel > 255) shinelevel = (0x100 - shinelevel) & 0xFF;
shinelevel = ((shinelevel * shinelevel) >> 7) - 0x100; // really (2*shinelevel*shinelevel)-1 shinelevel = ((shinelevel * shinelevel) >> 7) - 0x100; // really (2*shinelevel*shinelevel)-1
if (shinelevel < 0) shinelevel = 0; if (shinelevel < 0) shinelevel = 0;
else if (shinelevel > 255) shinelevel = 255;
if (UseShininessTable) if (UseShininessTable)
{ {
@ -1155,7 +1156,6 @@ void PosTest()
void VecTest(u32* params) void VecTest(u32* params)
{ {
// TODO: apparently requires matrix mode 2
// TODO: maybe it overwrites the normal registers, too // TODO: maybe it overwrites the normal registers, too
s16 normal[3]; s16 normal[3];