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 */

ACT_*

#define ACT_BASKET_NULL         0
#define ACT_STAR_FLOAT          1
#define ACT_JUMP_PAD_FLOOR      2
#define ACT_ARROW_PISTON_W      3
#define ACT_ARROW_PISTON_E      4
#define ACT_FIREBALL_W          5
#define ACT_FIREBALL_E          6
#define ACT_HEAD_SWITCH_BLUE    7
#define ACT_HEAD_SWITCH_RED     8
#define ACT_HEAD_SWITCH_GREEN   9
#define ACT_HEAD_SWITCH_YELLOW  10
#define ACT_DOOR_BLUE           11
#define ACT_DOOR_RED            12
#define ACT_DOOR_GREEN          13
#define ACT_DOOR_YELLOW         14
#define ACT_JUMP_PAD_ROBOT      16
#define ACT_SPIKES_FLOOR        17
#define ACT_SPIKES_FLOOR_RECIP  18
#define ACT_SAW_BLADE_VERT      20
#define ACT_SAW_BLADE_HORIZ     22
#define ACT_BOMB_ARMED          24
#define ACT_CABBAGE             25
#define ACT_POWER_UP_FLOAT      28
#define ACT_BARREL_POWER_UP     29
#define ACT_BASKET_GRN_TOMATO   31
#define ACT_GRN_TOMATO          32
#define ACT_BASKET_RED_TOMATO   33
#define ACT_RED_TOMATO          34
#define ACT_BARREL_YEL_PEAR     35
#define ACT_YEL_PEAR            36
#define ACT_BARREL_ONION        37
#define ACT_ONION               38
#define ACT_EXIT_SIGN           39
#define ACT_SPEAR               40
#define ACT_SPEAR_RECIP         41
#define ACT_GRN_SLIME_THROB     42
#define ACT_GRN_SLIME_DRIP      43
#define ACT_FLYING_WISP         44
#define ACT_TWO_TONS_CRUSHER    45
#define ACT_JUMPING_BULLET      46
#define ACT_STONE_HEAD_CRUSHER  47
#define ACT_PYRAMID_CEIL        48
#define ACT_PYRAMID_FALLING     49
#define ACT_PYRAMID_FLOOR       50
#define ACT_GHOST               51
#define ACT_BASKET_GRN_GOURD    52
#define ACT_BASKET_BLU_SPHERES  53
#define ACT_MOON                54
#define ACT_HEART_PLANT         55
#define ACT_BARREL_BOMB         56
#define ACT_BOMB_IDLE           57
#define ACT_BARREL_JUMP_PAD_FL  58
#define ACT_SWITCH_PLATFORMS    59
#define ACT_SWITCH_MYSTERY_WALL 61
#define ACT_MYSTERY_WALL        62
#define ACT_SPIKES_FLOOR_BENT   63
#define ACT_MONUMENT            64
#define ACT_BABY_GHOST          65
#define ACT_PROJECTILE_SW       66
#define ACT_PROJECTILE_SE       67
#define ACT_PROJECTILE_S        68
#define ACT_ROAMER_SLUG         69
#define ACT_PIPE_CORNER_N       70
#define ACT_PIPE_CORNER_S       71
#define ACT_PIPE_CORNER_W       72
#define ACT_PIPE_CORNER_E       73
#define ACT_BABY_GHOST_EGG_PROX 74
#define ACT_BABY_GHOST_EGG      75
#define ACT_SHARP_ROBOT_FLOOR   78
#define ACT_SHARP_ROBOT_CEIL    80
#define ACT_BASKET_HAMBURGER    81
#define ACT_HAMBURGER           82
#define ACT_CLAM_PLANT_FLOOR    83
#define ACT_CLAM_PLANT_CEIL     84
#define ACT_GRAPES              85
#define ACT_PARACHUTE_BALL      86
#define ACT_SPIKES_E            87
#define ACT_SPIKES_E_RECIP      88
#define ACT_SPIKES_W            89
#define ACT_BEAM_ROBOT          90
#define ACT_SPLITTING_PLATFORM  91
#define ACT_SPARK               92
#define ACT_BASKET_DANCE_MUSH   93
#define ACT_DANCING_MUSHROOM    94
#define ACT_EYE_PLANT_FLOOR     95
#define ACT_EYE_PLANT_CEIL      96
#define ACT_BARREL_CABB_HARDER  100
#define ACT_RED_JUMPER          101
#define ACT_BOSS                102
#define ACT_PIPE_OUTLET         104
#define ACT_PIPE_INLET          105
#define ACT_SUCTION_WALKER      106
#define ACT_TRANSPORTER_1       107
#define ACT_TRANSPORTER_2       108
#define ACT_PROJECTILE_W        109
#define ACT_PROJECTILE_E        110
#define ACT_SPIT_WALL_PLANT_E   111
#define ACT_SPIT_WALL_PLANT_W   112
#define ACT_SPITTING_TURRET     113
#define ACT_SCOOTER             114
#define ACT_BASKET_PEA_PILE     115
#define ACT_BASKET_LUMPY_FRUIT  116
#define ACT_BARREL_HORN         117
#define ACT_RED_CHOMPER         118
#define ACT_BASKET_POD          119
#define ACT_SWITCH_LIGHTS       120
#define ACT_SWITCH_FORCE_FIELD  121
#define ACT_FORCE_FIELD_VERT    122
#define ACT_FORCE_FIELD_HORIZ   123
#define ACT_PINK_WORM           124
#define ACT_HINT_GLOBE_0        125
#define ACT_PUSHER_ROBOT        126
#define ACT_SENTRY_ROBOT        127
#define ACT_PINK_WORM_SLIME     128
#define ACT_DRAGONFLY           129
#define ACT_WORM_CRATE          130
#define ACT_BOTTLE_DRINK        134
#define ACT_GRN_GOURD           135
#define ACT_BLU_SPHERES         136
#define ACT_POD                 137
#define ACT_PEA_PILE            138
#define ACT_LUMPY_FRUIT         139
#define ACT_HORN                140
#define ACT_RED_BERRIES         141
#define ACT_BARREL_BOTL_DRINK   142
#define ACT_SATELLITE           143
#define ACT_IVY_PLANT           145
#define ACT_YEL_FRUIT_VINE      146
#define ACT_HEADDRESS           147
#define ACT_BASKET_HEADDRESS    148
#define ACT_EXIT_MONSTER_W      149
#define ACT_EXIT_LINE_VERT      150
#define ACT_SMALL_FLAME         151
#define ACT_TULIP_LAUNCHER      152
#define ACT_ROTATING_ORNAMENT   153
#define ACT_BLU_CRYSTAL         154
#define ACT_RED_CRYSTAL_FLOOR   155
#define ACT_BARREL_RT_ORNAMENT  156
#define ACT_BARREL_BLU_CRYSTAL  157
#define ACT_BARREL_RED_CRYSTAL  158
#define ACT_GRN_TOMATO_FLOAT    159
#define ACT_RED_TOMATO_FLOAT    160
#define ACT_YEL_PEAR_FLOAT      161
#define ACT_BEAR_TRAP           162
#define ACT_FALLING_FLOOR       163
#define ACT_EP1_END_1           164
#define ACT_EP1_END_2           165
#define ACT_EP1_END_3           166
#define ACT_BASKET_ROOT         167
#define ACT_ROOT                168
#define ACT_BASKET_RG_BERRIES   169
#define ACT_REDGRN_BERRIES      170
#define ACT_BASKET_RED_GOURD    171
#define ACT_RED_GOURD           172
#define ACT_BARREL_GRN_EMERALD  173
#define ACT_GRN_EMERALD         174
#define ACT_BARREL_CLR_DIAMOND  175
#define ACT_CLR_DIAMOND         176
#define ACT_SCORE_EFFECT_100    177
#define ACT_SCORE_EFFECT_200    178
#define ACT_SCORE_EFFECT_400    179
#define ACT_SCORE_EFFECT_800    180
#define ACT_SCORE_EFFECT_1600   181
#define ACT_SCORE_EFFECT_3200   182
#define ACT_SCORE_EFFECT_6400   183
#define ACT_SCORE_EFFECT_12800  184
#define ACT_EXIT_PLANT          186
#define ACT_BIRD                187
#define ACT_ROCKET              188
#define ACT_INVINCIBILITY_CUBE  189
#define ACT_PEDESTAL_SMALL      190
#define ACT_PEDESTAL_MEDIUM     191
#define ACT_PEDESTAL_LARGE      192
#define ACT_BARREL_CYA_DIAMOND  193
#define ACT_CYA_DIAMOND         194
#define ACT_BARREL_RED_DIAMOND  195
#define ACT_RED_DIAMOND         196
#define ACT_BARREL_GRY_OCTAHED  197
#define ACT_GRY_OCTAHEDRON      198
#define ACT_BARREL_BLU_EMERALD  199
#define ACT_BLU_EMERALD         200
#define ACT_INVINCIBILITY_BUBB  201
#define ACT_THRUSTER_JET        202
#define ACT_EXIT_TRANSPORTER    203
#define ACT_HINT_GLOBE_1        204
#define ACT_HINT_GLOBE_2        205
#define ACT_HINT_GLOBE_3        206
#define ACT_HINT_GLOBE_4        207
#define ACT_HINT_GLOBE_5        208
#define ACT_HINT_GLOBE_6        209
#define ACT_HINT_GLOBE_7        210
#define ACT_HINT_GLOBE_8        211
#define ACT_HINT_GLOBE_9        212
#define ACT_CYA_DIAMOND_FLOAT   213
#define ACT_RED_DIAMOND_FLOAT   214
#define ACT_GRY_OCTAHED_FLOAT   215
#define ACT_BLU_EMERALD_FLOAT   216
#define ACT_JUMP_PAD_CEIL       217
#define ACT_BARREL_HEADPHONES   218
#define ACT_HEADPHONES_FLOAT    219
#define ACT_HEADPHONES          220
#define ACT_FROZEN_DN           221
#define ACT_BANANAS             223
#define ACT_BASKET_RED_LEAFY    224
#define ACT_RED_LEAFY_FLOAT     225
#define ACT_RED_LEAFY           226
#define ACT_BASKET_BRN_PEAR     227
#define ACT_BRN_PEAR_FLOAT      228
#define ACT_BRN_PEAR            229
#define ACT_BASKET_CANDY_CORN   230
#define ACT_CANDY_CORN_FLOAT    231
#define ACT_CANDY_CORN          232
#define ACT_FLAME_PULSE_W       233
#define ACT_FLAME_PULSE_E       234
#define ACT_SPEECH_OUCH         235
#define ACT_RED_SLIME_THROB     236
#define ACT_RED_SLIME_DRIP      237
#define ACT_HINT_GLOBE_10       238
#define ACT_HINT_GLOBE_11       239
#define ACT_HINT_GLOBE_12       240
#define ACT_HINT_GLOBE_13       241
#define ACT_HINT_GLOBE_14       242
#define ACT_HINT_GLOBE_15       243
#define ACT_SPEECH_WHOA         244
#define ACT_SPEECH_UMPH         245
#define ACT_SPEECH_WOW_50K      246
#define ACT_EXIT_MONSTER_N      247
#define ACT_SMOKE_EMIT_SMALL    248
#define ACT_SMOKE_EMIT_LARGE    249
#define ACT_EXIT_LINE_HORIZ     250
#define ACT_CABBAGE_HARDER      251
#define ACT_RED_CRYSTAL_CEIL    252
#define ACT_HINT_GLOBE_16       253
#define ACT_HINT_GLOBE_17       254
#define ACT_HINT_GLOBE_18       255
#define ACT_HINT_GLOBE_19       256
#define ACT_HINT_GLOBE_20       257
#define ACT_HINT_GLOBE_21       258
#define ACT_HINT_GLOBE_22       259
#define ACT_HINT_GLOBE_23       260
#define ACT_HINT_GLOBE_24       261
#define ACT_HINT_GLOBE_25       262
#define ACT_POWER_UP            263
#define ACT_STAR                264
#define ACT_EP2_END_LINE        265

