PS4 app: Test controllers, opened with Options or from Actions, shows what
each signed-in user's controller sends, read the way a game reads it, on
the controller page's picture. Holding L3 + R3 opens its menu: change user,
rumble each motor, set or reset the light bar, reset orientation, go back.
Service: the control protocol takes motion ('m'), and info says so. Rumble
reached the page with the large and small motors swapped: fixed.
Page: Settings > Experimental, every switch off by default. Lights, rumble
and touchpad fingers for a DualShock 4 or DualSense over WebHID; trigger
rumble on Xbox controllers and a linked DualSense; motion from a phone or a
linked controller.
Read system TV-remote input independently, expose launcher actions through arrows and OK, and preserve DS4 shortcuts. Add reconnect handling, explicit Stop confirmation, diagnostics, and reader/navigation regressions.
Prepare the next patch version as a test candidate; PS4 HDMI-CEC reception still needs hardware confirmation before release.
When Control4Free was sent but did not answer, the app locked itself until
the PS4 restarted, so two copies could never run. The payload already takes
care of that: a second copy finds the instance lock and quits at once. So
the app now says to press Cross to try again, and a restart never helped a
payload that cannot start anyway. The lock stays only for the app itself
failing to start ("Reopen the app").
For consoles it fails on, so a user can send screenshots instead of digging
out log files. `make C4F_DIAG=1` and `make -C launcher C4F_DIAG=1` (or
tools/build-launcher.ps1 -Diag) build Control4Free-<version>-diag.pkg, listed
as "Control4Free (diagnostic)".
Its app shows plain pages in place of the normal screen: a summary with a
verdict (firmware, GoldHEN, sandbox, auto-start files, the service and the
last start), the service log and the previous one, and the kernel log,
filtered and in full. The kernel log is read only in short windows, at
start-up, around a start and on Options, since Control4Free needs it to sign
controllers in. The pages are also saved to
/data/control4free/diag-report.txt, and to a USB stick when one is plugged in.
The payload says on screen that it started, and logs the kernel addresses
the SDK found and the process PayLoader runs it in.
The package declared itself a game (CATEGORY gd), so the PS4 filed it under
Games in the library.
It now uses the values Apollo Save Tool ships with: CATEGORY gde ("Non-Game Mini
App"), ATTRIBUTE 32, APP_TYPE 1. Apollo is built with the same OpenOrbis tools and
lists under Applications. APP_TYPE 4 ("Freemium"), which is reported to move apps
there too, made the PS4 refuse to start ours (CE-39929-2), so it stays 1.
Confirmed on the console (firmware 10.01): the app installs, starts, and lists
under Library > Applications. A test reads the fields back out of the built
package.
Three bits of polish for people who did not write this.
The payload serves /manifest.webmanifest and /icon-192.png, and the page points
at both, so a phone can keep the controller on its home screen instead of typing
an IP address again. The icon is the app's own icon, rendered by the launcher's
drawing code and committed, so the payload build needs no renderer; a test
re-renders it and fails if the two drift apart. One size only: the gradient does
not compress, and a 512 copy would add 150 KB for a splash screen that a plain
HTTP shortcut never shows. write_png now picks the best filter per row, which
also shrinks the package icon.
When the service starts it works out which address the console is actually
reachable on, from the route to the outside world without sending anything, and
puts it in the start-up notification on the TV.
Every error the page can show now says what happened and what to do about it,
rather than "Invalid axis", and the README has a troubleshooting section covering
the ones people will actually hit.
The staged spike that worked out the VDA call order is no longer part of the
build. It is kept at tag spike-final.
- src/main.c is the service only: instance lock, credentials, MBus and pad
init, then the web service. src/server.c and include/c4f_server.h are gone
with stage 8, and so are the stage-only helpers in src/vda.c: the MBus bind
and holds, the assignment and button-map probes, and the GoldHEN klog stream
path. The service reads /dev/klog, which is what works.
- VERSION holds the only version number. Both Makefiles pass it in, the
packager reads it for param.sfo and the package name, and the build and
deploy scripts read it for the file they look for.
- The payload's log is /data/control4free/control4free.log, not spike.log.
- The page drops the protocol 1 branches: the payload has always answered 2.
A console slot is a "controller" and a pad plugged into the phone or PC is a
"gamepad", so the two no longer read as the same word.
- The host tests move to tests/, with tests/run.py to run all four suites. They
build the real sources with the PS4 calls stubbed, so they need no console.
klog_test now covers the device path only, and asserts that nothing ever
connects to GoldHEN's klog server.
On the console, 0.2.1 often could not add a controller ("Cannot read
controller sign-in events"). Its log shows why: once Control4Free let go
of GoldHEN's klog stream, every new connection read nothing for 4-5
minutes. GoldHEN's klog server serves one client at a time and is slow to
notice that one has left.
The browser service now opens /dev/klog itself, only while a controller
waits for sign-in, and releases it afterwards, so GoldHEN's klog server
works the rest of the time. It never uses GoldHEN's stream; only the
diagnostic stages still fall back to it.
Version 0.2.2 (APP_VER 00.22).
- The service checks its listener every second and notices long pauses
such as rest mode. It then drops stale connections, keeps controllers
neutral, and rebuilds the listener. Confirmed on the console: Control4Free
survives rest mode.
- A lock in /data/control4free stops a second copy before it touches the
host process's credentials or the log.
- Browser mode reads klog through GoldHEN's klog server first, after a
marker check, and falls back to /dev/klog. It holds a reader only while
controllers wait for sign-in, so GoldHEN's own klog keeps working.
- Log lines carry elapsed time, the previous run is kept as
spike.log.previous, and a heartbeat is logged every minute.
- Version 0.2.1 (APP_VER 00.21).
The mark is a vector DualShock 4 seen from above (launcher/logo.c), filled
with stb_truetype's anti-aliased rasterizer through a small path API in
draw.c. The app's top bar and the page's top bar, toast and favicon all use
it. The package icon shows three controllers with their light bars glowing
in the page's player colours.
- The first Cross copies the bundled payload to /data/payloads and adds it
to GoldHEN's AutoRun list, then starts it if PayLoader is on. Triangle
turns auto-start on or off, or updates an older copy. The app leaves its
sandbox for this through GoldHEN's SDK call and returns right after.
- The app tries 127.0.0.1 and then the console's own address, for both
Control4Free and PayLoader, and shows why neither answered.
- The launcher API no longer requires a loopback source address, since
the app's sandbox may not appear as 127.0.0.1. The custom header and
the Origin check still keep websites out.
- The screen and messages no longer assume a phone.
An OpenOrbis app that sends the bundled payload to GoldHEN's PayLoader,
shows its address and a QR code, and stops it through the loopback API.
It draws its screen in software in the controller page's style
(stb_truetype with Roboto), and its icon with the same code.
The package (title ID CFRE00001) carries OpenOrbis's stub libc.prx and
libSceFios2.prx in sce_module/, as the toolchain asks.
The README covers GoldHEN AutoRun, the launcher, the page and the build.
A GoldHEN ELF payload that creates virtual DualShock 4 controllers with
scePadVirtualDevice*, the path Remote Play uses, so they work on the home
screen, at sign-in and in games. A phone or PC drives them from a page the
payload serves on port 4264.
- Stage 0 (default) is the browser controller: four slots, explicit
creation, native PS4 user selection, input over a WebSocket.
- Stages 1-8 are the diagnostics that established the VDA call order.
- Loopback-only /api/status and /api/stop for the launcher app.
- The klog connection is reopened when a controller is created, so a
start through GoldHEN AutoRun still works if it beats the klog server.
The VDA code is ported from seregonwar/SplashDown (GPL-3.0).