Patch:Oracle Janitor

From KeenWiki
Jump to navigation Jump to search

The Oracle Janitor is a special version of the Council Member found throughout Keen 4. While it's sprite behavior is identical to, and inseparable from the ordinary member's, something different happens when Keen rescues him. Instead of the usual message sequence Keen gets a different, and much longer sequence, that results in him not exiting the level or saving a council member. It is however possible to separate the two sprites so they at differently, though this is difficult.

The difference depends on what level Keen meets the 'member' in. See also Patch: Oracle.


This patch will disable the Oracle Janitor, making him act like an ordinary Council Member.

Keen 4

#Disable Oracle janitor
%patch $CD92 $EB

Janitor vanishes when touched, no text

This patch disables the Janitor windows, so no message is displayed, but still removes the Janitor when Keen touches him. This creates a Council Messenger that vanishes when touched.

Keen 4

#Disable Janitor windows
%patch $CD94 $90 $90 $90 $90 $90

Level Janitor appears in

This is the level that triggers the difference between the Janitor and ordinary council member. By default the unusual behavior occurs only in the Pyramid of the Forbidden. This can be altered to multiple levels, all levels or not at all. (See Patch:Jump conditions.)

Keen 4

#Level(s) that Janitor appears in:
%patch $CD91 [$0E] {$75}

Text windows

These patches cover the five windows displayed in sequence when the Janitor is rescued.

Number of windows in conversation

These patches allow the modder to change the number of windows in the Oracle Janitor conversation. Only one patch may be used; windows are removed from the end of the conversation working back, so the last patch removes the final window while the first leaves only the first window.

Keen 4

#Janitor conversation is only...
%patch $F183 $E9 $01B6W #1 Window
%patch $F1F4 $E9 $0145W #2 windows
%patch $F267 $E9 $00D2W #3 windows
%patch $F2D8 $EB $62    #4 windows


The windows must cache the graphics they are using before they appear. In this case three sets of images are saved; Keen's head, the member's head 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 plus six (when exported via ModKeen, Keengraph numbers the bitmaps 'correctly') .

Keen 4

#Bitmap cache (3 bitmaps, 104, 105 and 107)
%patch $F0E6 [$006EW] #Janitor
%patch $F0ED [$006FW] #Keen
%patch $F0F4 [$0071W] #Angry Keen

Window setup

The Oracle Janitor text windows differ in one important respect from most other text patches; their text is not in the data segment with most other game text, instead, each window has its own separate executable segment. This is handled with a text pointer divided into two parts. As an example the first window has two pointers, $1F58RW and $0000W which add as follows; 1F58 * 10 + 0000 = 1F580, the location of the first window's text.

This is of little import, unless the patcher desires to alter the length of the window's text significantly. (By default a lot of space is wasted.) As long as each window has its own segment (That is the first pointer is different.) then any location can be used.

Aside from this the text position variables are worth mentioning; there are three of them. The first is the location of the text, in pixels, from the top of the window. The second is the 'right border' of the text, in pixels, left of the window's right side; this determines how far right text can go and thus where the text is 'centered' in the window. The third is, in essence, the width of the window bitmap; it is a 'left border' for the text,in pixels, from the left side of the window. (Notice it is, by default, the same as the window bitmap's width.)

Oracle Janitor - first window

#Janitor window 1
%patch $F113 [$0008W]  #Height
%patch $F117 [$001AW]  #Width
%patch $F16E [$003CW]  #Time displayed
%patch $F123 [$006EW]  #Bitmap displayed + 6 (Show BMP 104)
%patch $F146 [$1F58RW] #Text read from 1
%patch $F14A [$0000W]  #2
%patch $F13A [$06]     #Text vertical position
%patch $F13F [$30]     #Text right border (Pixels LEFT)
%patch $F144 [$30]     #Text and image position

%patch $1F580 "Thanks for going to all" $0A
              "that trouble, but I'm" $0A
              "just the janitor for the" $0A
              "High Council." $00

Oracle Janitor - second window

