~ml-launchpad/ubuntu/natty/gcompris/fix-for-777349

« back to all changes in this revision

Viewing changes to src/boards/railroad.c

  • Committer: Bazaar Package Importer
  • Author(s): Marc Gariepy, Marc Gariepy, Stephane Graber
  • Date: 2010-01-04 17:42:49 UTC
  • mfrom: (1.1.14 upstream)
  • Revision ID: james.westby@ubuntu.com-20100104174249-7bupatd9dtxyhvs4
Tags: 9.0-0ubuntu1
[Marc Gariepy]
* New upstream release (9.0).
* Remove cache.c from POTFILES to avoid FTBFS
* Remove unneeded rm in debian/rules (file no longer exists upstream)

[Stephane Graber]
* Bump Debian standards to 3.8.3
* Add patch system (dpatch)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* gcompris - railroad.c
2
 
 *
3
 
 * Copyright (C) 2001 Pascal Georges
4
 
 *
5
 
 *   This program is free software; you can redistribute it and/or modify
6
 
 *   it under the terms of the GNU General Public License as published by
7
 
 *   the Free Software Foundation; either version 3 of the License, or
8
 
 *   (at your option) any later version.
9
 
 *
10
 
 *   This program is distributed in the hope that it will be useful,
11
 
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 *   GNU General Public License for more details.
14
 
 *
15
 
 *   You should have received a copy of the GNU General Public License
16
 
 *   along with this program; if not, see <http://www.gnu.org/licenses/>.
17
 
 */
18
 
 
19
 
#include "gcompris/gcompris.h"
20
 
 
21
 
#define SOUNDLISTFILE PACKAGE
22
 
 
23
 
static GcomprisBoard *gcomprisBoard = NULL;
24
 
static gboolean board_paused = TRUE;
25
 
 
26
 
static void              start_board (GcomprisBoard *agcomprisBoard);
27
 
static void              pause_board (gboolean pause);
28
 
static void              end_board (void);
29
 
static gboolean          is_our_board (GcomprisBoard *gcomprisBoard);
30
 
static void              set_level (guint level);
31
 
static int gamewon;
32
 
static void              process_ok(void);
33
 
static void              game_won(void);
34
 
static void              repeat(void);
35
 
static void              animate_model(void);
36
 
static gboolean          animate_step(void);
37
 
 
38
 
#define ENGINES 9
39
 
#define WAGONS 13
40
 
#define NUMBER_OF_SUBLEVELS 3
41
 
#define NUMBER_OF_LEVELS 3
42
 
#define MODEL_MAX_SIZE NUMBER_OF_LEVELS+1
43
 
 
44
 
static const int line[] = { 100,180,260,340, 420, 500};
45
 
static gboolean animation_pending;
46
 
static gint animation_count = 0;
47
 
 
48
 
static GnomeCanvasGroup *boardRootItem = NULL;
49
 
 
50
 
static GnomeCanvasGroup *allwagonsRootItem = NULL;
51
 
static GnomeCanvasGroup *modelRootItem = NULL;
52
 
static GnomeCanvasGroup *answerRootItem = NULL;
53
 
 
54
 
static GList * listPixmapEngines = NULL;
55
 
static GList * listPixmapWagons = NULL;
56
 
 
57
 
// ==========================================
58
 
// In all the lists below, 0 is the LEFTmost vehicle|
59
 
// ==========================================
60
 
// contains the list of vehicles to be found.
61
 
static GnomeCanvasItem *item_model[MODEL_MAX_SIZE];
62
 
// contains the list of vehicles proposed by child.
63
 
static GList *item_answer_list = NULL;
64
 
// contains the list of vehicles proposed by child.
65
 
static GList *int_answer_list = NULL;
66
 
// contains the list of vehicles to be found
67
 
static GList *int_model_list = NULL;
68
 
 
69
 
static int model_size = 0;
70
 
static gint timer_id;
71
 
 
72
 
static GnomeCanvasItem *railroad_create_item(GnomeCanvasGroup *parent);
73
 
static void railroad_destroy_all_items(void);
74
 
static void railroad_next_level(void);
75
 
static gint item_event(GnomeCanvasItem *item, GdkEvent *event, gpointer data);
76
 
static gint answer_event(GnomeCanvasItem *item, GdkEvent *event, gpointer data);
77
 
 
78
 
