Commit Graph
259 Commits
Author SHA1 Message Date
MarcZX10 97a5564fd4 feat(videoout): time the frame-limit wait as its own flip phase
The wait shows as frame_limit in the VideoOut.Flip timing, so a title held
by ANYPS5_FPS_LIMIT is told apart from one held by the vblank wait in the
trace and in the phases of the performance overlay's second page.
2026-11-01 01:49:43 +00:00
MarcZX10 66615554c3 feat(videoout): hold each flip of the window until its frame-limit deadline
With ANYPS5_FPS_LIMIT set, processFlip waits for the pacer's deadline after
the flip's vblank wait and before the frame is presented, so the delay
falls on the presentation and on the flip's completion event, which is
what paces the title. The wait takes no lock, sleeps with PreciseSleepUs in
slices of 20 ms and re-checks between slices whether the output was closed
or failed. The limit is read at the first flip, where an invalid value
stops the title with the error that names it. Without the variable the
pacer does not exist and processFlip does what it did. Flips of the overlay
bus are not paced.
2026-11-01 01:49:43 +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
MarcZX10 68a4689e62 Merge remote-tracking branch 'upstream/main' into fix/pad-port0-connected-state 2026-10-30 23:46:32 +00:00
Adrià 93f5331fd7 Merge pull request #13463 from notHaze/feat/configurable-mouse-stick
feat(input): add configurable mouse stick target
2026-10-30 22:50:29 +01: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
Adrià d09e7a46e9 fix(libScePad): resolve the merge with ShowPadStatus in the volume actions 2026-10-30 16:29:56 +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 7cd80adfd5 feat(libSceVideoOut): read the window's focus once when it first exists
With the option on, a window that opens behind another one starts silent instead of waiting for a first focus event that never comes. With the option off this changes nothing.
2026-10-30 16:29:55 +01:00
MarcZX10 5bb5ac189b feat(libSceVideoOut): mute the host audio while the window has no focus
The display window's focus events drive the shared host volume. With ANYPS5_MUTE_ON_FOCUS_LOSS unset or 0 they change nothing; with 1 the audio is silent from focus lost until focus gained, and each change prints one line on stderr.
2026-10-30 16:29:55 +01:00
MarcZX10 c2bcf86059 feat(libSceVideoOut): run the volume and mute hotkeys and report them on stderr
The requests are handled only for key events of the display window, like fullscreen, the overlay and the screenshot, and each handled press prints one line with the resulting level or mute.
2026-10-30 16:29:55 +01:00
MarcZX10 41fd68c00a feat(libSceVideoOut): read the host volume settings when video output starts
PadInput applies ANYPS5_VOLUME and ANYPS5_MUTE_ON_FOCUS_LOSS next to the input mapping, so an invalid value stops the game at the same point as an invalid mapping file, with an error naming the variable.
2026-10-30 16:29:55 +01:00
MarcZX10 d8eea5e340 feat(libSceVideoOut): accept ToggleMute as an input mapping action
The action takes keyboard keys only, like ToggleFullscreen, TogglePerformanceOverlay and Screenshot, and has no built-in binding yet. The input mapper lists it as keyboard-only and its source-contract test follows the native table.
2026-10-30 16:29:55 +01:00
MarcZX10 93e0a7a398 feat(libSceVideoOut): accept VolumeDown as an input mapping action
The action takes keyboard keys only, like ToggleFullscreen, TogglePerformanceOverlay and Screenshot, and has no built-in binding yet. The input mapper lists it as keyboard-only and its source-contract test follows the native table.
2026-10-30 16:29:55 +01:00
MarcZX10 b0614a752a feat(libSceVideoOut): accept VolumeUp as an input mapping action
The action takes keyboard keys only, like ToggleFullscreen, TogglePerformanceOverlay and Screenshot, and has no built-in binding yet. The input mapper lists it as keyboard-only and its source-contract test follows the native table.
2026-10-30 16:29:55 +01:00
MarcZX10 b960b79aa8 feat(libSceVideoOut): turn a ToggleMute key press into a toggleMute request
Only a first keyboard key-down counts: key repeat and the release ask for nothing, and a mouse button bound to it is ignored, like the other host requests.
2026-10-30 16:29:55 +01:00
MarcZX10 1ae4916799 feat(libSceVideoOut): turn a VolumeDown key press into a volumeDown request
Only a first keyboard key-down counts: key repeat and the release ask for nothing, and a mouse button bound to it is ignored, like the other host requests.
2026-10-30 16:29:55 +01:00
MarcZX10 88a0626f72 feat(libSceVideoOut): turn a VolumeUp key press into a volumeUp request
Only a first keyboard key-down counts: key repeat and the release ask for nothing, and a mouse button bound to it is ignored, like the other host requests.
2026-10-30 16:29:55 +01:00
MarcZX10 7f7eaa7d18 feat(libScePad): add the volume and mute input controls
VolumeUp, VolumeDown and ToggleMute join the controls that never reach the title's pad state: Compose ignores them like the fullscreen, overlay and screenshot controls.
2026-10-30 16:29:55 +01:00
Florent Combet 26d36e9645 feat(input): add configurable mouse stick target 2026-10-30 15:41:51 +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
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à e7529df44e Merge pull request #12996 from JJenkx/windows/diagnostics-unicode-paths
fix(diagnostics): open VideoOut telemetry and sampler files under any Unicode path on Windows
2026-10-30 10:55:46 +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
Adrià 7d4006607a Merge pull request #11196 from p3n1cillin/claude/videoout-unregister-busy
fix(libSceVideoOut): refuse to unregister the buffer set on screen as the console does
2026-10-30 06:21:30 +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
MarcZX10 9d2beb0084 feat(input): add the ShowPadStatus keyboard action
A rebindable keyboard action, F9 by default, that asks for the
controller status panel. F9 is the first free function key: F7, F10,
F11 and F12 are bound by default and no default keyboard-to-pad binding
uses it. Like ToggleFullscreen, TogglePerformanceOverlay and Screenshot
it accepts only keyboard keys, fires once per press (not on key repeat)
and does not press any pad button.

