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

« back to all changes in this revision

Viewing changes to src/boards/clockgame.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 - clockgame.c
2
 
 *
3
 
 * Copyright (C) 2000 Bruno Coudoin
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 <ctype.h>
20
 
#include <math.h>
21
 
 
22
 
#include "gcompris/gcompris.h"
23
 
 
24
 
#define SOUNDLISTFILE PACKAGE
25
 
 
26
 
static GcomprisBoard *gcomprisBoard = NULL;
27
 
static gboolean board_paused = TRUE;
28
 
 
29
 
static GnomeCanvasGroup *boardRootItem = NULL;
30
 
 
31
 
static GnomeCanvasItem *second_item;
32
 
static GnomeCanvasItem *hour_item;
33
 
static GnomeCanvasItem *minute_item;
34
 
static GnomeCanvasItem *digital_time_item;
35
 
static GnomeCanvasItem *digital_time_item_s;
36
 
static GnomeCanvasItem *time_to_find_item;
37
 
static GnomeCanvasItem *time_to_find_item_s;
38
 
 
39
 
/* Center of the clock and it's size */
40
 
double cx;
41
 
double cy;
42
 
double clock_size;
43
 
 
44
 
typedef struct {
45
 
  guint hour;
46
 
  guint minute;
47
 
  guint second;
48
 
} GcomprisTime;
49
 
static GcomprisTime timeToFind, currentTime;
50
 
 
51
 
static void              start_board (GcomprisBoard *agcomprisBoard);
52
 
static void              pause_board (gboolean pause);
53
 
static void              end_board (void);
54
 
static gboolean          is_our_board (GcomprisBoard *gcomprisBoard);
55
 
static void              set_level (guint level);
56
 
static void              process_ok(void);
57
 
 
58
 
static int gamewon;
59
 
static void              game_won(void);
60
 
 
61
 
static void              clockgame_create_item(GnomeCanvasGroup *parent);
62
 
static void              destroy_all_items(void);
63
 
static void              get_random_hour(GcomprisTime *time);
64
 
static void              clockgame_next_level(void);
65
 
static gint              item_event(GnomeCanvasItem *item, GdkEvent *event, gpointer data);
66
 
static void              display_hour(guint hour);
67
 
static void              display_minute(guint minute);
68
 
static void              display_second(guint second);
69
 
static gboolean          time_equal(GcomprisTime *time1, GcomprisTime *time2);
70
 
 
71
 
/* Description of this plugin */
72
 
static BoardPlugin menu_bp =
73
 
{
74
 
   NULL,
75
 
   NULL,
76
 
   "Learning Clock",
77
 
   "Learn how to tell the time",
78
 
   "Bruno Coudoin <bruno.coudoin@free.fr>",
79
 
   NULL,
80
 
   NULL,
81
 
   NULL,
82
 
   NULL,
83
 
   start_board,
84
 
   pause_board,
85
 
   end_board,
86
 
   is_our_board,
87
 
   NULL,
88
 
   process_ok,
89
 
   set_level,
90
 
   NULL,
91
 
   NULL,
92
 
   NULL,
93
 
   NULL
94
 
};
95
 
 
96
 
 
97
 
/*
98
 
 * Main entry point mandatory for each Gcompris's game
99
 
 * ---------------------------------------------------
100
 
 *
101
 
 */
102
 
 
103
 
GET_BPLUGIN_INFO(clockgame)
104
 
 
105
 
/*
106
 
 * in : boolean TRUE = PAUSE : FALSE = CONTINUE
107
 
 *
108
 
 */
109
 
static void pause_board (gboolean pause)
110
 
{
111
 
 
112
 
  if(gcomprisBoard==NULL)
113
 
    return;
114
 
 
115
 
  if(gamewon == TRUE && pause == FALSE) /* the game is won */
116
 
    {
117
 
      game_won();
118
 
    }
119
 
 
120
 
  board_paused = pause;
121
 
}
122
 
 
123
 
