SDL sends scePadSetVibration rumble as report 0x31 with audio haptics
turned off. Once the rumble stopped, the stream's haptics came back at a
different strength than before it. The stream thread now sends its
configuration report 0x31 again 100 ms after slot 0's rumble stops, which
brought the haptics back to their level before the rumble.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The worker sent a backlog of buffered blocks back to back. It now sends at
most one report 0x32 per 10.67 ms, the length of one 32-frame block at
3 kHz, without a catch-up burst after a pause.
A failed report write cleared the stream-open flag, which sent the vibration
ports to motor rumble. The flag now stays set until the controller
disconnects, so the ports stay silent while the stream is stopped.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The 10.672 ms timer took a block only when it fired, so audio arriving in
blocks smaller than 32 haptic frames (16 from a 256-frame legacy port)
regularly found fewer than 32 frames and the report was skipped; catching
up after falling behind sent two reports back to back and left a ~21 ms
hole. The controller, asked to queue only 16 frames, then ran dry, and
the haptics dropped out about once per second on hardware.
The stream thread now waits on a condition variable until two blocks are
buffered and sends one, so reports follow the audio clock, and report
0x32 asks the controller to queue 64 frames (21 ms) to absorb Bluetooth
jitter and the difference between the title's rate and the controller's
crystal. Closing the stream wakes the waiting thread before the join.
Co-authored-by: seradavid <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
While an IME dialog or session captures the keyboard, Ctrl+V (Command+V
on macOS, Ctrl+Shift+V too) and Shift+Insert read the clipboard through a
provider the window installs and hand it to the IME as one paste. Key
repeat, Alt combinations and any press while nothing captures the
keyboard do nothing, and the clipboard is not read in those cases. With
no provider installed nothing is pasted.
When ANYPS5_PAD_IDENTIFY is connect or always, a controller that is
bound to a player slot gets a short pulse pattern once the title has
been quiet for 500 ms: one pulse for player 1, two for player 2 and so
on up to four. The scheduler runs in the existing output pass, so a
title's own rumble, its refreshes and its stop always take precedence,
and the pulse is scaled by ANYPS5_RUMBLE. A controller without rumble
support logs one line and gets no pulse. The keyboard and mouse never
get a pulse, since they are not bound to a slot. The mode is read when
the pad input starts, so an invalid value stops the title there. With
the default off, the output pass sends exactly what it sent before.
libSceVideoOut reads and changes the shared host volume state, and linking libSceAudioOut for it puts a second shared library with its own static SDL2 into libSceVideoOut. Both libraries already link libScePad, so the headers that describe that state move there first; the include paths and guards follow.
Only focus lost and gained events of the display window count. Minimizing, restoring, closing and the events of other windows change nothing, and the shared volume only acts on them when the focus option is on.
ApplyHostVolumeRequests runs the requested commands in the order up, down, mute and reports whether there was one, leaving the final state for the caller to print.
With ANYPS5_PAD_PORT0_STATE=controller, port 0 follows the controller bound to
slot 0: the presence rule commits a change after the hold, and the commit
sets libScePad's port 0 state and user 0's login state. Keyboard and mouse
do not count as a pad there, so while port 0 is withdrawn their input is not
composed into it and titles see the withdrawn port.
Opening or closing a controller no longer sets port 0 directly; slots 1 to 3
keep their immediate updates. The default mode never commits a change, so
port 0 stays connected and user 0 logged in as before.
The rule behind the opt-in port 0 mode: ANYPS5_PAD_PORT0_STATE is default
(unset: port 0 stays connected as before) or controller (port 0 follows a
controller being bound to slot 0). A change of state is committed only after
the controller has stayed absent or present for 500 ms, so a cable that drops
and returns does not flap the title. An invalid value throws, naming the
variable, when the mode is read. The clock is an argument, so the rule has
no host dependency.
APS5_PAD_INPUT_FILE input was merged only into guest pad reads. While a
modal dialog or the IME held the pad, the title saw the intercepted
state and the dialog saw only host SDL input, and without a controller
video out did not publish slot 0 at all. A message dialog opened by the
title (Void Terrarium++ "System data not found" on a fresh profile)
could then never be answered in a scripted run.
Merge the injected input into the host state handed to the capturing
dialog, publish slot 0 every frame while the pad is captured, and once
more when the capture ends so the title stops reading the intercepted
state.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
PadInput hands its provider to the display's poll on every update
instead of building and comparing a snapshot itself, so with
ANYPS5_PAD_STATUS unset or 0 and no request an update no longer copies
controller names or reads SDL_JoystickCurrentPowerLevel. A press of the
ShowPadStatus key polls at once, so the panel lists the controllers
from its first frame.
PadInput remembers each slot's SDL controller type and name when it
opens the controller, and on every update reads the slot's connection
and SDL_JoystickCurrentPowerLevel through a PadStatusProvider. Only a
changed snapshot is handed to the pad status display, so an idle loop
takes no lock; hot-plug events reach it on the next update. A press of
the ShowPadStatus key in the game window asks the display to show the
panel. PadInput is no longer copyable, as its provider refers to it.
PadKindFromSdl and PadPowerFromSdl turn SDL's game controller type and
joystick power level (SDL_JoystickCurrentPowerLevel: unknown, empty,
low, medium, full, wired) into the pad status types. SDL_JOYSTICK_POWER_MAX
is the enumeration's bound, not a level, and reads as unknown, like any
value outside the enumeration. They are plain functions of the enums,
so tests need neither an SDL subsystem nor a device.
Emscripten targets wasm64 without x86 assembly, Linux-only headers or the
x87 long double. These changes add __EMSCRIPTEN__ paths beside the host
ones; native builds compile the same code as before.
- libc: long doubles in guest varargs and scanf go through
GuestLongDouble, a plain copy where long double is the x87 format;
APS5_EXPORT emits no assembler alias; the guest arena is one aligned
allocation that zeroes pages when they are committed again; getifaddrs
keeps its link-level entries on Linux; /proc lookups and the host
stderr duplicate are left out.
- libkernel: file-backed mmap, EVFILT_VNODE watches, getcontext and
setcontext throw; getdents replaces the raw getdents64 syscall;
getdtablesize takes the resource limit alone.
- VideoOut leaves SDL, the display window and the HDR probe out,
Sysmodule asks libkernel for unwind information and Net includes
sys/time.h.
PC5 (PPSA11018) imports the NID and the library did not export it, so the converted executable stopped at load with error 127. The call validates the handle and index like the other cursor calls and returns 0: no cursor image is drawn, so the magnification has no observable effect. The unmeasured behaviour is recorded under Silent stubs.
When the first button event arrives while a modal dialog captures input, MouseInput
publishes a button reset instead of it and drops every press and release until
the dialog is gone, so a button the title saw pressed before the dialog opened
does not stay pressed when its release is dropped.
When the first key event arrives while a modal dialog captures input, KeyboardInput
publishes a key reset instead of it and then drops every key press and release
until the dialog is gone, so a key the title saw pressed before the dialog opened
does not stay pressed when its release is dropped.
DialogInput turns window events into modal dialog inputs: Left, Up, Right, Down,
Tab and Shift+Tab and the mouse wheel move the focus, Enter, the keypad Enter and
Space and a left click confirm, Escape and a right click cancel. Repeats of the
confirming and cancelling keys, other windows' events and other keys are
ignored. The presentation thread feeds it with the events it already polls for
the IME text input.
PS5_Vulkan measured on a base PS5 set to 1080p output that
sceVideoOutIsOutputSupported(15) answers 0, neither 1 nor an error, and
that sceVideoOutConfigureOutput(15) then returns 0x80290019, in a title
declaring high-frame-rate output. A host display below 120 Hz answered
0x80290016 to both instead. Titles that branch on the answer being 1
are unchanged; the undeclared-title answer stays 0x80290016.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The invalid-handle assertions ran before the guarded sceVideoOutOpen, so a machine without a display failed instead of skipping. They now follow the open. ANYPS5_REQUIRE_DISPLAY still turns a missing display into a failure. The capability and ModeSetAny declarations move from the test into VideoOut.hpp.