Archive of https://github.com/drakmor/ps5-native-gamepad-input-research — Native PS5 controller input research, recovered APIs, low-latency examples, and DualSense feature documentation for homebrew developers https://github.com/drakmor/ps5-native-gamepad-input-research
  • C++ 97.3%
  • Makefile 2.7%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
BlackBearReloaded 16e9b953b2
Acknowledge OpenAI Codex assistance in README
Added acknowledgment of OpenAI Codex assistance in project development.
2026-08-29 17:06:42 -04:00
.github/workflows Modernize examples to C++20 2026-08-28 17:36:05 -04:00
examples Validate native input hot-plug recovery 2026-08-29 10:29:36 -04:00
include Probe native keyboard and mouse indexes 2026-08-29 10:06:39 -04:00
tests Document native keyboard and mouse validation 2026-08-29 10:18:46 -04:00
.gitignore Add native keyboard and mouse research 2026-08-29 09:31:11 -04:00
CONTROLLER-DATA.md Modernize examples to C++20 2026-08-28 17:36:05 -04:00
FEATURES.md Modernize examples to C++20 2026-08-28 17:36:05 -04:00
FOLLOW-UP.md Validate native input hot-plug recovery 2026-08-29 10:29:36 -04:00
HANDOFF.md Validate native input hot-plug recovery 2026-08-29 10:29:36 -04:00
INVESTIGATION.md Modernize examples to C++20 2026-08-28 17:36:05 -04:00
KEYBOARD-MOUSE.md Validate native input hot-plug recovery 2026-08-29 10:29:36 -04:00
LIBRARIES.md Document native keyboard and mouse validation 2026-08-29 10:18:46 -04:00
LICENSE Initial public release 2026-08-28 17:19:41 -04:00
Makefile Add native keyboard and mouse research 2026-08-29 09:31:11 -04:00
NOTICE.md Initial public release 2026-08-28 17:19:41 -04:00
PLAN.md Validate native input hot-plug recovery 2026-08-29 10:29:36 -04:00
PRODUCTION-INTEGRATION.md Modernize examples to C++20 2026-08-28 17:36:05 -04:00
README.md Acknowledge OpenAI Codex assistance in README 2026-08-29 17:06:42 -04:00
STATIC-EVIDENCE.md Document native keyboard and mouse validation 2026-08-29 10:18:46 -04:00
USAGE.md Add native keyboard and mouse research 2026-08-29 09:31:11 -04:00
VALIDATION.md Validate native input hot-plug recovery 2026-08-29 10:29:36 -04:00

PS5 Native Gamepad, Keyboard and Mouse Input Research

Examples Input APIs License: GPL-3.0

Independently documented guidance for native, low-latency PlayStation 5 input. The repository covers gamepad, USB keyboard, and USB mouse lifecycle and batching; every verified DualSense field; motion, touch, feedback, and adaptive triggers; and the responsibilities of the underlying PS5 libraries.

The normal application path is deliberately small: use libSceUserService to resolve the signed-in player, then libScePad, libSceKeyboard, or libSceMouse for the selected device. No SDL input subsystem, raw HID report parser, controller pairing code, or privileged device-control interface is required.

Project status

Area Status
Signed-in user and pad lifecycle Device-tested
Digital buttons Device-tested in working applications
Left and right sticks Device-tested in working applications
Analog L2 and R2 Device-tested in working applications
Batched low-latency reads Device-tested in UI and streaming applications
Current-state polling Device-tested at approximately 243–250 Hz
Sample timestamp and connection generation Contract-tested and behavior corroborated
Two-contact touch data Contract-tested; dedicated physical test pending
Orientation, acceleration, and angular velocity Contract-tested; dedicated physical test pending
Controller information and reported dead zones Contract-tested and behavior corroborated
Vibration and light bar Contract-tested; repository device test pending
Adaptive trigger effects and state Contract-tested; repository device test pending
Specialized device classes Partial compatibility evidence only
Native keyboard queue and 96-byte record Device-tested with timestamped HID key transitions
Native mouse queue and 40-byte record Device-tested with motion, clicks, wheel, and tilt
Keyboard/mouse hot-plug Device-tested with retained handles across receiver removal and reconnection
CI Builds strict C++20 examples and runs host-side contract checks

Platform interfaces can change. Re-run the layout checks and device tests before assuming compatibility with another system-software version.

Main findings