Defines meaningful names for each actor type defined in the game.

ACT_BASKET_NULL is a special sentinel value for the spawner functions and cannot be expressed in the map format. ACT_STAR_FLOAT has the value 32 in the map format, and all other actor types follow sequentially. Map actor types below 32 are special actors, see SPA_*.


Actor

typedef struct {
    word sprite, frame, x, y;
    bool forceactive, stayactive, acrophile, weighted;
    word westfree, eastfree, data1, data2, data3, data4, data5;
    bool dead;
    word falltime;
    byte hurtcooldown;
    ActorTickFunction tickfunc;
} Actor;

Holds the current sprite, frame, x, and y position of one actor. dead actors are inactive and may be reclaimed. hurtcooldown is a decrementing counter while the actor is recovering from a player attack. Remaining members are either private-use or uncommon.

In more detail:

  • sprite: One of the SPR_* values, representing the base sprite type that this actor displays as. This is usually the most identifying characteristic of an the actor and the closest representation to the original actor type that was created.
  • frame: Holds the current frame number of the sprite that is in view. Some actors with complicated drawing needs will use other mechanisms to make this determination.
  • x: The horizontal position on the map where this actor is now located.
  • y: Similar to x, but in the vertical direction.
  • forceactive: An actor is considered “visible” if any portion of its sprite can be seen anywhere inside the scrolling game window. An actor’s “active” state controls whether it thinks and moves, versus being paused and frozen in place. By default an actor is only active while it is visible, and activity stops as soon as it leaves the visible area. The “force active” flag overrides the visibility check and makes the actor permanently active.
  • stayactive: When enabled, causes an actor to enable its own “force active” flag once it has become visible for the first time.
  • acrophile: When enabled, informs the common actor-movement code that this actor should be willing to walk off ledges. Otherwise actors will treat such ledges as impassible terrain and turn around. Not all actors use the common movement code.
  • weighted: When enabled, indicates that the actor has “weight” and should automatically be pulled down by the force of gravity. Actors that float in the air (e.g. prizes and ceiling-mounted actors) must have this flag disabled to prevent falling, and actors that have complicated vertical movement behavior may enable this flag to false to prevent the global gravity system from interfering.
  • westfree: For actors that use the common walking functionality, this is a flag variable that holds a nonzero value if movement is permitted in the western direction, or zero if that movement is blocked. Some complex/non-walking actors repurpose these as additional data fields.
  • eastfree: Similar to westfree, but in the eastern direction.
  • data1data5: Internal data specific to each tick function’s needs. There are no simple generalizations about what these members contain or how they should be interpreted; these would be explained on the page specific to the tick function in question.
  • dead: When true, indicates that this actor was once active on the map but has since been destroyed or picked up. It will never come back from this state and the processing functions will unconditionally skip it. The slot containing this actor may be overwritten with a newly-created actor.
  • falltime: Holds a value that represents how long this actor has been in a falling state. Influences the fall speed and some actors’ behavior.
  • hurtcooldown: Holds a decrementing, nonzero value after an actor has been injured (but not destroyed) by the player or some other force. Prevents actors from taking too much damage in too short a time, similar to playerHurtCooldown for the player’s protection.
  • tickfunc: A pointer to one of the C functions that contains the actor’s per-tick behavior and movement code. Many actors share tick functions, and generally use the sprite type or one of the data fields to differentiate the underlying actor types.

BACKDROP_HEIGHT

#define BACKDROP_HEIGHT 18

Defines the height (in tiles) of backdrop images.


BACKDROP_SIZE

#define BACKDROP_SIZE 23040

Defines the size (in bytes) of a backdrop image.


BACKDROP_SIZE_EGA_MEM

#define BACKDROP_SIZE_EGA_MEM (BACKDROP_SIZE / 4)

Defines the size (in bytes) of EGA memory address space used by a backdrop image.

Derived from one fourth of BACKDROP_SIZE, or 5,760 bytes.


BACKDROP_WIDTH

#define BACKDROP_WIDTH 40

Defines the width (in tiles) of backdrop images.


CPU_TYPE_*

#define CPU_TYPE_8088  0  /* Intel 8088 */
#define CPU_TYPE_8086  1  /* Intel 8086 */
#define CPU_TYPE_V20   2  /* NEC V20 */
#define CPU_TYPE_V30   3  /* NEC V30 */
#define CPU_TYPE_80188 4  /* Intel 80188 */
#define CPU_TYPE_80186 5  /* Intel 80186 */
#define CPU_TYPE_80286 6  /* Intel 80286 */
#define CPU_TYPE_80386 7  /* Intel 80386 or above */

Provides meaningful names for the detected processor type.

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


DEMO_STATE_*

#define DEMO_STATE_NONE   0
#define DEMO_STATE_RECORD 1
#define DEMO_STATE_PLAY   2

Defines constant values that represent the input processing mode that should be used by the game loop.

Symbolic ConstantValueDescription
DEMO_STATE_NONE0The game is played in the usual way, with user keyboard input controlling the player. All in-game hints and intermission screens are displayed.
DEMO_STATE_RECORD1The game is played in demo recording mode. The keyboard controls the player, but the level progression is altered and in-game hints are skipped. All player movement is captured into a demo file on disk.
DEMO_STATE_PLAY2The game runs in demo playback mode. Keyboard input is ignored (any keypress ends the game) and player movement commands are read from the demo file. Level progression and hint display are altered in the same way as with DEMO_STATE_RECORD.

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


DIR2_*

#define DIR2_SOUTH 0
#define DIR2_NORTH 1
#define DIR2_WEST  0
#define DIR2_EAST  1

Defines pairs of values for two-way direction systems. “South” and “north” can be negated for a ping-pong movement effect; “east” and “west” can be changed similarly.

Symbolic ConstantValueDescription
DIR2_SOUTH0Points toward the bottom edge of the screen.
DIR2_NORTH1Points toward the top edge of the screen.
DIR2_WEST0Points toward the left edge of the screen.
DIR2_EAST1Points toward the right edge of the screen.

This is conceptually similar to DIR4_*, but the values here should only be used in cases where objects move in one dimension.

Note: DIR2_SOUTH equals DIR4_NORTH, while DIR2_NORTH equals DIR4_SOUTH. They are not interchangeable.


DIR4_*

#define DIR4_NONE  0  /* Used by player bomb/cling */
#define DIR4_NORTH 0
#define DIR4_SOUTH 1
#define DIR4_WEST  2
#define DIR4_EAST  3

Defines a set of values for a four-way direction system. “North” and “none” map to the same value, but are named differently to clarify the intent where they appear.

Symbolic ConstantValueDescription
DIR4_NONE0Refers to a “directionless” state. Numerically identical to DIR4_NORTH, but used in code to clarify that there is no direction instead of it being interpreted as a literal “north.”
DIR4_NORTH0Points toward the top edge of the screen.
DIR4_SOUTH1Points toward the bottom edge of the screen.
DIR4_WEST2Points toward the left edge of the screen.
DIR4_EAST3Points toward the right edge of the screen.

The arrangement of these cardinal directions follows the conventional layout of a compass rose.


DIR8_*

#define DIR8_NONE      0  /* Stationary and/or directionless */
#define DIR8_NORTH     1
#define DIR8_NORTHEAST 2
#define DIR8_EAST      3
#define DIR8_SOUTHEAST 4
#define DIR8_SOUTH     5
#define DIR8_SOUTHWEST 6
#define DIR8_WEST      7
#define DIR8_NORTHWEST 8