/*
124
 
 */
125
 
static void start_board (GcomprisBoard *agcomprisBoard)
126
 
{
127
 
 
128
 
  if(agcomprisBoard!=NULL)
129
 
    {
130
 
      gchar *img;
131
 
      gcomprisBoard=agcomprisBoard;
132
 
 
133
 
      img = gc_skin_image_get("clockgame-bg.jpg");
134
 
      gc_set_background(gnome_canvas_root(gcomprisBoard->canvas),
135
 
                              img);
136
 
      g_free(img);
137
 
 
138
 
      /* set initial values for this level adjusted to fit the watch background */
139
 
      cx =  gcomprisBoard->width/2;
140
 
      cy =  gcomprisBoard->height*0.4 + 42;
141
 
      clock_size = gcomprisBoard->height*0.3;
142
 
 
143
 
      gcomprisBoard->level=1;
144
 
      gcomprisBoard->maxlevel=6;
145
 
      gcomprisBoard->sublevel=1;
146
 
      gcomprisBoard->number_of_sublevel=3; /* Go to next level after this number of 'play' */
147
 
      gc_score_start(SCORESTYLE_NOTE,
148
 
                           gcomprisBoard->width - 220,
149
 
                           gcomprisBoard->height - 50,
150
 
                           gcomprisBoard->number_of_sublevel);
151
 
      gc_bar_set(GC_BAR_LEVEL|GC_BAR_OK);
152
 
 
153
 
      clockgame_next_level();
154
 
 
155
 
      gamewon = FALSE;
156
 
      pause_board(FALSE);
157
 
 
158
 
    }
159
 
 
160
 
}
161
 
 
162
 
static void
163
 
end_board ()
164
 
{
165
 
 
166
 
  if(gcomprisBoard!=NULL)
167
 
    {
168
 
      pause_board(TRUE);
169
 
      gc_score_end();
170
 
      destroy_all_items();
171
 
    }
172
 
  gcomprisBoard = NULL;
173
 
}
174
 
 
175
 
static void
176
 
set_level (guint level)
177
 
{
178
 
 
179
 
  if(gcomprisBoard!=NULL)
180
 
    {
181
 
      gcomprisBoard->level=level;
182
 
      gcomprisBoard->sublevel=1;
183
 
      clockgame_next_level();
184
 
    }
185
 
}
186
 
 
187
 
static gboolean
188
 
is_our_board (GcomprisBoard *gcomprisBoard)
189
 
{
190
 
  if (gcomprisBoard)
191
 
    {
192
 
      if(g_strcasecmp(gcomprisBoard->type, "clockgame")==0)
193
 
        {
194
 
          /* Set the plugin entry */
195
 
          gcomprisBoard->plugin=&menu_bp;
196
 
 
197
 
          return TRUE;
198
 
        }
199
 
    }
200
 
  return FALSE;
201
 
}
202
 
 
203
 
 
204
 
/*-------------------------------------------------------------------------------*/
205
 
/*-------------------------------------------------------------------------------*/
206
 
/*-------------------------------------------------------------------------------*/
207
 
/*-------------------------------------------------------------------------------*/
208
 
 
209
 
/* set initial values for the next level */
210
 
static void clockgame_next_level()
211
 
{
212
 
 
213
 
  gc_bar_set_level(gcomprisBoard);
214
 
  gc_score_set(gcomprisBoard->sublevel);
215
 
 
216
 
  destroy_all_items();
217
 
 
218
 
  /* Try the next level */
219
 
  get_random_hour(&timeToFind);
220
 
 
221
 
  /* Avoid to show up the solution directly */
222
 
  do {
223
 
    get_random_hour(&currentTime);
224
 
  } while(time_equal(&timeToFind, &currentTime));
225
 
 
226
 
  clockgame_create_item(gnome_canvas_root(gcomprisBoard->canvas));
227
 
 
228
 
}
229
 
 
230
 
/* ==================================== */
231
 
