changeset 315:363b650a77cc

merge
author Robert McIntyre <rlm@mit.edu>
date Mon, 02 Apr 2012 20:30:28 -0500
parents 073600cba28a (current diff) 2060219691fa (diff)
children d263df762c59
files
diffstat 5 files changed, 440 insertions(+), 205 deletions(-) [+]
line wrap: on
line diff
     1.1 --- a/clojure/com/aurellem/gb/hxc.clj	Mon Apr 02 20:30:02 2012 -0500
     1.2 +++ b/clojure/com/aurellem/gb/hxc.clj	Mon Apr 02 20:30:28 2012 -0500
     1.3 @@ -1,7 +1,6 @@
     1.4  (ns com.aurellem.gb.hxc
     1.5 -  (:use (com.aurellem.gb assembly characters gb-driver util
     1.6 +  (:use (com.aurellem.gb assembly characters gb-driver util mem-util
     1.7                           constants species))
     1.8 - ;; (:use (com.aurellem.world practice))
     1.9    (:import [com.aurellem.gb.gb_driver SaveState]))
    1.10  
    1.11  
    1.12 @@ -208,6 +207,49 @@
    1.13  
    1.14  
    1.15  
    1.16 +;; http://hax.iimarck.us/topic/581/
    1.17 +(defn hxc-cry
    1.18 +  "The pokemon cry data in internal order. List begins at ROM@39462"
    1.19 +  ([](hxc-cry com.aurellem.gb.gb-driver/original-rom))
    1.20 +  ([rom]
    1.21 +     (zipmap
    1.22 +      (hxc-pokenames rom)
    1.23 +      (map
    1.24 +       (fn [[cry-id pitch length]]
    1.25 +         {:cry-id cry-id
    1.26 +         :pitch pitch
    1.27 +          :length length}
    1.28 +         )
    1.29 +       (partition 3
    1.30 +                  (drop 0x39462 rom))))))
    1.31 +
    1.32 +(defn hxc-cry-groups
    1.33 +  ([] (hxc-cry-groups com.aurellem.gb.gb-driver/original-rom))
    1.34 +  ([rom]
    1.35 +     (map #(mapv first
    1.36 +                (filter
    1.37 +                 (fn [[k v]]
    1.38 +                   (= % (:cry-id v)))
    1.39 +                 (hxc-cry)))
    1.40 +          ((comp
    1.41 +            range
    1.42 +            count
    1.43 +            set
    1.44 +            (partial map :cry-id)
    1.45 +            vals
    1.46 +            hxc-cry)
    1.47 +           rom))))
    1.48 +
    1.49 +
    1.50 +(defn cry-conversion!
    1.51 +  "Convert Porygon's cry in ROM to be the cry of the given pokemon."
    1.52 +  [pkmn]
    1.53 +  (write-rom!
    1.54 +   (rewrite-memory
    1.55 +    (vec(rom))
    1.56 +    0x3965D 
    1.57 +    (map second
    1.58 +         ((hxc-cry) pkmn)))))
    1.59  
    1.60  (def hxc-items-raw
    1.61    "The hardcoded names of the items in memory. List begins at
    1.62 @@ -398,7 +440,7 @@
    1.63    
    1.64  
    1.65  (defn hxc-machines
    1.66 -  "The hardcoded moves taught by TMs and HMs. List begins at ROM@0x1232D."
    1.67 +  "The hardcoded moves taught by TMs and HMs. List begins at ROM@1232D."
    1.68    ([] (hxc-machines
    1.69         com.aurellem.gb.gb-driver/original-rom))
    1.70    ([rom]
    1.71 @@ -694,6 +736,9 @@
    1.72                :base-def rating-def
    1.73                :base-speed rating-speed
    1.74                :base-special rating-special
    1.75 +              :o0 pic-dimensions
    1.76 +              :o1 ptr-pic-obverse-1
    1.77 +              :o2 ptr-pic-obverse-2
    1.78                }))
    1.79           
    1.80           (partition entry-size
    1.81 @@ -702,7 +747,27 @@
    1.82                                  rom))))))))
    1.83    
    1.84    
    1.85 +(defn hxc-intro-pkmn
    1.86 +  "The hardcoded pokemon to display in Prof. Oak's introduction; the pokemon's
    1.87 +internal id is stored at ROM@5EDB."
    1.88 +  ([] (hxc-intro-pkmn
    1.89 +       com.aurellem.gb.gb-driver/original-rom))
    1.90 +  ([rom]
    1.91 +     (nth (hxc-pokenames rom) (nth rom 0x5EDB))))
    1.92 +
    1.93 +(defn sxc-intro-pkmn!
    1.94 +  "Set the hardcoded pokemon to display in Prof. Oak's introduction."
    1.95 +  [pokemon]
    1.96 +  (write-rom! 
    1.97 +   (rewrite-rom 0x5EDB
    1.98 +                [
    1.99 +                 (inc
   1.100 +                  ((zipmap
   1.101 +                    (hxc-pokenames)
   1.102 +                    (range))
   1.103 +                   pokemon))])))
   1.104    
   1.105 +
   1.106  (defn hxc-item-prices
   1.107    "The hardcoded list of item prices in memory. List begins at ROM@4495"
   1.108    ([] (hxc-item-prices com.aurellem.gb.gb-driver/original-rom))
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/clojure/com/aurellem/gb/mem_util.clj	Mon Apr 02 20:30:28 2012 -0500
     2.3 @@ -0,0 +1,192 @@
     2.4 +(ns com.aurellem.gb.mem-util
     2.5 +  (:use (com.aurellem.gb assembly characters gb-driver))
     2.6 +  (:import [com.aurellem.gb.gb_driver SaveState]))
     2.7 +
     2.8 +
     2.9 +
    2.10 +
    2.11 +  
    2.12 +(def hex-pc (comp hex PC))
    2.13 +
    2.14 +(defn nstep [state n]
    2.15 +  (if (zero? n) state
    2.16 +      (recur (step state) (dec n))))
    2.17 +
    2.18 +
    2.19 +(defn view-memory*
    2.20 +  "View a region of indexable memory in the given state."
    2.21 +  [state start length]
    2.22 +  ((comp vec map)
    2.23 +   #((comp  aget) (memory state) %)
    2.24 +   (range start (+ start length))))
    2.25 +
    2.26 +
    2.27 +(defn pc-trail
    2.28 +  "Track the PC for a number of ticks."
    2.29 +  [state ticks]
    2.30 +  (tick state)
    2.31 +  (set-state! state)
    2.32 +  (loop [pcs [(PC)] ]
    2.33 +    (if (> (count pcs) ticks) pcs
    2.34 +        (do
    2.35 +          (com.aurellem.gb.Gb/tick)
    2.36 +          (recur (conj pcs (PC)))))))
    2.37 +
    2.38 +
    2.39 +(defn get-memory [state n]
    2.40 +  (aget (memory state) n))
    2.41 +
    2.42 +(defn first-change
    2.43 +  "Watch the current memory location as it ticks,
    2.44 +return the first state that differs at location mem." 
    2.45 +  [state n]
    2.46 +  (tick state)
    2.47 +  (set-state! state)
    2.48 +  (let [init (aget (memory state) n)]
    2.49 +    (loop []
    2.50 +      (if (= (aget (memory) n) init)
    2.51 +        (do
    2.52 +          (com.aurellem.gb.Gb/tick)
    2.53 +          (recur))))
    2.54 +    (update-state)))
    2.55 +
    2.56 +
    2.57 +
    2.58 +
    2.59 +
    2.60 +
    2.61 +
    2.62 +(defn differences 
    2.63 +  "Return the differences between the two lists as triples [index
    2.64 +(list-1 index) (list-2 index)]."
    2.65 +[list-1 list-2]
    2.66 +  (remove
    2.67 +   (fn [[a b c]] (= b c))
    2.68 +   (map vector
    2.69 +        (range)
    2.70 +        list-1
    2.71 +        list-2)))
    2.72 +
    2.73 +(defn pc-diff
    2.74 +  "Return the differences between the program counter evolution
    2.75 +between the two states (measured for 10000 ticks)."
    2.76 +  [state-1 state-2]
    2.77 +  (differences (map hex (pc-trail state-1 10000))
    2.78 +               (map hex (pc-trail state-2 10000))))
    2.79 +
    2.80 +
    2.81 +(defn memory-diff [state-1 state-2]
    2.82 +  (remove
    2.83 +  (fn[[a b c]] (= b c))
    2.84 +  (map (comp vec (partial map hex) list)
    2.85 +       (range)
    2.86 +       (vec (memory state-1))
    2.87 +       (vec (memory state-2)))
    2.88 +  ))
    2.89 +
    2.90 +
    2.91 +(defn spell-array
    2.92 +  "Interpret the array as a string of printable Pokemon-text characters."
    2.93 +  [array start n]
    2.94 +  (character-codes->str
    2.95 +          (take n (drop start
    2.96 +                        (vec array)))))
    2.97 +
    2.98 +(defn spell-memory
    2.99 +  "Interpret the indexable memory of the state as a string of printable
   2.100 +Pokemon-text characters. If no state is given, uses current-state."
   2.101 +  ([state mem n]
   2.102 +     (spell-array (memory state) mem n))
   2.103 +  ([mem n] (spell-array @current-state mem n)))
   2.104 +
   2.105 +
   2.106 +(defn sublist
   2.107 +  "Unshifts the list until the sublist is at the start."
   2.108 +  [list sub]
   2.109 +  (cond
   2.110 +    (empty? sub) list
   2.111 +    (empty? list) nil
   2.112 +    (= (take (count sub) list) sub) list
   2.113 +    :else (recur (rest list) sub)))
   2.114 +
   2.115 +(defn find-sublist
   2.116 +  "Returns the position of the first occurence of sublist."
   2.117 +  [list sub]
   2.118 +  (loop [n 0 a list]
   2.119 +    (cond
   2.120 +      (empty? a) nil
   2.121 +      (= (take (count sub) a) sub) n
   2.122 +      :else (recur (inc n) (rest a)))))
   2.123 +
   2.124 +(defn find-sublists
   2.125 +  "Returns a vector of the occurences of sublists."
   2.126 +  [list sub]
   2.127 +  (let [m (find-sublist list sub)]
   2.128 +    (if (nil? m) '()
   2.129 +        (cons m
   2.130 +              (map (partial + (inc m))
   2.131 +                   (find-sublists
   2.132 +                    (drop (inc m) list)
   2.133 +                    sub))))))
   2.134 +
   2.135 +
   2.136 +
   2.137 +(defn search-memory
   2.138 +  "Search for the given codes in memory, returning short snippets of
   2.139 +text around the results."
   2.140 +  ([codes k]
   2.141 +     (search-memory com.aurellem.gb.gb-driver/original-rom codes k))
   2.142 +  ([array codes k]
   2.143 +     (map
   2.144 +      (fn [n]
   2.145 +        [(hex n)
   2.146 +         (take k (drop n array))])
   2.147 +      
   2.148 +      (find-sublists
   2.149 +       array
   2.150 +       codes))))
   2.151 +
   2.152 +(defn spelling-bee
   2.153 +  "Search for the given string in ROM, returning short snippets of
   2.154 +  text around the results."
   2.155 +  ([str k]
   2.156 +     (spelling-bee com.aurellem.gb.gb-driver/original-rom str k))
   2.157 +  ([rom str k]
   2.158 +     (map
   2.159 +      (fn [[address snip]]
   2.160 +        [address (character-codes->str snip)])
   2.161 +        (search-memory rom (str->character-codes str) k))))
   2.162 +     
   2.163 +
   2.164 +
   2.165 +
   2.166 +
   2.167 +
   2.168 +(defn rewrite-memory
   2.169 +  "Alter the vector of memory. Treats strings as lists of character
   2.170 +ops."
   2.171 +  ([mem start strs-or-ops]
   2.172 +     (let [x (first strs-or-ops)]
   2.173 +       (cond (empty? strs-or-ops) mem
   2.174 +             (string? x)
   2.175 +             
   2.176 +             (recur mem start
   2.177 +                    (concat
   2.178 +                     (str->character-codes x)
   2.179 +                     (rest strs-or-ops)))
   2.180 +        :else
   2.181 +        (recur
   2.182 +         (assoc mem start x)
   2.183 +         (inc start)
   2.184 +         (rest strs-or-ops))))))
   2.185 +
   2.186 +
   2.187 +(defn rewrite-rom
   2.188 +  "Alter the rom at the given location. Takes a list of
   2.189 +various strings/bytes as data."
   2.190 +  [start strs-or-bytes]
   2.191 +  ((partial rewrite-memory (vec (rom(root))))
   2.192 +   start strs-or-bytes))
   2.193 +
   2.194 +(defn restore-rom! [] (write-rom! original-rom))
   2.195 +
     3.1 --- a/clojure/com/aurellem/music/midi_util.clj	Mon Apr 02 20:30:02 2012 -0500
     3.2 +++ b/clojure/com/aurellem/music/midi_util.clj	Mon Apr 02 20:30:28 2012 -0500
     3.3 @@ -10,9 +10,10 @@
     3.4             (com.sun.media.sound FastShortMessage)
     3.5             (java.io File))
     3.6    
     3.7 - (:use (com.aurellem.gb saves util constants gb-driver vbm items assembly characters))
     3.8 + (:use (com.aurellem.gb saves util mem-util constants gb-driver vbm items assembly characters))
     3.9   (:use (com.aurellem.run title))
    3.10   (:use (com.aurellem.exp pokemon item-bridge))
    3.11 +;; (:use (com.aurellem.world practice))
    3.12   (:import [com.aurellem.gb.gb_driver SaveState]))
    3.13  
    3.14  
    3.15 @@ -29,12 +30,6 @@
    3.16  
    3.17  
    3.18  
    3.19 -(def midi-play-file
    3.20 -  "Plays the MIDI file at the given location. The MIDI file runs in
    3.21 -the current thread until it finishes or is cancelled."
    3.22 -  (comp midi-play-seq midi-load))
    3.23 -
    3.24 -
    3.25  (defn midi-play-seq
    3.26    "Plays the MIDI Sequence. The MIDI runs in
    3.27  the current thread until it finishes or is cancelled."
    3.28 @@ -56,6 +51,14 @@
    3.29              (finally (.close song))))))
    3.30  
    3.31  
    3.32 +(def midi-play-file
    3.33 +  "Plays the MIDI file at the given location. The MIDI file runs in
    3.34 +the current thread until it finishes or is cancelled."
    3.35 +  (comp midi-play-seq midi-load))
    3.36 +
    3.37 +
    3.38 +
    3.39 +
    3.40  (defn midi-test-1 []
    3.41    (-> (.
    3.42         (midi-load
    3.43 @@ -154,10 +157,18 @@
    3.44        ;;(.add (midi-short 360 [-1 47 0])) ;; system reset = -1
    3.45  
    3.46      sequence
    3.47 -    )))
    3.48 +    ))
    3.49  
    3.50  
    3.51 -  
    3.52 +
    3.53 +
    3.54 +(defn read-memory 
    3.55 +  ([mem start length]
    3.56 +     (take length
    3.57 +           (drop start
    3.58 +                 mem)))
    3.59 +  ([start length]
    3.60 +     (read-memory (rom(root)) start length)))
    3.61  
    3.62  ;;; ROM MUSIC MANIPULATION
    3.63  
    3.64 @@ -176,14 +187,26 @@
    3.65     :meet-prof 0x8291
    3.66     :meet-blue 0x829A
    3.67     :follow 0x82A3
    3.68 -   :safari 0x82AF
    3.69 -   :sfx-heal 0x82BA
    3.70 +   :evolution 0x82AF
    3.71 +   :sfx-heal 0x82B8
    3.72     :route-1 0x82C1 ;; route 1,2
    3.73     :route-2 0x82CD ;; route 24, 25
    3.74     :route-3 0x82D9 ;; route 3-10,16-22
    3.75     :route-4 0x82E5 ;; route 11-15
    3.76     :route-5 0x82F1 ;; indigo plateau
    3.77  
    3.78 +   ;;:1 0xc977 ;; fourteen "tracks" X
    3.79 +   :1 0x801cb  ;; slot machine music
    3.80 +   :2 0x801d4  
    3.81 +   :3 0x801dd 
    3.82 +
    3.83 +   :4 0x202be ;; uber slow battle songs?
    3.84 +   :5 0x202c7 ;; can't play with pallet or bike (wrong base)
    3.85 +   :6 0x202d9
    3.86 +   :7 0x202e2
    3.87 +   :8 0x202eb
    3.88 +   :9 0x202f4
    3.89 +   
    3.90     :title 0x7C249
    3.91     :credits 0x7C255
    3.92     :hall-of-fame 0x7C25E
    3.93 @@ -192,19 +215,16 @@
    3.94     :bike 0x7C276
    3.95     :surfing 0x7C282
    3.96     :casino 0x7C28B
    3.97 -   :intro-battle 0x7C294
    3.98 -   :power-plant 0x7C2A0 ;; power plant, unknown dungeon
    3.99 -   :viridian-forest 0x7C2AC ;;viridian forest, seafoam islands
   3.100 -   :victory-rd 0x7C2B8 ;;mt moon, rock tunnel, victory rd 
   3.101 -   :mansion 0x7C2C4
   3.102 -   :pkmn-tower 0x7C2D0
   3.103 -   :silph 0x7C2D9
   3.104 -   :trainer-bad 0x7C2E2
   3.105 -   :trainer-girl 0x7C2EB 
   3.106 -   :trainer-angry 0x7C2F4
   3.107 -   })
   3.108 -   
   3.109 -
   3.110 +   :intro 0x7C294
   3.111 +   :power-plant 0x7C29D ;; power plant, unknown dungeon
   3.112 +   :viridian-forest 0x7C2A9 ;;viridian forest, seafoam islands
   3.113 +   :victory-rd 0x7C2B5 ;;mt moon, rock tunnel, victory rd 
   3.114 +   :mansion 0x7C2C1
   3.115 +   :pkmn-tower 0x7C2CD
   3.116 +   :silph 0x7C2D6
   3.117 +   :trainer-bad 0x7C2DF
   3.118 +   :trainer-girl 0x7C2E8 
   3.119 +   :trainer-angry 0x7C2F1
   3.120     })
   3.121  
   3.122  
   3.123 @@ -244,31 +264,98 @@
   3.124    
   3.125  
   3.126  
   3.127 +(defn find-music []
   3.128 +  (let [extract-song
   3.129 +        (fn [mem]
   3.130 +          (if (and
   3.131 +               (> (count mem) 6)
   3.132 +               (zero? (rem (first mem) 16))
   3.133 +               (not(zero? (first mem)))
   3.134 +               (= (nth mem 3) 1)
   3.135 +               (= (nth mem 6) 2))
   3.136 +            (take 12 mem)))]
   3.137 +    (loop [mem (rom)
   3.138 +           results []
   3.139 +           ptr 0]
   3.140 +      (cond (empty? mem)
   3.141 +            results
   3.142  
   3.143 -(defn note?
   3.144 -  "Does the given byte correspond to a note?"
   3.145 -  [n]
   3.146 +            (nil? (extract-song mem))
   3.147 +            (recur (rest mem)
   3.148 +                   results
   3.149 +                   (inc ptr))
   3.150 +            :else
   3.151 +            (recur (rest mem)
   3.152 +                   (conj results
   3.153 +                         [(hex ptr) (extract-song mem)])
   3.154 +                   (inc ptr))))))
   3.155 +           
   3.156 +(defn music-header
   3.157 +  "Given a valid address to a music header, returns the music header."
   3.158 +  [address]
   3.159 +  (let [
   3.160 +        rom (rom)
   3.161 +        data   (drop address rom)
   3.162 +        ]
   3.163 +    (->
   3.164 +     (loop [n 1 k 3]
   3.165 +       (if (= n (nth data k))
   3.166 +         (recur (inc n) (+ k 3))
   3.167 +         k))
   3.168 +     (take data))))
   3.169 +
   3.170 +(defn pallet-song [song-name]
   3.171 +  (write-rom!
   3.172 +   (rewrite-memory
   3.173 +    (vec(rom))
   3.174 +    0x822e
   3.175 +    (music-header (songs song-name)))))
   3.176 +
   3.177 +(defn bike-song [song-name]
   3.178 +  (write-rom!
   3.179 +   (rewrite-memory
   3.180 +    (vec(rom))
   3.181 +    0x7c276
   3.182 +    (music-header (songs song-name)))))
   3.183 +
   3.184 +(defn bike-song* [address]
   3.185 +  (write-rom!
   3.186 +   (rewrite-memory
   3.187 +    (vec(rom))
   3.188 +    0x7c276
   3.189 +    (music-header address))))
   3.190 +
   3.191 +
   3.192 +(defn pallet-song* [address]
   3.193 +  (write-rom!
   3.194 +   (rewrite-memory
   3.195 +    (vec(rom))
   3.196 +    0x822e
   3.197 +    (music-header address))))
   3.198 +;; (defn note?
   3.199 +;;   "Does the given byte correspond to a note?"
   3.200 +;;   [n])
   3.201    
   3.202 -(defn parse-ops
   3.203 -  "Consumes the list of opcodes, returning a runnable MIDI Sequence object."
   3.204 -  [ops]
   3.205 -  (
   3.206 -   (fn [midi ops]
   3.207 -     (let [x (first ops)]
   3.208 -       (cond (empty? ops) midi
   3.209 -             (= x 0xDA)
   3.210 -               ;; set tempo (high-low (nth ops 1)(nth ops 2))
   3.211 -             (recur (identity midi) (drop 3 ops))
   3.212 +;; (comment defn parse-ops
   3.213 +;;   "Consumes the list of opcodes, returning a runnable MIDI Sequence object."
   3.214 +;;   [ops]
   3.215 +;;   (
   3.216 +;;    (fn [midi ops]
   3.217 +;;      (let [x (first ops)]
   3.218 +;;        (cond (empty? ops) midi
   3.219 +;;              (= x 0xDA)
   3.220 +;;                ;; set tempo (high-low (nth ops 1)(nth ops 2))
   3.221 +;;              (recur (identity midi) (drop 3 ops))
   3.222               
   3.223 -             (note? x)
   3.224 +;;              (note? x)
   3.225               
   3.226  
   3.227 -             )
   3.228 +;;              )
   3.229  
   3.230 -   (doto (Sequence. (float 30) 15) ;; 30 fps, 15 frames per beat
   3.231 -     (.createTrack))
   3.232 -   ops
   3.233 -   ))
   3.234 +;;    (doto (Sequence. (float 30) 15) ;; 30 fps, 15 frames per beat
   3.235 +;;      (.createTrack))
   3.236 +;;    ops
   3.237 +;;   ))))
   3.238  
   3.239  
   3.240  
     4.1 --- a/clojure/com/aurellem/world/practice.clj	Mon Apr 02 20:30:02 2012 -0500
     4.2 +++ b/clojure/com/aurellem/world/practice.clj	Mon Apr 02 20:30:28 2012 -0500
     4.3 @@ -1,5 +1,5 @@
     4.4  (ns com.aurellem.world.practice
     4.5 - (:use (com.aurellem.gb saves util constants gb-driver vbm items assembly characters))
     4.6 + (:use (com.aurellem.gb saves util mem-util constants gb-driver vbm items assembly characters))
     4.7   (:use (com.aurellem.exp pokemon))
     4.8   (:use (com.aurellem.exp item-bridge))
     4.9   (:import [com.aurellem.gb.gb_driver SaveState]))
    4.10 @@ -7,22 +7,6 @@
    4.11  
    4.12  ;;(def original-rom (rom(root)))
    4.13  
    4.14 -
    4.15 -(def hex-pc (comp hex PC))
    4.16 -
    4.17 -(defn nstep [state n]
    4.18 -  (if (zero? n) state
    4.19 -      (recur (step state) (dec n))))
    4.20 -
    4.21 -
    4.22 -(defn view-memory*
    4.23 -  "View a region of indexable memory in the given state."
    4.24 -  [state start length]
    4.25 -  ((comp vec map)
    4.26 -   #((comp  aget) (memory state) %)
    4.27 -   (range start (+ start length))))
    4.28 -
    4.29 -
    4.30  (defn state-surprise
    4.31    "This is one tick before the trainer goes [!]"
    4.32    []
    4.33 @@ -47,40 +31,6 @@
    4.34  
    4.35  
    4.36  
    4.37 -(defn pc-trail
    4.38 -  "Track the PC for a number of ticks."
    4.39 -  [state ticks]
    4.40 -  (tick state)
    4.41 -  (set-state! state)
    4.42 -  (loop [pcs [(PC)] ]
    4.43 -    (if (> (count pcs) ticks) pcs
    4.44 -        (do
    4.45 -          (com.aurellem.gb.Gb/tick)
    4.46 -          (recur (conj pcs (PC)))))))
    4.47 -
    4.48 -
    4.49 -
    4.50 -(defn differences [list-1 list-2]
    4.51 -  (remove
    4.52 -   (fn [[a b c]] (= b c))
    4.53 -   (map vector
    4.54 -        (range)
    4.55 -        list-1
    4.56 -        list-2)))
    4.57 -
    4.58 -(defn pc-diff [state-1 state-2]
    4.59 -  (differences (map hex (pc-trail state-1 10000))
    4.60 -               (map hex (pc-trail state-2 10000))))
    4.61 -
    4.62 -
    4.63 -(defn memory-diff [state-1 state-2]
    4.64 -  (remove
    4.65 -  (fn[[a b c]] (= b c))
    4.66 -  (map (comp vec (partial map hex) list)
    4.67 -       (range)
    4.68 -       (vec (memory state-1))
    4.69 -       (vec (memory state-2)))
    4.70 -   ))
    4.71  
    4.72  
    4.73  
    4.74 @@ -106,36 +56,7 @@
    4.75    
    4.76    
    4.77  
    4.78 -(defn get-memory [state n]
    4.79 -  (aget (memory state) n))
    4.80  
    4.81 -(defn first-change
    4.82 -  "Watch the current memory location as it ticks,
    4.83 -return the first state that differs at location mem." 
    4.84 -  [state n]
    4.85 -  (tick state)
    4.86 -  (set-state! state)
    4.87 -  (let [init (aget (memory state) n)]
    4.88 -    (loop []
    4.89 -      (if (= (aget (memory) n) init)
    4.90 -        (do
    4.91 -          (com.aurellem.gb.Gb/tick)
    4.92 -          (recur))))
    4.93 -    (update-state)))
    4.94 -
    4.95 -
    4.96 -
    4.97 -
    4.98 -(defn spell-array
    4.99 -  [array mem n]
   4.100 -  (character-codes->str
   4.101 -          (take n (drop mem
   4.102 -                        (vec array)))))
   4.103 -
   4.104 -(defn spell
   4.105 -  ([state mem n]
   4.106 -     (spell (memory state) mem n))
   4.107 -  ([mem n] (spell @current-state mem n)))
   4.108  
   4.109  
   4.110  
   4.111 @@ -151,63 +72,6 @@
   4.112  (def surprise-words
   4.113    [0x80 0xAB 0xAB 0x7F 0xB1 0xA8 0xA6 0xA7 0xB3 0xE7 0x7F 0x8B 0xA4 0xB3 0xE0 0xB2 0x7F 0xB1 0xAE 0xAB 0xAB 0x7F 0xB3 0xA7 0xA4 0x7F 0xA3 0xA8 0xA2 0xA4 0xE7])
   4.114  
   4.115 -(defn sublist
   4.116 -  "Unshifts the list until the sublist is at the start."
   4.117 -  [list sub]
   4.118 -  (cond
   4.119 -    (empty? sub) list
   4.120 -    (empty? list) nil
   4.121 -    (= (take (count sub) list) sub) list
   4.122 -    :else (recur (rest list) sub)))
   4.123 -
   4.124 -(defn find-sublist
   4.125 -  "Returns the position of the first occurence of sublist."
   4.126 -  [list sub]
   4.127 -  (loop [n 0 a list]
   4.128 -    (cond
   4.129 -      (empty? a) nil
   4.130 -      (= (take (count sub) a) sub) n
   4.131 -      :else (recur (inc n) (rest a)))))
   4.132 -
   4.133 -(defn find-sublists
   4.134 -  "Returns a vector of the occurences of sublists."
   4.135 -  [list sub]
   4.136 -  (let [m (find-sublist list sub)]
   4.137 -    (if (nil? m) '()
   4.138 -        (cons m
   4.139 -              (map (partial + (inc m))
   4.140 -                   (find-sublists
   4.141 -                    (drop (inc m) list)
   4.142 -                    sub))))))
   4.143 -
   4.144 -
   4.145 -
   4.146 -(defn search-rom
   4.147 -  "Search for the given codes in ROM, returning short snippets of
   4.148 -text around the results."
   4.149 -  ([codes k]
   4.150 -     (search-rom com.aurellem.gb.gb-driver/original-rom codes k))
   4.151 -  ([rom codes k]
   4.152 -     (map
   4.153 -      (fn [n]
   4.154 -        [(hex n)
   4.155 -         (take k (drop n rom))])
   4.156 -      
   4.157 -      (find-sublists
   4.158 -       rom
   4.159 -       codes))))
   4.160 -
   4.161 -(defn spelling-bee
   4.162 -  "Search for the given string in ROM, returning short snippets of
   4.163 -  text around the results."
   4.164 -  ([str k]
   4.165 -     (spelling-bee com.aurellem.gb.gb-driver/original-rom str k))
   4.166 -  ([rom str k]
   4.167 -     (map
   4.168 -      (fn [[address snip]]
   4.169 -        [address (character-codes->str snip)])
   4.170 -        (search-rom rom (str->character-codes str) k))))
   4.171 -     
   4.172  
   4.173  
   4.174  
   4.175 @@ -231,30 +95,9 @@
   4.176  
   4.177  
   4.178  
   4.179 -(defn rewrite-memory
   4.180 -  "Alters the vector of memory. Treats strings as lists of character
   4.181 -ops."
   4.182 -  ([mem start strs-or-ops]
   4.183 -     (let [x (first strs-or-ops)]
   4.184 -       (cond (empty? strs-or-ops) mem
   4.185 -             (string? x)
   4.186 -             
   4.187 -             (recur mem start
   4.188 -                    (concat
   4.189 -                     (str->character-codes x)
   4.190 -                     (rest strs-or-ops)))
   4.191 -        :else
   4.192 -        (recur
   4.193 -         (assoc mem start x)
   4.194 -         (inc start)
   4.195 -         (rest strs-or-ops))))))
   4.196  
   4.197 -(def rewrite-rom
   4.198 -  "Alters the ROM array using write-memory. Takes a list of
   4.199 -various strings/bytes as data."
   4.200 -  (partial rewrite-memory (vec (rom(root)))))
   4.201  
   4.202 -(defn restore-rom! [] (write-rom! original-rom))
   4.203 +
   4.204  
   4.205  
   4.206  
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/org/rom.org	Mon Apr 02 20:30:28 2012 -0500
     5.3 @@ -0,0 +1,48 @@
     5.4 +#+title: Notes on Deconstructing Pokemon Yellow
     5.5 +#+author: Dylan Holmes
     5.6 +#+email: rlm@mit.edu
     5.7 +#+description:
     5.8 +#+keywords:
     5.9 +#+SETUPFILE: ../../aurellem/org/setup.org
    5.10 +#+INCLUDE: ../../aurellem/org/level-0.org
    5.11 +#+BABEL: :exports both :noweb yes :cache no :mkdirp yes
    5.12 +
    5.13 +
    5.14 +# pokedollar: U+20B1
    5.15 +* Mapping the ROM
    5.16 +
    5.17 +| ROM address (hex) | Description     | Format          | Example         |
    5.18 +|-------------------+-----------------+-----------------+-----------------|
    5.19 +|                   | <15>            | <15>            | <15>            |
    5.20 +| 0233C-            | Shop inventories. |                 |                 |
    5.21 +| 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. |
    5.22 +| 045B7-0491E       | Names of the items in memory. | Variable-length item names (strings of character codes). Names are separated by a single 0x80 character. | MASTER BALL#ULTRA BALL#... |
    5.23 +| 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, level 0 end-of-list. |
    5.24 +| 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. |
    5.25 +| 06698-            | ? Background music. |                 |                 |
    5.26 +| 0822E-082F?       | Pointers to background music, part I. |                 |                 |
    5.27 +| 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 above). |
    5.28 +| 1232D-            | Which moves are taught by the TMs and HMs |                 |                 |
    5.29 +| 27D99-27DFF       | Names of the Pok\eacute{}mon types. | Variable-length type names (strings of character codes). Names are separated by a single 0x80 character. | NORMAL#FIGHTING#... |
    5.30 +| 27E77-            | Trainer title names. |                 | YOUNGSTER#BUG CATCHER#LASS#... |
    5.31 +| 34000-            | Evolution and learnset data. |                 |                 |
    5.32 +| 38000-            | The basic properties and effects of moves. | Fixed-length (6 byte) continguous descriptions (no separating character): move-index, move-effect, power, move-type, accuracy, pp. | The entry for Pound, the first attack in the list, is (1 0 40 0 255 35). See below for more explanation. |
    5.33 +| 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. |                 |                 |
    5.34 +| 39462-            | The Pok\eacute{}mon cry data. | Fixed-length (3 byte) descriptions of cries. |                 |
    5.35 +| 3B1E5-            | Pointers to evolution/learnset data. |                 |                 |
    5.36 +| 40687-            | Species data from the Pok\eacute{}dex: species name, height, weight, etc. | Fixed-length sequences of bytes. See below for specifics. |                 |
    5.37 +| 410B1-            | A conversion table between internal order and Pokedex order. |                 |                 |
    5.38 +| 71500-            | Names of places. |                 |                 |
    5.39 +| 7C249-7C2??       | Pointers to background music, pt II. |                 |                 |
    5.40 +| 98000-            | Dialogue        |                 |                 |
    5.41 +| B8000-            | The text of each Pokemon's Pok\eacute{}dex entry. |                 |                 |
    5.42 +| BC000-            | Move names.     |                 |                 |
    5.43 +| 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 0x80. The names are in \ldquo{}internal order\rdquo{}. | RHYDON####KANGASKHANNIDORAN♂#... |
    5.44 +|                   |                 |                 |                 |
    5.45 +|                   |                 |                 |                 |
    5.46 +
    5.47 +* Appendices
    5.48 +** Internal Pok\eacute{}mon IDs
    5.49 +** Type IDs
    5.50 +** Basic effects of moves
    5.51 +** Alphabet code