~ubuntu-branches/ubuntu/lucid/sgt-puzzles/lucid

« back to all changes in this revision

Viewing changes to nestedvm.c

  • Committer: Bazaar Package Importer
  • Author(s): Didier Roche
  • Date: 2009-05-03 14:54:23 UTC
  • mfrom: (1.1.7 upstream) (3.1.3 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090503145423-o4d0ubd8ocykbad8
Tags: 8446-1ubuntu1
* Merge from debian unstable, remaining changes:
  - typos in debian/desktop/netslide.desktop (Exec=netslide)
  - xpm icons files for the menus
  - debian/rules adapted to install desktop and icons files.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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(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
    int timer_active;
 
35
    struct timeval last_time;
 
36
    config_item *cfg;
 
37
    int cfg_which, cfgret;
 
38
    int ox, oy;
 
39
};
 
40
 
 
41
static frontend *_fe;
 
42
 
 
43
void get_random_seed(void **randseed, int *randseedsize)
 
44
{
 
45
    struct timeval *tvp = snew(struct timeval);
 
46
    gettimeofday(tvp, NULL);
 
47
    *randseed = (void *)tvp;
 
48
    *randseedsize = sizeof(struct timeval);
 
49
}
 
50
 
 
51
void frontend_default_colour(frontend *fe, float *output)
 
52
{
 
53
    output[0] = output[1]= output[2] = 0.8f;
 
54
}
 
55
 
 
56
void nestedvm_status_bar(void *handle, char *text)
 
57
{
 
58
    _call_java(4,0,(int)text,0);
 
59
}
 
60
 
 
61
void nestedvm_start_draw(void *handle)
 
62
{
 
63
    frontend *fe = (frontend *)handle;
 
64
    _call_java(4, 1, fe->ox, fe->oy);
 
65
}
 
66
 
 
67
void nestedvm_clip(void *handle, int x, int y, int w, int h)
 
68
{
 
69
    frontend *fe = (frontend *)handle;
 
70
    _call_java(5, w, h, 0);
 
71
    _call_java(4, 3, x + fe->ox, y + fe->oy);
 
72
}
 
73
 
 
74
void nestedvm_unclip(void *handle)
 
75
{
 
76
    frontend *fe = (frontend *)handle;
 
77
    _call_java(4, 4, fe->ox, fe->oy);
 
78
}
 
79
 
 
80
void nestedvm_draw_text(void *handle, int x, int y, int fonttype, int fontsize,
 
81
                   int align, int colour, char *text)
 
82
{
 
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);
 
87
}
 
88
 
 
89
void nestedvm_draw_rect(void *handle, int x, int y, int w, int h, int colour)
 
90
{
 
91
    frontend *fe = (frontend *)handle;
 
92
    _call_java(5, w, h, colour);
 
93
    _call_java(4, 5, x + fe->ox, y + fe->oy);
 
94
}
 
95
 
 
96
void nestedvm_draw_line(void *handle, int x1, int y1, int x2, int y2, 
 
97
                        int colour)
 
98
{
 
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);
 
102
}
 
103
 
 
104
void nestedvm_draw_poly(void *handle, int *coords, int npoints,
 
105
                        int fillcolour, int outlinecolour)
 
106
{
 
107
    frontend *fe = (frontend *)handle;
 
108
    int i;
 
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);
 
112
    }
 
113
    _call_java(4, 8, outlinecolour, fillcolour);
 
114
}
 
115
 
 
116
void nestedvm_draw_circle(void *handle, int cx, int cy, int radius,
 
117
                     int fillcolour, int outlinecolour)
 
118
{
 
119
    frontend *fe = (frontend *)handle;
 
120
    _call_java(5, cx+fe->ox, cy+fe->oy, radius);
 
121
    _call_java(4, 9, outlinecolour, fillcolour);
 
122
}
 
123
 
 
124
struct blitter {
 
125
    int handle, w, h, x, y;
 
126
};
 
127
 
 
128
blitter *nestedvm_blitter_new(void *handle, int w, int h)
 
129
{
 
130
    blitter *bl = snew(blitter);
 
131
    bl->handle = -1;
 
132
    bl->w = w;
 
133
    bl->h = h;
 
134
    return bl;
 
135
}
 
136
 
 
137
void nestedvm_blitter_free(void *handle, blitter *bl)
 
138
{
 
139
    if (bl->handle != -1)
 
140
        _call_java(4, 11, bl->handle, 0);
 
141
    sfree(bl);
 
142
}
 
143
 
 
144
void nestedvm_blitter_save(void *handle, blitter *bl, int x, int y)
 