static void reposition_model(void);
79
 
static void reposition_answer(void);
80
 
 
81
 
// helper function because g_list_free does not actually reset a list
82
 
static GList * reset_list(GList * list);
83
 
static void reset_all_lists(void);
84
 
 
85
 
/* Description of this plugin */
86
 
static BoardPlugin menu_bp =
87
 
  {
88
 
    NULL,
89
 
    NULL,
90
 
    N_("Memory game"),
91
 
    N_("Build a train according to the model"),
92
 
    "Pascal Georges pascal.georges1@free.fr>",
93
 
    NULL,
94
 
    NULL,
95
 
    NULL,
96
 
    NULL,
97
 
    start_board,
98
 
    pause_board,
99
 
    end_board,
100
 
    is_our_board,
101
 
    NULL,
102
 
    process_ok,
103
 
    set_level,
104
 
    NULL,
105
 
    repeat,
106
 
    NULL,
107
 
    NULL
108
 
  };
109
 
 
110
 
/*
111
 
 * Main entry point mandatory for each Gcompris's game
112
 
 * ---------------------------------------------------
113
 
 *
114
 
 */
115
 
 
116
 
GET_BPLUGIN_INFO(railroad)
117
 
 
118
 
/*
119
 
 * in : boolean TRUE = PAUSE : FALSE = CONTINUE
120
 
 *
121
 
 */
122
 
static void pause_board (gboolean pause)
123
 
{
124
 
  if(gcomprisBoard==NULL)
125
 
    return;
126
 
 
127
 
  if(gamewon == TRUE && pause == FALSE) /* the game is won */
128
 
    {
129
 
      game_won();
130
 
    }
131
 
 
132
 
  board_paused = pause;
133
 
}
134
 
 
135
 
/* ======================================= */
136
 
static void start_board (GcomprisBoard *agcomprisBoard)
137
 
{
138
 
  int i;
139
 
  char *str;
140
 
  GdkPixbuf *pixmap = NULL;
141
 
 
142
 
  if(agcomprisBoard!=NULL)
143
 
    {
144
 
      gcomprisBoard=agcomprisBoard;
145
 
      gc_set_background(gnome_canvas_root(gcomprisBoard->canvas),
146
 
                              "opt/railroad-bg.png");
147
 
 
148
 
      for (i=0; i<ENGINES; i++) {
149
 
        str = g_strdup_printf("railroad/loco%d.png", i+1);
150
 
        pixmap = gc_pixmap_load(str);
151
 
        listPixmapEngines = g_list_append(listPixmapEngines, pixmap);
152
 
        g_free(str);
153
 
      }
154
 
 
155
 
      for (i=0; i<WAGONS; i++) {
156
 
        str = g_strdup_printf("railroad/wagon%d.png", i+1);
157
 
        pixmap = gc_pixmap_load(str);
158
 
        listPixmapWagons = g_list_append(listPixmapWagons, pixmap);
159
 
        g_free(str);
160
 
      }
161
 
 
162
 
      animation_pending = FALSE;
163
 
      gcomprisBoard->level=1;
164
 
      gcomprisBoard->maxlevel=NUMBER_OF_LEVELS;
165
 
      gcomprisBoard->sublevel=1;
166
 
      gcomprisBoard->number_of_sublevel=NUMBER_OF_SUBLEVELS; /* Go to next level after this number of 'play' */
167
 
      gc_score_start(SCORESTYLE_NOTE,
168
 
                           gcomprisBoard->width - 220,
169
 
                           gcomprisBoard->height - 50,
170
 
                           gcomprisBoard->number_of_sublevel);
171
 
 
172
 
 
173
 
      str = gc_skin_image_get("button_reload.png");
174
 
      pixmap = gc_pixmap_load(str);
175
 
      g_free(str);
176
 
      if(pixmap) {
177
 
        gc_bar_set_repeat_icon(pixmap);
178
 
        gdk_pixbuf_unref(pixmap);
179
 
        gc_bar_set(GC_BAR_LEVEL|GC_BAR_OK|GC_BAR_REPEAT_ICON);
180
 
      } else {
181
 
        gc_bar_set(GC_BAR_LEVEL|GC_BAR_OK|GC_BAR_REPEAT);
182
 
      }
183
 
 
184
 
      railroad_next_level();
185
 
 
186
 
      gamewon = FALSE;
187
 
      pause_board(FALSE);
188
 
    }
189
 
}
190
 