Defines a set of values for an eight-way direction system. “None,” while not technically a direction, is used in places where an object that could move chooses not to.

Symbolic ConstantValueDescription
DIR8_NONE0Represents the absence of direction and/or a state of no movement.
DIR8_NORTH1Points toward the top edge of the screen.
DIR8_NORTHEAST2Points up and to the right.
DIR8_EAST3Points toward the right edge of the screen.
DIR8_SOUTHEAST4Points down and toward the right.
DIR8_SOUTH5Points toward the bottom edge of the screen.
DIR8_SOUTHWEST6Points down and toward the left.
DIR8_WEST7Points toward the left edge of the screen.
DIR8_NORTHWEST8Points up and toward the left.

The arrangement of these cardinal directions follows the conventional layout of a compass rose. The values defined here can be converted into X/Y deltas by using the dir8X[] and dir8Y[] arrays.


DRAW_MODE_*

#define DRAW_MODE_NORMAL      0
#define DRAW_MODE_HIDDEN      1
#define DRAW_MODE_WHITE       2
#define DRAW_MODE_TRANSLUCENT 3
#define DRAW_MODE_FLIPPED     4
#define DRAW_MODE_IN_FRONT    5
#define DRAW_MODE_ABSOLUTE    6

Defines the drawing modes available for the sprite drawing functions.

Symbolic ConstantValueDescription
DRAW_MODE_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.
DRAW_MODE_HIDDEN1Do not draw any part of the sprite.
DRAW_MODE_WHITE2Same as DRAW_MODE_NORMAL, but all opaque pixel positions in the sprite are drawn in bright white.
DRAW_MODE_TRANSLUCENT3Same as DRAW_MODE_WHITE, but the sprite color is translucent.
DRAW_MODE_FLIPPED4Same as DRAW_MODE_NORMAL, but the sprite is drawn flipped vertically.
DRAW_MODE_IN_FRONT5Same as DRAW_MODE_NORMAL, but the sprite will cover all map tiles, regardless of their “draw in front” attribute.
DRAW_MODE_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.

Decoration

typedef struct {
    bool alive;
    word sprite, numframes, x, y, dir, numtimes;
} Decoration;

Holds the x and y position for a single decoration, displayed as a sprite type with an associated numframes count. The decoration moves in the direction specified by dir and loops for numtimes. alive is true when the the decoration slot is in use.

The dir member should contain one of the DIR8_* values.

The Decoration structure has associated data stored separately in the decorationFrame[] array.


EGA_OFFSET_*

#define EGA_OFFSET_SOLID_TILES  0x4000
#define EGA_OFFSET_STATUS_TILES 0x8000
#define EGA_OFFSET_BDROP_EVEN   0xa300
#define EGA_OFFSET_BDROP_ODD_X  0xb980
#define EGA_OFFSET_BDROP_ODD_Y  0xd000
#define EGA_OFFSET_BDROP_ODD_XY 0xe680

Defines a number of useful EGA memory offsets relative to the adapter’s segment address (A000h). Every byte of address space here represents four actual bytes in the EGA’s memory, due to the separation of color planes.


END_ANIMATION

#define END_ANIMATION BYTE_MAX

Defines 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.


Explosion

typedef struct {
    word age, x, y;
} Explosion;

Holds the x and y position for a single explosion. age is zero if this explosion slot is inactive, or an incrementing value while the explosion progresses.


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.


Fountain

typedef struct {
    word x, y, dir, stepcount, height, stepmax, delayleft;
} Fountain;

Holds the x and y position for a single fountain. The remaining structure values track the movement direction and height.

  • dir is a DIR4_* value representing the current movement direction. Each fountain starts in DIR4_NORTH.
  • stepcount is an incrementing counter that tracks the number of frames the fountain has moved since it last changed direction. Once the direction change occurs, this value is zeroed again.
  • height is the height of the stream beneath the portion of the fountain that can be stood on.
  • stepmax is the maximum value for stepcount that can be reached before the fountain switches directions. This is derived from the actor’s type in the map data.
  • delayleft is a decrementing counter that, if nonzero, means that the fountain is pausing to change directions.

GAME_INPUT_*

#define GAME_INPUT_CONTINUE 0
#define GAME_INPUT_QUIT     1
#define GAME_INPUT_RESTART  2

Defines a set of symbolic return values for the game input handling functions.

These are the return values for the ProcessGameInput() function, used to differentiate how the game loop should respond.

Symbolic ConstantValueDescription
GAME_INPUT_CONTINUE0The user did not do anything that would affect the current iteration of the game loop or the state of gameplay as a whole.
GAME_INPUT_QUIT1The user wants to quit the current game, and the game loop needs to stop running.
GAME_INPUT_RESTART2The user loaded a saved game, and the game loop needs to restart from the beginning with this new state.

Contrast with the values defined in HELP_MENU_*.


GAME_VERSION

#define GAME_VERSION "1.20"

Holds a string value which represents the current released version of the game. For centering purposes, this should be four characters long.


HELP_MENU_*

#define HELP_MENU_CONTINUE 0
#define HELP_MENU_RESTART  1
#define HELP_MENU_QUIT     2

Defines the possible return values of the in-game help menu.

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

Symbolic ConstantValueDescription
HELP_MENU_CONTINUE0The user did not do anything that would affect the current iteration of the game loop or the state of gameplay as a whole.
HELP_MENU_RESTART1The user loaded a saved game, and the game loop needs to restart from the beginning with this new state.
HELP_MENU_QUIT2The user wants to quit the current game, and the game loop needs to stop running.

Contrast with the values defined in GAME_INPUT_*.


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, 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.


LIGHT_SIDE_*

#define LIGHT_SIDE_WEST   0
#define LIGHT_SIDE_MIDDLE 1
#define LIGHT_SIDE_EAST   2

Defines a set of constants used to identify which “side” (or type) of light is represented.

Symbolic ConstantValueShapeDescription
LIGHT_SIDE_WEST0Represents the left side of a light cone. This lightens the lower-right area of a tile.
LIGHT_SIDE_MIDDLE1Represents the middle of a lighted area. The entire tile is lightened.
LIGHT_SIDE_EAST2Represents the right side of a light cone. This lightens the lower-left area of a tile.

See the Light structure.


LIGHT_CAST_DISTANCE

#define LIGHT_CAST_DISTANCE 11  /* episode 1, or */
#define LIGHT_CAST_DISTANCE 13  /* episodes 2 and 3 */

Defines the maximum number of tiles that can be flooded by each light. This limit is lower in the shareware episode.


Light

typedef struct {
    word side, x, y;
} Light;

Holds the x position, y position, and type (expressed as a side) of a light actor.


MAX_ACTORS

#define MAX_ACTORS 410

Controls the size of the global actor state array, and governs the maximum number of actors that can be present on a map at any given time.


MAX_DECORATIONS

#define MAX_DECORATIONS 10

Controls the size of the global decoration state array, and governs the maximum number of decorations that can be present on a map at any given time.


MAX_EXPLOSIONS

#define MAX_EXPLOSIONS 7

Controls the size of the global explosion state array, and governs the maximum number of explosions that can be present on a map at any given time.


MAX_FOUNTAINS

#define MAX_FOUNTAINS 10

Controls the size of the global fountain state array, and governs the maximum number of fountains that can be present on a map at any given time.


MAX_LIGHTS

#define MAX_LIGHTS 200

Controls the size of the global lights array, and governs the maximum number of lights that can be present on a map at any given time.


MAX_PLATFORMS

#define MAX_PLATFORMS 10

Controls the size of the global platform state array, and governs the maximum number of platforms that can be present on a map at any given time.


MAX_SHARDS

#define MAX_SHARDS 16

Controls the size of the global shards state array, and governs the maximum number of shards that can be present on a map at any given time.


MAX_SPAWNERS

#define MAX_SPAWNERS 6

Controls the size of the global spawner state array, and governs the maximum number of spawners that can be present on a map at any given time.


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.


MOVE_*

define MOVE_FREE    0
define MOVE_BLOCKED 1
define MOVE_SLOPED  2

Provides meaningful names for the results returned by player/sprite movement test functions.

These are the return values for the TestPlayerMove() and TestSpriteMove() functions.

Symbolic ConstantValueDescription
MOVE_FREE0The attempted move places the sprite into an area of free space on the map; hence the move is permissible.
MOVE_BLOCKED1The attempted move places the sprite either partially or completely inside an impassible area of the map; the move attempt should be blocked.
MOVE_SLOPED2The attempted move is legal (similar to MOVE_FREE) but it involves a sloped surface that requires further adjustment in the vertical direction.

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 numbers available in the game.


Music

