Mercurial > vba-clojure
view clojure/com/aurellem/gb/mem_util.clj @ 369:abcc522a3242
script: wrote memory pattern from within game!
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Tue, 10 Apr 2012 06:33:44 -0500 |
parents | 5639312a393f |
children |
line wrap: on
line source
1 (ns com.aurellem.gb.mem-util2 (:use (com.aurellem.gb assembly characters gb-driver))3 (:import [com.aurellem.gb.gb_driver SaveState]))9 (def hex-pc (comp hex PC))11 (defn nstep [state n]12 (if (zero? n) state13 (recur (step state) (dec n))))16 (defn view-memory*17 "View a region of indexable memory in the given state."18 [state start length]19 ((comp vec map)20 #((comp aget) (memory state) %)21 (range start (+ start length))))24 (defn pc-trail25 "Track the PC for a number of ticks."26 [state ticks]27 (tick state)28 (set-state! state)29 (loop [pcs [(PC)] ]30 (if (> (count pcs) ticks) pcs31 (do32 (com.aurellem.gb.Gb/tick)33 (recur (conj pcs (PC)))))))36 (defn get-memory [state n]37 (aget (memory state) n))39 (defn first-change40 "Watch the current memory location as it ticks,41 return the first state that differs at location mem."42 [state n]43 (tick state)44 (set-state! state)45 (let [init (aget (memory state) n)]46 (loop []47 (if (= (aget (memory) n) init)48 (do49 (com.aurellem.gb.Gb/tick)50 (recur))))51 (update-state)))59 (defn differences60 "Return the differences between the two lists as triples [index61 (list-1 index) (list-2 index)]."62 [list-1 list-2]63 (remove64 (fn [[a b c]] (= b c))65 (map vector66 (range)67 list-168 list-2)))70 (defn pc-diff71 "Return the differences between the program counter evolution72 between the two states (measured for 10000 ticks)."73 [state-1 state-2]74 (differences (map hex (pc-trail state-1 10000))75 (map hex (pc-trail state-2 10000))))78 (defn memory-diff [state-1 state-2]79 (remove80 (fn[[a b c]] (= b c))81 (map (comp vec (partial map hex) list)82 (range)83 (vec (memory state-1))84 (vec (memory state-2)))85 ))88 (defn spell-array89 "Interpret the array as a string of printable Pokemon-text characters."90 [array start n]91 (character-codes->str92 (take n (drop start93 (vec array)))))95 (defn spell-memory96 "Interpret the indexable memory of the state as a string of printable97 Pokemon-text characters. If no state is given, uses current-state."98 ([state mem n]99 (spell-array (memory state) mem n))100 ([mem n] (spell-array @current-state mem n)))103 (defn sublist104 "Unshifts the list until the sublist is at the start."105 [list sub]106 (cond107 (empty? sub) list108 (empty? list) nil109 (= (take (count sub) list) sub) list110 :else (recur (rest list) sub)))112 (defn find-sublist113 "Returns the position of the first occurence of sublist."114 [list sub]115 (loop [n 0 a list]116 (cond117 (empty? a) nil118 (= (take (count sub) a) sub) n119 :else (recur (inc n) (rest a)))))121 (defn find-sublists122 "Returns a vector of the occurences of sublists."123 [list sub]124 (let [m (find-sublist list sub)]125 (if (nil? m) '()126 (cons m127 (map (partial + (inc m))128 (find-sublists129 (drop (inc m) list)130 sub))))))134 (defn search-memory135 "Search for the given codes in memory, returning short snippets of136 text around the results."137 ([codes k]138 (search-memory com.aurellem.gb.gb-driver/original-rom codes k))139 ([array codes k]140 (map141 (fn [n]142 [(hex n)143 (take k (drop n array))])145 (find-sublists146 array147 codes))))149 (defn spelling-bee150 "Search for the given string in ROM, returning short snippets of151 text around the results."152 ([str k]153 (spelling-bee com.aurellem.gb.gb-driver/original-rom str k))154 ([rom str k]155 (map156 (fn [[address snip]]157 [address (character-codes->str snip)])158 (search-memory rom (str->character-codes str) k))))165 (defn rewrite-memory166 "Alter the vector of memory. Treats strings as lists of character167 ops."168 ([mem start strs-or-ops]169 (let [x (first strs-or-ops)]170 (cond (empty? strs-or-ops) mem171 (string? x)173 (recur mem start174 (concat175 (str->character-codes x)176 (rest strs-or-ops)))177 :else178 (recur179 (assoc mem start x)180 (inc start)181 (rest strs-or-ops))))))184 (defn rewrite-rom185 "Alter the rom at the given location. Takes a list of186 various strings/bytes as data."187 [start strs-or-bytes]188 ((partial rewrite-memory (vec (rom(root))))189 start strs-or-bytes))191 (defn restore-rom! [] (write-rom! original-rom))194 (defn endian-flip195 "Flip the bytes of the two-byte number."196 [n]197 (assert (< n 0xFFFF))198 (+ (* 0x100 (rem n 0x100))199 (int (/ n 0x100))))202 (defn offset->ptr203 "Convert an offset into a little-endian pointer."204 [n]205 (->206 n207 (rem 0x10000) ;; take last four bytes208 (rem 0x4000) ;; get relative offset from the start of the bank209 (+ 0x4000)210 endian-flip))212 (defn offset->bank213 "Get the bank of the offset."214 [n]215 (int (/ n 0x4000)))217 (defn ptr->offset218 "Convert a two-byte little-endian pointer into an offset."219 [bank ptr]220 (->221 ptr222 endian-flip223 (- 0x4000)224 (+ (* 0x4000 bank))225 ))227 (defn same-bank-offset228 "Convert a ptr into an absolute offset by using the bank of the reference."229 [reference ptr]230 (ptr->offset231 (offset->bank reference)232 ptr))