Back to index

gcompris  8.2.2
colors.c
Go to the documentation of this file.
00001 /* gcompris - colors.c
00002  *
00003  * Copyright (C) 2002 Pascal Georges
00004  *
00005  *   This program is free software; you can redistribute it and/or modify
00006  *   it under the terms of the GNU General Public License as published by
00007  *   the Free Software Foundation; either version 2 of the License, or
00008  *   (at your option) any later version.
00009  *
00010  *   This program is distributed in the hope that it will be useful,
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *   GNU General Public License for more details.
00014  *
00015  *   You should have received a copy of the GNU General Public License
00016  *   along with this program; if not, write to the Free Software
00017  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018  */
00019 
00020 #include "gcompris/gcompris.h"
00021 
00022 #define SOUNDLISTFILE PACKAGE
00023 
00024 static GcomprisBoard *gcomprisBoard = NULL;
00025 static gboolean board_paused = TRUE;
00026 
00027 static void           start_board (GcomprisBoard *agcomprisBoard);
00028 static void           pause_board (gboolean pause);
00029 static void           end_board (void);
00030 static gboolean              is_our_board (GcomprisBoard *gcomprisBoard);
00031 static int gamewon;
00032 
00033 static void           process_ok(void);
00034 static void           highlight_selected(int);
00035 static void           game_won(void);
00036 static void           repeat(void);
00037 static void           colors_config_start(GcomprisBoard *agcomprisBoard,
00038                                         GcomprisProfile *aProfile);
00039 static void           colors_config_stop(void);
00040 
00041 /* ================================================================ */
00042 static GnomeCanvasGroup *boardRootItem = NULL;
00043 static GnomeCanvasItem *highlight_image_item = NULL;
00044 
00045 static GnomeCanvasItem *colors_create_item(GnomeCanvasGroup *parent);
00046 static void colors_destroy_all_items(void);
00047 static void colors_next_level(void);
00048 static gint item_event(GnomeCanvasItem *item, GdkEvent *event, gpointer data);
00049 static int highlight_width, highlight_height;
00050 static GList * listColors = NULL;
00051 
00052 #define LAST_COLOR 10
00053 static gchar *colors[LAST_COLOR*2] = {
00054   "blue",     N_("Click on the blue duck"),
00055   "brown",    N_("Click on the brown duck"),
00056   "green",    N_("Click on the green duck"),
00057   "grey",     N_("Click on the grey duck"),
00058   "orange",   N_("Click on the orange duck"),
00059   "purple",   N_("Click on the purple duck"),
00060   "red",      N_("Click on the red duck"),
00061   "yellow",   N_("Click on the yellow duck"),
00062   "black",    N_("Click on the black duck"),
00063   "white",    N_("Click on the white duck")
00064 };
00065 
00066 static int X[] = {75,212,242,368,414,533,578,709};
00067 static int Y[] = {25,170,180,335,337,500};
00068 
00069 /* Description of this plugin */
00070 static BoardPlugin menu_bp =
00071   {
00072     NULL,
00073     NULL,
00074     "Colors",
00075     "Click on the right color",
00076     "Pascal Georges <pascal.georges1@free.fr>",
00077     NULL,
00078     NULL,
00079     NULL,
00080     NULL,
00081     start_board,
00082     pause_board,
00083     end_board,
00084     is_our_board,
00085     NULL,
00086     NULL,
00087     NULL,//set_level,
00088     NULL,
00089     repeat,
00090     colors_config_start,
00091     colors_config_stop
00092   };
00093 
00094 /* =====================================================================
00095  *
00096  * =====================================================================*/
00097 GET_BPLUGIN_INFO(colors)
00098 
00099 
00100 /* ======================= */
00101 /* = config_start        = */
00102 /* ======================= */
00103 
00104 static GcomprisProfile *profile_conf;
00105 static GcomprisBoard   *board_conf;
00106 
00107 static void save_table (gpointer key,
00108                      gpointer value,
00109                      gpointer user_data)
00110 {
00111   gc_db_set_board_conf ( profile_conf,
00112                          board_conf,
00113                          (gchar *) key,
00114                          (gchar *) value);
00115 }
00116 
00117 static void
00118 conf_ok(GHashTable *table)
00119 {
00120   if (!table){
00121     if (gcomprisBoard)
00122       pause_board(FALSE);
00123     return;
00124   }
00125 
00126   g_hash_table_foreach(table, (GHFunc) save_table, NULL);
00127 
00128   if (gcomprisBoard){
00129     GHashTable *config = gc_db_get_board_conf();
00130 
00131     if (profile_conf)
00132       config = gc_db_get_board_conf();
00133     else
00134       config = table;
00135 
00136     gc_locale_reset();
00137     gc_locale_set(g_hash_table_lookup(config, "locale_sound"));
00138 
00139     if (profile_conf)
00140       g_hash_table_destroy(config);
00141 
00142     colors_next_level();
00143 
00144     pause_board(FALSE);
00145 
00146   }
00147   board_conf = NULL;
00148   profile_conf = NULL;
00149 }
00150 
00151 static void
00152 colors_config_start(GcomprisBoard *agcomprisBoard,
00153                   GcomprisProfile *aProfile)
00154 {
00155   board_conf = agcomprisBoard;
00156   profile_conf = aProfile;
00157 
00158   gchar *label;
00159 
00160   if (gcomprisBoard)
00161     pause_board(TRUE);
00162 
00163   label = g_strdup_printf("<b>%s</b> configuration\n for profile <b>%s</b>",
00164                        agcomprisBoard->name, aProfile ? aProfile->name : "");
00165 
00166   gc_board_config_window_display(label, conf_ok);
00167 
00168   g_free(label);
00169 
00170   /* init the combo to previously saved value */
00171   GHashTable *config = gc_db_get_conf( profile_conf, board_conf);
00172 
00173   gchar *saved_locale_sound = g_hash_table_lookup( config, "locale_sound");
00174 
00175   gc_board_config_combo_locales_asset( "Select sound locale", saved_locale_sound,
00176                             "sounds/$LOCALE/colors/purple.ogg");
00177 
00178   g_hash_table_destroy(config);
00179 
00180 }
00181 
00182 
00183 /* ======================= */
00184 /* = config_stop        = */
00185 /* ======================= */
00186 static void
00187 colors_config_stop()
00188 {
00189 }
00190 
00191 
00192 /* =====================================================================
00193  * in : boolean TRUE = PAUSE : FALSE = CONTINUE
00194  * =====================================================================*/
00195 static void pause_board (gboolean pause)
00196 {
00197   if(gcomprisBoard==NULL)
00198     return;
00199 
00200   gc_bar_hide(FALSE);
00201   if(gamewon == TRUE && pause == FALSE) /* the game is won */
00202     game_won();
00203 
00204   board_paused = pause;
00205 }
00206 
00207 /* =====================================================================
00208  *
00209  * =====================================================================*/
00210 static void start_board (GcomprisBoard *agcomprisBoard) {
00211   GcomprisProperties *properties = gc_prop_get();
00212   GList * list = NULL;
00213   int * item;
00214   int i;
00215 
00216   GHashTable *config = gc_db_get_board_conf();
00217 
00218   gc_locale_set(g_hash_table_lookup(config, "locale_sound"));
00219 
00220   g_hash_table_destroy(config);
00221 
00222   gc_sound_pause();
00223 
00224   if(agcomprisBoard!=NULL) {
00225     gcomprisBoard=agcomprisBoard;
00226     gc_set_background(gnome_canvas_root(gcomprisBoard->canvas), "colors/colors_bg.png");
00227     gcomprisBoard->level=1;
00228     gcomprisBoard->maxlevel=1;
00229 
00230     if(properties->fx) {
00231       gc_bar_set(GC_BAR_CONFIG|GC_BAR_REPEAT);
00232     } else {
00233       gc_bar_set(GC_BAR_CONFIG);
00234     }
00235 
00236     gamewon = FALSE;
00237 
00238     // we generate a list of color indexes in a random order
00239     for (i=0; i<LAST_COLOR; i++)
00240       list = g_list_append(list, GINT_TO_POINTER(i));
00241 
00242     while ((g_list_length(list) > 0)) {
00243       i = RAND(0,g_list_length(list)-1);
00244       item = g_list_nth_data(list, i);
00245       listColors = g_list_append(listColors, item);
00246       list = g_list_remove(list, item);
00247     }
00248     g_list_free(list);
00249 
00250     gtk_signal_connect(GTK_OBJECT(gcomprisBoard->canvas), "event",  (GtkSignalFunc) item_event, NULL);
00251     colors_next_level();
00252     pause_board(FALSE);
00253   }
00254 }
00255 
00256 /* =====================================================================
00257  *
00258  * =====================================================================*/
00259 static void end_board () {
00260 
00261   if(gcomprisBoard!=NULL){
00262     pause_board(TRUE);
00263     gc_score_end();
00264     colors_destroy_all_items();
00265     // free list
00266     while (g_list_length(listColors) > 0)
00267       listColors = g_list_remove(listColors, g_list_nth_data(listColors,0));
00268     g_list_free(listColors);
00269     listColors=NULL;
00270   }
00271   gc_locale_reset();
00272   gcomprisBoard = NULL;
00273   gc_sound_resume();
00274 }
00275 
00276 /* =====================================================================
00277  *
00278  * =====================================================================*/
00279 static gboolean is_our_board (GcomprisBoard *gcomprisBoard) {
00280   if (gcomprisBoard) {
00281     if(g_strcasecmp(gcomprisBoard->type, "colors")==0) {
00282       /* Set the plugin entry */
00283       gcomprisBoard->plugin=&menu_bp;
00284       return TRUE;
00285     }
00286   }
00287   return FALSE;
00288 }
00289 /* =====================================================================
00290  * set initial values for the next level
00291  * =====================================================================*/
00292 static void colors_next_level() {
00293   colors_destroy_all_items();
00294   gamewon = FALSE;
00295 
00296   /* Try the next level */
00297   colors_create_item(gnome_canvas_root(gcomprisBoard->canvas));
00298   repeat();
00299 }
00300 /* ======================================= */
00301 static void repeat (){
00302 
00303   if(gcomprisBoard!=NULL)
00304     {
00305       char *str  = NULL;
00306       GcomprisProperties *properties = gc_prop_get();
00307 
00308       str = g_strdup_printf("sounds/$LOCALE/colors/%s.ogg",
00309                          colors[GPOINTER_TO_INT(g_list_nth_data(listColors, 0))*2]);
00310 
00311       /* If we don't find a sound in our locale or the sounds are disabled */
00312       if(str && properties->fx)
00313        {
00314          gc_sound_play_ogg(str, NULL);
00315        }
00316       else
00317        {
00318          str = g_strdup_printf(gettext(colors[GPOINTER_TO_INT(g_list_nth_data(listColors, 0))*2+1]));
00319 
00320          gnome_canvas_item_new (boardRootItem,
00321                              gnome_canvas_text_get_type (),
00322                              "text", str,
00323                              "font", gc_skin_font_board_huge_bold,
00324                              "x", (double) BOARDWIDTH/2+2,
00325                              "y", (double) BOARDHEIGHT-25+2,
00326                              "anchor", GTK_ANCHOR_CENTER,
00327                              "fill_color", "black",
00328                              NULL);
00329 
00330          gnome_canvas_item_new (boardRootItem,
00331                              gnome_canvas_text_get_type (),
00332                              "text", str,
00333                              "font", gc_skin_font_board_huge_bold,
00334                              "x", (double) BOARDWIDTH/2,
00335                              "y", (double) BOARDHEIGHT-25,
00336                              "anchor", GTK_ANCHOR_CENTER,
00337                              "fill_color", "blue",
00338                              NULL);
00339        }
00340 
00341       g_free(str);
00342     }
00343 }
00344 /* =====================================================================
00345  * Destroy all the items
00346  * =====================================================================*/
00347 static void colors_destroy_all_items() {
00348   if(boardRootItem!=NULL)
00349     gtk_object_destroy (GTK_OBJECT(boardRootItem));
00350 
00351   boardRootItem = NULL;
00352 }
00353 
00354 /* =====================================================================
00355  *
00356  * =====================================================================*/
00357 static GnomeCanvasItem *colors_create_item(GnomeCanvasGroup *parent) {
00358   GdkPixbuf *highlight_pixmap = NULL;
00359   char *str = NULL;
00360 
00361   boardRootItem = GNOME_CANVAS_GROUP(
00362                                  gnome_canvas_item_new (gnome_canvas_root(gcomprisBoard->canvas),
00363                                                      gnome_canvas_group_get_type (),
00364                                                      "x", (double) 0,
00365                                                      "y", (double) 0,
00366                                                      NULL));
00367 
00368   str = g_strdup_printf("%s/%s", gcomprisBoard->boarddir, "colors_highlight.png");
00369   highlight_pixmap = gc_pixmap_load(str);
00370 
00371   highlight_image_item = gnome_canvas_item_new (boardRootItem,
00372                                           gnome_canvas_pixbuf_get_type (),
00373                                           "pixbuf", highlight_pixmap,
00374                                           "x", (double) 0,
00375                                           "y", (double) 0,
00376                                           "width", (double) gdk_pixbuf_get_width(highlight_pixmap),
00377                                           "height", (double) gdk_pixbuf_get_height(highlight_pixmap),
00378                                           "width_set", TRUE,
00379                                           "height_set", TRUE,
00380                                           NULL);
00381 
00382   highlight_width = gdk_pixbuf_get_width(highlight_pixmap);
00383   highlight_height = gdk_pixbuf_get_height(highlight_pixmap);
00384 
00385   g_free(str);
00386 
00387   gnome_canvas_item_hide(highlight_image_item);
00388 
00389   gdk_pixbuf_unref(highlight_pixmap);
00390 
00391   return NULL;
00392 }
00393 /* =====================================================================
00394  *
00395  * =====================================================================*/
00396 static void game_won() {
00397   gcomprisBoard->sublevel++;
00398 
00399   listColors = g_list_remove(listColors, g_list_nth_data(listColors,0));
00400 
00401   if( g_list_length(listColors) <= 0 ) { // the current board is finished : bail out
00402     gc_bonus_end_display(BOARD_FINISHED_TUXLOCO);
00403     return;
00404   }
00405 
00406   colors_next_level();
00407 }
00408 /* =====================================================================
00409  *
00410  * =====================================================================*/
00411 static gboolean process_ok_timeout() {
00412   gc_bonus_display(gamewon, BONUS_GNU);
00413   return FALSE;
00414 }
00415 
00416 static void process_ok() {
00417   gc_bar_hide(TRUE);
00418   // leave time to display the right answer
00419   g_timeout_add(TIME_CLICK_TO_BONUS, process_ok_timeout, NULL);
00420 }
00421 /* =====================================================================
00422  *
00423  * =====================================================================*/
00424 static gint item_event(GnomeCanvasItem *item, GdkEvent *event, gpointer data) {
00425   double x, y;
00426   int i, j, clicked;
00427 
00428   x = event->button.x;
00429   y = event->button.y;
00430 
00431   if (!gcomprisBoard || board_paused)
00432     return FALSE;
00433 
00434   switch (event->type)
00435     {
00436     case GDK_BUTTON_PRESS:
00437       gnome_canvas_c2w(gcomprisBoard->canvas, x, y, &x, &y);
00438       clicked = -1;
00439       for (i=0; i<4; i++) {
00440        for (j=0; j<2; j++) {
00441          if (x>X[i*2] && x<X[i*2+1] && y>Y[j*2] && y<Y[j*2+1]) {
00442            clicked = j*4 + i;
00443          }
00444        }
00445       }
00446       if (x>X[2] && x<X[3] && y>Y[4] && y<Y[5])
00447        clicked = 8;
00448       if (x>X[4] && x<X[5] && y>Y[4] && y<Y[5])
00449        clicked = 9;
00450 
00451       if (clicked >= 0) {
00452        board_paused = TRUE;
00453        highlight_selected(clicked);
00454        gamewon = (clicked == GPOINTER_TO_INT(g_list_nth_data(listColors,0)));
00455         process_ok();
00456       }
00457       break;
00458 
00459     default:
00460       break;
00461     }
00462   return FALSE;
00463 }
00464 
00465 /* =====================================================================
00466  *
00467  * =====================================================================*/
00468 static void highlight_selected(int c) {
00469   int x, y;
00470 
00471   g_assert(c>=0 && c<=9);
00472 
00473   if (c<8) {
00474     x = (X[(c%4)*2] + X[(c%4)*2+1]) /2;
00475     y = (Y[(int)(c/4)*2] + Y[(int)(c/4)*2+1]) /2;
00476   } else {
00477     y = (Y[4]+Y[5]) /2;
00478     if (c==8)
00479       x = (X[2] + X[3]) /2;
00480     else
00481       x = (X[4] + X[5]) /2;
00482   }
00483   x -= highlight_width/2;
00484   y -= highlight_height/2;
00485   gnome_canvas_item_show(highlight_image_item);
00486   gc_item_absolute_move(highlight_image_item, x, y);
00487 }