Patch:Tiles

From KeenWiki
Jump to: navigation, search

This page contains patches relating to tiles and tile properties in Keen. Some tile properties have their own pages, such as Patch:Ice tiles. Patching the 'tileinfo' file that contains a 'list' of what tiles have what properties in the game is discussed under Patch:Tileinfo.

This page has five sections: the first is a list of individual tile properties with their own pages; the second a note about how level and map tile codes work; the third a section on various patches involving the tile processing code in the games; a fourth a section explaining how tiles work; and finally a section for tile property editing tools.


Tile types with their own pages

This is a list of tile property pages, each one containing patches on how that individual tile property works. Some of these pages are only for one specific episode of Keen, other span multiple episodes. Some, especially in Keen Galaxy have sprite counterparts.


Levels map tile code is used in

In Keen Galaxy and Dreams there are two 'player tile interactions' that are used by the current player sprite in addition to that sprite's own tile interaction code. The 'level tile code' is responsible for the player's interactions with items, gem holders and deadly tiles while the 'map tile code' is responsible for the player's interaction with map teleporters and water entrances.

By default only in level 0 does the player sprite use the map tile code; otherwise the level tile code is used instead. This can however be changed.

Patch: Levels map tile code is used in
#What level(s) Keen uses map tile interaction in -Keen 4
%patch $8FBC $A7EDW $00 $74
#What level(s) Keen uses map tile interaction in -Keen 5
%patch $8F2E $9E55W $00 $74
#What level(s) Keen uses map tile interaction in -Keen 6
%patch $8D96 $A97BW $00 $74


Tile code patches

These patches change the tile code in the games, that is, how the game deals with tiles themselves. A number of patches that would have been included here are included instead on other tiles pages. (See above section.)


Keen 3 style tiles in Keen 1 and 2

These patches replicate the Keen 3 'row' type behavior in Keen 1 and 2. This allows a modder to have a greater variety of 'background' tiles in their mods. The reverse (Keen 1\2 type behavior in Keen 3) is possible, but has not been requested.

Please note that Keen 1 and 2 actually use two background tiles, due to how the code works. The first is tile 143, the second is tile 276. This is seldom noticed, but can be seen in Keen 2.)

The patches have three sections, the first affecting point items, the second affecting other items and the third affecting doors. The third section is independent; it can be left out if desired. The second section requires the first section to work, but lines can be removed from it if, for example, just keycards are desired to behave as in Keen 1.

The blue $0Ds are important; in the patches below any tile 'got' is replaced by one that is the nearest multiple of 13 ($0D) below it in the tileset. Since each row of tileset is 13 tiles, the default patch replaces any tile with the first one in its row. If you double this it becomes the first tile in every second row and so on. (Good if you have a lot of item tiles and such.) It can even be narrowed down to $02 (Items will be replaced by every second tile, versatile, but uses a LOT of tiles!)

Because the door section is independent it has its own variable. This can be useful if you don't want to waste background tiles on doors.

Patch: Keen 1 background tiles behave like Keen 3
#Change item tiles to use tiles at the end of each row ($0D) of tiles
%patch $4409 $26 $8B $07 $B6 $0D $F6 $FE %patch $4410 $F6 $EE $26 $89 $07 $E9 $60 $01
#Change keys, items, etc to use point tiles instead
%patch $4482 $E9 $74 $FF
#Affect ship parts
%patch $44BA $E9 $3C $FF
#Affect raygun, pogo
%patch $4513 $E9 $E3 $FE
#Affect keycards
#Change doors
%patch $28EC $26 $8B $07 $B6 %patch $28F0 $0D $F6 $FE $F6 $EE $26 $89 $07 %patch $28F8 $03 $1E $08 $6C $03 $1E $08 $6C %patch $2900 $26 $89 $07 $90 $90 $90 $90 $90

Patch: Keen 2 background tiles behave like Keen 3
#Change item tiles to use tiles at the end of each row ($0D) of tiles
%patch $724B $26 $8B $07 $B6 $0D %patch $7250 $F6 $FE $F6 $EE $26 $89 $07 $E9 %patch $7258 $14 $01
#Change keys, items, etc to use point tiles instead
%patch $72A2 $EB $97
#Affect raygun, pogo
%patch $7327 $E9 $11 $FF
#Affect keycards
#Change doors
%patch $572E $26 $8B %patch $5730 $07 $B6 $0D $F6 $FE $F6 $EE $26 %patch $5738 $89 $07 $03 $1E $E4 $6B $03 $1E %patch $5740 $E4 $6B $26 $89 $07 $90 $90 $90 %patch $5748 $90 $90


Free up 15Kb of patch space (Keen 1)

By rewriting the procedure that draws tiles into a more compact form, $38C0 = 14528 bytes are freed. Of course the procedure takes marginally longer to execute now, but on DOSBox at 3000 cycles it is not noticeable.

$1940 bytes are freed in the code segment
$1F80 bytes are freed starting at segment 1000:0.
The first byte is located at $E6C0.

Patch: Keen 1
#Rewrite tile routine to free up 15Kb
%patch $11F80 $06 $1E $50 $A1 $B2 $35 $8E $C0 $A1 $6A $83 $8E $D8 $A4 $A4 $03 $FA $A4 $A4 $03 $FA $A4 $A4 $03 $FA $A4 $A4 $03 $FA $A4 $A4 $03 $FA $A4 $A4 $03 $FA $A4 $A4 $03 $FA $A4 $A4 $03 $FA $A4 $A4 $03 $FA $A4 $A4 $03 $FA $A4 $A4 $03 $FA $A4 $A4 $03 $FA $A4 $A4 $03 $FA $A4 $A4 $03 $FA $A4 $A4 $03 $FA $A4 $A4 $03 $FA $58 $1F $07 $C3 $BA $2E $00 $66 $33 $C0 $8B $C3 $66 $8B $D8 $66 $33 $C0 $8B $C8 $3D $26 $01 $7D $35 $67 $26 $8B $34 $43 $D1 $E6 $8B $32 $67 $3B $34 $45 $16 $5B $00 $00 $74 $13 $67 $89 $34 $45 $16 $5B $00 $00 $67 $8B $3C $45 $C0 $35 $00 $00 $E8 $74 $FF $40 $41 $83 $F9 $15 $7C $CE $33 $C9 $03 $1E $54 $56 $EB $C6 $CB $BA $2E $00 $66 $33 $C0 $8B $C3 $66 $8B $D8 $66 $33 $C0 $8B $C8 $3D $26 $01 $7D $35 $67 $26 $8B $34 $43 $D1 $E6 $8B $32 $67 $3B $34 $45 $B8 $5D $00 $00 $74 $13 $67 $89 $34 $45 $B8 $5D $00 $00 $67 $8B $3C $45 $C0 $35 $00 $00 $E8 $29 $FF $40 $41 $83 $F9 $15 $7C $CE $33 $C9 $03 $1E $54 $56 $EB $C6 $CB %patch $B7B2 $3911W
#UpdateFarCall to ADT_0
%patch $B7AA $395CW
#UpdateFarCall to ADT_1


