ckmakeobj — A tool for generating DOS .OBJ files from Keen data files

ckmakeobj is a program which creates DOS-compatible .OBJ files which embed a file as a symbol. These then can be linked into a program and accessed as any other variable.

It was written because the Commander Keen games link headers and huffman dictionaries into the game executable, and so these need to be available in object form at compile time. The original tools used to develop the game often supported generating these .OBJ files, but community-made tools, like level and graphics editors usually do not.

In particular ckmakeobj was written in 2014, when the source code to Commander Keen was found, and the folks at id Software were attempting to get it to compile. The surviving source code did not exactly match the released version 1.4 of the games, so ckmakeobj was used to reconstruct the .OBJ files in order to compile an executable compatible with the available data. Alas, despite the reconstruction being successful (and — rumour has it — even getting signed off by the lawyers), the source code release is yet to see the light of day.

The source code for ckmakeobj is written in C, and can be downloaded here. Precompiled binaries are also available for x86 Linux, Windows, and MS-DOS (386 or greater required).

ckmakeobj is pretty simple to use. Just run:

./ckmakeobj infile outfile symbol segtype [segname]

The arguments are as follows:

  1. infile - the name of the input datafile (must be less than 64kb in size to fit in a single real-mode segment)
  2. outfile - the name of the output .OBJ file to create
  3. symbol - the symbol name to export the data as
  4. segtype - the type of segment to create. This must be one of DATA, CODE, or FARDATA.
  5. [segname] - an optional name for a FARDATA segment

For example, the headers for Commander Keen 4 can be converted to .OBJ files with the following commands.

./ckmakeobj MAPHEAD.CK4 CK4MHEAD.OBJ _maphead FARDATA MapHeader
./ckmakeobj EGAHEAD.CK4 CK4EHEAD.OBJ _EGAhead FARDATA EGA_grafixheader
./ckmakeobj EGADICT.CK4 CK4EDICT.OBJ _EGAdict DATA
./ckmakeobj AUDIOHHD.CK4 CK4AHEAD.OBJ _audiohed FARDATA _AudioHeader
./ckmakeobj AUDIODCT.CK4 CK4ADICT.OBJ _audiodict DATA

There are a few other tools to do the same thing. Blzut3 (Braden Obrzut) wrote a similar tool as part of the release of the Keen Dreams source code. And the original MakeOBJ function can be seen in the TED5 source code.

For modern systems, a similar trick can be achieved either with ld or objcopy:

# Using ld:
$ ld -r --format binary -o output.o input.ck4

# Using objcopy
$ objcopy -I bianry input.ck4 -O elf32-i386 -B i386 output.o

Note that these tools don't give you any control over the exported symbol name: it'll always be of the form binary_filename_start. It does, however, provide _end and _size symbols as well.

It is also possible to generate a C source file containing the data, which is then compiled into an object file. The xxd utility can do this with the -i option.