#Janitor window 2
%patch $F184 [$0008W]  #Height
%patch $F188 [$001AW]  #Width
%patch $F1DF [$003CW]  #Time displayed
%patch $F194 [$006EW]  #Bitmap displayed + 6 (Show BMP 104)
%patch $F1B7 [$1F5ERW] #Text read from 1
%patch $F1BB [$0000W]  #2
%patch $F1AB [$06]     #Text vertical position
%patch $F1B0 [$30]     #Text right border (Pixels LEFT)
%patch $F1B5 [$30]     #Text and image position

%patch $1F5E0 "I tried to tell the" $0A
              "Shikadi that but they" $0A
              "just wouldn't listen..." $00

Oracle Janitor - third window

#Keen's reply
%patch $F1F5 [$0008W]  #Height
%patch $F1F9 [$001AW]  #Width
%patch $F252 [$003CW]  #Time displayed
%patch $F205 [$006FW]  #Bitmap displayed + 6 (Show BMP 105)
%patch $F22A [$1F63RW] #Text read from 1
%patch $F22E [$0000W]  #2
%patch $F228 [$0C]     #Text vertical position
%patch $F223 [$30]     #Text right border (Pixels LEFT)
%patch $F214 [$30]     #Text and image position

%patch $1F630 "This had better" $0A
              "be a joke." $00

Oracle Janitor - fourth window

#Janitor window 4
%patch $F268 [$0008W]  #Height
%patch $F26C [$001AW]  #Width
%patch $F2C3 [$003CW]  #Time displayed
%patch $F278 [$006EW]  #Bitmap displayed + 6 (Show BMP 104)
%patch $F29B [$1F65RW] #Text read from 1
%patch $F29F [$0000W]  #2
%patch $F28F [$06]     #Text vertical position
%patch $F294 [$30]     #Text right border (Pixels LEFT)
%patch $F299 [$30]     #Text and image position

%patch $1F650 "Sorry.  You aren't" $0A
              "mad, are you?" $00

Oracle Janitor - fifth window

#Keen's look (Is made up of two bitmaps)
%patch $F2D9 [$0008W]  #Height
%patch $F2DD [$001AW]  #Width
%patch $F327 [$001EW]  #Time displayed
%patch $F2E9 [$006FW]  #Bitmap displayed + 6 (Show BMP 105)
%patch $F2F8 [$0030W]  #Bitmap x position
%patch $F304 [$0071W]  #Bitmap displayed + 6 (Show BMP 107)
%patch $F30B [$0018W]  #Bitmap x
%patch $F316 [$0018W]  #Bitmap y

Windows don't wait for the player to press a key

These patches remove the 'wait for key' code from the various windows. This makes them seem much more immediate, since the player must read them before they vanish. Each window has a separate segment of code so they can be mixed; use one line only for the noted window.

Oracle Janitor windows don't wait for player keypress

#Oracle Janitor windows don't wait for player keypress
%patch $F17E $90 $90 $90 $90 $90 #Window 1
%patch $F1EF $90 $90 $90 $90 $90 #Window 2
%patch $F262 $90 $90 $90 $90 $90 #Window 3
%patch $F2D3 $90 $90 $90 $90 $90 #Window 4
%patch $F337 $90 $90 $90 $90 $90 #Window 5

Don't display bitmaps in windows

These patches remove some of the bitmaps from the Janitor windows.

Oracle Janitor fifth window

#Don't show Keen's face
%patch $F319 $90 $90 $90 $90 $90

#Don't show frowning part of Keen frowning bitmap
%patch $F2FB $90 $90 $90 $90 $90

Text in last window

This patch modifies the window code in complex manner so that the final window has text in it, as well as a bitmap appearing in the same place as the other windows. It does this by rewriting the last three windows, making it incompatible with any patches involving them found elsewhere on this page, with the exception of the 3rd window's size and text patches.

The last blue value is the 'window display time' for the last three windows, the minimum time all three will be visible before the player can move on. Altering this affects all three windows.

The 4th and 5th windows have identical formats; the first two blue values are the window's height and width in 8x8 blocks, after that is the bitmap displayed in the window and finally the two values that give the location of the window's text. (In this patch window 4 and 5 use the same text, this can be altered.)

Keen 4

#Text in last Janitor window
#Shorten 3rd window
%patch $F24C $9A $0E8F0A31RL