/* ======================================= */
191
 
static void end_board ()
192
 
{
193
 
  GdkPixbuf * pixmap = NULL;
194
 
  // If we don't end animation, there may be a segfault if leaving while the animation is pending
195
 
  if (timer_id) {
196
 
    gtk_timeout_remove (timer_id);
197
 
    timer_id = 0;
198
 
  }
199
 
 
200
 
  if(gcomprisBoard!=NULL)
201
 
    {
202
 
      pause_board(TRUE);
203
 
      gc_score_end();
204
 
      railroad_destroy_all_items();
205
 
 
206
 
      while(g_list_length(listPixmapEngines)>0) {
207
 
        pixmap = g_list_nth_data(listPixmapEngines, 0);
208
 
        listPixmapEngines = g_list_remove (listPixmapEngines, pixmap);
209
 
        gdk_pixbuf_unref(pixmap);
210
 
      }
211
 
 
212
 
      while(g_list_length(listPixmapWagons)>0) {
213
 
        pixmap = g_list_nth_data(listPixmapWagons, 0);
214
 
        listPixmapWagons = g_list_remove (listPixmapWagons, pixmap);
215
 
        gdk_pixbuf_unref(pixmap);
216
 
      }
217
 
 
218
 
    }
219
 
  gcomprisBoard = NULL;
220
 
}
221
 
 
222
 
/* ======================================= */
223
 
static void set_level (guint level)
224
 
{
225
 
 
226
 
  if(gcomprisBoard!=NULL)
227
 
    {
228
 
      gcomprisBoard->level=level;
229
 
      gcomprisBoard->sublevel=1;
230
 
      railroad_next_level();
231
 
    }
232
 
}
233
 
/* ======================================= */
234
 
gboolean is_our_board (GcomprisBoard *gcomprisBoard)
235
 
{
236
 
  if (gcomprisBoard)
237
 
    {
238
 
      if(g_strcasecmp(gcomprisBoard->type, "railroad")==0)
239
 
        {
240
 
          /* Set the plugin entry */
241
 
          gcomprisBoard->plugin=&menu_bp;
242
 
 
243
 
          return TRUE;
244
 
        }
245
 
    }
246
 
  return FALSE;
247
 
}
248
 
 
249
 
/* ======================================= */
250
 
static void repeat ()
251
 
{
252
 
  if(gcomprisBoard!=NULL && !animation_pending) {
253
 
    gnome_canvas_item_hide(GNOME_CANVAS_ITEM(answerRootItem));
254
 
    gnome_canvas_item_show(GNOME_CANVAS_ITEM(modelRootItem));
255
 
    gnome_canvas_item_hide(GNOME_CANVAS_ITEM(allwagonsRootItem));
256
 
    reposition_model();
257
 
    animate_model();
258
 
  }
259
 
}
260
 
 
261
 
/* ==================================== */
262
 
/* set initial values for the next level */
263
 
static void railroad_next_level()
264
 
{
265
 
  gc_bar_set_level(gcomprisBoard);
266
 
 
267
 
  reset_all_lists();
268
 
  // I have big troubles with the GList API : the worst I have ever seen !
269
 
  g_assert(g_list_length(item_answer_list) == 0 && g_list_length(int_answer_list) == 0 && g_list_length(int_model_list) == 0);
270
 
 
271
 
  model_size = 0;
272
 
 
273
 
  railroad_destroy_all_items();
274
 
  gamewon = FALSE;
275
 
  gc_score_set(gcomprisBoard->sublevel);
276
 
 
277
 
  /* Try the next level */
278
 
  railroad_create_item(gnome_canvas_root(gcomprisBoard->canvas));
279
 
}
280
 
/* ==================================== */
281
 
/* Destroy all the items */
282
 
static void railroad_destroy_all_items()
283
 
{
284
 
  if(boardRootItem!=NULL)
285
 
    gtk_object_destroy (GTK_OBJECT(boardRootItem));
286
 
 
287
 
  boardRootItem = NULL;
288
 
}
289
 
/* ==================================== */
290
 
static GnomeCanvasItem *railroad_create_item(GnomeCanvasGroup *parent)
291
 
