PORTCLUB
Cabecera de X-Men Legends II: Rise of Apocalypse
Port nativo

X-Men Legends II: Rise of Apocalypse

Port nativo de X-Men Legends II: Rise of Apocalypse para PC.

X-Men Legends II: Rise of Apocalypse

Port nativo basado en su ficha de origen.

README del repositorio

X-Men Legends II — native PC port

Turn X-Men Legends II: Rise of Apocalypse (2005, Activision / Raven / Vicarious Visions) into a native, buildable codebase whose hand-written native subsystems cooperate with shared/x86port's runtime x86-32 JIT. The host maps the user's own PC PE images, dynamically translates every non-native guest path on demand, and hands selected title/engine functions to native overrides.

Direction: one native-overrides + dynarec/JIT gameplay product — see docs/strategy.md. Explicit interpreter mode is confined to a separately built test/diagnostic target. The product may enter a bounded, counted interpreter fallback only when JIT compilation fails or is unsupported, or when executing emitted code would be unsafe; those intervals cannot support gameplay or performance conformance claims.

What is in this repository — and what is not

No game content is distributed here. This repository contains the port's source, its RE notes, and encoding-free analysis metadata used to implement and verify the native host. It ships no game executables, libraries, instruction bytes, textures, audio, or data files. The runtime reads the required restricted inputs from a copy you already own, located through a gitignored .env (see .env.example) or selected through the packaged setup flow. The install directory is treated as strictly read-only; nothing is written back.

You need your own legally obtained copy of the 2005 PC release to build or run anything. Without it the tools refuse rather than degrade: --selftest exits 77 (SKIP) and says nothing was checked.

X-Men Legends II: Rise of Apocalypse is © Activision, developed by Raven Software and Vicarious Visions. Marvel and X-Men are trademarks of Marvel Characters, Inc. This project is unaffiliated with, and unendorsed by, any of them. The runtime reads guest instructions from the player's copy; the repository and release packages contain no game-derived code. The MIT licence in LICENSE covers this repository's own code only and makes no claim over the game.

Setup and run from a fresh clone

The host and packaging layers exist for Linux x86-64, Apple Silicon macOS, and Android ARM64. The x86port ARM64 JIT backend is now present and selected for both Apple Silicon and Android; the remaining work on those targets is host/ABI, executable-memory, and real-title gameplay qualification. The arm64 Mach-O keeps the normal 4 GB __PAGEZERO; guest addresses are translated into a separate reserved 4 GB arena instead of weakening the executable's page-zero guard. Neither the test interpreter nor bounded per-block fallback can substitute for a missing product backend. Native Windows is not implemented.

Install uv, a C/C++ compiler (GCC or Clang), and the native development packages. On Fedora/RHEL-family systems:

sudo dnf install SDL3-devel SDL3_image-devel ffmpeg-free-devel freetype-devel \
  glslc pkgconf-pkg-config vulkan-loader mesa-vulkan-drivers

On Debian 13 or Ubuntu 26.04 and newer:

sudo apt install libsdl3-dev libsdl3-image-dev libavformat-dev libavcodec-dev \
  libavutil-dev libswscale-dev libswresample-dev libfreetype-dev glslc \
  pkg-config libvulkan1 mesa-vulkan-drivers

On Apple Silicon macOS with Homebrew:

brew install sdl3 sdl3_image ffmpeg freetype shaderc pkg-config \
  molten-vk vulkan-loader

Then place the matching PC release at ./game/, put XMen2.exe and the rest of its install directly in the repository or in one immediate child directory, or set GAME_PC_DIR in a gitignored .env. Run:

./run.sh

That command has no modes or arguments. It enters the locked uv environment, validates the game revision, obtains the pinned redistributable dependencies, prepares only native redistributable assets, builds, and launches the JIT gameplay product. It does not analyze the executable or generate guest source, objects, dispatch tables, or any derived guest-code artifact. Ghidra, ImageMagick, a system Python environment, Wine, and pre-existing sibling checkouts are not player prerequisites. Maintainer and diagnostic entry points live under tools/; they are deliberately not commands of run.sh. The re-harness checkout is maintainer-only and is not fetched by the player bootstrap.

