Skip to content

fix: OSK and message dialog crash from GU display list misuse#10

Merged
AndrewAltimit merged 3 commits intomainfrom
fix/osk-crash
Feb 16, 2026
Merged

fix: OSK and message dialog crash from GU display list misuse#10
AndrewAltimit merged 3 commits intomainfrom
fix/osk-crash

Conversation

@AndrewAltimit
Copy link
Owner

Summary

  • Move sceUtilityOskUpdate and sceUtilityMsgDialogUpdate calls outside the open GU display list frame, matching the PSPSDK convention that utility dialog updates must not be called within sceGuStart/sceGuFinish blocks
  • Add a cleared background frame (opaque black) before each dialog update so the dialog renders correctly
  • Break on negative status codes (error states) to avoid infinite polling
  • Add post-loop shutdown drain: if the dialog reached QUIT (3) or FINISHED (4) but the polling loop timed out before draining to NONE (0), properly call ShutdownStart and wait for the state machine to complete

Affected files

  • psp/src/osk.rs -- On-Screen Keyboard dialog
  • psp/src/dialog.rs -- Message/confirm/error dialogs

Test plan

  • EBOOT builds with RUST_PSP_BUILD_STD=1 cargo +nightly psp --release
  • OSK opens without crash in PPSSPP (automated test via scripts/test-osk-ppsspp.sh in oasis-os)
  • Message dialog (confirm_dialog in rm command) follows same fix pattern
  • Manual test on real PSP hardware

Generated with Claude Code

AI Agent Bot and others added 3 commits February 16, 2026 03:44
sceUtilityOskUpdate() and sceUtilityMsgDialogUpdate() were called
inside an open GU display list (between sceGuStart/sceGuFinish).
Per PSPSDK convention, dialog update functions manage their own GU
rendering and must be called after the caller's display list is
closed. The incorrect ordering corrupts GE state and crashes on
real PSP hardware when opening the OSK.

Also adds screen clear each frame (matching PSPSDK samples) and
breaks on negative status values (error conditions).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
After the polling loop exits (timeout or error), check if the dialog
is still active and force-shutdown to prevent subsequent utility calls
from failing with UTILITY_INVALID_STATUS. This is particularly
important in PPSSPP headless mode where no user input closes the
dialog, but also protects against edge cases on real hardware.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
After the polling loop exits, if the dialog reached QUIT (3) or
FINISHED (4) but didn't drain to NONE (0), complete the shutdown
sequence. Only attempts shutdown from valid states -- ShutdownStart
requires the dialog to be in QUIT state, not RUNNING.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions
Copy link

Gemini AI Code Review

Issues

(none)

Previous Issues

(none)

Suggestions

  • psp/src/dialog.rs:160 - The cleanup loop (120 iterations) uses sceDisplayWaitVblankStart() which is ~2 seconds of blocking time. While appropriate for a safety drain, consider if a shorter timeout is sufficient given that the main loop already ran for up to 600 iterations.
  • psp/src/osk.rs:227 - Same as above; 120 iterations is a safe but long timeout for a background drain.

Notes

  • The fix correctly addresses the GU display list state machine conflict. Moving sceUtility*Update calls outside the sceGuStart/sceGuFinish block is the standard PSPSDK requirement to prevent the utility library from attempting to open its own display list while one is already active on the same context.
  • The addition of sceGuClear ensures that the dialog background doesn't contain garbage data from previous frames, improving visual consistency.
  • The use of 0xff00_0000 (opaque black) for clear color is correct for the PSP's ABGR/RGBA color formats depending on the display mode, providing a neutral backdrop for system dialogs.
  • Error handling for status < 0 in the loop condition is a good hardening measure against hardware/firmware failures that would previously cause infinite polling.

Reaction


Generated by Gemini AI (gemini-3-flash-preview). Supplementary to human reviews.

@AndrewAltimit
Copy link
Owner Author

Review Response Agent (Iteration 1)

Status: No changes needed

Fixed Issues

  • (none - no legitimate issues found)

Ignored Issues

  • Gemini suggestion about 120-iteration cleanup loop timeout (dialog.rs:149, osk.rs:218): This is a reasonable safety margin for draining the dialog state machine. The loop breaks early on success, so the 120 cap is only hit in pathological cases. Not worth reducing.

Deferred to Human

  • (none)

Notes

  • Gemini review found no issues; only made optional suggestions about timeout length
  • Codex review failed entirely due to OpenAI rate limiting (HTTP 429) and produced no feedback
  • Both dialog.rs and osk.rs correctly implement the PSPSDK convention of calling utility dialog updates outside GU display list frames
  • The shutdown drain loops properly handle the QUIT(3) -> FINISHED(4) -> NONE(0) state transitions

The agent reviewed feedback but determined no code changes were required.

@AndrewAltimit AndrewAltimit merged commit d9d5ab2 into main Feb 16, 2026
7 checks passed
@AndrewAltimit AndrewAltimit deleted the fix/osk-crash branch February 16, 2026 11:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant