Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🎮 RetroXR

One front-end, every retro system, anywhere — Quest 3, Android phone & tablet, Android TV

Status Platform libretro Languages License

A modern, lightweight retro front-end built around the libretro core ecosystem (Hatari, MAME, Snes9x, Genesis Plus GX, Mupen64Plus, Beetle PSX HW, …) with a Compose UI tuned for VR panel apps and classic 2D Android.


⚠️ This is a work-in-progress. Most features below work — some are fragile, a few are scaffolded only. Read the Status section before installing.

✨ Features

📚 Library

  • 🎯 107 systems / 200+ libretro cores catalogued (Atari ST, Amiga, MAME, C64, ZX Spectrum, NES, SNES, Mega Drive, PSX, N64, Saturn, Dreamcast, GBA, DS, PSP, 3DS, …)
  • 🌍 8 languages (FR, EN, ES, DE, IT, PT, JA, ZH)
  • 👤 User profiles (per-profile saves, mappings, library)
  • 🖼️ Cover scraper with cascade fallback (boxart → title screen → procedural placeholder), persistent miss cache
  • 🔍 Cross-system search + sort (alphabetical / recently played / favorites / most played / recently added)
  • 📌 Pin systems to top of home grid, hide unused ones
  • 📊 Battery + Wi-Fi widgets in the home top bar
  • 🤖 Pixel-art mascot in the corner (taps cycle helpful tips)

🚀 Game flow

  • 📥 In-app Core Manager (downloads .so from libretro buildbot)
  • 📁 ROM scanner via Storage Access Framework with multi-disc auto-detection (PSX, Amiga, …)
  • 💾 BIOS importer (file or folder picker) → files/system/
  • 🔍 Long-press game → Rename / Favorite / Delete
  • 🎚️ Per-game core override (persisted)
  • 📸 Screenshots gallery with full-screen preview, share, delete
  • 🛌 Auto-resume: best-effort autosave on activity pause, prompt at relaunch
  • 🛡️ Onboarding wizard (Cores → Sources → BIOS) on first run

🎮 In-game

  • 🕹️ Hardware controllers detected & classified (Quest Touch / Xbox / DualShock / DualSense / 8BitDo / Switch Pro)
  • 🔁 Hot-swap (plug/unplug live during play)
  • ⌨️ Per-controller remapping (vendor-product keyed, persistable JSON)
  • 📱 Touch overlay (auto-shown when no physical controller)
  • ⏸️ In-game menu: Resume / Screenshot / Reset / Save states (8 slots with thumbnails) / Speed (¼×–4× + frame advance) / Rewind (60-snap ring buffer) / Cheats (.cht import) / Disk control / Core options / Quit
  • 📺 Aspect ratio: Fit / Fill / Stretch / 1× / 2× / 4:3 CRT (per-game, persisted)
  • 🎨 Post-FX shaders (Compose-side): Off / Scanlines / Phosphor / Heavy CRT / Soft Glow
  • 🖼️ Bezel overlay: None / CRT / Arcade cabinet / Handheld
  • ⚡ Performance overlay (FPS / frame ms / audio underruns)
  • 🔉 Dedicated audio thread with ring buffer (no emu-loop stalls)
  • 🥽 Auto-pause on activity pause / window focus loss

🥽 XR / MR

  • ✅ Niveau 1 — App is declared MR-aware (com.oculus.feature.PASSTHROUGH, environmentBlendMode=alpha_blend); Quest can render the 2D panel over your real space via the system passthrough.
  • ⚠️ Niveau 2 — Native OpenXR session with XR_FB_passthrough + quad layer is integrated (animated test-pattern quad, real-room background). Whether Quest's compositor accepts the immersive transition depends on launch context (works best from Quest Library; Intent launch from a 2D activity may be paused). See cpp/openxr_session.cpp.