typedef struct {
    word length, 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.


PAL_ANIM_*

#define PAL_ANIM_NONE       0
#define PAL_ANIM_LIGHTNING  1
#define PAL_ANIM_R_Y_W      2
#define PAL_ANIM_R_G_B      3
#define PAL_ANIM_MONO       4
#define PAL_ANIM_W_R_M      5
#define PAL_ANIM_EXPLOSIONS 6

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


PALETTE_KEY_INDEX

#define PALETTE_KEY_INDEX MAGENTA

Defines which EGA palette register will be affected by the various palette animation functions in the game.


PLAYER_*

#define PLAYER_WALK_1         0
#define PLAYER_WALK_2         1
#define PLAYER_WALK_3         2
#define PLAYER_WALK_4         3
#define PLAYER_STAND          4
#define PLAYER_LOOK_NORTH     5
#define PLAYER_LOOK_SOUTH     6
#define PLAYER_JUMP           7
#define PLAYER_FALL           8
#define PLAYER_CLING          9
#define PLAYER_CLING_OPPOSITE 10
#define PLAYER_CLING_NORTH    11
#define PLAYER_CLING_SOUTH    12
#define PLAYER_FALL_LONG      13
#define PLAYER_CROUCH         14
#define PLAYER_PAIN           15
#define PLAYER_FALL_SEVERE    16
#define PLAYER_PUSHED         17
#define PLAYER_STAND_BLINK    18
#define PLAYER_SHAKE_1        19
#define PLAYER_SHAKE_2        20
#define PLAYER_SHAKE_3        21
#define PLAYER_JUMP_LONG      22
#define PLAYER_DEAD_1         46
#define PLAYER_DEAD_2         47
#define PLAYER_HIDDEN         BYTE_MAX

Provides meaningful names for the player sprite frames available in the game.

Most of these values must be combined with one of the PLAYER_BASE_* constants to select between the west- and east-facing variants of each frame. The only exceptions are the “dead” and “hidden” values, which are directionless.


PLAYER_BASE_*

#define PLAYER_BASE_WEST 0
#define PLAYER_BASE_EAST 23

Defines the base frame number for the west- and east-facing sets of player sprites.

The values here should be added to one of the PLAYER_* constants to produce the true frame number for the desired combination.


Platform

typedef struct {
    word x, y;
    word mapstash[5];
} Platform;

Holds the x and y position for a single platform. The mapstash[] array provides temporary storage space for the five map tiles that are swapped out as the platform’s tiles cover them.

Due to hard-coded offsets in LoadMapData() and MovePlatforms(), the mapstash[] array must begin at word offset 2 in this structure.


POUNCE_HINT_*

#define POUNCE_HINT_UNSEEN 0
#define POUNCE_HINT_QUEUED 1
#define POUNCE_HINT_SEEN   2

Defines constants that represent the current state of the “jump on top of creatures…” hint message.

Symbolic ConstantValueDescription
POUNCE_HINT_UNSEEN0The hint has never been shown. If the player is hurt, it is appropriate to show the hint.
POUNCE_HINT_QUEUED1The player has just been hurt, and the hint needs to be shown. The hint message is queued for display when the current frame’s drawing is complete.
POUNCE_HINT_SEEN2The hint has been shown, or the player has demonstrated that they know how to pounce on enemies. All saved games are written with this pounce hint state, so all loaded games will suppress the hint.

RESTORE_GAME_*

#define RESTORE_GAME_NOT_FOUND 0
#define RESTORE_GAME_SUCCESS   1
#define RESTORE_GAME_ABORT     2

Defines constants that represent the possible outcomes of a user’s interaction with the “restore game” menu.

Symbolic ConstantValueDescription
RESTORE_GAME_NOT_FOUND0The user chose a valid save slot, but there was no file saved there.
RESTORE_GAME_SUCCESS1The restore completed successfully and the new game state is ready to play.
RESTORE_GAME_ABORT2The user aborted the restore procedure, either explicitly by pressing Esc or implicitly by choosing an invalid save slot.

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


SAVE_SLOT_INDEX

#define SAVE_SLOT_INDEX 9

Holds the (zero-indexed) position in the filename template string where save game slot numbers should be inserted.

In the official version of the game, the save file template is "COSMOx.SV " with x having a value between '1' and '3' depending on the episode. The ninth index of this string is a space character, which is replaced with the save slot character during calls to LoadGameState() and SaveGameState().


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.


SCROLLH

#define SCROLLH 18

The height of the scrolling view into the game world, in tiles.


SCROLLW

#define SCROLLW 38

The width of the scrolling view into the game world, in tiles.


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.


SPA_*

#define SPA_PLAYER_START    0
#define SPA_PLATFORM        1
#define SPA_FOUNTAIN_SMALL  2
#define SPA_FOUNTAIN_MEDIUM 3
#define SPA_FOUNTAIN_LARGE  4
#define SPA_FOUNTAIN_HUGE   5
#define SPA_LIGHT_WEST      6
#define SPA_LIGHT_MIDDLE    7
#define SPA_LIGHT_EAST      8

Defines meaningful names for each special actor type defined in the game.

These special actor types map directly to the values found in the map files.


SPR_*

#define SPR_BASKET             0
#define SPR_STAR               1
#define SPR_JUMP_PAD           2
#define SPR_ARROW_PISTON_W     3
#define SPR_ARROW_PISTON_E     4
#define SPR_FIREBALL           5
#define SPR_6                  6
#define SPR_HEAD_SWITCH_BLUE   7
#define SPR_HEAD_SWITCH_RED    8
#define SPR_HEAD_SWITCH_GREEN  9
#define SPR_HEAD_SWITCH_YELLOW 10
#define SPR_DOOR_BLUE          11
#define SPR_DOOR_RED           12
#define SPR_DOOR_GREEN         13
#define SPR_DOOR_YELLOW        14
#define SPR_SPARKLE_SHORT      15
#define SPR_JUMP_PAD_ROBOT     16
#define SPR_SPIKES_FLOOR       17
#define SPR_SPIKES_FLOOR_RECIP 18
#define SPR_SCOOTER_EXHAUST    19
#define SPR_SAW_BLADE          20
#define SPR_POUNCE_DEBRIS      21
#define SPR_SPARKLE_LONG       23
#define SPR_BOMB_ARMED         24
#define SPR_CABBAGE            25
#define SPR_EXPLOSION          26
#define SPR_RAINDROP           27
#define SPR_POWER_UP           28
#define SPR_BARREL             29
#define SPR_BARREL_SHARDS      30
#define SPR_GRN_TOMATO         32
#define SPR_RED_TOMATO         34
#define SPR_YEL_PEAR           36
#define SPR_ONION              38
#define SPR_EXIT_SIGN          39
#define SPR_SPEAR              41
#define SPR_GREEN_SLIME        43
#define SPR_FLYING_WISP        44
#define SPR_TWO_TONS_CRUSHER   45
#define SPR_JUMPING_BULLET     46
#define SPR_STONE_HEAD_CRUSHER 47
#define SPR_48                 48
#define SPR_PYRAMID            49
#define SPR_50                 50
#define SPR_GHOST              51
#define SPR_MOON               54
#define SPR_HEART_PLANT        55
#define SPR_BOMB_IDLE          57
#define SPR_FOOT_SWITCH_KNOB   60
#define SPR_MYSTERY_WALL       62
#define SPR_SPIKES_FLOOR_BENT  63
#define SPR_MONUMENT           64
#define SPR_BABY_GHOST         65
#define SPR_PROJECTILE         68
#define SPR_ROAMER_SLUG        69
#define SPR_PIPE_CORNER_N      70
#define SPR_PIPE_CORNER_S      71
#define SPR_PIPE_CORNER_W      72
#define SPR_PIPE_CORNER_E      73
#define SPR_74                 74
#define SPR_BABY_GHOST_EGG     75
#define SPR_BGHOST_EGG_SHARD_1 76
#define SPR_BGHOST_EGG_SHARD_2 77
#define SPR_SHARP_ROBOT_FLOOR  78
#define SPR_FOUNTAIN           79
#define SPR_SHARP_ROBOT_CEIL   80
#define SPR_HAMBURGER          82
#define SPR_CLAM_PLANT         83
#define SPR_84                 84
#define SPR_GRAPES             85
#define SPR_PARACHUTE_BALL     86
#define SPR_SPIKES_E           87
#define SPR_SPIKES_E_RECIP     88
#define SPR_SPIKES_W           89
#define SPR_BEAM_ROBOT         90
#define SPR_SPLITTING_PLATFORM 91
#define SPR_SPARK              92
#define SPR_DANCING_MUSHROOM   94
#define SPR_EYE_PLANT          95
#define SPR_96                 96
#define SPR_SMOKE              97
#define SPR_SMOKE_LARGE        98
#define SPR_SPARKLE_SLIPPERY   99
#define SPR_RED_JUMPER         101
#define SPR_BOSS               102
#define SPR_PIPE_END           105
#define SPR_SUCTION_WALKER     106
#define SPR_TRANSPORTER_COPY   107
#define SPR_TRANSPORTER        108
#define SPR_SPIT_WALL_PLANT_E  111
#define SPR_SPIT_WALL_PLANT_W  112
#define SPR_SPITTING_TURRET    113
#define SPR_SCOOTER            114
#define SPR_RED_CHOMPER        118
#define SPR_FORCE_FIELD_VERT   122
#define SPR_FORCE_FIELD_HORIZ  123
#define SPR_PINK_WORM          124
#define SPR_HINT_GLOBE         125
#define SPR_PUSHER_ROBOT       126
#define SPR_SENTRY_ROBOT       127
#define SPR_PINK_WORM_SLIME    128
#define SPR_DRAGONFLY          129
#define SPR_WORM_CRATE         130
#define SPR_WORM_CRATE_SHARDS  131
#define SPR_BGHOST_EGG_SHARD_3 132
#define SPR_BGHOST_EGG_SHARD_4 133
#define SPR_BOTTLE_DRINK       134
#define SPR_GRN_GOURD          135
#define SPR_BLU_SPHERES        136
#define SPR_POD                137
#define SPR_PEA_PILE           138
#define SPR_LUMPY_FRUIT        139
#define SPR_HORN               140
#define SPR_RED_BERRIES        141
#define SPR_SATELLITE          143
#define SPR_SATELLITE_SHARDS   144
#define SPR_IVY_PLANT          145
#define SPR_YEL_FRUIT_VINE     146
#define SPR_HEADDRESS          147
#define SPR_EXIT_MONSTER_W     149
#define SPR_150                150
#define SPR_SMALL_FLAME        151
#define SPR_TULIP_LAUNCHER     152
#define SPR_ROTATING_ORNAMENT  153
#define SPR_BLU_CRYSTAL        154
#define SPR_RED_CRYSTAL        155
#define SPR_BEAR_TRAP          162
#define SPR_FALLING_FLOOR      163
#define SPR_164                164
#define SPR_ROOT               168
#define SPR_REDGRN_BERRIES     170
#define SPR_RED_GOURD          172
#define SPR_GRN_EMERALD        174
#define SPR_CLR_DIAMOND        176
#define SPR_SCORE_EFFECT_100   177
#define SPR_SCORE_EFFECT_200   178
#define SPR_SCORE_EFFECT_400   179
#define SPR_SCORE_EFFECT_800   180
#define SPR_SCORE_EFFECT_1600  181
#define SPR_SCORE_EFFECT_3200  182
#define SPR_SCORE_EFFECT_6400  183
#define SPR_SCORE_EFFECT_12800 184
#define SPR_BASKET_SHARDS      185
#define SPR_EXIT_PLANT         186
#define SPR_BIRD               187
#define SPR_ROCKET             188
#define SPR_INVINCIBILITY_CUBE 189
#define SPR_PEDESTAL           192
#define SPR_CYA_DIAMOND        194
#define SPR_RED_DIAMOND        196
#define SPR_GRY_OCTAHEDRON     198
#define SPR_BLU_EMERALD        200
#define SPR_INVINCIBILITY_BUBB 201
#define SPR_THRUSTER_JET       202
#define SPR_HEADPHONES         220
#define SPR_FROZEN_DN          221
#define SPR_SPEECH_MULTI       222
#define SPR_BANANAS            223
#define SPR_RED_LEAFY          226
#define SPR_BRN_PEAR           229
#define SPR_CANDY_CORN         232
#define SPR_FLAME_PULSE_W      233
#define SPR_FLAME_PULSE_E      234
#define SPR_SPEECH_OUCH        235
#define SPR_RED_SLIME          237
#define SPR_SPEECH_WHOA        244
#define SPR_SPEECH_UMPH        245
#define SPR_SPEECH_WOW_50K     246
#define SPR_EXIT_MONSTER_N     247
#define SPR_248                248
#define SPR_249                249
#define SPR_250                250
#define SPR_265                265
#define SPR_DEMO_OVERLAY       266

Defines meaningful names for each sprite type defined in the game.

Sprite type numbers map directly to graphics in the ACTORS.MNI masked tile image data. These sprites are not just used by actors – decorations, shards, explosions, and other arbitrary elements draw from this set of objects.

Some of the constants use a number instead of a description of the sprite. These are “non-canonical” names that either serve as an additional handle to the same data (i.e. there are two different constants that point to the same image data after being looked up through the tile info table) or they hold a nonsensical value that doesn’t matter because the sprite never actually displays on the screen. The following table explains these cases:

Symbolic ConstantDuplicate Version OfDescription
SPR_6SPR_FIREBALLReferenced in InteractPlayer() as a possible object that could interact with the player. Most likely left over from an older implementation of Fireball Projectile (moves east) which now cannot occur anymore.
SPR_48SPR_PYRAMIDReferenced in InteractPlayer() as a possible object that could interact with the player. Most likely left over from an older implementation of Pyramid Spike (on ceiling, stationary) which now cannot occur anymore.
SPR_50SPR_GHOSTReferenced in InteractPlayer() as a possible object that could interact with the player. Most likely left over from an older implementation of Pyramid Spike (on floor) which now cannot occur anymore.
SPR_74SPR_BABY_GHOST_EGGReferenced in InteractPlayer(), CanExplode(), and AddScoreForSprite() as a possible object that could interact with the player. Most likely left over from an older implementation of Baby Ghost Egg (cracks when pounced or player is near) which now cannot occur anymore.
SPR_84SPR_GRAPESReferenced in InteractPlayer(), CanExplode(), and AddScoreForSprite() as a possible object that could interact with the player. Most likely left over from an older implementation of Clam Plant (ceiling mounted) which now cannot occur anymore.
SPR_96SPR_SMOKEReferenced in CanExplode() and AddScoreForSprite() as a possible object that could interact with the player. Most likely left over from an older implementation of Eye Plant (ceiling mounted) which now cannot occur anymore.
SPR_150SPR_SMALL_FLAMEReferenced in NewActorAtIndex() as the sprite type for the invisible actor Exit Line (vertical, exit when east of the line).
SPR_164SPR_ROOTReferenced in NewActorAtIndex() as the sprite type for the invisible actors Episode 1 End Trigger Line (#1, horizontal), Episode 1 End Trigger Line (#2, horizontal), and Episode 1 End Trigger Line (#3, horizontal).
SPR_248SPR_CABBAGEReferenced in NewActorAtIndex() as the sprite type for the invisible actor Smoke Emitter. The graphics referenced here only contain one frame of the SPR_CABBAGE sprite.
SPR_249SPR_CABBAGEReferenced in NewActorAtIndex() as the sprite type for the invisible actor Large Smoke Emitter. The graphics referenced here only contain one frame of the SPR_CABBAGE sprite.
SPR_250SPR_CABBAGEReferenced in NewActorAtIndex() as the sprite type for the invisible actor Exit Line (horizontal, exit when south of the line). The graphics referenced here only contain one frame of the SPR_CABBAGE sprite.
SPR_265SPR_DEMO_OVERLAYReferenced in NewActorAtIndex() as the sprite type for the invisible actor Episode 2 End Trigger Line (horizontal).

Shard

typedef struct {
    word sprite, x, y, frame, age, xmode;
    bool bounced;
} Shard;

Holds the x and y position for a single shard, comprised of a sprite type and a frame. age is zero if this shard slot is inactive, or an incrementing value while the spawner progresses. xmode controls the horizontal movement behavior, bounced is a flag that becomes true once the shard has hit the ground.


Spawner

typedef struct {
    word actor, x, y, age;
} Spawner;

Holds the x and y position for a single spawner. age is zero if this spawner slot is inactive, or an incrementing value while the spawner progresses. actor is the actor type that will be created once the spawner completes.


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.


WORD_MAX

#define WORD_MAX 0xffffU

Constant holding the largest expressible 16-bit unsigned integer value, also known as a machine word.


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.

This is a Music structure.


activePage

word activePage;

Holds the zero-indexed number (0 or 1) of the graphics page that is currently being shown on the screen.

This is only used during gameplay, where it will usually hold the opposite value that drawPageNumber has.


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.


activeTransporter

word activeTransporter;

Holds the number of the destination transporter when one is in use, or zero during normal gameplay.

This is the identifier of the transporter the player is moving to, but the test for this is rather simplistic. For each transporter in the map, if its “to address” data is different from activeTransporter, that transporter is the destination. This limits each map to having two transporters that ping-pong the player between them.

As a special case, a activeTransporter value of 3 will win the level, allowing for one or more Transporter Exits to be implemented separately from any other transporters on the map.


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.


actors[]

Actor actors[MAX_ACTORS];

Contains a fixed amount of space for all of the actors defined on the current map.

Each element of this array is an Actor structure. The array size is bounded by the MAX_ACTORS constant.


areForceFieldsActive

bool areForceFieldsActive;

When true, any force fields present on the map are enabled.

This is always true by default, and can only be set false by using a Foot Switch (deactivates force fields).


areLightsActive

bool areLightsActive;

When true, any lights present on the map are enabled.

On most maps, this variable is set to true by default. It only becomes false if a Foot Switch (activates lights) is loaded into the map, and activation of that switch can set it true again. This variable also influences the behavior of Sentry Robots: when false, the do not shoot at the player.

Related to hasLightSwitch.


arePlatformsActive

bool arePlatformsActive;

When true, any platforms present on the map are enabled.

This is usually true, except on maps that have a Foot Switch (activates platforms). On these maps, this variable is set to false when the actor is constructed and remains in that state until the player activates that switch.


backdropNames[]

char *backdropNames[] = {
    "bdblank.mni", "bdpipe.MNI", "bdredsky.MNI", "bdrocktk.MNI",
    "bdjungle.MNI", "bdstar.MNI", "bdwierd.mni", "bdcave.mni", "bdice.mni",
    "bdshrum.mni", "bdtechms.mni", "bdnewsky.mni", "bdstar2.mni",
    "bdstar3.mni", "bdforest.mni", "bdmountn.mni", "bdguts.mni",
    "bdbrktec.mni", "bdclouds.mni", "bdfutcty.mni", "bdice2.mni",
    "bdcliff.mni", "bdspooky.mni", "bdcrystl.mni", "bdcircut.mni",
    "bdcircpc.mni"
};

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

Note: Not all of the names defined here exist in all of the group files. Some of these names do not exist in any group file.


backdropTable[]

word backdropTable[BACKDROP_WIDTH * BACKDROP_HEIGHT * 4];

A lookup table containing 2,880 words of precalculated offset data used for drawing the in-game parallax scrolling backdrop. It contains four identical copies of the backdrop’s tile offsets, which allows for efficient wrapping without using modulo division.

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

See also BACKDROP_WIDTH and BACKDROP_HEIGHT.


blockActionCmds

bool blockActionCmds;

When true, prevents the player from moving, being hurt, or being drawn.

This variable takes a true value when the player is “removed” from the map, like when interacting with a Tulip Launcher Plant, Exit Monster, Exit Plant, or the E1M11 Exit Monster.


blockMovementCmds

bbool blockMovementCmds;

When true, prevents the player from walking or jumping.

Unlike blockActionCmds, this variable does not hide the player or make them invincible; this is purely an immobilization flag. The only place this is used without an accompanying blockActionCmds is with the Bear Trap actor.

Due to an oversight, this only immobilizes the player when keyboard input is being used. This variable is ignored when a joystick is employed.


canPlayerCling

bool canPlayerCling;

Holds a true value if the player is able to cling to the most recently tested east/west surface.

This is set by TestPlayerMove() and will receive a different result depending on whether DIR4_WEST or DIR4_EAST was most recently tested.


cartoonInfoData

word *cartoonInfoData;

Points to a block of memory containing tile info data (widths, heights, and offsets) for cartoon sprites.

This points to tile info data which has been read directly from disk. No processing is done to pre-parse this data.


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.


decorationFrame[]

word decorationFrame[MAX_DECORATIONS];

Contains the current frame number being displayed by each decoration slot.

This is conceptually a missing member of the Decoration structure, indexed identically to decorations[].


decorations[]

Decoration decorations[MAX_DECORATIONS];

Contains a fixed amount of space for all of the decoration entities defined on the current map.

Each element of this array is a Decoration structure. The array size is bounded by the MAX_DECORATIONS constant.


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 DEMO_STATE_* values while the game is running:

Symbolic ConstantValueDescription
DEMO_STATE_NONE0Game is being played interactively, no demo is being recorded or played.
DEMO_STATE_RECORD1Game is being played interactively, and demo data is being recorded from the input.
DEMO_STATE_PLAY2Game is being controlled by demo data.

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


dir8X[]

int dir8X[] = {0,  0,  1,  1,  1,  0, -1, -1, -1};

Defines the horizontal movement components for the game’s eight-way direction system.

Related to the DIR8_* constants, this array and its counterpart dir8Y[] specify how to change an object’s X and Y coordinates to affect a move in the necessary direction. The dir8X[] and dir8Y[] elements should be added to an object’s X and Y coordinates (respectively).

Symbolic ConstantValuedir8X[Value]dir8Y[Value]
DIR8_NONE000
DIR8_NORTH10-1
DIR8_NORTHEAST21-1
DIR8_EAST310
DIR8_SOUTHEAST411
DIR8_SOUTH501
DIR8_SOUTHWEST6-11
DIR8_WEST7-10
DIR8_NORTHWEST8-1-1

dir8Y[]

int dir8Y[] = {0, -1, -1,  0,  1,  1,  1,  0, -1};

Defines the vertical movement components for the game’s eight-way direction system.

See dir8X[] for details.


drawPageNumber

word drawPageNumber;

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

During gameplay (where double-buffering is used) activePage will usually hold the opposite value, preventing changes from becoming visible on the screen until the pages are flipped.


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.


explosions[]

Explosion explosions[MAX_EXPLOSIONS];

Contains a fixed amount of space for all of the explosion entities defined on the current map.

Each element of this array is an Explosion structure. The array size is bounded by the MAX_EXPLOSIONS constant.


fontTileData

byte *fontTileData;

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


fountains[]

Fountain fountains[MAX_FOUNTAINS];

Contains a fixed amount of space for all of the fountain entities defined on the current map.

Each element of this array is a Fountain structure. The array size is bounded by the MAX_FOUNTAINS constant.


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.


gameScore

dword gameScore;

Holds the number of points that the player has earned over the course of the current game.

Most events in the game add points to this variable. Its purpose is purely vanity, the only effect is to earn a spot in the high score table at the end of the game. The smallest score value implemented in the game is worth 100 points, and the score should always be a multiple of 50 unless e.g. a save file was manipulated.

The acceptable range of values for this variable is 0–9,999,999. Numbers with more than seven characters must be avoided, otherwise draw overflow issues will occur in the status bar.


gameStars

dword gameStars;

Holds the number of stars that the player has collected.

Each star represents a 1,000 point bonus which is added to gameScore during the ShowStarBonus() sequence. The star count is reset to zero once the bonus has been added. The star count also influences which bonus maps are entered over the course of the game:

StarsBonus Map
0–24Skipped.
25–49BONUS1 (E1), BONUS3 (E2), or BONUS5 (E3).
≥50BONUS2 (E1), BONUS4 (E2), or BONUS6 (E3).

The acceptable range of values for this variable is 0–99. Numbers with two or more characters must be avoided, otherwise draw overflow issues will occur in the status bar.


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.


hasHScrollBackdrop

bool hasHScrollBackdrop;

When true, indicates that the current map has a backdrop that should scroll horizontally as the player moves through the game world.


hasLightSwitch

bool hasLightSwitch;

When true, indicates that the current map has a switch that can control the lights.

This variable influences the behavior of Sentry Robots to help them differentiate if areLightsActive is true because there is no Foot Switch (activates lights) on the map, or because the switch is present and has been activated by the player.


hasRain

bool hasRain;

When true, indicates that the current map should spawn random raindrops in uncovered areas.


hasVScrollBackdrop

bool hasVScrollBackdrop;

When true, indicates that the current map has a backdrop that should scroll vertically as the player moves through the game world.


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.


isCartoonDataLoaded

bbool isCartoonDataLoaded;

Holds a true value if the cartoon tile image data has been loaded into the shared memory. When false, this memory is either uninitialized or contains map data.

This is checked by DrawCartoon() to determine if the cartoon data needs to be loaded from disk, avoiding an extra disk access if so. The memory area used for cartoon images (or map data) is mapData.


isDebugMode

bbool isDebugMode;

Holds a true value if the debug 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.

isGodMode

bool isGodMode;

Holds a true value if the god mode has been activated by using the debug keys, and false during normal gameplay.

If isDebugMode is true, this can be toggled while in a game by pressing F10+G.

God mode makes the player invincible to any damage that would deduct health. The player can still die by falling off bottom of the map.


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.


isNewGame

bbool isNewGame;

Holds a true value if the game loop was started via the “Begin New Game” menu option, and false in all other cases (load game or demo mode).

This is set in TitleLoop() and controls whether InitializeLevel() displays a “One Moment” image before loading the first level.


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().


isPlayerInPipe

bbool isPlayerInPipe;

Holds a true value if the player is currently inside the pipe system and false during normal gameplay.

While this variable is true, the player cannot take damage by touching enemies, and will be pushed around the map any time a pipe corner actor is touched.


isPlayerInvincible

bbool isPlayerInvincible;

When true, makes the player immune to all actors that would normally cause damage. Does not protect from falling off the bottom of the map.

This variable is only true while an Invincibility Sphere is present on the map. It gives the same level of protection as the isGodMode cheat flag.


isPlayerNearHintGlobe

bool isPlayerNearHintGlobe;

Holds a true value if the player is currently near any hint globe actor, and false otherwise.

This is used to override the “look up” input command, instead using it to activate a hint globe.


isPlayerNearTransporter

bool isPlayerNearTransporter;

Holds a true value if the player is currently near any transporter actor, and false otherwise.

This is used to override the “look up” input command, instead using it to activate a transporter. In order for this to be true, the player must specifically be standing “inside” the transporter sprite. Merely touching its edge is not sufficient.


isPlayerPushAbortable

bbool isPlayerPushAbortable;

Holds a true value if the currently active push can be ended early by issuing a jump command.

None of the pushes available in the retail game set up a push that enables this flag. Its effect can never be seen without modification.


isPlayerPushBlockable

bool isPlayerPushBlockable;

Holds a true value if the currently active push should stop if a map tile is encountered that blocks movement in the pushed direction.

With this flag unset; the player can be pushed through solid walls. This is how the pipe system moves the player.


isPlayerPushed

bool isPlayerPushed;

Holds a true value if the player is currently immobilized in a “pushed” state, moving in a fixed direction without considering user input.

When true, any player cling is immediately released, the scooter is force-unmounted, and regular player input and movement processing is suspended. After the push has run its course (or the player smacks into something) this becomes false again.


isPlayerSlidingEast

bool isPlayerSlidingEast;

Holds a true value if the player is standing on a surface that is both slippery and sloped down toward the eastern direction.

This value is unconditionally cleared during every call to TestPlayerMove(). It is only possible for it to be reset during cases where DIR4_EAST was the direction tested.


isPlayerSlidingWest

bool isPlayerSlidingWest;

Holds a true value if the player is standing on a surface that is both slippery and sloped down toward the western direction.

This value is unconditionally cleared during every call to TestPlayerMove(). It is only possible for it to be reset during cases where DIR4_WEST was the direction tested.


isPounceReady

bool isPounceReady;

Holds a true value if the player’s horizontal and vertical pounce position are correct relative to the position of the last actor tested by InteractPlayer().

This is also modified during interactions with Scooter and Tulip Launcher Plant actors.


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.


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.

lights[]

Light lights[MAX_LIGHTS];

Contains a fixed amount of space for all of the light actors defined on the current map.

Each element of this array is a Light structure. The array size is bounded by the MAX_LIGHTS constant.


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.


mapNames[]

#define MAP_NAMES { \
    "A1.MNI",  "A2.MNI",  "bonus1.mni", "bonus2.mni", \
    "A3.mni",  "A4.mni",  "bonus1.mni", "bonus2.mni", \
    "A5.mni",  "A6.mni",  "bonus1.mni", "bonus2.mni", \
    "A7.mni",  "A8.mni",  "bonus1.mni", "bonus2.mni", \
    "A9.mni",  "A10.mni", "bonus1.mni", "bonus2.mni", \
    "A11.mni", "A12.mni", "bonus1.mni", "bonus2.mni", \
    "A13.mni", "A14.mni", "bonus1.mni", "bonus2.mni", \
    "A15.mni", "A16.mni" \
}  /* episode 1, or */
#define MAP_NAMES { \
    "B1.MNI",  "B2.MNI",  "bonus3.mni", "bonus4.mni", \
    "B3.mni",  "B4.mni",  "bonus3.mni", "bonus4.mni", \
    "B5.mni",  "B6.mni",  "bonus3.mni", "bonus4.mni", \
    "B7.mni",  "B8.mni",  "bonus3.mni", "bonus4.mni", \
    "B9.mni",  "B10.mni", "bonus3.mni", "bonus4.mni", \
    "B11.mni", "B12.mni", "bonus3.mni", "bonus4.mni", \
    "B13.mni", "B14.mni", "bonus3.mni", "bonus4.mni", \
    "B15.mni", "B16.mni" \
}  /* episode 2, or */
#define MAP_NAMES { \
    "C1.MNI",  "C2.MNI",  "bonus5.mni", "bonus6.mni", \
    "C3.mni",  "C4.mni",  "bonus5.mni", "bonus6.mni", \
    "C5.mni",  "C6.mni",  "bonus5.mni", "bonus6.mni", \
    "C7.mni",  "C8.mni",  "bonus5.mni", "bonus6.mni", \
    "C9.mni",  "C10.mni", "bonus5.mni", "bonus6.mni", \
    "C11.mni", "C12.mni", "bonus5.mni", "bonus6.mni", \
    "C13.mni", "C14.mni", "bonus5.mni", "bonus6.mni", \
    "C15.mni", "C16.mni" \
}  /* episode 3 */
char *mapNames[] = MAP_NAMES;

