changeset 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
files clojure/com/aurellem/exp/pokemon.clj clojure/com/aurellem/gb/characters.clj save-states/1-pokemon.sav save-states/2-pokemon.sav save-states/3-pokemon.sav save-states/4-pokemon.sav save-states/5-pokemon.sav save-states/6-pokemon.sav
diffstat 8 files changed, 352 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
     1.1 --- a/clojure/com/aurellem/exp/pokemon.clj	Mon Mar 19 21:35:43 2012 -0500
     1.2 +++ b/clojure/com/aurellem/exp/pokemon.clj	Mon Mar 19 22:42:36 2012 -0500
     1.3 @@ -89,15 +89,360 @@
     1.4  
     1.5  
     1.6  (def end-of-name-marker 0x50)
     1.7 -(def max-name-length 11)
     1.8 +(def max-name-length 10)
     1.9 +(def name-width 11)
    1.10 +
    1.11 +(defn read-pokemon-name [codes]
    1.12 +  (character-codes->str
    1.13 +   (take-while
    1.14 +    (partial not= end-of-name-marker) codes)))
    1.15 +    
    1.16  
    1.17  (defn sixth-pokemon-name [^SaveState state]
    1.18 -  (character-codes->str
    1.19 -   (take-while
    1.20 -    (partial not= 0x50)
    1.21 +  (read-pokemon-name
    1.22      (subvec (vec (memory state))
    1.23              sixth-pokemon-name-start
    1.24              (+ (inc max-name-length)
    1.25 -               sixth-pokemon-name-start)))))
    1.26 -          
    1.27 +               sixth-pokemon-name-start))))
    1.28  
    1.29 +(defn rename-sixth-pokemon
    1.30 +  ([^SaveState state new-name]
    1.31 +     (assert (< (count new-name) max-name-length))
    1.32 +     (set-memory-range state sixth-pokemon-name-start
    1.33 +                       (concat (str->character-codes new-name)
    1.34 +                               [end-of-name-marker])))
    1.35 +  ([new-name]
    1.36 +     (rename-sixth-pokemon @current-state new-name)))
    1.37 +
    1.38 +(defn print-text
    1.39 +  ([^SaveState state begin end]
    1.40 +     (dorun
    1.41 +      (map (fn [character-code line]
    1.42 +             (println
    1.43 +              (format "0x%04X: " line)
    1.44 +                      (str (character-code->character character-code))))
    1.45 +           (subvec (vec (memory state)) begin end)
    1.46 +           (range begin end)))
    1.47 +     state)
    1.48 +  ([begin end]
    1.49 +     (print-text @current-state begin end)))
    1.50 +
    1.51 +
    1.52 +
    1.53 +
    1.54 +(defn examine-name-memory []
    1.55 +  (print-text
    1.56 +   named-A
    1.57 +   (- sixth-pokemon-name-start 100)
    1.58 +   (+ sixth-pokemon-name-start 100)))
    1.59 +
    1.60 +
    1.61 +;; results:
    1.62 +;; 0xD287:  end-of-name-sentinel
    1.63 +;; 0xD288:  R
    1.64 +;; 0xD289:  L
    1.65 +;; 0xD28A:  M
    1.66 +;; 0xD28B:  end-of-pokemon-name-sentinel
    1.67 +;; 0xD28C:  end-of-name-sentinel
    1.68 +;; 0xD28D:  end-of-name-sentinel
    1.69 +;; 0xD28E:  end-of-name-sentinel
    1.70 +;; 0xD28F:  end-of-name-sentinel
    1.71 +;; 0xD290:  end-of-name-sentinel
    1.72 +;; 0xD291:  end-of-name-sentinel
    1.73 +;; 0xD292:  end-of-name-sentinel
    1.74 +;; 0xD293:  R
    1.75 +;; 0xD294:  L
    1.76 +;; 0xD295:  M
    1.77 +;; 0xD296:  end-of-pokemon-name-sentinel
    1.78 +;; 0xD297:  end-of-name-sentinel
    1.79 +;; 0xD298:  end-of-name-sentinel
    1.80 +;; 0xD299:  end-of-name-sentinel
    1.81 +;; 0xD29A:  end-of-name-sentinel
    1.82 +;; 0xD29B:  end-of-name-sentinel
    1.83 +;; 0xD29C:  end-of-name-sentinel
    1.84 +;; 0xD29D:  end-of-name-sentinel
    1.85 +;; 0xD29E:  R
    1.86 +;; 0xD29F:  L
    1.87 +;; 0xD2A0:  M
    1.88 +;; 0xD2A1:  end-of-pokemon-name-sentinel
    1.89 +;; 0xD2A2:  end-of-name-sentinel
    1.90 +;; 0xD2A3:  end-of-name-sentinel
    1.91 +;; 0xD2A4:  end-of-name-sentinel
    1.92 +;; 0xD2A5:  end-of-name-sentinel
    1.93 +;; 0xD2A6:  end-of-name-sentinel
    1.94 +;; 0xD2A7:  end-of-name-sentinel
    1.95 +;; 0xD2A8:  end-of-name-sentinel
    1.96 +;; 0xD2A9:  R
    1.97 +;; 0xD2AA:  L
    1.98 +;; 0xD2AB:  M
    1.99 +;; 0xD2AC:  end-of-pokemon-name-sentinel
   1.100 +;; 0xD2AD:  end-of-name-sentinel
   1.101 +;; 0xD2AE:  end-of-name-sentinel
   1.102 +;; 0xD2AF:  end-of-name-sentinel
   1.103 +;; 0xD2B0:  end-of-name-sentinel
   1.104 +;; 0xD2B1:  end-of-name-sentinel
   1.105 +;; 0xD2B2:  end-of-name-sentinel
   1.106 +;; 0xD2B3:  end-of-name-sentinel
   1.107 +;; 0xD2B4:  P
   1.108 +;; 0xD2B5:  I
   1.109 +;; 0xD2B6:  D
   1.110 +;; 0xD2B7:  G
   1.111 +;; 0xD2B8:  E
   1.112 +;; 0xD2B9:  O
   1.113 +;; 0xD2BA:  T
   1.114 +;; 0xD2BB:  end-of-pokemon-name-sentinel
   1.115 +;; 0xD2BC:  end-of-pokemon-name-sentinel
   1.116 +;; 0xD2BD:  end-of-pokemon-name-sentinel
   1.117 +;; 0xD2BE:  end-of-pokemon-name-sentinel
   1.118 +;; 0xD2BF:  P
   1.119 +;; 0xD2C0:  I
   1.120 +;; 0xD2C1:  K
   1.121 +;; 0xD2C2:  A
   1.122 +;; 0xD2C3:  C
   1.123 +;; 0xD2C4:  H
   1.124 +;; 0xD2C5:  U
   1.125 +;; 0xD2C6:  end-of-pokemon-name-sentinel
   1.126 +;; 0xD2C7:  end-of-pokemon-name-sentinel
   1.127 +;; 0xD2C8:  end-of-pokemon-name-sentinel
   1.128 +;; 0xD2C9:  end-of-pokemon-name-sentinel
   1.129 +;; 0xD2CA:  C
   1.130 +;; 0xD2CB:  H
   1.131 +;; 0xD2CC:  A
   1.132 +;; 0xD2CD:  R
   1.133 +;; 0xD2CE:  I
   1.134 +;; 0xD2CF:  Z
   1.135 +;; 0xD2D0:  A
   1.136 +;; 0xD2D1:  R
   1.137 +;; 0xD2D2:  D
   1.138 +;; 0xD2D3:  end-of-pokemon-name-sentinel
   1.139 +;; 0xD2D4:  end-of-pokemon-name-sentinel
   1.140 +;; 0xD2D5:  V
   1.141 +;; 0xD2D6:  E
   1.142 +;; 0xD2D7:  N
   1.143 +;; 0xD2D8:  U
   1.144 +;; 0xD2D9:  S
   1.145 +;; 0xD2DA:  A
   1.146 +;; 0xD2DB:  U
   1.147 +;; 0xD2DC:  R
   1.148 +;; 0xD2DD:  end-of-pokemon-name-sentinel
   1.149 +;; 0xD2DE:  end-of-pokemon-name-sentinel
   1.150 +;; 0xD2DF:  end-of-pokemon-name-sentinel
   1.151 +;; 0xD2E0:  P
   1.152 +;; 0xD2E1:  R
   1.153 +;; 0xD2E2:  I
   1.154 +;; 0xD2E3:  M
   1.155 +;; 0xD2E4:  E
   1.156 +;; 0xD2E5:  A
   1.157 +;; 0xD2E6:  P
   1.158 +;; 0xD2E7:  E
   1.159 +;; 0xD2E8:  end-of-pokemon-name-sentinel
   1.160 +;; 0xD2E9:  end-of-pokemon-name-sentinel
   1.161 +;; 0xD2EA:  end-of-pokemon-name-sentinel
   1.162 +;; 0xD2EB:  A
   1.163 +;; 0xD2EC:  end-of-pokemon-name-sentinel
   1.164 +;; 0xD2ED:  S
   1.165 +;; 0xD2EE:  T
   1.166 +;; 0xD2EF:  E
   1.167 +;; 0xD2F0:  R
   1.168 +;; 0xD2F1:  
   1.169 +;; 0xD2F2:  B
   1.170 +;; 0xD2F3:  A
   1.171 +;; 0xD2F4:  L
   1.172 +;; 0xD2F5:  L
   1.173 +;; 0xD2F6:  
   1.174 +;; 0xD2F7:  A
   1.175 +;; 0xD2F8:  
   1.176 +;; 0xD2F9:  
   1.177 +;; 0xD2FA:  end-of-name-sentinel
   1.178 +;; 0xD2FB:  end-of-name-sentinel
   1.179 +;; 0xD2FC:  A
   1.180 +;; 0xD2FD:  
   1.181 +;; 0xD2FE:  end-of-name-sentinel
   1.182 +;; 0xD2FF:  end-of-name-sentinel
   1.183 +;; 0xD300:  end-of-name-sentinel
   1.184 +;; 0xD301:  end-of-name-sentinel
   1.185 +;; 0xD302:  end-of-name-sentinel
   1.186 +;; 0xD303:  end-of-name-sentinel
   1.187 +;; 0xD304:  end-of-name-sentinel
   1.188 +;; 0xD305:  end-of-name-sentinel
   1.189 +;; 0xD306:  end-of-name-sentinel
   1.190 +;; 0xD307:  end-of-name-sentinel
   1.191 +;; 0xD308:  end-of-name-sentinel
   1.192 +;; 0xD309:  
   1.193 +;; 0xD30A:  w
   1.194 +;; 0xD30B:  
   1.195 +;; 0xD30C:  V
   1.196 +;; 0xD30D:  
   1.197 +;; 0xD30E:  
   1.198 +;; 0xD30F:  K
   1.199 +;; 0xD310:  
   1.200 +;; 0xD311:  
   1.201 +;; 0xD312:  
   1.202 +;; 0xD313:  A
   1.203 +;; 0xD314:  
   1.204 +;; 0xD315:  
   1.205 +;; 0xD316:  
   1.206 +;; 0xD317:  i
   1.207 +;; 0xD318:  
   1.208 +;; 0xD319:  
   1.209 +;; 0xD31A:  end-of-name-sentinel
   1.210 +;; 0xD31B:  end-of-name-sentinel
   1.211 +;; 0xD31C:  
   1.212 +;; 0xD31D:  
   1.213 +;; 0xD31E:  
   1.214 +;; 0xD31F:  
   1.215 +;; 0xD320:  
   1.216 +;; 0xD321:  
   1.217 +;; 0xD322:  
   1.218 +;; 0xD323:  
   1.219 +;; 0xD324:  
   1.220 +;; 0xD325:  
   1.221 +;; 0xD326:  
   1.222 +;; 0xD327:  
   1.223 +;; 0xD328:  
   1.224 +;; 0xD329:  
   1.225 +;; 0xD32A:  
   1.226 +;; 0xD32B:  
   1.227 +;; 0xD32C:  
   1.228 +;; 0xD32D:  
   1.229 +;; 0xD32E:  
   1.230 +;; 0xD32F:  
   1.231 +;; 0xD330:  
   1.232 +;; 0xD331:  9
   1.233 +;; 0xD332:  end-of-name-sentinel
   1.234 +;; 0xD333:  9
   1.235 +;; 0xD334:  
   1.236 +;; 0xD335:  9
   1.237 +;; 0xD336:  
   1.238 +;; 0xD337:  9
   1.239 +;; 0xD338:  end-of-name-sentinel
   1.240 +;; 0xD339:  end-of-name-sentinel
   1.241 +;; 0xD33A:  end-of-name-sentinel
   1.242 +;; 0xD33B:  end-of-name-sentinel
   1.243 +;; 0xD33C:  end-of-name-sentinel
   1.244 +;; 0xD33D:  end-of-name-sentinel
   1.245 +;; 0xD33E:  end-of-name-sentinel
   1.246 +;; 0xD33F:  end-of-name-sentinel
   1.247 +;; 0xD340:  end-of-name-sentinel
   1.248 +;; 0xD341:  end-of-name-sentinel
   1.249 +;; 0xD342:  end-of-name-sentinel
   1.250 +;; 0xD343:  end-of-name-sentinel
   1.251 +;; 0xD344:  end-of-name-sentinel
   1.252 +;; 0xD345:  end-of-name-sentinel
   1.253 +;; 0xD346:  
   1.254 +;; 0xD347:  
   1.255 +;; 0xD348:  
   1.256 +;; 0xD349:  G
   1.257 +;; 0xD34A:  A
   1.258 +;; 0xD34B:  R
   1.259 +;; 0xD34C:  Y
   1.260 +;; 0xD34D:  end-of-pokemon-name-sentinel
   1.261 +;; 0xD34E:  J
   1.262 +
   1.263 +  
   1.264 +;; from this, it looks like the pokemon names are stored all
   1.265 +;; together in one location that begins at 0xD2B4 and
   1.266 +;; extends until 0xD2F5, with each name taking up 11 bytes.
   1.267 +;;
   1.268 +;; rival's name again clearly starts at 0xD349.
   1.269 +
   1.270 +
   1.271 +(def pokemon-names-start 0xD2B4)
   1.272 +     
   1.273 +
   1.274 +;; determine whether "number of pokemon in party"
   1.275 +;; might be kept in RAM and if so, where?
   1.276 +
   1.277 +(def six-pokemon (read-state "6-pokemon"))
   1.278 +(def five-pokemon (read-state "5-pokemon"))
   1.279 +(def four-pokemon (read-state "4-pokemon"))
   1.280 +(def three-pokemon (read-state "3-pokemon"))
   1.281 +(def two-pokemon (read-state "2-pokemon"))
   1.282 +(def one-pokemon (read-state "1-pokemon"))
   1.283 +
   1.284 +
   1.285 +(defn analyze-num-pokemon []
   1.286 +    (apply common-differences
   1.287 +         (map (comp vec memory)
   1.288 +              [one-pokemon
   1.289 +               two-pokemon
   1.290 +               three-pokemon
   1.291 +               four-pokemon
   1.292 +               five-pokemon
   1.293 +               six-pokemon])))
   1.294 +
   1.295 +;; ;; results
   1.296 +;; ([53602 (1 2 3 4 5 6)]
   1.297 +;;  [65314 (105 61 93 60 92 34)]
   1.298 +;;  [55875 (34 36 43 52 7 0)]
   1.299 +;;  [55876 (18 0 33 52 54 30)]
   1.300 +;;  [49158 (197 194 77 117 174 134)]
   1.301 +;;  [49160 (29 26 57 239 15 243)]
   1.302 +;;  [49736 (74 93 34 89 91 59)]
   1.303 +;;  [49162 (165 162 182 179 197 109)]
   1.304 +;;  [49227 (187 105 204 5 90 238)]
   1.305 +;;  [53067 (128 136 132 145 135 11)]
   1.306 +;;  [53068 (147 131 141 136 128 7)]
   1.307 +;;  [53069 (136 134 148 140 145 2)]
   1.308 +;;  [49904 (2 11 10 3 27 12)]
   1.309 +;;  [49172 (100 109 213 195 68 104)]
   1.310 +;;  [65492 (11 103 128 160 19 56)]
   1.311 +;;  [49173 (80 77 72 75 76 67)]
   1.312 +;;  [49334 (8 10 11 5 3 1)]
   1.313 +;;  [49335 (49 10 11 19 17 15)]
   1.314 +;;  [49336 (8 10 11 5 3 1)]
   1.315 +;;  [49720 (106 14 118 0 38 11)]
   1.316 +;;  [65304 (32 88 19 114 106 33)]
   1.317 +;;  [53561 (59 229 48 17 155 103)]
   1.318 +;;  [55935 (6 5 4 3 2 1)])
   1.319 +
   1.320 +
   1.321 +;; two canidates : 0xD162 or 0xDA7F
   1.322 +;; they seem to always sum to 6...
   1.323 +
   1.324 +
   1.325 +
   1.326 +;; try to set both of them when having only one pokemon.
   1.327 +
   1.328 +(defn change-party-number [^SaveState state new-num]
   1.329 +  (set-memory state 0xD162 new-num))
   1.330 +
   1.331 +;; (continue! (change-party-number one-pokemon 3))
   1.332 +;; result -- can scroll down beyone first pokemon, finding
   1.333 +;; glitched pokemon in places where there were previously no
   1.334 +;; pokemon.
   1.335 +
   1.336 +
   1.337 +(defn change-party-number* [^SaveState state new-num]
   1.338 +  (set-memory state 0xDA7F new-num))
   1.339 +
   1.340 +
   1.341 +;; (continue! (change-party-number* one-pokemon 3))
   1.342 +;; cannot widthdraw any pokemon from box 1 past the third
   1.343 +;; pokemon.
   1.344 +
   1.345 +(def party-number-address 0xD162)
   1.346 +
   1.347 +(defn party-number
   1.348 +  ([^SaveState state]
   1.349 +     (aget (memory state) party-number-address))
   1.350 +  ([] (party-number @current-state)))
   1.351 +
   1.352 +(def pokemon-in-box-1-address 0xDA7F)
   1.353 +
   1.354 +(defn party-names
   1.355 +  ([^SaveState state]
   1.356 +     (let [raw-names
   1.357 +           (subvec (vec (memory state))
   1.358 +                   pokemon-names-start
   1.359 +                   (+ pokemon-names-start
   1.360 +                      (*  name-width 6)))]
   1.361 +       (map
   1.362 +        read-pokemon-name
   1.363 +        (take
   1.364 +         (party-number state)
   1.365 +          (partition name-width
   1.366 +                   raw-names)))))
   1.367 +  ([] (party-names @current-state)))
   1.368 +
   1.369 +  
   1.370 \ No newline at end of file
     2.1 --- a/clojure/com/aurellem/gb/characters.clj	Mon Mar 19 21:35:43 2012 -0500
     2.2 +++ b/clojure/com/aurellem/gb/characters.clj	Mon Mar 19 22:42:36 2012 -0500
     2.3 @@ -5,6 +5,7 @@
     2.4  (def character-code->character
     2.5    {
     2.6     0x00   "end-of-name-sentinel"
     2.7 +   0x50   "end-of-pokemon-name-sentinel"
     2.8     0x60   "A-bold"
     2.9     0x61   "B-bold"
    2.10     0x62   "C-bold"
     3.1 Binary file save-states/1-pokemon.sav has changed
     4.1 Binary file save-states/2-pokemon.sav has changed
     5.1 Binary file save-states/3-pokemon.sav has changed
     6.1 Binary file save-states/4-pokemon.sav has changed
     7.1 Binary file save-states/5-pokemon.sav has changed
     8.1 Binary file save-states/6-pokemon.sav has changed