view clojure/com/aurellem/exp/pokemon.clj @ 147:279e9ee6fccb

can now determine the number of pokemon in the party.
author Robert McIntyre <rlm@mit.edu>
date Mon, 19 Mar 2012 22:42:36 -0500
parents c5914665012d
children 06426d25c65b
line wrap: on
line source
1 (ns com.aurellem.exp.pokemon
2 "Here I find out how pokemon are stored in memory."
3 (:use (com.aurellem.gb gb-driver items assembly util
4 characters))
5 (:import [com.aurellem.gb.gb_driver SaveState]))
8 (def pidgeot-lvl-36 (mid-game))
11 (def pidgeot-lvl-37 (read-state "pidgeot-lvl-37"))
14 (def pidgeot-lvl-38 (read-state "pidgeot-lvl-38"))
17 (def pidgeot-lvl-39 (read-state "pidgeot-lvl-39"))
20 (def pidgeot-lvl-40 (read-state "pidgeot-lvl-40"))
23 (defn level-analysis []
24 (apply common-differences
25 (map (comp vec memory)
26 [pidgeot-lvl-36
27 pidgeot-lvl-37
28 pidgeot-lvl-38
29 pidgeot-lvl-39
30 pidgeot-lvl-40])))
32 ;; inconclusive -- implies that level is calculated from
33 ;; some other values.
36 (def name-pidgeotto (read-state "name-pidgeotto"))
37 (def named-A (read-state "named-A"))
38 (def named-B (read-state "named-B"))
39 (def named-C (read-state "named-C"))
40 (def named-D (read-state "named-D"))
41 (def named-E (read-state "named-E"))
42 (def named-F (read-state "named-F"))
44 (defn name-analysis []
45 (apply common-differences
46 (map (comp vec memory)
47 [named-A
48 named-B
49 named-C
50 named-D
51 named-E
52 named-F])))
54 ;; resluted in 3 separate locations that could
55 ;; possibly hold the first letter of the pokemon's name
57 0xCF4A
58 0xD2EB
59 0xCEED
61 ;; try changing each of them
64 (defn test-cf4a []
65 (continue!
66 (set-memory named-A 0xCF4A (character->character-code "Z"))))
67 ;; result -- pidgeotto named "A"
69 (defn test-d2eb []
70 (continue!
71 (set-memory named-A 0xD2EB (character->character-code "Z"))))
72 ;; result -- pidgeotto named "Z"
74 (defn test-ceed []
75 (continue!
76 (set-memory named-A 0xCEED (character->character-code "Z"))))
77 ;; result -- pidgeotto named "A"
79 (def sixth-pokemon-name-start 0xD2EB)
82 (defn set-sixth-pokemon-name-first-character
83 ([state character]
84 (set-memory state sixth-pokemon-name-start
85 (character->character-code character)))
86 ([character]
87 (set-sixth-pokemon-name-first-character @current-state
88 character)))
91 (def end-of-name-marker 0x50)
92 (def max-name-length 10)
93 (def name-width 11)
95 (defn read-pokemon-name [codes]
96 (character-codes->str
97 (take-while
98 (partial not= end-of-name-marker) codes)))
101 (defn sixth-pokemon-name [^SaveState state]
102 (read-pokemon-name
103 (subvec (vec (memory state))
104 sixth-pokemon-name-start
105 (+ (inc max-name-length)
106 sixth-pokemon-name-start))))
108 (defn rename-sixth-pokemon
109 ([^SaveState state new-name]
110 (assert (< (count new-name) max-name-length))
111 (set-memory-range state sixth-pokemon-name-start
112 (concat (str->character-codes new-name)
113 [end-of-name-marker])))
114 ([new-name]
115 (rename-sixth-pokemon @current-state new-name)))
117 (defn print-text
118 ([^SaveState state begin end]
119 (dorun
120 (map (fn [character-code line]
121 (println
122 (format "0x%04X: " line)
123 (str (character-code->character character-code))))
124 (subvec (vec (memory state)) begin end)
125 (range begin end)))
126 state)
127 ([begin end]
128 (print-text @current-state begin end)))
133 (defn examine-name-memory []
134 (print-text
135 named-A
136 (- sixth-pokemon-name-start 100)
137 (+ sixth-pokemon-name-start 100)))
140 ;; results:
141 ;; 0xD287: end-of-name-sentinel
142 ;; 0xD288: R
143 ;; 0xD289: L
144 ;; 0xD28A: M
145 ;; 0xD28B: end-of-pokemon-name-sentinel
146 ;; 0xD28C: end-of-name-sentinel
147 ;; 0xD28D: end-of-name-sentinel
148 ;; 0xD28E: end-of-name-sentinel
149 ;; 0xD28F: end-of-name-sentinel
150 ;; 0xD290: end-of-name-sentinel
151 ;; 0xD291: end-of-name-sentinel
152 ;; 0xD292: end-of-name-sentinel
153 ;; 0xD293: R
154 ;; 0xD294: L
155 ;; 0xD295: M
156 ;; 0xD296: end-of-pokemon-name-sentinel
157 ;; 0xD297: end-of-name-sentinel
158 ;; 0xD298: end-of-name-sentinel
159 ;; 0xD299: end-of-name-sentinel
160 ;; 0xD29A: end-of-name-sentinel
161 ;; 0xD29B: end-of-name-sentinel
162 ;; 0xD29C: end-of-name-sentinel
163 ;; 0xD29D: end-of-name-sentinel
164 ;; 0xD29E: R
165 ;; 0xD29F: L
166 ;; 0xD2A0: M
167 ;; 0xD2A1: end-of-pokemon-name-sentinel
168 ;; 0xD2A2: end-of-name-sentinel
169 ;; 0xD2A3: end-of-name-sentinel
170 ;; 0xD2A4: end-of-name-sentinel
171 ;; 0xD2A5: end-of-name-sentinel
172 ;; 0xD2A6: end-of-name-sentinel
173 ;; 0xD2A7: end-of-name-sentinel
174 ;; 0xD2A8: end-of-name-sentinel
175 ;; 0xD2A9: R
176 ;; 0xD2AA: L
177 ;; 0xD2AB: M
178 ;; 0xD2AC: end-of-pokemon-name-sentinel
179 ;; 0xD2AD: end-of-name-sentinel
180 ;; 0xD2AE: end-of-name-sentinel
181 ;; 0xD2AF: end-of-name-sentinel
182 ;; 0xD2B0: end-of-name-sentinel
183 ;; 0xD2B1: end-of-name-sentinel
184 ;; 0xD2B2: end-of-name-sentinel
185 ;; 0xD2B3: end-of-name-sentinel
186 ;; 0xD2B4: P
187 ;; 0xD2B5: I
188 ;; 0xD2B6: D
189 ;; 0xD2B7: G
190 ;; 0xD2B8: E
191 ;; 0xD2B9: O
192 ;; 0xD2BA: T
193 ;; 0xD2BB: end-of-pokemon-name-sentinel
194 ;; 0xD2BC: end-of-pokemon-name-sentinel
195 ;; 0xD2BD: end-of-pokemon-name-sentinel
196 ;; 0xD2BE: end-of-pokemon-name-sentinel
197 ;; 0xD2BF: P
198 ;; 0xD2C0: I
199 ;; 0xD2C1: K
200 ;; 0xD2C2: A
201 ;; 0xD2C3: C
202 ;; 0xD2C4: H
203 ;; 0xD2C5: U
204 ;; 0xD2C6: end-of-pokemon-name-sentinel
205 ;; 0xD2C7: end-of-pokemon-name-sentinel
206 ;; 0xD2C8: end-of-pokemon-name-sentinel
207 ;; 0xD2C9: end-of-pokemon-name-sentinel
208 ;; 0xD2CA: C
209 ;; 0xD2CB: H
210 ;; 0xD2CC: A
211 ;; 0xD2CD: R
212 ;; 0xD2CE: I
213 ;; 0xD2CF: Z
214 ;; 0xD2D0: A
215 ;; 0xD2D1: R
216 ;; 0xD2D2: D
217 ;; 0xD2D3: end-of-pokemon-name-sentinel
218 ;; 0xD2D4: end-of-pokemon-name-sentinel
219 ;; 0xD2D5: V
220 ;; 0xD2D6: E
221 ;; 0xD2D7: N
222 ;; 0xD2D8: U
223 ;; 0xD2D9: S
224 ;; 0xD2DA: A
225 ;; 0xD2DB: U
226 ;; 0xD2DC: R
227 ;; 0xD2DD: end-of-pokemon-name-sentinel
228 ;; 0xD2DE: end-of-pokemon-name-sentinel
229 ;; 0xD2DF: end-of-pokemon-name-sentinel
230 ;; 0xD2E0: P
231 ;; 0xD2E1: R
232 ;; 0xD2E2: I
233 ;; 0xD2E3: M
234 ;; 0xD2E4: E
235 ;; 0xD2E5: A
236 ;; 0xD2E6: P
237 ;; 0xD2E7: E
238 ;; 0xD2E8: end-of-pokemon-name-sentinel
239 ;; 0xD2E9: end-of-pokemon-name-sentinel
240 ;; 0xD2EA: end-of-pokemon-name-sentinel
241 ;; 0xD2EB: A
242 ;; 0xD2EC: end-of-pokemon-name-sentinel
243 ;; 0xD2ED: S
244 ;; 0xD2EE: T
245 ;; 0xD2EF: E
246 ;; 0xD2F0: R
247 ;; 0xD2F1:
248 ;; 0xD2F2: B
249 ;; 0xD2F3: A
250 ;; 0xD2F4: L
251 ;; 0xD2F5: L
252 ;; 0xD2F6:
253 ;; 0xD2F7: A
254 ;; 0xD2F8:
255 ;; 0xD2F9:
256 ;; 0xD2FA: end-of-name-sentinel
257 ;; 0xD2FB: end-of-name-sentinel
258 ;; 0xD2FC: A
259 ;; 0xD2FD:
260 ;; 0xD2FE: end-of-name-sentinel
261 ;; 0xD2FF: end-of-name-sentinel
262 ;; 0xD300: end-of-name-sentinel
263 ;; 0xD301: end-of-name-sentinel
264 ;; 0xD302: end-of-name-sentinel
265 ;; 0xD303: end-of-name-sentinel
266 ;; 0xD304: end-of-name-sentinel
267 ;; 0xD305: end-of-name-sentinel
268 ;; 0xD306: end-of-name-sentinel
269 ;; 0xD307: end-of-name-sentinel
270 ;; 0xD308: end-of-name-sentinel
271 ;; 0xD309:
272 ;; 0xD30A: w
273 ;; 0xD30B:
274 ;; 0xD30C: V
275 ;; 0xD30D:
276 ;; 0xD30E:
277 ;; 0xD30F: K
278 ;; 0xD310:
279 ;; 0xD311:
280 ;; 0xD312:
281 ;; 0xD313: A
282 ;; 0xD314:
283 ;; 0xD315:
284 ;; 0xD316:
285 ;; 0xD317: i
286 ;; 0xD318:
287 ;; 0xD319:
288 ;; 0xD31A: end-of-name-sentinel
289 ;; 0xD31B: end-of-name-sentinel
290 ;; 0xD31C:
291 ;; 0xD31D:
292 ;; 0xD31E:
293 ;; 0xD31F:
294 ;; 0xD320:
295 ;; 0xD321:
296 ;; 0xD322:
297 ;; 0xD323:
298 ;; 0xD324:
299 ;; 0xD325:
300 ;; 0xD326:
301 ;; 0xD327:
302 ;; 0xD328:
303 ;; 0xD329:
304 ;; 0xD32A:
305 ;; 0xD32B:
306 ;; 0xD32C:
307 ;; 0xD32D:
308 ;; 0xD32E:
309 ;; 0xD32F:
310 ;; 0xD330:
311 ;; 0xD331: 9
312 ;; 0xD332: end-of-name-sentinel
313 ;; 0xD333: 9
314 ;; 0xD334:
315 ;; 0xD335: 9
316 ;; 0xD336:
317 ;; 0xD337: 9
318 ;; 0xD338: end-of-name-sentinel
319 ;; 0xD339: end-of-name-sentinel
320 ;; 0xD33A: end-of-name-sentinel
321 ;; 0xD33B: end-of-name-sentinel
322 ;; 0xD33C: end-of-name-sentinel
323 ;; 0xD33D: end-of-name-sentinel
324 ;; 0xD33E: end-of-name-sentinel
325 ;; 0xD33F: end-of-name-sentinel
326 ;; 0xD340: end-of-name-sentinel
327 ;; 0xD341: end-of-name-sentinel
328 ;; 0xD342: end-of-name-sentinel
329 ;; 0xD343: end-of-name-sentinel
330 ;; 0xD344: end-of-name-sentinel
331 ;; 0xD345: end-of-name-sentinel
332 ;; 0xD346:
333 ;; 0xD347:
334 ;; 0xD348:
335 ;; 0xD349: G
336 ;; 0xD34A: A
337 ;; 0xD34B: R
338 ;; 0xD34C: Y
339 ;; 0xD34D: end-of-pokemon-name-sentinel
340 ;; 0xD34E: J
343 ;; from this, it looks like the pokemon names are stored all
344 ;; together in one location that begins at 0xD2B4 and
345 ;; extends until 0xD2F5, with each name taking up 11 bytes.
346 ;;
347 ;; rival's name again clearly starts at 0xD349.
350 (def pokemon-names-start 0xD2B4)
353 ;; determine whether "number of pokemon in party"
354 ;; might be kept in RAM and if so, where?
356 (def six-pokemon (read-state "6-pokemon"))
357 (def five-pokemon (read-state "5-pokemon"))
358 (def four-pokemon (read-state "4-pokemon"))
359 (def three-pokemon (read-state "3-pokemon"))
360 (def two-pokemon (read-state "2-pokemon"))
361 (def one-pokemon (read-state "1-pokemon"))
364 (defn analyze-num-pokemon []
365 (apply common-differences
366 (map (comp vec memory)
367 [one-pokemon
368 two-pokemon
369 three-pokemon
370 four-pokemon
371 five-pokemon
372 six-pokemon])))
374 ;; ;; results
375 ;; ([53602 (1 2 3 4 5 6)]
376 ;; [65314 (105 61 93 60 92 34)]
377 ;; [55875 (34 36 43 52 7 0)]
378 ;; [55876 (18 0 33 52 54 30)]
379 ;; [49158 (197 194 77 117 174 134)]
380 ;; [49160 (29 26 57 239 15 243)]
381 ;; [49736 (74 93 34 89 91 59)]
382 ;; [49162 (165 162 182 179 197 109)]
383 ;; [49227 (187 105 204 5 90 238)]
384 ;; [53067 (128 136 132 145 135 11)]
385 ;; [53068 (147 131 141 136 128 7)]
386 ;; [53069 (136 134 148 140 145 2)]
387 ;; [49904 (2 11 10 3 27 12)]
388 ;; [49172 (100 109 213 195 68 104)]
389 ;; [65492 (11 103 128 160 19 56)]
390 ;; [49173 (80 77 72 75 76 67)]
391 ;; [49334 (8 10 11 5 3 1)]
392 ;; [49335 (49 10 11 19 17 15)]
393 ;; [49336 (8 10 11 5 3 1)]
394 ;; [49720 (106 14 118 0 38 11)]
395 ;; [65304 (32 88 19 114 106 33)]
396 ;; [53561 (59 229 48 17 155 103)]
397 ;; [55935 (6 5 4 3 2 1)])
400 ;; two canidates : 0xD162 or 0xDA7F
401 ;; they seem to always sum to 6...
405 ;; try to set both of them when having only one pokemon.
407 (defn change-party-number [^SaveState state new-num]
408 (set-memory state 0xD162 new-num))
410 ;; (continue! (change-party-number one-pokemon 3))
411 ;; result -- can scroll down beyone first pokemon, finding
412 ;; glitched pokemon in places where there were previously no
413 ;; pokemon.
416 (defn change-party-number* [^SaveState state new-num]
417 (set-memory state 0xDA7F new-num))
420 ;; (continue! (change-party-number* one-pokemon 3))
421 ;; cannot widthdraw any pokemon from box 1 past the third
422 ;; pokemon.
424 (def party-number-address 0xD162)
426 (defn party-number
427 ([^SaveState state]
428 (aget (memory state) party-number-address))
429 ([] (party-number @current-state)))
431 (def pokemon-in-box-1-address 0xDA7F)
433 (defn party-names
434 ([^SaveState state]
435 (let [raw-names
436 (subvec (vec (memory state))
437 pokemon-names-start
438 (+ pokemon-names-start
439 (* name-width 6)))]
440 (map
441 read-pokemon-name
442 (take
443 (party-number state)
444 (partition name-width
445 raw-names)))))
446 ([] (party-names @current-state)))