Defines a list of the map file names corresponding to each level number in the game. Each episode includes higher-numbered maps that do not exist and cannot be reached.


mapWidth

word mapWidth;

Holds the width of the currently-loaded map, in tiles.

This is also the number of tiles that must be added or subtracted to reach a given horizontal position in the next or previous row of the map data. This is usually not used to stride over a fixed number of rows; see mapYPower for that.


mapYPower

word mapYPower;

Holds the width of the currently-loaded map, in tiles, expressed as 2 to the Nth power.

By expressing map width as 2n, it becomes possible to convert X,Y positions to linear tile offsets by calculating X + (Y << mapYPower). This is considerably faster than multiplying Y by mapWidth.


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.


maxScrollY

word maxScrollY;

Holds the largest allowable Y scroll position value for the current map.

This is not the same thing as map height; this is instead the height of the map minus the height of the game window. This is the largest possible value for scrollY before garbage begins to display at the bottom of the game window.


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 maps, 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 maps 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.


mysteryWallTime

word mysteryWallTime;

Controls activation of each Mystery Wall Block on the current map.

This is initialized to zero each time NewActorAtIndex() creates a Mystery Wall Block. It is also forced to zero at the end of each MoveAndDrawActors() call. It is set to four (the actual value has no significance) when a Foot Switch (activates mystery wall) is activated. Any nonzero value activates the Mystery Wall Blocks.