{
292
 
  int xOffset = 0, yOffset = 0;
293
 
  int i, r, l = 1;
294
 
  GdkPixbuf * pixmap = NULL;
295
 
  GnomeCanvasItem *item;
296
 
 
297
 
  boardRootItem = GNOME_CANVAS_GROUP(
298
 
                                     gnome_canvas_item_new (parent,
299
 
                                                            gnome_canvas_group_get_type (),
300
 
                                                            "x", (double) 0,
301
 
                                                            "y", (double) 0,
302
 
                                                            NULL));
303
 
  /* Create a root group for the answer */
304
 
  answerRootItem = GNOME_CANVAS_GROUP(
305
 
                                      gnome_canvas_item_new (boardRootItem,
306
 
                                                             gnome_canvas_group_get_type (),
307
 
                                                             "x", (double) 0,
308
 
                                                             "y", (double) 0,
309
 
                                                             NULL));
310
 
 
311
 
  // Create the vehicules
312
 
  allwagonsRootItem = GNOME_CANVAS_GROUP(
313
 
                                         gnome_canvas_item_new (boardRootItem,
314
 
                                                                gnome_canvas_group_get_type (),
315
 
                                                                "x", (double) 0,
316
 
                                                                "y", (double) 0,
317
 
                                                                NULL));
318
 
 
319
 
  for (i=0; i<ENGINES+WAGONS; i++) {
320
 
    if (i<ENGINES)
321
 
      pixmap = g_list_nth_data(listPixmapEngines, i);
322
 
    else
323
 
      pixmap = g_list_nth_data(listPixmapWagons, i-ENGINES);
324
 
 
325
 
    if ( (xOffset + gdk_pixbuf_get_width(pixmap)) >= gcomprisBoard->width) {
326
 
      xOffset = 0;
327
 
      l++;
328
 
    }
329
 
    yOffset = line[l] - gdk_pixbuf_get_height(pixmap);
330
 
 
331
 
    item = gnome_canvas_item_new (allwagonsRootItem,
332
 
                                  gnome_canvas_pixbuf_get_type (),
333
 
                                  "pixbuf",  pixmap,
334
 
                                  "x",  (double) xOffset,
335
 
                                  "y",  (double) yOffset,
336
 
                                  NULL);
337
 
    xOffset += gdk_pixbuf_get_width(pixmap);
338
 
 
339
 
    gtk_signal_connect(GTK_OBJECT(item), "event", (GtkSignalFunc) item_event,
340
 
                       GINT_TO_POINTER(i));
341
 
 
342
 
  }
343
 
  // hide them
344
 
  gnome_canvas_item_hide(GNOME_CANVAS_ITEM(allwagonsRootItem));
345
 
 
346
 
  // construct the model to be recognized
347
 
  modelRootItem = GNOME_CANVAS_GROUP(
348
 
                                     gnome_canvas_item_new (boardRootItem,
349
 
                                                            gnome_canvas_group_get_type (),
350
 
                                                            "x", (double) 0,
351
 
                                                            "y", (double) 0,
352
 
                                                            NULL));
353
 
 
354
 
  yOffset = line[0];
355
 
  xOffset = 0;
356
 
  model_size = gcomprisBoard->level +1; // engine + cars
357
 
  // First the cars, depending of the level
358
 
  for (i=0; i<model_size-1; i++) {
359
 
    r = g_random_int_range( 0, WAGONS);
360
 
    g_assert( r >=0 && r < WAGONS);
361
 
    // keep track of the answer
362
 
    int_model_list = g_list_append(int_model_list, GINT_TO_POINTER(r+ENGINES));
363
 
    pixmap = g_list_nth_data(listPixmapWagons, r);
364
 
    g_assert(i >= 0 && i<MODEL_MAX_SIZE);
365
 
    item_model[i] =gnome_canvas_item_new (modelRootItem,
366
 
                                          gnome_canvas_pixbuf_get_type (),
367
 
                                          "pixbuf",  pixmap,
368
 
                                          "x",  (double) xOffset,
369
 
                                          "y",  (double) yOffset - gdk_pixbuf_get_height(pixmap),
370
 
                                          NULL);
371
 
    xOffset  += gdk_pixbuf_get_width(pixmap);
372
 
  }
373
 
 
374
 
  // Then the engine
375
 
  r = g_random_int_range( 0, ENGINES);
376
 
  g_assert( r >=0 && r < ENGINES);
377
 
  // keep track of the answer
378
 
  int_model_list = g_list_append(int_model_list, GINT_TO_POINTER(r));
379
 
  pixmap = g_list_nth_data(listPixmapEngines, r);
380
 
  item_model[model_size-1] =gnome_canvas_item_new (modelRootItem,
381
 
                                                   gnome_canvas_pixbuf_get_type (),
382
 
                                                   "pixbuf",  pixmap,
383
 
                                                   "x",  (double) xOffset,
384
 
                                                   "y",  (double) yOffset  - gdk_pixbuf_get_height(pixmap),
385
 
                                                   NULL);
386
 
 
387
 
  animate_model();
388
 
 
389
 
  return NULL;
390
 
}
391
 
