# HG changeset patch # User Robert McIntyre # Date 1332751817 18000 # Node ID 40b5bff9576cd828057f9ed1b72ae9487f948571 # Parent b7f682bb3090fd7e129f4409b2f02b7e1ea17a99# Parent 99227bec1123f40fc54a6280a119058e091f8698 merge diff -r b7f682bb3090 -r 40b5bff9576c clojure/com/aurellem/gb/hxc.clj --- a/clojure/com/aurellem/gb/hxc.clj Mon Mar 26 03:49:33 2012 -0500 +++ b/clojure/com/aurellem/gb/hxc.clj Mon Mar 26 03:50:17 2012 -0500 @@ -6,6 +6,9 @@ + +; ************* HANDWRITTEN CONSTANTS + (def pkmn-types [:normal :fighting @@ -110,8 +113,8 @@ "opponent evd -2" "doubles user spc when attacked" "doubles user def when attacked" - "poisons opponent" ;;acr taken from move acr - "paralyzes opponent" ;; + "just poisons opponent" ;;acr taken from move acr + "just paralyzes opponent" ;; "0x19 chance opponent atk -1" "0x19 chance opponent def -1" "0x19 chance opponent spd -1" @@ -135,133 +138,167 @@ ]) +;; ************** HARDCODED DATA +(defn hxc-thunk + "Creates a thunk (unary fn) that grabs data in a certain region of rom and +splits it into a collection by 0x50. If rom is not supplied, uses the + original rom data." + [start length] + (fn self + ([rom] + (take-nth 2 + (partition-by #(= % 0x50) + (take length + (drop start rom))))) + ([] + (self com.aurellem.gb.gb-driver/original-rom)))) +(def hxc-thunk-words + "Same as hxc-thunk, except it interprets the rom data as characters, + returning a collection of strings." + (comp + (partial comp (partial map character-codes->str)) + hxc-thunk)) + + +;; -------------------------------------------------- (def hxc-items - "The hardcoded names of the items in memory. List begins at ROM@045B7 " - (map character-codes->str - (take-nth 2 - (partition-by #(= % 0x50) - (take 1200 - (drop 0x45B7 (rom (root)))))))) + "The hardcoded names of the items in memory. List begins at +ROM@045B7" + (hxc-thunk-words 0x45B7 870)) (def hxc-types "The hardcoded type names in memory. List begins at ROM@27D99, shortly before hxc-titles." - (map character-codes->str - (take-nth 2 - (partition-by #(= 0x50 %) - (take 102 - (drop 0x27D99 - (rom (root)))))))) + (hxc-thunk-words 0x27D99 102)) (def hxc-titles "The hardcoded names of the trainer titles in memory. List begins at ROM@27E77" - (map character-codes->str - (take-nth 2 - (partition-by #(= 0x50 %) - (take 196 - (drop 0x27E77 - (rom (root)))))))) - + (hxc-thunk-words 0x27E77 196)) (def hxc-places "The hardcoded place names in memory. List begins at -ROM@71500. Cinnabar Mansion is dynamically calculated." - (map character-codes->str - (take-nth 2 - (partition-by #(= % 0x50) - (take 560 - (drop 0x71500 - (rom (root)))))))) +ROM@71500. [Cinnabar] Mansion seems to be dynamically calculated." + (hxc-thunk-words 0x71500 560)) -(def hxc-dialog - "The hardcoded dialogue in memory, including in-game alerts. List begins at ROM@98000." -(character-codes->str(take 0x0F728 - (drop (+ 0x98000) - (rom (root)))))) +(defn hxc-dialog + "The hardcoded dialogue in memory, including in-game alerts. Dialog + seems to be separated by 0x57 instead of 0x50 (END). Begins at ROM@98000." + ([rom] + (map character-codes->str + (take-nth 2 + (partition-by #(= % 0x57) + (take 0x0F728 + (drop 0x98000 rom)))))) + ([] + (hxc-dialog com.aurellem.gb.gb-driver/original-rom))) + (def hxc-pokedex "The hardcoded pokedex entries in memory. List begins at ROM@B8000, shortly before move names." - (map character-codes->str - (take-nth 2 - (partition-by #(= % 0x50) - (take 14754 - (drop 0xB8000 - (rom (root)))))))) + (hxc-thunk-words 0xB8000 14754)) + (def hxc-move-names "The hardcoded move names in memory. List begins at ROM@BC000" - (map character-codes->str - (take-nth 2 - (partition-by #(= % 0x50) - (take 1551 - (drop 0xBC000 - (rom (root)))))))) + (hxc-thunk-words 0xBC000 1551)) -(def hxc-move-data + +(defn hxc-move-data "The hardcoded (basic (move effects)) in memory. List begins at -0x38000. Effect descriptions were handwritten and aren't hardcoded." - (let [names (vec hxc-move-names) - move-count (count names) - move-size 6 - format-name (fn [s] +0x38000. Returns a map of {:name :power :accuracy :pp :fx-id + :fx-txt}. The move descriptions are handwritten, not hardcoded." + ([] + (hxc-move-data com.aurellem.gb.gb-driver/original-rom)) + ([rom] + (let [names (vec (hxc-move-names rom)) + move-count (count names) + move-size 6 + format-name (fn [s] (keyword (.toLowerCase - (apply str - (map #(if (= % \space) "-" %) s))))) - ] - (zipmap (map format-name names) - (map - (fn [[idx effect power type accuracy pp]] - {:name (names (dec idx)) - :power power - :accuracy (hex accuracy) - :pp pp - :fx-id (hex effect) - :fx-txt (get move-effects effect) - } - ) - - (partition move-size - (take (* move-size move-count) - (drop 0x38000 (rom(root))))))))) + (apply str + (map #(if (= % \space) "-" %) s)))))] + (zipmap (map format-name names) + (map + (fn [[idx effect power type accuracy pp]] + {:name (names (dec idx)) + :power power + :accuracy accuracy + :pp pp + :fx-id effect + :fx-txt (get move-effects effect) + } + ) + + (partition move-size + (take (* move-size move-count) + (drop 0x38000 rom)))))))) -(def hxc-pokenames - "The hardcoded names of the 190 species in memory. List begins at ROM@E8000." - (let [count-species 190 - name-length 10] - (map character-codes->str - (partition name-length - (take (* count-species name-length) - (drop 0xE8000 - (rom(root)))))))) - - - - - - - - - -(def hxc-advantage - "The hardcoded type advantages in memory, returned as tuples of [atk-type def-type multiplier]. By default (i.e. if not listed here), the multiplier is 1." - (map - (fn [[atk def mult]] [(get pkmn-types atk (hex atk)) - (get pkmn-types def (hex def)) - (/ mult 10)]) - (partition 3 - (take-while (partial not= 0xFF) - (drop 0x3E62D (rom(root))))))) +(defn hxc-move-data* + "Like hxc-move-data, but reports numbers as hexadecimal symbols instead." + ([] + (hxc-move-data* com.aurellem.gb.gb-driver/original-rom)) + ([rom] + (let [names (vec (hxc-move-names rom)) + move-count (count names) + move-size 6 + format-name (fn [s] + (keyword (.toLowerCase + (apply str + (map #(if (= % \space) "-" %) s))))) + ] + (zipmap (map format-name names) + (map + (fn [[idx effect power type accuracy pp]] + {:name (names (dec idx)) + :power power + :accuracy (hex accuracy) + :pp pp + :fx-id (hex effect) + :fx-txt (get move-effects effect) + } + ) + + (partition move-size + (take (* move-size move-count) + (drop 0x38000 rom)))))))) +(defn hxc-pokenames + "The hardcoded names of the 190 species in memory. List begins at +ROM@E8000. Although names in memory are padded with 0x50 to be 10 characters + long, these names are stripped of padding." + ([] + (hxc-pokenames com.aurellem.gb.gb-driver/original-rom)) + ([rom] + (let [count-species 190 + name-length 10] + (map character-codes->str + (partition name-length + (map #(if (= 0x50 %) 0x00 %) + (take (* count-species name-length) + (drop 0xE8000 + rom)))))))) +(defn hxc-advantage + "The hardcoded type advantages in memory, returned as tuples of atk-type def-type multiplier. By default (i.e. if not listed here), +the multiplier is 1." + ([] (hxc-advantage com.aurellem.gb.gb-driver/original-rom)) + ([rom] + (map + (fn [[atk def mult]] [(get pkmn-types atk (hex atk)) + (get pkmn-types def (hex def)) + (/ mult 10)]) + (partition 3 + (take-while (partial not= 0xFF) + (drop 0x3E62D rom)))))) @@ -272,6 +309,56 @@ +;; ********************** MANIPULATION FNS + + + + +(defn submap? + "Compares the two maps. Returns true if map-big has the same associations as map-small, otherwise false." + [map-small map-big] + (cond (empty? map-small) true + (and + (contains? map-big (ffirst map-small)) + (= (get map-big (ffirst map-small)) + (second (first map-small)))) + (recur (next map-small) map-big) + + :else false)) + + +(defn search-map [proto-map maps] + "Returns all the maps that make the same associations as proto-map." + (some (partial submap? proto-map) maps)) + +;; (I don't use this for anything so far.) +;; +;; (defn filter-vals +;; "Returns a map consisting of all the pairs [key val] for which (pred +;; key) returns true." +;; [pred map] +;; (reduce (partial apply assoc) {} (filter (fn [[k v]] (pred v)) map))) + + +(defn search-moves + "Returns a subcollection of all hardcoded moves with the given + attributes. Attributes consist of :name :power :accuracy :pp :fx-id + (and also :fx-txt, but it contains the same information as :fx-id)" + ([attribute-map] + (search-moves com.aurellem.gb.gb-driver/original-rom attribute-map)) + ([rom attribute-map] + (filter-vals (partial submap? attribute-map) (hxc-move-data + rom)))) + + + + + + + + + + ;; note for later: credits start at F1290