mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-01 03:57:17 +01:00
HOME button quit screen, with the firmware's art when available
As on a PSP: pressing HOME in a game shows "Do you want to quit the game?" over it. The game keeps running but gets no input while it's up (sceCtrl samples are blanked). Left/right picks Yes or No, the confirm button (our Confirmation button setting, or what compat forces) chooses, the other face button or HOME closes it, and Yes/No can be tapped. The volume keys change the game volume a step at a time, shown on the volume bar. Yes runs the game's registered exit callback first, like the PSP does, showing "Please wait..." meanwhile. Then, if the XMB launched the game, the XMB is booted again; otherwise it's back to the game browser, like Exit to menu. If the callback hasn't ended the game in 10 s, it's quit anyway. Not in the XMB itself, the PS1 emulator (its own HOME menu) or GE dumps. It lives in UI/ImposeHome.cpp; EmuScreen only feeds it input and frames and draws it over the PSP display. With a firmware dump installed, it's drawn with the firmware's own art from flash0:/kd/resource/impose.rsc, which is what impose.prx draws it from: prerendered text for each system language (the question, Yes/No normal and highlighted, Enter/Back, Please wait...), the button icons, the lines, the volume bar, the battery and the clock glyphs. The format is documented in ImposeHome.cpp. Without one, the same screen is drawn with our font and simple shapes at the same positions. Where impose.rsc doesn't say where things go, the layout follows impose_02g.prx (6.61), decrypted and disassembled: - The screen is filled with 0x9CE7 (#393939); the images are opaque. - Lines at (80, 96) and (80, 175); impose.prx grows them from the middle when it opens, which isn't done here. - Volume bar: the speaker at (28, 223), 30 steps from x 62, 12 apart. It shows our game volume in the PSP's 30 steps. - Button guide: the cross icon always left, the circle right, "Enter" and "Back" next to whichever confirms and cancels. - Status bar: the battery at (450, 5) (60% and up full, 30% two bars, 12% one, then empty), the clock ending next to it at y 5: "M/D H:MM", or "D/M" for the DD/MM/YYYY format, no leading zero on the month, day or hour, AM/PM for the 12-hour clock. The clock is the emulated PSP's local time (__RtcGetCurrentLocalTime, new), in the system's date and time formats. The battery is this device's, since the emulated PSP's is always full; a device without one shows it full. For that, Windows now reports -1 for SYSPROP_BATTERY_PERCENTAGE without a battery (was 100), as SDL already did; SDL polls the battery even when the status overlay doesn't show it, and the overlay leaves it out when there's none. Core side: __CtrlSetGameInputBlocked; __KernelCanExitToVSH and __KernelRequestExitToVSH to quit to the XMB from outside a syscall; and __KernelInvokeRegisteredExitCallback(toVSH), so a callback that returns without exiting ends in the XMB rather than powering down. New strings: "Do you want to quit the game?", "Please wait..." (Dialog). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NB244iFpvm14JH2FbwHXeQ
This commit is contained in:
1 parent
888abaa97e
commit
90cea302b9
67 files changed
+1217
-12
No files matched your search
@@ -280,6 +280,10 @@ public:
|
||||
g_exitCallbackPending = false;
|
||||
// The callback may have already powered down by calling sceKernelExitGame - that's fine,
|
||||
// Core_Stop is idempotent. Either way, the host will see CORE_POWERDOWN and tear the game down.
|
||||
// Quitting from the HOME screen goes back to the XMB instead, as on a PSP.
|
||||
if (toVSH && coreState != CORE_POWERDOWN && __KernelRequestExitToVSH()) {
|
||||
return;
|
||||
}
|
||||
Core_Stop();
|
||||
}
|
||||
|
||||
@@ -288,14 +292,22 @@ public:
|
||||
}
|
||||
|
||||
void DoState(PointerWrap &p) override {
|
||||
auto s = p.Section("ActionAfterExitCallback", 1);
|
||||
auto s = p.Section("ActionAfterExitCallback", 1, 2);
|
||||
if (!s)
|
||||
return;
|
||||
if (s >= 2) {
|
||||
Do(p, toVSH);
|
||||
} else {
|
||||
toVSH = false;
|
||||
}
|
||||
if (p.mode == p.MODE_READ) {
|
||||
// The dispatch is still in flight in the loaded state (see __KernelThreadingDoState.)
|
||||
g_exitCallbackPending = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Set when the HOME button's quit screen asked for the exit: then it ends in the XMB.
|
||||
bool toVSH = false;
|
||||
};
|
||||
|
||||
u32 PSPThread::GetMissingErrorCode() {
|
||||
@@ -4006,7 +4018,7 @@ int sceKernelRegisterExitCallback(SceUID cbId) {
|
||||
// be dispatched (none registered, registering thread dead, etc.) - the caller should then power down
|
||||
// immediately. While true is returned, __KernelIsExitCallbackPending() will report true until the
|
||||
// callback returns (via the chained ActionAfterExitCallback).
|
||||
bool __KernelInvokeRegisteredExitCallback() {
|
||||
bool __KernelInvokeRegisteredExitCallback(bool toVSH) {
|
||||
if (g_exitCallbackPending) {
|
||||
WARN_LOG(Log::sceKernel, "__KernelInvokeRegisteredExitCallback: already in progress");
|
||||
return true;
|
||||
@@ -4030,6 +4042,7 @@ bool __KernelInvokeRegisteredExitCallback() {
|
||||
}
|
||||
|
||||
ActionAfterExitCallback *action = (ActionAfterExitCallback *)__KernelCreateAction(actionAfterExitCallback);
|
||||
action->toVSH = toVSH;
|
||||
|
||||
// Exit callbacks on real PSP receive (arg1, arg2, common) where arg1/arg2 are zero for HOME-button exit.
|
||||
const u32 args[] = { 0, 0, cb->nc.commonArgument };
|
||||
|
||||
Reference in new issue
Block a user