Stop Player interacting with tiles

This patch stops the player from interacting with tile properties; the player will still stand on solid tiles or appear behind foreground tiles. But they will be unable to obtain tile points or be killed by deadly tiles.

Patch: Keen 4
#Stop Keen from interacting with tiles
%patch $8FC5 $90 $90 $90 $90 $90


Tile code

There are two parts to the tile code in each Keen game, the tile code pointer list and the actual codes themselves.

The pointer list is exactly what it sounds like, tile properties of tiles the player is touching in level maps are simply values in the from $00-$FF. The pointer list takes this value and tells the game where code saying what to do next is located.

There are three parts to this, the list's location, its length (minus one) and the list itself. The list consists of a number of two-byte values each related to the location of a sprite's initiation code. Every collision with a tile with a property of a certain number will be directed via the list to a certain segment of initiation code.

Sometimes several tile types use the same code. In that case there needs to be a further check to see what must be done for each tile type. Sometimes also the list does not begin at type 0, this is the case for the Galaxy games, where the list begins at type 3.


Keen 1

Pointer list

Patch: Keen 1
#Pointer to tile property list
%patch $4385 $4590W
#Number of tile properties -1
%patch $437A $19
#Tile property references
%patch $4590 $4387W
#Kills
%patch $4592 $438DW
#Door 1
%patch $4594 $438DW
#Door 2
%patch $4596 $438DW
#Door 3
%patch $4598 $438DW
#Door 4
%patch $459A $43E2W
#500
%patch $459C $43E2W
#100
%patch $459E $43E2W
#200
%patch $45A0 $43E2W
#1000
%patch $45A2 $43E2W
#5000
%patch $45A4 $4440W
#Joystick
%patch $45A6 $4440W
#Battery
%patch $45A8 $4440W
#Vacuum
%patch $45AA $4440W
#Whiskey
%patch $45AC $449AW
#Raygun
%patch $45AE $449AW
#Pogo
%patch $45B0 $44D2W
#Exit
%patch $45B2 $44FFW
#Key 1
%patch $45B4 $44FFW
#Key 2
%patch $45B6 $44FFW
#Key 3
%patch $45B8 $44FFW
#Key 4
%patch $45BA $452AW
#Message
%patch $45BC $4562W
#Lightswitch
%patch $45BE $4572W
#Teleporter
%patch $45C0 $4562W
#Switch on
%patch $45C2 $4562W
#Switch off


Ship parts tile code

The parts tile code is the same for all four Ship parts. As such it checks for each tile type individually. The first part of the code is four checks for tile types $0B to $0E which if the tile matches the appropriate part counter is set to 1. At the start of line 4 a call is made to point increasing code adding 10'000 points ($2710W) and sound $0B is played.

Following this the tile is removed and replaced with tile $8F.

Patch: Keen 1
#Default ship parts tile code
%patch $4440 $83 $7E $F6 $0B $75 $06 $C7 $06 $AA94W $0001W $83 $7E $F6 $0C $75 $06 $C7 $06 $AA9CW $0001W $83 $7E $F6 $0D $75 $06 $C7 $06 $AA96W $0001W $83 $7E $F6 $0E $75 $06 $C7 $06 $AA98W $0001W $B8 $2710W $50 $E8 $C8DBW $44 $44 $B8 $000BW $50 $E8 $7A73W $44 $44 $8B $C6 $F7 $2E $08 $6C $03 $C7 $D1 $E0 $C4 $1E $48 $6C $03 $D8 $26 $C7 $07 $008FW $E9 $00DEW


Keycard tile code

The parts tile code is the same for all four keycards. Unlike the ship parts tile code there is no tile type check. On the first line it appears as if the first keycard value is set to 1, however the actual variable set will depend on which tile type (And thus keycard) Keen obtained, $AA7AW is merely the first of four variables.

Following this sound $20 is played and the tile is removed and replaced with tile $8F.

Patch: Keen 1
#Default keycard tile code
%patch $44FF $8B $5E $F6 $D1 $E3 $C7 $87 $AA7AW $0001W $B8 $0020W $50 $E8 $79E2W $44 $44 $8B $C6 $F7 $2E $08 $6C $03 $C7 $D1 $E0 $C4 $1E $48 $6C $03 $D8 $26 $C7 $07 $008FW $EB $4E


Pogo and ammo tile code

Both the pogo and ammo use the same code, possibly due to using the same sound when obtained. This causes the code to need to check the tile type again. On the first line the ammo tile type is checked for; if found Keen's ammo variable is increased by 5. On the same line the Pogo's tile type is checked for, if found the Pogo variable is set to 1. After that both codes are the same; sound $0A is played.

Following this the tile is removed and replaced with tile $8F.

Patch: Keen 1
#Default Pogo and ammo tile code
%patch $449A $83 $7E $F6 $0F $75 $05 $83 $06 $AAC8W $05 $83 $7E $F6 $10 $75 $06 $C7 $06 $AA9AW $0001W $B8 $000AW $50 $E8 $7A3BW $44 $44 $8B $C6 $F7 $2E $08 $6C $03 $C7 $D1 $E0 $C4 $1E $48 $6C $03 $D8 $26 $C7 $07 $008FW $E9 $00A6W


