OpenJKDF2
A cross-platform reimplementation of JKDF2 in C
Install / Use
/learn @shinyquagsire23/OpenJKDF2README
OpenJKDF2

Latest Releases | Report a crash or bug
OpenJKDF2 is a function-by-function reimplementation of DF2 in C, with 64-bit ports to Windows 7+, macOS 10.15+, and Linux. Files are organized as closely to the original game as possible, based on symbols from the Grim Fandango Remaster Android/Linux/macOS port, as well as scattered assertions from various other games. It also contains the original versions of byacc and flex used for COG script parsing.
OpenJKDF2 does not include any original game assets; a valid copy of JKDF2 is required and can be purchased from GOG or Steam. The GOG version is recommended, since it is DRM-free and also includes the soundtrack in Ogg Vorbis format. If you'd like to try before you buy, a WebAssembly demo of OpenJKDF2 can be found at https://maxthomas.dev/openjkdf2/.
Support for playing the original soundtrack from Ogg Vorbis files is primarily supported for the GOG and Steam versions of the game assets. Original disk soundtracks can also be loaded from MUSIC/1/Track<2..8>.ogg and MUSIC/2/Track<2..12>.ogg for each disk's soundtrack. If files are missing, it will instead attempt to use a GOG track number from MUSIC/Track<12..32>.ogg. Dumping the soundtrack from disks at install time is planned for a future release of OpenJKDF2, but is not currently implemented.
Platforms
OpenJKDF2 supports the following configurations:
| Configuration | Renderer | Description | | --- | --- | --- | | 64-bit Windows/SDL2 | OpenGL 3.3 | 64-bit Windows compilation with SDL2 and OpenAL. DirectX dependencies are replaced with SDL2 and OpenAL. | | MacOS x86_64/AArch64 | OpenGL 3.3 | 64-bit MacOS compilation with SDL2 and OpenAL Soft. All release packages include both Intel and ARM64. | | 64-bit Linux/SDL2 | OpenGL 3.3 | 64-bit Linux compilation with SDL2 and OpenAL. | | ARM64 Android | OpenGL ES 3 | ARMv8 Android compilation with SDL2 and OpenAL Soft. | | Nintendo DSi | Custom | Nintendo DSi port with hardware rendering, software audio. Extremely RAM-limited, supports emissive palettes. | | Emscripten/WebAssembly | WebGL 2/OpenGL ES 3 | WebAssembly with SDL2 and OpenAL. Runs in a web browser. Since WASM only supports 32-bit pointers, this will likely be less buggy than 64-bit, but less performant. |
The following implementations are in-progress or planned:
| Configuration | Renderer | Description | Status | | --- | --- | --- | --- | | iOS | Metal? | Not a huge priority, but would be nice to have. | Not started | | Switch libnx | OpenGL ES 3 | Not a huge priority, but would be nice to have. | Not started | | 32-bit Windows/SDL2 | OpenGL 3.3 | Windows compilation with SDL2 and OpenAL. DirectX dependencies are replaced with SDL2 and OpenAL. Targeting Windows XP ~ Windows 7 | Not started | | 32-bit Windows/DirectX | Direct3D 3 | Faithful decompilation with original DirectX bindings/renderer. | Not started |
The following configurations are deprecated:
| Configuration | Renderer | Description |
| --- | --- | --- |
| x86 Linux/SDL2, mmap blobs | OpenGL 3.3 | 32-bit Linux compilation with SDL2 and OpenAL. JK.EXE is memory mapped into the process and used as a "binary blob"; Unimplemented functions will fall back to JK.EXE implementations. |
| 32-bit Linux/SDL2, blobless | OpenGL 3.3 | 32-bit Linux compilation with SDL2 and OpenAL. The output executable is a swap-in replacement for JK.EXE, but will be missing functions and will crash on reaching unimplemented code. |
| x86 Win32/MinGW DLL | Software/DirectX | Win32 hooked build, JK.EXE is patched to load df2_reimpl.dll execute hook_init_win before JK.EXE's main function. Unimplemented functions will fall back to JK.EXE implementations. df2_reimpl_kvm.dll is used for the KVM target |
Linux building works on AArch64/RPi4 with llvmpipe, but V3D GLES has trouble with palettes.
OpenJKDF2 requires game data from a licensed copy of Jedi Knight: Dark Forces II in order to run; No game assets are provided by OpenJKDF2. On Linux, paths and filenames may be case-sensitive. Your directory structure should look something like this:
.
├── JK.EXE
├── MUSIC
│ ├── Track12.ogg
│ ├── Track13.ogg
│ ├── Track14.ogg
│ ├── Track15.ogg
│ ├── Track16.ogg
│ ├── Track17.ogg
│ ├── Track18.ogg
│ ├── Track22.ogg
│ ├── Track23.ogg
│ ├── Track24.ogg
│ ├── Track25.ogg
│ ├── Track26.ogg
│ ├── Track27.ogg
│ ├── Track28.ogg
│ ├── Track29.ogg
│ ├── Track30.ogg
│ ├── Track31.ogg
│ └── Track32.ogg
├── episode
│ ├── JK1.gob
│ ├── JK1CTF.gob
│ └── JK1MP.gob
├── openjkdf2-64
├── player
└── resource
├── Res1hi.gob
├── Res2.gob
├── jk_.cd
└── video
├── 01-02A.SMK
├── 03-04A.SMK
├── 06A.SMK
├── 08-10A.SMK
├── 12A.SMK
├── 16A.SMK
├── 18-19A.SMK
├── 21A.SMK
├── 23A.SMK
├── 25A.SMK
├── 27A.SMK
├── 33-34A.SMK
├── 36A.SMK
├── 38A.SMK
├── 39A.SMK
├── 41-42A.SMK
├── 41DA.SMK
├── 41DSA.SMK
├── 44A.SMK
├── 46A.SMK
├── 48A.SMK
├── 50A.SMK
├── 52-53A.SMK
├── 54A.SMK
└── 57A.SMK
Building
See here for instructions.
Contributing
Contributions in the form of code cleanup and documentation are highly welcomed. See CONTRIBUTING.md for details on what kinds of cleanup tasks still need to be done. OpenJKDF2 is not currently accepting monetary donations, however detailed bug and crash reports are always appreciated, including bugs/crashes involving mods.
TL;DR: What Isn't Implemented, Yet
- Load Configuration and Save Configuration in Setup > Controls > Options
- Using plus or minus to resize the screen (with SDL2, resolution auto-resizes to window size)
Usage with original JK.EXE and DirectX using hooks
See here for instructions.
Methodology
The bulk of research and documentation occurs in IDA. Every function has been identified to a file prefix (ie stdHashTable_) with a corresponding .c/.h file. RenderDroid (rd*) and LEC stdlib (std*) functions are 90% canonically named, based on symbols from Grim Fandango Remastered.
Reverse engineering is a parallel effort between structure documentation and function identification. Once structures are sufficiently documented, Hex-Rays can be used for decompilation. While most Hex-Rays output works outright, many loops and structures require manual intervention. Output is generally cleaned and tidied to remove redunant stack variables or too-deep nesting. sizeof and obvious inlining and macros should also be adjusted as appropriate.
Engine variables and yet-to-be-decompiled functions are referenced using define macros and static function pointers, respectively. Once a file is decompiled enough that an engine variable is no longer referenced by non-decompiled code, the variables can be declared in their respective C files. For decompiled functions which are only referenced by non-decompiled functions, a hook_function call is added in main.c to redirect code execution to df2_reimpl.dll from JK.EXE.
Progress is tracked using analyze.py, output.map and ida_copypaste_funclist_nostdlib.txt: After compiling df2_reimpl.dll, symbols can be compared against the .idb to determine how much of the original .text is actually in use, and how much has been hooked and replaced.
If you'd like a copy of my IDB to examine functions which haven't been decompiled yet (or for any other use), let me know.
Current Progress
Generated using analyze.py. Some filenames may be inaccurate or incomplete (see ida_copypaste_funclist_nostdlib.txt for a full function name listing).
[file] [size] [% of text] [% complete] [decomp / total]
DirectX 0x1e 0.003% 100.000% 5 / 5
jkGob 0x29 0.004% 100.000% 2 / 2
jkGuiDecision 0x45 0.006% 100.000% 3 / 3
sithStrTable 0x5b 0.008% 100.000% 4 / 4
sithCopyright 0x67 0.010% 100.000% 1 / 1
jkStrings 0x89 0.013% 100.000% 5 / 5
jkGuiGeneral 0xc5 0.018% 100.000% 3 / 3
jkSmack 0xee 0.022% 100.000% 4 / 4
rdFace 0xf6 0.023% 100.000% 4 / 4
jkGuiControlOptions 0x105 0.024% 100.000% 3 / 3
stdHashKey 0x107 0.024% 100.000% 10 / 10
rdCanvas 0x113 0.025% 100.000% 4 / 4
jkGuiEsc 0x18f 0.037% 100.000% 3 / 3
rdroid 0x1f6 0.047% 100.000% 27 / 27
sithHeader 0x1f9 0.047% 100.000% 1 / 1
sithTime 0x213 0.049% 100.000% 6 / 6
jkGuiSingleTally 0x21b 0.050% 100.000% 4 / 4
jkGuiSetup 0x240 0.053% 100.000% 4 / 4
jkGuiSound 0x274 0.058% 100.000% 3 / 3
sithItem 0x275 0.058% 100.000% 5 / 5
jkGuiGameplay 0x2b2 0.064%
Related Skills
node-connect
349.0kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
109.4kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
349.0kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
349.0kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
