Global Variables and Constants

This page contains a listing of every global variable defined in the game, along with the declarations and a brief description of what each one does.

For our purposes, a global variable is anything that is defined outside of a function, whether it is declared static (private to its compilation unit) or not. This page also includes enums, #defines, and really anything else that seems useful to document.


Common Types

These are the enumerations and custom types that are frequently used. Generally any variable that holds an unsigned data type will use one of the following:

enum {false = 0, true};
typedef unsigned char byte;   /* 8-bit unsigned integer */
typedef unsigned int  word;   /* 16-bit unsigned integer */
typedef unsigned long dword;  /* 32-bit unsigned integer */
typedef word bool;            /* Boolean stored in a machine word (16-bit) */
typedef byte bbool;           /* Boolean stored in a byte */

CPUTYPE_*

#define CPUTYPE_8088  0  /* Intel 8088 */
#define CPUTYPE_8086  1  /* Intel 8086 */
#define CPUTYPE_V20   2  /* NEC V20 */
#define CPUTYPE_V30   3  /* NEC V30 */
#define CPUTYPE_80188 4  /* Intel 80188 */
#define CPUTYPE_80186 5  /* Intel 80186 */
#define CPUTYPE_80286 6  /* Intel 80286 */
#define CPUTYPE_80386 7  /* Intel 80386 or above */

Provides meaningful names for the detected processor type.

These are the return values for the GetProcessorType() function.


DRAWMODE_*

#define DRAWMODE_NORMAL      0
#define DRAWMODE_HIDDEN      1
#define DRAWMODE_WHITE       2
#define DRAWMODE_TRANSLUCENT 3
#define DRAWMODE_FLIPPED     4
#define DRAWMODE_IN_FRONT    5
#define DRAWMODE_ABSOLUTE    6

Defines the drawing modes available for the sprite drawing functions.

Symbolic ConstantValueDescription
DRAWMODE_NORMAL0Draw the sprite unmodified, with X/Y positions measured relative to the game world. If the map data contains a “draw in front” tiles that intersect the sprite, the map tiles will prevail.
DRAWMODE_HIDDEN1Do not draw any part of the sprite.
DRAWMODE_WHITE2Same as DRAWMODE_NORMAL, but all opaque pixel positions in the sprite are drawn in bright white.
DRAWMODE_TRANSLUCENT3Same as DRAWMODE_WHITE, but the sprite color is translucent.
DRAWMODE_FLIPPED4Same as DRAWMODE_NORMAL, but the sprite is drawn flipped vertically.
DRAWMODE_IN_FRONT5Same as DRAWMODE_NORMAL, but the sprite will cover all map tiles, regardless of their “draw in front” attribute.
DRAWMODE_ABSOLUTE6Draw the sprite unmodified, with X/Y positions measured relative to the screen. Since there is no relationship to the game world in this mode, “draw in front” attributes from the map (if present) have no effect.

END_ANIMATION

#define END_ANIMATION BYTE_MAX

Define the marker that terminates palette animation tables. In Turbo C, this value is FFh.


END_SCREEN

#define END_SCREEN "END1.MNI"  /* episode 1, or */
#define END_SCREEN "END2.MNI"  /* episode 2, or */
#define END_SCREEN "END3.MNI"  /* episode 3 */

Defines the group file entry name of the full-screen image to show when the game has been won.


FILENAME_BASE

#define FILENAME_BASE "COSMO1"  /* episode 1, or */
#define FILENAME_BASE "COSMO2"  /* episode 2, or */
#define FILENAME_BASE "COSMO3"  /* episode 3 */

Defines the base file name (without extension) used for the group, configuration, and save files.


FONT_*

#define FONT_UP_ARROW        0x0050
#define FONT_LOWER_BAR_0     0x0140
#define FONT_UPPER_BAR_0     0x0168
#define FONT_0               0x0410
#define FONT_LOWER_A         0x0ac8
#define FONT_UPPER_BAR_1     0x0ed8
#define FONT_LOWER_BAR_1     0x0f00
#define FONT_BACKGROUND_GRAY 0x0f28

Provides meaningful names for some, but not all, of the font tile graphics.

The game font is built from 100 masked tiles, each beginning on a 40-byte boundary. Only a handful of these tiles are referenced directly in the game code; all other tile offsets are calculated by adding a multiple of 40 to one of the above base values.


IMAGE_*

#define IMAGE_PRETITLE   0
#define IMAGE_TITLE      1
#define IMAGE_CREDITS    2
#define IMAGE_BONUS      3
#define IMAGE_END        4
#define IMAGE_ONE_MOMENT 5
#define IMAGE_TILEATTR   0x1111
#define IMAGE_DEMO       0xfff1
#define IMAGE_NONE       0xffff

Provides meaningful names for various full-screen image files.

The names are described in more detail on the full-screen image database page.

The values for IMAGE_TILEATTR, IMAGE_DEMO, and IMAGE_NONE do not refer to actual files that can be displayed; they are flags placed into miscDataContents to facilitate skipping load operations on data that may already be in memory.


JOYSTICK_*

#define JOYSTICK_A 1
#define JOYSTICK_B 2

