mirror of
https://github.com/HarbourMasters/SpaghettiKart
synced 2026-08-23 15:47:03 -04:00
Fix widescreen letterbox/divider left-edge clipping on ARM64 (#709)
* Fix widescreen letterbox/divider left-edge clipping on ARM64 The race-intro letterbox bars (draw_box_fill_wide) and the splitscreen divider lines fed the float OTRGetDimensionFromLeftEdge result into gDPFillWideRectangle, whose _SHIFTL packing casts float->unsigned. Converting a negative float to unsigned is UB: x86 wraps (and the wide-rect handler's sign extension recovers the value, so the bug is invisible there), but ARM64 fcvtzu saturates negatives to zero — so on Apple Silicon the fills started at the 4:3 left edge instead of the true left edge, leaving a strip of sky visible left of the intro bars in widescreen. Use the integer OTRGetRectDimensionFrom*Edge getters, matching the sibling draw_box_wide helpers. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Shorten the fix comment Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+5
-2
@@ -3476,8 +3476,11 @@ Gfx* draw_box_fill_wide(Gfx* displayListHead, s32 ulx, s32 uly, s32 lrx, s32 lry
|
||||
gSPDisplayList(displayListHead++, D_02008030);
|
||||
gDPSetFillColor(displayListHead++, (GPACK_RGBA5551(red, green, (u32) blue, alpha) << 0x10 |
|
||||
GPACK_RGBA5551(red, green, (u32) blue, alpha)));
|
||||
gDPFillWideRectangle(displayListHead++, OTRGetDimensionFromLeftEdge(ulx) - 1, uly, OTRGetDimensionFromRightEdge(lrx) + 1,
|
||||
lry);
|
||||
// Use the integer Rect getters: the float getters' negative left edge goes
|
||||
// through a float->unsigned cast in _SHIFTL (UB) that ARM64 saturates to 0,
|
||||
// pushing the fill's left edge to the 4:3 boundary in widescreen.
|
||||
gDPFillWideRectangle(displayListHead++, OTRGetRectDimensionFromLeftEdge(ulx) - 1, uly,
|
||||
OTRGetRectDimensionFromRightEdge(lrx) + 1, lry);
|
||||
gDPFillRectangle(displayListHead++, ulx, uly, lrx, lry);
|
||||
gSPDisplayList(displayListHead++, D_02008058);
|
||||
return displayListHead;
|
||||
|
||||
@@ -308,11 +308,16 @@ void func_802A4300(void) {
|
||||
gDPFillRectangle(gDisplayListHead++, 157, 0, 159, 239);
|
||||
break;
|
||||
case SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL:
|
||||
gDPFillWideRectangle(gDisplayListHead++, OTRGetDimensionFromLeftEdge(0), 119, OTRGetGameRenderWidth(), 121);
|
||||
// Integer Rect getter: the float getter's negative result through
|
||||
// _SHIFTL is float->unsigned UB, which saturates to 0 on ARM64 and
|
||||
// clips the divider's left extension (see draw_box_fill_wide).
|
||||
gDPFillWideRectangle(gDisplayListHead++, OTRGetRectDimensionFromLeftEdge(0), 119,
|
||||
OTRGetGameRenderWidth(), 121);
|
||||
break;
|
||||
case SCREEN_MODE_3P_4P_SPLITSCREEN:
|
||||
gDPFillRectangle(gDisplayListHead++, 157, 0, 159, 239);
|
||||
gDPFillWideRectangle(gDisplayListHead++, OTRGetDimensionFromLeftEdge(0), 119, OTRGetGameRenderWidth(), 121);
|
||||
gDPFillWideRectangle(gDisplayListHead++, OTRGetRectDimensionFromLeftEdge(0), 119,
|
||||
OTRGetGameRenderWidth(), 121);
|
||||
break;
|
||||
}
|
||||
gDPPipeSync(gDisplayListHead++);
|
||||
|
||||
Reference in New Issue
Block a user