Mercurial > vba-clojure
view clojure/com/aurellem/vbm.clj @ 72:c88ad4f6d9b4
can now write proper vbm files from clojure
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Thu, 08 Mar 2012 03:41:24 -0600 |
parents | 39928bf4622d |
children | 8a895ed4c0f9 |
line wrap: on
line source
1 (ns com.aurellem.vbm2 (:import java.io.File)3 (:import org.apache.commons.io.FileUtils)4 (:use com.aurellem.gb-driver))6 (defn vbm-bytes [#^File vbm]7 (let [bytes (FileUtils/readFileToByteArray vbm)8 ints (int-array (count bytes))]9 (areduce bytes idx _ nil10 (aset ints idx11 (bit-and 0xFF (aget bytes idx))))12 ints))14 (def vbm-header-length 255)16 (defn repair-vbm17 "Two 0's must be inserted after every reset."18 [vbm-masks]19 (loop [fixed []20 pending vbm-masks]21 (if (empty? pending) fixed22 (let [mask (first pending)]23 (if (not= 0x0000 (bit-and mask (button-code :reset)))24 (recur (conj fixed mask 0x0000 0x0000) (next pending))25 (recur (conj fixed mask) (next pending)))))))27 (defn vbm-masks [#^File vbm]28 (repair-vbm29 (map (fn [[a b]]30 (+ (bit-shift-left a 8) b))31 (partition32 2 (drop vbm-header-length (vbm-bytes vbm))))))34 (defn vbm-buttons [#^File vbm]35 (map buttons (vbm-masks vbm)))37 (defn play-vbm [#^File vbm]38 (reset)39 (dorun (map step (vbm-masks vbm))))41 (defn convert-buttons42 "To write a vbm file, we must remove the last two buttons after any43 reset event."44 [buttons]45 (loop [fixed []46 pending buttons]47 (if (empty? pending) fixed48 (let [mask (first pending)]49 (if (contains? (first pending) :reset)50 (recur (conj fixed mask) (drop 3 pending))51 (recur (conj fixed mask) (next pending)))))))53 (def vbm-header54 (byte-array55 (map56 byte57 [86 66 77 26 1 0 0 0 105 74 88 79 89 1 0 0 0 0 0 0 0 1 2 112 0 0 058 0 0 0 0 0 1 0 0 0 80 79 75 69 77 79 78 32 89 69 76 76 1 -105 124 459 3 0 0 0 0 0 0 0 0 1 0 0 95 95 95 95 95 95 95 95 95 95 95 95 95 9560 95 95 82 111 98 101 114 116 32 32 77 99 73 110 116 121 114 101 9561 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 9562 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 9563 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 9564 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 9565 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 9566 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 9567 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 9568 95 95 95 95])))70 (def vbm-trailer71 (byte-array72 (map byte [0])))74 (defn buttons->vbm-bytes [buttons]75 (let [bytes-in-ints76 (map button-mask (convert-buttons buttons))77 high-bits (map #(bit-shift-right (bit-and 0xFF00 %) 8)78 bytes-in-ints)79 low-bits (map #(bit-and 0xFF %) bytes-in-ints)80 convert-byte (fn [i] (byte (if (>= i 128) (- i 256) i)))81 contents82 (byte-array83 (concat84 vbm-header85 (map convert-byte (interleave high-bits low-bits))86 vbm-trailer))]87 contents))89 (defn write-vbm [buttons #^File out]90 (clojure.java.io/copy (buttons->vbm-bytes buttons) out))