Saltar al contenido
PORTSNATIVE.
InicioCatálogo
Juegos WebEmuladoresHerramientasNovedades
PORTSNATIVE.

Un catálogo para descubrir ports y proyectos relacionados. Enlazamos a las fuentes oficiales y no alojamos archivos de los juegos originales.

ExplorarCatálogoMi lista
InformaciónNosotrosProponer un portSoporteApoyo y donacionesAviso legal
© 2026 PortsNative
Volver al catálogo
Castlevania: Legacy of Darkness (PC)
PORTSNATIVE

Castlevania: Legacy of Darkness (PC)

PORT NATIVOPLATAFORMASWINDOWSANDROIDALPHA

Castlevania: Legacy of Darkness (PC)

Castlevania: Legacy of Darkness

OrigenNintendo 64

TecnologíaRecompilación Estática (C/C++ nativo)

Disponible paraWindows, Android

Ver proyecto oficial

Sobre el proyecto

Castlevania Legacy of Darkness es un videojuego desarrollado y publicado por Konami para Nintendo 64. Pertenece a la serie Castlevania y es una precuela del videojuego Castlevania 64, publicado con anterioridad también para Nintendo 64 pero con una historia posterior dentro de la saga. Castlevania: Legacy of Darkness salió al mercado el 30 de noviembre de 1999 en Norteamérica, el 25 de diciembre de 1999 en Japón y el 3 de marzo de 2000 en Europa, siendo el segundo y último juego de la serie Castlevania que llegó a Nintendo 64.

2 versiones de Castlevania: Legacy of Darkness

Estás viendo: Castlevania: Legacy of Darkness (PC)

Castlevania: Legacy of Darkness (PC)github.com/sergiomanzur/cvlod_recomp
Windows
Android
Actual
Castlevania: Legacy of Darkness Recompiledgithub.com/fliperama86/cvlod_recomp
Windows
Linux
macOS
›

Información oficial del proyecto

README original del autor (en inglés)Abrir en GitHub ↗

Castlevania: Legacy of Darkness recompilation WIP

This repository is an in-progress recompilation/recovery project. The current goal is to reach and stabilize real gameplay while preserving enough telemetry to diagnose remaining crashes.

Reproducible checkout for testers

Testers should pin the top-level repository commit, not individual submodule commits. The top-level commit records the exact submodule SHAs that should be used.

Maintainer/tester flow:

git clone --recursive https://github.com/fliperama86/cvlod_recomp.git
cd cvlod_recomp
git checkout <top-level-sha-provided-by-maintainer>
git submodule sync --recursive
git submodule update --init --recursive
git submodule status --recursive

If the repo was already cloned:

git fetch origin
git checkout <top-level-sha-provided-by-maintainer>
git submodule sync --recursive
git submodule update --init --recursive
git submodule status --recursive

Do not run:

git submodule update --remote

--remote advances submodules to newer upstream commits and can move testers away from the known baseline.

ZeldaRecomp menu primary build

Primary builds use the imported Zelda64Recomp menu framework/assets by default. The legacy LoD overlay remains available for fallback/debug builds with -DLOD_USE_ZELDA_MENU=OFF. Because the imported menu framework/assets are GPL-3.0, this branch is licensed under GPL-3.0-only; see LICENSE and docs/ZELDA_MENU_PORT.md.

Current important submodules

The exact pins are determined by the checked-out top-level commit. For reference, the current baseline records these key submodules:

lib/N64ModernRuntime  366e1499288f78a2dc91100bb6083afa51dc7639
lib/rt64              589e172da86f8390cb7d31b904494c522a8f46ba
lib/RmlUi             7a06f27db04fe5d13a5dacc19b2b4544673a4eca
lib/lunasvg           4166d0cccfc059b39d5ecfc372524375e59448f9

Use git submodule status --recursive to report the actual SHAs when filing build or crash reports. If these differ after checking out the maintainer-provided top-level SHA and running git submodule update --init --recursive, the checkout is not on the expected baseline.

Generated/local files

ROMs and generated artifacts are intentionally not fully distributed through Git.

A source build/test checkout needs, at minimum, the generated RecompiledFuncs/ outputs and runtime ROM resources expected by the project, including:

