Patch:Horizontal-Vertical Platform (Keen 4)
Platforms in Keen 4 are sprites that Keen can stand on and sometimes be carried places on. This page lists patches relating to a specific Platform sprite, the Horizontal-Vertical Platform. The page is divided into sections relating to the various sprite properties the patches involved. Being fluent with various sprite patch pages will help when working with these patches.
The Horizontal-Vertical Platform referred to on this page is the platform in Keen 4 that moves either vertically or horizontally back and forth in a straight line. The other kind of Keen 4 Platform is the Dropping Platform.
Patches relating to other Keen 4 platforms can be found at Patch:Platform (Keen 4). Patches relating to the Horizontal-Vertical Platform in other Keen games can be found at Patch:Horizontal-Vertical Platform (Keen 5) and Patch:Horizontal-Vertical Platform (Keen 6).
Sprite Type
Horizontal-Vertical Platforms use type 20, one of the types that lets Keen stand on a sprite. Changing this may make it impossible for Keen to stand on the platforms. The Horizontal-Vertical Platform uses the same value as all other platforms.
Keen 4
#Horizontal-Vertical Platform sprite type
%patch $114BF $14
Sprite Actions
There is only one action associated with the Horizontal-Vertical Platform. The platform is spawned using this action, doing nothing else indefinitely.
Actions: $1B5EW #Horizontal-Vertical Platform
Keen 4
#Spawn Horizontal-Vertical Platforms:
%patch $1152B [$316AW]
#Horizontal-Vertical Platform does nothing:
%patch $31FF6 [$0000W]
Sprite Behavior
The Horizontal-Vertical Platform has only one behavior. It is shared with the Underwater mines.
Behaviors: $10800D44RL #Horizontal-Vertical Platform
Keen 4 Platform behaviors
#Horizontal-Vertical Platform behavior
%patch $31FEA $10800D44RL
Platforms can follow guided paths
This patch alters the Horizontal-Vertical Platforms so that they can follow arbitrary paths; changing direction whenever they encounter a certain tile. As a side effect the Platform flames are not displayed, their code space is used for the patch.
The first part of the patch removes the flames and calls the tile checking code, the second part of the patch. The first five lines check for tiles while the remaining code responds to special tile types. Four tile types are checked for, $0A-$0E, these are the 'water entrance' types used on the map but not in regular levels. Each type sets one of the Platform's horizontal ($0E) or Vertical ($10) directions to zero and the other to +/-1 ($0001W/$FFFFW)
Platforms using this patch will still reverse direction on encountering [B] sprites. Unlike with [B] sprites however, Platforms will react to tiles when their hitbox touches them, meaning that they will not always move in a nice, neat aligned manner. Also, unlike in Keen 5 Platforms do not need a tile on every part of their path; only where they should change direction. A Platform that 'misses' a tile will just keep going until it runs into a barrier, another turning tile, or [B] sprite.
Platforms can follow guided paths
#Remove flames- call plat-turn code
%patch $11792 $56 $9A $10800F9ERL $83 $C4 $02 $E9 $0134W
#Tile interaction code =$10800FA5RL
%patch $1179E $55 $8B $EC $83 $EC $04 $56 $57 $8B $76 $06
$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] {$75} $0A $C7 $44 $0E [$0000W]
$C7 $44 $10 [$FFFFW] $83 $FF [$0C] {$75} $0A $C7 $44 $0E [$FFFFW] $C7
$44 $10 [$0000W] $83 $FF [$0D] {$75} $0A $C7 $44 $0E [$0000W] $C7 $44
$10 $0001W $83 $FF [$0E] {$75} $0A $C7 $44 $0E [$0001W] $C7 $44
$10 [$0000W] $5F $5E $8B $E5 $5D $CB
Speed and [B] sprites
The speed of Platforms is controlled entirely by their code and not their animation motion. Note that the Platform's speeds are shared by the Underwater mines and so altering them will alter the Mine's speeds.
Motion
#Platform\Mine's speeds
%patch $11553 [$000CW] #Horizontal speed
%patch $11562 [$000CW] #Vertical speed
Animation motion
#Horizontal-Vertical Platform
%patch $31FE6 [$0000W $0000W] #Speed
Moving Platform initial directions
The number of different platforms is 4 (3 + 1), which can be changed in the code. The types are differentiated by their placement value, so if more platform types are added, they should be added directly after the existing types.
The Moving Platforms have four directions they may start the level moving in. These are combinations of $C7 $47 $10 $xxxxW (The vertical direction the sprite starts moving in, either $0001W (Facing down), $FFFFW (Facing up) or $0000W, none.) and) $C7 $47 $0E $xxxxW, the horizontal direction (Same values for right, left or none.) As an example to start the level moving left a platform needs a vertical value of 0 and a horizontal value of -1.
It is possible for platforms to move both horizontally and vertically (that is, diagonally.) This can be difficult to make work but is possible.
Keen 4
#Number of different platform types
%patch $114E2 $03
#Location of direction list
%patch $114EA $0D3CW
#Platform direction list
%patch $1153C $0CECW #Up platform
$0CFCW #Right platform
$0D0CW #Down platform
$0D1CW #Left platform
#Platform directions
#Up platform
%patch $114F2 $0E [$0000W]
%patch $114F7 $10 [$FFFFW]
#Right platform
%patch $11502 $0E [$0001W]
%patch $11507 $10 [$0000W]
#Down platform
%patch $11512 $0E [$0000W]
%patch $11517 $10 [$0001W]
#Left platform
%patch $11522 $0E [$FFFFW]
%patch $11527 $10 [$0000W]
[B] sprites and changing directions
Moving Platforms change direction when they touch a [B] sprite (More specifically when they are on a tile where that sprite has been placed. The [B] sprite itself is not a sprite in the traditional sense but merely a value in the 'infoplane' of the level. The code that handles this is rather strange and inefficient.
Each of four directions is treated separately. The first thing involved in each of the four directions is thus a check to confirm that the Platform is in fact moving in that direction. (Here the value $0E\$10 refers to the sprite parameter involved; $74\$75 is a jump condition.)
The next check is to see whether the Platform is on a tile with the correct infoplane value. This is the same as the sprite value of the [B] sprite. By default it is exceedingly specific reacting only to this value. In the case of Platforms moving vertically two checks are made.
Finally one or two sprite variables are changed. By default the direction of the Platform is reversed so the Platform 'turns around' (and in the case of vertically moving Platforms the 'sprite draw' variable, which is of unknown function, is changed to 1.) This does not have to be the case however; it is possible for other variables to be changed and even for an additional variable to be inserted.
Falling Platforms stop moving when they touch a [B] sprite. This is currently not patchable.
Platform [B] checks and direction changes
#Moving right
%patch $1156F {$0E} [$01] {$75} #Check direction
%patch $115AA [$1F] {$74} #Respond to this infoplane value
%patch $115B2 {$0E} [$FFFFW] #Change direction
#Moving left
%patch $115D3 {$0E} [$FF] {$75} #Check direction
%patch $1160E [$1F] {$74} #Respond to this infoplane value
%patch $11616 {$0E} [$0001W] #Change direction
#Moving down
%patch $1163A {$10} [$01] {$74} #Check direction
%patch $11678 [$1F] {$74} #Respond to this infoplane value
%patch $11698 [$1F] {$75} #Respond to this infoplane value
%patch $116A3 {$04} [$0001W] #Change 'sprite draw'
%patch $116AE {$10} [$FFFFW] #Change direction
#Moving up
%patch $116CF {$10} [$FF] {$75} #Check direction
%patch $11707 [$1F] {$75} #Respond to this infoplane value
%patch $11724 [$1F] {$75} #Respond to this infoplane value
%patch $1172F {$04} [$0001W] #Change 'sprite draw'
%patch $1173A {$10} [$0001W] #Change direction
Sprite Collision
Horizontal-Vertical Platforms have no sprite collision. They do not interact with any sprites.
Collision values
Horizontal-Vertical Platforms have no collision at all. They do not interact with any sprites. (Keen being able to stand on them is part of his collision, not the platform's.) Giving the platform a collision can make them more interesting. (Destructible for instance.)
Keen 4 collision values
#Horizontal-Vertical Platform
%patch $31FEE $00000000L #Nothing
Animations
The Horizontal-Vertical Platforms use one animation by default. 'It's' cache is not however used only by them; instead it is used by the Dropping Platform as well. This means that changing them will affect the other platforms and cause either memory issues or an uncached sprite error. This makes editing the Horizontal-Vertical Platform's animations difficult.
Keen 4 Caches
#Cache
%patch $30704 {$01E4W} #Platform cache start
%patch $3074E {$01EAW} #Cache end
#Horizontal-Vertical Platform
%patch $31FDA $01E4W $01E4W
%patch $31FE4 $0000W
Invisible Platform
This patch makes the main platform invisible (not use an image.) Keen can still stand on it. This patch does not affect the dropping Platform.
Keen 4
#Invisible Moving Platforms:
%patch $11756 $CB
Accessory Animations
These are the 'flames' that appear on moving platforms to indicate which direction they are moving. They are not separate sprites, but additions to the main sprite. It is possible to change both the animations and when they appear (See below.) By default there are different accessories for the moving platform moving up, down, left and right. These are actually part of the sprite-tile interaction covered in a following section.
Note that the positions of the accessory animations is covered in the next section. (This will be vital if the animations are made larger.)
Change Accessory Animations
This simply allows the modder to change what animation frames are used. Notice that the actual accessories use both the frame listed and the next one.
Keen 4
%patch $1179B $01E5W #Platform moving left flame
%patch $117FD $01E5W #Platform moving right flame
%patch $1182D $01E9W #Platform moving up left side flame
%patch $11853 $01E7W #Platform moving up right side flame
%patch $11887 $01E9W #Platform moving down/still left side flame
%patch $118AD $01E7W #Platform moving down/still right side flame
Don't Use Accessory Animations
These patches remove one or more accessory animations. The first patch will simply remove all accessory animations. The second set can be used to selectively remove or display accessory animations. To never show an animation replace the '$75' on a line with '$90 $90'; to always display the animation (No matter what direction the platform is moving.) replace it with '$EB'
Each line controls one accessory, and they all depend on what direction the platform is moving; $0E is horizontal, $10 vertical. (Thus $0E $FF means 'moving left') Note that another way to stop moving platforms from showing any flames is to change their sprite-tile interaction to the 'sit' tile interaction. (See below.)
Keen 4
#Platforms don't have any flames
%patch $11792 $E9 $3B $01
#Conditions for a flame appearing
%patch $11790 {$0E} [$01] $75 #Draw if moving right (Right flame)
%patch $117DB {$0E} [$FF] $75 #Draw if moving left (Left flame)
%patch $11822 {$10} [$FF] $75 #Draw if moving up (Up flames)
%patch $11878 {$10} [$01] $75 #Draw if moving down (Down flames)
Using this it is possible to make the same flame appear when the board is moving left or right, and up or down. This is done by making the first and third condition 'jump if not zero' rather than 'jump if left\down':
Keen 4
#Conditions for a flame appearing
%patch $11790 {$0E} [$00] $74 #Same flame moving right OR left
%patch $11822 {$10} [$00] $74 #Same flame moving down OR up
Change Accessory Animation Properties
Different accessory animations behave slightly differently. Notably the downwards flames flicker, and the left flame appears in front of the main platform animation. This can be changed in both cases.
Keen 4
#Left flame is behind Platforms (Like other flames)
%patch $117F4 $0000W
#Platform going down flames don't flicker
%patch $1187C $90 $90 $90 $90
Clipping and foreground
The Horizontal-Vertical Platforms have a foreground variable of 0, meaning they appears behind all sprites and foreground tiles. The clipping cannot be patched by default; having no clipping allowing them to fall through solid tiles.
Keen 4
#Horizontal-Vertical Platform foreground variable
%patch $114C9 $0000W
Change Moving Platform's clipping
This patch allows the modder to change the Moving Platform's clipping. It does this by overwriting the Platform's foreground values (Which was 0 anyway.) This patch results in the platform having no clipping and thus being able to pass through tiles. This is of course incompatible with the above M.P. foreground patch.
Keen 4
#Horizontal-Vertical Platform has no clipping
%patch $114C8 $06 $0000W
Moving Platform Activity
The Moving Platform must be active when offscreen, so it specifically has its activity variable set to 2. If it is any other value the Platform will stop moving when Keen cannot see it, meaning that they are much, much harder to use. (If for example Keen is stuck at the bottom of a deep pit and the platform to get out moves up offscreen, it will not come back down.)
Keen 4
#Horizontal-Vertical Platform activity variable
%patch $114C4 $0002W
Sprite-tile interaction
The Horizontal-Vertical Platforms do not interact with tiles at all. (Tiles will block them by default due to their clipping.) However the Platform's tile interaction also allows its accessory animations to be drawn, which is exceedingly important to the look and feel of the platform by default.
Keen 4
#Horizontal-Vertical Platform
%patch $31FF2 $10800F56RL
Action type
The Horizontal-Vertical Platforms need to be instantly responsive, as such they use type 2 for their action.
Keen 4
#Horizontal-Vertical Red Platform action type
%patch $31FDE [$0002W]
Deprotect and stick to ground
The Horizontal-Vertical Platforms need neither of these variables and so both are set to 0 in its action.
Keen 4
#Horizontal-Vertical Red Platform
%patch $31FE0 [$0000W $0000W]
Sprite spawn code
The first thing to note is that there are five different initiation pointers involved with Platforms. Each of the four different Platform direction requires a different sprite (Heading to the same spawn code however.) The 'B' sprite goes directly to the 'nothing' spawn code, since its job is just to act as a placeholder to affect things in levels.
In the initiation code notice the Platform cache being set ($C7 $06 $CB6FW $0001W). The same cache is set by the Dropping Platform.
In the spawning code the last blue highlighted value is the sprite action the sprite uses as it proceeds to act in-level. $C7 $06 $xxxxW sets the clipping, $C7 $07 $xxxxW sets the sprite type, $C7 $20 $xxxxW sets the foreground value.
Note that $C7 $02 $xxxxW sets the sprite activity; this must be 2 for the moving platform since it allows he sprite to function when not onscreen. (The game by default would be unbeatable if Platforms vanished offscreen never to return unless Keen found a way to get close to them.)
The Moving Platforms have four directions they may start the level moving in. These are combinations of $C7 $47 $10 $xxxxW (The vertical direction the sprite starts moving in, either $0001W (Facing down), $FFFFW (Facing up) or $0000W, none.) and) $C7 $47 $0E $xxxxW, the horizontal direction (Same values for right, left or none.) As an example to start the level moving left a platform needs a vertical value of 0 and a horizontal value of -1.
It is possible for platforms to move both horizontally and vertically (that is, diagonally.) This can be difficult to make work but is possible. The spawning code patch contains, and is thus incompatible with, a number of other patches on this page, such as the sprite type, clipping and initial directions patches. It should be a simple matter to see where these patches are located in the spawn code.
The number of different platforms is 4 (3 + 1), which can be changed in the code. The types are differentiated by their placement value, so if more platform types are added, they should be added directly after the existing types.
Keen 4
#Location of initiation code
%patch $EEC1 [$050DW] #B Block (At $EDFD)
Keen 4
#Location of initiation codes
%patch $EEB9 [$0372W] #Up Platform (At $EC62)
%patch $EEBB [$0372W] #Right Platform (At $EC62)
%patch $EEBD [$0372W] #Down Platform (At $EC62)
%patch $EEBF [$0372W] #Left Platform (At $EC62)
#Moving Platforms Initiation code
%patch $EC62 $8B $46 $F8 $05 $E5 $FF $50 $FF $76 $FC $57 $9A {$10800CABRL}
$83 $C4 $06 $C7 $06 $CB6FW $0001W $E9 $017FW
#Moving Platforms Spawning code
%patch $114AB $55 $8B $EC $33 $C0 $50 $9A $06BD1E11RL $83 $C4 $02 $8B $1E
$D8 $A7 $C7 $07 [$0014W] $C7 $47 $02 [$0002W] $C7 $47 $20 [$0000W]
$8B $46 $06 $B1 $08 $D3 $E0 $89 $47 $0A $8B $46 $08 $D3 $E0 $89
$47 $0C $8B $5E $0A $83 $FB [$03] $77 $45 $D1 $E3 $2E $FF $A7 [$0D3CW] #4 kinds of platform, direction list at $1153C
$8B $1E $D8 $A7 $C7 $47 $0E [$0000W] $C7 $47 $10 [$FFFFW] $EB #Up platform
$2E $8B $1E $D8 $A7 $C7 $47 $0E [$0001W] $C7 $47 $10 [$0000W] $EB #Right platform
$1E $8B $1E $D8 $A7 $C7 $47 $0E [$0000W] $C7 $47 $10 [$0001W] $EB #Down platform
$0E $8B $1E $D8 $A7 $C7 $47 $0E [$FFFFW] $C7 $47 $10 [$0000W] $B8 #Left platform
[$316AW] $50 $FF $36 $D8 $A7 $9A $09DC118CRL $83 $C4 $04 $5D
$CB
#Platform direction list
%patch $1153C $0CECW #Up platform
$0CFCW #Right platform
$0D0CW #Down platform
$0D1CW #Left platform