Asset-free continuous verification

GitHub Actions runs only repository-owned policy checks and native components that do not need the game. It never receives a game install, an oracle prefix, or a generated substitute for player-derived data. The workflow and its support matrix are checked by uv run --frozen python tools/ci.py policy --target <target>; action revisions are exact commits and Python/CMake/Ninja versions come from the locked environment.

TargetCI evidenceGameplay product status
Linux x86-64policy + native/JIT component build and testsJIT available; CI makes no asset-backed gameplay claim
Apple Silicon macOSpolicy + platform-neutral native component build and testsARM64 JIT present; host/runtime and real-title qualification pending
Windows x86-64policy + llvm-mingw native/JIT component build and testsx86-64 JIT and host boundaries built with llvm-mingw; boots under Wine, native Windows qualification pending
Android ARM64policy + arm64 APK assemblyARM64 JIT present; emulator boot/gameplay and device qualification pending
Web (WASM + PWA)policy + measured wasm32 portability with denominatorsBrowser package build/deployment is in progress; real-title browser execution remains a separate qualification gate (docs/web-release.md)

The Android job deliberately does not compile an APK around a placeholder font ratio, and the macOS job does not use the test interpreter as a substitute JIT. Local asset-backed verification remains the release authority.

Linux AppImage release

The AppImage is launched from a desktop and does not require a terminal or an environment variable. On its first launch, choose Browse and select XMen2.exe from your legally obtained PC installation, or choose a ZIP that contains exactly one XMen2.exe at any depth. The port also checks that every original DLL the native runner maps is beside that executable; it rejects an incomplete selection before replacing a previous one. It then remembers the resulting directory in the OS user configuration directory and keeps the source install read-only. The package contains no game files.

Maintainers can create it after building the native target with:

uv run --frozen python tools/package_appimage.py \
  --linuxdeploy <linuxdeploy.AppImage> \
  --appimagetool <appimagetool.AppImage> \
  --patchelf <patchelf-0.19-or-newer>

linuxdeploy and appimagetool must be available; the output is written to build/release/X-Men-Legends-II-x86_64.AppImage.

The Android APK has the same no-terminal setup rule. Its setup/package shell can be assembled for development with uv run --frozen python tools/build_android.py after selecting the Android SDK and NDK, a supported JDK, and the release signing inputs documented in docs/android-release.md. Its Browse screen uses SAF, stages a ZIP or install folder into app-private storage only after the complete PC install validates, and supplies the same Lucent user-data root used for saves/configuration.

Touch controls are not part of that package. They ship in every build, on every platform, and turn themselves on for whoever is touching a screen — a Windows or Linux tablet and a 2-in-1 get the on-screen pad and the mobile HUD placement exactly as a phone does, while an Android player holding a controller gets neither. The Input setting (input.touch_controls) forces either end anywhere, so the layout can be looked at on a desktop with no touchscreen. Movement uses the left thumb; Jump, Attack, Smash, and Use form the right-hand diamond. Hold Powers above the left stick to select an ability with the right thumb. Bold outlined SVG icons and short labels remain readable over the scene. See docs/touch-play.md.

Touch controls during gameplay, captured with the native Vulkan renderer The missing ARM64 JIT backend and mobile performance evidence are tracked in docs/project-state.md and docs/android-release.md.