/* Destroy all the items */
232
 
static void
233
 
destroy_all_items()
234
 
{
235
 
 
236
 
  if(boardRootItem!=NULL)
237
 
    gtk_object_destroy (GTK_OBJECT(boardRootItem));
238
 
 
239
 
  boardRootItem = NULL;
240
 
}
241
 
 
242
 
 
243
 
static void display_digital_time(GnomeCanvasItem *item, GcomprisTime *time)
244
 
{
245
 
  gchar *text = NULL;
246
 
  int temps;
247
 
 
248
 
  temps = (time->hour+12)*3600 + time->minute*60 + time->second;
249
 
  time->hour = (temps / 3600) % 12;
250
 
  time->minute = (temps / 60) % 60;
251
 
  time->second = temps % 60;
252
 
 
253
 
  if(item==NULL)
254
 
    return;
255
 
 
256
 
  if(gcomprisBoard->level<=2)
257
 
    text = g_strdup_printf("%.2d:%.2d", time->hour, time->minute);
258
 
  else
259
 
    text = g_strdup_printf("%.2d:%.2d:%.2d", time->hour, time->minute, time->second);
260
 
 
261
 
  gnome_canvas_item_set (item,
262
 
                         "text", text,
263
 
                         NULL);
264
 
  g_free(text);
265
 
 
266
 
}
267
 
 
268
 
static void display_hour(guint hour)
269
 
{
270
 
  double needle_size = clock_size*0.70;
271
 
  double ang;
272
 
  GnomeCanvasPoints *canvasPoints;
273
 
 
274
 
  if(hour_item==NULL)
275
 
    return;
276
 
 
277
 
  /* Calc the needle angle */
278
 
  ang = ((hour > 12) ? hour-12 : hour) * M_PI / 6;
279
 
  ang += currentTime.minute * M_PI / 360;
280
 
  ang += currentTime.second * M_PI / 21600;
281
 
 
282
 
  canvasPoints = gnome_canvas_points_new (2);
283
 
  canvasPoints->coords[0]=cx;
284
 
  canvasPoints->coords[1]=cy;
285
 
  canvasPoints->coords[2]=cx + needle_size * sin(ang);
286
 
  canvasPoints->coords[3]=cy - needle_size * cos(ang);
287
 
  gnome_canvas_item_set (hour_item,
288
 
                         "points", canvasPoints,
289
 
                         "fill_color", "darkblue",
290
 
                         "width_units", (double)1,
291
 
                         "width_pixels", (guint) 4,
292
 
                         "last_arrowhead", TRUE,
293
 
                         "arrow_shape_a", (double) needle_size,
294
 
                         "arrow_shape_b", (double) needle_size-20,
295
 
                         "arrow_shape_c", (double) 8.0,
296
 
                         NULL);
297
 
  gnome_canvas_points_free(canvasPoints);
298
 
 
299
 
  currentTime.hour=hour;
300
 
  display_digital_time(digital_time_item, &currentTime);
301
 
  display_digital_time(digital_time_item_s, &currentTime);
302
 
}
303
 
 
304
 
static void display_minute(guint minute)
305
 
{
306
 
  double needle_size = clock_size;
307
 
  double ang;
308
 
  GnomeCanvasPoints *canvasPoints;
309
 
 
310
 
  if(minute_item==NULL)
311
 
    return;
312
 
 
313
 
  ang = minute * M_PI / 30;
314
 
  ang += currentTime.second * M_PI / 1800;
315
 
 
316
 
  canvasPoints = gnome_canvas_points_new (2);
317
 
  canvasPoints->coords[0]=cx;
318
 
  canvasPoints->coords[1]=cy;
319
 
  canvasPoints->coords[2]=cx + needle_size * sin(ang);
320
 
  canvasPoints->coords[3]=cy - needle_size * cos(ang);
321
 
  gnome_canvas_item_set (minute_item,
322
 
                         "points", canvasPoints,
323
 
                         "fill_color", "red",
324
 
                         "width_units", (double)1,
325
 
                         "width_pixels", (guint) 4,
326
 
                         "last_arrowhead", TRUE,
327
 
                         "arrow_shape_a", (double) needle_size,
328
 
                         "arrow_shape_b", (double) needle_size-10,
329
 
                         "arrow_shape_c", (double) 3.0,
330
 
                         NULL);
331
 
  gnome_canvas_points_free(canvasPoints);
332
 
 
333
 
  currentTime.minute=minute;
334
 
  display_digital_time(digital_time_item, &currentTime);
335
 
  display_digital_time(digital_time_item_s, &currentTime);
336
 
}
337
 
 
338
 
