Patch:Text patches

From KeenWiki
Jump to navigation Jump to search

This is a page explaining how text patches work. For more specific patches, such as the About Id text, see the relevant patch page (E.g Patch:About Id. Specific examples include Patch:End text, Patch:Help text, Patch:Previews text, Patch:Story text and Patch:Ordering Info.

Basic concepts

A text patch is a patch that involves changing a string of text in the Keen executable. They differ from other patches in that machine instructions are not being altered, but textual data instead. A text patch has two patchable parts, the text itself, and the reference (or pointer) to the text. Text strings are stored in a region of the keen executable known as the "data segment." The reference to the text, or "pointer," is part of the actual game code, located in a separate segment. The location of the data segment for each Keen game is listed below:

Keen 1: $13050
Keen 2: $17780
Keen 3: $19820
Keen 4: $2EE70
Keen 5: $30340
Keen 6: $30D30
Keen D: $23A70

An example text patch is given below. It patches the name of the saved game files in Keen 3. (The '?' is replaced by the game number, e.g SAVED3.CK3) The first pair of patches changes the actual text in the executable. The second pair changes the values of the pointers. Notice that the two pointers are NOT the absolute location of the text from the beginning of the executable, but that location minus the data segment start (e.g. second patch: $1CA35 - $19820 = $3215).

Patch the text

%patch $1CA28 "SAVED?." $00      #load game from this filename
%patch $1CA35 "SAVED?." $00      #save game to this filename

Patch Keen 3 saved game filename

%patch $A2BD $08 $32 #Save game to
%patch $A44D $15 $32 #Load game from

Notice that the string is null-terminated ($00), that is, the byte $00 denotes the end of a string. Also note that a string patched to be longer than the original may overwrite other data in the executable. What this means for our example patch is that we can have some text shorter or the same length as the original. Thus 'SAVE?.' or 'GAME?.' are both ok, but 'SAVEGAME?.' is not. (In fact you will notice that these two pieces of text are almost right after each other.)

The 'newline' character, $0A, means 'go down a line' and is used in longer text patches. While some patches (Simple patches like the above or the Patch:Story text patch) don't need these, many do. As an example, this is some cheat text from Keen 4, as it is stored in the executable:

Keen 4 cheat text:

%patch $2F435 "Cheat Option!" $0A $0A
              "You just got all" $0A
              "the keys, 99 shots," $0A
              "and an extra keen!" $00

Here each line ends with $0A, so that the next line starts one line lower. Finally the text is ended with $00. The text has been arranged so this can be seen.

The restrictions on space and format can be annoying and at present there is only two programs that can partially automate some text patches. (Startext and The Neural Stunner) It is possible, with some skill, to rearrange text patches to allow yourself more space when patching. (By overwriting useless text or spare space for example.)

Text files

When a large amount of text is to be patched, it is often simpler to place it all into a text file and then use a %patchfile patch. That way the text can be edited easily in Notepad or Wordpad without having to worry about taxing CKPatch with long lines. In general this works with a specific class of text patch, notably the '*TEXT's (STORYTEXT, HELPTEXT...) in Keen Vorticons. The game here reads a large amount of text as a single block, automatically parsing the text. In fact, in Keen 1 the texts are external *.CK1 files with no need of a patch. An example is:

Keen 2

#Change the story, max file length 2'016 bytes
%patchfile $15BC0 "HELPTXT.CK2"

In this example the file "HELPTXT.CK2" would contain the new story's text. Note again, there is a limit to how much text the file can contain without overwriting other text.

Add Message Windows to Keen Dreams

This patch adds a 'note tile' to Keen Dreams. It exploits the default property 'Top of fire', which does nothing in the original game. With this patch any tile of that property can be 'read' if the player presses the up key while in front of it. (Unless the tile is at their feet, in which case the down key will suffice.)

Reading the note plays sound $04, changes the player's animation to $63 and, after a short pause, brings up a text window. The window is $09 by $1C in size and reads from a text list at $23A70 + $012CW = $23B9C.

This allows a different message in every game level (Except level 0, the map, which Keen cannot behave normally in.) This patch uses some unused 'napping Keen tile collision' code and also moves some of Keen's pole gripping code to another location. This will make it incompatible with some pole patches.

Keen Dreams

#Note reading action
%patch $24BDC [$0063W $0063W] $0000W $0000W $0000W $0040W $0000W $0000W
              $05E81D64RL   $05E817FCRL   $05E81AE2RL   $0ED8W

#Modify Keen's code to trigger note (+2)
%patch $6C6C $74 $04 $7D $05 $EB $25 $E9 $0F3EW $C7 $44 $1E $116CW  $B8 [$0004W]
             $50 $9A $10BB1282RL     $44 $44 $B8 $0001W  $5F $5E $8B $E5 $5D $CB

#Move pole grip to here
%patch $7BB3 $8B $C7 $D3 $E0 $05 $FF80W  $2B $44 $0A $89 $44 $12 $A1 $7020W
             $B1 $05 $D3 $E0 $89 $44 $14 $89 $7C $44 $C7 $44 $06 $0000W  $C7
             $44 $1E $118AW  $B8 $0001W  $EB $02 $33 $C0 $5F $5E $8B $E5 $5D $CB

#Message window =$05E81D64RL
%patch $7BE4 $55 $8B $EC $4C $4C $56 $B8 [$0009W]  $50 $B8 [$001CW]  $50 $9A
         $11FA1C64RL     $83 $C4 $04 $8B $1E $8F3EW  $D1 $E3 $FF $B7 [$012CW]
             $9A $11FA1ABBRL     $44 $44 $9A $0CA508C0RL     $9A $0FE40C8ERL
                     $9A $0E450A00RL    $5E $8B $E5 $5D $CB

#Message pointer list
%patch $23B9E [$014EW] #Level 1
              [$014EW] #Level 2
              [$014EW] #Level 3
              [$014EW] #Level 4
              [$014EW] #Level 5
              [$01A9W] #Level 6
              [$01A9W] #Level 7
              [$01A9W] #Level 8
              [$01A9W] #Level 9
              [$01A9W] #Level 10
              [$0218W] #Level 11
              [$0218W] #Level 12
              [$0218W] #Level 13
              [$0218W] #Level 14
              [$0218W] #Level 15
              [$0218W] #Level 16

%patch $23BBE "First message." $00
%patch $23C19 "Second message." $00
%patch $23C88 "Third message." $00