Sources

  • PC build ($GAME_PC_DIR): XMen2.exe (2.61 MB) + 16 libIG*.dll + cgD3D8.dll / cg.dll / libMovie.dll — 6.47 MB of x86 machine code total, consumed directly by the runtime JIT rather than emitted into the build. Much of the gameplay is data-driven (Data/*.XMLB = compressed XML, Data/*.engb = Enbaya, Scripts/ Lua, Conversations/, missions/, entities/, Maps/).
  • Xbox ISO ($XBOX_ISO): default.xbe (5.7 MB) plus its packages — the ground truth for the Xbox release's controller defaults and controller UI. No Xbox asset is shipped by this repository; prompt art is this port's SVG.
  • Alchemy 5.0 Kit (archive.org alchemy-kit_202309, 152 MB): engine source + docs. The architectural Rosetta stone. XML2 ships Alchemy 3.2; 5.0 assets are version- incompatible but the engine architecture (igCore/igDisplay class model, IGB format, file-package system, DLL boundary) is directly analogous.

shared/alchemy provides partial native IGB/image/mesh/raster/Enbaya and input libraries plus XMLB/ARK tools. x2native now links its neutral alchemy::input target and publishes the same latched controller sample through a title-owned igControllerManager adapter while retaining DirectInput as an A/B oracle. This establishes the dependency and conformance seam; real-game callback/hotplug evidence is still required before the retained concrete path can be removed. MUA remains deferred until every X-Men 2 goal is verified, then migrates to the proven engine without a gameplay rewrite.

The durable outcomes are in docs/project-goals.md; factual capability coverage, gaps and the current focus are in docs/project-state.md.

Features and enhancements over the vanilla PC release

The port keeps the original game data and retail game logic as its baseline, while adding a native host and quality-of-life improvements that the 2005 PC release does not provide:

  • Wine-free native execution (partial) through SDL3, native overrides, and runtime x86 translation. Linux x86-64 has the current product JIT; Apple Silicon and Android remain intended hosts but need an ARM64 x86port backend.
  • Controller hot-plug and persistent assignment through SDL3, including late attach/detach and player assignment without restarting the game.
  • Xbox/PS2-style controller defaults and source-aware prompts, with controller glyphs and keyboard keycaps selected for the active input source.
  • Port-owned settings and presentation controls, including window mode, aspect-fit presentation and live display changes where supported by the current host.
  • Native cutscene skipping that advances the authored cutscene work while preserving the guest clock and avoiding stray dialogue/audio presentation.

The current product is still an active port: native execution and the reached menu, movie, level and return-to-menu paths are verified, but full physical controller playability and complete renderer fidelity remain partial. See docs/project-state.md for the exact coverage.

The input-specific features are:

  1. Controller hotswap — implemented through SDL3 and the game's own DirectInput enumeration/connection callbacks; late attach and detach are exercised by a frame-scheduled virtual pad.
  2. Controller defaults UI — implemented at the retained PC controller editor: Keyboard Defaults keeps the shipped keyboard table and Xbox Defaults applies the assignments recovered from the Xbox executable—not a modern mapping invented by the port. Black/White pack use remains a direct-action RE boundary because the PC binding table has no Health/Energy rows.
  3. Xbox button prompts — the input-name overrides publish private prompt codepoints for the active controller or keyboard source, and the engine's own text layout positions them. The port renders shared SVG art from its own GPU atlas at the RE'd Alchemy text-batch boundary; the game's font pixels and UVs remain untouched. Only width, height, advance and baseline metrics for those private cells are published in memory. The 21-row bindable Xbox preset and native prompt draw path are implemented.

Verification

  • Oracle: the original PC build under Wine. tools/run_shim.py <rundir> runs it headless on Xvfb and captures a frame; scratch/run/stock is the unmodified reference and scratch/run/proxy swaps in our DLL. Both are symlink farms — the real game install is never modified.
  • Notes: search docs/ with rg before re-deriving anything.

Progress tracking

Current status is owned by docs/project-state.md. docs/codemap.md maps responsibility and placement only; docs/re-frontier.md orders binary-grounded RE work and names shortcut debt. uv run --frozen python tools/re_frontier.py next is the executable view.

Reference materials (M1)

  • Alchemy 5.0 Kit at scratch/ref/alchemy5/Alchemy50/ (gitignored; re-download from archive.org alchemy-kit_202309 if lost). Contents:
    • include/ — full engine header suite (igCore/igDisplay/igSg/igGfx/...). Verified: igController::BUTTONS, igControllerManager::initializeControllers match the XML2 libIGDisplay.dll binary exactly → Alchemy 3.2 class API ≡ 5.0 headers.
    • DirectX9/lib/ — prebuilt Alchemy 5.0 engine DLLs (reference behavior).
    • sources/ — app source only (insight/viewer/libMovie/animationProducer), NOT the engine core source.
    • bin/ — tools: igen.exe, igbTypes.exe, sgOptimizer.exe, lua.exe, eventTracker.exe.
    • docs/ — PDFs (GettingStarted, UsersGuide).
    • .igo files beside headers are compiled meta-object descriptors (serialization schema).
  • raven-formats (nikita488, MIT) at tools/raven-formats/ — Python XMLB/engb/fb/zsnd read+write. Installed with pip install -e tools/raven-formats; CLI: python3 -m raven_formats.xmlb -d in out. Verified on PC Data/colors.XMLB, herostat.engb/XMLB.
  • XMLB vs engb are the same format; engb uses global @DATA@... string-pool refs, XMLB inlines strings. Both decompile to identical XML modulo those refs.
  • Community: XMLBCUI (old compiler), alchemymarvel.miraheze.org wiki, serptools IGB docs, igb-blender addon, EthanReed517/XML2-Ultimate-Patch.

Conventions

  • Repo root is CWD for all work. Machine-specific paths live only in .env (gitignored), template in .env.example.
  • Transient run artifacts go to gitignored scratch/; compiler outputs, generated assets, dependencies, and packages go to gitignored build/. Nothing uses /tmp.
  • RE scripts in tools/; Ghidra project in build/ghidra/.
  • tools/pe.py reads PE32 exports/imports/sections and generates proxy .def files; tools/run_shim.py runs the game headless for A/B comparison.
  • No copyrighted game assets committed to git; they stay in the game dirs referenced by .env.

Current state

The x86-64 JIT path runs real game code with native overrides active. Prior headless observations reached main menu → New Game → difficulty → story cutscene → loaded and simulated level → death dialog → rendered main menu. Earlier test-only differential sessions compared hundreds of millions of in-game JIT block entries without divergence. These are real execution and regression facts, but they are not the complete product gate: a bounded representative interactive gameplay scenario, an independent oracle comparison, and the product execution-boundary audit remain open.

./run.sh is the supported default launcher: with no arguments it builds when needed and runs the current native SDL3 GPU game target. It records the exact DirectInput states returned to the game under scratch/recordings/, and tools/x2ctl.py discovers the live PID, port, and recording without manual flags. Wine oracle/control workflows remain separate tools and cannot become an accidental launcher mode.

What that does not mean. It is not yet release-qualified in the sense that matters. The consumer-proven JIT revision in the canonical shared/x86port checkout still has to be published and reconciled with this project's pin, the x86-64 gameplay product must prove that explicit interpreter selection is absent and any bounded fallback is counted and reported, and every declared host needs a real JIT backend. Apple Silicon and Android ARM64 cannot use interpretation as a substitute backend. Controller enumeration, polling and hotswap run end-to-end under a synthetic pad; an equivalent physical-pad play-through has not been done. The renderer accepts every draw the engine issues and reads every render state the engine sets except fog and specular, which this title disables — but "nothing is refused" is a statement about coverage, not about the picture being right. See docs/project-state.md for the capability status, docs/codemap.md for subsystem ownership, and docs/info/claims/ for what has been proven, each with the observation that would falsify it.

Earlier facts established during RE (see the durable claims under docs/info/):

  • The game uses DirectInput 7 and 8. The native host serves both through one device implementation; joystick hotswap re-enters the game's own enumeration routine rather than writing its controller table from the host (C160/C161).
  • BUTTONS enum + ControllerType meta-enum extracted from libIGDisplay.dll.
  • Xbox assetsfb.wad is ZIP-like with a trailing block; entries are raw deflate; extractor in tools/extract_wad.py.
  • The Xbox button art is not in the HUD font and is not addressable by existing medium-font codepoints. This port rasterises shared SVG equivalents into its own GPU atlas and inserts them at the RE'd Alchemy text-batch boundary; the shipped font assets remain untouched.

Built with AI assistance (Claude and other LLMs).

Comentarios (0)

Inicia sesión para dejar un comentario.

Sé el primero en comentar sobre este juego.