static void display_second(guint second)
339
 
{
340
 
  double needle_size = clock_size;
341
 
  double ang;
342
 
  GnomeCanvasPoints *canvasPoints;
343
 
 
344
 
  /* No seconds at first levels */
345
 
  if(second_item==NULL || gcomprisBoard->level<=2)
346
 
    return;
347
 
 
348
 
  ang = second * M_PI / 30;
349
 
 
350
 
  canvasPoints = gnome_canvas_points_new (2);
351
 
  canvasPoints->coords[0]=cx;
352
 
  canvasPoints->coords[1]=cy;
353
 
  canvasPoints->coords[2]=cx + needle_size * sin(ang);
354
 
  canvasPoints->coords[3]=cy - needle_size * cos(ang);
355
 
  gnome_canvas_item_set (second_item,
356
 
                         "points", canvasPoints,
357
 
                         "fill_color_rgba", 0x68c46fFF,
358
 
                         "width_units", (double)1,
359
 
                         "width_pixels", (guint) 4,
360
 
                         "last_arrowhead", TRUE,
361
 
                         "arrow_shape_a", (double) 0,
362
 
                         "arrow_shape_b", (double) 0,
363
 
                         "arrow_shape_c", (double) 0,
364
 
                         NULL);
365
 
  gnome_canvas_points_free(canvasPoints);
366
 
 
367
 
  currentTime.second=second;
368
 
  display_digital_time(digital_time_item, &currentTime);
369
 
  display_digital_time(digital_time_item_s, &currentTime);
370
 
}
371
 
 
372
 
 
373
 
static void
374
 
clockgame_create_item(GnomeCanvasGroup *parent)
375
 
