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 enum
s, #define
s, 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 Constant | Value | Description |
---|---|---|
DRAWMODE_NORMAL | 0 | Draw 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_HIDDEN | 1 | Do not draw any part of the sprite. |
DRAWMODE_WHITE | 2 | Same as DRAWMODE_NORMAL , but all opaque pixel positions in the sprite are drawn in bright white. |
DRAWMODE_TRANSLUCENT | 3 | Same as DRAWMODE_WHITE , but the sprite color is translucent. |
DRAWMODE_FLIPPED | 4 | Same as DRAWMODE_NORMAL , but the sprite is drawn flipped vertically. |
DRAWMODE_IN_FRONT | 5 | Same as DRAWMODE_NORMAL , but the sprite will cover all map tiles, regardless of their “draw in front” attribute. |
DRAWMODE_ABSOLUTE | 6 | Draw 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
orFREE
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 Constant | Value | Description |
---|---|---|
DEMOSTATE_NONE | 0 | Game is being played interactively, no demo is being recorded or played. |
DEMOSTATE_RECORD | 1 | Game is being played interactively, and demo data is being recorded from the input. |
DEMOSTATE_PLAY | 2 | Game 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 Number | Map Number | Notes |
---|---|---|
0 | 1 | |
1 | 2 | |
2 | Bonus A | The warp menu chooses this instance. |
3 | Bonus B | The warp menu chooses this instance. |
4 | 3 | |
5 | 4 | |
6 | Bonus A | |
7 | Bonus B | |
8 | 5 | |
9 | 6 | |
10 | Bonus A | |
11 | Bonus B | |
12 | 7 | |
13 | 8 | |
14 | Bonus A | |
15 | Bonus B | |
16 | 9 | |
17 | 10 | |
18 | Bonus A | |
19 | Bonus B | |
20 | 11 | Only present in episode 1. |
21 | 12 | Supported; never used. |
22 | Bonus A | |
23 | Bonus B | |
24 | 13 | Supported; never used. |
25 | 14 | Supported; never used. |
26 | Bonus A | |
27 | Bonus B | |
28 | 15 | Supported; never used. |
29 | 16 | Not 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.