🧠 Tech

  • Kotlin + Jetpack Compose for UI
  • Native C++17 via NDK 27 with a custom libretro bridge (dlopen any .so, pixel-format conversion 0RGB1555 / RGB565 / XRGB8888, audio batch, input poll, retro_serialize ↔ ring buffer for rewind, save state thumbnails)
  • OpenGL ES 3 path for cores that request XR_HW_RENDER (Beetle PSX HW, Mupen64Plus, PPSSPP, Flycast)
  • OpenXR via Khronos loader (Maven org.khronos.openxr:openxr_loader_for_android) for the Niveau 2 immersive session
  • Room v4 DB (profiles, games, save states, cheats, controller mappings, cover misses)
  • Coil for cover loading with custom URL cascade

📦 Install (sideload on Quest 3 / Quest 3s / Quest Pro)

  1. Enable Developer Mode in the Meta Horizon mobile app
  2. Connect your Quest via USB-C, accept the RSA prompt inside the headset
  3. Download the latest APK from the Releases page
  4. Install:
    adb install -r RetroXR-vX.Y.Z.apk
  5. Launch from Library → Unknown Sources → RetroXR

On Android phone, tablet, Android TV

Same APK. Sideload via adb install, or open the file in any file manager. The app declares category.LAUNCHER + LEANBACK_LAUNCHER so it appears in both the standard launcher grid and Android TV home rows.

🛠️ Build from source

Requirements:

  • Android Studio Hedgehog (2023.1) or newer
  • Android SDK 34
  • NDK 27.2.12479018 (auto-installed by Gradle on first build)
  • CMake 3.22.1 (auto-installed)
  • JDK 17
git clone https://github.com/Oli97430/retroxr.git
cd retroxr
./gradlew assembleDebug
adb install -r app/build/outputs/apk/debug/app-debug.apk

The first build downloads ~1.5 GB (NDK + CMake + Gradle + AGP + Compose). Subsequent builds are seconds.

🧭 Status

Area State
2D galerie / library / search / sort / profiles ✅ Stable
ROM scanner (SAF) + multi-disc M3U ✅ Stable
Cover scraper + miss cache ✅ Stable
Atari ST emulation (Hatari) ✅ Verified end-to-end
In-game menu + save states + thumbnails + rewind + cheats + disk-control ✅ Code complete
HW context (Beetle PSX HW, Mupen64, PPSSPP) ⚙️ Code in place, needs in-headset testing
Per-controller remap UI ✅ Functional
Bezel / shaders / aspect ratio ✅ Functional
Audio dedicated thread + ring buffer ✅ Stable
Niveau 1 MR (passthrough panel) ✅ Manifest declared, Quest does the rest
Niveau 2 MR (immersive OpenXR + quad) 🟡 Integrated, fragile (Quest pauses occasionally — depends on launch context)
AR Niveau 3 (3D arcade-cabinet scene) ❌ Not started
Netplay ❌ Not started
RetroAchievements ❌ Not started (local trophy stub only)
Cloud save sync ❌ Not started
CRT/HQ4x real GLSL shaders ❌ Compose-side approximations only

🗺️ Roadmap

Short term:

  • Connect HW core path (Beetle PSX HW) end-to-end with in-headset validation
  • Real shader chain (HQ4x, xBR) via GLSurfaceView
  • Save state import/export (SAF)
  • Cloud sync via Google Drive / WebDAV

Medium term:

  • RetroAchievements full integration
  • Netplay LAN p2p
  • Mixed-Reality Niveau 3 (3D cabinet over passthrough)
  • Vulkan path for Citra / Dolphin / PPSSPP

Production:

  • Tests (zero today)
  • Release build with R8 + signing
  • Crashlytics
  • GitHub Actions CI
  • F-Droid manifest

⚖️ Legal & ROMs

RetroXR is a front-end. It distributes no ROMs and no BIOS files. Many systems require a BIOS that you must own and provide yourself (Atari ST / TOS, Amiga / Kickstart, PSX / scph...bin, Saturn / saturn_bios.bin, Neo Geo / neogeo.zip, etc.).

Where to find legal ROMs (homebrew / public domain)

The in-app "Where to find ROMs" section (globe 🌐 icon on the home screen) links to 12 curated legal sources: Internet Archive Software Library, Itch.io free games, PICO-8 BBS, TIC-80 Surf, ZXArt (Spectrum PD), CPCwiki PD, Pouët, Atari Mania PD, Macintosh Garden, Aminet, libretro thumbnails, etc.