#4th window
                         $B8 [$0008W]  $50 $B8 [$001AW]  $50 $9A $19311070RL   
             $83 $C4 $04 $B8 [$006EW]  $50 $FF $36 $DE $A7 $FF $36 $33 $A5 $9A
             $1D060C79RL     $83 $C4 $06 $83 $06 $35 $A5 $06 $83 $2E $31 $A5
             $30 $83 $06 $33 $A5 $30 $B8 [$1F65RW] $50 $B8 [$0000W]  $50 $16 $8D
             $86 $38 $FF $50 $9A $000037B3RL     $83 $C4 $08 $8D $86 $38 $FF
             $50 $9A $19310EBDRL     $83 $C4 $02 $9A $0E8F0A31RL

#New 5th window
                         $B8 [$0008W]  $50 $B8 [$001AW]  $50 $9A $19311070RL   
             $83 $C4 $04 $B8 [$0071W]  $50 $FF $36 $DE $A7 $FF $36 $33 $A5 $9A
             $1D060C79RL     $83 $C4 $06 $83 $06 $35 $A5 $06 $83 $2E $31 $A5
             $30 $83 $06 $33 $A5 $30 $B8 [$1F65RW] $50 $B8 [$0000W]  $50 $16 $8D
             $86 $38 $FF $50 $9A $000037B3RL     $83 $C4 $08 $8D $86 $38 $FF
             $50 $9A $19310EBDRL     $83 $C4 $02 $9A $0E8F0A31RL
                             $9A $06BD2092RL     $9A $12A614EDRL
                     $FF $36 $68 $7A $9A $06BD20C7RL     $83 $C4 $02 $8B $E5
             $5D $CB

#New code to make windows shorter
%patch $F321 $55 $8B $EC $9A $1D060A9BRL     $B8 [$003CW]  $50 $9A $1E0A0AD3RL
             $83 $C4 $02 $9A $146008A8RL     $9A $14600EDFRL     $5D $CB

Janitor wins the level

This patch changes things so that instead of vanishing the Janitor wins the level. Keen will not however be credited with saving a member. This patch works by changing the level state to 2, or 'win level'. Changing that value to other things can result in Keen doing things like losing the level or getting a Wetsuit.

Keen 4

#Oracle Janitor wins level
%patch $CD9E $C7 $06 {$7A70W}  [$0002W]  $90 $90 $90

Do not remove Janitor after text

This patch stops the Janitor being removed from the level when Keen contacts him. By itself this patch is quite useless; since Keen is still touching the Janitor, this loops the Janitor's message over and over about ten times before Keen can 'break free'; however in combination with other patches, especially ones that make the Janitor change after talking to Keen, this patch can be exceedingly useful.

Keen 4

#Don't remove Janitor when touched
%patch $CD9F $90 $90 $90 $90 $90


By default new music plays when the Oracle Janitor is being spoken to, and it is stopped afterwards. The song used is a unique one not used for other levels. See also Patch:Music.

Note that while the new music code is part of the Janitor window code, the 'stop old music' code is not. This may be important when the window code is called in an odd way. (Such as when a sprite dies.)

Music played

By default the song played is -1, or silence. It can however be turned into positive values for other songs. In that case the value is not the song number, but rather the level number of what music is desired. (So a value of +1 will play the same music as plays in level 1.)

Keen 4

#Music played when talking to Janitor
%patch $F107 [$FFFFW]

Don't change music for conversation

This patch stops the music changing when Keen is talking to the Member. Instead the level music continues, uninterrupted. (It is best to also include the below 'after conversation' patch to stop the level music 'stuttering' when the conversation ends.)

Keen 4

#Don't change music when talking to Oracle janitor
%patch $EF3D $90 $90 $90 $90 $90
%patch $F106 $EB $0A

Don't revert music after conversation

This patch stops the music changing back to the normal level music after Keen has talked to the Janitor, instead the Janitor music keeps playing. (If the player brings up the Main Menu however then the regular music will start playing when they return to the game.)

Keen 4

#Don't revert music after Janitor conversation
%patch $F33C $9A $12A614EDRL     $8B $E5  $5D $CB