Commit Graph

19 Commits

Author SHA1 Message Date
89f590480f Add ESP32 Joy-Con bridge serial reader
Adds app-side support for the ESP32-WROOM-32 Joy-Con bridge over USB
serial. The ESP32 pairs with the Joy-Con via Bluetooth Classic (using
Bluepad32), parses input reports, and streams an 11-byte wire protocol
frame at 60 Hz over the CP2102's USB-CDC serial connection.

ControllerManager now auto-detects known USB-serial chips (CP2102,
CH340, Espressif native USB) by VID/PID, opens the port at 115200 8N1
via usb-serial-for-android, and parses incoming frames into the same
dispatchButton / onAnalogEvent pipeline used by all other controller
paths. Frame format: [0xA5 sync] [seq] [btns_lo] [btns_hi] [dpad hat]
[lx] [ly] [rx] [ry] [flags] [XOR crc8].

Verified stable for 10+ minutes with zero disconnects on the Samsung
Fold 6 — the 8BitDo USB adapter wedged within 2 minutes on the same
phone. Full firmware control eliminates the OTG selective-suspend issue
that plagued the adapter path.
2026-04-12 15:57:30 -04:00
2154f7fd3c Merge feature/joycon: USB gamepad support + stability fixes
Adds USB host-mode game controller support, focused on the NES Joy-Con
via the 8BitDo USB Wireless Adapter 2 in PS-Classic mode, the only
adapter mode the Samsung Fold 6 kernel will bind as a real gamepad.
Includes a Test Controller screen under Settings with live button/axis
indicators, a USB device enumeration view, and a scrolling raw event
log for debugging.

Also ships a batch of stability fixes discovered during controller
bring-up: white-screen-on-USB-detach (missing configChanges for
keyboard/navigation tore down MainActivity when the gamepad
disappeared), OOM during in-game input delivery (cover-art bitmaps
decoding at full resolution), and a FLAG_KEEP_SCREEN_ON on GameScreen
to keep the system out of the deeper sleep states that aggravate OTG
selective-suspend.

Captures a design direction for replacing the 8BitDo adapter
entirely with a DIY ESP32-WROOM-32 Joy-Con bridge that re-advertises
as a BLE HID gamepad. Not implemented yet — docs only.
2026-04-11 19:49:21 -04:00
d496902e57 Move JOYCON_HANDOFF.md into docs/ and mark it historical
The handoff doc was the starting point for this session's controller
work — a list of open questions about getting a Joy-Con working on the
Samsung Fold 6 via the 8BitDo adapter. Those questions have been
answered (the working path is PS-Classic mode) and the adapter approach
is being replaced entirely by a DIY ESP32 bridge. Move the doc into
docs/ so it's not sitting at the repo root, rename it to reflect that
it's archaeology rather than an active handoff, and add a banner at
the top pointing at joycon-esp32-bridge.md for the current plan.
2026-04-11 19:47:03 -04:00
155f0f209b Lock in Path A and hardware choice for Joy-Con ESP32 bridge
Path A (fully wireless: BT Classic host + BLE HID peripheral) is the
chosen architecture. Bridge will be self-powered off a LiPo in a
3D-printed case and sit next to the phone — no cables to the phone at
all. Hardware picked: ESP32-WROOM-32 USB-C dev board (original ESP32
silicon, has BT Classic, CP2102 onboard). Path B (USB-CDC serial) kept
in the doc as a fallback if dual-mode BT coexistence proves painful
during bring-up.
2026-04-11 19:45:38 -04:00
2e1c80b7c2 Keep screen on during gameplay + ESP32 bridge design notes
GameScreen: add FLAG_KEEP_SCREEN_ON while a game is active. Keeps the
system out of the deeper sleep states that aggravate OTG selective-suspend
on Samsung, where the 8BitDo adapter otherwise drops every 60-120 seconds.
Cleared on dispose so other screens are unaffected.

