From 5ff6431a6a9f1fe6ba0eddb6a6d266c7d0e15e30 Mon Sep 17 00:00:00 2001 From: BenMitnicK Date: Tue, 9 Jun 2026 13:13:48 +0200 Subject: [PATCH 1/8] Add background audio playback option --- theseus/desktop/menu_bar.cpp | 8 ++++++++ theseus/desktop/sdl_main.cpp | 9 +++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/theseus/desktop/menu_bar.cpp b/theseus/desktop/menu_bar.cpp index 308f44d..5e1675c 100644 --- a/theseus/desktop/menu_bar.cpp +++ b/theseus/desktop/menu_bar.cpp @@ -16,6 +16,9 @@ extern bool g_bWireframe; extern float g_masterVolume; +extern bool g_audioBackground; +extern void ApplyEffectiveMute_Public(); +extern void SaveDesktopSettings(); #include #include @@ -221,6 +224,11 @@ void RenderMainMenuBar() { DashAudio_SetMasterVolume(v); MediaPlayer_SetMasterVolume(v); } + + if (ImGui::Checkbox("Keep audio playing in background", &g_audioBackground)) { + ApplyEffectiveMute_Public(); + SaveDesktopSettings(); + } if (ImGui::IsItemDeactivatedAfterEdit()) { SaveDesktopSettings(); } diff --git a/theseus/desktop/sdl_main.cpp b/theseus/desktop/sdl_main.cpp index 01651bf..6e3464e 100644 --- a/theseus/desktop/sdl_main.cpp +++ b/theseus/desktop/sdl_main.cpp @@ -348,7 +348,8 @@ static bool s_softRestartPending = false; // reinit after game exits // Audio mute state (Ctrl+M toggle, auto-muted during game launch) bool g_audioMuted = false; // user choice (Ctrl+M) -float g_masterVolume = 1.0f; // 0.0 - 1.0, applied to mixer + libmpv +float g_masterVolume = 1.0f; +bool g_audioBackground = false; // 0.0 - 1.0, applied to mixer + libmpv bool g_useMilkdropViz = false; // opt-in: replace legacy orb viz with projectM bool g_showAlbumCover = false; // when set + album.* present, replace orb viz with cover bool g_windowFocused = true; // SDL focus state @@ -361,7 +362,7 @@ static void ApplyEffectiveMute() extern bool g_mediaFullscreen; extern bool MilkdropWindow_IsOpen(); bool focusLost = !g_windowFocused && !MilkdropWindow_IsOpen(); - bool shouldMute = g_audioMuted || focusLost || g_mediaFullscreen; + bool shouldMute = g_audioMuted || (!g_audioBackground && focusLost) || g_mediaFullscreen; if (shouldMute) DashAudio_MuteAll(); else DashAudio_UnmuteAll(); } @@ -530,6 +531,9 @@ void LoadDesktopSettings() { if (v < 0.0f) v = 0.0f; if (v > 1.0f) v = 1.0f; g_masterVolume = v; } + else if (strncmp(line, "AudioBackground=", 16) == 0) { + g_audioBackground = atoi(line + 16) != 0; + } else if (strncmp(line, "UseMilkdropViz=", 15) == 0) g_useMilkdropViz = atoi(line + 15) != 0; else if (strncmp(line, "ShowAlbumCover=", 15) == 0) @@ -602,6 +606,7 @@ void SaveDesktopSettings() { fprintf(fp, "FpsCap=%d\n", g_fpsCap); fprintf(fp, "Hwdec=%d\n", g_hwdec ? 1 : 0); fprintf(fp, "MasterVolume=%.3f\n", g_masterVolume); + fprintf(fp, "AudioBackground=%d\n", g_audioBackground ? 1 : 0); fprintf(fp, "UseMilkdropViz=%d\n", g_useMilkdropViz ? 1 : 0); fprintf(fp, "ShowAlbumCover=%d\n", g_showAlbumCover ? 1 : 0); { From 79f5d667c9a5f07cbed13d766b6ad7f800ad00b9 Mon Sep 17 00:00:00 2001 From: BenMitnicK Date: Mon, 15 Jun 2026 13:18:46 +0200 Subject: [PATCH 2/8] Fix music track duration probing --- theseus/desktop/audio_sdl.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/theseus/desktop/audio_sdl.cpp b/theseus/desktop/audio_sdl.cpp index a71f857..2383848 100644 --- a/theseus/desktop/audio_sdl.cpp +++ b/theseus/desktop/audio_sdl.cpp @@ -4,7 +4,7 @@ // include std.h, to avoid #define new conflicts with STL. #include -#include +#include #include #include #include @@ -801,6 +801,15 @@ static int MetadataLookup(mpv_node* meta, const char* key, std::string* out) return 0; } +static int ProbeSongDurationWithMixer(const std::string& path) +{ + Mix_Music* probe = Mix_LoadMUS(path.c_str()); + if (!probe) return 0; + double d = Mix_MusicDuration(probe); + Mix_FreeMusic(probe); + return (d > 0.0) ? (int)(d + 0.5) : 0; +} + static bool ProbeSong(mpv_handle* h, const std::string& path, Song& out) { if (!h) return false; @@ -820,6 +829,7 @@ static bool ProbeSong(mpv_handle* h, const std::string& path, Song& out) double dur = 0; mpv_get_property(h, "duration", MPV_FORMAT_DOUBLE, &dur); if (dur > 0) out.duration = (int)(dur + 0.5); + if (out.duration <= 0) out.duration = ProbeSongDurationWithMixer(path); mpv_node meta; memset(&meta, 0, sizeof(meta)); @@ -860,7 +870,7 @@ struct DBEntry { typedef std::map DBMap; static const uint32_t kMusicDBMagic = 0x42444D54; // 'TMDB' -static const uint32_t kMusicDBVersion = 2; +static const uint32_t kMusicDBVersion = 3; static void DB_WriteU32(FILE* fp, uint32_t v) { fwrite(&v, 4, 1, fp); } static void DB_WriteI32(FILE* fp, int32_t v) { fwrite(&v, 4, 1, fp); } @@ -1044,6 +1054,8 @@ int DashMusic_Scan(const char* musicRoot) if (!probeMpv) probeMpv = ProbeMpv_Create(); if (probeMpv && ProbeSong(probeMpv, fullPath, song)) probedCount++; + if (song.duration <= 0) + song.duration = ProbeSongDurationWithMixer(fullPath); } DBEntry e; SongToDB(song, e); From 7cb82fcbe38af627da87eaf97f60f38610be05db Mon Sep 17 00:00:00 2001 From: BenMitnicK Date: Mon, 15 Jun 2026 13:18:46 +0200 Subject: [PATCH 3/8] Fix SDL_mixer include path in audio_sdl.cpp --- theseus/desktop/audio_sdl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/theseus/desktop/audio_sdl.cpp b/theseus/desktop/audio_sdl.cpp index 2383848..4697a73 100644 --- a/theseus/desktop/audio_sdl.cpp +++ b/theseus/desktop/audio_sdl.cpp @@ -4,7 +4,7 @@ // include std.h, to avoid #define new conflicts with STL. #include -#include +#include #include #include #include From 02c901fd8131b0249f777aafc71ee5236c819856 Mon Sep 17 00:00:00 2001 From: BenMitnicK Date: Mon, 15 Jun 2026 13:18:47 +0200 Subject: [PATCH 4/8] Add Windows executable icon resource --- build/Makefile | 11 +++++++++-- theseus/desktop/resources/theseus.ico | Bin 0 -> 91083 bytes theseus/desktop/resources/theseus.rc | 1 + 3 files changed, 10 insertions(+), 2 deletions(-) create mode 100644 theseus/desktop/resources/theseus.ico create mode 100644 theseus/desktop/resources/theseus.rc diff --git a/build/Makefile b/build/Makefile index 626688c..0a06705 100644 --- a/build/Makefile +++ b/build/Makefile @@ -1130,6 +1130,8 @@ endif # Same source list as desktop. the compiler reads the same files. WIN64_OBJS = $(patsubst $(THESEUS_SRC)/%.cpp,$(WIN64_DIR)/%.o,$(WIN64_SRCS)) WIN64_DEPS = $(WIN64_OBJS:.o=.d) +WIN64_RES_RC = $(THESEUS_SRC)/desktop/resources/theseus.rc +WIN64_RES_OBJ = $(WIN64_DIR)/desktop/resources/theseus_res.o -include $(WIN64_DEPS) .PHONY: desktop-win64 desktop-win64-clean projectm-deps-win64 projectm-win64-clean @@ -1167,9 +1169,9 @@ $(PROJECTM_WIN64_MARKER): projectm-win64-clean: rm -rf $(PROJECTM_SRC)/build-win64 $(PROJECTM_WIN64_PREFIX) -$(WIN64_TARGET): $(WIN64_OBJS) +$(WIN64_TARGET): $(WIN64_OBJS) $(WIN64_RES_OBJ) @mkdir -p $(WIN64_DIR) - $(WIN64_CXX) -o $@ $(WIN64_OBJS) $(WIN64_LDFLAGS) + $(WIN64_CXX) -o $@ $(WIN64_OBJS) $(WIN64_RES_OBJ) $(WIN64_LDFLAGS) @# Bundle every DLL the exe needs so the build directory is a self- @# contained Windows drop. -static-libgcc -static-libstdc++ folds the @# core runtime in; SDL2 / SDL2_mixer / libmpv / libcurl / libwinpthread @@ -1206,6 +1208,11 @@ $(WIN64_TARGET): $(WIN64_OBJS) printf '[default]\nversion=%s\n' "$$STAMP" > "$$VFILE" @echo " (bundled DLLs + Configs/Data/Library + stamped version -> $(WIN64_DIR))" + +$(WIN64_RES_OBJ): $(WIN64_RES_RC) + @mkdir -p $(dir $@) + x86_64-w64-mingw32-windres -I$(THESEUS_SRC)/desktop/resources -i $< -o $@ + $(WIN64_DIR)/%.o: $(THESEUS_SRC)/%.cpp @mkdir -p $(dir $@) $(WIN64_CXX) $(WIN64_CFLAGS) -c -o $@ $< diff --git a/theseus/desktop/resources/theseus.ico b/theseus/desktop/resources/theseus.ico new file mode 100644 index 0000000000000000000000000000000000000000..fef8dc6c119de97465cc831a556b3c8991c75ef9 GIT binary patch literal 91083 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 a8F0&hTL#=R@V_eqO@9l(eg6NC1Ahl9>7yC| literal 0 HcmV?d00001 diff --git a/theseus/desktop/resources/theseus.rc b/theseus/desktop/resources/theseus.rc new file mode 100644 index 0000000..48e6b1f --- /dev/null +++ b/theseus/desktop/resources/theseus.rc @@ -0,0 +1 @@ +1 ICON "theseus.ico" From 5c0b19ab6c868c4e872aa02ef4d4dbaf2ed7c7d2 Mon Sep 17 00:00:00 2001 From: BenMitnicK Date: Wed, 8 Jul 2026 20:23:01 +0200 Subject: [PATCH 5/8] Add README for Theseus project Added README documentation for Theseus project, detailing features, installation instructions, and developer information. --- README_Theseus.md | 306 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 306 insertions(+) create mode 100644 README_Theseus.md diff --git a/README_Theseus.md b/README_Theseus.md new file mode 100644 index 0000000..a7afdce --- /dev/null +++ b/README_Theseus.md @@ -0,0 +1,306 @@ +# Theseus + +[![build](https://github.com/MrMilenko/Theseus/actions/workflows/build.yml/badge.svg?branch=main)](https://github.com/MrMilenko/Theseus/actions/workflows/build.yml) +[![License](https://img.shields.io/badge/license-GPL--3.0--or--later-blue.svg)](LICENSE) +[![Platform](https://img.shields.io/badge/platform-Xbox%20%7C%20macOS%20%7C%20Linux%20%7C%20Windows-lightgrey.svg)](#) + +

    + Vulkan +      + Metal +

    + +Six years of reverse engineering the original Xbox dashboard. This repo is the result. + +Theseus boots on modded Xbox hardware as a drop in replacement for the stock dashboard. The same engine compiles natively on macOS, Linux, and Windows, where it doubles as **UIX Desktop**: a 3D launcher and media center. The desktop build renders through [bgfx](https://github.com/bkaradzic/bgfx): Metal on macOS, Vulkan on Linux and Windows. + +The split is intentional. The Xbox build stays faithful to what you'd expect from the Xbox dashboard (or UIX Lite, if you've used a custom dashboard before). Everything that doesn't belong on an Xbox (Steam libraries, modern video playback, emulator-hosted ISOs, playlists, skin authoring tools) lives on the desktop side instead. Two projects, one engine. + +

    + Xbox dashboard + UIX Desktop launcher +

    +

    + Media library + Custom skin +

    +

    + Steam tab in Title Maker + RetroArch tab in Title Maker +

    + +## On Xbox + +A drop-in replacement for the stock Xbox dashboard on modded consoles. Same look and behavior, because that's what it is. Rebuilt plank by plank and still going. + +What works: +- Every original scene, animation, and skin slot +- UIX Lite skins drop in unchanged. Skin authors don't have to do anything +- Hot swap skins from settings, no reboot +- ISO / CCI launching from the harddrive menu, plus the original XBE flow +- Hundreds of titles scan in milliseconds +- Title icons auto populate from each game's XBE certificate +- Quick overlay (LT + B) for ISO loader, file manager, FTP / drive widgets +- FTP server, recovery / panic screen, MP3 soundtrack playback + +[Download for Xbox ->](https://github.com/MrMilenko/Theseus/releases) (or build from source, see below) + +## On the desktop (UIX Desktop) + +UIX Desktop is the Theseus engine compiled for your computer, with the modern features bolted on. macOS, Linux, Windows, Steam Deck friendly. + +- **3D launcher** for native PC games, Steam libraries, RetroArch ROMs, and Xbox ISOs via [xemu](https://xemu.app) +- **Media library** that scans your Movies and TV folders, pulls posters from [TMDB](https://www.themoviedb.org/), plays back through libmpv +- **Skin editor** with live XAP scripting and a scene inspector. Change a skin, see it instantly +- **Title Maker** for adding games and apps, with per launcher import flows for Steam and RetroArch +- **Xbox HDD browser** that opens qcow2 and FATX images +- **CRT post process** for the old TV look. Scanlines, curvature, phosphor, bloom, all tunable +- **Graphics knobs** in Settings -> Display: vsync mode, FPS cap, MSAA, hardware video decode +- **Controllers**: Xbox and PlayStation pads via SDL2 + +[Download for desktop ->](https://github.com/MrMilenko/Theseus/releases) + +## Quick Start + +### Xbox + +1. Grab the latest Xbox release (`default.xbe` + `uixdata/`) +2. Drop the XBE somewhere on the Xbox HDD, e.g. `E:\Dashboards\Theseus\default.xbe` +3. Copy `uixdata/` next to it +4. Copy `Configs/` to `C:\UIX Configs\` +5. Boot it. If something's missing, the panic screen tells you what. + +### Desktop + +1. Grab the release for your OS +2. Run it. That's it. + +The Windows release ships with the DLLs it needs. macOS and Linux dynamically link to system libraries, so you'll want these installed: + +**macOS (Homebrew):** +``` +brew install sdl2 sdl2_mixer mpv curl +``` + +**Linux (Debian / Ubuntu):** +``` +sudo apt install libsdl2-2.0-0 libsdl2-mixer-2.0-0 libmpv2 libcurl4 +``` + +(Some distros ship `libmpv1` instead of `libmpv2`. Either works.) + +If you'd rather build from source, jump down to [Building](#building). + +## Adding games + +Title Maker (F3 from the dashboard) is where you connect games to dashboard tiles. Three tabs: + +**Main** is the catch all. Every title you've added shows up here, regardless of which tab created it. This is also where you add the weird stuff that doesn't belong to a launcher: a Windows .exe, a .bat script, a macOS .command file, a shell one liner, anything that takes a path or command. Edit names, swap icons, tweak the launch line. Most of your time managing the library happens here. + +**Steam** auto detects your Steam install (Find button), or you point at it once. Hit Import Steam Library and your installed games come in with icons fetched from Valve's CDN. There's also a manual "Add by App ID" form for launching betas, demos, or games not in your normal library scan. + +**RetroArch** detects your RetroArch install the same way. Import Recent Titles pulls in everything you've recently played in RetroArch, with the right core auto resolved and boxart copied from RetroArch's thumbnail packs. You can also add manually: pick a ROM, pick a core from the dropdown, done. + +If you don't use Steam or RetroArch, you can turn either tab off under Optional Tabs (top of Main). Anything you've already added stays in Main either way. + +## Customization + +**Skins.** Drop them into `Data/Skins/` (Xbox: `uixdata\Skins\`) and pick from settings. UIX Lite community skins work as is, no conversion needed. Hot swap, no reboot. + +**Scene authoring** (for the people building dashboards from scratch). Scenes are XAP scripts packed into `.xip` archives. The desktop build has a live XAP editor (F2), scene inspector (F1), and asset reload so you can tweak and see results immediately. The XAP node interface is the contract; the C++ behind it can change but the node API is treated as sacred. Full reference in [`docs/xap-contract.md`](docs/xap-contract.md). + +## Controls (desktop) + +**Dashboard:** + +| Key | Xbox button | Action | +|---|---|---| +| Arrow keys | D-pad | Navigate | +| Enter / Space | A | Select | +| Backspace | B | Back | +| X / Y | X / Y | Context actions | +| Tab | White | Play / Pause | +| ` (backtick) | Black | Stop | +| WASD | Left stick | Analog navigation | + +**Media playback:** + +| Key | Action | +|---|---| +| Esc / Q | Stop, return to dashboard | +| Space | Pause / Resume | +| Left / Right | Seek 5s | +| `[` / `]` | Previous / Next in playlist | +| T | Track picker (audio + subtitles) | + +**Tools (desktop only):** + +| Key | Action | +|---|---| +| F1 | Scene inspector | +| F2 | XAP script editor | +| F3 | Title Maker | +| F4 | Settings | +| F5 | Xbox HDD browser | +| F6 | Playlist Maker | +| F10 | Toggle menu bar | +| F11 | Toggle fullscreen | +| Ctrl+M | Mute | +| Ctrl+R | Restart dashboard | + +Xbox and PlayStation controllers also work via SDL2 GameController. + +--- + +# For developers + +The rest is build instructions, architecture notes, and the lineage. Skip if you just want to run it. + +## Building + +Both builds live in this repo and use the same Makefile. + +### Xbox + +Cross-compiles from macOS or Linux using clang + lld-link + cxbe. Requires: +- clang and lld-link (`brew install llvm` on macOS, `apt install clang lld` on Linux) +- [OXDK](https://github.com/MrMilenko/OXDK) cloned and built +- An Xbox SDK source tree (path passed as `XDK_BASE`) + +``` +git clone https://github.com/MrMilenko/OXDK ~/OXDK +cd ~/OXDK/tools/cxbe && make +cd /path/to/Theseus/build +make CONFIG=retail XDK_BASE=/path/to/xbox +``` + +Output lands at `~/builds/theseus/xbox-retail/default.xbe`. + +### Desktop + +Same source tree, different Makefile target. Needs C++17, SDL2, SDL2_mixer, libmpv, libcurl. Rendering goes through bgfx: Metal on macOS, Vulkan on Linux and Windows. bgfx ships as a git submodule and the shaders compile from .sc source via `shaderc`. + +Init the submodules once before the first build: + +``` +git submodule update --init --recursive +``` + +Then build the bgfx libraries (one time per platform) and compile shaders: + +``` +# macOS (Apple Silicon) +make -C theseus/third-party/bgfx -j osx-arm64 +make -C build shaders-bgfx + +# Linux +make -C theseus/third-party/bgfx -j linux-release64 +make -C build shaders-bgfx-spirv + +# Windows (built from a MSYS2 mingw shell, or cross-compiled from Linux) +make -C theseus/third-party/bgfx -j mingw-gcc-release64 +make -C build shaders-bgfx-spirv +``` + +After that, the per-OS build commands: + +**macOS:** +``` +brew install sdl2 sdl2_mixer mpv curl pkg-config +cd build && make desktop BGFX=1 +~/builds/theseus/desktop/theseus +``` + +**Linux:** +``` +sudo apt install build-essential pkg-config libsdl2-dev libsdl2-mixer-dev \ + libvulkan-dev libx11-dev libmpv-dev libcurl4-openssl-dev +cd build && make desktop BGFX=1 +~/builds/theseus/desktop/theseus +``` + +**Windows (MSYS2 / MinGW64):** +``` +pacman -S make pkg-config mingw-w64-x86_64-gcc \ + mingw-w64-x86_64-SDL2 mingw-w64-x86_64-SDL2_mixer \ + mingw-w64-x86_64-mpv mingw-w64-x86_64-curl \ + mingw-w64-x86_64-vulkan-headers mingw-w64-x86_64-vulkan-loader +cd build && make desktop-win64 BGFX=1 +``` + +Cross-compiling for Windows from macOS / Linux, ARM64 Linux, or any of the more involved setups is in [`docs/desktop/`](docs/desktop/). The CI workflow runs all the build matrix combinations on every push, which is the closest thing to executable docs for the one-time setup. + +The legacy OpenGL backend still compiles by dropping the `BGFX=1` flag, useful for older hardware without Vulkan support. Shipped releases use the bgfx path. + +## How it works + +The engine is approximately 50 source files reconstructed from the retail and patched XBE's spanning 4920 to 5960, organized the same way the original dashboard was: script VM, scene graph, rendering, asset loading, UI framework, system integration, and launcher. Per-subsystem reverse engineering notes are in [`docs/decomp/`](docs/decomp/). + +The XAP scripting layer is a custom JS-like bytecode VM. The scene graph is VRML97-inspired with runtime reflection via FND/PRD property tables. On the desktop side, D3D8 calls translate through a thin shim into bgfx, which targets Metal on macOS and Vulkan on Linux and Windows. Everything else compiles for both targets from the same shared source. + +If you're poking around the source, the high-level layout: + +``` +theseus/ + engine/ Pure logic (VM, nodes, math) + shared/ Cross-platform with Win32 types (file I/O, audio, settings) + render/ Scene graph, materials, shapes + xbox/ Xbox-only (XTL, modchip, kernel APIs) + desktop/ Desktop-only (SDL, bgfx, ImGui tools) + toolbox/ PrometheOS-derived FTP / drive / network (Xbox-only) +theseuslib/ Shared C library (xiso parser, xip parser) +``` + +Heavier docs index lives at [`docs/README.md`](docs/README.md). + +## Heritage + +Theseus is part of the TeamUIX lineage. JbOnE created *User.Interface.X* (UIX), a source level modification of the original Xbox Dashboard, which we also poked around in via Ghidra to figure certain things out. Modern TeamUIX continues that tradition with [UIX Lite](https://github.com/OfficialTeamUIX/UIX-Lite) (a heavily patched retail XBE) and Theseus (this repository). + +There's a circularity to it. UIX modified the dashboard at the source level. Theseus reaches the same destination from the other side of the river, rebuilding the codebase from binary analysis and untangling changes made to XIPs over 25 years of community modification. + +For the broader UIX project narrative, see [UIX History](https://github.com/MrMilenko/UIX-History). + +## Credits + +**Team UIX:** +- **Milenko**: primary RE and development, UIX Desktop port +- **BigJx**: UIX Lite XIPs (XAP scripts, skins, scene assets), testing, bug reports +- **Rocky5**: skin presets and the Colourizer XBE color patcher (technique descends from **ZogoChieftan**'s in-dashboard color patching in BlackStormX, circa 2004) +- **JbOnE**: original UIX, the lineage Theseus continues + +**Related projects:** +- [Team Resurgent](https://github.com/Team-Resurgent): [PrometheOS](https://github.com/Team-Resurgent/PrometheOS-Firmware) (the toolbox is forked from here via [UIX Lite Toolbox](https://github.com/OfficialTeamUIX/UIX-Lite-Toolbox)) and [Hermes](https://github.com/Team-Resurgent/Hermes) (ISO/CCI mount support) +- [xemu](https://xemu.app): Original Xbox emulator that the desktop launcher integrates with for ISO playback + +## Third-party libraries + +Xbox build: + +| Library | License | Purpose | +|---|---|---| +| [minimp3](https://github.com/lieff/minimp3) | CC0 | MP3 decoder for the music system | + +Desktop build: + +| Library | License | Purpose | +|---|---|---| +| [SDL2](https://www.libsdl.org/) | zlib | Window, input, audio | +| [SDL2_mixer](https://github.com/libsdl-org/SDL_mixer) | zlib | Sound playback | +| [libmpv](https://mpv.io/) | LGPL 2.1+ | Video playback | +| [libcurl](https://curl.se/libcurl/) | curl | HTTPS for TMDB metadata | +| [Dear ImGui](https://github.com/ocornut/imgui) | MIT | Developer tool UI | +| [ImGuiColorTextEdit](https://github.com/BalazsJako/ImGuiColorTextEdit) | MIT | XAP script editor with syntax highlighting | +| [stb_image](https://github.com/nothings/stb) | Public Domain | Image loading | +| [bgfx](https://github.com/bkaradzic/bgfx) | BSD 2-Clause | Cross-platform render abstraction (Metal, Vulkan) | +| [bx](https://github.com/bkaradzic/bx) | BSD 2-Clause | bgfx base library | +| [bimg](https://github.com/bkaradzic/bimg) | BSD 2-Clause | bgfx image utility library | +| [GLEW](https://glew.sourceforge.net/) | Modified BSD / MIT | OpenGL extension loader (legacy GL backend, Windows only) | + +Full catalog with attributions is in [`LICENSE-THIRD-PARTY.md`](LICENSE-THIRD-PARTY.md). + +## License + +Theseus is licensed under the **GNU General Public License, version 3 or later** (`GPL-3.0-or-later`). Full license text in [`LICENSE`](LICENSE). + +Inherited code keeps its origin license intact (`theseus/toolbox/` from PrometheOS via UIX Lite Toolbox is GPL-3.0; Hermes is GPL-3.0). The XIPs and skin assets shipped in `Data/` are TeamUIX's UIX Lite work and ship under GPL-3.0-or-later. From 4e3376710477d0c4aceb714a0618768e1bd9ae14 Mon Sep 17 00:00:00 2001 From: BenMitnicK Date: Wed, 8 Jul 2026 20:25:20 +0200 Subject: [PATCH 6/8] Add reference to Theseus Original and update title Updated README to include a reference to the original Theseus documentation and added a title for the modded version. --- README.md | 307 +----------------------------------------------------- 1 file changed, 2 insertions(+), 305 deletions(-) diff --git a/README.md b/README.md index a7afdce..3bd7a0a 100644 --- a/README.md +++ b/README.md @@ -1,306 +1,3 @@ -# Theseus +[Theseus_Original](README_Theseus.md) -[![build](https://github.com/MrMilenko/Theseus/actions/workflows/build.yml/badge.svg?branch=main)](https://github.com/MrMilenko/Theseus/actions/workflows/build.yml) -[![License](https://img.shields.io/badge/license-GPL--3.0--or--later-blue.svg)](LICENSE) -[![Platform](https://img.shields.io/badge/platform-Xbox%20%7C%20macOS%20%7C%20Linux%20%7C%20Windows-lightgrey.svg)](#) - -

    - Vulkan -      - Metal -

    - -Six years of reverse engineering the original Xbox dashboard. This repo is the result. - -Theseus boots on modded Xbox hardware as a drop in replacement for the stock dashboard. The same engine compiles natively on macOS, Linux, and Windows, where it doubles as **UIX Desktop**: a 3D launcher and media center. The desktop build renders through [bgfx](https://github.com/bkaradzic/bgfx): Metal on macOS, Vulkan on Linux and Windows. - -The split is intentional. The Xbox build stays faithful to what you'd expect from the Xbox dashboard (or UIX Lite, if you've used a custom dashboard before). Everything that doesn't belong on an Xbox (Steam libraries, modern video playback, emulator-hosted ISOs, playlists, skin authoring tools) lives on the desktop side instead. Two projects, one engine. - -

    - Xbox dashboard - UIX Desktop launcher -

    -

    - Media library - Custom skin -

    -

    - Steam tab in Title Maker - RetroArch tab in Title Maker -

    - -## On Xbox - -A drop-in replacement for the stock Xbox dashboard on modded consoles. Same look and behavior, because that's what it is. Rebuilt plank by plank and still going. - -What works: -- Every original scene, animation, and skin slot -- UIX Lite skins drop in unchanged. Skin authors don't have to do anything -- Hot swap skins from settings, no reboot -- ISO / CCI launching from the harddrive menu, plus the original XBE flow -- Hundreds of titles scan in milliseconds -- Title icons auto populate from each game's XBE certificate -- Quick overlay (LT + B) for ISO loader, file manager, FTP / drive widgets -- FTP server, recovery / panic screen, MP3 soundtrack playback - -[Download for Xbox ->](https://github.com/MrMilenko/Theseus/releases) (or build from source, see below) - -## On the desktop (UIX Desktop) - -UIX Desktop is the Theseus engine compiled for your computer, with the modern features bolted on. macOS, Linux, Windows, Steam Deck friendly. - -- **3D launcher** for native PC games, Steam libraries, RetroArch ROMs, and Xbox ISOs via [xemu](https://xemu.app) -- **Media library** that scans your Movies and TV folders, pulls posters from [TMDB](https://www.themoviedb.org/), plays back through libmpv -- **Skin editor** with live XAP scripting and a scene inspector. Change a skin, see it instantly -- **Title Maker** for adding games and apps, with per launcher import flows for Steam and RetroArch -- **Xbox HDD browser** that opens qcow2 and FATX images -- **CRT post process** for the old TV look. Scanlines, curvature, phosphor, bloom, all tunable -- **Graphics knobs** in Settings -> Display: vsync mode, FPS cap, MSAA, hardware video decode -- **Controllers**: Xbox and PlayStation pads via SDL2 - -[Download for desktop ->](https://github.com/MrMilenko/Theseus/releases) - -## Quick Start - -### Xbox - -1. Grab the latest Xbox release (`default.xbe` + `uixdata/`) -2. Drop the XBE somewhere on the Xbox HDD, e.g. `E:\Dashboards\Theseus\default.xbe` -3. Copy `uixdata/` next to it -4. Copy `Configs/` to `C:\UIX Configs\` -5. Boot it. If something's missing, the panic screen tells you what. - -### Desktop - -1. Grab the release for your OS -2. Run it. That's it. - -The Windows release ships with the DLLs it needs. macOS and Linux dynamically link to system libraries, so you'll want these installed: - -**macOS (Homebrew):** -``` -brew install sdl2 sdl2_mixer mpv curl -``` - -**Linux (Debian / Ubuntu):** -``` -sudo apt install libsdl2-2.0-0 libsdl2-mixer-2.0-0 libmpv2 libcurl4 -``` - -(Some distros ship `libmpv1` instead of `libmpv2`. Either works.) - -If you'd rather build from source, jump down to [Building](#building). - -## Adding games - -Title Maker (F3 from the dashboard) is where you connect games to dashboard tiles. Three tabs: - -**Main** is the catch all. Every title you've added shows up here, regardless of which tab created it. This is also where you add the weird stuff that doesn't belong to a launcher: a Windows .exe, a .bat script, a macOS .command file, a shell one liner, anything that takes a path or command. Edit names, swap icons, tweak the launch line. Most of your time managing the library happens here. - -**Steam** auto detects your Steam install (Find button), or you point at it once. Hit Import Steam Library and your installed games come in with icons fetched from Valve's CDN. There's also a manual "Add by App ID" form for launching betas, demos, or games not in your normal library scan. - -**RetroArch** detects your RetroArch install the same way. Import Recent Titles pulls in everything you've recently played in RetroArch, with the right core auto resolved and boxart copied from RetroArch's thumbnail packs. You can also add manually: pick a ROM, pick a core from the dropdown, done. - -If you don't use Steam or RetroArch, you can turn either tab off under Optional Tabs (top of Main). Anything you've already added stays in Main either way. - -## Customization - -**Skins.** Drop them into `Data/Skins/` (Xbox: `uixdata\Skins\`) and pick from settings. UIX Lite community skins work as is, no conversion needed. Hot swap, no reboot. - -**Scene authoring** (for the people building dashboards from scratch). Scenes are XAP scripts packed into `.xip` archives. The desktop build has a live XAP editor (F2), scene inspector (F1), and asset reload so you can tweak and see results immediately. The XAP node interface is the contract; the C++ behind it can change but the node API is treated as sacred. Full reference in [`docs/xap-contract.md`](docs/xap-contract.md). - -## Controls (desktop) - -**Dashboard:** - -| Key | Xbox button | Action | -|---|---|---| -| Arrow keys | D-pad | Navigate | -| Enter / Space | A | Select | -| Backspace | B | Back | -| X / Y | X / Y | Context actions | -| Tab | White | Play / Pause | -| ` (backtick) | Black | Stop | -| WASD | Left stick | Analog navigation | - -**Media playback:** - -| Key | Action | -|---|---| -| Esc / Q | Stop, return to dashboard | -| Space | Pause / Resume | -| Left / Right | Seek 5s | -| `[` / `]` | Previous / Next in playlist | -| T | Track picker (audio + subtitles) | - -**Tools (desktop only):** - -| Key | Action | -|---|---| -| F1 | Scene inspector | -| F2 | XAP script editor | -| F3 | Title Maker | -| F4 | Settings | -| F5 | Xbox HDD browser | -| F6 | Playlist Maker | -| F10 | Toggle menu bar | -| F11 | Toggle fullscreen | -| Ctrl+M | Mute | -| Ctrl+R | Restart dashboard | - -Xbox and PlayStation controllers also work via SDL2 GameController. - ---- - -# For developers - -The rest is build instructions, architecture notes, and the lineage. Skip if you just want to run it. - -## Building - -Both builds live in this repo and use the same Makefile. - -### Xbox - -Cross-compiles from macOS or Linux using clang + lld-link + cxbe. Requires: -- clang and lld-link (`brew install llvm` on macOS, `apt install clang lld` on Linux) -- [OXDK](https://github.com/MrMilenko/OXDK) cloned and built -- An Xbox SDK source tree (path passed as `XDK_BASE`) - -``` -git clone https://github.com/MrMilenko/OXDK ~/OXDK -cd ~/OXDK/tools/cxbe && make -cd /path/to/Theseus/build -make CONFIG=retail XDK_BASE=/path/to/xbox -``` - -Output lands at `~/builds/theseus/xbox-retail/default.xbe`. - -### Desktop - -Same source tree, different Makefile target. Needs C++17, SDL2, SDL2_mixer, libmpv, libcurl. Rendering goes through bgfx: Metal on macOS, Vulkan on Linux and Windows. bgfx ships as a git submodule and the shaders compile from .sc source via `shaderc`. - -Init the submodules once before the first build: - -``` -git submodule update --init --recursive -``` - -Then build the bgfx libraries (one time per platform) and compile shaders: - -``` -# macOS (Apple Silicon) -make -C theseus/third-party/bgfx -j osx-arm64 -make -C build shaders-bgfx - -# Linux -make -C theseus/third-party/bgfx -j linux-release64 -make -C build shaders-bgfx-spirv - -# Windows (built from a MSYS2 mingw shell, or cross-compiled from Linux) -make -C theseus/third-party/bgfx -j mingw-gcc-release64 -make -C build shaders-bgfx-spirv -``` - -After that, the per-OS build commands: - -**macOS:** -``` -brew install sdl2 sdl2_mixer mpv curl pkg-config -cd build && make desktop BGFX=1 -~/builds/theseus/desktop/theseus -``` - -**Linux:** -``` -sudo apt install build-essential pkg-config libsdl2-dev libsdl2-mixer-dev \ - libvulkan-dev libx11-dev libmpv-dev libcurl4-openssl-dev -cd build && make desktop BGFX=1 -~/builds/theseus/desktop/theseus -``` - -**Windows (MSYS2 / MinGW64):** -``` -pacman -S make pkg-config mingw-w64-x86_64-gcc \ - mingw-w64-x86_64-SDL2 mingw-w64-x86_64-SDL2_mixer \ - mingw-w64-x86_64-mpv mingw-w64-x86_64-curl \ - mingw-w64-x86_64-vulkan-headers mingw-w64-x86_64-vulkan-loader -cd build && make desktop-win64 BGFX=1 -``` - -Cross-compiling for Windows from macOS / Linux, ARM64 Linux, or any of the more involved setups is in [`docs/desktop/`](docs/desktop/). The CI workflow runs all the build matrix combinations on every push, which is the closest thing to executable docs for the one-time setup. - -The legacy OpenGL backend still compiles by dropping the `BGFX=1` flag, useful for older hardware without Vulkan support. Shipped releases use the bgfx path. - -## How it works - -The engine is approximately 50 source files reconstructed from the retail and patched XBE's spanning 4920 to 5960, organized the same way the original dashboard was: script VM, scene graph, rendering, asset loading, UI framework, system integration, and launcher. Per-subsystem reverse engineering notes are in [`docs/decomp/`](docs/decomp/). - -The XAP scripting layer is a custom JS-like bytecode VM. The scene graph is VRML97-inspired with runtime reflection via FND/PRD property tables. On the desktop side, D3D8 calls translate through a thin shim into bgfx, which targets Metal on macOS and Vulkan on Linux and Windows. Everything else compiles for both targets from the same shared source. - -If you're poking around the source, the high-level layout: - -``` -theseus/ - engine/ Pure logic (VM, nodes, math) - shared/ Cross-platform with Win32 types (file I/O, audio, settings) - render/ Scene graph, materials, shapes - xbox/ Xbox-only (XTL, modchip, kernel APIs) - desktop/ Desktop-only (SDL, bgfx, ImGui tools) - toolbox/ PrometheOS-derived FTP / drive / network (Xbox-only) -theseuslib/ Shared C library (xiso parser, xip parser) -``` - -Heavier docs index lives at [`docs/README.md`](docs/README.md). - -## Heritage - -Theseus is part of the TeamUIX lineage. JbOnE created *User.Interface.X* (UIX), a source level modification of the original Xbox Dashboard, which we also poked around in via Ghidra to figure certain things out. Modern TeamUIX continues that tradition with [UIX Lite](https://github.com/OfficialTeamUIX/UIX-Lite) (a heavily patched retail XBE) and Theseus (this repository). - -There's a circularity to it. UIX modified the dashboard at the source level. Theseus reaches the same destination from the other side of the river, rebuilding the codebase from binary analysis and untangling changes made to XIPs over 25 years of community modification. - -For the broader UIX project narrative, see [UIX History](https://github.com/MrMilenko/UIX-History). - -## Credits - -**Team UIX:** -- **Milenko**: primary RE and development, UIX Desktop port -- **BigJx**: UIX Lite XIPs (XAP scripts, skins, scene assets), testing, bug reports -- **Rocky5**: skin presets and the Colourizer XBE color patcher (technique descends from **ZogoChieftan**'s in-dashboard color patching in BlackStormX, circa 2004) -- **JbOnE**: original UIX, the lineage Theseus continues - -**Related projects:** -- [Team Resurgent](https://github.com/Team-Resurgent): [PrometheOS](https://github.com/Team-Resurgent/PrometheOS-Firmware) (the toolbox is forked from here via [UIX Lite Toolbox](https://github.com/OfficialTeamUIX/UIX-Lite-Toolbox)) and [Hermes](https://github.com/Team-Resurgent/Hermes) (ISO/CCI mount support) -- [xemu](https://xemu.app): Original Xbox emulator that the desktop launcher integrates with for ISO playback - -## Third-party libraries - -Xbox build: - -| Library | License | Purpose | -|---|---|---| -| [minimp3](https://github.com/lieff/minimp3) | CC0 | MP3 decoder for the music system | - -Desktop build: - -| Library | License | Purpose | -|---|---|---| -| [SDL2](https://www.libsdl.org/) | zlib | Window, input, audio | -| [SDL2_mixer](https://github.com/libsdl-org/SDL_mixer) | zlib | Sound playback | -| [libmpv](https://mpv.io/) | LGPL 2.1+ | Video playback | -| [libcurl](https://curl.se/libcurl/) | curl | HTTPS for TMDB metadata | -| [Dear ImGui](https://github.com/ocornut/imgui) | MIT | Developer tool UI | -| [ImGuiColorTextEdit](https://github.com/BalazsJako/ImGuiColorTextEdit) | MIT | XAP script editor with syntax highlighting | -| [stb_image](https://github.com/nothings/stb) | Public Domain | Image loading | -| [bgfx](https://github.com/bkaradzic/bgfx) | BSD 2-Clause | Cross-platform render abstraction (Metal, Vulkan) | -| [bx](https://github.com/bkaradzic/bx) | BSD 2-Clause | bgfx base library | -| [bimg](https://github.com/bkaradzic/bimg) | BSD 2-Clause | bgfx image utility library | -| [GLEW](https://glew.sourceforge.net/) | Modified BSD / MIT | OpenGL extension loader (legacy GL backend, Windows only) | - -Full catalog with attributions is in [`LICENSE-THIRD-PARTY.md`](LICENSE-THIRD-PARTY.md). - -## License - -Theseus is licensed under the **GNU General Public License, version 3 or later** (`GPL-3.0-or-later`). Full license text in [`LICENSE`](LICENSE). - -Inherited code keeps its origin license intact (`theseus/toolbox/` from PrometheOS via UIX Lite Toolbox is GPL-3.0; Hermes is GPL-3.0). The XIPs and skin assets shipped in `Data/` are TeamUIX's UIX Lite work and ship under GPL-3.0-or-later. +# Theseus Modded From 89f577aafe073a23a6a7406b5c3efee27ee67afd Mon Sep 17 00:00:00 2001 From: BenMitnicK Date: Fri, 10 Jul 2026 02:18:27 +0200 Subject: [PATCH 7/8] Revise README for Theseus Project modifications This README update provides detailed information about the modified Theseus Project, including new features, controls, and credits. --- README.md | 162 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 161 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3bd7a0a..447c2a1 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,163 @@ [Theseus_Original](README_Theseus.md) -# Theseus Modded +# Theseus Project - BMK-Studio Modified Version + +This is a modified version of the original Theseus Project, based on the Microsoft dashboard for the original Xbox. + +The goal of this version is to add new visual features, extra customization options, background music, panels, and new dashboard interactions while keeping the original Xbox dashboard feeling. + +--- + +## Features + +### 1. BMK Controller Panel + +- Background Mesh +- Orbs +- Skins +- Visibility +- UIX Settings / Config + +--- + +### 2. Custom Orbs + +- Main Orb +- Setting Main Orb +- Emulator Orb +- Application Orb +- Game Orb +- Dashboard Orb + +--- + +### 3. skin.ini Support + +- Custom background images +- Background image rotation +- Background image timer +- Custom SMAP +- SMAP rotation +- SMAP timer +- CellWall visibility + +--- + +### 4. REZN8 Menu + +- Integrated REZN8 quick menu +- Switch between M$Dash and REZN8 +- Access to main dashboard sections + +--- + +### 5. BMK ScreenSaver + +- Custom BMK ScreenSaver added + +--- + +### 6. Background Music + +- Automatic background music +- Random music mode +- Play / Pause support +- Soundtrack switching +- Song switching + +--- + +### 7. Music Panel + +- Current music title display +- Scrolling music text + +--- + +### 8. Second Music Panel + +- Active soundtrack +- Current track +- Track duration +- Remaining time + +--- + +### 9. Multi-Info Panel + +- IP address +- Free space E / F / G +- BIOS info +- Dashboard version +- Temperature info +- Fan speed + +--- + +### 10. BMK Menu Animation + +- Custom menu animation +- Pods animation +- Panels animation +- Animation mode: Off / UIX / BMK + +--- + +### 11. MemoryX MiniGame + +- MemoryX mini-game integrated into the dashboard + +--- + +### 12. Visibility Options + +- Show / hide dashboard elements +- Manage dashboard visual elements from BMK Controller Panel + +--- + +## Controls + +```text +A => Select + +B => Back + +X => NextClockInfoPanel +White(Tab)+(X) => MemoryX (MiniGame) + +Y => Play/Pause BackGroundMusic + +LeftThumbDown (W) => BMKControlerPanel + +RightThumbDown (C) => Toggle beetween MusicPanel + +White (Tab) => Superkey + +Black + +LeftDown (A) => Screensaver_tHc +LeftDown White(Tab)+(A) => Screensaver_BMK + +RightDown (E) => Toggle Beetween M$Dash and Rezn8 + +Up => MenuUp +White(Tab)+(Up) => BMKNextBackground Or BMKNextSmap + +Down => MenuDown +White(Tab)+(Down) => BMKPreviousBackground Or BMKPreviousSmap + +Right => Next SoundTrack +White(Tab)+(Right) => Next Song + +Left => Previous SoundTrack +White(Tab)+(Left) => Previous Song +``` + +--- + +## Credits + +Original Theseus Project by MrMilenko. + +This version is a personal modified version made for testing, customization, and preservation of the original Xbox dashboard style. From abe9b7f335c6a2469137cb2fca48d50910d875f5 Mon Sep 17 00:00:00 2001 From: BenMitnicK Date: Fri, 10 Jul 2026 02:20:14 +0200 Subject: [PATCH 8/8] Add YouTube link to README --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 447c2a1..625429f 100644 --- a/README.md +++ b/README.md @@ -156,6 +156,12 @@ White(Tab)+(Left) => Previous Song --- +## Youtube + +https://www.youtube.com/watch?v=c1mkhrvneNI + +--- + ## Credits Original Theseus Project by MrMilenko.