##// END OF EJS Templates
Update markup a bit
naryl -
r68:b533adc9 default
parent child Browse files
Show More
@@ -1,523 +1,522 b''
1
1
2 (in-package txt2web.api)
2 (in-package txt2web.api)
3
3
4 ;;; API deals with DOM manipulation and some bookkeeping for the
4 ;;; API deals with DOM manipulation and some bookkeeping for the
5 ;;; intrinsics, namely variables
5 ;;; intrinsics, namely variables
6 ;;; API is an implementation detail and has no QSP documentation. It
6 ;;; API is an implementation detail and has no QSP documentation. It
7 ;;; doesn't call intrinsics
7 ;;; doesn't call intrinsics
8
8
9 ;;; Utils
9 ;;; Utils
10
10
11 (defun make-act-html (title img)
11 (defun make-act-html (title img)
12 (+ "<a class='qsp-act' href='" (href-call call-act title) "' onmouseover='" (inline-call select-act title) "'>"
12 (+ "<a class='qsp-act' href='" (href-call call-act title) "' onmouseover='" (inline-call select-act title) "'>"
13 (if img (+ "<img src='" img "'>") "")
13 (if img (+ "<img src='" img "'>") "")
14 title
14 title
15 "</a>"))
15 "</a>"))
16
16
17 (defun make-menu-item-html (num title img loc)
17 (defun make-menu-item-html (num title img loc)
18 (+ "<a href='" (href-call finish-menu loc) "'>"
18 (+ "<a href='" (href-call finish-menu loc) "'>"
19 (if img (+ "<img src='" img "'>") "")
19 (if img (+ "<img src='" img "'>") "")
20 title
20 title
21 "</a>"))
21 "</a>"))
22
22
23 (defun make-obj (title img selected)
23 (defun make-obj (title img selected)
24 (+ "<li onclick='" (inline-call select-obj title img) "'>"
24 (+ "<li onclick='" (inline-call select-obj title img)
25 "<a class='qsp-obj" (if selected " qsp-obj-selected" "") "'>"
25 "' class='qsp-obj" (if selected " selected" "") "'>"
26 (if img (+ "<img src='" img "'>") "")
26 (if img (+ "<img src='" img "'>") "")
27 title
27 title
28 "</a>"))
28 "</li>"))
29
29
30 (defun make-menu-delimiter ()
30 (defun make-menu-delimiter ()
31 "<hr>")
31 "<hr>")
32
32
33 (defun copy-obj (obj)
33 (defun copy-obj (obj)
34 (chain *j-s-o-n (parse (chain *j-s-o-n (stringify obj)))))
34 (chain *j-s-o-n (parse (chain *j-s-o-n (stringify obj)))))
35
35
36 (defun report-error (text)
36 (defun report-error (text)
37 (alert text))
37 (alert text))
38
38
39 (defun start-sleeping ()
39 (defun start-sleeping ()
40 (chain (by-id "qsp") class-list (add "disable")))
40 (chain (by-id "qsp") class-list (add "disable")))
41
41
42 (defun finish-sleeping ()
42 (defun finish-sleeping ()
43 (chain (by-id "qsp") class-list (remove "disable")))
43 (chain (by-id "qsp") class-list (remove "disable")))
44
44
45 (defun sleep (msec)
45 (defun sleep (msec)
46 (with-sleep (resume)
46 (with-sleep (resume)
47 (set-timeout resume msec)))
47 (set-timeout resume msec)))
48
48
49 (defun init-dom ()
49 (defun init-dom ()
50 ;; Save/load buttons
50 ;; Save/load buttons
51 (let ((btn (by-id "qsp-btn-save")))
51 (let ((btn (by-id "qsp-btn-save")))
52 (setf (@ btn onclick) savegame)
52 (setf (@ btn onclick) savegame)
53 (setf (@ btn href) "#"))
53 (setf (@ btn href) "#"))
54 (let ((btn (by-id "qsp-btn-open")))
54 (let ((btn (by-id "qsp-btn-open")))
55 (setf (@ btn onclick) opengame)
55 (setf (@ btn onclick) opengame)
56 (setf (@ btn href) "#"))
56 (setf (@ btn href) "#"))
57 ;; Close image on click
57 ;; Close image on click
58 (setf (@ (by-id "qsp-image-container") onclick)
58 (setf (@ (by-id "qsp-image-container") onclick)
59 show-image)
59 show-image)
60 ;; Enter in input field
60 ;; Enter in input field
61 (setf (@ (get-frame :input) onkeyup)
61 (setf (@ (get-frame :input) onkeyup)
62 on-input-key)
62 on-input-key)
63 ;; Close the dropdown on any click
63 ;; Close the dropdown on any click
64 (setf (@ window onclick)
64 (setf (@ window onclick)
65 (lambda (event)
65 (lambda (event)
66 (setf (@ window mouse)
66 (setf (@ window mouse)
67 (list (@ event page-x)
67 (list (@ event page-x)
68 (@ event page-y)))
68 (@ event page-y)))
69 (finish-menu nil))))
69 (finish-menu nil))))
70
70
71 (defun init-globals (game-name)
71 (defun init-globals (game-name)
72 (chain *object (assign *globals (getprop *default-globals game-name))))
72 (chain *object (assign *globals (getprop *default-globals game-name))))
73
73
74 (defun call-serv-loc (var-name &rest args)
74 (defun call-serv-loc (var-name &rest args)
75 (let ((loc-name (get-global var-name 0)))
75 (let ((loc-name (get-global var-name 0)))
76 (when loc-name
76 (when loc-name
77 (let ((loc (getprop *locs (chain loc-name (to-upper-case)))))
77 (let ((loc (getprop *locs (chain loc-name (to-upper-case)))))
78 (when loc
78 (when loc
79 (call-loc loc-name args))))))
79 (call-loc loc-name args))))))
80
80
81 (defun filename-game (filename)
81 (defun filename-game (filename)
82 (let ((game-name (chain filename (match "(.*/)?([^.]+)(\\.[a-zA-Z]+)?") 2))))
82 (let ((game-name (chain filename (match "(.*/)?([^.]+)(\\.[a-zA-Z]+)?") 2))))
83 (getprop *games game-name))
83 (getprop *games game-name))
84
84
85 (defun run-game (name)
85 (defun run-game (name)
86 (let ((game (filename-game name)))
86 (let ((game (filename-game name)))
87 (setf *main-game name)
87 (setf *main-game name)
88 ;; Replace locations with the new game's
88 ;; Replace locations with the new game's
89 (setf *locs game)
89 (setf *locs game)
90 (funcall (getprop game
90 (funcall (getprop game
91 (chain *object (keys game) 0))
91 (chain *object (keys game) 0))
92 (list))))
92 (list))))
93
93
94 ;;; Misc
94 ;;; Misc
95
95
96 (defun newline (key)
96 (defun newline (key)
97 (append-id (key-to-id key) "<br>" t))
97 (append-id (key-to-id key) "<br>" t))
98
98
99 (defun clear-id (id)
99 (defun clear-id (id)
100 (setf (inner-html (by-id id)) ""))
100 (setf (inner-html (by-id id)) ""))
101
101
102 (defun escape-html (text)
102 (defun escape-html (text)
103 (chain text
103 (chain text
104 (replace (regex "/&/g") "&amp;")
104 (replace (regex "/&/g") "&amp;")
105 (replace (regex "/</g") "&lt;")
105 (replace (regex "/</g") "&lt;")
106 (replace (regex "/>/g") "&gt;")
106 (replace (regex "/>/g") "&gt;")
107 (replace (regex "/\"/g") "&quot;")
107 (replace (regex "/\"/g") "&quot;")
108 (replace (regex "/'/g") "&apos;")))
108 (replace (regex "/'/g") "&apos;")))
109
109
110 (defun prepare-contents (s &optional force-html)
110 (defun prepare-contents (s &optional force-html)
111 (setf s (chain s (to-string)))
111 (setf s (chain s (to-string)))
112 (if (or force-html (get-global "USEHTML" 0))
112 (if (or force-html (get-global "USEHTML" 0))
113 s
113 s
114 (escape-html s)))
114 (escape-html s)))
115
115
116 (defun get-id (id &optional force-html)
116 (defun get-id (id &optional force-html)
117 (inner-html (by-id id)))
117 (inner-html (by-id id)))
118
118
119 (defun set-id (id contents &optional force-html)
119 (defun set-id (id contents &optional force-html)
120 (setf (inner-html (by-id id)) (prepare-contents contents force-html)))
120 (setf (inner-html (by-id id)) (prepare-contents contents force-html)))
121
121
122 (defun append-id (id contents &optional force-html)
122 (defun append-id (id contents &optional force-html)
123 (when contents
123 (when contents
124 (incf (inner-html (by-id id)) (prepare-contents contents force-html))))
124 (incf (inner-html (by-id id)) (prepare-contents contents force-html))))
125
125
126 (defun on-input-key (ev)
126 (defun on-input-key (ev)
127 (when (= 13 (@ ev key-code))
127 (when (= 13 (@ ev key-code))
128 (chain ev (prevent-default))
128 (chain ev (prevent-default))
129 (call-serv-loc "$USERCOM")))
129 (call-serv-loc "$USERCOM")))
130
130
131 ;;; Function calls
131 ;;; Function calls
132
132
133 (defun init-args (args)
133 (defun init-args (args)
134 (dotimes (i 10)
134 (dotimes (i 10)
135 (set-global "ARGS" i 0)
135 (set-global "ARGS" i 0)
136 (set-global "$ARGS" i "")
136 (set-global "$ARGS" i "")
137 (when (and args (< i (length args)))
137 (when (and args (< i (length args)))
138 (let ((arg (elt args i)))
138 (let ((arg (elt args i)))
139 (if (numberp arg)
139 (if (numberp arg)
140 (set-global "ARGS" i arg)
140 (set-global "ARGS" i arg)
141 (set-global "$ARGS" i arg))))))
141 (set-global "$ARGS" i arg))))))
142
142
143 (defun get-result ()
143 (defun get-result ()
144 (or (get-global "$RESULT" 0)
144 (or (get-global "$RESULT" 0)
145 (get-global "RESULT" 0)))
145 (get-global "RESULT" 0)))
146
146
147 (defun call-loc (name args)
147 (defun call-loc (name args)
148 (setf name (chain name (to-upper-case)))
148 (setf name (chain name (to-upper-case)))
149 (with-frame
149 (with-frame
150 (with-call-args args t
150 (with-call-args args t
151 (funcall (getprop *locs name)))))
151 (funcall (getprop *locs name)))))
152
152
153 (defun call-act (title)
153 (defun call-act (title)
154 (with-frame
154 (with-frame
155 (funcall (getprop *acts title :act)))
155 (funcall (getprop *acts title :act)))
156 (void))
156 (void))
157
157
158 ;;; Text windows
158 ;;; Text windows
159
159
160 (defun key-to-id (key)
160 (defun key-to-id (key)
161 (case key
161 (case key
162 (:all "qsp")
162 (:all "qsp")
163 (:main "qsp-main")
163 (:main "qsp-main")
164 (:stat "qsp-stat")
164 (:stat "qsp-stat")
165 (:objs "qsp-objs")
165 (:objs "qsp-objs")
166 (:acts "qsp-acts")
166 (:acts "qsp-acts")
167 (:input "qsp-input")
167 (:input "qsp-input")
168 (:image "qsp-image")
168 (:image "qsp-image")
169 (:dropdown "qsp-dropdown")
169 (:dropdown "qsp-dropdown")
170 (t (report-error "Internal error!"))))
170 (t (report-error "Internal error!"))))
171
171
172 (defun get-frame (key)
172 (defun get-frame (key)
173 (by-id (key-to-id key)))
173 (by-id (key-to-id key)))
174
174
175 (defun add-text (key text)
175 (defun add-text (key text)
176 (append-id (key-to-id key) text))
176 (append-id (key-to-id key) text))
177
177
178 (defun get-text (key)
178 (defun get-text (key)
179 (get-id (key-to-id key)))
179 (get-id (key-to-id key)))
180
180
181 (defun clear-text (key)
181 (defun clear-text (key)
182 (clear-id (key-to-id key)))
182 (clear-id (key-to-id key)))
183
183
184 (defun enable-frame (key enable)
184 (defun enable-frame (key enable)
185 (let ((obj (get-frame key)))
185 (let ((obj (get-frame key)))
186 (setf (@ obj style display) (if enable "block" "none"))
186 (setf (@ obj style display) (if enable "block" "none"))
187 (void)))
187 (void)))
188
188
189 ;;; Actions
189 ;;; Actions
190
190
191 (defun add-act (title img act)
191 (defun add-act (title img act)
192 (setf (getprop *acts title)
192 (setf (getprop *acts title)
193 (create :title title :img img :act act :selected nil))
193 (create :title title :img img :act act :selected nil))
194 (update-acts))
194 (update-acts))
195
195
196 (defun del-act (title)
196 (defun del-act (title)
197 (delete (getprop *acts title))
197 (delete (getprop *acts title))
198 (update-acts))
198 (update-acts))
199
199
200 (defun clear-act ()
200 (defun clear-act ()
201 (setf *acts (create))
201 (setf *acts (create))
202 (update-acts))
202 (update-acts))
203
203
204 (defun update-acts ()
204 (defun update-acts ()
205 (clear-id "qsp-acts")
205 (clear-id "qsp-acts")
206 (let ((elt (by-id "qsp-acts")))
206 (let ((elt (by-id "qsp-acts")))
207 (for-in (title *acts)
207 (for-in (title *acts)
208 (let ((obj (getprop *acts title)))
208 (let ((obj (getprop *acts title)))
209 (incf (inner-html elt) (make-act-html title (getprop obj :img)))))))
209 (incf (inner-html elt) (make-act-html title (getprop obj :img)))))))
210
210
211 (defun select-act (title)
211 (defun select-act (title)
212 (loop :for (k v) :of *acts
212 (loop :for (k v) :of *acts
213 :do (setf (getprop v :selected) nil))
213 :do (setf (getprop v :selected) nil))
214 (setf (getprop *acts title :selected) t)
214 (setf (getprop *acts title :selected) t)
215 (call-serv-loc "$ONACTSEL"))
215 (call-serv-loc "$ONACTSEL"))
216
216
217 ;;; Variables
217 ;;; Variables
218
218
219 (defun new-var (slot &rest indexes)
219 (defun new-var (slot &rest indexes)
220 (let ((v (list)))
220 (let ((v (list)))
221 (dolist (index indexes)
221 (dolist (index indexes)
222 (setf (elt v index) (if (eq #\$ (elt slot 0)) "" 0)))
222 (setf (elt v index) (if (eq #\$ (elt slot 0)) "" 0)))
223 (setf (@ v :indexes) (create))
223 (setf (@ v :indexes) (create))
224 v))
224 v))
225
225
226 (defun set-str-element (slot index value)
226 (defun set-str-element (slot index value)
227 (if (has index (getprop slot :indexes))
227 (if (has index (getprop slot :indexes))
228 (setf (elt slot (getprop slot :indexes index))
228 (setf (elt slot (getprop slot :indexes index))
229 value)
229 value)
230 (progn
230 (progn
231 (chain slot (push value))
231 (chain slot (push value))
232 (setf (getprop slot :indexes index)
232 (setf (getprop slot :indexes index)
233 (1- (length slot)))))
233 (1- (length slot)))))
234 (void))
234 (void))
235
235
236 (defun set-any-element (slot index value)
236 (defun set-any-element (slot index value)
237 (cond ((null index)
237 (cond ((null index)
238 (chain (elt slot) (push value)))
238 (chain (elt slot) (push value)))
239 ((numberp index)
239 ((numberp index)
240 (setf (elt slot index) value))
240 (setf (elt slot index) value))
241 ((stringp index)
241 ((stringp index)
242 (set-str-element slot index value))
242 (set-str-element slot index value))
243 (t (report-error "INTERNAL ERROR")))
243 (t (report-error "INTERNAL ERROR")))
244 (void))
244 (void))
245
245
246 (defun set-serv-var (name index value)
246 (defun set-serv-var (name index value)
247 (let ((slot (getprop *globals name)))
247 (let ((slot (getprop *globals name)))
248 (set-any-element slot index value))
248 (set-any-element slot index value))
249 (funcall (getprop serv-vars name :body) value index)
249 (funcall (getprop serv-vars name :body) value index)
250 (void))
250 (void))
251
251
252 (defun get-element (slot index)
252 (defun get-element (slot index)
253 (if (numberp index)
253 (if (numberp index)
254 (elt slot index)
254 (elt slot index)
255 (elt slot (getprop slot :indexes index))))
255 (elt slot (getprop slot :indexes index))))
256
256
257 (defun set-global (name index value)
257 (defun set-global (name index value)
258 (set-any-element (getprop *globals name) index value))
258 (set-any-element (getprop *globals name) index value))
259
259
260 (defun get-global (name index)
260 (defun get-global (name index)
261 (get-element (getprop *globals name) index))
261 (get-element (getprop *globals name) index))
262
262
263 (defun kill-var (&optional name index)
263 (defun kill-var (&optional name index)
264 (cond (name
264 (cond (name
265 (setf name (chain name (to-upper-case)))
265 (setf name (chain name (to-upper-case)))
266 (cond ((and index (not (= 0 index)))
266 (cond ((and index (not (= 0 index)))
267 (chain (getprop *globals name) (kill index)))
267 (chain (getprop *globals name) (kill index)))
268 (t
268 (t
269 (setf (getprop *globals name) (list))
269 (setf (getprop *globals name) (list))
270 (setf (getprop *globals name "indexes") (create)))))
270 (setf (getprop *globals name "indexes") (create)))))
271 (t
271 (t
272 (setf *globals (create))
272 (setf *globals (create))
273 (init-globals *main-game)))
273 (init-globals *main-game)))
274 (void))
274 (void))
275
275
276 (defun array-size (name)
276 (defun array-size (name)
277 (@ (var-ref name) :values length))
277 (@ (var-ref name) :values length))
278
278
279 ;;; Locals
279 ;;; Locals
280
280
281 (defun push-local-frame ()
281 (defun push-local-frame ()
282 (chain *locals (push (create)))
282 (chain *locals (push (create)))
283 (void))
283 (void))
284
284
285 (defun pop-local-frame ()
285 (defun pop-local-frame ()
286 (chain *locals (pop))
286 (chain *locals (pop))
287 (void))
287 (void))
288
288
289 (defun current-local-frame ()
289 (defun current-local-frame ()
290 (elt *locals (1- (length *locals))))
290 (elt *locals (1- (length *locals))))
291
291
292 ;;; Objects
292 ;;; Objects
293
293
294 (defun select-obj (title img)
294 (defun select-obj (title img)
295 (loop :for (k v) :of *objs
295 (loop :for (k v) :of *objs
296 :do (setf (getprop v :selected) nil))
296 :do (setf (getprop v :selected) nil))
297 (setf (getprop *objs title :selected) t)
297 (setf (getprop *objs title :selected) t)
298 (call-serv-loc "$ONOBJSEL" title img))
298 (call-serv-loc "$ONOBJSEL" title img))
299
299
300 (defun update-objs ()
300 (defun update-objs ()
301 (clear-id "qsp-objs")
301 (let ((elt (by-id "qsp-objs")))
302 (let ((elt (by-id "qsp-objs")))
302 (setf (inner-html elt) "<ul>")
303 (loop :for (name obj) :of *objs
303 (loop :for (name obj) :of *objs
304 :do (incf (inner-html elt)
304 :do (incf (inner-html elt)
305 (make-obj name (@ obj :img) (@ obj :selected))))
305 (make-obj name (@ obj :img) (@ obj :selected))))))
306 (incf (inner-html elt) "</ul>")))
307
306
308 ;;; Menu
307 ;;; Menu
309
308
310 (defun open-menu (menu-data)
309 (defun open-menu (menu-data)
311 (let ((elt (get-frame :dropdown))
310 (let ((elt (get-frame :dropdown))
312 (i 0))
311 (i 0))
313 (loop :for item :in menu-data
312 (loop :for item :in menu-data
314 :do (incf i)
313 :do (incf i)
315 :do (incf (inner-html elt)
314 :do (incf (inner-html elt)
316 (if (eq item :delimiter)
315 (if (eq item :delimiter)
317 (make-menu-delimiter i)
316 (make-menu-delimiter i)
318 (make-menu-item-html i
317 (make-menu-item-html i
319 (@ item :text)
318 (@ item :text)
320 (@ item :icon)
319 (@ item :icon)
321 (@ item :loc)))))
320 (@ item :loc)))))
322 (let ((mouse (@ window mouse)))
321 (let ((mouse (@ window mouse)))
323 (setf (@ elt style left) (+ (elt mouse 0) "px"))
322 (setf (@ elt style left) (+ (elt mouse 0) "px"))
324 (setf (@ elt style top) (+ (elt mouse 1) "px"))
323 (setf (@ elt style top) (+ (elt mouse 1) "px"))
325 ;; Make sure it's inside the viewport
324 ;; Make sure it's inside the viewport
326 (when (> (@ document body inner-width)
325 (when (> (@ document body inner-width)
327 (+ (elt mouse 0) (@ elt inner-width)))
326 (+ (elt mouse 0) (@ elt inner-width)))
328 (incf (@ elt style left) (@ elt inner-width)))
327 (incf (@ elt style left) (@ elt inner-width)))
329 (when (> (@ document body inner-height)
328 (when (> (@ document body inner-height)
330 (+ (elt mouse 0) (@ elt inner-height)))
329 (+ (elt mouse 0) (@ elt inner-height)))
331 (incf (@ elt style top) (@ elt inner-height))))
330 (incf (@ elt style top) (@ elt inner-height))))
332 (setf (@ elt style display) "block")))
331 (setf (@ elt style display) "block")))
333
332
334 (defun finish-menu (loc)
333 (defun finish-menu (loc)
335 (when *menu-resume
334 (when *menu-resume
336 (let ((elt (get-frame :dropdown)))
335 (let ((elt (get-frame :dropdown)))
337 (setf (inner-html elt) "")
336 (setf (inner-html elt) "")
338 (setf (@ elt style display) "none")
337 (setf (@ elt style display) "none")
339 (funcall *menu-resume)
338 (funcall *menu-resume)
340 (setf *menu-resume nil))
339 (setf *menu-resume nil))
341 (when loc
340 (when loc
342 (call-loc loc)))
341 (call-loc loc)))
343 (void))
342 (void))
344
343
345 (defun menu (menu-data)
344 (defun menu (menu-data)
346 (with-sleep (resume)
345 (with-sleep (resume)
347 (open-menu menu-data)
346 (open-menu menu-data)
348 (setf *menu-resume resume))
347 (setf *menu-resume resume))
349 (void))
348 (void))
350
349
351 ;;; Content
350 ;;; Content
352
351
353 (defun clean-audio ()
352 (defun clean-audio ()
354 (loop :for k :in (chain *object (keys *playing))
353 (loop :for k :in (chain *object (keys *playing))
355 :for v := (getprop *playing k)
354 :for v := (getprop *playing k)
356 :do (when (@ v ended)
355 :do (when (@ v ended)
357 (delete (@ *playing k)))))
356 (delete (@ *playing k)))))
358
357
359 (defun show-image (path)
358 (defun show-image (path)
360 (let ((img (get-frame :image)))
359 (let ((img (get-frame :image)))
361 (cond (path
360 (cond (path
362 (setf (@ img src) path)
361 (setf (@ img src) path)
363 (setf (@ img style display) "flex"))
362 (setf (@ img style display) "flex"))
364 (t
363 (t
365 (setf (@ img src) "")
364 (setf (@ img src) "")
366 (setf (@ img style display) "hidden")))))
365 (setf (@ img style display) "hidden")))))
367
366
368 (defun rgb-string (rgb)
367 (defun rgb-string (rgb)
369 (let ((red (ps::>> rgb 16))
368 (let ((red (ps::>> rgb 16))
370 (green (logand (ps::>> rgb 8) 255))
369 (green (logand (ps::>> rgb 8) 255))
371 (blue (logand rgb 255)))
370 (blue (logand rgb 255)))
372 (flet ((rgb-to-hex (comp)
371 (flet ((rgb-to-hex (comp)
373 (let ((hex (chain (*number comp) (to-string 16))))
372 (let ((hex (chain (*number comp) (to-string 16))))
374 (if (< (length hex) 2)
373 (if (< (length hex) 2)
375 (+ "0" hex)
374 (+ "0" hex)
376 hex))))
375 hex))))
377 (+ "#" (rgb-to-hex red) (rgb-to-hex green) (rgb-to-hex blue)))))
376 (+ "#" (rgb-to-hex red) (rgb-to-hex green) (rgb-to-hex blue)))))
378
377
379 (defun store-obj (key obj)
378 (defun store-obj (key obj)
380 (store-str key (btoa (encode-u-r-i-component (chain *j-s-o-n (stringify obj)))))
379 (store-str key (btoa (encode-u-r-i-component (chain *j-s-o-n (stringify obj)))))
381 (void))
380 (void))
382 (defun store-str (key str)
381 (defun store-str (key str)
383 (chain local-storage (set-item (+ "qsp_" key) str))
382 (chain local-storage (set-item (+ "qsp_" key) str))
384 (void))
383 (void))
385
384
386 (defun load-obj (key)
385 (defun load-obj (key)
387 (chain *j-s-o-n (parse (encode-u-r-i-component (atob (load-str key))))))
386 (chain *j-s-o-n (parse (encode-u-r-i-component (atob (load-str key))))))
388 (defun load-str (key)
387 (defun load-str (key)
389 (chain local-storage (get-item (+ "qsp_" key))))
388 (chain local-storage (get-item (+ "qsp_" key))))
390
389
391 ;;; Saves
390 ;;; Saves
392
391
393 (defun slot-savegame (slot comment)
392 (defun slot-savegame (slot comment)
394 (let ((saves (load-obj "saves")))
393 (let ((saves (load-obj "saves")))
395 (setf (@ saves slot) comment)
394 (setf (@ saves slot) comment)
396 (store-obj saves))
395 (store-obj saves))
397 (store-str slot (state-to-base64))
396 (store-str slot (state-to-base64))
398 (void))
397 (void))
399
398
400 (defun slot-loadgame (slot)
399 (defun slot-loadgame (slot)
401 (base64-to-state (load-str slot))
400 (base64-to-state (load-str slot))
402 (void))
401 (void))
403
402
404 (defun slot-deletegame (slot)
403 (defun slot-deletegame (slot)
405 (let ((saves (load-obj "saves")))
404 (let ((saves (load-obj "saves")))
406 (setf (@ saves slot) undefined)
405 (setf (@ saves slot) undefined)
407 (store-obj saves))
406 (store-obj saves))
408 (store-str slot undefined)
407 (store-str slot undefined)
409 (void))
408 (void))
410
409
411 (defun slot-listgames ()
410 (defun slot-listgames ()
412 (load-obj "saves"))
411 (load-obj "saves"))
413
412
414 (defun opengame ()
413 (defun opengame ()
415 (let ((element (chain document (create-element :input))))
414 (let ((element (chain document (create-element :input))))
416 (chain element (set-attribute :type :file))
415 (chain element (set-attribute :type :file))
417 (chain element (set-attribute :id :qsp-opengame))
416 (chain element (set-attribute :id :qsp-opengame))
418 (chain element (set-attribute :tabindex -1))
417 (chain element (set-attribute :tabindex -1))
419 (chain element (set-attribute "aria-hidden" t))
418 (chain element (set-attribute "aria-hidden" t))
420 (setf (@ element style display) :block)
419 (setf (@ element style display) :block)
421 (setf (@ element style visibility) :hidden)
420 (setf (@ element style visibility) :hidden)
422 (setf (@ element style position) :fixed)
421 (setf (@ element style position) :fixed)
423 (setf (@ element onchange)
422 (setf (@ element onchange)
424 (lambda (event)
423 (lambda (event)
425 (let* ((file (@ event target files 0))
424 (let* ((file (@ event target files 0))
426 (reader (new (*file-reader))))
425 (reader (new (*file-reader))))
427 (setf (@ reader onload)
426 (setf (@ reader onload)
428 (lambda (ev)
427 (lambda (ev)
429 (block nil
428 (block nil
430 (let ((target (@ ev current-target)))
429 (let ((target (@ ev current-target)))
431 (unless (@ target result)
430 (unless (@ target result)
432 (return))
431 (return))
433 (base64-to-state (@ target result))
432 (base64-to-state (@ target result))
434 (unstash-state)))))
433 (unstash-state)))))
435 (chain reader (read-as-text file)))))
434 (chain reader (read-as-text file)))))
436 (chain document body (append-child element))
435 (chain document body (append-child element))
437 (chain element (click))
436 (chain element (click))
438 (chain document body (remove-child element))))
437 (chain document body (remove-child element))))
439
438
440 (defun savegame ()
439 (defun savegame ()
441 (let ((element (chain document (create-element :a))))
440 (let ((element (chain document (create-element :a))))
442 (chain element (set-attribute :href (+ "data:text/plain;charset=utf-8," (state-to-base64))))
441 (chain element (set-attribute :href (+ "data:text/plain;charset=utf-8," (state-to-base64))))
443 (chain element (set-attribute :download "savegame.sav"))
442 (chain element (set-attribute :download "savegame.sav"))
444 (setf (@ element style display) :none)
443 (setf (@ element style display) :none)
445 (chain document body (append-child element))
444 (chain document body (append-child element))
446 (chain element (click))
445 (chain element (click))
447 (chain document body (remove-child element))))
446 (chain document body (remove-child element))))
448
447
449 (defun stash-state (args)
448 (defun stash-state (args)
450 (call-serv-loc "$ONGSAVE")
449 (call-serv-loc "$ONGSAVE")
451 (setf *state-stash
450 (setf *state-stash
452 (chain *j-s-o-n (stringify
451 (chain *j-s-o-n (stringify
453 (create :vars *globals
452 (create :vars *globals
454 :objs *objs
453 :objs *objs
455 :loc-args args
454 :loc-args args
456 :msecs (- (chain *date (now)) *started-at)
455 :msecs (- (chain *date (now)) *started-at)
457 :timer-interval *timer-interval
456 :timer-interval *timer-interval
458 :main-html (inner-html
457 :main-html (inner-html
459 (get-frame :main))
458 (get-frame :main))
460 :stat-html (inner-html
459 :stat-html (inner-html
461 (get-frame :stat))
460 (get-frame :stat))
462 :next-location *current-location))))
461 :next-location *current-location))))
463 (void))
462 (void))
464
463
465 (defun unstash-state ()
464 (defun unstash-state ()
466 (let ((data (chain *j-s-o-n (parse *state-stash))))
465 (let ((data (chain *j-s-o-n (parse *state-stash))))
467 (clear-act)
466 (clear-act)
468 (setf *globals (@ data :vars))
467 (setf *globals (@ data :vars))
469 (loop :for k :in (chain *object (keys *globals))
468 (loop :for k :in (chain *object (keys *globals))
470 :do (chain *object (set-prototype-of (getprop *globals k)
469 :do (chain *object (set-prototype-of (getprop *globals k)
471 (@ *var prototype))))
470 (@ *var prototype))))
472 (setf *started-at (- (chain *date (now)) (@ data :msecs)))
471 (setf *started-at (- (chain *date (now)) (@ data :msecs)))
473 (setf *objs (@ data :objs))
472 (setf *objs (@ data :objs))
474 (setf *current-location (@ data :next-location))
473 (setf *current-location (@ data :next-location))
475 (setf (inner-html (get-frame :main))
474 (setf (inner-html (get-frame :main))
476 (@ data :main-html))
475 (@ data :main-html))
477 (setf (inner-html (get-frame :stat))
476 (setf (inner-html (get-frame :stat))
478 (@ data :stat-html))
477 (@ data :stat-html))
479 (update-objs)
478 (update-objs)
480 (set-timer (@ data :timer-interval))
479 (set-timer (@ data :timer-interval))
481 (call-serv-loc "$ONGLOAD")
480 (call-serv-loc "$ONGLOAD")
482 (call-loc *current-location (@ data :loc-args))
481 (call-loc *current-location (@ data :loc-args))
483 (void)))
482 (void)))
484
483
485 (defun state-to-base64 ()
484 (defun state-to-base64 ()
486 (btoa (encode-u-r-i-component *state-stash)))
485 (btoa (encode-u-r-i-component *state-stash)))
487
486
488 (defun base64-to-state (data)
487 (defun base64-to-state (data)
489 (setf *state-stash (decode-u-r-i-component (atob data))))
488 (setf *state-stash (decode-u-r-i-component (atob data))))
490
489
491 ;;; Timers
490 ;;; Timers
492
491
493 (defun set-timer (interval)
492 (defun set-timer (interval)
494 (setf *timer-interval interval)
493 (setf *timer-interval interval)
495 (clear-interval *timer-obj)
494 (clear-interval *timer-obj)
496 (setf *timer-obj
495 (setf *timer-obj
497 (set-interval
496 (set-interval
498 (lambda ()
497 (lambda ()
499 (call-serv-loc "$COUNTER"))
498 (call-serv-loc "$COUNTER"))
500 interval)))
499 interval)))
501
500
502 ;;; Special variables
501 ;;; Special variables
503
502
504 (defvar serv-vars (create))
503 (defvar serv-vars (create))
505
504
506 (define-serv-var $backimage (path)
505 (define-serv-var $backimage (path)
507 (setf (@ (get-frame :main) style background-image) path))
506 (setf (@ (get-frame :main) style background-image) path))
508
507
509 (define-serv-var bcolor (color)
508 (define-serv-var bcolor (color)
510 (setf (@ (get-frame :all) style background-color) (rgb-string color)))
509 (setf (@ (get-frame :all) style background-color) (rgb-string color)))
511
510
512 (define-serv-var fcolor (color)
511 (define-serv-var fcolor (color)
513 (setf (@ (get-frame :all) style color) (rgb-string color)))
512 (setf (@ (get-frame :all) style color) (rgb-string color)))
514
513
515 (define-serv-var lcolor (color)
514 (define-serv-var lcolor (color)
516 (setf (@ (get-frame :style) inner-text)
515 (setf (@ (get-frame :style) inner-text)
517 (+ "a { color: " (rgb-string color) ";}")))
516 (+ "a { color: " (rgb-string color) ";}")))
518
517
519 (define-serv-var fsize (size)
518 (define-serv-var fsize (size)
520 (setf (@ (get-frame :all) style font-size) size))
519 (setf (@ (get-frame :all) style font-size) size))
521
520
522 (define-serv-var $fname (font-name)
521 (define-serv-var $fname (font-name)
523 (setf (@ (get-frame :all) style font-family) (+ font-name ",serif")))
522 (setf (@ (get-frame :all) style font-family) (+ font-name ",serif")))
General Comments 0
You need to be logged in to leave comments. Login now