Back to index

gcompris  8.2.2
bonus.c
Go to the documentation of this file.
00001 /* gcompris - bonus.c
00002  *
00003  * Time-stamp: <2001/10/15 01:10:21 bruno>
00004  *
00005  * Copyright (C) 2001 Pascal George
00006  *
00007  * This program is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; either version 2 of the License, or
00010  * (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00020  */
00021 
00022 #include "gcompris.h"
00023 #include "gc_core.h"
00024 
00025 #include <ctype.h>
00026 #include <math.h>
00027 
00028 #define SOUNDLISTFILE PACKAGE
00029 #define BONUS_DURATION 2000
00030 #define TUX_TIME_STEP 300
00031 
00032 static GnomeCanvasGroup *bonus_group   = NULL;
00033 static GnomeCanvasItem  *door1_item    = NULL;
00034 static GnomeCanvasItem  *door2_item    = NULL;
00035 static GnomeCanvasItem  *tuxplane_item = NULL;
00036 
00037 static gboolean gc_bonus_end_display_running = FALSE;
00038 static gboolean bonus_display_running = FALSE;
00039 
00040 static gint end_bonus_id = 0, gc_bonus_end_display_id = 0;
00041 
00042 //static gint end_board_count = 0;
00043 static int left_door_limit = 0;
00044 
00045 // List of sounds to use for greetings
00046 static gchar *greetingsList[] =
00047 {
00048   "sounds/$LOCALE/misc/congratulation.ogg",
00049   "sounds/$LOCALE/misc/great.ogg",
00050   "sounds/$LOCALE/misc/good.ogg",
00051   "sounds/$LOCALE/misc/awesome.ogg",
00052   "sounds/$LOCALE/misc/fantastic.ogg",
00053   "sounds/$LOCALE/misc/waytogo.ogg",
00054   "sounds/$LOCALE/misc/super.ogg",
00055   "sounds/$LOCALE/misc/perfect.ogg"
00056 };
00057 #define NUMBER_OF_GREETINGS G_N_ELEMENTS(greetingsList)
00058 
00059 // List of sounds to use for loosing
00060 static gchar *loosingList[] =
00061 {
00062   "sounds/$LOCALE/misc/check_answer.ogg",
00063 };
00064 #define NUMBER_OF_LOOSING 1
00065 
00066 /*
00067  * Function definition
00068  * -------------------
00069  */
00070 static void    bonus_image(char *,BonusStatusList);
00071 static void    end_bonus(void);
00072 
00073 
00074 /* ==================================== */
00075 static void
00076 end_gc_bonus_end_display() {
00077   double dx1, dy1, dx2, dy2;
00078   //end_board_count++;
00079   gnome_canvas_item_get_bounds(tuxplane_item,  &dx1, &dy1, &dx2, &dy2);
00080   // animates tuxplane
00081   if (/*end_board_count*/ dx2 +50.0 < (double) (left_door_limit)) {
00082     gnome_canvas_item_move(tuxplane_item, 50, 0);
00083     return;
00084   }
00085 
00086   if (gc_bonus_end_display_id) {
00087     gtk_timeout_remove(gc_bonus_end_display_id);
00088     gc_bonus_end_display_id = 0;
00089   }
00090 
00091   if(door1_item)
00092     gtk_object_destroy (GTK_OBJECT(door1_item));
00093   if(door2_item)
00094     gtk_object_destroy (GTK_OBJECT(door2_item));
00095   if(tuxplane_item)
00096     gtk_object_destroy (GTK_OBJECT(tuxplane_item));
00097 
00098   door1_item = NULL;
00099   door2_item = NULL;
00100   tuxplane_item = NULL;
00101 
00102   gc_bonus_end_display_running = FALSE;
00103   
00104   gc_bar_hide(FALSE);
00105 
00106   // go back to previous board layout
00107   if (gc_board_get_current_board_plugin()->end_board)
00108     gc_board_get_current_board_plugin()->end_board();
00109   gc_board_end();
00110 }
00111 /* ==================================== */
00112 #define OFFSET 100
00113 void
00114 gc_bonus_end_display(BoardFinishedList type) {
00115   GcomprisBoard *gcomprisBoard = gc_board_get_current();
00116 
00117   int x,y;
00118   GdkPixbuf *pixmap_door1 = NULL,*pixmap_door2 = NULL,*pixmap_tuxplane = NULL;
00119   char * str = NULL;
00120 
00121   g_assert(type < BOARD_FINISHED_LAST);
00122 
00123   gc_bar_hide(TRUE);
00124 
00125   if (gc_bonus_end_display_running)
00126     return;
00127   else
00128     gc_bonus_end_display_running = TRUE;
00129 
00130   /* First pause the board */
00131   gc_board_pause(TRUE);
00132 
00133   /* WARNING: I remove 1 to the BOARD_FINISHED_LAST because RANDOM is for GOOD end only */
00134   if(type==BOARD_FINISHED_RANDOM)
00135     type = RAND(1,BOARD_FINISHED_LAST-2);
00136 
00137   /* Record the end of board */
00138   gc_log_end (gcomprisBoard, GCOMPRIS_LOG_STATUS_COMPLETED);
00139 
00140   switch (type) {
00141        case BOARD_FINISHED_TUXPLANE :
00142               str = g_strdup_printf("gcompris/misc/tuxplane.png");
00143               break;
00144        case BOARD_FINISHED_TUXLOCO :
00145               str = g_strdup_printf("gcompris/misc/tuxloco.png");
00146               break;
00147        case BOARD_FINISHED_TOOMANYERRORS :
00148               str = g_strdup_printf("gcompris/misc/toomanyerrors.png");
00149               break;
00150        default :
00151               str = g_strdup_printf("gcompris/misc/tuxplane.png");
00152               break;
00153   }
00154 
00155   pixmap_door1 = gc_pixmap_load("gcompris/misc/door1.png");
00156   pixmap_door2 = gc_pixmap_load("gcompris/misc/door2.png");
00157   pixmap_tuxplane = gc_pixmap_load(str);
00158   g_free(str);
00159 
00160   g_assert(gcomprisBoard != NULL);
00161 
00162   x = gcomprisBoard->width - OFFSET - gdk_pixbuf_get_width(pixmap_door1);
00163   y = OFFSET;
00164   left_door_limit = x + gdk_pixbuf_get_width(pixmap_door1);
00165 
00166   door1_item = gnome_canvas_item_new (gnome_canvas_root(gcomprisBoard->canvas),
00167                                   gnome_canvas_pixbuf_get_type (),
00168                                   "pixbuf", pixmap_door1,
00169                                   "x", (double) x,
00170                                   "y", (double) y,
00171                                   "width", (double) gdk_pixbuf_get_width(pixmap_door1),
00172                                   "height", (double) gdk_pixbuf_get_height(pixmap_door1),
00173                                   "width_set", TRUE,
00174                                   "height_set", TRUE,
00175                                   NULL);
00176 
00177   x = OFFSET;
00178   y = (gcomprisBoard->height - gdk_pixbuf_get_height(pixmap_tuxplane)) /2;
00179   tuxplane_item = gnome_canvas_item_new (gnome_canvas_root(gcomprisBoard->canvas),
00180                                   gnome_canvas_pixbuf_get_type (),
00181                                   "pixbuf", pixmap_tuxplane,
00182                                   "x", (double) x,
00183                                   "y", (double) y,
00184                                   "width", (double) gdk_pixbuf_get_width(pixmap_tuxplane),
00185                                   "height", (double) gdk_pixbuf_get_height(pixmap_tuxplane),
00186                                   "width_set", TRUE,
00187                                   "height_set", TRUE,
00188                                   NULL);
00189 
00190   x = gcomprisBoard->width - OFFSET - gdk_pixbuf_get_width(pixmap_door2);
00191   y = OFFSET;
00192   door2_item = gnome_canvas_item_new (gnome_canvas_root(gcomprisBoard->canvas),
00193                                   gnome_canvas_pixbuf_get_type (),
00194                                   "pixbuf", pixmap_door2,
00195                                   "x", (double) x,
00196                                   "y", (double) y,
00197                                   "width", (double) gdk_pixbuf_get_width(pixmap_door2),
00198                                   "height", (double) gdk_pixbuf_get_height(pixmap_door2),
00199                                   "width_set", TRUE,
00200                                   "height_set", TRUE,
00201                                   NULL);
00202 
00203   gdk_pixbuf_unref(pixmap_door1);
00204   gdk_pixbuf_unref(pixmap_door2);
00205   gdk_pixbuf_unref(pixmap_tuxplane);
00206 
00207   gc_bonus_end_display_id = gtk_timeout_add (TUX_TIME_STEP, (GtkFunction) end_gc_bonus_end_display, NULL);
00208 
00209 }
00210 
00211 /* ==================================== */
00212 void
00213 gc_bonus_display(BonusStatusList gamewon, BonusList bonus_id)
00214 {
00215   gchar *absolute_file;
00216 
00217   g_assert(bonus_id < BONUS_LAST);
00218 
00219   gc_bar_hide(TRUE);
00220 
00221   if (bonus_display_running)
00222     return;
00223   else
00224     bonus_display_running = TRUE;
00225   
00226   if(gamewon == BOARD_WIN || gamewon == BOARD_DRAW) {
00227     absolute_file = gc_file_find_absolute(greetingsList[RAND(0, NUMBER_OF_GREETINGS-1)]);
00228 
00229     if (absolute_file)
00230       {
00231        gc_sound_play_ogg(absolute_file, NULL);
00232        g_free(absolute_file);
00233       }
00234     else
00235       gc_sound_play_ogg("sounds/wahoo.ogg", NULL);
00236 
00237   } else {
00238     absolute_file = gc_file_find_absolute(loosingList[RAND(0, NUMBER_OF_LOOSING-1)]);
00239 
00240     if (absolute_file)
00241       {
00242        gc_sound_play_ogg(absolute_file, NULL);
00243        g_free(absolute_file);
00244       }
00245     else
00246       gc_sound_play_ogg("sounds/crash.ogg", NULL);
00247   }
00248 
00249   /* First pause the board */
00250   gc_board_pause(TRUE);
00251 
00252   if(bonus_id==BONUS_RANDOM)
00253     bonus_id = RAND(1, BONUS_LAST-2);
00254 
00255   switch(bonus_id) {
00256   case BONUS_SMILEY :
00257     bonus_image("smiley",gamewon);
00258     break;
00259   case BONUS_FLOWER :
00260     bonus_image("flower",gamewon);
00261     break;
00262   case BONUS_TUX :
00263     bonus_image("tux",gamewon);
00264     break;
00265   case BONUS_GNU :
00266     bonus_image("gnu",gamewon);
00267     break;
00268   default :
00269     bonus_image("smiley",gamewon);
00270     break;
00271   }
00272 }
00273 
00274 /* ==================================== */
00275 static void
00276 bonus_image(char *image, BonusStatusList gamewon)
00277 {
00278   char *str= NULL;
00279   int x,y;
00280   GdkPixbuf *pixmap = NULL;
00281   GcomprisBoard *gcomprisBoard = gc_board_get_current();
00282 
00283   /* check that bonus_group is a singleton */
00284   if (bonus_group != NULL) {
00285     bonus_display_running = FALSE;
00286     return;
00287   }
00288 
00289 
00290   switch (gamewon) {
00291   case BOARD_WIN :
00292     str = g_strdup_printf("%s%s%s", "gcompris/bonus/",image,"_good.png");
00293     /* Record the end of board */
00294     gc_log_end (gcomprisBoard, GCOMPRIS_LOG_STATUS_PASSED);
00295     break;
00296   case BOARD_LOOSE :
00297     str = g_strdup_printf("%s%s%s", "gcompris/bonus/",image,"_bad.png");
00298     /* Record the end of board */
00299     gc_log_end (gcomprisBoard, GCOMPRIS_LOG_STATUS_FAILED);
00300     break;
00301   case BOARD_DRAW :
00302     /* We do not have draw image so a text message is displayed bellow under the
00303      * win image
00304      */
00305     str = g_strdup_printf("%s%s%s", "gcompris/bonus/",image,"_good.png");
00306     /* Record the end of board */
00307     gc_log_end (gcomprisBoard, GCOMPRIS_LOG_STATUS_DRAW);
00308     break;
00309   }
00310 
00311   /* Log the board start again*/
00312   gc_log_start(gcomprisBoard);
00313 
00314   g_assert(gcomprisBoard != NULL);
00315 
00316   pixmap = gc_pixmap_load(str);
00317 
00318   bonus_group = (GnomeCanvasGroup *) \
00319     gnome_canvas_item_new (gnome_canvas_root(gcomprisBoard->canvas),
00320                         gnome_canvas_group_get_type (),
00321                         "x", (double)0,
00322                         "y", (double)0,
00323                         NULL);
00324 
00325   x = (gcomprisBoard->width - gdk_pixbuf_get_width(pixmap))/2;
00326   y = (gcomprisBoard->height - gdk_pixbuf_get_height(pixmap))/2;
00327   gnome_canvas_item_new (bonus_group,
00328                       gnome_canvas_pixbuf_get_type (),
00329                       "pixbuf", pixmap,
00330                       "x", (double) x,
00331                       "y", (double) y,
00332                       "width", (double) gdk_pixbuf_get_width(pixmap),
00333                       "height", (double) gdk_pixbuf_get_height(pixmap),
00334                       "width_set", TRUE,
00335                       "height_set", TRUE,
00336                       NULL);
00337 
00338 
00339   if(gamewon==BOARD_DRAW) {
00340     gnome_canvas_item_new (bonus_group,
00341                         gnome_canvas_text_get_type (),
00342                         "text", _("Drawn game"),
00343                         "font", gc_skin_font_title,
00344                         "x", (double) BOARDWIDTH/2 + 1.0,
00345                         "y", (double) gdk_pixbuf_get_height(pixmap) + 1.0,
00346                         "anchor", GTK_ANCHOR_CENTER,
00347                         "fill_color", "black",
00348                         NULL);
00349     gnome_canvas_item_new (bonus_group,
00350                         gnome_canvas_text_get_type (),
00351                         "text", _("Drawn game"),
00352                         "font", gc_skin_font_title,
00353                         "x", (double) BOARDWIDTH/2,
00354                         "y", (double) gdk_pixbuf_get_height(pixmap),
00355                         "anchor", GTK_ANCHOR_CENTER,
00356                         "fill_color_rgba", gc_skin_color_title,
00357                         NULL);
00358   }
00359 
00360   gdk_pixbuf_unref(pixmap);
00361 
00362   g_free(str);
00363   end_bonus_id = gtk_timeout_add (BONUS_DURATION, (GtkFunction) end_bonus, NULL);
00364 }
00365 
00366 /* ==================================== */
00367 static void
00368 end_bonus()
00369 {
00370   if (end_bonus_id) {
00371     gtk_timeout_remove (end_bonus_id);
00372     end_bonus_id = 0;
00373   }
00374 
00375   if(bonus_group)
00376     gtk_object_destroy (GTK_OBJECT(bonus_group));
00377 
00378   bonus_group = NULL;
00379   bonus_display_running = FALSE;
00380 
00381   gc_bar_hide(FALSE);
00382 
00383   /* Re-Start the board */
00384   gc_board_pause(FALSE);
00385 }