rlm@530
|
1 (ns com.aurellem.run.final-cut
|
rlm@530
|
2 (:use (com.aurellem.gb saves gb-driver util constants
|
rlm@530
|
3 items vbm characters money
|
rlm@530
|
4 rlm-assembly))
|
rlm@530
|
5 (:use (com.aurellem.run util sound music title save-corruption
|
rlm@530
|
6 bootstrap-0 bootstrap-1
|
rlm@530
|
7 ram-display
|
rlm@530
|
8 ))
|
rlm@530
|
9 (:require clojure.string)
|
rlm@530
|
10 (:import [com.aurellem.gb.gb_driver SaveState])
|
rlm@530
|
11 (:import java.awt.image.BufferedImage)
|
rlm@530
|
12 (:import java.io.File)
|
rlm@530
|
13 (:import com.aurellem.gb.WaveWriter))
|
rlm@530
|
14
|
rlm@530
|
15
|
rlm@530
|
16 (def render-dir (File. user-home "proj/vba-clojure/render"))
|
rlm@530
|
17
|
rlm@530
|
18 (defn render-files!
|
rlm@530
|
19 ([^File target-dir initial-state moves]
|
rlm@530
|
20 (let [ram-map-dir (File. target-dir "ram-map")
|
rlm@530
|
21 frames-dir (File. target-dir "frames")
|
rlm@530
|
22 audio-file (File. target-dir "audio.wav")
|
rlm@533
|
23 _ (.mkdir target-dir)
|
rlm@533
|
24 _ (.mkdir ram-map-dir)
|
rlm@533
|
25 _ (.mkdir frames-dir)
|
rlm@530
|
26 wave-writer (WaveWriter. audio-file)
|
rlm@530
|
27 moves (vec moves)]
|
rlm@530
|
28 (set-state! initial-state)
|
rlm@530
|
29 (dorun
|
rlm@530
|
30 (map
|
rlm@530
|
31 (fn [index]
|
rlm@530
|
32 (run-moves @current-state (vector (moves index)))
|
rlm@530
|
33
|
rlm@530
|
34 ;; record audio
|
rlm@530
|
35 (.process wave-writer (sound-bytes)
|
rlm@530
|
36 gb-sound-format)
|
rlm@530
|
37
|
rlm@530
|
38 ;; write screenshot
|
rlm@530
|
39 (write-png!
|
rlm@530
|
40 @current-state
|
rlm@530
|
41 (File. frames-dir (format "%07d.png" index)))
|
rlm@530
|
42
|
rlm@530
|
43 ;; write ram-image
|
rlm@530
|
44 (write-ram-image!
|
rlm@530
|
45 @current-state
|
rlm@530
|
46 (File. ram-map-dir (format "%07d.png" index))))
|
rlm@530
|
47 (range (count moves))))
|
rlm@530
|
48 (.cleanup wave-writer)))
|
rlm@530
|
49 ([initial-state moves]
|
rlm@530
|
50 (render-files! render-dir initial-state moves))
|
rlm@530
|
51 ([moves]
|
rlm@530
|
52 (render-files! (root) moves)))
|
rlm@530
|
53
|
rlm@531
|
54 (defn file-names [#^File dir]
|
rlm@531
|
55 (mapv #(.getCanonicalPath %) (next (sort (file-seq dir)))))
|
rlm@531
|
56
|
rlm@531
|
57 (defn composite-frames-command
|
rlm@532
|
58 [screenshot ram-map target move]
|
rlm@532
|
59 (let [actual-keys (set move)
|
rlm@532
|
60 keys [:a :b :start :select :u :d :l :r]
|
rlm@532
|
61 button-on-name ["-size" "5x5" "xc:red"]
|
rlm@534
|
62 button-off-name ["-size" "5x5" "xc:white"]]
|
rlm@532
|
63 ["convert"
|
rlm@532
|
64 "-size" "318x276" "xc:white"
|
rlm@532
|
65 (map
|
rlm@532
|
66 (fn [index]
|
rlm@532
|
67 (let [position ["-geometry"
|
rlm@532
|
68 (str "+" (+ 30 (* index 8))
|
rlm@532
|
69 "+" "225") "-composite"]]
|
rlm@532
|
70 (if (actual-keys (keys index))
|
rlm@532
|
71 [button-on-name position]
|
rlm@532
|
72 [button-off-name position])))
|
rlm@532
|
73 (range (count keys)))
|
rlm@532
|
74 screenshot "-geometry" "+10+10" "-composite"
|
rlm@532
|
75 ram-map "-geometry" "+180+10" "-composite"
|
rlm@532
|
76 target]))
|
rlm@531
|
77
|
rlm@531
|
78 (defn generate-composite-frames!
|
rlm@532
|
79 [^File rendered-dir moves]
|
rlm@532
|
80 (let [final-frames (File. rendered-dir "final")
|
rlm@532
|
81 _ (.mkdir final-frames)
|
rlm@532
|
82 screenshots (file-names (File. rendered-dir "frames"))
|
rlm@532
|
83 ram-maps (file-names (File. rendered-dir "ram-map"))
|
rlm@532
|
84 targets (map #(.getCanonicalPath
|
rlm@532
|
85 (File. final-frames (format "%07d.bmp" %)))
|
rlm@532
|
86 (range (count screenshots)))]
|
rlm@532
|
87 (dorun
|
rlm@532
|
88 (map
|
rlm@532
|
89 (comp
|
rlm@532
|
90 (partial apply clojure.java.shell/sh)
|
rlm@532
|
91 flatten
|
rlm@532
|
92 (partial apply composite-frames-command)
|
rlm@532
|
93 (fn [a b c d] (println c) [a b c d]))
|
rlm@532
|
94 screenshots ram-maps targets moves))))
|
rlm@531
|
95
|
rlm@532
|
96
|
rlm@532
|
97 (defn final-cut! [^File render-dir]
|
rlm@532
|
98 (let [movie (File. render-dir "final.ogg")
|
rlm@532
|
99 final (File. render-dir "final")]
|
rlm@532
|
100 (.delete movie)
|
rlm@532
|
101 (clojure.java.shell/sh
|
rlm@532
|
102 "ffmpeg" "-r" "60"
|
rlm@532
|
103 "-i" (str (.getCanonicalPath final) "/" "%07d.bmp")
|
rlm@532
|
104 "-i" (.getCanonicalPath (File. render-dir "audio.wav"))
|
rlm@532
|
105 "-b:a" "128k"
|
rlm@532
|
106 "-b:v" "9000k"
|
rlm@532
|
107 "-c:a" "libvorbis"
|
rlm@532
|
108 "-c:v" "libtheora"
|
rlm@532
|
109 (.getCanonicalPath movie)) nil))
|
rlm@532
|
110
|
rlm@531
|
111
|
rlm@532
|
112 (comment
|
rlm@531
|
113
|
rlm@532
|
114 ;; step 1
|
rlm@532
|
115
|
rlm@532
|
116 (render-files!
|
rlm@532
|
117 render-dir (root)
|
rlm@532
|
118 (take 9000 (first (control-checkpoint))))
|
rlm@531
|
119
|
rlm@532
|
120 ;; step 2
|
rlm@532
|
121
|
rlm@532
|
122 (generate-composite-frames!
|
rlm@532
|
123 render-dir
|
rlm@532
|
124 (take 9000 (first (control-checkpoint))))
|
rlm@532
|
125
|
rlm@532
|
126 ;; step 3
|
rlm@532
|
127 (final-cut! render-dir)
|
rlm@532
|
128 ) |