Identifiers for joystick 1 (A) and 2 (B). JOYSTICK_B is not used by name anywhere in the game.


JoystickState

typedef struct {
    bool button1;
    bool button2;
} JoystickState;

Holds the state of two buttons (button1 and button2) on a single joystick. The values are true if the corresponding button is currently pressed, or false if it is unpressed.


enum MODE1_COLORS

enum MODE1_COLORS {
    MODE1_BLACK = BLACK, MODE1_BLUE, MODE1_GREEN, MODE1_CYAN,
    MODE1_RED, MODE1_MAGENTA, MODE1_BROWN, MODE1_LIGHTGRAY,
    MODE1_DARKGRAY = DARKGRAY + 8, MODE1_LIGHTBLUE, MODE1_LIGHTGREEN,
    MODE1_LIGHTCYAN, MODE1_LIGHTRED, MODE1_LIGHTMAGENTA, MODE1_YELLOW,
    MODE1_WHITE
};

Defines the colors available for the EGA “display mode 1” palette. Display mode 1 is used in all 200-line modes (like the mode used by this game) and only supports the 16 RGBI output combinations.

The colors here are based on the Borland enum COLORS members, with the “light” variants shifted by 8 to compensate for the EGA’s color requirements. See SetPaletteRegister() for more information about this difference.


MUSIC_*

#define MUSIC_CAVES   0
#define MUSIC_SCARRY  1
#define MUSIC_BOSS    2
#define MUSIC_RUNAWAY 3
#define MUSIC_CIRCUS  4
#define MUSIC_TEKWRD  5
#define MUSIC_EASYLEV 6
#define MUSIC_ROCKIT  7
#define MUSIC_HAPPY   8
#define MUSIC_DEVO    9
#define MUSIC_DADODA  10
#define MUSIC_BELLS   11
#define MUSIC_DRUMS   12
#define MUSIC_BANJO   13
#define MUSIC_EASY2   14
#define MUSIC_TECK2   15
#define MUSIC_TECK3   16
#define MUSIC_TECK4   17
#define MUSIC_ZZTOP   18

Provides meaningful names for all of the music available in the game.


Music

typedef struct {
    word length;
    word datahead;
} Music;

Holds the length in bytes and first word of music data (datahead). Memory blocks that are cast to this structure type are generally much larger than the struct, and reading beyond datahead is typical and expected.


PALANIM_*

#define PALANIM_NONE       0
#define PALANIM_LIGHTNING  1
#define PALANIM_R_Y_W      2
#define PALANIM_R_G_B      3
#define PALANIM_MONO       4
#define PALANIM_W_R_M      5
#define PALANIM_EXPLOSIONS 6

Provides meaningful names for all of the palette animation types available in the game.


SCANCODE_*

