2
* nestedvm.c: NestedVM front end for my puzzle collection.
18
extern int _call_java(int cmd, int arg1, int arg2, int arg3);
20
void fatal(char *fmt, ...)
23
fprintf(stderr, "fatal error: ");
25
vfprintf(stderr, fmt, ap);
27
fprintf(stderr, "\n");
32
// TODO kill unneeded members!
35
struct timeval last_time;
37
int cfg_which, cfgret;
43
void get_random_seed(void **randseed, int *randseedsize)
45
struct timeval *tvp = snew(struct timeval);
46
gettimeofday(tvp, NULL);
47
*randseed = (void *)tvp;
48
*randseedsize = sizeof(struct timeval);
51
void frontend_default_colour(frontend *fe, float *output)
53
output[0] = output[1]= output[2] = 0.8f;
56
void nestedvm_status_bar(void *handle, char *text)
58
_call_java(4,0,(int)text,0);
61
void nestedvm_start_draw(void *handle)
63
frontend *fe = (frontend *)handle;
64
_call_java(4, 1, fe->ox, fe->oy);
67
void nestedvm_clip(void *handle, int x, int y, int w, int h)
69
frontend *fe = (frontend *)handle;
70
_call_java(5, w, h, 0);
71
_call_java(4, 3, x + fe->ox, y + fe->oy);
74
void nestedvm_unclip(void *handle)
76
frontend *fe = (frontend *)handle;
77
_call_java(4, 4, fe->ox, fe->oy);
80
void nestedvm_draw_text(void *handle, int x, int y, int fonttype, int fontsize,
81
int align, int colour, char *text)
83
frontend *fe = (frontend *)handle;
84
_call_java(5, x + fe->ox, y + fe->oy,
85
(fonttype == FONT_FIXED ? 0x10 : 0x0) | align);
86
_call_java(7, fontsize, colour, (int)text);
89
void nestedvm_draw_rect(void *handle, int x, int y, int w, int h, int colour)
91
frontend *fe = (frontend *)handle;
92
_call_java(5, w, h, colour);
93
_call_java(4, 5, x + fe->ox, y + fe->oy);
96
void nestedvm_draw_line(void *handle, int x1, int y1, int x2, int y2,
99
frontend *fe = (frontend *)handle;
100
_call_java(5, x2 + fe->ox, y2 + fe->oy, colour);
101
_call_java(4, 6, x1 + fe->ox, y1 + fe->oy);
104
void nestedvm_draw_poly(void *handle, int *coords, int npoints,
105
int fillcolour, int outlinecolour)
107
frontend *fe = (frontend *)handle;
109
_call_java(4, 7, npoints, 0);
110
for (i = 0; i < npoints; i++) {
111
_call_java(6, i, coords[i*2] + fe->ox, coords[i*2+1] + fe->oy);
113
_call_java(4, 8, outlinecolour, fillcolour);
116
void nestedvm_draw_circle(void *handle, int cx, int cy, int radius,
117
int fillcolour, int outlinecolour)
119
frontend *fe = (frontend *)handle;
120
_call_java(5, cx+fe->ox, cy+fe->oy, radius);
121
_call_java(4, 9, outlinecolour, fillcolour);
125
int handle, w, h, x, y;
128
blitter *nestedvm_blitter_new(void *handle, int w, int h)
130
blitter *bl = snew(blitter);
137
void nestedvm_blitter_free(void *handle, blitter *bl)
139
if (bl->handle != -1)
140
_call_java(4, 11, bl->handle, 0);
144
void nestedvm_blitter_save(void *handle, blitter *bl, int x, int y)
146
frontend *fe = (frontend *)handle;
147
if (bl->handle == -1)
148
bl->handle = _call_java(4,10,bl->w, bl->h);
151
_call_java(8, bl->handle, x + fe->ox, y + fe->oy);
154
void nestedvm_blitter_load(void *handle, blitter *bl, int x, int y)
156
frontend *fe = (frontend *)handle;
157
assert(bl->handle != -1);
158
if (x == BLITTER_FROMSAVED && y == BLITTER_FROMSAVED) {
162
_call_java(9, bl->handle, x + fe->ox, y + fe->oy);
165
void nestedvm_end_draw(void *handle)
170
const struct drawing_api nestedvm_drawing = {
175
nestedvm_draw_circle,
176
NULL, // draw_update,
182
nestedvm_blitter_new,
183
nestedvm_blitter_free,
184
nestedvm_blitter_save,
185
nestedvm_blitter_load,
186
NULL, NULL, NULL, NULL, NULL, NULL, /* {begin,end}_{doc,page,puzzle} */
187
NULL, /* line_width */
190
int jcallback_key_event(int x, int y, int keyval)
192
frontend *fe = (frontend *)_fe;
196
!midend_process_key(fe->me, x - fe->ox, y - fe->oy, keyval))
201
int jcallback_resize(int width, int height)
203
frontend *fe = (frontend *)_fe;
207
midend_size(fe->me, &x, &y, TRUE);
208
fe->ox = (width - x) / 2;
209
fe->oy = (height - y) / 2;
210
midend_force_redraw(fe->me);
214
int jcallback_timer_func()
216
frontend *fe = (frontend *)_fe;
217
if (fe->timer_active) {
220
gettimeofday(&now, NULL);
221
elapsed = ((now.tv_usec - fe->last_time.tv_usec) * 0.000001F +
222
(now.tv_sec - fe->last_time.tv_sec));
223
midend_timer(fe->me, elapsed); /* may clear timer_active */
226
return fe->timer_active;
229
void deactivate_timer(frontend *fe)
231
if (fe->timer_active)
232
_call_java(4, 13, 0, 0);
233
fe->timer_active = FALSE;
236
void activate_timer(frontend *fe)
238
if (!fe->timer_active) {
239
_call_java(4, 12, 0, 0);
240
gettimeofday(&fe->last_time, NULL);
242
fe->timer_active = TRUE;
245
void jcallback_config_ok()
247
frontend *fe = (frontend *)_fe;
250
err = midend_set_config(fe->me, fe->cfg_which, fe->cfg);
253
_call_java(2, (int) "Error", (int)err, 1);
259
void jcallback_config_set_string(int item_ptr, int char_ptr) {
260
config_item *i = (config_item *)item_ptr;
261
char* newval = (char*) char_ptr;
263
i->sval = dupstr(newval);
267
void jcallback_config_set_boolean(int item_ptr, int selected) {
268
config_item *i = (config_item *)item_ptr;
269
i->ival = selected != 0 ? TRUE : FALSE;
272
void jcallback_config_set_choice(int item_ptr, int selected) {
273
config_item *i = (config_item *)item_ptr;
277
static int get_config(frontend *fe, int which)
281
fe->cfg = midend_get_config(fe->me, which, &title);
282
fe->cfg_which = which;
284
_call_java(10, (int)title, 0, 0);
285
for (i = fe->cfg; i->type != C_END; i++) {
286
_call_java(5, (int)i, i->type, (int)i->name);
287
_call_java(11, (int)i->sval, i->ival, 0);
289
_call_java(12,0,0,0);
294
int jcallback_menu_key_event(int key)
296
frontend *fe = (frontend *)_fe;
297
if (!midend_process_key(fe->me, 0, 0, key))
302
static void resize_fe(frontend *fe)
308
midend_size(fe->me, &x, &y, FALSE);
309
_call_java(3, x, y, 0);
312
int jcallback_preset_event(int ptr_game_params)
314
frontend *fe = (frontend *)_fe;
315
game_params *params =
316
(game_params *)ptr_game_params;
318
midend_set_params(fe->me, params);
319
midend_new_game(fe->me);
321
_call_java(13, midend_which_preset(fe->me), 0, 0);
325
int jcallback_solve_event()
327
frontend *fe = (frontend *)_fe;
330
msg = midend_solve(fe->me);
333
_call_java(2, (int) "Error", (int)msg, 1);
337
int jcallback_restart_event()
339
frontend *fe = (frontend *)_fe;
341
midend_restart_game(fe->me);
345
int jcallback_config_event(int which)
347
frontend *fe = (frontend *)_fe;
348
_call_java(13, midend_which_preset(fe->me), 0, 0);
349
if (!get_config(fe, which))
351
midend_new_game(fe->me);
353
_call_java(13, midend_which_preset(fe->me), 0, 0);
357
int jcallback_about_event()
362
sprintf(titlebuf, "About %.200s", thegame.name);
365
"from Simon Tatham's Portable Puzzle Collection\n\n"
366
"%.500s", thegame.name, ver);
367
_call_java(2, (int)&titlebuf, (int)&textbuf, 0);
371
int main(int argc, char **argv)
376
_fe = snew(frontend);
377
_fe->timer_active = FALSE;
378
_fe->me = midend_new(_fe, &thegame, &nestedvm_drawing, _fe);
380
midend_game_id(_fe->me, argv[1]); /* ignore failure */
381
midend_new_game(_fe->me);
383
if ((n = midend_num_presets(_fe->me)) > 0) {
385
for (i = 0; i < n; i++) {
388
midend_fetch_preset(_fe->me, i, &name, ¶ms);
389
_call_java(1, (int)name, (int)params, 0);
393
colours = midend_colours(_fe->me, &n);
396
_call_java(0, (int)thegame.name,
397
(thegame.can_configure ? 1 : 0) |
398
(midend_wants_statusbar(_fe->me) ? 2 : 0) |
399
(thegame.can_solve ? 4 : 0), n);
400
for (i = 0; i < n; i++) {
402
(int)(colours[i*3] * 0xFF),
403
(int)(colours[i*3+1] * 0xFF),
404
(int)(colours[i*3+2] * 0xFF));
408
_call_java(13, midend_which_preset(_fe->me), 0, 0);
410
// Now pause the vm. The VM will be call()ed when
411
// an input event occurs.
414
// shut down when the VM is resumed.
415
deactivate_timer(_fe);
416
midend_free(_fe->me);