annotate org/rom.org @ 396:c7a43f4ffd9d

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