# HG changeset patch # User Robert McIntyre # Date 1332214956 18000 # Node ID 279e9ee6fccb3bcb60b53ac46e4dc562cd13f21e # Parent c5914665012d2e749ff82bb42bfc0ba2ba186eb7 can now determine the number of pokemon in the party. diff -r c5914665012d -r 279e9ee6fccb clojure/com/aurellem/exp/pokemon.clj --- a/clojure/com/aurellem/exp/pokemon.clj Mon Mar 19 21:35:43 2012 -0500 +++ b/clojure/com/aurellem/exp/pokemon.clj Mon Mar 19 22:42:36 2012 -0500 @@ -89,15 +89,360 @@ (def end-of-name-marker 0x50) -(def max-name-length 11) +(def max-name-length 10) +(def name-width 11) + +(defn read-pokemon-name [codes] + (character-codes->str + (take-while + (partial not= end-of-name-marker) codes))) + (defn sixth-pokemon-name [^SaveState state] - (character-codes->str - (take-while - (partial not= 0x50) + (read-pokemon-name (subvec (vec (memory state)) sixth-pokemon-name-start (+ (inc max-name-length) - sixth-pokemon-name-start))))) - + sixth-pokemon-name-start)))) +(defn rename-sixth-pokemon + ([^SaveState state new-name] + (assert (< (count new-name) max-name-length)) + (set-memory-range state sixth-pokemon-name-start + (concat (str->character-codes new-name) + [end-of-name-marker]))) + ([new-name] + (rename-sixth-pokemon @current-state new-name))) + +(defn print-text + ([^SaveState state begin end] + (dorun + (map (fn [character-code line] + (println + (format "0x%04X: " line) + (str (character-code->character character-code)))) + (subvec (vec (memory state)) begin end) + (range begin end))) + state) + ([begin end] + (print-text @current-state begin end))) + + + + +(defn examine-name-memory [] + (print-text + named-A + (- sixth-pokemon-name-start 100) + (+ sixth-pokemon-name-start 100))) + + +;; results: +;; 0xD287: end-of-name-sentinel +;; 0xD288: R +;; 0xD289: L +;; 0xD28A: M +;; 0xD28B: end-of-pokemon-name-sentinel +;; 0xD28C: end-of-name-sentinel +;; 0xD28D: end-of-name-sentinel +;; 0xD28E: end-of-name-sentinel +;; 0xD28F: end-of-name-sentinel +;; 0xD290: end-of-name-sentinel +;; 0xD291: end-of-name-sentinel +;; 0xD292: end-of-name-sentinel +;; 0xD293: R +;; 0xD294: L +;; 0xD295: M +;; 0xD296: end-of-pokemon-name-sentinel +;; 0xD297: end-of-name-sentinel +;; 0xD298: end-of-name-sentinel +;; 0xD299: end-of-name-sentinel +;; 0xD29A: end-of-name-sentinel +;; 0xD29B: end-of-name-sentinel +;; 0xD29C: end-of-name-sentinel +;; 0xD29D: end-of-name-sentinel +;; 0xD29E: R +;; 0xD29F: L +;; 0xD2A0: M +;; 0xD2A1: end-of-pokemon-name-sentinel +;; 0xD2A2: end-of-name-sentinel +;; 0xD2A3: end-of-name-sentinel +;; 0xD2A4: end-of-name-sentinel +;; 0xD2A5: end-of-name-sentinel +;; 0xD2A6: end-of-name-sentinel +;; 0xD2A7: end-of-name-sentinel +;; 0xD2A8: end-of-name-sentinel +;; 0xD2A9: R +;; 0xD2AA: L +;; 0xD2AB: M +;; 0xD2AC: end-of-pokemon-name-sentinel +;; 0xD2AD: end-of-name-sentinel +;; 0xD2AE: end-of-name-sentinel +;; 0xD2AF: end-of-name-sentinel +;; 0xD2B0: end-of-name-sentinel +;; 0xD2B1: end-of-name-sentinel +;; 0xD2B2: end-of-name-sentinel +;; 0xD2B3: end-of-name-sentinel +;; 0xD2B4: P +;; 0xD2B5: I +;; 0xD2B6: D +;; 0xD2B7: G +;; 0xD2B8: E +;; 0xD2B9: O +;; 0xD2BA: T +;; 0xD2BB: end-of-pokemon-name-sentinel +;; 0xD2BC: end-of-pokemon-name-sentinel +;; 0xD2BD: end-of-pokemon-name-sentinel +;; 0xD2BE: end-of-pokemon-name-sentinel +;; 0xD2BF: P +;; 0xD2C0: I +;; 0xD2C1: K +;; 0xD2C2: A +;; 0xD2C3: C +;; 0xD2C4: H +;; 0xD2C5: U +;; 0xD2C6: end-of-pokemon-name-sentinel +;; 0xD2C7: end-of-pokemon-name-sentinel +;; 0xD2C8: end-of-pokemon-name-sentinel +;; 0xD2C9: end-of-pokemon-name-sentinel +;; 0xD2CA: C +;; 0xD2CB: H +;; 0xD2CC: A +;; 0xD2CD: R +;; 0xD2CE: I +;; 0xD2CF: Z +;; 0xD2D0: A +;; 0xD2D1: R +;; 0xD2D2: D +;; 0xD2D3: end-of-pokemon-name-sentinel +;; 0xD2D4: end-of-pokemon-name-sentinel +;; 0xD2D5: V +;; 0xD2D6: E +;; 0xD2D7: N +;; 0xD2D8: U +;; 0xD2D9: S +;; 0xD2DA: A +;; 0xD2DB: U +;; 0xD2DC: R +;; 0xD2DD: end-of-pokemon-name-sentinel +;; 0xD2DE: end-of-pokemon-name-sentinel +;; 0xD2DF: end-of-pokemon-name-sentinel +;; 0xD2E0: P +;; 0xD2E1: R +;; 0xD2E2: I +;; 0xD2E3: M +;; 0xD2E4: E +;; 0xD2E5: A +;; 0xD2E6: P +;; 0xD2E7: E +;; 0xD2E8: end-of-pokemon-name-sentinel +;; 0xD2E9: end-of-pokemon-name-sentinel +;; 0xD2EA: end-of-pokemon-name-sentinel +;; 0xD2EB: A +;; 0xD2EC: end-of-pokemon-name-sentinel +;; 0xD2ED: S +;; 0xD2EE: T +;; 0xD2EF: E +;; 0xD2F0: R +;; 0xD2F1: +;; 0xD2F2: B +;; 0xD2F3: A +;; 0xD2F4: L +;; 0xD2F5: L +;; 0xD2F6: +;; 0xD2F7: A +;; 0xD2F8: +;; 0xD2F9: +;; 0xD2FA: end-of-name-sentinel +;; 0xD2FB: end-of-name-sentinel +;; 0xD2FC: A +;; 0xD2FD: +;; 0xD2FE: end-of-name-sentinel +;; 0xD2FF: end-of-name-sentinel +;; 0xD300: end-of-name-sentinel +;; 0xD301: end-of-name-sentinel +;; 0xD302: end-of-name-sentinel +;; 0xD303: end-of-name-sentinel +;; 0xD304: end-of-name-sentinel +;; 0xD305: end-of-name-sentinel +;; 0xD306: end-of-name-sentinel +;; 0xD307: end-of-name-sentinel +;; 0xD308: end-of-name-sentinel +;; 0xD309: +;; 0xD30A: w +;; 0xD30B: +;; 0xD30C: V +;; 0xD30D: +;; 0xD30E: +;; 0xD30F: K +;; 0xD310: +;; 0xD311: +;; 0xD312: +;; 0xD313: A +;; 0xD314: +;; 0xD315: +;; 0xD316: +;; 0xD317: i +;; 0xD318: +;; 0xD319: +;; 0xD31A: end-of-name-sentinel +;; 0xD31B: end-of-name-sentinel +;; 0xD31C: +;; 0xD31D: +;; 0xD31E: +;; 0xD31F: +;; 0xD320: +;; 0xD321: +;; 0xD322: +;; 0xD323: +;; 0xD324: +;; 0xD325: +;; 0xD326: +;; 0xD327: +;; 0xD328: +;; 0xD329: +;; 0xD32A: +;; 0xD32B: +;; 0xD32C: +;; 0xD32D: +;; 0xD32E: +;; 0xD32F: +;; 0xD330: +;; 0xD331: 9 +;; 0xD332: end-of-name-sentinel +;; 0xD333: 9 +;; 0xD334: +;; 0xD335: 9 +;; 0xD336: +;; 0xD337: 9 +;; 0xD338: end-of-name-sentinel +;; 0xD339: end-of-name-sentinel +;; 0xD33A: end-of-name-sentinel +;; 0xD33B: end-of-name-sentinel +;; 0xD33C: end-of-name-sentinel +;; 0xD33D: end-of-name-sentinel +;; 0xD33E: end-of-name-sentinel +;; 0xD33F: end-of-name-sentinel +;; 0xD340: end-of-name-sentinel +;; 0xD341: end-of-name-sentinel +;; 0xD342: end-of-name-sentinel +;; 0xD343: end-of-name-sentinel +;; 0xD344: end-of-name-sentinel +;; 0xD345: end-of-name-sentinel +;; 0xD346: +;; 0xD347: +;; 0xD348: +;; 0xD349: G +;; 0xD34A: A +;; 0xD34B: R +;; 0xD34C: Y +;; 0xD34D: end-of-pokemon-name-sentinel +;; 0xD34E: J + + +;; from this, it looks like the pokemon names are stored all +;; together in one location that begins at 0xD2B4 and +;; extends until 0xD2F5, with each name taking up 11 bytes. +;; +;; rival's name again clearly starts at 0xD349. + + +(def pokemon-names-start 0xD2B4) + + +;; determine whether "number of pokemon in party" +;; might be kept in RAM and if so, where? + +(def six-pokemon (read-state "6-pokemon")) +(def five-pokemon (read-state "5-pokemon")) +(def four-pokemon (read-state "4-pokemon")) +(def three-pokemon (read-state "3-pokemon")) +(def two-pokemon (read-state "2-pokemon")) +(def one-pokemon (read-state "1-pokemon")) + + +(defn analyze-num-pokemon [] + (apply common-differences + (map (comp vec memory) + [one-pokemon + two-pokemon + three-pokemon + four-pokemon + five-pokemon + six-pokemon]))) + +;; ;; results +;; ([53602 (1 2 3 4 5 6)] +;; [65314 (105 61 93 60 92 34)] +;; [55875 (34 36 43 52 7 0)] +;; [55876 (18 0 33 52 54 30)] +;; [49158 (197 194 77 117 174 134)] +;; [49160 (29 26 57 239 15 243)] +;; [49736 (74 93 34 89 91 59)] +;; [49162 (165 162 182 179 197 109)] +;; [49227 (187 105 204 5 90 238)] +;; [53067 (128 136 132 145 135 11)] +;; [53068 (147 131 141 136 128 7)] +;; [53069 (136 134 148 140 145 2)] +;; [49904 (2 11 10 3 27 12)] +;; [49172 (100 109 213 195 68 104)] +;; [65492 (11 103 128 160 19 56)] +;; [49173 (80 77 72 75 76 67)] +;; [49334 (8 10 11 5 3 1)] +;; [49335 (49 10 11 19 17 15)] +;; [49336 (8 10 11 5 3 1)] +;; [49720 (106 14 118 0 38 11)] +;; [65304 (32 88 19 114 106 33)] +;; [53561 (59 229 48 17 155 103)] +;; [55935 (6 5 4 3 2 1)]) + + +;; two canidates : 0xD162 or 0xDA7F +;; they seem to always sum to 6... + + + +;; try to set both of them when having only one pokemon. + +(defn change-party-number [^SaveState state new-num] + (set-memory state 0xD162 new-num)) + +;; (continue! (change-party-number one-pokemon 3)) +;; result -- can scroll down beyone first pokemon, finding +;; glitched pokemon in places where there were previously no +;; pokemon. + + +(defn change-party-number* [^SaveState state new-num] + (set-memory state 0xDA7F new-num)) + + +;; (continue! (change-party-number* one-pokemon 3)) +;; cannot widthdraw any pokemon from box 1 past the third +;; pokemon. + +(def party-number-address 0xD162) + +(defn party-number + ([^SaveState state] + (aget (memory state) party-number-address)) + ([] (party-number @current-state))) + +(def pokemon-in-box-1-address 0xDA7F) + +(defn party-names + ([^SaveState state] + (let [raw-names + (subvec (vec (memory state)) + pokemon-names-start + (+ pokemon-names-start + (* name-width 6)))] + (map + read-pokemon-name + (take + (party-number state) + (partition name-width + raw-names))))) + ([] (party-names @current-state))) + + \ No newline at end of file diff -r c5914665012d -r 279e9ee6fccb clojure/com/aurellem/gb/characters.clj --- a/clojure/com/aurellem/gb/characters.clj Mon Mar 19 21:35:43 2012 -0500 +++ b/clojure/com/aurellem/gb/characters.clj Mon Mar 19 22:42:36 2012 -0500 @@ -5,6 +5,7 @@ (def character-code->character { 0x00 "end-of-name-sentinel" + 0x50 "end-of-pokemon-name-sentinel" 0x60 "A-bold" 0x61 "B-bold" 0x62 "C-bold" diff -r c5914665012d -r 279e9ee6fccb save-states/1-pokemon.sav Binary file save-states/1-pokemon.sav has changed diff -r c5914665012d -r 279e9ee6fccb save-states/2-pokemon.sav Binary file save-states/2-pokemon.sav has changed diff -r c5914665012d -r 279e9ee6fccb save-states/3-pokemon.sav Binary file save-states/3-pokemon.sav has changed diff -r c5914665012d -r 279e9ee6fccb save-states/4-pokemon.sav Binary file save-states/4-pokemon.sav has changed diff -r c5914665012d -r 279e9ee6fccb save-states/5-pokemon.sav Binary file save-states/5-pokemon.sav has changed diff -r c5914665012d -r 279e9ee6fccb save-states/6-pokemon.sav Binary file save-states/6-pokemon.sav has changed