Exit tile code

The exit tile code begins with a check of the player's current behavior. (This can be different from Keen's behavior causing the 'midair exit glitch'.) If this is not his standing behavior then the remaining code is skipped. This prevents Keen from exiting when not on the ground. (Most of the time.) After this sound $F is played and the player's behavior set to $40EFW, or 'exit walk'. The player's sprite collision is set to $3360W or 'nothing' to prevent the player dying, etc when exiting. Two other player variables are also set.

Patch: Keen 1
#Default exit tile code
%patch $44D2 $81 $3E $6F0CW $3867W $74 $03 $E9 $009BW $B8 $000FW $50 $E8 $7A0FW $44 $44 $C7 $06 $6F0CW $40EFW $C7 $06 $6F0EW $3360W $8B $C7 $40 $40 $A3 $6F04W $89 $36 $6F06W $EB $79


Teleporter tile code

The teleporter tile code is quite basic; when Keen touches the tile the 'teleport' variable is set to 2, triggering the actual teleportation elsewhere.

Patch: Keen 1
#Default teleporter tile code
%patch $4572 $C7 $06 $6C60W $0002W


Keen 2

Pointer list

Patch: Keen 2
#Pointer to tile property list
%patch $71C7 $7386W
#Number of tile properties -1
%patch $71BC $19
#Tile property references
%patch $7386 $71C9W
#Kills
%patch $7388 $71CFW
#Door 1
%patch $738A $71CFW
#Door 2
%patch $738C $71CFW
#Door 3
%patch $738E $71CFW
#Door 4
%patch $7390 $7224W
#500
%patch $7392 $7224W
#100
%patch $7394 $7224W
#200
%patch $7396 $7224W
#1000
%patch $7398 $7224W
#5000
%patch $739A $736EW
#Joystick
%patch $739C $736EW
#Battery
%patch $739E $736EW
#Vacuum
%patch $73A0 $736EW
#Whiskey
%patch $73A2 $7282W
#Raygun
%patch $73A4 $7282W
#Pogo
%patch $73A6 $72E9W
#Exit
%patch $73A8 $7313W
#Key 1
%patch $73AA $7313W
#Key 2
%patch $73AC $7313W
#Key 3
%patch $73AE $7313W
#Key 4
%patch $73B0 $733EW
#Message
%patch $73B2 $7358W
#Lightswitch
%patch $73B4 $7368W
#Teleporter
%patch $73B6 $7358W
#Switch on
%patch $73B8 $7358W
#Switch off


Keen 3

Pointer list

Patch: Keen 3
#Pointer to tile property list
%patch $7A30 $7C1BW
#Number of tile properties -1
%patch $7A25 $1B
#Tile property references
%patch $7C1B $7A32W
#Kills
%patch $7C1D $7A38W
#Door 1
%patch $7C1F $7A38W
#Door 2
%patch $7C21 $7A38W
#Door 3
%patch $7C23 $7A38W
#Door 4
%patch $7C25 $7A8AW
#500
%patch $7C27 $7A8AW
#100
%patch $7C29 $7A8AW
#200
%patch $7C2B $7A8AW
#1000
%patch $7C2D $7A8AW
#5000
%patch $7C2F $7C03W
#Joystick
%patch $7C31 $7C03W
#Battery
%patch $7C33 $7C03W
#Vacuum
%patch $7C35 $7C03W
#Whiskey
%patch $7C37 $7AC5W
#Raygun
%patch $7C39 $7AC5W
#Pogo
%patch $7C3B $7B0AW
#Exit
%patch $7C3D $7B34W
#Key 1
%patch $7C3F $7B34W
#Key 2
%patch $7C41 $7B34W
#Key 3
%patch $7C43 $7B34W
#Key 4
%patch $7C45 $7B6DW
#Message
%patch $7C47 $7B87W
#Lightswitch
%patch $7C49 $7B97W
#Teleporter
%patch $7C4B $7B87W
#Switch on
%patch $7C4D $7B87W
#Switch off
%patch $7C4F $7B9FW
#Ankh
%patch $7C51 $7BD2W
#Single bullet


Masked tile code

In Keen Vorticons -2 and only -2 is the masked tile property. This property must be less than zero and is checked for at one point in the code. Changing the jump condition marked in brown can allow several types of masked tile that could be given different properties.

Patch: Masked tile property
#Masked tile property - Keen 1
%patch $049F $FE $75
#Masked tile property - Keen 2
%patch $049F $FE $75
#Masked tile property - Keen 3
%patch $04B7 $FE $75


Keen 4

Pointer list

Patch: Keen 4
#Pointer to tile property list
%patch $D16F $1A47W
#Number of tile properties -1
%patch $D164 $19
#Tile property references
%patch $D247 $1971W
#Deadly (At $D171)
%patch $D249 $1978W
#Raindrop: Vanish with a splash, add 1 to raindrop counter (At $D178)
%patch $D24B $1A1EW
#Switch ON: nothing (At $D21E)
%patch $D24D $1A1EW
#Switch OFF: nothing (At $D21E)
%patch $D24F $1986W
#Red holder (At $D186)
%patch $D251 $1986W
#Yellow holder (At $D186)
%patch $D253 $1986W
#Blue holder (At $D186)
%patch $D255 $1986W
#Green holder (At $D186)
%patch $D257 $1A1EW
#Top water: nothing (At $D21E)
%patch $D259 $1A1EW
#Right water: nothing (At $D21E)
%patch $D25B $1A1EW
#Bottom water: nothing (At $D21E)
%patch $D25D $1A1EW
#Left water: nothing (At $D21E)
%patch $D25F $1A1EW
#Moving platform switch (At $D21E)
%patch $D261 $19F8W
#Moon tile: Make Keen moon (At $D1F8)
%patch $D263 $1A1EW
#Sprite arrow path: nothing (At $D21E)
%patch $D265 $1A1EW
#Bridge tile: nothing (At $D21E)
%patch $D267 $1A1EW
#Active zapper: nothing (At $D21E)
%patch $D269 $1A1EW
#Teleport entrance: nothing (At $D21E)
%patch $D26B $1A09W
#100 points: vanish, do item stuff (At $D209)
%patch $D26D $1A09W
#200 points: vanish, do item stuff (At $D209)
%patch $D26F $1A09W
#500 points: vanish, do item stuff (At $D209)
%patch $D271 $1A09W
#1000 points: vanish, do item stuff (At $D209)
%patch $D273 $1A09W
#2000 points: vanish, do item stuff (At $D209)
%patch $D275 $1A09W
#5000 points: vanish, do item stuff (At $D209)
%patch $D277 $1A09W
#1UP: vanish, do item stuff (At $D209)
%patch $D279 $1A09W
#Stunner tile: vanish, do item stuff (At $D209)


