Mercurial > vba-clojure
diff org/rom.org @ 348:497ca041f5af
finished working for now. i've completed more carving up of code blocks.
author | Dylan Holmes <ocsenave@gmail.com> |
---|---|
date | Sun, 08 Apr 2012 07:55:06 -0500 |
parents | ff65ee0944fe |
children | 37616a97beaa |
line wrap: on
line diff
1.1 --- a/org/rom.org Sun Apr 08 06:13:39 2012 -0500 1.2 +++ b/org/rom.org Sun Apr 08 07:55:06 2012 -0500 1.3 @@ -12,6 +12,826 @@ 1.4 # pokedollar: U+20B1 1.5 * Introduction 1.6 1.7 + 1.8 +** COMMENT Getting linguistic data: names, words, etc. 1.9 + 1.10 +Some of the simplest data 1.11 + 1.12 + 1.13 +One of the simplest data structures in the Pok\eacute{} ROM is an 1.14 +unbroken list of strings that either (a) all have a specific length, 1.15 +or (b) are all separated by the same character. 1.16 + 1.17 +Because lots of good data has this format, we'll start by writing a 1.18 +template function to extract it: 1.19 + 1.20 +#+name: hxc-thunks 1.21 +#+begin_src clojure :results silent 1.22 +(defn hxc-thunk 1.23 + "Creates a thunk (nullary fn) that grabs data in a certain region of rom and 1.24 +splits it into a collection by 0x50. If rom is not supplied, uses the 1.25 + original rom data." 1.26 + [start length] 1.27 + (fn self 1.28 + ([rom] 1.29 + (take-nth 2 1.30 + (partition-by #(= % 0x50) 1.31 + (take length 1.32 + (drop start rom))))) 1.33 + ([] 1.34 + (self com.aurellem.gb.gb-driver/original-rom)))) 1.35 + 1.36 +(def hxc-thunk-words 1.37 + "Same as hxc-thunk, except it interprets the rom data as characters, 1.38 + returning a collection of strings." 1.39 + (comp 1.40 + (partial comp (partial map character-codes->str)) 1.41 + hxc-thunk)) 1.42 + 1.43 +#+end_src 1.44 + 1.45 + 1.46 +* Pok\eacute{}mon I 1.47 +** Names of each species 1.48 +The names of the Pok\eacute{}mon species are stored in 1.49 +ROM@E8000. This name list is interesting, for a number of reasons: 1.50 +- The names are stored in [[ ][internal order]] rather than in the familiar 1.51 + Pok\eacute{}dex order. This seemingly random order probably represents the order in which the authors created or 1.52 + programmed in the Pok\eacute{}mon; it's used throughout the game. 1.53 +- There is enough space allocated for 190 Pok\eacute{}mon. As I 1.54 + understand it, there were originally going to be 190 Pok\eacute{}mon 1.55 + in Generation I, but the creators decided to defer some to 1.56 + Generation II. This explains why many Gen I and Gen II Pok\eacute{}mon 1.57 + have the same aesthetic feel. 1.58 +- The list is pockmarked with random gaps, due to the strange internal 1.59 + ordering 1.60 + and the 39 unused spaces [fn::190 allocated spaces minus 151 true Pok\eacute{}mon]. These missing spaces are filled with the 1.61 + placeholder name =MISSINGNO.= (\ldquo{}Missing number\rdquo{}). 1.62 + 1.63 +Each name is exactly ten letters long; whenever a name would be too short, the extra 1.64 +space is padded with the character 0x50. 1.65 + 1.66 +*** See the data 1.67 + 1.68 +Here you can see the raw data in three stages: in the first stage, we 1.69 +just grab the first few bytes starting from position 0xE8000. In the 1.70 +second stage, we partition it into ten-letter chunks to show you 1.71 +where the names begin and end. In the final stage, we convert each 1.72 +byte into the letter it represents using the =character-codes->str= 1.73 +function. (0x50 is rendered as the symbol \ldquo{} =#= \rdquo{} for 1.74 +ease of reading). 1.75 + 1.76 +#+begin_src clojure :exports both :cache no :results output 1.77 +(ns com.aurellem.gb.hxc 1.78 + (:use (com.aurellem.gb assembly characters gb-driver util mem-util 1.79 + constants)) 1.80 + (:import [com.aurellem.gb.gb_driver SaveState])) 1.81 + 1.82 +(println (take 100 (drop 0xE8000 (rom)))) 1.83 + 1.84 +(println (partition 10 (take 100 (drop 0xE8000 (rom))))) 1.85 + 1.86 +(println (character-codes->str (take 100 (drop 0xE8000 (rom))))) 1.87 + 1.88 + 1.89 +#+end_src 1.90 + 1.91 +#+results: 1.92 +: (145 135 152 131 142 141 80 80 80 80 138 128 141 134 128 146 138 135 128 141 141 136 131 142 145 128 141 239 80 80 130 139 132 133 128 136 145 152 80 80 146 143 132 128 145 142 150 80 80 80 149 142 139 147 142 145 129 80 80 80 141 136 131 142 138 136 141 134 80 80 146 139 142 150 129 145 142 80 80 80 136 149 152 146 128 148 145 80 80 80 132 151 132 134 134 148 147 142 145 80) 1.93 +: ((145 135 152 131 142 141 80 80 80 80) (138 128 141 134 128 146 138 135 128 141) (141 136 131 142 145 128 141 239 80 80) (130 139 132 133 128 136 145 152 80 80) (146 143 132 128 145 142 150 80 80 80) (149 142 139 147 142 145 129 80 80 80) (141 136 131 142 138 136 141 134 80 80) (146 139 142 150 129 145 142 80 80 80) (136 149 152 146 128 148 145 80 80 80) (132 151 132 134 134 148 147 142 145 80)) 1.94 +: RHYDON####KANGASKHANNIDORAN♂##CLEFAIRY##SPEAROW###VOLTORB###NIDOKING##SLOWBRO###IVYSAUR###EXEGGUTOR# 1.95 + 1.96 + 1.97 +*** Automatically grab the data. 1.98 + 1.99 + #+name: pokenames 1.100 + #+begin_src clojure 1.101 + 1.102 +(defn hxc-pokenames-raw 1.103 + "The hardcoded names of the 190 species in memory. List begins at 1.104 +ROM@E8000. Although names in memory are padded with 0x50 to be 10 characters 1.105 + long, these names are stripped of padding. See also, hxc-pokedex-names" 1.106 + ([] 1.107 + (hxc-pokenames-raw com.aurellem.gb.gb-driver/original-rom)) 1.108 + ([rom] 1.109 + (let [count-species 190 1.110 + name-length 10] 1.111 + (map character-codes->str 1.112 + (partition name-length 1.113 + (map #(if (= 0x50 %) 0x00 %) 1.114 + (take (* count-species name-length) 1.115 + (drop 0xE8000 1.116 + rom)))))))) 1.117 +(def hxc-pokenames 1.118 + (comp 1.119 + (partial map format-name) 1.120 + hxc-pokenames-raw)) 1.121 + 1.122 + 1.123 + 1.124 + 1.125 +(defn hxc-pokedex-names 1.126 + "The names of the pokemon in hardcoded pokedex order. List begins at 1.127 +ROM@410B1. See also, hxc-pokenames." 1.128 + ([] (hxc-pokedex-names 1.129 + com.aurellem.gb.gb-driver/original-rom)) 1.130 + ([rom] 1.131 + (let [names (hxc-pokenames rom)] 1.132 + (#(mapv % 1.133 + ((comp range count keys) %)) 1.134 + (zipmap 1.135 + (take (count names) 1.136 + (drop 0x410b1 rom)) 1.137 + 1.138 + names))))) 1.139 + 1.140 + #+end_src 1.141 + 1.142 + 1.143 + 1.144 +** Generic species information 1.145 + 1.146 +#+name: pokebase 1.147 +#+begin_src clojure 1.148 +(defn hxc-pokemon-base 1.149 + ([] (hxc-pokemon-base com.aurellem.gb.gb-driver/original-rom)) 1.150 + ([rom] 1.151 + (let [entry-size 28 1.152 + pkmn-count (count (hxc-pokedex-text rom)) 1.153 + pokemon (rest (hxc-pokedex-names)) 1.154 + types (apply assoc {} 1.155 + (interleave 1.156 + (range) 1.157 + pkmn-types)) ;;!! softcoded 1.158 + moves (apply assoc {} 1.159 + (interleave 1.160 + (range) 1.161 + (map format-name 1.162 + (hxc-move-names rom)))) 1.163 + machines (hxc-machines) 1.164 + ] 1.165 + (zipmap 1.166 + pokemon 1.167 + (map 1.168 + (fn [[n 1.169 + rating-hp 1.170 + rating-atk 1.171 + rating-def 1.172 + rating-speed 1.173 + rating-special 1.174 + type-1 1.175 + type-2 1.176 + rarity 1.177 + rating-xp 1.178 + pic-dimensions ;; tile_width|tile_height (8px/tile) 1.179 + ptr-pic-obverse-1 1.180 + ptr-pic-obverse-2 1.181 + ptr-pic-reverse-1 1.182 + ptr-pic-reverse-2 1.183 + move-1 1.184 + move-2 1.185 + move-3 1.186 + move-4 1.187 + growth-rate 1.188 + & 1.189 + TMs|HMs]] 1.190 + (let 1.191 + [base-moves 1.192 + (mapv moves 1.193 + ((comp 1.194 + ;; since the game uses zero as a delimiter, 1.195 + ;; it must also increment all move indices by 1. 1.196 + ;; heren we decrement to correct this. 1.197 + (partial map dec) 1.198 + (partial take-while (comp not zero?))) 1.199 + [move-1 move-2 move-3 move-4])) 1.200 + 1.201 + types 1.202 + (set (list (types type-1) 1.203 + (types type-2))) 1.204 + TMs|HMs 1.205 + (map 1.206 + (comp 1.207 + (partial map first) 1.208 + (partial remove (comp zero? second))) 1.209 + (split-at 1.210 + 50 1.211 + (map vector 1.212 + (rest(range)) 1.213 + (reduce concat 1.214 + (map 1.215 + #(take 8 1.216 + (concat (bit-list %) 1.217 + (repeat 0))) 1.218 + 1.219 + TMs|HMs))))) 1.220 + 1.221 + TMs (vec (first TMs|HMs)) 1.222 + HMs (take 5 (map (partial + -50) (vec (second TMs|HMs)))) 1.223 + 1.224 + 1.225 + ] 1.226 + 1.227 + 1.228 + {:dex# n 1.229 + :base-moves base-moves 1.230 + :types types 1.231 + :TMs TMs 1.232 + :HMs HMs 1.233 + :base-hp rating-hp 1.234 + :base-atk rating-atk 1.235 + :base-def rating-def 1.236 + :base-speed rating-speed 1.237 + :base-special rating-special 1.238 + :o0 pic-dimensions 1.239 + :o1 ptr-pic-obverse-1 1.240 + :o2 ptr-pic-obverse-2 1.241 + })) 1.242 + 1.243 + (partition entry-size 1.244 + (take (* entry-size pkmn-count) 1.245 + (drop 0x383DE 1.246 + rom)))))))) 1.247 + 1.248 +#+end_src 1.249 + 1.250 + 1.251 +** Pok\eacute{}mon evolutions 1.252 +#+name: evolution-header 1.253 +#+begin_src clojure 1.254 +(defn format-evo 1.255 + "Parse a sequence of evolution data, returning a map. First is the 1.256 +method: 0 = end-evolution-data. 1 = level-up, 2 = item, 3 = trade. Next is an item id, if the 1.257 + method of evolution is by item (only stones will actually make pokemon 1.258 + evolve, for some auxillary reason.) Finally, the minimum level for 1.259 + evolution to occur (level 1 means no limit, which is used for trade 1.260 + and item evolutions), followed by the internal id of the pokemon 1.261 + into which to evolve. Hence, level up and trade evolutions are 1.262 + described with 3 1.263 + bytes; item evolutions with four." 1.264 + [coll] 1.265 + (let [method (first coll)] 1.266 + (cond (empty? coll) [] 1.267 + (= 0 method) [] ;; just in case 1.268 + (= 1 method) ;; level-up evolution 1.269 + (conj (format-evo (drop 3 coll)) 1.270 + {:method :level-up 1.271 + :min-level (nth coll 1) 1.272 + :into (dec (nth coll 2))}) 1.273 + 1.274 + (= 2 method) ;; item evolution 1.275 + (conj (format-evo (drop 4 coll)) 1.276 + {:method :item 1.277 + :item (dec (nth coll 1)) 1.278 + :min-level (nth coll 2) 1.279 + :into (dec (nth coll 3))}) 1.280 + 1.281 + (= 3 method) ;; trade evolution 1.282 + (conj (format-evo (drop 3 coll)) 1.283 + {:method :trade 1.284 + :min-level (nth coll 1) ;; always 1 for trade. 1.285 + :into (dec (nth coll 2))})))) 1.286 + 1.287 + 1.288 +(defn hxc-ptrs-evolve 1.289 + "A hardcoded collection of 190 pointers to alternating evolution/learnset data, 1.290 +in internal order." 1.291 + ([] 1.292 + (hxc-ptrs-evolve com.aurellem.gb.gb-driver/original-rom)) 1.293 + ([rom] 1.294 + (let [ 1.295 + pkmn-count (count (hxc-pokenames-raw)) ;; 190 1.296 + ptrs 1.297 + (map (fn [[a b]] (low-high a b)) 1.298 + (partition 2 1.299 + (take (* 2 pkmn-count) 1.300 + (drop 0x3b1e5 rom))))] 1.301 + (map (partial + 0x34000) ptrs) 1.302 + 1.303 + ))) 1.304 +#+end_src 1.305 + 1.306 +#+name:evolution 1.307 +#+begin_src clojure 1.308 + 1.309 +(defn hxc-evolution 1.310 + "Hardcoded evolution data in memory. The data exists at ROM@34000, 1.311 + sorted by internal order. Pointers to the data exist at ROM@3B1E5; see also, hxc-ptrs-evolve." 1.312 + ([] (hxc-evolution com.aurellem.gb.gb-driver/original-rom)) 1.313 + ([rom] 1.314 + (apply assoc {} 1.315 + (interleave 1.316 + (hxc-pokenames rom) 1.317 + (map 1.318 + (comp 1.319 + format-evo 1.320 + (partial take-while (comp not zero?)) 1.321 + #(drop % rom)) 1.322 + (hxc-ptrs-evolve rom) 1.323 + ))))) 1.324 + 1.325 +(defn hxc-evolution-pretty 1.326 + "Like hxc-evolution, except it uses the names of items and pokemon 1.327 +--- grabbed from ROM --- rather than their numerical identifiers." 1.328 + ([] (hxc-evolution-pretty com.aurellem.gb.gb-driver/original-rom)) 1.329 + ([rom] 1.330 + (let 1.331 + [poke-names (vec (hxc-pokenames rom)) 1.332 + item-names (vec (hxc-items rom)) 1.333 + use-names 1.334 + (fn [m] 1.335 + (loop [ks (keys m) new-map m] 1.336 + (let [k (first ks)] 1.337 + (cond (nil? ks) new-map 1.338 + (= k :into) 1.339 + (recur 1.340 + (next ks) 1.341 + (assoc new-map 1.342 + :into 1.343 + (poke-names 1.344 + (:into 1.345 + new-map)))) 1.346 + (= k :item) 1.347 + (recur 1.348 + (next ks) 1.349 + (assoc new-map 1.350 + :item 1.351 + (item-names 1.352 + (:item new-map)))) 1.353 + :else 1.354 + (recur 1.355 + (next ks) 1.356 + new-map) 1.357 + ))))] 1.358 + 1.359 + (into {} 1.360 + (map (fn [[pkmn evo-coll]] 1.361 + [pkmn (map use-names evo-coll)]) 1.362 + (hxc-evolution rom)))))) 1.363 + 1.364 + 1.365 +#+end_src 1.366 + 1.367 + 1.368 +** Level-up moves (learnsets) 1.369 +#+name: learnsets 1.370 +#+begin_src clojure 1.371 + 1.372 + 1.373 +(defn hxc-learnsets 1.374 + "Hardcoded map associating pokemon names to lists of pairs [lvl 1.375 + move] of abilities they learn as they level up. The data 1.376 +exists at ROM@34000, sorted by internal order. Pointers to the data 1.377 + exist at ROM@3B1E5; see also, hxc-ptrs-evolve" 1.378 + ([] (hxc-learnsets com.aurellem.gb.gb-driver/original-rom)) 1.379 + ([rom] 1.380 + (apply assoc 1.381 + {} 1.382 + (interleave 1.383 + (hxc-pokenames rom) 1.384 + (map (comp 1.385 + (partial map 1.386 + (fn [[lvl mv]] [lvl (dec mv)])) 1.387 + (partial partition 2) 1.388 + ;; keep the learnset data 1.389 + (partial take-while (comp not zero?)) 1.390 + ;; skip the evolution data 1.391 + rest 1.392 + (partial drop-while (comp not zero?))) 1.393 + (map #(drop % rom) 1.394 + (hxc-ptrs-evolve rom))))))) 1.395 + 1.396 +(defn hxc-learnsets-pretty 1.397 + "Live hxc-learnsets except it reports the name of each move --- as 1.398 +it appears in rom --- rather than the move index." 1.399 + ([] (hxc-learnsets-pretty com.aurellem.gb.gb-driver/original-rom)) 1.400 + ([rom] 1.401 + (let [moves (vec(map format-name (hxc-move-names)))] 1.402 + (into {} 1.403 + (map (fn [[pkmn learnset]] 1.404 + [pkmn (map (fn [[lvl mv]] [lvl (moves mv)]) 1.405 + learnset)]) 1.406 + (hxc-learnsets rom)))))) 1.407 + 1.408 + 1.409 + 1.410 +#+end_src 1.411 + 1.412 + 1.413 + 1.414 +* Pok\eacute{}mon II : the Pok\eacute{}dex 1.415 +** Species vital stats 1.416 +#+name: dex-stats 1.417 +#+begin_src clojure 1.418 +(defn hxc-pokedex-stats 1.419 + "The hardcoded pokedex stats (species height weight) in memory. List 1.420 +begins at ROM@40687" 1.421 + ([] (hxc-pokedex-stats com.aurellem.gb.gb-driver/original-rom)) 1.422 + ([rom] 1.423 + (let [pokedex-names (zipmap (range) (hxc-pokedex-names rom)) 1.424 + pkmn-count (count pokedex-names) 1.425 + ] 1.426 + ((fn capture-stats 1.427 + [n stats data] 1.428 + (if (zero? n) stats 1.429 + (let [[species 1.430 + [_ 1.431 + height-ft 1.432 + height-in 1.433 + weight-1 1.434 + weight-2 1.435 + _ 1.436 + dex-ptr-1 1.437 + dex-ptr-2 1.438 + dex-bank 1.439 + _ 1.440 + & data]] 1.441 + (split-with (partial not= 0x50) data)] 1.442 + (recur (dec n) 1.443 + (assoc stats 1.444 + (pokedex-names (- pkmn-count (dec n))) 1.445 + {:species 1.446 + (format-name (character-codes->str species)) 1.447 + :height-ft 1.448 + height-ft 1.449 + :height-in 1.450 + height-in 1.451 + :weight 1.452 + (/ (low-high weight-1 weight-2) 10.) 1.453 + 1.454 + ;; :text 1.455 + ;; (character-codes->str 1.456 + ;; (take-while 1.457 + ;; (partial not= 0x50) 1.458 + ;; (drop 1.459 + ;; (+ 0xB8000 1.460 + ;; -0x4000 1.461 + ;; (low-high dex-ptr-1 dex-ptr-2)) 1.462 + ;; rom))) 1.463 + }) 1.464 + 1.465 + data) 1.466 + 1.467 + 1.468 + ))) 1.469 + 1.470 + pkmn-count 1.471 + {} 1.472 + (drop 0x40687 rom))) )) 1.473 +#+end_src 1.474 + 1.475 +** Species synopses 1.476 + 1.477 +#+name: dex-text 1.478 +#+begin_src clojure 1.479 +(def hxc-pokedex-text-raw 1.480 + "The hardcoded pokedex entries in memory. List begins at 1.481 +ROM@B8000, shortly before move names." 1.482 + (hxc-thunk-words 0xB8000 14754)) 1.483 + 1.484 + 1.485 + 1.486 + 1.487 +(defn hxc-pokedex-text 1.488 + "The hardcoded pokedex entries in memory, presented as an 1.489 +associative hash map. List begins at ROM@B8000." 1.490 + ([] (hxc-pokedex-text com.aurellem.gb.gb-driver/original-rom)) 1.491 + ([rom] 1.492 + (zipmap 1.493 + (hxc-pokedex-names rom) 1.494 + (cons nil ;; for missingno. 1.495 + (hxc-pokedex-text-raw rom))))) 1.496 +#+end_src 1.497 + 1.498 + 1.499 +** Pok\eacute{}mon cries 1.500 +#+name: pokecry 1.501 +#+begin_src clojure 1.502 +(defn hxc-cry 1.503 + "The pokemon cry data in internal order. List begins at ROM@39462" 1.504 + ([](hxc-cry com.aurellem.gb.gb-driver/original-rom)) 1.505 + ([rom] 1.506 + (zipmap 1.507 + (hxc-pokenames rom) 1.508 + (map 1.509 + (fn [[cry-id pitch length]] 1.510 + {:cry-id cry-id 1.511 + :pitch pitch 1.512 + :length length} 1.513 + ) 1.514 + (partition 3 1.515 + (drop 0x39462 rom)))))) 1.516 + 1.517 +(defn hxc-cry-groups 1.518 + ([] (hxc-cry-groups com.aurellem.gb.gb-driver/original-rom)) 1.519 + ([rom] 1.520 + (map #(mapv first 1.521 + (filter 1.522 + (fn [[k v]] 1.523 + (= % (:cry-id v))) 1.524 + (hxc-cry))) 1.525 + ((comp 1.526 + range 1.527 + count 1.528 + set 1.529 + (partial map :cry-id) 1.530 + vals 1.531 + hxc-cry) 1.532 + rom)))) 1.533 + 1.534 + 1.535 +(defn cry-conversion! 1.536 + "Convert Porygon's cry in ROM to be the cry of the given pokemon." 1.537 + [pkmn] 1.538 + (write-rom! 1.539 + (rewrite-memory 1.540 + (vec(rom)) 1.541 + 0x3965D 1.542 + (map second 1.543 + ((hxc-cry) pkmn))))) 1.544 + 1.545 +#+end_src 1.546 + 1.547 +** COMMENT Names of permanent stats 1.548 +0DD4D-DD72 1.549 + 1.550 +* Items 1.551 +** Item names 1.552 +#+name: item-names 1.553 +#+begin_src clojure 1.554 + 1.555 +(def hxc-items-raw 1.556 + "The hardcoded names of the items in memory. List begins at 1.557 +ROM@045B7" 1.558 + (hxc-thunk-words 0x45B7 870)) 1.559 + 1.560 +(def hxc-items 1.561 + "The hardcoded names of the items in memory, presented as 1.562 + keywords. List begins at ROM@045B7. See also, hxc-items-raw." 1.563 + (comp (partial map format-name) hxc-items-raw)) 1.564 +#+end_src 1.565 + 1.566 +** Item prices 1.567 +#+name: item-prices 1.568 +#+begin_src clojure 1.569 +(defn hxc-item-prices 1.570 + "The hardcoded list of item prices in memory. List begins at ROM@4495" 1.571 + ([] (hxc-item-prices com.aurellem.gb.gb-driver/original-rom)) 1.572 + ([rom] 1.573 + (let [items (hxc-items rom) 1.574 + price-size 3] 1.575 + (zipmap items 1.576 + (map (comp 1.577 + ;; zero-cost items are "priceless" 1.578 + #(if (zero? %) :priceless %) 1.579 + decode-bcd butlast) 1.580 + (partition price-size 1.581 + (take (* price-size (count items)) 1.582 + (drop 0x4495 rom)))))))) 1.583 +#+end_src 1.584 +** Vendor inventories 1.585 + 1.586 +#+name: item-vendors 1.587 +#+begin_src clojure 1.588 +(defn hxc-shops 1.589 + ([] (hxc-shops com.aurellem.gb.gb-driver/original-rom)) 1.590 + ([rom] 1.591 + (let [items (zipmap (range) (hxc-items rom)) 1.592 + 1.593 + ;; temporarily softcode the TM items 1.594 + items (into 1.595 + items 1.596 + (map (juxt identity 1.597 + (comp keyword 1.598 + (partial str "tm-") 1.599 + (partial + 1 -200) 1.600 + )) 1.601 + (take 200 (drop 200 (range))))) 1.602 + 1.603 + ] 1.604 + 1.605 + ((fn parse-shop [coll [num-items & items-etc]] 1.606 + (let [inventory (take-while 1.607 + (partial not= 0xFF) 1.608 + items-etc) 1.609 + [separator & items-etc] (drop num-items (rest items-etc))] 1.610 + (if (= separator 0x50) 1.611 + (map (partial mapv (comp items dec)) (conj coll inventory)) 1.612 + (recur (conj coll inventory) items-etc) 1.613 + ) 1.614 + )) 1.615 + 1.616 + '() 1.617 + (drop 0x233C rom)) 1.618 + 1.619 + 1.620 + ))) 1.621 +#+end_src 1.622 + 1.623 +#+results: item-vendors 1.624 +: #'com.aurellem.gb.hxc/hxc-shops 1.625 + 1.626 + 1.627 + 1.628 +* Types 1.629 +** Names of types 1.630 +#+name: type-names 1.631 +#+begin_src clojure 1.632 +(def hxc-types 1.633 + "The hardcoded type names in memory. List begins at ROM@27D99, 1.634 + shortly before hxc-titles." 1.635 + (hxc-thunk-words 0x27D99 102)) 1.636 + 1.637 +#+end_src 1.638 + 1.639 +** Type effectiveness 1.640 +#+name type-advantage 1.641 +#+begin_src clojure 1.642 +(defn hxc-advantage 1.643 + ;; in-game multipliers are stored as 10x their effective value 1.644 + ;; to allow for fractional multipliers like 1/2 1.645 + 1.646 + "The hardcoded type advantages in memory, returned as tuples of 1.647 + atk-type def-type multiplier. By default (i.e. if not listed here), 1.648 +the multiplier is 1. List begins at 0x3E62D." 1.649 + ([] (hxc-advantage com.aurellem.gb.gb-driver/original-rom)) 1.650 + ([rom] 1.651 + (map 1.652 + (fn [[atk def mult]] [(get pkmn-types atk (hex atk)) 1.653 + (get pkmn-types def (hex def)) 1.654 + (/ mult 10)]) 1.655 + (partition 3 1.656 + (take-while (partial not= 0xFF) 1.657 + (drop 0x3E62D rom)))))) 1.658 +#+end_src 1.659 + 1.660 + 1.661 + 1.662 +* Moves 1.663 +** Names of moves 1.664 +#+name: move-names 1.665 +#+begin_src clojure 1.666 +(def hxc-move-names 1.667 + "The hardcoded move names in memory. List begins at ROM@BC000" 1.668 + (hxc-thunk-words 0xBC000 1551)) 1.669 +#+end_src 1.670 + 1.671 +** Properties of moves 1.672 + 1.673 +#+name: move-data 1.674 +#+begin_src clojure 1.675 +(defn hxc-move-data 1.676 + "The hardcoded (basic (move effects)) in memory. List begins at 1.677 +0x38000. Returns a map of {:name :power :accuracy :pp :fx-id 1.678 + :fx-txt}. The move descriptions are handwritten, not hardcoded." 1.679 + ([] 1.680 + (hxc-move-data com.aurellem.gb.gb-driver/original-rom)) 1.681 + ([rom] 1.682 + (let [names (vec (hxc-move-names rom)) 1.683 + move-count (count names) 1.684 + move-size 6 1.685 + types pkmn-types ;;; !! hardcoded types 1.686 + ] 1.687 + (zipmap (map format-name names) 1.688 + (map 1.689 + (fn [[idx effect power type-id accuracy pp]] 1.690 + {:name (names (dec idx)) 1.691 + :power power 1.692 + :accuracy accuracy 1.693 + :pp pp 1.694 + :type (types type-id) 1.695 + :fx-id effect 1.696 + :fx-txt (get move-effects effect) 1.697 + } 1.698 + ) 1.699 + 1.700 + (partition move-size 1.701 + (take (* move-size move-count) 1.702 + (drop 0x38000 rom)))))))) 1.703 + 1.704 + 1.705 + 1.706 +(defn hxc-move-data* 1.707 + "Like hxc-move-data, but reports numbers as hexadecimal symbols instead." 1.708 + ([] 1.709 + (hxc-move-data* com.aurellem.gb.gb-driver/original-rom)) 1.710 + ([rom] 1.711 + (let [names (vec (hxc-move-names rom)) 1.712 + move-count (count names) 1.713 + move-size 6 1.714 + format-name (fn [s] 1.715 + (keyword (.toLowerCase 1.716 + (apply str 1.717 + (map #(if (= % \space) "-" %) s))))) 1.718 + ] 1.719 + (zipmap (map format-name names) 1.720 + (map 1.721 + (fn [[idx effect power type accuracy pp]] 1.722 + {:name (names (dec idx)) 1.723 + :power power 1.724 + :accuracy (hex accuracy) 1.725 + :pp pp 1.726 + :fx-id (hex effect) 1.727 + :fx-txt (get move-effects effect) 1.728 + } 1.729 + ) 1.730 + 1.731 + (partition move-size 1.732 + (take (* move-size move-count) 1.733 + (drop 0x38000 rom)))))))) 1.734 + 1.735 +#+end_src 1.736 + 1.737 +** TM and HM moves 1.738 + 1.739 +#+name: machines 1.740 +#+begin_src clojure 1.741 +(defn hxc-machines 1.742 + "The hardcoded moves taught by TMs and HMs. List begins at ROM@1232D." 1.743 + ([] (hxc-machines 1.744 + com.aurellem.gb.gb-driver/original-rom)) 1.745 + ([rom] 1.746 + (let [moves (hxc-move-names rom)] 1.747 + (zipmap 1.748 + (range) 1.749 + (take-while 1.750 + (comp not nil?) 1.751 + (map (comp 1.752 + format-name 1.753 + (zipmap 1.754 + (range) 1.755 + moves) 1.756 + dec) 1.757 + (take 100 1.758 + (drop 0x1232D rom)))))))) 1.759 + 1.760 +#+end_src 1.761 + 1.762 + 1.763 + 1.764 + 1.765 + 1.766 +** COMMENT Status ailments 1.767 + 1.768 +* Places 1.769 +** Names of places 1.770 + 1.771 +#+name: places 1.772 +#+begin_src clojure 1.773 +(def hxc-places 1.774 + "The hardcoded place names in memory. List begins at 1.775 +ROM@71500. [Cinnabar] Mansion seems to be dynamically calculated." 1.776 + (hxc-thunk-words 0x71500 560)) 1.777 + 1.778 +#+end_src 1.779 + 1.780 +** Wild Pok\eacute{}mon demographics 1.781 +#+name: wilds 1.782 +#+begin_src clojure 1.783 + 1.784 + 1.785 + 1.786 +(defn hxc-ptrs-wild 1.787 + "A list of the hardcoded wild encounter data in memory. Pointers 1.788 + begin at ROM@0CB95; data begins at ROM@0x04D89" 1.789 + ([] (hxc-ptrs-wild com.aurellem.gb.gb-driver/original-rom)) 1.790 + ([rom] 1.791 + (let [ptrs 1.792 + (map (fn [[a b]] (+ a (* 0x100 b))) 1.793 + (take-while (partial not= (list 0xFF 0xFF)) 1.794 + (partition 2 (drop 0xCB95 rom))))] 1.795 + ptrs))) 1.796 + 1.797 + 1.798 + 1.799 +(defn hxc-wilds 1.800 + "A list of the hardcoded wild encounter data in memory. Pointers 1.801 + begin at ROM@0CB95; data begins at ROM@0x04D89" 1.802 + ([] (hxc-wilds com.aurellem.gb.gb-driver/original-rom)) 1.803 + ([rom] 1.804 + (let [pokenames (zipmap (range) (hxc-pokenames rom))] 1.805 + (map 1.806 + (partial map (fn [[a b]] {:species (pokenames (dec b)) :level 1.807 + a})) 1.808 + (partition 10 1.809 + 1.810 + (take-while (comp (partial not= 1) 1.811 + first) 1.812 + (partition 2 1.813 + (drop 0xCD8C rom)) 1.814 + 1.815 + )))))) 1.816 + 1.817 +#+end_src 1.818 + 1.819 + 1.820 + 1.821 + 1.822 + 1.823 +* Appendices 1.824 + 1.825 + 1.826 + 1.827 ** Mapping the ROM 1.828 1.829 | ROM address (hex) | Description | Format | Example | 1.830 @@ -56,110 +876,6 @@ 1.831 1.832 1.833 1.834 - 1.835 -** COMMENT Getting linguistic data: names, words, etc. 1.836 - 1.837 -Some of the simplest data 1.838 - 1.839 - 1.840 -One of the simplest data structures in the Pok\eacute{} ROM is an 1.841 -unbroken list of strings that either (a) all have a specific length, 1.842 -or (b) are all separated by the same character. 1.843 - 1.844 -Because lots of good data has this format, we'll start by writing a 1.845 -template function to extract it: 1.846 - 1.847 -#+name: hxc-thunks 1.848 -#+begin_src clojure :results silent 1.849 -(defn hxc-thunk 1.850 - "Creates a thunk (nullary fn) that grabs data in a certain region of rom and 1.851 -splits it into a collection by 0x50. If rom is not supplied, uses the 1.852 - original rom data." 1.853 - [start length] 1.854 - (fn self 1.855 - ([rom] 1.856 - (take-nth 2 1.857 - (partition-by #(= % 0x50) 1.858 - (take length 1.859 - (drop start rom))))) 1.860 - ([] 1.861 - (self com.aurellem.gb.gb-driver/original-rom)))) 1.862 - 1.863 -(def hxc-thunk-words 1.864 - "Same as hxc-thunk, except it interprets the rom data as characters, 1.865 - returning a collection of strings." 1.866 - (comp 1.867 - (partial comp (partial map character-codes->str)) 1.868 - hxc-thunk)) 1.869 - 1.870 -#+end_src 1.871 - 1.872 -* Pok\eacute{}mon 1.873 -** Names of each species 1.874 -The names of the Pok\eacute{}mon species are stored in 1.875 -ROM@E8000. This name list is interesting, for a number of reasons: 1.876 -- The names are stored in [[ ][internal order]] rather than in the familiar 1.877 - Pok\eacute{}dex order. This seemingly random order probably represents the order in which the authors created or 1.878 - programmed in the Pok\eacute{}mon; it's used throughout the game. 1.879 -- There is enough space allocated for 190 Pok\eacute{}mon. As I 1.880 - understand it, there were originally going to be 190 Pok\eacute{}mon 1.881 - in Generation I, but the creators decided to defer some to 1.882 - Generation II. This explains why many Gen I and Gen II Pok\eacute{}mon 1.883 - have the same aesthetic feel. 1.884 -- The list is pockmarked with random gaps, due to the strange internal 1.885 - ordering 1.886 - and 39 unused spaces [fn::190 allocated spaces minus 151 true Pok\eacute{}mon]. These missing spaces are filled with the 1.887 - placeholder name, =MISSINGNO.= (\ldquo{}Missing number\rdquo{}). 1.888 - 1.889 -Each name is exactly ten letters long (Whenever a name is too short, the extra 1.890 -space is padded with the character 0x50). 1.891 - 1.892 - 1.893 - 1.894 -#+name: pokenames 1.895 -#+begin_src clojure 1.896 - 1.897 -(defn hxc-pokenames-raw 1.898 - "The hardcoded names of the 190 species in memory. List begins at 1.899 -ROM@E8000. Although names in memory are padded with 0x50 to be 10 characters 1.900 - long, these names are stripped of padding. See also, hxc-pokedex-names" 1.901 - ([] 1.902 - (hxc-pokenames-raw com.aurellem.gb.gb-driver/original-rom)) 1.903 - ([rom] 1.904 - (let [count-species 190 1.905 - name-length 10] 1.906 - (map character-codes->str 1.907 - (partition name-length 1.908 - (map #(if (= 0x50 %) 0x00 %) 1.909 - (take (* count-species name-length) 1.910 - (drop 0xE8000 1.911 - rom)))))))) 1.912 -(def hxc-pokenames 1.913 - (comp 1.914 - (partial map format-name) 1.915 - hxc-pokenames-raw)) 1.916 - 1.917 - 1.918 - 1.919 - 1.920 -(defn hxc-pokedex-names 1.921 - "The names of the pokemon in hardcoded pokedex order. List begins at 1.922 -ROM@410B1. See also, hxc-pokenames." 1.923 - ([] (hxc-pokedex-names 1.924 - com.aurellem.gb.gb-driver/original-rom)) 1.925 - ([rom] 1.926 - (let [names (hxc-pokenames rom)] 1.927 - (#(mapv % 1.928 - ((comp range count keys) %)) 1.929 - (zipmap 1.930 - (take (count names) 1.931 - (drop 0x410b1 rom)) 1.932 - 1.933 - names))))) 1.934 - 1.935 -#+end_src 1.936 - 1.937 -* Appendices 1.938 ** Internal Pok\eacute{}mon IDs 1.939 ** Type IDs 1.940 1.941 @@ -412,6 +1128,8 @@ 1.942 1.943 ** Alphabet code 1.944 1.945 +* Source 1.946 + 1.947 #+begin_src clojure :tangle ../clojure/com/aurellem/gb/hxc.clj 1.948 1.949 (ns com.aurellem.gb.hxc 1.950 @@ -419,9 +1137,6 @@ 1.951 constants species)) 1.952 (:import [com.aurellem.gb.gb_driver SaveState])) 1.953 1.954 - 1.955 - 1.956 - 1.957 ; ************* HANDWRITTEN CONSTANTS 1.958 1.959 <<type-ids>> 1.960 @@ -439,62 +1154,16 @@ 1.961 <<hxc-thunks>> 1.962 ;; -------------------------------------------------- 1.963 1.964 - 1.965 <<pokenames>> 1.966 +<<type-names>> 1.967 1.968 ;; http://hax.iimarck.us/topic/581/ 1.969 -(defn hxc-cry 1.970 - "The pokemon cry data in internal order. List begins at ROM@39462" 1.971 - ([](hxc-cry com.aurellem.gb.gb-driver/original-rom)) 1.972 - ([rom] 1.973 - (zipmap 1.974 - (hxc-pokenames rom) 1.975 - (map 1.976 - (fn [[cry-id pitch length]] 1.977 - {:cry-id cry-id 1.978 - :pitch pitch 1.979 - :length length} 1.980 - ) 1.981 - (partition 3 1.982 - (drop 0x39462 rom)))))) 1.983 +<<pokecry>> 1.984 1.985 -(defn hxc-cry-groups 1.986 - ([] (hxc-cry-groups com.aurellem.gb.gb-driver/original-rom)) 1.987 - ([rom] 1.988 - (map #(mapv first 1.989 - (filter 1.990 - (fn [[k v]] 1.991 - (= % (:cry-id v))) 1.992 - (hxc-cry))) 1.993 - ((comp 1.994 - range 1.995 - count 1.996 - set 1.997 - (partial map :cry-id) 1.998 - vals 1.999 - hxc-cry) 1.1000 - rom)))) 1.1001 1.1002 +<<item-names>> 1.1003 1.1004 -(defn cry-conversion! 1.1005 - "Convert Porygon's cry in ROM to be the cry of the given pokemon." 1.1006 - [pkmn] 1.1007 - (write-rom! 1.1008 - (rewrite-memory 1.1009 - (vec(rom)) 1.1010 - 0x3965D 1.1011 - (map second 1.1012 - ((hxc-cry) pkmn))))) 1.1013 1.1014 -(def hxc-items-raw 1.1015 - "The hardcoded names of the items in memory. List begins at 1.1016 -ROM@045B7" 1.1017 - (hxc-thunk-words 0x45B7 870)) 1.1018 - 1.1019 -(def hxc-types 1.1020 - "The hardcoded type names in memory. List begins at ROM@27D99, 1.1021 - shortly before hxc-titles." 1.1022 - (hxc-thunk-words 0x27D99 102)) 1.1023 1.1024 (def hxc-titles 1.1025 "The hardcoded names of the trainer titles in memory. List begins at 1.1026 @@ -502,98 +1171,16 @@ 1.1027 (hxc-thunk-words 0x27E77 196)) 1.1028 1.1029 1.1030 -(def hxc-pokedex-text-raw 1.1031 - "The hardcoded pokedex entries in memory. List begins at 1.1032 -ROM@B8000, shortly before move names." 1.1033 - (hxc-thunk-words 0xB8000 14754)) 1.1034 - 1.1035 - 1.1036 - 1.1037 -(def hxc-items 1.1038 - "The hardcoded names of the items in memory, presented as 1.1039 - keywords. List begins at ROM@045B7. See also, hxc-items-raw." 1.1040 - (comp (partial map format-name) hxc-items-raw)) 1.1041 - 1.1042 -(defn hxc-pokedex-text 1.1043 - "The hardcoded pokedex entries in memory, presented as an 1.1044 -associative hash map. List begins at ROM@B8000." 1.1045 - ([] (hxc-pokedex-text com.aurellem.gb.gb-driver/original-rom)) 1.1046 - ([rom] 1.1047 - (zipmap 1.1048 - (hxc-pokedex-names rom) 1.1049 - (cons nil ;; for missingno. 1.1050 - (hxc-pokedex-text-raw rom))))) 1.1051 +<<dex-text>> 1.1052 1.1053 ;; In red/blue, pokedex stats are in internal order. 1.1054 ;; In yellow, pokedex stats are in pokedex order. 1.1055 +<<dex-stats>> 1.1056 1.1057 -(defn hxc-pokedex-stats 1.1058 - "The hardcoded pokedex stats (species height weight) in memory. List 1.1059 -begins at ROM@40687" 1.1060 - ([] (hxc-pokedex-stats com.aurellem.gb.gb-driver/original-rom)) 1.1061 - ([rom] 1.1062 - (let [pokedex-names (zipmap (range) (hxc-pokedex-names rom)) 1.1063 - pkmn-count (count pokedex-names) 1.1064 - ] 1.1065 - ((fn capture-stats 1.1066 - [n stats data] 1.1067 - (if (zero? n) stats 1.1068 - (let [[species 1.1069 - [_ 1.1070 - height-ft 1.1071 - height-in 1.1072 - weight-1 1.1073 - weight-2 1.1074 - _ 1.1075 - dex-ptr-1 1.1076 - dex-ptr-2 1.1077 - dex-bank 1.1078 - _ 1.1079 - & data]] 1.1080 - (split-with (partial not= 0x50) data)] 1.1081 - (recur (dec n) 1.1082 - (assoc stats 1.1083 - (pokedex-names (- pkmn-count (dec n))) 1.1084 - {:species 1.1085 - (format-name (character-codes->str species)) 1.1086 - :height-ft 1.1087 - height-ft 1.1088 - :height-in 1.1089 - height-in 1.1090 - :weight 1.1091 - (/ (low-high weight-1 weight-2) 10.) 1.1092 - 1.1093 - ;; :text 1.1094 - ;; (character-codes->str 1.1095 - ;; (take-while 1.1096 - ;; (partial not= 0x50) 1.1097 - ;; (drop 1.1098 - ;; (+ 0xB8000 1.1099 - ;; -0x4000 1.1100 - ;; (low-high dex-ptr-1 dex-ptr-2)) 1.1101 - ;; rom))) 1.1102 - }) 1.1103 - 1.1104 - data) 1.1105 - 1.1106 - 1.1107 - ))) 1.1108 - 1.1109 - pkmn-count 1.1110 - {} 1.1111 - (drop 0x40687 rom))) )) 1.1112 1.1113 1.1114 1.1115 - 1.1116 - 1.1117 - 1.1118 - 1.1119 -(def hxc-places 1.1120 - "The hardcoded place names in memory. List begins at 1.1121 -ROM@71500. [Cinnabar] Mansion seems to be dynamically calculated." 1.1122 - (hxc-thunk-words 0x71500 560)) 1.1123 - 1.1124 +<<places>> 1.1125 1.1126 (defn hxc-dialog 1.1127 "The hardcoded dialogue in memory, including in-game alerts. Dialog 1.1128 @@ -608,90 +1195,10 @@ 1.1129 (hxc-dialog com.aurellem.gb.gb-driver/original-rom))) 1.1130 1.1131 1.1132 -(def hxc-move-names 1.1133 - "The hardcoded move names in memory. List begins at ROM@BC000" 1.1134 - (hxc-thunk-words 0xBC000 1551)) 1.1135 +<<move-names>> 1.1136 +<<move-data>> 1.1137 1.1138 - 1.1139 -(defn hxc-move-data 1.1140 - "The hardcoded (basic (move effects)) in memory. List begins at 1.1141 -0x38000. Returns a map of {:name :power :accuracy :pp :fx-id 1.1142 - :fx-txt}. The move descriptions are handwritten, not hardcoded." 1.1143 - ([] 1.1144 - (hxc-move-data com.aurellem.gb.gb-driver/original-rom)) 1.1145 - ([rom] 1.1146 - (let [names (vec (hxc-move-names rom)) 1.1147 - move-count (count names) 1.1148 - move-size 6 1.1149 - types pkmn-types ;;; !! hardcoded types 1.1150 - ] 1.1151 - (zipmap (map format-name names) 1.1152 - (map 1.1153 - (fn [[idx effect power type-id accuracy pp]] 1.1154 - {:name (names (dec idx)) 1.1155 - :power power 1.1156 - :accuracy accuracy 1.1157 - :pp pp 1.1158 - :type (types type-id) 1.1159 - :fx-id effect 1.1160 - :fx-txt (get move-effects effect) 1.1161 - } 1.1162 - ) 1.1163 - 1.1164 - (partition move-size 1.1165 - (take (* move-size move-count) 1.1166 - (drop 0x38000 rom)))))))) 1.1167 - 1.1168 - 1.1169 - 1.1170 -(defn hxc-move-data* 1.1171 - "Like hxc-move-data, but reports numbers as hexadecimal symbols instead." 1.1172 - ([] 1.1173 - (hxc-move-data* com.aurellem.gb.gb-driver/original-rom)) 1.1174 - ([rom] 1.1175 - (let [names (vec (hxc-move-names rom)) 1.1176 - move-count (count names) 1.1177 - move-size 6 1.1178 - format-name (fn [s] 1.1179 - (keyword (.toLowerCase 1.1180 - (apply str 1.1181 - (map #(if (= % \space) "-" %) s))))) 1.1182 - ] 1.1183 - (zipmap (map format-name names) 1.1184 - (map 1.1185 - (fn [[idx effect power type accuracy pp]] 1.1186 - {:name (names (dec idx)) 1.1187 - :power power 1.1188 - :accuracy (hex accuracy) 1.1189 - :pp pp 1.1190 - :fx-id (hex effect) 1.1191 - :fx-txt (get move-effects effect) 1.1192 - } 1.1193 - ) 1.1194 - 1.1195 - (partition move-size 1.1196 - (take (* move-size move-count) 1.1197 - (drop 0x38000 rom)))))))) 1.1198 - 1.1199 - 1.1200 -(defn hxc-machines 1.1201 - "The hardcoded moves taught by TMs and HMs. List begins at ROM@1232D." 1.1202 - ([] (hxc-machines 1.1203 - com.aurellem.gb.gb-driver/original-rom)) 1.1204 - ([rom] 1.1205 - (let [moves (hxc-move-names rom)] 1.1206 - (zipmap 1.1207 - (range) 1.1208 - (take-while 1.1209 - (comp not nil?) 1.1210 - (map (comp 1.1211 - format-name 1.1212 - (zipmap 1.1213 - (range) 1.1214 - moves) 1.1215 - dec) 1.1216 - (take 100 1.1217 - (drop 0x1232D rom)))))))) 1.1218 +<<machines>> 1.1219 1.1220 1.1221 1.1222 @@ -724,271 +1231,13 @@ 1.1223 1.1224 1.1225 1.1226 +<<type-advantage>> 1.1227 1.1228 -(defn hxc-advantage 1.1229 - ;; in-game multipliers are stored as 10x their effective value 1.1230 - ;; to allow for fractional multipliers like 1/2 1.1231 - 1.1232 - "The hardcoded type advantages in memory, returned as tuples of 1.1233 - atk-type def-type multiplier. By default (i.e. if not listed here), 1.1234 -the multiplier is 1. List begins at 0x3E62D." 1.1235 - ([] (hxc-advantage com.aurellem.gb.gb-driver/original-rom)) 1.1236 - ([rom] 1.1237 - (map 1.1238 - (fn [[atk def mult]] [(get pkmn-types atk (hex atk)) 1.1239 - (get pkmn-types def (hex def)) 1.1240 - (/ mult 10)]) 1.1241 - (partition 3 1.1242 - (take-while (partial not= 0xFF) 1.1243 - (drop 0x3E62D rom)))))) 1.1244 1.1245 1.1246 - 1.1247 -(defn format-evo 1.1248 - "Parse a sequence of evolution data, returning a map. First is the 1.1249 -method: 0 = end-evolution-data. 1 = level-up, 2 = item, 3 = trade. Next is an item id, if the 1.1250 - method of evolution is by item (only stones will actually make pokemon 1.1251 - evolve, for some auxillary reason.) Finally, the minimum level for 1.1252 - evolution to occur (level 1 means no limit, which is used for trade 1.1253 - and item evolutions), followed by the internal id of the pokemon 1.1254 - into which to evolve. Hence, level up and trade evolutions are 1.1255 - described with 3 1.1256 - bytes; item evolutions with four." 1.1257 - [coll] 1.1258 - (let [method (first coll)] 1.1259 - (cond (empty? coll) [] 1.1260 - (= 0 method) [] ;; just in case 1.1261 - (= 1 method) ;; level-up evolution 1.1262 - (conj (format-evo (drop 3 coll)) 1.1263 - {:method :level-up 1.1264 - :min-level (nth coll 1) 1.1265 - :into (dec (nth coll 2))}) 1.1266 - 1.1267 - (= 2 method) ;; item evolution 1.1268 - (conj (format-evo (drop 4 coll)) 1.1269 - {:method :item 1.1270 - :item (dec (nth coll 1)) 1.1271 - :min-level (nth coll 2) 1.1272 - :into (dec (nth coll 3))}) 1.1273 - 1.1274 - (= 3 method) ;; trade evolution 1.1275 - (conj (format-evo (drop 3 coll)) 1.1276 - {:method :trade 1.1277 - :min-level (nth coll 1) ;; always 1 for trade. 1.1278 - :into (dec (nth coll 2))})))) 1.1279 - 1.1280 - 1.1281 -(defn hxc-ptrs-evolve 1.1282 - "A hardcoded collection of 190 pointers to alternating evolution/learnset data, 1.1283 -in internal order." 1.1284 - ([] 1.1285 - (hxc-ptrs-evolve com.aurellem.gb.gb-driver/original-rom)) 1.1286 - ([rom] 1.1287 - (let [ 1.1288 - pkmn-count (count (hxc-pokenames-raw)) ;; 190 1.1289 - ptrs 1.1290 - (map (fn [[a b]] (low-high a b)) 1.1291 - (partition 2 1.1292 - (take (* 2 pkmn-count) 1.1293 - (drop 0x3b1e5 rom))))] 1.1294 - (map (partial + 0x34000) ptrs) 1.1295 - 1.1296 - ))) 1.1297 - 1.1298 - 1.1299 -(defn hxc-learnsets 1.1300 - "Hardcoded map associating pokemon names to lists of pairs [lvl 1.1301 - move] of abilities they learn as they level up. The data 1.1302 -exists at ROM@34000, sorted by internal order. Pointers to the data 1.1303 - exist at ROM@3B1E5; see also, hxc-ptrs-evolve" 1.1304 - ([] (hxc-learnsets com.aurellem.gb.gb-driver/original-rom)) 1.1305 - ([rom] 1.1306 - (apply assoc 1.1307 - {} 1.1308 - (interleave 1.1309 - (hxc-pokenames rom) 1.1310 - (map (comp 1.1311 - (partial map 1.1312 - (fn [[lvl mv]] [lvl (dec mv)])) 1.1313 - (partial partition 2) 1.1314 - ;; keep the learnset data 1.1315 - (partial take-while (comp not zero?)) 1.1316 - ;; skip the evolution data 1.1317 - rest 1.1318 - (partial drop-while (comp not zero?))) 1.1319 - (map #(drop % rom) 1.1320 - (hxc-ptrs-evolve rom))))))) 1.1321 - 1.1322 -(defn hxc-learnsets-pretty 1.1323 - "Live hxc-learnsets except it reports the name of each move --- as 1.1324 -it appears in rom --- rather than the move index." 1.1325 - ([] (hxc-learnsets-pretty com.aurellem.gb.gb-driver/original-rom)) 1.1326 - ([rom] 1.1327 - (let [moves (vec(map format-name (hxc-move-names)))] 1.1328 - (into {} 1.1329 - (map (fn [[pkmn learnset]] 1.1330 - [pkmn (map (fn [[lvl mv]] [lvl (moves mv)]) 1.1331 - learnset)]) 1.1332 - (hxc-learnsets rom)))))) 1.1333 - 1.1334 - 1.1335 - 1.1336 - 1.1337 -(defn hxc-evolution 1.1338 - "Hardcoded evolution data in memory. The data exists at ROM@34000, 1.1339 - sorted by internal order. Pointers to the data exist at ROM@3B1E5; see also, hxc-ptrs-evolve." 1.1340 - ([] (hxc-evolution com.aurellem.gb.gb-driver/original-rom)) 1.1341 - ([rom] 1.1342 - (apply assoc {} 1.1343 - (interleave 1.1344 - (hxc-pokenames rom) 1.1345 - (map 1.1346 - (comp 1.1347 - format-evo 1.1348 - (partial take-while (comp not zero?)) 1.1349 - #(drop % rom)) 1.1350 - (hxc-ptrs-evolve rom) 1.1351 - ))))) 1.1352 - 1.1353 -(defn hxc-evolution-pretty 1.1354 - "Like hxc-evolution, except it uses the names of items and pokemon 1.1355 ---- grabbed from ROM --- rather than their numerical identifiers." 1.1356 - ([] (hxc-evolution-pretty com.aurellem.gb.gb-driver/original-rom)) 1.1357 - ([rom] 1.1358 - (let 1.1359 - [poke-names (vec (hxc-pokenames rom)) 1.1360 - item-names (vec (hxc-items rom)) 1.1361 - use-names 1.1362 - (fn [m] 1.1363 - (loop [ks (keys m) new-map m] 1.1364 - (let [k (first ks)] 1.1365 - (cond (nil? ks) new-map 1.1366 - (= k :into) 1.1367 - (recur 1.1368 - (next ks) 1.1369 - (assoc new-map 1.1370 - :into 1.1371 - (poke-names 1.1372 - (:into 1.1373 - new-map)))) 1.1374 - (= k :item) 1.1375 - (recur 1.1376 - (next ks) 1.1377 - (assoc new-map 1.1378 - :item 1.1379 - (item-names 1.1380 - (:item new-map)))) 1.1381 - :else 1.1382 - (recur 1.1383 - (next ks) 1.1384 - new-map) 1.1385 - ))))] 1.1386 - 1.1387 - (into {} 1.1388 - (map (fn [[pkmn evo-coll]] 1.1389 - [pkmn (map use-names evo-coll)]) 1.1390 - (hxc-evolution rom)))))) 1.1391 - 1.1392 - 1.1393 -(defn hxc-pokemon-base 1.1394 - ([] (hxc-pokemon-base com.aurellem.gb.gb-driver/original-rom)) 1.1395 - ([rom] 1.1396 - (let [entry-size 28 1.1397 - pkmn-count (count (hxc-pokedex-text rom)) 1.1398 - pokemon (rest (hxc-pokedex-names)) 1.1399 - types (apply assoc {} 1.1400 - (interleave 1.1401 - (range) 1.1402 - pkmn-types)) ;;!! softcoded 1.1403 - moves (apply assoc {} 1.1404 - (interleave 1.1405 - (range) 1.1406 - (map format-name 1.1407 - (hxc-move-names rom)))) 1.1408 - machines (hxc-machines) 1.1409 - ] 1.1410 - (zipmap 1.1411 - pokemon 1.1412 - (map 1.1413 - (fn [[n 1.1414 - rating-hp 1.1415 - rating-atk 1.1416 - rating-def 1.1417 - rating-speed 1.1418 - rating-special 1.1419 - type-1 1.1420 - type-2 1.1421 - rarity 1.1422 - rating-xp 1.1423 - pic-dimensions ;; tile_width|tile_height (8px/tile) 1.1424 - ptr-pic-obverse-1 1.1425 - ptr-pic-obverse-2 1.1426 - ptr-pic-reverse-1 1.1427 - ptr-pic-reverse-2 1.1428 - move-1 1.1429 - move-2 1.1430 - move-3 1.1431 - move-4 1.1432 - growth-rate 1.1433 - & 1.1434 - TMs|HMs]] 1.1435 - (let 1.1436 - [base-moves 1.1437 - (mapv moves 1.1438 - ((comp 1.1439 - ;; since the game uses zero as a delimiter, 1.1440 - ;; it must also increment all move indices by 1. 1.1441 - ;; heren we decrement to correct this. 1.1442 - (partial map dec) 1.1443 - (partial take-while (comp not zero?))) 1.1444 - [move-1 move-2 move-3 move-4])) 1.1445 - 1.1446 - types 1.1447 - (set (list (types type-1) 1.1448 - (types type-2))) 1.1449 - TMs|HMs 1.1450 - (map 1.1451 - (comp 1.1452 - (partial map first) 1.1453 - (partial remove (comp zero? second))) 1.1454 - (split-at 1.1455 - 50 1.1456 - (map vector 1.1457 - (rest(range)) 1.1458 - (reduce concat 1.1459 - (map 1.1460 - #(take 8 1.1461 - (concat (bit-list %) 1.1462 - (repeat 0))) 1.1463 - 1.1464 - TMs|HMs))))) 1.1465 - 1.1466 - TMs (vec (first TMs|HMs)) 1.1467 - HMs (take 5 (map (partial + -50) (vec (second TMs|HMs)))) 1.1468 - 1.1469 - 1.1470 - ] 1.1471 - 1.1472 - 1.1473 - {:dex# n 1.1474 - :base-moves base-moves 1.1475 - :types types 1.1476 - :TMs TMs 1.1477 - :HMs HMs 1.1478 - :base-hp rating-hp 1.1479 - :base-atk rating-atk 1.1480 - :base-def rating-def 1.1481 - :base-speed rating-speed 1.1482 - :base-special rating-special 1.1483 - :o0 pic-dimensions 1.1484 - :o1 ptr-pic-obverse-1 1.1485 - :o2 ptr-pic-obverse-2 1.1486 - })) 1.1487 - 1.1488 - (partition entry-size 1.1489 - (take (* entry-size pkmn-count) 1.1490 - (drop 0x383DE 1.1491 - rom)))))))) 1.1492 +<<evolution-header>> 1.1493 +<<learnsets>> 1.1494 +<<pokebase>> 1.1495 1.1496 1.1497 (defn hxc-intro-pkmn 1.1498 @@ -1012,101 +1261,11 @@ 1.1499 pokemon))]))) 1.1500 1.1501 1.1502 -(defn hxc-item-prices 1.1503 - "The hardcoded list of item prices in memory. List begins at ROM@4495" 1.1504 - ([] (hxc-item-prices com.aurellem.gb.gb-driver/original-rom)) 1.1505 - ([rom] 1.1506 - (let [items (hxc-items rom) 1.1507 - price-size 3] 1.1508 - (zipmap items 1.1509 - (map (comp 1.1510 - ;; zero-cost items are "priceless" 1.1511 - #(if (zero? %) :priceless %) 1.1512 - decode-bcd butlast) 1.1513 - (partition price-size 1.1514 - (take (* price-size (count items)) 1.1515 - (drop 0x4495 rom)))))))) 1.1516 +<<item-prices>> 1.1517 1.1518 -(defn hxc-shops 1.1519 - ([] (hxc-shops com.aurellem.gb.gb-driver/original-rom)) 1.1520 - ([rom] 1.1521 - (let [items (zipmap (range) (hxc-items rom)) 1.1522 +<<item-vendors>> 1.1523 1.1524 - ;; temporarily softcode the TM items 1.1525 - items (into 1.1526 - items 1.1527 - (map (juxt identity 1.1528 - (comp keyword 1.1529 - (partial str "tm-") 1.1530 - (partial + 1 -200) 1.1531 - )) 1.1532 - (take 200 (drop 200 (range))))) 1.1533 - 1.1534 - ] 1.1535 - 1.1536 - ((fn parse-shop [coll [num-items & items-etc]] 1.1537 - (let [inventory (take-while 1.1538 - (partial not= 0xFF) 1.1539 - items-etc) 1.1540 - [separator & items-etc] (drop num-items (rest items-etc))] 1.1541 - (if (= separator 0x50) 1.1542 - (map (partial mapv (comp items dec)) (conj coll inventory)) 1.1543 - (recur (conj coll inventory) items-etc) 1.1544 - ) 1.1545 - )) 1.1546 - 1.1547 - '() 1.1548 - (drop 0x233C rom)) 1.1549 - 1.1550 - 1.1551 - ))) 1.1552 - 1.1553 - 1.1554 - 1.1555 - 1.1556 - 1.1557 -(defn hxc-ptrs-wild 1.1558 - "A list of the hardcoded wild encounter data in memory. Pointers 1.1559 - begin at ROM@0CB95; data begins at ROM@0x04D89" 1.1560 - ([] (hxc-ptrs-wild com.aurellem.gb.gb-driver/original-rom)) 1.1561 - ([rom] 1.1562 - (let [ptrs 1.1563 - (map (fn [[a b]] (+ a (* 0x100 b))) 1.1564 - (take-while (partial not= (list 0xFF 0xFF)) 1.1565 - (partition 2 (drop 0xCB95 rom))))] 1.1566 - ptrs))) 1.1567 - 1.1568 - 1.1569 - 1.1570 -(defn hxc-wilds 1.1571 - "A list of the hardcoded wild encounter data in memory. Pointers 1.1572 - begin at ROM@0CB95; data begins at ROM@0x04D89" 1.1573 - ([] (hxc-wilds com.aurellem.gb.gb-driver/original-rom)) 1.1574 - ([rom] 1.1575 - (let [pokenames (zipmap (range) (hxc-pokenames rom))] 1.1576 - (map 1.1577 - (partial map (fn [[a b]] {:species (pokenames (dec b)) :level 1.1578 - a})) 1.1579 - (partition 10 1.1580 - 1.1581 - (take-while (comp (partial not= 1) 1.1582 - first) 1.1583 - (partition 2 1.1584 - (drop 0xCD8C rom)) 1.1585 - 1.1586 - )))))) 1.1587 - 1.1588 - 1.1589 - 1.1590 - 1.1591 - 1.1592 - 1.1593 - 1.1594 - 1.1595 - 1.1596 - 1.1597 - 1.1598 - 1.1599 +<<wilds>> 1.1600 1.1601 1.1602 ;; ********************** MANIPULATION FNS 1.1603 @@ -1202,3 +1361,6 @@ 1.1604 1.1605 #+end_src 1.1606 1.1607 +#+results: 1.1608 +: nil 1.1609 +