Reconstructed Commander Keen 1-3 Source Code
This package contains full source code for all versions of Keen 1-3 that I know, from the November 1990 beta version of Keen 1 to the relatively obscure Precision Software Applications release (version 1.34). Compiling the source code with the correct compiler and assembler versions and compressing the resulting executables with LZEXE or PKLITE (if necessary) generates executables that are 100% identical to the original files.
You will need Turbo C++ 1.00 (not 1.01!) and Turbo Assembler (2.0 or above) to compile exact copies of most versions of Keen 1-3 (versions 1.31 and earlier). The later special releases (the "pre-registered" Gravis version 1.32 and the PSA release version 1.34) require Borland C++ 2.0 for a fully identical copy.
---
If you have read the timeline.txt file I released along with my Reconstructed BioMenace Source Code last year, you might have noticed an entry that said "got side-tracked revisiting another old project". This is that project.
Most of the Keen 1-3 code reconstruction was done back in early 2021, before I started preparing my reconstructed Keen 4-6 source code for release. The big problem that prevented me from getting my Keen 1-3 code to compile and compress into 100% identical copies of the original executables was the fact that I didn't have access to the right compiler back then. I only had Turbo C++ 1.01, which generates slightly different code than Turbo C++ 1.00. It was impossible to get Turbo C++ 1.01 to produce the code that I needed.
Another contributing factor is that the order of the uninitialized variables in the so-called BSS segment depends on the names of the variables when using Turbo C++ 1.x to compile the code. And since some of these variables need to be accessed from within the assembly code, I couldn't simply group the variables into a struct like I did elsewhere. I had to find names that would allow the variables to appear in the correct order. So after some trial and error, I wrote a small throw-away program that generated a bunch of variables with random names and ran that list of variables through the Turbo C++ compiler. Disassembling the generated .OBJ file showed me which order these variable names would produce, so all I had left to do was to let the compiler (and the assembler) rename the variables internally. This is done in the BSSCHEAT.H and BSSCHEAT.EQU files.
A word of advice for those attempting to use a similar trick to modify the order of the variables in the BSS segment: If two names produce the same hash value for whatever hash function the compiler uses, the order of the variable declarations can have an effect on the order of the variables in the generated code. This includes "extern" declarations as well, not just the actual declaration of the variable. One way to detect hash collisions in a list of randomly generated variable names would be to reverse the order of the variables and compile the file again. If the order of certain names changes after that, those names have the same hash values and you are probably better off using only one of those names to avoid having to move (extern) declarations around to get the result you want.
---
If you check out IDLIB.C and IDLIB.ASM, you will see that I based the code in these files on The Catacomb and Hovertank. This is the code that got the team in trouble. They used the same routines they wrote for their day jobs at Softdisk in the Keen code. No matter what those old letters posted by Scott Miller said, the boys were in serious trouble.
Most of the IDLIB.C code must have come directly from the PC version of Dangerous Dave. I don't think the Dave source code has been released to the public, so you'll just have to take my word for it. But there is some extremely strong evidence showing that the id founders used Softdisk's code in their own game. Sure, it's not the code responsible for the smooth scrolling, but it is code they probably didn't have the rights to use.
---
That's all for now. Have fun messing with the code.