From KeenWiki
Jump to navigation Jump to search

This page deals with the Keen 6 map obstacle known as the slavering Grabbiter. It requires Keen to have an object (The Stupendous Sandwich of Chungella IV) to pass. Like most Keen 6 map objects its interaction with Keen revolves around text boxes that appear when Keen contacts it. It is thus worth checking Patch:Keen Galaxy Text Windows.

This page is divided up into two sections, the first deals with the Grabbiter's text windows, which appear when Keen contacts it on the map. The second deals with the Grabbiter's sprite properties, how the Grabbiter sprite itself works.

Grabbiter text windows

Each text window contains nine values that can be patched to change the window. The first two are the most simple, the window's size in 8x8 blocks. The third is how long the text window remains before the player can dismiss it. (This prevents accidental dismissal when the window 'pops up' during gameplay.) The next three relate to the text; the first two control where it is placed in the window (relative to the right and top edges of the window!) while the third controls where the text is read from.

The final three variables relate to the bitmap; it must be stored and then displayed and it too has a horizontal position in the window. Positions of all things range from 0-7F for being left and FF-80 for being right.

Grabbiter text windows

#Hungry Grabbiter window
%patch $F56B [$0008W] #Window height
%patch $F56F [$001AW] #Window width
%patch $F5BD [$001EW] #Pause before window can be dismissed

%patch $F599 [$30]    #Horizontal location of text
%patch $F59E [$05]    #Vertical location of text
%patch $F5A0 [$22EAW] #Text read from

%patch $F54E [$0023W] #Store this bitmap (35 - 6 = 29)
%patch $F57B [$0023W] #Show this bitmap (35 - 6 = 29)
%patch $F58A [$0030W] #Bitmap horizontal location (From window right edge)

%patch $3301A "Oh, no!" $0A
              "It's a slavering" $0A
              "Grabbiter! He says," $0A
          $22 "Get me lunch and" $0A
              "I'll tell ya a secret!" $22 $00

#Fed Grabbiter window:
%patch $F611 [$0008W] #Window height
%patch $F615 [$001AW] #Window width
%patch $F657 [$001EW] #Pause before window can be dismissed

%patch $F63F [$30]    #Horizontal location of text
%patch $F644 [$02]    #Vertical location of text
%patch $F646 [$2341W] #Text read from

%patch $F600 [$0023W] #Store this bitmap (35 - 6 = 29)
%patch $F621 [$0023W] #Show this bitmap (35 - 6 = 29)
%patch $F630 [$0030W] #Bitmap horizontal location (From window left edge)

%patch $33071 "The Grabbiter grabs" $0A
              "the gigantic sandwich," $0A
              "downs it in one bite," $0A
              "and says," $22 "Here's your" $0A
              "secret. Big meals" $0A
              "make me sleepy!" $22 $00

Keen's head appears on the left side of windows instead of the right

This patch modifies the two windows so that the text and bitmap stick to the opposite side of the window than the default. It will be noted that this is done by changing their horizontal positions from +48 ($30) to -46 ($D0).

Keen's head appear on the left side of windows instead of the right

#Keen's head appears on the left side of hungry window
%patch $F58A [$00D0W] #Bitmap
%patch $F599 [$D0]    #Text

#Keen's head appears on the left side of fed window
%patch $F630 [$00D0W] #Bitmap
%patch $F63F [$D0]    #Text

Disable text windows

Grabbiter doesn't respond if Keen has the Sandwich

This patch stops the Grabbiter from responding when Keen has the sandwich. No window or sound appears and it will continue animating and Keen will be able to walk right by it.

Grabbiter doesn't respond if Keen has the sandwich

#Grabbiter doesn't respond if Keen has the sandwich
%patch $F545 $EB

Disable fed text window

This patch disables the fed Grabbiter window. When Keen has the Sandwich the Grabbiter simply falls asleep when touched.

Disable fed text window

#Disable Grabbiter fed window
%patch $F5FF $EB $6B

Complete window codes

These patches contain the complete code for various Grabbiter windows. They contain all the other window patches (and will thus overwrite them.)

Hungry Grabbiter window

This is the complete window code for the window that appears when the player touches the Grabbiter without the sandwich. It is not standalone code, instead being part of a larger code segment. The first line plays sound $39, as well as cache Keen's head bitmap ($0023W) which is then displayed on line 3. Notice that bitmaps are referred to by their 'chunk number', that is, what graphic chunk they are in EGAGRAPH.CK6; this is the bitmap number (When exported via ModKeen, Keengraph numbers the bitmaps 'correctly') plus six. The window's size is set on lines 2/3 as being $08x$1A