/* ==================================== */
392
 
static void game_won()
393
 
{
394
 
  gcomprisBoard->sublevel++;
395
 
 
396
 
  if(gcomprisBoard->sublevel>gcomprisBoard->number_of_sublevel) {
397
 
    /* Try the next level */
398
 
    gcomprisBoard->sublevel=1;
399
 
    gcomprisBoard->level++;
400
 
    if(gcomprisBoard->level>gcomprisBoard->maxlevel) { // the current board is finished : bail out
401
 
      gc_bonus_end_display(GC_BOARD_FINISHED_RANDOM);
402
 
      return;
403
 
    }
404
 
    gc_sound_play_ogg ("sounds/bonus.wav", NULL);
405
 
  }
406
 
  railroad_next_level();
407
 
}
408
 
 
409
 
/* ==================================== */
410
 
static void process_ok()
411
 
{
412
 
  int i;
413
 
 
414
 
  gamewon = TRUE;
415
 
 
416
 
  // DEBUG
417
 
  g_warning("l answer = %d\tl model = %d\n", g_list_length(int_answer_list), g_list_length(int_model_list));
418
 
  if (g_list_length(int_answer_list) != g_list_length(int_model_list))
419
 
    gamewon = FALSE;
420
 
  else
421
 
    for (i=0; i<g_list_length(int_answer_list); i++) {
422
 
      if ( GPOINTER_TO_INT(g_list_nth_data(int_answer_list,i)) != GPOINTER_TO_INT(g_list_nth_data(int_model_list,i))) {
423
 
        printf("pour i= %d --> diff�rent\n", i);
424
 
        gamewon = FALSE;
425
 
        break;
426
 
      }
427
 
    }
428
 
  // DUMP lists
429
 
  g_warning("answer:\n");
430
 
  for (i=0; i<g_list_length(int_answer_list); i++)
431
 
    g_warning(" i = \t%d val = \t%d\n", i, GPOINTER_TO_INT(g_list_nth_data(int_answer_list,i)) );
432
 
  g_warning("model:\n");
433
 
  for (i=0; i<g_list_length(int_model_list); i++)
434
 
    g_warning(" i = \t%d val = \t%d\n", i, GPOINTER_TO_INT(g_list_nth_data(int_model_list,i)) );
435
 
 
436
 
  gc_bonus_display(gamewon, GC_BONUS_FLOWER);
437
 
}
438
 
/* ==================================== */
439
 
