comparison org/rom.org @ 419:4901ba2d3860

Figured out how NPC Pokemon teams are encoded.
author Dylan Holmes <ocsenave@gmail.com>
date Sat, 14 Apr 2012 05:20:28 -0500
parents 543a78679971
children acc3d1ad24e8
comparison
equal deleted inserted replaced
416:21b8b3350b20 419:4901ba2d3860
1 #+title: Notes on Deconstructing Pokemon Yellow 1 #+title: Notes on Deconstructing Pokemon Yellow
2 #+author: Dylan Holmes 2 #+author: Dylan Holmes
3 #+email: rlm@mit.edu 3 #+email: rlm@mit.edu
4 #+description: 4 #+description: A detailed explication of Pok\eacute{}mon Yellow, helped by Clojure.
5 #+keywords: 5 #+keywords: pokemon, pokemon yellow, rom, gameboy, assembly, hex, pointers, clojure
6 #+SETUPFILE: ../../aurellem/org/setup.org 6 #+SETUPFILE: ../../aurellem/org/setup.org
7 #+INCLUDE: ../../aurellem/org/level-0.org 7 #+INCLUDE: ../../aurellem/org/level-0.org
8 #+BABEL: :exports both :noweb yes :cache no :mkdirp yes 8 #+BABEL: :exports both :noweb yes :cache no :mkdirp yes
9 9
10 # about map headers http://datacrystal.romhacking.net/wiki/Pokemon_Red/Blue:Notes 10 # about map headers http://datacrystal.romhacking.net/wiki/Pokemon_Red/Blue:Notes
11 # map headers Yellow http://www.pokecommunity.com/archive/index.php/t-235311.html 11 # map headers Yellow http://www.pokecommunity.com/archive/index.php/t-235311.html
12 # pokedollar: U+20B1 12 # pokedollar: U+20B1
13 * Introduction 13 * Introduction
14
15 14
16 ** COMMENT Getting linguistic data: names, words, etc. 15 ** COMMENT Getting linguistic data: names, words, etc.
17 16
18 Some of the simplest data 17 Some of the simplest data
19 18
1009 1008
1010 1009
1011 1010
1012 ** COMMENT Status ailments 1011 ** COMMENT Status ailments
1013 1012
1013
1014 * NPC Trainers
1015
1016 ** Trainer Pok\eacute{}mon
1017 # http://hax.iimarck.us/topic/103/
1018 There are two formats for specifying lists of NPC PPok\eacute{}mon:
1019 - If all the Pok\eacute{}mon will have the same level, the format is
1020 - Level (used for all the Pok\eacute{}mon)
1021 - Any number of Pok\eacute{}mon internal ids.
1022 - 0x00, to indicate end-of-list.
1023 - Otherwise, all the Pok\eacute{}mon will have their level
1024 specified. The format is
1025 - 0xFF, to indicate that we will be specifying the levels individually[fn::Because 0xFF is a
1026 forbidden level within the usual gameplay discipline, the game
1027 makers could safely use 0xFF as a mode indicator.].
1028 - Any number of alternating Level/Pokemon pairs
1029 - 0x00, to indicate end-of-list.
1030
1031 *** Get the pointers
1032 *** See the data
1033 #+begin_src clojure :exports both :results output
1034 (ns com.aurellem.gb.hxc
1035 (:use (com.aurellem.gb assembly characters gb-driver util mem-util
1036 constants))
1037 (:import [com.aurellem.gb.gb_driver SaveState]))
1038
1039 (->>
1040 (rom)
1041 (drop 0x39E2F)
1042 (take 21)
1043 (println))
1044
1045
1046 (->>
1047 (rom)
1048 (drop 0x39E2F)
1049 (take 21)
1050 (partition-by zero?)
1051 (take-nth 2)
1052 (println))
1053
1054
1055
1056 (let
1057 [pokenames
1058 (zipmap
1059 (rest (range))
1060 (hxc-pokenames-raw))]
1061
1062 (->>
1063 (rom)
1064 (drop 0x39E2F)
1065 (take 21) ;; (1922 in all)
1066 (partition-by zero?)
1067 (take-nth 2)
1068 (map
1069 (fn parse-team [[mode & team]]
1070 (if (not= 0xFF mode)
1071 (mapv
1072 #(hash-map :level mode :species (pokenames %))
1073 team)
1074
1075 (mapv
1076 (fn [[lvl id]] (hash-map :level lvl :species (pokenames id)))
1077 (partition 2 team)))))
1078
1079 (println)))
1080
1081
1082
1083 #+end_src
1084
1085 #+results:
1086 : (11 165 108 0 14 5 0 10 165 165 107 0 14 165 108 107 0 15 165 5 0)
1087 : ((11 165 108) (14 5) (10 165 165 107) (14 165 108 107) (15 165 5))
1088 : ([{:species RATTATA, :level 11} {:species EKANS, :level 11}] [{:species SPEAROW, :level 14}] [{:species RATTATA, :level 10} {:species RATTATA, :level 10} {:species ZUBAT, :level 10}] [{:species RATTATA, :level 14} {:species EKANS, :level 14} {:species ZUBAT, :level 14}] [{:species RATTATA, :level 15} {:species SPEAROW, :level 15}])
1089
1014 * Places 1090 * Places
1015 ** Names of places 1091 ** Names of places
1016 1092
1017 #+name: places 1093 #+name: places
1018 #+begin_src clojure 1094 #+begin_src clojure
1019 (def hxc-places 1095 (def hxc-places
1020 "The hardcoded place names in memory. List begins at 1096 "The hardcoded place names in memory. List begins at
1021 ROM@71500. [Cinnabar] Mansion seems to be dynamically calculated." 1097 ROM@71500. [Cinnabar/Cerulean] Mansion seems to be dynamically calculated."
1022 (hxc-thunk-words 0x71500 560)) 1098 (hxc-thunk-words 0x71500 560))
1023 1099 #+end_src
1024 #+end_src 1100
1101 *** See it work
1102 #+begin_src clojure :exports both :results output
1103 (println (hxc-places))
1104 #+end_src
1105
1106 #+results:
1107 : (PALLET TOWN VIRIDIAN CITY PEWTER CITY CERULEAN CITY LAVENDER TOWN VERMILION CITY CELADON CITY FUCHSIA CITY CINNABAR ISLAND INDIGO PLATEAU SAFFRON CITY ROUTE 1 ROUTE 2 ROUTE 3 ROUTE 4 ROUTE 5 ROUTE 6 ROUTE 7 ROUTE 8 ROUTE 9 ROUTE 10 ROUTE 11 ROUTE 12 ROUTE 13 ROUTE 14 ROUTE 15 ROUTE 16 ROUTE 17 ROUTE 18 SEA ROUTE 19 SEA ROUTE 20 SEA ROUTE 21 ROUTE 22 ROUTE 23 ROUTE 24 ROUTE 25 VIRIDIAN FOREST MT.MOON ROCK TUNNEL SEA COTTAGE S.S.ANNE [POKE]MON LEAGUE UNDERGROUND PATH [POKE]MON TOWER SEAFOAM ISLANDS VICTORY ROAD DIGLETT's CAVE ROCKET HQ SILPH CO. [0x4A] MANSION SAFARI ZONE)
1025 1108
1026 ** Wild Pok\eacute{}mon demographics 1109 ** Wild Pok\eacute{}mon demographics
1027 #+name: wilds 1110 #+name: wilds
1028 #+begin_src clojure 1111 #+begin_src clojure
1029 1112
1065 1148
1066 1149
1067 1150
1068 1151
1069 * Appendices 1152 * Appendices
1070
1071
1072
1073 ** Mapping the ROM 1153 ** Mapping the ROM
1074 1154
1075 | ROM address (hex) | Description | Format | Example | 1155 | ROM address (hex) | Description | Format | Example |
1076 |-----------------------+-----------------+-----------------+-----------------| 1156 |-----------------------+-----------------+-----------------+-----------------|
1077 | | <15> | <15> | <15> | 1157 | | <15> | <15> | <15> |
1116 | 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. | | | 1196 | 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. | | |
1117 | 39462- | The Pok\eacute{}mon cry data. | Fixed-length (3 byte) descriptions of cries. | | 1197 | 39462- | The Pok\eacute{}mon cry data. | Fixed-length (3 byte) descriptions of cries. | |
1118 |-----------------------+-----------------+-----------------+-----------------| 1198 |-----------------------+-----------------+-----------------+-----------------|
1119 | 3997D-39B05 | Trainer titles (extended; see 27E77). This list includes strictly more trainers, seemingly at random inserted into the list from 27E77.[fn::The names added are in bold: YOUNGSTER, BUG CATCHER, LASS, *SAILOR*, JR TRAINER(m), JR TRAINER(f), POK\eacute{}MANIAC, SUPER NERD, *HIKER*, *BIKER*, BURGLAR, ENGINEER, JUGGLER, *FISHERMAN*, SWIMMER, *CUE BALL*, *GAMBLER*, BEAUTY, *PSYCHIC*, ROCKER, JUGGLER (again), *TAMER*, *BIRDKEEPER*, BLACKBELT, *RIVAL1*, PROF OAK, CHIEF, SCIENTIST, *GIOVANNI*, ROCKET, COOLTRAINER(m), COOLTRAINER(f), *BRUNO*, *BROCK*, *MISTY*, *LT. SURGE*, *ERIKA*, *KOGA*, *BLAINE*, *SABRINA*, *GENTLEMAN*, *RIVAL2*, *RIVAL3*, *LORELEI*, *CHANNELER*, *AGATHA*, *LANCE*.] | | | 1199 | 3997D-39B05 | Trainer titles (extended; see 27E77). This list includes strictly more trainers, seemingly at random inserted into the list from 27E77.[fn::The names added are in bold: YOUNGSTER, BUG CATCHER, LASS, *SAILOR*, JR TRAINER(m), JR TRAINER(f), POK\eacute{}MANIAC, SUPER NERD, *HIKER*, *BIKER*, BURGLAR, ENGINEER, JUGGLER, *FISHERMAN*, SWIMMER, *CUE BALL*, *GAMBLER*, BEAUTY, *PSYCHIC*, ROCKER, JUGGLER (again), *TAMER*, *BIRDKEEPER*, BLACKBELT, *RIVAL1*, PROF OAK, CHIEF, SCIENTIST, *GIOVANNI*, ROCKET, COOLTRAINER(m), COOLTRAINER(f), *BRUNO*, *BROCK*, *MISTY*, *LT. SURGE*, *ERIKA*, *KOGA*, *BLAINE*, *SABRINA*, *GENTLEMAN*, *RIVAL2*, *RIVAL3*, *LORELEI*, *CHANNELER*, *AGATHA*, *LANCE*.] | | |
1120 | 39B05-39DD0. | unknown | | | 1200 | 39B05-39DD0. | unknown | | |
1121 | 39DD1- | (?) Pointers to trainer Pok\eacute{}mon | | | 1201 | 39DD1-39E2E | Pointers to trainer Pok\eacute{}mon | Pairs of low-high bits. | The first pair is 0x2F 0x5E, which corresponds to memory location 5E2F relative to this 38000-3C000 bank, i.e.[fn::For details about how relative bank pointers work, see the relevant Appendix.] position 39E2F overall. |
1122 | 3A289-3A540 (approx) | Trainer Pok\eacute{}mon | Consecutive level/internal-id pairs (as with wild Pok\eacute{}mon; see 04D89) with irregular spacing \mdash{} the separators seem to have some metadata purpose. | The first entry is 0x05 0x66, representing level 5 Eevee (from your first battle in the game[fn::Incidentally, to change your rival's starter Pok\eacute{}mon, it's enough just to change its species in all of your battles with him.].) | 1202 | 39E2F-3A5B2 | Trainer Pok\eacute{}mon | Specially-formatted lists of various length, separated by 0x00. If the list starts with 0xFF, the rest of the list will alternate between levels and internal-ids. Otherwise, start of the list is the level of the whole team, and the rest of the list is internal-ids. | The first entry is (11 165 108 0), which means a level 11 team consisting of Rattata and Ekans. The entry for MISTY is (255 18 27 21 152 0), which means a team of various levels consisting of level 18 Staryu and level 21 Starmie. [fn::Incidentally, if you want to change your rival's starter Pok\eacute{}mon, it's enough just to change its species in all of your battles with him.].) |
1123 | 3B1E5-3B361 | Pointers to evolution/learnset data. | One high-low byte pair for each of the 190 Pok\eacute{}mon in internal order. | | 1203 | 3B1E5-3B361 | Pointers to evolution/learnset data. | One high-low byte pair for each of the 190 Pok\eacute{}mon in internal order. | |
1124 |-----------------------+-----------------+-----------------+-----------------| 1204 |-----------------------+-----------------+-----------------+-----------------|
1125 | 3B361-3BBAA | Evolution and learnset data. [fn::Evolution data consists of how to make Pok\eacute{}mon evolve, and what they evolve into. Learnset data consists of the moves that Pok\eacute{}mon learn as they level up.] | Variable-length evolution information (see below), followed by a list of level/move-id learnset pairs. | | 1205 | 3B361-3BBAA | Evolution and learnset data. [fn::Evolution data consists of how to make Pok\eacute{}mon evolve, and what they evolve into. Learnset data consists of the moves that Pok\eacute{}mon learn as they level up.] | Variable-length evolution information (see below), followed by a list of level/move-id learnset pairs. | |
1126 | 3BBAA-3C000 | (empty) | | 0 0 0 0 ... | 1206 | 3BBAA-3C000 | (empty) | | 0 0 0 0 ... |
1127 |-----------------------+-----------------+-----------------+-----------------| 1207 |-----------------------+-----------------+-----------------+-----------------|
1141 | 70442- | Play time/money | The text "PLAY TIME [0x50] MONEY" | | 1221 | 70442- | Play time/money | The text "PLAY TIME [0x50] MONEY" | |
1142 | 71500-7174B | Names of places. | Variable-length place names (strings), separated by 0x50. | PALLET TOWN#VIRIDIAN CITY#PEWTER CITY#CERULEAN CITY#... | 1222 | 71500-7174B | Names of places. | Variable-length place names (strings), separated by 0x50. | PALLET TOWN#VIRIDIAN CITY#PEWTER CITY#CERULEAN CITY#... |
1143 | 71C1E-71CAA (approx.) | Tradeable NPC Pok\eacute{}mon. | Internal ID, followed by nickname (11 chars; extra space padded by 0x50). Some of the Pokemon have unknown extra data around the id. | The first entry is [0x76] "GURIO######", corresponding to a Dugtrio named "GURIO". | 1223 | 71C1E-71CAA (approx.) | Tradeable NPC Pok\eacute{}mon. | Internal ID, followed by nickname (11 chars; extra space padded by 0x50). Some of the Pokemon have unknown extra data around the id. | The first entry is [0x76] "GURIO######", corresponding to a Dugtrio named "GURIO". |
1144 | 7C249-7C2?? | Pointers to background music, pt II. | | | 1224 | 7C249-7C2?? | Pointers to background music, pt II. | | |
1145 |-----------------------+-----------------+-----------------+-----------------| 1225 |-----------------------+-----------------+-----------------+-----------------|
1146 | 98000-B8000 | Dialogue and other messsages. | Variable-length strings. | | 1226 | 98000-B7190 | Dialogue and other messsages. | Variable-length strings. | |
1227 | B7190-B8000 | (empty space) | | 0 0 0 0 0 ... |
1147 | B8000-BC000 | The text of each Pok\eacute{}mon's Pok\eacute{}dex entry. | Variable-length descriptions (strings) in Pok\eacute{}dex order, separated by 0x50. These entries use the special characters *0x49* (new page), *0x4E* (new line), and *0x5F* (end entry). | The first entry (Bulbasaur's) is: "It can go for days [0x4E] without eating a [0x4E] single morsel. [0x49] In the bulb on [0x4E] its back, it [0x4E] stores energy [0x5F] [0x50]." | 1228 | B8000-BC000 | The text of each Pok\eacute{}mon's Pok\eacute{}dex entry. | Variable-length descriptions (strings) in Pok\eacute{}dex order, separated by 0x50. These entries use the special characters *0x49* (new page), *0x4E* (new line), and *0x5F* (end entry). | The first entry (Bulbasaur's) is: "It can go for days [0x4E] without eating a [0x4E] single morsel. [0x49] In the bulb on [0x4E] its back, it [0x4E] stores energy [0x5F] [0x50]." |
1148 | BC000-BC60E | Move names. | Variable-length move names, separated by 0x50. The moves are in internal order. | POUND#KARATE CHOP#DOUBLESLAP#COMET PUNCH#... | 1229 | BC000-BC60F | Move names. | Variable-length move names, separated by 0x50. The moves are in internal order. | POUND#KARATE CHOP#DOUBLESLAP#COMET PUNCH#... |
1230 | BC610-BD000 | (empty space) | | 0 0 0 0 0 ... |
1149 | E8000-E876C | Names of the \ldquo{}190\rdquo{} species of Pok\eacute{}mon in memory. | Fixed length (10-letter) Pok\eacute{}mon names. Any extra space is padded with the character 0x50. The names are in \ldquo{}internal order\rdquo{}. | RHYDON####KANGASKHANNIDORAN♂#... | 1231 | E8000-E876C | Names of the \ldquo{}190\rdquo{} species of Pok\eacute{}mon in memory. | Fixed length (10-letter) Pok\eacute{}mon names. Any extra space is padded with the character 0x50. The names are in \ldquo{}internal order\rdquo{}. | RHYDON####KANGASKHANNIDORAN♂#... |
1150 |-----------------------+-----------------+-----------------+-----------------| 1232 |-----------------------+-----------------+-----------------+-----------------|
1151 | E9BD5- | The text PLAY TIME (see above, 70442) | | | 1233 | E9BD5- | The text PLAY TIME (see above, 70442) | | |
1152 #+TBLFM: 1234 #+TBLFM:
1153 1235
1236
1237 ** Understanding memory banks and pointers
1238 #+begin_src clojure
1239
1240 (defn endian-flip
1241 "Flip the bytes of the two-byte number."
1242 [n]
1243 (assert (< n 0xFFFF))
1244 (+ (* 0x100 (rem n 0x100))
1245 (int (/ n 0x100))))
1246
1247
1248 (defn offset->ptr
1249 "Convert an offset into a little-endian pointer."
1250 [n]
1251 (->
1252 n
1253 (rem 0x10000) ;; take last four bytes
1254 (rem 0x4000) ;; get relative offset from the start of the bank
1255 (+ 0x4000)
1256 endian-flip))
1257
1258 (defn offset->bank
1259 "Get the bank of the offset."
1260 [n]
1261 (int (/ n 0x4000)))
1262
1263 (defn ptr->offset
1264 "Convert a two-byte little-endian pointer into an offset."
1265 [bank ptr]
1266 (->
1267 ptr
1268 endian-flip
1269 (- 0x4000)
1270 (+ (* 0x4000 bank))
1271 ))
1272
1273 (defn same-bank-offset
1274 "Convert a ptr into an absolute offset by using the bank of the reference."
1275 [reference ptr]
1276 (ptr->offset
1277 (offset->bank reference)
1278 ptr))
1279 #+end_src
1154 1280
1155 1281
1156 ** Internal Pok\eacute{}mon IDs 1282 ** Internal Pok\eacute{}mon IDs
1157 ** Type IDs 1283 ** Type IDs
1158 1284
1661 reverse bit-list) 1787 reverse bit-list)
1662 1788
1663 (take 0xFFF (drop 0x8800 (memory state)))))) 1789 (take 0xFFF (drop 0x8800 (memory state))))))
1664 1790
1665 1791
1666 (defn test-2 [] 1792 ;; (defn test-2 []
1667 (loop [n 0 1793 ;; (loop [n 0
1668 pc-1 (pc-trail (-> state-defend (tick) (step [:a]) (step [:a]) (step []) (nstep 100)) 100000) 1794 ;; pc-1 (pc-trail (-> state-defend (tick) (step [:a]) (step [:a]) (step []) (nstep 100)) 100000)
1669 pc-2 (pc-trail (-> state-speed (tick) (step [:a]) (step [:a]) 1795 ;; pc-2 (pc-trail (-> state-speed (tick) (step [:a]) (step [:a])
1670 (step []) (nstep 100)) 100000)] 1796 ;; (step []) (nstep 100)) 100000)]
1671 (cond (empty? (drop n pc-1)) [pc-1 n] 1797 ;; (cond (empty? (drop n pc-1)) [pc-1 n]
1672 (not= (take 10 (drop n pc-1)) (take 10 pc-2)) 1798 ;; (not= (take 10 (drop n pc-1)) (take 10 pc-2))
1673 (recur pc-1 pc-2 (inc n)) 1799 ;; (recur pc-1 pc-2 (inc n))
1674 :else 1800 ;; :else
1675 [(take 1000 pc-2) n]))) 1801 ;; [(take 1000 pc-2) n])))
1676 1802
1677 1803
1678 1804
1679 1805
1680 (defn test-3 1806 (defn test-3
1681 "Explore trainer data" 1807 "Explore trainer data"
1682 [] 1808 ([] (test-3 0x3A289))
1809 ([start]
1683 (let [pokenames (vec(hxc-pokenames-raw))] 1810 (let [pokenames (vec(hxc-pokenames-raw))]
1684 (println 1811 (println
1685 (reduce 1812 (reduce
1686 str 1813 str
1687 (map 1814 (map
1688 (fn [[lvl pkmn]] 1815 (fn [[adr lvl pkmn]]
1689 (str (format "%-11s %4d %02X %02X" 1816 (str (format "%-11s %4d %02X %02X \t %05X\n"
1817
1690 (cond 1818 (cond
1691 (zero? lvl) "+" 1819 (zero? lvl) "+"
1692 (nil? (get pokenames (dec pkmn))) 1820 (nil? (get pokenames (dec pkmn)))
1693 "-" 1821 "-"
1694 :else 1822 :else
1695 (get pokenames (dec pkmn))) 1823 (get pokenames (dec pkmn)))
1696 lvl 1824 lvl
1697 pkmn 1825 pkmn
1698 lvl 1826 lvl
1699 ) "\n")) 1827 adr
1700 1828 )))
1701 (partition 2 1829 (map cons
1702 (take 100;;703 1830 (take-nth 2 (drop start (range)))
1703 (drop 1831 (partition 2
1704 0x3A281 1832 (take 400;;703
1705 ;; 0x3A75D 1833 (drop
1706 (rom))))))))) 1834 start
1835 ;; 0x3A75D
1836 (rom)))))))))))
1707 1837
1708 (defn search-memory* [mem codes k] 1838 (defn search-memory* [mem codes k]
1709 (loop [index 0 1839 (loop [index 0
1710 index-next 1 1840 index-next 1
1711 start-match 0 1841 start-match 0