145
{
 
146
    frontend *fe = (frontend *)handle;    
 
147
    if (bl->handle == -1)
 
148
        bl->handle = _call_java(4,10,bl->w, bl->h);
 
149
    bl->x = x;
 
150
    bl->y = y;
 
151
    _call_java(8, bl->handle, x + fe->ox, y + fe->oy);
 
152
}
 
153
 
 
154
void nestedvm_blitter_load(void *handle, blitter *bl, int x, int y)
 
155
{
 
156
    frontend *fe = (frontend *)handle;
 
157
    assert(bl->handle != -1);
 
158
    if (x == BLITTER_FROMSAVED && y == BLITTER_FROMSAVED) {
 
159
        x = bl->x;
 
160
        y = bl->y;
 
161
    }
 
162
    _call_java(9, bl->handle, x + fe->ox, y + fe->oy);
 
163
}
 
164
 
 
165
void nestedvm_end_draw(void *handle)
 
166
{
 
167
    _call_java(4,2,0,0);
 
168
}
 
169
 
 
170
const struct drawing_api nestedvm_drawing = {
 
171
    nestedvm_draw_text,
 
172
    nestedvm_draw_rect,
 
173
    nestedvm_draw_line,
 
174
    nestedvm_draw_poly,
 
175
    nestedvm_draw_circle,
 
176
    NULL, // draw_update,
 
177
    nestedvm_clip,
 
178
    nestedvm_unclip,
 
179
    nestedvm_start_draw,
 
180
    nestedvm_end_draw,
 
181
    nestedvm_status_bar,
 
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 */
 
188
};
 
189
 
 
190
int jcallback_key_event(int x, int y, int keyval)
 
191
{
 
192
    frontend *fe = (frontend *)_fe;
 
193
    if (fe->ox == -1)
 
194
        return 1;
 
195
    if (keyval >= 0 &&
 
196
        !midend_process_key(fe->me, x - fe->ox, y - fe->oy, keyval))
 
197
        return 42;
 
198
    return 1;
 
199
}
 
200
 
 
201
int jcallback_resize(int width, int height)
 
202
{
 
203
    frontend *fe = (frontend *)_fe;
 
204
    int x, y;
 
205
    x = width;
 
206
    y = height;
 
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);
 
211
    return 0;
 
212
}
 
213
 
 
214
int jcallback_timer_func()
 
215
{
 
216
    frontend *fe = (frontend *)_fe;
 
217
    if (fe->timer_active) {
 
218
        struct timeval now;
 
219
        float elapsed;
 
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 */
 
224
        fe->last_time = now;
 
225
    }
 
226
    return fe->timer_active;
 
227
}
 
228
 
 
229
void deactivate_timer(frontend *fe)
 
230
{
 
231
    if (fe->timer_active)
 
232
        _call_java(4, 13, 0, 0);
 
233
    fe->timer_active = FALSE;
 
234
}
 
235
 
 
236
void activate_timer(frontend *fe)
 
237
{
 
238
    if (!fe->timer_active) {
 
239
        _call_java(4, 12, 0, 0);
 
240
        gettimeofday(&fe->last_time, NULL);
 
241
    }
 
242
    fe->timer_active = TRUE;
 
243
}
 
244
 
 
245
void jcallback_config_ok()
 
246
{
 
247
    frontend *fe = (frontend *)_fe;
 
248
    char *err;
 
249
 
 
250
    err = midend_set_config(fe->me, fe->cfg_which, fe->cfg);
 
251
 
 
252
    if (err)
 
253
        _call_java(2, (int) "Error", (int)err, 1);
 
254
    else {
 
255
        fe->cfgret = TRUE;
 
256
    }
 
257
}
 
258
 
 
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;
 
262
    sfree(i->sval);
 
263
    i->sval = dupstr(newval);
 
264
    free(newval);
 
265
}
 
266
 
 
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;
 
270
}
 
271
 
 
272
void jcallback_config_set_choice(int item_ptr, int selected) {
 
273
    config_item *i = (config_item *)item_ptr;
 
274
    i->ival = selected;
 
275
}
 
276
 
 
277
static int get_config(frontend *fe, int which)
 
278
{
 
279
    char *title;
 
280
    config_item *i;
 
281
    fe->cfg = midend_get_config(fe->me, which, &title);
 
282
    fe->cfg_which = which;
 
283
    fe->cfgret = FALSE;
 
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);
 
288
    }
 
289
    _call_java(12,0,0,0);
 
290
    free_cfg(fe->cfg);
 
291
    return fe->cfgret;
 