#define SCANCODE_NULL        0x00
#define SCANCODE_ESC         0x01
#define SCANCODE_1           0x02  /* 1  ! */
#define SCANCODE_2           0x03  /* 2  @ */
#define SCANCODE_3           0x04  /* 3  # */
#define SCANCODE_4           0x05  /* 4  $ */
#define SCANCODE_5           0x06  /* 5  % */
#define SCANCODE_6           0x07  /* 6  ^ */
#define SCANCODE_7           0x08  /* 7  & */
#define SCANCODE_8           0x09  /* 8  * */
#define SCANCODE_9           0x0a  /* 9  ( */
#define SCANCODE_0           0x0b  /* 0  ) */
#define SCANCODE_MINUS       0x0c  /* -  _ */
#define SCANCODE_EQUAL       0x0d  /* =  + */
#define SCANCODE_BACKSPACE   0x0e
#define SCANCODE_TAB         0x0f
#define SCANCODE_Q           0x10  /* q  Q */
#define SCANCODE_W           0x11  /* w  W */
#define SCANCODE_E           0x12  /* e  E */
#define SCANCODE_R           0x13  /* r  R */
#define SCANCODE_T           0x14  /* t  T */
#define SCANCODE_Y           0x15  /* y  Y */
#define SCANCODE_U           0x16  /* u  U */
#define SCANCODE_I           0x17  /* i  I */
#define SCANCODE_O           0x18  /* o  O */
#define SCANCODE_P           0x19  /* p  P */
#define SCANCODE_LEFT_BRACE  0x1a  /* [  { */
#define SCANCODE_RIGHT_BRACE 0x1b  /* ]  } */
#define SCANCODE_ENTER       0x1c
#define SCANCODE_CTRL        0x1d
#define SCANCODE_A           0x1e  /* a  A */
#define SCANCODE_S           0x1f  /* s  S */
#define SCANCODE_D           0x20  /* d  D */
#define SCANCODE_F           0x21  /* f  F */
#define SCANCODE_G           0x22  /* g  G */
#define SCANCODE_H           0x23  /* h  H */
#define SCANCODE_J           0x24  /* j  J */
#define SCANCODE_K           0x25  /* k  K */
#define SCANCODE_L           0x26  /* l  L */
#define SCANCODE_SEMICOLON   0x27  /* ;  : */
#define SCANCODE_APOSTROPHE  0x28  /* '  " */
#define SCANCODE_GRAVE       0x29  /* `  ~ */
#define SCANCODE_LEFT_SHIFT  0x2a
#define SCANCODE_BACKSLASH   0x2b  /* \  | */
#define SCANCODE_Z           0x2c  /* z  Z */
#define SCANCODE_X           0x2d  /* x  X */
#define SCANCODE_C           0x2e  /* c  C */
#define SCANCODE_V           0x2f  /* v  V */
#define SCANCODE_B           0x30  /* b  B */
#define SCANCODE_N           0x31  /* n  N */
#define SCANCODE_M           0x32  /* m  M */
#define SCANCODE_COMMA       0x33  /* ,  < */
#define SCANCODE_DOT         0x34  /* .  > */
#define SCANCODE_SLASH       0x35  /* /  ? */
#define SCANCODE_RIGHT_SHIFT 0x36
#define SCANCODE_KP_ASTERISK 0x37  /* *  PrtSc */
#define SCANCODE_ALT         0x38
#define SCANCODE_SPACE       0x39
#define SCANCODE_CAPS_LOCK   0x3a
#define SCANCODE_F1          0x3b
#define SCANCODE_F2          0x3c
#define SCANCODE_F3          0x3d
#define SCANCODE_F4          0x3e
#define SCANCODE_F5          0x3f
#define SCANCODE_F6          0x40
#define SCANCODE_F7          0x41
#define SCANCODE_F8          0x42
#define SCANCODE_F9          0x43
#define SCANCODE_F10         0x44
#define SCANCODE_NUM_LOCK    0x45
#define SCANCODE_SCROLL_LOCK 0x46
#define SCANCODE_KP_7        0x47  /* Home         7 */
#define SCANCODE_KP_8        0x48  /* Up Arrow     8 */
#define SCANCODE_KP_9        0x49  /* Pg Up        9 */
#define SCANCODE_KP_MINUS    0x4a  /*              - */
#define SCANCODE_KP_4        0x4b  /* Left Arrow   4 */
#define SCANCODE_KP_5        0x4c  /*              5 */
#define SCANCODE_KP_6        0x4d  /* Right Arrow  6 */
#define SCANCODE_KP_PLUS     0x4e  /*              + */
#define SCANCODE_KP_1        0x4f  /* End          1 */
#define SCANCODE_KP_2        0x50  /* Down Arrow   2 */
#define SCANCODE_KP_3        0x51  /* Pg Down      3 */
#define SCANCODE_KP_0        0x52  /* Ins          0 */
#define SCANCODE_KP_DOT      0x53  /* Del          . */
#define SCANCODE_SYS_REQ     0x54
#define SCANCODE_F11         0x57
#define SCANCODE_F12         0x58
#define SCANCODE_EXTENDED    0xe0

Provides meaningful names for all of the IBM PC/AT keyboard scancodes. These are all well-defined and well-known.


SND_*

#define SND_BIG_PRIZE           1
#define SND_PLAYER_JUMP         2
#define SND_PLAYER_LAND         3
#define SND_PLAYER_CLING        4
#define SND_PLAYER_HIT_HEAD     5
#define SND_PLAYER_POUNCE       6
#define SND_PLAYER_DEATH        7
#define SND_DOOR_UNLOCK         8
#define SND_SPIKES_MOVE         9
#define SND_EXPLOSION           10
#define SND_WIN_LEVEL           11
#define SND_BARREL_DESTROY_1    12
#define SND_PRIZE               13
#define SND_PLAYER_HURT         14
#define SND_FOOT_SWITCH_MOVE    15
#define SND_FOOT_SWITCH_ON      16
#define SND_ROAMER_GIFT         17
#define SND_DESTROY_SATELLITE   18
#define SND_PLAYER_FOOTSTEP     19
#define SND_PUSH_PLAYER         20
#define SND_DRIP                21
#define SND_PIPE_CORNER_HIT     22
#define SND_TRANSPORTER_ON      23
#define SND_SCOOTER_PUTT        24
#define SND_DESTROY_SOLID       25
#define SND_PROJECTILE_LAUNCH   26
#define SND_BIG_OBJECT_HIT      27
#define SND_NO_BOMBS            28
#define SND_PLACE_BOMB          29
#define SND_HINT_DIALOG_ALERT   30
#define SND_RED_JUMPER_JUMP     31
#define SND_RED_JUMPER_LAND     32
#define SND_BGHOST_EGG_CRACK    33
#define SND_BGHOST_EGG_HATCH    34
#define SND_SAW_BLADE_MOVE      35
#define SND_FIREBALL_LAUNCH     36
#define SND_OBJECT_HIT          37
#define SND_EXIT_MONSTER_OPEN   38
#define SND_EXIT_MONSTER_INGEST 39
#define SND_BEAR_TRAP_CLOSE     40
#define SND_PAUSE_GAME          41
#define SND_WEEEEEEEE           42
#define SND_JUMP_PAD_ROBOT      43
#define SND_TEXT_TYPEWRITER     44
#define SND_BONUS_STAGE         45
#define SND_SHARD_BOUNCE        46
#define SND_TULIP_LAUNCH        47
#define SND_NEW_GAME            48
#define SND_ROCKET_BURN         49
#define SND_SMASH               50
#define SND_HIGH_SCORE_DISPLAY  51
#define SND_HIGH_SCORE_SET      52
#define SND_IVY_PLANT_RISE      53
#define SND_FLAME_PULSE         54
#define SND_BOSS_DAMAGE         55
#define SND_BOSS_MOVE           56
#define SND_SPEECH_BUBBLE       57
#define SND_BABY_GHOST_JUMP     58
#define SND_BABY_GHOST_LAND     59
#define SND_THUNDER             60
#define SND_BARREL_DESTROY_2    61
#define SND_TULIP_INGEST        62
#define SND_PLANT_MOUTH_OPEN    63
#define SND_ENTERING_LEVEL_NUM  64
#define SND_BOSS_LAUNCH         65