RecompiledFuncs/funcs.h
RecompiledFuncs/recomp_overlays.inl
RecompiledFuncs/*.c              # full generated set, not only tracked patched files
rom.z64                          # preferred runtime name; stock Castlevania: LoD ROM image

Developer checkouts may also use the older resources/*.z64 layout as a fallback, but release binaries prefer ./rom.z64.

For source regeneration on macOS/Linux, do not run N64Recomp directly. Use:

./tools/regen_recomp.sh

That script verifies the tool, repairs known truncation issues, reapplies patches, and keeps symbol replacements consistent. On Windows, follow the equivalent step-by-step pipeline in Regenerating RecompiledFuncs on Windows. If external testers are only validating Windows builds/gameplay, the maintainer should provide a prepared source/resources bundle or generated artifact bundle matching the top-level commit.

macOS release / tag run instructions

Running the macOS binary asset

Download the macOS .app asset from the GitHub release, extract it, and place your legally dumped stock Castlevania: Legacy of Darkness ROM next to the app as rom.z64:

LodRecomp.app
rom.z64

The current macOS app is Apple Silicon/arm64, ad-hoc signed, and links against Homebrew SDL2 and Freetype. Install runtime dependencies if needed:

brew install sdl2 freetype

From the extracted folder, double-click LodRecomp.app, or run:

open ./LodRecomp.app

On first launch, macOS may block the ad-hoc signed app. Open System Settings → Privacy & Security, choose Open Anyway, then confirm Open.

The app intentionally looks for rom.z64 beside LodRecomp.app first, so keep both files in the same folder. If no valid ROM is found — for example because macOS App Translocation hides the adjacent file — the app opens an in-window ROM Setup screen. Choose your stock LoD ROM with the native file picker; after validation succeeds, the selected path is remembered for future launches. Runtime NI overlay data is prepared in memory from the stock ROM on startup; users do not need to run a separate preparation script.

Graphics/settings overlay

The app creates persistent settings and a current-session log in its config folder. The log is LodRecomp.log, is truncated on each launch, and keeps the most recent 512 KiB of output by default. On macOS this is under ~/Library/Application Support/LodRecomp/; on Windows it is under %APPDATA%\LodRecomp\. Fresh configs default to Original2x internal resolution; existing configs are preserved.

To use portable mode, create an empty portable.txt beside LodRecomp/LodRecomp.app. Config files and saves will be stored in that same folder.

For repro/debug builds, you can override only the save location without moving configs:

./LodRecomp --save-path /path/to/castlevania2.n64.us.bin
./LodRecomp --save-dir /path/to/saves

--save-path uses the exact file. --save-dir uses <dir>/castlevania2.n64.us.bin. Do not pass both.

For boss/crash repros where survival is the only goal, LOD_CHEAT_INFINITE_HEALTH=1 enables a default-off infinite-health GameShark-equivalent runtime poke.

The overlay starts hidden. Press F1 to show/hide the in-game RmlUi settings overlay. The current overlay includes General, Graphics, Controls, and Audio tabs. Graphics options are clickable and staged until Apply writes graphics.json; Discard restores the active renderer values. Esc / controller B closes the overlay, prompting first if graphics changes are pending.

Release packages include the RmlUi assets required by the Zelda-style launcher and settings UI. CI runs short packaged-app smoke tests where the hosted runner graphics stack supports it, plus packaged asset checks for the macOS app bundle.

Existing graphics hotkeys are still supported:

KeyAction
F1Show/hide the RmlUi settings overlay
EscClose prompt/settings overlay
F11Toggle windowed/fullscreen
F5Cycle internal resolution mode (Original, Original2x, Auto)
F6Cycle aspect ratio mode (Original, Expand, Manual)
F7Cycle anti-aliasing (None, MSAA2X, MSAA4X, MSAA8X)
F8Cycle refresh-rate mode (Original, Display, Manual)

Graphics hotkeys apply live and save automatically during gameplay. When the overlay is open, those same graphics hotkeys stage pending UI changes until Apply; if a confirmation prompt is open, they are consumed without changing settings behind the prompt.

Native LoD Expansion Pak high-resolution mode is currently skipped in default builds. The runtime still maps/guards the internal 8MB RDRAM mirror and reports 4MB to the game, but the selector still appears on the stock boot path; default builds therefore hard-skip only that selector (gs=12) by requesting the normal post-selector transition (gs=-5, which creates gs=5) to keep testers on the validated low-resolution route. Developers can investigate the native selector/high-res route with -DLOD_SKIP_EXPANSION_PAK_SCREEN=OFF -DLOD_ENABLE_NATIVE_HIGH_RES=ON.

Building from a release tag

GitHub releases are also tagged source baselines. Use the release tag with git clone --recursive; do not rely on GitHub's auto-generated "Source code" zip/tarball for a fresh build because it does not include submodule contents and it still requires the local/generated files listed above.

Prerequisites:

xcode-select --install
brew install cmake ninja pkg-config sdl2 freetype

Checkout a release tag, for example v0.1.2:

git clone --recursive --branch v0.1.2 https://github.com/fliperama86/cvlod_recomp.git
cd cvlod_recomp
git submodule sync --recursive
git submodule update --init --recursive
git submodule status --recursive

Before building, provide the generated/local files listed in Generated/local files, especially a stock rom.z64 and the full generated RecompiledFuncs/ output matching the release tag.

Build:

cmake -S . -B build-macos -G Ninja -DCMAKE_BUILD_TYPE=RelWithDebInfo
cmake --build build-macos --target LodRecomp --parallel

Codesign before running on macOS:

codesign -s - --entitlements .github/macos/entitlements.plist -f build-macos/LodRecomp

Run from the repository root so ./rom.z64 resolves:

./build-macos/LodRecomp

For tester reports against a release, include:

git rev-parse HEAD
git describe --tags --always --dirty
git submodule status --recursive

Linux build

Validated on Ubuntu 24.04/aarch64 in Docker with Clang 18. GCC currently fails at the final link step because generated RECOMP_FUNC symbols are strong under GCC, which conflicts with the project override shims. Use Clang for Linux builds.

Prerequisites on Ubuntu 24.04:

sudo apt-get update
sudo apt-get install -y \
  git build-essential cmake ninja-build pkg-config python3 clang lld \
  libsdl2-dev libfreetype-dev zlib1g-dev libvulkan-dev libgtk-3-dev \
  libx11-dev libxrandr-dev libxi-dev libxcursor-dev libxinerama-dev

From the repository root, after git submodule update --init --recursive and after copying/providing the generated/local files listed above:

CC=clang CXX=clang++ cmake -S . -B build-linux -G Ninja -DCMAKE_BUILD_TYPE=RelWithDebInfo
cmake --build build-linux --target LodRecomp --parallel

Run from the repository root so relative resources/... paths resolve:

./build-linux/LodRecomp

Windows

Running the Windows binary asset

Download LodRecomp-vX.Y.Z-windows-x64.zip from the GitHub release, extract the whole folder (keep the DLLs next to the exe), and place your legally dumped stock Castlevania: Legacy of Darkness ROM in the same folder as rom.z64:

LodRecomp.exe   (+ SDL2.dll, dxcompiler.dll, dxil.dll, freetype.dll, ...)
rom.z64

If no valid rom.z64 is found, the app opens an in-window ROM Setup screen. Choose your stock LoD ROM with the native file picker; after validation succeeds, the selected path is remembered for future launches.

The binary is not code-signed yet, so the first launch may show a SmartScreen "Windows protected your PC" prompt — click More info → Run anyway. Verify the download against the SHA256 checksum published in the release notes first.

Config files (graphics.json, controls.json) and the current-session log (LodRecomp.log) are stored in %APPDATA%\LodRecomp.

Building from source on Windows

The Windows build requires clang-cl (the ClangCL toolset). Plain MSVC cl cannot build the project: it hard-errors on the GNU-style warning flags used by the runtime submodules, and COFF builds rely on /FORCE:MULTIPLE + link order instead of ELF weak-symbol interposition for the RECOMP_FUNC override shims.

Prerequisites:

  • Git
  • Visual Studio 2022 (or Build Tools) with the Desktop development with C++ workload and the "C++ Clang tools for Windows" component (provides clang-cl and the ClangCL MSBuild toolset)
  • CMake 3.20+
  • vcpkg-provided ZLIB and Freetype (Freetype is required by RmlUi on every platform)
# One-time vcpkg setup, if needed
git clone https://github.com/microsoft/vcpkg C:\src\vcpkg
C:\src\vcpkg\bootstrap-vcpkg.bat
C:\src\vcpkg\vcpkg install zlib:x64-windows freetype:x64-windows

# From the repo root — note the ClangCL toolset (-T ClangCL)
cmake -S . -B build-win -G "Visual Studio 17 2022" -A x64 -T ClangCL `
  -DCMAKE_TOOLCHAIN_FILE=C:/src/vcpkg/scripts/buildsystems/vcpkg.cmake
cmake --build build-win --config RelWithDebInfo --target LodRecomp

SDL2 is fetched automatically by CMake on Windows. The RT64 DXC DLLs are copied from the lib/rt64 submodule and the vcpkg runtime DLLs are deployed next to the exe during the post-build step.

If a parallel build fails with Permission denied errors on CMake *.tmp stamp files (concurrent per-project re-configures racing), re-run the configure once and build serially:

cmake -S . -B build-win
cmake --build build-win --config RelWithDebInfo --target LodRecomp -- /m:1

Run from the repository root so ./rom.z64 and relative resources/... paths resolve:

.\build-win\RelWithDebInfo\LodRecomp.exe

Regenerating RecompiledFuncs on Windows

tools/regen_recomp.sh is a bash/macOS pipeline and expects the maintainer's known-good N64Recomp binary. On Windows, the equivalent validated flow (output verified byte-identical to the macOS generation) is:

# 1. Build the N64Recomp CLI from the clean, pinned submodule
cmake -S lib\N64ModernRuntime\N64Recomp -B build-n64recomp -G "Visual Studio 17 2022" -A x64
cmake --build build-n64recomp --config Release --target N64RecompCLI

# 2. Prepare the NI-extended ROM from the stock ROM (use python, not python3)
python tools\ni_ovl\step1_dump_table.py rom.z64
python tools\ni_ovl\step2_decompress.py rom.z64
python tools\ni_ovl\step3_boundaries.py
python tools\ni_ovl\step4_functions.py
python tools\ni_ovl\step6_extended_rom.py rom.z64   # needs resources\ to exist

# 3. Run N64Recomp (exits non-zero on the known overlay_system message; that is expected)
.\build-n64recomp\Release\N64Recomp.exe recomp.toml

# 4. Post-processing chain (same order as regen_recomp.sh)
python tools\fix_n64recomp_truncation.py
python tools\ni_ovl\repair_overlay_table.py --fix
python tools\ni_ovl\fix_undeclared_labels.py
python tools\apply_patches.py
python tools\apply_symbols.py

The Windows N64Recomp build aborts slightly later than the macOS one, producing two extra artifacts that the fixer chain now handles automatically: a dangling overlay_sections_by_index opener in recomp_overlays.inl, and a duplicate static_*_0E0037A0 definition. The N64Recomp submodule source must be clean (git -C lib/N64ModernRuntime/N64Recomp status) — never regenerate with a modified tool.

Android port

Validated on a Retroid Pocket 6 (Snapdragon 8 Gen 2, Adreno 740, Android 13). The port is a Gradle wrapper around the same CMake project, so the game logic, RT64 renderer and UI are shared with the desktop builds. Vulkan 1.1 is required and declared mandatory in the manifest.

Running the APK

Download app-release.apk from the GitHub release and install it by opening the file on the device (you will need to allow installs from your browser or file manager). No ROM is bundled: on first launch the launcher asks you to pick your own legally dumped Castlevania: Legacy of Darkness (USA) ROM through the Android document picker. The ROM is copied into the app private storage (/data/data/org.cvlod.recomp/files/) and validated before the game will start. You do not need to place it under Android/data or grant the app broad storage access: tap Select ROM in the launcher and choose the file from Downloads or another document provider.

Because the ROM, saves and settings all live in app private storage, uninstalling the app deletes your saves. Android also forces an uninstall when an APK is signed with a different key, so keep to APKs from the same release stream if you care about your save files.

Controls

A physical controller is picked up automatically through SDL, including the built-in pads on handhelds like the Retroid. For touch-only devices there is an on-screen overlay:

  • It is on by default on Android and the choice persists in controls.json. Existing saved choices are respected.
  • The game controls appear during gameplay and step aside whenever a menu is open. A small SHOW/HIDE button remains visible in gameplay, including while a menu is open, so touch users can restore the controls without a physical pad.
  • The full N64 layout is provided (analog stick, A, B, Z, L, R, Start and the four C buttons) plus a MENU button, which is the only way to reach the emulator menu without a keyboard or controller.
  • Touch input is additive, so the overlay and a physical pad can be used at the same time.

Cheats

Settings -> Cheats exposes six toggles (invincibility, money, red jewels, all consumables, max power-ups and Henry's ammunition) implemented as GameShark-style RDRAM writes re-applied every VI. They persist in cheats.json and the launcher shows a warning while any are active, so a save file cannot be quietly shaped by a cheat you forgot about.

Building the APK

Prerequisites:

  • Android SDK with platform 34 and NDK 26.x (the CMake toolchain comes from the NDK)
  • CMake 3.22.1 as shipped by the SDK
  • JDK 17. The Android Gradle Plugin 8.5.1 will not run on Java 8, and newer JDKs are not supported by this Gradle version. Point JAVA_HOME at a 17 install, for example the one bundled with Android Studio.

Set the SDK location in android/local.properties (not committed):

sdk.dir=/absolute/path/to/Android/Sdk

Vendored submodule patches (required)

Two fixes the Android port depends on live inside submodules this repository does not own:

cvlod_recomp -> lib/rt64 (fliperama86/rt64) -> src/contrib/plume (renderbag/plume)

They cannot be committed here, so they are vendored as diffs in patches/ and re-applied after a fresh submodule checkout:

python tools/apply_submodule_patches.py          # apply (idempotent)
python tools/apply_submodule_patches.py --check  # report status only

The Gradle build runs this automatically before compiling, so a normal ./gradlew assembleRelease needs no extra step. Run it by hand for the desktop CMake builds.

patches/plume.patch is not optional: without it the game crashes on "Start game" on Adreno GPUs, because RT64 sizes the Vulkan descriptor pool to the requested variable count while Adreno accounts it against the descriptor count declared in the set layout, so vkAllocateDescriptorSets returns VK_ERROR_OUT_OF_POOL_MEMORY and the failed allocation leaves a null handle that is dereferenced later. patches/rt64.patch additionally supplies file_to_c.py, which rt64's CMakeLists invokes during the shader build but which is not tracked upstream.

Then, after git submodule update --init --recursive and after providing the generated/local files listed above, build from the android/ directory:

cd android
JAVA_HOME=/path/to/jdk-17 ./gradlew assembleRelease

The APK is written to android/app/build/outputs/apk/release/app-release.apk and contains both arm64-v8a and x86_64. A debug build works too but is not playable: the recompiled game functions are compiled -O0, which is the difference between full speed and roughly a third of it. Always test with assembleRelease.

Two things worth knowing about the build:

  • Do not pass -Pandroid.injected.build.abi=.... It halves build time by skipping an ABI, but it also marks the APK android:testOnly=true, which can then only be installed via adb install -t and cannot be distributed.
  • versionName/versionCode are derived from the repo VERSION file, so bump that rather than editing android/app/build.gradle.kts.

Android-specific implementation notes

  • The shared assets/ tree is staged into the APK by the stageGameAssets Gradle task and unpacked to filesDir/assets on launch, refreshed whenever the installed package changes. The desktop builds get these files from the LodRecompAssets CMake target, which cannot apply to an APK.
  • SplashActivity shows the splash art before handing off to MainActivity. A theme windowBackground alone is not enough, because SDL covers it within ~200ms of launch.
  • Menu music plays through Android MediaPlayer rather than the SDL device, since the project has no MP3 decoder. Its volume follows the in-app master volume and mute.
  • A release build cannot currently emit diagnostics: adb run-as is refused when the package is not debuggable, and fprintf(stderr, ...) does not reach logcat. Add isDebuggable = true to the release build type temporarily if you need to read LodRecomp.log off a device.

Audio baseline and useful CMake flags

The default build is intended to produce audible game audio. The current audio baseline is:

  • LOD_USE_RECOMPILED_AUDIO_RSP=ON — uses the generated LoD audio RSP microcode instead of the timing-only stub.
  • LOD_OVERRIDE_ALENVMIXERPULL=OFF — keeps the real alEnvmixerPull path active. Turning this override on mutes synthesis and is only useful for A/B diagnostics.

These are the defaults, so normal testers should not need to pass audio flags. If you need to state them explicitly:

cmake -S . -B build -DLOD_USE_RECOMPILED_AUDIO_RSP=ON -DLOD_OVERRIDE_ALENVMIXERPULL=OFF

Debug audio traces remain default-off. Use LOD_ENABLE_AUDIO_TRACE, LOD_ENABLE_RSP_AUDIO_TRACE, LOD_ENABLE_AUDIO_PULL_TRACE, or LOD_ENABLE_AUDIO_RAW_DUMP only for targeted diagnostics, and include those flags in crash/test reports.

Controls

Keyboard input remains available:

  • Enter = N64 A
  • Right Shift = N64 B
  • Z = N64 Z
  • Space = Start
  • Arrow keys = D-pad
  • WASD = analog stick

SDL game controllers are also supported. Xbox controllers and DualSense/DualShock controllers should be detected through SDL's standard GameController mappings:

  • A / Cross = N64 A / jump
  • X / Square = N64 B / attack 1 / primary attack
  • Y / Triangle = N64 C-Left / attack 2 / secondary attack
  • B / Circle = N64 C-Right / collect / interact
  • Start / Options = Start
  • Left stick = analog stick
  • D-pad = N64 D-pad
  • Left stick click / L3 = N64 R / lock-on
  • Right bumper / R1 = N64 C-Down / throw item
  • Left trigger / L2 = N64 Z
  • Right trigger / R2 = N64 L
  • Right stick = inverted N64 D-pad / camera

Gamepad controls are configurable by editing controls.json in the same config directory as graphics.json:

  • macOS: ~/Library/Application Support/LodRecomp/controls.json
  • Windows: %APPDATA%\LodRecomp\controls.json
  • Linux/other local builds: ~/.lodrecomp/controls.json

The file is created on first launch. Edit it while the game is closed, then relaunch. Valid N64 binding values are:

none, n64_a, n64_b, n64_z, n64_start,
n64_dpad_up, n64_dpad_down, n64_dpad_left, n64_dpad_right,
n64_l, n64_r,
n64_c_up, n64_c_down, n64_c_left, n64_c_right

Example:

{
  "gamepad": {
    "buttons": {
      "a": "n64_a",
      "b": "n64_c_right",
      "x": "n64_b",
      "y": "n64_c_left",
      "start": "n64_start",
      "left_stick": "n64_r",
      "right_bumper": "n64_c_down",
      "dpad_up": "n64_dpad_up",
      "dpad_down": "n64_dpad_down",
      "dpad_left": "n64_dpad_left",
      "dpad_right": "n64_dpad_right"
    },
    "axes": {
      "left_trigger": "n64_z",
      "right_trigger": "n64_l",
      "trigger_threshold": 12000
    },
    "right_stick": {
      "mode": "n64_dpad",
      "invert_x": true,
      "invert_y": true,
      "deadzone": 0.5
    }
  }
}

Crash/test reports

When reporting a crash or regression, include:

  • Top-level commit SHA: git rev-parse HEAD
  • Submodule SHAs: git submodule status --recursive
  • Build flags/CMake options used
  • LodRecomp.log from the config folder or portable folder. It is truncated on each launch, keeps a header plus the most recent 512 KiB, and can be enlarged for targeted debugging with LOD_LOG_MAX_KB=4096.
  • Whether the run used low-resolution or high-resolution mode

Known current posture is tracked in docs/RECOVERY_TO_GAMEPLAY.md.

Leer guía oficial
CALIFICACIÓN
—
Cargando votos…
Publicidad

FICHA DEL PROYECTO

Tipo de proyecto
PORT NATIVO
Género
Plataformas
Estado
alpha
Plataforma de origen
Nintendo 64
Tecnología
Recompilación Estática (C/C++ nativo)
Versión
—
Actualización
—

Plataformas de destino 2

Windows
Android
Ver en GitHub
Publicidad