{
376
 
  GnomeCanvasItem *item;
377
 
  double needle_size = clock_size;
378
 
  double min_point_size = clock_size*0.05;
379
 
  double hour_point_size = clock_size*0.1;
380
 
  double ang;
381
 
  guint min;
382
 
  GnomeCanvasPoints *canvasPoints;
383
 
  char *color;
384
 
  char *color_text;
385
 
  gchar *mtext = NULL;
386
 
  gchar *font = NULL;
387
 
 
388
 
  boardRootItem = GNOME_CANVAS_GROUP(
389
 
                                     gnome_canvas_item_new (gnome_canvas_root(gcomprisBoard->canvas),
390
 
                                                            gnome_canvas_group_get_type (),
391
 
                                                            "x", (double) 0,
392
 
                                                            "y", (double) 0,
393
 
                                                            NULL));
394
 
 
395
 
  canvasPoints = gnome_canvas_points_new (2);
396
 
 
397
 
  for(min = 1 ; min <= 60 ; min += 1)
398
 
    {
399
 
      ang = min * M_PI / 30;
400
 
      if(min%5==0)
401
 
        {
402
 
          /* Hour point */
403
 
          canvasPoints->coords[0]=cx + (needle_size-hour_point_size) * sin(ang);
404
 
          canvasPoints->coords[1]=cy - (needle_size-hour_point_size) * cos(ang);
405
 
          color="darkblue";
406
 
          color_text="red";
407
 
          font = gc_skin_font_board_small;
408
 
        }
409
 
      else
410
 
        {
411
 
          /* Minute point */
412
 
          canvasPoints->coords[0]=cx + (needle_size-min_point_size) * sin(ang);
413
 
          canvasPoints->coords[1]=cy - (needle_size-min_point_size) * cos(ang);
414
 
          color="red";
415
 
          color_text="red";
416
 
          font = gc_skin_font_board_tiny;
417
 
        }
418
 
 
419
 
      canvasPoints->coords[2]=cx + needle_size * sin(ang);
420
 
      canvasPoints->coords[3]=cy - needle_size * cos(ang);
421
 
      item = gnome_canvas_item_new (boardRootItem,
422
 
                                    gnome_canvas_line_get_type (),
423
 
                                    "points", canvasPoints,
424
 
                                    "fill_color", color,
425
 
                                    "width_units", (double)1,
426
 
                                    "width_pixels", (guint) 2,
427
 
                                    NULL);
428
 
 
429
 
      /* Display minute number */
430
 
      if(gcomprisBoard->level<5)
431
 
        {
432
 
          mtext = g_strdup_printf("%d", min);
433
 
          item = gnome_canvas_item_new (boardRootItem,
434
 
                                        gnome_canvas_text_get_type (),
435
 
                                        "text", mtext,
436
 
                                        "font", font,
437
 
                                        "x", (double) cx + (needle_size+10) * sin(ang),
438
 
                                        "y", (double) cy - (needle_size+10) * cos(ang),
439
 
                                        "anchor", GTK_ANCHOR_CENTER,
440
 
                                        "fill_color", color_text,
441
 
                                        "justification", GTK_JUSTIFY_CENTER,
442
 
                                        NULL);
443
 
          g_free(mtext);
444
 
        }
445
 
 
446
 
      /* Display hour numbers */
447
 
      if(gcomprisBoard->level<6)
448
 
        if(min%5==0)
449
 
          {
450
 
            mtext = g_strdup_printf( "%d", min/5);
451
 
            item = gnome_canvas_item_new (boardRootItem,
452
 
                                          gnome_canvas_text_get_type (),
453
 
                                          "text", mtext,
454
 
                                          "font", font,
455
 
                                          "x", (double) cx + (needle_size-30) * sin(ang),
456
 
                                          "y", (double) cy - (needle_size-30) * cos(ang),
457
 
                                          "anchor", GTK_ANCHOR_CENTER,
458
 
                                          "fill_color", "blue",
459
 
                                          "justification", GTK_JUSTIFY_CENTER,
460
 
                                          NULL);
461
 
            g_free(mtext);
462
 
          }
463
 
    }
464
 
 
465
 
  /* Create the text area for the digital time display */
466
 
  if(gcomprisBoard->level<4)
467
 
    {
468
 
      digital_time_item_s =
469
 
        gnome_canvas_item_new (boardRootItem,
470
 
                               gnome_canvas_text_get_type (),
471
 
                               "text", "",
472
 
                               "font", gc_skin_font_board_medium,
473
 
                               "x", (double) cx + 1.0,
474
 
                               "y", (double) cy +  needle_size/2 + 1.0,
475
 
                               "anchor", GTK_ANCHOR_CENTER,
476
 
                               "fill_color_rgba", 0xc4c4c4ff,
477
 
                               NULL);
478
 
      display_digital_time(digital_time_item_s, &currentTime);
479
 
 
480
 
      digital_time_item =
481
 
        gnome_canvas_item_new (boardRootItem,
482
 
                               gnome_canvas_text_get_type (),
483
 
                               "text", "",
484
 
                               "font", gc_skin_font_board_medium,
485
 
                               "x", (double) cx,
486
 
                               "y", (double) cy +  needle_size/2,
487
 
                               "anchor", GTK_ANCHOR_CENTER,
488
 
                               "fill_color", "blue",
489
 
                               NULL);
490
 
      display_digital_time(digital_time_item, &currentTime);
491
 
    }
492
 
  else
493
 
    {
494
 
      digital_time_item_s = NULL;
495
 
      digital_time_item = NULL;
496
 
    }
497
 
 
498
 
  /* Create the Hour needle */
499
 
 
500
 
  canvasPoints->coords[0]=0;
501
 
  canvasPoints->coords[1]=0;
502
 
  canvasPoints->coords[2]=0;
503
 
  canvasPoints->coords[3]=0;
504
 
  hour_item = gnome_canvas_item_new (boardRootItem,
505
 
                                     gnome_canvas_line_get_type (),
506
 
                                     "points", canvasPoints,
507
 
                                     "fill_color", "darkblue",
508
 
                                     "width_units", (double)1,
509
 
                                     "width_pixels", (guint) 0,
510
 
                                     NULL);
511
 
  gtk_signal_connect(GTK_OBJECT(hour_item), "event",
512
 
                     (GtkSignalFunc) item_event,
513
 
                     NULL);
514
 
  display_hour(currentTime.hour);
515
 
 
516
 
  /* Create the minute needle */
517
 
 
518
 
  minute_item = gnome_canvas_item_new (boardRootItem,
519
 
                                       gnome_canvas_line_get_type (),
520
 
                                       "points", canvasPoints,
521
 
                                       "fill_color", "darkblue",
522
 
                                       "width_units", (double)1,
523
 
                                       "width_pixels", (guint) 0,
524
 
                                       NULL);
525
 
  gtk_signal_connect(GTK_OBJECT(minute_item), "event",
526
 
                     (GtkSignalFunc) item_event,
527
 
                     NULL);
528
 
  display_minute(currentTime.minute);
529
 
 
530
 
  /* Create the second needle */
531
 
 
532
 
  second_item = gnome_canvas_item_new (boardRootItem,
533
 
                                       gnome_canvas_line_get_type (),
534
 
                                       "points", canvasPoints,
535
 
                                       "fill_color", "darkblue",
536
 
                                       "width_units", (double)1,
537
 
                                       "width_pixels", (guint) 0,
538
 
                                       NULL);
539
 
  gtk_signal_connect(GTK_OBJECT(second_item), "event",
540
 
                     (GtkSignalFunc) item_event,
541
 
                     NULL);
542
 
  display_second(currentTime.second);
543
 
 
544
 
  /* Create the text area for the time to find display */
545
 
  gnome_canvas_item_new (boardRootItem,
546
 
                         gnome_canvas_text_get_type (),
547
 
                         "text", _("Set the watch to:"),
548
 
                         "font", gc_skin_font_board_small,
549
 
                         "x", (double) gcomprisBoard->width*0.17 + 1.0,
550
 
                         "y", (double) cy + needle_size +  needle_size / 3 - 30 + 1.0,
551
 
                         "anchor", GTK_ANCHOR_CENTER,
552
 
                         "fill_color_rgba", gc_skin_color_shadow,
553
 
                         NULL);
554
 
 
555
 
  gnome_canvas_item_new (boardRootItem,
556
 
                         gnome_canvas_text_get_type (),
557
 
                         "text", _("Set the watch to:"),
558
 
                         "font", gc_skin_font_board_small,
559
 
                         "x", (double) gcomprisBoard->width*0.17,
560
 
                         "y", (double) cy + needle_size +  needle_size / 3 - 30,
561
 
                         "anchor", GTK_ANCHOR_CENTER,
562
 
                         "fill_color_rgba", gc_skin_get_color("clockgame/text"),
563
 
                         NULL);
564
 
 
565
 
  time_to_find_item_s =
566
 
    gnome_canvas_item_new (boardRootItem,
567
 
                           gnome_canvas_text_get_type (),
568
 
                           "text", "",
569
 
                           "font", gc_skin_font_board_big_bold,
570
 
                           "x", (double) gcomprisBoard->width*0.17 + 1.0,
571
 
                           "y", (double) cy + needle_size +  needle_size / 3 + 1.0,
572
 
                           "anchor", GTK_ANCHOR_CENTER,
573
 
                           "fill_color_rgba", gc_skin_color_shadow,
574
 
                           NULL);
575
 
  display_digital_time(time_to_find_item_s, &timeToFind);
576
 
 
577
 
  time_to_find_item =
578
 
    gnome_canvas_item_new (boardRootItem,
579
 
                           gnome_canvas_text_get_type (),
580
 
                           "text", "",
581
 
                           "font", gc_skin_font_board_big_bold,
582
 
                           "x", (double) gcomprisBoard->width*0.17,
583
 
                           "y", (double) cy + needle_size +  needle_size / 3,
584
 
                           "anchor", GTK_ANCHOR_CENTER,
585
 
                           "fill_color_rgba", gc_skin_get_color("clockgame/text"),
586
 
                           NULL);
587
 
  display_digital_time(time_to_find_item, &timeToFind);
588
 
 
589
 
  gnome_canvas_points_free(canvasPoints);
590
 
 
591
 
}
592
 
 
593
 
