136 Commits
Author SHA1 Message Date
Dean be9b38d939 Merge pull request #9880 from ntamas94/fix/ps4-videoout-device-capability
feat(libSceVideoOut): add the PS4 device capability and ModeSetAny exports
2026-11-06 00:03:50 +13:00
LeandroLP23andClaude Opus 5.5 d7fb2a3ec3 fix(pad): restore the DualSense haptics configuration after a rumble stops
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]>
2026-11-04 21:47:03 +01:00
LeandroLP23andClaude Opus 5.5 986ae87c8a fix(pad): pace Bluetooth DualSense haptics reports and keep a failed stream silent
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]>
2026-11-04 21:47:03 +01:00
e0b0f2b91d fix(pad): send a DualSense haptics report once two blocks are buffered
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]>
2026-11-04 21:46:45 +01:00
115c187398 feat(pad): stream vibration ports to a Bluetooth DualSense as haptics reports
Co-Authored-By: beecrepaldi-afk <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-04 21:46:30 +01:00
ntamas94 0ee4601bf6 fix(libSceVideoOut): merge main and remove obsolete flip-master debt 2026-11-03 21:41:02 +01:00
B-HowellandClaude Opus 5.5 fbd82632e4 feat(libSceVideoOut): declare later callable exports
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-02 20:03:55 -05:00
Dean 8c581d2926 Merge pull request #12596 from MarcZX10/feat/ime-composition-clipboard
feat(ime): show host IME composition in the dialog and paste the clipboard
2026-11-03 02:38:26 +13:00
Dean d5ec8e6575 Merge pull request #11854 from ionut27001/fix/wf-videoout-outputstatus-hdr-flags-zero
fix(videoout): report output status flags 0 with HDR output
2026-11-01 23:35:45 +13:00
MarcZX10 8c15f4921d feat(videoout): paste the clipboard with Ctrl+V or Shift+Insert
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.
2026-11-01 00:29:12 +00:00
MarcZX10 ef631376a0 feat(libSceVideoOut): pulse each bound controller with its player number
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.
2026-11-01 00:04:30 +01:00
Adrià 3197f0ad06 Merge pull request #13705 from MarcZX10/fix/pad-port0-connected-state
feat(libScePad): report port 0 as connected only while its controller is present, opt-in with ANYPS5_PAD_PORT0_STATE
2026-10-31 20:50:35 +01:00
Adrià b7d3fd3c52 Merge pull request #13629 from kyon-eth/feat/videoout-320-legacy-exports
feat(libSceVideoOut): declare older callable exports
2026-10-31 11:03:31 +01:00
MarcZX10 68a4689e62 Merge remote-tracking branch 'upstream/main' into fix/pad-port0-connected-state 2026-10-30 23:46:32 +00:00
Kyon b0d9058d42 feat(libSceVideoOut): declare configuration mode export 2026-10-30 21:05:16 +00:00
Kyon 9aa490f583 feat(libSceVideoOut): declare older callable exports 2026-10-30 20:21:35 +00:00
MarcZX10 bc37a818a0 Merge remote-tracking branch 'upstream/main' into fix/pad-port0-connected-state
# Conflicts:
#	core/libs/prx/libSceVideoOut/include/PadInput.hpp
2026-10-30 18:52:51 +00:00
ntamas94 4c50d02a53 Merge remote-tracking branch 'origin/main' into fix/ps4-videoout-device-capability
# Conflicts:
#	docs/dev/debt/libSceVideoOut.md
2026-10-30 17:11:07 +01:00
MarcZX10 14b0b4b5f2 refactor(libScePad): move the host volume headers from libSceAudioOut
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.
2026-10-30 16:29:55 +01:00
MarcZX10 f58d816ad9 feat(libSceVideoOut): remember whether the host focus was read once
A window created without focus sends no focus lost event, so the first update reads the focus itself.
2026-10-30 16:29:55 +01:00
MarcZX10 0a93f3ae8c feat(libSceVideoOut): follow the display window's focus for the host volume
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.
2026-10-30 16:29:55 +01:00
MarcZX10 4cdc503ffb feat(libSceVideoOut): turn volume and mute requests into host volume commands
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.
2026-10-30 16:29:55 +01:00
MarcZX10 a621ec06bc feat(libSceVideoOut): drive port 0 connection from the controller on slot 0
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.
2026-10-30 13:58:48 +00:00
MarcZX10 77e48aabcb feat(libSceVideoOut): add the port 0 presence rule behind ANYPS5_PAD_PORT0_STATE
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.
2026-10-30 13:56:36 +00:00
JJenkxandClaude Opus 5.5 728d7aa34c fix(pad): let harness input answer system dialogs
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]>
2026-10-30 08:14:30 -04:00
Adrià cc7b82ac6f Merge pull request #12702 from MarcZX10/feat/overlay-pad-status
feat(overlay): show controller status on demand or on connect, disconnect and battery drop
2026-10-30 13:05:28 +01:00
Adrià 8304ccaedb Merge pull request #11341 from SteelCrab/review/emscripten-libraries
build(libs): support Emscripten memory64 compilation
2026-10-30 12:49:20 +01:00
Adrià 63970eded4 Merge pull request #13123 from kyon-eth/feat/video-out-320-exports
feat(libSceVideoOut): declare 182 callable exports
2026-10-30 12:46:18 +01:00
Adrià 65df5a3630 Merge pull request #13008 from relativespace2K/feat/videoout-cursor-set2x-magnify
feat(libSceVideoOut): export sceVideoOutCursorSet2xMagnify
2026-10-30 10:42:00 +01:00
MarcZX10 f656845051 feat(videoout): build the pad snapshot only while the panel is wanted
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.
2026-10-30 05:55:09 +01:00
MarcZX10 a25d9e0b7c feat(videoout): report controller status to the pad status panel
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.
2026-10-30 05:54:56 +01:00
MarcZX10 7b8939999c feat(videoout): map SDL controller types and power levels to pad status
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.
2026-10-30 05:54:47 +01:00
Kyon a19a8b5501 refactor(libSceVideoOut): exclude overlapping export 2026-10-30 02:46:03 +00:00
Kyon d1c779a8a3 refactor(libSceVideoOut): defer mismatched identity 2026-10-30 02:45:33 +00:00
Kyon a5c690355b Merge remote-tracking branch 'origin/main' into feat/video-out-320-exports 2026-10-30 02:43:38 +00:00
pista d64e85164b build(libs): let the system libraries compile with Emscripten
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.
2026-10-30 10:50:57 +09:00
mrph28 6a2c3e7d99 feat(libSceVideoOut): export sceVideoOutCursorSet2xMagnify
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.
2026-10-29 17:54:07 -03:00
Kyon 38715d5610 feat(libSceVideoOut): declare 184 callable exports 2026-10-29 18:15:41 +00:00
MarcZX10 0e32c5a792 feat(libSceVideoOut): release the title's mouse buttons once when a dialog starts taking clicks
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.
2026-10-29 14:06:13 +00:00
MarcZX10 73e6580767 feat(libSceVideoOut): release the title's keys once when a dialog starts taking keys
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.
2026-10-29 14:06:13 +00:00
MarcZX10 71cd480ce2 feat(libSceVideoOut): drive a modal dialog from the keyboard and the mouse
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.
2026-10-29 14:06:13 +00:00
Adrià b9246db364 Merge pull request #11853 from ionut27001/fix/wf-videoout-flipmaster-measured-codes
fix(libSceVideoOut): answer the flip-master calls as measured on a PS5
2026-10-29 12:57:56 +01:00
Dean Galvin c739cfcd5a Merge branch 'main' into fix/ps4-videoout-device-capability
# Conflicts:
#	core/libs/prx/libSceVideoOut/CMakeLists.txt
#	docs/dev/debt/libSceVideoOut.md
2026-10-30 00:23:15 +13:00
p3nicillinandClaude Opus 5.5 cce9311f34 fix(libSceVideoOut): answer 0 and UNAVAILABLE_OUTPUT_MODE when the output has no 120 Hz
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]>
2026-10-28 13:48:19 +00:00
ionut27001 7af0c1dc60 fix(libSceVideoOut): answer flip-master calls only on a handle that never had buffers 2026-10-27 14:40:31 +02:00
ionut27001 e604020013 fix(videoout): report output status flags 0 with HDR output 2026-10-27 14:26:14 +02:00
Adrià d410ce253f Merge pull request #11207 from EagleBearerYS/feat/imedialog-pad-keyboard
feat(libSceImeDialog): type with the controller on an on-screen keyboard
2026-10-27 12:00:58 +01:00
Adrià 5c356f41c3 Merge pull request #11048 from imellag/feat/libkernel-macos-main-thread
feat(libkernel): start the guest off the main thread on macOS
2026-10-27 08:27:20 +01:00
Yunus Shaikh 2a3cd39882 feat(libSceVideoOut): hand the pad to an open keyboard and hold back the game's reads 2026-10-27 05:19:49 +01:00
Dean Galvin c21e03299d test(libSceVideoOut): check invalid capability handles only after the display opens, declare the exports in the public header
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.
2026-10-26 18:11:27 +13:00