Provides meaningful names for all of the PC speaker sound effects included with the game.

These constants should be passed to StartSound() to start playing a PC speaker sound effect. Each sound number is described in more detail on the sound database page.


TILE_*

#define TILE_EMPTY              0x0000
#define TILE_INVISIBLE_PLATFORM 0x0048
#define TILE_STRIPED_PLATFORM   0x0050
#define TILE_SWITCH_FREE_1N     0x3d68
#define TILE_SWITCH_BLOCK_1     0x3d88
#define TILE_SWITCH_BLOCK_2     0x3d90
#define TILE_SWITCH_BLOCK_3     0x3d98
#define TILE_SWITCH_BLOCK_4     0x3da0
#define TILE_SWITCH_FREE_1L     0x3da8
#define TILE_DOOR_BLOCK         0x3dc8
#define TILE_BLUE_PLATFORM      0x3dd0
#define TILE_MYSTERY_BLOCK_NW   0x3df8
#define TILE_MYSTERY_BLOCK_NE   0x3e00
#define TILE_MYSTERY_BLOCK_SW   0x3e08
#define TILE_MYSTERY_BLOCK_SE   0x3e10
#define TILE_WAIT_SPINNER_1     0x3e18
#define TILE_TXTFRAME_NORTHWEST 0x3e38
#define TILE_TXTFRAME_NORTHEAST 0x3e40
#define TILE_TXTFRAME_SOUTHWEST 0x3e48
#define TILE_TXTFRAME_SOUTHEAST 0x3e50
#define TILE_TXTFRAME_NORTH     0x3e58
#define TILE_TXTFRAME_SOUTH     0x3e60
#define TILE_TXTFRAME_WEST      0x3e68
#define TILE_TXTFRAME_EAST      0x3e70
#define TILE_DARK_GRAY          0x3e78
#define TILE_MASKED_0           0x3e80  /* aka 16,000 */

Provides meaningful names for certain map tile values.

For space reasons, some of the names are a bit obtuse:

  • TILE_SWITCH_FREE_1N has no (“N”) line at its top.
  • TILE_SWITCH_FREE_1L has a light-colored (“L”) line at its top.
  • Names that include EMPTY or FREE do not restrict movement, and essentially behave as “air.”
  • Names including PLATFORM only block movement in the southern direction. The player may jump up through them freely, but movement will stop if they land on it from above.
  • Names including BLOCK are solid, and block movement in all directions.
  • Names with a direction indicate that they are meant to be used in conjunction with other, similarly named tiles to draw larger constructions. The directions indicate the correct relative position for each tile.

TITLE_SCREEN

#define TITLE_SCREEN "TITLE1.MNI"  /* episode 1, or */
#define TITLE_SCREEN "TITLE2.MNI"  /* episode 2, or */
#define TITLE_SCREEN "TITLE3.MNI"  /* episode 3 */

Defines the group file entry name of the full-screen image to show during the main title sequence.


activeMusic

Music *activeMusic;

Holds a pointer to the structure containing the length and data bytes of the most recent piece of music that has been started.

This is updated whenever StartGameMusic() or StartMenuMusic() is called, and read whenever the music needs to be restarted – for instance, after the game is paused and then unpaused.


activeSoundIndex

word activeSoundIndex;

Holds the zero-indexed sound number of the PC speaker sound effect that is currently playing.


activeSoundPriority

word activeSoundPriority;

Holds the priority value of the PC speaker sound effect that is currently playing.

This is checked and updated during calls to StartSound(). If the new sound has a priority value that is less than activeSoundPriority, the new sound will not play and the currently-playing sound will continue.


actorTileData[]

byte *actorTileData[3];

Points to masked tile image data used to draw actors, decorations, spawners, explosions, shards, and miscellaneous UI sprites.

Its allocations are divided into three distinct byte-aligned memory blocks due to the overall size of the data. The first two blocks each hold 65,535 bytes and the final block holds 60,840 bytes.


backdropTable[]

word backdropTable[2880];

A lookup table containing 2,880 words of precalculated offset data used for drawing the in-game parallax scrolling backdrop.

This is also used as scratch storage during calls to DrawFullscreenText().


cmdBomb

bbool cmdBomb;

Controls the state of the player’s “drop bomb” action command.


cmdEast

bbool cmdEast;

Controls the state of the player’s “walk east” movement command.


