Mercurial > vba-clojure
comparison clojure/com/aurellem/gb_driver.clj @ 106:3a60bb14a64a
better functional assembly interface; removed frame numbers from SaveStates
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Wed, 14 Mar 2012 21:37:37 -0500 |
parents | 2f8089eacab9 |
children | ad96e9464d6a |
comparison
equal
deleted
inserted
replaced
105:2f8089eacab9 | 106:3a60bb14a64a |
---|---|
3 (:import java.io.File) | 3 (:import java.io.File) |
4 (:import org.apache.commons.io.FileUtils) | 4 (:import org.apache.commons.io.FileUtils) |
5 (:import (java.nio IntBuffer ByteOrder))) | 5 (:import (java.nio IntBuffer ByteOrder))) |
6 | 6 |
7 ;; Savestates | 7 ;; Savestates |
8 (defrecord SaveState [frame data]) | 8 (defrecord SaveState [data]) |
9 | 9 |
10 (def ^:dynamic *save-state-cache* | 10 (def ^:dynamic *save-state-cache* |
11 (File. "/home/r/proj/pokemon-escape/save-states/")) | 11 (File. "/home/r/proj/pokemon-escape/save-states/")) |
12 | 12 |
13 (defn frame->filename [frame] | 13 (def current-state (atom nil)) |
14 (File. *save-state-cache* (format "%07d.sav" frame))) | 14 |
15 | 15 (defn state-cache-file [name] |
16 (defn write-state! [^SaveState save] | 16 (File. *save-state-cache* (str name ".sav"))) |
17 (let [buf (:data save) | 17 |
18 bytes (byte-array (.limit buf)) | 18 (defn write-state! |
19 dest (frame->filename (:frame save))] | 19 ([^SaveState name] |
20 (.get buf bytes) | 20 (write-state! @current-state name)) |
21 (FileUtils/writeByteArrayToFile dest bytes) | 21 ([^SaveState save ^String name] |
22 (.rewind buf) | 22 (let [buffer (:data save) |
23 dest)) | 23 bytes (byte-array (.limit buffer)) |
24 | 24 dest (state-cache-file name)] |
25 (defn read-state [frame] | 25 (.get buffer bytes) |
26 (let [save (frame->filename frame)] | 26 (FileUtils/writeByteArrayToFile dest bytes) |
27 (.rewind buffer) | |
28 dest))) | |
29 | |
30 (defn read-state [name] | |
31 (let [save (state-cache-file name)] | |
27 (if (.exists save) | 32 (if (.exists save) |
28 (let [buf (Gb/saveBuffer) | 33 (let [buffer (Gb/saveBuffer) |
29 bytes (FileUtils/readFileToByteArray save)] | 34 bytes (FileUtils/readFileToByteArray save)] |
30 (.put buf bytes) | 35 (.put buffer bytes) |
31 (.flip buf) | 36 (.flip buffer) |
32 (SaveState. frame buf))))) | 37 (SaveState. buffer))))) |
33 ;;;;;;;;;;;;;;;; | 38 ;;;;;;;;;;;;;;;; |
34 | 39 |
35 ;; Gameboy management | 40 ;; Gameboy management |
36 (Gb/loadVBA) | 41 (Gb/loadVBA) |
37 | 42 |
52 (reset! on? true)) | 57 (reset! on? true)) |
53 | 58 |
54 ;;; The first state! | 59 ;;; The first state! |
55 (defn gen-root! [] | 60 (defn gen-root! [] |
56 (restart!) | 61 (restart!) |
57 (let [state (SaveState. 0 (Gb/saveState))] | 62 (let [state (SaveState. (Gb/saveState))] |
58 (write-state! state) | 63 (write-state! state "root" ) state)) |
59 state)) | |
60 | 64 |
61 (defn root [] | 65 (defn root [] |
62 (if (.exists (frame->filename 0)) | 66 (if (.exists (state-cache-file "root")) |
63 (read-state 0) | 67 (read-state "root") |
64 (gen-root!))) | 68 (gen-root!))) |
65 | 69 |
66 ;;;; Press Buttons | 70 ;;;; Press Buttons |
67 | 71 |
68 (def button-code | 72 (def button-code |
86 }) | 90 }) |
87 | 91 |
88 (defn button-mask [buttons] | 92 (defn button-mask [buttons] |
89 (reduce bit-or 0x0000 (map button-code buttons))) | 93 (reduce bit-or 0x0000 (map button-code buttons))) |
90 | 94 |
91 (def current-state (atom nil)) | |
92 | |
93 (defn set-state! [^SaveState state] | 95 (defn set-state! [^SaveState state] |
94 (assert (:data state) "Not a valid state!") | 96 (assert (:data state) "Not a valid state!") |
95 (if (not @on?) (restart!)) | 97 (if (not @on?) (restart!)) |
96 (Gb/loadState (:data state)) | 98 (if (not= state @current-state) |
97 (reset! current-state state)) | 99 (do |
98 | 100 (Gb/loadState (:data state)) |
99 (defrecord Move [keys state]) | 101 (reset! current-state state)))) |
100 | 102 |
101 (defn update-state [] | 103 (defn update-state [] |
102 (reset! current-state | 104 (reset! current-state |
103 (SaveState. (:frame @current-state) | 105 (SaveState. (Gb/saveState)))) |
104 (Gb/saveState)))) | |
105 | 106 |
106 (defn step | 107 (defn step |
107 ([^SaveState state buttons] | 108 ([^SaveState state buttons] |
108 (set-state! state) | 109 (set-state! state) |
109 (Gb/step (button-mask buttons)) | 110 (Gb/step (button-mask buttons)) |
110 (reset! current-state | 111 (reset! current-state |
111 (SaveState. (inc (:frame state))(Gb/saveState)))) | 112 (SaveState. (Gb/saveState)))) |
112 ([^SaveState state] | 113 ([^SaveState state] |
113 (step state [:listen])) | 114 (step state [:listen])) |
114 ([] (step (if @current-state @current-state (root))))) | 115 ([] (step (if @current-state @current-state (root))))) |
115 | 116 |
116 (defn tick | 117 (defn tick |
118 ([state] | 119 ([state] |
119 (set-state! state) | 120 (set-state! state) |
120 (Gb/tick) | 121 (Gb/tick) |
121 (update-state))) | 122 (update-state))) |
122 | 123 |
123 (defn move | |
124 [^Move move buttons] | |
125 (Move. (step (:state move) buttons) buttons)) | |
126 | |
127 (defn play | 124 (defn play |
128 ([^SaveState state n] | 125 ([^SaveState state n] |
129 (reduce (fn [s _] (step s)) state (range n))) | 126 (try |
127 (set-state! state) | |
128 (dorun (dotimes [_ n] | |
129 (Thread/sleep 1) | |
130 (Gb/step))) | |
131 | |
132 (finally | |
133 (update-state)))) | |
130 ([n] | 134 ([n] |
131 (play @current-state n))) | 135 (play @current-state n))) |
132 | 136 |
133 (defn continue! [] | 137 (defn continue! |
134 (play @current-state Integer/MAX_VALUE)) | 138 ([state] |
139 (play state Integer/MAX_VALUE)) | |
140 ([] | |
141 (continue! @current-state))) | |
135 | 142 |
136 (defn play-moves | 143 (defn play-moves |
137 ([moves [prev state]] | 144 ([moves [prev state]] |
138 (set-state! state) | 145 (set-state! state) |
139 (dorun (map (fn [move] (step @current-state move)) moves)) | 146 (dorun (map (fn [move] (step @current-state move)) moves)) |
150 ([] (get-data @current-state)) | 157 ([] (get-data @current-state)) |
151 ([state] | 158 ([state] |
152 (set-state! state) (arr-fn store) store)))) | 159 (set-state! state) (arr-fn store) store)))) |
153 | 160 |
154 (defn write-cpu-data [size store-fn] | 161 (defn write-cpu-data [size store-fn] |
155 (fn [new-data] | 162 (fn store-data |
156 (let [store (int-array new-data)] | 163 ([state new-data] |
157 (assert (= size (count new-data))) | 164 (set-state! state) |
158 (store-fn store)))) | 165 (let [store (int-array new-data)] |
166 (assert (= size (count new-data))) | |
167 (store-fn store) | |
168 (update-state))) | |
169 ([new-data] | |
170 (store-data @current-state new-data)))) | |
171 | |
159 | 172 |
160 (def memory | 173 (def memory |
161 (cpu-data Gb/GB_MEMORY #(Gb/getMemory %))) | 174 (cpu-data Gb/GB_MEMORY #(Gb/getMemory %))) |
162 | 175 |
163 (def ram | 176 (def ram |