Mercurial > vba-clojure
changeset 83:95cb2152d7cd
fleshing out functional gb interface
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Fri, 09 Mar 2012 19:18:00 -0600 |
parents | 04d539d26bdc |
children | 26f002f2868c |
files | clojure/com/aurellem/gb_driver.clj clojure/com/aurellem/gb_funs.clj java/src/com/aurellem/gb/Gb.java src/clojure/clojure.cpp |
diffstat | 4 files changed, 138 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
1.1 --- a/clojure/com/aurellem/gb_driver.clj Fri Mar 09 13:24:02 2012 -0600 1.2 +++ b/clojure/com/aurellem/gb_driver.clj Fri Mar 09 19:18:00 2012 -0600 1.3 @@ -177,3 +177,30 @@ 1.4 `(binding [*save-history* false] 1.5 ~@forms)) 1.6 1.7 + 1.8 +(require '(clojure [zip :as zip])) 1.9 + 1.10 + 1.11 + 1.12 + 1.13 +(defn tree->str [original] 1.14 + (loop [s ".\n" loc (zip/down (zip/seq-zip (seq original)))] 1.15 + (if (zip/end? loc) s 1.16 + (let [d (count (zip/path loc)) 1.17 + rep 1.18 + (str 1.19 + s 1.20 + (if (and (zip/up loc) 1.21 + (> (count (-> loc zip/up zip/rights)) 0)) 1.22 + "|" "") 1.23 + (apply str (repeat (dec d) " ")) 1.24 + (if (= (count (zip/rights loc)) 0) 1.25 + "`-- " 1.26 + "|-- ") 1.27 + (zip/node loc) 1.28 + "\n")] 1.29 + (recur rep (zip/next loc)))))) 1.30 + 1.31 + 1.32 + 1.33 +
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/clojure/com/aurellem/gb_funs.clj Fri Mar 09 19:18:00 2012 -0600 2.3 @@ -0,0 +1,104 @@ 2.4 +(ns com.aurellem.gb-funs 2.5 + (:import com.aurellem.gb.Gb) 2.6 + (:import java.io.File) 2.7 + (:import org.apache.commons.io.FileUtils) 2.8 + (:import (java.nio IntBuffer ByteOrder))) 2.9 + 2.10 +;; Savestates 2.11 +(defrecord SaveState [frame data]) 2.12 + 2.13 +(def ^:dynamic *save-state-cache* 2.14 + (File. "/home/r/proj/pokemon-escape/save-states/")) 2.15 + 2.16 +(defn frame->filename [frame] 2.17 + (File. *save-state-cache* (format "%07d.sav" frame))) 2.18 + 2.19 +(defn write-save! [^SaveState save] 2.20 + (let [buf (:data save) 2.21 + bytes (byte-array (.limit buf)) 2.22 + dest (frame->filename (:frame save))] 2.23 + (.get buf bytes) 2.24 + (FileUtils/writeByteArrayToFile dest bytes) 2.25 + (.rewind buf) 2.26 + save)) 2.27 + 2.28 +(defn read-save [frame] 2.29 + (let [save (frame->filename frame)] 2.30 + (if (.exists save) 2.31 + (let [buf (Gb/saveBuffer) 2.32 + bytes (FileUtils/readFileToByteArray save)] 2.33 + (.put buf bytes) 2.34 + (.flip buf) 2.35 + (SaveState. frame buf))))) 2.36 +;;;;;;;;;;;;;;;; 2.37 + 2.38 +;; Gameboy management 2.39 +(Gb/loadVBA) 2.40 + 2.41 +(def yellow-rom-image 2.42 + (File. "/home/r/proj/pokemon-escape/roms/yellow.gbc")) 2.43 + 2.44 +(def yellow-save-file 2.45 + (File. "/home/r/proj/pokemon-escape/roms/yellow.sav")) 2.46 + 2.47 +(def on? (atom nil)) 2.48 + 2.49 +(defn shutdown! [] (Gb/shutdown) (reset! on? false)) 2.50 + 2.51 +(defn restart! [] 2.52 + (shutdown!) 2.53 + (.delete yellow-save-file) 2.54 + (Gb/startEmulator (.getCanonicalPath yellow-rom-image)) 2.55 + (reset! on? true)) 2.56 + 2.57 +;;; The first state! 2.58 +(defn gen-root! [] 2.59 + (restart!) 2.60 + (write-save! (SaveState. 0 (Gb/saveState)))) 2.61 + 2.62 +(defn root [] 2.63 + (if (.exists (frame->filename 0)) 2.64 + (read-save 0) 2.65 + (gen-root!))) 2.66 + 2.67 +;;;; Press Buttons 2.68 + 2.69 +(def button-code 2.70 + {;; main buttons 2.71 + :a 0x0001 2.72 + :b 0x0002 2.73 + 2.74 + ;; directional pad 2.75 + :r 0x0010 2.76 + :l 0x0020 2.77 + :u 0x0040 2.78 + :d 0x0080 2.79 + 2.80 + ;; meta buttons 2.81 + :select 0x0004 2.82 + :start 0x0008 2.83 + 2.84 + ;; pseudo-buttons 2.85 + :restart 0x0800 ; hard reset -- not really a button 2.86 + :listen -1 ; listen for user input 2.87 + }) 2.88 + 2.89 +(defn button-mask [buttons] 2.90 + (reduce bit-or 0x0000 (map button-code buttons))) 2.91 + 2.92 +(def current-state (atom nil)) 2.93 + 2.94 +(defn step 2.95 + ([^SaveState state buttons] 2.96 + (if (not @on?) (restart!)) 2.97 + (if (not= @current-state state) 2.98 + (Gb/loadState (:data state))) 2.99 + (Gb/step (button-mask buttons)) 2.100 + (reset! current-state 2.101 + (SaveState. (inc (:frame state))(Gb/saveState))))) 2.102 + 2.103 +(defn play 2.104 + ([^SaveState state] 2.105 + (step state [:listen])) 2.106 + ([] (step (if @current-state @current-state (root))))) 2.107 +
3.1 --- a/java/src/com/aurellem/gb/Gb.java Fri Mar 09 13:24:02 2012 -0600 3.2 +++ b/java/src/com/aurellem/gb/Gb.java Fri Mar 09 19:18:00 2012 -0600 3.3 @@ -28,7 +28,11 @@ 3.4 3.5 public static native void step(); 3.6 3.7 - public static native void step(int keymask); 3.8 + public static native void nstep(int keymask); 3.9 + 3.10 + public static void step(int keymask){ 3.11 + if (-1 == keymask) {step();} 3.12 + else {nstep(keymask);}} 3.13 3.14 public static native void shutdown(); 3.15
4.1 --- a/src/clojure/clojure.cpp Fri Mar 09 13:24:02 2012 -0600 4.2 +++ b/src/clojure/clojure.cpp Fri Mar 09 19:18:00 2012 -0600 4.3 @@ -46,7 +46,7 @@ 4.4 * Method: step 4.5 * Signature: ()V 4.6 */ 4.7 -JNIEXPORT void JNICALL Java_com_aurellem_gb_Gb_step__ 4.8 +JNIEXPORT void JNICALL Java_com_aurellem_gb_Gb_step 4.9 (JNIEnv *env, jclass clazz){ 4.10 step(); 4.11 } 4.12 @@ -56,7 +56,7 @@ 4.13 * Method: step 4.14 * Signature: (I)V 4.15 */ 4.16 -JNIEXPORT void JNICALL Java_com_aurellem_gb_Gb_step__I 4.17 +JNIEXPORT void JNICALL Java_com_aurellem_gb_Gb_nstep 4.18 (JNIEnv *env, jclass clazz, jint keymask){ 4.19 step(keymask); 4.20 }