Finding Result
Recommended libraries libSceUserService plus libScePad, libSceKeyboard, or libSceMouse
Lowest-risk low-latency API scePadRead(handle, samples, 64)
Driver interaction One platform-driver request per batch read
Returned order Oldest retained sample first; newest sample last
Maximum normal batch 64 records, 7,680 bytes total
Normal record size 120 bytes
Current-state API scePadReadState, with cached-state fallback
Short button transitions Preserved by processing every batched record
Observed production batch Up to 7 records despite a 4 ms application poll
USB versus Bluetooth Hidden behind the same Pad API
libSceHidControl Specialized Jedi/Spark service controls, not the normal gamepad queue
libSceBluetoothHid Raw Bluetooth transport, not a faster application input path
Keyboard path sceKeyboardRead(handle, samples, 16) with USB HID usages
Mouse path sceMouseRead(handle, samples, 64) with relative axes and wheels
Keyboard/mouse loading Load native sysmodule IDs 0x0106 and 0x00a9 before initialization
Physical index discovery Open every accepted index and retain successful handles for hot-plug and multiple devices
Empty/inactive reads Process exactly the returned count; a neutral record may be returned for an inactive index
Hot-plug behavior Existing handles reported removal and resumed input after reconnection; no reopen was needed
Signed-in application user
  -> scePadInit
  -> scePadOpen(user, standard port, index 0)
  -> scePadRead(handle, records, 64)
  -> neutralize disconnected or system-intercepted records
  -> process every button and touch transition oldest-first
  -> publish the final record as current analog and motion state
  -> simulation or UI update
  -> render

Call the read immediately before the application consumes input. Reading after simulation adds an avoidable application frame of latency. Do not surround the batch read with scePadReadState calls on the same handle; both enter the same globally locked read core.

Capability matrix

Capability Native representation Notes
Create, Options, D-pad, face buttons ScePadData.buttons Verified button mask
L1/R1, L2/R2, L3/R3 Digital mask L2/R2 also provide analog travel
Touch-pad click Digital mask bit 0x00100000 Separate from touch contacts
System interception Mask bit 0x80000000 Discard the sample and publish neutral state
Left/right sticks Four unsigned bytes Range 0–255, center 128
Analog triggers Two unsigned bytes Range 0–255
Touch pad Up to two contacts X/Y, stable contact ID, controller-specific resolution
Motion Quaternion + acceleration + angular velocity Timestamp every sample
Connection 32-bit state + generation byte Clear cached edges/calibration when generation changes
Vibration Two unsigned levels Low- and high-frequency components
Light bar RGB parameter Reset restores platform behavior
Adaptive triggers Off, feedback, weapon, vibration Separate L2/R2 commands and state values
PS button System-owned Not exposed as a normal application button
Mute button and controller audio Separate services Not verified in the normal 120-byte Pad record

See Controller data format for the exact offsets, button values, coordinate handling, timestamps, and connection rules.

Physical keyboards and mice use separate native queues. See Native keyboard and mouse input for their exact layouts, batch limits, lifecycle, idle semantics, and C++20 examples.

Quick start

The examples are portable C++20 contract snippets. Host checks require no vendor SDK, firmware files, proprietary headers, or console toolchain.

git clone git@github.com:blackbearreloaded/ps5-native-gamepad-input-research.git
cd ps5-native-gamepad-input-research
make check

make check verifies all documented gamepad, keyboard, and mouse structure sizes and offsets; exercises edge and neutral-state behavior; checks axis conversion and mouse no-record semantics; and compiles every portable example with strict C++20 warnings.

For a native PS5 application, import libSceUserService and libScePad, then use the declarations in include/ps5_pad.hpp:

#include "ps5_pad.hpp"

#include <array>
#include <cstddef>
#include <cstdint>
#include <span>

std::int32_t user_id{};
sceUserServiceInitialize(nullptr);
sceUserServiceGetInitialUser(&user_id);
scePadInit();

const auto handle =
    scePadOpen(user_id, ps5::pad::kPortTypeStandard, 0, nullptr);

std::array<ps5::pad::Data, ps5::pad::kMaxSamples> samples{};
const auto count = scePadRead(
    handle, samples.data(), static_cast<std::int32_t>(samples.size()));
if (count < 0)
    handle_error(count);

for (const auto& sample :
     std::span{samples}.first(static_cast<std::size_t>(count)))
    process_sample(sample);

Production code must check every return value, neutralize disconnected or intercepted records, stop active output effects, and close the handle during shutdown. Usage and lifecycle provides the complete sequence.

Implementation guidance

  1. Open a standard pad for the real signed-in user, not the system user.
  2. Use scePadRead(..., 64) when press/release fidelity matters.
  3. Process every returned record in order and retain the final record as the current analog, touch, and motion state.
  4. Treat disconnection and system interception as a neutral controller; raw zero-filled stick fields are not neutral because their center is 128.
  5. Use sample timestamps for ordering and motion integration, not render time.
  6. Read once near input consumption and keep one owner per pad handle.
  7. Use libScePad feedback calls instead of constructing raw Bluetooth output reports.
  8. Validate touch, motion, vibration, lighting, and trigger effects on the target controller and firmware before advertising those features.

Documentation

