[Tux4kids-commits] r226 - in tuxtype/trunk: . tuxtype
dbruce-guest at alioth.debian.org
dbruce-guest at alioth.debian.org
Mon Sep 3 23:40:40 UTC 2007
Author: dbruce-guest
Date: 2007-09-03 23:40:40 +0000 (Mon, 03 Sep 2007)
New Revision: 226
Modified:
tuxtype/trunk/ChangeLog
tuxtype/trunk/INSTALL
tuxtype/trunk/README-CROSSBUILD.txt
tuxtype/trunk/tuxtype/alphabet.c
tuxtype/trunk/tuxtype/funcs.h
tuxtype/trunk/tuxtype/globals.h
tuxtype/trunk/tuxtype/laser.c
tuxtype/trunk/tuxtype/playgame.c
tuxtype/trunk/tuxtype/practice.c
tuxtype/trunk/tuxtype/setup.c
tuxtype/trunk/tuxtype/theme.c
Log:
Work to keep "practice" activity from crashing in German and other languages.
Modified: tuxtype/trunk/ChangeLog
===================================================================
--- tuxtype/trunk/ChangeLog 2007-09-03 08:08:21 UTC (rev 225)
+++ tuxtype/trunk/ChangeLog 2007-09-03 23:40:40 UTC (rev 226)
@@ -1,4 +1,18 @@
-v 1.5.12
+v 1.5.13
+03 Sep 2007
+[ David Bruce ]
+ - practice.c revised significantly to prevent crashes if
+ keyboard.lst erroneous or incomplete - if entry not found
+ in FINGER[] array for a character, fingering hint not
+ shown but program still functions. "Practice" now uses the
+ same RenderLetters() code as the Cascade and Comet Zap
+ activities.
+ - BlackOutLine() for single letters now uses
+ TTF_RenderUNICODE_Blended() rather than
+ TTF_RenderGlyph_Blended() because the former version
+ renders all glyphs to a consistent baseline, simplifying
+ our code.
+
26 Aug 2007
[ David Bruce ]
- got rid of autogen.sh - autoreconf is recommended way to
Modified: tuxtype/trunk/INSTALL
===================================================================
--- tuxtype/trunk/INSTALL 2007-09-03 08:08:21 UTC (rev 225)
+++ tuxtype/trunk/INSTALL 2007-09-03 23:40:40 UTC (rev 226)
@@ -21,7 +21,7 @@
if you run into problems rerun:
-autoreconf
+autoreconf --install
We want this to work for everybody, everywhere, if it doesn't
work for you please contact calarndt at tux4kids.org
Modified: tuxtype/trunk/README-CROSSBUILD.txt
===================================================================
--- tuxtype/trunk/README-CROSSBUILD.txt 2007-09-03 08:08:21 UTC (rev 225)
+++ tuxtype/trunk/README-CROSSBUILD.txt 2007-09-03 23:40:40 UTC (rev 226)
@@ -83,7 +83,7 @@
and "make distclean" to get rid of the autogenerated files.
7. From the trunk dir, run:
- ./autoreconf
+ ./autoreconf --install
./cross-configure.sh --with-sdl-prefix
./cross-make.sh
./cross-make.sh nsis
Modified: tuxtype/trunk/tuxtype/alphabet.c
===================================================================
--- tuxtype/trunk/tuxtype/alphabet.c 2007-09-03 08:08:21 UTC (rev 225)
+++ tuxtype/trunk/tuxtype/alphabet.c 2007-09-03 23:40:40 UTC (rev 226)
@@ -177,7 +177,10 @@
}
-SDL_Surface* BlackOutline(const unsigned char *t, TTF_Font *font, const SDL_Color *c)
+/* NOTE if we can consistently use SDLPango on all platforms, we can simply */
+/* rename the pango version to BlackOutline() and get rid of this one. */
+/* The input for this function should be UTF-8. */
+SDL_Surface* BlackOutline(const unsigned char* t, const TTF_Font* font, const SDL_Color* c)
{
SDL_Surface* out = NULL;
SDL_Surface* black_letters = NULL;
@@ -269,7 +272,7 @@
/* This version basically uses the SDLPango lib instead of */
/* TTF_RenderUTF*_Blended() to properly render Indic text. */
-SDL_Surface* BlackOutline_SDLPango(const unsigned char *t, TTF_Font *font, const SDL_Color *c)
+SDL_Surface* BlackOutline_SDLPango(const unsigned char* t, const TTF_Font* font, const SDL_Color* c)
{
SDL_Surface* out = NULL;
SDL_Surface* black_letters = NULL;
@@ -355,9 +358,11 @@
/* End of win32-excluded coded */
-/* This version takes a single wide character and renders it with the */
-/* Unicode glyph versions of the SDL_ttf functions: */
-SDL_Surface* BlackOutline_wchar(wchar_t t, TTF_Font* font, const SDL_Color* c)
+
+
+/* This version takes a wide character string and renders it with the */
+/* Unicode string versions of the SDL_ttf functions: */
+SDL_Surface* BlackOutline_Unicode(const Uint16* t, const TTF_Font* font, const SDL_Color* c)
{
SDL_Surface* out = NULL;
SDL_Surface* black_letters = NULL;
@@ -372,11 +377,11 @@
return NULL;
}
- black_letters = TTF_RenderGlyph_Blended(font, t, black);
+ black_letters = TTF_RenderUNICODE_Blended(font, t, black);
if (!black_letters)
{
- fprintf (stderr, "Warning - BlackOutline_wchar() could not create image for %lc\n", t);
+ fprintf (stderr, "Warning - BlackOutline_wchar() could not create image for %S\n", t);
return NULL;
}
@@ -402,7 +407,7 @@
SDL_FreeSurface(black_letters);
/* --- Put the color version of the text on top! --- */
- white_letters = TTF_RenderGlyph_Blended(font, t, *c);
+ white_letters = TTF_RenderUNICODE_Blended(font, t, *c);
dstrect.x = 1;
dstrect.y = 1;
SDL_BlitSurface(white_letters, NULL, bg, &dstrect);
@@ -712,14 +717,11 @@
-
-/* Now that the words are stored internally as wchars, we use the */
-/* Unicode glyph version of black_outline(): */
+/* This version creates the letters using TTF_RenderUNICODE_Blended */
int RenderLetters(const TTF_Font* letter_font)
{
- wchar_t t;
- int i;
- int maxy;
+ Uint16 t[2];
+ int i, j; /* i is chars attempted, j is chars actually rendered. */
if (!letter_font)
{
@@ -727,31 +729,25 @@
return 0;
}
- /* The following will supercede the old code: */
i = num_chars_used = 0;
+ j = 0;
+ t[1] = '\0';
+
while (char_list[i] != '\0')
{
- t = char_list[i];
-
- if(TTF_GlyphMetrics(letter_font, t, NULL , NULL, NULL,
- &maxy, NULL) == -1)
- {
- fprintf(stderr, "Could not get glyph metrics for %lc", t);
- i++;
- continue;
- }
-
+ t[0] = char_list[i];
+
DEBUGCODE
{
- fprintf(stderr, "Creating SDL_Surface for list element %d, char = %lc\n", i, t);
+ fprintf(stderr, "Creating SDL_Surface for list element %d, char = %lc\n", i, *t);
}
- char_glyphs[i].unicode_value = t;
- char_glyphs[i].white_glyph = BlackOutline_wchar(t, letter_font, &white);
- char_glyphs[i].red_glyph = BlackOutline_wchar(t, letter_font, &red);
- char_glyphs[i].max_y = maxy;
+ char_glyphs[j].unicode_value = t[0];
+ char_glyphs[j].white_glyph = BlackOutline_Unicode(t, letter_font, &white);
+ char_glyphs[j].red_glyph = BlackOutline_Unicode(t, letter_font, &red);
i++;
+ j++;
num_chars_used++;
}
/* Remember how many letters we added: */
@@ -759,6 +755,7 @@
}
+
void FreeLetters(void)
{
int i;
@@ -767,6 +764,9 @@
{
SDL_FreeSurface(char_glyphs[i].white_glyph);
SDL_FreeSurface(char_glyphs[i].red_glyph);
+ char_glyphs[i].unicode_value = 0;
+ char_glyphs[i].white_glyph = NULL;
+ char_glyphs[i].red_glyph = NULL;
}
/* List now empty: */
num_chars_used = 0;
@@ -818,35 +818,8 @@
}
-/* Since SDL drawing just uses the upper left corner, but text needs to be drawn relative to */
-/* the glyph origin (i.e. the lower left corner for a character that doesn't go below */
-/* the baseline), we need to convert them - basically just subtracting the max_y, which is */
-/* the glyph's height above the baseline. */
-/* So - 'x' and 'y' before the function should be the coords where the *origin* is supposed */
-/* to be, and after the function they will contain the correct coords for blitting of the */
-/* glyph. OK? */
-int GetGlyphCoords(wchar_t t, int* x, int* y)
-{
- int i;
- for (i = 0;
- char_glyphs[i].unicode_value != t && i <= num_chars_used;
- i++)
- {}
- if (i > num_chars_used)
- {
- /* Didn't find character: */
- fprintf(stderr, "Could not find glyph for unicode character %lc\n", t);
- return 0;
- }
-
- /* Set "upper left" coordinates for blitting (currently, don't need to */
- /* do anything to x): */
- *y -= char_glyphs[i].max_y;
- return 1;
-}
-
/****************************************************/
/* */
/* Local ("private") functions: */
@@ -884,6 +857,43 @@
+void ResetCharList(void)
+{
+ char_list[0] = '\0';
+}
+
+
+
+/* Creates a list of distinct Unicode characters in */
+/* the argument string for subsequent rendering. */
+/* Like gen_char_list() but takes a string argument */
+/* instead of going through the currently selected */
+/* word list. Argument should be UTF-8 */
+/* Can be called multiple times on different strings */
+/* to accumulate entire repertoire - call ResetCharList() */
+/* to start over */
+void GenCharListFromString(const char* UTF8_str)
+{
+ int i = 0;
+ wchar_t wchar_buf[MAX_UNICODES];
+
+ convert_from_UTF8(wchar_buf, UTF8_str);
+
+ /* FNLEN is max length of phrase (I think) */
+ while (wchar_buf[i] != '\0' && i < FNLEN)
+ {
+ add_char(wchar_buf[i]);
+ i++;
+ }
+
+ DEBUGCODE
+ {
+ fprintf(stderr, "char_list = %S\n", char_list);
+ }
+}
+
+
+
/* FIXME this function is currently dead code */
/* --- setup the alphabet --- */
static void set_letters(unsigned char *t) {
@@ -905,7 +915,7 @@
/* Checks to see if the argument is already in the list and adds */
/* it if necessary. Returns 1 if char added, 0 if already in list, */
/* -1 if list already up to maximum size: */
-
+/* FIXME performance would be better with hashtable */
static int add_char(wchar_t uc)
{
int i = 0;
Modified: tuxtype/trunk/tuxtype/funcs.h
===================================================================
--- tuxtype/trunk/tuxtype/funcs.h 2007-09-03 08:08:21 UTC (rev 225)
+++ tuxtype/trunk/tuxtype/funcs.h 2007-09-03 23:40:40 UTC (rev 226)
@@ -21,23 +21,26 @@
/* In alphabet.c */
-SDL_Surface* BlackOutline(const unsigned char *t, TTF_Font* font, const SDL_Color* c);
-SDL_Surface* BlackOutline_wchar(wchar_t t, TTF_Font* font, const SDL_Color* c);
+SDL_Surface* BlackOutline(const unsigned char *t, const TTF_Font* font, const SDL_Color* c);
+SDL_Surface* BlackOutline_Unicode(const Uint16* t, const TTF_Font* font, const SDL_Color* c);
#ifndef WIN32
-SDL_Surface* BlackOutline_SDLPango(const unsigned char *t, TTF_Font* font, const SDL_Color* c);
+SDL_Surface* BlackOutline_SDLPango(const unsigned char* t, const TTF_Font* font, const SDL_Color* c);
#endif
+/* (still in alphabet.c:) */
void ClearWordList(void);
void FreeLetters(void);
void GenerateWordList(const char* wordFn);
+void GenCharListFromString(const char* UTF8_str);
+void ResetCharList(void);
wchar_t GetLetter(void);
wchar_t* GetWord(void);
SDL_Surface* GetWhiteGlyph(wchar_t t);
SDL_Surface* GetRedGlyph(wchar_t t);
-int GetGlyphCoords(wchar_t t, int* x, int* y);
int LoadKeyboard(void);
int RenderLetters(const TTF_Font* letter_font);
+
void UseAlphabet(void);
Modified: tuxtype/trunk/tuxtype/globals.h
===================================================================
--- tuxtype/trunk/tuxtype/globals.h 2007-09-03 08:08:21 UTC (rev 225)
+++ tuxtype/trunk/tuxtype/globals.h 2007-09-03 23:40:40 UTC (rev 226)
@@ -241,5 +241,4 @@
wchar_t unicode_value;
SDL_Surface* white_glyph;
SDL_Surface* red_glyph;
- int max_y;
} uni_glyph;
Modified: tuxtype/trunk/tuxtype/laser.c
===================================================================
--- tuxtype/trunk/tuxtype/laser.c 2007-09-03 08:08:21 UTC (rev 225)
+++ tuxtype/trunk/tuxtype/laser.c 2007-09-03 23:40:40 UTC (rev 226)
@@ -872,17 +872,17 @@
static void laser_draw_let(wchar_t c, int x, int y)
{
- int top_x, top_y;
+ /* Draw letter in correct place relative to comet: */
+ const int offset_x = -10; /* Values determined by trial and error: */
+ const int offset_y = -50;
+
SDL_Rect dst;
- /* Start with coords for where we want glyph origin to go: */
- top_x = x - (GetWhiteGlyph(c)->w/2);
- top_y = y - 10;
- /* Correct for varying height of glyphs: */
- GetGlyphCoords(c, &top_x, &top_y);
- /* Plug into the SDL_Rect and blit: */
- dst.x = top_x;
- dst.y = top_y;
- SDL_BlitSurface(GetWhiteGlyph(c), NULL, screen, &dst);
+ SDL_Surface* s;
+ dst.x = x + offset_x;
+ dst.y = y + offset_y;
+ s = GetWhiteGlyph(c);
+ if (s)
+ SDL_BlitSurface(s, NULL, screen, &dst);
}
Modified: tuxtype/trunk/tuxtype/playgame.c
===================================================================
--- tuxtype/trunk/tuxtype/playgame.c 2007-09-03 08:08:21 UTC (rev 225)
+++ tuxtype/trunk/tuxtype/playgame.c 2007-09-03 23:40:40 UTC (rev 226)
@@ -137,9 +137,7 @@
LoadTuxAnims();
LoadFishies();
LoadOthers();
-printf("before RenderLetters\n");
RenderLetters(font);
-printf("after RenderLetters\n");
LOG( " starting game \n ");
while (still_playing) {
@@ -1385,10 +1383,10 @@
int j = 0;
int red_letters = 0;
int current_letter;
- /* 'x_origin' and 'y_origin' are where the glyph origin should be */
- /* located relative to the fishy graphic (lower left corner of most chars) */
- const int x_origin = 10;
- const int y_origin = 30;
+ /* 'x_inset' and 'y_inset' are where the glyph to be drawn relative */
+ /* the fishy graphic: */
+ const int x_inset = 10;
+ const int y_inset = 10;
/* letter_x and letter_y are where the upper left corner of the glyph needs */
/* to be located - (e.g. how SDL blitting understands locations) */
int letter_x = 0;
@@ -1449,14 +1447,11 @@
else
letter_surface = GetWhiteGlyph(current_letter);
- /* Set "letter_x" and "letter_y to where we want the *origin* drawn: */
- letter_x = fish_object[which].x + (j * fishy->frame[0]->w) + x_origin;
- letter_y = fish_object[which].y + y_origin;
- /* Now get correct upper-left coords for this particular glyph: */
- GetGlyphCoords(current_letter, &letter_x, &letter_y);
+ /* Set "letter_x" and "letter_y to where we want the letter drawn: */
+ letter_x = fish_object[which].x + (j * fishy->frame[0]->w) + x_inset;
+ letter_y = fish_object[which].y + y_inset;
DrawObject(letter_surface, letter_x, letter_y);
-
}
}
/* LOG ("Leaving DrawFish()\n");*/
Modified: tuxtype/trunk/tuxtype/practice.c
===================================================================
--- tuxtype/trunk/tuxtype/practice.c 2007-09-03 08:08:21 UTC (rev 225)
+++ tuxtype/trunk/tuxtype/practice.c 2007-09-03 23:40:40 UTC (rev 226)
@@ -30,7 +30,7 @@
/*local function prototypes: */
static int get_phrase(const char* phr);
-static void practice_load_media(void);
+static int practice_load_media(void);
static void practice_unload_media(void);
static void print_at(const char* pphrase, int wrap, int x, int y);
static void show(unsigned char t);
@@ -43,136 +43,238 @@
/************************************************************************/
+/* FIXME this is not UTF-8/Unicode compatible */
+int Phrases(char* pphrase )
+{
-int Phrases(char* pphrase ) {
+ /* TODO
+ *
+ *
+ *
+ */
- /* TODO
- *
- *
- *
- */
+ Uint32 start = 0, a = 0;
+ int quit = 0,
+ i = 0,
+ c = 0,
+ wp = 0,
+ z = 0,
+ total = 0,
+ state = 0;
+ int key[100] = {0};
+ SDL_Rect dst, dst2, dst3, dst4, dst5;
+ char keytime[FNLEN],
+ totaltime[FNLEN];
+ SDL_Surface* srfc = NULL;
- Uint32 start=0,a=0;
- int quit=0,
- i=0,
- c=0,
- wp=0,
- z=0,
- total=0,
- state=0;
- int key[100];
- SDL_Rect dst, dst2, dst3, dst4,dst5;
- char keytime[FNLEN],
- totaltime[FNLEN];
- practice_load_media();
- SDL_BlitSurface(bg, NULL, screen, NULL);
- SDL_BlitSurface(hands, NULL, screen, &hand_loc);
- SDL_Flip(screen);
+
+ if (!practice_load_media())
+ {
+ fprintf(stderr, "Phrases() - practice_load_media() failed, returning.\n");
+ return 0;
+ }
- wp = get_phrase(pphrase);
- if (!strncmp(phrase[0], "", 1))
- strncpy(pphrase, phrase[0], 80);
+ SDL_BlitSurface(bg, NULL, screen, NULL);
+ SDL_BlitSurface(hands, NULL, screen, &hand_loc);
+ SDL_Flip(screen);
- dst.x = 320 - (letters[65]->w/2); dst.y = 100; dst.w = letters[65]->w; dst.h = letters[65]->h;
- dst2.x = 50; dst2.y = 400; dst2.w = letters[65]->w; dst2.h = letters[65]->h;
- dst3.x = 50; dst3.y = 400; dst3.w = 160; dst3.h = 50;
- dst4.x = 480; dst4.y = 400; dst4.w = 240; dst4.h = 50;
- dst5.x = 480; dst5.y = 400; dst5.w = 240; dst5.h = 50;
- dst.x = 40;
+ wp = get_phrase(pphrase);
- start = SDL_GetTicks();
+ if (!strncmp(phrase[0], "", 1))
+ strncpy(pphrase, phrase[0], 80);
- do {
- switch (state) {
- case 0:
- start = SDL_GetTicks();
- SDL_BlitSurface(hands, NULL, screen, &hand_loc);
- state = 1;
- break;
- case 1:
- if (SDL_GetTicks() - start > 500) {
- for (i=0; i<10; i++)
- if (FINGER[(int)pphrase[c]][i]){
- SDL_BlitSurface(hand[i], NULL, screen, &hand_loc);
- }
- state = 2;
- }
- break;
- case 2:
- if (state == 2 && SDL_GetTicks() - start > 750) {
- state = 3;
- }
- break;
- case 3:
- SDL_BlitSurface(hands, NULL, screen, &hand_loc);
- state = 12;
- break;
- case 4:
- for (i=0; i<10; i++)
- if (FINGER[(int)pphrase[c]][i])
- SDL_BlitSurface(hand[i], NULL, screen, &hand_loc);
- state = 11;
- break;
- default:
- state -= 2; // this is to make the flashing slower
- }
+ if (!letters[65])
+ {
+ fprintf(stderr, "Phrases() - letters[65] not defined - bailing out.\n");
+ return 0;
+ }
- while (SDL_PollEvent(&event)) {
- if (event.type == SDL_KEYDOWN) {
- a=SDL_GetTicks();
- key[c]=a-start;
- total += key[c];
- sprintf(keytime, "%.2f", (float) key[c] / 1000);
- sprintf(totaltime, "%.2f", (float) total / 1000);
- start = a;
- if (event.key.keysym.sym == SDLK_ESCAPE)
- quit=1;
- if (event.key.keysym.sym == SDLK_DOWN) {
- //practice next phase in list
- //a=a;
- } else {
- if (ALPHABET[event.key.keysym.unicode] && pphrase[c]==(char)event.key.keysym.unicode){
- state=0;
- dst2.x=40;
- dst4.x=480;
- SDL_BlitSurface(bg, &dst3, screen, &dst2);
- SDL_BlitSurface(bg, &dst5, screen, &dst4);
- SDL_Flip(screen);
- SDL_BlitSurface(letters[event.key.keysym.unicode], NULL, screen, &dst);
- for (z=0;z<strlen(keytime);z++){
- SDL_BlitSurface(letters[(int)keytime[z]], NULL, screen, &dst2);
- dst2.x = dst2.x + letters[(int)keytime[z]]->w-2;
- }
- for (z=0;z<strlen(totaltime);z++){
- SDL_BlitSurface(letters[(int)totaltime[z]], NULL, screen, &dst4);
- dst4.x = dst4.x + letters[(int)totaltime[z]]->w-2;
- }
- dst.x = (dst.x + letters[event.key.keysym.unicode]->w) - 5;
- if (c==(strlen(pphrase)-1)){
- print_at("Great!",6 ,275 ,200);
- SDL_Flip(screen);
- SDL_Delay(2500);
- quit=1;
- }
- if (c==wp){
- c++;
- dst.x=40;
- dst.y=142;
- }
- c++;
- } else {
- if ( event.key.keysym.sym != SDLK_RSHIFT && event.key.keysym.sym != SDLK_LSHIFT )
- PlaySound(wrong);
- }
- }
- }
- }
- SDL_Flip(screen);
- SDL_Delay(30);
- }while (!quit);
- practice_unload_media();
- return 1;
+ dst.x = 320 - (letters[65]->w/2);
+ dst.y = 100;
+ dst.w = letters[65]->w;
+ dst.h = letters[65]->h;
+
+ dst2.x = 50;
+ dst2.y = 400;
+ dst2.w = letters[65]->w;
+ dst2.h = letters[65]->h;
+
+ dst3.x = 50;
+ dst3.y = 400;
+ dst3.w = 160;
+ dst3.h = 50;
+
+ dst4.x = 480;
+ dst4.y = 400;
+ dst4.w = 240;
+ dst4.h = 50;
+
+ dst5.x = 480;
+ dst5.y = 400;
+ dst5.w = 240;
+ dst5.h = 50;
+
+ dst.x = 40;
+
+ start = SDL_GetTicks();
+
+ do
+ {
+ switch (state)
+ {
+ case 0:
+ start = SDL_GetTicks();
+ SDL_BlitSurface(hands, NULL, screen, &hand_loc);
+ state = 1;
+ break;
+
+ case 1:
+ if (SDL_GetTicks() - start > 500)
+ {
+ for (i = 0; i < 10; i++)
+ {
+ if (((int)pphrase[c] >= 0) /* Prevent bounds violation */
+ &&((int)pphrase[c] < 256)
+ && FINGER[(int)pphrase[c]][i])
+ {
+ SDL_BlitSurface(hand[i], NULL, screen, &hand_loc);
+ }
+ }
+ state = 2;
+ }
+ break;
+
+ case 2:
+ if (state == 2 && SDL_GetTicks() - start > 750)
+ {
+ state = 3;
+ }
+ break;
+
+ case 3:
+ SDL_BlitSurface(hands, NULL, screen, &hand_loc);
+ state = 12;
+ break;
+
+ case 4:
+ for (i = 0; i < 10; i++)
+ {
+ if (((int)pphrase[c] >= 0) /* Prevent bounds violation */
+ &&((int)pphrase[c] < 256) /* This can't actually occur for type char */
+ && FINGER[(int)pphrase[c]][i])
+ {
+ SDL_BlitSurface(hand[i], NULL, screen, &hand_loc);
+ }
+ }
+ state = 11;
+ break;
+
+ default:
+ state -= 2; // this is to make the flashing slower
+ }
+
+
+ while (SDL_PollEvent(&event))
+ {
+ if (event.type == SDL_KEYDOWN)
+ {
+ a = SDL_GetTicks();
+ key[c] = a - start;
+ total += key[c];
+ sprintf(keytime, "%.2f", (float) key[c] / 1000);
+ sprintf(totaltime, "%.2f", (float) total / 1000);
+ start = a;
+
+ if (event.key.keysym.sym == SDLK_ESCAPE)
+ quit = 1;
+
+ if (event.key.keysym.sym == SDLK_DOWN)
+ {
+ //practice next phase in list
+ //a=a;
+ }
+ else
+ {
+ /* Keep from segfaulting on unicode chars beyond 255 */
+ /* until practice mode is fixed: */
+ if (event.key.keysym.unicode > 255)
+ {
+ fprintf(stderr, "Practice mode cannot handle this unicode char\n");
+ continue;
+ }
+
+ if (pphrase[c]==(char)event.key.keysym.unicode)
+ {
+ state = 0;
+ dst2.x = 40;
+ dst4.x = 480;
+ SDL_BlitSurface(bg, &dst3, screen, &dst2);
+ SDL_BlitSurface(bg, &dst5, screen, &dst4);
+ SDL_Flip(screen);
+
+ srfc = GetWhiteGlyph(event.key.keysym.unicode);
+ if (srfc)
+ {
+ SDL_BlitSurface(srfc, NULL, screen, &dst);
+ dst.x = (dst.x + srfc->w) - 5;
+ }
+
+ for (z = 0; z < strlen(keytime); z++)
+ {
+ srfc = GetWhiteGlyph((int)keytime[z]);
+ if (srfc)
+ {
+ SDL_BlitSurface(srfc, NULL, screen, &dst2);
+ dst2.x = dst2.x + srfc->w - 2;
+ }
+ }
+
+ for (z = 0;z < strlen(totaltime); z++)
+ {
+ srfc = GetWhiteGlyph((int)totaltime[z]);
+ if (srfc)
+ {
+ SDL_BlitSurface(srfc, NULL, screen, &dst4);
+ dst4.x = dst4.x + srfc->w - 2;
+ }
+ }
+
+
+ if (c == (strlen(pphrase) - 1))
+ {
+ print_at("Great!",6 ,275 ,200);
+ SDL_Flip(screen);
+ SDL_Delay(2500);
+ quit = 1;
+ }
+
+ if (c == wp)
+ {
+ c++;
+ dst.x = 40;
+ dst.y = 142;
+ }
+
+ c++;
+ }
+ else
+ {
+ if (event.key.keysym.sym != SDLK_RSHIFT
+ && event.key.keysym.sym != SDLK_LSHIFT)
+ PlaySound(wrong);
+ }
+ }
+ }
+ }
+ SDL_Flip(screen);
+ SDL_Delay(30);
+
+ }while (!quit);
+
+ practice_unload_media();
+
+ return 1;
}
@@ -185,41 +287,64 @@
/* FIXME use RenderLetters(), etc */
-static void practice_load_media(void)
+static int practice_load_media(void)
{
- int i;
- unsigned char fn[FNLEN];
- unsigned char let[5];
+ int i;
+ unsigned char fn[FNLEN];
+ unsigned char let[5];
+ int load_failed = 0;
- LOG("Loading practice media\n");
- for (i=0; i<10; i++) {
- sprintf(fn, "hands/%d.png", i);
- hand[i] = LoadImage(fn, IMG_ALPHA);
- }
- hands = LoadImage("hands/hands.png", IMG_ALPHA);
+ LOG("Loading practice media\n");
- hand_loc.x = (screen->w/2) - (hand[0]->w/2);
- hand_loc.y = screen->h - (hand[0]->h);
- hand_loc.w = (hand[0]->w);
- hand_loc.h = (hand[0]->h);
- bg = LoadImage("main_bkg.png", IMG_ALPHA);
+ hands = LoadImage("hands/hands.png", IMG_ALPHA);
+ bg = LoadImage("main_bkg.png", IMG_ALPHA);
+ wrong = LoadSound("tock.wav");
- font = LoadFont(settings.theme_font_name, 32 );
+ for (i = 0; i < 10; i++)
+ {
+ sprintf(fn, "hands/%d.png", i);
+ hand[i] = LoadImage(fn, IMG_ALPHA);
+ if (!hand[i])
+ load_failed = 1;
+ }
- wrong = LoadSound("tock.wav");
+ /* Get out if anything failed to load: */
+ if (load_failed
+ ||!hands
+ ||!bg
+ ||!wrong)
+ {
+ fprintf(stderr, "practice_load_media() - failed to load needed media \n");
+ practice_unload_media;
+ return 0;
+ }
- let[1]=0;
- for (i=1; i<255; i++)
- if (ALPHABET[i]) {
- let[0]=i;
- letters[i] = BlackOutline(let, font, &white);
- }
+ /* Should be safe from here on out: */
- TTF_CloseFont(font);
- font = NULL;
+ hand_loc.x = (screen->w/2) - (hand[0]->w/2);
+ hand_loc.y = screen->h - (hand[0]->h);
+ hand_loc.w = (hand[0]->w);
+ hand_loc.h = (hand[0]->h);
- LOG("DONE - Loading practice media\n");
+ /* Now render letters for glyphs in alphabet: */
+ font = LoadFont(settings.theme_font_name, 32 );
+
+ /* FIXME below problem with i18n: */
+ let[1]=0;
+ for (i=1; i<255; i++)
+ /* until we fix or get rid of ALPHABET[], just render the whole range: */
+ if (ALPHABET[i])
+ {
+ let[0] = i;
+ letters[i] = BlackOutline(let, font, &white);
+ }
+
+ TTF_CloseFont(font);
+ font = NULL;
+
+ LOG("DONE - Loading practice media\n");
+ return 1;
}
@@ -238,7 +363,7 @@
SDL_FreeSurface(hand[i]);
hand[i] = NULL;
}
- for (i=1; i<255; i++)
+ for (i = 1; i < 255; i++)
if (ALPHABET[i])
{
SDL_FreeSurface(letters[i]);
@@ -249,124 +374,233 @@
}
-
+/* looks like dead code: */
static void show(unsigned char t)
{
SDL_Rect dst;
- dst.x = 320 - (letters[(int)t]->w/2);
+ SDL_Surface* s = NULL;
+
+ s= GetWhiteGlyph((int)t);
+ if (!s)
+ return;
+ dst.x = 320 - (s->w/2);
dst.y = 100;
- dst.w = letters[(int)t]->w;
- dst.h = letters[(int)t]->h;
- SDL_BlitSurface(letters[(int)t], NULL, screen, &dst);
+ dst.w = s->w;
+ dst.h = s->h;
+ SDL_BlitSurface(s, NULL, screen, &dst);
}
static int get_phrase(const char* phr)
{
- int pc=0,
- pw[256] = { 0 },
- wp=0,
- i=0,
- c=0,
- z=0;
- char fn[FNLEN];
+ int pc = 0; // 'phrase count' (?)
+ int pw[256] = { 0 };
+ int wp = 0, i = 0, c = 0, z = 0;
+ char fn[FNLEN];
- /* If we didn't receive a phrase get the first one from the file...*/
-
- if (strncmp("", phr, 40)==0){
- FILE *pf;
- /* set the phrases directory/file */
- #ifdef WIN32
- snprintf( fn, FNLEN-1, "userdata/phrases.txt" );
- #else
- snprintf( fn, FNLEN-1, (const char*)"%s/.tuxtype/phrases.txt", getenv("HOME") );
- #endif
+ /* If we didn't receive a phrase get the first one from the file...*/
+ if (strncmp("", phr, 40) == 0)
+ {
+ FILE* pf; /* "phrase file" */
+ /* set the phrases directory/file */
+ /* FIXME I think the phrases should be under data or the theme */
+#ifdef WIN32
+ snprintf(fn, FNLEN - 1, "userdata/phrases.txt");
+#else
+ snprintf(fn, FNLEN - 1, (const char*)"%s/.tuxtype/phrases.txt", getenv("HOME"));
+#endif
- DEBUGCODE { printf("get_phrases(): phrases file is '%s'\n", fn ); }
- LOG("get_phrases(): trying to open phrases file\n");
- pf = fopen( fn, "r" );
- if (pf == NULL)
- return(wp);
- while (!feof(pf)) {
- fscanf( pf, "%[^\n]\n", phrase[pc] );
- pc++;
- DEBUGCODE { printf( "%s", phrase[pc] ); }
- }
- fclose( pf );
- pc--;
- } else {
- pc=1;
- strncpy(phrase[0], phr, 80);
- }
+ DEBUGCODE { printf("get_phrases(): phrases file is '%s'\n", fn ); }
+ LOG("get_phrases(): trying to open phrases file\n");
+ pf = fopen( fn, "r" );
+ if (pf == NULL)
+ return(wp); /* why not just 'return 0;' ??? */
- //Calculate and record pixel width of phrases
- for (c=0;c<=pc;c++){
- for(i=0; i<strlen(phrase[c]); i++){
- if (letters[(int)phrase[c][i]] == NULL)
- printf("no letter defined in keyboard.lst\n");
- else
- pw[c]+= letters[(int)phrase[c][i]]->w-5;
- }
- }
+ /* So now copy each line into phrases array: */
+ while (!feof(pf) && pc < 256)
+ {
+ fscanf( pf, "%[^\n]\n", phrase[pc] );
+ pc++;
+ DEBUGCODE {printf("%s", phrase[pc]);}
+ }
+ if (pc == 256)
+ LOG("File contains more than max allowed phrases - stopping\n");
- //Find wrapping point
- for ( c=0; c<=pc; c++ ){
- if (pw[c]<598){
- if ( c==0 ){
- wp=strlen(phrase[c]);
- print_at( phrase[0], wp, 40, 10 );
- }
- }else{
- z=0;
- wp=0;
- for (i=0;i<strlen(phrase[c]);i++){
- z += letters[(int)phrase[c][i]]->w-5;
- if (wp == 0 && z > 598){
- wp = i-1;
- break;
- }
- }
- for (i=wp;i>=0;i--){
- if ( strncmp( " ", &phrase[c][i], 1 ) == 0 ){
- wp=i-1;
- break;
- }
- }
- if ( c==0 ){
- print_at( phrase[0], wp, 40, 10 );
- }
- }
- }
- return(wp);
+ fclose(pf);
+ pc--;
+ }
+ else
+ {
+ pc = 1;
+ strncpy(phrase[0], phr, 80);
+ }
+
+
+ /* Need to generate glyphs for all the needed Unicode chars: */
+
+ ResetCharList();
+ /* 'A' (i.e. 65) always has to go into list because width used for layout */
+ /* HACK also need chars for "Great!" because of congrats message - this */
+ /* obviously is not a general solution. Numerals also needed for timers. */
+ {
+ char* let = "AGreat!0123456789.";
+ GenCharListFromString(let);
+ }
+
+
+ /* Scan through all the phrases and put needed chars into list: */
+ for (c = 0; c <= pc; c++)
+ GenCharListFromString(phrase[c]);
+
+ /* Now render letters for glyphs in list: */
+ font = LoadFont(settings.theme_font_name, 32 );
+ if (!font)
+ {
+ fprintf(stderr, "get_phrase() - could not load font\n");
+ return 0;
+ }
+
+ RenderLetters(font);
+
+ TTF_CloseFont(font);
+ font = NULL;
+
+
+ //Calculate and record pixel width of phrases
+ {
+ SDL_Surface* let = NULL;
+ for (c = 0; c <= pc; c++)
+ {
+ for(i = 0; i < strlen(phrase[c]); i++)
+ {
+ let = GetWhiteGlyph((int)phrase[c][i]);
+ if (let)
+ pw[c]+= let->w - 5;
+ else
+ {
+ fprintf(stderr, "get_phrase() - needed glyph not in letters[]\n");
+ return;
+ }
+ }
+ }
+ }
+
+ //Find wrapping point
+ for (c = 0; c <= pc; c++)
+ {
+ if (pw[c] < 598) // If the phrase is less than 598 pixels wide
+ {
+ if (c == 0)
+ {
+ wp = strlen(phrase[c]);
+ print_at(phrase[0], wp, 40, 10);
+ }
+ }
+ else
+ {
+ z = 0;
+ wp = 0;
+
+ for (i = 0; i < strlen(phrase[c]); i++)
+ {
+ /* Should be safe (if no glyph, will have returned above) */
+ z += GetWhiteGlyph((int)phrase[c][i])->w-5;
+ if (wp == 0 && z > 598)
+ {
+ wp = i - 1;
+ break;
+ }
+ }
+
+ for (i = wp; i >= 0; i--)
+ {
+ if (strncmp(" ", &phrase[c][i], 1) == 0)
+ {
+ wp = i-1;
+ break;
+ }
+ }
+
+ if (c == 0)
+ {
+ print_at(phrase[0], wp, 40, 10);
+ }
+ }
+ }
+ LOG("Leaving get_phrase()\n");
+ return(wp);
}
static void print_at(const char *pphrase, int wrap, int x, int y)
{
- int z=0;
- letter_loc.x = x;
- letter_loc.y = y;
- letter_loc.w = letters[65]->w;
- letter_loc.h = letters[65]->h;
- if ( wrap == strlen(pphrase) ){
- for (z=0;z<strlen(pphrase);z++){
- SDL_BlitSurface(letters[(int)pphrase[z]], NULL, screen, &letter_loc);
- letter_loc.x = (letter_loc.x + letters[(int)pphrase[z]]->w)-5;
- }
- }else{
- for (z=0;z<=wrap;z++){
- SDL_BlitSurface(letters[(int)pphrase[z]], NULL, screen, &letter_loc);
- letter_loc.x = (letter_loc.x + letters[(int)pphrase[z]]->w)-5;
- }
- letter_loc.x = 40;
- // - (letter_loc.h/4) to account for free space at top and bottom of rendered letters
- letter_loc.y = letter_loc.y + letter_loc.h - (letter_loc.h/4);
- for (z=wrap+2;z<strlen(pphrase);z++){
- SDL_BlitSurface(letters[(int)pphrase[z]], NULL, screen, &letter_loc);
- letter_loc.x = (letter_loc.x + letters[(int)pphrase[z]]->w)-5;
- }
- }
+ int z = 0;
+ SDL_Surface* surf = NULL;
+ letter_loc.x = x;
+ letter_loc.y = y;
+ letter_loc.w = GetWhiteGlyph(65)->w;
+ letter_loc.h = GetWhiteGlyph(65)->h;
+
+ LOG("Entering print_at()\n");
+
+ if (wrap >= strlen(pphrase)) // I think this means it fits on a single line
+ {
+ for (z = 0; z <strlen(pphrase); z++)
+ {
+ surf = GetWhiteGlyph((wchar_t)pphrase[z]);
+ if (surf)
+ {
+ DEBUGCODE{printf("surf not NULL for %c\n", pphrase[z]);}
+ SDL_BlitSurface(surf, NULL, screen, &letter_loc);
+ letter_loc.x = (letter_loc.x + surf->w) - 5;
+ }
+ else
+ {
+ fprintf(stderr, "print_at(): needed glyph for %c not found\n",
+ pphrase[z]);
+ }
+ }
+ }
+ else /* Another line required - code only seems to support 1 or 2 lines! */
+ {
+ for (z = 0; z <= wrap; z++)
+ {
+ surf = GetWhiteGlyph((wchar_t)pphrase[z]);
+ if (surf)
+ {
+ DEBUGCODE{printf("surf not NULL for %c\n", pphrase[z]);}
+ SDL_BlitSurface(surf, NULL, screen, &letter_loc);
+ letter_loc.x = (letter_loc.x + surf->w) - 5; }
+ else
+ {
+ fprintf(stderr, "print_at(): needed glyph for %c not found\n",
+ pphrase[z]);
+ }
+ }
+
+ /* Move 'cursor' back to left and down one line: */
+ letter_loc.x = 40;
+ // - (letter_loc.h/4) to account for free space at top and bottom of rendered letters
+ letter_loc.y = letter_loc.y + letter_loc.h - (letter_loc.h/4);
+
+ for (z = wrap + 2; z <strlen(pphrase); z++)
+ {
+ surf = GetWhiteGlyph((wchar_t)pphrase[z]);
+ if (surf)
+ {
+ DEBUGCODE{printf("surf not NULL for %c\n", pphrase[z]);}
+ SDL_BlitSurface(surf, NULL, screen, &letter_loc);
+ letter_loc.x = (letter_loc.x + surf->w) - 5;
+ }
+ else
+ {
+ fprintf(stderr, "print_at(): needed glyph for %c not found",
+ pphrase[z]);
+ }
+ }
+ }
+ LOG("Leaving print_at()\n");
}
Modified: tuxtype/trunk/tuxtype/setup.c
===================================================================
--- tuxtype/trunk/tuxtype/setup.c 2007-09-03 08:08:21 UTC (rev 225)
+++ tuxtype/trunk/tuxtype/setup.c 2007-09-03 23:40:40 UTC (rev 226)
@@ -93,6 +93,7 @@
LOG( "LibInit():\n-About to init SDL Library\n" );
if (SDL_Init(lib_flags) < 0)
+ /* FIXME this looks wrong - if no sys_sound, we don't init video??? */
if (settings.sys_sound) {
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
fprintf(stderr, "Couldn't initialize SDL: %s\n",
@@ -109,11 +110,17 @@
LOG( "-SDL Library init'd successfully\n" );
- if (settings.sys_sound)
- if (Mix_OpenAudio( 22050, AUDIO_S16, 1, 2048) < 0) {
- fprintf( stderr, "Warning: couldn't set 22050 Hz 8-bit audio\n - Reasons: %s\n", SDL_GetError());
- settings.sys_sound=0;
- }
+ /* FIXME should read settings before we do this: */
+ if (settings.sys_sound)
+ {
+ if (Mix_OpenAudio(22050, AUDIO_S16, 1, 2048) == -1)
+ {
+ fprintf( stderr, "Warning: couldn't set 22050 Hz 8-bit audio\n - Reasons: %s\n", SDL_GetError());
+ settings.sys_sound=0;
+ }
+ else
+ LOG("Mix_OpenAudio() successful\n");
+ }
LOG( "-about to init SDL_ttf\n" );
Modified: tuxtype/trunk/tuxtype/theme.c
===================================================================
--- tuxtype/trunk/tuxtype/theme.c 2007-09-03 08:08:21 UTC (rev 225)
+++ tuxtype/trunk/tuxtype/theme.c 2007-09-03 23:40:40 UTC (rev 226)
@@ -22,7 +22,7 @@
SDL_Surface* letters[255] = {NULL}; //get rid of this
wchar_t ALPHABET[256];
-unsigned char FINGER[256][10];
+unsigned char FINGER[256][10] = {0};
int ALPHABET_SIZE;
More information about the Tux4kids-commits
mailing list