The image is aligned right by $0030W pixels. By default this is the same as the image's width so that the displayed bitmap is 'right aligned'. Paired with this is a second, equal variable that moves the text in the opposite direction so that it is not centered in the window (and thus overwriting the bitmap.) These variables can be 'reversed' by making them negative. (Changing $0030W to $00D0W and $30 to $D0 for example.)

Finally the text call on line 6 which determines where the window's text is called from. (See Patch:Text patches.) The value $001EW is the 'pause' before the player can dismiss the window by pressing a key. Finally after the window has been displayed the window is cleared and some miscellaneous code run.

Keen 6

#Complete hungry Grabbiter window code
%patch $F54D $B8 [$0023W]  $50 $9A $125A1108RL     $83 $C4 $02 $B8 [$0039W]  $50
             $9A $183B09F1RL     $83 $C4 $02 $9A $1CF709A3RL     $B8 [$0008W]
             $50 $B8 [$001AW]  $50 $9A $18F81070RL     $83 $C4 $04 $B8 [$0023W]
             $50 $FF $36 $6C $A9 $A1 $C1 $A6 $03 $06 $BF $A6 $2D [$0030W]  $50
             $9A $1CF70C83RL     $83 $C4 $06 $83 $2E $BF $A6 [$30] $83 $06 $C3
             $A6 $05 $B8 [$22EAW]  $50 $9A $18F80EBDRL     $83 $C4 $02 $9A
         $1CF70AA5RL     $B8 $000EW  $50 $9A $183B09F1RL     $83 $C4 $02 $B8
             [$001EW]  $50 $9A $1DFB0ADDRL     $83 $C4 $02 $9A $141308A9RL   
             $9A $14130EE0RL     $9A $16080E88RL     $8B $44 $12 $F7 $D8 $A3
             $89 $CA $8B $44 $14 $F7 $D8 $A3 $87 $CA $33 $C0 $89 $44 $10 $89
             $44 $0E $56 $9A $08F406A5RL     $83 $C4 $02 $5E $5D $CB

Grabbiter sprite properties

These patches deal with the Grabbiter sprite itself, some of them control what triggers the text windows dealt with above.

Sprite Type

The Grabbiter uses sprite type 30, which is what triggers Map Keen to start the Grabbiter conversation.

Keen 6

#Grabbiter sprite type
%patch $F4F8 [$1E] #When spawned

Sprite Actions

The Grabbiter has four actions in two cycles, hungry and napping. It's spawned either hungry or napping depending on whether or not Keen has fed it before. (This is necessary since Keen can revisit the map both before and after feeding the Grabbiter.)

If hungry the Grabbiter remains so until Keen feeds it, at which point it will change to the first napping action. Once napping the Grabbiter naps indefinitely.

$1A90W #Grabbiter hungry 1
$1AAEW #Grabbiter hungry 2
$1ACCW #Grabbiter napping 1
$1AEAW #Grabbiter napping 2

<patch title=="Sprite actions">

  1. Spawn Grabbiter unfed

%patch $F523 [$1A90W]

  1. Spawn Grabbiter fed

%patch $F514 [$1ACCW]

  1. Grabbiter hungry loop

%patch $327FA [$1A90W] %patch $327DC [$1AAEW]

  1. Grabbiter naps after being fed

%patch $F66D [$1ACCW]

  1. Grabbiter napping loop

%patch $32836 [$1ACCW] %patch $32818 [$1AEAW]</syntaxhighlight>

Sprite Behavior

The Grabbiter has no behaviors of its own, it simply sits there doing nothing. Its interactions with Keen are controlled by its sprite collision.

<patch title=="Sprite behaviors">

  1. Grabbiter hungry

%patch $327D0 $00000000L %patch $327EE $00000000L

  1. Grabbiter napping

%patch $3280C $00000000L %patch $3282A $00000000L</syntaxhighlight>

Speed and Jump Height

The Grabbiter has no speeds, it sits completely still by default.

<patch title=="Sprite speeds">

  1. Grabbiter hungry

%patch $327CC [$0000W $0000W] %patch $327EA [$0000W $0000W]

  1. Grabbiter napping

%patch $32808 [$0000W $0000W] %patch $32826 [$0000W $0000W]</syntaxhighlight>

Sprite Collision

The hungry Grabbiter has a unique collision that responds to Keen and brings up its text windows. If napping however it has no collision and doesn't interact with anything.

<patch title=="Sprite collisions"> %patch $327D4 $0EFC0574RL %patch $327F2 $0EFC0574RL

  1. Grabbiter napping

%patch $32810 $00000000L %patch $3282E $00000000L</syntaxhighlight>


The Grabbiter has two animation sequences, one when hungry and one when napping. Each sequence is two actions long. The Grabbiter itself has no cache, depending on Map Keen's cache.

Keen 6