docs: drop a design sketch for a DIY Joy-Con bridge built on an original
ESP32 or Raspberry Pi Pico W. Covers the two architectures (fully
wireless via BT Classic host + BLE peripheral, or wired hybrid via
BT Classic host + USB-CDC serial), the Joy-Con init subcommand
requirement, a proposed wire protocol for the serial path, and the
changes we'd make app-side to consume it. Also captures the dongle
rabbit hole we went through so future-us doesn't repeat the same
experiments.

Notes that Bluepad32 already implements BT Classic HID host with
first-class Joy-Con support on original ESP32 and Pico W, which
shrinks the firmware side considerably. Also warns explicitly against
ESP32-S3 for this project — despite being the obvious "newer, better"
ESP32, it is BLE-only and cannot pair with Joy-Cons (BR/EDR-only).
2026-04-11 19:35:31 -04:00
31f7bd8904 Fix white-screen on USB detach and OOM from cover art bitmaps
Three independent stability fixes that surfaced while testing the Joy-Con
controller path:

1. Manifest: add keyboard|keyboardHidden|navigation|uiMode to MainActivity's
   configChanges. Without these, unplugging the OTG cable mid-game triggered
   a navigation/keyboard configuration change that destroyed and recreated
   the activity. The new activity instance never re-established the emulator
   surface cleanly, leaving a white screen, and Samsung Freecess then froze
   the seemingly-idle process.

2. GameCard: cap Coil's image decode at 384px. LibRetro thumbnail PNGs are
   often 1500x2000+, which burns ~12 MB of bitmap per card. With 30 visible
   tiles that's hundreds of MB and was OOM-ing the app during in-game input
   delivery (NewObjectV in nativePollOnce → JNI abort).

3. CoverArtManager: try (World) as a fallback region tag and add a cleaned-
   title-plus-common-region cascade. LibRetro stores Super Mario Bros. as
   '(World).png' but most US dumps tag the ROM '(U)', so the previous
   expansion table only tried (USA)/(USA, Europe) and missed it.
2026-04-11 17:33:29 -04:00
da5f3a912b Add USB controller support with NES Joy-Con via 8BitDo adapter
Wires up ControllerManager to handle the 8BitDo USB Wireless Adapter 2 in
PS-Classic mode (Select+Down 3s), which is the only adapter mode the
Samsung Fold 6 kernel actually binds. Adds a Test Controller screen
(reachable from Settings) showing detected input devices, USB host
enumeration, live pressed-button chips, axis readout, and a scrolling raw
event log for debugging.

Per-device fixups for the adapter's PS-Classic identity (Sony 0x054C/0x0CDA):
treat ABS_X/Y as the dpad (no real analog stick), remap BTN_TL2/TR2 to
Select/Start so the Joy-Con's minus/plus buttons reach cores, and remap
BTN_C to FACE_BOTTOM so the NES Joy-Con's bottom face button works as
NES B / SNES B / PS Cross.

Also includes a manifest USB intent filter and a vendor-spec XInput
claim/reader path retained for future XInput-mode adapters, dpad routing
through dispatchButton so buttonMappingManager applies to dpad input, and
a concurrency fix in cover-art fetching (parallelism 8->2 + per-fetch
try/catch) to stop OOM crashes during launch.
2026-04-11 17:13:17 -04:00
7aed3ecbaf Merge feature/genisis: Genesis emulation with bundled Genesis Plus GX core 2026-04-11 08:55:49 -04:00
447bc20b61 Add Genesis emulation support with bundled Genesis Plus GX core
Bundles genesis_plus_gx_libretro_android.so (~12 MB) as an asset and
wires up GenesisCore with 3/6-button Genesis mappings (A/B/C/X/Y/Z/
Mode/Start/D-pad) following Genesis Plus GX's default retropad layout.
2026-04-10 20:19:15 -04:00
bf346db085 Merge feature/snes: SNES emulation with bundled Snes9x core 2026-04-10 20:03:02 -04:00
a06390cac2 Add SNES emulation support with bundled Snes9x core
Bundles snes9x_libretro_android.so (~2.8 MB) as an asset and wires up
SnesCore with full SNES button mappings (B/A/Y/X/L/R/Select/Start/D-pad).
2026-04-10 20:02:59 -04:00
a12409dde2 Merge feature/nes: NES emulation, search, favorites, save state delete 2026-04-10 19:36:28 -04:00
2e41f1e6ea Add delete option for save state slots
Add deleteState method to EmulatorCore interface and implement in
Ps1Core and NesCore. Delete button (trash icon) in the in-game
Save/Load menu removes the state file and its screenshot, then
refreshes the slot list.
2026-04-10 19:36:04 -04:00
981ac2eed9 Add search, favorites tab, and persistent favorites
Replace static console filter with swipeable tabs (All / Favorites /
per-console) and a collapsible search icon in the app bar. Persist
favorites via SharedPreferences keyed by ROM path. Display titles are
now cleaned (region tags stripped) for better UX while raw filenames
are preserved for cover art lookups. Sort games alphabetically and
fetch cover art in parallel (8 concurrent) for faster initial load.