cmdJump

bbool cmdJump;

Controls the state of the player’s “jump” movement command.


cmdNorth

bbool cmdNorth;

Controls the state of the player’s “look north” action command.


cmdSouth

bbool cmdSouth;

Controls the state of the player’s “look south” action command.


cmdWest

bbool cmdWest;

Controls the state of the player’s “walk west” movement command.


demoDataLength

word demoDataLength;

Holds the size, in bytes, of the demo data currently loaded into memory.


demoDataPos

word demoDataPos;

Holds the byte offset of the current read/write position within the demo data while playing/recording a demo.


demoState

byte demoState;

Indicates the current state of input handling for gameplay.

This variable can hold one of the following values while the game is running:

Symbolic ConstantValueDescription
DEMOSTATE_NONE0Game is being played interactively, no demo is being recorded or played.
DEMOSTATE_RECORD1Game is being played interactively, and demo data is being recorded from the input.
DEMOSTATE_PLAY2Game is being controlled by demo data.

When set to DEMOSTATE_RECORD or DEMOSTATE_PLAY, this suppresses the “Now entering level” message and all in-game hints, and adds a “DEMO” overlay.


drawPageNumber

word drawPageNumber;

Holds the zero-indexed number (0 or 1) of the graphics page that the drawing procedures will operate on.


drawPageSegment

word drawPageSegment;

Holds the memory segment address of the graphics page that the drawing procedures will operate on.


enableAdLib

bool enableAdLib;

When true, this permits the AdLib service to actually send music data to the AdLib hardware. When false, this inhibits these transfers, holding the AdLib hardware “frozen” in its current state.


enableSpeaker

bool enableSpeaker;

When true, this permits the PC speaker hardware to actually emit sounds. When false, this unconditionally silences the speaker output.


fontTileData

byte *fontTileData;

Points to a 4,000 byte block of memory used to hold masked tile image data for the UI font.


fullscreenImageNames[]

char *fullscreenImageNames[] = {
    "PRETITLE.MNI", TITLE_SCREEN, "CREDIT.MNI", "BONUS.MNI", END_SCREEN,
    "ONEMOMNT.MNI"
};

Holds a list of all group file entry names that refer to full-screen image data.

The values for TITLE_SCREEN and END_SCREEN are different depending on the episode; typically these will be "TITLEx.MNI" and "ENDx.MNI" (respectively) with x matching the episode number.


gameTickCount

word gameTickCount;

Holds a running counter that increments precisely 140 times per second, regardless of the state of program execution.

This value is used by various delay functions to produce pauses of a constant length, regardless of processor speed. It is also used to govern the speed of the GameLoop function.


highScoreNames[]

typedef char HighScoreName[16];
HighScoreName highScoreNames[11];

Points to the first element of an 11-element fixed-length string array. Each element is 16 bytes long, and holds one of the names on the high score table.

The table is arranged in score order, from highest score to lowest.


highScoreValues[]

dword highScoreValues[11];

Points to the first element of an 11-element numeric array. Each element is a doubleword value, and holds one of the scores on the high score table.

The table is arranged in score order, from highest score to lowest.


isAdLibPresent

bbool isAdLibPresent;

Holds a true value if an AdLib card was detected in the system, and false otherwise.

This variable directly mirrors the state of the hardware and cannot be influenced by any in-game setting. This affects the behavior of memory allocation for the tileAttributeData pointer.


isAdLibPresentPrivate

bool isAdLibPresentPrivate;

Holds a true value if an AdLib card was detected in the system, and false otherwise.

This is a duplicate (but separately managed) copy of isAdLibPresent. This is used internally by the AdLib functions only.


isAdLibServiceRunning

bool isAdLibServiceRunning;

Holds a true value if the system timer is running at the faster AdLib rate and the AdLib service is being called. Otherwise, holds false to indicate that the timer is running slowly and only the PC speaker service is being called.


isAdLibStarted

bool isAdLibStarted;

Holds a true value if the AdLib startup code has executed, and false if the AdLib has either never been started or was explicitly stopped.

This variable is managed by StartAdLib() and StopAdLib() to ensure no attempts are made to start an already-started AdLib card or stop an already-stopped one.


isDebugMode

bbool isDebugMode;

Holds a true value if the debug/cheat mode has been activated by the player, and false during normal gameplay.

This can be toggled while in a game by pressing Tab+F12+Del. It cannot be toggled in the menus.

Debug mode has the following effects:

  • In the game, enables the F10+___ cheat codes.
  • In the main menu, adds the ability to press F11 to begin recording a demo.
  • At all times, adds the ability to press Alt+C to call the system’s original keyboard interrupt handler.

isInGame

bbool isInGame;

Holds a true value if a game is currently being played, and false if the main menu is being shown.

This controls whether or not ShowHighScoreTable clears the screen before and after showing.


isJoystickReady

bool isJoystickReady;

Controls whether game input should come from the keyboard or the joystick.

When true, ProcessGameInput only accepts player movement from the joystick. When false, player movement is only accepted from the keyboard.

Entering the “joystick redefine” menu and completing the calibration process sets this value to true. Merely entering the “keyboard redefine” menu sets this value to false.