nextActorIndex

word nextActorIndex;

Used as a pass-by-global variable to communicate the actor array slot that should be filled during construction of one actor.


nextDrawMode

word nextDrawMode;

Used as a pass-by-global variable to communicate the display mode to be used when drawing the actively-processing actor’s sprite.


numActors

word numActors;

Holds the current number of utilized elements in the actors array.

This is used as an insertion cursor as actors are being created, pointing to the next available element where one could be inserted. It also is checked against MAX_ACTORS to prevent overflowing the array.


numBarrels

word numBarrels;

Holds the current number of barrel and basket actors (combined) that are alive on the map.

This value in incremented when ConstructActor() adds Barrel/Basket actors to the map, and it is decremented in DestroyBarrel(). When the last remaining barrel is destroyed, the player is given a 50,000 point bonus.


numDecorations

word numDecorations;

Holds the current number of elements in the decorations array, regardless of the number of elements in actual use.

This always has the value of MAX_DECORATIONS.


numExplosions

word numExplosions;

Holds the current number of elements in the explosions array, regardless of the number of elements in actual use.

This always has the value of MAX_EXPLOSIONS.


numEyePlants

word numEyePlants;

Holds the current number of eye plant actors that are alive on the map.

This value in incremented when NewActorAtIndex() adds Eye Plant actors to the map, and it is decremented in CanExplode(). When the last remaining Eye Plant is destroyed, the player is given a 50,000 point bonus.