Dumping ROMs you don't own is illegal in most countries. RetroXR will not help you do that.

📂 Project structure

RETRO XR VR/
├── app/
│   ├── src/main/
│   │   ├── java/com/retroxr/
│   │   │   ├── MainActivity.kt           ← Compose host, Idle tracker
│   │   │   ├── data/
│   │   │   │   ├── catalog/              ← 107 systems + brand colors + thumbnails folders + HW hints
│   │   │   │   ├── db/                   ← Room v4 (entities, daos, AutoMigration 3→4)
│   │   │   │   ├── OnboardingPrefs.kt
│   │   │   │   ├── SystemPrefs.kt        ← Pinned / hidden systems
│   │   │   │   └── GameMetadata.kt       ← Offline metadata catalog
│   │   │   ├── emulator/
│   │   │   │   ├── EmulatorActivity.kt   ← run loop, lifecycle, HW/SW switching
│   │   │   │   ├── LibretroCore.kt       ← Kotlin facade over JNI
│   │   │   │   ├── GLEmulatorView.kt     ← HW path (GLSurfaceView)
│   │   │   │   ├── InGameMenu.kt
│   │   │   │   ├── BezelOverlay.kt
│   │   │   │   ├── CrtOverlay.kt
│   │   │   │   ├── AudioPump.kt          ← dedicated thread + ring buffer
│   │   │   │   ├── RewindBuffer.kt
│   │   │   │   ├── AspectRatio.kt
│   │   │   │   └── …
│   │   │   ├── input/
│   │   │   │   ├── ControllerManager.kt  ← detect + classify
│   │   │   │   ├── ControllerMapping.kt  ← persistable JSON
│   │   │   │   └── LibretroButtons.kt
│   │   │   ├── library/                  ← RomScanner, BiosImporter, CheatParser
│   │   │   ├── cores/CoreManager.kt      ← libretro buildbot downloader
│   │   │   ├── ui/                       ← Compose screens, theme, components
│   │   │   └── …
│   │   ├── cpp/
│   │   │   ├── libretro_bridge.cpp       ← dlopen + JNI exports + frame conversion
│   │   │   ├── libretro_callbacks.cpp    ← env handler (~12 retro env opcodes)
│   │   │   ├── libretro_gl.cpp           ← HW context, FBO, blit shader
│   │   │   ├── openxr_session.cpp        ← Niveau 2 immersive session
│   │   │   └── include/libretro.h        ← subset header
│   │   ├── res/values{,-fr,-es,-de,-it,-pt,-ja,-zh}/strings.xml
│   │   └── AndroidManifest.xml
│   ├── build.gradle.kts                  ← AGP 8.7, Kotlin 2.1, Compose BOM 2024.09
│   └── proguard-rules.pro
├── gradle/libs.versions.toml
├── settings.gradle.kts
└── README.md (this file)

🤝 Contributing

The codebase is large (~12 k LOC Kotlin + ~2 k LOC C++) and evolving fast. If you find a bug or want a feature, open an issue. PRs welcome — please keep the Compose-only style and avoid external network deps for core flows.

📄 License

MIT — do whatever you want, but don't bundle ROMs or BIOS files in any fork or distribution. Libretro cores are GPLv2/v3 (per core) and remain the property of their respective authors. RetroXR loads them at runtime, never relinks them.

🙏 Credits & inspiration

  • libretro / RetroArch — the cores that do all the actual emulation
  • libretro-thumbnails — community-curated boxart database
  • Khronos OpenXR — open standard for AR/VR
  • Bitmap Brothers, Core Design, Image Works, Activision-Irem, MichTron, Arcadia — for the games used in dev fixtures
  • The Quest hardware team for the most ergonomic VR HMD on the market

🎮 Built with way too much coffee for a project that started as a 2-line ask.

About

Multi-system retro emulator front-end for Quest 3 / Android / Android TV. 200+ libretro cores, Compose UI, OpenXR Mixed Reality. Alpha.

Resources

Stars

8 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages