rlm@345: (ns com.aurellem.run.bootstrap-1 rlm@345: (:use (com.aurellem.gb saves gb-driver util rlm@345: items vbm characters money)) rlm@345: (:use (com.aurellem.run util title save-corruption bootstrap-0)) rlm@345: (:use (com.aurellem.exp item-bridge)) rlm@345: (:import [com.aurellem.gb.gb_driver SaveState])) rlm@345: rlm@345: (defn pc-item-writer-program rlm@345: [] rlm@345: (let [limit 201 rlm@345: [target-high target-low] (disect-bytes-2 0xD162)] rlm@345: (flatten rlm@345: [[0x00 ;; (item-hack) set increment stack pointer no-op rlm@345: 0x1E ;; load limit into E rlm@345: limit rlm@345: 0x3F ;; (item-hack) set carry flag no-op rlm@345: rlm@345: ;; load 2 into C. rlm@345: 0x0E ;; C == 1 means input-first nybble rlm@345: 0x04 ;; C == 0 means input-second nybble rlm@345: rlm@345: 0x21 ;; load target into HL rlm@345: target-low rlm@345: target-high rlm@345: 0x37 ;; (item-hack) set carry flag no-op rlm@345: rlm@345: 0x00 ;; (item-hack) no-op rlm@345: 0x37 ;; (item-hack) set carry flag no-op rlm@345: rlm@345: 0x00 ;; (item-hack) no-op rlm@345: 0xF3 ;; disable interrupts rlm@345: ;; Input Section rlm@345: rlm@345: 0x3E ;; load 0x20 into A, to measure buttons rlm@345: 0x10 rlm@345: rlm@345: 0x00 ;; (item-hack) no-op rlm@345: 0xE0 ;; load A into [FF00] rlm@345: 0x00 rlm@345: rlm@345: 0xF0 ;; load 0xFF00 into A to get rlm@345: 0x00 ;; button presses rlm@345: rlm@345: 0xE6 rlm@345: 0x0F ;; select bottom four bits of A rlm@345: 0x37 ;; (item-hack) set carry flag no-op rlm@345: rlm@345: 0x00 ;; (item-hack) no-op rlm@345: 0xB8 ;; see if input is different (CP A B) rlm@345: rlm@345: 0x00 ;; (item-hack) (INC SP) rlm@345: 0x28 ;; repeat above steps if input is not different rlm@345: ;; (jump relative backwards if B != A) rlm@345: 0xED ;; (literal -19) (item-hack) -19 == egg bomb (TM37) rlm@345: rlm@345: 0x47 ;; load A into B rlm@345: rlm@345: 0x0D ;; dec C rlm@345: 0x37 ;; (item-hack) set-carry flag rlm@345: ;; branch based on C: rlm@345: 0x20 ;; JR NZ rlm@345: 23 ;; skip "input second nybble" and "jump to target" below rlm@345: rlm@345: ;; input second nybble rlm@345: rlm@345: 0x0C ;; inc C rlm@345: 0x0C ;; inc C rlm@345: rlm@345: 0x00 ;; (item-hack) no-op rlm@345: 0xE6 ;; select bottom bits rlm@345: 0x0F rlm@345: 0x37 ;; (item-hack) set-carry flag no-op rlm@345: rlm@345: 0x00 ;; (item-hack) no-op rlm@345: 0xB2 ;; (OR A D) -> A rlm@345: rlm@345: 0x22 ;; (do (A -> (HL)) (INC HL)) rlm@345: rlm@345: 0x1D ;; (DEC E) rlm@345: rlm@345: 0x00 ;; (item-hack) rlm@345: 0x20 ;; jump back to input section if not done rlm@345: 0xDA ;; literal -36 == TM 18 (counter) rlm@345: 0x01 ;; (item-hack) set BC to literal (no-op) rlm@345: rlm@345: ;; jump to target rlm@345: 0x00 ;; (item-hack) these two bytes can be anything. rlm@345: 0x01 rlm@345: rlm@345: 0x00 ;; (item-hack) no-op rlm@345: 0xBF ;; (CP A A) ensures Z rlm@345: rlm@345: 0xCA ;; (item-hack) jump if Z rlm@345: target-low rlm@345: target-high rlm@345: 0x01 ;; (item-hack) will never be reached. rlm@345: rlm@345: ;; input first nybble rlm@345: 0x00 rlm@345: 0xCB rlm@345: 0x37 ;; swap nybbles on A rlm@345: rlm@345: 0x57 ;; A -> D rlm@345: rlm@345: 0x37 ;; (item-hack) set carry flag no-op rlm@345: 0x18 ;; relative jump backwards rlm@345: 0xCD ;; literal -51 == TM05; go back to input section rlm@345: 0x01 ;; (item-hack) will never reach this instruction rlm@345: rlm@345: ] rlm@345: (repeat 8 [0xFF 0x01]) rlm@345: rlm@345: [;; jump to actual program rlm@345: 0x00 rlm@345: 0x37 ;; (item-hack) set carry flag no-op rlm@345: rlm@345: 0x2E ;; 0x3A -> L rlm@345: 0x3A rlm@345: rlm@345: rlm@345: 0x00 ;; (item-hack) no-op rlm@345: 0x26 ;; 0xD5 -> L rlm@345: 0xD5 rlm@345: 0x01 ;; (item-hack) set-carry BC rlm@345: rlm@345: 0x00 ;; (item-hack) these can be anything rlm@345: 0x01 rlm@345: rlm@345: 0x00 rlm@345: 0xE9 ;; jump to (HL) rlm@345: ]]))) rlm@345: rlm@345: (defn view-desired-item-layout [] rlm@345: (clojure.pprint/pprint rlm@345: (raw-inventory->inventory (pc-item-writer-program)))) rlm@345: rlm@345: (defn pc-item-writer-state [] rlm@345: (-> (read-state "bootstrap-init") rlm@345: (set-memory pc-item-list-start 50) rlm@345: (set-memory-range rlm@345: map-function-address-start rlm@345: [0x8B 0xD5]) rlm@345: (set-memory-range rlm@345: (inc pc-item-list-start) rlm@345: (pc-item-writer-program)))) rlm@345: rlm@345: (defn test-pc-item-writer [] rlm@345: (let [orig (read-state "pc-item-writer")] rlm@345: (-> orig rlm@345: (print-listing 0xD162 (+ 0xD162 20)) rlm@345: (run-moves (reduce concat rlm@345: (repeat 10 [[:a :b :start :select] []]))) rlm@345: ((fn [_] (println "===========") _)) rlm@345: (print-listing 0xD162 (+ 0xD162 20))))) rlm@345: rlm@345: (defn close-all-menus [[moves state :as script]] rlm@345: (loop [s script] rlm@345: (let [depth (current-depth (second (do-nothing 50 s)))] rlm@345: (println "depth" depth) rlm@345: (if (= depth 1) rlm@345: s rlm@345: (recur (close-menu s)))))) rlm@345: rlm@345: (defn-memo name-rival rlm@345: ([] (name-rival (to-rival-name))) rlm@345: ([script] rlm@345: (->> script rlm@345: (first-difference [] [:a] AF) rlm@345: (first-difference [] [:r] DE) rlm@345: (play-moves rlm@345: [[] rlm@345: [] [] [:r] [] [:d] [:a] ;; L rlm@345: [:r] [] [:r] [] [:r] [] [:r] [] rlm@345: [:r] [] [:d] [] [:d] [:a] ;; [PK] rlm@345: [:d] [] [:r] [:a] rlm@345: ])))) rlm@345: rlm@345: (defn-memo to-room-pc rlm@345: ([] (to-room-pc (name-rival))) rlm@345: ([script] rlm@345: (->> script rlm@345: finish-title rlm@345: (walk [← ← ↑ ← ↑ ↑ ↑])))) rlm@345: rlm@345: (defn-memo bootstrap-corrupt-save rlm@345: ([] (bootstrap-corrupt-save (to-room-pc))) rlm@345: ([script] rlm@345: (->> script rlm@345: (do-save-corruption 2) rlm@345: (corrupt-item-list 0) rlm@345: close-all-menus))) rlm@345: rlm@345: (defn-memo begin-initial-deposits rlm@345: ([] (begin-initial-deposits rlm@345: (bootstrap-corrupt-save))) rlm@345: ([script] rlm@345: (->> script rlm@345: (first-difference [] [:a] AF) rlm@345: (scroll-text) rlm@345: (set-cursor 1) rlm@345: select-menu-entry))) rlm@345: rlm@345: (defn deposit-held-item [n quantity [moves state :as script]] rlm@345: (let [total-quantity (second (nth-item state n))] rlm@345: (println "total-quantity" total-quantity) rlm@345: (->> script rlm@345: (set-cursor n) rlm@345: (select-menu-entry 1) rlm@345: ((fn [[moves state :as script]] rlm@345: (if (not= (item-quantity-selected state) 1) rlm@345: (repeat-until-different [] item-quantity-selected script) rlm@345: script))) rlm@345: (set-quantity total-quantity quantity) rlm@345: (delayed-difference [] [:a] 100 #(search-string % "stored")) rlm@345: (scroll-text)))) rlm@345: rlm@345: (defn widthdraw-pc-item [n quantity [moves state :as script]] rlm@345: (let [total-quantity (second (nth-pc-item state n))] rlm@345: (->> script rlm@345: (set-cursor n) rlm@345: (select-menu-entry 1) rlm@345: ((fn [[moves state :as script]] rlm@345: (if (not= (item-quantity-selected state) 1) rlm@345: (repeat-until-different [] item-quantity-selected rlm@345: script) rlm@345: script))) rlm@345: (set-quantity total-quantity quantity) rlm@345: (delayed-difference [] [:a] 100 #(search-string % "Withdrew")) rlm@345: (scroll-text)))) rlm@345: rlm@345: (defn toss-held-item [n quantity [moves state :as script]] rlm@345: (let [total-quantity (second (nth-item state n))] rlm@345: (->> script rlm@345: (set-cursor n) rlm@345: (select-menu-entry 1) rlm@345: (set-cursor-relative 1) rlm@345: (select-menu-entry -1) rlm@345: ((fn [[moves state :as script]] rlm@345: (if (not= (item-quantity-selected state) 1) rlm@345: (repeat-until-different [] item-quantity-selected rlm@345: script) rlm@345: script))) rlm@345: (set-quantity total-quantity quantity) rlm@345: (play-moves [[:a]]) rlm@345: (scroll-text) rlm@345: (delayed-difference [] [:a] 100 #(search-string % "Threw")) rlm@345: (scroll-text) rlm@345: ))) rlm@345: rlm@345: rlm@345: (def desired-zero-quantities rlm@345: (map second (filter (comp (partial = 0) first) rlm@345: (partition 2 (pc-item-writer-program))))) rlm@345: rlm@345: (defn-memo initial-deposits rlm@345: ([] (initial-deposits (begin-initial-deposits))) rlm@345: ([script] rlm@345: (->> script rlm@345: (deposit-held-item 0 0xFE) rlm@345: (deposit-held-item 1 0xFE) rlm@345: ((fn [script] rlm@345: (reduce rlm@345: (fn [script item] (deposit-held-item item 0xFF script)) rlm@345: script rlm@345: (range 2 (+ 12 2))))) rlm@345: close-all-menus))) rlm@345: rlm@345: rlm@345: (defn-memo prepare-celadon-warp rlm@345: ([] (prepare-celadon-warp (initial-deposits))) rlm@345: ([script] rlm@345: (->> script rlm@345: (activate-start-menu) rlm@345: (set-cursor-relative 1) rlm@345: (select-menu-entry) rlm@345: (toss-held-item 35 0xFA) rlm@345: (close-all-menus)))) rlm@345: rlm@345: rlm@345: ;;0 -- 256 rlm@345: ;;1 -- 254 rlm@345: ;;2 -- 254 rlm@345: ;;3 -- 255 rlm@345: rlm@345: (defn-memo restore-items rlm@345: ([] (restore-items (prepare-celadon-warp))) rlm@345: ([script] rlm@345: (->> script rlm@345: (first-difference [] [:a] AF) rlm@345: (scroll-text) rlm@345: (select-menu-entry) rlm@345: (widthdraw-pc-item 0 1) rlm@345: (widthdraw-pc-item 3 99) rlm@345: (widthdraw-pc-item 3 99) rlm@345: (widthdraw-pc-item 3 57) rlm@345: (widthdraw-pc-item 2 99) rlm@345: (widthdraw-pc-item 2 99) rlm@345: (widthdraw-pc-item 2 56) rlm@345: (widthdraw-pc-item 1 99) rlm@345: (widthdraw-pc-item 1 99) rlm@345: (widthdraw-pc-item 1 56) rlm@345: (widthdraw-pc-item 0 99) rlm@345: (widthdraw-pc-item 0 99) rlm@345: (widthdraw-pc-item 0 57) rlm@345: (close-all-menus)))) rlm@345: rlm@345: (defn-memo to-celadon rlm@345: ([] (to-celadon (restore-items))) rlm@345: ([script] rlm@345: (->> script rlm@345: (walk [→ → → → → → → ↑ rlm@345: ↓ ↓ ↓ ↓ ↓ ← ← ← ← rlm@345: ↓ ↓])))) rlm@345: rlm@345: rlm@345: rlm@345: rlm@345: rlm@345: rlm@345: rlm@345: