Unqualified pow picks up the double overload on platforms whose <cmath> only
drops the C version into the global namespace, which computes the whole thing at
double precision and rounds once at the end - a different result decided by the
standard library rather than by us. std::pow always gets the float overload.
That's only half the problem, so there's a TODO next to it: powf isn't correctly
rounded, so it differs between glibc, musl, bionic, Apple's libm and the UCRT,
and all three callers feed the result into a LightCeil - which turns a one-ULP
difference into a full 1/512 step in the light factor instead of letting it wash
out. The PSP almost certainly uses a fixed approximation of its own; settling
that against the pspautotests rendering tests is a job for once the platform
differences are gone and there's a stable base to compare against.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vd8ntC2brCUtCrDJMqLbs8
Rasterizer.cpp: the secondary color fallback does `prim_color[i] = ` where the
SSE and NEON branches add, so the base/texture color is thrown away and the
triangle renders as pure specular. Introduced by 250abe0d56 (Loongarch64 build
fixes) changing one character; the structurally identical block in DrawRectangle
still has the `+=`. Live on ARM32, LoongArch64, RISC-V64 and anything else that
isn't SSE2 or ARM64.
Lighting.cpp: IsLargerThanHalf's scalar path assigns instead of accumulating in
its loop, so it returns only `v[2] > 1` and ignores the other components, and the
NEON path computes a max where SSE computes a sum. All three disagreed. The
question being asked is "is this color factor non-zero" - the test this replaced
in fcc3b7684e was `!(colorFactor == ones)` - and since LightColorFactor produces
2*c+1, every component is >= 1 and the sum of four is >= 4, which is why the SSE
sum > 4 is the correct one. Made the other two match it.
Getting this wrong doesn't shift a shade, it enables or disables a whole light:
x86-32 and ARM64 were switching lights off that x86-64 left on.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vd8ntC2brCUtCrDJMqLbs8
In many cases, games use lighting just for diffuse or something, this
helps skip what's not needed too. Good improvement in a scene from a
Naruto game.
This seems to be a bit more accurate. Color blending seems correct now,
but the factors and especially pow results are off.
Also, normalize normal to 0, 0, 1, which seems to match results better.
This is correct per hardware tests, see #8403. Note that the PS3 emulator
running PSP HD remasters does not correctly handle this, and applies
specular for negative diffuse factor.