Also fix PS1 controller setup so it works with both new games and save
states: pcsx_rearmed needs retro_set_controller_port_device called at
a specific point inside loadCore (between callbacks and get_system_info)
which FCEUmm crashes on. Added a "pending controller device" mechanism
that the Kotlin core can pre-set before nativeLoadCore. Save states are
now loaded BEFORE start() so the game's first frame already has the
restored state, avoiding the "controller removed" detection race.
2026-04-10 19:33:25 -04:00
d502304d95 Add NES emulation support with bundled FCEUmm core
Implement NesCore with FCEUmm/Nestopia/Mesen libretro core support.
Generalize native frontend to handle cores that require ROM data in
memory (need_fullpath=false) and move PS1-specific config out of C++
into Ps1Core. Bundle both core .so files as APK assets with automatic
extraction. Fix cover art fetching for GoodNES-named ROMs by expanding
region codes (U)->(USA, Europe) to match LibRetro thumbnail naming.
2026-04-09 21:34:49 -04:00
547d1501c0 Add automatic cover art fetching from LibRetro thumbnails
Downloads box art from libretro-thumbnails GitHub repos for all
supported consoles (PS1, NES, SNES, N64, Genesis, PS2). Art is
fetched in the background on first scan and cached locally. Also
fixes multi-track .bin files showing as separate game entries.
2026-04-09 21:09:26 -04:00
0b4e408d18 Add save state slots with per-game saves, screenshots, and launch menu
Save states now support 5 slots per game with per-game directories,
screenshot thumbnails captured via PixelCopy, and a launch menu that
shows existing saves on game start (continue/new game flow). In-game
menu combines save and load into a single overlay. Also adds button
remapping, controller overlay visibility settings, and preferences
management.
2026-04-09 20:46:21 -04:00
14045accb5 Add display mode options: stretch, aspect ratio, and integer scaling
Renders the emulator framebuffer into a calculated sub-rect with
nearest-neighbor scaling and black bars, driven by the core's
reported aspect ratio. Adds a cycle button in the game HUD and
a display mode setting in the settings screen.
2026-04-08 20:48:52 -04:00
39e3f8b7c0 Initial commit: multi-platform emulator with PS1 support
Jetpack Compose app with adaptive layouts (phone/tablet/foldable) using
Window Size Classes. Integrates a C++ libretro frontend via JNI for
actual PS1 emulation using pcsx_rearmed, with AAudio output and
ANativeWindow rendering.

- Emulation core architecture with interface for NES, SNES, N64,
  Genesis, PS1, PS2 (PS1 implemented, others placeholder)
- Touch controller overlay with D-pad (diagonal support), face buttons,
  shoulders, and analog sticks
- Bluetooth/USB controller detection and input mapping
- Customizable controller layout editor with drag-to-reposition
- Game library with auto-scan of /sdcard/Games/ subfolders
- Auto-import of libretro core .so from /sdcard/Games/cores/
- Save states and SRAM persistence
2026-04-08 20:34:37 -04:00