Global Variables and Constants
This page contains a listing of every global variable defined in the game, along with the declarations and a brief description of what each one does.
For our purposes, a global variable is anything that is defined outside of a function, whether it is declared static
(private to its compilation unit) or not. This page also includes enum
s, #define
s, and really anything else that seems useful to document.
Common Types
These are the enumerations and custom types that are frequently used. Generally any variable that holds an unsigned data type will use one of the following:
enum {false = 0, true};
typedef unsigned char byte; /* 8-bit unsigned integer */
typedef unsigned int word; /* 16-bit unsigned integer */
typedef unsigned long dword; /* 32-bit unsigned integer */
typedef word bool; /* Boolean stored in a machine word (16-bit) */
typedef byte bbool; /* Boolean stored in a byte */
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 theSPR_*
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 tox
, 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 additionaldata
fields.eastfree
: Similar towestfree
, but in the eastern direction.data1
–data5
: 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 toplayerHurtCooldown
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 Constant | Value | Description |
---|---|---|
DEMO_STATE_NONE | 0 | The 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_RECORD | 1 | The 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_PLAY | 2 | The 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 Constant | Value | Description |
---|---|---|
DIR2_SOUTH | 0 | Points toward the bottom edge of the screen. |
DIR2_NORTH | 1 | Points toward the top edge of the screen. |
DIR2_WEST | 0 | Points toward the left edge of the screen. |
DIR2_EAST | 1 | Points 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
equalsDIR4_NORTH
, whileDIR2_NORTH
equalsDIR4_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 Constant | Value | Description |
---|---|---|
DIR4_NONE | 0 | Refers 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_NORTH | 0 | Points toward the top edge of the screen. |
DIR4_SOUTH | 1 | Points toward the bottom edge of the screen. |
DIR4_WEST | 2 | Points toward the left edge of the screen. |
DIR4_EAST | 3 | Points 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 Constant | Value | Description |
---|---|---|
DIR8_NONE | 0 | Represents the absence of direction and/or a state of no movement. |
DIR8_NORTH | 1 | Points toward the top edge of the screen. |
DIR8_NORTHEAST | 2 | Points up and to the right. |
DIR8_EAST | 3 | Points toward the right edge of the screen. |
DIR8_SOUTHEAST | 4 | Points down and toward the right. |
DIR8_SOUTH | 5 | Points toward the bottom edge of the screen. |
DIR8_SOUTHWEST | 6 | Points down and toward the left. |
DIR8_WEST | 7 | Points toward the left edge of the screen. |
DIR8_NORTHWEST | 8 | Points 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 Constant | Value | Description |
---|---|---|
DRAW_MODE_NORMAL | 0 | Draw the sprite unmodified, with X/Y positions measured relative to the game world. If the map data contains a “draw in front” tiles that intersect the sprite, the map tiles will prevail. |
DRAW_MODE_HIDDEN | 1 | Do not draw any part of the sprite. |
DRAW_MODE_WHITE | 2 | Same as DRAW_MODE_NORMAL , but all opaque pixel positions in the sprite are drawn in bright white. |
DRAW_MODE_TRANSLUCENT | 3 | Same as DRAW_MODE_WHITE , but the sprite color is translucent. |
DRAW_MODE_FLIPPED | 4 | Same as DRAW_MODE_NORMAL , but the sprite is drawn flipped vertically. |
DRAW_MODE_IN_FRONT | 5 | Same as DRAW_MODE_NORMAL , but the sprite will cover all map tiles, regardless of their “draw in front” attribute. |
DRAW_MODE_ABSOLUTE | 6 | Draw the sprite unmodified, with X/Y positions measured relative to the screen. Since there is no relationship to the game world in this mode, “draw in front” attributes from the map (if present) have no effect. |
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 aDIR4_*
value representing the current movement direction. Each fountain starts inDIR4_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 forstepcount
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 Constant | Value | Description |
---|---|---|
GAME_INPUT_CONTINUE | 0 | The 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_QUIT | 1 | The user wants to quit the current game, and the game loop needs to stop running. |
GAME_INPUT_RESTART | 2 | The 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 Constant | Value | Description |
---|---|---|
HELP_MENU_CONTINUE | 0 | The 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_RESTART | 1 | The user loaded a saved game, and the game loop needs to restart from the beginning with this new state. |
HELP_MENU_QUIT | 2 | The 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 Constant | Value | Shape | Description |
---|---|---|---|
LIGHT_SIDE_WEST | 0 | ◢ | Represents the left side of a light cone. This lightens the lower-right area of a tile. |
LIGHT_SIDE_MIDDLE | 1 | ◼ | Represents the middle of a lighted area. The entire tile is lightened. |
LIGHT_SIDE_EAST | 2 | ◣ | Represents 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 Constant | Value | Description |
---|---|---|
MOVE_FREE | 0 | The attempted move places the sprite into an area of free space on the map; hence the move is permissible. |
MOVE_BLOCKED | 1 | The attempted move places the sprite either partially or completely inside an impassible area of the map; the move attempt should be blocked. |
MOVE_SLOPED | 2 | The 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 Constant | Value | Description |
---|---|---|
POUNCE_HINT_UNSEEN | 0 | The hint has never been shown. If the player is hurt, it is appropriate to show the hint. |
POUNCE_HINT_QUEUED | 1 | The 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_SEEN | 2 | The 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 Constant | Value | Description |
---|---|---|
RESTORE_GAME_NOT_FOUND | 0 | The user chose a valid save slot, but there was no file saved there. |
RESTORE_GAME_SUCCESS | 1 | The restore completed successfully and the new game state is ready to play. |
RESTORE_GAME_ABORT | 2 | The 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_107 107
#define SPR_TRANSPORTER_108 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 Constant | Duplicate Version Of | Description |
---|---|---|
SPR_6 | SPR_FIREBALL | Referenced 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_48 | SPR_PYRAMID | Referenced 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_50 | SPR_GHOST | Referenced 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_74 | SPR_BABY_GHOST_EGG | Referenced 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_84 | SPR_GRAPES | Referenced 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_96 | SPR_SMOKE | Referenced 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_150 | SPR_SMALL_FLAME | Referenced in NewActorAtIndex() as the sprite type for the invisible actor Exit Line (vertical, exit when east of the line). |
SPR_164 | SPR_ROOT | Referenced 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_248 | SPR_CABBAGE | Referenced 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_249 | SPR_CABBAGE | Referenced 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_250 | SPR_CABBAGE | Referenced 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_265 | SPR_DEMO_OVERLAY | Referenced 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
orFREE
do not restrict movement, and essentially behave as “air.” - Names including
PLATFORM
only block movement in the southern direction. The player may jump up through them freely, but movement will stop if they land on it from above. - Names including
BLOCK
are solid, and block movement in all directions. - Names with a direction indicate that they are meant to be used in conjunction with other, similarly named tiles to draw larger constructions. The directions indicate the correct relative position for each tile.
TITLE_SCREEN
#define TITLE_SCREEN "TITLE1.MNI" /* episode 1, or */
#define TITLE_SCREEN "TITLE2.MNI" /* episode 2, or */
#define TITLE_SCREEN "TITLE3.MNI" /* episode 3 */
Defines the group file entry name of the full-screen image to show during the main title sequence.
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 Constant | Value | Description |
---|---|---|
DEMO_STATE_NONE | 0 | Game is being played interactively, no demo is being recorded or played. |
DEMO_STATE_RECORD | 1 | Game is being played interactively, and demo data is being recorded from the input. |
DEMO_STATE_PLAY | 2 | Game 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 Constant | Value | dir8X[Value] | dir8Y[Value] |
---|---|---|---|
DIR8_NONE | 0 | 0 | 0 |
DIR8_NORTH | 1 | 0 | -1 |
DIR8_NORTHEAST | 2 | 1 | -1 |
DIR8_EAST | 3 | 1 | 0 |
DIR8_SOUTHEAST | 4 | 1 | 1 |
DIR8_SOUTH | 5 | 0 | 1 |
DIR8_SOUTHWEST | 6 | -1 | 1 |
DIR8_WEST | 7 | -1 | 0 |
DIR8_NORTHWEST | 8 | -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:
Stars | Bonus Map |
---|---|
0–24 | Skipped. |
25–49 | BONUS1 (E1), BONUS3 (E2), or BONUS5 (E3). |
≥50 | BONUS2 (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 Number | Map Number | Notes |
---|---|---|
0 | 1 | |
1 | 2 | |
2 | Bonus A | The warp menu chooses this instance. |
3 | Bonus B | The warp menu chooses this instance. |
4 | 3 | |
5 | 4 | |
6 | Bonus A | |
7 | Bonus B | |
8 | 5 | |
9 | 6 | |
10 | Bonus A | |
11 | Bonus B | |
12 | 7 | |
13 | 8 | |
14 | Bonus A | |
15 | Bonus B | |
16 | 9 | |
17 | 10 | |
18 | Bonus A | |
19 | Bonus B | |
20 | 11 | Only present in episode 1. |
21 | 12 | Supported; never used. |
22 | Bonus A | |
23 | Bonus B | |
24 | 13 | Supported; never used. |
25 | 14 | Supported; never used. |
26 | Bonus A | |
27 | Bonus B | |
28 | 15 | Supported; never used. |
29 | 16 | Not supported; implementation incomplete. |
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 |
---|---|
1 | SND_PLAYER_HURT sound effect is started. |
1–9 | Player sprite is shown as a stationary angel, with a two-frame “wing flap” animation based on the value playerDeadTime % 2 . |
10 | SND_PLAYER_DEATH sound effect is started. |
10–11 | The game window scrolls up by one tile on each frame. |
10–37 | Player 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. |
37 | With 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 |
---|---|
1 | Skipped; playerFallDeadTime is incremented before any comparisons occur. |
2 | SND_PLAYER_HURT sound effect is started. |
2–11 | Occurs 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. |
13 | SND_PLAYER_DEATH sound effect is started. |
13–18 | One of the speech bubbles appears above the player, rising by one tile each frame. |
19–31 | The speech bubble remains fixed in its final position. |
31 | The 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 usesoundPriority[]
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.