view clojure/com/aurellem/exp/item_bridge.clj @ 360:51aa6486c2ab

repairing route
author Robert McIntyre <rlm@mit.edu>
date Mon, 09 Apr 2012 08:51:47 -0500
parents 3b3cd62b6106
children 1f14c1b8af7e
line wrap: on
line source
1 (ns com.aurellem.exp.item-bridge
2 (:use (com.aurellem.gb saves util constants gb-driver vbm items assembly))
3 (:use (com.aurellem.run util title save-corruption))
4 ;;(:use (com.aurellem.exp pokemon))
5 (:import [com.aurellem.gb.gb_driver SaveState]))
7 (defn corrupt-item-state []
8 (second (destroy-item-end-of-list-marker)))
10 (defn corrupt-item-state []
11 (read-state "corrupt-items"))
13 (defn view-memory-range
14 ([start end]
15 (view-memory-range
16 @current-state start end))
17 ([state start end]
18 (dorun
19 (map (fn [loc val]
20 (println (format "%04X : %02X" loc val)))
21 (range start end) (subvec (vec (memory state)) start end)))
22 state))
24 (defn almost-broken
25 "if one more memory location is turned into 0x03, the game crashes."
26 [n]
27 (view-memory-range
28 (set-inv-mem (mid-game)
29 (concat [0xFF] (repeat 64 0x03)
30 (subvec (vec (memory (mid-game)))
31 (+ item-list-start 65)
32 (+ item-list-start 65 n))
33 (repeat (- 255 65 n) 0x03)))
34 item-list-start (+ item-list-start 255)))
36 (defn actually-broken
37 "if this memory location is turned into 0x03, the game crashes."
38 []
39 (set-memory (mid-game) 0xD35D 0x03))
42 ;; (almost-broken 20) more or less works
44 (defn capture-program-counter
45 "records the program counter for each tick"
46 [^SaveState state ticks]
47 (let [i (atom 0)]
48 (reduce (fn [[program-counters state] _]
49 (println (swap! i inc))
50 [(conj program-counters (PC state))
51 (tick state)])
52 [[] state]
53 (range ticks))))
56 (defn capture-program-counter
57 [^SaveState state ticks]
58 (tick state)
60 (loop [i 0
61 pcs []]
62 (if (= i ticks)
63 (filter (partial < 0x2000)(sort (set pcs)))
64 (do
65 (com.aurellem.gb.Gb/tick)
66 (recur (inc i)
67 (conj pcs (first (registers))))))))
69 (defn loop-program []
70 [0x00 ;0xD31D ;; disable-interrupts
72 0xC3 ;; loop forever
73 0x1D
74 0xD3])
76 (def map-function-address-start 0xD36D)
78 (defn test-loop []
79 (continue!
80 (-> (mid-game)
81 (set-memory-range 0xD31D (loop-program))
82 (set-memory-range
83 map-function-address-start
84 [0xD3 0x1D]))))
86 (defn-memo corrupt-moves []
87 (concat
88 (first
89 (->>
90 [[] (mid-game)]
91 (first-difference [:b] [:b :start] AF)
92 (first-difference [] [:d] AF)
93 (play-moves [[] [] [] [:d] [] [] [] [:d] [] [] [:a]])
94 (do-nothing 200)
95 (play-moves [[:a]])
96 (play-moves
97 ;; this section is copied from speedrun-2942
98 ;; and corrupts the save so that the end-of-list marker
99 ;; for the pokemon roster is destroyed, but the save is still
100 ;; playable.
101 [[] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] []
102 [] [] [] [] [] [] [] [] [] [] [:select] [:restart]])
103 (title)
104 (first-difference [] [:start] AF)
105 (first-difference [] [:a] AF)
106 (first-difference [:a] [:a :start] AF)))
107 [[]]))
109 (defn corrupt
110 "enter the codes to destroy the
111 pokemon list using save corruption"
112 ([^SaveState state]
113 (run-moves
114 state
115 (corrupt-moves)))
116 ([] (corrupt @current-state)))
118 (defn mid-game-corrupt []
119 (read-state "corrupt-mid-game"))
121 (defn gen-start-game-corrupt []
122 (->> (second (intro))
123 (first-difference [:b] [:a :b :start] AF)
124 (play-moves (corrupt-moves))))
126 (defn start-game-corrupt []
127 (read-state "corrupt-start-game"))
129 (defn test-memory-fun [n]
130 (capture-program-counter
131 (set-memory-range
132 (tick (mid-game))
133 0xD36D
134 [0 0])
135 n))
137 ;;(def good (test-memory-fun 17000))
139 ;;(def bad (test-memory-fun 18000))
143 (defn menu-open-state []
144 (read-state "menu-open"))
146 (defn prepare-memory
147 ([^SaveState state]
148 (-> state
149 (set-memory-range 0xD31D (loop-program))
150 (set-memory-range 0xD36D [0x1D 0xD3])))
151 ([] (prepare-memory @current-state)))
153 (def memory-function-address-start 0xD36D)
155 (defn read-map-function-address
156 ([^SaveState state]
157 (let [mem (memory state)]
158 [(aget mem memory-function-address-start)
159 (aget mem (inc memory-function-address-start))]))
160 ([] (read-map-function-address @current-state)))
162 (defn succesful-PC-capture
163 "This function demonstrates successful PC capturing by
164 setting 0xD36D to the value of the start location of
165 a specially prepared program.
167 You must run the function and then exit the open menu
168 to see the effect."
169 []
170 (dorun
171 (map #(println (Integer/toHexString %))
172 (capture-program-counter
173 (prepare-memory (menu-open-state))
174 9000000))))
176 (defn trampoline-assembly [^SaveState state]
177 (flatten
178 [0x3E ;;
179 0x3E ;; load lemonade into A
181 0xEA
182 0x1D
183 0xD3 ;; set first item to lemonade
185 0xC3 ;; return control to the game via absolute jump.
186 (read-map-function-address state)
187 ]))
189 (defn test-trampoline
190 "Demonstrates item-program execution via the map-function that
191 returns control to the main pokemon game after one loop."
192 [assembly-fn state]
193 (let [insertion-address 0xD33D
194 insertion-address-bits [0x3D 0xD3]]
195 (->
196 state
197 (set-memory-range
198 insertion-address
199 (assembly-fn state))
200 (set-memory-range
201 memory-function-address-start
202 insertion-address-bits))))
204 (def lemonade-trampoline
205 (partial test-trampoline
206 trampoline-assembly
207 (menu-open-state)))
209 (defn trampoline-assembly-burn-heal [^SaveState state]
210 (flatten
211 [0x3E ;;
212 0x3E ;; load lemonade into A
214 0xEA
215 0x1D
216 0xD3 ;; set first item to lemonade
218 0xC3 ;; return control to the game via absolute jump
219 0x0C ;; to Route 3's map-function
220 0x55
221 ]))
223 (def corrupted-items-width 512)
225 (defn items-record
226 ([^SaveState state]
227 (subvec (vec (memory state))
228 item-list-start
229 (+ item-list-start corrupted-items-width)))
230 ([] (items-record @current-state)))
232 (defn pc-items-record
233 ([^SaveState state]
234 (subvec (vec (memory state))
235 pc-item-list-start
236 (+ pc-item-list-width pc-item-list-start)))
237 ([] (pc-items-record @current-state)))
239 (defn print-listing-items
240 ([^SaveState state]
241 (print-listing state item-list-start
242 (+ item-list-start corrupted-items-width))
243 state)
244 ([] (print-listing-items @current-state)))
246 (defn print-listing-pc-items
247 ([^SaveState state]
248 (print-listing
249 state
250 pc-item-list-start
251 (+ pc-item-list-width pc-item-list-start))
252 state)
253 ([] (print-listing-pc-items @current-state)))