Skip to content
nolffanPublic

About

Contract J.A.C.K. source code

Topics

Resources

Stars

16 stars

Watchers

2 watching

Forks

Latest commit

 

History

465 Commits

Folders and files

Repository files navigation

cjacksrc

Contract J.A.C.K. (Monolith, 2003), built from source.

Monolith never released Contract J.A.C.K.'s source, as it did for No One Lives Forever 2. This project reconstructs it: the game code from NOLF2's source release (Contract J.A.C.K. was built from the same tree, C:\proj\to2\source\Game\, as its binaries' strings show), and the engine from the LithTech Jupiter engine source (the 2006 distribution of the same engine line, built with the same compiler), each brought to what the retail binaries are, function by function. As for nolfsrc and nolf2src, the aim is two builds:

  • legacy: Contract J.A.C.K. (Europe) at its last update, 1.1, rebuilt so that it compiles back to the retail binaries byte for byte, as far as that can be done -- with the compiler Monolith used, Visual C++ .NET 2003 (13.10.3077), under Wine;
  • modern: the same source with fixes and new features (CJACK_MODERN).

Compiling back to the retail bytes means compiling the retail game's bugs as well; their fixes go behind CJACK_MODERN, into the modern build only, so the legacy build keeps matching the retail one.

Where it stands

Started. The retail game is installed from its discs and update (ext/rez/), the compiler is in ext/toolchains/ (msvc-7.10-3077), and the scoreboard scores every retail binary against our build. ltmsg.dll is built (the retail file but for its link time stamp) and SndDrv.dll builds; the rest is to come. docs/PLAN.md is the plan, package by package.

Progress

How much of each binary compiles to exactly the bytes of the retail game (version 1.1). A function counts when our compiled code is identical to the retail function, with only the addresses the linker fills in left out of the comparison; the bars measure the share of each binary's code, by size, those functions make up.

Binary Byte-identical functions Byte-identical code Unwritten Unplaced
Lithtech.exe the engine 7,297 / 7,972 1,126,387 / 1,163,487 bytes ███████████████████░ 96.8% 0 38
server.dll the engine's server 2,902 / 3,136 392,698 / 403,695 bytes ███████████████████░ 97.2% 0 10
SndDrv.dll the sound driver 251 / 264 28,521 / 28,605 bytes ███████████████████░ 99.7% 0 0
GameSpy.dll the GameSpy services 176 / 191 19,322 / 20,268 bytes ███████████████████░ 95.3% 0 0
ContractJack.exe the launcher 328 / 344 40,582 / 40,763 bytes ███████████████████░ 99.5% 0 0
ContractJackServer.exe the dedicated server 627 / 669 75,174 / 75,852 bytes ███████████████████░ 99.1% 0 0
CShell.dll the game: client 6,329 / 6,658 1,092,275 / 1,155,989 bytes ██████████████████░░ 94.4% 0 0
Object.lto the game: server objects 9,507 / 9,876 1,590,396 / 1,638,452 bytes ███████████████████░ 97.0% 0 0
ClientFx.fxd the game: client effects 443 / 455 104,672 / 104,763 bytes ███████████████████░ 99.9% 0 0
ltmsg.dll the engine's messages, not in the total 5 / 5 resources 2,054 / 2,054 bytes ████████████████████ 100.0% 0 --
CRes.dll the game's client resources, not in the total 457 / 457 resources 330,555 / 330,555 bytes ████████████████████ 100.0% 0 --
SRes.dll the game's server resources, not in the total no resources -- -- -- --
Lithtech.exe:rsrc the engine's resources, not in the total 18 / 53 resources 8,296 / 20,810 bytes ███████░░░░░░░░░░░░░ 39.8% 1 --
server.dll:rsrc the engine's server's resources, not in the total 2 / 2 resources 760 / 760 bytes ████████████████████ 100.0% 0 --
ContractJack.exe:rsrc the launcher's resources, not in the total 101 / 101 resources 4,917,154 / 4,917,154 bytes ████████████████████ 100.0% 0 --
ContractJackServer.exe:rsrc the dedicated server's resources, not in the total 18 / 18 resources 937,508 / 937,508 bytes ████████████████████ 100.0% 0 --
All 27,860 / 29,565 4,470,027 / 4,631,874 bytes ███████████████████░ 96.5% 0 48

Every function in that table is recorded in progress/identical.txt, and make progress re-scores the current build against the retail binaries and fails if any of them stops matching. See progress/README.md for how the scoring works and what it leaves out. Which compiler built each binary, and the evidence, is progress/COMPILERS.md.

Building

Needs docker and the submodules (git submodule update --init): ext/toolchains/ (the compilers), ext/rez/ (which fetches the European discs from archive.org and installs the game with its 1.1 update), ext/tools/ (the reconstruction tools) and ext/lithtools/ (whose lithrez packs the 1.1 update's data, assets/, into cjacksrc.rez); and, for make modern, ext/ffmpeg (FFmpeg n8.1.3, which the modern build's Bink player is built on, by build/ext.sh).

make            # out/cjack-legacy-release/: what is built so far, with the retail data
make progress   # score the build against the retail binaries
make help       # everything else

Each build also makes two archives of its game directory (build/package.sh): out/<name>-private.tar.gz, with the retail game's data, for your own machines, and out/<name>-public.tar.gz, without the discs' data, to give to other people (it carries only the free 1.1 update's, as cjacksrc.rez: assets/README.md). The public one carries scripts that copy the rest out of the player's own images of both discs (European or USA; a plain .iso, redump's .bin/.cue or its .zip), checking every file they write (ext/tools/mkinstall.py):

cjack-modern-release/linux-install.sh disc1.zip disc2.zip    # Linux
cjack-modern-release/mac-install.command disc1.zip disc2.zip # a Mac, for CrossOver

On Windows, drop the two images onto windows-install.bat. Each script also finds them in the game directory or the one above it by itself (double-click mac-install.command in Finder), and can be run again.

Both archives also carry the scripts that start the game (build/game-scripts/): linux-run.sh (starts the game under Wine, in a prefix of its own; the legacy build's launcher gets the registry values the retail installer wrote) and linux-server.sh (a dedicated server, headless under xvfb-run without a display); each prints its usage with --help. On Windows, start ContractJack.exe.

In modern builds, ContractJack.exe (and linux-run.sh) starts the game immediately using the launcher's saved settings and arguments, skips the first-run detail prompt, and waits until Lithtech.exe exits. Open ContractJackLauncher.exe for the interactive launcher. Under Wine, use the same prefix as linux-run.sh (~/.wine-cjack by default). Legacy builds keep their original launcher behavior.

The modern build plays the intro movies with its own binkw32.dll, built on FFmpeg, and decodes the characters' speech (MP3) in its own SndDrv.dll, so it needs no codec (MODERN.md X-1, EN-50). The legacy build is the retail game's: it plays the movies with RAD's Bink, which stalls under some Wine setups, so linux-run.sh turns them off (+DisableMovies 1); and under Wine its speech needs Fraunhofer's MP3 codec, since Wine's own (winemp3.acm) plays the streamed lines as a drone of their first samples. linux-run.sh installs it into the legacy build's prefix the first time (winetricks l3codecx); with another Wine prefix or a CrossOver bottle, run WINEPREFIX=<its folder> winetricks l3codecx once. Windows has it already.

Releases

GitHub Actions (.github/workflows/public-archives.yml) builds the four public archives on every push and pull request. Pushing a tag v* makes a GitHub release of it with the modern build's two public archives (cjacksrc-<tag>.tar.gz and cjacksrc-debug-<tag>.tar.gz; a tag with a hyphen is a pre-release), and every push to master whose builds pass replaces the pre-release nightly with that commit's (cjacksrc-nightly-<commit>.tar.gz). The release text is .github/release_notes.md.

About

Contract J.A.C.K. source code

Topics

Resources

Stars

16 stars

Watchers

2 watching

Forks

Releases

Contributors

Languages