Patch:Princess Lindsey
Princess Lindsey is a character in Keen 4 who provides advice to Keen whenever he comes across her. By default he will encounter her in two levels, giving two different messages.
There are two parts to Princess Lindsey, her sprite, which floats up and down in the level for Keen to contact, and her message, which is a typical text patch. This page will cover both.
Princess Lindsey's messages
There are two different messages, and replies from Keen, depending on what level Keen encounters the princess.
Call messages code
This is the code run when Keen touches a sprite of Lindsey's type. It calls three subroutines, the first of which is Lindsey's message windows. (The second removes Lindsey after her message plays, and the third removes the window from the screen.)
Keen 4
#Linsdey sprite-type collision code
%patch $CDF9 $9A $0E8F0645RL $56 $9A $06BD1E8BRL $83 $C4 $02 $9A
$16540D59RL $5F $5E $5D $CB
Lindsey wins level
This patch makes it such that after Lindsey's message has displayed Keen will win the level.
Keen 4
#Linsdey wins level when contacted
%patch $CDF9 $9A $0E8F0645RL $C7 $06 $7A70W $0002W $5F $5E $5D $CB
Lindsey wins game
This patch makes it so that Princess Lindsey win the game after she is contacted and her windows displayed. As a side effect the Oracle Council Members will also do this, with no message at all. Removing the second line will make Lindsey's message play, and the Members, with Members behaving normally (And thus the game only being won if Lindsey is contacted when Keen has one less than the needed number of Members saved.)
Keen 4
#Linsdey wins game when contacted
#SIDE EFFECT: So do Oracle Members
%patch $CDF9 $9A $0E8F0645RL $C7 $06 $7A70W $0003W $5F $5E $5D $CB
%patch $6ACB $EB $25
Lindsey doesn't react to Keen
This patch prevents Lindsey and Keen from interacting. (The same goes for any other sprite using Lindsey's sprite type.) They will simply pass through each other.
Keen 4
#Lindsey doesn't react to Keen
%patch $CDF9 $5F $5E $5D $CB
Level that changes reply
There is one level by default that changes what message Keen will receive and what reply he will give. In every other level he will get\respond in the same way. This is actually two separate checks of what level the player is in. Both of these checks can be changed so the reply changes in multiple levels, see Patch:Jump conditions.
Keen 4
#Level where Lindsey gives the Miragia hint instead of the Pyramid one:
%patch $EFB6 [$07] {$75} #Hillville
#Level where Keen gives the Miragia reply instead of the Pyramid one:
%patch $F033 [$07] {$75} #Hillville
Level specific messages
This patch alters Princess Lindsey's or Keen's windows so that they give a different message on every level. It does this by copying the Oracle Member replies. As such, as the patch is written here it will display Keen's replies. The brown value is the variable counted. (Here current level.) while the blue variable is the location of the pointer list.
Keen 4
#Lindsey uses level specific replies
%patch $EFB2 $8B $1E {$A7EDW} $D1 $E3 $FF $B7 [$19DCW] $9A $19310EBDRL $83
$C4 $02 $EB $0D
#Keen uses level specific replies
%patch $F02F $8B $1E {$A7EDW} $D1 $E3 $FF $B7 [$19DCW] $9A $19310EBDRL $83
$C4 $02 $EB $0D
Window setups
These are the text windows that appear when Keen contacts Lindsey. There are two of them each time; Lindsey's and Keen's. When the first window appears a sound plays. The windows are always the same, except for a special level when both windows can use a different text. The special level can be different for each window. This is noted in the previous section.
Disable windows
These patches remove one or the other window. The first patch displays only Keen's reply window when Lindsey is spoken to., while the second displays only Keen's replies.
Keen 4
#No Lindsey window
%patch $EF73 $E9 $0084W
#No Keen's reply window
%patch $EFFA $E9 $00A1W
Caching images and playing sound
The windows must cache the graphics they are using before they appear. In this case three sets of images are saved; Keen's head, Lindsey and Keen giving a thumbs up. Notice that bitmaps are referred to by their 'chunk number', that is, what graphic chunk they are in EGAGRAPH.CK4; this is the bitmap number (When exported via ModKeen, Keengraph numbers the bitmaps 'correctly') plus six. There is also a sound played.
Keen 4
#Bitmap cache (3 bitmaps, 104-6)
%patch $EF53 [$0072W] #Cache Lindsey's head
%patch $EF5A [$006FW] #Cache Talking Keen
%patch $EF61 [$0070W] #Cache Thumbs up Keen head
%patch $EFD9 [$002DW] #Sound played
Don't display Lindsey's head
This patch stops Lindsey's head being displayed in her window (or being cached, freeing up some memory.) The last two lines are optional, they make the text center in the Princess' window so it doesn't look odd. (They set the 'off-center' variables to 0.)
Keen 4
#Don't display Lindsey's head in window, center text
%patch $EF4E $EB $05
%patch $EF83 $EB $12
%patch $EFA0 $00
%patch $EFA5 $00
Don't play sound
This patch stops the sound playing when Lindsey is spoken to.
Keen 4
#Don't play sound when Lindsey spoken to
%patch $EFD8 $EB $0A
Change music when window appears
This patch causes the music to change when Lindsey is spoken to. The music will revert back to 'normal' when the last window is closed. As a side-effect no sound plays when Lindsey is spoken to. The blue value used here is the level who's music is used. (For example a value of 0 will play the map level's music.)
Keen 4
#Change music when Lindsey spoken to
%patch $EFDD $06BD20C7RL
%patch $EFD9 [$0001W] #Play this level's song
Size and text location
Both of the windows displayed must be set up. (See Patch:Text patches). The first thing to note is the size of the window in 8x8 tiles. There is a height and width variable for this. After this comes the image shown.
The image and text interact in complex ways. If the image is on the right side of the window (Like Keen) it will have a width variable (Technically how far from the right side of the window the LEFT side of the bitmap is.) Text is centered in the window using a value that should match the width of the image in it. (Here $30 or 48 pixels wide in all cases.) Finally the text begins a certain number of pixels down from the window top.
The texts themselves are interesting. The first line of Lindsey's window is always the same. However the two advice lines and replies are stored in a list 4 entries long. The location of this list is called, then the list read to see the location of the text.
Keen 4
#Lindsey's window
%patch $EF74 [$0008W] #Height
%patch $EF78 [$001AW] #Width
%patch $EF84 [$0072W] #Display Lindsey's head (at 0,0)
%patch $EFA0 [$30W] #Text alignment
%patch $EFE5 [$003CW] #Window dismissal time
#Texts read from
%patch $0EFA7 [$1BB5W] #Lindsey says
%patch $30844 [$1ADCW] #Scuba gear...
%patch $30846 [$1B29W] #Pyramid...
#Texts:
%patch $30A25 "Princess Lindsey says:" $0A $00
%patch $3094C "There's gear to help" $0A
"you swim in Three-Tooth" $0A
"Lake. It is hidden in" $0A
"Miragia." $0A $00
%patch $30999 "The way to the Pyramid" $0A
"of the Forbidden lies" $0A
"under the Pyramid of" $0A
"Moons." $0A $00
#Keen's reply window
%patch $EFFB [$0008W] #Height
%patch $EFFF [$001AW] #Width
%patch $F00B [$006FW] #Display Keen's head
%patch $F01A [$0030W] #Horizontal location of Keen's head
%patch $F029 [$30] #Horizontal alignment of text
%patch $F02E [$0C] #Text location from window top
%patch $F056 [$001EW] #Window dismissal time
%patch $F089 [$001EW] #Thumbs up dismissal time
#Replies read from
%patch $30848 [$1B73W] #Reply 1
%patch $3084A [$1B8AW] #Reply 2
#Keen's replies:
%patch $309E3 "Thanks, your Highness!" $00
%patch $309FA "Thanks for the" $0A
"mysterious clue," $0A
"Princess!" $0A $00
No 'Lindsey says' text
This removes the 'Princess Lindsey says' text from both of Lindsey's windows. This means neither window has any text in common. If using this patch then any patch that alters the location of the 'Lindsey says' text will cause problems if used.
Keen 4
#No 'Lindsey says' text
%patch $EFA6 $EB $0A
How far right text centers
Because of Princess Lindsey's bitmap the text in her window must be 'pushed' to the right. Two variables control how far off center the text is. (Always in a rightwards direction.) If Lindsey's head is removed (See above.) then these values can be set to 0. Otherwise they should be adjusted to fit Lindsey's image. (Note that the variables are the same size as Lindsey's image's width.) If text is forced outside the window the game will crash with a 'String exceeds width ' error.
Keen 4
#Window text 'off-center' variables
%patch $EFA0 $30
%patch $EFA5 $30
Pauses
There are two pauses in the conversation, one between Lindsey and Keen's windows (After the player has pressed a key.) and the second after Keen's window is dismissed. The pause can be made only as small as 4 ticks or the game will crash.
Keen 4
#Pause between two windows
%patch $EFE5 [$003EW]
#Pause before Keen's window vanishes
%patch $F089 [$001EW]
Princess Lindsey's Sprite
This is the 'actor' in the game that is touched by Keen, producing the text messages.
Sprite Type
Lindsey uses sprite type 24 which is used only by Lindsey and doesn't affect anything else. This type reacts specifically with Keen to bring up the text messages, if this is changed, Lindsey will no longer interact with Keen.
Keen 4
#Lindsey sprite type
%patch $127E9 $18
Sprite Actions
Lindsey has four actions, all of them the same, they make her float up and down. (When used by other sprites they result in the sprite floating up offscreen.) As such her behavior is remarkably simple, after being placed in a level she does nothing.
Actions: $38EAW #Princess Lindsey 1 $3908W #Princess Lindsey 2 $3926W #Princess Lindsey 3 $3944W #Princess Lindsey 4
Keen 4
#Princess placed in-level
%patch $12813 [$38EAW] #Spawn Princess Lindsey (Float)
#Floating Princess
%patch $32776 [$3908W] #Princess Lindsey 1
%patch $32794 [$3926W] #Princess Lindsey 2
%patch $327B2 [$3944W] #Princess Lindsey 3
%patch $327D0 [$38EAW] #Princess Lindsey 4
Sprite Behavior
Lindsey has only one behavior, the 'float' behavior and she performs it all the time.
Behaviors: $11A20E01RL #Lindsey
Keen 4
#Floating
%patch $3276A $11A20E01RL #Lindsey
%patch $32788 $11A20E01RL #Lindsey
%patch $327A6 $11A20E01RL #Lindsey
%patch $327C4 $11A20E01RL #Lindsey
Speed and Jump Height
Lindsey has no animation motion, but she does float smoothly, her floating speeds and magnitude are completely separate and depend on her floating behavior code. There are three variables, the floating speed, and how long Lindsey spends floating upwards and downwards.
Animation motion
#Floating
%patch $32766 [$0000W $0000W]
%patch $32784 [$0000W $0000W]
%patch $327A2 [$0000W $0000W]
%patch $327C0 [$0000W $0000W]
Animation motion
#Floating speeds
%patch $12829 [$0008W] #Floating speed
%patch $1283F [$0020W] #Floating u time
%patch $1284F [$0020W] #Floating d time
Only float up or down
This patch and the one following it change Lindsey's directions so she either only floats up, or floats down. Ony one of these two may be used per patch file.
Keen 4
#Only float up
%patch $12846 $FFFFW
#Only float down
%patch $12856 $0001W
Sprite Collision
Lindsey's collision is simple, she doesn't have one by default.
Collision values
Princess Lindsey has no collision. This means, technically nothing can affect her, instead, when Keen touches her, his code responds to Lindsey's sprite type (see above section) making her vanish.
Keen 4 collision values
#Floating
%patch $3276E $00000000L #No collision
%patch $3278C $00000000L #No collision
%patch $327AA $00000000L #No collision
%patch $327C8 $00000000L #No collision
Animations
Lindsey's animations are simple enough, she cycles through four frames.
Keen 4
#Cache
%patch $306EC $0149W #Lindsey Cache start
%patch $30736 $014CW #Lindsey cache end
#Floating
%patch $3275A $0149W $0149W
%patch $32764 $0014W #Animation speed
%patch $32778 $014AW $014AW
%patch $32782 $0014W #Animation speed
%patch $32796 $014BW $014BW
%patch $327A0 $0014W #Animation speed
%patch $327B4 $014CW $014CW
%patch $327BE $0014W #Animation speed
Sounds
This is covered under the first section of this page dealing with Lindsey's text windows.
Sprite positioning and landing on the ground
Lindsey is spawned one tile up from her placed position, though there is no reason for this as she does not need to touch the ground.
Keen 4
#Spawn height:
%patch $12805 [$FF00W] #1 tile up
Clipping and foreground
Lindsey's foreground is set to 0, which means she appears behind everything, including Keen.
Keen 4
#Lindsey Foreground variable
%patch $127F3 $0000W
Sprite-tile interaction
Lindsey uses the 'sit' tile interaction, which is a short way of saying she has no specific interactions with tiles at all.
Keen 4
#Floating
%patch $32772 $09DC176ERL
%patch $32790 $09DC176ERL
%patch $327AE $09DC176ERL
%patch $327CC $09DC176ERL
Action type
Lindsey uses type 3 for its actions, allowing it to move smoothly.
Keen 4
#Floating
%patch $3275E [$0003W] #Princess Lindsey 1
%patch $3277C [$0003W] #Princess Lindsey 2
%patch $3279A [$0003W] #Princess Lindsey 3
%patch $327B8 [$0003W] #Princess Lindsey 4
Deprotect and stick to ground
As Lindsey doesn't need to move up or down hills she has a value of zero for all her frames.
Keen 4
#Floating
%patch $32760 [$0000W $0000W]
%patch $3277E [$0000W $0000W]
%patch $3279C [$0000W $0000W]
%patch $327BA [$0000W $0000W]
Sprite spawn code
In the initiation code notice the Sprite cache being set ($C7 $06 $57 $CB $0001W.)
In the spawning code the last blue highlighted value is the sprite action the sprite uses as it proceeds to act in-level. $C7 $02 $xxxxW sets the sprite activity, $C7 $07 $xxxxW sets the sprite type, $C7 $20 $xxxxW sets the foreground value. Finally $D3 $E0 $05 $xxxx is how far down (Or more usually up) the sprite is spawned from where it is placed. This is necessary for sprites that walk on the ground as they can only be placed in the level at multiples of 16 pixels high while their actual height can be anything.
Lindsey always starts the level moving down. $C7 $47 $10 $xxxxW is the vertical direction the sprite starts moving in, either $0001W (Facing down), $FFFFW (Facing up) or $0000W (Neither, never used.) Notice that this patch contains, and is thus incompatible with, a number of other patches above it on this page. (For example the spawning action in the sprite actions section.) It should be easy enough to see where these patches fit if combining them is needed.
Keen 4
#Location of initiation code
%patch $EE8F [$0122W] #Lindsey (At $EA12)
#Lindsey Initiation code
%patch $EA12 $FF $76 $FC $57 $9A {$11A20DB5RL} $83 $C4 $04 $C7 $06 $57 $CB
$0001W $E9 $03D6W
#Lindsey spawn code
%patch $127D5 $55 $8B $EC $33 $C0 $50 $9A $06BD1E11RL $83 $C4 $02 $8B $1E
$D8 $A7 $C7 $07 [$0018W] $C7 $47 $02 [$0001W] $C7 $47 $20 [$0000W]
$8B $46 $06 $B1 $08 $D3 $E0 $89 $47 $0A $8B $46 $08 $D3 $E0 $05
[$FF00W] $89 $47 $3E $89 $47 $0C $C7 $47 $10 [$0001W] $B8 [$38EAW]
$50 $53 $9A $09DC118CRL $83 $C4 $04 $5D $CB