292
}
 
293
 
 
294
int jcallback_menu_key_event(int key)
 
295
{
 
296
    frontend *fe = (frontend *)_fe;
 
297
    if (!midend_process_key(fe->me, 0, 0, key))
 
298
        return 42;
 
299
    return 0;
 
300
}
 
301
 
 
302
static void resize_fe(frontend *fe)
 
303
{
 
304
    int x, y;
 
305
 
 
306
    x = INT_MAX;
 
307
    y = INT_MAX;
 
308
    midend_size(fe->me, &x, &y, FALSE);
 
309
    _call_java(3, x, y, 0);
 
310
}
 
311
 
 
312
int jcallback_preset_event(int ptr_game_params)
 
313
{
 
314
    frontend *fe = (frontend *)_fe;
 
315
    game_params *params =
 
316
        (game_params *)ptr_game_params;
 
317
 
 
318
    midend_set_params(fe->me, params);
 
319
    midend_new_game(fe->me);
 
320
    resize_fe(fe);
 
321
    _call_java(13, midend_which_preset(fe->me), 0, 0);
 
322
    return 0;
 
323
}
 
324
 
 
325
int jcallback_solve_event()
 
326
{
 
327
    frontend *fe = (frontend *)_fe;
 
328
    char *msg;
 
329
 
 
330
    msg = midend_solve(fe->me);
 
331
 
 
332
    if (msg)
 
333
        _call_java(2, (int) "Error", (int)msg, 1);
 
334
    return 0;
 
335
}
 
336
 
 
337
int jcallback_restart_event()
 
338
{
 
339
    frontend *fe = (frontend *)_fe;
 
340
 
 
341
    midend_restart_game(fe->me);
 
342
    return 0;
 
343
}
 
344
 
 
345
int jcallback_config_event(int which)
 
346
{
 
347
    frontend *fe = (frontend *)_fe;
 
348
    _call_java(13, midend_which_preset(fe->me), 0, 0);
 
349
    if (!get_config(fe, which))
 
350
        return 0;
 
351
    midend_new_game(fe->me);
 
352
    resize_fe(fe);
 
353
    _call_java(13, midend_which_preset(fe->me), 0, 0);
 
354
    return 0;
 
355
}
 
356
 
 
357
int jcallback_about_event()
 
358
{
 
359
    char titlebuf[256];
 
360
    char textbuf[1024];
 
361
 
 
362
    sprintf(titlebuf, "About %.200s", thegame.name);
 
363
    sprintf(textbuf,
 
364
            "%.200s\n\n"
 
365
            "from Simon Tatham's Portable Puzzle Collection\n\n"
 
366
            "%.500s", thegame.name, ver);
 
367
    _call_java(2, (int)&titlebuf, (int)&textbuf, 0);
 
368
    return 0;
 
369
}
 
370
 
 
371
int main(int argc, char **argv)
 
372
{
 
373
    int i, n;
 
374
    float* colours;
 
375
 
 
376
    _fe = snew(frontend);
 
377
    _fe->timer_active = FALSE;
 
378
    _fe->me = midend_new(_fe, &thegame, &nestedvm_drawing, _fe);
 
379
    if (argc > 1)
 
380
        midend_game_id(_fe->me, argv[1]);   /* ignore failure */
 
381
    midend_new_game(_fe->me);
 
382
 
 
383
    if ((n = midend_num_presets(_fe->me)) > 0) {
 
384
        int i;
 
385
        for (i = 0; i < n; i++) {
 
386
            char *name;
 
387
            game_params *params;
 
388
            midend_fetch_preset(_fe->me, i, &name, &params);
 
389
            _call_java(1, (int)name, (int)params, 0);
 
390
        }
 
391
    }
 
392
 
 
393
    colours = midend_colours(_fe->me, &n);
 
394
    _fe->ox = -1;
 
395
 
 
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++) {
 
401
        _call_java(1024+ i,
 
402
                   (int)(colours[i*3] * 0xFF),
 
403
                   (int)(colours[i*3+1] * 0xFF),
 
404
                   (int)(colours[i*3+2] * 0xFF));
 
405
    }
 
406
    resize_fe(_fe);
 
407
 
 
408
    _call_java(13, midend_which_preset(_fe->me), 0, 0);
 
409
 
 
410
    // Now pause the vm. The VM will be call()ed when
 
411
    // an input event occurs.
 
412
    _pause();
 
413
 
 
414
    // shut down when the VM is resumed.
 
415
    deactivate_timer(_fe);
 
416
    midend_free(_fe->me);
 
417
    return 0;
 
418
}