isKeyDown[]

bbool isKeyDown[255];

Holds the down/up state of each keyboard key. Elements are indexed by the key’s “make” code, and each element holds a true value if the key is down and false if it is up.

This array is twice as large as it needs to be. Due to the high bit being used as the make/break flag, only 128 keys can actually be encoded by the keyboard controller’s input buffer. Elements 128–255 of this array can never hold true values.


isMusicEnabled

bool isMusicEnabled;

Controls whether or not the AdLib music should be sent to the hardware.

Music may play when this is true, and music is silenced when false. This setting can be toggled by the user, and the value is persisted in the configuration file.


isNewSound

bool isNewSound;

Indicates that the currently-playing PC speaker sound effect has been changed.

This serves as a communication flag between StartSound() and PCSpeakerService().


isSoundEnabled

bool isSoundEnabled;

Controls whether or not the PC speaker sound effects should be sent to the hardware.

Sound effects may play when this is true, and sound effects are silenced when false. This setting can be toggled by the user, and the value is persisted in the configuration file.


joinPathBuffer[]

char joinPathBuffer[80];

Holds an 80-byte scratch area used for joining directory and file names into full path names.


joystickBandBottom[]

int joystickBandBottom[3];

Holds the timer values for the bottom edge of each joystick’s dead zone. Index 0 is unused; index 1 and 2 are for joystick 1 and 2, respectively.


joystickBandLeft[]

int joystickBandLeft[3];

Holds the timer values for the left edge of each joystick’s dead zone. Index 0 is unused; index 1 and 2 are for joystick 1 and 2, respectively.


joystickBandRight[]

int joystickBandRight[3];

Holds the timer values for the right edge of each joystick’s dead zone. Index 0 is unused; index 1 and 2 are for joystick 1 and 2, respectively.


joystickBandTop[]

int joystickBandTop[3];

Holds the timer values for the top edge of each joystick’s dead zone. Index 0 is unused; index 1 and 2 are for joystick 1 and 2, respectively.


joystickBtn1Bombs

bool joystickBtn1Bombs;

Controls which action the primary joystick button performs. When true, this button places a bomb. When false, this button makes the player jump. In either case, the secondary button takes the opposite action.


keyNames

typedef char KeyName[6];
KeyName keyNames[] = {
    "NULL", "ESC", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "-",
    "=", "BKSP", "TAB", "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P",
    " ", " ", "ENTR", "CTRL", "A", "S", "D", "F", "G", "H", "J", "K", "L",
    ";", "\"", " ", "LSHFT", " ", "Z", "X", "C", "V", "B", "N", "M", ",",
    ".", "?", "RSHFT", "PRTSC", "ALT", "SPACE", "CAPLK", "F1", "F2", "F3",
    "F4", "F5", "F6", "F7", "F8", "F9", "F10", "NUMLK", "SCRLK", "HOME",
    "\x18", "PGUP", "-", "\x1B", "5", "\x1C", "+", "END", "\x19", "PGDN",
    "INS", "DEL", "SYSRQ", "", "", "F11", "F12", ""
};

Defines short (5 character or less) key name strings for the most common scancodes on the 84-key IBM PC/AT keyboard.

