diff options
-rw-r--r-- | .cvsignore | 1 | ||||
-rw-r--r-- | ChangeLog | 28 | ||||
-rw-r--r-- | boards/boardicons/chronos.png | bin | 0 -> 5600 bytes | |||
-rw-r--r-- | boards/flags/en_CA.png | bin | 0 -> 641 bytes | |||
-rw-r--r-- | boards/flags/gcompris_flags.assetml.in | 5 | ||||
-rw-r--r-- | boards/gletters/gletters.ja | 134 | ||||
-rw-r--r-- | boards/melody.xml.in | 7 | ||||
-rw-r--r-- | configure.in | 3 | ||||
-rwxr-xr-x | list_translators.sh | 15 | ||||
-rw-r--r-- | src/boards/clockgame.c | 16 | ||||
-rw-r--r-- | src/boards/gletters.c | 463 | ||||
-rw-r--r-- | src/boards/memory.c | 211 | ||||
-rw-r--r-- | src/boards/shapegame.c | 5 | ||||
-rw-r--r-- | src/gcompris/about.c | 4 | ||||
-rw-r--r-- | src/gcompris/config.c | 3 | ||||
-rw-r--r-- | src/gcompris/gameutil.c | 13 |
16 files changed, 698 insertions, 210 deletions
@@ -16,6 +16,7 @@ configure.scan core-translation-report intl libtool +list_translators.sh ltconfig ltmain.sh missing @@ -1,3 +1,31 @@ +2004-02-28 Bruno coudoin <bruno.coudoin@free.fr> + + * .cvsignore: added list_translators.sh + * boards/boardicons/chronos.png: added by Jose + * boards/flags/en_CA.png: added. taken from gkb. + * boards/flags/gcompris_flags.assetml.in: added en_CA.png + * boards/gletters/gletters.ja: created by Yan Seiner. It holds the japanese letters/key mapping. + * boards/melody.xml.in: added help + * configure.in: fixed bug 134838 python libm not detected + * list_translators.sh: added. used to list the last translators after a CVS TAG + * src/boards/clockgame.c: (display_hour), (display_minute), + (display_second), (clockgame_create_item): changed uint by guint. more portable + * src/boards/gletters.c: (level_set_score), (pause_board), + (fill_letters), (load_default_charset), (whitespace), + (load_charset_from_file), (get_charset), (start_board), + (end_board), (set_level), (is_falling_letter), (key_press), + (gletters_next_level), (gletters_create_item), (player_win), + (player_loose): added support for letters/key mapping in a specific file (by Yan Seiner) + * src/boards/memory.c: (memory_next_level), (get_image), + (create_item), (item_event): complete review to work without letter pixmap. + * src/boards/shapegame.c: (increment_sublevel): fixed for the logs + * src/gcompris/config.c: added en_CA + * src/gcompris/gameutil.c: (gcompris_load_pixmap): moved a var declaration to work with old compiler. + +2004-02-18 Bruno coudoin <bruno.coudoin@free.fr> + + * boards/melody.xml.in: added prerequisite and manual (by Jose) + 2004-02-24 Adam Weinberger <adamw@FreeBSD.org> * configure.in: Added "en_CA" (Canadian English) to ALL_LINGUAS. diff --git a/boards/boardicons/chronos.png b/boards/boardicons/chronos.png Binary files differnew file mode 100644 index 0000000..e88e46e --- /dev/null +++ b/boards/boardicons/chronos.png diff --git a/boards/flags/en_CA.png b/boards/flags/en_CA.png Binary files differnew file mode 100644 index 0000000..8d6d0da --- /dev/null +++ b/boards/flags/en_CA.png diff --git a/boards/flags/gcompris_flags.assetml.in b/boards/flags/gcompris_flags.assetml.in index ec73ba8..2b9bdeb 100644 --- a/boards/flags/gcompris_flags.assetml.in +++ b/boards/flags/gcompris_flags.assetml.in @@ -45,6 +45,11 @@ <_Credits>All these images taken from GKB Keyboard Switcher applet</_Credits> <Categories>flags</Categories> </Asset> + <Asset file="en_CA.png" mimetype="image/png"> + <_Description>Canadian English</_Description> + <_Credits>All these images taken from GKB Keyboard Switcher applet</_Credits> + <Categories>flags</Categories> + </Asset> <Asset file="es.png" mimetype="image/png"> <_Description>Spanish</_Description> <_Credits>All these images taken from GKB Keyboard Switcher applet</_Credits> diff --git a/boards/gletters/gletters.ja b/boards/gletters/gletters.ja new file mode 100644 index 0000000..dfb794f --- /dev/null +++ b/boards/gletters/gletters.ja @@ -0,0 +1,134 @@ +# commands can appear in any order +# comments begin with '#' +# blank lines are ignored +# all items in this file are optional and have program defaults + +# levels define the characters to be dropped for that level of play +# note that the gletters keyboard is case-insensitive so the A key +# will "pop" both A and a, no shifting or mapping is necessary + +level 1 ABCDEFGHIJKLMNOPQRSTUVWXYZ +level 2 ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 +level 3 ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvxyz +level 4 あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをん +level 5 アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲン +level 6 ABCDEFGHIJKLMNOPQRSTUVWXYZあいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをん +level 7 ABCDEFGHIJKLMNOPQRSTUVWXYZアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲン +level 8 あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをんアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲン +level 9 あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをんアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲンABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvxyz + +# key maps map keys on the keyboard to characters that are dropped +# so for example for this japanese keyboard, we map the lower case +# keys letters (a-z0-9) and some punctuation to hiragana and katakana +# gcompris at this point does not recognize alternate input methods +# so kana input has to be done via mapping the romaji keyboard + +key 1ぬ +key 2ふ +key 3あ +key 4う +key 5え +key 6お +key 7や +key 8ゆ +key 9よ +key 0わ +key -ほ +key ^へ +key qた +key wて +key eい +key rす +key tか +key yん +key uな +key iに +key oら +key pせ +key aち +key sと +key dし +key fは +key gき +key hく +key jま +key kの +key lり +key ;れ +key :け +key 」む +key zつ +key xさ +key cそ +key vひ +key bこ +key nみ +key mも +key ,ぬ +key .る +key /ぬ +key \ろ +key 1ヌ +key 2フ +key 3ア +key 4ウ +key 5エ +key 6オ +key 7ヤ +key 8ユ +key 9ヨ +key 0ワ +key -ホ +key ^ヘ +key qタ +key wテ +key eイ +key rス +key tカ +key yン +key uナ +key iニ +key oラ +key pセ +key aチ +key sト +key dシ +key fハ +key gキ +key hク +key jマ +key kノ +key lリ +key ;レ +key :ケ +key 」ム +key zツ +key xサ +key cソ +key vヒ +key bニ +key nミ +key mモ +key ,ヌ +key .ロ +key /ヌ +key \ロ + +# the fallrate is the rate at which letters fall +# the smaller the numbers, the faster they fall +# the first number is the base +# the second number is the variability by level +# the sum of the numbers should be around 140 +# use a slower fall rate for beginning typists +# use a faster rate to keep the challenge for more +# skilled typists + +fallrate 40 100 + +# the droprate is the rate at which letters are dropped +# the smaller the numbers, the more letters drop +# the first number is the base +# the second number is the variability by level +# the sum of the numbers should be around 9000 + +droprate 1000 8000 diff --git a/boards/melody.xml.in b/boards/melody.xml.in index bda1f7d..180d593 100644 --- a/boards/melody.xml.in +++ b/boards/melody.xml.in @@ -11,8 +11,11 @@ boarddir="melody"> <_title>Melody</_title> <_description>Repeat a melody</_description> - <_prerequisite></_prerequisite> + <_prerequisite>Move and click the mouse</_prerequisite> <_goal>Ear training activity</_goal> - <_manual></_manual> + <_manual>Listen the sound sequence played. +Then try to repeat it clicking on +the elements. +You can listen again clicking on the repeat button.</_manual> </Board> </GCompris> diff --git a/configure.in b/configure.in index 8d0e9a1..d9a7f4c 100644 --- a/configure.in +++ b/configure.in @@ -207,8 +207,9 @@ else python_localmodlibs=`sed -n -e 's/^LOCALMODLIBS=\(.*\)/\1/p' $python_makefile` python_basemodlibs=`sed -n -e 's/^BASEMODLIBS=\(.*\)/\1/p' $python_makefile` python_other_libs=`sed -n -e 's/^LIBS=\(.*\)/\1/p' $python_makefile` + python_libs_m=`sed -n -e 's/^LIBM=\(.*\)/\1/p' $python_makefile` python_libs_cflags=`sed -n -e 's/^LINKFORSHARED=\(.*\)/\1/p' $python_makefile` - python_libs="${python_localmodlibs} ${python_basemodlibs} ${python_other_libs}" + python_libs="${python_localmodlibs} ${python_basemodlibs} ${python_other_libs} ${python_libs_m}" python_old_ldflags=${LDFLAGS} LDFLAGS="${LDFLAGS} ${python_libs_cflags} -L${python_exec_prefix}/lib/python${python_version}/config ${python_libs}" diff --git a/list_translators.sh b/list_translators.sh new file mode 100755 index 0000000..0329340 --- /dev/null +++ b/list_translators.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +# usage: tranlators.sh LAST_RELEASE_TAG + +if [ ! $# -eq 1 ] ; then + echo "usage: $0 LAST_RELEASE_TAG" + exit 1; +fi + +cvs diff -r $1 po/ChangeLog | \ + (awk '/\.po/ { print gensub ("[:,]", "\n", "g", $3); }' | \ + while read file; do + if [ -z "po/$file" ]; then continue; fi + echo $(grep "Last-Translator" po/$file | sed -e 's/"Last-Translator: *\(.*\) *<.*/\1/') "(${file%%.po})" +done) | sort | uniq diff --git a/src/boards/clockgame.c b/src/boards/clockgame.c index fc41ac3..a263191 100644 --- a/src/boards/clockgame.c +++ b/src/boards/clockgame.c @@ -1,6 +1,6 @@ /* gcompris - clockgame.c * - * Time-stamp: <2003/01/27 01:16:48 bruno> + * Time-stamp: <2004/02/27 00:41:19 bcoudoin> * * Copyright (C) 2000 Bruno Coudoin * @@ -289,7 +289,7 @@ static void display_hour(guint hour) "points", canvasPoints, "fill_color", "darkblue", "width_units", (double)1, - "width_pixels", (uint) 4, + "width_pixels", (guint) 4, "last_arrowhead", TRUE, "arrow_shape_a", (double) needle_size, "arrow_shape_b", (double) needle_size-20, @@ -321,7 +321,7 @@ static void display_minute(guint minute) "points", canvasPoints, "fill_color", "red", "width_units", (double)1, - "width_pixels", (uint) 4, + "width_pixels", (guint) 4, "last_arrowhead", TRUE, "arrow_shape_a", (double) needle_size, "arrow_shape_b", (double) needle_size-10, @@ -353,7 +353,7 @@ static void display_second(guint second) "points", canvasPoints, "fill_color_rgba", 0x68c46fFF, "width_units", (double)1, - "width_pixels", (uint) 4, + "width_pixels", (guint) 4, "last_arrowhead", TRUE, "arrow_shape_a", (double) 0, "arrow_shape_b", (double) 0, @@ -410,7 +410,7 @@ static GnomeCanvasItem *clockgame_create_item(GnomeCanvasGroup *parent) "points", canvasPoints, "fill_color", color, "width_units", (double)1, - "width_pixels", (uint) 2, + "width_pixels", (guint) 2, NULL); item_list = g_list_append (item_list, item); @@ -485,7 +485,7 @@ static GnomeCanvasItem *clockgame_create_item(GnomeCanvasGroup *parent) "points", canvasPoints, "fill_color", "darkblue", "width_units", (double)1, - "width_pixels", (uint) 0, + "width_pixels", (guint) 0, NULL); gtk_signal_connect(GTK_OBJECT(hour_item), "event", (GtkSignalFunc) item_event, @@ -500,7 +500,7 @@ static GnomeCanvasItem *clockgame_create_item(GnomeCanvasGroup *parent) "points", canvasPoints, "fill_color", "darkblue", "width_units", (double)1, - "width_pixels", (uint) 0, + "width_pixels", (guint) 0, NULL); gtk_signal_connect(GTK_OBJECT(minute_item), "event", (GtkSignalFunc) item_event, @@ -515,7 +515,7 @@ static GnomeCanvasItem *clockgame_create_item(GnomeCanvasGroup *parent) "points", canvasPoints, "fill_color", "darkblue", "width_units", (double)1, - "width_pixels", (uint) 0, + "width_pixels", (guint) 0, NULL); gtk_signal_connect(GTK_OBJECT(second_item), "event", (GtkSignalFunc) item_event, diff --git a/src/boards/gletters.c b/src/boards/gletters.c index fbf3e97..f514d09 100644 --- a/src/boards/gletters.c +++ b/src/boards/gletters.c @@ -1,6 +1,6 @@ /* gcompris - gletters.c * - * Time-stamp: <2004/02/08 10:44:15 bcoudoin> + * Time-stamp: <2004/02/24 00:06:24 bcoudoin> * * Copyright (C) 2000 Bruno Coudoin * @@ -33,12 +33,64 @@ static GcomprisBoard *gcomprisBoard = NULL; static gint dummy_id = 0; static gint drop_items_id = 0; -#define LETTERS_ARRAY_LENGTH 3 -static char *letters_array[LETTERS_ARRAY_LENGTH] = { - "0123456789", - G_CSET_A_2_Z, - G_CSET_a_2_z -}; +/* Sublevels are now allocated dynamically + * based on the number of chars at that level + * Set DEFAULT_SUBLEVEL to the minimum + * number of sublevels you want + */ + +#define DEFAULT_SUBLEVEL 8 + +/* these constants control how fast letters fall + * the base rate is fixed + * the increment governs increase per level + * the smaller the numbers, the faster the letters fall + */ + +#define FALL_RATE_BASE 40 +float fallRateBase = FALL_RATE_BASE; +#define FALL_RATE_MULT 100 +float fallRateMult = FALL_RATE_MULT; + +/* these constants control how often letters are dropped + * the base rate is fixed + * the increment governs increase per level + */ + +#define DROP_RATE_BASE 1000 +float dropRateBase = DROP_RATE_BASE; +#define DROP_RATE_MULT 8000 +float dropRateMult = DROP_RATE_MULT; + +/* both letters_array and keymap are read in + * dynamically at run-time from files based on + * user locale + */ + +/* letters_array contains letters you want shown + * on each play level + * there can be an arbitrary number of levels, + * but there are only graphics to level 9 + * so that's where we stop + */ + +#define MAXLEVEL 10 +int maxLevel; +char *letters_array[MAXLEVEL]; + +/* keymap contains pairs of chars. The first char is + * on the keyboard map, the second is the unichar that + * is also represented by that key. That way, if there is more + * than one character represented by a key, the user doesn't + * have to use alternate input methods. + * It turns out that some keyboards generate long unichars, + * so keymap has to be big enough for 2 unichars + * both chars are packed into the same string; this makes it + * easier to deal with. + */ + +int keyMapSize; +char **keyMap; /* Hash table of all displayed letters */ static GHashTable *letters_table= NULL; @@ -70,26 +122,26 @@ static int gamewon; /* Description of this plugin */ BoardPlugin menu_bp = -{ - NULL, - NULL, - N_("Simple Letters"), - N_("Type the falling letters before they reach the ground"), - "Bruno Coudoin <bruno.coudoin@free.fr>", - NULL, - NULL, - NULL, - NULL, - start_board, - pause_board, - end_board, - is_our_board, - key_press, - NULL, - set_level, - NULL, - NULL -}; + { + NULL, + NULL, + N_("Simple Letters"), + N_("Type the falling letters before they reach the ground"), + "Bruno Coudoin <bruno.coudoin@free.fr>", + NULL, + NULL, + NULL, + NULL, + start_board, + pause_board, + end_board, + is_our_board, + key_press, + NULL, + set_level, + NULL, + NULL + }; /* * Main entry point mandatory for each Gcompris's game @@ -107,6 +159,24 @@ BoardPlugin * in : boolean TRUE = PAUSE : FALSE = UNPAUSE * */ + +static void level_set_score() { + int l; + +#ifdef DEBUG + g_message("letters_array length for level %d is %d\n",gcomprisBoard->level, + g_utf8_strlen(letters_array[gcomprisBoard->level-1],-1)); +#endif + l = g_utf8_strlen(letters_array[gcomprisBoard->level-1],-1)/3; + gcomprisBoard->number_of_sublevel=(DEFAULT_SUBLEVEL>l?DEFAULT_SUBLEVEL:l); + + gcompris_score_start(SCORESTYLE_NOTE, + gcomprisBoard->width - 220, + gcomprisBoard->height - 50, + gcomprisBoard->number_of_sublevel); + gcompris_bar_set(GCOMPRIS_BAR_LEVEL); +} + static void pause_board (gboolean pause) { if(gcomprisBoard==NULL) @@ -127,6 +197,7 @@ static void pause_board (gboolean pause) { if(gamewon == TRUE) /* the game is won */ { + level_set_score(); gletters_next_level(); } @@ -140,6 +211,151 @@ static void pause_board (gboolean pause) } } +int fill_letters(char **letterString,char *buffer) { +#ifdef DEBUG + g_message("in fill_letters\n"); +#endif + *letterString = g_malloc(strlen(buffer)+1); + sprintf(*letterString,"%s",buffer); +} + +int load_default_charset() { +#ifdef DEBUG + g_message("in load_default_charset\n"); +#endif + fill_letters(&letters_array[0],"ABCDEFGHIJKLMNOPQRSTUVWXYZ"); + fill_letters(&letters_array[1],"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"); + fill_letters(&letters_array[2],"abcdefghijklmnopqrstuvwxyz"); + fill_letters(&letters_array[3],"abcdefghijklmnopqrstuvwxyz0123456789"); + fill_letters(&letters_array[4],"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); + fill_letters(&letters_array[5],"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"); + keyMapSize = 0; + maxLevel = 6; + return TRUE; +} + +int whitespace(char *buffer) { + int i; + i = 0; + while(buffer[i] != '\0') { + if(buffer[i] == ' ' || buffer[i] == '\t' || buffer[i++] == '\n') + continue; + else return FALSE; + } + return TRUE; +} + +int load_charset_from_file(FILE *fp) { + int level, fp_ret_code, currKeyMap; + char lineBuffer[4096], strBuffer[4096], charBuffer[12]; + + /* keymap size is dynamically allocated */ +#ifdef DEBUG + g_message("scanning line\n"); +#endif + keyMapSize = 64; + currKeyMap = 0; + keyMap = (char **)g_malloc((sizeof (char *))*keyMapSize); +#ifdef DEBUG + printf("in load_charset_from_file\n"); +#endif + /* first read each line into a buffer */ + while( fgets(lineBuffer,4095,fp) ) { + /* if it's a comment or blank (empty), skip line */ + if ( lineBuffer[0] == '#' || whitespace(lineBuffer) ) continue; + /* if it's not a comment, it can be one of 4 things + * a level string, where it starts with "level " + * and the format is "level %d %s" or + * a keymap which starts with "key" and the format is "key %lc%lc" + * fall rate, which starts with "fallrate" and format is "fallrate %f %f" + * drop rate, which starts with "droprate" and format is "droprate %f %f" + */ +#ifdef DEBUG + g_message("scanning line\n"); +#endif + if( sscanf(lineBuffer,"level %d %s",&level, strBuffer) == 2 ) { + /* we have a level charset */ + if (level > MAXLEVEL || level < 1) { + g_message("level %d outside range of 1 to %d in line %s ",level,MAXLEVEL,lineBuffer); + return FALSE; + } + fill_letters(&letters_array[level-1],strBuffer); + if(maxLevel < level) maxLevel = level; +#ifdef DEBUG + g_message("maxLevel: %d\n",maxLevel); +#endif + } + else if( sscanf(lineBuffer,"key %11s",charBuffer) == 1) { + /* we potentially have a keymap */ + if( !g_utf8_validate(charBuffer,-1,(void *)NULL) ) { + /* it's not a valid UTF-8 string */ + g_message("malformed UTF-8 character string >%s< ",charBuffer); + return FALSE; + } + keyMap[currKeyMap] = (char *)g_malloc((sizeof (char))*strlen(charBuffer)); + sprintf(keyMap[currKeyMap],"%s",charBuffer); + currKeyMap++; + if(currKeyMap == keyMapSize) { + keyMapSize *= 2; + keyMap = (char **)realloc(keyMap,(sizeof(char *))*keyMapSize); + } + } + else if (sscanf(lineBuffer,"fallrate %f %f",&fallRateBase,&fallRateMult) == 2) { + if(fallRateBase < 5 || fallRateBase > 500 || fallRateMult < 5 || fallRateMult > 500) + g_message("WARNING: fallrate outside reasonable parameters"); + } + else if (sscanf(lineBuffer,"droprate %f %f",&dropRateBase,&dropRateMult) == 2) { + if(dropRateBase < 100 || dropRateBase > 20000 || dropRateMult < 100 || dropRateMult > 20000) + g_message("WARNING: droprate outside reasonable parameters"); + } + else + g_message("unknown or bad command in file: >%s<",lineBuffer); + } + /* now check to see all levels have been filled + */ + keyMapSize = currKeyMap; + return TRUE; +} + +int get_charset(char *locale) { + char *filename; + FILE *charsfd = NULL; + int i; + + /* zero out letters_array so we know which ones got assigned */ + for(i = 0; i < MAXLEVEL; i++) + letters_array[i] = (char *)0; + maxLevel=0; + + /* First Try to find a file matching the level and the locale */ + filename = g_strdup_printf("%s%s.%.2s", + PACKAGE_DATA_DIR, "/gletters/gletters", + locale); + g_message("Trying to open file %s ", filename); + charsfd = fopen (filename, "r"); + g_free(filename); + + + if (charsfd == (FILE *)NULL) { + g_message("failed to open file.\n"); + load_default_charset(); + } + else if (load_charset_from_file(charsfd)) + g_message("loaded charset from file.\n"); + else { + g_message("failed to load charset from file - using defaults.\n"); + load_default_charset(); + } + + /*now make sure all levels have been filled */ + for(i = 0; i < maxLevel; i++) + if(letters_array[i] == (char *)0) { + g_message("WARNING: level %d uninitialized in config file, setting defaults",i); + fill_letters(&letters_array[i],"ABCDEFGHIJKLMNOPQRSTUVWXYZ"); + } + +} + /* */ static void start_board (GcomprisBoard *agcomprisBoard) @@ -148,31 +364,37 @@ static void start_board (GcomprisBoard *agcomprisBoard) { gcomprisBoard=agcomprisBoard; gcompris_set_background(gnome_canvas_root(gcomprisBoard->canvas), "images/scenery_background.jpg"); - + get_charset(gcompris_get_locale()); + gcomprisBoard->maxlevel=maxLevel; gcomprisBoard->level = 1; - gcomprisBoard->maxlevel=6; - gcomprisBoard->number_of_sublevel=10; /* Go to next level after this number of 'play' */ - gcompris_score_start(SCORESTYLE_NOTE, - gcomprisBoard->width - 220, - gcomprisBoard->height - 50, - gcomprisBoard->number_of_sublevel); - gcompris_bar_set(GCOMPRIS_BAR_LEVEL); - + level_set_score(); gletters_next_level(); - gamewon = FALSE; pause_board(FALSE); } } + + static void end_board () { + int i; if(gcomprisBoard!=NULL) { pause_board(TRUE); gcompris_score_end(); gletters_destroy_all_items(); +#ifdef DEBUG + g_message("freeing memory"); +#endif + for (i = 0; i < maxLevel; i++) + g_free(letters_array[i]); + + for (i = 0; i < keyMapSize; i++) + g_free(keyMap[i]); + + g_free(keyMap); } gcomprisBoard = NULL; } @@ -184,6 +406,7 @@ set_level (guint level) if(gcomprisBoard!=NULL) { gcomprisBoard->level=level; + level_set_score(); gletters_next_level(); } } @@ -194,12 +417,30 @@ static void add_char(char *key, char *value, char *char_list) strcat(char_list, key); } -gint key_press(guint keyval) -{ +gint is_falling_letter(char *utfchar) { gchar *old_value; gchar *old_name; + + if (g_hash_table_lookup_extended (letters_table, + utfchar, + (gpointer) &old_name, + (gpointer) &old_value)) + { + player_win(item_find_by_title(utfchar)); + return TRUE; + } + return FALSE; +} + +gint key_press(guint keyval) { char c; - char str[2]; + char lcStr[6],ucStr[6], *str; + char utf8char[6], keyChar[6], mapChar[6]; + int i; + +#ifdef DEBUG + g_message("in key_press: %d, %c, %lc",keyval,keyval,keyval); +#endif if(!gcomprisBoard) return TRUE; @@ -266,34 +507,80 @@ gint key_press(guint keyval) break; } - c = tolower(keyval); - str[0] = c; - str[1] = '\0'; - if (g_hash_table_lookup_extended (letters_table, - (char *)&str, - (gpointer) &old_name, - (gpointer) &old_value)) - { - - player_win(item_find_by_title((char *)&str)); - + /* first check the obvious - simple keystrokes + check for keymap + convert to unichar/utf8 + set to lower case + check direct match + check upper case match + */ +#ifdef DEBUG + g_message("checking keymap: %d\n",keyMapSize); +#endif + g_unichar_to_utf8 (gdk_keyval_to_unicode(keyval),utf8char); + + for(i = 0; i < keyMapSize; ++i) { +#ifdef DEBUG + g_message("keymap: %d: %s\n",i,keyMap[i]); +#endif + + sprintf(keyChar, "%lc", g_utf8_get_char(keyMap[i])); + sprintf(mapChar, "%lc", g_utf8_get_char(g_utf8_find_next_char(keyMap[i],-1))); + +#ifdef DEBUG + g_message("char1: %s, char2: %s",keyChar, mapChar); +#endif + + if (strcmp(utf8char, keyChar) == 0) { + + /* match in keymap */ + sprintf(utf8char, "%s", mapChar); + if( is_falling_letter(utf8char) ) { + str = utf8char; + break; + } } - else - { - gchar *list_of_letters[255]; + } + +#ifdef DEBUG + g_message("no match-moving on\n"); +#endif - list_of_letters[0] = '\0'; + /* no match in keymap */ + if (i == keyMapSize) { - /* We have to loop to concat the letters */ - g_hash_table_foreach (letters_table, - (GHFunc) add_char, - list_of_letters); + g_unichar_to_utf8 (gdk_keyval_to_unicode(keyval),utf8char); - /* Log what happened, what was expected, what we got */ - gcompris_log_set_comment(gcomprisBoard, list_of_letters, str); + sprintf(lcStr,"%s",g_utf8_strdown(utf8char,-1)); + sprintf(ucStr,"%s",g_utf8_strup(utf8char,-1)); + if ( is_falling_letter(lcStr) ) { + str = lcStr; + } + else if( is_falling_letter(ucStr) ) { + str = ucStr; + } + else { + str = utf8char; player_loose(); } + } + + gchar *list_of_letters[255]; + list_of_letters[0] = '\0'; + + /* We have to loop to concat the letters */ + g_hash_table_foreach (letters_table, + (GHFunc) add_char, + list_of_letters); + + /* Log what happened, what was expected, what we got */ + + gcompris_log_set_comment(gcomprisBoard, list_of_letters, str); + +#ifdef DEBUG + g_message("leaving key_press\n"); +#endif return TRUE; } @@ -330,8 +617,8 @@ static void gletters_next_level() gletters_destroy_all_items(); /* Try the next level */ - speed=100+(40/gcomprisBoard->level); - fallSpeed=5000-gcomprisBoard->level*200; + speed=fallRateBase+(fallRateMult/gcomprisBoard->level); + fallSpeed=dropRateBase+(dropRateMult/gcomprisBoard->level); gcomprisBoard->sublevel=1; gcompris_score_set(gcomprisBoard->sublevel); @@ -425,35 +712,40 @@ static GnomeCanvasItem *gletters_create_item(GnomeCanvasGroup *parent) GnomeCanvasItem *item; char *str = NULL; char *str2 = NULL; - int i; + int i,j,k; guint c, x; - char *lettersItem; + char *lettersItem, *str_p; if (!letters_table) { letters_table= g_hash_table_new (g_str_hash, g_str_equal); } - lettersItem = g_malloc (2); + lettersItem = g_malloc (6); /* Beware, since we put the letters in a hash table, we do not allow the same letter to be displayed two times WARNING : This can cause an infinite loop if there is not enough element to choose */ + +#ifdef DEBUG + printf("dump: %d, %s\n",gcomprisBoard->level,letters_array[gcomprisBoard->level-1]); +#endif + + k=g_utf8_strlen(letters_array[gcomprisBoard->level-1],-1); do { - i=rand()%strlen(letters_array[gcomprisBoard->level%LETTERS_ARRAY_LENGTH]); - sprintf(lettersItem, "%c", - letters_array[gcomprisBoard->level%LETTERS_ARRAY_LENGTH][i]); + str_p=letters_array[gcomprisBoard->level-1]; + i=1+(int)((float)k*rand()/(RAND_MAX+1.0)); - /* Changing the letter to lower case : should be easier but these works */ - c = tolower(lettersItem[0]); - sprintf(lettersItem, "%c", c); + for( j = 0; j < i; j++) { + str_p=g_utf8_find_next_char(str_p,NULL); + } + sprintf(lettersItem, "%lc", + g_utf8_get_char(str_p)); } while(item_find_by_title(lettersItem)!=NULL); - lettersItem[1] = '\0'; - str = g_strdup_printf("%s%s", lettersItem, ".ogg"); str2 = gcompris_get_asset_file("gcompris alphabet", NULL, "audio/x-ogg", str); gcompris_play_ogg(str2, NULL); @@ -461,7 +753,6 @@ static GnomeCanvasItem *gletters_create_item(GnomeCanvasGroup *parent) g_free(str); g_free(str2); - item = \ gnome_canvas_item_new (parent, gnome_canvas_group_get_type (), @@ -469,7 +760,7 @@ static GnomeCanvasItem *gletters_create_item(GnomeCanvasGroup *parent) "y", (double) -12, NULL); - x = 80 + (rand()%(gcomprisBoard->width-160)); + x = 80 + (int)((float)(gcomprisBoard->width-160)*rand()/(RAND_MAX+1.0)); gnome_canvas_item_new (GNOME_CANVAS_GROUP(item), gnome_canvas_text_get_type (), "text", lettersItem, @@ -495,6 +786,10 @@ static GnomeCanvasItem *gletters_create_item(GnomeCanvasGroup *parent) /* Add letter to hash table of all falling letters. */ g_hash_table_insert (letters_table, lettersItem, item); +#ifdef DEBUG + printf("done\n"); +#endif + return (item); } @@ -518,12 +813,16 @@ static gint gletters_drop_items (GtkWidget *widget, gpointer data) static void player_win(GnomeCanvasItem *item) { +#ifdef DEBUG + g_message("in player_win\n"); +#endif + gletters_destroy_item(item); gcompris_play_ogg ("gobble", NULL); gcomprisBoard->sublevel++; - if(gcomprisBoard->sublevel>gcomprisBoard->number_of_sublevel) + if(gcomprisBoard->sublevel > gcomprisBoard->number_of_sublevel) { /* Try the next level */ gcomprisBoard->level++; @@ -555,11 +854,21 @@ static void player_win(GnomeCanvasItem *item) } } } +#ifdef DEBUG + printf("leaving player_win\n"); +#endif } static void player_loose() { +#ifdef DEBUG + printf("entering player_loose\n"); +#endif + gcompris_play_ogg ("crash", NULL); +#ifdef DEBUG + printf("leaving player_loose\n"); +#endif } /* Return in item the key if the value equals the item */ diff --git a/src/boards/memory.c b/src/boards/memory.c index 193ab83..6188e17 100644 --- a/src/boards/memory.c +++ b/src/boards/memory.c @@ -1,6 +1,6 @@ /* gcompris - memory.c * - * Time-stamp: <2003/01/05 00:10:15 bruno> + * Time-stamp: <2004/02/24 01:33:01 bcoudoin> * * Copyright (C) 2000 Bruno Coudoin * @@ -50,8 +50,11 @@ typedef enum HIDDEN = 2 } CardStatus; +static gchar *alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + typedef struct { char *image; + char text[2]; guint status; GnomeCanvasItem *rootItem; GnomeCanvasItem *backcardItem; @@ -150,74 +153,8 @@ static gchar *imageList[] = "gcompris/misc/windflag0.png", "gcompris/misc/windflag4.png", "gcompris/misc/windflag5.png", - "gcompris/letters/0.png", - "gcompris/letters/1.png", - "gcompris/letters/2.png", - "gcompris/letters/3.png", - "gcompris/letters/4.png", - "gcompris/letters/5.png", - "gcompris/letters/6.png", - "gcompris/letters/7.png", - "gcompris/letters/8.png", - "gcompris/letters/9.png", - "gcompris/letters/a.png", - "gcompris/letters/A.png", - "gcompris/letters/b.png", - "gcompris/letters/B.png", - "gcompris/letters/c.png", - "gcompris/letters/C.png", - "gcompris/letters/d.png", - "gcompris/letters/D.png", - "gcompris/letters/e.png", - "gcompris/letters/E.png", - "gcompris/letters/f.png", - "gcompris/letters/F.png", - "gcompris/letters/g.png", - "gcompris/letters/G.png", - "gcompris/letters/h.png", - "gcompris/letters/H.png", - "gcompris/letters/i.png", - "gcompris/letters/I.png", - "gcompris/letters/j.png", - "gcompris/letters/J.png", - "gcompris/letters/k.png", - "gcompris/letters/K.png", - "gcompris/letters/l.png", - "gcompris/letters/L.png", - "gcompris/letters/m.png", - "gcompris/letters/M.png", - "gcompris/letters/n.png", - "gcompris/letters/N.png", - "gcompris/letters/o.png", - "gcompris/letters/O.png", - "gcompris/letters/p.png", - "gcompris/letters/P.png", - "gcompris/letters/q.png", - "gcompris/letters/Q.png", - "gcompris/letters/r.png", - "gcompris/letters/R.png", - "gcompris/letters/s.png", - "gcompris/letters/S.png", - "gcompris/letters/t.png", - "gcompris/letters/T.png", - "gcompris/letters/u.png", - "gcompris/letters/U.png", - "gcompris/letters/v.png", - "gcompris/letters/V.png", - "gcompris/letters/w.png", - "gcompris/letters/W.png", - "gcompris/letters/x.png", - "gcompris/letters/X.png", - "gcompris/letters/y.png", - "gcompris/letters/Y.png", - "gcompris/letters/z.png", - "gcompris/letters/Z.png" }; -#define NUMBER_OF_IMAGES 103 -#define LETTERS_BEGIN_AT ( (NUMBER_OF_IMAGES) - 52 ) - -// These index are use to select only a subset of the previous image list by level -guint lowerImageIndex, upperImageIndex; +#define NUMBER_OF_IMAGES 41 /* Description of this plugin */ BoardPlugin menu_bp = @@ -360,17 +297,6 @@ static void memory_next_level() numberOfLine = levelDescription[gcomprisBoard->level*2+1]; remainingCards = numberOfColumn * numberOfLine; - if(gcomprisBoard->level<5) - { - lowerImageIndex = 0; - upperImageIndex = LETTERS_BEGIN_AT; - } - else - { - lowerImageIndex = LETTERS_BEGIN_AT; - upperImageIndex = NUMBER_OF_IMAGES; - } - gcomprisBoard->number_of_sublevel=1; gcomprisBoard->sublevel=0; @@ -419,13 +345,47 @@ static void get_image(MemoryItem *memoryItem, guint x, guint y) { // Get the pair's image memoryItem->image = memoryArray[x][y]->image; + strcpy((char *)&memoryItem->text, (char *)&memoryArray[x][y]->text); memoryArray[x][y] = memoryItem; return; } - i = lowerImageIndex + (int)((upperImageIndex-lowerImageIndex)*((double)rand()/RAND_MAX)); memoryArray[x][y] = memoryItem; - memoryItem->image = imageList[i]; + + + switch(gcomprisBoard->level) { + + case 0: + case 1: + case 2: + case 3: + case 4: + /* Image mode */ + i = rand()%NUMBER_OF_IMAGES; + memoryItem->image = imageList[i]; + memoryItem->text[0] = '\0'; + break; + + case 5: + /* Limited Text mode Numbers only */ + memoryItem->image = NULL; + memoryItem->text[0] = alphabet[rand()%(strlen(alphabet)-52)]; + memoryItem->text[1] = '\0'; + break; + + case 6: + /* Limited Text mode Numbers + Capitals */ + memoryItem->image = NULL; + memoryItem->text[0] = alphabet[rand()%(strlen(alphabet)-26)]; + memoryItem->text[1] = '\0'; + break; + + default: + /* Text mode ALL */ + memoryItem->image = NULL; + memoryItem->text[0] = alphabet[rand()%strlen(alphabet)]; + memoryItem->text[1] = '\0'; + } // Randomly set the pair rx = (int)(numberOfColumn*((double)rand()/RAND_MAX)); @@ -512,36 +472,54 @@ static GnomeCanvasItem *create_item(GnomeCanvasGroup *parent) // Display the image itself while taking care of its size and maximize the ratio - get_image(memoryItem, x, y); - pixmap = gcompris_load_pixmap(memoryItem->image); - - yratio=(height2*0.8)/(float)gdk_pixbuf_get_height(pixmap); - xratio=(width2*0.8)/(float)gdk_pixbuf_get_width(pixmap); - yratio=xratio=MIN(xratio, yratio); - card_shadow_w = width*0.07; - card_shadow_h = height*0.07; + get_image(memoryItem, x, y); + + if(memoryItem->image) { + pixmap = gcompris_load_pixmap(memoryItem->image); + + yratio=(height2*0.8)/(float)gdk_pixbuf_get_height(pixmap); + xratio=(width2*0.8)/(float)gdk_pixbuf_get_width(pixmap); + yratio=xratio=MIN(xratio, yratio); + card_shadow_w = width*0.07; + card_shadow_h = height*0.07; + + memoryItem->frontcardItem = \ + gnome_canvas_item_new (GNOME_CANVAS_GROUP(memoryItem->rootItem), + gnome_canvas_pixbuf_get_type (), + "pixbuf", pixmap, + "x", (double) ((width*0.9)- + gdk_pixbuf_get_width(pixmap)*xratio*0.8)/2 - + card_shadow_w, + "y", (double) ((height*0.9)- + gdk_pixbuf_get_height(pixmap)*yratio*0.8)/2 - + card_shadow_h, + "width", (double) gdk_pixbuf_get_width(pixmap)*xratio*0.8, + "height", (double) gdk_pixbuf_get_height(pixmap)*yratio*0.8, + "width_set", TRUE, + "height_set", TRUE, + NULL); + gdk_pixbuf_unref(pixmap); + + } else { + /* It's a letter */ + memoryItem->frontcardItem = \ + gnome_canvas_item_new (GNOME_CANVAS_GROUP(memoryItem->rootItem), + gnome_canvas_text_get_type (), + "text", &memoryItem->text, + "font", gcompris_skin_font_board_huge_bold, + "x", (double) (width*0.8)/2, + "y", (double) (height*0.8)/2, + "anchor", GTK_ANCHOR_CENTER, + "fill_color_rgba", 0x99CDFFFF, + NULL); + + } - memoryItem->frontcardItem = \ - gnome_canvas_item_new (GNOME_CANVAS_GROUP(memoryItem->rootItem), - gnome_canvas_pixbuf_get_type (), - "pixbuf", pixmap, - "x", (double) ((width*0.9)- - gdk_pixbuf_get_width(pixmap)*xratio*0.8)/2 - - card_shadow_w, - "y", (double) ((height*0.9)- - gdk_pixbuf_get_height(pixmap)*yratio*0.8)/2 - - card_shadow_h, - "width", (double) gdk_pixbuf_get_width(pixmap)*xratio*0.8, - "height", (double) gdk_pixbuf_get_height(pixmap)*yratio*0.8, - "width_set", TRUE, - "height_set", TRUE, - NULL); gnome_canvas_item_hide(memoryItem->frontcardItem); - gdk_pixbuf_unref(pixmap); - gtk_signal_connect(GTK_OBJECT(memoryItem->rootItem), "event", (GtkSignalFunc) item_event, memoryItem); + } } @@ -649,12 +627,23 @@ item_event(GnomeCanvasItem *item, GdkEvent *event, MemoryItem *memoryItem) secondCard = memoryItem; // Check win - if(strcmp(firstCard->image, secondCard->image)==0) - { - gcompris_play_ogg ("gobble", NULL); - win_id = gtk_timeout_add (1000, + if(firstCard->image && secondCard->image) { + /* It's images in both cards */ + if(strcmp(firstCard->image, secondCard->image)==0) + { + gcompris_play_ogg ("gobble", NULL); + win_id = gtk_timeout_add (1000, + (GtkFunction) hide_card, NULL); + } + } else if (!firstCard->image && !secondCard->image) { + /* It's text in both cards */ + if(strcmp(&firstCard->text, &secondCard->text)==0) + { + gcompris_play_ogg ("gobble", NULL); + win_id = gtk_timeout_add (1000, (GtkFunction) hide_card, NULL); - } + } + } } break; default: diff --git a/src/boards/shapegame.c b/src/boards/shapegame.c index 8550486..940864f 100644 --- a/src/boards/shapegame.c +++ b/src/boards/shapegame.c @@ -1,6 +1,6 @@ /* gcompris - shapegame.c * - * Time-stamp: <2003/12/06 04:54:07 bcoudoin> + * Time-stamp: <2004/02/20 00:54:46 bcoudoin> * * Copyright (C) 2000 Bruno Coudoin * @@ -469,12 +469,13 @@ static gboolean increment_sublevel() if(gcomprisBoard->sublevel>gcomprisBoard->number_of_sublevel) { /* Try the next level */ gcomprisBoard->level++; + gcomprisBoard->sublevel=0; + if(gcomprisBoard->level>gcomprisBoard->maxlevel) { // the current board is finished : bail out board_finished(BOARD_FINISHED_RANDOM); return FALSE; } - gcomprisBoard->sublevel=0; } gcompris_bar_set_level(gcomprisBoard); diff --git a/src/gcompris/about.c b/src/gcompris/about.c index 84f1a88..9b95bbe 100644 --- a/src/gcompris/about.c +++ b/src/gcompris/about.c @@ -1,6 +1,6 @@ /* gcompris - about.c * - * Time-stamp: <2004/02/08 11:24:30 bcoudoin> + * Time-stamp: <2004/02/28 01:27:59 bcoudoin> * * Copyright (C) 2000 Bruno Coudoin * @@ -58,7 +58,7 @@ void gcompris_about_start () GnomeCanvasItem *item, *item2; static gchar *content = N_("Author: Bruno Coudoin\n" - "Contribution: Pascal Georges\n" + "Contribution: Pascal Georges, Jose Jorge\n" "Graphics: Renaud Blanchard\n" "Intro Music: Djilali Sebihi\n" "Background Music: Rico Da Halvarez\n" diff --git a/src/gcompris/config.c b/src/gcompris/config.c index c9f0f7b..f38aef9 100644 --- a/src/gcompris/config.c +++ b/src/gcompris/config.c @@ -1,6 +1,6 @@ /* gcompris - config.c * - * Time-stamp: <2004/02/07 02:40:18 bcoudoin> + * Time-stamp: <2004/02/28 00:09:28 bcoudoin> * * Copyright (C) 2000-2003 Bruno Coudoin * @@ -58,6 +58,7 @@ static gchar *linguas[] = { "de_DE.UTF-8", N_("German"), "el_GR.UTF-8", N_("Greek"), "en_GB.UTF-8", N_("English"), + "en_CA.UTF-8", N_("Canadian English"), "es_ES.UTF-8", N_("Spanish"), "fi_FI.UTF-8", N_("Finnish"), "fr_FR.UTF-8", N_("French"), diff --git a/src/gcompris/gameutil.c b/src/gcompris/gameutil.c index 85c68de..8660534 100644 --- a/src/gcompris/gameutil.c +++ b/src/gcompris/gameutil.c @@ -1,6 +1,6 @@ /* gcompris - gameutil.c * - * Time-stamp: <2004/02/16 00:38:50 bcoudoin> + * Time-stamp: <2004/02/23 23:47:00 bcoudoin> * * Copyright (C) 2000 Bruno Coudoin * @@ -121,13 +121,14 @@ GdkPixbuf *gcompris_load_pixmap(char *pixmapfile) filename = g_strdup_printf("%s/%s", PACKAGE_DATA_DIR, pixmapfile); if (!g_file_test ((filename), G_FILE_TEST_EXISTS)) { + char *str; g_warning (_("Couldn't find file %s !"), filename); - char *str = g_strdup_printf("%s\n%s\n%s\n%s", - _("Couldn't find file"), - pixmapfile, - _("This activity is incomplete."), - _("Exit it and report\nus the problem")); + str = g_strdup_printf("%s\n%s\n%s\n%s", + _("Couldn't find file"), + pixmapfile, + _("This activity is incomplete."), + _("Exit it and report\nus the problem")); gcompris_dialog (str, NULL); g_free(str); } |