This is the RP2040-zero/Raspberry Pi Pico 2W standalone version of remotejoy, with the video output function removed and enabling control via external controllers. By combining it with the external output function of the PSP-2000/3000, remote play using a TV screen is possible without a PC. Does not require psplink.prx or usbhostfs.prx on the PSP side.
The repository contains the PSP plugin and two input firmware options:
| Firmware | Input | Configuration | Players |
|---|---|---|---|
| Pico 2 W | Bluetooth via joypad-os | Wi-Fi Web portal | 1P and optional POPS 2P |
| RP2040-Zero | Wired PS1/PS2 controllers | USB Web portal | 1P and PS1 multitap POPS 2P |
Both firmwares support mapping profiles, configurable RGB indication, multilingual browser configuration, and JSON mapping import/export; the JSON format is shared, so profiles can be moved between them.
- The Pico 2 W firmware is configured over its Wi-Fi access point and also supports persistent Bluetooth controller pairing.
- The RP2040-Zero firmware is configured over USB: holding L1 + L2 + D-pad Down
on the player 1 controller at power-on starts the Web configuration mode,
in which the RP2040-Zero appears to a PC as a USB network adapter
(
http://192.168.7.1/). It also supports a real Namco GunCon and the Pop'n Music / Guitar Freaks controllers.
See each firmware's README for hardware and setup instructions.
Install PSPSDK/VitaSDK and ensure psp-config is available, then run:
makeThe output is remotejoy-minus.prx.
To enable the separate player-2 stream for two-player POPS titles:
make clean
make RJM_ENABLE_POPS_2P=1See POPS_2P.md for the POPS controller-assignment behavior and known compatibility details.
To enable POPS GunCon emulation, for gyro aiming from the Pico 2 W firmware or a real GunCon on the RP2040-Zero firmware (see POPS GunCon emulation):
make clean
make RJM_ENABLE_POPS_AIM=1It can be combined with RJM_ENABLE_POPS_2P=1. On the PSP LCD the plugin reads
POPS's HOME-menu screen size (Original, Normal, Zoom, Full) and places the
crosshair and the GunCon correction for the selected mode automatically. The
rectangle below is only a fallback until POPS is found; its default is the
"Original" placement (320x240 at 80,16 on the 480x272 LCD):
make RJM_ENABLE_POPS_AIM=1 \
RJM_POPS_AIM_SCREEN="RJM_POPS_AIM_SCREEN_X=112 RJM_POPS_AIM_SCREEN_W=256"On TV out the picture is assumed to be scaled uniformly to fit the output and
centred. The TV screen size (XMB: Connected Display Settings > Screen Size) is
read from the system registry: with 4:3 the picture spans the whole width,
with 16:9 it is pillarboxed. Add RJM_POPS_AIM_TV_4_3=1 (or =0) to
RJM_POPS_AIM_SCREEN to force it. A measured TV rectangle can be given with
RJM_POPS_AIM_TV_X, RJM_POPS_AIM_TV_Y, RJM_POPS_AIM_TV_W, and
RJM_POPS_AIM_TV_H in the same way.
For a diagnostic plugin that writes ms0:/rjm_standalone.log:
make clean
make RJM_ENABLE_LOG=1Normal builds do not write a log file.
-
Copy
remotejoy-minus.prxto the PSPsepluginsdirectory. -
Add the following line to
VSH.txt,GAME.txt, orPOPS.txtas needed:ms0:/seplugins/remotejoy-minus.prx -
Enable the plugin from the CFW recovery/plugin menu.
Do not enable remotejoy.prx or RemoteJoyLite.prx at the same time; they use
the same PSP USB/controller facilities and conflict with this plugin.
When built with RJM_ENABLE_POPS_2P=1, loading the plugin from VSH/GAME is
normally sufficient for the plugin to reserve itself for POPS. Some CFW setups
may also require the entry in POPS.txt.
The Bluetooth/Web-config firmware is in pico2w/. Its
UF2 output is:
pico2w/build/remotejoy_minus_pico2w.uf2
The wired PS1/PS2 firmware is in rp2040-zero/.
Its UF2 output is:
rp2040-zero/build/remotejoy_minus_rp2040.uf2
The same UF2 contains the Web configuration mode; no separate configuration
build is needed. It builds TinyUSB's NCM driver from
rp2040-zero/tinyusb_patch/, which
carries a fix needed by Windows 11.
The optional P2 protocol keeps the original RemoteJoy event types unchanged and adds a separate player-2 button, analog, and connection-status stream. Player 1 remains the normal remotejoy-minus input. Player 2 is injected through the POPS port-B hook only while a second controller is connected.
POPS's HOME-menu controller assignment remains in control of the normal input. For games requiring PS1 L2/R2, configure the POPS controller assignment as described in POPS_2P.md.
The wired firmware has been tested with the SCPH-1070 PS1 multitap. The SCPH-10090 PS2 multitap did not respond to its controller-port-only bitbang wiring.
With RJM_ENABLE_POPS_AIM=1, the plugin can present POPS controller port 1 to
the PS1 game as a Namco GunCon, so GunCon-compatible PS1 games can be played
with a gyro-equipped controller. No per-game patch is needed.
- The Pico 2 W firmware sends an absolute aim position while the active mapping profile has GunCon mode enabled (see pico2w/README.md).
- The RP2040-Zero firmware forwards a real Namco GunCon connected to its player 1 controller connector, passing the gun's own X/Y coordinates unchanged (see rp2040-zero/README.md).
- Without aim data, port 1 stays the normal digital pad.
- POPS emulates the PS1 controller protocol with a per-port state block in PSP
scratchpad RAM. While aim data arrives, the plugin sets port 1's controller
ID to the GunCon (
0x63) and supplies the gun X/Y coordinates. When aiming stops, the digital pad (0x41) is restored. The block is only modified when its contents match the expected POPS layout. - Off-screen aim is reported as the GunCon "no light" value (X=01h, Y=0Ah).
- Buttons come from the normal remotejoy-minus input. On the GunCon, the trigger is Circle, A is START, and B is Cross.
- GunCon games hide their own cursor, so the plugin draws a small crosshair on the PSP screen while aiming on screen. Holding START + Cross (GunCon A + B) for two seconds shows or hides it. With a real gun the crosshair can only follow over lit parts of the picture: the gun reports no position over dark parts, so there the crosshair stops or disappears.
- A real gun cannot see where it points over a dark part of the picture. When
its trigger is pulled there, the plugin holds the trigger back, inverts the
colours of the shown frame so that the dark parts turn bright, and passes
the trigger on together with the position the gun then reports. If no light
comes within 100 ms, the gun points off screen and the shot goes through as
"no light" (reload). For 250 ms after each shot, "no light" is replaced by
the shot position, so games that flash the screen on a shot (such as Time
Crisis) still read where the shot went. Build with
RJM_POPS_AIM_FLASH=0passed inRJM_POPS_AIM_SCREENto turn the flash off;RJM_POPS_AIM_FLASH_WAIT_MSandRJM_POPS_AIM_SHOT_HOLD_MSset the two times. - Only player 1 is converted. In POPS 2P, player 2 remains a digital pad.
Tested with Time Crisis and Biohazard Gun Survivor.
This implementation uses the PSPLINKUSB/RemoteJoy controller protocol and a USBHostFS-compatible endpoint layout. The PSP input-injection logic derives from the original RemoteJoy approach and is reduced to input-only operation.
RemoteJoyLite by Kethen was used as a technical reference for the standalone USB PRX structure, controller hooks, and POPS behavior.
The firmware uses Raspberry Pi Pico SDK and TinyUSB. The Pico 2 W build also uses joypad-os and BTstack.
Unless otherwise noted, remotejoy-minus is distributed under the same BSD
license as PSPLINKUSB. Third-party files retain their respective licenses; see
THIRD_PARTY_NOTICES.md.
This tree contains code and protocol structure derived from PSPLINKUSB
RemoteJoy/usbhostfs, so its copyright notice, license conditions, and
disclaimer must be preserved when redistributing source or binaries.
remotejoy.h retains its original license header. When distributing firmware,
also comply with the licenses of Pico SDK, TinyUSB (including the patched
rp2040-zero/tinyusb_patch/ncm_device.c), joypad-os, BTstack, and the
vendored pico-examples/MicroPython components. Binary distributions should
include the license and notice files identified in THIRD_PARTY_NOTICES.md.