static gint item_event(GnomeCanvasItem *item, GdkEvent *event, gpointer data) {
440
 
  double item_x, item_y;
441
 
  int item_number;
442
 
  GdkPixbuf * pixmap = NULL;
443
 
  int i, xOffset = 0;
444
 
  GnomeCanvasItem * local_item;
445
 
  double dx1, dy1, dx2, dy2;
446
 
  item_number = GPOINTER_TO_INT(data);
447
 
 
448
 
  // we don't allow any input until train is gone
449
 
  if (animation_pending)
450
 
    return FALSE;
451
 
 
452
 
  item_x = event->button.x;
453
 
  item_y = event->button.y;
454
 
  gnome_canvas_item_w2i(item->parent, &item_x, &item_y);
455
 
 
456
 
  if(board_paused)
457
 
    return FALSE;
458
 
 
459
 
  switch (event->type)
460
 
    {
461
 
    case GDK_BUTTON_PRESS:
462
 
      g_warning("GDK_BUTTON_PRESS item %d\tlength answer = %d\n",item_number,g_list_length(item_answer_list));
463
 
      gc_sound_play_ogg ("sounds/bleep.wav", NULL);
464
 
      xOffset = 0;
465
 
      for (i=0; i<g_list_length(item_answer_list); i++) {
466
 
        gnome_canvas_item_get_bounds(g_list_nth_data(item_answer_list,i), &dx1, &dy1, &dx2, &dy2);
467
 
        xOffset += dx2-dx1;
468
 
      }
469
 
      if (item_number < ENGINES)
470
 
        pixmap = g_list_nth_data(listPixmapEngines, item_number);
471
 
      else
472
 
        pixmap = g_list_nth_data(listPixmapWagons, item_number-ENGINES);
473
 
 
474
 
      local_item =gnome_canvas_item_new (answerRootItem,
475
 
                                         gnome_canvas_pixbuf_get_type (),
476
 
                                         "pixbuf",  pixmap,
477
 
                                         "x",  (double) xOffset,
478
 
                                         "y",  (double) line[0] - gdk_pixbuf_get_height(pixmap),
479
 
                                         NULL);
480
 
      item_answer_list = g_list_append(item_answer_list, local_item);
481
 
      int_answer_list = g_list_append(int_answer_list,GINT_TO_POINTER(item_number));
482
 
      //        printf("added %d to int_answer_list\n", item_number);
483
 
      gtk_signal_connect(GTK_OBJECT(local_item), "event", (GtkSignalFunc) answer_event, GINT_TO_POINTER( g_list_length(item_answer_list)-1 ));
484
 
      break;
485
 
 
486
 
    default:
487
 
      break;
488
 
    }
489
 
  return FALSE;
490
 
}
491
 
/* ==================================== */
492
 
/* Used to delete a vehicule at the top (the proposed answer) */
493
 
static gint answer_event(GnomeCanvasItem *item, GdkEvent *event, gpointer data) {
494
 
  double item_x, item_y;
495
 
  int item_number, i;
496
 
  GnomeCanvasItem *local_item;
497
 
  item_number = GPOINTER_TO_INT(data);
498
 
  // we don't allow any input until train is gone
499
 
  if (animation_pending)
500
 
    return FALSE;
501
 
 
502
 
  item_x = event->button.x;
503
 
  item_y = event->button.y;
504
 
  gnome_canvas_item_w2i(item->parent, &item_x, &item_y);
505
 
 
506
 
  if(board_paused)
507
 
    return FALSE;
508
 
 
509
 
  switch (event->type)
510
 
    {
511
 
    case GDK_BUTTON_PRESS:
512
 
      gc_sound_play_ogg ("sounds/smudge.wav", NULL);
513
 
      g_warning("Deleting %d\n",item_number);
514
 
      local_item = g_list_nth_data(item_answer_list,item_number);
515
 
      item_answer_list = g_list_remove( item_answer_list, local_item );
516
 
      //        gtk_signal_disconnect(GTK_OBJECT(local_item), (GtkSignalFunc) answer_event, NULL);
517
 
      gtk_object_destroy (GTK_OBJECT(local_item));
518
 
      int_answer_list = g_list_remove(int_answer_list, g_list_nth_data(int_answer_list, item_number) );
519
 
      reposition_answer();
520
 
      // setup the signals for the cars at the right side of the deleted object
521
 
      for (i=item_number; i<g_list_length(item_answer_list); i++) {
522
 
        local_item = g_list_nth_data(item_answer_list, i);
523
 
        gtk_signal_disconnect_by_func(GTK_OBJECT(local_item), (GtkSignalFunc) answer_event, GINT_TO_POINTER( i+1 ));
524
 
        gtk_signal_connect(GTK_OBJECT(local_item),"event", (GtkSignalFunc) answer_event, GINT_TO_POINTER( i ));
525
 
      }
526
 
      break;
527
 
 
528
 
    default:
529
 
      break;
530
 
    }
531
 
  return FALSE;
532
 
}
533
 
/* ==================================== */
534
 
static void reposition_answer() {
535
 
  double dx1, dy1, dx2, dy2;
536
 
  int i;
537
 
  int xOffset = 0;
538
 
  GnomeCanvasItem * item = NULL;
539
 
 
540
 
  if(!gcomprisBoard)
541
 
    return;
542
 
 
543
 
  g_warning("+++ reposition_answer\n");
544
 
  for (i=0; i<g_list_length(item_answer_list); i++) {
545
 
    item = g_list_nth_data(item_answer_list,i);
546
 
    gnome_canvas_item_get_bounds(item, &dx1, &dy1, &dx2, &dy2);
547
 
    gnome_canvas_item_move(item, xOffset-dx1, line[0]-dy2);
548
 
    xOffset += dx2-dx1;
549
 
  }
550
 
}
551
 