Generally keys are named using their base (unshifted) case, but all letters are stored capitalized. There are some exceptions and oddities:

  • NULL is not a key, and is generally indicative of an error condition. There shouldn’t be any circumstance in the game where this name is shown.
  • The keys [, ], `, and \ are defined as blank spaces. The game font does not contain any tiles for these characters or their shifted companions.
  • The ' key renders as ", despite both characters being available in the game font.
  • The / key renders as ?.
  • The numeric keypad keys render as their non-numeric functions, if available.
  • The character codes 18h, 19h, 1Bh, and 1Ch produce the symbols , , , and respectively.

lastGroupEntryLength

dword lastGroupEntryLength;

Holds the file size, in bytes, of the most recent group file entry that was opened.

This value is updated each time GroupEntryFp() opens a group file entry.


lastScancode

byte lastScancode;

Holds the most recent byte of data received by the system’s keyboard controller.

In the case of a key down/“make” code, this will be a value in the range 0h–7Fh. For key up/“break” codes, this will be a value in the range 80h–FFh. Break codes can be converted into corresponding make codes by taking the value bitwise-AND 7Fh.

In the case of multi-byte scancodes like those added with the 101-key PS/2 keyboard, this will only hold the most recent byte that was received.


levelNum

word levelNum;

Holds the current level number being played.

This is distinct from the map number – the level number tracks multiple plays through the bonus maps. The relationship between level and map progression is as follows:

Level NumberMap NumberNotes
01
12
2Bonus AThe warp menu chooses this instance.
3Bonus BThe warp menu chooses this instance.
43
54
6Bonus A
7Bonus B
85
96
10Bonus A
11Bonus B
127
138
14Bonus A
15Bonus B
169
1710
18Bonus A
19Bonus B
2011Only present in episode 1.
2112Supported; never used.
22Bonus A
23Bonus B
2413Supported; never used.
2514Supported; never used.
26Bonus A
27Bonus B
2815Supported; never used.
2916Not supported; implementation incomplete.

mapData

union {
    byte *b;
    word *w;
} mapData;

Points to a 65,535 byte block of memory used to hold map data during the game OR temporary data in the main menu.

Maps are interpreted as word-aligned data, and temporary data is byte-aligned. This temporary data consists of masked tile image data for cartoons and scratch storage needed during the loading of backdrop images.


maskedTileData

byte *maskedTileData;

Points to a 40,000 byte block of memory used to hold masked tile image data during the game OR music data in the main menu.


miscData

byte *miscData;

Points to a 35,000 byte block of memory used to hold a variety of different unrelated things.

Outside of gameplay, this is used as a temporary buffer while copying full-screen image data into EGA memory.

When switching levels, this is used as scratch storage during the loading of backdrop images.

During gameplay, the first 5,000 bytes of this block are used to hold any demo data that is being played or recorded. The remainder of the block is used to hold music data for the level if there is an AdLib card installed, or tile attributes data if there is not an AdLib card installed. (See tileAttributeData.)


miscDataContents

word miscDataContents;

Provides an indication of the last data that was loaded into the miscellaneous data block.

When functions modify the contents of the miscData memory block, they also update this value with one of the IMAGE_* values to indicate what has been written there. This value is then used during DrawFullscreenImage() to skip loading in cases where miscData already contains the image content that is going to be drawn.


musicDataHead

word *musicDataHead;

Holds the memory address of the first word of the current music data. Used to rewind the music playback pointer each time the music loops.


musicDataLeft

word musicDataLeft;

Tracks the number of bytes of music data that still remain to be played. Once this value reaches zero, the music must restart from the beginning.


musicDataLength

word musicDataLength;

Tracks the total length of the current music data, in bytes.


musicDataPtr

word *musicDataPtr;

Points to the next word of music data that is going to be sent to the AdLib hardware.


musicNames[]

char *musicNames[] = {
    "mcaves.mni", "mscarry.mni", "mboss.mni", "mrunaway.mni",
    "mcircus.mni", "mtekwrd.mni", "measylev.mni", "mrockit.mni",
    "mhappy.mni", "mdevo.mni", "mdadoda.mni", "mbells.mni", "mdrums.mni",
    "mbanjo.mni", "measy2.mni", "mteck2.mni", "mteck3.mni", "mteck4.mni",
    "mzztop.mni"
};

Holds a list of all group file entry names that refer to music data.

Each array index matches with a MUSIC_* constant.


musicNextDue

dword musicNextDue;

Tracks the timestamp, in music ticks, when the next chunk of music is scheduled to be sent to the AdLib hardware.


musicTickCount

dword musicTickCount;

Tracks the current timestamp, in music ticks. Increments each time the AdLib service runs.


paletteAnimationNum

byte paletteAnimationNum;

Holds the current palette animation number that was specified by the map being played.


paletteStepCount

dword paletteStepCount;

Holds the current position within the palette animation table.

Once the end of the palette table has been reached (as indicated by encountering an END_ANIMATION marker) this resets to 0 and the pattern repeats.


pit0Value

dword pit0Value;

Holds a copy of the most recent value used to reconfigure channel 0 of the system’s Programmable Interval Timer.

This is modified during calls to SetPIT0Value(), and takes the value that is passed during each call. It is treated as a 16-bit value in all contexts where it appears.


playerTileData

byte *playerTileData;

Points to a block of memory matching the size and content of the PLAYERS.MNI group file entry, nominally 30,000 bytes.

This block is used to hold the masked tile image data that the player’s sprites are built from.


profCountCPU

word profCountCPU;

Used temporarily during CPU profiling to track the number of busy loop iterations the CPU has performed so far.

This is updated when the ProfileCPUService() function runs, and interpreted during calculations in ProfileCPU().


profCountPIT

word profCountPIT;

Used temporarily during CPU profiling to track the number of timer interrupts that have been raised by the Programmable Interval Timer so far.

This is updated when the ProfileCPUService() function runs, and interpreted during calculations in ProfileCPU(). It is read during WaitWallclock(), but the actual value is irrelevant in that particular function.


savedInt8

typedef void interrupt (*InterruptFunction)(void);
InterruptFunction savedInt8;

Holds a reference to the old interrupt service routine for interrupt vector 8.

This function was the system timer interrupt handler when the program was started.


savedInt9

typedef void interrupt (*InterruptFunction)(void);
InterruptFunction savedInt9;

Holds a reference to the old interrupt service routine for interrupt vector 9.

This function was the keyboard handler when the program was started.


scancodeBomb

byte scancodeBomb;

Holds the keyboard scancode that the user has selected for the player’s “bomb” action.

This setting can be configured by the user in the “keyboard redefine” menu, and the value is persisted in the configuration file.


scancodeEast

byte scancodeEast;

Holds the keyboard scancode that the user has selected for the player’s “walk east” movement command.

This setting can be configured by the user in the “keyboard redefine” menu, and the value is persisted in the configuration file.


scancodeJump

byte scancodeJump;

Holds the keyboard scancode that the user has selected for the player’s “jump” movement command.

This setting can be configured by the user in the “keyboard redefine” menu, and the value is persisted in the configuration file.


scancodeNorth

byte scancodeNorth;

Holds the keyboard scancode that the user has selected for the player’s “look north” action.

This setting can be configured by the user in the “keyboard redefine” menu, and the value is persisted in the configuration file.


scancodeSouth

byte scancodeSouth;

Holds the keyboard scancode that the user has selected for the player’s “look south” action.

This setting can be configured by the user in the “keyboard redefine” menu, and the value is persisted in the configuration file.


scancodeWest

byte scancodeWest;

Holds the keyboard scancode that the user has selected for the player’s “walk west” movement command.

This setting can be configured by the user in the “keyboard redefine” menu, and the value is persisted in the configuration file.


skipDetectAdLib

bool skipDetectAdLib;

Always false; part of an unused piece of code that would allow AdLib detection to be skipped based on a command-line switch.

If the feature were implemented, it would suppress only the first (of two) AdLib detection attempts and the assignment of its return value to isAdLibPresentPrivate.


soundData1

word *soundData1;

Points to a block of memory matching the size and content of the SOUNDS.MNI group file entry, nominally 3,332 bytes.

This pointer is used for initial allocation and loading of this PC speaker sound data. Once loaded, the soundDataPtr[] array is used to address sound data and this variable is no longer necessary.


soundData2

word *soundData2;

Points to a block of memory matching the size and content of the SOUNDS2.MNI group file entry, nominally 3,876 bytes.

See soundData1.


soundData3

word *soundData3;

Points to a block of memory matching the size and content of the SOUNDS3.MNI group file entry, nominally 4,020 bytes.

See soundData1.


soundDataPtr[]

word *soundDataPtr[80];

Zero-indexed array of 80 elements, although not all are used. Each element points to the first data word of a PC speaker sound effect. Unused elements are null pointers.


soundPriority[]

byte soundPriority[81];

One-indexed array of 81 elements, although not all are used. Each element holds the priority value of a PC speaker sound effect. Unused elements are zero.


stnGroupFilename

char *stnGroupFilename = FILENAME_BASE ".STN";

Holds the name of the STN group file; this is a value like COSMOx.STN.

This value adjusts itself based on the value in FILENAME_BASE.


tileAttributeData

byte *tileAttributeData;

If an AdLib card is installed, points to a dedicated 7,000 byte block of memory. If an AdLib card is not installed, points to the address 5,000 bytes into miscData.

Regardless of the underlying memory location, the data referenced by this pointer is the tile attributes data.


timerTickCount

dword timerTickCount;

Holds a computed running tally of how many 1.1931818… MHz timer ticks have occurred so far. Its range is artificially limited to 16 bits.

This value is maintained by TimerInterruptService() where its 16-bit treatment causes an overflow at a rate of 18.2 Hz, mimicking the default timer interrupt rate.


totalMemFreeAfter

dword totalMemFreeAfter;

Captures the amount of free memory, in bytes, after all allocations have been completed.

This value can be seen in the “Memory free” line in the Memory Usage debug menu.


totalMemFreeBefore

dword totalMemFreeBefore;

Captures the amount of free memory, in bytes, immediately after the program started running.

This value can be seen in the “Take Up” line in the Memory Usage debug menu.


volGroupFilename

char *volGroupFilename = FILENAME_BASE ".VOL";

Holds the name of the VOL group file; this is a value like COSMOx.VOL.

This value adjusts itself based on the value in FILENAME_BASE.


wallclock10us

word wallclock10us;

Holds the calculated number of busy loop iterations that must be performed by the system’s CPU to produce a delay of 10 microseconds.

This value is calculated in ProfileCPU(), and should only be used as an argument to WaitWallclock().


wallclock25us

word wallclock25us;

Holds the calculated number of busy loop iterations that must be performed by the system’s CPU to produce a delay of 25 microseconds.

This value is calculated in ProfileCPU(), and should only be used as an argument to WaitWallclock().


wallclock100us

word wallclock100us;

Holds the calculated number of busy loop iterations that must be performed by the system’s CPU to produce a delay of 100 microseconds.

This value is calculated in ProfileCPU(), and should only be used as an argument to WaitWallclock().


winLevel

bool winLevel;

Indicates if the conditions have been met for the current level to be “won,” allowing the player to advance to the next level in the progression.

At the start of each level, winLevel is set to false. At the end of each iteration of the game loop, it is checked for a true value – if anything between these two points sets the value to true, the level is considered to have been won.

winLevel is activated by several actors and the demo playback/recording functions.


writePath

char *writePath;

Holds the value of the write path.

The write path is usually an empty string, indicating the current working directory. Can also be either an absolute or a relative path, which is used as a prefix when loading/saving the configuration and save files.


yOffsetTable[]

word yOffsetTable[] = {
    0, 320, 640, 960, 1280, 1600, 1920, 2240, 2560, 2880, 3200, 3520, 3840,
    4160, 4480, 4800, 5120, 5440, 5760, 6080, 6400, 6720, 7040, 7360, 7680
};

Holds a list of the first 25 multiples of 320, used to translate a tile’s Y coordinate on the screen to a video memory address offset.