#Grabbiter hungry
%patch $327C0 $00D9W $00D9W
%patch $327CA $000CW        #Animation speed
%patch $327DE $00DAW $00DAW
%patch $327E8 $000CW        #Animation speed

#Grabbiter napping
%patch $327FC $00DBW $00DBW
%patch $32806 $000CW        #Animation speed
%patch $3281A $00DCW $00DCW
%patch $32824 $000CW        #Animation speed

Clipping and foreground

The Grabbiter has a foreground variable of 2, meaning it appears in front of all non-foreground tiles and most sprites. This is so that it always appears in front of Keen when he passes by it. It has no clipping to avoid issues on the map with blocking tiles.

Keen 4

#Grabbiter foreground variable
%patch $F4F4 [$0002W]

#Grabbiter foreground variable
%patch $F4EF [$0000W]

Sprite-tile interaction

The Grabbiter has no real need to interact with tiles and so uses a simple 'display sprite' interaction that does nothing but let it sit there.

<patch title=="Sprite tile interactions">

  1. Grabbiter hungry

%patch $327D8 $08F4180ARL %patch $327F6 $08F4180ARL

  1. Grabbiter napping

%patch $32814 $08F4180ARL %patch $32832 $08F4180ARL</syntaxhighlight>

Action type

As it does not move or do anything special the Grabbiter uses type 0 for all of its actions.

<patch title=="Sprite action types">

  1. Grabbiter hungry

%patch $327C4 [$0000W] %patch $327E2 [$0000W]

  1. Grabbiter napping

%patch $32800 [$0000W] %patch $3281E [$0000W]</syntaxhighlight>

Deprotect and stick to ground

The Grabbiter has no need for either of these variables and so has a value of 0 for both in all of its actions.

<patch title=="Sprite deprotect, stick">

  1. Grabbiter hungry

%patch $327C6 [$0000W $0000W] %patch $327E4 [$0000W $0000W]

  1. Grabbiter napping

%patch $32802 [$0000W $0000W] %patch $32820 [$0000W $0000W]</syntaxhighlight>

Sprite spawn code

The Grabbiter's spawning is quite simple. Its initiation relies on Map Keen, and so doesn't set any cache. In the spawning code proper $C7 $02 $xxxxW sets the sprite activity, $C7 $07 $xxxxW sets the sprite type, $C7 $20 $xxxxW sets the foreground value.

One complication is that the Grabbiter's starting action depends on whether or not Keen has fed it a Sandwich at any time in the game. If this is the case (The sandwich variable is 2.) then the napping Grabbiter is spawned, otherwise the hungry Grabbiter is. These values are the last two blue values in the code.

Keen 6

#Location of initiation code
%patch $EA00 $0428W #Grabbiter (At $E848)

#Grabbiter initiation code
%patch $E848 $57 $56 $9A $0EFC0515RL     $83 $C4 $04 $EB $73

#Grabbiter spawn code
%patch $F4D5 $55 $8B $EC $33 $C0 $50 $9A $069A1E25RL     $83 $C4 $02 $8B $1E
             $66 $A9 $C7 $47 $02 [$0001W]  $C7 $47 $06 [$0000W]  $C7 $47 $20 [$0002W]
                 $C7 $07 [$001EW]  $8B $46 $06 $B1 $08 $D3 $E0 $89 $47 $0A $8B
             $46 $08 $D3 $E0 $89 $47 $0C $83 $3E {$7594W}  [$02] {$75} $0F $B8 [$1ACCW]
                 $50 $53 $9A $08F41219RL     $83 $C4 $04 $5D $CB
                                                                 $B8 [$1A90W]
             $50 $FF $36 $66 $A9 $9A $08F41219RL     $83 $C4 $04 $5D $CB

Grabbiter spawn has extra variable

This patch compresses the default Grabbiter spawn so that another sprite variable my be set. In this example the Grabbiter's horizontal direction is being set to -1 (Left.)

Keen 6

#Grabbiter spawn code -add variable
%patch $F4D5 $55 $8B $EC $33 $C0 $50 $9A $069A1E25RL     $83 $C4 $02 $8B $1E
             $66 $A9 $C7 $47 $02 [$0001W]  $C7 $47 $06 [$0000W]  $C7 $47 $20 [$0002W]
             $C7 $47 $0E [$FFFFW]
                 $C7 $07 [$001EW]  $8B $46 $06 $B1 $08 $D3 $E0 $89 $47 $0A $8B
             $46 $08 $D3 $E0 $89 $47 $0C $83 $3E {$7594W}  [$02] {$75} $07 $B8 [$1ACCW]
                 $50 $53 $EB $08 $B8 [$1A90W]  $50 $FF $36 $66 $A9 $9A $08F41219RL
             $83 $C4 $04 $5D $CB