/* ==================================== */
552
 
static void reposition_model() {
553
 
  double dx1, dy1, dx2, dy2;
554
 
  int i;
555
 
  int xOffset = 0;
556
 
  GnomeCanvasItem * item = NULL;
557
 
 
558
 
  if(!gcomprisBoard)
559
 
    return;
560
 
 
561
 
  g_warning("+++ reposition_model\n");
562
 
  gnome_canvas_item_move(GNOME_CANVAS_ITEM(modelRootItem), 0, 0);
563
 
  for (i=0; i<model_size; i++) {
564
 
    item = item_model[i];
565
 
    gnome_canvas_item_get_bounds(item, &dx1, &dy1, &dx2, &dy2);
566
 
    gnome_canvas_item_move(item, xOffset-dx1, line[0]-dy2);
567
 
    xOffset += dx2-dx1;
568
 
  }
569
 
}
570
 
 
571
 
/* ==================================== */
572
 
static gboolean animate_step() {
573
 
  double step = 0;
574
 
 
575
 
  // this defines how the train waits before start
576
 
#define MODEL_PAUSE 30
577
 
  //    printf("+++animate_step %d \n",animation_count);
578
 
 
579
 
  if(board_paused)
580
 
    return TRUE;
581
 
 
582
 
  if(!gcomprisBoard)
583
 
    return FALSE;
584
 
 
585
 
  animation_count++;
586
 
 
587
 
  if (animation_count < MODEL_PAUSE)
588
 
    return TRUE;
589
 
 
590
 
  if (animation_count >= 160+MODEL_PAUSE) {
591
 
    if (timer_id) {
592
 
      gtk_timeout_remove (timer_id);
593
 
      timer_id = 0;
594
 
    }
595
 
    animation_pending = FALSE;
596
 
    gnome_canvas_item_hide(GNOME_CANVAS_ITEM(modelRootItem));
597
 
    /* Move back the model to its 0 position */
598
 
    gnome_canvas_item_set(GNOME_CANVAS_ITEM(modelRootItem),
599
 
                          "x", 0.0,
600
 
                          NULL);
601
 
 
602
 
    gnome_canvas_item_show(GNOME_CANVAS_ITEM(allwagonsRootItem));
603
 
    gnome_canvas_item_show(GNOME_CANVAS_ITEM(answerRootItem));
604
 
    return FALSE;
605
 
  }
606
 
 
607
 
  step = (double) (animation_count-MODEL_PAUSE) / 50.0;
608
 
  step *= step;
609
 
 
610
 
  gnome_canvas_item_move(GNOME_CANVAS_ITEM(modelRootItem), step, 0.0);
611
 
 
612
 
  return TRUE;
613
 
}
614
 
/* ==================================== */
615
 
static void animate_model() {
616
 
  animation_pending = TRUE;
617
 
  animation_count = 0;
618
 
 
619
 
  gc_sound_play_ogg( "sounds/train.wav", NULL );
620
 
 
621
 
  // warning : if timeout is too low, the model will not be displayed
622
 
  timer_id = gtk_timeout_add (100, (GtkFunction) animate_step, NULL);
623
 
}
624
 
/* ==================================== */
625
 
static void reset_all_lists(void) {
626
 
  GnomeCanvasItem *item;
627
 
 
628
 
  int_model_list = reset_list(int_model_list);
629
 
  int_answer_list = reset_list(int_answer_list);
630
 
 
631
 
  while(g_list_length(item_answer_list)>0) {
632
 
    item = g_list_nth_data(item_answer_list, 0);
633
 
    item_answer_list = g_list_remove (item_answer_list, item);
634
 
    // causes segfaults
635
 
    //          gtk_object_destroy (GTK_OBJECT(item));
636
 
  }
637
 
 
638
 
}
639
 
/* ==================================== */
640
 
static GList * reset_list(GList * list) {
641
 
  while (g_list_length(list) > 0)
642
 
    list = g_list_remove(list, g_list_nth_data(list,0));
643
 
 
644
 
  return list;
645
 
}