Deadly tile code

The deadly tile code simply calls the player death code, causing the player to die.

Patch: Keen 4
#Deadly tile property code
%patch $D171 $0E $E8 $FA74W $E9 $00A6W


Raindrop tile code

The raindrop code is quite simple. When run it calls the actual raindrop code which removes the tile and adds 1 to Keen's drop counter.

Patch: Keen 4
#Raindrop tile property code
%patch $D178 $FF $76 $FE $57 $0E $E8 $FEBFW $83 $C4 $04 $E9 $0098W


Gem holder tile code

The gem holder tile code is responsible for initiating the opening of doors. The gem holder code is somewhat complicated. The first section of the code deals with checks. The first check checks to see if the gem holder tile is 1 tile below Keen's head (So Keen cannot open just any gem holder tile.) The next check determines whether the tile below the gem holder is upwards blocking (So Keen cannot open gem holders in the air.) On the second line Keen's action is checked and if he is already placing a gem then the following code is skipped. (This avoids Keen constantly trying to place a gem but being unable to do so, see also Patch:Jump conditions.)

The next check, on line 3, looks to see if Keen has the right kind of gem (See Patch:Game stats.); seven is taken away from the tile type then, using the red gem variable as a start, the right gem variable is checked. After all these checks are passed then Keen's action is set to 'turn away from screen', starting the door opening sequence and he begins to 'slide' into alignment with the holder. The final check looks to see that this alignment is complete (Otherwise he will try to use the wrong tile as a door locator causing a 'bad spot' error.) if so then the second section is run.

The second section causes Keen to go to the door opening code where his action is set to 'place gem' and a gem is removed from his inventory. (Again seven is taken from the tile type to determine which gem variable is affected.)

Patch: Keen 4
#Gem holder tile property code
%patch $D186 $8B $44 $32 $3B $46 $FE $74 $03 $E9 $00B0W $83 $7C $36 $00 $75 $03 $E9 $00A7W $81 $7C $1C $0E1EW $75 $03 $E9 $009DW $8B $5E $F6 $83 $EB $07 $D1 $E3 $83 $BF $7A60W $00 $75 $03 $E9 $008BW $8B $C7 $B1 $08 $D3 $E0 $05 $FFC0W $89 $46 $F4 $8B $44 $0A $3B $46 $F4 $74 $11 $8B $46 $F4 $89 $44 $3E $C7 $44 $1C $0E3CW $5F $5E $8B $E5 $5D $CB $8B $5E $F6 $83 $EB $07 $D1 $E3 $FF $8F $7A60W $B8 $0E1EW $50 $56 $9A $09DC120ARL $83 $C4 $04 $EB $28


Moon tile code

