External control driver

External control drivers are an obscure feature of the DOS Doom executables, which allows an external program to provide input into Doom. The purpose of the feature is to allow manufacturers of new control devices to write custom drivers to provide input for the game. Long believed to have been an unused feature, multiple devices are now known to have been released with drivers that use it.

Background
The DOS Doom executables include built-in support for a number of different input devices: along with keyboard, mouse and joysticks, also supported is the Logitech Cyberman, an experimental controller that aimed to provide 6DOF control. At the time Doom was released, a number of different manufacturers such as Logitech were beginning to develop more advanced input devices than the standard two-button joysticks supported on the PC.

Often these devices were supported through proprietary APIs, such as Logitech's SWIFT API (for the Cyberman). It would not be reasonable for Doom to include built-in support for every device on the market, and new devices released after work on Doom finished would also not be supported. External control drivers provide a means for manufacturers to do this work themselves, and inject input into the game.

Heretic and Hexen include a different command line parameter, -externdriver, which provides similar functionality, albeit with a different, incompatible interface. Later releases of Heretic include an external driver named VIOHT.EXE that is used to interface the game with Virtual I/O's i-glasses device, a 3D headset sold during the 1990s.

Technical
External control drivers operate in a similar fashion to the Doom networking component (where the networking code is contained in an external executable), or Statistics drivers. The external driver installs an interrupt vector, and invokes Doom, passing a special command line option with a pointer to a memory buffer containing a structure that it has initialized. For example:

doom -control 1234567

The format of the structure is fairly simple:

typedef struct {       long intnum; ticcmd_t ticcmd; } control_buf_t;

'intnum' is a 32-bit integer containing the interrupt vector that has been hooked by the driver. When each game ticcmd is constructed, the interrupt is invoked; this triggers the driver to read input from the control device. These inputs are set in the ticcmd structure.

Devices that used the control API

 * - a still-active website for which includes a number of example demos.
 * - derivative of the Assassin 3D
 * - derivative of the Assassin 3D

Alternative uses
There are some alternative uses for external control drivers, examples of which can be found in the :


 * External statistics drivers need to be triggered regularly in order to collect statistics about each level that was played (otherwise only the statistics of the last completed level will be acquired). The interrupt provided by the control driver mechanism is a way to achieve this.
 * As control drivers provide a way to inject raw ticcmd data into the game, they can be used to play back demos. This has the advantage that it allows an incomplete demo to be replayed and continued at the end by the player.