diff options
Diffstat (limited to 'apps/plugins/puzzles/src/nestedvm.c')
-rw-r--r-- | apps/plugins/puzzles/src/nestedvm.c | 486 |
1 files changed, 0 insertions, 486 deletions
diff --git a/apps/plugins/puzzles/src/nestedvm.c b/apps/plugins/puzzles/src/nestedvm.c deleted file mode 100644 index 947abe0fae..0000000000 --- a/apps/plugins/puzzles/src/nestedvm.c +++ /dev/null | |||
@@ -1,486 +0,0 @@ | |||
1 | /* | ||
2 | * nestedvm.c: NestedVM front end for my puzzle collection. | ||
3 | */ | ||
4 | |||
5 | #include <stdio.h> | ||
6 | #include <assert.h> | ||
7 | #include <stdlib.h> | ||
8 | #include <time.h> | ||
9 | #include <stdarg.h> | ||
10 | #include <string.h> | ||
11 | #include <errno.h> | ||
12 | |||
13 | #include <sys/time.h> | ||
14 | |||
15 | #include "puzzles.h" | ||
16 | |||
17 | extern void _pause(); | ||
18 | extern int _call_java(int cmd, int arg1, int arg2, int arg3); | ||
19 | |||
20 | void fatal(const char *fmt, ...) | ||
21 | { | ||
22 | va_list ap; | ||
23 | fprintf(stderr, "fatal error: "); | ||
24 | va_start(ap, fmt); | ||
25 | vfprintf(stderr, fmt, ap); | ||
26 | va_end(ap); | ||
27 | fprintf(stderr, "\n"); | ||
28 | exit(1); | ||
29 | } | ||
30 | |||
31 | struct frontend { | ||
32 | // TODO kill unneeded members! | ||
33 | midend *me; | ||
34 | bool timer_active; | ||
35 | struct timeval last_time; | ||
36 | config_item *cfg; | ||
37 | int cfg_which; | ||
38 | bool cfgret; | ||
39 | int ox, oy, w, h; | ||
40 | }; | ||
41 | |||
42 | static frontend *_fe; | ||
43 | |||
44 | void get_random_seed(void **randseed, int *randseedsize) | ||
45 | { | ||
46 | struct timeval *tvp = snew(struct timeval); | ||
47 | gettimeofday(tvp, NULL); | ||
48 | *randseed = (void *)tvp; | ||
49 | *randseedsize = sizeof(struct timeval); | ||
50 | } | ||
51 | |||
52 | void frontend_default_colour(frontend *fe, float *output) | ||
53 | { | ||
54 | output[0] = output[1]= output[2] = 0.8f; | ||
55 | } | ||
56 | |||
57 | void nestedvm_status_bar(void *handle, const char *text) | ||
58 | { | ||
59 | _call_java(4,0,(int)text,0); | ||
60 | } | ||
61 | |||
62 | void nestedvm_start_draw(void *handle) | ||
63 | { | ||
64 | frontend *fe = (frontend *)handle; | ||
65 | _call_java(5, 0, fe->w, fe->h); | ||
66 | _call_java(4, 1, fe->ox, fe->oy); | ||
67 | } | ||
68 | |||
69 | void nestedvm_clip(void *handle, int x, int y, int w, int h) | ||
70 | { | ||
71 | frontend *fe = (frontend *)handle; | ||
72 | _call_java(5, w, h, 0); | ||
73 | _call_java(4, 3, x + fe->ox, y + fe->oy); | ||
74 | } | ||
75 | |||
76 | void nestedvm_unclip(void *handle) | ||
77 | { | ||
78 | frontend *fe = (frontend *)handle; | ||
79 | _call_java(4, 4, fe->ox, fe->oy); | ||
80 | } | ||
81 | |||
82 | void nestedvm_draw_text(void *handle, int x, int y, int fonttype, int fontsize, | ||
83 | int align, int colour, const char *text) | ||
84 | { | ||
85 | frontend *fe = (frontend *)handle; | ||
86 | _call_java(5, x + fe->ox, y + fe->oy, | ||
87 | (fonttype == FONT_FIXED ? 0x10 : 0x0) | align); | ||
88 | _call_java(7, fontsize, colour, (int)text); | ||
89 | } | ||
90 | |||
91 | void nestedvm_draw_rect(void *handle, int x, int y, int w, int h, int colour) | ||
92 | { | ||
93 | frontend *fe = (frontend *)handle; | ||
94 | _call_java(5, w, h, colour); | ||
95 | _call_java(4, 5, x + fe->ox, y + fe->oy); | ||
96 | } | ||
97 | |||
98 | void nestedvm_draw_line(void *handle, int x1, int y1, int x2, int y2, | ||
99 | int colour) | ||
100 | { | ||
101 | frontend *fe = (frontend *)handle; | ||
102 | _call_java(5, x2 + fe->ox, y2 + fe->oy, colour); | ||
103 | _call_java(4, 6, x1 + fe->ox, y1 + fe->oy); | ||
104 | } | ||
105 | |||
106 | void nestedvm_draw_poly(void *handle, int *coords, int npoints, | ||
107 | int fillcolour, int outlinecolour) | ||
108 | { | ||
109 | frontend *fe = (frontend *)handle; | ||
110 | int i; | ||
111 | _call_java(4, 7, npoints, 0); | ||
112 | for (i = 0; i < npoints; i++) { | ||
113 | _call_java(6, i, coords[i*2] + fe->ox, coords[i*2+1] + fe->oy); | ||
114 | } | ||
115 | _call_java(4, 8, outlinecolour, fillcolour); | ||
116 | } | ||
117 | |||
118 | void nestedvm_draw_circle(void *handle, int cx, int cy, int radius, | ||
119 | int fillcolour, int outlinecolour) | ||
120 | { | ||
121 | frontend *fe = (frontend *)handle; | ||
122 | _call_java(5, cx+fe->ox, cy+fe->oy, radius); | ||
123 | _call_java(4, 9, outlinecolour, fillcolour); | ||
124 | } | ||
125 | |||
126 | struct blitter { | ||
127 | int handle, w, h, x, y; | ||
128 | }; | ||
129 | |||
130 | blitter *nestedvm_blitter_new(void *handle, int w, int h) | ||
131 | { | ||
132 | blitter *bl = snew(blitter); | ||
133 | bl->handle = -1; | ||
134 | bl->w = w; | ||
135 | bl->h = h; | ||
136 | return bl; | ||
137 | } | ||
138 | |||
139 | void nestedvm_blitter_free(void *handle, blitter *bl) | ||
140 | { | ||
141 | if (bl->handle != -1) | ||
142 | _call_java(4, 11, bl->handle, 0); | ||
143 | sfree(bl); | ||
144 | } | ||
145 | |||
146 | void nestedvm_blitter_save(void *handle, blitter *bl, int x, int y) | ||
147 | { | ||
148 | frontend *fe = (frontend *)handle; | ||
149 | if (bl->handle == -1) | ||
150 | bl->handle = _call_java(4,10,bl->w, bl->h); | ||
151 | bl->x = x; | ||
152 | bl->y = y; | ||
153 | _call_java(8, bl->handle, x + fe->ox, y + fe->oy); | ||
154 | } | ||
155 | |||
156 | void nestedvm_blitter_load(void *handle, blitter *bl, int x, int y) | ||
157 | { | ||
158 | frontend *fe = (frontend *)handle; | ||
159 | assert(bl->handle != -1); | ||
160 | if (x == BLITTER_FROMSAVED && y == BLITTER_FROMSAVED) { | ||
161 | x = bl->x; | ||
162 | y = bl->y; | ||
163 | } | ||
164 | _call_java(9, bl->handle, x + fe->ox, y + fe->oy); | ||
165 | } | ||
166 | |||
167 | void nestedvm_end_draw(void *handle) | ||
168 | { | ||
169 | _call_java(4,2,0,0); | ||
170 | } | ||
171 | |||
172 | char *nestedvm_text_fallback(void *handle, const char *const *strings, | ||
173 | int nstrings) | ||
174 | { | ||
175 | /* | ||
176 | * We assume Java can cope with any UTF-8 likely to be emitted | ||
177 | * by a puzzle. | ||
178 | */ | ||
179 | return dupstr(strings[0]); | ||
180 | } | ||
181 | |||
182 | const struct drawing_api nestedvm_drawing = { | ||
183 | nestedvm_draw_text, | ||
184 | nestedvm_draw_rect, | ||
185 | nestedvm_draw_line, | ||
186 | nestedvm_draw_poly, | ||
187 | nestedvm_draw_circle, | ||
188 | NULL, // draw_update, | ||
189 | nestedvm_clip, | ||
190 | nestedvm_unclip, | ||
191 | nestedvm_start_draw, | ||
192 | nestedvm_end_draw, | ||
193 | nestedvm_status_bar, | ||
194 | nestedvm_blitter_new, | ||
195 | nestedvm_blitter_free, | ||
196 | nestedvm_blitter_save, | ||
197 | nestedvm_blitter_load, | ||
198 | NULL, NULL, NULL, NULL, NULL, NULL, /* {begin,end}_{doc,page,puzzle} */ | ||
199 | NULL, NULL, /* line_width, line_dotted */ | ||
200 | nestedvm_text_fallback, | ||
201 | }; | ||
202 | |||
203 | int jcallback_key_event(int x, int y, int keyval) | ||
204 | { | ||
205 | frontend *fe = (frontend *)_fe; | ||
206 | if (fe->ox == -1) | ||
207 | return 1; | ||
208 | if (keyval >= 0 && | ||
209 | !midend_process_key(fe->me, x - fe->ox, y - fe->oy, keyval)) | ||
210 | return 42; | ||
211 | return 1; | ||
212 | } | ||
213 | |||
214 | int jcallback_resize(int width, int height) | ||
215 | { | ||
216 | frontend *fe = (frontend *)_fe; | ||
217 | int x, y; | ||
218 | x = width; | ||
219 | y = height; | ||
220 | midend_size(fe->me, &x, &y, true); | ||
221 | fe->ox = (width - x) / 2; | ||
222 | fe->oy = (height - y) / 2; | ||
223 | fe->w = x; | ||
224 | fe->h = y; | ||
225 | midend_force_redraw(fe->me); | ||
226 | return 0; | ||
227 | } | ||
228 | |||
229 | int jcallback_timer_func() | ||
230 | { | ||
231 | frontend *fe = (frontend *)_fe; | ||
232 | if (fe->timer_active) { | ||
233 | struct timeval now; | ||
234 | float elapsed; | ||
235 | gettimeofday(&now, NULL); | ||
236 | elapsed = ((now.tv_usec - fe->last_time.tv_usec) * 0.000001F + | ||
237 | (now.tv_sec - fe->last_time.tv_sec)); | ||
238 | midend_timer(fe->me, elapsed); /* may clear timer_active */ | ||
239 | fe->last_time = now; | ||
240 | } | ||
241 | return fe->timer_active; | ||
242 | } | ||
243 | |||
244 | void deactivate_timer(frontend *fe) | ||
245 | { | ||
246 | if (fe->timer_active) | ||
247 | _call_java(4, 13, 0, 0); | ||
248 | fe->timer_active = false; | ||
249 | } | ||
250 | |||
251 | void activate_timer(frontend *fe) | ||
252 | { | ||
253 | if (!fe->timer_active) { | ||
254 | _call_java(4, 12, 0, 0); | ||
255 | gettimeofday(&fe->last_time, NULL); | ||
256 | } | ||
257 | fe->timer_active = true; | ||
258 | } | ||
259 | |||
260 | void jcallback_config_ok() | ||
261 | { | ||
262 | frontend *fe = (frontend *)_fe; | ||
263 | const char *err; | ||
264 | |||
265 | err = midend_set_config(fe->me, fe->cfg_which, fe->cfg); | ||
266 | |||
267 | if (err) | ||
268 | _call_java(2, (int) "Error", (int)err, 1); | ||
269 | else { | ||
270 | fe->cfgret = true; | ||
271 | } | ||
272 | } | ||
273 | |||
274 | void jcallback_config_set_string(int item_ptr, int char_ptr) { | ||
275 | config_item *i = (config_item *)item_ptr; | ||
276 | char* newval = (char*) char_ptr; | ||
277 | assert(i->type == C_STRING); | ||
278 | sfree(i->u.string.sval); | ||
279 | i->u.string.sval = dupstr(newval); | ||
280 | free(newval); | ||
281 | } | ||
282 | |||
283 | void jcallback_config_set_boolean(int item_ptr, int selected) { | ||
284 | config_item *i = (config_item *)item_ptr; | ||
285 | assert(i->type == C_BOOLEAN); | ||
286 | i->u.boolean.bval = selected != 0 ? true : false; | ||
287 | } | ||
288 | |||
289 | void jcallback_config_set_choice(int item_ptr, int selected) { | ||
290 | config_item *i = (config_item *)item_ptr; | ||
291 | assert(i->type == C_CHOICES); | ||
292 | i->u.choices.selected = selected; | ||
293 | } | ||
294 | |||
295 | static bool get_config(frontend *fe, int which) | ||
296 | { | ||
297 | char *title; | ||
298 | config_item *i; | ||
299 | fe->cfg = midend_get_config(fe->me, which, &title); | ||
300 | fe->cfg_which = which; | ||
301 | fe->cfgret = false; | ||
302 | _call_java(10, (int)title, 0, 0); | ||
303 | for (i = fe->cfg; i->type != C_END; i++) { | ||
304 | _call_java(5, (int)i, i->type, (int)i->name); | ||
305 | switch (i->type) { | ||
306 | case C_STRING: | ||
307 | _call_java(11, (int)i->u.string.sval, 0, 0); | ||
308 | break; | ||
309 | case C_BOOLEAN: | ||
310 | _call_java(11, 0, i->u.boolean.bval, 0); | ||
311 | break; | ||
312 | case C_CHOICES: | ||
313 | _call_java(11, (int)i->u.choices.choicenames, | ||
314 | i->u.choices.selected, 0); | ||
315 | break; | ||
316 | } | ||
317 | } | ||
318 | _call_java(12,0,0,0); | ||
319 | free_cfg(fe->cfg); | ||
320 | return fe->cfgret; | ||
321 | } | ||
322 | |||
323 | int jcallback_newgame_event(void) | ||
324 | { | ||
325 | frontend *fe = (frontend *)_fe; | ||
326 | if (!midend_process_key(fe->me, 0, 0, UI_NEWGAME)) | ||
327 | return 42; | ||
328 | return 0; | ||
329 | } | ||
330 | |||
331 | int jcallback_undo_event(void) | ||
332 | { | ||
333 | frontend *fe = (frontend *)_fe; | ||
334 | if (!midend_process_key(fe->me, 0, 0, UI_UNDO)) | ||
335 | return 42; | ||
336 | return 0; | ||
337 | } | ||
338 | |||
339 | int jcallback_redo_event(void) | ||
340 | { | ||
341 | frontend *fe = (frontend *)_fe; | ||
342 | if (!midend_process_key(fe->me, 0, 0, UI_REDO)) | ||
343 | return 42; | ||
344 | return 0; | ||
345 | } | ||
346 | |||
347 | int jcallback_quit_event(void) | ||
348 | { | ||
349 | frontend *fe = (frontend *)_fe; | ||
350 | if (!midend_process_key(fe->me, 0, 0, UI_QUIT)) | ||
351 | return 42; | ||
352 | return 0; | ||
353 | } | ||
354 | |||
355 | static void resize_fe(frontend *fe) | ||
356 | { | ||
357 | int x, y; | ||
358 | |||
359 | x = INT_MAX; | ||
360 | y = INT_MAX; | ||
361 | midend_size(fe->me, &x, &y, false); | ||
362 | _call_java(3, x, y, 0); | ||
363 | } | ||
364 | |||
365 | int jcallback_preset_event(int ptr_game_params) | ||
366 | { | ||
367 | frontend *fe = (frontend *)_fe; | ||
368 | game_params *params = | ||
369 | (game_params *)ptr_game_params; | ||
370 | |||
371 | midend_set_params(fe->me, params); | ||
372 | midend_new_game(fe->me); | ||
373 | resize_fe(fe); | ||
374 | _call_java(13, midend_which_preset(fe->me), 0, 0); | ||
375 | return 0; | ||
376 | } | ||
377 | |||
378 | int jcallback_solve_event() | ||
379 | { | ||
380 | frontend *fe = (frontend *)_fe; | ||
381 | const char *msg; | ||
382 | |||
383 | msg = midend_solve(fe->me); | ||
384 | |||
385 | if (msg) | ||
386 | _call_java(2, (int) "Error", (int)msg, 1); | ||
387 | return 0; | ||
388 | } | ||
389 | |||
390 | int jcallback_restart_event() | ||
391 | { | ||
392 | frontend *fe = (frontend *)_fe; | ||
393 | |||
394 | midend_restart_game(fe->me); | ||
395 | return 0; | ||
396 | } | ||
397 | |||
398 | int jcallback_config_event(int which) | ||
399 | { | ||
400 | frontend *fe = (frontend *)_fe; | ||
401 | _call_java(13, midend_which_preset(fe->me), 0, 0); | ||
402 | if (!get_config(fe, which)) | ||
403 | return 0; | ||
404 | midend_new_game(fe->me); | ||
405 | resize_fe(fe); | ||
406 | _call_java(13, midend_which_preset(fe->me), 0, 0); | ||
407 | return 0; | ||
408 | } | ||
409 | |||
410 | int jcallback_about_event() | ||
411 | { | ||
412 | char titlebuf[256]; | ||
413 | char textbuf[1024]; | ||
414 | |||
415 | sprintf(titlebuf, "About %.200s", thegame.name); | ||
416 | sprintf(textbuf, | ||
417 | "%.200s\n\n" | ||
418 | "from Simon Tatham's Portable Puzzle Collection\n\n" | ||
419 | "%.500s", thegame.name, ver); | ||
420 | _call_java(2, (int)&titlebuf, (int)&textbuf, 0); | ||
421 | return 0; | ||
422 | } | ||
423 | |||
424 | void preset_menu_populate(struct preset_menu *menu, int menuid) | ||
425 | { | ||
426 | int i; | ||
427 | |||
428 | for (i = 0; i < menu->n_entries; i++) { | ||
429 | struct preset_menu_entry *entry = &menu->entries[i]; | ||
430 | if (entry->params) { | ||
431 | _call_java(5, (int)entry->params, 0, 0); | ||
432 | _call_java(1, (int)entry->title, menuid, entry->id); | ||
433 | } else { | ||
434 | _call_java(5, 0, 0, 0); | ||
435 | _call_java(1, (int)entry->title, menuid, entry->id); | ||
436 | preset_menu_populate(entry->submenu, entry->id); | ||
437 | } | ||
438 | } | ||
439 | } | ||
440 | |||
441 | int main(int argc, char **argv) | ||
442 | { | ||
443 | int i, n; | ||
444 | float* colours; | ||
445 | |||
446 | _fe = snew(frontend); | ||
447 | _fe->timer_active = false; | ||
448 | _fe->me = midend_new(_fe, &thegame, &nestedvm_drawing, _fe); | ||
449 | if (argc > 1) | ||
450 | midend_game_id(_fe->me, argv[1]); /* ignore failure */ | ||
451 | midend_new_game(_fe->me); | ||
452 | |||
453 | { | ||
454 | struct preset_menu *menu; | ||
455 | int nids, topmenu; | ||
456 | menu = midend_get_presets(_fe->me, &nids); | ||
457 | topmenu = _call_java(1, 0, nids, 0); | ||
458 | preset_menu_populate(menu, topmenu); | ||
459 | } | ||
460 | |||
461 | colours = midend_colours(_fe->me, &n); | ||
462 | _fe->ox = -1; | ||
463 | |||
464 | _call_java(0, (int)thegame.name, | ||
465 | (thegame.can_configure ? 1 : 0) | | ||
466 | (midend_wants_statusbar(_fe->me) ? 2 : 0) | | ||
467 | (thegame.can_solve ? 4 : 0), n); | ||
468 | for (i = 0; i < n; i++) { | ||
469 | _call_java(1024+ i, | ||
470 | (int)(colours[i*3] * 0xFF), | ||
471 | (int)(colours[i*3+1] * 0xFF), | ||
472 | (int)(colours[i*3+2] * 0xFF)); | ||
473 | } | ||
474 | resize_fe(_fe); | ||
475 | |||
476 | _call_java(13, midend_which_preset(_fe->me), 0, 0); | ||
477 | |||
478 | // Now pause the vm. The VM will be call()ed when | ||
479 | // an input event occurs. | ||
480 | _pause(); | ||
481 | |||
482 | // shut down when the VM is resumed. | ||
483 | deactivate_timer(_fe); | ||
484 | midend_free(_fe->me); | ||
485 | return 0; | ||
486 | } | ||