Document Purpose
Usage and lifecycle Imports, signed-in user, open/read/close, polling models, multi-user handling, and errors
Controller data format Exact 120-byte layout, buttons, axes, touch, motion, timing, and connection state
Controller features Information, dead zones, motion configuration, vibration, light bar, and adaptive triggers
Native keyboard and mouse input Keyboard/mouse lifecycle, exact records, batching, HID usages, relative axes, and idle rules
Library responsibilities UserService, Pad, Keyboard, and Mouse versus lower-level HID services
Low-latency investigation Queue behavior, driver path, API comparison, and recommended architecture
Static compatibility evidence Functional read behavior, independently documented layouts, and library conclusions
Validation Working applications, aggregate device evidence, publication boundary, and acceptance matrix
Production integration Batched streaming telemetry, protocol lifecycle, local chords, mouse mode, and latency diagnosis
Follow-up experiments Remaining latency measurements and optional ABI investigations
Examples Feature-focused native C++20 examples

Examples

Example Demonstrates
01-lifecycle.cpp Signed-in user, ownership-aware initialization, RAII open, and shutdown
02-current-state.cpp Cached latest-state polling and correct neutral synthesis
03-low-latency-batch.cpp 64-record drain with chronological press/release edges
04-full-joystick.cpp Both sticks, analog triggers, complete button mask, and signed axes
05-motion-touch.cpp Motion configuration and two-contact extraction
06-feedback.cpp Vibration, light bar, adaptive-trigger feedback, and safe reset
07-controller-info.cpp Connection, device class, dead zones, and touch resolution
08-keyboard-batch.cpp Sixteen-record keyboard drain and chronological HID-usage edges
09-mouse-batch.cpp Sixty-four-record relative mouse drain and correct no-record/neutral handling
native-keyboard-mouse-poc Deployable source overlay for attached-device capture evidence

The validation guide also summarizes two complete integrations: a native controller-forwarding path and an SDL-free UI adapter. Both were physically exercised with a DualSense; private application paths and logs are intentionally not part of this repository.

Repository layout

README.md                       Research overview and application guidance
USAGE.md                        Initialization, polling, shutdown, and errors
CONTROLLER-DATA.md              Exact input-record contract
KEYBOARD-MOUSE.md               Native keyboard and mouse contracts
FEATURES.md                     Motion, touch, feedback, and controller information
LIBRARIES.md                    Native library selection and scope
INVESTIGATION.md                Low-latency read-path analysis
STATIC-EVIDENCE.md              Functional compatibility evidence
VALIDATION.md                   Device evidence and publication boundary
PRODUCTION-INTEGRATION.md       Production batching, multiplexing, and telemetry lessons
FOLLOW-UP.md                    Remaining optional experiments
include/ps5_*.hpp               Independently authored C++20 compatibility declarations
examples/                       Small feature-focused C++20 examples
tests/layout_check.cpp          ABI size and offset regression
tests/logic_check.cpp           Edge, neutral-state, and axis regression
tests/keyboard_mouse_check.cpp  Keyboard/mouse queue behavior regression
.github/workflows/examples.yml  Host-side CI validation

Methodology

The investigation combined independently authored compatibility declarations, host-side contract tests, functional analysis of the application-facing interfaces, and runtime behavior from working applications using physical devices. Proprietary files, private task data, binary fingerprints, analysis databases, and internal addresses are not published.

Evidence labels are intentionally narrow:

  • Device-tested: the path executed successfully on a PS5 or was physically confirmed with a controller.
  • Contract-tested: independently authored sizes, offsets, values, or prototypes passed layout and host-side checks.
  • Behavior corroborated: functional conclusions agree with application telemetry and compatibility analysis.
  • Experimental: a plausible interface exists, but physical behavior, privileges, or some structure fields remain incomplete.

External projects and acknowledgements

Project Relevance
Ghostcontrol — PS5 USB Controller Patcher Inspiration and related investigation into third-party USB controller support and virtual DualSense input by StonedModder

Scope

This repository publishes independently authored documentation and small examples. It does not contain vendor SDK files, firmware or system modules, retail binaries, decrypted content, signing material, credentials, cryptographic keys, analysis databases, controller firmware, copied vendor source, or proprietary headers. It does not provide an exploit or access-control bypass, pair devices, update device firmware, or replace platform device policy.

The PS button, microphone mute control, speaker/microphone audio, headset routing, raw Bluetooth registration, and privileged system interception are outside the verified normal application-input contract.

See NOTICE.md for the legal-use boundary, third-party rights, and trademark attribution.

License and attribution

Repository-authored documentation and examples are licensed under GPL-3.0. See LICENSE and NOTICE.md.

PlayStation, PS5, and DualSense are trademarks of Sony Interactive Entertainment. This independent project is not affiliated with or endorsed by Sony Interactive Entertainment.

This project was developed with assistance from OpenAI Codex, including some original interface artwork. Project maintainers reviewed and validated the resulting code, tests, documentation, dependencies, and generated assets.