Skip to content

feat(vita): svc mailbox + video plane + audio over WiFi TCP#169

Draft
doodlewind wants to merge 2 commits into
feat/pknt-wirefrom
feat/vita-svc-wifi
Draft

feat(vita): svc mailbox + video plane + audio over WiFi TCP#169
doodlewind wants to merge 2 commits into
feat/pknt-wirefrom
feat/vita-svc-wifi

Conversation

@doodlewind

Copy link
Copy Markdown
Collaborator

Part 2/2 of the Vita networking series (stacked on #168). The Vita host grows ops 30–38 — the entire svc/video/audio family — over the PKNT wire.

Architecture

main/render thread          pjs-net (supervisor)         pjs-net-tx      pjs-audio
──────────────────          ────────────────────         ──────────      ─────────
svcOpen ── spawn once ────▶ host.txt / PKDB beacon
svcPoll ◀─ line queue ◀──── TCP connect + handshake
svcSend ──▶ mpsc ─────────────────────────────────────▶ write_all
loadImgFile ◀ LRU cache ◀── rx: CTRL→queue FILE→cache
videoTick ◀── RamStream ◀──     SLOT/CHUNK/MARK→ring
  │ stage newest slot,          PING→PONG
  │ top up PCM ring ──────────────────────────────────────────────────▶ sceAudioOutOutput
  ▼                          on error: mark ended,                       (BGM 44.1 kHz,
vid::present() in the        1 s backoff, rediscover                      blocking)
GPU-idle window
  • Main thread never blocks on the network — ops pop queues / short mutexes (worst case one ~130 KiB slot memcpy).
  • vid.rs is the PSP reader over RamStream::buf() — same epoch/lap/seq validation, same stage-then-present split. Runtime::render = begin_frame → vid::present → render_over; new graphics::update_texture_in_place rewrites plane pixels without the per-frame allocate+GXM-drain the recycle path would cost at 24 fps.
  • audio.rs = the PSP design on sceAudioOut (SPSC ring ~743 ms, starvation sleeps, main-thread port release — the channel-leak lesson, ×1/×2/×4 upsampler).
  • Graceful everywhere Vita3K is blind: net::init() failure is remembered and final → svcOpen false → connect screen; no crash paths in emulator runs.
  • debugStats (38) wired with a net section + bundle FNV-1a64 (stale-embed tripwire) — the throughput instrument for real-HW tuning.

Validation

  • Full release VPK build with the vita toolchain (all new modules compiled into im-main.vpk).
  • Vita3K e2e cursor-main 5/5 byte-exact — new modules are dormant without svcOpen, zero UI regression.
  • Wire/ring correctness is feat(contracts): PKNT wire protocol + RAM .pkst assembler #168's cargo suite (incl. the byte-exact golden reconstruction).
  • Transport itself is real-hardware-verified only (Vita3K has no sceNet); the checklist ships in the follow-up docs PR.

🤖 Generated with Claude Code

doodlewind added a commit that referenced this pull request Jul 23, 2026
…cklist

The companion document for the PKNT wire (#168) and the Vita svc/video/
audio host (#169): why one ordered TCP connection, why the RAM ring is a
byte-exact .pkst file image, the thread/ownership diagram, the GPU-idle
present discipline, and the real-hardware verification checklist (Vita3K
has no network stack, so the transport only proves itself on a device).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@doodlewind
doodlewind force-pushed the feat/vita-svc-wifi branch from 5c377ca to f7e6c51 Compare July 23, 2026 12:50
doodlewind added a commit that referenced this pull request Jul 23, 2026
…cklist

The companion document for the PKNT wire (#168) and the Vita svc/video/
audio host (#169): why one ordered TCP connection, why the RAM ring is a
byte-exact .pkst file image, the thread/ownership diagram, the GPU-idle
present discipline, and the real-hardware verification checklist (Vita3K
has no network stack, so the transport only proves itself on a device).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@doodlewind
doodlewind force-pushed the feat/vita-svc-wifi branch from f7e6c51 to ec84d24 Compare July 23, 2026 12:55
The Vita host registered only ops 1–29: no svc channel, no video plane, no
audio, no network stack. This implements the whole family (ops 30–38) over
the PKNT wire protocol:

- net.rs: sceNet init confined to one function (module load, 1 MiB static
  pool, sceNetCtlInit; failure is remembered and final — Vita3K has no
  network stack, so svcOpen stays false and emulator e2e never regresses);
  everything after rides std::net over the newlib shims. Supervisor thread
  (host.txt override → UDP beacon discovery → connect + handshake → rx
  loop: CTRL → line queue, FILE → 6 MiB LRU cache, SLOT/CHUNK/MARK →
  RamStream, PING → PONG) + tx thread draining an mpsc channel. On
  disconnect the ring is marked ended, 1 s backoff, rediscover. The 60 fps
  main thread never blocks: its ops pop queues and take short-held mutexes.

- svc.rs (ops 30–33): PSP guest semantics verbatim — non-blocking svcOpen
  the app's connect pump retries, batched svcPoll, side files resolved from
  the proactive-push cache so the synchronous loadImgFile never waits on
  the network.

- vid.rs (ops 34–37): the PSP vid.rs reader over RamStream::buf() — same
  epoch/lap/seq-validation logic, same stage-then-present split, minus the
  IO budget (reads are memcpys). present() commits in the GPU-idle window:
  Runtime::render now runs begin_frame → vid::present → render_over, and
  graphics grows update_texture_in_place (rewrites the existing vita2d
  texture's pixels — the register/recycle path would allocate + drain GXM
  once per presented frame at 24 fps). The GE race discipline, GXM edition.

- audio.rs: the PSP design with sceAudioOut — BGM port at 44.1 kHz, SPSC
  ring (~743 ms), starvation sleeps, port opened AND released on the main
  thread (the channel-leak class of bug). Integer ×1/×2/×4 upsampler keeps
  PSP-profile 22.05 kHz streams playable.

- stats.rs + debugStats (op 38): PSP shape + a net section (rxBytes/
  txBytes/reconnects/slotsRx/fileEvicts); build.rs bakes the FNV-1a64
  bundle hash for the stale-embed tripwire.

Validated: full release VPK build (im-main) with the vita toolchain;
Vita3K e2e cursor-main 5/5 byte-exact (new modules dormant without svcOpen).
The wire/ring logic itself is covered by the engine/core tests (#168);
transport verification is real-hardware only (Vita3K has no sceNet).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
doodlewind added a commit that referenced this pull request Jul 23, 2026
…cklist

The companion document for the PKNT wire (#168) and the Vita svc/video/
audio host (#169): why one ordered TCP connection, why the RAM ring is a
byte-exact .pkst file image, the thread/ownership diagram, the GPU-idle
present discipline, and the real-hardware verification checklist (Vita3K
has no network stack, so the transport only proves itself on a device).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@doodlewind
doodlewind force-pushed the feat/vita-svc-wifi branch from ec84d24 to a90ceb0 Compare July 23, 2026 13:04
First hardware bring-up caught it immediately: the Mac's DHCP lease moved,
the ux0:data/pocketjs/host.txt override pointed at a dead address, and
because the override took precedence unconditionally the transport retried
it forever — beacon discovery could never rescue the session. Connect
failures now alternate the next discovery round onto the beacon listener,
so a stale override degrades to broadcast discovery instead of wedging.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
doodlewind added a commit that referenced this pull request Jul 23, 2026
…cklist

The companion document for the PKNT wire (#168) and the Vita svc/video/
audio host (#169): why one ordered TCP connection, why the RAM ring is a
byte-exact .pkst file image, the thread/ownership diagram, the GPU-idle
present discipline, and the real-hardware verification checklist (Vita3K
has no network stack, so the transport only proves itself on a device).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant