Patch:Sprite cache
This page relates to sprite caches A sprite cache consists of some values that tell the game what sprite graphics chunks to decompress and read into memory. This is important when patching sprite animations since a sprite can only use animations that have been cached, otherwise the game will crash.
What triggers the caching of sprites is the presence in a level of a certain sprite. (This is explained further below.) This means that every level caches different sprites. Since there is not enough memory for the game to cache all the graphics, a modder must be careful as to the size of their caches and the free memory available. If there is too little free memory music won't play or the level won't load.
It is notable that this applies to Dreams and Galaxy games only, Vorticons caches all graphics when the game starts. This page is divided into two sections, the first explains how caches work as code while the second lists the default caches used in the Galaxy and Dreams games. To modders the second section is likely to be the more valuable.
Caches in code
Sprite images are cached when the level is first loaded and a sprite's initiation code is first run. There are two ways to do this; a 'defined cache' which sets a specific variable to 1, turning a cache 'on' and an 'undefined cache' which manually saves a selection of sprites.
This section relies heavily on the page Patch:Sprite spawning.
Defined caches
Defined caches are the 'traditional' kind of cache. A six byte string of code in a sprite's initiation code sets a variable to 1, later on when the defined cache code is run, all defined caches are detected, read from a list, and cached. This six byte string of code in effect 'ticks off' an item on the cache list. The first cache (In the list, normal Keen) is defined as follows in the various games:
First defined cache code Keen 4 $C7 $06 $CB3DW $0001W Keen 5 $C7 $06 $C269W $0001W Keen 6 $C7 $06 $CD01W $0001W Keen Dreams $C7 $06 $????W $0001W
This can be seen in Keen 4's initiation code for left facing normal Keen, and the Egg's code sets two caches (One for itself, and one for the Blue Bird.) Here the defined cache code has been highlighted in brown:
Keen 4 initiation codes
#Left facing Keen
%patch $E980 $B8 [$FFFFW] $50 $FF $76 $FC $57 $9A $0B80000ERL #Keen's direction is -1
$83 $C4 $06 $9A $0D8F0003RL {$C7 $06 $CB3DW $0001W} $B8 $2A3ARW
$8A $16 $EC $7A $8E $C0 $26 $08 $16 [$00FDW] $E9 $0451W
#Egg
%patch $EB01 $FF $76 $FC $57 $9A $0FA8055DRL $83 $C4 $04 {$C7 $06 $CB5FW}
{$0001W $C7 $06 $CB83W $0001W} $E9 $02E1W
It can easily be seen that Keen's cache code is the same as first cache code, and indeed Keen's cache appears first in the list of caches in the second section on this page. The Egg's cache codes differ in the value $CB5FW\$CB83W, meaning they are different caches. The specific cache can be found for, e.g. $CB83W as follows:
($CB83W - $CB3DW) / 2 = $23.
It is thus the 35th cache after Keen's, which turns out to be the Eggs. So the second cache in the egg initiation code is that of the Eggs itself.
As a note, the items have pseudo-cache strings, $C7 $87 $CB3BW $0001W, these are not cache code at all and should be ignored. (Their defined caches are even more complex.)
Undefined caches
Undefined caches manually cache a series of animations in the sprite's initiation code. This takes up more space than a defined cache, but is much more flexible since a modder can create their own custom cache for any sprite. From the above section it will be noticed that there is 'extra' code in the left normal Keen initiation, and the Wetsuit initiation code below has no defined cache code at all. Here the 'cache a single extra animation' code has been highlighted in brown, with the single animation value that follows it highlighted in blue:
Keen 4 initiation codes
#Left facing Keen
%patch $E980 $B8 [$FFFFW] $50 $FF $76 $FC $57 $9A $0B80000ERL #Keen's direction is -1
$83 $C4 $06 $9A $0D8F0003RL $C7 $06 $CB3DW $0001W {$B8 $2A3ARW}
$8A $16 $EC $7A $8E $C0 $26 $08 $16} [$00FDW] $E9 $0451W
#Wetsuit - Note single frame is cached
%patch $ECCE $FF $76 $FC $57 $9A {$11A20FD1RL} $83 $C4 $04 {$B8 $2A3ARW $8A}
$16 $EC $7A $8E $C0 $26 $08 $16} [$01AEW] $E9 $0112W
It can be seen that Keen caches $00FDW (The scoreboard) and the Wetsuit caches $01AEW, the only animation it uses. This shows that undefined and defined caches can be used by the same sprite, and also how much longer, code-wise, undefined caches are.
It is also possible to cache an entire selection of animations instead of just a single frame. This is even longer and more complex and can be seen in Swimming Keen's and the Inchworm's initiation codes; again marked in brown:
Keen 4 initiation codes
#Inchworm
%patch $EABD $FF $76 $FC $57 $9A $108006B2RL $83 $C4 $04 $C7 $06 $CB59W
$0001W {$BE} [$015EW] {$EB $0F $B8 $3A $2A $8A $16 $EC $7A $8E $C0} #Also cache Smirky clouds, start
{$26 $08 $94 $00 $00 $46 $81 $FE} [$0161W] {$76 $EB} $E9 $0311W #End
#Swimming Keen
%patch $ECEB $FF $76 $FC $57 $9A $0E8F0CFERL $83 $C4 $04 $9A $0D8F0003RL
$C7 $06 $CB7BW $0001W $BE [$00DBW] {$EB $0F $B8 $2A3ARW $8A} #Cache items got - start
{$16 $EC $7A $8E $C0 $26 $08 $94 $00 $00 $46 $81 $FE} [$00E2W] {$76} #Cache items got - end
{$EB} $B8 $2A3ARW $8A $16 $EC $7A $8E $C0 $26 $08 $16 [$00FDW] $E9 #Cache scoreboard
$00D0W
Notice Swimming Keen has a defined cache, a selection and then a single frame cached, making it quite complex. If a modder desires to create a custom undefined cache they will have to also create custom initiation code. The page Patch:Sprite spawning has more details.
Caches in games
These are the default caches in the games, in the correct location. (They can be used for patching.) A cache start value MUST be smaller than the cache end value, and all the sprite chunks, including the start and end values are cached. The size (in KB) of a cache depends directly on the size of the sprites being cached and how many copies of that sprite must be saved to memory.
For convenience two lists have been combined in these entries; the cache start list and the cache end list. But it should be kept in mind that these are not a single list. For example the Soda item uses cache $02, this is the second entry in both individual lists, but the 3rd and 4th entry in this combined list.
Keen 4
Keen 4
%patch $306D2 [$0082W] #Keen Cache start
%patch $3071C [$00E2W] #Keen cache end
%patch $306D4 [$00E3W] #Soda Cache start
%patch $3071E [$00E4W] #Soda cache end
%patch $306D6 [$00E5W] #Candybar Cache start
%patch $30720 [$00E6W] #Candybar cache end
%patch $306D8 [$00E7W] #Choc Cache start
%patch $30722 [$00E8W] #Choc cache end
%patch $306DA [$00E9W] #Jawbreaker Cache start
%patch $30724 [$00EAW] #Jawbreaker cache end
%patch $306DC [$00EBW] #Donut Cache start
%patch $30726 [$00ECW] #Donut cache end
%patch $306DF [$00EDW] #Icecream Cache start
%patch $30728 [$00EEW] #Icecream cache end
%patch $306E0 [$00EFW] #Flask Cache start
%patch $3072A [$00F0W] #Flask cache end
%patch $306E2 [$00FBW] #Raygun Cache start
%patch $3072C [$00FCW] #Raygun cache end
%patch $306E4 [$00FEW] #Map Keen Cache start
%patch $3072E [$0134W] #Map Keen cache end
%patch $306E6 [$013BW] #Slug Cache start
%patch $30730 [$0144W] #Slug cache end
%patch $306E8 [$0145W] #Mushroom Cache start
%patch $30732 [$0148W] #Mushroom cache end
%patch $306EA [$0000W] #Dart shooter Cache start
%patch $30734 [$0000W] #Dart shooter cache end
%patch $306EC [$0149W] #Lindsey Cache start
%patch $30736 [$014CW] #Lindsey cache end
%patch $306EE [$014DW] #Inchworm Cache start
%patch $30738 [$0151W] #Inchworm cache end
%patch $306F0 [$0152W] #Smirky Cache start
%patch $3073A [$0163W] #Smirky cache end
%patch $306F2 [$0164W] #Council Member Cache start
%patch $3073C [$0169W] #Council member cache end
%patch $306F4 [$016FW] #Blue bird Cache start
%patch $3073E [$017BW] #Blue bird cache end
%patch $306F6 [$0184W] #Mimrock Cache start
%patch $30740 [$0193W] #Mimrock cache end
%patch $306F8 [$0194W] #Dopefish Cache start
%patch $30742 [$01A4W] #Dopefish cache end
%patch $306FA [$01A5W] #Schoolfish Cache start
%patch $30744 [$01A8W] #Schoolfish cache end
%patch $306FC [$01A9W] #Arachnut Cache start
%patch $30746 [$01ADW] #Arachnut cache end
%patch $306FE [$01BBW] #Skypest Cache start
%patch $30748 [$01C8W] #Skypest cache end
%patch $30700 [$01C9W] #Wormouth Cache start
%patch $3074A [$01D4W] #Wormouth cache end
%patch $30702 [$01D5W] #Lick Cache start
%patch $3074C [$01E3W] #Lick cache end
%patch $30704 [$01E4W] #Airboard Cache start
%patch $3074E [$01EAW] #Airboard cache end
%patch $30706 [$01EBW] #Bounder Cache start
%patch $30750 [$01F1W] #Bounder cache end
%patch $30708 [$01F2W] #Cloud Cache start
%patch $30752 [$01F6W] #Cloud cache end
%patch $3070A [$01F7W] #Berkeloid Cache start
%patch $30754 [$0206W] #Berkeloid cache end
%patch $3070C [$00F2W] #Gems Cache start
%patch $30756 [$00FAW] #Gems cache end
%patch $3070E [$017CW] #Darts Cache start
%patch $30758 [$0183W] #Darts cache end
%patch $30710 [$0135W] #Keen swimming Cache start
%patch $3075A [$013AW] #Keen swimming cache end
%patch $30712 [$01AFW] #Sprite Cache start
%patch $3075C [$01B7W] #Sprite cache end
%patch $30714 [$01B8W] #Mine Cache start
%patch $3075E [$01BAW] #Mine cache end
%patch $30716 [$0207W] #Mooning Keen Cache start
%patch $30760 [$0208W] #Mooning Keen cache end
%patch $30718 [$016AW] #Egg Cache start
%patch $30762 [$016EW] #Egg cache end
Keen 5
Keen 5
%patch $31A16 [$006CW] #Keen cache start
%patch $31A6A [$00CEW] #Keen cache end
%patch $31A18 [$00D2W] #Candy cache start
%patch $31A6C [$00D3W] #Cache end
%patch $31A1A [$00D4W] #Mallow cache start
%patch $31A6E [$00D5W] #Cache end
%patch $31A1C [$00D6W] #Cola cache start
%patch $31A70 [$00D7W] #Cache end
%patch $31A1E [$00D8W] #Stix cache start
%patch $31A72 [$00D9W] #Cache end
%patch $31A20 [$00DAW] #Stoopies cache start
%patch $31A74 [$00DBW] #Cache end
%patch $31A22 [$00DCW] #Sugar cache start
%patch $31A76 [$00DDW] #Cache end
%patch $31A24 [$00DEW] #Keg cache start
%patch $31A78 [$00DFW] #Cache end
%patch $31A26 [$00E0W] #Gems cache start
%patch $31A7A [$00E8W] #Cache end
%patch $31A28 [$00E9W] #Ammo cache start
%patch $31A7C [$00EAW] #Cache end
%patch $31A2A [$00ECW] #Pink shot cache start
%patch $31A7E [$00F1W] #Cache end
%patch $31A2C [$00F2W] #Map Keen cache start
%patch $31A80 [$011AW] #Cache end
%patch $31A2E [$0130W] #Master cache start
%patch $31A82 [$013FW] #Cache end
%patch $31A30 [$0140W] #Shikadi cache start
%patch $31A84 [$0150W] #Cache end
%patch $31A32 [$0151W] #Shocksund cache start
%patch $31A86 [$0165W] #Cache end
%patch $31A34 [$0166W] #Sphereful cache start
%patch $31A88 [$016DW] #Cache end
%patch $31A36 [$016EW] #Sparky cache start
%patch $31A8A [$0179W] #Cache end
%patch $31A38 [$017AW] #Mine cache start
%patch $31A8C [$0180W] #Cache end
%patch $31A3A [$0181W] #Slicestar cache start
%patch $31A8E [$0182W] #Cache end
%patch $31A3C [$0183W] #Robo Red cache start
%patch $31A90 [$0188W] #Cache end
%patch $31A3E [$0189W] #Spriogrip cache start
%patch $31A92 [$0194W] #Cache end
%patch $31A40 [$0195W] #Ampton cache start
%patch $31A94 [$01A0W] #Cache end
%patch $31A42 [$01A1W] #Volte cache start
%patch $31A96 [$01A5W] #Cache end
%patch $31A44 [$01A6W] #Purple plat cache start
%patch $31A98 [$01A7W] #Cache end
%patch $31A46 [$01A8W] #Spindred cache start
%patch $31A9A [$01ABW] #Cache end
%patch $31A48 [$01ACW] #Shelley cache start
%patch $31A9C [$01BDW] #Cache end
%patch $31A4A [$01BEW] #Red plat cache start
%patch $31A9E [$01BEW] #Cache end
%patch $31A4C [$01BFW] #Small red plat cache start
%patch $31AA0 [$01BFW] #Cache end
%patch $31A4E [$00CFW] #Card cache start
%patch $31AA2 [$00D1W] #Cache end
%patch $31A50 [$0126W] #Korath cache start
%patch $31AA4 [$012FW] #Cache end
%patch $31A52 [$011BW] #Q.E.D\Fuse cache start
%patch $31AA6 [$011DW] #Cache end
%patch $31A54 [$011EW] #Teleporter cache start
%patch $31AA8 [$0121W] #Cache end
%patch $31A56 [$0122W] #Q.E.D explosion cache start
%patch $31AAA [$0125W] #Cache end
Unused Platform cache
There is one unused sprite cache in Keen 5. It is a single animation in size and contains a small red platform. This is useful since it is not hard to expand it or use it for a totally unique sprite. It's call is $C29F.
Keen 5 Cache
#Cache
%patch $31A4C $01BFW #Small red platform cache start
%patch $31AA0 $01BFW #Cache end
Keen 6
Keen 6
%patch $32414 [$0034W] #Keen cache start
%patch $32464 [$0095W] #Keen cache end
%patch $32416 [$0096W] #Soda cache start
%patch $32466 [$0097W] #Soda cache end
%patch $32418 [$0098W] #Iceblock cache start
%patch $32468 [$0099W] #Iceblock cache end
%patch $3241A [$009AW] #Sundae cache start
%patch $3246A [$009BW] #Sundae cache end
%patch $3241C [$009CW] #Cola glass cache start
%patch $3246C [$009DW] #Cola glass cache end
%patch $3241E [$009EW] #Split cache start
%patch $3246E [$009FW] #Split cache end
%patch $32420 [$00A0W] #Pizza cache start
%patch $32470 [$00A1W] #Pizza cache end
%patch $32422 [$00A2W] #Viva cache start
%patch $32472 [$00A3W] #Viva cache end
%patch $32424 [$00A4W] #Gems cache start
%patch $32474 [$00ACW] #Gems cache end
%patch $32426 [$00ADW] #Raygun cache start
%patch $32476 [$00AEW] #Raygun cache end
%patch $32428 [$00B8W] #Map Keen cache start
%patch $32478 [$00EEW] #Map Keen cache end
%patch $3242A [$0000W] #Unused cache start
%patch $3247A [$0000W] #Unused cache end
%patch $3242C [$0156W] #Bloog cache start
%patch $3247C [$015EW] #Bloog cache end
%patch $3242E [$015FW] #Red blooglet cache start
%patch $3247E [$0167W] #Red blooglet cache end
%patch $32430 [$0168W] #Yellow blooglet cache start
%patch $32480 [$0170W] #Yellow blooglet cache end
%patch $32432 [$0171W] #Blue blooglet cache start
%patch $32482 [$0179W] #Blue blooglet cache end
%patch $32434 [$017AW] #Green blooglet cache start
%patch $32484 [$0182W] #Green blooglet cache end
%patch $32436 [$01A8W] #Platform cache start
%patch $32486 [$01B0W] #Platform cache end
%patch $32438 [$0183W] #Gik cache start
%patch $32488 [$018EW] #Gik cache end
%patch $3243A [$018FW] #Blorb cache start
%patch $3248A [$0191W] #Blorb cache end
%patch $3243C [$0192W] #Bobba cache start
%patch $3248C [$019DW] #Bobba cache end
%patch $3243E [$011DW] #Babobba cache start
%patch $3248E [$0129W] #Baboba cache end
%patch $32440 [$00FEW] #Blooguard cache start
%patch $32490 [$010CW] #Bloguard cache end
%patch $32442 [$013DW] #Flect cache start
%patch $32492 [$0148W] #Flect cache end
%patch $32444 [$019EW] #Bip cache start
%patch $32494 [$01A6W] #Bip cache end
%patch $32446 [$01A7W] #Squished Bip cache start
%patch $32496 [$01A7W] #Squished Bip cache end
%patch $32448 [$010DW] #Bipship cache start
%patch $32498 [$011CW] #Bipship cache end
%patch $3244A [$012AW] #Nospike cache start
%patch $3249A [$013CW] #Nospike cache end
%patch $3244C [$0149W] #Orbatrix cache start
%patch $3249C [$0155W] #Orbatrix cache end
%patch $3244E [$00F6W] #Ceilick cache start
%patch $3249E [$00FDW] #Ceilick cache end
%patch $32450 [$00EFW] #Fleex cache start
%patch $324A0 [$00F5W] #Fleex cache end
%patch $32452 [$00B7W] #Rope cache start
%patch $324A2 [$00B7W] #Rope cache end
%patch $32454 [$00B6W] #Sandwich cache start
%patch $324A4 [$00B6W] #Sandwich cache end
%patch $32456 [$00B0W] #Enemy shot cache start
%patch $324A6 [$00B5W] #Enemy shot cache end
%patch $32458 [$01B3W] #Card cache start
%patch $324A8 [$01B3W] #Card cache end
%patch $3245A [$01B1W] #Molly cache start
%patch $324AA [$01B2W] #Molly cache end
Keen Dreams
In Keen Dreams Keen's in-level cache is treated specially. The 'normal' Keen cache is completely ignored, instead Keen's cached animations are dealt with in two locations, both of which should match. This means that Keen's animations are in fact loaded in every level, including the map.
Keen Dreams
#Keen's cache
%patch $3AFA [$0048W] #Keen cache start 1
%patch $3B59 [$0048W] #Keen cache start 2
%patch $3B74 [$00D4W] #Keen cache end 1
%patch $3B08 [$00D4W] #Keen cache end 2
#Normal caches
%patch $23E74 [$0048W] #Keen cache start
%patch $23EA0 [$00D4W] #Keen cache end
%patch $23E76 [$00D5W] #Map Keen cache start
%patch $23EA2 [$00F0W] #Map Keen cache end
%patch $23E78 [$00F1W] #Broccoli cache start
%patch $23EA4 [$0100W] #Broccoli cache end
%patch $23E7A [$0101W] #Tomato cache start
%patch $23EA6 [$0104W] #Tomato cache end
%patch $23E7C [$0105W] #Carrot cache start
%patch $23EA8 [$010EW] #Carrot cache end
%patch $23E7E [$010FW] #Asparagusto cache start
%patch $23EAA [$0116W] #Asparagusto cache end
%patch $23E80 [$0117W] #Grape cache start
%patch $23EAC [$0118W] #Grape cache end
%patch $23E82 [$0119W] #Tater Trooper cache start
%patch $23EAE [$0124W] #Tater Trooper cache end
%patch $23E84 [$0125W] #Melon minecart cache start
%patch $23EB0 [$0126W] #Melon minecart cache end
%patch $23E86 [$0127W] #Frenchy cache start
%patch $23EB2 [$0134W] #Frenchy cache end
%patch $23E88 [$0135W] #Melon cache start
%patch $23EB4 [$0140W] #Melon cache end
%patch $23E8A [$0141W] #Squash cache start
%patch $23EB6 [$0148W] #Squash cache end
%patch $23E8C [$0149W] #Apple cache start
%patch $23EB8 [$0154W] #Apple cache end
%patch $23E8E [$0155W] #Pea and Peapod cache start
%patch $23EBA [$0166W] #Pea and Peapod cache end
%patch $23E90 [$0167W] #Boobus Tuber cache start
%patch $23EBC [$016FW] #Boobus Tuber cache end