Mercurial > vba-clojure
diff org/rom.org @ 347:ff65ee0944fe
more progess: now rom.org tangles into hxc.clj; i'll be subdividing the code blocks as I write more.
author | Dylan Holmes <ocsenave@gmail.com> |
---|---|
date | Sun, 08 Apr 2012 06:13:39 -0500 |
parents | 5639312a393f |
children | 497ca041f5af |
line wrap: on
line diff
1.1 --- a/org/rom.org Sun Apr 08 01:28:39 2012 -0500 1.2 +++ b/org/rom.org Sun Apr 08 06:13:39 2012 -0500 1.3 @@ -10,7 +10,9 @@ 1.4 # about map headers http://datacrystal.romhacking.net/wiki/Pokemon_Red/Blue:Notes 1.5 # map headers Yellow http://www.pokecommunity.com/archive/index.php/t-235311.html 1.6 # pokedollar: U+20B1 1.7 -* Mapping the ROM 1.8 +* Introduction 1.9 + 1.10 +** Mapping the ROM 1.11 1.12 | ROM address (hex) | Description | Format | Example | 1.13 |-------------------+-----------------+-----------------+-----------------| 1.14 @@ -22,18 +24,24 @@ 1.15 | 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. | 1.16 | 06698- | ? Background music. | | | 1.17 | 0822E-082F? | Pointers to background music, part I. | | | 1.18 -| 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 above). | 1.19 +| 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). | 1.20 +|-------------------+-----------------+-----------------+-----------------| 1.21 +| 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 | 1.22 +| 0DAE0. | Amount of HP restored by Super Potion. | " | 50 | 1.23 +| 0DAE3. | Amount of HP restored by Potion. | " | 20 | 1.24 +|-------------------+-----------------+-----------------+-----------------| 1.25 | 0DD4D-DD72 | Names of permanent stats. | Variable-length strings separated by 0x50. | #HEALTH#ATTACK#DEFENSE#SPEED#SPECIAL# | 1.26 | 1195C-1196A | The two terms for being able/unable to learn a TM/HM. | Variable-length strings separated by 0x50. | ABLE#NOT ABLE# | 1.27 | 119C0-119CE | The two terms for being able/unable to evolve using the current stone. | Variable-length strings separated by 0x50. | ABLE#NOT ABLE# | 1.28 | 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), ... | 1.29 | 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#... | 1.30 -| 27E77- | Trainer title names. | | YOUNGSTER#BUG CATCHER#LASS#... | 1.31 -| 34000- | Evolution and learnset data. | | | 1.32 -| 38000- | The basic properties and effects of moves. | 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. | 1.33 +| 27E77- | Trainer title names. | Variable-length names separated by 0x80. | YOUNGSTER#BUG CATCHER#LASS#... | 1.34 +| 34000- | | | | 1.35 +| 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. | 1.36 | 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. | | | 1.37 | 39462- | The Pok\eacute{}mon cry data. | Fixed-length (3 byte) descriptions of cries. | | 1.38 | 3B1E5- | Pointers to evolution/learnset data. | | | 1.39 +| 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. | | 1.40 | 40687- | Species data from the Pok\eacute{}dex: species name, height, weight, etc. | Fixed-length sequences of bytes. See below for specifics. | | 1.41 | 410B1- | A conversion table between internal order and Pokedex order. | | | 1.42 | 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]... | 1.43 @@ -41,13 +49,1156 @@ 1.44 | 7C249-7C2?? | Pointers to background music, pt II. | | | 1.45 | 98000- | Dialogue | | | 1.46 | B8000- | The text of each Pokemon's Pok\eacute{}dex entry. | | | 1.47 -| BC000- | Move names. | | | 1.48 +| BC000-BC60E | Move names. | Variable-length move names, separated by 0x80. The moves are in internal order. | POUND#KARATE CHOP#DOUBLESLAP#COMET PUNCH#... | 1.49 | 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♂#... | 1.50 | | | | | 1.51 | | | | | 1.52 1.53 + 1.54 + 1.55 + 1.56 +** COMMENT Getting linguistic data: names, words, etc. 1.57 + 1.58 +Some of the simplest data 1.59 + 1.60 + 1.61 +One of the simplest data structures in the Pok\eacute{} ROM is an 1.62 +unbroken list of strings that either (a) all have a specific length, 1.63 +or (b) are all separated by the same character. 1.64 + 1.65 +Because lots of good data has this format, we'll start by writing a 1.66 +template function to extract it: 1.67 + 1.68 +#+name: hxc-thunks 1.69 +#+begin_src clojure :results silent 1.70 +(defn hxc-thunk 1.71 + "Creates a thunk (nullary fn) that grabs data in a certain region of rom and 1.72 +splits it into a collection by 0x50. If rom is not supplied, uses the 1.73 + original rom data." 1.74 + [start length] 1.75 + (fn self 1.76 + ([rom] 1.77 + (take-nth 2 1.78 + (partition-by #(= % 0x50) 1.79 + (take length 1.80 + (drop start rom))))) 1.81 + ([] 1.82 + (self com.aurellem.gb.gb-driver/original-rom)))) 1.83 + 1.84 +(def hxc-thunk-words 1.85 + "Same as hxc-thunk, except it interprets the rom data as characters, 1.86 + returning a collection of strings." 1.87 + (comp 1.88 + (partial comp (partial map character-codes->str)) 1.89 + hxc-thunk)) 1.90 + 1.91 +#+end_src 1.92 + 1.93 +* Pok\eacute{}mon 1.94 +** Names of each species 1.95 +The names of the Pok\eacute{}mon species are stored in 1.96 +ROM@E8000. This name list is interesting, for a number of reasons: 1.97 +- The names are stored in [[ ][internal order]] rather than in the familiar 1.98 + Pok\eacute{}dex order. This seemingly random order probably represents the order in which the authors created or 1.99 + programmed in the Pok\eacute{}mon; it's used throughout the game. 1.100 +- There is enough space allocated for 190 Pok\eacute{}mon. As I 1.101 + understand it, there were originally going to be 190 Pok\eacute{}mon 1.102 + in Generation I, but the creators decided to defer some to 1.103 + Generation II. This explains why many Gen I and Gen II Pok\eacute{}mon 1.104 + have the same aesthetic feel. 1.105 +- The list is pockmarked with random gaps, due to the strange internal 1.106 + ordering 1.107 + and 39 unused spaces [fn::190 allocated spaces minus 151 true Pok\eacute{}mon]. These missing spaces are filled with the 1.108 + placeholder name, =MISSINGNO.= (\ldquo{}Missing number\rdquo{}). 1.109 + 1.110 +Each name is exactly ten letters long (Whenever a name is too short, the extra 1.111 +space is padded with the character 0x50). 1.112 + 1.113 + 1.114 + 1.115 +#+name: pokenames 1.116 +#+begin_src clojure 1.117 + 1.118 +(defn hxc-pokenames-raw 1.119 + "The hardcoded names of the 190 species in memory. List begins at 1.120 +ROM@E8000. Although names in memory are padded with 0x50 to be 10 characters 1.121 + long, these names are stripped of padding. See also, hxc-pokedex-names" 1.122 + ([] 1.123 + (hxc-pokenames-raw com.aurellem.gb.gb-driver/original-rom)) 1.124 + ([rom] 1.125 + (let [count-species 190 1.126 + name-length 10] 1.127 + (map character-codes->str 1.128 + (partition name-length 1.129 + (map #(if (= 0x50 %) 0x00 %) 1.130 + (take (* count-species name-length) 1.131 + (drop 0xE8000 1.132 + rom)))))))) 1.133 +(def hxc-pokenames 1.134 + (comp 1.135 + (partial map format-name) 1.136 + hxc-pokenames-raw)) 1.137 + 1.138 + 1.139 + 1.140 + 1.141 +(defn hxc-pokedex-names 1.142 + "The names of the pokemon in hardcoded pokedex order. List begins at 1.143 +ROM@410B1. See also, hxc-pokenames." 1.144 + ([] (hxc-pokedex-names 1.145 + com.aurellem.gb.gb-driver/original-rom)) 1.146 + ([rom] 1.147 + (let [names (hxc-pokenames rom)] 1.148 + (#(mapv % 1.149 + ((comp range count keys) %)) 1.150 + (zipmap 1.151 + (take (count names) 1.152 + (drop 0x410b1 rom)) 1.153 + 1.154 + names))))) 1.155 + 1.156 +#+end_src 1.157 + 1.158 * Appendices 1.159 ** Internal Pok\eacute{}mon IDs 1.160 ** Type IDs 1.161 + 1.162 +#+name: type-ids 1.163 +#+begin_src clojure 1.164 +(def pkmn-types 1.165 + [:normal ;;0 1.166 + :fighting ;;1 1.167 + :flying ;;2 1.168 + :poison ;;3 1.169 + :ground ;;4 1.170 + :rock ;;5 1.171 + :bird ;;6 1.172 + :bug ;;7 1.173 + :ghost ;;8 1.174 + :A 1.175 + :B 1.176 + :C 1.177 + :D 1.178 + :E 1.179 + :F 1.180 + :G 1.181 + :H 1.182 + :I 1.183 + :J 1.184 + :K 1.185 + :fire ;;20 (0x14) 1.186 + :water ;;21 (0x15) 1.187 + :grass ;;22 (0x16) 1.188 + :electric ;;23 (0x17) 1.189 + :psychic ;;24 (0x18) 1.190 + :ice ;;25 (0x19) 1.191 + :dragon ;;26 (0x1A) 1.192 + ]) 1.193 +#+end_src 1.194 + 1.195 ** Basic effects of moves 1.196 + 1.197 +*** Table of basic effects 1.198 + 1.199 +The possible effects of moves in Pok\eacute{}mon \mdash{} for example, dealing 1.200 +damage, leeching health, or potentially poisoning the opponent 1.201 +\mdash{} are stored in a table. Each move has exactly one effect, and 1.202 +different moves might have the same effect. 1.203 + 1.204 +For example, Leech Life, Mega Drain, and Absorb all have effect ID #3, which is \ldquo{}Leech half of the inflicted damage.\rdquo{} 1.205 + 1.206 +All the legitimate move effects are listed in the table 1.207 +below. Here are some notes for reading it: 1.208 + 1.209 +- Whenever an effect has a chance of doing something (like a chance of 1.210 + poisoning the opponent), I list the chance as a hexadecimal amount out of 256 to avoid rounding errors. To convert the hex amount into a percentage, divide by 256. 1.211 +- For some effects, the description is too cumbersome to 1.212 + write. Instead, I just write a move name 1.213 + in parentheses, like: (leech seed). That move gives a characteristic example 1.214 + of the effect. 1.215 +- I use the abbreviations =atk=, =def=, =spd=, =spc=, =acr=, =evd= for 1.216 + attack, defense, speed, special, accuracy, and evasion. 1.217 +. 1.218 + 1.219 + 1.220 + 1.221 +| ID (hex) | Description | Notes | 1.222 +|----------+-------------------------------------------------------------------------------------------------+------------------------------------------------------------------| 1.223 +| 0 | normal damage | | 1.224 +| 1 | no damage, just sleep | TODO: find out how many turns | 1.225 +| 2 | 0x4C chance of poison | | 1.226 +| 3 | leech half of inflicted damage | | 1.227 +| 4 | 0x19 chance of burn | | 1.228 +| 5 | 0x19 chance of freeze | | 1.229 +| 6 | 0x19 chance of paralysis | | 1.230 +| 7 | user faints; opponent's defense is halved during attack. | | 1.231 +| 8 | leech half of inflicted damage ONLY if the opponent is asleep | | 1.232 +| 9 | imitate last attack | | 1.233 +| A | user atk +1 | | 1.234 +| B | user def +1 | | 1.235 +| C | user spd +1 | | 1.236 +| D | user spc +1 | | 1.237 +| E | user acr +1 | This effect is unused. | 1.238 +| F | user evd +1 | | 1.239 +| 10 | get post-battle money = 2 * level * uses | | 1.240 +| 11 | move has 0xFE acr, regardless of battle stat modifications. | | 1.241 +| 12 | opponent atk -1 | | 1.242 +| 13 | opponent def -1 | | 1.243 +| 14 | opponent spd -1 | | 1.244 +| 15 | opponent spc -1 | | 1.245 +| 16 | opponent acr -1 | | 1.246 +| 17 | opponent evd -1 | | 1.247 +| 18 | converts user's type to opponent's. | | 1.248 +| 19 | (haze) | | 1.249 +| 1A | (bide) | | 1.250 +| 1B | (thrash) | | 1.251 +| 1C | (teleport) | | 1.252 +| 1D | (fury swipes) | | 1.253 +| 1E | attacks 2-5 turns | Unused. TODO: find out what it does. | 1.254 +| 1F | 0x19 chance of flinching | | 1.255 +| 20 | opponent sleep for 1-7 turns | | 1.256 +| 21 | 0x66 chance of poison | | 1.257 +| 22 | 0x4D chance of burn | | 1.258 +| 23 | 0x4D chance of freeze | | 1.259 +| 24 | 0x4D chance of paralysis | | 1.260 +| 25 | 0x4D chance of flinching | | 1.261 +| 26 | one-hit KO | | 1.262 +| 27 | charge one turn, atk next. | | 1.263 +| 28 | fixed damage, leaves 1HP. | Is the fixed damage the power of the move? | 1.264 +| 29 | fixed damage. | Like seismic toss, dragon rage, psywave. | 1.265 +| 2A | atk 2-5 turns; opponent can't attack | The odds of attacking for /n/ turns are: (0 0x60 0x60 0x20 0x20) | 1.266 +| 2B | charge one turn, atk next. (can't be hit when charging) | | 1.267 +| 2C | atk hits twice. | | 1.268 +| 2D | user takes 1 damage if misses. | | 1.269 +| 2E | evade status-lowering effects | Caused by you or also your opponent? | 1.270 +| 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. | 1.271 +| 30 | atk causes recoil dmg = 1/4 dmg dealt | | 1.272 +| 31 | confuses opponent | | 1.273 +| 32 | user atk +2 | | 1.274 +| 33 | user def +2 | | 1.275 +| 34 | user spd +2 | | 1.276 +| 35 | user spc +2 | | 1.277 +| 36 | user acr +2 | This effect is unused. | 1.278 +| 37 | user evd +2 | This effect is unused. | 1.279 +| 38 | restores up to half of user's max hp. | | 1.280 +| 39 | (transform) | | 1.281 +| 3A | opponent atk -2 | | 1.282 +| 3B | opponent def -2 | | 1.283 +| 3C | opponent spd -2 | | 1.284 +| 3D | opponent spc -2 | | 1.285 +| 3E | opponent acr -2 | | 1.286 +| 3F | opponent evd -2 | | 1.287 +| 40 | doubles user spc when attacked | | 1.288 +| 41 | doubles user def when attacked | | 1.289 +| 42 | just poisons opponent | | 1.290 +| 43 | just paralyzes opponent | | 1.291 +| 44 | 0x19 chance opponent atk -1 | | 1.292 +| 45 | 0x19 chance opponent def -1 | | 1.293 +| 46 | 0x19 chance opponent spd -1 | | 1.294 +| 47 | 0x4C chance opponent spc -1 | | 1.295 +| 48 | 0x19 chance opponent acr -1 | | 1.296 +| 49 | 0x19 chance opponent evd -1 | | 1.297 +| 4A | ??? | ;; unused? no effect? | 1.298 +| 4B | ??? | ;; unused? no effect? | 1.299 +| 4C | 0x19 chance of confusing the opponent | | 1.300 +| 4D | atk hits twice. 0x33 chance opponent poisioned. | | 1.301 +| 4E | broken. crash the game after attack. | | 1.302 +| 4F | (substitute) | | 1.303 +| 50 | unless opponent faints, user must recharge after atk. some exceptions apply | | 1.304 +| 51 | (rage) | | 1.305 +| 52 | (mimic) | | 1.306 +| 53 | (metronome) | | 1.307 +| 54 | (leech seed) | | 1.308 +| 55 | does nothing (splash) | | 1.309 +| 56 | (disable) | | 1.310 +#+end_src 1.311 + 1.312 +*** Source 1.313 +#+name: move-effects 1.314 +#+begin_src clojure 1.315 +(def move-effects 1.316 + ["normal damage" 1.317 + "no damage, just opponent sleep" ;; how many turns? is atk power ignored? 1.318 + "0x4C chance of poison" 1.319 + "leech half of inflicted damage" 1.320 + "0x19 chance of burn" 1.321 + "0x19 chance of freeze" 1.322 + "0x19 chance of paralyze" 1.323 + "user faints; opponent defense halved during attack." 1.324 + "leech half of inflicted damage ONLY if sleeping opponent." 1.325 + "imitate last attack" 1.326 + "user atk +1" 1.327 + "user def +1" 1.328 + "user spd +1" 1.329 + "user spc +1" 1.330 + "user acr +1" ;; unused?! 1.331 + "user evd +1" 1.332 + "get post-battle $ = 2*level*uses" 1.333 + "0xFE acr, no matter what." 1.334 + "opponent atk -1" ;; acr taken from move acr? 1.335 + "opponent def -1" ;; 1.336 + "opponent spd -1" ;; 1.337 + "opponent spc -1" ;; 1.338 + "opponent acr -1";; 1.339 + "opponent evd -1" 1.340 + "converts user's type to opponent's." 1.341 + "(haze)" 1.342 + "(bide)" 1.343 + "(thrash)" 1.344 + "(teleport)" 1.345 + "(fury swipes)" 1.346 + "attacks 2-5 turns" ;; unused? like rollout? 1.347 + "0x19 chance of flinch" 1.348 + "opponent sleep for 1-7 turns" 1.349 + "0x66 chance of poison" 1.350 + "0x4D chance of burn" 1.351 + "0x4D chance of freeze" 1.352 + "0x4D chance of paralyze" 1.353 + "0x4D chance of flinch" 1.354 + "one-hit KO" 1.355 + "charge one turn, atk next." 1.356 + "fixed damage, leaves 1HP." ;; how is dmg determined? 1.357 + "fixed damage." ;; cf seismic toss, dragon rage, psywave. 1.358 + "atk 2-5 turns; opponent can't attack" ;; unnormalized? (0 0x60 0x60 0x20 0x20) 1.359 + "charge one turn, atk next. (can't be hit when charging)" 1.360 + "atk hits twice." 1.361 + "user takes 1 damage if misses." 1.362 + "evade status-lowering effects" ;;caused by you or also your opponent? 1.363 + "(broken) if user is slower than opponent, makes critical hit impossible, otherwise has no effect" 1.364 + "atk causes recoil dmg = 1/4 dmg dealt" 1.365 + "confuses opponent" ;; acr taken from move acr 1.366 + "user atk +2" 1.367 + "user def +2" 1.368 + "user spd +2" 1.369 + "user spc +2" 1.370 + "user acr +2" ;; unused! 1.371 + "user evd +2" ;; unused! 1.372 + "restores up to half of user's max hp." ;; broken: fails if the difference 1.373 + ;; b/w max and current hp is one less than a multiple of 256. 1.374 + "(transform)" 1.375 + "opponent atk -2" 1.376 + "opponent def -2" 1.377 + "opponent spd -2" 1.378 + "opponent spc -2" 1.379 + "opponent acr -2" 1.380 + "opponent evd -2" 1.381 + "doubles user spc when attacked" 1.382 + "doubles user def when attacked" 1.383 + "just poisons opponent" ;;acr taken from move acr 1.384 + "just paralyzes opponent" ;; 1.385 + "0x19 chance opponent atk -1" 1.386 + "0x19 chance opponent def -1" 1.387 + "0x19 chance opponent spd -1" 1.388 + "0x4C chance opponent spc -1" ;; context suggest chance is 0x19 1.389 + "0x19 chance opponent acr -1" 1.390 + "0x19 chance opponent evd -1" 1.391 + "???" ;; unused? no effect? 1.392 + "???" ;; unused? no effect? 1.393 + "0x19 chance opponent confused" 1.394 + "atk hits twice. 0x33 chance opponent poisioned." 1.395 + "broken. crash the game after attack." 1.396 + "(substitute)" 1.397 + "unless opponent faints, user must recharge after atk. some 1.398 + exceptions apply." 1.399 + "(rage)" 1.400 + "(mimic)" 1.401 + "(metronome)" 1.402 + "(leech seed)" 1.403 + "does nothing (splash)" 1.404 + "(disable)" 1.405 + ]) 1.406 +#+end_src 1.407 + 1.408 + 1.409 ** Alphabet code 1.410 + 1.411 +#+begin_src clojure :tangle ../clojure/com/aurellem/gb/hxc.clj 1.412 + 1.413 +(ns com.aurellem.gb.hxc 1.414 + (:use (com.aurellem.gb assembly characters gb-driver util mem-util 1.415 + constants species)) 1.416 + (:import [com.aurellem.gb.gb_driver SaveState])) 1.417 + 1.418 + 1.419 + 1.420 + 1.421 +; ************* HANDWRITTEN CONSTANTS 1.422 + 1.423 +<<type-ids>> 1.424 + 1.425 + 1.426 +;; question: when status effects claim to take 1.427 +;; their accuracy from the move accuracy, does 1.428 +;; this mean that the move always "hits" but the 1.429 +;; status effect may not? 1.430 + 1.431 +<<move-effects>> 1.432 + 1.433 +;; ************** HARDCODED DATA 1.434 + 1.435 +<<hxc-thunks>> 1.436 +;; -------------------------------------------------- 1.437 + 1.438 + 1.439 +<<pokenames>> 1.440 + 1.441 +;; http://hax.iimarck.us/topic/581/ 1.442 +(defn hxc-cry 1.443 + "The pokemon cry data in internal order. List begins at ROM@39462" 1.444 + ([](hxc-cry com.aurellem.gb.gb-driver/original-rom)) 1.445 + ([rom] 1.446 + (zipmap 1.447 + (hxc-pokenames rom) 1.448 + (map 1.449 + (fn [[cry-id pitch length]] 1.450 + {:cry-id cry-id 1.451 + :pitch pitch 1.452 + :length length} 1.453 + ) 1.454 + (partition 3 1.455 + (drop 0x39462 rom)))))) 1.456 + 1.457 +(defn hxc-cry-groups 1.458 + ([] (hxc-cry-groups com.aurellem.gb.gb-driver/original-rom)) 1.459 + ([rom] 1.460 + (map #(mapv first 1.461 + (filter 1.462 + (fn [[k v]] 1.463 + (= % (:cry-id v))) 1.464 + (hxc-cry))) 1.465 + ((comp 1.466 + range 1.467 + count 1.468 + set 1.469 + (partial map :cry-id) 1.470 + vals 1.471 + hxc-cry) 1.472 + rom)))) 1.473 + 1.474 + 1.475 +(defn cry-conversion! 1.476 + "Convert Porygon's cry in ROM to be the cry of the given pokemon." 1.477 + [pkmn] 1.478 + (write-rom! 1.479 + (rewrite-memory 1.480 + (vec(rom)) 1.481 + 0x3965D 1.482 + (map second 1.483 + ((hxc-cry) pkmn))))) 1.484 + 1.485 +(def hxc-items-raw 1.486 + "The hardcoded names of the items in memory. List begins at 1.487 +ROM@045B7" 1.488 + (hxc-thunk-words 0x45B7 870)) 1.489 + 1.490 +(def hxc-types 1.491 + "The hardcoded type names in memory. List begins at ROM@27D99, 1.492 + shortly before hxc-titles." 1.493 + (hxc-thunk-words 0x27D99 102)) 1.494 + 1.495 +(def hxc-titles 1.496 + "The hardcoded names of the trainer titles in memory. List begins at 1.497 +ROM@27E77" 1.498 + (hxc-thunk-words 0x27E77 196)) 1.499 + 1.500 + 1.501 +(def hxc-pokedex-text-raw 1.502 + "The hardcoded pokedex entries in memory. List begins at 1.503 +ROM@B8000, shortly before move names." 1.504 + (hxc-thunk-words 0xB8000 14754)) 1.505 + 1.506 + 1.507 + 1.508 +(def hxc-items 1.509 + "The hardcoded names of the items in memory, presented as 1.510 + keywords. List begins at ROM@045B7. See also, hxc-items-raw." 1.511 + (comp (partial map format-name) hxc-items-raw)) 1.512 + 1.513 +(defn hxc-pokedex-text 1.514 + "The hardcoded pokedex entries in memory, presented as an 1.515 +associative hash map. List begins at ROM@B8000." 1.516 + ([] (hxc-pokedex-text com.aurellem.gb.gb-driver/original-rom)) 1.517 + ([rom] 1.518 + (zipmap 1.519 + (hxc-pokedex-names rom) 1.520 + (cons nil ;; for missingno. 1.521 + (hxc-pokedex-text-raw rom))))) 1.522 + 1.523 +;; In red/blue, pokedex stats are in internal order. 1.524 +;; In yellow, pokedex stats are in pokedex order. 1.525 + 1.526 +(defn hxc-pokedex-stats 1.527 + "The hardcoded pokedex stats (species height weight) in memory. List 1.528 +begins at ROM@40687" 1.529 + ([] (hxc-pokedex-stats com.aurellem.gb.gb-driver/original-rom)) 1.530 + ([rom] 1.531 + (let [pokedex-names (zipmap (range) (hxc-pokedex-names rom)) 1.532 + pkmn-count (count pokedex-names) 1.533 + ] 1.534 + ((fn capture-stats 1.535 + [n stats data] 1.536 + (if (zero? n) stats 1.537 + (let [[species 1.538 + [_ 1.539 + height-ft 1.540 + height-in 1.541 + weight-1 1.542 + weight-2 1.543 + _ 1.544 + dex-ptr-1 1.545 + dex-ptr-2 1.546 + dex-bank 1.547 + _ 1.548 + & data]] 1.549 + (split-with (partial not= 0x50) data)] 1.550 + (recur (dec n) 1.551 + (assoc stats 1.552 + (pokedex-names (- pkmn-count (dec n))) 1.553 + {:species 1.554 + (format-name (character-codes->str species)) 1.555 + :height-ft 1.556 + height-ft 1.557 + :height-in 1.558 + height-in 1.559 + :weight 1.560 + (/ (low-high weight-1 weight-2) 10.) 1.561 + 1.562 + ;; :text 1.563 + ;; (character-codes->str 1.564 + ;; (take-while 1.565 + ;; (partial not= 0x50) 1.566 + ;; (drop 1.567 + ;; (+ 0xB8000 1.568 + ;; -0x4000 1.569 + ;; (low-high dex-ptr-1 dex-ptr-2)) 1.570 + ;; rom))) 1.571 + }) 1.572 + 1.573 + data) 1.574 + 1.575 + 1.576 + ))) 1.577 + 1.578 + pkmn-count 1.579 + {} 1.580 + (drop 0x40687 rom))) )) 1.581 + 1.582 + 1.583 + 1.584 + 1.585 + 1.586 + 1.587 + 1.588 +(def hxc-places 1.589 + "The hardcoded place names in memory. List begins at 1.590 +ROM@71500. [Cinnabar] Mansion seems to be dynamically calculated." 1.591 + (hxc-thunk-words 0x71500 560)) 1.592 + 1.593 + 1.594 +(defn hxc-dialog 1.595 + "The hardcoded dialogue in memory, including in-game alerts. Dialog 1.596 + seems to be separated by 0x57 instead of 0x50 (END). Begins at ROM@98000." 1.597 + ([rom] 1.598 + (map character-codes->str 1.599 + (take-nth 2 1.600 + (partition-by #(= % 0x57) 1.601 + (take 0x0F728 1.602 + (drop 0x98000 rom)))))) 1.603 + ([] 1.604 + (hxc-dialog com.aurellem.gb.gb-driver/original-rom))) 1.605 + 1.606 + 1.607 +(def hxc-move-names 1.608 + "The hardcoded move names in memory. List begins at ROM@BC000" 1.609 + (hxc-thunk-words 0xBC000 1551)) 1.610 + 1.611 + 1.612 +(defn hxc-move-data 1.613 + "The hardcoded (basic (move effects)) in memory. List begins at 1.614 +0x38000. Returns a map of {:name :power :accuracy :pp :fx-id 1.615 + :fx-txt}. The move descriptions are handwritten, not hardcoded." 1.616 + ([] 1.617 + (hxc-move-data com.aurellem.gb.gb-driver/original-rom)) 1.618 + ([rom] 1.619 + (let [names (vec (hxc-move-names rom)) 1.620 + move-count (count names) 1.621 + move-size 6 1.622 + types pkmn-types ;;; !! hardcoded types 1.623 + ] 1.624 + (zipmap (map format-name names) 1.625 + (map 1.626 + (fn [[idx effect power type-id accuracy pp]] 1.627 + {:name (names (dec idx)) 1.628 + :power power 1.629 + :accuracy accuracy 1.630 + :pp pp 1.631 + :type (types type-id) 1.632 + :fx-id effect 1.633 + :fx-txt (get move-effects effect) 1.634 + } 1.635 + ) 1.636 + 1.637 + (partition move-size 1.638 + (take (* move-size move-count) 1.639 + (drop 0x38000 rom)))))))) 1.640 + 1.641 + 1.642 + 1.643 +(defn hxc-move-data* 1.644 + "Like hxc-move-data, but reports numbers as hexadecimal symbols instead." 1.645 + ([] 1.646 + (hxc-move-data* com.aurellem.gb.gb-driver/original-rom)) 1.647 + ([rom] 1.648 + (let [names (vec (hxc-move-names rom)) 1.649 + move-count (count names) 1.650 + move-size 6 1.651 + format-name (fn [s] 1.652 + (keyword (.toLowerCase 1.653 + (apply str 1.654 + (map #(if (= % \space) "-" %) s))))) 1.655 + ] 1.656 + (zipmap (map format-name names) 1.657 + (map 1.658 + (fn [[idx effect power type accuracy pp]] 1.659 + {:name (names (dec idx)) 1.660 + :power power 1.661 + :accuracy (hex accuracy) 1.662 + :pp pp 1.663 + :fx-id (hex effect) 1.664 + :fx-txt (get move-effects effect) 1.665 + } 1.666 + ) 1.667 + 1.668 + (partition move-size 1.669 + (take (* move-size move-count) 1.670 + (drop 0x38000 rom)))))))) 1.671 + 1.672 + 1.673 +(defn hxc-machines 1.674 + "The hardcoded moves taught by TMs and HMs. List begins at ROM@1232D." 1.675 + ([] (hxc-machines 1.676 + com.aurellem.gb.gb-driver/original-rom)) 1.677 + ([rom] 1.678 + (let [moves (hxc-move-names rom)] 1.679 + (zipmap 1.680 + (range) 1.681 + (take-while 1.682 + (comp not nil?) 1.683 + (map (comp 1.684 + format-name 1.685 + (zipmap 1.686 + (range) 1.687 + moves) 1.688 + dec) 1.689 + (take 100 1.690 + (drop 0x1232D rom)))))))) 1.691 + 1.692 + 1.693 + 1.694 +(defn internal-id 1.695 + ([rom] 1.696 + (zipmap 1.697 + (hxc-pokenames rom) 1.698 + (range))) 1.699 + ([] 1.700 + (internal-id com.aurellem.gb.gb-driver/original-rom))) 1.701 + 1.702 + 1.703 + 1.704 + 1.705 + 1.706 +;; nidoran gender change upon levelup 1.707 +;; (-> 1.708 +;; @current-state 1.709 +;; rom 1.710 +;; vec 1.711 +;; (rewrite-memory 1.712 +;; (nth (hxc-ptrs-evolve) ((internal-id) :nidoran♂)) 1.713 +;; [1 1 15]) 1.714 +;; (rewrite-memory 1.715 +;; (nth (hxc-ptrs-evolve) ((internal-id) :nidoran♀)) 1.716 +;; [1 1 3]) 1.717 +;; (write-rom!) 1.718 + 1.719 +;; ) 1.720 + 1.721 + 1.722 + 1.723 + 1.724 +(defn hxc-advantage 1.725 + ;; in-game multipliers are stored as 10x their effective value 1.726 + ;; to allow for fractional multipliers like 1/2 1.727 + 1.728 + "The hardcoded type advantages in memory, returned as tuples of 1.729 + atk-type def-type multiplier. By default (i.e. if not listed here), 1.730 +the multiplier is 1. List begins at 0x3E62D." 1.731 + ([] (hxc-advantage com.aurellem.gb.gb-driver/original-rom)) 1.732 + ([rom] 1.733 + (map 1.734 + (fn [[atk def mult]] [(get pkmn-types atk (hex atk)) 1.735 + (get pkmn-types def (hex def)) 1.736 + (/ mult 10)]) 1.737 + (partition 3 1.738 + (take-while (partial not= 0xFF) 1.739 + (drop 0x3E62D rom)))))) 1.740 + 1.741 + 1.742 + 1.743 +(defn format-evo 1.744 + "Parse a sequence of evolution data, returning a map. First is the 1.745 +method: 0 = end-evolution-data. 1 = level-up, 2 = item, 3 = trade. Next is an item id, if the 1.746 + method of evolution is by item (only stones will actually make pokemon 1.747 + evolve, for some auxillary reason.) Finally, the minimum level for 1.748 + evolution to occur (level 1 means no limit, which is used for trade 1.749 + and item evolutions), followed by the internal id of the pokemon 1.750 + into which to evolve. Hence, level up and trade evolutions are 1.751 + described with 3 1.752 + bytes; item evolutions with four." 1.753 + [coll] 1.754 + (let [method (first coll)] 1.755 + (cond (empty? coll) [] 1.756 + (= 0 method) [] ;; just in case 1.757 + (= 1 method) ;; level-up evolution 1.758 + (conj (format-evo (drop 3 coll)) 1.759 + {:method :level-up 1.760 + :min-level (nth coll 1) 1.761 + :into (dec (nth coll 2))}) 1.762 + 1.763 + (= 2 method) ;; item evolution 1.764 + (conj (format-evo (drop 4 coll)) 1.765 + {:method :item 1.766 + :item (dec (nth coll 1)) 1.767 + :min-level (nth coll 2) 1.768 + :into (dec (nth coll 3))}) 1.769 + 1.770 + (= 3 method) ;; trade evolution 1.771 + (conj (format-evo (drop 3 coll)) 1.772 + {:method :trade 1.773 + :min-level (nth coll 1) ;; always 1 for trade. 1.774 + :into (dec (nth coll 2))})))) 1.775 + 1.776 + 1.777 +(defn hxc-ptrs-evolve 1.778 + "A hardcoded collection of 190 pointers to alternating evolution/learnset data, 1.779 +in internal order." 1.780 + ([] 1.781 + (hxc-ptrs-evolve com.aurellem.gb.gb-driver/original-rom)) 1.782 + ([rom] 1.783 + (let [ 1.784 + pkmn-count (count (hxc-pokenames-raw)) ;; 190 1.785 + ptrs 1.786 + (map (fn [[a b]] (low-high a b)) 1.787 + (partition 2 1.788 + (take (* 2 pkmn-count) 1.789 + (drop 0x3b1e5 rom))))] 1.790 + (map (partial + 0x34000) ptrs) 1.791 + 1.792 + ))) 1.793 + 1.794 + 1.795 +(defn hxc-learnsets 1.796 + "Hardcoded map associating pokemon names to lists of pairs [lvl 1.797 + move] of abilities they learn as they level up. The data 1.798 +exists at ROM@34000, sorted by internal order. Pointers to the data 1.799 + exist at ROM@3B1E5; see also, hxc-ptrs-evolve" 1.800 + ([] (hxc-learnsets com.aurellem.gb.gb-driver/original-rom)) 1.801 + ([rom] 1.802 + (apply assoc 1.803 + {} 1.804 + (interleave 1.805 + (hxc-pokenames rom) 1.806 + (map (comp 1.807 + (partial map 1.808 + (fn [[lvl mv]] [lvl (dec mv)])) 1.809 + (partial partition 2) 1.810 + ;; keep the learnset data 1.811 + (partial take-while (comp not zero?)) 1.812 + ;; skip the evolution data 1.813 + rest 1.814 + (partial drop-while (comp not zero?))) 1.815 + (map #(drop % rom) 1.816 + (hxc-ptrs-evolve rom))))))) 1.817 + 1.818 +(defn hxc-learnsets-pretty 1.819 + "Live hxc-learnsets except it reports the name of each move --- as 1.820 +it appears in rom --- rather than the move index." 1.821 + ([] (hxc-learnsets-pretty com.aurellem.gb.gb-driver/original-rom)) 1.822 + ([rom] 1.823 + (let [moves (vec(map format-name (hxc-move-names)))] 1.824 + (into {} 1.825 + (map (fn [[pkmn learnset]] 1.826 + [pkmn (map (fn [[lvl mv]] [lvl (moves mv)]) 1.827 + learnset)]) 1.828 + (hxc-learnsets rom)))))) 1.829 + 1.830 + 1.831 + 1.832 + 1.833 +(defn hxc-evolution 1.834 + "Hardcoded evolution data in memory. The data exists at ROM@34000, 1.835 + sorted by internal order. Pointers to the data exist at ROM@3B1E5; see also, hxc-ptrs-evolve." 1.836 + ([] (hxc-evolution com.aurellem.gb.gb-driver/original-rom)) 1.837 + ([rom] 1.838 + (apply assoc {} 1.839 + (interleave 1.840 + (hxc-pokenames rom) 1.841 + (map 1.842 + (comp 1.843 + format-evo 1.844 + (partial take-while (comp not zero?)) 1.845 + #(drop % rom)) 1.846 + (hxc-ptrs-evolve rom) 1.847 + ))))) 1.848 + 1.849 +(defn hxc-evolution-pretty 1.850 + "Like hxc-evolution, except it uses the names of items and pokemon 1.851 +--- grabbed from ROM --- rather than their numerical identifiers." 1.852 + ([] (hxc-evolution-pretty com.aurellem.gb.gb-driver/original-rom)) 1.853 + ([rom] 1.854 + (let 1.855 + [poke-names (vec (hxc-pokenames rom)) 1.856 + item-names (vec (hxc-items rom)) 1.857 + use-names 1.858 + (fn [m] 1.859 + (loop [ks (keys m) new-map m] 1.860 + (let [k (first ks)] 1.861 + (cond (nil? ks) new-map 1.862 + (= k :into) 1.863 + (recur 1.864 + (next ks) 1.865 + (assoc new-map 1.866 + :into 1.867 + (poke-names 1.868 + (:into 1.869 + new-map)))) 1.870 + (= k :item) 1.871 + (recur 1.872 + (next ks) 1.873 + (assoc new-map 1.874 + :item 1.875 + (item-names 1.876 + (:item new-map)))) 1.877 + :else 1.878 + (recur 1.879 + (next ks) 1.880 + new-map) 1.881 + ))))] 1.882 + 1.883 + (into {} 1.884 + (map (fn [[pkmn evo-coll]] 1.885 + [pkmn (map use-names evo-coll)]) 1.886 + (hxc-evolution rom)))))) 1.887 + 1.888 + 1.889 +(defn hxc-pokemon-base 1.890 + ([] (hxc-pokemon-base com.aurellem.gb.gb-driver/original-rom)) 1.891 + ([rom] 1.892 + (let [entry-size 28 1.893 + pkmn-count (count (hxc-pokedex-text rom)) 1.894 + pokemon (rest (hxc-pokedex-names)) 1.895 + types (apply assoc {} 1.896 + (interleave 1.897 + (range) 1.898 + pkmn-types)) ;;!! softcoded 1.899 + moves (apply assoc {} 1.900 + (interleave 1.901 + (range) 1.902 + (map format-name 1.903 + (hxc-move-names rom)))) 1.904 + machines (hxc-machines) 1.905 + ] 1.906 + (zipmap 1.907 + pokemon 1.908 + (map 1.909 + (fn [[n 1.910 + rating-hp 1.911 + rating-atk 1.912 + rating-def 1.913 + rating-speed 1.914 + rating-special 1.915 + type-1 1.916 + type-2 1.917 + rarity 1.918 + rating-xp 1.919 + pic-dimensions ;; tile_width|tile_height (8px/tile) 1.920 + ptr-pic-obverse-1 1.921 + ptr-pic-obverse-2 1.922 + ptr-pic-reverse-1 1.923 + ptr-pic-reverse-2 1.924 + move-1 1.925 + move-2 1.926 + move-3 1.927 + move-4 1.928 + growth-rate 1.929 + & 1.930 + TMs|HMs]] 1.931 + (let 1.932 + [base-moves 1.933 + (mapv moves 1.934 + ((comp 1.935 + ;; since the game uses zero as a delimiter, 1.936 + ;; it must also increment all move indices by 1. 1.937 + ;; heren we decrement to correct this. 1.938 + (partial map dec) 1.939 + (partial take-while (comp not zero?))) 1.940 + [move-1 move-2 move-3 move-4])) 1.941 + 1.942 + types 1.943 + (set (list (types type-1) 1.944 + (types type-2))) 1.945 + TMs|HMs 1.946 + (map 1.947 + (comp 1.948 + (partial map first) 1.949 + (partial remove (comp zero? second))) 1.950 + (split-at 1.951 + 50 1.952 + (map vector 1.953 + (rest(range)) 1.954 + (reduce concat 1.955 + (map 1.956 + #(take 8 1.957 + (concat (bit-list %) 1.958 + (repeat 0))) 1.959 + 1.960 + TMs|HMs))))) 1.961 + 1.962 + TMs (vec (first TMs|HMs)) 1.963 + HMs (take 5 (map (partial + -50) (vec (second TMs|HMs)))) 1.964 + 1.965 + 1.966 + ] 1.967 + 1.968 + 1.969 + {:dex# n 1.970 + :base-moves base-moves 1.971 + :types types 1.972 + :TMs TMs 1.973 + :HMs HMs 1.974 + :base-hp rating-hp 1.975 + :base-atk rating-atk 1.976 + :base-def rating-def 1.977 + :base-speed rating-speed 1.978 + :base-special rating-special 1.979 + :o0 pic-dimensions 1.980 + :o1 ptr-pic-obverse-1 1.981 + :o2 ptr-pic-obverse-2 1.982 + })) 1.983 + 1.984 + (partition entry-size 1.985 + (take (* entry-size pkmn-count) 1.986 + (drop 0x383DE 1.987 + rom)))))))) 1.988 + 1.989 + 1.990 +(defn hxc-intro-pkmn 1.991 + "The hardcoded pokemon to display in Prof. Oak's introduction; the pokemon's 1.992 +internal id is stored at ROM@5EDB." 1.993 + ([] (hxc-intro-pkmn 1.994 + com.aurellem.gb.gb-driver/original-rom)) 1.995 + ([rom] 1.996 + (nth (hxc-pokenames rom) (nth rom 0x5EDB)))) 1.997 + 1.998 +(defn sxc-intro-pkmn! 1.999 + "Set the hardcoded pokemon to display in Prof. Oak's introduction." 1.1000 + [pokemon] 1.1001 + (write-rom! 1.1002 + (rewrite-rom 0x5EDB 1.1003 + [ 1.1004 + (inc 1.1005 + ((zipmap 1.1006 + (hxc-pokenames) 1.1007 + (range)) 1.1008 + pokemon))]))) 1.1009 + 1.1010 + 1.1011 +(defn hxc-item-prices 1.1012 + "The hardcoded list of item prices in memory. List begins at ROM@4495" 1.1013 + ([] (hxc-item-prices com.aurellem.gb.gb-driver/original-rom)) 1.1014 + ([rom] 1.1015 + (let [items (hxc-items rom) 1.1016 + price-size 3] 1.1017 + (zipmap items 1.1018 + (map (comp 1.1019 + ;; zero-cost items are "priceless" 1.1020 + #(if (zero? %) :priceless %) 1.1021 + decode-bcd butlast) 1.1022 + (partition price-size 1.1023 + (take (* price-size (count items)) 1.1024 + (drop 0x4495 rom)))))))) 1.1025 + 1.1026 +(defn hxc-shops 1.1027 + ([] (hxc-shops com.aurellem.gb.gb-driver/original-rom)) 1.1028 + ([rom] 1.1029 + (let [items (zipmap (range) (hxc-items rom)) 1.1030 + 1.1031 + ;; temporarily softcode the TM items 1.1032 + items (into 1.1033 + items 1.1034 + (map (juxt identity 1.1035 + (comp keyword 1.1036 + (partial str "tm-") 1.1037 + (partial + 1 -200) 1.1038 + )) 1.1039 + (take 200 (drop 200 (range))))) 1.1040 + 1.1041 + ] 1.1042 + 1.1043 + ((fn parse-shop [coll [num-items & items-etc]] 1.1044 + (let [inventory (take-while 1.1045 + (partial not= 0xFF) 1.1046 + items-etc) 1.1047 + [separator & items-etc] (drop num-items (rest items-etc))] 1.1048 + (if (= separator 0x50) 1.1049 + (map (partial mapv (comp items dec)) (conj coll inventory)) 1.1050 + (recur (conj coll inventory) items-etc) 1.1051 + ) 1.1052 + )) 1.1053 + 1.1054 + '() 1.1055 + (drop 0x233C rom)) 1.1056 + 1.1057 + 1.1058 + ))) 1.1059 + 1.1060 + 1.1061 + 1.1062 + 1.1063 + 1.1064 +(defn hxc-ptrs-wild 1.1065 + "A list of the hardcoded wild encounter data in memory. Pointers 1.1066 + begin at ROM@0CB95; data begins at ROM@0x04D89" 1.1067 + ([] (hxc-ptrs-wild com.aurellem.gb.gb-driver/original-rom)) 1.1068 + ([rom] 1.1069 + (let [ptrs 1.1070 + (map (fn [[a b]] (+ a (* 0x100 b))) 1.1071 + (take-while (partial not= (list 0xFF 0xFF)) 1.1072 + (partition 2 (drop 0xCB95 rom))))] 1.1073 + ptrs))) 1.1074 + 1.1075 + 1.1076 + 1.1077 +(defn hxc-wilds 1.1078 + "A list of the hardcoded wild encounter data in memory. Pointers 1.1079 + begin at ROM@0CB95; data begins at ROM@0x04D89" 1.1080 + ([] (hxc-wilds com.aurellem.gb.gb-driver/original-rom)) 1.1081 + ([rom] 1.1082 + (let [pokenames (zipmap (range) (hxc-pokenames rom))] 1.1083 + (map 1.1084 + (partial map (fn [[a b]] {:species (pokenames (dec b)) :level 1.1085 + a})) 1.1086 + (partition 10 1.1087 + 1.1088 + (take-while (comp (partial not= 1) 1.1089 + first) 1.1090 + (partition 2 1.1091 + (drop 0xCD8C rom)) 1.1092 + 1.1093 + )))))) 1.1094 + 1.1095 + 1.1096 + 1.1097 + 1.1098 + 1.1099 + 1.1100 + 1.1101 + 1.1102 + 1.1103 + 1.1104 + 1.1105 + 1.1106 + 1.1107 + 1.1108 +;; ********************** MANIPULATION FNS 1.1109 + 1.1110 + 1.1111 +(defn same-type 1.1112 + ([pkmn move] 1.1113 + (same-type 1.1114 + com.aurellem.gb.gb-driver/original-rom pkmn move)) 1.1115 + ([rom pkmn move] 1.1116 + (((comp :types (hxc-pokemon-base rom)) pkmn) 1.1117 + ((comp :type (hxc-move-data rom)) move)))) 1.1118 + 1.1119 + 1.1120 + 1.1121 + 1.1122 +(defn submap? 1.1123 + "Compares the two maps. Returns true if map-big has the same associations as map-small, otherwise false." 1.1124 + [map-small map-big] 1.1125 + (cond (empty? map-small) true 1.1126 + (and 1.1127 + (contains? map-big (ffirst map-small)) 1.1128 + (= (get map-big (ffirst map-small)) 1.1129 + (second (first map-small)))) 1.1130 + (recur (next map-small) map-big) 1.1131 + 1.1132 + :else false)) 1.1133 + 1.1134 + 1.1135 +(defn search-map [proto-map maps] 1.1136 + "Returns all the maps that make the same associations as proto-map." 1.1137 + (some (partial submap? proto-map) maps)) 1.1138 + 1.1139 +(defn filter-vals 1.1140 + "Returns a map consisting of all the pairs [key val] for 1.1141 + which (pred key) returns true." 1.1142 + [pred map] 1.1143 + (reduce (partial apply assoc) {} 1.1144 + (filter (fn [[k v]] (pred v)) map))) 1.1145 + 1.1146 + 1.1147 +(defn search-moves 1.1148 + "Returns a subcollection of all hardcoded moves with the 1.1149 + given attributes. Attributes consist of :name :power 1.1150 + :accuracy :pp :fx-id 1.1151 + (and also :fx-txt, but it contains the same information 1.1152 + as :fx-id)" 1.1153 + ([attribute-map] 1.1154 + (search-moves 1.1155 + com.aurellem.gb.gb-driver/original-rom attribute-map)) 1.1156 + ([rom attribute-map] 1.1157 + (filter-vals (partial submap? attribute-map) 1.1158 + (hxc-move-data rom)))) 1.1159 + 1.1160 + 1.1161 + 1.1162 + 1.1163 + 1.1164 +;; note: 0x2f31 contains the names "TM" "HM"? 1.1165 + 1.1166 +;; note for later: credits start at F1290 1.1167 + 1.1168 +;; note: DADB hyper-potion-hp _ _ _ super-potion-hp _ _ _ potion-hp ?? 1.1169 + 1.1170 +;; note: DD4D spells out pokemon vital stat names ("speed", etc.) 1.1171 + 1.1172 +;; note: 1195C-6A says ABLE#NOT ABLE#, but so does 119C0-119CE. 1.1173 +;; The first instance is for Machines; the second, for stones. 1.1174 + 1.1175 +;; 0x251A (in indexable mem): image decompression routine seems to begin here. 1.1176 + 1.1177 + 1.1178 +(comment 1.1179 + 1.1180 +(def hxc-later 1.1181 + "Running this code produces, e.g. hardcoded names NPCs give 1.1182 +their pokemon. Will sort through it later." 1.1183 +(print (character-codes->str(take 10000 1.1184 + (drop 0x71597 1.1185 + (rom (root))))))) 1.1186 + 1.1187 +(let [dex 1.1188 + (partition-by #(= 0x50 %) 1.1189 + (take 2540 1.1190 + (drop 0x40687 1.1191 + (rom (root)))))] 1.1192 + (def dex dex) 1.1193 + (def hxc-species 1.1194 + (map character-codes->str 1.1195 + (take-nth 4 dex)))) 1.1196 +) 1.1197 + 1.1198 + 1.1199 +#+end_src 1.1200 +