annotate org/rom.org @ 470:c02108ddcb35

Added introduction.
author Dylan Holmes <ocsenave@gmail.com>
date Sun, 29 Apr 2012 19:48:43 -0500
parents 13165fb5852b
children 5f87c3e46c22
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@419 4 #+description: A detailed explication of Pok\eacute{}mon Yellow, helped by Clojure.
ocsenave@419 5 #+keywords: pokemon, pokemon yellow, rom, gameboy, assembly, hex, pointers, clojure
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@470 14 This article contains the results of my investigations with
ocsenave@470 15 Pok\eacute{}mon Yellow as I searched for interesting
ocsenave@470 16 data in the ROM. By using the Clojure language interface
ocsenave@470 17 written by Robert[fn::This Clojure interface will be published to aurellem.org soon.], I
ocsenave@470 18 was able to interact with the game in real-time, sending commands and
ocsenave@470 19 gathering data. The result is a manifestly accurate map of
ocsenave@470 20 Pok\eacute{}mon Yellow; every result
ocsenave@470 21 comes with runnable code that /works/. You can see the code and the output of
ocsenave@470 22 every function and confirm for yourself that they are all correct. I
ocsenave@470 23 hope you like the result!
ocsenave@470 24
ocsenave@470 25 To orient yourself, you can look for a specific topic in the table of contents
ocsenave@470 26 above, or browse the [[#sec-9-1][map of the ROM]], below.
ocsenave@470 27
ocsenave@470 28
ocsenave@470 29 (If you have any questions or comments, please e-mail =rlm@mit.edu=)
ocsenave@470 30
ocsenave@347 31
ocsenave@348 32 ** COMMENT Getting linguistic data: names, words, etc.
ocsenave@348 33
ocsenave@348 34 Some of the simplest data
ocsenave@348 35
ocsenave@348 36
ocsenave@348 37 One of the simplest data structures in the Pok\eacute{} ROM is an
ocsenave@348 38 unbroken list of strings that either (a) all have a specific length,
ocsenave@348 39 or (b) are all separated by the same character.
ocsenave@348 40
ocsenave@348 41 Because lots of good data has this format, we'll start by writing a
ocsenave@348 42 template function to extract it:
ocsenave@348 43
ocsenave@348 44 #+name: hxc-thunks
ocsenave@348 45 #+begin_src clojure :results silent
ocsenave@348 46 (defn hxc-thunk
ocsenave@348 47 "Creates a thunk (nullary fn) that grabs data in a certain region of rom and
ocsenave@348 48 splits it into a collection by 0x50. If rom is not supplied, uses the
ocsenave@348 49 original rom data."
ocsenave@348 50 [start length]
ocsenave@348 51 (fn self
ocsenave@348 52 ([rom]
ocsenave@348 53 (take-nth 2
ocsenave@348 54 (partition-by #(= % 0x50)
ocsenave@348 55 (take length
ocsenave@348 56 (drop start rom)))))
ocsenave@348 57 ([]
ocsenave@348 58 (self com.aurellem.gb.gb-driver/original-rom))))
ocsenave@348 59
ocsenave@348 60 (def hxc-thunk-words
ocsenave@348 61 "Same as hxc-thunk, except it interprets the rom data as characters,
ocsenave@348 62 returning a collection of strings."
ocsenave@348 63 (comp
ocsenave@348 64 (partial comp (partial map character-codes->str))
ocsenave@348 65 hxc-thunk))
ocsenave@348 66
ocsenave@348 67 #+end_src
ocsenave@348 68
ocsenave@348 69
ocsenave@348 70 * Pok\eacute{}mon I
ocsenave@348 71 ** Names of each species
ocsenave@348 72 The names of the Pok\eacute{}mon species are stored in
ocsenave@348 73 ROM@E8000. This name list is interesting, for a number of reasons:
ocsenave@348 74 - The names are stored in [[ ][internal order]] rather than in the familiar
ocsenave@348 75 Pok\eacute{}dex order. This seemingly random order probably represents the order in which the authors created or
ocsenave@348 76 programmed in the Pok\eacute{}mon; it's used throughout the game.
ocsenave@348 77 - There is enough space allocated for 190 Pok\eacute{}mon. As I
ocsenave@348 78 understand it, there were originally going to be 190 Pok\eacute{}mon
ocsenave@348 79 in Generation I, but the creators decided to defer some to
ocsenave@348 80 Generation II. This explains why many Gen I and Gen II Pok\eacute{}mon
ocsenave@348 81 have the same aesthetic feel.
ocsenave@348 82 - The list is pockmarked with random gaps, due to the strange internal
ocsenave@348 83 ordering
ocsenave@348 84 and the 39 unused spaces [fn::190 allocated spaces minus 151 true Pok\eacute{}mon]. These missing spaces are filled with the
ocsenave@348 85 placeholder name =MISSINGNO.= (\ldquo{}Missing number\rdquo{}).
ocsenave@348 86
ocsenave@348 87 Each name is exactly ten letters long; whenever a name would be too short, the extra
ocsenave@348 88 space is padded with the character 0x50.
ocsenave@348 89
ocsenave@348 90 *** See the data
ocsenave@348 91
ocsenave@348 92 Here you can see the raw data in three stages: in the first stage, we
ocsenave@348 93 just grab the first few bytes starting from position 0xE8000. In the
ocsenave@371 94 second stage, we partition the bytes into ten-letter chunks to show you
ocsenave@348 95 where the names begin and end. In the final stage, we convert each
ocsenave@348 96 byte into the letter it represents using the =character-codes->str=
ocsenave@348 97 function. (0x50 is rendered as the symbol \ldquo{} =#= \rdquo{} for
ocsenave@348 98 ease of reading).
ocsenave@348 99
ocsenave@348 100 #+begin_src clojure :exports both :cache no :results output
ocsenave@348 101 (ns com.aurellem.gb.hxc
ocsenave@348 102 (:use (com.aurellem.gb assembly characters gb-driver util mem-util
ocsenave@348 103 constants))
ocsenave@348 104 (:import [com.aurellem.gb.gb_driver SaveState]))
ocsenave@348 105
ocsenave@371 106
ocsenave@348 107 (println (take 100 (drop 0xE8000 (rom))))
ocsenave@348 108
ocsenave@348 109 (println (partition 10 (take 100 (drop 0xE8000 (rom)))))
ocsenave@348 110
ocsenave@348 111 (println (character-codes->str (take 100 (drop 0xE8000 (rom)))))
ocsenave@348 112
ocsenave@348 113
ocsenave@348 114 #+end_src
ocsenave@348 115
ocsenave@348 116 #+results:
ocsenave@348 117 : (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 118 : ((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 119 : RHYDON####KANGASKHANNIDORAN♂##CLEFAIRY##SPEAROW###VOLTORB###NIDOKING##SLOWBRO###IVYSAUR###EXEGGUTOR#
ocsenave@348 120
ocsenave@348 121
ocsenave@348 122 *** Automatically grab the data.
ocsenave@348 123
ocsenave@348 124 #+name: pokenames
ocsenave@348 125 #+begin_src clojure
ocsenave@348 126
ocsenave@348 127 (defn hxc-pokenames-raw
ocsenave@348 128 "The hardcoded names of the 190 species in memory. List begins at
ocsenave@348 129 ROM@E8000. Although names in memory are padded with 0x50 to be 10 characters
ocsenave@348 130 long, these names are stripped of padding. See also, hxc-pokedex-names"
ocsenave@348 131 ([]
ocsenave@348 132 (hxc-pokenames-raw com.aurellem.gb.gb-driver/original-rom))
ocsenave@348 133 ([rom]
ocsenave@348 134 (let [count-species 190
ocsenave@348 135 name-length 10]
ocsenave@348 136 (map character-codes->str
ocsenave@348 137 (partition name-length
ocsenave@348 138 (map #(if (= 0x50 %) 0x00 %)
ocsenave@348 139 (take (* count-species name-length)
ocsenave@348 140 (drop 0xE8000
ocsenave@348 141 rom))))))))
ocsenave@348 142 (def hxc-pokenames
ocsenave@348 143 (comp
ocsenave@348 144 (partial map format-name)
ocsenave@348 145 hxc-pokenames-raw))
ocsenave@348 146
ocsenave@348 147
ocsenave@348 148
ocsenave@348 149
ocsenave@348 150 (defn hxc-pokedex-names
ocsenave@411 151 "The names of the pokemon in hardcoded pokedex order. List of the
ocsenave@411 152 pokedex numbers of each pokemon (in internal order) begins at
ocsenave@348 153 ROM@410B1. See also, hxc-pokenames."
ocsenave@348 154 ([] (hxc-pokedex-names
ocsenave@348 155 com.aurellem.gb.gb-driver/original-rom))
ocsenave@348 156 ([rom]
ocsenave@348 157 (let [names (hxc-pokenames rom)]
ocsenave@348 158 (#(mapv %
ocsenave@348 159 ((comp range count keys) %))
ocsenave@348 160 (zipmap
ocsenave@348 161 (take (count names)
ocsenave@348 162 (drop 0x410b1 rom))
ocsenave@348 163
ocsenave@348 164 names)))))
ocsenave@348 165
ocsenave@348 166 #+end_src
ocsenave@348 167
ocsenave@348 168
ocsenave@348 169
ocsenave@348 170 ** Generic species information
ocsenave@348 171
ocsenave@348 172 #+name: pokebase
ocsenave@348 173 #+begin_src clojure
ocsenave@348 174 (defn hxc-pokemon-base
ocsenave@348 175 ([] (hxc-pokemon-base com.aurellem.gb.gb-driver/original-rom))
ocsenave@348 176 ([rom]
ocsenave@348 177 (let [entry-size 28
ocsenave@371 178
ocsenave@348 179 pokemon (rest (hxc-pokedex-names))
ocsenave@371 180 pkmn-count (inc(count pokemon))
ocsenave@348 181 types (apply assoc {}
ocsenave@348 182 (interleave
ocsenave@348 183 (range)
ocsenave@348 184 pkmn-types)) ;;!! softcoded
ocsenave@348 185 moves (apply assoc {}
ocsenave@348 186 (interleave
ocsenave@348 187 (range)
ocsenave@348 188 (map format-name
ocsenave@348 189 (hxc-move-names rom))))
ocsenave@348 190 machines (hxc-machines)
ocsenave@348 191 ]
ocsenave@348 192 (zipmap
ocsenave@348 193 pokemon
ocsenave@348 194 (map
ocsenave@348 195 (fn [[n
ocsenave@348 196 rating-hp
ocsenave@348 197 rating-atk
ocsenave@348 198 rating-def
ocsenave@348 199 rating-speed
ocsenave@348 200 rating-special
ocsenave@348 201 type-1
ocsenave@348 202 type-2
ocsenave@348 203 rarity
ocsenave@348 204 rating-xp
ocsenave@348 205 pic-dimensions ;; tile_width|tile_height (8px/tile)
ocsenave@348 206 ptr-pic-obverse-1
ocsenave@348 207 ptr-pic-obverse-2
ocsenave@348 208 ptr-pic-reverse-1
ocsenave@348 209 ptr-pic-reverse-2
ocsenave@348 210 move-1
ocsenave@348 211 move-2
ocsenave@348 212 move-3
ocsenave@348 213 move-4
ocsenave@348 214 growth-rate
ocsenave@348 215 &
ocsenave@348 216 TMs|HMs]]
ocsenave@348 217 (let
ocsenave@348 218 [base-moves
ocsenave@348 219 (mapv moves
ocsenave@348 220 ((comp
ocsenave@348 221 ;; since the game uses zero as a delimiter,
ocsenave@348 222 ;; it must also increment all move indices by 1.
ocsenave@348 223 ;; heren we decrement to correct this.
ocsenave@348 224 (partial map dec)
ocsenave@348 225 (partial take-while (comp not zero?)))
ocsenave@348 226 [move-1 move-2 move-3 move-4]))
ocsenave@348 227
ocsenave@348 228 types
ocsenave@348 229 (set (list (types type-1)
ocsenave@348 230 (types type-2)))
ocsenave@348 231 TMs|HMs
ocsenave@348 232 (map
ocsenave@348 233 (comp
ocsenave@348 234 (partial map first)
ocsenave@348 235 (partial remove (comp zero? second)))
ocsenave@348 236 (split-at
ocsenave@348 237 50
ocsenave@348 238 (map vector
ocsenave@348 239 (rest(range))
ocsenave@348 240 (reduce concat
ocsenave@348 241 (map
ocsenave@348 242 #(take 8
ocsenave@348 243 (concat (bit-list %)
ocsenave@348 244 (repeat 0)))
ocsenave@348 245
ocsenave@348 246 TMs|HMs)))))
ocsenave@348 247
ocsenave@348 248 TMs (vec (first TMs|HMs))
ocsenave@348 249 HMs (take 5 (map (partial + -50) (vec (second TMs|HMs))))
ocsenave@348 250
ocsenave@348 251
ocsenave@348 252 ]
ocsenave@348 253
ocsenave@348 254
ocsenave@348 255 {:dex# n
ocsenave@348 256 :base-moves base-moves
ocsenave@348 257 :types types
ocsenave@348 258 :TMs TMs
ocsenave@348 259 :HMs HMs
ocsenave@348 260 :base-hp rating-hp
ocsenave@348 261 :base-atk rating-atk
ocsenave@348 262 :base-def rating-def
ocsenave@348 263 :base-speed rating-speed
ocsenave@348 264 :base-special rating-special
ocsenave@348 265 :o0 pic-dimensions
ocsenave@348 266 :o1 ptr-pic-obverse-1
ocsenave@348 267 :o2 ptr-pic-obverse-2
ocsenave@348 268 }))
ocsenave@348 269
ocsenave@348 270 (partition entry-size
ocsenave@348 271 (take (* entry-size pkmn-count)
ocsenave@348 272 (drop 0x383DE
ocsenave@348 273 rom))))))))
ocsenave@348 274
ocsenave@348 275 #+end_src
ocsenave@348 276
ocsenave@348 277
ocsenave@348 278 ** Pok\eacute{}mon evolutions
ocsenave@348 279 #+name: evolution-header
ocsenave@348 280 #+begin_src clojure
ocsenave@348 281 (defn format-evo
ocsenave@348 282 "Parse a sequence of evolution data, returning a map. First is the
ocsenave@348 283 method: 0 = end-evolution-data. 1 = level-up, 2 = item, 3 = trade. Next is an item id, if the
ocsenave@348 284 method of evolution is by item (only stones will actually make pokemon
ocsenave@348 285 evolve, for some auxillary reason.) Finally, the minimum level for
ocsenave@348 286 evolution to occur (level 1 means no limit, which is used for trade
ocsenave@348 287 and item evolutions), followed by the internal id of the pokemon
ocsenave@348 288 into which to evolve. Hence, level up and trade evolutions are
ocsenave@348 289 described with 3
ocsenave@348 290 bytes; item evolutions with four."
ocsenave@348 291 [coll]
ocsenave@348 292 (let [method (first coll)]
ocsenave@348 293 (cond (empty? coll) []
ocsenave@348 294 (= 0 method) [] ;; just in case
ocsenave@348 295 (= 1 method) ;; level-up evolution
ocsenave@348 296 (conj (format-evo (drop 3 coll))
ocsenave@348 297 {:method :level-up
ocsenave@348 298 :min-level (nth coll 1)
ocsenave@348 299 :into (dec (nth coll 2))})
ocsenave@348 300
ocsenave@348 301 (= 2 method) ;; item evolution
ocsenave@348 302 (conj (format-evo (drop 4 coll))
ocsenave@348 303 {:method :item
ocsenave@348 304 :item (dec (nth coll 1))
ocsenave@348 305 :min-level (nth coll 2)
ocsenave@348 306 :into (dec (nth coll 3))})
ocsenave@348 307
ocsenave@348 308 (= 3 method) ;; trade evolution
ocsenave@348 309 (conj (format-evo (drop 3 coll))
ocsenave@348 310 {:method :trade
ocsenave@348 311 :min-level (nth coll 1) ;; always 1 for trade.
ocsenave@348 312 :into (dec (nth coll 2))}))))
ocsenave@348 313
ocsenave@348 314
ocsenave@348 315 (defn hxc-ptrs-evolve
ocsenave@348 316 "A hardcoded collection of 190 pointers to alternating evolution/learnset data,
ocsenave@348 317 in internal order."
ocsenave@348 318 ([]
ocsenave@348 319 (hxc-ptrs-evolve com.aurellem.gb.gb-driver/original-rom))
ocsenave@348 320 ([rom]
ocsenave@348 321 (let [
ocsenave@348 322 pkmn-count (count (hxc-pokenames-raw)) ;; 190
ocsenave@348 323 ptrs
ocsenave@348 324 (map (fn [[a b]] (low-high a b))
ocsenave@348 325 (partition 2
ocsenave@348 326 (take (* 2 pkmn-count)
ocsenave@348 327 (drop 0x3b1e5 rom))))]
ocsenave@348 328 (map (partial + 0x34000) ptrs)
ocsenave@348 329
ocsenave@348 330 )))
ocsenave@348 331 #+end_src
ocsenave@348 332
ocsenave@348 333 #+name:evolution
ocsenave@348 334 #+begin_src clojure
ocsenave@348 335
ocsenave@348 336 (defn hxc-evolution
ocsenave@348 337 "Hardcoded evolution data in memory. The data exists at ROM@34000,
ocsenave@348 338 sorted by internal order. Pointers to the data exist at ROM@3B1E5; see also, hxc-ptrs-evolve."
ocsenave@348 339 ([] (hxc-evolution com.aurellem.gb.gb-driver/original-rom))
ocsenave@348 340 ([rom]
ocsenave@348 341 (apply assoc {}
ocsenave@348 342 (interleave
ocsenave@348 343 (hxc-pokenames rom)
ocsenave@348 344 (map
ocsenave@348 345 (comp
ocsenave@348 346 format-evo
ocsenave@348 347 (partial take-while (comp not zero?))
ocsenave@348 348 #(drop % rom))
ocsenave@348 349 (hxc-ptrs-evolve rom)
ocsenave@348 350 )))))
ocsenave@348 351
ocsenave@348 352 (defn hxc-evolution-pretty
ocsenave@348 353 "Like hxc-evolution, except it uses the names of items and pokemon
ocsenave@348 354 --- grabbed from ROM --- rather than their numerical identifiers."
ocsenave@348 355 ([] (hxc-evolution-pretty com.aurellem.gb.gb-driver/original-rom))
ocsenave@348 356 ([rom]
ocsenave@348 357 (let
ocsenave@348 358 [poke-names (vec (hxc-pokenames rom))
ocsenave@348 359 item-names (vec (hxc-items rom))
ocsenave@348 360 use-names
ocsenave@348 361 (fn [m]
ocsenave@348 362 (loop [ks (keys m) new-map m]
ocsenave@348 363 (let [k (first ks)]
ocsenave@348 364 (cond (nil? ks) new-map
ocsenave@348 365 (= k :into)
ocsenave@348 366 (recur
ocsenave@348 367 (next ks)
ocsenave@348 368 (assoc new-map
ocsenave@348 369 :into
ocsenave@348 370 (poke-names
ocsenave@348 371 (:into
ocsenave@348 372 new-map))))
ocsenave@348 373 (= k :item)
ocsenave@348 374 (recur
ocsenave@348 375 (next ks)
ocsenave@348 376 (assoc new-map
ocsenave@348 377 :item
ocsenave@348 378 (item-names
ocsenave@348 379 (:item new-map))))
ocsenave@348 380 :else
ocsenave@348 381 (recur
ocsenave@348 382 (next ks)
ocsenave@348 383 new-map)
ocsenave@348 384 ))))]
ocsenave@348 385
ocsenave@348 386 (into {}
ocsenave@348 387 (map (fn [[pkmn evo-coll]]
ocsenave@348 388 [pkmn (map use-names evo-coll)])
ocsenave@348 389 (hxc-evolution rom))))))
ocsenave@348 390
ocsenave@348 391
ocsenave@348 392 #+end_src
ocsenave@348 393
ocsenave@348 394
ocsenave@348 395 ** Level-up moves (learnsets)
ocsenave@348 396 #+name: learnsets
ocsenave@348 397 #+begin_src clojure
ocsenave@348 398
ocsenave@348 399
ocsenave@348 400 (defn hxc-learnsets
ocsenave@348 401 "Hardcoded map associating pokemon names to lists of pairs [lvl
ocsenave@348 402 move] of abilities they learn as they level up. The data
ocsenave@348 403 exists at ROM@34000, sorted by internal order. Pointers to the data
ocsenave@348 404 exist at ROM@3B1E5; see also, hxc-ptrs-evolve"
ocsenave@348 405 ([] (hxc-learnsets com.aurellem.gb.gb-driver/original-rom))
ocsenave@348 406 ([rom]
ocsenave@348 407 (apply assoc
ocsenave@348 408 {}
ocsenave@348 409 (interleave
ocsenave@348 410 (hxc-pokenames rom)
ocsenave@348 411 (map (comp
ocsenave@348 412 (partial map
ocsenave@348 413 (fn [[lvl mv]] [lvl (dec mv)]))
ocsenave@348 414 (partial partition 2)
ocsenave@348 415 ;; keep the learnset data
ocsenave@348 416 (partial take-while (comp not zero?))
ocsenave@348 417 ;; skip the evolution data
ocsenave@348 418 rest
ocsenave@348 419 (partial drop-while (comp not zero?)))
ocsenave@348 420 (map #(drop % rom)
ocsenave@348 421 (hxc-ptrs-evolve rom)))))))
ocsenave@348 422
ocsenave@348 423 (defn hxc-learnsets-pretty
ocsenave@348 424 "Live hxc-learnsets except it reports the name of each move --- as
ocsenave@348 425 it appears in rom --- rather than the move index."
ocsenave@348 426 ([] (hxc-learnsets-pretty com.aurellem.gb.gb-driver/original-rom))
ocsenave@348 427 ([rom]
ocsenave@348 428 (let [moves (vec(map format-name (hxc-move-names)))]
ocsenave@348 429 (into {}
ocsenave@348 430 (map (fn [[pkmn learnset]]
ocsenave@348 431 [pkmn (map (fn [[lvl mv]] [lvl (moves mv)])
ocsenave@348 432 learnset)])
ocsenave@348 433 (hxc-learnsets rom))))))
ocsenave@348 434
ocsenave@348 435
ocsenave@348 436
ocsenave@348 437 #+end_src
ocsenave@348 438
ocsenave@348 439
ocsenave@348 440
ocsenave@348 441 * Pok\eacute{}mon II : the Pok\eacute{}dex
ocsenave@348 442 ** Species vital stats
ocsenave@348 443 #+name: dex-stats
ocsenave@348 444 #+begin_src clojure
ocsenave@348 445 (defn hxc-pokedex-stats
ocsenave@348 446 "The hardcoded pokedex stats (species height weight) in memory. List
ocsenave@348 447 begins at ROM@40687"
ocsenave@348 448 ([] (hxc-pokedex-stats com.aurellem.gb.gb-driver/original-rom))
ocsenave@348 449 ([rom]
ocsenave@348 450 (let [pokedex-names (zipmap (range) (hxc-pokedex-names rom))
ocsenave@348 451 pkmn-count (count pokedex-names)
ocsenave@348 452 ]
ocsenave@348 453 ((fn capture-stats
ocsenave@348 454 [n stats data]
ocsenave@348 455 (if (zero? n) stats
ocsenave@348 456 (let [[species
ocsenave@348 457 [_
ocsenave@348 458 height-ft
ocsenave@348 459 height-in
ocsenave@348 460 weight-1
ocsenave@348 461 weight-2
ocsenave@348 462 _
ocsenave@348 463 dex-ptr-1
ocsenave@348 464 dex-ptr-2
ocsenave@348 465 dex-bank
ocsenave@348 466 _
ocsenave@348 467 & data]]
ocsenave@348 468 (split-with (partial not= 0x50) data)]
ocsenave@348 469 (recur (dec n)
ocsenave@348 470 (assoc stats
ocsenave@348 471 (pokedex-names (- pkmn-count (dec n)))
ocsenave@348 472 {:species
ocsenave@348 473 (format-name (character-codes->str species))
ocsenave@348 474 :height-ft
ocsenave@348 475 height-ft
ocsenave@348 476 :height-in
ocsenave@348 477 height-in
ocsenave@348 478 :weight
ocsenave@348 479 (/ (low-high weight-1 weight-2) 10.)
ocsenave@348 480
ocsenave@348 481 ;; :text
ocsenave@348 482 ;; (character-codes->str
ocsenave@348 483 ;; (take-while
ocsenave@348 484 ;; (partial not= 0x50)
ocsenave@348 485 ;; (drop
ocsenave@348 486 ;; (+ 0xB8000
ocsenave@348 487 ;; -0x4000
ocsenave@348 488 ;; (low-high dex-ptr-1 dex-ptr-2))
ocsenave@348 489 ;; rom)))
ocsenave@348 490 })
ocsenave@348 491
ocsenave@348 492 data)
ocsenave@348 493
ocsenave@348 494
ocsenave@348 495 )))
ocsenave@348 496
ocsenave@348 497 pkmn-count
ocsenave@348 498 {}
ocsenave@348 499 (drop 0x40687 rom))) ))
ocsenave@348 500 #+end_src
ocsenave@348 501
ocsenave@411 502 #+results: dex-stats
ocsenave@411 503 : #'com.aurellem.gb.hxc/hxc-pokedex-stats
ocsenave@411 504
ocsenave@348 505 ** Species synopses
ocsenave@348 506
ocsenave@348 507 #+name: dex-text
ocsenave@348 508 #+begin_src clojure
ocsenave@348 509 (def hxc-pokedex-text-raw
ocsenave@348 510 "The hardcoded pokedex entries in memory. List begins at
ocsenave@348 511 ROM@B8000, shortly before move names."
ocsenave@348 512 (hxc-thunk-words 0xB8000 14754))
ocsenave@348 513
ocsenave@348 514
ocsenave@348 515
ocsenave@348 516
ocsenave@348 517 (defn hxc-pokedex-text
ocsenave@348 518 "The hardcoded pokedex entries in memory, presented as an
ocsenave@348 519 associative hash map. List begins at ROM@B8000."
ocsenave@348 520 ([] (hxc-pokedex-text com.aurellem.gb.gb-driver/original-rom))
ocsenave@348 521 ([rom]
ocsenave@348 522 (zipmap
ocsenave@348 523 (hxc-pokedex-names rom)
ocsenave@348 524 (cons nil ;; for missingno.
ocsenave@348 525 (hxc-pokedex-text-raw rom)))))
ocsenave@348 526 #+end_src
ocsenave@348 527
ocsenave@348 528
ocsenave@348 529 ** Pok\eacute{}mon cries
ocsenave@348 530 #+name: pokecry
ocsenave@348 531 #+begin_src clojure
ocsenave@348 532 (defn hxc-cry
ocsenave@348 533 "The pokemon cry data in internal order. List begins at ROM@39462"
ocsenave@348 534 ([](hxc-cry com.aurellem.gb.gb-driver/original-rom))
ocsenave@348 535 ([rom]
ocsenave@348 536 (zipmap
ocsenave@348 537 (hxc-pokenames rom)
ocsenave@348 538 (map
ocsenave@348 539 (fn [[cry-id pitch length]]
ocsenave@348 540 {:cry-id cry-id
ocsenave@348 541 :pitch pitch
ocsenave@348 542 :length length}
ocsenave@348 543 )
ocsenave@348 544 (partition 3
ocsenave@348 545 (drop 0x39462 rom))))))
ocsenave@348 546
ocsenave@348 547 (defn hxc-cry-groups
ocsenave@348 548 ([] (hxc-cry-groups com.aurellem.gb.gb-driver/original-rom))
ocsenave@348 549 ([rom]
ocsenave@348 550 (map #(mapv first
ocsenave@348 551 (filter
ocsenave@348 552 (fn [[k v]]
ocsenave@348 553 (= % (:cry-id v)))
ocsenave@348 554 (hxc-cry)))
ocsenave@348 555 ((comp
ocsenave@348 556 range
ocsenave@348 557 count
ocsenave@348 558 set
ocsenave@348 559 (partial map :cry-id)
ocsenave@348 560 vals
ocsenave@348 561 hxc-cry)
ocsenave@348 562 rom))))
ocsenave@348 563
ocsenave@348 564
ocsenave@348 565 (defn cry-conversion!
ocsenave@348 566 "Convert Porygon's cry in ROM to be the cry of the given pokemon."
ocsenave@348 567 [pkmn]
ocsenave@348 568 (write-rom!
ocsenave@348 569 (rewrite-memory
ocsenave@348 570 (vec(rom))
ocsenave@348 571 0x3965D
ocsenave@348 572 (map second
ocsenave@348 573 ((hxc-cry) pkmn)))))
ocsenave@348 574
ocsenave@348 575 #+end_src
ocsenave@348 576
ocsenave@348 577 ** COMMENT Names of permanent stats
ocsenave@348 578 0DD4D-DD72
ocsenave@348 579
ocsenave@348 580 * Items
ocsenave@348 581 ** Item names
ocsenave@371 582
ocsenave@371 583 *** See the data
ocsenave@371 584 #+begin_src clojure :exports both :results output
ocsenave@371 585 (ns com.aurellem.gb.hxc
ocsenave@371 586 (:use (com.aurellem.gb assembly characters gb-driver util mem-util
ocsenave@371 587 constants))
ocsenave@371 588 (:import [com.aurellem.gb.gb_driver SaveState]))
ocsenave@371 589
ocsenave@371 590 (println (take 100 (drop 0x045B7 (rom))))
ocsenave@371 591
ocsenave@371 592 (println
ocsenave@371 593 (partition-by
ocsenave@371 594 (partial = 0x50)
ocsenave@371 595 (take 100 (drop 0x045B7 (rom)))))
ocsenave@371 596
ocsenave@371 597 (println
ocsenave@371 598 (map character-codes->str
ocsenave@371 599 (partition-by
ocsenave@371 600 (partial = 0x50)
ocsenave@371 601 (take 100 (drop 0x045B7 (rom))))))
ocsenave@371 602
ocsenave@371 603
ocsenave@371 604 #+end_src
ocsenave@371 605
ocsenave@371 606 #+results:
ocsenave@371 607 : (140 128 146 147 132 145 127 129 128 139 139 80 148 139 147 145 128 127 129 128 139 139 80 134 145 132 128 147 127 129 128 139 139 80 143 142 138 186 127 129 128 139 139 80 147 142 150 141 127 140 128 143 80 129 136 130 152 130 139 132 80 230 230 230 230 230 80 146 128 133 128 145 136 127 129 128 139 139 80 143 142 138 186 131 132 151 80 140 142 142 141 127 146 147 142 141 132 80 128 141)
ocsenave@371 608 : ((140 128 146 147 132 145 127 129 128 139 139) (80) (148 139 147 145 128 127 129 128 139 139) (80) (134 145 132 128 147 127 129 128 139 139) (80) (143 142 138 186 127 129 128 139 139) (80) (147 142 150 141 127 140 128 143) (80) (129 136 130 152 130 139 132) (80) (230 230 230 230 230) (80) (146 128 133 128 145 136 127 129 128 139 139) (80) (143 142 138 186 131 132 151) (80) (140 142 142 141 127 146 147 142 141 132) (80) (128 141))
ocsenave@371 609 : (MASTER BALL # ULTRA BALL # GREAT BALL # POKĂ© BALL # TOWN MAP # BICYCLE # ????? # SAFARI BALL # POKĂ©DEX # MOON STONE # AN)
ocsenave@371 610
ocsenave@371 611 *** Automatically grab the data
ocsenave@348 612 #+name: item-names
ocsenave@348 613 #+begin_src clojure
ocsenave@348 614
ocsenave@348 615 (def hxc-items-raw
ocsenave@348 616 "The hardcoded names of the items in memory. List begins at
ocsenave@348 617 ROM@045B7"
ocsenave@348 618 (hxc-thunk-words 0x45B7 870))
ocsenave@348 619
ocsenave@348 620 (def hxc-items
ocsenave@348 621 "The hardcoded names of the items in memory, presented as
ocsenave@348 622 keywords. List begins at ROM@045B7. See also, hxc-items-raw."
ocsenave@348 623 (comp (partial map format-name) hxc-items-raw))
ocsenave@348 624 #+end_src
ocsenave@348 625
ocsenave@348 626 ** Item prices
ocsenave@371 627
ocsenave@371 628 ***
ocsenave@371 629 #+begin_src clojure :exports both :results output
ocsenave@371 630 (ns com.aurellem.gb.hxc
ocsenave@371 631 (:use (com.aurellem.gb assembly characters gb-driver util mem-util
ocsenave@371 632 constants))
ocsenave@371 633 (:import [com.aurellem.gb.gb_driver SaveState]))
ocsenave@371 634
ocsenave@371 635 (println (take 90 (drop 0x4495 (rom))))
ocsenave@371 636
ocsenave@371 637 (println
ocsenave@371 638 (partition 3
ocsenave@371 639 (take 90 (drop 0x4495 (rom)))))
ocsenave@371 640
ocsenave@371 641 (println
ocsenave@371 642 (partition 3
ocsenave@371 643 (map hex
ocsenave@371 644 (take 90 (drop 0x4495 (rom))))))
ocsenave@371 645
ocsenave@371 646 (println
ocsenave@371 647 (map decode-bcd
ocsenave@371 648 (map butlast
ocsenave@371 649 (partition 3
ocsenave@371 650 (take 90 (drop 0x4495 (rom)))))))
ocsenave@371 651
ocsenave@371 652 (println
ocsenave@371 653 (map
ocsenave@371 654 vector
ocsenave@371 655 (hxc-items (rom))
ocsenave@371 656 (map decode-bcd
ocsenave@371 657 (map butlast
ocsenave@371 658 (partition 3
ocsenave@371 659 (take 90 (drop 0x4495 (rom))))))))
ocsenave@371 660
ocsenave@371 661
ocsenave@371 662
ocsenave@371 663
ocsenave@371 664
ocsenave@371 665 #+end_src
ocsenave@371 666
ocsenave@371 667 #+results:
ocsenave@371 668 : (0 0 0 18 0 0 6 0 0 2 0 0 0 0 0 0 0 0 0 0 0 16 0 0 0 0 0 0 0 0 1 0 0 2 80 0 2 80 0 2 0 0 2 0 0 48 0 0 37 0 0 21 0 0 7 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5 80 0 3 80 0)
ocsenave@371 669 : ((0 0 0) (18 0 0) (6 0 0) (2 0 0) (0 0 0) (0 0 0) (0 0 0) (16 0 0) (0 0 0) (0 0 0) (1 0 0) (2 80 0) (2 80 0) (2 0 0) (2 0 0) (48 0 0) (37 0 0) (21 0 0) (7 0 0) (3 0 0) (0 0 0) (0 0 0) (0 0 0) (0 0 0) (0 0 0) (0 0 0) (0 0 0) (0 0 0) (5 80 0) (3 80 0))
ocsenave@371 670 : ((0x0 0x0 0x0) (0x12 0x0 0x0) (0x6 0x0 0x0) (0x2 0x0 0x0) (0x0 0x0 0x0) (0x0 0x0 0x0) (0x0 0x0 0x0) (0x10 0x0 0x0) (0x0 0x0 0x0) (0x0 0x0 0x0) (0x1 0x0 0x0) (0x2 0x50 0x0) (0x2 0x50 0x0) (0x2 0x0 0x0) (0x2 0x0 0x0) (0x30 0x0 0x0) (0x25 0x0 0x0) (0x15 0x0 0x0) (0x7 0x0 0x0) (0x3 0x0 0x0) (0x0 0x0 0x0) (0x0 0x0 0x0) (0x0 0x0 0x0) (0x0 0x0 0x0) (0x0 0x0 0x0) (0x0 0x0 0x0) (0x0 0x0 0x0) (0x0 0x0 0x0) (0x5 0x50 0x0) (0x3 0x50 0x0))
ocsenave@371 671 : (0 1200 600 200 0 0 0 1000 0 0 100 250 250 200 200 3000 2500 1500 700 300 0 0 0 0 0 0 0 0 550 350)
ocsenave@371 672 : ([:master-ball 0] [:ultra-ball 1200] [:great-ball 600] [:poké-ball 200] [:town-map 0] [:bicycle 0] [:????? 0] [:safari-ball 1000] [:pokédex 0] [:moon-stone 0] [:antidote 100] [:burn-heal 250] [:ice-heal 250] [:awakening 200] [:parlyz-heal 200] [:full-restore 3000] [:max-potion 2500] [:hyper-potion 1500] [:super-potion 700] [:potion 300] [:boulderbadge 0] [:cascadebadge 0] [:thunderbadge 0] [:rainbowbadge 0] [:soulbadge 0] [:marshbadge 0] [:volcanobadge 0] [:earthbadge 0] [:escape-rope 550] [:repel 350])
ocsenave@371 673
ocsenave@371 674
ocsenave@371 675 ***
ocsenave@348 676 #+name: item-prices
ocsenave@348 677 #+begin_src clojure
ocsenave@348 678 (defn hxc-item-prices
ocsenave@348 679 "The hardcoded list of item prices in memory. List begins at ROM@4495"
ocsenave@348 680 ([] (hxc-item-prices com.aurellem.gb.gb-driver/original-rom))
ocsenave@348 681 ([rom]
ocsenave@348 682 (let [items (hxc-items rom)
ocsenave@348 683 price-size 3]
ocsenave@348 684 (zipmap items
ocsenave@348 685 (map (comp
ocsenave@348 686 ;; zero-cost items are "priceless"
ocsenave@348 687 #(if (zero? %) :priceless %)
ocsenave@348 688 decode-bcd butlast)
ocsenave@348 689 (partition price-size
ocsenave@348 690 (take (* price-size (count items))
ocsenave@348 691 (drop 0x4495 rom))))))))
ocsenave@348 692 #+end_src
ocsenave@348 693 ** Vendor inventories
ocsenave@348 694
ocsenave@348 695 #+name: item-vendors
ocsenave@348 696 #+begin_src clojure
ocsenave@348 697 (defn hxc-shops
ocsenave@348 698 ([] (hxc-shops com.aurellem.gb.gb-driver/original-rom))
ocsenave@348 699 ([rom]
ocsenave@348 700 (let [items (zipmap (range) (hxc-items rom))
ocsenave@348 701
ocsenave@348 702 ;; temporarily softcode the TM items
ocsenave@348 703 items (into
ocsenave@348 704 items
ocsenave@348 705 (map (juxt identity
ocsenave@348 706 (comp keyword
ocsenave@348 707 (partial str "tm-")
ocsenave@348 708 (partial + 1 -200)
ocsenave@348 709 ))
ocsenave@348 710 (take 200 (drop 200 (range)))))
ocsenave@348 711
ocsenave@348 712 ]
ocsenave@348 713
ocsenave@348 714 ((fn parse-shop [coll [num-items & items-etc]]
ocsenave@348 715 (let [inventory (take-while
ocsenave@348 716 (partial not= 0xFF)
ocsenave@348 717 items-etc)
ocsenave@348 718 [separator & items-etc] (drop num-items (rest items-etc))]
ocsenave@348 719 (if (= separator 0x50)
ocsenave@348 720 (map (partial mapv (comp items dec)) (conj coll inventory))
ocsenave@348 721 (recur (conj coll inventory) items-etc)
ocsenave@348 722 )
ocsenave@348 723 ))
ocsenave@348 724
ocsenave@348 725 '()
ocsenave@348 726 (drop 0x233C rom))
ocsenave@348 727
ocsenave@348 728
ocsenave@348 729 )))
ocsenave@348 730 #+end_src
ocsenave@348 731
ocsenave@348 732 #+results: item-vendors
ocsenave@348 733 : #'com.aurellem.gb.hxc/hxc-shops
ocsenave@348 734
ocsenave@348 735
ocsenave@348 736
ocsenave@348 737 * Types
ocsenave@348 738 ** Names of types
ocsenave@406 739
ocsenave@406 740 *** COMMENT Pointers to type names
ocsenave@406 741 #+begin_src clojure :exports both :results output
ocsenave@406 742 (map (comp character-codes->str #(take-while (partial not= 80) (drop % (rom))) (partial + 0x20000) (partial apply low-high)) (partition 2 (take 54 (drop 0x27D63 (rom)))))
ocsenave@406 743 #+end_src
ocsenave@406 744
ocsenave@406 745
ocsenave@371 746 ***
ocsenave@371 747 #+begin_src clojure :exports both :results output
ocsenave@371 748 (ns com.aurellem.gb.hxc
ocsenave@371 749 (:use (com.aurellem.gb assembly characters gb-driver util mem-util
ocsenave@371 750 constants))
ocsenave@371 751 (:import [com.aurellem.gb.gb_driver SaveState]))
ocsenave@371 752
ocsenave@371 753 (println (take 90 (drop 0x27D99 (rom))))
ocsenave@371 754
ocsenave@371 755 (println
ocsenave@371 756 (partition-by (partial = 0x50)
ocsenave@371 757 (take 90 (drop 0x27D99 (rom)))))
ocsenave@371 758
ocsenave@371 759 (println
ocsenave@371 760 (map character-codes->str
ocsenave@371 761 (partition-by (partial = 0x50)
ocsenave@371 762 (take 90 (drop 0x27D99 (rom))))))
ocsenave@371 763
ocsenave@371 764 #+end_src
ocsenave@371 765
ocsenave@371 766 #+results:
ocsenave@371 767 : (141 142 145 140 128 139 80 133 136 134 135 147 136 141 134 80 133 139 152 136 141 134 80 143 142 136 146 142 141 80 133 136 145 132 80 150 128 147 132 145 80 134 145 128 146 146 80 132 139 132 130 147 145 136 130 80 143 146 152 130 135 136 130 80 136 130 132 80 134 145 142 148 141 131 80 145 142 130 138 80 129 136 145 131 80 129 148 134 80 134)
ocsenave@371 768 : ((141 142 145 140 128 139) (80) (133 136 134 135 147 136 141 134) (80) (133 139 152 136 141 134) (80) (143 142 136 146 142 141) (80) (133 136 145 132) (80) (150 128 147 132 145) (80) (134 145 128 146 146) (80) (132 139 132 130 147 145 136 130) (80) (143 146 152 130 135 136 130) (80) (136 130 132) (80) (134 145 142 148 141 131) (80) (145 142 130 138) (80) (129 136 145 131) (80) (129 148 134) (80) (134))
ocsenave@371 769 : (NORMAL # FIGHTING # FLYING # POISON # FIRE # WATER # GRASS # ELECTRIC # PSYCHIC # ICE # GROUND # ROCK # BIRD # BUG # G)
ocsenave@371 770
ocsenave@371 771
ocsenave@371 772 ***
ocsenave@348 773 #+name: type-names
ocsenave@348 774 #+begin_src clojure
ocsenave@348 775 (def hxc-types
ocsenave@348 776 "The hardcoded type names in memory. List begins at ROM@27D99,
ocsenave@348 777 shortly before hxc-titles."
ocsenave@348 778 (hxc-thunk-words 0x27D99 102))
ocsenave@348 779
ocsenave@348 780 #+end_src
ocsenave@348 781
ocsenave@348 782 ** Type effectiveness
ocsenave@371 783 ***
ocsenave@371 784 #+begin_src clojure :exports both :results output
ocsenave@371 785 (ns com.aurellem.gb.hxc
ocsenave@371 786 (:use (com.aurellem.gb assembly characters gb-driver util mem-util
ocsenave@371 787 constants))
ocsenave@371 788 (:import [com.aurellem.gb.gb_driver SaveState]))
ocsenave@371 789
ocsenave@371 790
ocsenave@371 791 ;; POKEMON TYPES
ocsenave@371 792
ocsenave@371 793 (println pkmn-types) ;; these are the pokemon types
ocsenave@371 794 (println (map vector (range) pkmn-types)) ;; each type has an id number.
ocsenave@371 795
ocsenave@371 796 (newline)
ocsenave@371 797
ocsenave@371 798
ocsenave@371 799
ocsenave@371 800
ocsenave@371 801 ;;; TYPE EFFECTIVENESS
ocsenave@371 802
ocsenave@371 803 (println (take 15 (drop 0x3E62D (rom))))
ocsenave@371 804 (println (partition 3 (take 15 (drop 0x3E62D (rom)))))
ocsenave@371 805
ocsenave@371 806 (println
ocsenave@371 807 (map
ocsenave@371 808 (fn [[atk-type def-type multiplier]]
ocsenave@371 809 (list atk-type def-type (/ multiplier 10.)))
ocsenave@371 810
ocsenave@371 811 (partition 3
ocsenave@371 812 (take 15 (drop 0x3E62D (rom))))))
ocsenave@371 813
ocsenave@371 814
ocsenave@371 815 (println
ocsenave@371 816 (map
ocsenave@371 817 (fn [[atk-type def-type multiplier]]
ocsenave@371 818 [
ocsenave@371 819 (get pkmn-types atk-type)
ocsenave@371 820 (get pkmn-types def-type)
ocsenave@371 821 (/ multiplier 10.)
ocsenave@371 822 ])
ocsenave@371 823
ocsenave@371 824 (partition 3
ocsenave@371 825 (take 15 (drop 0x3E62D (rom))))))
ocsenave@371 826
ocsenave@371 827 #+end_src
ocsenave@371 828
ocsenave@371 829 #+results:
ocsenave@371 830 : [:normal :fighting :flying :poison :ground :rock :bird :bug :ghost :A :B :C :D :E :F :G :H :I :J :K :fire :water :grass :electric :psychic :ice :dragon]
ocsenave@371 831 : ([0 :normal] [1 :fighting] [2 :flying] [3 :poison] [4 :ground] [5 :rock] [6 :bird] [7 :bug] [8 :ghost] [9 :A] [10 :B] [11 :C] [12 :D] [13 :E] [14 :F] [15 :G] [16 :H] [17 :I] [18 :J] [19 :K] [20 :fire] [21 :water] [22 :grass] [23 :electric] [24 :psychic] [25 :ice] [26 :dragon])
ocsenave@371 832 :
ocsenave@371 833 : (0 5 5 0 8 0 8 8 20 20 7 20 20 5 5)
ocsenave@371 834 : ((0 5 5) (0 8 0) (8 8 20) (20 7 20) (20 5 5))
ocsenave@371 835 : ((0 5 0.5) (0 8 0.0) (8 8 2.0) (20 7 2.0) (20 5 0.5))
ocsenave@371 836 : ([:normal :rock 0.5] [:normal :ghost 0.0] [:ghost :ghost 2.0] [:fire :bug 2.0] [:fire :rock 0.5])
ocsenave@371 837
ocsenave@371 838
ocsenave@371 839 ***
ocsenave@372 840
ocsenave@349 841 #+name: type-advantage
ocsenave@348 842 #+begin_src clojure
ocsenave@348 843 (defn hxc-advantage
ocsenave@348 844 ;; in-game multipliers are stored as 10x their effective value
ocsenave@348 845 ;; to allow for fractional multipliers like 1/2
ocsenave@348 846
ocsenave@348 847 "The hardcoded type advantages in memory, returned as tuples of
ocsenave@348 848 atk-type def-type multiplier. By default (i.e. if not listed here),
ocsenave@348 849 the multiplier is 1. List begins at 0x3E62D."
ocsenave@348 850 ([] (hxc-advantage com.aurellem.gb.gb-driver/original-rom))
ocsenave@348 851 ([rom]
ocsenave@348 852 (map
ocsenave@348 853 (fn [[atk def mult]] [(get pkmn-types atk (hex atk))
ocsenave@348 854 (get pkmn-types def (hex def))
ocsenave@348 855 (/ mult 10)])
ocsenave@348 856 (partition 3
ocsenave@348 857 (take-while (partial not= 0xFF)
ocsenave@348 858 (drop 0x3E62D rom))))))
ocsenave@348 859 #+end_src
ocsenave@348 860
ocsenave@348 861
ocsenave@348 862
ocsenave@348 863 * Moves
ocsenave@348 864 ** Names of moves
ocsenave@371 865 *** See the data
ocsenave@371 866 #+begin_src clojure :exports both :results output
ocsenave@371 867 (ns com.aurellem.gb.hxc
ocsenave@371 868 (:use (com.aurellem.gb assembly characters gb-driver util mem-util
ocsenave@371 869 constants))
ocsenave@371 870 (:import [com.aurellem.gb.gb_driver SaveState]))
ocsenave@371 871
ocsenave@371 872 (println (take 100 (drop 0xBC000 (rom))))
ocsenave@371 873
ocsenave@371 874 (println
ocsenave@371 875 (partition-by
ocsenave@371 876 (partial = 0x50)
ocsenave@371 877 (take 100 (drop 0xBC000 (rom)))))
ocsenave@371 878
ocsenave@371 879 (println
ocsenave@371 880 (map character-codes->str
ocsenave@371 881 (partition-by
ocsenave@371 882 (partial = 0x50)
ocsenave@371 883 (take 100 (drop 0xBC000 (rom))))))
ocsenave@371 884
ocsenave@371 885
ocsenave@371 886 #+end_src
ocsenave@371 887
ocsenave@371 888 #+results:
ocsenave@371 889 : (143 142 148 141 131 80 138 128 145 128 147 132 127 130 135 142 143 80 131 142 148 129 139 132 146 139 128 143 80 130 142 140 132 147 127 143 148 141 130 135 80 140 132 134 128 127 143 148 141 130 135 80 143 128 152 127 131 128 152 80 133 136 145 132 127 143 148 141 130 135 80 136 130 132 127 143 148 141 130 135 80 147 135 148 141 131 132 145 143 148 141 130 135 80 146 130 145 128 147 130)
ocsenave@371 890 : ((143 142 148 141 131) (80) (138 128 145 128 147 132 127 130 135 142 143) (80) (131 142 148 129 139 132 146 139 128 143) (80) (130 142 140 132 147 127 143 148 141 130 135) (80) (140 132 134 128 127 143 148 141 130 135) (80) (143 128 152 127 131 128 152) (80) (133 136 145 132 127 143 148 141 130 135) (80) (136 130 132 127 143 148 141 130 135) (80) (147 135 148 141 131 132 145 143 148 141 130 135) (80) (146 130 145 128 147 130))
ocsenave@371 891 : (POUND # KARATE CHOP # DOUBLESLAP # COMET PUNCH # MEGA PUNCH # PAY DAY # FIRE PUNCH # ICE PUNCH # THUNDERPUNCH # SCRATC)
ocsenave@371 892
ocsenave@371 893 *** Automatically grab the data
ocsenave@371 894
ocsenave@348 895 #+name: move-names
ocsenave@348 896 #+begin_src clojure
ocsenave@348 897 (def hxc-move-names
ocsenave@348 898 "The hardcoded move names in memory. List begins at ROM@BC000"
ocsenave@348 899 (hxc-thunk-words 0xBC000 1551))
ocsenave@348 900 #+end_src
ocsenave@348 901
ocsenave@348 902 ** Properties of moves
ocsenave@348 903
ocsenave@348 904 #+name: move-data
ocsenave@348 905 #+begin_src clojure
ocsenave@348 906 (defn hxc-move-data
ocsenave@348 907 "The hardcoded (basic (move effects)) in memory. List begins at
ocsenave@348 908 0x38000. Returns a map of {:name :power :accuracy :pp :fx-id
ocsenave@348 909 :fx-txt}. The move descriptions are handwritten, not hardcoded."
ocsenave@348 910 ([]
ocsenave@348 911 (hxc-move-data com.aurellem.gb.gb-driver/original-rom))
ocsenave@348 912 ([rom]
ocsenave@348 913 (let [names (vec (hxc-move-names rom))
ocsenave@348 914 move-count (count names)
ocsenave@348 915 move-size 6
ocsenave@348 916 types pkmn-types ;;; !! hardcoded types
ocsenave@348 917 ]
ocsenave@348 918 (zipmap (map format-name names)
ocsenave@348 919 (map
ocsenave@348 920 (fn [[idx effect power type-id accuracy pp]]
ocsenave@348 921 {:name (names (dec idx))
ocsenave@348 922 :power power
ocsenave@348 923 :accuracy accuracy
ocsenave@348 924 :pp pp
ocsenave@348 925 :type (types type-id)
ocsenave@348 926 :fx-id effect
ocsenave@348 927 :fx-txt (get move-effects effect)
ocsenave@348 928 }
ocsenave@348 929 )
ocsenave@348 930
ocsenave@348 931 (partition move-size
ocsenave@348 932 (take (* move-size move-count)
ocsenave@348 933 (drop 0x38000 rom))))))))
ocsenave@348 934
ocsenave@348 935
ocsenave@348 936
ocsenave@348 937 (defn hxc-move-data*
ocsenave@348 938 "Like hxc-move-data, but reports numbers as hexadecimal symbols instead."
ocsenave@348 939 ([]
ocsenave@348 940 (hxc-move-data* com.aurellem.gb.gb-driver/original-rom))
ocsenave@348 941 ([rom]
ocsenave@348 942 (let [names (vec (hxc-move-names rom))
ocsenave@348 943 move-count (count names)
ocsenave@348 944 move-size 6
ocsenave@348 945 format-name (fn [s]
ocsenave@348 946 (keyword (.toLowerCase
ocsenave@348 947 (apply str
ocsenave@348 948 (map #(if (= % \space) "-" %) s)))))
ocsenave@348 949 ]
ocsenave@348 950 (zipmap (map format-name names)
ocsenave@348 951 (map
ocsenave@348 952 (fn [[idx effect power type accuracy pp]]
ocsenave@348 953 {:name (names (dec idx))
ocsenave@348 954 :power power
ocsenave@348 955 :accuracy (hex accuracy)
ocsenave@348 956 :pp pp
ocsenave@348 957 :fx-id (hex effect)
ocsenave@348 958 :fx-txt (get move-effects effect)
ocsenave@348 959 }
ocsenave@348 960 )
ocsenave@348 961
ocsenave@348 962 (partition move-size
ocsenave@348 963 (take (* move-size move-count)
ocsenave@348 964 (drop 0x38000 rom))))))))
ocsenave@348 965
ocsenave@348 966 #+end_src
ocsenave@348 967
ocsenave@348 968 ** TM and HM moves
ocsenave@371 969 ***
ocsenave@371 970 #+begin_src clojure :exports both :results output
ocsenave@371 971 (ns com.aurellem.gb.hxc
ocsenave@371 972 (:use (com.aurellem.gb assembly characters gb-driver util mem-util
ocsenave@371 973 constants))
ocsenave@371 974 (:import [com.aurellem.gb.gb_driver SaveState]))
ocsenave@348 975
ocsenave@371 976
ocsenave@371 977 (println (hxc-move-names))
ocsenave@371 978 (println (map vector (rest(range)) (hxc-move-names)))
ocsenave@371 979
ocsenave@371 980 (newline)
ocsenave@371 981
ocsenave@371 982 (println (take 55 (drop 0x1232D (rom))))
ocsenave@371 983
ocsenave@371 984 (println
ocsenave@371 985 (interpose "."
ocsenave@371 986 (map
ocsenave@371 987 (zipmap (rest (range)) (hxc-move-names))
ocsenave@371 988 (take 55 (drop 0x1232D (rom))))))
ocsenave@371 989
ocsenave@371 990 #+end_src
ocsenave@371 991
ocsenave@371 992 #+results:
ocsenave@371 993 : (POUND KARATE CHOP DOUBLESLAP COMET PUNCH MEGA PUNCH PAY DAY FIRE PUNCH ICE PUNCH THUNDERPUNCH SCRATCH VICEGRIP GUILLOTINE RAZOR WIND SWORDS DANCE CUT GUST WING ATTACK WHIRLWIND FLY BIND SLAM VINE WHIP STOMP DOUBLE KICK MEGA KICK JUMP KICK ROLLING KICK SAND-ATTACK HEADBUTT HORN ATTACK FURY ATTACK HORN DRILL TACKLE BODY SLAM WRAP TAKE DOWN THRASH DOUBLE-EDGE TAIL WHIP POISON STING TWINEEDLE PIN MISSILE LEER BITE GROWL ROAR SING SUPERSONIC SONICBOOM DISABLE ACID EMBER FLAMETHROWER MIST WATER GUN HYDRO PUMP SURF ICE BEAM BLIZZARD PSYBEAM BUBBLEBEAM AURORA BEAM HYPER BEAM PECK DRILL PECK SUBMISSION LOW KICK COUNTER SEISMIC TOSS STRENGTH ABSORB MEGA DRAIN LEECH SEED GROWTH RAZOR LEAF SOLARBEAM POISONPOWDER STUN SPORE SLEEP POWDER PETAL DANCE STRING SHOT DRAGON RAGE FIRE SPIN THUNDERSHOCK THUNDERBOLT THUNDER WAVE THUNDER ROCK THROW EARTHQUAKE FISSURE DIG TOXIC CONFUSION PSYCHIC HYPNOSIS MEDITATE AGILITY QUICK ATTACK RAGE TELEPORT NIGHT SHADE MIMIC SCREECH DOUBLE TEAM RECOVER HARDEN MINIMIZE SMOKESCREEN CONFUSE RAY WITHDRAW DEFENSE CURL BARRIER LIGHT SCREEN HAZE REFLECT FOCUS ENERGY BIDE METRONOME MIRROR MOVE SELFDESTRUCT EGG BOMB LICK SMOG SLUDGE BONE CLUB FIRE BLAST WATERFALL CLAMP SWIFT SKULL BASH SPIKE CANNON CONSTRICT AMNESIA KINESIS SOFTBOILED HI JUMP KICK GLARE DREAM EATER POISON GAS BARRAGE LEECH LIFE LOVELY KISS SKY ATTACK TRANSFORM BUBBLE DIZZY PUNCH SPORE FLASH PSYWAVE SPLASH ACID ARMOR CRABHAMMER EXPLOSION FURY SWIPES BONEMERANG REST ROCK SLIDE HYPER FANG SHARPEN CONVERSION TRI ATTACK SUPER FANG SLASH SUBSTITUTE STRUGGLE)
ocsenave@371 994 : ([1 POUND] [2 KARATE CHOP] [3 DOUBLESLAP] [4 COMET PUNCH] [5 MEGA PUNCH] [6 PAY DAY] [7 FIRE PUNCH] [8 ICE PUNCH] [9 THUNDERPUNCH] [10 SCRATCH] [11 VICEGRIP] [12 GUILLOTINE] [13 RAZOR WIND] [14 SWORDS DANCE] [15 CUT] [16 GUST] [17 WING ATTACK] [18 WHIRLWIND] [19 FLY] [20 BIND] [21 SLAM] [22 VINE WHIP] [23 STOMP] [24 DOUBLE KICK] [25 MEGA KICK] [26 JUMP KICK] [27 ROLLING KICK] [28 SAND-ATTACK] [29 HEADBUTT] [30 HORN ATTACK] [31 FURY ATTACK] [32 HORN DRILL] [33 TACKLE] [34 BODY SLAM] [35 WRAP] [36 TAKE DOWN] [37 THRASH] [38 DOUBLE-EDGE] [39 TAIL WHIP] [40 POISON STING] [41 TWINEEDLE] [42 PIN MISSILE] [43 LEER] [44 BITE] [45 GROWL] [46 ROAR] [47 SING] [48 SUPERSONIC] [49 SONICBOOM] [50 DISABLE] [51 ACID] [52 EMBER] [53 FLAMETHROWER] [54 MIST] [55 WATER GUN] [56 HYDRO PUMP] [57 SURF] [58 ICE BEAM] [59 BLIZZARD] [60 PSYBEAM] [61 BUBBLEBEAM] [62 AURORA BEAM] [63 HYPER BEAM] [64 PECK] [65 DRILL PECK] [66 SUBMISSION] [67 LOW KICK] [68 COUNTER] [69 SEISMIC TOSS] [70 STRENGTH] [71 ABSORB] [72 MEGA DRAIN] [73 LEECH SEED] [74 GROWTH] [75 RAZOR LEAF] [76 SOLARBEAM] [77 POISONPOWDER] [78 STUN SPORE] [79 SLEEP POWDER] [80 PETAL DANCE] [81 STRING SHOT] [82 DRAGON RAGE] [83 FIRE SPIN] [84 THUNDERSHOCK] [85 THUNDERBOLT] [86 THUNDER WAVE] [87 THUNDER] [88 ROCK THROW] [89 EARTHQUAKE] [90 FISSURE] [91 DIG] [92 TOXIC] [93 CONFUSION] [94 PSYCHIC] [95 HYPNOSIS] [96 MEDITATE] [97 AGILITY] [98 QUICK ATTACK] [99 RAGE] [100 TELEPORT] [101 NIGHT SHADE] [102 MIMIC] [103 SCREECH] [104 DOUBLE TEAM] [105 RECOVER] [106 HARDEN] [107 MINIMIZE] [108 SMOKESCREEN] [109 CONFUSE RAY] [110 WITHDRAW] [111 DEFENSE CURL] [112 BARRIER] [113 LIGHT SCREEN] [114 HAZE] [115 REFLECT] [116 FOCUS ENERGY] [117 BIDE] [118 METRONOME] [119 MIRROR MOVE] [120 SELFDESTRUCT] [121 EGG BOMB] [122 LICK] [123 SMOG] [124 SLUDGE] [125 BONE CLUB] [126 FIRE BLAST] [127 WATERFALL] [128 CLAMP] [129 SWIFT] [130 SKULL BASH] [131 SPIKE CANNON] [132 CONSTRICT] [133 AMNESIA] [134 KINESIS] [135 SOFTBOILED] [136 HI JUMP KICK] [137 GLARE] [138 DREAM EATER] [139 POISON GAS] [140 BARRAGE] [141 LEECH LIFE] [142 LOVELY KISS] [143 SKY ATTACK] [144 TRANSFORM] [145 BUBBLE] [146 DIZZY PUNCH] [147 SPORE] [148 FLASH] [149 PSYWAVE] [150 SPLASH] [151 ACID ARMOR] [152 CRABHAMMER] [153 EXPLOSION] [154 FURY SWIPES] [155 BONEMERANG] [156 REST] [157 ROCK SLIDE] [158 HYPER FANG] [159 SHARPEN] [160 CONVERSION] [161 TRI ATTACK] [162 SUPER FANG] [163 SLASH] [164 SUBSTITUTE] [165 STRUGGLE])
ocsenave@371 995 :
ocsenave@371 996 : (5 13 14 18 25 92 32 34 36 38 61 55 58 59 63 6 66 68 69 99 72 76 82 85 87 89 90 91 94 100 102 104 115 117 118 120 121 126 129 130 135 138 143 156 86 149 153 157 161 164 15 19 57 70 148)
ocsenave@371 997 : (MEGA PUNCH . RAZOR WIND . SWORDS DANCE . WHIRLWIND . MEGA KICK . TOXIC . HORN DRILL . BODY SLAM . TAKE DOWN . DOUBLE-EDGE . BUBBLEBEAM . WATER GUN . ICE BEAM . BLIZZARD . HYPER BEAM . PAY DAY . SUBMISSION . COUNTER . SEISMIC TOSS . RAGE . MEGA DRAIN . SOLARBEAM . DRAGON RAGE . THUNDERBOLT . THUNDER . EARTHQUAKE . FISSURE . DIG . PSYCHIC . TELEPORT . MIMIC . DOUBLE TEAM . REFLECT . BIDE . METRONOME . SELFDESTRUCT . EGG BOMB . FIRE BLAST . SWIFT . SKULL BASH . SOFTBOILED . DREAM EATER . SKY ATTACK . REST . THUNDER WAVE . PSYWAVE . EXPLOSION . ROCK SLIDE . TRI ATTACK . SUBSTITUTE . CUT . FLY . SURF . STRENGTH . FLASH)
ocsenave@371 998
ocsenave@371 999
ocsenave@371 1000 ***
ocsenave@348 1001 #+name: machines
ocsenave@348 1002 #+begin_src clojure
ocsenave@348 1003 (defn hxc-machines
ocsenave@348 1004 "The hardcoded moves taught by TMs and HMs. List begins at ROM@1232D."
ocsenave@348 1005 ([] (hxc-machines
ocsenave@348 1006 com.aurellem.gb.gb-driver/original-rom))
ocsenave@348 1007 ([rom]
ocsenave@348 1008 (let [moves (hxc-move-names rom)]
ocsenave@348 1009 (zipmap
ocsenave@348 1010 (range)
ocsenave@348 1011 (take-while
ocsenave@348 1012 (comp not nil?)
ocsenave@348 1013 (map (comp
ocsenave@348 1014 format-name
ocsenave@348 1015 (zipmap
ocsenave@348 1016 (range)
ocsenave@348 1017 moves)
ocsenave@348 1018 dec)
ocsenave@348 1019 (take 100
ocsenave@348 1020 (drop 0x1232D rom))))))))
ocsenave@348 1021
ocsenave@348 1022 #+end_src
ocsenave@348 1023
ocsenave@348 1024
ocsenave@348 1025
ocsenave@348 1026
ocsenave@348 1027
ocsenave@348 1028 ** COMMENT Status ailments
ocsenave@348 1029
ocsenave@419 1030
ocsenave@419 1031 * NPC Trainers
ocsenave@419 1032
ocsenave@419 1033 ** Trainer Pok\eacute{}mon
ocsenave@419 1034 # http://hax.iimarck.us/topic/103/
ocsenave@419 1035 There are two formats for specifying lists of NPC PPok\eacute{}mon:
ocsenave@419 1036 - If all the Pok\eacute{}mon will have the same level, the format is
ocsenave@419 1037 - Level (used for all the Pok\eacute{}mon)
ocsenave@419 1038 - Any number of Pok\eacute{}mon internal ids.
ocsenave@419 1039 - 0x00, to indicate end-of-list.
ocsenave@419 1040 - Otherwise, all the Pok\eacute{}mon will have their level
ocsenave@419 1041 specified. The format is
ocsenave@419 1042 - 0xFF, to indicate that we will be specifying the levels individually[fn::Because 0xFF is a
ocsenave@419 1043 forbidden level within the usual gameplay discipline, the game
ocsenave@419 1044 makers could safely use 0xFF as a mode indicator.].
ocsenave@419 1045 - Any number of alternating Level/Pokemon pairs
ocsenave@419 1046 - 0x00, to indicate end-of-list.
ocsenave@419 1047
ocsenave@419 1048 *** Get the pointers
ocsenave@419 1049 *** See the data
ocsenave@419 1050 #+begin_src clojure :exports both :results output
ocsenave@419 1051 (ns com.aurellem.gb.hxc
ocsenave@419 1052 (:use (com.aurellem.gb assembly characters gb-driver util mem-util
ocsenave@419 1053 constants))
ocsenave@419 1054 (:import [com.aurellem.gb.gb_driver SaveState]))
ocsenave@419 1055
ocsenave@419 1056 (->>
ocsenave@419 1057 (rom)
ocsenave@419 1058 (drop 0x39E2F)
ocsenave@419 1059 (take 21)
ocsenave@419 1060 (println))
ocsenave@419 1061
ocsenave@419 1062
ocsenave@419 1063 (->>
ocsenave@419 1064 (rom)
ocsenave@419 1065 (drop 0x39E2F)
ocsenave@419 1066 (take 21)
ocsenave@419 1067 (partition-by zero?)
ocsenave@419 1068 (take-nth 2)
ocsenave@419 1069 (println))
ocsenave@419 1070
ocsenave@419 1071
ocsenave@419 1072
ocsenave@419 1073 (let
ocsenave@419 1074 [pokenames
ocsenave@419 1075 (zipmap
ocsenave@419 1076 (rest (range))
ocsenave@419 1077 (hxc-pokenames-raw))]
ocsenave@419 1078
ocsenave@419 1079 (->>
ocsenave@419 1080 (rom)
ocsenave@419 1081 (drop 0x39E2F)
ocsenave@419 1082 (take 21) ;; (1922 in all)
ocsenave@419 1083 (partition-by zero?)
ocsenave@419 1084 (take-nth 2)
ocsenave@419 1085 (map
ocsenave@419 1086 (fn parse-team [[mode & team]]
ocsenave@419 1087 (if (not= 0xFF mode)
ocsenave@419 1088 (mapv
ocsenave@419 1089 #(hash-map :level mode :species (pokenames %))
ocsenave@419 1090 team)
ocsenave@419 1091
ocsenave@419 1092 (mapv
ocsenave@419 1093 (fn [[lvl id]] (hash-map :level lvl :species (pokenames id)))
ocsenave@419 1094 (partition 2 team)))))
ocsenave@419 1095
ocsenave@419 1096 (println)))
ocsenave@419 1097
ocsenave@419 1098
ocsenave@419 1099
ocsenave@419 1100 #+end_src
ocsenave@419 1101
ocsenave@419 1102 #+results:
ocsenave@419 1103 : (11 165 108 0 14 5 0 10 165 165 107 0 14 165 108 107 0 15 165 5 0)
ocsenave@419 1104 : ((11 165 108) (14 5) (10 165 165 107) (14 165 108 107) (15 165 5))
ocsenave@419 1105 : ([{:species RATTATA, :level 11} {:species EKANS, :level 11}] [{:species SPEAROW, :level 14}] [{:species RATTATA, :level 10} {:species RATTATA, :level 10} {:species ZUBAT, :level 10}] [{:species RATTATA, :level 14} {:species EKANS, :level 14} {:species ZUBAT, :level 14}] [{:species RATTATA, :level 15} {:species SPEAROW, :level 15}])
ocsenave@419 1106
ocsenave@348 1107 * Places
ocsenave@348 1108 ** Names of places
ocsenave@348 1109
ocsenave@348 1110 #+name: places
ocsenave@348 1111 #+begin_src clojure
ocsenave@348 1112 (def hxc-places
ocsenave@348 1113 "The hardcoded place names in memory. List begins at
ocsenave@420 1114 ROM@71500. [Cinnabar/Celadon] Mansion seems to be dynamically calculated."
ocsenave@348 1115 (hxc-thunk-words 0x71500 560))
ocsenave@419 1116 #+end_src
ocsenave@348 1117
ocsenave@419 1118 *** See it work
ocsenave@419 1119 #+begin_src clojure :exports both :results output
ocsenave@419 1120 (println (hxc-places))
ocsenave@348 1121 #+end_src
ocsenave@348 1122
ocsenave@419 1123 #+results:
ocsenave@419 1124 : (PALLET TOWN VIRIDIAN CITY PEWTER CITY CERULEAN CITY LAVENDER TOWN VERMILION CITY CELADON CITY FUCHSIA CITY CINNABAR ISLAND INDIGO PLATEAU SAFFRON CITY ROUTE 1 ROUTE 2 ROUTE 3 ROUTE 4 ROUTE 5 ROUTE 6 ROUTE 7 ROUTE 8 ROUTE 9 ROUTE 10 ROUTE 11 ROUTE 12 ROUTE 13 ROUTE 14 ROUTE 15 ROUTE 16 ROUTE 17 ROUTE 18 SEA ROUTE 19 SEA ROUTE 20 SEA ROUTE 21 ROUTE 22 ROUTE 23 ROUTE 24 ROUTE 25 VIRIDIAN FOREST MT.MOON ROCK TUNNEL SEA COTTAGE S.S.ANNE [POKE]MON LEAGUE UNDERGROUND PATH [POKE]MON TOWER SEAFOAM ISLANDS VICTORY ROAD DIGLETT's CAVE ROCKET HQ SILPH CO. [0x4A] MANSION SAFARI ZONE)
ocsenave@419 1125
ocsenave@348 1126 ** Wild Pok\eacute{}mon demographics
ocsenave@348 1127 #+name: wilds
ocsenave@348 1128 #+begin_src clojure
ocsenave@348 1129
ocsenave@348 1130
ocsenave@348 1131
ocsenave@348 1132 (defn hxc-ptrs-wild
ocsenave@348 1133 "A list of the hardcoded wild encounter data in memory. Pointers
ocsenave@348 1134 begin at ROM@0CB95; data begins at ROM@0x04D89"
ocsenave@348 1135 ([] (hxc-ptrs-wild com.aurellem.gb.gb-driver/original-rom))
ocsenave@348 1136 ([rom]
ocsenave@348 1137 (let [ptrs
ocsenave@348 1138 (map (fn [[a b]] (+ a (* 0x100 b)))
ocsenave@348 1139 (take-while (partial not= (list 0xFF 0xFF))
ocsenave@348 1140 (partition 2 (drop 0xCB95 rom))))]
ocsenave@348 1141 ptrs)))
ocsenave@348 1142
ocsenave@348 1143
ocsenave@348 1144
ocsenave@348 1145 (defn hxc-wilds
ocsenave@348 1146 "A list of the hardcoded wild encounter data in memory. Pointers
ocsenave@348 1147 begin at ROM@0CB95; data begins at ROM@0x04D89"
ocsenave@348 1148 ([] (hxc-wilds com.aurellem.gb.gb-driver/original-rom))
ocsenave@348 1149 ([rom]
ocsenave@348 1150 (let [pokenames (zipmap (range) (hxc-pokenames rom))]
ocsenave@348 1151 (map
ocsenave@348 1152 (partial map (fn [[a b]] {:species (pokenames (dec b)) :level
ocsenave@348 1153 a}))
ocsenave@348 1154 (partition 10
ocsenave@348 1155
ocsenave@348 1156 (take-while (comp (partial not= 1)
ocsenave@348 1157 first)
ocsenave@348 1158 (partition 2
ocsenave@348 1159 (drop 0xCD8C rom))
ocsenave@348 1160
ocsenave@348 1161 ))))))
ocsenave@348 1162
ocsenave@348 1163 #+end_src
ocsenave@348 1164
ocsenave@348 1165
ocsenave@348 1166
ocsenave@348 1167
ocsenave@420 1168 ** Map data
ocsenave@420 1169
ocsenave@420 1170 # http://www.pokecommunity.com/showthread.php?t=235311
ocsenave@420 1171 # http://datacrystal.romhacking.net/wiki/Pokemon_Red/Blue:Notes
ocsenave@420 1172
ocsenave@420 1173 #+name map
ocsenave@420 1174 #+begin_src clojure :exports both :results output
ocsenave@420 1175 (ns com.aurellem.gb.hxc
ocsenave@420 1176 (:use (com.aurellem.gb assembly characters gb-driver util mem-util
ocsenave@420 1177 constants))
ocsenave@420 1178 (:import [com.aurellem.gb.gb_driver SaveState]))
ocsenave@420 1179
ocsenave@420 1180
ocsenave@420 1181 (defn parse-header-tileset
ocsenave@420 1182 [[bank# ;; memory bank for blocks & tileset
ocsenave@420 1183
ocsenave@420 1184 blocks-lo ;; structure
ocsenave@420 1185 blocks-hi
ocsenave@420 1186
ocsenave@420 1187 tileset-lo ;; style
ocsenave@420 1188 tileset-hi
ocsenave@420 1189
ocsenave@420 1190 collision-lo ;; collision info
ocsenave@420 1191 collision-hi
ocsenave@420 1192
ocsenave@420 1193 talk-here-1 ;; positions of up to three
ocsenave@420 1194 talk-here-2 ;; talk-over-countertop tiles
ocsenave@420 1195 talk-here-3 ;; --- 0xFF if unused.
ocsenave@420 1196
ocsenave@420 1197 grass ;; grass tile --- 0xFF if unused
ocsenave@420 1198
ocsenave@420 1199 animation-flags ;; settings for animation
ocsenave@420 1200 & _]]
ocsenave@420 1201
ocsenave@420 1202 [bank#
ocsenave@420 1203
ocsenave@420 1204 blocks-lo ;; structure
ocsenave@420 1205 blocks-hi
ocsenave@420 1206
ocsenave@420 1207 tileset-lo ;; style
ocsenave@420 1208 tileset-hi
ocsenave@420 1209
ocsenave@420 1210 collision-lo ;; collision info
ocsenave@420 1211 collision-hi
ocsenave@420 1212
ocsenave@420 1213 talk-here-1 ;; positions of up to three
ocsenave@420 1214 talk-here-2 ;; talk-over-countertop tiles
ocsenave@420 1215 talk-here-3 ;; --- 0xFF if unused.
ocsenave@420 1216
ocsenave@420 1217 grass ;; grass tile --- 0xFF if unused
ocsenave@420 1218
ocsenave@420 1219 animation-flags ;; settings for animation
ocsenave@420 1220 ])
ocsenave@420 1221
ocsenave@420 1222
ocsenave@420 1223
ocsenave@420 1224 (defn parse-header-map
ocsenave@420 1225 [start]
ocsenave@420 1226
ocsenave@420 1227 (let [connection-size 11
ocsenave@420 1228
ocsenave@420 1229 [tileset-index
ocsenave@420 1230 map-height
ocsenave@420 1231 map-width
ocsenave@420 1232 layout-lo
ocsenave@420 1233 layout-hi
ocsenave@420 1234 text-lo
ocsenave@420 1235 text-hi
ocsenave@420 1236 script-lo
ocsenave@420 1237 script-hi
ocsenave@420 1238 adjacency-flags ;; x x x x N S W E
ocsenave@420 1239 & etc]
ocsenave@420 1240 (drop start (rom))
ocsenave@420 1241
ocsenave@420 1242 [east? west? south? north?]
ocsenave@420 1243 (bit-list adjacency-flags)
ocsenave@420 1244
ocsenave@420 1245 [connections object-data]
ocsenave@420 1246 (split-at
ocsenave@420 1247 (* connection-size (+ east? west? south? north?))
ocsenave@420 1248 etc)
ocsenave@420 1249
ocsenave@420 1250 connections
ocsenave@420 1251 (partition connection-size connections)
ocsenave@420 1252
ocsenave@420 1253
ocsenave@420 1254
ocsenave@420 1255
ocsenave@420 1256 ]
ocsenave@420 1257 (ptr->offset
ocsenave@420 1258 3
ocsenave@420 1259 (low-high layout-lo layout-hi))
ocsenave@420 1260
ocsenave@420 1261
ocsenave@420 1262 ))
ocsenave@420 1263 #+end_src
ocsenave@420 1264
ocsenave@420 1265 #+results:
ocsenave@420 1266 :
ocsenave@420 1267
ocsenave@420 1268
ocsenave@348 1269
ocsenave@348 1270 * Appendices
ocsenave@347 1271 ** Mapping the ROM
ocsenave@420 1272 # D3AD: Script:Use Pokeball?
ocsenave@311 1273
ocsenave@411 1274 | ROM address (hex) | Description | Format | Example |
ocsenave@411 1275 |-----------------------+-----------------+-----------------+-----------------|
ocsenave@411 1276 | | <15> | <15> | <15> |
ocsenave@411 1277 | 01823-0184A | Important prefix strings. | Variable-length strings, separated by 0x50. | TM#TRAINER#PC#ROCKET#POK\eacute{}#... |
ocsenave@411 1278 | 0233C- | Shop inventories. | | |
ocsenave@412 1279 | 02F47- | (?) Move ids of some HM moves. | One byte per move id | 0x0F 0x13 0x39 0x46 0x94 0xFF, the move ids of CUT, FLY, SURF, STRENGTH, FLASH, then cancel. |
ocsenave@421 1280 | 03E59- | Start of the Give-Pok\eacute{}mon script. | Assembly. When called, converts the contents of register BC into a Pok\eacute{}mon: (B) is the level; (C) is the species. | |
ocsenave@421 1281 | 03E3F- | Start of the give-item script. | Assembly. When called, converts the contents of register BC into an item: (B) is the item type; (C) is the quantity. | |
ocsenave@411 1282 | 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@412 1283 | 04524-04527 | (unconfirmed) possibly the bike price in Cerulean. | | |
ocsenave@411 1284 | 045B7-0491E | Names of the items in memory. | Variable-length item names (strings of character codes). Names are separated by a single 0x50 character. | MASTER BALL#ULTRA BALL#... |
ocsenave@411 1285 | 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@412 1286 |-----------------------+-----------------+-----------------+-----------------|
ocsenave@412 1287 | 05DD2-05DF2 | Menu text for player info. | | PLAYER [newline] BADGES [nelwine] POK\Eacute{}DEX [newline] TIME [0x50] |
ocsenave@411 1288 | 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@411 1289 | 06698- | ? Background music. | | |
ocsenave@421 1290 |-----------------------+-----------------+-----------------+-----------------|
ocsenave@412 1291 | 7550-7570 | Menu options for map directions[fn:unused:According to [[http://tcrf.net/Pok%C3%A9mon_Red_and_Blue#NORTH.2FWEST.2FSOUTH.2FEAST][The Cutting Room Floor]], this data is unused. ]. | Variable-length strings. | NORTH [newline] WEST [0x50] SOUTH [newline] EAST [0x50] NORTH [newline] EAST[0x50] |
ocsenave@412 1292 | 7570-757D | Menu options for trading Pok\eacute{}mon | | TRADE [newline] CANCEL [0x50] |
ocsenave@412 1293 | 757D-758A | Menu options for healing Pok\eacute{}mon | | HEAL [newline] CANCEL [0x50] |
ocsenave@412 1294 | 7635- | Menu options for selected Pok\eacute{}mon (Includes names of out-of-battle moves). | Variable-length strings separated by 0x50. | CUT [0x50] FLY [0x50] SURF [0x50] STRENGTH [0x50] FLASH [0x50] DIG [0x50] TELEPORT [0x50] SOFTBOILED [0x50] STATS [newline] SWITCH [newline] CANCEL [0x50] |
ocsenave@412 1295 | 7AF0-8000 | (empty space) | | 0 0 0 0 0 ... |
ocsenave@411 1296 | 0822E-082F? | Pointers to background music, part I. | | |
ocsenave@411 1297 | 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@411 1298 |-----------------------+-----------------+-----------------+-----------------|
ocsenave@420 1299 | 0DACB. | Amount of HP restored by Soda Pop | The HP consists of a single numerical byte. | 60 |
ocsenave@420 1300 | 0DACF. | Amount of HP restored by Lemonade | " | 80 |
ocsenave@420 1301 | 0DAD5. | Amount of HP restored by Fresh Water | " | 50 |
ocsenave@420 1302 | 0DADB. | Amount of HP restored by Hyper Potion. | " | 200 |
ocsenave@411 1303 | 0DAE0. | Amount of HP restored by Super Potion. | " | 50 |
ocsenave@411 1304 | 0DAE3. | Amount of HP restored by Potion. | " | 20 |
ocsenave@411 1305 |-----------------------+-----------------+-----------------+-----------------|
ocsenave@411 1306 | 0DD4D-DD72 | Names of permanent stats. | Variable-length strings separated by 0x50. | #HEALTH#ATTACK#DEFENSE#SPEED#SPECIAL# |
ocsenave@420 1307 |-----------------------+-----------------+-----------------+-----------------|
ocsenave@421 1308 | 0DE2F. | Duration of Repel. | A single byte, representing the number of steps you can take before the effect wears off. | 100 |
ocsenave@420 1309 | 0DF39. | Duration of Super Repel. | " | 200 |
ocsenave@420 1310 | 0DF3E. | Duration of Max Repel. | " | 250 |
ocsenave@420 1311 |-----------------------+-----------------+-----------------+-----------------|
ocsenave@412 1312 | 1164B- | Terminology for the Pok\eacute{}mon menu. | Contiguous, variable-length strings. | TYPE1[newline]TYPE2[newline] *â„–*,[newline]OT,[newline][0x50]STATUS,[0x50]OK |
ocsenave@412 1313 | 116DE- | Terminology for permanent stats in the Pok\eacute{}mon menu. | Contiguous, variable-length strings. | ATTACK[newline]DEFENSE[newline]SPEED[newline]SPECIAL[0x50] |
ocsenave@412 1314 | 11852- | Terminology for current stats in the Pok\eacute{}mon menu. | Contiguous, variable-length strings. | EXP POINTS[newline]LEVEL UP[0x50] |
ocsenave@411 1315 | 1195C-1196A | The two terms for being able/unable to learn a TM/HM. | Variable-length strings separated by 0x50. | ABLE#NOT ABLE# |
ocsenave@411 1316 | 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@421 1317 |-----------------------+-----------------+-----------------+-----------------|
ocsenave@421 1318 | 11D53. | Which badge is a prerequisite for CUT? | op code: which bit of A to test? | When this script is called, the bits of A contain your badges, and this op code will check a certain bit of A. The op codes for the badges are, in order, [0x47 0x4F 0x57 0x5F 0x67 0x6F 0x77 0x7F]. |
ocsenave@421 1319 | 11D67. | Which badge is a prerequisite for SURF? | " | 0x67 (test for Soul Badge) |
ocsenave@421 1320 | 11DAC. | Which badge is a prerequisite for STRENGTH? | " | 0x5F (test for Rainbow Badge) |
ocsenave@421 1321 |-----------------------+-----------------+-----------------+-----------------|
ocsenave@411 1322 | 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@411 1323 |-----------------------+-----------------+-----------------+-----------------|
ocsenave@421 1324 | 1CF8B-1CF8C | Which Pok\eacute{}mon does Melanie give you in Cerulean City? | A level/internal-id pair. | (10 153), corresponding to a level 10 Bulbasaur. |
ocsenave@421 1325 | 1D651-1D652 | Which Pok\eacute{}mon do you find at the top of Celadon Mansion? | A level/internal-id pair. | (25 102), corresponding to a level 25 Eevee. |
ocsenave@421 1326 |-----------------------+-----------------+-----------------+-----------------|
ocsenave@411 1327 | 27D56 & 27D57. | Pointer to the pointers to type names. | A single low-byte, high-byte pair. | 0x63 0x7D, corresponding to location 27D63\mdash{} the start of the next entry. |
ocsenave@411 1328 | 27D63-27D99 | Pointers to type names. | Each point is a low-byte, high-byte pair. The type names follows immediately after this section; see below. | The first pointer is [0x99 0x7D], corresponding to the location 27D99 ("NORMAL"). |
ocsenave@411 1329 | 27D99-27DFF | Names of the Pok\eacute{}mon types. | Variable-length type names (strings of character codes). Names are separated by a single 0x50 character. | NORMAL#FIGHTING#... |
ocsenave@411 1330 | 27DFF-27E77 | ? | 120 bytes of unknown data. | |
ocsenave@411 1331 | 27E77- | Trainer title names. | Variable-length names separated by 0x50. | YOUNGSTER#BUG CATCHER#LASS#... |
ocsenave@411 1332 | 34000- | | | |
ocsenave@411 1333 | 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@411 1334 | 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@411 1335 | 39462- | The Pok\eacute{}mon cry data. | Fixed-length (3 byte) descriptions of cries. | |
ocsenave@411 1336 |-----------------------+-----------------+-----------------+-----------------|
ocsenave@411 1337 | 3997D-39B05 | Trainer titles (extended; see 27E77). This list includes strictly more trainers, seemingly at random inserted into the list from 27E77.[fn::The names added are in bold: YOUNGSTER, BUG CATCHER, LASS, *SAILOR*, JR TRAINER(m), JR TRAINER(f), POK\eacute{}MANIAC, SUPER NERD, *HIKER*, *BIKER*, BURGLAR, ENGINEER, JUGGLER, *FISHERMAN*, SWIMMER, *CUE BALL*, *GAMBLER*, BEAUTY, *PSYCHIC*, ROCKER, JUGGLER (again), *TAMER*, *BIRDKEEPER*, BLACKBELT, *RIVAL1*, PROF OAK, CHIEF, SCIENTIST, *GIOVANNI*, ROCKET, COOLTRAINER(m), COOLTRAINER(f), *BRUNO*, *BROCK*, *MISTY*, *LT. SURGE*, *ERIKA*, *KOGA*, *BLAINE*, *SABRINA*, *GENTLEMAN*, *RIVAL2*, *RIVAL3*, *LORELEI*, *CHANNELER*, *AGATHA*, *LANCE*.] | | |
ocsenave@412 1338 | 39B05-39DD0. | unknown | | |
ocsenave@419 1339 | 39DD1-39E2E | Pointers to trainer Pok\eacute{}mon | Pairs of low-high bits. | The first pair is 0x2F 0x5E, which corresponds to memory location 5E2F relative to this 38000-3C000 bank, i.e.[fn::For details about how relative bank pointers work, see the relevant Appendix.] position 39E2F overall. |
ocsenave@419 1340 | 39E2F-3A5B2 | Trainer Pok\eacute{}mon | Specially-formatted lists of various length, separated by 0x00. If the list starts with 0xFF, the rest of the list will alternate between levels and internal-ids. Otherwise, start of the list is the level of the whole team, and the rest of the list is internal-ids. | The first entry is (11 165 108 0), which means a level 11 team consisting of Rattata and Ekans. The entry for MISTY is (255 18 27 21 152 0), which means a team of various levels consisting of level 18 Staryu and level 21 Starmie. [fn::Incidentally, if you want to change your rival's starter Pok\eacute{}mon, it's enough just to change its species in all of your battles with him.].) |
ocsenave@411 1341 | 3B1E5-3B361 | Pointers to evolution/learnset data. | One high-low byte pair for each of the 190 Pok\eacute{}mon in internal order. | |
ocsenave@411 1342 |-----------------------+-----------------+-----------------+-----------------|
ocsenave@411 1343 | 3B361-3BBAA | 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@411 1344 | 3BBAA-3C000 | (empty) | | 0 0 0 0 ... |
ocsenave@411 1345 |-----------------------+-----------------+-----------------+-----------------|
ocsenave@412 1346 | 3D131-3D133 | The inventory of both OLD MAN and PROF. OAK when they battle for you. | Pairs of [item-id quantity], terminated by 0xFF. | (0x04 0x01 0xFF) They only have one Pok\eacute{}ball [fn::If you give them any ball, OAK will catch the enemy Pok\eacute{}mon and OLD MAN will miss. (OLD MAN misses even if he throws a MASTER BALL, which is a sight to see!) If you give them some other item first in the list, you'll be able to use that item normally but then you'll trigger the Safari Zone message: Pa will claim you're out of SAFARI BALLs and the battle will end. If you engage in either an OLD MAN or OAK battle with a Gym Leader, you will [1] get reprimanded if you try to throw a ball [2] incur the Safari Zone message [3] automatically win no matter which item you use [4] earn whichever reward they give you as usual [5] permanently retain the name OLD MAN / PROF. OAK.]. |
ocsenave@411 1347 | 3D6C7-3D6D6 | Two miscellaneous strings. | Variable length, separated by 0x50 | Disabled!#TYPE |
ocsenave@421 1348 | 3E190-3E194 | Which moves have an increased critical-hit ratio? | List of move ids, terminated by 0xFF. | (0x02 0x4B 0x98 0xA3 0xFF) corresponding to karate-chop, razor-leaf, crabhammer, slash, end-of-list. |
ocsenave@421 1349 | 3E200-3E204 | " (???) | " | " |
ocsenave@421 1350 | 3E231. | Besides normal-type, which type of move can COUNTER counter? | A single byte representing a type id. | This is set to 1, the id of the FIGHTING type. |
ocsenave@411 1351 |-----------------------+-----------------+-----------------+-----------------|
ocsenave@411 1352 | 40252-4027B | Pok\eacute{}dex menu text | Variable-length strings separated by 0x50. | SEEN#OWN#CONTENTS#... |
ocsenave@411 1353 | 40370-40386 | Important constants for Pok\eacute{}dex entries | | HT _ _ *?′??″* [newline] WT _ _ _ *???* lb [0x50] *POK\Eacute{}* [0x50] |
ocsenave@411 1354 | 40687-41072 | Species data from the Pok\eacute{}dex: species name, height, weight, etc. | Variable-length species names, followed by 0x50, followed by fixed-length height/weight/etc. data. | The first entry is (*146 132 132 131*, 80, *2 4*, *150 0*, 23, 0 64 46, 80), which are the the stats of Bulbasaur: the first entry spells "SEED", then 0x80, then the height (2' 4"), then the weight (formatted as a low-high byte pair), then various Pokédex pointer data (see elsewhere). |
ocsenave@411 1355 | 41072- | Pok\eacute{} placeholder species, "???" | | |
ocsenave@411 1356 |-----------------------+-----------------+-----------------+-----------------|
ocsenave@411 1357 | 410B1-4116F | A conversion table between internal order and Pokedex order. | 190 bytes, corresponding to the Pok\eacute{}dex numbers of the 190 Pok\eacute{}mon listed in internal order. All =MISSINGNO.= are assigned a Pok\eacute{}dex number of 0. | The first few entries are (112 115 32 35 21 100 34 80 2 ...), which are the Pok\eacute{}dex numbers of Rhydon, Kangaskhan, Nidoran(m), Clefairy, Spearow, Voltorb, Nidoking, Slobrow, and Ivysaur. |
ocsenave@420 1358 |-----------------------+-----------------+-----------------+-----------------|
ocsenave@420 1359 | 509B4-509E0 | Saffron City's adjacency info. | Four adjacency lists, each 11 bytes long. (For more info on adjacency lists a.k.a. connection data, see [[http://datacrystal.romhacking.net/wiki/Pokemon_Red/Blue:Notes][here]]) | The first adjacency list is (0x10 0x70 0x46 0xF0 0xC6 0x0A 0x0A 0x23 0xF6 0x09 0xC8) |
ocsenave@420 1360 |-----------------------+-----------------+-----------------+-----------------|
ocsenave@421 1361 | 515AE-515AF | Which Pok\eacute{}mon does the trainer near Route 25 give you? | A level/internal-id pair. | (10 176) corresponding to a level 10 Charmander. |
ocsenave@421 1362 | 51DD5-51DD6 | Which Pok\eacute{}mon does the Silph Co. trainer give you? | A level/internal-id pair. | (15 19) corresponding to a level 15 Lapras. |
ocsenave@421 1363 |-----------------------+-----------------+-----------------+-----------------|
ocsenave@412 1364 | 527BA-527DB | The costs and kinds of prizes from Celadon Game Corner. | The following pattern repeats three times, once per window[fn::For the first two prize lists, ids are interpreted as Pok\eacute{}mon ids. For the last prize list, ids are (somehow) interpreted as item ids.]: Internal ids / 0x50 / Prices (two bytes of BCD)/ 0x50. | (0x94 0x52 0x65 0x50) Abra Vulpix Wigglytuff (0x02 0x30 0x10 0x00 0x26 0x80) 230C, 1000C, 2680C |
ocsenave@411 1365 | 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@412 1366 |-----------------------+-----------------+-----------------+-----------------|
ocsenave@412 1367 | 70295- | Hall of fame | The text "HALL OF FAME" | |
ocsenave@412 1368 | 70442- | Play time/money | The text "PLAY TIME [0x50] MONEY" | |
ocsenave@411 1369 | 71500-7174B | Names of places. | Variable-length place names (strings), separated by 0x50. | PALLET TOWN#VIRIDIAN CITY#PEWTER CITY#CERULEAN CITY#... |
ocsenave@411 1370 | 71C1E-71CAA (approx.) | Tradeable NPC Pok\eacute{}mon. | Internal ID, followed by nickname (11 chars; extra space padded by 0x50). Some of the Pokemon have unknown extra data around the id. | The first entry is [0x76] "GURIO######", corresponding to a Dugtrio named "GURIO". |
ocsenave@411 1371 | 7C249-7C2?? | Pointers to background music, pt II. | | |
ocsenave@412 1372 |-----------------------+-----------------+-----------------+-----------------|
ocsenave@419 1373 | 98000-B7190 | Dialogue and other messsages. | Variable-length strings. | |
ocsenave@419 1374 | B7190-B8000 | (empty space) | | 0 0 0 0 0 ... |
ocsenave@411 1375 | B8000-BC000 | The text of each Pok\eacute{}mon's Pok\eacute{}dex entry. | Variable-length descriptions (strings) in Pok\eacute{}dex order, separated by 0x50. These entries use the special characters *0x49* (new page), *0x4E* (new line), and *0x5F* (end entry). | The first entry (Bulbasaur's) is: "It can go for days [0x4E] without eating a [0x4E] single morsel. [0x49] In the bulb on [0x4E] its back, it [0x4E] stores energy [0x5F] [0x50]." |
ocsenave@419 1376 | BC000-BC60F | Move names. | Variable-length move names, separated by 0x50. The moves are in internal order. | POUND#KARATE CHOP#DOUBLESLAP#COMET PUNCH#... |
ocsenave@419 1377 | BC610-BD000 | (empty space) | | 0 0 0 0 0 ... |
ocsenave@411 1378 | 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 0x50. The names are in \ldquo{}internal order\rdquo{}. | RHYDON####KANGASKHANNIDORAN♂#... |
ocsenave@412 1379 |-----------------------+-----------------+-----------------+-----------------|
ocsenave@412 1380 | E9BD5- | The text PLAY TIME (see above, 70442) | | |
ocsenave@421 1381 | F1A44-F1A45 | Which Pok\eacute{}mon does Officer Jenny give you? | A level/internal-id pair. | (10 177), corresponding to a level 10 Squirtle. |
ocsenave@421 1382 | F21BF-F21C0 | Which Pok\eacute{}mon does the salesman at the Mt. Moon Pok\eacute{}mon center give you? | A level/internal-id pair | (5 133), corresponding to a level 5 Magikarp. |
ocsenave@470 1383 | | |
ocsenave@410 1384 #+TBLFM:
ocsenave@312 1385
ocsenave@421 1386 ** COMMENT
ocsenave@421 1387 Locations where Give Pokemon is used in a nonstraightforward way
ocsenave@421 1388 0x5287C
ocsenave@421 1389 0x5CE23
ocsenave@421 1390 0x5C36B
ocsenave@421 1391 0x7562E
ocsenave@421 1392
ocsenave@470 1393 Find GivePokemon
ocsenave@470 1394 (search-memory* (vec(rom)) [120 234 \_ \_ 121 234 \_ \_ 175 234 \_ \_ 6] 10)
ocsenave@470 1395
ocsenave@470 1396 F4011 : ASM script for asking if it's oak battle
ocsenave@470 1397
ocsenave@347 1398
ocsenave@419 1399 ** Understanding memory banks and pointers
ocsenave@419 1400 #+begin_src clojure
ocsenave@419 1401
ocsenave@419 1402 (defn endian-flip
ocsenave@419 1403 "Flip the bytes of the two-byte number."
ocsenave@419 1404 [n]
ocsenave@419 1405 (assert (< n 0xFFFF))
ocsenave@419 1406 (+ (* 0x100 (rem n 0x100))
ocsenave@419 1407 (int (/ n 0x100))))
ocsenave@419 1408
ocsenave@419 1409
ocsenave@419 1410 (defn offset->ptr
ocsenave@419 1411 "Convert an offset into a little-endian pointer."
ocsenave@419 1412 [n]
ocsenave@419 1413 (->
ocsenave@419 1414 n
ocsenave@419 1415 (rem 0x10000) ;; take last four bytes
ocsenave@419 1416 (rem 0x4000) ;; get relative offset from the start of the bank
ocsenave@419 1417 (+ 0x4000)
ocsenave@419 1418 endian-flip))
ocsenave@419 1419
ocsenave@419 1420 (defn offset->bank
ocsenave@419 1421 "Get the bank of the offset."
ocsenave@419 1422 [n]
ocsenave@419 1423 (int (/ n 0x4000)))
ocsenave@419 1424
ocsenave@419 1425 (defn ptr->offset
ocsenave@419 1426 "Convert a two-byte little-endian pointer into an offset."
ocsenave@419 1427 [bank ptr]
ocsenave@419 1428 (->
ocsenave@419 1429 ptr
ocsenave@419 1430 endian-flip
ocsenave@419 1431 (- 0x4000)
ocsenave@419 1432 (+ (* 0x4000 bank))
ocsenave@419 1433 ))
ocsenave@419 1434
ocsenave@419 1435 (defn same-bank-offset
ocsenave@419 1436 "Convert a ptr into an absolute offset by using the bank of the reference."
ocsenave@419 1437 [reference ptr]
ocsenave@419 1438 (ptr->offset
ocsenave@419 1439 (offset->bank reference)
ocsenave@419 1440 ptr))
ocsenave@419 1441 #+end_src
ocsenave@419 1442
ocsenave@347 1443
ocsenave@312 1444 ** Internal Pok\eacute{}mon IDs
ocsenave@312 1445 ** Type IDs
ocsenave@347 1446
ocsenave@347 1447 #+name: type-ids
ocsenave@347 1448 #+begin_src clojure
ocsenave@347 1449 (def pkmn-types
ocsenave@347 1450 [:normal ;;0
ocsenave@347 1451 :fighting ;;1
ocsenave@347 1452 :flying ;;2
ocsenave@347 1453 :poison ;;3
ocsenave@347 1454 :ground ;;4
ocsenave@347 1455 :rock ;;5
ocsenave@347 1456 :bird ;;6
ocsenave@347 1457 :bug ;;7
ocsenave@347 1458 :ghost ;;8
ocsenave@347 1459 :A
ocsenave@347 1460 :B
ocsenave@347 1461 :C
ocsenave@347 1462 :D
ocsenave@347 1463 :E
ocsenave@347 1464 :F
ocsenave@347 1465 :G
ocsenave@347 1466 :H
ocsenave@347 1467 :I
ocsenave@347 1468 :J
ocsenave@347 1469 :K
ocsenave@347 1470 :fire ;;20 (0x14)
ocsenave@347 1471 :water ;;21 (0x15)
ocsenave@347 1472 :grass ;;22 (0x16)
ocsenave@347 1473 :electric ;;23 (0x17)
ocsenave@347 1474 :psychic ;;24 (0x18)
ocsenave@347 1475 :ice ;;25 (0x19)
ocsenave@347 1476 :dragon ;;26 (0x1A)
ocsenave@347 1477 ])
ocsenave@347 1478 #+end_src
ocsenave@347 1479
ocsenave@312 1480 ** Basic effects of moves
ocsenave@347 1481
ocsenave@347 1482 *** Table of basic effects
ocsenave@347 1483
ocsenave@347 1484 The possible effects of moves in Pok\eacute{}mon \mdash{} for example, dealing
ocsenave@347 1485 damage, leeching health, or potentially poisoning the opponent
ocsenave@347 1486 \mdash{} are stored in a table. Each move has exactly one effect, and
ocsenave@347 1487 different moves might have the same effect.
ocsenave@347 1488
ocsenave@347 1489 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 1490
ocsenave@347 1491 All the legitimate move effects are listed in the table
ocsenave@347 1492 below. Here are some notes for reading it:
ocsenave@347 1493
ocsenave@347 1494 - Whenever an effect has a chance of doing something (like a chance of
ocsenave@371 1495 poisoning the opponent), I list the chance as a hexadecimal amount
ocsenave@371 1496 out of 256; this is to avoid rounding errors. To convert the hex amount into a percentage, divide by 256.
ocsenave@347 1497 - For some effects, the description is too cumbersome to
ocsenave@347 1498 write. Instead, I just write a move name
ocsenave@347 1499 in parentheses, like: (leech seed). That move gives a characteristic example
ocsenave@347 1500 of the effect.
ocsenave@347 1501 - I use the abbreviations =atk=, =def=, =spd=, =spc=, =acr=, =evd= for
ocsenave@371 1502 attack, defense, speed, special, accuracy, and evasiveness.
ocsenave@347 1503 .
ocsenave@347 1504
ocsenave@347 1505
ocsenave@347 1506
ocsenave@347 1507 | ID (hex) | Description | Notes |
ocsenave@347 1508 |----------+-------------------------------------------------------------------------------------------------+------------------------------------------------------------------|
ocsenave@347 1509 | 0 | normal damage | |
ocsenave@347 1510 | 1 | no damage, just sleep | TODO: find out how many turns |
ocsenave@347 1511 | 2 | 0x4C chance of poison | |
ocsenave@347 1512 | 3 | leech half of inflicted damage | |
ocsenave@347 1513 | 4 | 0x19 chance of burn | |
ocsenave@347 1514 | 5 | 0x19 chance of freeze | |
ocsenave@347 1515 | 6 | 0x19 chance of paralysis | |
ocsenave@347 1516 | 7 | user faints; opponent's defense is halved during attack. | |
ocsenave@347 1517 | 8 | leech half of inflicted damage ONLY if the opponent is asleep | |
ocsenave@347 1518 | 9 | imitate last attack | |
ocsenave@347 1519 | A | user atk +1 | |
ocsenave@347 1520 | B | user def +1 | |
ocsenave@347 1521 | C | user spd +1 | |
ocsenave@347 1522 | D | user spc +1 | |
ocsenave@347 1523 | E | user acr +1 | This effect is unused. |
ocsenave@347 1524 | F | user evd +1 | |
ocsenave@347 1525 | 10 | get post-battle money = 2 * level * uses | |
ocsenave@347 1526 | 11 | move has 0xFE acr, regardless of battle stat modifications. | |
ocsenave@347 1527 | 12 | opponent atk -1 | |
ocsenave@347 1528 | 13 | opponent def -1 | |
ocsenave@347 1529 | 14 | opponent spd -1 | |
ocsenave@347 1530 | 15 | opponent spc -1 | |
ocsenave@347 1531 | 16 | opponent acr -1 | |
ocsenave@347 1532 | 17 | opponent evd -1 | |
ocsenave@347 1533 | 18 | converts user's type to opponent's. | |
ocsenave@347 1534 | 19 | (haze) | |
ocsenave@347 1535 | 1A | (bide) | |
ocsenave@347 1536 | 1B | (thrash) | |
ocsenave@347 1537 | 1C | (teleport) | |
ocsenave@347 1538 | 1D | (fury swipes) | |
ocsenave@347 1539 | 1E | attacks 2-5 turns | Unused. TODO: find out what it does. |
ocsenave@347 1540 | 1F | 0x19 chance of flinching | |
ocsenave@347 1541 | 20 | opponent sleep for 1-7 turns | |
ocsenave@347 1542 | 21 | 0x66 chance of poison | |
ocsenave@347 1543 | 22 | 0x4D chance of burn | |
ocsenave@347 1544 | 23 | 0x4D chance of freeze | |
ocsenave@347 1545 | 24 | 0x4D chance of paralysis | |
ocsenave@347 1546 | 25 | 0x4D chance of flinching | |
ocsenave@347 1547 | 26 | one-hit KO | |
ocsenave@347 1548 | 27 | charge one turn, atk next. | |
ocsenave@347 1549 | 28 | fixed damage, leaves 1HP. | Is the fixed damage the power of the move? |
ocsenave@347 1550 | 29 | fixed damage. | Like seismic toss, dragon rage, psywave. |
ocsenave@347 1551 | 2A | atk 2-5 turns; opponent can't attack | The odds of attacking for /n/ turns are: (0 0x60 0x60 0x20 0x20) |
ocsenave@347 1552 | 2B | charge one turn, atk next. (can't be hit when charging) | |
ocsenave@347 1553 | 2C | atk hits twice. | |
ocsenave@347 1554 | 2D | user takes 1 damage if misses. | |
ocsenave@347 1555 | 2E | evade status-lowering effects | Caused by you or also your opponent? |
ocsenave@347 1556 | 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 1557 | 30 | atk causes recoil dmg = 1/4 dmg dealt | |
ocsenave@347 1558 | 31 | confuses opponent | |
ocsenave@347 1559 | 32 | user atk +2 | |
ocsenave@347 1560 | 33 | user def +2 | |
ocsenave@347 1561 | 34 | user spd +2 | |
ocsenave@347 1562 | 35 | user spc +2 | |
ocsenave@347 1563 | 36 | user acr +2 | This effect is unused. |
ocsenave@347 1564 | 37 | user evd +2 | This effect is unused. |
ocsenave@347 1565 | 38 | restores up to half of user's max hp. | |
ocsenave@347 1566 | 39 | (transform) | |
ocsenave@347 1567 | 3A | opponent atk -2 | |
ocsenave@347 1568 | 3B | opponent def -2 | |
ocsenave@347 1569 | 3C | opponent spd -2 | |
ocsenave@347 1570 | 3D | opponent spc -2 | |
ocsenave@347 1571 | 3E | opponent acr -2 | |
ocsenave@347 1572 | 3F | opponent evd -2 | |
ocsenave@347 1573 | 40 | doubles user spc when attacked | |
ocsenave@347 1574 | 41 | doubles user def when attacked | |
ocsenave@347 1575 | 42 | just poisons opponent | |
ocsenave@347 1576 | 43 | just paralyzes opponent | |
ocsenave@347 1577 | 44 | 0x19 chance opponent atk -1 | |
ocsenave@347 1578 | 45 | 0x19 chance opponent def -1 | |
ocsenave@347 1579 | 46 | 0x19 chance opponent spd -1 | |
ocsenave@347 1580 | 47 | 0x4C chance opponent spc -1 | |
ocsenave@347 1581 | 48 | 0x19 chance opponent acr -1 | |
ocsenave@347 1582 | 49 | 0x19 chance opponent evd -1 | |
ocsenave@347 1583 | 4A | ??? | ;; unused? no effect? |
ocsenave@347 1584 | 4B | ??? | ;; unused? no effect? |
ocsenave@347 1585 | 4C | 0x19 chance of confusing the opponent | |
ocsenave@347 1586 | 4D | atk hits twice. 0x33 chance opponent poisioned. | |
ocsenave@347 1587 | 4E | broken. crash the game after attack. | |
ocsenave@347 1588 | 4F | (substitute) | |
ocsenave@347 1589 | 50 | unless opponent faints, user must recharge after atk. some exceptions apply | |
ocsenave@347 1590 | 51 | (rage) | |
ocsenave@347 1591 | 52 | (mimic) | |
ocsenave@347 1592 | 53 | (metronome) | |
ocsenave@347 1593 | 54 | (leech seed) | |
ocsenave@347 1594 | 55 | does nothing (splash) | |
ocsenave@347 1595 | 56 | (disable) | |
ocsenave@347 1596 #+end_src
ocsenave@347 1597
ocsenave@347 1598 *** Source
ocsenave@347 1599 #+name: move-effects
ocsenave@347 1600 #+begin_src clojure
ocsenave@347 1601 (def move-effects
ocsenave@347 1602 ["normal damage"
ocsenave@347 1603 "no damage, just opponent sleep" ;; how many turns? is atk power ignored?
ocsenave@347 1604 "0x4C chance of poison"
ocsenave@347 1605 "leech half of inflicted damage"
ocsenave@347 1606 "0x19 chance of burn"
ocsenave@347 1607 "0x19 chance of freeze"
ocsenave@347 1608 "0x19 chance of paralyze"
ocsenave@347 1609 "user faints; opponent defense halved during attack."
ocsenave@347 1610 "leech half of inflicted damage ONLY if sleeping opponent."
ocsenave@347 1611 "imitate last attack"
ocsenave@347 1612 "user atk +1"
ocsenave@347 1613 "user def +1"
ocsenave@347 1614 "user spd +1"
ocsenave@347 1615 "user spc +1"
ocsenave@347 1616 "user acr +1" ;; unused?!
ocsenave@347 1617 "user evd +1"
ocsenave@347 1618 "get post-battle $ = 2*level*uses"
ocsenave@347 1619 "0xFE acr, no matter what."
ocsenave@347 1620 "opponent atk -1" ;; acr taken from move acr?
ocsenave@347 1621 "opponent def -1" ;;
ocsenave@347 1622 "opponent spd -1" ;;
ocsenave@347 1623 "opponent spc -1" ;;
ocsenave@347 1624 "opponent acr -1";;
ocsenave@347 1625 "opponent evd -1"
ocsenave@347 1626 "converts user's type to opponent's."
ocsenave@347 1627 "(haze)"
ocsenave@347 1628 "(bide)"
ocsenave@347 1629 "(thrash)"
ocsenave@347 1630 "(teleport)"
ocsenave@347 1631 "(fury swipes)"
ocsenave@347 1632 "attacks 2-5 turns" ;; unused? like rollout?
ocsenave@347 1633 "0x19 chance of flinch"
ocsenave@347 1634 "opponent sleep for 1-7 turns"
ocsenave@347 1635 "0x66 chance of poison"
ocsenave@347 1636 "0x4D chance of burn"
ocsenave@347 1637 "0x4D chance of freeze"
ocsenave@347 1638 "0x4D chance of paralyze"
ocsenave@347 1639 "0x4D chance of flinch"
ocsenave@347 1640 "one-hit KO"
ocsenave@347 1641 "charge one turn, atk next."
ocsenave@347 1642 "fixed damage, leaves 1HP." ;; how is dmg determined?
ocsenave@347 1643 "fixed damage." ;; cf seismic toss, dragon rage, psywave.
ocsenave@347 1644 "atk 2-5 turns; opponent can't attack" ;; unnormalized? (0 0x60 0x60 0x20 0x20)
ocsenave@347 1645 "charge one turn, atk next. (can't be hit when charging)"
ocsenave@347 1646 "atk hits twice."
ocsenave@347 1647 "user takes 1 damage if misses."
ocsenave@347 1648 "evade status-lowering effects" ;;caused by you or also your opponent?
ocsenave@347 1649 "(broken) if user is slower than opponent, makes critical hit impossible, otherwise has no effect"
ocsenave@347 1650 "atk causes recoil dmg = 1/4 dmg dealt"
ocsenave@347 1651 "confuses opponent" ;; acr taken from move acr
ocsenave@347 1652 "user atk +2"
ocsenave@347 1653 "user def +2"
ocsenave@347 1654 "user spd +2"
ocsenave@347 1655 "user spc +2"
ocsenave@347 1656 "user acr +2" ;; unused!
ocsenave@347 1657 "user evd +2" ;; unused!
ocsenave@347 1658 "restores up to half of user's max hp." ;; broken: fails if the difference
ocsenave@347 1659 ;; b/w max and current hp is one less than a multiple of 256.
ocsenave@347 1660 "(transform)"
ocsenave@347 1661 "opponent atk -2"
ocsenave@347 1662 "opponent def -2"
ocsenave@347 1663 "opponent spd -2"
ocsenave@347 1664 "opponent spc -2"
ocsenave@347 1665 "opponent acr -2"
ocsenave@347 1666 "opponent evd -2"
ocsenave@347 1667 "doubles user spc when attacked"
ocsenave@347 1668 "doubles user def when attacked"
ocsenave@347 1669 "just poisons opponent" ;;acr taken from move acr
ocsenave@347 1670 "just paralyzes opponent" ;;
ocsenave@347 1671 "0x19 chance opponent atk -1"
ocsenave@347 1672 "0x19 chance opponent def -1"
ocsenave@347 1673 "0x19 chance opponent spd -1"
ocsenave@347 1674 "0x4C chance opponent spc -1" ;; context suggest chance is 0x19
ocsenave@347 1675 "0x19 chance opponent acr -1"
ocsenave@347 1676 "0x19 chance opponent evd -1"
ocsenave@347 1677 "???" ;; unused? no effect?
ocsenave@347 1678 "???" ;; unused? no effect?
ocsenave@347 1679 "0x19 chance opponent confused"
ocsenave@347 1680 "atk hits twice. 0x33 chance opponent poisioned."
ocsenave@347 1681 "broken. crash the game after attack."
ocsenave@347 1682 "(substitute)"
ocsenave@347 1683 "unless opponent faints, user must recharge after atk. some
ocsenave@347 1684 exceptions apply."
ocsenave@347 1685 "(rage)"
ocsenave@347 1686 "(mimic)"
ocsenave@347 1687 "(metronome)"
ocsenave@347 1688 "(leech seed)"
ocsenave@347 1689 "does nothing (splash)"
ocsenave@347 1690 "(disable)"
ocsenave@347 1691 ])
ocsenave@347 1692 #+end_src
ocsenave@347 1693
ocsenave@347 1694
ocsenave@312 1695 ** Alphabet code
ocsenave@347 1696
ocsenave@348 1697 * Source
ocsenave@348 1698
ocsenave@347 1699 #+begin_src clojure :tangle ../clojure/com/aurellem/gb/hxc.clj
ocsenave@347 1700
ocsenave@347 1701 (ns com.aurellem.gb.hxc
ocsenave@347 1702 (:use (com.aurellem.gb assembly characters gb-driver util mem-util
ocsenave@347 1703 constants species))
ocsenave@347 1704 (:import [com.aurellem.gb.gb_driver SaveState]))
ocsenave@347 1705
ocsenave@347 1706 ; ************* HANDWRITTEN CONSTANTS
ocsenave@347 1707
ocsenave@347 1708 <<type-ids>>
ocsenave@347 1709
ocsenave@347 1710
ocsenave@347 1711 ;; question: when status effects claim to take
ocsenave@347 1712 ;; their accuracy from the move accuracy, does
ocsenave@347 1713 ;; this mean that the move always "hits" but the
ocsenave@347 1714 ;; status effect may not?
ocsenave@347 1715
ocsenave@347 1716 <<move-effects>>
ocsenave@347 1717
ocsenave@347 1718 ;; ************** HARDCODED DATA
ocsenave@347 1719
ocsenave@347 1720 <<hxc-thunks>>
ocsenave@347 1721 ;; --------------------------------------------------
ocsenave@347 1722
ocsenave@347 1723 <<pokenames>>
ocsenave@348 1724 <<type-names>>
ocsenave@347 1725
ocsenave@347 1726 ;; http://hax.iimarck.us/topic/581/
ocsenave@348 1727 <<pokecry>>
ocsenave@347 1728
ocsenave@347 1729
ocsenave@348 1730 <<item-names>>
ocsenave@347 1731
ocsenave@347 1732
ocsenave@347 1733
ocsenave@347 1734 (def hxc-titles
ocsenave@347 1735 "The hardcoded names of the trainer titles in memory. List begins at
ocsenave@347 1736 ROM@27E77"
ocsenave@347 1737 (hxc-thunk-words 0x27E77 196))
ocsenave@347 1738
ocsenave@347 1739
ocsenave@348 1740 <<dex-text>>
ocsenave@347 1741
ocsenave@347 1742 ;; In red/blue, pokedex stats are in internal order.
ocsenave@347 1743 ;; In yellow, pokedex stats are in pokedex order.
ocsenave@348 1744 <<dex-stats>>
ocsenave@347 1745
ocsenave@347 1746
ocsenave@347 1747
ocsenave@347 1748
ocsenave@348 1749 <<places>>
ocsenave@347 1750
ocsenave@347 1751 (defn hxc-dialog
ocsenave@347 1752 "The hardcoded dialogue in memory, including in-game alerts. Dialog
ocsenave@347 1753 seems to be separated by 0x57 instead of 0x50 (END). Begins at ROM@98000."
ocsenave@347 1754 ([rom]
ocsenave@347 1755 (map character-codes->str
ocsenave@347 1756 (take-nth 2
ocsenave@347 1757 (partition-by #(= % 0x57)
ocsenave@347 1758 (take 0x0F728
ocsenave@347 1759 (drop 0x98000 rom))))))
ocsenave@347 1760 ([]
ocsenave@347 1761 (hxc-dialog com.aurellem.gb.gb-driver/original-rom)))
ocsenave@347 1762
ocsenave@347 1763
ocsenave@348 1764 <<move-names>>
ocsenave@348 1765 <<move-data>>
ocsenave@347 1766
ocsenave@348 1767 <<machines>>
ocsenave@347 1768
ocsenave@347 1769
ocsenave@347 1770
ocsenave@347 1771 (defn internal-id
ocsenave@347 1772 ([rom]
ocsenave@347 1773 (zipmap
ocsenave@347 1774 (hxc-pokenames rom)
ocsenave@347 1775 (range)))
ocsenave@347 1776 ([]
ocsenave@347 1777 (internal-id com.aurellem.gb.gb-driver/original-rom)))
ocsenave@347 1778
ocsenave@347 1779
ocsenave@347 1780
ocsenave@347 1781
ocsenave@347 1782
ocsenave@347 1783 ;; nidoran gender change upon levelup
ocsenave@347 1784 ;; (->
ocsenave@347 1785 ;; @current-state
ocsenave@347 1786 ;; rom
ocsenave@347 1787 ;; vec
ocsenave@347 1788 ;; (rewrite-memory
ocsenave@347 1789 ;; (nth (hxc-ptrs-evolve) ((internal-id) :nidoran♂))
ocsenave@347 1790 ;; [1 1 15])
ocsenave@347 1791 ;; (rewrite-memory
ocsenave@347 1792 ;; (nth (hxc-ptrs-evolve) ((internal-id) :nidoran♀))
ocsenave@347 1793 ;; [1 1 3])
ocsenave@347 1794 ;; (write-rom!)
ocsenave@347 1795
ocsenave@347 1796 ;; )
ocsenave@347 1797
ocsenave@347 1798
ocsenave@347 1799
ocsenave@348 1800 <<type-advantage>>
ocsenave@347 1801
ocsenave@347 1802
ocsenave@347 1803
ocsenave@348 1804 <<evolution-header>>
ocsenave@349 1805 <<evolution>>
ocsenave@348 1806 <<learnsets>>
ocsenave@348 1807 <<pokebase>>
ocsenave@347 1808
ocsenave@347 1809
ocsenave@347 1810 (defn hxc-intro-pkmn
ocsenave@347 1811 "The hardcoded pokemon to display in Prof. Oak's introduction; the pokemon's
ocsenave@347 1812 internal id is stored at ROM@5EDB."
ocsenave@347 1813 ([] (hxc-intro-pkmn
ocsenave@347 1814 com.aurellem.gb.gb-driver/original-rom))
ocsenave@347 1815 ([rom]
ocsenave@347 1816 (nth (hxc-pokenames rom) (nth rom 0x5EDB))))
ocsenave@347 1817
ocsenave@347 1818 (defn sxc-intro-pkmn!
ocsenave@347 1819 "Set the hardcoded pokemon to display in Prof. Oak's introduction."
ocsenave@347 1820 [pokemon]
ocsenave@347 1821 (write-rom!
ocsenave@347 1822 (rewrite-rom 0x5EDB
ocsenave@347 1823 [
ocsenave@347 1824 (inc
ocsenave@347 1825 ((zipmap
ocsenave@347 1826 (hxc-pokenames)
ocsenave@347 1827 (range))
ocsenave@347 1828 pokemon))])))
ocsenave@347 1829
ocsenave@347 1830
ocsenave@348 1831 <<item-prices>>
ocsenave@347 1832
ocsenave@348 1833 <<item-vendors>>
ocsenave@347 1834
ocsenave@348 1835 <<wilds>>
ocsenave@347 1836
ocsenave@347 1837
ocsenave@347 1838 ;; ********************** MANIPULATION FNS
ocsenave@347 1839
ocsenave@347 1840
ocsenave@347 1841 (defn same-type
ocsenave@347 1842 ([pkmn move]
ocsenave@347 1843 (same-type
ocsenave@347 1844 com.aurellem.gb.gb-driver/original-rom pkmn move))
ocsenave@347 1845 ([rom pkmn move]
ocsenave@347 1846 (((comp :types (hxc-pokemon-base rom)) pkmn)
ocsenave@347 1847 ((comp :type (hxc-move-data rom)) move))))
ocsenave@347 1848
ocsenave@347 1849
ocsenave@347 1850
ocsenave@347 1851
ocsenave@347 1852 (defn submap?
ocsenave@347 1853 "Compares the two maps. Returns true if map-big has the same associations as map-small, otherwise false."
ocsenave@347 1854 [map-small map-big]
ocsenave@347 1855 (cond (empty? map-small) true
ocsenave@347 1856 (and
ocsenave@347 1857 (contains? map-big (ffirst map-small))
ocsenave@347 1858 (= (get map-big (ffirst map-small))
ocsenave@347 1859 (second (first map-small))))
ocsenave@347 1860 (recur (next map-small) map-big)
ocsenave@347 1861
ocsenave@347 1862 :else false))
ocsenave@347 1863
ocsenave@347 1864
ocsenave@347 1865 (defn search-map [proto-map maps]
ocsenave@347 1866 "Returns all the maps that make the same associations as proto-map."
ocsenave@347 1867 (some (partial submap? proto-map) maps))
ocsenave@347 1868
ocsenave@347 1869 (defn filter-vals
ocsenave@347 1870 "Returns a map consisting of all the pairs [key val] for
ocsenave@347 1871 which (pred key) returns true."
ocsenave@347 1872 [pred map]
ocsenave@347 1873 (reduce (partial apply assoc) {}
ocsenave@347 1874 (filter (fn [[k v]] (pred v)) map)))
ocsenave@347 1875
ocsenave@347 1876
ocsenave@347 1877 (defn search-moves
ocsenave@347 1878 "Returns a subcollection of all hardcoded moves with the
ocsenave@347 1879 given attributes. Attributes consist of :name :power
ocsenave@347 1880 :accuracy :pp :fx-id
ocsenave@347 1881 (and also :fx-txt, but it contains the same information
ocsenave@347 1882 as :fx-id)"
ocsenave@347 1883 ([attribute-map]
ocsenave@347 1884 (search-moves
ocsenave@347 1885 com.aurellem.gb.gb-driver/original-rom attribute-map))
ocsenave@347 1886 ([rom attribute-map]
ocsenave@347 1887 (filter-vals (partial submap? attribute-map)
ocsenave@347 1888 (hxc-move-data rom))))
ocsenave@347 1889
ocsenave@347 1890
ocsenave@347 1891
ocsenave@347 1892
ocsenave@347 1893
ocsenave@347 1894 ;; note: 0x2f31 contains the names "TM" "HM"?
ocsenave@347 1895
ocsenave@347 1896 ;; note for later: credits start at F1290
ocsenave@347 1897
ocsenave@347 1898 ;; note: DADB hyper-potion-hp _ _ _ super-potion-hp _ _ _ potion-hp ??
ocsenave@347 1899
ocsenave@347 1900 ;; note: DD4D spells out pokemon vital stat names ("speed", etc.)
ocsenave@347 1901
ocsenave@347 1902 ;; note: 1195C-6A says ABLE#NOT ABLE#, but so does 119C0-119CE.
ocsenave@347 1903 ;; The first instance is for Machines; the second, for stones.
ocsenave@347 1904
ocsenave@410 1905 ;; note: according to
ocsenave@410 1906 ;; http://www.upokecenter.com/games/rby/guides/rgbtrainers.php
ocsenave@410 1907 ;; the amount of money given by a trainer is equal to the
ocsenave@410 1908 ;; base money times the level of the last Pokemon on that trainer's
ocsenave@410 1909 ;; list. Other sources say it's the the level of the last pokemon
ocsenave@410 1910 ;; /defeated/.
ocsenave@410 1911
ocsenave@410 1912 ;; todo: find base money.
ocsenave@410 1913
ocsenave@410 1914
ocsenave@411 1915 ;; note: 0xDFEA (in indexable mem) is the dex# of the currently-viewed Pokemon in
ocsenave@411 1916 ;; in the pokedex. It's used for other purposes if there is none.
ocsenave@411 1917
ocsenave@412 1918 ;; note: 0x9D35 (index.) switches from 0xFF to 0x00 temporarily when
ocsenave@412 1919 ;; you walk between areas.
ocsenave@412 1920
ocsenave@412 1921 ;; note: 0xD059 (index.) is the special battle type of your next battle:
ocsenave@412 1922 ;; - 00 is a usual battle
ocsenave@412 1923 ;; - 01 is a pre-scripted OLD MAN battle which always fails to catch the
ocsenave@412 1924 ;; target Pokemon.
ocsenave@412 1925 ;; - 02 is a safari zone battle
ocsenave@412 1926 ;; - 03 obligates you to run away. (unused)
ocsenave@412 1927 ;; - 04 is a pre-scripted OAK battle, which (temporarily) causes the
ocsenave@412 1928 ;; enemy Pokemon to cry PIKAAA, and which always catches the target
ocsenave@412 1929 ;; Pokemon. The target Pokemon is erased after the battle.
ocsenave@412 1930 ;; - 05+ are glitch states in which you are sort of the Pokemon.
ocsenave@412 1931
ocsenave@412 1932
ocsenave@412 1933 ;; note: 0x251A (in indexable mem): image decompression routine seems to begin here.
ocsenave@347 1934
ocsenave@420 1935 ;; note: 0x4845 (index): vending inventory is loaded here. possibly
ocsenave@420 1936 ;; other things, too.
ocsenave@420 1937 (comment
ocsenave@420 1938 ;; temporarily intercept/adjust what pops out of the vending
ocsenave@420 1939 ;; machine.
ocsenave@420 1940 ;; (and how much it costs)
ocsenave@420 1941
ocsenave@420 1942 ;; located at 0x4845
ocsenave@420 1943 ;; not to be confused with shop inventory, 0xCF7B
ocsenave@420 1944 (do
ocsenave@420 1945 (step (read-state "vend-menu"))
ocsenave@420 1946 (write-memory! (rewrite-memory (vec(memory)) 0x4845 [2 0 1 0]))
ocsenave@420 1947 (step @current-state [:a])
ocsenave@420 1948 (step @current-state [])
ocsenave@420 1949 (nstep @current-state 200) ))
ocsenave@420 1950
ocsenave@347 1951
ocsenave@373 1952 ;; Note: There are two tile tables, one from 8000-8FFF, the other from
ocsenave@373 1953 ;; 8800-97FF. The latter contains symbols, possibly map tiles(?), with some japanese chars and stuff at the end.
ocsenave@373 1954 (defn print-pixel-letters!
ocsenave@373 1955 "The pixel tiles representing letters. Neat!"
ocsenave@373 1956 ([] (print-pixel-letters! (read-state "oak-speaks")))
ocsenave@373 1957 ([state]
ocsenave@373 1958 (map
ocsenave@373 1959 (comp
ocsenave@373 1960 println
ocsenave@373 1961 (partial map #(if (zero? %) \space 0))
ocsenave@373 1962 #(if (< (count %) 8)
ocsenave@373 1963 (recur (cons 0 %))
ocsenave@373 1964 %)
ocsenave@373 1965 reverse bit-list)
ocsenave@373 1966
ocsenave@373 1967 (take 0xFFF (drop 0x8800 (memory state))))))
ocsenave@373 1968
ocsenave@373 1969
ocsenave@419 1970 ;; (defn test-2 []
ocsenave@419 1971 ;; (loop [n 0
ocsenave@419 1972 ;; pc-1 (pc-trail (-> state-defend (tick) (step [:a]) (step [:a]) (step []) (nstep 100)) 100000)
ocsenave@419 1973 ;; pc-2 (pc-trail (-> state-speed (tick) (step [:a]) (step [:a])
ocsenave@419 1974 ;; (step []) (nstep 100)) 100000)]
ocsenave@419 1975 ;; (cond (empty? (drop n pc-1)) [pc-1 n]
ocsenave@419 1976 ;; (not= (take 10 (drop n pc-1)) (take 10 pc-2))
ocsenave@419 1977 ;; (recur pc-1 pc-2 (inc n))
ocsenave@419 1978 ;; :else
ocsenave@419 1979 ;; [(take 1000 pc-2) n])))
ocsenave@406 1980
ocsenave@406 1981
ocsenave@406 1982
ocsenave@406 1983
ocsenave@410 1984 (defn test-3
ocsenave@410 1985 "Explore trainer data"
ocsenave@419 1986 ([] (test-3 0x3A289))
ocsenave@419 1987 ([start]
ocsenave@410 1988 (let [pokenames (vec(hxc-pokenames-raw))]
ocsenave@410 1989 (println
ocsenave@410 1990 (reduce
ocsenave@410 1991 str
ocsenave@410 1992 (map
ocsenave@419 1993 (fn [[adr lvl pkmn]]
ocsenave@419 1994 (str (format "%-11s %4d %02X %02X \t %05X\n"
ocsenave@419 1995
ocsenave@410 1996 (cond
ocsenave@410 1997 (zero? lvl) "+"
ocsenave@410 1998 (nil? (get pokenames (dec pkmn)))
ocsenave@410 1999 "-"
ocsenave@410 2000 :else
ocsenave@410 2001 (get pokenames (dec pkmn)))
ocsenave@410 2002 lvl
ocsenave@410 2003 pkmn
ocsenave@410 2004 lvl
ocsenave@419 2005 adr
ocsenave@419 2006 )))
ocsenave@419 2007 (map cons
ocsenave@419 2008 (take-nth 2 (drop start (range)))
ocsenave@419 2009 (partition 2
ocsenave@419 2010 (take 400;;703
ocsenave@419 2011 (drop
ocsenave@419 2012 start
ocsenave@419 2013 ;; 0x3A75D
ocsenave@419 2014 (rom)))))))))))
ocsenave@410 2015
ocsenave@412 2016 (defn search-memory* [mem codes k]
ocsenave@412 2017 (loop [index 0
ocsenave@412 2018 index-next 1
ocsenave@412 2019 start-match 0
ocsenave@412 2020 to-match codes
ocsenave@412 2021 matches []]
ocsenave@412 2022 (cond
ocsenave@412 2023 (>= index (count mem)) matches
ocsenave@412 2024
ocsenave@412 2025 (empty? to-match)
ocsenave@412 2026 (recur
ocsenave@412 2027 index-next
ocsenave@412 2028 (inc index-next)
ocsenave@412 2029 index-next
ocsenave@412 2030 codes
ocsenave@412 2031 (conj matches
ocsenave@412 2032 [(hex start-match) (take k (drop start-match mem))])
ocsenave@412 2033 )
ocsenave@412 2034
ocsenave@412 2035 (or (= (first to-match) \_) ;; wildcard
ocsenave@412 2036 (= (first to-match) (nth mem index)))
ocsenave@412 2037 (recur
ocsenave@412 2038 (inc index)
ocsenave@412 2039 index-next
ocsenave@412 2040 start-match
ocsenave@412 2041 (rest to-match)
ocsenave@412 2042 matches)
ocsenave@412 2043
ocsenave@412 2044 :else
ocsenave@412 2045 (recur
ocsenave@412 2046 index-next
ocsenave@412 2047 (inc index-next)
ocsenave@412 2048 index-next
ocsenave@412 2049 codes
ocsenave@412 2050 matches))))
ocsenave@420 2051
ocsenave@420 2052
ocsenave@420 2053 (def script-use-ball
ocsenave@420 2054 [0xFA ;; ld A, nn
ocsenave@420 2055 \_
ocsenave@420 2056 \_
ocsenave@420 2057 0xA7 ;; and A
ocsenave@420 2058 0xCA ;; JP Z
ocsenave@420 2059 \_
ocsenave@420 2060 \_
ocsenave@420 2061 0x3D ;; dec A
ocsenave@420 2062 0xC2 ;; JP NZ
ocsenave@420 2063 \_
ocsenave@420 2064 \_
ocsenave@420 2065 0xFA ;; LD A
ocsenave@420 2066 \_
ocsenave@420 2067 \_
ocsenave@420 2068 ])
ocsenave@420 2069
ocsenave@420 2070
ocsenave@420 2071
ocsenave@420 2072 (defn search-pattern [ptn coll]
ocsenave@420 2073 (loop
ocsenave@420 2074 [index 0
ocsenave@420 2075 to-match ptn
ocsenave@420 2076 binds {}
ocsenave@420 2077
ocsenave@420 2078 next-index 1
ocsenave@420 2079 match-start 0
ocsenave@420 2080 matches []]
ocsenave@420 2081
ocsenave@420 2082 (cond
ocsenave@420 2083 (>= index (count coll)) matches
ocsenave@420 2084 (empty? to-match)
ocsenave@420 2085 (recur
ocsenave@420 2086 next-index
ocsenave@420 2087 ptn
ocsenave@420 2088 {}
ocsenave@420 2089 (inc next-index)
ocsenave@420 2090 next-index
ocsenave@420 2091 (conj match-start
ocsenave@420 2092 [(hex match-start) binds]))
ocsenave@420 2093
ocsenave@420 2094 :else
ocsenave@420 2095 (let [k (first to-match)
ocsenave@420 2096 v (nth coll index)]
ocsenave@420 2097 (cond
ocsenave@420 2098 (= k \_) ;; wildcard
ocsenave@420 2099 (recur
ocsenave@420 2100 (inc index)
ocsenave@420 2101 (rest to-match)
ocsenave@420 2102 binds
ocsenave@420 2103
ocsenave@420 2104 next-index
ocsenave@420 2105 match-start
ocsenave@420 2106 matches)
ocsenave@420 2107
ocsenave@420 2108 (keyword? k)
ocsenave@420 2109 (if (binds k)
ocsenave@420 2110 (if (= (binds k) v)
ocsenave@420 2111 (recur
ocsenave@420 2112 (inc index)
ocsenave@420 2113 (rest to-match)
ocsenave@420 2114 binds
ocsenave@420 2115 next-index
ocsenave@420 2116 match-start
ocsenave@420 2117 matches)
ocsenave@420 2118
ocsenave@420 2119 (recur
ocsenave@420 2120 next-index
ocsenave@420 2121 ptn
ocsenave@420 2122 {}
ocsenave@420 2123 (inc next-index)
ocsenave@420 2124 next-index
ocsenave@420 2125 matches))
ocsenave@420 2126
ocsenave@420 2127 ;; ;; consistent bindings
ocsenave@420 2128 ;; (recur
ocsenave@420 2129 ;; (inc index)
ocsenave@420 2130 ;; (rest to-match)
ocsenave@420 2131 ;; binds
ocsenave@420 2132
ocsenave@420 2133 ;; next-index
ocsenave@420 2134 ;; match-start
ocsenave@420 2135 ;; matches)
ocsenave@420 2136
ocsenave@420 2137 ;; ;; inconsistent bindings
ocsenave@420 2138 ;; (recur
ocsenave@420 2139 ;; next-index
ocsenave@420 2140 ;; ptn
ocsenave@420 2141 ;; {}
ocsenave@420 2142 ;; (inc next-index)
ocsenave@420 2143 ;; next-index
ocsenave@420 2144 ;; matches))
ocsenave@420 2145
ocsenave@420 2146 (if ((set (vals binds)) v)
ocsenave@420 2147 ;; bindings are not unique
ocsenave@420 2148 (recur
ocsenave@420 2149 next-index
ocsenave@420 2150 ptn
ocsenave@420 2151 {}
ocsenave@420 2152 (inc next-index)
ocsenave@420 2153 next-index
ocsenave@420 2154 matches)
ocsenave@420 2155
ocsenave@420 2156 ;; bindings are unique
ocsenave@420 2157 (recur
ocsenave@420 2158 (inc index)
ocsenave@420 2159 (rest to-match)
ocsenave@420 2160 (assoc binds k v)
ocsenave@420 2161
ocsenave@420 2162 next-index
ocsenave@420 2163 match-start
ocsenave@420 2164 matches)))
ocsenave@420 2165
ocsenave@420 2166 :else ;; k is just a number
ocsenave@420 2167 (if (= k v)
ocsenave@420 2168 (recur
ocsenave@420 2169 (inc index)
ocsenave@420 2170 (rest to-match)
ocsenave@420 2171 binds
ocsenave@420 2172
ocsenave@420 2173 next-index
ocsenave@420 2174 match-start
ocsenave@420 2175 matches)
ocsenave@420 2176
ocsenave@420 2177 (recur
ocsenave@420 2178 next-index
ocsenave@420 2179 ptn
ocsenave@420 2180 {}
ocsenave@420 2181 (inc next-index)
ocsenave@420 2182 next-index
ocsenave@420 2183 matches)))))))
ocsenave@420 2184
ocsenave@420 2185
ocsenave@420 2186
ocsenave@420 2187
ocsenave@420 2188
ocsenave@420 2189
ocsenave@420 2190
ocsenave@420 2191
ocsenave@420 2192
ocsenave@420 2193 (defn search-pattern* [ptn coll]
ocsenave@420 2194 (loop
ocsenave@420 2195 [
ocsenave@420 2196 binds {}
ocsenave@420 2197 index 0
ocsenave@420 2198 index-next 1
ocsenave@420 2199 start-match 0
ocsenave@420 2200 to-match ptn
ocsenave@420 2201 matches []]
ocsenave@420 2202
ocsenave@420 2203 (cond
ocsenave@420 2204 (>= index (count coll)) matches
ocsenave@420 2205 (empty? to-match)
ocsenave@420 2206 (recur
ocsenave@420 2207 {}
ocsenave@420 2208 index-next
ocsenave@420 2209 (inc index-next)
ocsenave@420 2210 index-next
ocsenave@420 2211 ptn
ocsenave@420 2212 (conj matches
ocsenave@420 2213 [(hex start-match) binds]))
ocsenave@420 2214
ocsenave@420 2215 :else
ocsenave@420 2216 (let [k (first to-match)
ocsenave@420 2217 v (nth coll index)]
ocsenave@420 2218 (cond
ocsenave@420 2219 (= k \_) ;; wildcard
ocsenave@420 2220 (recur
ocsenave@420 2221 binds
ocsenave@420 2222 (inc index)
ocsenave@420 2223 index-next
ocsenave@420 2224 start-match
ocsenave@420 2225 (rest to-match)
ocsenave@420 2226 matches)
ocsenave@420 2227
ocsenave@420 2228 (keyword? k)
ocsenave@420 2229 (if (binds k)
ocsenave@420 2230 (if (= (binds k) v)
ocsenave@420 2231 (recur
ocsenave@420 2232 binds
ocsenave@420 2233 (inc index)
ocsenave@420 2234 index-next
ocsenave@420 2235 start-match
ocsenave@420 2236 (rest to-match)
ocsenave@420 2237 matches)
ocsenave@420 2238 (recur
ocsenave@420 2239 {}
ocsenave@420 2240 index-next
ocsenave@420 2241 (inc index-next)
ocsenave@420 2242 index-next
ocsenave@420 2243 ptn
ocsenave@420 2244 matches))
ocsenave@420 2245 (if
ocsenave@420 2246 ;; every symbol must be bound to a different thing.
ocsenave@420 2247 ((set (vals binds)) v)
ocsenave@420 2248 (recur
ocsenave@420 2249 {}
ocsenave@420 2250 index-next
ocsenave@420 2251 (inc index-next)
ocsenave@420 2252 index-next
ocsenave@420 2253 ptn
ocsenave@420 2254 matches)
ocsenave@420 2255 (recur
ocsenave@420 2256 (assoc binds k v)
ocsenave@420 2257 (inc index)
ocsenave@420 2258 index-next
ocsenave@420 2259 start-match
ocsenave@420 2260 (rest to-match)
ocsenave@421 2261 matches)))
ocsenave@421 2262
ocsenave@421 2263 :else
ocsenave@421 2264 (if (= k v)
ocsenave@421 2265 (recur
ocsenave@421 2266 binds
ocsenave@421 2267 (inc index)
ocsenave@421 2268 index-next
ocsenave@421 2269 start-match
ocsenave@421 2270 (rest to-match)
ocsenave@421 2271 matches)
ocsenave@421 2272 (recur
ocsenave@421 2273 {}
ocsenave@421 2274 index-next
ocsenave@421 2275 (inc index-next)
ocsenave@421 2276 index-next
ocsenave@421 2277 ptn
ocsenave@421 2278 matches))
ocsenave@421 2279
ocsenave@421 2280
ocsenave@421 2281
ocsenave@421 2282 )))))
ocsenave@420 2283
ocsenave@412 2284
ocsenave@406 2285
ocsenave@406 2286
ocsenave@410 2287 ;; look for the rainbow badge in memory
ocsenave@410 2288 (println (reduce str (map #(str (first %) "\t" (vec(second %)) "\n") (search-memory (rom) [221] 10))))
ocsenave@410 2289
ocsenave@406 2290
ocsenave@347 2291 (comment
ocsenave@347 2292
ocsenave@347 2293 (def hxc-later
ocsenave@347 2294 "Running this code produces, e.g. hardcoded names NPCs give
ocsenave@347 2295 their pokemon. Will sort through it later."
ocsenave@347 2296 (print (character-codes->str(take 10000
ocsenave@347 2297 (drop 0x71597
ocsenave@347 2298 (rom (root)))))))
ocsenave@347 2299
ocsenave@347 2300 (let [dex
ocsenave@347 2301 (partition-by #(= 0x50 %)
ocsenave@347 2302 (take 2540
ocsenave@347 2303 (drop 0x40687
ocsenave@347 2304 (rom (root)))))]
ocsenave@347 2305 (def dex dex)
ocsenave@347 2306 (def hxc-species
ocsenave@347 2307 (map character-codes->str
ocsenave@347 2308 (take-nth 4 dex))))
ocsenave@347 2309 )
ocsenave@347 2310
ocsenave@347 2311
ocsenave@347 2312 #+end_src
ocsenave@347 2313
ocsenave@348 2314 #+results:
ocsenave@348 2315 : nil
ocsenave@348 2316