comparison org/rom.org @ 422:b58a356f7cc2

merge.
author Robert McIntyre <rlm@mit.edu>
date Tue, 17 Apr 2012 06:36:43 -0500
parents 13165fb5852b
children c02108ddcb35
comparison
equal deleted inserted replaced
418:f211cd655ccb 422:b58a356f7cc2
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/Celadon] 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
1063 #+end_src 1146 #+end_src
1064 1147
1065 1148
1066 1149
1067 1150
1151 ** Map data
1152
1153 # http://www.pokecommunity.com/showthread.php?t=235311
1154 # http://datacrystal.romhacking.net/wiki/Pokemon_Red/Blue:Notes
1155
1156 #+name map
1157 #+begin_src clojure :exports both :results output
1158 (ns com.aurellem.gb.hxc
1159 (:use (com.aurellem.gb assembly characters gb-driver util mem-util
1160 constants))
1161 (:import [com.aurellem.gb.gb_driver SaveState]))
1162
1163
1164 (defn parse-header-tileset
1165 [[bank# ;; memory bank for blocks & tileset
1166
1167 blocks-lo ;; structure
1168 blocks-hi
1169
1170 tileset-lo ;; style
1171 tileset-hi
1172
1173 collision-lo ;; collision info
1174 collision-hi
1175
1176 talk-here-1 ;; positions of up to three
1177 talk-here-2 ;; talk-over-countertop tiles
1178 talk-here-3 ;; --- 0xFF if unused.
1179
1180 grass ;; grass tile --- 0xFF if unused
1181
1182 animation-flags ;; settings for animation
1183 & _]]
1184
1185 [bank#
1186
1187 blocks-lo ;; structure
1188 blocks-hi
1189
1190 tileset-lo ;; style
1191 tileset-hi
1192
1193 collision-lo ;; collision info
1194 collision-hi
1195
1196 talk-here-1 ;; positions of up to three
1197 talk-here-2 ;; talk-over-countertop tiles
1198 talk-here-3 ;; --- 0xFF if unused.
1199
1200 grass ;; grass tile --- 0xFF if unused
1201
1202 animation-flags ;; settings for animation
1203 ])
1204
1205
1206
1207 (defn parse-header-map
1208 [start]
1209
1210 (let [connection-size 11
1211
1212 [tileset-index
1213 map-height
1214 map-width
1215 layout-lo
1216 layout-hi
1217 text-lo
1218 text-hi
1219 script-lo
1220 script-hi
1221 adjacency-flags ;; x x x x N S W E
1222 & etc]
1223 (drop start (rom))
1224
1225 [east? west? south? north?]
1226 (bit-list adjacency-flags)
1227
1228 [connections object-data]
1229 (split-at
1230 (* connection-size (+ east? west? south? north?))
1231 etc)
1232
1233 connections
1234 (partition connection-size connections)
1235
1236
1237
1238
1239 ]
1240 (ptr->offset
1241 3
1242 (low-high layout-lo layout-hi))
1243
1244
1245 ))
1246 #+end_src
1247
1248 #+results:
1249 :
1250
1251
1068 1252
1069 * Appendices 1253 * Appendices
1070
1071
1072
1073 ** Mapping the ROM 1254 ** Mapping the ROM
1255 # D3AD: Script:Use Pokeball?
1074 1256
1075 | ROM address (hex) | Description | Format | Example | 1257 | ROM address (hex) | Description | Format | Example |
1076 |-----------------------+-----------------+-----------------+-----------------| 1258 |-----------------------+-----------------+-----------------+-----------------|
1077 | | <15> | <15> | <15> | 1259 | | <15> | <15> | <15> |
1078 | 01823-0184A | Important prefix strings. | Variable-length strings, separated by 0x50. | TM#TRAINER#PC#ROCKET#POK\eacute{}#... | 1260 | 01823-0184A | Important prefix strings. | Variable-length strings, separated by 0x50. | TM#TRAINER#PC#ROCKET#POK\eacute{}#... |
1079 | 0233C- | Shop inventories. | | | 1261 | 0233C- | Shop inventories. | | |
1080 | 02F47- | (?) Move ids of some HM moves. | One byte per move id | 0x0F 0x13 0x39 0x46 0x94 0xFF, the move ids of CUT, FLY, SURF, STRENGTH, FLASH, then cancel. | 1262 | 02F47- | (?) Move ids of some HM moves. | One byte per move id | 0x0F 0x13 0x39 0x46 0x94 0xFF, the move ids of CUT, FLY, SURF, STRENGTH, FLASH, then cancel. |
1263 | 03E59- | Start of the Give-Pok\eacute{}mon script. | Assembly. When called, converts the contents of register BC into a Pok\eacute{}mon: (B) is the level; (C) is the species. | |
1264 | 03E3F- | Start of the give-item script. | Assembly. When called, converts the contents of register BC into an item: (B) is the item type; (C) is the quantity. | |
1081 | 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. | 1265 | 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. |
1082 | 04524-04527 | (unconfirmed) possibly the bike price in Cerulean. | | | 1266 | 04524-04527 | (unconfirmed) possibly the bike price in Cerulean. | | |
1083 | 045B7-0491E | Names of the items in memory. | Variable-length item names (strings of character codes). Names are separated by a single 0x50 character. | MASTER BALL#ULTRA BALL#... | 1267 | 045B7-0491E | Names of the items in memory. | Variable-length item names (strings of character codes). Names are separated by a single 0x50 character. | MASTER BALL#ULTRA BALL#... |
1084 | 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). | 1268 | 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). |
1085 |-----------------------+-----------------+-----------------+-----------------| 1269 |-----------------------+-----------------+-----------------+-----------------|
1086 | 05DD2-05DF2 | Menu text for player info. | | PLAYER [newline] BADGES [nelwine] POK\Eacute{}DEX [newline] TIME [0x50] | 1270 | 05DD2-05DF2 | Menu text for player info. | | PLAYER [newline] BADGES [nelwine] POK\Eacute{}DEX [newline] TIME [0x50] |
1087 | 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. | 1271 | 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. |
1088 | 06698- | ? Background music. | | | 1272 | 06698- | ? Background music. | | |
1273 |-----------------------+-----------------+-----------------+-----------------|
1089 | 7550-7570 | Menu options for map directions[fn:unused:According to [[http://tcrf.net/Pok%C3%A9mon_Red_and_Blue#NORTH.2FWEST.2FSOUTH.2FEAST][The Cutting Room Floor]], this data is unused. ]. | Variable-length strings. | NORTH [newline] WEST [0x50] SOUTH [newline] EAST [0x50] NORTH [newline] EAST[0x50] | 1274 | 7550-7570 | Menu options for map directions[fn:unused:According to [[http://tcrf.net/Pok%C3%A9mon_Red_and_Blue#NORTH.2FWEST.2FSOUTH.2FEAST][The Cutting Room Floor]], this data is unused. ]. | Variable-length strings. | NORTH [newline] WEST [0x50] SOUTH [newline] EAST [0x50] NORTH [newline] EAST[0x50] |
1090 | 7570-757D | Menu options for trading Pok\eacute{}mon | | TRADE [newline] CANCEL [0x50] | 1275 | 7570-757D | Menu options for trading Pok\eacute{}mon | | TRADE [newline] CANCEL [0x50] |
1091 | 757D-758A | Menu options for healing Pok\eacute{}mon | | HEAL [newline] CANCEL [0x50] | 1276 | 757D-758A | Menu options for healing Pok\eacute{}mon | | HEAL [newline] CANCEL [0x50] |
1092 | 7635- | Menu options for selected Pok\eacute{}mon (Includes names of out-of-battle moves). | Variable-length strings separated by 0x50. | CUT [0x50] FLY [0x50] SURF [0x50] STRENGTH [0x50] FLASH [0x50] DIG [0x50] TELEPORT [0x50] SOFTBOILED [0x50] STATS [newline] SWITCH [newline] CANCEL [0x50] | 1277 | 7635- | Menu options for selected Pok\eacute{}mon (Includes names of out-of-battle moves). | Variable-length strings separated by 0x50. | CUT [0x50] FLY [0x50] SURF [0x50] STRENGTH [0x50] FLASH [0x50] DIG [0x50] TELEPORT [0x50] SOFTBOILED [0x50] STATS [newline] SWITCH [newline] CANCEL [0x50] |
1093 | 7AF0-8000 | (empty space) | | 0 0 0 0 0 ... | 1278 | 7AF0-8000 | (empty space) | | 0 0 0 0 0 ... |
1094 | 0822E-082F? | Pointers to background music, part I. | | | 1279 | 0822E-082F? | Pointers to background music, part I. | | |
1095 | 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). | 1280 | 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). |
1096 |-----------------------+-----------------+-----------------+-----------------| 1281 |-----------------------+-----------------+-----------------+-----------------|
1097 | 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 | 1282 | 0DACB. | Amount of HP restored by Soda Pop | The HP consists of a single numerical byte. | 60 |
1283 | 0DACF. | Amount of HP restored by Lemonade | " | 80 |
1284 | 0DAD5. | Amount of HP restored by Fresh Water | " | 50 |
1285 | 0DADB. | Amount of HP restored by Hyper Potion. | " | 200 |
1098 | 0DAE0. | Amount of HP restored by Super Potion. | " | 50 | 1286 | 0DAE0. | Amount of HP restored by Super Potion. | " | 50 |
1099 | 0DAE3. | Amount of HP restored by Potion. | " | 20 | 1287 | 0DAE3. | Amount of HP restored by Potion. | " | 20 |
1100 |-----------------------+-----------------+-----------------+-----------------| 1288 |-----------------------+-----------------+-----------------+-----------------|
1101 | 0DD4D-DD72 | Names of permanent stats. | Variable-length strings separated by 0x50. | #HEALTH#ATTACK#DEFENSE#SPEED#SPECIAL# | 1289 | 0DD4D-DD72 | Names of permanent stats. | Variable-length strings separated by 0x50. | #HEALTH#ATTACK#DEFENSE#SPEED#SPECIAL# |
1290 |-----------------------+-----------------+-----------------+-----------------|
1291 | 0DE2F. | Duration of Repel. | A single byte, representing the number of steps you can take before the effect wears off. | 100 |
1292 | 0DF39. | Duration of Super Repel. | " | 200 |
1293 | 0DF3E. | Duration of Max Repel. | " | 250 |
1294 |-----------------------+-----------------+-----------------+-----------------|
1102 | 1164B- | Terminology for the Pok\eacute{}mon menu. | Contiguous, variable-length strings. | TYPE1[newline]TYPE2[newline] *№*,[newline]OT,[newline][0x50]STATUS,[0x50]OK | 1295 | 1164B- | Terminology for the Pok\eacute{}mon menu. | Contiguous, variable-length strings. | TYPE1[newline]TYPE2[newline] *№*,[newline]OT,[newline][0x50]STATUS,[0x50]OK |
1103 | 116DE- | Terminology for permanent stats in the Pok\eacute{}mon menu. | Contiguous, variable-length strings. | ATTACK[newline]DEFENSE[newline]SPEED[newline]SPECIAL[0x50] | 1296 | 116DE- | Terminology for permanent stats in the Pok\eacute{}mon menu. | Contiguous, variable-length strings. | ATTACK[newline]DEFENSE[newline]SPEED[newline]SPECIAL[0x50] |
1104 | 11852- | Terminology for current stats in the Pok\eacute{}mon menu. | Contiguous, variable-length strings. | EXP POINTS[newline]LEVEL UP[0x50] | 1297 | 11852- | Terminology for current stats in the Pok\eacute{}mon menu. | Contiguous, variable-length strings. | EXP POINTS[newline]LEVEL UP[0x50] |
1105 | 1195C-1196A | The two terms for being able/unable to learn a TM/HM. | Variable-length strings separated by 0x50. | ABLE#NOT ABLE# | 1298 | 1195C-1196A | The two terms for being able/unable to learn a TM/HM. | Variable-length strings separated by 0x50. | ABLE#NOT ABLE# |
1106 | 119C0-119CE | The two terms for being able/unable to evolve using the current stone. | Variable-length strings separated by 0x50. | ABLE#NOT ABLE# | 1299 | 119C0-119CE | The two terms for being able/unable to evolve using the current stone. | Variable-length strings separated by 0x50. | ABLE#NOT ABLE# |
1300 |-----------------------+-----------------+-----------------+-----------------|
1301 | 11D53. | Which badge is a prerequisite for CUT? | op code: which bit of A to test? | When this script is called, the bits of A contain your badges, and this op code will check a certain bit of A. The op codes for the badges are, in order, [0x47 0x4F 0x57 0x5F 0x67 0x6F 0x77 0x7F]. |
1302 | 11D67. | Which badge is a prerequisite for SURF? | " | 0x67 (test for Soul Badge) |
1303 | 11DAC. | Which badge is a prerequisite for STRENGTH? | " | 0x5F (test for Rainbow Badge) |
1304 |-----------------------+-----------------+-----------------+-----------------|
1107 | 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), ... | 1305 | 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), ... |
1306 |-----------------------+-----------------+-----------------+-----------------|
1307 | 1CF8B-1CF8C | Which Pok\eacute{}mon does Melanie give you in Cerulean City? | A level/internal-id pair. | (10 153), corresponding to a level 10 Bulbasaur. |
1308 | 1D651-1D652 | Which Pok\eacute{}mon do you find at the top of Celadon Mansion? | A level/internal-id pair. | (25 102), corresponding to a level 25 Eevee. |
1108 |-----------------------+-----------------+-----------------+-----------------| 1309 |-----------------------+-----------------+-----------------+-----------------|
1109 | 27D56 & 27D57. | Pointer to the pointers to type names. | A single low-byte, high-byte pair. | 0x63 0x7D, corresponding to location 27D63\mdash{} the start of the next entry. | 1310 | 27D56 & 27D57. | Pointer to the pointers to type names. | A single low-byte, high-byte pair. | 0x63 0x7D, corresponding to location 27D63\mdash{} the start of the next entry. |
1110 | 27D63-27D99 | Pointers to type names. | Each point is a low-byte, high-byte pair. The type names follows immediately after this section; see below. | The first pointer is [0x99 0x7D], corresponding to the location 27D99 ("NORMAL"). | 1311 | 27D63-27D99 | Pointers to type names. | Each point is a low-byte, high-byte pair. The type names follows immediately after this section; see below. | The first pointer is [0x99 0x7D], corresponding to the location 27D99 ("NORMAL"). |
1111 | 27D99-27DFF | Names of the Pok\eacute{}mon types. | Variable-length type names (strings of character codes). Names are separated by a single 0x50 character. | NORMAL#FIGHTING#... | 1312 | 27D99-27DFF | Names of the Pok\eacute{}mon types. | Variable-length type names (strings of character codes). Names are separated by a single 0x50 character. | NORMAL#FIGHTING#... |
1112 | 27DFF-27E77 | ? | 120 bytes of unknown data. | | 1313 | 27DFF-27E77 | ? | 120 bytes of unknown data. | |
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. | | | 1317 | 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. | | 1318 | 39462- | The Pok\eacute{}mon cry data. | Fixed-length (3 byte) descriptions of cries. | |
1118 |-----------------------+-----------------+-----------------+-----------------| 1319 |-----------------------+-----------------+-----------------+-----------------|
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*.] | | | 1320 | 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 | | | 1321 | 39B05-39DD0. | unknown | | |
1121 | 39DD1- | (?) Pointers to trainer Pok\eacute{}mon | | | 1322 | 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.].) | 1323 | 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. | | 1324 | 3B1E5-3B361 | Pointers to evolution/learnset data. | One high-low byte pair for each of the 190 Pok\eacute{}mon in internal order. | |
1124 |-----------------------+-----------------+-----------------+-----------------| 1325 |-----------------------+-----------------+-----------------+-----------------|
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. | | 1326 | 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 ... | 1327 | 3BBAA-3C000 | (empty) | | 0 0 0 0 ... |
1127 |-----------------------+-----------------+-----------------+-----------------| 1328 |-----------------------+-----------------+-----------------+-----------------|
1128 | 3D131-3D133 | The inventory of both OLD MAN and PROF. OAK when they battle for you. | Pairs of [item-id quantity], terminated by 0xFF. | (0x04 0x01 0xFF) They only have one Pok\eacute{}ball [fn::If you give them any ball, OAK will catch the enemy Pok\eacute{}mon and OLD MAN will miss. (OLD MAN misses even if he throws a MASTER BALL, which is a sight to see!) If you give them some other item first in the list, you'll be able to use that item normally but then you'll trigger the Safari Zone message: Pa will claim you're out of SAFARI BALLs and the battle will end. If you engage in either an OLD MAN or OAK battle with a Gym Leader, you will [1] get reprimanded if you try to throw a ball [2] incur the Safari Zone message [3] automatically win no matter which item you use [4] earn whichever reward they give you as usual [5] permanently retain the name OLD MAN / PROF. OAK.]. | 1329 | 3D131-3D133 | The inventory of both OLD MAN and PROF. OAK when they battle for you. | Pairs of [item-id quantity], terminated by 0xFF. | (0x04 0x01 0xFF) They only have one Pok\eacute{}ball [fn::If you give them any ball, OAK will catch the enemy Pok\eacute{}mon and OLD MAN will miss. (OLD MAN misses even if he throws a MASTER BALL, which is a sight to see!) If you give them some other item first in the list, you'll be able to use that item normally but then you'll trigger the Safari Zone message: Pa will claim you're out of SAFARI BALLs and the battle will end. If you engage in either an OLD MAN or OAK battle with a Gym Leader, you will [1] get reprimanded if you try to throw a ball [2] incur the Safari Zone message [3] automatically win no matter which item you use [4] earn whichever reward they give you as usual [5] permanently retain the name OLD MAN / PROF. OAK.]. |
1129 | 3D6C7-3D6D6 | Two miscellaneous strings. | Variable length, separated by 0x50 | Disabled!#TYPE | 1330 | 3D6C7-3D6D6 | Two miscellaneous strings. | Variable length, separated by 0x50 | Disabled!#TYPE |
1331 | 3E190-3E194 | Which moves have an increased critical-hit ratio? | List of move ids, terminated by 0xFF. | (0x02 0x4B 0x98 0xA3 0xFF) corresponding to karate-chop, razor-leaf, crabhammer, slash, end-of-list. |
1332 | 3E200-3E204 | " (???) | " | " |
1333 | 3E231. | Besides normal-type, which type of move can COUNTER counter? | A single byte representing a type id. | This is set to 1, the id of the FIGHTING type. |
1130 |-----------------------+-----------------+-----------------+-----------------| 1334 |-----------------------+-----------------+-----------------+-----------------|
1131 | 40252-4027B | Pok\eacute{}dex menu text | Variable-length strings separated by 0x50. | SEEN#OWN#CONTENTS#... | 1335 | 40252-4027B | Pok\eacute{}dex menu text | Variable-length strings separated by 0x50. | SEEN#OWN#CONTENTS#... |
1132 | 40370-40386 | Important constants for Pok\eacute{}dex entries | | HT _ _ *?′??″* [newline] WT _ _ _ *???* lb [0x50] *POK\Eacute{}* [0x50] | 1336 | 40370-40386 | Important constants for Pok\eacute{}dex entries | | HT _ _ *?′??″* [newline] WT _ _ _ *???* lb [0x50] *POK\Eacute{}* [0x50] |
1133 | 40687-41072 | Species data from the Pok\eacute{}dex: species name, height, weight, etc. | Variable-length species names, followed by 0x50, followed by fixed-length height/weight/etc. data. | The first entry is (*146 132 132 131*, 80, *2 4*, *150 0*, 23, 0 64 46, 80), which are the the stats of Bulbasaur: the first entry spells "SEED", then 0x80, then the height (2' 4"), then the weight (formatted as a low-high byte pair), then various Pokédex pointer data (see elsewhere). | 1337 | 40687-41072 | Species data from the Pok\eacute{}dex: species name, height, weight, etc. | Variable-length species names, followed by 0x50, followed by fixed-length height/weight/etc. data. | The first entry is (*146 132 132 131*, 80, *2 4*, *150 0*, 23, 0 64 46, 80), which are the the stats of Bulbasaur: the first entry spells "SEED", then 0x80, then the height (2' 4"), then the weight (formatted as a low-high byte pair), then various Pokédex pointer data (see elsewhere). |
1134 | 41072- | Pok\eacute{} placeholder species, "???" | | | 1338 | 41072- | Pok\eacute{} placeholder species, "???" | | |
1135 |-----------------------+-----------------+-----------------+-----------------| 1339 |-----------------------+-----------------+-----------------+-----------------|
1136 | 410B1-4116F | A conversion table between internal order and Pokedex order. | 190 bytes, corresponding to the Pok\eacute{}dex numbers of the 190 Pok\eacute{}mon listed in internal order. All =MISSINGNO.= are assigned a Pok\eacute{}dex number of 0. | The first few entries are (112 115 32 35 21 100 34 80 2 ...), which are the Pok\eacute{}dex numbers of Rhydon, Kangaskhan, Nidoran(m), Clefairy, Spearow, Voltorb, Nidoking, Slobrow, and Ivysaur. | 1340 | 410B1-4116F | A conversion table between internal order and Pokedex order. | 190 bytes, corresponding to the Pok\eacute{}dex numbers of the 190 Pok\eacute{}mon listed in internal order. All =MISSINGNO.= are assigned a Pok\eacute{}dex number of 0. | The first few entries are (112 115 32 35 21 100 34 80 2 ...), which are the Pok\eacute{}dex numbers of Rhydon, Kangaskhan, Nidoran(m), Clefairy, Spearow, Voltorb, Nidoking, Slobrow, and Ivysaur. |
1341 |-----------------------+-----------------+-----------------+-----------------|
1342 | 509B4-509E0 | Saffron City's adjacency info. | Four adjacency lists, each 11 bytes long. (For more info on adjacency lists a.k.a. connection data, see [[http://datacrystal.romhacking.net/wiki/Pokemon_Red/Blue:Notes][here]]) | The first adjacency list is (0x10 0x70 0x46 0xF0 0xC6 0x0A 0x0A 0x23 0xF6 0x09 0xC8) |
1343 |-----------------------+-----------------+-----------------+-----------------|
1344 | 515AE-515AF | Which Pok\eacute{}mon does the trainer near Route 25 give you? | A level/internal-id pair. | (10 176) corresponding to a level 10 Charmander. |
1345 | 51DD5-51DD6 | Which Pok\eacute{}mon does the Silph Co. trainer give you? | A level/internal-id pair. | (15 19) corresponding to a level 15 Lapras. |
1346 |-----------------------+-----------------+-----------------+-----------------|
1137 | 527BA-527DB | The costs and kinds of prizes from Celadon Game Corner. | The following pattern repeats three times, once per window[fn::For the first two prize lists, ids are interpreted as Pok\eacute{}mon ids. For the last prize list, ids are (somehow) interpreted as item ids.]: Internal ids / 0x50 / Prices (two bytes of BCD)/ 0x50. | (0x94 0x52 0x65 0x50) Abra Vulpix Wigglytuff (0x02 0x30 0x10 0x00 0x26 0x80) 230C, 1000C, 2680C | 1347 | 527BA-527DB | The costs and kinds of prizes from Celadon Game Corner. | The following pattern repeats three times, once per window[fn::For the first two prize lists, ids are interpreted as Pok\eacute{}mon ids. For the last prize list, ids are (somehow) interpreted as item ids.]: Internal ids / 0x50 / Prices (two bytes of BCD)/ 0x50. | (0x94 0x52 0x65 0x50) Abra Vulpix Wigglytuff (0x02 0x30 0x10 0x00 0x26 0x80) 230C, 1000C, 2680C |
1138 | 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]... | 1348 | 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]... |
1139 |-----------------------+-----------------+-----------------+-----------------| 1349 |-----------------------+-----------------+-----------------+-----------------|
1140 | 70295- | Hall of fame | The text "HALL OF FAME" | | 1350 | 70295- | Hall of fame | The text "HALL OF FAME" | |
1141 | 70442- | Play time/money | The text "PLAY TIME [0x50] MONEY" | | 1351 | 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#... | 1352 | 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". | 1353 | 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. | | | 1354 | 7C249-7C2?? | Pointers to background music, pt II. | | |
1145 |-----------------------+-----------------+-----------------+-----------------| 1355 |-----------------------+-----------------+-----------------+-----------------|
1146 | 98000-B8000 | Dialogue and other messsages. | Variable-length strings. | | 1356 | 98000-B7190 | Dialogue and other messsages. | Variable-length strings. | |
1357 | 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]." | 1358 | 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#... | 1359 | BC000-BC60F | Move names. | Variable-length move names, separated by 0x50. The moves are in internal order. | POUND#KARATE CHOP#DOUBLESLAP#COMET PUNCH#... |
1360 | 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♂#... | 1361 | 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 |-----------------------+-----------------+-----------------+-----------------| 1362 |-----------------------+-----------------+-----------------+-----------------|
1151 | E9BD5- | The text PLAY TIME (see above, 70442) | | | 1363 | E9BD5- | The text PLAY TIME (see above, 70442) | | |
1364 | F1A44-F1A45 | Which Pok\eacute{}mon does Officer Jenny give you? | A level/internal-id pair. | (10 177), corresponding to a level 10 Squirtle. |
1365 | F21BF-F21C0 | Which Pok\eacute{}mon does the salesman at the Mt. Moon Pok\eacute{}mon center give you? | A level/internal-id pair | (5 133), corresponding to a level 5 Magikarp. |
1366 | | | | |
1152 #+TBLFM: 1367 #+TBLFM:
1153 1368
1369 ** COMMENT
1370 Locations where Give Pokemon is used in a nonstraightforward way
1371 0x5287C
1372 0x5CE23
1373 0x5C36B
1374 0x7562E
1375
1376
1377 ** Understanding memory banks and pointers
1378 #+begin_src clojure
1379
1380 (defn endian-flip
1381 "Flip the bytes of the two-byte number."
1382 [n]
1383 (assert (< n 0xFFFF))
1384 (+ (* 0x100 (rem n 0x100))
1385 (int (/ n 0x100))))
1386
1387
1388 (defn offset->ptr
1389 "Convert an offset into a little-endian pointer."
1390 [n]
1391 (->
1392 n
1393 (rem 0x10000) ;; take last four bytes
1394 (rem 0x4000) ;; get relative offset from the start of the bank
1395 (+ 0x4000)
1396 endian-flip))
1397
1398 (defn offset->bank
1399 "Get the bank of the offset."
1400 [n]
1401 (int (/ n 0x4000)))
1402
1403 (defn ptr->offset
1404 "Convert a two-byte little-endian pointer into an offset."
1405 [bank ptr]
1406 (->
1407 ptr
1408 endian-flip
1409 (- 0x4000)
1410 (+ (* 0x4000 bank))
1411 ))
1412
1413 (defn same-bank-offset
1414 "Convert a ptr into an absolute offset by using the bank of the reference."
1415 [reference ptr]
1416 (ptr->offset
1417 (offset->bank reference)
1418 ptr))
1419 #+end_src
1154 1420
1155 1421
1156 ** Internal Pok\eacute{}mon IDs 1422 ** Internal Pok\eacute{}mon IDs
1157 ** Type IDs 1423 ** Type IDs
1158 1424
1642 ;; - 05+ are glitch states in which you are sort of the Pokemon. 1908 ;; - 05+ are glitch states in which you are sort of the Pokemon.
1643 1909
1644 1910
1645 ;; note: 0x251A (in indexable mem): image decompression routine seems to begin here. 1911 ;; note: 0x251A (in indexable mem): image decompression routine seems to begin here.
1646 1912
1913 ;; note: 0x4845 (index): vending inventory is loaded here. possibly
1914 ;; other things, too.
1915 (comment
1916 ;; temporarily intercept/adjust what pops out of the vending
1917 ;; machine.
1918 ;; (and how much it costs)
1919
1920 ;; located at 0x4845
1921 ;; not to be confused with shop inventory, 0xCF7B
1922 (do
1923 (step (read-state "vend-menu"))
1924 (write-memory! (rewrite-memory (vec(memory)) 0x4845 [2 0 1 0]))
1925 (step @current-state [:a])
1926 (step @current-state [])
1927 (nstep @current-state 200) ))
1928
1647 1929
1648 ;; Note: There are two tile tables, one from 8000-8FFF, the other from 1930 ;; Note: There are two tile tables, one from 8000-8FFF, the other from
1649 ;; 8800-97FF. The latter contains symbols, possibly map tiles(?), with some japanese chars and stuff at the end. 1931 ;; 8800-97FF. The latter contains symbols, possibly map tiles(?), with some japanese chars and stuff at the end.
1650 (defn print-pixel-letters! 1932 (defn print-pixel-letters!
1651 "The pixel tiles representing letters. Neat!" 1933 "The pixel tiles representing letters. Neat!"
1661 reverse bit-list) 1943 reverse bit-list)
1662 1944
1663 (take 0xFFF (drop 0x8800 (memory state)))))) 1945 (take 0xFFF (drop 0x8800 (memory state))))))
1664 1946
1665 1947
1666 (defn test-2 [] 1948 ;; (defn test-2 []
1667 (loop [n 0 1949 ;; (loop [n 0
1668 pc-1 (pc-trail (-> state-defend (tick) (step [:a]) (step [:a]) (step []) (nstep 100)) 100000) 1950 ;; 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]) 1951 ;; pc-2 (pc-trail (-> state-speed (tick) (step [:a]) (step [:a])
1670 (step []) (nstep 100)) 100000)] 1952 ;; (step []) (nstep 100)) 100000)]
1671 (cond (empty? (drop n pc-1)) [pc-1 n] 1953 ;; (cond (empty? (drop n pc-1)) [pc-1 n]
1672 (not= (take 10 (drop n pc-1)) (take 10 pc-2)) 1954 ;; (not= (take 10 (drop n pc-1)) (take 10 pc-2))
1673 (recur pc-1 pc-2 (inc n)) 1955 ;; (recur pc-1 pc-2 (inc n))
1674 :else 1956 ;; :else
1675 [(take 1000 pc-2) n]))) 1957 ;; [(take 1000 pc-2) n])))
1676 1958
1677 1959
1678 1960
1679 1961
1680 (defn test-3 1962 (defn test-3
1681 "Explore trainer data" 1963 "Explore trainer data"
1682 [] 1964 ([] (test-3 0x3A289))
1965 ([start]
1683 (let [pokenames (vec(hxc-pokenames-raw))] 1966 (let [pokenames (vec(hxc-pokenames-raw))]
1684 (println 1967 (println
1685 (reduce 1968 (reduce
1686 str 1969 str
1687 (map 1970 (map
1688 (fn [[lvl pkmn]] 1971 (fn [[adr lvl pkmn]]
1689 (str (format "%-11s %4d %02X %02X" 1972 (str (format "%-11s %4d %02X %02X \t %05X\n"
1973
1690 (cond 1974 (cond
1691 (zero? lvl) "+" 1975 (zero? lvl) "+"
1692 (nil? (get pokenames (dec pkmn))) 1976 (nil? (get pokenames (dec pkmn)))
1693 "-" 1977 "-"
1694 :else 1978 :else
1695 (get pokenames (dec pkmn))) 1979 (get pokenames (dec pkmn)))
1696 lvl 1980 lvl
1697 pkmn 1981 pkmn
1698 lvl 1982 lvl
1699 ) "\n")) 1983 adr
1700 1984 )))
1701 (partition 2 1985 (map cons
1702 (take 100;;703 1986 (take-nth 2 (drop start (range)))
1703 (drop 1987 (partition 2
1704 0x3A281 1988 (take 400;;703
1705 ;; 0x3A75D 1989 (drop
1706 (rom))))))))) 1990 start
1991 ;; 0x3A75D
1992 (rom)))))))))))
1707 1993
1708 (defn search-memory* [mem codes k] 1994 (defn search-memory* [mem codes k]
1709 (loop [index 0 1995 (loop [index 0
1710 index-next 1 1996 index-next 1
1711 start-match 0 1997 start-match 0
1738 index-next 2024 index-next
1739 (inc index-next) 2025 (inc index-next)
1740 index-next 2026 index-next
1741 codes 2027 codes
1742 matches)))) 2028 matches))))
1743 2029
1744 2030
2031 (def script-use-ball
2032 [0xFA ;; ld A, nn
2033 \_
2034 \_
2035 0xA7 ;; and A
2036 0xCA ;; JP Z
2037 \_
2038 \_
2039 0x3D ;; dec A
2040 0xC2 ;; JP NZ
2041 \_
2042 \_
2043 0xFA ;; LD A
2044 \_
2045 \_
2046 ])
2047
2048
2049
2050 (defn search-pattern [ptn coll]
2051 (loop
2052 [index 0
2053 to-match ptn
2054 binds {}
2055
2056 next-index 1
2057 match-start 0
2058 matches []]
2059
2060 (cond
2061 (>= index (count coll)) matches
2062 (empty? to-match)
2063 (recur
2064 next-index
2065 ptn
2066 {}
2067 (inc next-index)
2068 next-index
2069 (conj match-start
2070 [(hex match-start) binds]))
2071
2072 :else
2073 (let [k (first to-match)
2074 v (nth coll index)]
2075 (cond
2076 (= k \_) ;; wildcard
2077 (recur
2078 (inc index)
2079 (rest to-match)
2080 binds
2081
2082 next-index
2083 match-start
2084 matches)
2085
2086 (keyword? k)
2087 (if (binds k)
2088 (if (= (binds k) v)
2089 (recur
2090 (inc index)
2091 (rest to-match)
2092 binds
2093 next-index
2094 match-start
2095 matches)
2096
2097 (recur
2098 next-index
2099 ptn
2100 {}
2101 (inc next-index)
2102 next-index
2103 matches))
2104
2105 ;; ;; consistent bindings
2106 ;; (recur
2107 ;; (inc index)
2108 ;; (rest to-match)
2109 ;; binds
2110
2111 ;; next-index
2112 ;; match-start
2113 ;; matches)
2114
2115 ;; ;; inconsistent bindings
2116 ;; (recur
2117 ;; next-index
2118 ;; ptn
2119 ;; {}
2120 ;; (inc next-index)
2121 ;; next-index
2122 ;; matches))
2123
2124 (if ((set (vals binds)) v)
2125 ;; bindings are not unique
2126 (recur
2127 next-index
2128 ptn
2129 {}
2130 (inc next-index)
2131 next-index
2132 matches)
2133
2134 ;; bindings are unique
2135 (recur
2136 (inc index)
2137 (rest to-match)
2138 (assoc binds k v)
2139
2140 next-index
2141 match-start
2142 matches)))
2143
2144 :else ;; k is just a number
2145 (if (= k v)
2146 (recur
2147 (inc index)
2148 (rest to-match)
2149 binds
2150
2151 next-index
2152 match-start
2153 matches)
2154
2155 (recur
2156 next-index
2157 ptn
2158 {}
2159 (inc next-index)
2160 next-index
2161 matches)))))))
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171 (defn search-pattern* [ptn coll]
2172 (loop
2173 [
2174 binds {}
2175 index 0
2176 index-next 1
2177 start-match 0
2178 to-match ptn
2179 matches []]
2180
2181 (cond
2182 (>= index (count coll)) matches
2183 (empty? to-match)
2184 (recur
2185 {}
2186 index-next
2187 (inc index-next)
2188 index-next
2189 ptn
2190 (conj matches
2191 [(hex start-match) binds]))
2192
2193 :else
2194 (let [k (first to-match)
2195 v (nth coll index)]
2196 (cond
2197 (= k \_) ;; wildcard
2198 (recur
2199 binds
2200 (inc index)
2201 index-next
2202 start-match
2203 (rest to-match)
2204 matches)
2205
2206 (keyword? k)
2207 (if (binds k)
2208 (if (= (binds k) v)
2209 (recur
2210 binds
2211 (inc index)
2212 index-next
2213 start-match
2214 (rest to-match)
2215 matches)
2216 (recur
2217 {}
2218 index-next
2219 (inc index-next)
2220 index-next
2221 ptn
2222 matches))
2223 (if
2224 ;; every symbol must be bound to a different thing.
2225 ((set (vals binds)) v)
2226 (recur
2227 {}
2228 index-next
2229 (inc index-next)
2230 index-next
2231 ptn
2232 matches)
2233 (recur
2234 (assoc binds k v)
2235 (inc index)
2236 index-next
2237 start-match
2238 (rest to-match)
2239 matches)))
2240
2241 :else
2242 (if (= k v)
2243 (recur
2244 binds
2245 (inc index)
2246 index-next
2247 start-match
2248 (rest to-match)
2249 matches)
2250 (recur
2251 {}
2252 index-next
2253 (inc index-next)
2254 index-next
2255 ptn
2256 matches))
2257
2258
2259
2260 )))))
2261
1745 2262
1746 2263
1747 2264
1748 ;; look for the rainbow badge in memory 2265 ;; look for the rainbow badge in memory
1749 (println (reduce str (map #(str (first %) "\t" (vec(second %)) "\n") (search-memory (rom) [221] 10)))) 2266 (println (reduce str (map #(str (first %) "\t" (vec(second %)) "\n") (search-memory (rom) [221] 10))))