This value is artificially constrained to 15. If a map has more than this many Eye Plants, only the first 15 are counted.


numFountains

word numFountains;

Holds the current number of utilized elements in the fountains array.

This is used as an insertion cursor as fountains are being created, pointing to the next available element where one could be inserted. This variable is not used for bounds checking, and overflow is possible with a malicious map file.


numLights

word numLights;

Holds the current number of utilized elements in the lights array.

This is used as an insertion cursor as lights are being created, pointing to the next available element where one could be inserted. It also is checked against MAX_LIGHTS to prevent overflowing the array.


numPlatforms

word numPlatforms;

Holds the current number of utilized elements in the platforms array.

This is used as an insertion cursor as platforms are being created, pointing to the next available element where one could be inserted. This variable is not used for bounds checking, and overflow is possible with a malicious map file.


numShards

word numShards;

Holds the current number of elements in the shards array, regardless of the number of elements in actual use.

This always has the value of MAX_SHARDS.


numSpawners

word numSpawners;

Holds the current number of elements in the spawners array, regardless of the number of elements in actual use.

This always has the value of MAX_SPAWNERS.


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.


platforms[]

Platform platforms[MAX_PLATFORMS];

Contains a fixed amount of space for all of the platform entities defined on the current map.

Each element of this array is a Platform structure. The array size is bounded by the MAX_PLATFORMS constant.


playerBaseFrame

word playerBaseFrame;

Tracks the direction the player is currently facing, either east or west, as a base frame offset in the player sprite data.

This should always contain one of the PLAYER_BASE_* values, and represents the number of player sprite frames that must be skipped over to index the appropriately-oriented version of a player sprite. (Left-facing frames require an offset of zero, while an equivalent right-facing frame requires an offset of 23.) When combined with the value in playerFrame, the correct sprite frame is identified.

Several functions in the game use this to determine the direction the player is facing, making this the canonical direction variable (as opposed to playerFaceDir).


playerBombs

word playerBombs;

Holds the number of bombs the player is currently carrying.

The acceptable range of values for this variable is 0–9. Numbers with two or more characters must be avoided, otherwise draw overflow issues will occur in the status bar.


playerClingDir

byte playerClingDir;

Holds a direction value that tracks if the player is clinging to a wall, and which side that wall is on.

This should always contain one of the DIR4_* values. When this equals DIR4_WEST, the player is clinging to a wall that is to their west (i.e. towards the left edge of the screen). Likewise with DIR4_EAST and an east/right wall. In the case of DIR4_NONE, the player is not clinging to any walls.

The remaining DIR4_* values do not make sense as cling directions and should not be used.


playerDeadTime

word playerDeadTime;

Holds a zero while the player is alive, and an incrementing value greater than zero while the player is dead and progressing through the death animation.

During normal gameplay, this holds a zero value. It is set to one the moment the player dies, either by depleting all the health bars or falling off the bottom of the map.

Once the player is dead from health depletion, the counter increments by one during each frame and performs the following actions:

playerDeadTime Value(s)Death Animation Sequence
1SND_PLAYER_HURT sound effect is started.
1–9Player sprite is shown as a stationary angel, with a two-frame “wing flap” animation based on the value playerDeadTime % 2.
10SND_PLAYER_DEATH sound effect is started.
10–11The game window scrolls up by one tile on each frame.
10–37Player sprite moves up by one tile on each frame. Regardless of the player’s starting position, this moves them far above the top edge of the screen.
37With the player fully off the screen, the level restarts.

Death by falling off the map is handled separately based on playerFallDeadTime.


playerDizzyLeft

word playerDizzyLeft;

When nonzero, indicates that the player is immobilized due to being dizzy from an extreme movement. This counter will decrement to zero, at which point the dizzy condition wears off and the player can move again.

The lifecycle of this variable is controlled by ProcessPlayerDizzy(), and it can immediately be canceled by calling ClearPlayerDizzy().


playerFaceDir

word playerFaceDir;

Tracks the direction the player is currently facing, either east or west, as a direction value.

This should always be one of the east/west DIR4_* values.

This is not the primary means of determining the player’s direction; see playerBaseFrame for that. This variable is principally responsible for adding a one-frame “turn around” when a player switches direction. As an example: With the player facing right, quickly tap the “walk left” key. The player will switch directions, but will not move in the horizontal direction. It is only on subsequent “walk left” inputs that the horizontal position will change. This variable is involved in producing that delay.


playerFallDeadTime

byte playerFallDeadTime;

Holds a zero while the player is alive, and an incrementing value greater than zero while the player has fallen off the bottom of the map and is progressing through the death animation.

During normal gameplay, this holds a zero value. It is set to one the moment the player falls off the bottom of the map.

Once the player is off the map, the counter increments by one during each frame and performs the following actions:

playerFallDeadTime Value(s)Death Animation Sequence
1Skipped; playerFallDeadTime is incremented before any comparisons occur.
2SND_PLAYER_HURT sound effect is started.
2–11Occurs during a single game frame, incrementing playerFallDeadTime from 2 to 11 with a hard wait of two ticks between each iteration. This freezes all gameplay for about 1 ⁄ 7 of a second.
13SND_PLAYER_DEATH sound effect is started.
13–18One of the speech bubbles appears above the player, rising by one tile each frame.
19–31The speech bubble remains fixed in its final position.
31The level restarts.

playerFrame

word playerFrame;

Holds the current sprite frame that should be used to represent the player, disregarding east/west-facing variations.

The value here should always be one of the PLAYER_* values, which represent the sprite frames described in the lower half of the player sprite database.