/*
594
 
 * Returns true is given times are equal
595
 
 */
596
 
static gboolean
597
 
time_equal(GcomprisTime *time1, GcomprisTime *time2)
598
 
{
599
 
  /* No seconds at first levels */
600
 
  if(second_item==NULL || gcomprisBoard->level<=2)
601
 
    return(time1->hour==time2->hour
602
 
           &&time1->minute==time2->minute);
603
 
  else
604
 
    return(time1->hour==time2->hour
605
 
           &&time1->minute==time2->minute
606
 
           &&time1->second==time2->second);
607
 
 
608
 
}
609
 
 
610
 
/* ==================================== */
611
 
static void game_won()
612
 
{
613
 
  gamewon = FALSE;
614
 
  gcomprisBoard->sublevel++;
615
 
 
616
 
  if(gcomprisBoard->sublevel>gcomprisBoard->number_of_sublevel) {
617
 
    /* Try the next level */
618
 
    gcomprisBoard->sublevel=1;
619
 
    gcomprisBoard->level++;
620
 
    if(gcomprisBoard->level>gcomprisBoard->maxlevel) { // the current board is finished : bail out
621
 
      gc_bonus_end_display(GC_BOARD_FINISHED_RANDOM);
622
 
      return;
623
 
    }
624
 
    gc_sound_play_ogg ("sounds/bonus.wav", NULL);
625
 
  }
626
 
  clockgame_next_level();
627
 
}
628
 
 
629
 
