summaryrefslogtreecommitdiff
path: root/apps/plugins/puzzles/src/nestedvm.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/puzzles/src/nestedvm.c')
-rw-r--r--apps/plugins/puzzles/src/nestedvm.c486
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
17extern void _pause();
18extern int _call_java(int cmd, int arg1, int arg2, int arg3);
19
20void 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
31struct 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
42static frontend *_fe;
43
44void 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
52void frontend_default_colour(frontend *fe, float *output)
53{
54 output[0] = output[1]= output[2] = 0.8f;
55}
56
57void nestedvm_status_bar(void *handle, const char *text)
58{
59 _call_java(4,0,(int)text,0);
60}
61
62void 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
69void 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
76void nestedvm_unclip(void *handle)
77{
78 frontend *fe = (frontend *)handle;
79 _call_java(4, 4, fe->ox, fe->oy);
80}
81
82void 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
91void 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
98void 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
106void 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
118void 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
126struct blitter {
127 int handle, w, h, x, y;
128};
129
130blitter *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
139void 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
146void 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
156void 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
167void nestedvm_end_draw(void *handle)
168{
169 _call_java(4,2,0,0);
170}
171
172char *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
182const 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
203int 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
214int 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
229int 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
244void deactivate_timer(frontend *fe)
245{
246 if (fe->timer_active)
247 _call_java(4, 13, 0, 0);
248 fe->timer_active = false;
249}
250
251void 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
260void 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
274void 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
283void 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
289void 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
295static 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
323int 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
331int 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
339int 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
347int 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
355static 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
365int 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
378int 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
390int jcallback_restart_event()
391{
392 frontend *fe = (frontend *)_fe;
393
394 midend_restart_game(fe->me);
395 return 0;
396}
397
398int 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
410int 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
424void 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
441int 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}