See also Patch:Keen mooning. When Keen touches a tile with the mooning property and his 'mooning variable' is also 0 (That is, he hasn't mooned before.) then it will be set to 1 (Allowing him to moon.)

Patch: Keen 4
#Mooning tile property code
%patch $D1F8 $83 $3E $CAB5W $00 $75 $1F $C7 $06 $CAB5W $0001W $EB $17


Item tile code

For tile items there are two sections of code that affects what happens. The first adjusts a few things and calls the tile removal code.

When Keen touches an item type tile the tile's property as $15 removed and $04 added to it before being passed to the item tile code proper, $0E $E8 $FD5AW. (This code is also called when item sprites are obtained.) Note the relative call which requires adjustment if this code is moved.

The two blue variables are somewhat redundant; a single subtraction of $11 would suffice. The cause of this complexity is due to the four gem items which cannot be got as tiles by default and the first item tile property being $15. Changing this allows the game to do things such as dealing with gem item tiles.

The second section is the tile removal code, responsible for everything the items do. The first two lines replace the 1x1 item tile are with the tile value stored at $2EE70 + $1424W (This is tile 0 by default.) Line 4 calls the item point list at $2EE70 + $13D4W. After this the item's type is checked, first gems (Types 0-3) which give the appropriate gem, then 1UPs (Type $0A) which add one to Keen's life counter then the neural stunner (Type $0B) which checks the difficulty and loads the right amount of ammo to give from the ammo list at $2EE70 + $13D4W.

Starting on line 8 the 'got item' sprite is spawned, type 1 (Misc) with type 3 foreground (In front of all tiles so it's always visible.) and moving upwards ($FFFFW). Its animation is taken from a list at $2EE70 + $140CW and it uses action $1428W. Finally it is given a clipping of 0, allowing it to pass through tiles.

Patch: Keen 4
#Item tile property code
%patch $D209 $8B $46 $F6 $2D $0015W $05 $0004W $50 $FF $76 $FE $57 $0E $E8 $FD5AW $83 $C4 $06
#Item tile removal code
%patch $CF75 $55 $8B $EC $56 $57 $8B $7E $06 $8B $76 $0A $B8 $0001W $50 $50 $FF $76 $08 $57 $50 $1E $B8 $1424W $50 $9A $16540F28RL $83 $C4 $0E $8B $DE $D1 $E3 $FF $B7 $DC $13 $9A $187409F1RL $83 $C4 $02 $8B $DE $D1 $E3 $FF $B7 $13F4W $9A $06BD1EF2RL $83 $C4 $02 $83 $FE $04 $73 $0A $8B $DE $D1 $E3 $FF $87 $7A60W $EB $1E $83 $FE $0A $75 $06 $FF $06 $7A6AW $EB $13 $83 $FE $0B $75 $0E $8B $1E $7A6CW $D1 $E3 $8B $87 $13D4W $01 $06 $7A58W $B8 $0001W $50 $9A $06BD1E11RL $83 $C4 $02 $8B $1E $D8 $A7 $C7 $07 $0001W $C7 $47 $20 $0003W $8B $C7 $B1 $08 $D3 $E0 $89 $47 $0A $8B $46 $08 $D3 $E0 $89 $47 $0C $C7 $47 $10 $FFFFW $8B $DE $D1 $E3 $8B $87 $140CW $8B $1E $D8 $A7 $89 $47 $1E $89 $47 $40 $B8 $1F28W $50 $53 $9A $09DC118CRL $83 $C4 $04 $8B $1E $D8 $A7 $C7 $47 $06 $0000W $5F $5E $5D $CB


Map tile code

This is the complete code for Keen's map tile interaction, used by the player sprite on the map only. In the main it responds to water entrances\exits. On the first line Keen's 'mask' variable is checked, if zero all code is skipped. The next five lines load tile data.

On lines six and seven the game checks for four kinds of water entrance\exit. If any of these are found the game proceeds to check whether Keen has the Wetsuit. If he does not then sound $0E is played and the 'can't swim' window code called. Finally Keen's horizontal and vertical movement are halted.

In the second section a list at $D8F0W + $09EFW = $E2DF is called for an entry based on the tile type less $0B. The list is 6 + 1 entries long and works differently if Keen is using action $14CEW (Map swimming as opposed to map walking.)

The tile-specific code starts on line 4, and there are 4 valid options; up, down, right and left in that order. Each sets Keen's horizontal and vertical directions. (Note that three of the list's options are 'invalid', not setting any directions.) All codes end up at line 7, setting Keen's 'sprite draw' Variable to 0 and Mask Variable to $12 (This sets the length of time Keen will spend moving in and out of water.)

A second check of Keen's action is then made. If Keen is swimming ($14CEW) then he will transform into walking($15A0W), otherwise the reverse will occur.

Patch: Keen 4
#Map Keen's tile interaction code
%patch $E199 $55 $8B $EC $83 $EC $04 $56 $57 $8B $76 $06 $83 $7C $42 $00 $74 $03 $E9 $012CW $8B $44 $34 $89 $46 $FE $8B $44 $28 $2B $44 $24 $D1 $E8 $8B $54 $24 $03 $D0 $B1 $08 $D3 $EA $89 $56 $FC $8B $5E $FC $D1 $E3 $8B $9F $25 $C9 $D1 $EB $D1 $E3 $8E $06 $E9 $A7 $8B $46 $FE $D1 $E0 $03 $D8 $26 $8B $1F $8E $06 $A1 $C8 $26 $8A $87 $A6 $44 $B4 $00 $8B $F8 $83 $FF $0B $74 $12 $83 $FF $0D $74 $0D $83 $FF $0E $74 $08 $83 $FF $0C $74 $03 $E9 $00D3W $83 $3E $7A5CW $00 $75 $3D $B8 $000EW $50 $9A $187409F1RL $83 $C4 $02 $9A $0E8F0A66RL $9A $16540D59RL $8B $44 $12 $F7 $D8 $A3 $C923W $8B $44 $14 $F7 $D8 $A3 $C921W $33 $C0 $89 $44 $10 $89 $44 $0E $56 $9A $09DC06A5RL $83 $C4 $02 $5F $5E $8B $E5 $5D $CB $8B $DF $83 $EB $0B $D1 $E3 $8B $87 $E6 $15 $89 $44 $3E $81 $7C $1C $14CEW $75 $0C $8B $5C $3E $D1 $E3 $8B $87 $46 $14 $89 $44 $3E $8B $5C $3E $83 $FB $06 $77 $35 $D1 $E3 $2E $FF $A7 $09EFW $C7 $44 $0E $0000W $C7 $44 $10 $FFFFW $EB $22 $C7 $44 $0E $0001W $C7 $44 $10 $0000W $EB $16 $C7 $44 $0E $0000W $C7 $44 $10 $0001W $EB $0A $C7 $44 $0E $FFFFW $C7 $44 $10 $0000W $C7 $44 $40 $0000W $C7 $44 $42 $0012W $81 $7C $1C $14CEW $75 $13 $B8 $15A0W $50 $56 $9A $09DC120ARL $83 $C4 $04 $5F $5E $8B $E5 $5D $CB $B8 $14CEW $50 $56 $9A $09DC120ARL $83 $C4 $04 $5F $5E $8B $E5 $5D $CB
#Tile interaction pointer list
%patch $E2DF $098AW
#Top water entrance (At $E27A)
%patch $E2E1 $09B8W
#INVALID (At $E2A8)
%patch $E2E3 $0996W
#Right water entrance (At $E286)
%patch $E2E5 $09B8W
#INVALID (At $E2A8)
%patch $E2E7 $09A2W
#Bottom water entrance (At $E292)
%patch $E2E9 $09B8W
#INVALID (At $E2A8)
%patch $E2EB $09AEW
#Left water entrance (At $E29E)


Keen 5

Pointer list

Patch: Keen 5
#Pointer to tile property list
%patch $C482 $1A6BW
#Number of tile properties -1
%patch $C477 $19
#Tile property references
%patch $C55B $1994W
#Deadly (At $C484)
%patch $C55D $199BW
#Vitalin: Vanish with a splash, add 1 to Vitalin counter(At $C48B)
%patch $C55F $1A41W
#Switch ON: nothing (At $C531)
%patch $C561 $1A41W
#Switch OFF: nothing (At $C531)
%patch $C563 $19A9W
#Red holder (At $C499)
%patch $C565 $19A9W
#Yellow holder (At $C499)
%patch $C567 $19A9W
#Blue holder (At $C499)
%patch $C569 $19A9W
#Green holder (At $C499)
%patch $C56B $1A41W
#Top water: nothing (At $C531)
%patch $C56D $1A41W
#Right water: nothing (At $C531)
%patch $C56F $1A41W
#Bottom water: nothing (At $C531)
%patch $C571 $1A41W
#Left water: nothing (At $C531)
%patch $C573 $1A41W
#Moving platform switch (At $C531)
%patch $C575 $1A1BW
#Moon tile: Make Keen moon (At $C50B)
%patch $C577 $1A41W
#Sprite arrow path: nothing (At $C531)
%patch $C579 $1A41W
#Bridge tile: nothing (At $C531)
%patch $C57B $1A41W
#Active zapper: nothing (At $C531)
%patch $C57D $1A41W
#Teleport entrance: nothing (At $C531)
%patch $C57F $1A2CW
#100 points: vanish, do item stuff (At $C51C)
%patch $C581 $1A2CW
#200 points: vanish, do item stuff (At $C51C)
%patch $C583 $1A2CW
#500 points: vanish, do item stuff (At $C51C)
%patch $C585 $1A2CW
#1000 points: vanish, do item stuff (At $C51C)
%patch $C587 $1A2CW
#2000 points: vanish, do item stuff (At $C51C)
%patch $C589 $1A2CW
#5000 points: vanish, do item stuff (At $C51C)
%patch $C58B $1A2CW
#1UP: vanish, do item stuff (At $C51C)
%patch $C58D $1A2CW
#Stunner tile: vanish, do item stuff (At $C51C)


Deadly tile code

The deadly tile code simply calls the player death code, causing the player to die.

Patch: Keen 5
#Deadly tile property code
%patch $C484 $0E $E8 $FB7FW $E9 $00A6W


Vitalin tile code

The raindrop code is quite simple. When run it calls the actual Vitalin code which removes the tile and adds 1 to Keen's Vitalin counter.

Patch: Keen 5
#Raindrop tile property code
%patch $C48B $FF $76 $FE $57 $0E $E8 $FEBFW $83 $C4 $04 $E9 $0098W


Gem holder tile code

The gem holder tile code is responsible for initiating the opening of doors. The gem holder code is somewhat complicated. The first section of the code deals with checks. The first check checks to see if the gem holder tile is 1 tile below Keen's head (So Keen cannot open just any gem holder tile.) The next check determines whether the tile below the gem holder is upwards blocking (So Keen cannot open gem holders in the air.) On the second line Keen's action is checked and if he is already placing a gem then the following code is skipped. (This avoids Keen constantly trying to place a gem but being unable to do so, see also Patch:Jump conditions.)

The next check, on line 3, looks to see if Keen has the right kind of gem (See Patch:Game stats.); seven is taken away from the tile type then, using the red gem variable as a start, the right gem variable is checked. After all these checks are passed then Keen's action is set to 'turn away from screen', starting the door opening sequence and he begins to 'slide' into alignment with the holder. The final check looks to see that this alignment is complete (Otherwise he will try to use the wrong tile as a door locator causing a 'bad spot' error.) if so then the second section is run.

The second section causes Keen to go to the door opening code where his action is set to 'place gem' and a gem is removed from his inventory. (Again seven is taken from the tile type to determine which gem variable is affected.)

Patch: Keen 5
#Gem holder tile property code
%patch $C499 $8B $44 $32 $3B $46 $FE $74 $03 $E9 $00B0W $83 $7C $36 $00 $75 $03 $E9 $00A7W $81 $7C $1C $0CA2W $75 $03 $E9 $009DW $8B $5E $F6 $83 $EB $07 $D1 $E3 $83 $BF $6F60W $00 $75 $03 $E9 $008BW $8B $C7 $B1 $08 $D3 $E0 $05 $FFC0W $89 $46 $F4 $8B $44 $0A $3B $46 $F4 $74 $11 $8B $46 $F4 $89 $44 $3E $C7 $44 $1C $0CC0W $5F $5E $8B $E5 $5D $CB $8B $5E $F6 $83 $EB $07 $D1 $E3 $FF $8F $6F60W $B8 $0CA2W $50 $56 $9A $090B1242RL $83 $C4 $04 $EB $28


Moon tile code

See also Patch:Keen mooning. When Keen touches a tile with the mooning property and his 'mooning variable' is also 0 (That is, he hasn't mooned before.) then it will be set to 1 (Allowing him to moon.) However Keen's sprite code does not make use of this variable, meaning he doesn't moon in Keen 5.

Patch: Keen 5
#Mooning tile property code
%patch $C50B $83 $3E $C17BW $00 $75 $1F $C7 $06 $C17BW $0001W $EB $17


Moon tile is ice instead

This patch alters the moon tile code so that if Keen touches it he slides back and forth like the ice in Keen 1. He can however turn around, walk and jump while touching ice tiles. The patch works by changing standing Keen's action to his first walking frame.

Patch: Keen 5
#Mooning tile is now 'ice'
%patch $C50B $81 $7C $1C $0888W $75 $05 $C7 $44 $1C $0F72W $EB $18


Item tile code

When Keen touches an item type tile the tile's property as $15 removed and $04 added to it before being passed to the item tile code proper, $0E $E8 $FD5AW. (This code is also called when item sprites are obtained.) Note the relative call which requires adjustment if this code is moved.

The two blue variables are somewhat redundant; a single subtraction of $11 would suffice. The cause of this complexity is due to the four gem items which cannot be got as tiles by default and the first item tile property being $15. Changing this allows the game to do things such as dealing with gem item tiles.

Patch: Keen 5
#Item tile property code
%patch $C51C $8B $46 $F6 $2D $0015W $05 $0004W $50 $FF $76 $FE $57 $0E $E8 $FD5AW $83 $C4 $06


Keen 6

Pointer list

Patch: Keen 6
#Pointer to tile property list
%patch $C269 $1921W
#Number of tile properties -1
%patch $C25E $19
#Tile property references
%patch $C341 $184BW
#Deadly (At $C26B)
%patch $C343 $1852W
#Raindrop: Vanish with a splash, add 1 to raindrop counter (At $C272)
%patch $C345 $18F8W
#Switch ON: nothing (At $C318)
%patch $C347 $18F8W
#Switch OFF: nothing (At $C318)
%patch $C349 $1860W
#Red holder (At $C280)
%patch $C34B $1860W
#Yellow holder (At $C280)
%patch $C34D $1860W
#Blue holder (At $C280)
%patch $C34F $1860W
#Green holder (At $C280)
%patch $C351 $18F8W
#Top water: nothing (At $C318)
%patch $C353 $18F8W
#Right water: nothing (At $C318)
%patch $C355 $18F8W
#Bottom water: nothing (At $C318)
%patch $C357 $18F8W
#Left water: nothing (At $C318)
%patch $C359 $18F8W
#Moving platform switch (At $C318)
%patch $C35B $18D2W
#Moon tile: Make Keen moon (At $C2F2)
%patch $C35D $18F8W
#Sprite arrow path: nothing (At $C318)
%patch $C35F $18F8W
#Bridge tile: nothing (At $C318)
%patch $C361 $18F8W
#Active zapper: nothing (At $C318)
%patch $C363 $18F8W
#Teleport entrance: nothing (At $C318)
%patch $C365 $18E3W
#100 points: vanish, do item stuff (At $C303)
%patch $C367 $18E3W
#200 points: vanish, do item stuff (At $C303)
%patch $C369 $18E3W
#500 points: vanish, do item stuff (At $C303)
%patch $C36B $18E3W
#1000 points: vanish, do item stuff (At $C303)
%patch $C36D $18E3W
#2000 points: vanish, do item stuff (At $C303)
%patch $C36F $18E3W
#5000 points: vanish, do item stuff (At $C303)
%patch $C371 $18E3W
#1UP: vanish, do item stuff (At $C303)
%patch $C373 $18E3W
#Stunner tile: vanish, do item stuff (At $C303)


Deadly tile code

The deadly tile code simply calls the player death code, causing the player to die.

Patch: Keen 6
#Deadly tile property code
%patch $C26B $0E $E8 $FB7BW $E9 $00A6W


Viva tile code

The Viva code is quite simple. When run it calls the actual Viva code which removes the tile and adds 1 to Keen's Viva counter.

Patch: Keen 6
#Viva tile property code
%patch $C272 $FF $76 $FE $57 $0E $E8 $FEBFW $83 $C4 $04 $E9 $0098W


Gem holder tile code

The gem holder tile code is responsible for initiating the opening of doors. The gem holder code is somewhat complicated. The first section of the code deals with checks. The first check checks to see if the gem holder tile is 1 tile below Keen's head (So Keen cannot open just any gem holder tile.) The next check determines whether the tile below the gem holder is upwards blocking (So Keen cannot open gem holders in the air.)

On the second line Keen's action is checked and if he is already placing a gem then the following code is skipped. (This avoids Keen constantly trying to place a gem but being unable to do so, see also Patch:Jump conditions.)

The next check, on line 3, looks to see if Keen has the right kind of gem (See Patch:Game stats.); seven is taken away from the tile type then, using the red gem variable as a start, the right gem variable is checked. After all these checks are passed then Keen's action is set to 'turn away from screen', starting the door opening sequence and he begins to 'slide' into alignment with the holder. The final check looks to see that this alignment is complete (Otherwise he will try to use the wrong tile as a door locator causing a 'bad spot' error.) if so then the second section is run.

The second section causes Keen to go to the door opening code where his action is set to 'place gem' and a gem is removed from his inventory. (Again seven is taken from the tile type to determine which gem variable is affected.)

Patch: Keen 6
#Gem holder tile property code
%patch $C280 $8B $44 $32 $3B $46 $FE $74 $03 $E9 $00B0W $83 $7C $36 $00 $75 $03 $E9 $00A7W $81 $7C $1C $0C96W $75 $03 $E9 $009DW $8B $5E $F6 $83 $EB $07 $D1 $E3 $83 $BF $759CW $00 $75 $03 $E9 $008BW $8B $C7 $B1 $08 $D3 $E0 $05 $FFC0W $89 $46 $F4 $8B $44 $0A $3B $46 $F4 $74 $11 $8B $46 $F4 $89 $44 $3E $C7 $44 $1C $0CB4W $5F $5E $8B $E5 $5D $CB $8B $5E $F6 $83 $EB $07 $D1 $E3 $FF $8F $759CW $B8 $0C96W $50 $56 $9A $08F41297RL $83 $C4 $04 $EB $28


Moon tile code

See also Patch:Keen mooning. When Keen touches a tile with the mooning property and his 'mooning variable' is also 0 (That is, he hasn't mooned before.) then it will be set to 1 (Allowing him to moon.) This is the case even though mooning is completely absent in Keen 6.

Patch: Keen 6
#Mooning tile property code
%patch $C2F2 $83 $3E $CC1BW $00 $75 $1F $C7 $06 $CC1BW $0001W $EB $17


Item tile code

When Keen touches an item type tile the tile's property as $15 removed and $04 added to it before being passed to the item tile code proper, $0E $E8 $FD5AW. (This code is also called when item sprites are obtained.) Note the relative call which requires adjustment if this code is moved.

The two blue variables are somewhat redundant; a single subtraction of $11 would suffice. The cause of this complexity is due to the four gem items which cannot be got as tiles by default and the first item tile property being $15. Changing this allows the game to do things such as dealing with gem item tiles.

Patch: Keen 6
#Item tile property code
%patch $C303 $8B $46 $F6 $2D $0015W $05 $0004W $50 $FF $76 $FE $57 $0E $E8 $FD5AW $83 $C4 $06


How tiles work

The following descriptions of tile properties are based heavily on data from CK456DTli by The CKGuy and User:Levellass.


Vorticons

The properties of each tile are encoded in various “flags”. Tiles have six flags. The term flags here is rather misleading, because this seems to imply that each one is either on or off. This is far from true—each flag for each tile is represented as a word in the resource, so in theory a flag could have one of 65536 values, but this does not happen in practice.

The flags for tiles, listed in the order they appear in the TileInfo resource:

  • AnimFlag
  • MiscFlag
  • TopFlag
  • RightFlag
  • BottomFlag
  • LeftFlag

Altering the properties of a tile consists of changing the values of one or more flags for that tile. Now we’ll go into specifics on the various flags.

  • AnimFlag — For tiles that do not animate, this is one. For animating tiles, it is two or four. It is the number of tiles in the 'animation loop' the tile is involved in. This means that for animating tiles a row of two or four tiles must have the same value or errors will occur. The tiles used in animation will depend on where in the loop a given tile is and this is hard-coded, meaning a given tile can only possibly animate to one other tile.
  • TopFlag — This specifies what the top of the tile is like. It can have four values, zero is 'fall through', 1 is 'solid' 2 is 'slippery' and 3 is 'ice'.
  • LeftFlag, BottomFlag and RightFlag — These are zero if you can enter from that side, and one if the tile is solid on that side.
  • MiscFlag — This is the most complicated flag. It encodes many of the special properties that tiles can have (such as being deadly, being an item with a certain point value, etc.). The following values are used:
00: Nothing        17: Exit
01: Kills          18: Key 1
02: Door 1         19: Key 2
03: Door 2         20: Key 3
04: Door 3         21: Key 4
05: Door 4         22: Message box popup
06: 500 points     23: Lightswitch
07: 100 points     24: Teleporter
08: 200 points     25: Switch on
09: 1000 points    26: Swtich off
10: 5000 points    27: Ankh (Keen 3 only)
11: Joystick       28: Single bullet (Keen 3 only)
12: Battery
13: Vaccum
14: Whiskey
15: Raygun         -1: Foreground
16: Pogo           -2: Masked


Galaxy and Dreams

The properties of each tile are encoded in various “flags”. Background tiles have two flags and foreground tiles have seven. The term flags here is rather misleading, because this seems to imply that each one is either on or off. This is far from true—each flag for each tile is represented as a byte in the resource, so in theory a flag could have one of 256 values, but this does not happen in practice.

The flags for background tiles, listed in the order they appear in the TileInfo resource:

  • TimeFlag
  • AnimFlag

The flags for foreground tiles, listed in the order they appear in the TileInfo resource:

  • TopFlag
  • RightFlag
  • BottomFlag
  • LeftFlag
  • AnimFlag
  • MiscFlag (including the pseudo-flag ForegroundFlag)
  • TimeFlag

Altering the properties of a tile consists of changing the values of one or more flags for that tile. Now we’ll go into specifics on the various flags.

  • AnimFlag — (For foreground and background tiles) For tiles that do not animate, this is zero. For animating tiles, it is a relative offset to the next tile in the animation sequence. This is stored as a signed byte, so the offset can be from -128 to +127.
  • TimeFlag — (For foreground and background tiles) For tiles that do not animate, this is zero. For animating tiles, it is the amount of time spent on this tile in the sequence. The time unit is not known. To quote from an old document of adurdin’s: “The time is specified in UNITS, from x00 to xFF. A value of x95 is approximately equal to 2 seconds. Values lower than x02 may animate only sporadically.”
  • Also — These flags are not just used for tiles that animate “by themselves”. Most of the time when tiles turn into other tiles (on switch to off switch and back, empty keygem holder to keygem holder with key, bridge opening/closing, keygem door opening, Keen 5 keycard door opening, etc.), the situation is handled by animating tiles. The AnimFlag for one tile points to the other, but the TimeFlag is set to zero.
  • TopFlag — This specifies what the top of the tile is like. It can be a flat solid top, an open top you can fall through, a particular slant, solid but has a pole going through, etc.
  • LeftFlag and RightFlag — These are zero if you can enter from that side, and one if the tile is solid on that side.
  • BottomFlag — This specifies what the bottom of the tile is like. If you specify the TopFlag to be solid, but specify the BottomFlag to be “jump through”, you will get a tile that you can jump up through and land on, and to get back down through, you look down and jump. Some examples of this kind of tile are the “narrow” floors in Keen 4, the holes in Keen 5, and the tree limbs in Keen 6.
  • MiscFlag — This is the most complicated flag. It encodes many of the special properties that tiles can have (such as being deadly, being an item with a certain point value, etc.). All of these are actually encoded in the lower seven bits of the flag. The high bit specifies whether or not the tile is to appear in front of Keen and other sprites, as opposed to behind them as most foreground tiles do. In this program, this is implemented as a separate pseudo-flag, ForegroundFlag.


Flag values

Unlike in Vorticons, most of the tile flags can have more than one value, meaning that potentially endless varieties of tile may be created. Following is a list of the known tile flag values as well as what games they are valid for. (4, 5, 6 and Dreams.)

Top flag:
D456	00	Fall through
D456	01	Flat top
D456	02	Top > Middle
D456	03	Middle > Bottom
D456	04	Top > Bottom
D456	05	Middle > Top
D456	06	Bottom > Middle
D456	07	Bottom > Top
D456	09	Deadly (and can't land on in God mode)
D456	11	Flat top with pole
6	21	Giant switch (on)
6	29	Conveyor belt
5	39	Fuse
Bottom flag:
D456	00	Jump through
D456	01	Flat bottom
D456	02	Bottom > Middle
D456	03	Middle > Top
D456	04	Bottom > Top
D456	05	Middle > Bottom
D456	06	Top > Middle
D456	07	Top > Bottom
D456	11	Pole going through
6	21	Giant switch (off)
Misc flag:
D456	00	No special properties
D456	01	Pole
456	02	Door
D	02	Top of fire
456	03	Deadly
456	04	Collect 100 to get 1UP
45	05	Switch for moving platforms (off)
45	06	Switch for moving platforms (on)
456	07	Red keygem holder
456	08	Yellow keygem holder
456	09	Blue keygem holder
456	0A	Green keygem holder
4	0B	Top water entrance
4	0C	Right water entrance
4	0D	Bottom water entrance
4	0E	Left water entrance
45	0F	Switch for bridges
4	10	"Moon" floor tile
56	11	Sprite path arrow
56	12	Bridge
6	13	Active zapper (top)
56	14	Teleport entrance
456	15	100 points
456	16	200 points
456	17	500 points
456	18	1000 points
456	19	2000 points
456	1A	5000 points
456	1B	1UP
456	1C	Neural stunner
6	1E	Inactive zapper
5	1F	Little Ampton computer
5	20	Keycard door
5	21	Elevator on map (left side)
5	22	Elevator on map (right side)
D	7F	Top of exit sign


Tools

The following utilities can be used to edit tile properties. This is done by displaying the tileset bitmap(s) and showing the tile properties for each 'square' of bitmap involved.