/* ==================================== */
630
 
static void process_ok()
631
 
{
632
 
  if(time_equal(&timeToFind, &currentTime))
633
 
    {
634
 
      gamewon = TRUE;
635
 
    }
636
 
  else
637
 
    {
638
 
      /* Oups, you're wrong */
639
 
      gamewon = FALSE;
640
 
    }
641
 
  gc_bonus_display(gamewon, GC_BONUS_FLOWER);
642
 
}
643
 
 
644
 
 
645
 
/* Callback for the 'toBeFoundItem' */
646
 
static gint
647
 
item_event(GnomeCanvasItem *item, GdkEvent *event, gpointer data)
648
 
{
649
 
  static double x, y;
650
 
  double item_x, item_y;
651
 
  static int dragging;
652
 
  GdkCursor *fleur;
653
 
  double new_x, new_y;
654
 
 
655
 
  if(board_paused)
656
 
    return FALSE;
657
 
 
658
 
  item_x = event->button.x;
659
 
  item_y = event->button.y;
660
 
  gnome_canvas_item_w2i(item->parent, &item_x, &item_y);
661
 
 
662
 
  switch (event->type)
663
 
    {
664
 
    case GDK_BUTTON_PRESS:
665
 
      gc_sound_play_ogg ("sounds/bleep.wav", NULL);
666
 
      x = item_x;
667
 
      y = item_y;
668
 
 
669
 
      fleur = gdk_cursor_new(GDK_FLEUR);
670
 
      gc_canvas_item_grab(item,
671
 
                             GDK_POINTER_MOTION_MASK |
672
 
                             GDK_BUTTON_RELEASE_MASK,
673
 
                             fleur,
674
 
                             event->button.time);
675
 
      gdk_cursor_destroy(fleur);
676
 
      dragging = TRUE;
677
 
      break;
678
 
 
679
 
    case GDK_MOTION_NOTIFY:
680
 
      if (dragging && (event->motion.state & GDK_BUTTON1_MASK))
681
 
        {
682
 
 
683
 
          double angle;
684
 
 
685
 
          /* only use coords relative to the center, with standard
686
 
             direction for axis (y's need to be negated for this) */
687
 
          new_x = item_x - cx;
688
 
          new_y = - item_y + cy;
689
 
 
690
 
          /* angle as mesured relatively to noon position */
691
 
          /* Thanks to Martin Herweg for this code        */
692
 
          angle =  atan2(new_x,new_y);
693
 
          if (angle<0) {angle= angle + 2.0*M_PI;}
694
 
 
695
 
          if(item==hour_item)
696
 
            display_hour(angle * 6 / M_PI);
697
 
          else if(item==minute_item)
698
 
          {
699
 
            if(currentTime.minute > 45 && angle * 30 / M_PI < 15)
700
 
              {
701
 
                currentTime.hour++;
702
 
                gc_sound_play_ogg ("sounds/paint1.wav", NULL);
703
 
              }
704
 
 
705
 
            if(currentTime.minute < 15 && angle * 30 / M_PI > 45)
706
 
              {
707
 
                currentTime.hour--;
708
 
                gc_sound_play_ogg ("sounds/paint1.wav", NULL);
709
 
              }
710
 
 
711
 
            display_minute(angle * 30 / M_PI);
712
 
            display_hour(currentTime.hour);
713
 
          }
714
 
          else if(item==second_item)
715
 
          {
716
 
            if(currentTime.second > 45 && angle * 30 / M_PI < 15)
717
 
              {
718
 
                currentTime.minute++;
719
 
                gc_sound_play_ogg ("sounds/paint1.wav", NULL);
720
 
              }
721
 
 
722
 
            if(currentTime.second < 15 && angle * 30 / M_PI > 45)
723
 
              {
724
 
                currentTime.minute--;
725
 
                gc_sound_play_ogg ("sounds/paint1.wav", NULL);
726
 
              }
727
 
 
728
 
            display_second(angle * 30 / M_PI);
729
 
            display_minute(currentTime.minute);
730
 
            display_hour(currentTime.hour);
731
 
          }
732
 
 
733
 
          x = new_x + cx;
734
 
          y = new_y + cy;
735
 
        }
736
 
      break;
737
 
 
738
 
    case GDK_BUTTON_RELEASE:
739
 
      if(dragging)
740
 
        {
741
 
          gc_canvas_item_ungrab(item, event->button.time);
742
 
          dragging = FALSE;
743
 
        }
744
 
      break;
745
 
 
746
 
    default:
747
 
      break;
748
 
    }
749
 
  return FALSE;
750
 
}
751
 
 
752
 
 
753
 
/* Returns a random time based on the current level */
754
 
static void get_random_hour(GcomprisTime *time)
755
 
{
756
 
 
757
 
  time->hour=g_random_int()%12;
758
 
 
759
 
  if(gcomprisBoard->level>3)
760
 
    time->second=g_random_int()%60;
761
 
  else time->second=0;
762
 
 
763
 
  time->minute=g_random_int()%60;
764
 
 
765
 
  switch(gcomprisBoard->level)
766
 
    {
767
 
    case 1:
768
 
      time->minute=g_random_int()%4*15;
769
 
      break;
770
 
    case 2:
771
 
      time->minute=g_random_int()%12*5;
772
 
      break;
773
 
    default:
774
 
      break;
775
 
    }
776
 
 
777
 
}