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
Windows also gets a filter of its own for them. iOS's picker takes any
file and Android's doesn't filter by extension.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A second Win32 window, added as a Game output like the SDL one. Keys
typed into it still go to the emulator; the mouse doesn't. It's for
testing multiple outputs (standing in for a TV over AirPlay) until real
multi-window support takes it over.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Win32 has no share sheet hookup yet, so sharing a file offers to save a
copy of it. ShareFilesAsZip no longer needs an app cache directory, which
Windows doesn't set; it falls back to the memstick cache folder through
DIRECTORY_APP_CACHE. The save dialog now asks before overwriting.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Windows now uses the same host interface as SDL and iOS: sceUsbMic sends
startRecording/stopRecording/deviceChanged, and drains buffered input on
the CPU thread with pollRecording. A capture thread asks WASAPI for mono
16-bit at the game's rate (it converts from the mix format, so no more
ffmpeg resampling), and copies packets into a lock-free ring buffer.
It reopens the device when the selection changes, and retries once a
second if the device is missing or gets unplugged.
The device list comes from the active capture endpoints. Their friendly
names are the ones Media Foundation reported, so existing MicDevice
settings still match. An empty setting, now selectable as Auto like on
SDL, means the default capture device.
The Media Foundation audio capture code is removed; the camera still
uses it.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Instead of the PSP's web browser, a dialog shows the URL the game wants
and opens it in the host's browser on X, or backs out on O. Either way the
game sees the browser closed normally. Platforms that can't open a URL
(the new SYSPROP_CAN_LAUNCH_URL) only offer to back out. Only plain
printable-ASCII http(s) addresses are handed over, and on Linux without a
shell.
What the firmware does (sceUtility_Driver, 6.61, plus
utility/dialog/htmlviewer): the HtmlViewer has its own state apart from the
other dialogs, so they don't block each other, and its calls return
WRONG_TYPE until one has started. The request size picks the 2.00 to 3.00
layout, and InitStart allocates 3.5MB of user memory (4.5MB with options
bit 0x400 from 2.70 on), failing with 800200d9 without it.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Destroy the ImGui debugger explicitly, not at static destruction time
* Windows: destroy the debugger windows before NativeShutdown()
* Clear the disassembly cache where it goes stale, not in view destructors
(behind a no-op stub for libretro, which doesn't build DisassemblyManager.cpp)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
VulkanGraphicsContext::InitSurface() threw away VulkanContext::InitSurface()'s
VkResult and carried on, so a failed surface init surfaced as
_dbg_assert_(GetAvailablePresentModes().size() > 0) in the VKContext
constructor rather than as a graphics error with the usual backend fallback.
The vkCreate*SurfaceKHR failure path in ReinitSurface() didn't log anything
either, so the assert was the only trace of it.
Now ReinitSurface() logs and sets init_error_ for all three ways it can bail
(surface creation, ChooseQueue, present mode enumeration), InitSurface()
checks the result, and MainThreadFunc() passes the message back out instead of
writing it to a local it then drops - Windows/main.cpp was reporting
"Failed to initialize main thread function." to the user.
Also deletes the Application on that failure path, which was leaked.
Windows/MainWindowMenu.cpp's Load/Save/Clear Symbol Map menu actions
mutated g_symbolMap directly from the WinMain thread; route them through
Core_RunOnCPUThread like the rest of the debugger. Windows/MainWindow.cpp's
WM_USER_GET_MODULE_INFO handler read it directly too; guard with
g_frameMutex. Windows/main.cpp's SortSymbols() calls turn out to already be
safe as-is - both notifications that trigger them (BOOT_DONE,
SYMBOL_MAP_UPDATED) are only ever fired from the CPU/NativeFrame thread -
so just fix the stale comment claiming reliance on the (now removed)
internal lock.
With those covered, every remaining caller is either on the CPU/NativeFrame
thread already or routes through Core_RunOnCPUThread/g_frameMutex, so
SymbolMap's internal recursive_mutex is redundant - remove it and all ~40
lock_guard call sites. Qt's mainwindow.cpp still pokes at g_symbolMap
directly and unguarded (a pre-existing issue, out of scope - Qt isn't a
maintained backend), but removing the lock doesn't change its public API,
so it still builds.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Hqm11k99viLfbJm2MkH4BH