Play-
Play- copied to clipboard
KOF series too low Z precision in XYZ2/3 cause graphical issues
Every King of Fighters game that use 3D backgrounds send XYZ2 (u16,u16,u32) as 0000xxxx 0000yyyy FFFFzzzz. It seems that Play! handle that similarly to pcsx2, and convert that to single precision float which is causing that last most important bits are lost. So result is something like FFFFzz00, that create various issues depending on game. I made simple test and filtered XYZ2 packets that have Z with FFFFzzzz, and changed it to 00FFzzzz, and that worked. Since first bits are unused by game, float precision improved due to lower initial value. Game worked as expected.
Affected games (thx to Immersion95): KOF 2002 (not very obvious but still is affected like Stage D1) KOF 2003 (https://github.com/jpd002/Play-Compatibility/issues/795) KOF XI (https://github.com/jpd002/Play-Compatibility/issues/796) KOF '94 Re-Bout KOF '98 Ultimate Match (https://github.com/jpd002/Play-Compatibility/issues/794) KOF 2002 Unlimited Match KOF 2002 Unlimited Match (Tougeki) KOF Neowave NeoGeo Battle Coliseum
Current master:
Hack applied:
To test that following code were used in GIF.cpp line 135:
if ((packet.nV[2] & 0xFFFF0000) == 0xFFFF0000)
temp |= (uint64)(packet.nV[2] & 0x00FFFFFF) << 32;
else
temp |= (uint64)(packet.nV[2] & 0xFFFFFFFF) << 32;
Keep in mind this isn't solution, just hack to confirm theory, and make tests. Thanks to kojin for figuring out what is real KOF games issue.
Yup, that thing is kinda annoying. I tried solving this problem a while ago, but I didn't find a definitive solution. Down the line, the problem is that GPUs can only interpolate floats (AFAIK).
https://github.com/jpd002/Play-/blob/master/Source/gs/GSH_OpenGL/GSH_OpenGL_Shader.cpp#L114
If we're thinking outside of the box, maybe there would be a way to find a proper scaling factor (or maybe a linear formulae, ie.: depth = ax - b
) for the line above using known values of Z that we got inside a frame. Maybe I'm not thinking this through, so, I'm open to other ideas :)
ARB_gpu_shader_int64 could be of any use?
From what I know, OpenGL/Vulkan won't interpolate integers.
There's also ARB_gpu_shader_fp64
, but the extension doc (https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_gpu_shader_fp64.txt) specifies that interpolation is not supported for doubles:
Interpolation not supported in this extension for double-precision
floating-point components. As with integer types in OpenGL 3.0,
double-precision floating-point fragment shader inputs must be qualified
as "flat".
I was considering something like Java's https://docs.oracle.com/javase/7/docs/api/java/lang/Float.html#floatToRawIntBits(float) . https://www.khronos.org/registry/OpenGL/extensions/NV/NV_gpu_shader5.txt seems like it could be used to implement it.