annotate clojure/com/aurellem/gb/moves.clj @ 438:067ea3f0d951

can now play midi files with two tracks.
author Robert McIntyre <rlm@mit.edu>
date Wed, 25 Apr 2012 13:46:31 -0500
parents df9cad9909d2
children
rev   line source
rlm@162 1 (ns com.aurellem.gb.moves
ocsenave@281 2 (:use (com.aurellem.gb gb-driver util constants hxc))
rlm@162 3 (:import [com.aurellem.gb.gb_driver SaveState]))
rlm@162 4
rlm@162 5
ocsenave@281 6 ;;; grab the move data directly from the rom
ocsenave@281 7 (def move-code->move-name ;; alternate name: moves
ocsenave@281 8 ((comp vec cons)
ocsenave@281 9 :end-of-moves
ocsenave@289 10 (map format-name (hxc-move-names))))
ocsenave@281 11
ocsenave@281 12 (def move-name->move-code ;; alternate name: move-id
ocsenave@281 13 (zipmap
ocsenave@289 14 move-code->move-name
ocsenave@281 15 (range)))
ocsenave@281 16
ocsenave@281 17 (def move-name->move-pp
ocsenave@281 18 (comp :pp (hxc-move-data)))
ocsenave@281 19
ocsenave@281 20 (defn max-pp [name pp-ups]
ocsenave@281 21 (if (= 40 (move-name->move-pp name))
ocsenave@281 22 (+ 40 (* 7 pp-ups))
ocsenave@281 23 (int (* (+ 1 (* (/ 1 5) pp-ups))
ocsenave@281 24 (move-name->move-pp name)))))
rlm@190 25
rlm@163 26 (def moves-codes-pokemon-1 0xD172)
rlm@163 27
rlm@163 28 (defn moves-codes-start [pokemon-num]
rlm@163 29 (assert (<= 0 pokemon-num 5))
rlm@163 30 (+ moves-codes-pokemon-1
rlm@163 31 (* pokemon-num pokemon-record-width)))
rlm@163 32
rlm@190 33 (defn read-moves
rlm@190 34 ([^SaveState state poke-num]
rlm@190 35 (let [start (moves-codes-start poke-num)]
rlm@190 36 (vec
rlm@190 37 (take-while
rlm@191 38 (partial not= :end-of-moves)
rlm@190 39 (map
rlm@190 40 move-code->move-name
rlm@190 41 (subvec (vec (memory state))
rlm@192 42 start (+ start 4)))))))
rlm@190 43 ([poke-num]
rlm@190 44 (read-moves @current-state poke-num)))
rlm@190 45
rlm@162 46 (defn give-moves
rlm@162 47 ([^SaveState state pokemon-num moves]
rlm@191 48 (assert (<= (count moves) 4))
rlm@162 49 (set-memory-range
rlm@162 50 state
rlm@162 51 (moves-codes-start pokemon-num)
rlm@191 52 (map #(move-name->move-code % %)
rlm@191 53 (concat moves
rlm@191 54 (repeat (- 4 (count moves)) :end-of-moves)))))
rlm@162 55 ([pokemon-num moves]
rlm@162 56 (give-moves @current-state pokemon-num moves))
rlm@162 57 ([moves]
rlm@162 58 (give-moves 0 moves)))
rlm@162 59
rlm@162 60 ;; Note regarding PP of moves -- both the current PP and the
rlm@162 61 ;; total PP are stored in the same value.
rlm@162 62 ;; they are bit-packed, with the first 2 bits containing the
rlm@162 63 ;; number of pp-ups that have been applied, and the next
rlm@162 64 ;; six bits containing the current pp of the move.
rlm@162 65 ;; thus, a move can have up to 63 current pp and up to
rlm@162 66 ;; three pp-ups applied.
rlm@162 67
rlm@162 68 (def pokemon-1-pp-start 0xD187)
rlm@162 69
rlm@162 70 (defn moves-pp-start [pokemon-num]
rlm@162 71 (assert (<= 0 pokemon-num 5))
rlm@162 72 (+ pokemon-1-pp-start (* pokemon-num pokemon-record-width)))
rlm@162 73
rlm@162 74 (defn read-pp
rlm@162 75 ([^SaveState state pokemon-num move-num]
rlm@162 76 (assert (<= 0 move-num 3))
rlm@162 77 (assert (<= 0 pokemon-num 5))
rlm@162 78 (let [pp-raw
rlm@162 79 (aget (memory state)
rlm@162 80 (+ (moves-pp-start pokemon-num)
rlm@162 81 move-num))
rlm@162 82 pp-up
rlm@162 83 (bit-shift-right
rlm@162 84 (bit-and
rlm@162 85 pp-raw
rlm@162 86 (Integer/parseInt "11000000" 2)) 6)
rlm@162 87 current-pp
rlm@162 88 (bit-and
rlm@162 89 pp-raw
rlm@162 90 (Integer/parseInt "00111111" 2))]
rlm@192 91 {:pp-ups pp-up :current-pp current-pp}))
rlm@162 92 ([pokemon-num move-num]
rlm@162 93 (read-pp @current-state pokemon-num move-num)))
rlm@162 94
rlm@162 95 (defn give-pp
rlm@162 96 ([^SaveState state pokemon-num move-num pp-ups current-pp]
rlm@162 97 (assert (<= 0 move-num 3))
rlm@162 98 (assert (<= 0 pokemon-num 5))
rlm@162 99 (assert (<= 0 pp-ups 3))
rlm@162 100 (assert (<= 0 current-pp 63))
rlm@162 101
rlm@162 102 (set-memory
rlm@162 103 state
rlm@162 104 (+ (moves-pp-start pokemon-num)
rlm@162 105 move-num)
rlm@162 106 (+
rlm@162 107 (bit-shift-left pp-ups 6)
rlm@162 108 (bit-and (Integer/parseInt
rlm@162 109 "00111111" 2)
rlm@162 110 current-pp))))
rlm@162 111 ([pokemon-num move-num pp-ups current-pp]
rlm@163 112 (give-pp @current-state
rlm@162 113 pokemon-num move-num pp-ups current-pp)))
rlm@190 114
rlm@209 115 (defn give-moves-pps
rlm@209 116 ([^SaveState state poke-num moves-pps]
rlm@209 117 (let [new-moves
rlm@209 118 (-> state
rlm@214 119 ;; zero out the pp of the pokemon's moves
rlm@214 120 (give-pp poke-num 0 0 0)
rlm@214 121 (give-pp poke-num 1 0 0)
rlm@214 122 (give-pp poke-num 2 0 0)
rlm@214 123 (give-pp poke-num 3 0 0)
rlm@209 124 (give-moves poke-num (map first moves-pps)))]
rlm@209 125 (reduce (fn [state move-num]
rlm@209 126 (let [pp (second (nth moves-pps move-num))]
rlm@209 127 (give-pp state poke-num move-num
rlm@209 128 (:pp-ups pp)
rlm@209 129 (:current-pp pp))))
rlm@209 130 new-moves (range (count moves-pps)))))
rlm@209 131 ([poke-num moves-pps]
rlm@209 132 (give-moves-pps @current-state poke-num moves-pps)))
rlm@209 133
rlm@197 134