rlm@98
|
1 (ns com.aurellem.items
|
rlm@98
|
2 (:use (com.aurellem gb-driver vbm title))
|
rlm@99
|
3 ;; this is bullshit
|
rlm@98
|
4 (:import [com.aurellem.gb_driver SaveState]))
|
rlm@98
|
5
|
rlm@98
|
6 (defn game-name []
|
rlm@98
|
7 (map char (subvec (vec (memory)) 0x134 0x142)))
|
rlm@98
|
8
|
rlm@99
|
9 (def item-list-start 0xD31C)
|
rlm@98
|
10
|
rlm@99
|
11 (defn item-list [^SaveState state]
|
rlm@99
|
12 (subvec
|
rlm@99
|
13 (vec (memory state))
|
rlm@99
|
14 item-list-start
|
rlm@100
|
15 (+ item-list-start 150)))
|
rlm@98
|
16
|
rlm@98
|
17 (def item-hack-3 (read-state 77557))
|
rlm@98
|
18
|
rlm@99
|
19 (def item-code->item-name
|
rlm@99
|
20 (hash-map
|
rlm@103
|
21 0x01 :master-ball
|
rlm@103
|
22 0x02 :ultra-ball
|
rlm@103
|
23 0x03 :great-ball
|
rlm@103
|
24 0x04 :poke-ball
|
rlm@103
|
25 0x05 :town-map
|
rlm@103
|
26 0x06 :bicycle
|
rlm@103
|
27 0x08 :safari-ball
|
rlm@103
|
28 0x09 :pokedex
|
rlm@103
|
29 0x0A :moon-stone
|
rlm@103
|
30 0x0B :antidote
|
rlm@103
|
31 0x0C :burn-heal
|
rlm@103
|
32 0x0D :ice-heal
|
rlm@103
|
33 0x0E :awakening
|
rlm@103
|
34 0x0F :parlyz-heal
|
rlm@103
|
35 0x10 :full-restore
|
rlm@103
|
36 0x11 :max-potion
|
rlm@103
|
37 0x12 :hyper-potion
|
rlm@103
|
38 0x13 :super-potion
|
rlm@103
|
39 0x14 :potion
|
rlm@103
|
40 0x15 :boulderbadge
|
rlm@103
|
41 0x16 :cascadebadge
|
rlm@103
|
42 0x17 :thunderbadge
|
rlm@103
|
43 0x18 :rainbowbadge
|
rlm@103
|
44 0x19 :soulbadge
|
rlm@103
|
45 0x1A :marshbadge
|
rlm@103
|
46 0x1B :volcanobadge
|
rlm@103
|
47 0x1C :earthbadge
|
rlm@103
|
48 0x1D :escape-rope
|
rlm@103
|
49 0x1E :repel
|
rlm@103
|
50 0x1F :old-amber
|
rlm@103
|
51 0x20 :fire-stone
|
rlm@103
|
52 0x21 :thunderstone
|
rlm@103
|
53 0x22 :water-stone
|
rlm@103
|
54 0x23 :hp-up
|
rlm@103
|
55 0x24 :protein
|
rlm@103
|
56 0x25 :iron
|
rlm@103
|
57 0x26 :carbos
|
rlm@103
|
58 0x27 :calcium
|
rlm@103
|
59 0x28 :rare-candy
|
rlm@103
|
60 0x29 :dome-fossil
|
rlm@103
|
61 0x2A :helix-fossil
|
rlm@103
|
62 0x2B :secret-key
|
rlm@103
|
63 0x2D :bike-voucher
|
rlm@103
|
64 0x2E :x-accuracy
|
rlm@103
|
65 0x2F :leaf-stone
|
rlm@103
|
66 0x30 :card-key
|
rlm@103
|
67 0x31 :nugget
|
rlm@103
|
68 0x32 :pp-up
|
rlm@103
|
69 0x33 :poke-doll
|
rlm@103
|
70 0x34 :full-heal
|
rlm@103
|
71 0x35 :revive
|
rlm@103
|
72 0x36 :max-revive
|
rlm@103
|
73 0x37 :guard-spec
|
rlm@103
|
74 0x38 :super-repel
|
rlm@103
|
75 0x39 :max-repel
|
rlm@103
|
76 0x3A :dire-hit
|
rlm@103
|
77 0x3B :coin
|
rlm@103
|
78 0x3C :fresh-water
|
rlm@103
|
79 0x3D :soda-pop
|
rlm@103
|
80 0x3E :lemonade
|
rlm@103
|
81 0x3F :s.s.ticket
|
rlm@103
|
82 0x40 :gold-teeth
|
rlm@103
|
83 0x41 :x-attach
|
rlm@103
|
84 0x42 :x-defend
|
rlm@103
|
85 0x43 :x-speed
|
rlm@103
|
86 0x44 :x-special
|
rlm@103
|
87 0x45 :coin-case
|
rlm@103
|
88 0x46 :oaks-parcel
|
rlm@103
|
89 0x47 :itemfinder
|
rlm@103
|
90 0x48 :silph-scope
|
rlm@103
|
91 0x49 :poke-flute
|
rlm@103
|
92 0x4A :lift-key
|
rlm@103
|
93 0x4B :exp.all
|
rlm@103
|
94 0x4C :old-rod
|
rlm@103
|
95 0x4D :good-rod
|
rlm@103
|
96 0x4E :super-rod
|
rlm@103
|
97 0x4F :pp-up
|
rlm@103
|
98 0x50 :ether
|
rlm@103
|
99 0x51 :max-ether
|
rlm@103
|
100 0x52 :elixer
|
rlm@103
|
101 0x53 :max-elixer
|
rlm@103
|
102 0xC4 :HM01 ;; cut
|
rlm@103
|
103 0xC5 :HM02 ;; fly
|
rlm@103
|
104 0xC6 :HM03 ;; surf
|
rlm@103
|
105 0xC7 :HM04 ;; strength
|
rlm@103
|
106 0xC8 :HM05 ;; flash
|
rlm@103
|
107 0xC9 :TM01 ;; mega punch
|
rlm@103
|
108 0xCA :TM02 ;; razor wind
|
rlm@103
|
109 0xCB :TM03 ;; swords dance
|
rlm@103
|
110 0xCC :TM04 ;; whirlwind
|
rlm@103
|
111 0xCD :TM05 ;; mega kick
|
rlm@103
|
112 0xCE :TM06 ;; toxic
|
rlm@103
|
113 0xCF :TM07 ;; horn drill
|
rlm@103
|
114 0xD0 :TM08 ;; body slam
|
rlm@103
|
115 0xD1 :TM09 ;; take down
|
rlm@103
|
116 0xD2 :TM10 ;; double-edge
|
rlm@103
|
117 0xD3 :TM11 ;; bubblebeam
|
rlm@103
|
118 0xD4 :TM12 ;; water gun
|
rlm@103
|
119 0xD5 :TM13 ;; ice beam
|
rlm@103
|
120 0xD6 :TM14 ;; blizzard
|
rlm@103
|
121 0xD7 :TM15 ;; hyper beam
|
rlm@103
|
122 0xD8 :TM16 ;; pay day
|
rlm@103
|
123 0xD9 :TM17 ;; submission
|
rlm@103
|
124 0xDA :TM18 ;; counter
|
rlm@103
|
125 0xDB :TM19 ;; seismic toss
|
rlm@103
|
126 0xDC :TM20 ;; rage
|
rlm@103
|
127 0xDD :TM21 ;; mega drain
|
rlm@103
|
128 0xDE :TM22 ;; solarbeam
|
rlm@103
|
129 0xDF :TM23 ;; dragon rage
|
rlm@103
|
130 0xE0 :TM24 ;; thunderbolt
|
rlm@103
|
131 0xE1 :TM25 ;; thunder
|
rlm@103
|
132 0xE2 :TM26 ;; earthquake
|
rlm@103
|
133 0xE3 :TM27 ;; fissure
|
rlm@103
|
134 0xE4 :TM28 ;; dig
|
rlm@103
|
135 0xE5 :TM29 ;; psychic
|
rlm@103
|
136 0xE6 :TM30 ;; teleport
|
rlm@103
|
137 0xE7 :TM31 ;; mimic
|
rlm@103
|
138 0xE8 :TM32 ;; double team
|
rlm@103
|
139 0xE9 :TM33 ;; reflect
|
rlm@103
|
140 0xEA :TM34 ;; bide
|
rlm@103
|
141 0xEB :TM35 ;; metronome
|
rlm@103
|
142 0xEC :TM36 ;; self destruct
|
rlm@103
|
143 0xED :TM37 ;; eggbomb
|
rlm@103
|
144 0xEE :TM38 ;; fire blast
|
rlm@103
|
145 0xEF :TM39 ;; swift
|
rlm@103
|
146 0xF0 :TM40 ;; skull bash
|
rlm@103
|
147 0xF1 :TM41 ;; softboiled
|
rlm@103
|
148 0xF2 :TM42 ;; dream eater
|
rlm@103
|
149 0xF3 :TM43 ;; sky attack
|
rlm@103
|
150 0xF4 :TM44 ;; rest
|
rlm@103
|
151 0xF5 :TM45 ;; thunder wave
|
rlm@103
|
152 0xF6 :TM46 ;; psywave
|
rlm@103
|
153 0xF7 :TM47 ;; explosion
|
rlm@103
|
154 0xF8 :TM48 ;; rock slide
|
rlm@103
|
155 0xF9 :TM49 ;; tri attack
|
rlm@103
|
156 0xFA :TM50 ;; substitute
|
rlm@103
|
157 0xFB :TM51 ;; "cut"
|
rlm@103
|
158 0xFC :TM52 ;; "fly"
|
rlm@103
|
159 0xFD :TM53 ;; "surf"
|
rlm@103
|
160 0xFE :TM54 ;; "strength"
|
rlm@103
|
161 0xFF :end-of-list-sentinel
|
rlm@103
|
162 ))
|
rlm@98
|
163
|
rlm@99
|
164 (def item-name->item-code
|
rlm@99
|
165 (zipmap (vals item-code->item-name)
|
rlm@99
|
166 (keys item-code->item-name)))
|
rlm@98
|
167
|
rlm@99
|
168 (defn inventory [^SaveState state]
|
rlm@99
|
169 (let [items (item-list state)]
|
rlm@99
|
170 (map
|
rlm@99
|
171 (fn [[item-code quantity]]
|
rlm@103
|
172 [(item-code->item-name
|
rlm@103
|
173 item-code
|
rlm@103
|
174 (str ":0x" (.toUpperCase (Integer/toHexString item-code))))
|
rlm@99
|
175 quantity])
|
rlm@99
|
176 (partition
|
rlm@99
|
177 2
|
rlm@99
|
178 (next (take-while (partial not= 255) items))))))
|
rlm@98
|
179
|
rlm@102
|
180 (defn print-inventory
|
rlm@102
|
181 ([] (print-inventory @current-state))
|
rlm@102
|
182 ([^SaveState state]
|
rlm@102
|
183 (println
|
rlm@102
|
184 (let [inv (inventory state)]
|
rlm@102
|
185 (reduce
|
rlm@102
|
186 str
|
rlm@102
|
187 (concat
|
rlm@102
|
188 ["+-------------------+----------+\n"
|
rlm@102
|
189 "|##| Item | Quantity |\n"
|
rlm@102
|
190 "+--+----------------+----------+\n"]
|
rlm@98
|
191
|
rlm@102
|
192 (map
|
rlm@102
|
193 (fn [index [item-name quantity]]
|
rlm@102
|
194 (str
|
rlm@102
|
195 (format "|%-2d| %-14s | %3d |\n" index
|
rlm@102
|
196 (apply str (rest (str item-name)))
|
rlm@102
|
197 quantity)))
|
rlm@102
|
198 (range 0 (count inv)) inv)
|
rlm@102
|
199 ["+--+----------------+----------+\n"]))))))
|
rlm@98
|
200
|
rlm@99
|
201 (defn inventory-codes [inventory]
|
rlm@99
|
202 (flatten
|
rlm@99
|
203 (concat [(count inventory)]
|
rlm@99
|
204 (map (fn [[item-name quantity]]
|
rlm@99
|
205 [(item-name->item-code item-name)
|
rlm@99
|
206 quantity]) inventory)
|
rlm@99
|
207 [(item-name->item-code :end-of-list-sentinel)])))
|
rlm@103
|
208
|
rlm@103
|
209 (defn set-inv-mem [^SaveState state inv-codes]
|
rlm@103
|
210 (set-state! state)
|
rlm@103
|
211 (let [mem (memory state)]
|
rlm@103
|
212 (dorun (map (fn [index val]
|
rlm@103
|
213 (aset mem index val))
|
rlm@103
|
214 (range item-list-start
|
rlm@103
|
215 (+ item-list-start (count inv-codes))) inv-codes))
|
rlm@103
|
216 (write-memory! mem)))
|
rlm@103
|
217
|
rlm@98
|
218
|
rlm@99
|
219 (defn set-inventory [^SaveState state new-inventory]
|
rlm@99
|
220 (set-state! state)
|
rlm@99
|
221 (let [mem (memory state)
|
rlm@99
|
222 inv (inventory-codes new-inventory)]
|
rlm@98
|
223
|
rlm@99
|
224 (dorun (map (fn [index val]
|
rlm@99
|
225 (aset mem index val))
|
rlm@99
|
226 (range item-list-start
|
rlm@99
|
227 (+ item-list-start (count inv))) inv))
|
rlm@99
|
228 (write-memory! mem)
|
rlm@99
|
229 (update-state)))
|
rlm@102
|
230
|
rlm@103
|
231 (defn give
|
rlm@103
|
232 ([^SaveState state items]
|
rlm@103
|
233 (set-inventory state
|
rlm@103
|
234 (concat items (inventory state))))
|
rlm@103
|
235 ([items]
|
rlm@103
|
236 (give @current-state items)))
|
rlm@103
|
237
|
rlm@103
|
238
|
rlm@102
|
239 (def gliched-tms
|
rlm@102
|
240 [[:TM51 1]
|
rlm@102
|
241 [:TM52 1]
|
rlm@102
|
242 [:TM53 1]
|
rlm@102
|
243 [:TM54 1]])
|
rlm@102
|
244
|
rlm@102
|
245 (def good-items
|
rlm@102
|
246 [[:bicycle 1]
|
rlm@102
|
247 [:ultra-ball 15]
|
rlm@102
|
248 [:pp-up 1]
|
rlm@102
|
249 [:master-ball 5]
|
rlm@102
|
250 [:rare-candy 99]
|
rlm@102
|
251 [:full-restore 25]
|
rlm@102
|
252 [:max-revive 8]
|
rlm@102
|
253 [:max-repel 40]
|
rlm@102
|
254 [:TM25 1]
|
rlm@102
|
255 [:TM11 1]
|
rlm@102
|
256 [:TM15 1]
|
rlm@102
|
257 ])
|
rlm@98
|
258
|
rlm@102
|
259 (def some-badges
|
rlm@102
|
260 [[:cascadebadge 1]
|
rlm@102
|
261 [:thunderbadge 1]
|
rlm@102
|
262 [:rainbowbadge 1]
|
rlm@102
|
263 [:soulbadge 1]
|
rlm@102
|
264 ])
|
rlm@102
|
265
|
rlm@102
|
266 (defn run-item-program
|
rlm@102
|
267 "This is my first assembly/item program!
|
rlm@102
|
268 it just increments BC by one.
|
rlm@102
|
269
|
rlm@103
|
270 The code places a 3 'great balls' at the beginning of the
|
rlm@102
|
271 inventory, then directly sets the program counter to start
|
rlm@103
|
272 executing at the position of the 'great balls' in memory.
|
rlm@102
|
273
|
rlm@102
|
274 Since a 'great ball' is represented in memory as 0x03, which
|
rlm@102
|
275 corresponts to the opcode which increments BC by one, that is
|
rlm@103
|
276 what happens. Then the program counter to the 0x03 quantity entry
|
rlm@103
|
277 and BC is incremented again.
|
rlm@102
|
278
|
rlm@102
|
279 Obviously, the game crashes more or less immediately after the
|
rlm@103
|
280 program counter advances past the 'great balls' into the next items
|
rlm@103
|
281 in the inventory, thus I call shutdown! before anything bad happens."
|
rlm@102
|
282 []
|
rlm@103
|
283 (set-inventory (read-state 578544) [[:great-ball 3]])
|
rlm@102
|
284 (print-inventory)
|
rlm@102
|
285 (println "3 ticks") (tick) (tick) (tick)
|
rlm@102
|
286 (println "PC before:" (PC))
|
rlm@102
|
287 (println "BC before:" (BC))
|
rlm@102
|
288 (PC! (inc item-list-start))
|
rlm@102
|
289 (println "PC after setting:" (PC))
|
rlm@102
|
290 (println "data at PC:" (aget (memory) (PC)))
|
rlm@102
|
291 (println "one tick")
|
rlm@102
|
292 (tick)
|
rlm@102
|
293 (println "PC after one tick:" (PC))
|
rlm@103
|
294 (println "BC after one tick:" (BC))
|
rlm@103
|
295 (tick)
|
rlm@103
|
296 (println "PC after two ticks:" (PC))
|
rlm@103
|
297 (println "BC after two ticks:" (BC))
|
rlm@103
|
298
|
rlm@103
|
299 (shutdown!))
|
rlm@103
|
300
|
rlm@103
|
301
|
rlm@103
|
302 (defn test-opcodes-1
|
rlm@103
|
303 []
|
rlm@103
|
304 (set-inv-mem (read-state 578544)
|
rlm@103
|
305 [20 0x02 0x00 0x00 0x02 0x00 0x00
|
rlm@103
|
306 0x00 0x0 0xFF])
|
rlm@103
|
307 (print-inventory)
|
rlm@103
|
308 (println "3 ticks") (tick) (tick) (tick)
|
rlm@103
|
309 (println "PC before:" (PC))
|
rlm@103
|
310 (println "BC before:" (BC))
|
rlm@103
|
311 (println "AF:" (AF))
|
rlm@103
|
312 (PC! (inc item-list-start))
|
rlm@103
|
313 (BC! (+ 1 item-list-start))
|
rlm@103
|
314 (println "PC after setting:" (PC))
|
rlm@103
|
315 (println "data at PC:" (aget (memory) (PC)))
|
rlm@103
|
316 (println "data at " (BC) "(BC):" (aget (memory) (BC)))
|
rlm@103
|
317
|
rlm@103
|
318 (println "one tick")
|
rlm@103
|
319 (tick)
|
rlm@103
|
320 (println "PC after one tick:" (PC))
|
rlm@103
|
321 (println "BC after one tick:" (BC))
|
rlm@103
|
322 (println "data at PC:" (aget (memory) (PC)))
|
rlm@103
|
323 (println "data at " (BC) "(BC):" (aget (memory) (BC)))
|
rlm@103
|
324 (tick)
|
rlm@103
|
325 (AF! 0xFFFF)
|
rlm@103
|
326 (println "PC after two ticks:" (PC))
|
rlm@103
|
327 (println "BC after two ticks:" (BC))
|
rlm@103
|
328 (println "data at PC:" (aget (memory) (PC)))
|
rlm@103
|
329 (println "data at " (BC) "(BC):" (aget (memory) (BC)))
|
rlm@103
|
330 (tick)
|
rlm@103
|
331 (println "PC after three ticks:" (PC))
|
rlm@103
|
332 (println "BC after three ticks:" (BC))
|
rlm@103
|
333 (println "data at PC:" (aget (memory) (PC)))
|
rlm@103
|
334 (println "data at " (BC) "(BC):" (aget (memory) (BC)))
|
rlm@103
|
335 (tick)
|
rlm@103
|
336 (println "PC after four ticks:" (PC))
|
rlm@103
|
337 (println "BC after four ticks:" (BC))
|
rlm@103
|
338 (println "data at PC:" (aget (memory) (PC)))
|
rlm@103
|
339 (println "data at " (BC) "(BC):" (aget (memory) (BC)))
|
rlm@103
|
340 (tick)
|
rlm@103
|
341 (println "PC after five ticks:" (PC))
|
rlm@103
|
342 (println "BC after five ticks:" (BC))
|
rlm@103
|
343 (println "data at PC:" (aget (memory) (PC)))
|
rlm@103
|
344 (println "data at " (BC) "(BC):" (aget (memory) (BC)))
|
rlm@103
|
345 (print-inventory)
|
rlm@103
|
346 (shutdown!))
|
rlm@103
|
347
|
rlm@103
|
348
|
rlm@103
|
349
|
rlm@103
|
350 (defn test-opcodes-2
|
rlm@103
|
351 []
|
rlm@103
|
352 (set-inv-mem (read-state 578544)
|
rlm@103
|
353 [20 0x08 0x1D 0xD3 0x00 0x00 0x00
|
rlm@103
|
354 0x00 0x0 0xFF])
|
rlm@103
|
355 (print-inventory)
|
rlm@103
|
356 (println "3 ticks") (tick) (tick) (tick)
|
rlm@103
|
357 (println "PC before:" (PC))
|
rlm@103
|
358 (println "SP:" (SP))
|
rlm@103
|
359 (PC! (inc item-list-start))
|
rlm@103
|
360 (println "PC after setting:" (PC))
|
rlm@103
|
361 (println "SP:" (Integer/toBinaryString (SP)))
|
rlm@103
|
362 (println "data at PC:" (aget (memory) (PC)))
|
rlm@103
|
363 (println "data at 0xD31D:" (Integer/toBinaryString (aget (memory) 0xD31D)))
|
rlm@103
|
364 (println "data at 0xD31E:" (Integer/toBinaryString (aget (memory) 0xD31E)))
|
rlm@103
|
365 (println "one tick")
|
rlm@103
|
366 (tick)
|
rlm@103
|
367 (println "PC after one tick:" (PC))
|
rlm@103
|
368 (println "data at PC:" (aget (memory) (PC)))
|
rlm@103
|
369 (println "data at 0xD31D:" (Integer/toBinaryString (aget (memory) 0xD31D)))
|
rlm@103
|
370 (println "data at 0xD31E:" (Integer/toBinaryString (aget (memory) 0xD31E)))
|
rlm@103
|
371 (tick) (tick) (tick)
|
rlm@103
|
372 (println "PC aftter four tick:" (PC))
|
rlm@103
|
373 (println "data at PC:" (aget (memory) (PC)))
|
rlm@103
|
374 (println "data at 0xD31D:" (aget (memory) 0xD31D))
|
rlm@103
|
375
|
rlm@103
|
376 (print-inventory)
|
rlm@103
|
377 (shutdown!))
|