gonetz / GLideN64

A new generation, open-source graphics plugin for N64 emulators.
Other
754 stars 174 forks source link

Mario Kart 64 - 0.95 F3DEX - Wrong gsSPCullDisplayList binary #2774

Open DeadHamster35 opened 1 year ago

DeadHamster35 commented 1 year ago

Mario Kart 64's USA release uses an early version of F3DEX labelled 0.95. This is not identical to the more common 1.21 F3DEX on a binary level - one of the quirks of this version is the inclusion of the full gsSPQuadrangle command, which starting with 1.21 F3DEX is converted at compilation to a gsSPTriangle2. This is emulated correctly which is apparently handled via a special microcode -

https://github.com/gonetz/GLideN64/blob/cb6e6cb73363a5787c41b0dc1454631e6073b407/src/GBI.cpp#L57

Recently (today) it was discovered that another command has a difference in the binary layout; gsSPCullDisplayList appears to use the same binary from F3D and not the later 1.21 F3DEX versions.

To test a region of 8 vertices, the correct 0.95 F3DEX binary command and parameters should read - BE 00 00 00 00 00 01 40

#define gsSPCullDisplayList(vstart,vend)                
{                                   
    _SHIFTL(G_CULLDL, 24, 8) | ((0x0f & (vstart))*40),      
    ((0x0f & ((vend)+1))*40)                    
}

whereas GLideN64 currently (incorrectly) expects the 1.21 binary format - BE 00 00 00 00 00 00 0E

#define gsSPCullDisplayList(vstart,vend)                
{                                   
    _SHIFTL(G_CULLDL, 24, 8) | _SHIFTL((vstart)*2, 0, 16),      
    _SHIFTL((vend)*2, 0, 16)                    
}

Using the newer 1.21 F3DEX binary leads to a crash on original hardware as it checks for an invalid number of verts. This has gone unnoticed as the original game never uses the gsSPCullDisplayList command, however this leads to a discrepancy when attempting to design mods that are compatible with both modern emulators and console.