annotate org/rom.org @ 365:dc39dfcad61f

almost halfway there!
author Robert McIntyre <rlm@mit.edu>
date Mon, 09 Apr 2012 11:31:09 -0500
parents 37616a97beaa
children b477970d0b7a
rev   line source
ocsenave@311 1 #+title: Notes on Deconstructing Pokemon Yellow
ocsenave@311 2 #+author: Dylan Holmes
ocsenave@311 3 #+email: rlm@mit.edu
ocsenave@311 4 #+description:
ocsenave@312 5 #+keywords:
ocsenave@311 6 #+SETUPFILE: ../../aurellem/org/setup.org
ocsenave@311 7 #+INCLUDE: ../../aurellem/org/level-0.org
ocsenave@311 8 #+BABEL: :exports both :noweb yes :cache no :mkdirp yes
ocsenave@311 9
ocsenave@346 10 # about map headers http://datacrystal.romhacking.net/wiki/Pokemon_Red/Blue:Notes
ocsenave@346 11 # map headers Yellow http://www.pokecommunity.com/archive/index.php/t-235311.html
ocsenave@312 12 # pokedollar: U+20B1
ocsenave@347 13 * Introduction
ocsenave@347 14
ocsenave@348 15
ocsenave@348 16 ** COMMENT Getting linguistic data: names, words, etc.
ocsenave@348 17
ocsenave@348 18 Some of the simplest data
ocsenave@348 19
ocsenave@348 20
ocsenave@348 21 One of the simplest data structures in the Pok\eacute{} ROM is an
ocsenave@348 22 unbroken list of strings that either (a) all have a specific length,
ocsenave@348 23 or (b) are all separated by the same character.
ocsenave@348 24
ocsenave@348 25 Because lots of good data has this format, we'll start by writing a
ocsenave@348 26 template function to extract it:
ocsenave@348 27
ocsenave@348 28 #+name: hxc-thunks
ocsenave@348 29 #+begin_src clojure :results silent
ocsenave@348 30 (defn hxc-thunk
ocsenave@348 31 "Creates a thunk (nullary fn) that grabs data in a certain region of rom and
ocsenave@348 32 splits it into a collection by 0x50. If rom is not supplied, uses the
ocsenave@348 33 original rom data."
ocsenave@348 34 [start length]
ocsenave@348 35 (fn self
ocsenave@348 36 ([rom]
ocsenave@348 37 (take-nth 2
ocsenave@348 38 (partition-by #(= % 0x50)
ocsenave@348 39 (take length
ocsenave@348 40 (drop start rom)))))
ocsenave@348 41 ([]
ocsenave@348 42 (self com.aurellem.gb.gb-driver/original-rom))))
ocsenave@348 43
ocsenave@348 44 (def hxc-thunk-words
ocsenave@348 45 "Same as hxc-thunk, except it interprets the rom data as characters,
ocsenave@348 46 returning a collection of strings."
ocsenave@348 47 (comp
ocsenave@348 48 (partial comp (partial map character-codes->str))
ocsenave@348 49 hxc-thunk))
ocsenave@348 50
ocsenave@348 51 #+end_src
ocsenave@348 52
ocsenave@348 53
ocsenave@348 54 * Pok\eacute{}mon I
ocsenave@348 55 ** Names of each species
ocsenave@348 56 The names of the Pok\eacute{}mon species are stored in
ocsenave@348 57 ROM@E8000. This name list is interesting, for a number of reasons:
ocsenave@348 58 - The names are stored in [[ ][internal order]] rather than in the familiar
ocsenave@348 59 Pok\eacute{}dex order. This seemingly random order probably represents the order in which the authors created or
ocsenave@348 60 programmed in the Pok\eacute{}mon; it's used throughout the game.
ocsenave@348 61 - There is enough space allocated for 190 Pok\eacute{}mon. As I
ocsenave@348 62 understand it, there were originally going to be 190 Pok\eacute{}mon
ocsenave@348 63 in Generation I, but the creators decided to defer some to
ocsenave@348 64 Generation II. This explains why many Gen I and Gen II Pok\eacute{}mon
ocsenave@348 65 have the same aesthetic feel.
ocsenave@348 66 - The list is pockmarked with random gaps, due to the strange internal
ocsenave@348 67 ordering
ocsenave@348 68 and the 39 unused spaces [fn::190 allocated spaces minus 151 true Pok\eacute{}mon]. These missing spaces are filled with the
ocsenave@348 69 placeholder name =MISSINGNO.= (\ldquo{}Missing number\rdquo{}).
ocsenave@348 70
ocsenave@348 71 Each name is exactly ten letters long; whenever a name would be too short, the extra
ocsenave@348 72 space is padded with the character 0x50.
ocsenave@348 73
ocsenave@348 74 *** See the data
ocsenave@348 75
ocsenave@348 76 Here you can see the raw data in three stages: in the first stage, we
ocsenave@348 77 just grab the first few bytes starting from position 0xE8000. In the
ocsenave@348 78 second stage, we partition it into ten-letter chunks to show you
ocsenave@348 79 where the names begin and end. In the final stage, we convert each
ocsenave@348 80 byte into the letter it represents using the =character-codes->str=
ocsenave@348 81 function. (0x50 is rendered as the symbol \ldquo{} =#= \rdquo{} for
ocsenave@348 82 ease of reading).
ocsenave@348 83
ocsenave@348 84 #+begin_src clojure :exports both :cache no :results output
ocsenave@348 85 (ns com.aurellem.gb.hxc
ocsenave@348 86 (:use (com.aurellem.gb assembly characters gb-driver util mem-util
ocsenave@348 87 constants))
ocsenave@348 88 (:import [com.aurellem.gb.gb_driver SaveState]))
ocsenave@348 89
ocsenave@348 90 (println (take 100 (drop 0xE8000 (rom))))
ocsenave@348 91
ocsenave@348 92 (println (partition 10 (take 100 (drop 0xE8000 (rom)))))
ocsenave@348 93
ocsenave@348 94 (println (character-codes->str (take 100 (drop 0xE8000 (rom)))))
ocsenave@348 95
ocsenave@348 96
ocsenave@348 97 #+end_src
ocsenave@348 98
ocsenave@348 99 #+results:
ocsenave@348 100 : (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)
ocsenave@348 101 : ((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))
ocsenave@348 102 : RHYDON####KANGASKHANNIDORAN♂##CLEFAIRY##SPEAROW###VOLTORB###NIDOKING##SLOWBRO###IVYSAUR###EXEGGUTOR#
ocsenave@348 103
ocsenave@348 104
ocsenave@348 105 *** Automatically grab the data.
ocsenave@348 106
ocsenave@348 107 #+name: pokenames
ocsenave@348 108 #+begin_src clojure
ocsenave@348 109
ocsenave@348 110 (defn hxc-pokenames-raw
ocsenave@348 111 "The hardcoded names of the 190 species in memory. List begins at
ocsenave@348 112 ROM@E8000. Although names in memory are padded with 0x50 to be 10 characters
ocsenave@348 113 long, these names are stripped of padding. See also, hxc-pokedex-names"
ocsenave@348 114 ([]
ocsenave@348 115 (hxc-pokenames-raw com.aurellem.gb.gb-driver/original-rom))
ocsenave@348 116 ([rom]
ocsenave@348 117 (let [count-species 190
ocsenave@348 118 name-length 10]
ocsenave@348 119 (map character-codes->str
ocsenave@348 120 (partition name-length
ocsenave@348 121 (map #(if (= 0x50 %) 0x00 %)
ocsenave@348 122 (take (* count-species name-length)
ocsenave@348 123 (drop 0xE8000
ocsenave@348 124 rom))))))))
ocsenave@348 125 (def hxc-pokenames
ocsenave@348 126 (comp
ocsenave@348 127 (partial map format-name)
ocsenave@348 128 hxc-pokenames-raw))
ocsenave@348 129
ocsenave@348 130
ocsenave@348 131
ocsenave@348 132
ocsenave@348 133 (defn hxc-pokedex-names
ocsenave@348 134 "The names of the pokemon in hardcoded pokedex order. List begins at
ocsenave@348 135 ROM@410B1. See also, hxc-pokenames."
ocsenave@348 136 ([] (hxc-pokedex-names
ocsenave@348 137 com.aurellem.gb.gb-driver/original-rom))
ocsenave@348 138 ([rom]
ocsenave@348 139 (let [names (hxc-pokenames rom)]
ocsenave@348 140 (#(mapv %
ocsenave@348 141 ((comp range count keys) %))
ocsenave@348 142 (zipmap
ocsenave@348 143 (take (count names)
ocsenave@348 144 (drop 0x410b1 rom))
ocsenave@348 145
ocsenave@348 146 names)))))
ocsenave@348 147
ocsenave@348 148 #+end_src
ocsenave@348 149
ocsenave@348 150
ocsenave@348 151
ocsenave@348 152 ** Generic species information
ocsenave@348 153
ocsenave@348 154 #+name: pokebase
ocsenave@348 155 #+begin_src clojure
ocsenave@348 156 (defn hxc-pokemon-base
ocsenave@348 157 ([] (hxc-pokemon-base com.aurellem.gb.gb-driver/original-rom))
ocsenave@348 158 ([rom]
ocsenave@348 159 (let [entry-size 28
ocsenave@348 160 pkmn-count (count (hxc-pokedex-text rom))
ocsenave@348 161 pokemon (rest (hxc-pokedex-names))
ocsenave@348 162 types (apply assoc {}
ocsenave@348 163 (interleave
ocsenave@348 164 (range)
ocsenave@348 165 pkmn-types)) ;;!! softcoded
ocsenave@348 166 moves (apply assoc {}
ocsenave@348 167 (interleave
ocsenave@348 168 (range)
ocsenave@348 169 (map format-name
ocsenave@348 170 (hxc-move-names rom))))
ocsenave@348 171 machines (hxc-machines)
ocsenave@348 172 ]
ocsenave@348 173 (zipmap
ocsenave@348 174 pokemon
ocsenave@348 175 (map
ocsenave@348 176 (fn [[n
ocsenave@348 177 rating-hp
ocsenave@348 178 rating-atk
ocsenave@348 179 rating-def
ocsenave@348 180 rating-speed
ocsenave@348 181 rating-special
ocsenave@348 182 type-1
ocsenave@348 183 type-2
ocsenave@348 184 rarity
ocsenave@348 185 rating-xp
ocsenave@348 186 pic-dimensions ;; tile_width|tile_height (8px/tile)
ocsenave@348 187 ptr-pic-obverse-1
ocsenave@348 188 ptr-pic-obverse-2
ocsenave@348 189 ptr-pic-reverse-1
ocsenave@348 190 ptr-pic-reverse-2
ocsenave@348 191 move-1
ocsenave@348 192 move-2
ocsenave@348 193 move-3
ocsenave@348 194 move-4
ocsenave@348 195 growth-rate
ocsenave@348 196 &
ocsenave@348 197 TMs|HMs]]
ocsenave@348 198 (let
ocsenave@348 199 [base-moves
ocsenave@348 200 (mapv moves
ocsenave@348 201 ((comp
ocsenave@348 202 ;; since the game uses zero as a delimiter,
ocsenave@348 203 ;; it must also increment all move indices by 1.
ocsenave@348 204 ;; heren we decrement to correct this.
ocsenave@348 205 (partial map dec)
ocsenave@348 206 (partial take-while (comp not zero?)))
ocsenave@348 207 [move-1 move-2 move-3 move-4]))
ocsenave@348 208
ocsenave@348 209 types
ocsenave@348 210 (set (list (types type-1)
ocsenave@348 211 (types type-2)))
ocsenave@348 212 TMs|HMs
ocsenave@348 213 (map
ocsenave@348 214 (comp
ocsenave@348 215 (partial map first)
ocsenave@348 216 (partial remove (comp zero? second)))
ocsenave@348 217 (split-at
ocsenave@348 218 50
ocsenave@348 219 (map vector
ocsenave@348 220 (rest(range))
ocsenave@348 221 (reduce concat
ocsenave@348 222 (map
ocsenave@348 223 #(take 8
ocsenave@348 224 (concat (bit-list %)
ocsenave@348 225 (repeat 0)))
ocsenave@348 226
ocsenave@348 227 TMs|HMs)))))
ocsenave@348 228
ocsenave@348 229 TMs (vec (first TMs|HMs))
ocsenave@348 230 HMs (take 5 (map (partial + -50) (vec (second TMs|HMs))))
ocsenave@348 231
ocsenave@348 232
ocsenave@348 233 ]
ocsenave@348 234
ocsenave@348 235
ocsenave@348 236 {:dex# n
ocsenave@348 237 :base-moves base-moves
ocsenave@348 238 :types types
ocsenave@348 239 :TMs TMs
ocsenave@348 240 :HMs HMs
ocsenave@348 241 :base-hp rating-hp
ocsenave@348 242 :base-atk rating-atk
ocsenave@348 243 :base-def rating-def
ocsenave@348 244 :base-speed rating-speed
ocsenave@348 245 :base-special rating-special
ocsenave@348 246 :o0 pic-dimensions
ocsenave@348 247 :o1 ptr-pic-obverse-1
ocsenave@348 248 :o2 ptr-pic-obverse-2
ocsenave@348 249 }))
ocsenave@348 250
ocsenave@348 251 (partition entry-size
ocsenave@348 252 (take (* entry-size pkmn-count)
ocsenave@348 253 (drop 0x383DE
ocsenave@348 254 rom))))))))
ocsenave@348 255
ocsenave@348 256 #+end_src
ocsenave@348 257
ocsenave@348 258
ocsenave@348 259 ** Pok\eacute{}mon evolutions
ocsenave@348 260 #+name: evolution-header
ocsenave@348 261 #+begin_src clojure
ocsenave@348 262 (defn format-evo
ocsenave@348 263 "Parse a sequence of evolution data, returning a map. First is the
ocsenave@348 264 method: 0 = end-evolution-data. 1 = level-up, 2 = item, 3 = trade. Next is an item id, if the
ocsenave@348 265 method of evolution is by item (only stones will actually make pokemon
ocsenave@348 266 evolve, for some auxillary reason.) Finally, the minimum level for
ocsenave@348 267 evolution to occur (level 1 means no limit, which is used for trade
ocsenave@348 268 and item evolutions), followed by the internal id of the pokemon
ocsenave@348 269 into which to evolve. Hence, level up and trade evolutions are
ocsenave@348 270 described with 3
ocsenave@348 271 bytes; item evolutions with four."
ocsenave@348 272 [coll]
ocsenave@348 273 (let [method (first coll)]
ocsenave@348 274 (cond (empty? coll) []
ocsenave@348 275 (= 0 method) [] ;; just in case
ocsenave@348 276 (= 1 method) ;; level-up evolution
ocsenave@348 277 (conj (format-evo (drop 3 coll))
ocsenave@348 278 {:method :level-up
ocsenave@348 279 :min-level (nth coll 1)
ocsenave@348 280 :into (dec (nth coll 2))})
ocsenave@348 281
ocsenave@348 282 (= 2 method) ;; item evolution
ocsenave@348 283 (conj (format-evo (drop 4 coll))
ocsenave@348 284 {:method :item
ocsenave@348 285 :item (dec (nth coll 1))
ocsenave@348 286 :min-level (nth coll 2)
ocsenave@348 287 :into (dec (nth coll 3))})
ocsenave@348 288
ocsenave@348 289 (= 3 method) ;; trade evolution
ocsenave@348 290 (conj (format-evo (drop 3 coll))
ocsenave@348 291 {:method :trade
ocsenave@348 292 :min-level (nth coll 1) ;; always 1 for trade.
ocsenave@348 293 :into (dec (nth coll 2))}))))
ocsenave@348 294
ocsenave@348 295
ocsenave@348 296 (defn hxc-ptrs-evolve
ocsenave@348 297 "A hardcoded collection of 190 pointers to alternating evolution/learnset data,
ocsenave@348 298 in internal order."
ocsenave@348 299 ([]
ocsenave@348 300 (hxc-ptrs-evolve com.aurellem.gb.gb-driver/original-rom))
ocsenave@348 301 ([rom]
ocsenave@348 302 (let [
ocsenave@348 303 pkmn-count (count (hxc-pokenames-raw)) ;; 190
ocsenave@348 304 ptrs
ocsenave@348 305 (map (fn [[a b]] (low-high a b))
ocsenave@348 306 (partition 2
ocsenave@348 307 (take (* 2 pkmn-count)
ocsenave@348 308 (drop 0x3b1e5 rom))))]
ocsenave@348 309 (map (partial + 0x34000) ptrs)
ocsenave@348 310
ocsenave@348 311 )))
ocsenave@348 312 #+end_src
ocsenave@348 313
ocsenave@348 314 #+name:evolution
ocsenave@348 315 #+begin_src clojure
ocsenave@348 316
ocsenave@348 317 (defn hxc-evolution
ocsenave@348 318 "Hardcoded evolution data in memory. The data exists at ROM@34000,
ocsenave@348 319 sorted by internal order. Pointers to the data exist at ROM@3B1E5; see also, hxc-ptrs-evolve."
ocsenave@348 320 ([] (hxc-evolution com.aurellem.gb.gb-driver/original-rom))
ocsenave@348 321 ([rom]
ocsenave@348 322 (apply assoc {}
ocsenave@348 323 (interleave
ocsenave@348 324 (hxc-pokenames rom)
ocsenave@348 325 (map
ocsenave@348 326 (comp
ocsenave@348 327 format-evo
ocsenave@348 328 (partial take-while (comp not zero?))
ocsenave@348 329 #(drop % rom))
ocsenave@348 330 (hxc-ptrs-evolve rom)
ocsenave@348 331 )))))
ocsenave@348 332
ocsenave@348 333 (defn hxc-evolution-pretty
ocsenave@348 334 "Like hxc-evolution, except it uses the names of items and pokemon
ocsenave@348 335 --- grabbed from ROM --- rather than their numerical identifiers."
ocsenave@348 336 ([] (hxc-evolution-pretty com.aurellem.gb.gb-driver/original-rom))
ocsenave@348 337 ([rom]
ocsenave@348 338 (let
ocsenave@348 339 [poke-names (vec (hxc-pokenames rom))
ocsenave@348 340 item-names (vec (hxc-items rom))
ocsenave@348 341 use-names
ocsenave@348 342 (fn [m]
ocsenave@348 343 (loop [ks (keys m) new-map m]
ocsenave@348 344 (let [k (first ks)]
ocsenave@348 345 (cond (nil? ks) new-map
ocsenave@348 346 (= k :into)
ocsenave@348 347 (recur
ocsenave@348 348 (next ks)
ocsenave@348 349 (assoc new-map
ocsenave@348 350 :into
ocsenave@348 351 (poke-names
ocsenave@348 352 (:into
ocsenave@348 353 new-map))))
ocsenave@348 354 (= k :item)
ocsenave@348 355 (recur
ocsenave@348 356 (next ks)
ocsenave@348 357 (assoc new-map
ocsenave@348 358 :item
ocsenave@348 359 (item-names
ocsenave@348 360 (:item new-map))))
ocsenave@348 361 :else
ocsenave@348 362 (recur
ocsenave@348 363 (next ks)
ocsenave@348 364 new-map)
ocsenave@348 365 ))))]
ocsenave@348 366
ocsenave@348 367 (into {}
ocsenave@348 368 (map (fn [[pkmn evo-coll]]
ocsenave@348 369 [pkmn (map use-names evo-coll)])
ocsenave@348 370 (hxc-evolution rom))))))
ocsenave@348 371
ocsenave@348 372
ocsenave@348 373 #+end_src
ocsenave@348 374
ocsenave@348 375
ocsenave@348 376 ** Level-up moves (learnsets)
ocsenave@348 377 #+name: learnsets
ocsenave@348 378 #+begin_src clojure
ocsenave@348 379
ocsenave@348 380
ocsenave@348 381 (defn hxc-learnsets
ocsenave@348 382 "Hardcoded map associating pokemon names to lists of pairs [lvl
ocsenave@348 383 move] of abilities they learn as they level up. The data
ocsenave@348 384 exists at ROM@34000, sorted by internal order. Pointers to the data
ocsenave@348 385 exist at ROM@3B1E5; see also, hxc-ptrs-evolve"
ocsenave@348 386 ([] (hxc-learnsets com.aurellem.gb.gb-driver/original-rom))
ocsenave@348 387 ([rom]
ocsenave@348 388 (apply assoc
ocsenave@348 389 {}
ocsenave@348 390 (interleave
ocsenave@348 391 (hxc-pokenames rom)
ocsenave@348 392 (map (comp
ocsenave@348 393 (partial map
ocsenave@348 394 (fn [[lvl mv]] [lvl (dec mv)]))
ocsenave@348 395 (partial partition 2)
ocsenave@348 396 ;; keep the learnset data
ocsenave@348 397 (partial take-while (comp not zero?))
ocsenave@348 398 ;; skip the evolution data
ocsenave@348 399 rest
ocsenave@348 400 (partial drop-while (comp not zero?)))
ocsenave@348 401 (map #(drop % rom)
ocsenave@348 402 (hxc-ptrs-evolve rom)))))))
ocsenave@348 403
ocsenave@348 404 (defn hxc-learnsets-pretty
ocsenave@348 405 "Live hxc-learnsets except it reports the name of each move --- as
ocsenave@348 406 it appears in rom --- rather than the move index."
ocsenave@348 407 ([] (hxc-learnsets-pretty com.aurellem.gb.gb-driver/original-rom))
ocsenave@348 408 ([rom]
ocsenave@348 409 (let [moves (vec(map format-name (hxc-move-names)))]
ocsenave@348 410 (into {}
ocsenave@348 411 (map (fn [[pkmn learnset]]
ocsenave@348 412 [pkmn (map (fn [[lvl mv]] [lvl (moves mv)])
ocsenave@348 413 learnset)])
ocsenave@348 414 (hxc-learnsets rom))))))
ocsenave@348 415
ocsenave@348 416
ocsenave@348 417
ocsenave@348 418 #+end_src
ocsenave@348 419
ocsenave@348 420
ocsenave@348 421
ocsenave@348 422 * Pok\eacute{}mon II : the Pok\eacute{}dex
ocsenave@348 423 ** Species vital stats
ocsenave@348 424 #+name: dex-stats
ocsenave@348 425 #+begin_src clojure
ocsenave@348 426 (defn hxc-pokedex-stats
ocsenave@348 427 "The hardcoded pokedex stats (species height weight) in memory. List
ocsenave@348 428 begins at ROM@40687"
ocsenave@348 429 ([] (hxc-pokedex-stats com.aurellem.gb.gb-driver/original-rom))
ocsenave@348 430 ([rom]
ocsenave@348 431 (let [pokedex-names (zipmap (range) (hxc-pokedex-names rom))
ocsenave@348 432 pkmn-count (count pokedex-names)
ocsenave@348 433 ]
ocsenave@348 434 ((fn capture-stats
ocsenave@348 435 [n stats data]
ocsenave@348 436 (if (zero? n) stats
ocsenave@348 437 (let [[species
ocsenave@348 438 [_
ocsenave@348 439 height-ft
ocsenave@348 440 height-in
ocsenave@348 441 weight-1
ocsenave@348 442 weight-2
ocsenave@348 443 _
ocsenave@348 444 dex-ptr-1
ocsenave@348 445 dex-ptr-2
ocsenave@348 446 dex-bank
ocsenave@348 447 _
ocsenave@348 448 & data]]
ocsenave@348 449 (split-with (partial not= 0x50) data)]
ocsenave@348 450 (recur (dec n)
ocsenave@348 451 (assoc stats
ocsenave@348 452 (pokedex-names (- pkmn-count (dec n)))
ocsenave@348 453 {:species
ocsenave@348 454 (format-name (character-codes->str species))
ocsenave@348 455 :height-ft
ocsenave@348 456 height-ft
ocsenave@348 457 :height-in
ocsenave@348 458 height-in
ocsenave@348 459 :weight
ocsenave@348 460 (/ (low-high weight-1 weight-2) 10.)
ocsenave@348 461
ocsenave@348 462 ;; :text
ocsenave@348 463 ;; (character-codes->str
ocsenave@348 464 ;; (take-while
ocsenave@348 465 ;; (partial not= 0x50)
ocsenave@348 466 ;; (drop
ocsenave@348 467 ;; (+ 0xB8000
ocsenave@348 468 ;; -0x4000
ocsenave@348 469 ;; (low-high dex-ptr-1 dex-ptr-2))
ocsenave@348 470 ;; rom)))
ocsenave@348 471 })
ocsenave@348 472
ocsenave@348 473 data)
ocsenave@348 474
ocsenave@348 475
ocsenave@348 476 )))
ocsenave@348 477
ocsenave@348 478 pkmn-count
ocsenave@348 479 {}
ocsenave@348 480 (drop 0x40687 rom))) ))
ocsenave@348 481 #+end_src
ocsenave@348 482
ocsenave@348 483 ** Species synopses
ocsenave@348 484
ocsenave@348 485 #+name: dex-text
ocsenave@348 486 #+begin_src clojure
ocsenave@348 487 (def hxc-pokedex-text-raw
ocsenave@348 488 "The hardcoded pokedex entries in memory. List begins at
ocsenave@348 489 ROM@B8000, shortly before move names."
ocsenave@348 490 (hxc-thunk-words 0xB8000 14754))
ocsenave@348 491
ocsenave@348 492
ocsenave@348 493
ocsenave@348 494
ocsenave@348 495 (defn hxc-pokedex-text
ocsenave@348 496 "The hardcoded pokedex entries in memory, presented as an
ocsenave@348 497 associative hash map. List begins at ROM@B8000."
ocsenave@348 498 ([] (hxc-pokedex-text com.aurellem.gb.gb-driver/original-rom))
ocsenave@348 499 ([rom]
ocsenave@348 500 (zipmap
ocsenave@348 501 (hxc-pokedex-names rom)
ocsenave@348 502 (cons nil ;; for missingno.
ocsenave@348 503 (hxc-pokedex-text-raw rom)))))
ocsenave@348 504 #+end_src
ocsenave@348 505
ocsenave@348 506
ocsenave@348 507 ** Pok\eacute{}mon cries
ocsenave@348 508 #+name: pokecry
ocsenave@348 509 #+begin_src clojure
ocsenave@348 510 (defn hxc-cry
ocsenave@348 511 "The pokemon cry data in internal order. List begins at ROM@39462"
ocsenave@348 512 ([](hxc-cry com.aurellem.gb.gb-driver/original-rom))
ocsenave@348 513 ([rom]
ocsenave@348 514 (zipmap
ocsenave@348 515 (hxc-pokenames rom)
ocsenave@348 516 (map
ocsenave@348 517 (fn [[cry-id pitch length]]
ocsenave@348 518 {:cry-id cry-id
ocsenave@348 519 :pitch pitch
ocsenave@348 520 :length length}
ocsenave@348 521 )
ocsenave@348 522 (partition 3
ocsenave@348 523 (drop 0x39462 rom))))))
ocsenave@348 524
ocsenave@348 525 (defn hxc-cry-groups
ocsenave@348 526 ([] (hxc-cry-groups com.aurellem.gb.gb-driver/original-rom))
ocsenave@348 527 ([rom]
ocsenave@348 528 (map #(mapv first
ocsenave@348 529 (filter
ocsenave@348 530 (fn [[k v]]
ocsenave@348 531 (= % (:cry-id v)))
ocsenave@348 532 (hxc-cry)))
ocsenave@348 533 ((comp
ocsenave@348 534 range
ocsenave@348 535 count
ocsenave@348 536 set
ocsenave@348 537 (partial map :cry-id)
ocsenave@348 538 vals
ocsenave@348 539 hxc-cry)
ocsenave@348 540 rom))))
ocsenave@348 541
ocsenave@348 542
ocsenave@348 543 (defn cry-conversion!
ocsenave@348 544 "Convert Porygon's cry in ROM to be the cry of the given pokemon."
ocsenave@348 545 [pkmn]
ocsenave@348 546 (write-rom!
ocsenave@348 547 (rewrite-memory
ocsenave@348 548 (vec(rom))
ocsenave@348 549 0x3965D
ocsenave@348 550 (map second
ocsenave@348 551 ((hxc-cry) pkmn)))))
ocsenave@348 552
ocsenave@348 553 #+end_src
ocsenave@348 554
ocsenave@348 555 ** COMMENT Names of permanent stats
ocsenave@348 556 0DD4D-DD72
ocsenave@348 557
ocsenave@348 558 * Items
ocsenave@348 559 ** Item names
ocsenave@348 560 #+name: item-names
ocsenave@348 561 #+begin_src clojure
ocsenave@348 562
ocsenave@348 563 (def hxc-items-raw
ocsenave@348 564 "The hardcoded names of the items in memory. List begins at
ocsenave@348 565 ROM@045B7"
ocsenave@348 566 (hxc-thunk-words 0x45B7 870))
ocsenave@348 567
ocsenave@348 568 (def hxc-items
ocsenave@348 569 "The hardcoded names of the items in memory, presented as
ocsenave@348 570 keywords. List begins at ROM@045B7. See also, hxc-items-raw."
ocsenave@348 571 (comp (partial map format-name) hxc-items-raw))
ocsenave@348 572 #+end_src
ocsenave@348 573
ocsenave@348 574 ** Item prices
ocsenave@348 575 #+name: item-prices
ocsenave@348 576 #+begin_src clojure
ocsenave@348 577 (defn hxc-item-prices
ocsenave@348 578 "The hardcoded list of item prices in memory. List begins at ROM@4495"
ocsenave@348 579 ([] (hxc-item-prices com.aurellem.gb.gb-driver/original-rom))
ocsenave@348 580 ([rom]
ocsenave@348 581 (let [items (hxc-items rom)
ocsenave@348 582 price-size 3]
ocsenave@348 583 (zipmap items
ocsenave@348 584 (map (comp
ocsenave@348 585 ;; zero-cost items are "priceless"
ocsenave@348 586 #(if (zero? %) :priceless %)
ocsenave@348 587 decode-bcd butlast)
ocsenave@348 588 (partition price-size
ocsenave@348 589 (take (* price-size (count items))
ocsenave@348 590 (drop 0x4495 rom))))))))
ocsenave@348 591 #+end_src
ocsenave@348 592 ** Vendor inventories
ocsenave@348 593
ocsenave@348 594 #+name: item-vendors
ocsenave@348 595 #+begin_src clojure
ocsenave@348 596 (defn hxc-shops
ocsenave@348 597 ([] (hxc-shops com.aurellem.gb.gb-driver/original-rom))
ocsenave@348 598 ([rom]
ocsenave@348 599 (let [items (zipmap (range) (hxc-items rom))
ocsenave@348 600
ocsenave@348 601 ;; temporarily softcode the TM items
ocsenave@348 602 items (into
ocsenave@348 603 items
ocsenave@348 604 (map (juxt identity
ocsenave@348 605 (comp keyword
ocsenave@348 606 (partial str "tm-")
ocsenave@348 607 (partial + 1 -200)
ocsenave@348 608 ))
ocsenave@348 609 (take 200 (drop 200 (range)))))
ocsenave@348 610
ocsenave@348 611 ]
ocsenave@348 612
ocsenave@348 613 ((fn parse-shop [coll [num-items & items-etc]]
ocsenave@348 614 (let [inventory (take-while
ocsenave@348 615 (partial not= 0xFF)
ocsenave@348 616 items-etc)
ocsenave@348 617 [separator & items-etc] (drop num-items (rest items-etc))]
ocsenave@348 618 (if (= separator 0x50)
ocsenave@348 619 (map (partial mapv (comp items dec)) (conj coll inventory))
ocsenave@348 620 (recur (conj coll inventory) items-etc)
ocsenave@348 621 )
ocsenave@348 622 ))
ocsenave@348 623
ocsenave@348 624 '()
ocsenave@348 625 (drop 0x233C rom))
ocsenave@348 626
ocsenave@348 627
ocsenave@348 628 )))
ocsenave@348 629 #+end_src
ocsenave@348 630
ocsenave@348 631 #+results: item-vendors
ocsenave@348 632 : #'com.aurellem.gb.hxc/hxc-shops
ocsenave@348 633
ocsenave@348 634
ocsenave@348 635
ocsenave@348 636 * Types
ocsenave@348 637 ** Names of types
ocsenave@348 638 #+name: type-names
ocsenave@348 639 #+begin_src clojure
ocsenave@348 640 (def hxc-types
ocsenave@348 641 "The hardcoded type names in memory. List begins at ROM@27D99,
ocsenave@348 642 shortly before hxc-titles."
ocsenave@348 643 (hxc-thunk-words 0x27D99 102))
ocsenave@348 644
ocsenave@348 645 #+end_src
ocsenave@348 646
ocsenave@348 647 ** Type effectiveness
ocsenave@349 648 #+name: type-advantage
ocsenave@348 649 #+begin_src clojure
ocsenave@348 650 (defn hxc-advantage
ocsenave@348 651 ;; in-game multipliers are stored as 10x their effective value
ocsenave@348 652 ;; to allow for fractional multipliers like 1/2
ocsenave@348 653
ocsenave@348 654 "The hardcoded type advantages in memory, returned as tuples of
ocsenave@348 655 atk-type def-type multiplier. By default (i.e. if not listed here),
ocsenave@348 656 the multiplier is 1. List begins at 0x3E62D."
ocsenave@348 657 ([] (hxc-advantage com.aurellem.gb.gb-driver/original-rom))
ocsenave@348 658 ([rom]
ocsenave@348 659 (map
ocsenave@348 660 (fn [[atk def mult]] [(get pkmn-types atk (hex atk))
ocsenave@348 661 (get pkmn-types def (hex def))
ocsenave@348 662 (/ mult 10)])
ocsenave@348 663 (partition 3
ocsenave@348 664 (take-while (partial not= 0xFF)
ocsenave@348 665 (drop 0x3E62D rom))))))
ocsenave@348 666 #+end_src
ocsenave@348 667
ocsenave@348 668
ocsenave@348 669
ocsenave@348 670 * Moves
ocsenave@348 671 ** Names of moves
ocsenave@348 672 #+name: move-names
ocsenave@348 673 #+begin_src clojure
ocsenave@348 674 (def hxc-move-names
ocsenave@348 675 "The hardcoded move names in memory. List begins at ROM@BC000"
ocsenave@348 676 (hxc-thunk-words 0xBC000 1551))
ocsenave@348 677 #+end_src
ocsenave@348 678
ocsenave@348 679 ** Properties of moves
ocsenave@348 680
ocsenave@348 681 #+name: move-data
ocsenave@348 682 #+begin_src clojure
ocsenave@348 683 (defn hxc-move-data
ocsenave@348 684 "The hardcoded (basic (move effects)) in memory. List begins at
ocsenave@348 685 0x38000. Returns a map of {:name :power :accuracy :pp :fx-id
ocsenave@348 686 :fx-txt}. The move descriptions are handwritten, not hardcoded."
ocsenave@348 687 ([]
ocsenave@348 688 (hxc-move-data com.aurellem.gb.gb-driver/original-rom))
ocsenave@348 689 ([rom]
ocsenave@348 690 (let [names (vec (hxc-move-names rom))
ocsenave@348 691 move-count (count names)
ocsenave@348 692 move-size 6
ocsenave@348 693 types pkmn-types ;;; !! hardcoded types
ocsenave@348 694 ]
ocsenave@348 695 (zipmap (map format-name names)
ocsenave@348 696 (map
ocsenave@348 697 (fn [[idx effect power type-id accuracy pp]]
ocsenave@348 698 {:name (names (dec idx))
ocsenave@348 699 :power power
ocsenave@348 700 :accuracy accuracy
ocsenave@348 701 :pp pp
ocsenave@348 702 :type (types type-id)
ocsenave@348 703 :fx-id effect
ocsenave@348 704 :fx-txt (get move-effects effect)
ocsenave@348 705 }
ocsenave@348 706 )
ocsenave@348 707
ocsenave@348 708 (partition move-size
ocsenave@348 709 (take (* move-size move-count)
ocsenave@348 710 (drop 0x38000 rom))))))))
ocsenave@348 711
ocsenave@348 712
ocsenave@348 713
ocsenave@348 714 (defn hxc-move-data*
ocsenave@348 715 "Like hxc-move-data, but reports numbers as hexadecimal symbols instead."
ocsenave@348 716 ([]
ocsenave@348 717 (hxc-move-data* com.aurellem.gb.gb-driver/original-rom))
ocsenave@348 718 ([rom]
ocsenave@348 719 (let [names (vec (hxc-move-names rom))
ocsenave@348 720 move-count (count names)
ocsenave@348 721 move-size 6
ocsenave@348 722 format-name (fn [s]
ocsenave@348 723 (keyword (.toLowerCase
ocsenave@348 724 (apply str
ocsenave@348 725 (map #(if (= % \space) "-" %) s)))))
ocsenave@348 726 ]
ocsenave@348 727 (zipmap (map format-name names)
ocsenave@348 728 (map
ocsenave@348 729 (fn [[idx effect power type accuracy pp]]
ocsenave@348 730 {:name (names (dec idx))
ocsenave@348 731 :power power
ocsenave@348 732 :accuracy (hex accuracy)
ocsenave@348 733 :pp pp
ocsenave@348 734 :fx-id (hex effect)
ocsenave@348 735 :fx-txt (get move-effects effect)
ocsenave@348 736 }
ocsenave@348 737 )
ocsenave@348 738
ocsenave@348 739 (partition move-size
ocsenave@348 740 (take (* move-size move-count)
ocsenave@348 741 (drop 0x38000 rom))))))))
ocsenave@348 742
ocsenave@348 743 #+end_src
ocsenave@348 744
ocsenave@348 745 ** TM and HM moves
ocsenave@348 746
ocsenave@348 747 #+name: machines
ocsenave@348 748 #+begin_src clojure
ocsenave@348 749 (defn hxc-machines
ocsenave@348 750 "The hardcoded moves taught by TMs and HMs. List begins at ROM@1232D."
ocsenave@348 751 ([] (hxc-machines
ocsenave@348 752 com.aurellem.gb.gb-driver/original-rom))
ocsenave@348 753 ([rom]
ocsenave@348 754 (let [moves (hxc-move-names rom)]
ocsenave@348 755 (zipmap
ocsenave@348 756 (range)
ocsenave@348 757 (take-while
ocsenave@348 758 (comp not nil?)
ocsenave@348 759 (map (comp
ocsenave@348 760 format-name
ocsenave@348 761 (zipmap
ocsenave@348 762 (range)
ocsenave@348 763 moves)
ocsenave@348 764 dec)
ocsenave@348 765 (take 100
ocsenave@348 766 (drop 0x1232D rom))))))))
ocsenave@348 767
ocsenave@348 768 #+end_src
ocsenave@348 769
ocsenave@348 770
ocsenave@348 771
ocsenave@348 772
ocsenave@348 773
ocsenave@348 774 ** COMMENT Status ailments
ocsenave@348 775
ocsenave@348 776 * Places
ocsenave@348 777 ** Names of places
ocsenave@348 778
ocsenave@348 779 #+name: places
ocsenave@348 780 #+begin_src clojure
ocsenave@348 781 (def hxc-places
ocsenave@348 782 "The hardcoded place names in memory. List begins at
ocsenave@348 783 ROM@71500. [Cinnabar] Mansion seems to be dynamically calculated."
ocsenave@348 784 (hxc-thunk-words 0x71500 560))
ocsenave@348 785
ocsenave@348 786 #+end_src
ocsenave@348 787
ocsenave@348 788 ** Wild Pok\eacute{}mon demographics
ocsenave@348 789 #+name: wilds
ocsenave@348 790 #+begin_src clojure
ocsenave@348 791
ocsenave@348 792
ocsenave@348 793
ocsenave@348 794 (defn hxc-ptrs-wild
ocsenave@348 795 "A list of the hardcoded wild encounter data in memory. Pointers
ocsenave@348 796 begin at ROM@0CB95; data begins at ROM@0x04D89"
ocsenave@348 797 ([] (hxc-ptrs-wild com.aurellem.gb.gb-driver/original-rom))
ocsenave@348 798 ([rom]
ocsenave@348 799 (let [ptrs
ocsenave@348 800 (map (fn [[a b]] (+ a (* 0x100 b)))
ocsenave@348 801 (take-while (partial not= (list 0xFF 0xFF))
ocsenave@348 802 (partition 2 (drop 0xCB95 rom))))]
ocsenave@348 803 ptrs)))
ocsenave@348 804
ocsenave@348 805
ocsenave@348 806
ocsenave@348 807 (defn hxc-wilds
ocsenave@348 808 "A list of the hardcoded wild encounter data in memory. Pointers
ocsenave@348 809 begin at ROM@0CB95; data begins at ROM@0x04D89"
ocsenave@348 810 ([] (hxc-wilds com.aurellem.gb.gb-driver/original-rom))
ocsenave@348 811 ([rom]
ocsenave@348 812 (let [pokenames (zipmap (range) (hxc-pokenames rom))]
ocsenave@348 813 (map
ocsenave@348 814 (partial map (fn [[a b]] {:species (pokenames (dec b)) :level
ocsenave@348 815 a}))
ocsenave@348 816 (partition 10
ocsenave@348 817
ocsenave@348 818 (take-while (comp (partial not= 1)
ocsenave@348 819 first)
ocsenave@348 820 (partition 2
ocsenave@348 821 (drop 0xCD8C rom))
ocsenave@348 822
ocsenave@348 823 ))))))
ocsenave@348 824
ocsenave@348 825 #+end_src
ocsenave@348 826
ocsenave@348 827
ocsenave@348 828
ocsenave@348 829
ocsenave@348 830
ocsenave@348 831 * Appendices
ocsenave@348 832
ocsenave@348 833
ocsenave@348 834
ocsenave@347 835 ** Mapping the ROM
ocsenave@311 836
ocsenave@311 837 | ROM address (hex) | Description | Format | Example |
ocsenave@311 838 |-------------------+-----------------+-----------------+-----------------|
ocsenave@311 839 | | <15> | <15> | <15> |
ocsenave@312 840 | 0233C- | Shop inventories. | | |
ocsenave@312 841 | 04495- | Prices of items. | Each price is two bytes of binary-coded decimal. Prices are separated by zeroes. Priceless items[fn::Like the Pok\eacute{}dex and other unsellable items.] are given a price of zero. | The cost of lemonade is 0x03 0x50, which translates to a price of ₱350. |
ocsenave@311 842 | 045B7-0491E | Names of the items in memory. | Variable-length item names (strings of character codes). Names are separated by a single 0x80 character. | MASTER BALL#ULTRA BALL#... |
ocsenave@346 843 | 04D89- | Lists of wild Pok\eacute{}mon to encounter in each region. | Each list contains ten Pokemon (ids) and their levels; twenty bytes in total. First, the level of the first Pokemon. Then the internal id of the first Pokemon. Next, the level of the second Pokemon, and so on. Since Pokemon cannot have level 0, the lists are separated by a pair 0 /X/, where /X/ is an apparently random Pokemon id. | The first list is (3 36 4 36 2 165 3 165 2 36 3 36 5 36 4 165 6 36 7 36 0 25), i.e. level 3 pidgey, level 4 pidgey, level 2 rattata, level 3 rattata, level 2 pidgey, level 3 pidgey, level 5 pidgey, level 4 rattata, level 6 pidgey, level 7 pidgey, \ldquo{}level 0 gastly\rdquo{} (i.e., end-of-list). |
ocsenave@311 844 | 05EDB. | Which Pok\eacute{}mon to show during Prof. Oak's introduction. | A single byte, the Pok\eacute{}mon's internal id. | In Pok\eacute{}mon Yellow, it shows Pikachu during the introduction; Pikachu's internal id is 0x54. |
ocsenave@312 845 | 06698- | ? Background music. | | |
ocsenave@312 846 | 0822E-082F? | Pointers to background music, part I. | | |
ocsenave@347 847 | 0CB95- | Pointers to lists of wild pokemon to encounter in each region. These lists begin at 04D89, see above. | Each pointer is a low-byte, high-byte pair. | The first entry is 0x89 0x4D, corresponding to the address 0x4D89, the location of the first list of wild Pok\eacute{}mon (see 04D89, above). |
ocsenave@347 848 |-------------------+-----------------+-----------------+-----------------|
ocsenave@347 849 | 0DADB. | Amount of HP restored by Hyper Potion. | The HP consists of a single byte. TODO: Discover what the surrounding data does, and find the data for the amount of HP restored by other items: Fresh Water (50HP), Soda (60HP), Lemonade(80HP). | 200 |
ocsenave@347 850 | 0DAE0. | Amount of HP restored by Super Potion. | " | 50 |
ocsenave@347 851 | 0DAE3. | Amount of HP restored by Potion. | " | 20 |
ocsenave@347 852 |-------------------+-----------------+-----------------+-----------------|
ocsenave@346 853 | 0DD4D-DD72 | Names of permanent stats. | Variable-length strings separated by 0x50. | #HEALTH#ATTACK#DEFENSE#SPEED#SPECIAL# |
ocsenave@346 854 | 1195C-1196A | The two terms for being able/unable to learn a TM/HM. | Variable-length strings separated by 0x50. | ABLE#NOT ABLE# |
ocsenave@346 855 | 119C0-119CE | The two terms for being able/unable to evolve using the current stone. | Variable-length strings separated by 0x50. | ABLE#NOT ABLE# |
ocsenave@346 856 | 1232D-12364 | Which moves are taught by the TMs and HMs | A list of 55 move ids (50 TMs, plus 5 HMs). First, the move that will be taught by TM01; second, the move that will be taught by TM02; and so on. The last five entries are the moves taught by HMs 1-5. (See also, BC000 below) | The first few entries are (5 13 14 18 ...) corresponding to Mega Punch (TM01), Razor Wind (TM02), Swords Dance (TM03), Whirlwind (TM04), ... |
ocsenave@311 857 | 27D99-27DFF | Names of the Pok\eacute{}mon types. | Variable-length type names (strings of character codes). Names are separated by a single 0x80 character. | NORMAL#FIGHTING#... |
ocsenave@347 858 | 27E77- | Trainer title names. | Variable-length names separated by 0x80. | YOUNGSTER#BUG CATCHER#LASS#... |
ocsenave@347 859 | 34000- | | | |
ocsenave@347 860 | 38000-383DE | The basic properties and effects of moves. (165 moves total) | Fixed-length (6 byte) continguous descriptions (no separating character): move-index, move-effect, power, move-type, accuracy, pp. | The entry for Pound, the first attack in the list, is (1 0 40 0 255 35). See below for more explanation. |
ocsenave@312 861 | 383DE- | Species data for the Pokemon, listed in Pokedex order: Pokedex number; base moves; types; learnable TMs and HMs; base HP, attack, defense, speed, special; sprite data. | | |
ocsenave@311 862 | 39462- | The Pok\eacute{}mon cry data. | Fixed-length (3 byte) descriptions of cries. | |
ocsenave@312 863 | 3B1E5- | Pointers to evolution/learnset data. | | |
ocsenave@347 864 | 3B361- | Evolution and learnset data. [fn::Evolution data consists of how to make Pok\eacute{}mon evolve, and what they evolve into. Learnset data consists of the moves that Pok\eacute{}mon learn as they level up.] | Variable-length evolution information (see below), followed by a list of level/move-id learnset pairs. | |
ocsenave@311 865 | 40687- | Species data from the Pok\eacute{}dex: species name, height, weight, etc. | Fixed-length sequences of bytes. See below for specifics. | |
ocsenave@312 866 | 410B1- | A conversion table between internal order and Pokedex order. | | |
ocsenave@346 867 | 5DE10-5DE30 | Abbreviations for status ailments. | Fixed-length strings, probably[fn::Here's something strange: all of the status messages start with 0x7F and end with 0x4F \mdash{}except PAR, which ends with 0x50.]. The last entry is QUIT##. | [0x7F] *SLP* [0x4E][0x7F] *PSN* [0x4E][0x7F] *PAR* [0x50][0x7F]... |
ocsenave@312 868 | 71500- | Names of places. | | |
ocsenave@312 869 | 7C249-7C2?? | Pointers to background music, pt II. | | |
ocsenave@312 870 | 98000- | Dialogue | | |
ocsenave@312 871 | B8000- | The text of each Pokemon's Pok\eacute{}dex entry. | | |
ocsenave@347 872 | BC000-BC60E | Move names. | Variable-length move names, separated by 0x80. The moves are in internal order. | POUND#KARATE CHOP#DOUBLESLAP#COMET PUNCH#... |
ocsenave@311 873 | E8000-E876C | Names of the \ldquo{}190\rdquo{} species of Pok\eacute{}mon in memory. | Fixed length (10-letter) Pok\eacute{}mon names. Any extra space is padded with the character 0x80. The names are in \ldquo{}internal order\rdquo{}. | RHYDON####KANGASKHANNIDORAN♂#... |
ocsenave@311 874 | | | | |
ocsenave@311 875 | | | | |
ocsenave@312 876
ocsenave@347 877
ocsenave@347 878
ocsenave@312 879 ** Internal Pok\eacute{}mon IDs
ocsenave@312 880 ** Type IDs
ocsenave@347 881
ocsenave@347 882 #+name: type-ids
ocsenave@347 883 #+begin_src clojure
ocsenave@347 884 (def pkmn-types
ocsenave@347 885 [:normal ;;0
ocsenave@347 886 :fighting ;;1
ocsenave@347 887 :flying ;;2
ocsenave@347 888 :poison ;;3
ocsenave@347 889 :ground ;;4
ocsenave@347 890 :rock ;;5
ocsenave@347 891 :bird ;;6
ocsenave@347 892 :bug ;;7
ocsenave@347 893 :ghost ;;8
ocsenave@347 894 :A
ocsenave@347 895 :B
ocsenave@347 896 :C
ocsenave@347 897 :D
ocsenave@347 898 :E
ocsenave@347 899 :F
ocsenave@347 900 :G
ocsenave@347 901 :H
ocsenave@347 902 :I
ocsenave@347 903 :J
ocsenave@347 904 :K
ocsenave@347 905 :fire ;;20 (0x14)
ocsenave@347 906 :water ;;21 (0x15)
ocsenave@347 907 :grass ;;22 (0x16)
ocsenave@347 908 :electric ;;23 (0x17)
ocsenave@347 909 :psychic ;;24 (0x18)
ocsenave@347 910 :ice ;;25 (0x19)
ocsenave@347 911 :dragon ;;26 (0x1A)
ocsenave@347 912 ])
ocsenave@347 913 #+end_src
ocsenave@347 914
ocsenave@312 915 ** Basic effects of moves
ocsenave@347 916
ocsenave@347 917 *** Table of basic effects
ocsenave@347 918
ocsenave@347 919 The possible effects of moves in Pok\eacute{}mon \mdash{} for example, dealing
ocsenave@347 920 damage, leeching health, or potentially poisoning the opponent
ocsenave@347 921 \mdash{} are stored in a table. Each move has exactly one effect, and
ocsenave@347 922 different moves might have the same effect.
ocsenave@347 923
ocsenave@347 924 For example, Leech Life, Mega Drain, and Absorb all have effect ID #3, which is \ldquo{}Leech half of the inflicted damage.\rdquo{}
ocsenave@347 925
ocsenave@347 926 All the legitimate move effects are listed in the table
ocsenave@347 927 below. Here are some notes for reading it:
ocsenave@347 928
ocsenave@347 929 - Whenever an effect has a chance of doing something (like a chance of
ocsenave@347 930 poisoning the opponent), I list the chance as a hexadecimal amount out of 256 to avoid rounding errors. To convert the hex amount into a percentage, divide by 256.
ocsenave@347 931 - For some effects, the description is too cumbersome to
ocsenave@347 932 write. Instead, I just write a move name
ocsenave@347 933 in parentheses, like: (leech seed). That move gives a characteristic example
ocsenave@347 934 of the effect.
ocsenave@347 935 - I use the abbreviations =atk=, =def=, =spd=, =spc=, =acr=, =evd= for
ocsenave@347 936 attack, defense, speed, special, accuracy, and evasion.
ocsenave@347 937 .
ocsenave@347 938
ocsenave@347 939
ocsenave@347 940
ocsenave@347 941 | ID (hex) | Description | Notes |
ocsenave@347 942 |----------+-------------------------------------------------------------------------------------------------+------------------------------------------------------------------|
ocsenave@347 943 | 0 | normal damage | |
ocsenave@347 944 | 1 | no damage, just sleep | TODO: find out how many turns |
ocsenave@347 945 | 2 | 0x4C chance of poison | |
ocsenave@347 946 | 3 | leech half of inflicted damage | |
ocsenave@347 947 | 4 | 0x19 chance of burn | |
ocsenave@347 948 | 5 | 0x19 chance of freeze | |
ocsenave@347 949 | 6 | 0x19 chance of paralysis | |
ocsenave@347 950 | 7 | user faints; opponent's defense is halved during attack. | |
ocsenave@347 951 | 8 | leech half of inflicted damage ONLY if the opponent is asleep | |
ocsenave@347 952 | 9 | imitate last attack | |
ocsenave@347 953 | A | user atk +1 | |
ocsenave@347 954 | B | user def +1 | |
ocsenave@347 955 | C | user spd +1 | |
ocsenave@347 956 | D | user spc +1 | |
ocsenave@347 957 | E | user acr +1 | This effect is unused. |
ocsenave@347 958 | F | user evd +1 | |
ocsenave@347 959 | 10 | get post-battle money = 2 * level * uses | |
ocsenave@347 960 | 11 | move has 0xFE acr, regardless of battle stat modifications. | |
ocsenave@347 961 | 12 | opponent atk -1 | |
ocsenave@347 962 | 13 | opponent def -1 | |
ocsenave@347 963 | 14 | opponent spd -1 | |
ocsenave@347 964 | 15 | opponent spc -1 | |
ocsenave@347 965 | 16 | opponent acr -1 | |
ocsenave@347 966 | 17 | opponent evd -1 | |
ocsenave@347 967 | 18 | converts user's type to opponent's. | |
ocsenave@347 968 | 19 | (haze) | |
ocsenave@347 969 | 1A | (bide) | |
ocsenave@347 970 | 1B | (thrash) | |
ocsenave@347 971 | 1C | (teleport) | |
ocsenave@347 972 | 1D | (fury swipes) | |
ocsenave@347 973 | 1E | attacks 2-5 turns | Unused. TODO: find out what it does. |
ocsenave@347 974 | 1F | 0x19 chance of flinching | |
ocsenave@347 975 | 20 | opponent sleep for 1-7 turns | |
ocsenave@347 976 | 21 | 0x66 chance of poison | |
ocsenave@347 977 | 22 | 0x4D chance of burn | |
ocsenave@347 978 | 23 | 0x4D chance of freeze | |
ocsenave@347 979 | 24 | 0x4D chance of paralysis | |
ocsenave@347 980 | 25 | 0x4D chance of flinching | |
ocsenave@347 981 | 26 | one-hit KO | |
ocsenave@347 982 | 27 | charge one turn, atk next. | |
ocsenave@347 983 | 28 | fixed damage, leaves 1HP. | Is the fixed damage the power of the move? |
ocsenave@347 984 | 29 | fixed damage. | Like seismic toss, dragon rage, psywave. |
ocsenave@347 985 | 2A | atk 2-5 turns; opponent can't attack | The odds of attacking for /n/ turns are: (0 0x60 0x60 0x20 0x20) |
ocsenave@347 986 | 2B | charge one turn, atk next. (can't be hit when charging) | |
ocsenave@347 987 | 2C | atk hits twice. | |
ocsenave@347 988 | 2D | user takes 1 damage if misses. | |
ocsenave@347 989 | 2E | evade status-lowering effects | Caused by you or also your opponent? |
ocsenave@347 990 | 2F | broken: if user is slower than opponent, makes critical hit impossible, otherwise has no effect | This is the effect of Focus Energy. It's (very) broken. |
ocsenave@347 991 | 30 | atk causes recoil dmg = 1/4 dmg dealt | |
ocsenave@347 992 | 31 | confuses opponent | |
ocsenave@347 993 | 32 | user atk +2 | |
ocsenave@347 994 | 33 | user def +2 | |
ocsenave@347 995 | 34 | user spd +2 | |
ocsenave@347 996 | 35 | user spc +2 | |
ocsenave@347 997 | 36 | user acr +2 | This effect is unused. |
ocsenave@347 998 | 37 | user evd +2 | This effect is unused. |
ocsenave@347 999 | 38 | restores up to half of user's max hp. | |
ocsenave@347 1000 | 39 | (transform) | |
ocsenave@347 1001 | 3A | opponent atk -2 | |
ocsenave@347 1002 | 3B | opponent def -2 | |
ocsenave@347 1003 | 3C | opponent spd -2 | |
ocsenave@347 1004 | 3D | opponent spc -2 | |
ocsenave@347 1005 | 3E | opponent acr -2 | |
ocsenave@347 1006 | 3F | opponent evd -2 | |
ocsenave@347 1007 | 40 | doubles user spc when attacked | |
ocsenave@347 1008 | 41 | doubles user def when attacked | |
ocsenave@347 1009 | 42 | just poisons opponent | |
ocsenave@347 1010 | 43 | just paralyzes opponent | |
ocsenave@347 1011 | 44 | 0x19 chance opponent atk -1 | |
ocsenave@347 1012 | 45 | 0x19 chance opponent def -1 | |
ocsenave@347 1013 | 46 | 0x19 chance opponent spd -1 | |
ocsenave@347 1014 | 47 | 0x4C chance opponent spc -1 | |
ocsenave@347 1015 | 48 | 0x19 chance opponent acr -1 | |
ocsenave@347 1016 | 49 | 0x19 chance opponent evd -1 | |
ocsenave@347 1017 | 4A | ??? | ;; unused? no effect? |
ocsenave@347 1018 | 4B | ??? | ;; unused? no effect? |
ocsenave@347 1019 | 4C | 0x19 chance of confusing the opponent | |
ocsenave@347 1020 | 4D | atk hits twice. 0x33 chance opponent poisioned. | |
ocsenave@347 1021 | 4E | broken. crash the game after attack. | |
ocsenave@347 1022 | 4F | (substitute) | |
ocsenave@347 1023 | 50 | unless opponent faints, user must recharge after atk. some exceptions apply | |
ocsenave@347 1024 | 51 | (rage) | |
ocsenave@347 1025 | 52 | (mimic) | |
ocsenave@347 1026 | 53 | (metronome) | |
ocsenave@347 1027 | 54 | (leech seed) | |
ocsenave@347 1028 | 55 | does nothing (splash) | |
ocsenave@347 1029 | 56 | (disable) | |
ocsenave@347 1030 #+end_src
ocsenave@347 1031
ocsenave@347 1032 *** Source
ocsenave@347 1033 #+name: move-effects
ocsenave@347 1034 #+begin_src clojure
ocsenave@347 1035 (def move-effects
ocsenave@347 1036 ["normal damage"
ocsenave@347 1037 "no damage, just opponent sleep" ;; how many turns? is atk power ignored?
ocsenave@347 1038 "0x4C chance of poison"
ocsenave@347 1039 "leech half of inflicted damage"
ocsenave@347 1040 "0x19 chance of burn"
ocsenave@347 1041 "0x19 chance of freeze"
ocsenave@347 1042 "0x19 chance of paralyze"
ocsenave@347 1043 "user faints; opponent defense halved during attack."
ocsenave@347 1044 "leech half of inflicted damage ONLY if sleeping opponent."
ocsenave@347 1045 "imitate last attack"
ocsenave@347 1046 "user atk +1"
ocsenave@347 1047 "user def +1"
ocsenave@347 1048 "user spd +1"
ocsenave@347 1049 "user spc +1"
ocsenave@347 1050 "user acr +1" ;; unused?!
ocsenave@347 1051 "user evd +1"
ocsenave@347 1052 "get post-battle $ = 2*level*uses"
ocsenave@347 1053 "0xFE acr, no matter what."
ocsenave@347 1054 "opponent atk -1" ;; acr taken from move acr?
ocsenave@347 1055 "opponent def -1" ;;
ocsenave@347 1056 "opponent spd -1" ;;
ocsenave@347 1057 "opponent spc -1" ;;
ocsenave@347 1058 "opponent acr -1";;
ocsenave@347 1059 "opponent evd -1"
ocsenave@347 1060 "converts user's type to opponent's."
ocsenave@347 1061 "(haze)"
ocsenave@347 1062 "(bide)"
ocsenave@347 1063 "(thrash)"
ocsenave@347 1064 "(teleport)"
ocsenave@347 1065 "(fury swipes)"
ocsenave@347 1066 "attacks 2-5 turns" ;; unused? like rollout?
ocsenave@347 1067 "0x19 chance of flinch"
ocsenave@347 1068 "opponent sleep for 1-7 turns"
ocsenave@347 1069 "0x66 chance of poison"
ocsenave@347 1070 "0x4D chance of burn"
ocsenave@347 1071 "0x4D chance of freeze"
ocsenave@347 1072 "0x4D chance of paralyze"
ocsenave@347 1073 "0x4D chance of flinch"
ocsenave@347 1074 "one-hit KO"
ocsenave@347 1075 "charge one turn, atk next."
ocsenave@347 1076 "fixed damage, leaves 1HP." ;; how is dmg determined?
ocsenave@347 1077 "fixed damage." ;; cf seismic toss, dragon rage, psywave.
ocsenave@347 1078 "atk 2-5 turns; opponent can't attack" ;; unnormalized? (0 0x60 0x60 0x20 0x20)
ocsenave@347 1079 "charge one turn, atk next. (can't be hit when charging)"
ocsenave@347 1080 "atk hits twice."
ocsenave@347 1081 "user takes 1 damage if misses."
ocsenave@347 1082 "evade status-lowering effects" ;;caused by you or also your opponent?
ocsenave@347 1083 "(broken) if user is slower than opponent, makes critical hit impossible, otherwise has no effect"
ocsenave@347 1084 "atk causes recoil dmg = 1/4 dmg dealt"
ocsenave@347 1085 "confuses opponent" ;; acr taken from move acr
ocsenave@347 1086 "user atk +2"
ocsenave@347 1087 "user def +2"
ocsenave@347 1088 "user spd +2"
ocsenave@347 1089 "user spc +2"
ocsenave@347 1090 "user acr +2" ;; unused!
ocsenave@347 1091 "user evd +2" ;; unused!
ocsenave@347 1092 "restores up to half of user's max hp." ;; broken: fails if the difference
ocsenave@347 1093 ;; b/w max and current hp is one less than a multiple of 256.
ocsenave@347 1094 "(transform)"
ocsenave@347 1095 "opponent atk -2"
ocsenave@347 1096 "opponent def -2"
ocsenave@347 1097 "opponent spd -2"
ocsenave@347 1098 "opponent spc -2"
ocsenave@347 1099 "opponent acr -2"
ocsenave@347 1100 "opponent evd -2"
ocsenave@347 1101 "doubles user spc when attacked"
ocsenave@347 1102 "doubles user def when attacked"
ocsenave@347 1103 "just poisons opponent" ;;acr taken from move acr
ocsenave@347 1104 "just paralyzes opponent" ;;
ocsenave@347 1105 "0x19 chance opponent atk -1"
ocsenave@347 1106 "0x19 chance opponent def -1"
ocsenave@347 1107 "0x19 chance opponent spd -1"
ocsenave@347 1108 "0x4C chance opponent spc -1" ;; context suggest chance is 0x19
ocsenave@347 1109 "0x19 chance opponent acr -1"
ocsenave@347 1110 "0x19 chance opponent evd -1"
ocsenave@347 1111 "???" ;; unused? no effect?
ocsenave@347 1112 "???" ;; unused? no effect?
ocsenave@347 1113 "0x19 chance opponent confused"
ocsenave@347 1114 "atk hits twice. 0x33 chance opponent poisioned."
ocsenave@347 1115 "broken. crash the game after attack."
ocsenave@347 1116 "(substitute)"
ocsenave@347 1117 "unless opponent faints, user must recharge after atk. some
ocsenave@347 1118 exceptions apply."
ocsenave@347 1119 "(rage)"
ocsenave@347 1120 "(mimic)"
ocsenave@347 1121 "(metronome)"
ocsenave@347 1122 "(leech seed)"
ocsenave@347 1123 "does nothing (splash)"
ocsenave@347 1124 "(disable)"
ocsenave@347 1125 ])
ocsenave@347 1126 #+end_src
ocsenave@347 1127
ocsenave@347 1128
ocsenave@312 1129 ** Alphabet code
ocsenave@347 1130
ocsenave@348 1131 * Source
ocsenave@348 1132
ocsenave@347 1133 #+begin_src clojure :tangle ../clojure/com/aurellem/gb/hxc.clj
ocsenave@347 1134
ocsenave@347 1135 (ns com.aurellem.gb.hxc
ocsenave@347 1136 (:use (com.aurellem.gb assembly characters gb-driver util mem-util
ocsenave@347 1137 constants species))
ocsenave@347 1138 (:import [com.aurellem.gb.gb_driver SaveState]))
ocsenave@347 1139
ocsenave@347 1140 ; ************* HANDWRITTEN CONSTANTS
ocsenave@347 1141
ocsenave@347 1142 <<type-ids>>
ocsenave@347 1143
ocsenave@347 1144
ocsenave@347 1145 ;; question: when status effects claim to take
ocsenave@347 1146 ;; their accuracy from the move accuracy, does
ocsenave@347 1147 ;; this mean that the move always "hits" but the
ocsenave@347 1148 ;; status effect may not?
ocsenave@347 1149
ocsenave@347 1150 <<move-effects>>
ocsenave@347 1151
ocsenave@347 1152 ;; ************** HARDCODED DATA
ocsenave@347 1153
ocsenave@347 1154 <<hxc-thunks>>
ocsenave@347 1155 ;; --------------------------------------------------
ocsenave@347 1156
ocsenave@347 1157 <<pokenames>>
ocsenave@348 1158 <<type-names>>
ocsenave@347 1159
ocsenave@347 1160 ;; http://hax.iimarck.us/topic/581/
ocsenave@348 1161 <<pokecry>>
ocsenave@347 1162
ocsenave@347 1163
ocsenave@348 1164 <<item-names>>
ocsenave@347 1165
ocsenave@347 1166
ocsenave@347 1167
ocsenave@347 1168 (def hxc-titles
ocsenave@347 1169 "The hardcoded names of the trainer titles in memory. List begins at
ocsenave@347 1170 ROM@27E77"
ocsenave@347 1171 (hxc-thunk-words 0x27E77 196))
ocsenave@347 1172
ocsenave@347 1173
ocsenave@348 1174 <<dex-text>>
ocsenave@347 1175
ocsenave@347 1176 ;; In red/blue, pokedex stats are in internal order.
ocsenave@347 1177 ;; In yellow, pokedex stats are in pokedex order.
ocsenave@348 1178 <<dex-stats>>
ocsenave@347 1179
ocsenave@347 1180
ocsenave@347 1181
ocsenave@347 1182
ocsenave@348 1183 <<places>>
ocsenave@347 1184
ocsenave@347 1185 (defn hxc-dialog
ocsenave@347 1186 "The hardcoded dialogue in memory, including in-game alerts. Dialog
ocsenave@347 1187 seems to be separated by 0x57 instead of 0x50 (END). Begins at ROM@98000."
ocsenave@347 1188 ([rom]
ocsenave@347 1189 (map character-codes->str
ocsenave@347 1190 (take-nth 2
ocsenave@347 1191 (partition-by #(= % 0x57)
ocsenave@347 1192 (take 0x0F728
ocsenave@347 1193 (drop 0x98000 rom))))))
ocsenave@347 1194 ([]
ocsenave@347 1195 (hxc-dialog com.aurellem.gb.gb-driver/original-rom)))
ocsenave@347 1196
ocsenave@347 1197
ocsenave@348 1198 <<move-names>>
ocsenave@348 1199 <<move-data>>
ocsenave@347 1200
ocsenave@348 1201 <<machines>>
ocsenave@347 1202
ocsenave@347 1203
ocsenave@347 1204
ocsenave@347 1205 (defn internal-id
ocsenave@347 1206 ([rom]
ocsenave@347 1207 (zipmap
ocsenave@347 1208 (hxc-pokenames rom)
ocsenave@347 1209 (range)))
ocsenave@347 1210 ([]
ocsenave@347 1211 (internal-id com.aurellem.gb.gb-driver/original-rom)))
ocsenave@347 1212
ocsenave@347 1213
ocsenave@347 1214
ocsenave@347 1215
ocsenave@347 1216
ocsenave@347 1217 ;; nidoran gender change upon levelup
ocsenave@347 1218 ;; (->
ocsenave@347 1219 ;; @current-state
ocsenave@347 1220 ;; rom
ocsenave@347 1221 ;; vec
ocsenave@347 1222 ;; (rewrite-memory
ocsenave@347 1223 ;; (nth (hxc-ptrs-evolve) ((internal-id) :nidoran♂))
ocsenave@347 1224 ;; [1 1 15])
ocsenave@347 1225 ;; (rewrite-memory
ocsenave@347 1226 ;; (nth (hxc-ptrs-evolve) ((internal-id) :nidoran♀))
ocsenave@347 1227 ;; [1 1 3])
ocsenave@347 1228 ;; (write-rom!)
ocsenave@347 1229
ocsenave@347 1230 ;; )
ocsenave@347 1231
ocsenave@347 1232
ocsenave@347 1233
ocsenave@348 1234 <<type-advantage>>
ocsenave@347 1235
ocsenave@347 1236
ocsenave@347 1237
ocsenave@348 1238 <<evolution-header>>
ocsenave@349 1239 <<evolution>>
ocsenave@348 1240 <<learnsets>>
ocsenave@348 1241 <<pokebase>>
ocsenave@347 1242
ocsenave@347 1243
ocsenave@347 1244 (defn hxc-intro-pkmn
ocsenave@347 1245 "The hardcoded pokemon to display in Prof. Oak's introduction; the pokemon's
ocsenave@347 1246 internal id is stored at ROM@5EDB."
ocsenave@347 1247 ([] (hxc-intro-pkmn
ocsenave@347 1248 com.aurellem.gb.gb-driver/original-rom))
ocsenave@347 1249 ([rom]
ocsenave@347 1250 (nth (hxc-pokenames rom) (nth rom 0x5EDB))))
ocsenave@347 1251
ocsenave@347 1252 (defn sxc-intro-pkmn!
ocsenave@347 1253 "Set the hardcoded pokemon to display in Prof. Oak's introduction."
ocsenave@347 1254 [pokemon]
ocsenave@347 1255 (write-rom!
ocsenave@347 1256 (rewrite-rom 0x5EDB
ocsenave@347 1257 [
ocsenave@347 1258 (inc
ocsenave@347 1259 ((zipmap
ocsenave@347 1260 (hxc-pokenames)
ocsenave@347 1261 (range))
ocsenave@347 1262 pokemon))])))
ocsenave@347 1263
ocsenave@347 1264
ocsenave@348 1265 <<item-prices>>
ocsenave@347 1266
ocsenave@348 1267 <<item-vendors>>
ocsenave@347 1268
ocsenave@348 1269 <<wilds>>
ocsenave@347 1270
ocsenave@347 1271
ocsenave@347 1272 ;; ********************** MANIPULATION FNS
ocsenave@347 1273
ocsenave@347 1274
ocsenave@347 1275 (defn same-type
ocsenave@347 1276 ([pkmn move]
ocsenave@347 1277 (same-type
ocsenave@347 1278 com.aurellem.gb.gb-driver/original-rom pkmn move))
ocsenave@347 1279 ([rom pkmn move]
ocsenave@347 1280 (((comp :types (hxc-pokemon-base rom)) pkmn)
ocsenave@347 1281 ((comp :type (hxc-move-data rom)) move))))
ocsenave@347 1282
ocsenave@347 1283
ocsenave@347 1284
ocsenave@347 1285
ocsenave@347 1286 (defn submap?
ocsenave@347 1287 "Compares the two maps. Returns true if map-big has the same associations as map-small, otherwise false."
ocsenave@347 1288 [map-small map-big]
ocsenave@347 1289 (cond (empty? map-small) true
ocsenave@347 1290 (and
ocsenave@347 1291 (contains? map-big (ffirst map-small))
ocsenave@347 1292 (= (get map-big (ffirst map-small))
ocsenave@347 1293 (second (first map-small))))
ocsenave@347 1294 (recur (next map-small) map-big)
ocsenave@347 1295
ocsenave@347 1296 :else false))
ocsenave@347 1297
ocsenave@347 1298
ocsenave@347 1299 (defn search-map [proto-map maps]
ocsenave@347 1300 "Returns all the maps that make the same associations as proto-map."
ocsenave@347 1301 (some (partial submap? proto-map) maps))
ocsenave@347 1302
ocsenave@347 1303 (defn filter-vals
ocsenave@347 1304 "Returns a map consisting of all the pairs [key val] for
ocsenave@347 1305 which (pred key) returns true."
ocsenave@347 1306 [pred map]
ocsenave@347 1307 (reduce (partial apply assoc) {}
ocsenave@347 1308 (filter (fn [[k v]] (pred v)) map)))
ocsenave@347 1309
ocsenave@347 1310
ocsenave@347 1311 (defn search-moves
ocsenave@347 1312 "Returns a subcollection of all hardcoded moves with the
ocsenave@347 1313 given attributes. Attributes consist of :name :power
ocsenave@347 1314 :accuracy :pp :fx-id
ocsenave@347 1315 (and also :fx-txt, but it contains the same information
ocsenave@347 1316 as :fx-id)"
ocsenave@347 1317 ([attribute-map]
ocsenave@347 1318 (search-moves
ocsenave@347 1319 com.aurellem.gb.gb-driver/original-rom attribute-map))
ocsenave@347 1320 ([rom attribute-map]
ocsenave@347 1321 (filter-vals (partial submap? attribute-map)
ocsenave@347 1322 (hxc-move-data rom))))
ocsenave@347 1323
ocsenave@347 1324
ocsenave@347 1325
ocsenave@347 1326
ocsenave@347 1327
ocsenave@347 1328 ;; note: 0x2f31 contains the names "TM" "HM"?
ocsenave@347 1329
ocsenave@347 1330 ;; note for later: credits start at F1290
ocsenave@347 1331
ocsenave@347 1332 ;; note: DADB hyper-potion-hp _ _ _ super-potion-hp _ _ _ potion-hp ??
ocsenave@347 1333
ocsenave@347 1334 ;; note: DD4D spells out pokemon vital stat names ("speed", etc.)
ocsenave@347 1335
ocsenave@347 1336 ;; note: 1195C-6A says ABLE#NOT ABLE#, but so does 119C0-119CE.
ocsenave@347 1337 ;; The first instance is for Machines; the second, for stones.
ocsenave@347 1338
ocsenave@347 1339 ;; 0x251A (in indexable mem): image decompression routine seems to begin here.
ocsenave@347 1340
ocsenave@347 1341
ocsenave@347 1342 (comment
ocsenave@347 1343
ocsenave@347 1344 (def hxc-later
ocsenave@347 1345 "Running this code produces, e.g. hardcoded names NPCs give
ocsenave@347 1346 their pokemon. Will sort through it later."
ocsenave@347 1347 (print (character-codes->str(take 10000
ocsenave@347 1348 (drop 0x71597
ocsenave@347 1349 (rom (root)))))))
ocsenave@347 1350
ocsenave@347 1351 (let [dex
ocsenave@347 1352 (partition-by #(= 0x50 %)
ocsenave@347 1353 (take 2540
ocsenave@347 1354 (drop 0x40687
ocsenave@347 1355 (rom (root)))))]
ocsenave@347 1356 (def dex dex)
ocsenave@347 1357 (def hxc-species
ocsenave@347 1358 (map character-codes->str
ocsenave@347 1359 (take-nth 4 dex))))
ocsenave@347 1360 )
ocsenave@347 1361
ocsenave@347 1362
ocsenave@347 1363 #+end_src
ocsenave@347 1364
ocsenave@348 1365 #+results:
ocsenave@348 1366 : nil
ocsenave@348 1367