The input mapper's catalogue gets the action, its F9 default and its
keyboard-only restriction, and its existing source-contract tests list
it, since they compare the actions, restrictions and built-in bindings
with the native files.
2026-10-30 05:54:47 +01:00
Adrià 086adee5e3 Merge pull request #12379 from MarcZX10/feat/msgdialog-overlay
feat(overlay): show PS5 system dialogs as real PC dialogs
2026-10-30 02:04:23 +01:00
Adrià 7a225bb303 Merge pull request #12686 from MarcZX10/feat/pad-rumble-intensity
feat(libSceVideoOut): add ANYPS5_RUMBLE to scale or turn off host controller vibration
2026-10-29 23:46:17 +01: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
JJenkxandClaude Opus 5.5 74ec7311f1 fix(diagnostics): open VideoOut telemetry and sampler files under any Unicode path on Windows
APS5_VIDEOOUT_TELEMETRY_DIR, APS5_SAMPLE_THREADS, APS5_SAMPLE_WORKER and
APS5_SAMPLE_COMMITTER were read with getenv and opened with the narrow
fopen/ofstream, so on Windows they worked only for characters in the
ANSI code page, and the tests, which pass UTF-8 path.string() values,
failed whenever %TEMP% was not ASCII.

They are now read with _wgetenv and carried as UTF-8, as the other
diagnostic directories (ANYPS5_SCREENSHOTS, APS5_DUMP_SUBMITS,
APS5_PAD_INPUT_FILE) already are, and the files are opened through
std::filesystem::path. The worker sampler test sets its variables with
_wputenv_s and reads the results through std::filesystem::path.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-29 15:26:10 -04: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 8c0fda8ce1 feat(libSceVideoOut): keep mouse button presses from the title while a dialog is shown
MouseInput drops a button press while a modal dialog captures input, so the click
that answers the dialog is not also delivered to the title. Releases still reach
it in this commit.
2026-10-29 14:06:13 +00:00
MarcZX10 e4034b2f89 feat(libSceVideoOut): keep mouse motion and wheel from the title while a dialog is shown
MouseInput drops relative motion and wheel steps while a modal dialog captures
input, so moving or scrolling to answer the dialog does not also move the title's
cursor. Button events are unchanged by this commit. video_out_mouse_tests links
libSceIme for the dialog tests that follow.
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 35599e971d feat(libSceVideoOut): keep key presses from the title's keyboard while a dialog is shown
KeyboardInput no longer publishes a key press to libSceKeyboard while a modal dialog
captures input, so the keys that answer the dialog are not also typed into the
title. Key releases still reach it. keyboard_tests links libSceIme because it
builds KeyboardInput.cpp itself.
2026-10-29 14:06:13 +00:00
MarcZX10 a30f2a2fc8 feat(libSceVideoOut): keep pad and key presses from the title while a dialog is shown
While a modal dialog captures input, the controller hand-off that already serves
an IME keyboard publishes slot 0's buttons and left stick to the dialog and
returns the neutral intercepted state to the title, and the button held when the
dialog closes stays hidden until it is released. Key presses, mouse button
presses, wheel steps and motion no longer reach the keyboard-to-pad mapping while
the dialog is shown; releases still do, so no mapped button stays pressed.
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
MarcZX10 e77ad1da30 feat(libSceVideoOut): hand the pending modal dialog to the presenter
The presentation thread registers itself as a modal dialog presenter while its
window exists and withdraws on exit, so a dialog opened with no window to show
it is refused and keeps its caller's own answer. Before each flip it reads the
pending dialog and passes it to the driver, or clears it. The IME keyboard keeps
the overlay: while it is shown or captures the keyboard or the pad, the dialog
is not read.
2026-10-29 14:06:13 +00:00
Dean ca6987de8a Merge pull request #11414 from p3n1cillin/claude/videoout-register-past-last-buffer
fix(libSceVideoOut): return INVALID_VALUE for a registration past the last buffer as the console does
2026-10-30 03:00:15 +13:00
p3nicillinandClaude Opus 5.5 ecadb6068a fix(libSceVideoOut): refuse the on-screen unregister on the main bus only
EVO Player and Prospero Win measured RESOURCE_BUSY on ports opened on
bus type 0. The overlay bus is unmeasured, so its on-screen set is
still released as before, which video_out_flip_overlay relies on.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-29 12:18:02 +00:00
p3nicillinandClaude Opus 5.5 5768bc971f fix(libSceVideoOut): refuse to unregister the buffer set on screen
The console answers RESOURCE_BUSY (0x80290009) when the set holding
the buffer on screen is unregistered, and the set stays registered:
EVO Player measured it with a re-registration then failing
SLOT_OCCUPIED, and Prospero Win on firmware 12.02 after its flips went
idle. The set was released and 0 returned instead.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-29 12:18:02 +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
MarcZX10 10a6d9bb0e feat(libSceVideoOut): scale host controller rumble by ANYPS5_RUMBLE
The motor rumble and the trigger rumble of non-DualSense controllers reach SDL with the amplitude a title asked for and no host-side way to reduce or disable it. Build both commands through the rumble intensity helper: at the default of 100 the command is the one built before, and at 0 the host only ever receives a stop. The variable is read when the pad input starts, so an invalid value stops the game there. Vibration that a title plays as audio and that falls back to motor rumble goes through the same path and is scaled with it. DualSense adaptive trigger effects are left untouched.
2026-10-29 02:06:36 +00: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
p3nicillinandClaude Opus 5.5 338ea713f2 fix(libSceVideoOut): return INVALID_VALUE for a registration past the last buffer
PS5_Vulkan measured on a PS5 (firmware 13.40) that
sceVideoOutRegisterBuffers2 refuses a set at buffers 15 to 19 with
0x80290001. The call threw instead. The other out-of-range arguments
keep throwing.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-28 13:48:15 +00:00
Dean 2227f13661 Merge pull request #11516 from Lindamea1/fix/videoout-event-getters-invalid-event
fix(libSceVideoOut): return INVALID_EVENT from the event getters for an event of another filter
2026-10-29 00:35:41 +13:00