docs: fool-proof guide + complete build walkthrough (md and html)

- docs/GUIDE.md: step-by-step usage (what you see at every step), tuning,
  symptom-by-symptom troubleshooting, uninstall
- docs/BUILD.md: complete build chain (payload via docker, PC toolchain
  install, exact commands, verification, gotchas)
- docs/index.html: rebuilt with quick-start detail, log-line table,
  troubleshooting, build section, anchors
- README: detailed quick start, corrected build commands (static dll,
  luxtheme, embed order) and links
This commit is contained in:
fstat13 committed 2026-10-15 15:12:13 +02:00
1 parent 99f895cafb
commit 0daa328a3c
4 files changed
+492 -50

No files matched your search

+43 -24
View File
@@ -31,50 +31,69 @@ No capture card. No Remote Play. No cloud. Just your console and your network.<b
## 🚀 Quick start
1. **Jailbreak your PS5** (payload loader on `:9021`, anonymous FTP on `:2121`,
`pldmgr` autoloader — all standard in today's setups).
2. **Run `PSCapture.exe`** (admin is requested automatically; set your PS5 IP
if it isn't the default).
3. **Press Start.** The app does the rest. The console pops a notification:
`PSCapture is streaming on:PORT`
4. In Discord/OBS pick the camera **PS5 Capture**.
1. **Jailbreak your PS5** — you need the standard setup: a payload loader on
TCP `9021` (`elfldr`-style), anonymous FTP on TCP `2121`, and optionally
`pldmgr` so the payload starts on every boot.
2. **Double-click `PSCapture.exe`** (one file — the console payload and the
Windows driver travel inside it). Accept the UAC prompt. If your PS5 isn't
at `192.168.0.36`, type its IP in the *PS5 IP* field and press *Apply*.
3. **Watch the log pane** — the app installs the capture driver (first run
only), sends the payload to the console and connects by itself. The status
pill turns green: `STREAMING`. The console shows the system toast
**PSCapture is streaming on:PORT**.
4. In Discord (*Settings → Voice & Video → Camera*) or OBS pick the camera
**PS5 Capture**.
📖 The illustrated guide lives in [`docs/index.html`](docs/index.html)
(open it in a browser, or enable GitHub Pages on `/docs`).
🔧 Curious about what happens under the hood when you press Start? See
[`docs/INSTALLER.md`](docs/INSTALLER.md) — the exact four steps the app runs,
down to registry keys and console paths.
Stuck on *“IN ATTESA DELLA PS5”*? Console off, not jailbroken yet, or wrong
IP — the app retries by itself every 2 seconds.
📖 Step-by-step with every log line explained: [`docs/GUIDE.md`](docs/GUIDE.md)
— or the [illustrated HTML guide](docs/index.html).
🔧 What the app does under the hood when you press Start:
[`docs/INSTALLER.md`](docs/INSTALLER.md).
## 📦 Repository layout
```
payload/ PS5 side: display-engine reader + NV12 streamer (ps5capture.elf)
pc/ PSCapture.exe — GUI + installer + payload deployer + feeder
payload/ PS5 side: display-engine reader + NV12 streamer (pscapture.elf)
pc/ PSCapture.exe — GUI + installer + payload deployer + feeder
pc/ps5cam.c the virtual capture-card driver (DirectShow source filter)
pc/shm.h shared-memory contract between feeder and driver
pc/*.dll the virtual capture-card driver (DirectShow source filter)
docs/ HTML guide (dark theme, ready for GitHub Pages)
docs/ guides: HTML, fool-proof step-by-step, build, installer, RE, log
```
## 🔧 Build
**Console payload** (needs the PS5 payload SDK; any Linux/docker with it):
Full walk-through (toolchain install, verification, gotchas):
**[`docs/BUILD.md`](docs/BUILD.md)**. The short version, in the **mandatory
order** (the `.res` embeds the driver and the payload as they are on disk):
**Console payload** → `payload/pscapture.elf` (needs Docker + the PS5 payload
SDK image; any tag works, here `ps5sdk:18`):
```bash
docker run --rm -v "$PWD/payload:/payload" -w /payload <ps5-payload-sdk-image> make
docker run --rm -v "$PWD/payload:/payload" -w /payload ps5sdk:18 make
```
**Driver + single-file app** (mingw-w64, no dependencies — build order matters,
the `.res` embeds the driver and the payload):
**PC side** → `pscapture.exe` + `pscapture.dll` (needs MinGW-w64 with `gcc` +
`windres`):
```bash
# 1) the capture-card driver
gcc -O2 -shared -o pc/pscapture.dll pc/ps5cam.c -lole32 -loleaut32 -luser32 -ladvapi32 -lws2_32
cd pc
cp ../payload/pscapture.elf . # gets embedded as-is
# 1) the capture-card driver (-static is mandatory, see BUILD.md)
gcc -O2 -shared -static -static-libgcc -o pscapture.dll ps5cam.c \
-lole32 -loleaut32 -luser32 -ladvapi32 -lws2_32
# 2) resources = icon + payload + driver
windres pc/pscapture.rc -O coff -o pc/pscapture.res
windres pscapture.rc -O coff -o pscapture.res
# 3) the app (one self-contained executable)
gcc -O2 -mwindows -o pc/pscapture.exe pc/pscapture.c pc/pscapture.res -lws2_32 -lshell32 -ladvapi32
gcc -O2 -mwindows -o pscapture.exe pscapture.c pscapture.res \
-lws2_32 -lshell32 -ladvapi32 -luxtheme
```
Rebuild rule: **DLL → windres → exe, every time** — rebuilding only the exe
ships the old driver inside it.
## ❓ FAQ
**Does it work on firmwares older than 13.60?**
+160
View File
@@ -0,0 +1,160 @@
# PSCapture — build from source, step by step
Everything needed to go from these sources to a working `PSCapture.exe` and a
`pscapture.elf` for the console. Every command is written exactly as it is
run, in order. Nothing here is optional magic — the order matters and each
step is explained.
There are two halves, built in different places:
| Half | Output | Where it builds | Toolchain |
|---|---|---|---|
| Console payload | `payload/pscapture.elf` | Docker (Linux container) | PS5 payload SDK (prospero-clang) |
| PC side | `pc/pscapture.exe` + `pc/pscapture.dll` | Windows | MinGW-w64 (`gcc` + `windres`) |
---
## Part 1 — The console payload
### 1.1 What you need
- **Docker** (Docker Desktop on Windows, or plain Docker on Linux/macOS).
- **The PS5 payload SDK container image.** This is the community PS5 payload
SDK (`prospero-clang`, `make`, `PS5_PAYLOAD_SDK` set in the environment)
baked into an image. On the development machine the image is tagged
`ps5sdk:18` — any name works, adjust the commands below to match yours.
Check the image is there:
```bash
docker images | grep ps5sdk
```
### 1.2 Build
From the repository root:
```bash
docker run --rm -v "$PWD/payload:/payload" -w /payload ps5sdk:18 make
```
On Windows PowerShell/cmd, give the full path instead of `"$PWD/payload"`,
e.g. `-v "C:\Users\you\PSCapture\payload:/payload"`.
Result: **`payload/pscapture.elf`** (~175 KB).
The `Makefile` does the only thing that matters: compile `main.c` with the
Prospero clang from the SDK and link the final ELF. No other inputs.
### 1.3 Optional — send it to the console
With the console jailbroken (payload loader on port 9021):
```bash
docker run --rm -v "$PWD/payload:/payload" -w /payload ps5sdk:18 \
make deploy PS5_HOST=192.168.0.36
```
(or just push `pscapture.elf` with whatever loader you normally use).
What a healthy run looks like on the console:
- `/data/pscapture.log` appears and logs the startup,
- `/data/pscapture.port` appears containing the TCP port of the stream,
- the console pops the notification *PSCapture is streaming on:PORT*.
---
## Part 2 — The PC side
### 2.1 What you need (Windows)
**MinGW-w64 64-bit** with `gcc` and `windres`. On the development machine:
```powershell
winget install BrechtSanders.WinLibs.POSIX.UCRT
```
(or any MSYS2 `mingw-w64-x86_64-gcc` install — `pacman -S mingw-w64-x86_64-gcc`).
Check both tools are on PATH:
```bash
gcc --version
windres --version
```
### 2.2 Build — the order is mandatory
`pscapture.res` is a bundle that **embeds files as they are on disk**: the
icon, the console payload and the capture-card driver. So the DLL must be
built *before* the resource step, and the payload must be sitting in `pc/`
when `windres` runs. Build the EXE last.
```bash
cd pc
# 0) bring the freshly built payload next to the .rc (it gets embedded as-is)
cp ../payload/pscapture.elf .
# 1) the capture-card driver (DirectShow source filter)
gcc -O2 -shared -static -static-libgcc -o pscapture.dll ps5cam.c \
-lole32 -loleaut32 -luser32 -ladvapi32 -lws2_32
# 2) bundle icon + payload + driver into one resource object
# (pscapture.rc => 1 ICON pscapture.ico / 2 RCDATA pscapture.elf
# / 3 RCDATA pscapture.dll)
windres pscapture.rc -O coff -o pscapture.res
# 3) the app — one self-contained executable
gcc -O2 -mwindows -o pscapture.exe pscapture.c pscapture.res \
-lws2_32 -lshell32 -ladvapi32 -luxtheme
```
### 2.3 Verify the build
```bash
# the driver must depend on system DLLs ONLY (no libgcc/libwinpthread):
objdump -p pscapture.dll | grep "DLL Name"
# sizes look right: exe ~500 KB, dll ~220 KB
ls -la pscapture.exe pscapture.dll
# both the payload and the driver are really inside the exe:
strings pscapture.exe | grep -c PSCapture
```
Run `pscapture.exe`: the window opens (UAC prompt → Yes), the log pane walks
through driver check → payload extraction → deploy attempt. That is the same
sequence described in `docs/INSTALLER.md`.
### 2.4 Gotchas (learned the hard way)
- **`-static -static-libgcc` on the DLL is not cosmetic.** Without it the
driver can end up needing mingw runtime DLLs that are *not* on the system
PATH when Windows (or another app) loads it — the classic
*"the specified module could not be found"*.
- **Build order.** `windres` reads `pscapture.dll` and `pscapture.elf` from
`pc/` at compile time. Rebuild the DLL → re-run `windres` → rebuild the
EXE, every time. Forgetting the middle step ships an old driver inside the
new exe.
- **ASCII only** in strings passed to the `*A` Win32 APIs (window titles,
buttons, logs). UTF-8 bytes in an ANSI string render as mojibake.
- The **manifest** (`pc/pscapture.manifest`) is kept for reference only;
the current build does **not** embed it — self-elevation is done in code
(`ShellExecuteEx … "runas"`), which avoids mingw's `.rsrc merge failure`
with multiple manifests.
### 2.5 Package a release
```bash
mkdir -p dist
cp pc/pscapture.exe pc/pscapture.dll dist/
```
`pscapture.exe` alone is enough for users (the DLL and the payload travel
inside it). The bare `pscapture.dll` is attached for manual installs:
```bash
rundll32 "pscapture.dll",DllRegisterServer
```
+112
View File
@@ -0,0 +1,112 @@
# PSCapture — the fool-proof guide
From zero to your PS5 inside Discord. Every step says exactly what you should
see on screen. If something doesn't match, jump to the troubleshooting table
at the bottom.
---
## 0. What you need
**On the console** — all standard in current jailbreak setups:
| Thing | Port | Why |
|---|---|---|
| Payload loader (`elfldr`-style) | TCP **9021** | runs the payload we send |
| Anonymous FTP | TCP **2121** | the app reads/writes files on the console |
| `pldmgr` autoloader (optional) | — | makes the payload start at every boot |
**On the PC**: Windows 10/11 64-bit, wired network recommended.
**The app**: `PSCapture.exe` — **one single file**. Download it from the
repository's Releases page. That's the whole package: the console payload and
the Windows capture-card driver are inside it.
---
## 1. First run on the PC
1. Put `PSCapture.exe` anywhere (the Desktop is fine) and **double-click it**.
2. Windows asks *"Do you want to allow this app to make changes to your
device?"* → click **Yes**.
*Why:* registering the virtual camera for every app on the machine needs
administrator rights, once. The app elevates itself — no right-click needed.
3. The window opens (dark, with a big blue **START STREAMING** button).
If your PS5 is not at `192.168.0.36`: type its address in the **PS5 IP**
field and press **Apply**.
4. From here the app does everything alone. Watch the dark log pane:
| You should read | Meaning |
|---|---|
| `driver gia' installato` | camera already registered — fine |
| `driver estratto dall'eseguibile (… byte)` + `driver registrato - la webcam 'PS5 Capture' e' pronta` | first run: driver installed |
| `payload dall'eseguibile (… byte)` + `payload avviato - la PS5 deve mostrare la notifica PSCapture` | the payload is now running on the console |
| `porta stream: 9xxx` then `collegato a 192.168.0.36:9xxx` | stream connected |
| status pill turns **green**: `STREAMING - scegli 'PS5 Capture' in Discord` | you're live |
5. The PS5 shows a system notification: **PSCapture is streaming on:PORT**.
(That toast is the console telling you the payload is alive.)
> If the pill stays on *"IN ATTESA DELLA PS5 — accesa e col jailbreak avviato?"*
> the console is off, not jailbroken, or the IP is wrong. See section 5.
## 2. Use it
**Discord (in a call)** — *Settings → Voice & Video → Camera* → **PS5 Capture**.
The in-call image is 720p: that's Discord's engine, it asks *every* camera
(capture cards included) for 1280x720.
**OBS** — *Sources → **+** → Video Capture Device* → **PS5 Capture**.
This runs at the full **1920x1080**.
**ffmpeg** — `ffmpeg -f dshow -i video="PS5 Capture" capture.mkv`
## 3. Daily use
- Open `PSCapture.exe` → **Yes** to the admin prompt. The app reconnects by
itself: if the payload is already on the console (autoloader) the stream
starts by itself; if the console is off the pill says
*"IN ATTESA DELLA PS5"* and connects the moment the console is ready.
- Press **Stop** (or close the app) to stop streaming. The camera goes black /
freezes on the last frame; consumers keep the device listed.
- **Deploy payload** re-sends the payload by hand (useful after a console
reboot without autoloader). **Install driver** re-registers the camera by
hand (useful if the log shows a driver error).
## 4. The two knobs
| Knob | What it does | Rules |
|---|---|---|
| `gain` | chroma (color) strength | `1.0` = raw, the correct default. Only touch it if colors look wrong. |
| `shift px` | moves the image left/right | **even numbers only** (an odd number inverts the colors). Tune until the picture is centered; the console's title text is a good anchor. |
Both apply live (about a second) and are saved in `pscapture.ini` next to the
exe, so they survive restarts.
## 5. Troubleshooting — symptom by symptom
| Symptom | Cause | Fix |
|---|---|---|
| Pill stays `AVVIO...` / `IN ATTESA DELLA PS5` | console off, **not jailbroken**, or wrong IP | turn the console on, run the jailbreak (ports 9021/2121 must be up), check the IP field |
| Log repeats `PS5 non raggiungibile (...)`, riprova | same as above | same |
| No `PS5 Capture` camera appears in Discord/OBS | driver never registered (install failed) | press **Install driver**; read the log line after it — it now reports the *real* error |
| Log: `ERRORE: driver non scrivibile in C:\Program Files\PSCapture (serve admin?)` | app not elevated | close it, restart `PSCapture.exe` and accept the UAC prompt |
| Log: `ERRORE caricando la dll (err=126)` | antivirus quarantined the extracted dll | check the antivirus quarantine for `pscapture.dll`, allow it, press **Install driver** again |
| Camera listed but the image is black | stream not running | check the pill; press **Deploy payload** and/or **START STREAMING** |
| Colors look wrong (skin reddish, sky orange) | `gain` was changed | set `gain` back to `1.0` → Apply |
| Image has a black bar / is off-center | alignment | tune `shift px` (even values) until centered |
| Discord keeps showing 720p | Discord's engine caps every camera at 720p | use OBS for 1080p, or Discord screen-share (1080p60 with Nitro) |
| OBS shows the camera, Discord doesn't | Discord was already open when the driver was installed | fully quit Discord (also from the tray) and reopen it |
| Everything else | — | read `pscapture-app.log` (next to the exe, or in `%TEMP%`) and the console log `/data/pscapture.log` (FTP) |
## 6. Uninstall
1. Close the app.
2. `rundll32 "%ProgramFiles%\PSCapture\pscapture.dll",DllUnregisterServer`
(removes the camera registration).
3. Delete `C:\Program Files\PSCapture`.
4. Optional, on the console: delete `/data/pldmgr/payloads/pscapture/` so the
autoloader stops starting it.
+177 -26
View File
@@ -30,6 +30,7 @@
padding:5px 12px;border-radius:999px;font-size:13px;color:var(--dim)}
.badge b{color:var(--fg)}
h2{margin:52px 0 14px;font-size:26px}
h3{margin:26px 0 10px;font-size:19px}
.cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:14px}
.card{background:var(--card);border:1px solid var(--line);border-radius:14px;padding:18px 20px}
.card h3{margin:0 0 8px;font-size:17px}
@@ -47,22 +48,35 @@
color:#fff;font-weight:600;display:flex;align-items:center;justify-content:center}
ol.steps b{color:var(--fg)}
ol.steps span{color:var(--dim)}
ul.plain{color:var(--dim);padding-left:22px}
ul.plain b{color:var(--fg)}
table{width:100%;border-collapse:collapse;margin-top:14px;font-size:14.5px}
th,td{text-align:left;padding:10px 12px;border-bottom:1px solid var(--line)}
th,td{text-align:left;padding:10px 12px;border-bottom:1px solid var(--line);
vertical-align:top}
th{color:var(--dim);font-weight:500}
td code,th code{white-space:nowrap}
code,kbd{background:#0a0d12;border:1px solid var(--line);border-radius:6px;
padding:1px 7px;font:13.5px/1.5 Consolas,monospace;color:#cfe3ff}
pre{background:#0a0d12;border:1px solid var(--line);border-radius:12px;
padding:14px 16px;overflow-x:auto;font:13.5px/1.6 Consolas,monospace;
color:#cfe3ff}
pre .c{color:#5f7186}
details{background:var(--card);border:1px solid var(--line);border-radius:12px;
padding:14px 18px;margin:10px 0}
summary{cursor:pointer;font-weight:600}
details p{color:var(--dim);margin:10px 0 0}
.note{background:linear-gradient(0deg,rgba(0,112,209,.08),rgba(0,112,209,.08)),
var(--card);border:1px solid #23405f;border-radius:12px;padding:14px 18px;color:#cfe3ff}
.warn{background:linear-gradient(0deg,rgba(226,34,54,.07),rgba(226,34,54,.07)),
var(--card);border:1px solid #5f2330;border-radius:12px;padding:14px 18px;color:#f3cdd3}
footer{color:var(--dim);border-top:1px solid var(--line);margin-top:70px;
padding:26px 0 40px;font-size:13.5px}
.dot{display:inline-block;width:9px;height:9px;border-radius:50%;
background:var(--rec);margin-right:8px;vertical-align:1px}
.ok{color:var(--ok);font-weight:600}
.toc{display:flex;gap:8px;flex-wrap:wrap;margin-top:18px}
.toc a{border:1px solid var(--line);background:var(--card);border-radius:999px;
padding:4px 12px;font-size:13px}
</style>
</head>
<body>
@@ -83,6 +97,13 @@
<span class="badge"><b>No</b> Remote&nbsp;Play</span>
<span class="badge">1080p &middot; ~30 fps</span>
</div>
<div class="toc">
<a href="#start">Quick start</a>
<a href="#daily">Daily use</a>
<a href="#trouble">Troubleshooting</a>
<a href="#build">Build from source</a>
<a href="#faq">FAQ</a>
</div>
</div>
</header>
@@ -121,30 +142,154 @@
<div>DirectShow filter exposes the ring as a camera every app can use.</div></div>
</div>
<h2>Quick start</h2>
<h2 id="start">Quick start — step by step</h2>
<div class="note" style="margin-bottom:20px">
<b>What you need first.</b> A jailbroken PS5 with the standard setup:
a payload loader on TCP <code>9021</code> (<code>elfldr</code>-style),
anonymous FTP on TCP <code>2121</code>, and optionally the
<code>pldmgr</code> autoloader so the payload starts on every boot.
PC and console on the same LAN. Download <b>PSCapture.exe</b> from the
Releases page — <b>it's one single file</b>: the console payload and the
Windows driver are inside it.
</div>
<ol class="steps">
<li><b>Jailbreak your PS5</b><br>
<span>Any kernel-capable jailbreak that gives you payloads
(<code>elfldr</code> on port 9021, anonymous FTP on 2121 and the
<code>pldmgr</code> autoloader).</span></li>
<li><b>Run <code>PSCapture.exe</code></b><br>
<span>Windows asks for administrator once. Type the PS5 IP address if it
is not the default <code>192.168.0.36</code>.</span></li>
<li><b>Press <i>Start</i></b><br>
<span>The app installs the virtual capture driver (first run), sends the
payload to the console, registers it in the autoloader and starts the
stream. The PS5 shows the streaming notification.</span></li>
<li><b>Discord / OBS / anything</b><br>
<span>Choose the camera <b>PS5 Capture</b>. Done — that is your PS5 on
the other side.</span></li>
<li><b>Jailbreak the console</b><br>
<span>Any kernel-capable jailbreak that gives you the payload loader
(:9021), anonymous FTP (:2121) and — optionally — the
<code>pldmgr</code> autoloader.</span></li>
<li><b>Double-click <code>PSCapture.exe</code></b><br>
<span>Windows asks <i>“Do you want to allow this app to make changes?”</i>
→ <b>Yes</b>. The app elevates itself; admin is needed once, to register
the virtual camera for every program on the machine.</span></li>
<li><b>Check the IP</b><br>
<span>If your PS5 is not at <code>192.168.0.36</code>, type its address
in the <b>PS5 IP</b> field and press <b>Apply</b>.</span></li>
<li><b>Watch it work — press nothing</b><br>
<span>The app does everything alone, and narrates it in the dark log pane
(see the table below). On the console you will also see the system
notification <i>“PSCapture is streaming on:PORT”</i>.</span></li>
<li><b>Use it in any app</b><br>
<span>Discord (call): <i>Settings → Voice &amp; Video → Camera</i> →
<b>PS5 Capture</b> (720p — Discord asks every camera for 720p, capture
cards included). OBS: add a <i>Video Capture Device</i> → full
<b>1920x1080</b>. ffmpeg:
<code>-f dshow -i video="PS5 Capture"</code>.</span></li>
</ol>
<div class="note" style="margin-top:22px">
<b>Tuning:</b> the <code>gain</code> field adjusts chroma intensity and
<code>shift&nbsp;px</code> fine-aligns the image horizontally (both live,
saved in <code>pscapture.ini</code> next to the exe).
<h3>What you should see in the app log</h3>
<table>
<tr><th>Line</th><th>Meaning</th></tr>
<tr><td><code>driver gia' installato</code></td>
<td>camera already registered — nothing to do</td></tr>
<tr><td><code>driver estratto dall'eseguibile (… byte)</code><br>
<code>driver registrato - la webcam 'PS5 Capture' e' pronta</code></td>
<td>first run: the driver was unpacked from the exe and registered</td></tr>
<tr><td><code>payload dall'eseguibile (… byte)</code></td>
<td>the console payload is on its way to the PS5</td></tr>
<tr><td><code>payload avviato - la PS5 deve mostrare la notifica PSCapture</code></td>
<td>the payload is running on the console</td></tr>
<tr><td><code>porta stream: 9xxx</code> → <code>collegato a …:9xxx</code></td>
<td>stream connected — the pill turns <span class="ok">green: STREAMING</span></td></tr>
</table>
<div class="warn" style="margin-top:18px">
<b>Pill stuck on “IN ATTESA DELLA PS5 — accesa e col jailbreak avviato?”</b><br>
The console is off, not jailbroken yet, or the IP is wrong. The app keeps
retrying every 2 seconds: the moment the console is ready it connects by
itself. Ports to check on the console: <code>9021</code> and
<code>2121</code> must be open.
</div>
<h2 id="daily">Daily use &amp; tuning</h2>
<ul class="plain">
<li>Open <b>PSCapture.exe</b> (UAC → Yes). If the payload is already on the
console (autoloader), the stream starts by itself; otherwise press
<b>Deploy payload</b> once.</li>
<li><b>Stop</b> / closing the app stops the stream — the camera freezes on
the last frame and consumers keep the device listed.</li>
<li><b>gain</b> — chroma strength. <b>Leave it at 1.0</b> (raw) unless
colors look off.</li>
<li><b>shift px</b> — horizontal alignment. <b>Even numbers only</b> (an
odd value inverts the colors). Applies live, saved in
<code>pscapture.ini</code> next to the exe.</li>
</ul>
<h2 id="trouble">Troubleshooting — symptom → fix</h2>
<table>
<tr><th>Symptom</th><th>Cause → fix</th></tr>
<tr><td>Pill stays <code>AVVIO…</code> / <code>IN ATTESA DELLA PS5</code></td>
<td>Console off or not jailbroken, or wrong IP → turn it on, run the
jailbreak, check the IP field</td></tr>
<tr><td>Log repeats <code>PS5 non raggiungibile</code></td>
<td>Same as above — the app retries by itself</td></tr>
<tr><td>No <b>PS5 Capture</b> camera in Discord/OBS</td>
<td>Driver never registered → press <b>Install driver</b>; the log now
reports the real error</td></tr>
<tr><td><code>ERRORE: driver non scrivibile in C:\Program Files\PSCapture (serve admin?)</code></td>
<td>App not elevated → restart PSCapture.exe and accept the UAC prompt</td></tr>
<tr><td><code>ERRORE caricando la dll (err=126)</code></td>
<td>Antivirus quarantined the extracted dll → allow
<code>pscapture.dll</code> in the antivirus, then press
<b>Install driver</b> again</td></tr>
<tr><td>Camera listed but image is black</td>
<td>Stream not started → check the pill, press <b>Deploy payload</b>
and/or <b>START STREAMING</b></td></tr>
<tr><td>Colors look wrong</td>
<td><code>gain</code> was moved → set it back to 1.0 and Apply</td></tr>
<tr><td>Image off-center / black bar</td>
<td>Alignment → tune <code>shift px</code> with even numbers</td></tr>
<tr><td>Discord shows 720p</td>
<td>Discord's engine caps every camera at 720p → use OBS for 1080p</td></tr>
<tr><td>OBS sees the camera, Discord doesn't</td>
<td>Discord was open before the driver install → fully quit Discord
(tray included) and reopen</td></tr>
<tr><td>Anything else</td>
<td>Read <code>pscapture-app.log</code> (next to the exe or in
<code>%TEMP%</code>) and the console log
<code>/data/pscapture.log</code> over FTP</td></tr>
</table>
<h2 id="build">Build from source</h2>
<p style="color:var(--dim)">Sources only — the repo contains no binaries.
Two halves, two toolchains. The full walk-through (toolchain install,
verification, gotchas) is in <a href="BUILD.md">docs/BUILD.md</a>.</p>
<h3>1 · Console payload → <code>pscapture.elf</code></h3>
<pre><span class="c"># needs Docker + the PS5 payload SDK image (prospero-clang; here tagged ps5sdk:18)</span>
docker run --rm -v "&lt;repo&gt;/payload:/payload" -w /payload ps5sdk:18 make</pre>
<h3>2 · PC side → <code>pscapture.exe</code> + <code>pscapture.dll</code></h3>
<p style="color:var(--dim)">Needs MinGW-w64 (<code>gcc</code> +
<code>windres</code>). <b>The order is mandatory</b>: the
<code>.res</code> embeds the driver and the payload as they are on disk.</p>
<pre><span class="c"># from the repo root</span>
cp payload/pscapture.elf pc/ <span class="c"># it gets embedded as-is</span>
cd pc
<span class="c"># 1) the capture-card driver (DirectShow source filter)</span>
gcc -O2 -shared -static -static-libgcc -o pscapture.dll ps5cam.c \
-lole32 -loleaut32 -luser32 -ladvapi32 -lws2_32
<span class="c"># 2) bundle icon + payload + driver into the resource object</span>
windres pscapture.rc -O coff -o pscapture.res
<span class="c"># 3) the single-file app</span>
gcc -O2 -mwindows -o pscapture.exe pscapture.c pscapture.res \
-lws2_32 -lshell32 -ladvapi32 -luxtheme</pre>
<details>
<summary>Why the order? (and the two classic build mistakes)</summary>
<p><b>windres embeds files as they are on disk:</b> if the DLL or the
payload is rebuilt after step 2, the exe still carries the old ones.
Rebuild = DLL → windres → exe, every time.<br>
<b><code>-static -static-libgcc</code> on the DLL is mandatory:</b>
without it Windows can fail to load the driver with the cryptic
“the specified module could not be found” (missing mingw runtime).</p>
</details>
<h2>Requirements</h2>
<table>
<tr><th>Where</th><th>What</th></tr>
@@ -154,7 +299,7 @@
<tr><td>Network</td><td>Both on the same LAN (gigabit is plenty for 1080p30)</td></tr>
</table>
<h2>FAQ</h2>
<h2 id="faq">FAQ</h2>
<details>
<summary>Does it work on firmware versions older than 13.60?</summary>
@@ -182,16 +327,22 @@
</details>
<details>
<summary>The camera lists but stays black / spinner</summary>
<p>Open the app: the status line shows what is happening — not reachable
IP, payload not running, or feeder reconnecting. Everything is logged
in the window; the console side logs to <code>/data/pscapture.log</code>
over FTP.</p>
<summary>How do I uninstall it?</summary>
<p>Close the app, then <code>rundll32 "%ProgramFiles%\PSCapture\pscapture.dll",DllUnregisterServer</code>,
delete <code>C:\Program Files\PSCapture</code>, and optionally delete
<code>/data/pldmgr/payloads/pscapture/</code> on the console so the
autoloader stops starting the payload.</p>
</details>
<footer>
PSCapture — bring your PS5 screen anywhere on your LAN, no card, no cloud.
<br><b>by fstat13</b> &middot; source-available. Built for the homebrew community. <span class="ok">Play responsibly.</span>
<br><br>
Docs: <a href="GUIDE.md">fool-proof guide (md)</a> &middot;
<a href="BUILD.md">build from source (md)</a> &middot;
<a href="INSTALLER.md">what the installer does inside</a> &middot;
<a href="REVERSE_ENGINEERING.md">reverse engineering</a> &middot;
<a href="ENGINEERING_LOG.md">engineering log</a>
</footer>
</div>