This variable is changed by MovePlayer, MovePlayerScooter, and ProcessPlayerDizzy(). It is read by ProcessAndDrawPlayer(), where it is combined with playerBaseFrame to control the player sprite frame displayed on the screen.


playerHealth

word playerHealth;

Holds the current amount of health the player has. Zero represents the immediate death of the player.

When a new game is started, this is initialized to 4, which represents three filled bars of health. It can decrement down to 1, representing all health bars unfilled. Once it decrements to zero, the player immediately dies.

The maximum amount of health obtainable, once all Hamburgers have been picked up, is 6.


playerHealthCells

word playerHealthCells;

Holds the number of health bar cells that are shown on the status bar. The player always has one unit of health more than the number of bar cells (i.e. the player is still alive if all the cells are unfilled).

When a new game is started, this is initialized to 3, which represents three available bars of health.

The maximum amount of health cells obtainable, once all Hamburgers have been picked up, is 5.


playerHurtCooldown

word playerHurtCooldown;

When greater than zero, makes the player temporarily invincible and flashes the sprite. Decrements toward zero during every frame of gameplay.


playerInfoData

word *playerInfoData;

Points to a block of memory containing tile info data (widths, heights, and offsets) for player sprites.

This points to tile info data which has been read directly from disk. No processing is done to pre-parse this data.


playerPushDir

word playerPushDir;

Specifies the direction in which the player should move during a “push” sequence.

This should be set to one of the DIR8_* constants.


playerPushForceFrame

word playerPushForceFrame;

Specifies the frame of player sprite animation to show during a “push” sequence.

When the player is pushed by actors, this will be set to one of the “force-pushed” frames based on the relative position of the actor. In pipe systems, this will be PLAYER_HIDDEN to temporarily remove the player from the map.


playerPushMaxTime

word playerPushMaxTime;

Holds the number of game ticks that need to elapse before the currently active “push” sequence completes. This duration (in terms of elapsed time) is unaffected by the speed of the push.


playerPushSpeed

word playerPushSpeed;

Holds the configured speed, in tiles per game tick, of the currently active “push” sequence.


playerPushTime

word playerPushTime;

Holds the number of game ticks that have elapsed since the currently active “push” sequence was started.

When this value equals playerPushMaxTime, the push has run to its natural point of completion and stops affecting the player.


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.


playerX

word playerX;

Represents the current horizontal position of the player within the map. The origin tile is on the left edge of the player’s sprite.


playerY

word playerY;

Represents the current vertical position of the player within the map. The origin tile is on the bottom edge of the player’s sprite.


pounceHintState

word pounceHintState;

Holds a flag that tracks whether the user has been shown the “jump on top of creatures…” hint dialog.

At any time, the value of this variable should be one of the POUNCE_HINT_* values. The hint is shown the first time the player is hurt, even if the injury came from an un-pounceable actor.


pounceStreak

word pounceStreak;

Holds a counter that tracks the number of times the player has pounced on any enemy actor without touching the ground.

This value is incremented and tested in TryPounce(), which also gives a 50,000 bonus point on the tenth consecutive pounce. This counter is reset to zero when the player touches the ground, or when they pounce on an actor who is designed to be used as a platform. Notably, the pounce streak is not reset when the player clings to a wall.


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.


queuePlayerDizzy

bool queuePlayerDizzy;

When true, indicates that a condition has been reached that will cause the player to become “dizzy” upon touching the ground – that is, temporarily immobilized due to an extreme amount of movement.

This variable is usually set while the player is off the ground (either free-falling or moving through pipes). Once the player lands on the ground, the presence of this flag initiates the dizzy countdown tracked in playerDizzyLeft.


randStepCount

word randStepCount;

Holds an index value between 0 and 35 that is used by the game’s pseudorandom number generator to produce deterministic random numbers for the game’s actors.

Used exclusively by GameRand(); only exposed globally so that it can be reset by InitializeMapGlobals().


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.


sawAutoHintGlobe

bbool sawAutoHintGlobe;

Holds a true value once the user has touched a hint globe, resulting in auto-activation without needing to press the “look up” key. Defaults to false each time a level is started.

Once a hint globe has auto-activated once, no other hint globe will do that on the current level – the player must explicitly press the “look up” key to see subsequent messages.

This variable is forced true during demo recording and playback to prevent hint display from interfering with gameplay in those contexts.


sawBearTrapBubble

bool sawBearTrapBubble;

Holds a true value once the user has encountered a bear trap actor for the first time, resulting in an “UMPH!” speech bubble Defaults to false each time a level is started.


sawBombHint

bool sawBombHint;

Holds a true value once the user has seen the hint dialog teaching them about finding and using bombs. Defaults to false when a new game is started.


sawBossBubble

bool sawBossBubble;

Holds a true value once the user has encountered a boss actor for the first time, resulting in a “WHOA!” speech bubble Defaults to false each time a level is started.


sawHamburgerBubble

bool sawHamburgerBubble;

Holds a true value once the user has picked up a hamburger for the first time, resulting in a “WHOA!” speech bubble Defaults to false each time a level is started.


sawHealthHint

bool sawHealthHint;

Holds a true value once the user has seen the hint dialog teaching them about Power Up modules and their effect on player health. Defaults to false when a new game is started.


sawHurtBubble

bool sawHurtBubble;

Holds a true value once the user has seen the “OUCH!” bubble that appears when they get hurt for the first time. Defaults to false each time a level is started.


sawJumpPadBubble

bool sawJumpPadBubble;

Holds a true value once the user has encountered a jump pad actor for the first time, resulting in a “WHOA!” speech bubble Defaults to false each time a level is started.


sawMonumentBubble

bool sawMonumentBubble;

Holds a true value once the user has encountered a monument actor for the first time, resulting in an “UMPH!” speech bubble Defaults to false each time a level is started.


sawMysteryWallBubble

bool sawMysteryWallBubble;

Holds a true value once the user has encountered the switch that activates the mystery wall for the first time, resulting in a “WHOA!” speech bubble Defaults to false each time a level is started.


sawPipeBubble

bool sawPipeBubble;

Holds a true value once the user has exited the pipe system for the first time, resulting in a “WHOA!” speech bubble Defaults to false each time a level is started.


sawPusherRobotBubble

bool sawPusherRobotBubble;

Holds a true value once the user has encountered a pusher robot actor for the first time, resulting in an “UMPH!” speech bubble Defaults to false each time a level is started.


sawScooterBubble

bool sawScooterBubble;

Holds a true value once the user has encountered a scooter actor for the first time, resulting in a “WHOA!” speech bubble Defaults to false each time a level is started.


sawTransporterBubble

bool sawTransporterBubble;

Holds a true value once the user has exited a transporter for the first time, resulting in a “WHOA!” speech bubble Defaults to false each time a level is started.


sawTulipLauncherBubble

bool sawTulipLauncherBubble;

Holds a true value once the user has been ejected by a tulip launcher actor for the first time, resulting in a “WHOA!” speech bubble Defaults to false each time a level is 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.


scooterMounted

word scooterMounted;

Holds a combination state flag/counter that tracks if the player is currently riding a scooter and for how long that has been the case.

This variable will hold zero when the player is not riding a scooter, and nonzero when the player is doing so. At the moment a scooter is initially mounted, this variable is set to 4 and decrements on each successive frame until reaching 1, where it remains until the scooter is unmounted. This decrementing counter governs the initial upward “takeoff” at mount time.


scrollX

word scrollX;

Holds the X coordinate of the map column currently positioned at the leftmost edge of the screen.


scrollY

word scrollY;

Holds the Y coordinate of the map row currently positioned at the topmost edge of the screen.


shards[]

Shard shards[MAX_SHARDS];

Contains a fixed amount of space for all of the shard entities defined on the current map.

Each element of this array is a Shard structure. The array size is bounded by the MAX_SHARDS constant.


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.

Note: soundPriority[0] is used to hold the data that underpins the (completely unrelated) playerJumpTime variable. Functions that use soundPriority[] should always be aware that the zeroth element should not be touched under any circumstances.


spawners[]

Spawner spawners[MAX_SPAWNERS];

Contains a fixed amount of space for all of the spawner entities defined on the current map.

Each element of this array is a Spawner structure. The array size is bounded by the MAX_SPAWNERS constant.


starBonusRanks[]

char *starBonusRanks[] = {
    "    Not Bad!    ", "    Way Cool    ", "     Groovy     ",
    "    Radical!    ", "     Insane     ", "     Gnarly     ",
    "   Outrageous   ", "   Incredible   ", "    Awesome!    ",
    "   Brilliant!   ", "    Profound    ", "    Towering    ",
    "Rocket Scientist"
};

Contains a sequence of thirteen fixed-length ranks which are shown as the player earns more stars.


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.


transporterTimeLeft

word transporterTimeLeft;

Holds a zero value while the player is not using any transporter, and a nonzero decrementing counter while a transporter is in use.

When any transporter is used, this value is set to 15. At that moment, all the transporters on the map emit several sparkle decorations and the SND_TRANSPORTER_ON sound effect is started. While this value decrements toward zero, all transporter sprites randomly flash white. Once zero is reached, the requisite transporter action occurs – either relocating the player or winning the level.


usedCheatCode

bool usedCheatCode;

Holds a flag that indicates that the user has used the cheat code.

This is usually false until the user enters the C+0+F10 cheat. The intention of this variable is to prevent the user from using the cheat code more than once in a single game.


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().


winGame

bool winGame;

Indicates if the conditions have been met for the entire game to be “won,” terminating the game loop and showing the ending story.

At the start of each level, winGame 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 game is considered to have been won.

winGame is activated by the Boss, Episode 1 End Trigger Line, and Episode 2 End Trigger Line actors.


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.