interp: Correct some negative invalid zero cases.

In these cases, the input value wires to +0.  Also, transposed the values
in a comment (oops.)
This commit is contained in:
Unknown W. Brackets 2019-03-31 13:06:12 -07:00
parent aa998b815c
commit 5736b1be2a
2 changed files with 9 additions and 4 deletions

View file

@ -774,8 +774,9 @@ namespace MIPSInt
VectorSize sz = GetVecSize(op);
ReadVector(s, sz, vs);
// Swizzle can cause V_Single to properly write both components.
// TODO: Minor, but negate shouldn't apply to invalid here. Maybe always?
ApplySwizzleS(s, V_Quad);
// Negate should not actually apply to invalid swizzle.
RetainInvalidSwizzleST(s, V_Quad);
VectorSize outsize = V_Single;
switch (sz) {
@ -1393,13 +1394,17 @@ namespace MIPSInt
float s[4]{};
ReadVector(s, V_Single, vs);
u32 sprefixRemove = VFPU_NEGATE(1, 0, 0, 0);
u32 sprefixAdd = VFPU_NEGATE(negSin, 0, 0, 0);
// TODO: Minor, but negate shouldn't apply to invalid here. Maybe always?
// We apply negSin later, not here. This handles zero a bit better.
u32 sprefixAdd = VFPU_NEGATE(0, 0, 0, 0);
ApplyPrefixST(s, VFPURewritePrefix(VFPU_CTRL_SPREFIX, sprefixRemove, sprefixAdd), V_Single);
// Cosine ignores all prefixes, so take the original.
cosine = vfpu_cos(V(vs));
sine = vfpu_sin(s[0]);
if (negSin)
sine = -sine;
RetainInvalidSwizzleST(&sine, V_Single);
}
if (sineLane == cosineLane) {

View file

@ -35,7 +35,7 @@ inline int Xpose(int v) {
// Some games depend on exact values, but sinf() and cosf() aren't always precise.
// Stepping down to [0, 2pi) helps, but we also check common exact-result values.
// TODO: cos(2) and sin(1) should be -0.0, but doing that gives wrong results (possibly from floorf.)
// TODO: cos(1) and sin(2) should be -0.0, but doing that gives wrong results (possibly from floorf.)
inline float vfpu_sin(float angle) {
angle -= floorf(angle * 0.25f) * 4.f;