[Tux4kids-commits] r1477 - tuxmath/branches/lan/src
David Bruce
dbruce-guest at alioth.debian.org
Thu Sep 3 22:06:06 UTC 2009
Author: dbruce-guest
Date: 2009-09-03 22:06:06 +0000 (Thu, 03 Sep 2009)
New Revision: 1477
Added:
tuxmath/branches/lan/src/menu.c
tuxmath/branches/lan/src/menu.h
tuxmath/branches/lan/src/titlescreen.c.old
Modified:
tuxmath/branches/lan/src/CMakeLists.txt
tuxmath/branches/lan/src/Makefile.am
tuxmath/branches/lan/src/SDL_extras.c
tuxmath/branches/lan/src/SDL_extras.h
tuxmath/branches/lan/src/SDL_rotozoom.c
tuxmath/branches/lan/src/campaign.c
tuxmath/branches/lan/src/convert_utf.c
tuxmath/branches/lan/src/credits.c
tuxmath/branches/lan/src/factoroids.c
tuxmath/branches/lan/src/fileops.c
tuxmath/branches/lan/src/fileops.h
tuxmath/branches/lan/src/fileops_media.c
tuxmath/branches/lan/src/game.c
tuxmath/branches/lan/src/game.h
tuxmath/branches/lan/src/globals.h
tuxmath/branches/lan/src/highscore.c
tuxmath/branches/lan/src/lessons.c
tuxmath/branches/lan/src/loaders.c
tuxmath/branches/lan/src/loaders.h
tuxmath/branches/lan/src/mathcards.c
tuxmath/branches/lan/src/mathcards.h
tuxmath/branches/lan/src/multiplayer.c
tuxmath/branches/lan/src/options.c
tuxmath/branches/lan/src/scandir.c
tuxmath/branches/lan/src/scandir.h
tuxmath/branches/lan/src/setup.c
tuxmath/branches/lan/src/titlescreen.c
tuxmath/branches/lan/src/titlescreen.h
tuxmath/branches/lan/src/tuxmath.c
tuxmath/branches/lan/src/tuxmath.h
Log:
committing merged files to branch
(does not build yet)
Modified: tuxmath/branches/lan/src/CMakeLists.txt
===================================================================
--- tuxmath/branches/lan/src/CMakeLists.txt 2009-09-02 10:50:25 UTC (rev 1476)
+++ tuxmath/branches/lan/src/CMakeLists.txt 2009-09-03 22:06:06 UTC (rev 1477)
@@ -24,6 +24,7 @@
fileops.c
fileops_media.c
game.c
+ menu.c
highscore.c
lessons.c
loaders.c
@@ -97,16 +98,26 @@
set(_rsvg_cflags "${_rsvg_cflags} ${f}")
endforeach(f)
+set(_cairo_cflags "")
+foreach(f ${CAIRO_CFLAGS})
+ set(_cairo_cflags "${_cairo_cflags} ${f}")
+endforeach(f)
+
set(_rsvg_ldflags "")
foreach(f ${RSVG_LDFLAGS})
set(_rsvg_ldflags "${_rsvg_ldflags} ${f}")
endforeach(f)
+set(_cairo_ldflags "")
+foreach(f ${CAIRO_LDFLAGS})
+ set(_cairo_ldflags "${_cairo_ldflags} ${f}")
+endforeach(f)
+
set_target_properties (
tuxmath
PROPERTIES COMPILE_FLAGS
- "-DDATA_PREFIX=\\\"${TUXMATH_DATA_PREFIX}\\\" -DVERSION=\\\"${TUXMATH_VERSION}\\\" -DLOCALEDIR=\\\"${LOCALE_DIR}\\\" -DPACKAGE=\\\"tuxmath\\\" ${_rsvg_cflags}"
- LINK_FLAGS "${_rsvg_ldflags}"
+ "-DDATA_PREFIX=\\\"${TUXMATH_DATA_PREFIX}\\\" -DVERSION=\\\"${TUXMATH_VERSION}\\\" -DLOCALEDIR=\\\"${LOCALE_DIR}\\\" -DPACKAGE=\\\"tuxmath\\\" ${_rsvg_cflags} ${_cairo_cflags}"
+ LINK_FLAGS "${_rsvg_ldflags} ${_cairo_ldflags}"
)
target_link_libraries (tuxmath
Modified: tuxmath/branches/lan/src/Makefile.am
===================================================================
--- tuxmath/branches/lan/src/Makefile.am 2009-09-02 10:50:25 UTC (rev 1476)
+++ tuxmath/branches/lan/src/Makefile.am 2009-09-03 22:06:06 UTC (rev 1477)
@@ -7,7 +7,7 @@
DEFS = -DLOCALEDIR=\"$(localedir)\" @DEFS@
AM_CFLAGS=-Wall -g -DDATA_PREFIX=\"${DATA_PREFIX}\" -DDEBUG \
- -DVERSION=\"@NAME_VERSION@\" -D$(SOUND)SOUND
+ -D$(SOUND)SOUND
AM_CPPFLAGS = -DLOCALEDIR=\"$(localedir)\" \
-I../intl -I$(top_srcdir)/intl
@@ -31,6 +31,7 @@
tuxmath_SOURCES = tuxmath.c \
setup.c \
titlescreen.c \
+ menu.c \
game.c \
factoroids.c \
fileops_media.c \
@@ -75,6 +76,7 @@
loaders.h \
network.h \
titlescreen.h \
+ menu.h \
options.h \
setup.h \
mathcards.h \
@@ -99,7 +101,3 @@
# How to make an RC file
tuxmathrc.o: tuxmathrc.rc
$(WINDRES) -i $< -o $@
-
-
-
-
Modified: tuxmath/branches/lan/src/SDL_extras.c
===================================================================
--- tuxmath/branches/lan/src/SDL_extras.c 2009-09-02 10:50:25 UTC (rev 1476)
+++ tuxmath/branches/lan/src/SDL_extras.c 2009-09-03 22:06:06 UTC (rev 1477)
@@ -19,29 +19,39 @@
-/* DrawButton() creates and draws a translucent button with */
-/* rounded ends. All colors and alpha values are supported.*/
+/* DrawButton() creates a translucent button with rounded ends
+ and draws it on the screen.
+ All colors and alpha values are supported.*/
void DrawButton(SDL_Rect* target_rect,
int radius,
Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
+ SDL_Surface* tmp_surf = CreateButton(target_rect->w, target_rect->h,
+ radius, r, g, b, a);
+ SDL_BlitSurface(tmp_surf, NULL, screen, target_rect);
+ SDL_FreeSurface(tmp_surf);
+}
+
+/* CreateButton() creates a translucent button with rounded ends
+ All colors and alpha values are supported.*/
+SDL_Surface* CreateButton(int w, int h, int radius,
+ Uint8 r, Uint8 g, Uint8 b, Uint8 a)
+{
/* NOTE - we use a 32-bit temp surface even if we have a 16-bit */
/* screen - it gets converted during blitting. */
SDL_Surface* tmp_surf = SDL_CreateRGBSurface(SDL_SWSURFACE|SDL_SRCALPHA,
- target_rect->w,
- target_rect->h,
+ w,
+ h,
32,
rmask, gmask, bmask, amask);
+
Uint32 color = SDL_MapRGBA(tmp_surf->format, r, g, b, a);
SDL_FillRect(tmp_surf, NULL, color);
RoundCorners(tmp_surf, radius);
-
- SDL_BlitSurface(tmp_surf, NULL, screen, target_rect);
- SDL_FreeSurface(tmp_surf);
+ return tmp_surf;
}
-
void RoundCorners(SDL_Surface* s, Uint16 radius)
{
int y = 0;
@@ -246,7 +256,7 @@
Currently this works only with RGBA images, but this is largely to
make the (fast) pointer arithmetic work out; it could be easily
generalized to other image types. */
-SDL_Surface* Blend(SDL_Surface *S1,SDL_Surface *S2,float gamma)
+SDL_Surface* Blend(SDL_Surface *S1, SDL_Surface *S2, float gamma)
{
SDL_PixelFormat *fmt1, *fmt2;
Uint8 r1, r2, g1, g2, b1, b2, a1, a2;
@@ -349,12 +359,40 @@
return ret;
}
+
+/* free every surface in the array together with the array itself */
+void FreeSurfaceArray(SDL_Surface** surfs, int length)
+{
+ int i;
+
+ if(surfs == NULL)
+ return;
+
+ for(i = 0; i < length; i++)
+ if(surfs[i] != NULL)
+ SDL_FreeSurface(surfs[i]);
+ free(surfs);
+}
+
int inRect( SDL_Rect r, int x, int y) {
if ((x < r.x) || (y < r.y) || (x > r.x + r.w) || (y > r.y + r.h))
return 0;
return 1;
}
+void UpdateRect(SDL_Surface* surf, SDL_Rect* rect)
+{
+ SDL_UpdateRect(surf, rect->x, rect->y, rect->w, rect->h);
+}
+
+void SetRect(SDL_Rect* rect, const float* pos)
+{
+ rect->x = pos[0] * screen->w;
+ rect->y = pos[1] * screen->h;
+ rect->w = pos[2] * screen->w;
+ rect->h = pos[3] * screen->h;
+}
+
/* Darkens the screen by a factor of 2^bits */
void DarkenScreen(Uint8 bits)
{
@@ -390,28 +428,49 @@
}
}
-
-void SwitchScreenMode(void)
+/* change window size (works only in windowed mode) */
+void ChangeWindowSize(int new_res_x, int new_res_y)
{
- int window = (screen->flags & SDL_FULLSCREEN);
SDL_Surface* oldscreen = screen;
- if (!window)
+ if(!(screen->flags & SDL_FULLSCREEN))
{
- screen = SDL_SetVideoMode(fs_res_x,
- fs_res_y,
+ screen = SDL_SetVideoMode(new_res_x,
+ new_res_y,
PIXEL_BITS,
- SDL_SWSURFACE|SDL_HWPALETTE|SDL_FULLSCREEN);
- }
- else
- {
- screen = SDL_SetVideoMode(RES_X,
- RES_Y,
- PIXEL_BITS,
SDL_SWSURFACE|SDL_HWPALETTE);
+ if(screen == NULL)
+ {
+ fprintf(stderr,
+ "\nError: I could not change screen mode into %d x %d.\n",
+ new_res_x, new_res_y);
+ screen = oldscreen;
+ }
+ else
+ {
+ DEBUGMSG(debug_sdl, "ChangeWindowSize(): Changed window size to %d x %d\n", screen->w, screen->h);
+ oldscreen = NULL;
+ win_res_x = screen->w;
+ win_res_y = screen->h;
+ SDL_UpdateRect(screen, 0, 0, 0, 0);
+ }
}
+ else
+ DEBUGMSG(debug_sdl, "ChangeWindowSize() can be run only in windowed mode !");
+}
+/* switch between fullscreen and windowed mode */
+void SwitchScreenMode(void)
+{
+ int window = (screen->flags & SDL_FULLSCREEN);
+ SDL_Surface* oldscreen = screen;
+
+ screen = SDL_SetVideoMode(window ? win_res_x : fs_res_x,
+ window ? win_res_y : fs_res_y,
+ PIXEL_BITS,
+ screen->flags ^ SDL_FULLSCREEN);
+
if (screen == NULL)
{
fprintf(stderr,
@@ -424,11 +483,11 @@
}
else
{
- SDL_FreeSurface(oldscreen);
+ //success, no need to free the old video surface
+ DEBUGMSG(debug_sdl, "Switched screen mode to %s\n", window ? "windowed" : "fullscreen");
oldscreen = NULL;
SDL_UpdateRect(screen, 0, 0, 0, 0);
}
-
}
/*
@@ -477,7 +536,7 @@
Uint8 r4, g4, b4, a4;
Uint8 r, g, b, a;
- tmdprintf("\nEntering zoom():\n");
+ DEBUGMSG(debug_sdl, "Entering zoom():\n");
/* Create surface for zoom: */
@@ -498,9 +557,9 @@
// exit(1);
}
- tmdprintf("orig surface %dx%d, %d bytes per pixel\n",
+ DEBUGMSG(debug_sdl, "zoom(): orig surface %dx%d, %d bytes per pixel\n",
src->w, src->h, src->format->BytesPerPixel);
- tmdprintf("new surface %dx%d, %d bytes per pixel\n",
+ DEBUGMSG(debug_sdl, "zoom(): new surface %dx%d, %d bytes per pixel\n",
s->w, s->h, s->format->BytesPerPixel);
/* Now assign function pointers to correct functions based */
@@ -575,7 +634,7 @@
SDL_UnlockSurface(s);
SDL_UnlockSurface(src);
- tmdprintf("\nLeaving zoom():\n");
+ DEBUGMSG(debug_sdl, "Leaving zoom():\n");
return s;
}
@@ -623,7 +682,7 @@
{
#ifdef HAVE_LIBSDL_PANGO
- tmdprintf("Setup_SDL_Text() - using SDL_Pango\n");
+ DEBUGMSG(debug_sdl, "Setup_SDL_Text() - using SDL_Pango\n");
SDLPango_Init();
if (!Set_SDL_Pango_Font_Size(DEFAULT_MENU_FONT_SIZE))
@@ -635,7 +694,7 @@
#else
/* using SDL_ttf: */
- tmdprintf("Setup_SDL_Text() - using SDL_ttf\n");
+ DEBUGMSG(debug_sdl, "Setup_SDL_Text() - using SDL_ttf\n");
if (TTF_Init() < 0)
{
@@ -704,10 +763,8 @@
return NULL;
}
-#ifdef TUXMATH_DEBUG
- fprintf( stderr, "\nEntering BlackOutline(): \n");
- fprintf( stderr, "BlackOutline of \"%s\"\n", t );
-#endif
+ DEBUGMSG(debug_sdl, "Entering BlackOutline():\n");
+ DEBUGMSG(debug_sdl, "BlackOutline of \"%s\"\n", t );
#ifdef HAVE_LIBSDL_PANGO
Set_SDL_Pango_Font_Size(size);
@@ -780,9 +837,7 @@
out = SDL_DisplayFormatAlpha(bg);
SDL_FreeSurface(bg);
-#ifdef TUXMATH_DEBUG
- fprintf( stderr, "\nLeaving BlackOutline(): \n");
-#endif
+ DEBUGMSG(debug_sdl, "\nLeaving BlackOutline(): \n");
return out;
}
@@ -916,7 +971,7 @@
{
char buf[64];
- tmdprintf("Setting font size to %d\n", size);
+ DEBUGMSG(debug_sdl, "Setting font size to %d\n", size);
if(context != NULL)
SDLPango_FreeContext(context);
@@ -1035,9 +1090,7 @@
if (f)
{
-#ifdef TUXMATH_DEBUG
- fprintf(stderr, "LoadFont(): %s loaded successfully\n\n", fontfile);
-#endif
+ DEBUGMSG(debug_sdl, "LoadFont(): %s loaded successfully\n\n", fontfile);
return f;
}
else
@@ -1048,8 +1101,3 @@
}
#endif
-
-
-
-
-
Modified: tuxmath/branches/lan/src/SDL_extras.h
===================================================================
--- tuxmath/branches/lan/src/SDL_extras.h 2009-09-02 10:50:25 UTC (rev 1476)
+++ tuxmath/branches/lan/src/SDL_extras.h 2009-09-03 22:06:06 UTC (rev 1477)
@@ -29,22 +29,31 @@
/* Non-text graphics functions: */
-void DrawButton(SDL_Rect* target_rect, int radius, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
-void RoundCorners(SDL_Surface* s, Uint16 radius);
-SDL_Surface* Flip(SDL_Surface *in, int x, int y);
-int inRect(SDL_Rect r, int x, int y);
-void DarkenScreen(Uint8 bits);
-void SwitchScreenMode(void);
-SDL_EventType WaitForEvent(SDL_EventMask events);
-SDL_Surface* Blend(SDL_Surface *S1, SDL_Surface *S2,float gamma);
-SDL_Surface* zoom(SDL_Surface* src, int new_w, int new_h);
+void DrawButton(SDL_Rect* target_rect, int radius, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
+SDL_Surface* CreateButton(int w, int h, int radius, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
+void RoundCorners(SDL_Surface* s, Uint16 radius);
+SDL_Surface* Flip(SDL_Surface *in, int x, int y);
+SDL_Surface* Blend(SDL_Surface *S1, SDL_Surface *S2, float gamma);
+
+void FreeSurfaceArray(SDL_Surface** surfs, int length);
+int inRect(SDL_Rect r, int x, int y);
+void SetRect(SDL_Rect* rect, const float* pos);
+void UpdateRect(SDL_Surface* surf, SDL_Rect* rect);
+
+void DarkenScreen(Uint8 bits);
+void ChangeWindowSize(int new_res_x, int new_res_y);
+void SwitchScreenMode(void);
+
+SDL_EventType WaitForEvent(SDL_EventMask events);
+SDL_Surface* zoom(SDL_Surface* src, int new_w, int new_h);
+
/*Text rendering functions: */
-int Setup_SDL_Text(void);
-void Cleanup_SDL_Text(void);
-SDL_Surface* BlackOutline(const char* t, int size, SDL_Color* c);
-SDL_Surface* SimpleText(const char *t, int size, SDL_Color* col);
-SDL_Surface* SimpleTextWithOffset(const char *t, int size, SDL_Color* col, int *glyph_offset);
+int Setup_SDL_Text(void);
+void Cleanup_SDL_Text(void);
+SDL_Surface* BlackOutline(const char* t, int size, SDL_Color* c);
+SDL_Surface* SimpleText(const char *t, int size, SDL_Color* col);
+SDL_Surface* SimpleTextWithOffset(const char *t, int size, SDL_Color* col, int *glyph_offset);
#endif
Modified: tuxmath/branches/lan/src/SDL_rotozoom.c
===================================================================
--- tuxmath/branches/lan/src/SDL_rotozoom.c 2009-09-02 10:50:25 UTC (rev 1476)
+++ tuxmath/branches/lan/src/SDL_rotozoom.c 2009-09-03 22:06:06 UTC (rev 1477)
@@ -493,6 +493,10 @@
tColorRGBA *pc, *sp;
int gap;
+ c00.r = c00.g = c00.b = c00.a = 0;
+ c01.r = c01.g = c01.b = c01.a = 0;
+ c10.r = c10.g = c10.b = c10.a = 0;
+ c11.r = c11.g = c11.b = c11.a = 0;
/*
* Variable setup
*/
Modified: tuxmath/branches/lan/src/campaign.c
===================================================================
--- tuxmath/branches/lan/src/campaign.c 2009-09-02 10:50:25 UTC (rev 1476)
+++ tuxmath/branches/lan/src/campaign.c 2009-09-03 22:06:06 UTC (rev 1477)
@@ -64,13 +64,13 @@
}
else if (gameresult == GAME_OVER_ERROR)
{
- tmdprintf("Error!\n");
+ DEBUGMSG(debug_game, "Error!\n");
endcampaign = 1;
}
#ifndef TESTING_CAMPAIGN
else if (gameresult == GAME_OVER_ESCAPE)
{
- tmdprintf("hit escape\n");
+ DEBUGMSG(debug_game, "hit escape\n");
endcampaign = 1;
}
#endif
@@ -194,15 +194,15 @@
SDL_FillRect(screen, NULL, 0);
//TransWipe(black, RANDOM_WIPE, 10, 20);
//show this stage's text
- tmdprintf("Briefing\n");
+ DEBUGMSG(debug_game, "Briefing\n");
SDL_BlitSurface(icon, NULL, screen, NULL);
linewrap_list(briefings[stage], wrapped_lines, 40, MAX_LINES, MAX_LINEWIDTH);
scroll_text(wrapped_lines, textarea, 1);
- tmdprintf("Finished briefing\n");
-
+ DEBUGMSG(debug_game, "Finished briefing\n");
+
SDL_FreeSurface(loadedsprite);
SDL_FreeSurface(icon);
}
Modified: tuxmath/branches/lan/src/convert_utf.c
===================================================================
--- tuxmath/branches/lan/src/convert_utf.c 2009-09-02 10:50:25 UTC (rev 1476)
+++ tuxmath/branches/lan/src/convert_utf.c 2009-09-03 22:06:06 UTC (rev 1477)
@@ -47,7 +47,7 @@
return 0;
}
- tmdprintf("ConvertFromUTF8(): UTF8_word = %s\n", UTF8_word);
+ DEBUGMSG(debug_convert_utf, "ConvertFromUTF8(): UTF8_word = %s\n", UTF8_word);
/* NOTE although we *should* be just able to pass "wchar_t" as the out_type, */
/* iconv_open() segfaults on Windows if this is done - grrr.... */
@@ -64,7 +64,7 @@
SDL_iconv_close(conv_descr);
wcsncpy(wide_word, temp_wchar, max_length);
- tmdprintf("ConvertToUTF8(): wide_word = %S\n", wide_word);
+ DEBUGMSG(debug_convert_utf, "ConvertToUTF8(): wide_word = %S\n", wide_word);
return wcslen(wide_word);
}
@@ -91,7 +91,7 @@
size_t in_length = (size_t)UTF_BUF_LENGTH;
size_t out_length = (size_t)UTF_BUF_LENGTH;
- tmdprintf("ConvertToUTF8(): wide_word = %S\n", wide_word);
+ DEBUGMSG(debug_convert_utf, "ConvertToUTF8(): wide_word = %S\n", wide_word);
if(max_length > UTF_BUF_LENGTH)
{
@@ -116,7 +116,7 @@
SDL_iconv_close(conv_descr);
strncpy(UTF8_word, temp_UTF8, max_length);
- tmdprintf("ConvertToUTF8(): UTF8_word = %s\n", UTF8_word);
+ DEBUGMSG(debug_convert_utf, "ConvertToUTF8(): UTF8_word = %s\n", UTF8_word);
return strlen(UTF8_word);
}
Modified: tuxmath/branches/lan/src/credits.c
===================================================================
--- tuxmath/branches/lan/src/credits.c 2009-09-02 10:50:25 UTC (rev 1476)
+++ tuxmath/branches/lan/src/credits.c 2009-09-03 22:06:06 UTC (rev 1477)
@@ -105,11 +105,11 @@
{" "},
{N_("These rights include the freedom to study, copy, modify, and redistribute the program.")},
{" "},
- {N_("A full copy of the GPL is included with the documenation for this program.")},
+ {N_("A full copy of the GPL is included with the documentation for this program.")},
{" "},
{N_("For more information about Free Software and the GNU GPL, visit:")},
{"http://www.fsf.org"},
- {NULL}
+ {" "}
};
@@ -472,7 +472,7 @@
clearing = 1; //scroll to blank
}
else
- tmdprintf("text[line]: %s\n", text[line]);
+ DEBUGMSG(debug_titlescreen, "text[line]: %s\n", text[line]);
}
}
@@ -583,8 +583,8 @@
if (!str || *str == '\0')
return;
- tmdprintf("Entering draw_text(%s)\n", str);
-
+ DEBUGMSG(debug_titlescreen, "Entering draw_text(%s)\n", str);
+
if (str[0] == '-') //highlight text
{
str++;
@@ -606,6 +606,6 @@
dest.x -= surf->w / 2; //center text
SDL_BlitSurface(surf, NULL, screen, &dest);
SDL_FreeSurface(surf);
- tmdprintf("done\n");
+ DEBUGMSG(debug_titlescreen, "done\n");
}
#endif
Modified: tuxmath/branches/lan/src/factoroids.c
===================================================================
--- tuxmath/branches/lan/src/factoroids.c 2009-09-02 10:50:25 UTC (rev 1476)
+++ tuxmath/branches/lan/src/factoroids.c 2009-09-03 22:06:06 UTC (rev 1477)
@@ -234,9 +234,7 @@
counter = 0;
tux_img = IMG_TUX_CONSOLE1;
- #ifdef TUXMATH_DEBUG
- fprintf(stderr, "Entering factors():\n");
- #endif
+ DEBUGMSG(debug_factoroids, "Entering factors():\n");
FF_game = FACTOROIDS_GAME;
@@ -316,11 +314,7 @@
counter = 0;
tux_img = IMG_TUX_CONSOLE1;
-
- #ifdef TUXMATH_DEBUG
- fprintf(stderr, "Entering factors():\n");
- #endif
-
+ DEBUGMSG(debug_factoroids, "Entering factors():\n");
/*****Initalizing the Factor activiy *****/
FF_game = FRACTIONS_GAME;
@@ -1230,9 +1224,6 @@
SDL_Rect dest_message;
SDL_Event event;
-#ifdef TUXMATH_DEBUG
- //print_exit_conditions();
-#endif
/* TODO: need better "victory" screen with animation, special music, etc., */
/* as well as options to review missed questions, play again using missed */
@@ -1286,9 +1277,7 @@
case GAME_OVER_ERROR:
{
-#ifdef TUXMATH_DEBUG
- printf("\ngame() exiting with error");
-#endif
+ DEBUGMSG(debug_factoroids, "game() exiting with error");
}
case GAME_OVER_LOST:
case GAME_OVER_OTHER:
@@ -1713,9 +1702,7 @@
s1 = s2 = s3 = s4 = NULL;
-#ifdef TUXMATH_DEBUG
- fprintf(stderr, "ShowMessage() - creating text\n" );
-#endif
+ DEBUGMSG(debug_factoroids, "ShowMessage() - creating text\n" );
if (str1)
s1 = BlackOutline(str1, DEFAULT_MENU_FONT_SIZE, &white);
@@ -1727,11 +1714,8 @@
if (str4)
s4 = BlackOutline(str4, DEFAULT_MENU_FONT_SIZE, &white);
-#ifdef TUXMATH_DEBUG
- fprintf(stderr, "ShowMessage() - drawing screen\n" );
-#endif
+ DEBUGMSG(debug_factoroids, "ShowMessage() - drawing screen\n" );
-
/* Draw lines of text (do after drawing Tux so text is in front): */
if (s1)
{
@@ -2202,10 +2186,6 @@
/* This SHOULD NOT HAPPEN and means we have a bug somewhere. */
/* if (!MC_ListQuestionsLeft() && !num_comets_alive)
{
- #ifdef TUXMATH_DEBUG
- printf("\nListQuestionsLeft() = %d", MC_ListQuestionsLeft());
- printf("\nnum_comets_alive = %d", num_comets_alive);
- #endif
return GAME_OVER_ERROR;
}
*/
Modified: tuxmath/branches/lan/src/fileops.c
===================================================================
--- tuxmath/branches/lan/src/fileops.c 2009-09-02 10:50:25 UTC (rev 1476)
+++ tuxmath/branches/lan/src/fileops.c 2009-09-03 22:06:06 UTC (rev 1477)
@@ -294,9 +294,7 @@
get_user_data_dir_with_subdir(opt_path);
strcat(opt_path, OPTIONS_FILENAME);
- #ifdef TUXMATH_DEBUG
- printf("\nIn read_user_config_file() full path to config file is: = %s\n", opt_path);
- #endif
+ DEBUGMSG(debug_fileops, "In read_user_config_file() full path to config file is: = %s\n", opt_path);
fp = fopen(opt_path, "r");
if (fp) /* file exists */
@@ -331,11 +329,8 @@
free(last_config_file_name);
last_config_file_name = strdup(filename);
- #ifdef TUXMATH_DEBUG
- printf("\nIn read_named_config_file() filename is: = %s\n", filename);
- #endif
+ DEBUGMSG(debug_fileops, "In read_named_config_file() filename is: = %s\n", filename);
-
/* First look in current working directory: */
getcwd(opt_path, PATH_MAX); /* get current working directory */
/* add separating '/' unless cwd is '/' : */
@@ -345,18 +340,12 @@
}
strcat(opt_path, filename); /* tack on filename */
+ DEBUGMSG(debug_fileops, "In read_named_config_file() checking for %s (cwd)\n", opt_path);
- #ifdef TUXMATH_DEBUG
- printf("\nIn read_named_config_file() checking for %s (cwd)\n", opt_path);
- #endif
-
-
fp = fopen(opt_path, "r"); /* try to open file */
if (fp) /* file exists */
{
- #ifdef TUXMATH_DEBUG
- printf("\nFound %s\n", opt_path);
- #endif
+ DEBUGMSG(debug_fileops, "Found %s\n", opt_path);
if (read_config_file(fp, USER_CONFIG_FILE))
{
@@ -384,16 +373,12 @@
strcat(opt_path, filename);
}
- #ifdef TUXMATH_DEBUG
- printf("\nIn read_named_config_file() checking for %s (abs)\n", opt_path);
- #endif
+ DEBUGMSG(debug_fileops, "In read_named_config_file() checking for %s (abs)\n", opt_path);
fp = fopen(opt_path, "r");
if (fp) /* file exists */
{
- #ifdef TUXMATH_DEBUG
- printf("\nFound %s\n", opt_path);
- #endif
+ DEBUGMSG(debug_fileops, "Found %s\n", opt_path);
if (read_config_file(fp, USER_CONFIG_FILE))
{
@@ -414,16 +399,12 @@
strcat(opt_path, "/missions/");
strcat(opt_path, filename);
- #ifdef TUXMATH_DEBUG
- printf("\nIn read_named_config_file() checking for %s (missions)\n", opt_path);
- #endif
+ DEBUGMSG(debug_fileops, "In read_named_config_file() checking for %s (missions)\n", opt_path);
fp = fopen(opt_path, "r");
if (fp) /* file exists */
{
- #ifdef TUXMATH_DEBUG
- printf("\nFound %s\n", opt_path);
- #endif
+ DEBUGMSG(debug_fileops, "Found %s\n", opt_path);
if (read_config_file(fp, USER_CONFIG_FILE))
{
@@ -443,16 +424,12 @@
strcat(opt_path, "/missions/lessons/");
strcat(opt_path, filename);
- #ifdef TUXMATH_DEBUG
- printf("\nIn read_named_config_file() checking for %s (missions/lessons)\n", opt_path);
- #endif
+ DEBUGMSG(debug_fileops, "In read_named_config_file() checking for %s (missions/lessons)\n", opt_path);
fp = fopen(opt_path, "r");
if (fp) /* file exists */
{
- #ifdef TUXMATH_DEBUG
- printf("\nFound %s\n", opt_path);
- #endif
+ DEBUGMSG(debug_fileops, "Found %s\n", opt_path);
if (read_config_file(fp, USER_CONFIG_FILE))
{
@@ -472,16 +449,12 @@
strcat(opt_path, "/missions/arcade/");
strcat(opt_path, filename);
- #ifdef TUXMATH_DEBUG
- printf("\nIn read_named_config_file() checking for %s (missions/arcade)\n", opt_path);
- #endif
+ DEBUGMSG(debug_fileops, "In read_named_config_file() checking for %s (missions/arcade)\n", opt_path);
fp = fopen(opt_path, "r");
if (fp) /* file exists */
{
- #ifdef TUXMATH_DEBUG
- printf("\nFound %s\n", opt_path);
- #endif
+ DEBUGMSG(debug_fileops, "Found %s\n", opt_path);
if (read_config_file(fp, USER_CONFIG_FILE))
{
@@ -501,16 +474,12 @@
get_user_data_dir_with_subdir(opt_path);
strcat(opt_path, filename);
- #ifdef TUXMATH_DEBUG
- printf("\nIn read_named_config_file() checking for %s (.tuxmath)\n", opt_path);
- #endif
+ DEBUGMSG(debug_fileops, "In read_named_config_file() checking for %s (.tuxmath)\n", opt_path);
fp = fopen(opt_path, "r");
if (fp) /* file exists */
{
- #ifdef TUXMATH_DEBUG
- printf("\nFound %s\n", opt_path);
- #endif
+ DEBUGMSG(debug_fileops, "Found %s\n", opt_path);
if (read_config_file(fp, USER_CONFIG_FILE))
{
@@ -532,16 +501,12 @@
strcat(opt_path, "/");
strcat(opt_path, filename);
- #ifdef TUXMATH_DEBUG
- printf("\nIn read_named_config_file() checking for %s (home)\n", opt_path);
- #endif
+ DEBUGMSG(debug_fileops, "In read_named_config_file() checking for %s (home)\n", opt_path);
fp = fopen(opt_path, "r");
if (fp) /* file exists */
{
- #ifdef TUXMATH_DEBUG
- printf("\nFound %s\n", opt_path);
- #endif
+ DEBUGMSG(debug_fileops, "Found %s\n", opt_path);
if (read_config_file(fp, USER_CONFIG_FILE))
{
@@ -557,9 +522,7 @@
}
/* Could not find file (or read it if found) in any location: */
- #ifdef TUXMATH_DEBUG
- printf("\nread_named_config_file() could not find/read: %s\n", opt_path);
- #endif
+ DEBUGMSG(debug_fileops, "read_named_config_file() could not find/read: %s\n", opt_path);
return 0;
}
@@ -596,18 +559,13 @@
return 0;
}
-#ifdef TUXMATH_DEBUG
- fprintf(stderr, "lesson_path is: %s\n", lesson_path);
-#endif
+ DEBUGMSG(debug_fileops, "lesson_path is: %s\n", lesson_path);
/* Believe we now have complete scandir() for all platforms :) */
num_lessons = scandir(lesson_path, &lesson_list_dirents, is_lesson_file, alphasort);
+ DEBUGMSG(debug_fileops, "num_lessons is: %d\n", num_lessons);
-#ifdef TUXMATH_DEBUG
- fprintf(stderr, "num_lessons is: %d\n", num_lessons);
-#endif
-
if (num_lessons < 0) {
perror("scanning lesson directory");
num_lessons = 0;
@@ -642,9 +600,7 @@
if (nchars < 0 || nchars >= NAME_BUF_SIZE)
continue;
-#ifdef TUXMATH_DEBUG
- fprintf(stderr, "Found lesson file %d:\t%s\n", lessons, lesson_list_filenames[lessons]);
-#endif
+ DEBUGMSG(debug_fileops, "Found lesson file %d:\t%s\n", lessons, lesson_list_filenames[lessons]);
/* load the name for the lesson from the file ... (1st line) */
tempFile = fopen(lesson_list_filenames[lessons], "r");
@@ -740,9 +696,7 @@
get_user_data_dir_with_subdir(opt_path);
strcat(opt_path, GOLDSTAR_FILENAME);
- #ifdef TUXMATH_DEBUG
- printf("\nIn read_goldstars() full path to file is: = %s\n", opt_path);
- #endif
+ DEBUGMSG(debug_fileops, "In read_goldstars() full path to file is: = %s\n", opt_path);
fp = fopen(opt_path, "r");
if (fp) /* file exists */
@@ -776,9 +730,7 @@
get_user_data_dir_with_subdir(opt_path);
strcat(opt_path, GOLDSTAR_FILENAME);
- #ifdef TUXMATH_DEBUG
- printf("\nIn write_goldstars() full path to file is: = %s\n", opt_path);
- #endif
+ DEBUGMSG(debug_fileops, "In write_goldstars() full path to file is: = %s\n", opt_path);
fp = fopen(opt_path, "w");
if (fp)
@@ -808,9 +760,7 @@
get_user_data_dir_with_subdir(opt_path);
strcat(opt_path, HIGHSCORE_FILENAME);
- #ifdef TUXMATH_DEBUG
- printf("\nIn read_high_scores() full path to file is: = %s\n", opt_path);
- #endif
+ DEBUGMSG(debug_fileops, "In read_high_scores() full path to file is: = %s\n", opt_path);
fp = fopen(opt_path, "r");
if (fp) /* file exists */
@@ -856,9 +806,7 @@
strncpy(opt_path,high_scores_file_path,PATH_MAX);
strcat(opt_path, HIGHSCORE_FILENAME);
- #ifdef TUXMATH_DEBUG
- printf("\nIn read_high_scores() full path to file is: = %s\n", opt_path);
- #endif
+ DEBUGMSG(debug_fileops, "In read_high_scores() full path to file is: = %s\n", opt_path);
fp = fopen(opt_path, "r");
if (fp) /* file exists */
@@ -933,9 +881,7 @@
strncpy(opt_path,high_scores_file_path,PATH_MAX);
strcat(opt_path, HIGHSCORE_FILENAME);
- #ifdef TUXMATH_DEBUG
- printf("\nIn write_high_scores() full path to file is: = %s\n", opt_path);
- #endif
+ DEBUGMSG(debug_fileops, "In write_high_scores() full path to file is: = %s\n", opt_path);
fp = fopen(opt_path, "a");
if (fp)
@@ -1062,17 +1008,13 @@
char buf[PATH_MAX];
char *parameter, *param_begin, *param_end, *value, *value_end;
- #ifdef TUXMATH_DEBUG
- printf("\nEntering read_config_file()\n");
- #endif
+ DEBUGMSG(debug_fileops, "Entering read_config_file()\n");
/* get out if file pointer invalid: */
if(!fp)
{
- #ifdef TUXMATH_DEBUG
- printf("config file pointer invalid!\n");
- printf("Leaving read_config_file()\n");
- #endif
+ DEBUGMSG(debug_fileops, "config file pointer invalid!\n");
+ DEBUGMSG(debug_fileops, "Leaving read_config_file()\n");
fprintf(stderr, "config file pointer invalid!\n");
return 0;
@@ -1084,9 +1026,6 @@
/* read in a line at a time: */
while (fgets (buf, PATH_MAX, fp))
{
- #ifdef TUXMATH_DEBUG
- //printf("Beginning fgets() loop\n");
- #endif
/* "parameter" and "value" will contain the non-whitespace chars */
/* before and after the '=' sign, respectively. e.g.: */
/* */
@@ -1098,9 +1037,6 @@
/* ignore comment lines */
if ((buf[0] == ';') || (buf[0] == '#'))
{
- #ifdef TUXMATH_DEBUG
- //printf("Skipping comment line\n");
- #endif
continue;
}
@@ -1140,10 +1076,6 @@
if (!value || (value == buf))
{
- #ifdef TUXMATH_DEBUG
- //fprintf(stderr, "Error while reading prefs - line with no '='!\n");
- #endif
-
free(parameter);
continue;
}
@@ -1169,8 +1101,8 @@
/* terminate string here: */
*value_end = 0;
- tmdprintf("parameter = '%s'\t, length = %zu\n", parameter, strlen(parameter));
- tmdprintf("value = '%s'\t, length = %zu\t, atoi() = %d\t, atof() = %.2f\n", value, strlen(value), atoi(value), atof(value));
+ DEBUGMSG(debug_fileops, "parameter = '%s'\t, length = %zu\n", parameter, strlen(parameter));
+ DEBUGMSG(debug_fileops, "value = '%s'\t, length = %zu\t, atoi() = %d\t, atof() = %.2f\n", value, strlen(value), atoi(value), atof(value));
/* Now ready to handle each name/value pair! */
@@ -1413,13 +1345,12 @@
MC_SetOpt(DIVISION_ALLOWED, 0);
if (MC_GetOpt(MIN_TYPING_NUM) > MC_GetOpt(MAX_TYPING_NUM) )
MC_SetOpt(TYPING_PRACTICE_ALLOWED, 0);
-
- #ifdef TUXMATH_DEBUG
- printf("\nAfter file read in:\n");
- write_config_file(stdout, 0);
- printf("Leaving read_config_file()\n");
- #endif
+ DEBUGMSG(debug_fileops, "After file read in:\n");
+ DEBUGCODE(debug_fileops)
+ write_config_file(stdout, 0);
+ DEBUGMSG(debug_fileops, "Leaving read_config_file()\n");
+
return 1;
}
@@ -1462,9 +1393,7 @@
get_user_data_dir_with_subdir(opt_path);
strcat(opt_path, OPTIONS_FILENAME);
- #ifdef TUXMATH_DEBUG
- printf("\nIn write_user_config_file() full path to config file is: = %s\n", opt_path);
- #endif
+ DEBUGMSG(debug_fileops, "In write_user_config_file() full path to config file is: = %s\n", opt_path);
/* save settings: */
fp = fopen(opt_path, "w");
@@ -1718,14 +1647,13 @@
"############################################################\n\n";
}
-
- tmdprintf("\nEntering write_config_file()\n");
+ DEBUGMSG(debug_fileops, "Entering write_config_file()\n");
/* get out if file pointer null */
if(!fp)
{
fprintf (stderr, "write_config_file() - file pointer invalid/n");
- tmdprintf("Leaving write_config_file()\n");
+ DEBUGMSG(debug_fileops, "Leaving write_config_file()\n");
return 0;
}
@@ -1944,9 +1872,7 @@
/* print options pertaining to math questions from MathCards: */
// MC_PrintMathOptions(fp, 1);
- #ifdef TUXMATH_DEBUG
- printf("Leaving write_config_file()\n");
- #endif
+ DEBUGMSG(debug_fileops, "Leaving write_config_file()\n");
return 1;
}
@@ -1967,6 +1893,8 @@
char filepath1[PATH_MAX];
char filepath2[PATH_MAX];
+ DEBUGMSG(debug_fileops,"Entering write_pregame_summary.\n")
+
/* Make sure tuxmath dir exists or can be created: */
if (!find_tuxmath_dir())
{
@@ -1986,9 +1914,7 @@
fp = fopen(filepath1, "r");
if (fp)
{
- #ifdef TUXMATH_DEBUG
- printf("\nIn write_pregame_summary() - removing oldest summary file\n");
- #endif
+ DEBUGMSG(debug_fileops,"\nIn write_pregame_summary() - removing oldest summary file\n")
fclose(fp);
remove(filepath1);
@@ -2038,10 +1964,12 @@
fprintf(fp, "\n\nNumber of Questions: %d", MC_StartingListLength());
fclose(fp);
+ DEBUGMSG(debug_fileops,"Leaving write_pregame_summary.\n")
return 1;
}
else /* Couldn't write file for some reason: */
{
+ DEBUGMSG(debug_fileops,"Can't write_pregame_summary.\n")
return 0;
}
}
@@ -2168,17 +2096,13 @@
/* find $HOME */
get_user_data_dir_with_subdir(opt_path);
- #ifdef TUXMATH_DEBUG
- printf("\nIn find_tuxmath_dir() tuxmath dir is: = %s\n", opt_path);
- #endif
+ DEBUGMSG(debug_fileops, "In find_tuxmath_dir() tuxmath dir is: = %s\n", opt_path);
/* find out if directory exists - if not, create it: */
dir_ptr = opendir(opt_path);
if (dir_ptr) /* don't leave DIR* open if it was already there */
{
- #ifdef TUXMATH_DEBUG
- printf("\nIn find_tuxmath_dir() tuxmath dir opened OK\n");
- #endif
+ DEBUGMSG(debug_fileops, "In find_tuxmath_dir() tuxmath dir opened OK\n");
closedir(dir_ptr);
return 1;
@@ -2196,17 +2120,13 @@
fp = fopen(opt_path, "r");
if (fp)
{
- #ifdef TUXMATH_DEBUG
- printf("\nIn find_tuxmath_dir() - removing old .tuxmath file\n");
- #endif
+ DEBUGMSG(debug_fileops, "In find_tuxmath_dir() - removing old .tuxmath file\n");
fclose(fp);
remove(opt_path);
}
- #ifdef TUXMATH_DEBUG
- printf("\nIn find_tuxmath_dir() - trying to create .tuxmath dir\n");
- #endif
+ DEBUGMSG(debug_fileops, "In find_tuxmath_dir() - trying to create .tuxmath dir\n");
//status = mkdir(opt_path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
@@ -2216,9 +2136,7 @@
status = mkdir(opt_path);
#endif
- #ifdef TUXMATH_DEBUG
- printf("\nIn find_tuxmath_dir() - mkdir returned: %d\n", status);
- #endif
+ DEBUGMSG(debug_fileops, "In find_tuxmath_dir() - mkdir returned: %d\n", status);
/* mkdir () returns 0 if successful */
if (0 == status)
Modified: tuxmath/branches/lan/src/fileops.h
===================================================================
--- tuxmath/branches/lan/src/fileops.h 2009-09-02 10:50:25 UTC (rev 1476)
+++ tuxmath/branches/lan/src/fileops.h 2009-09-03 22:06:06 UTC (rev 1477)
@@ -27,40 +27,13 @@
/* Names for images (formerly in images.h) */
enum {
- IMG_STANDBY,
- IMG_MENU_BKG,
- IMG_MENU_TITLE,
-// IMG_LOADING,
IMG_TITLE,
IMG_LEFT,
IMG_LEFT_GRAY,
IMG_RIGHT,
IMG_RIGHT_GRAY,
-// IMG_OPTIONS,
IMG_TUX4KIDS,
IMG_NBS,
-// IMG_TUX_HELMET1,
-// IMG_TUX_HELMET2,
-// IMG_TUX_HELMET3,
-// IMG_PLAY,
-// IMG_CMD_OPTIONS,
-// IMG_CMD_CREDITS,
-// IMG_CMD_QUIT,
-/* IMG_OPT_ADDITION,
- IMG_OPT_SUBTRACTION,
- IMG_OPT_MULTIPLICATION,
- IMG_OPT_DIVISION,
- IMG_OPT_MAX_ANSWER,
- IMG_OPT_SPEED,
- IMG_OPT_Q_RANGE,
- IMG_OPT_RNG_1_5,
- IMG_OPT_RNG_1_5_ON,
- IMG_OPT_RNG_6_12,
- IMG_OPT_RNG_6_12_ON,
- IMG_OPT_RNG_13_20,
- IMG_OPT_RNG_13_20_ON,
- IMG_OPT_CHECK,
- IMG_OPT_CHECK_ON,*/
IMG_CITY_BLUE,
IMG_CITY_BLUE_EXPL1,
IMG_CITY_BLUE_EXPL2,
@@ -90,35 +63,9 @@
IMG_CITY_RED_EXPL5,
IMG_CITY_RED_DEAD,
IMG_SHIELDS,
- IMG_COMET1,
- IMG_COMET2,
- IMG_COMET3,
- IMG_COMETEX8,
- COMET_EXPL_END = IMG_COMETEX8,
- IMG_COMETEX7,
- IMG_COMETEX6,
- IMG_COMETEX5,
- IMG_COMETEX4,
- IMG_COMETEX3,
- IMG_COMETEX2,
- IMG_COMETEX1,
- COMET_EXPL_START = IMG_COMETEX1,
IMG_MINI_COMET1,
IMG_MINI_COMET2,
IMG_MINI_COMET3,
- IMG_BONUS_COMET1,
- IMG_BONUS_COMET2,
- IMG_BONUS_COMET3,
- IMG_BONUS_COMETEX8,
- BONUS_COMET_EXPL_END = IMG_BONUS_COMETEX8,
- IMG_BONUS_COMETEX7,
- IMG_BONUS_COMETEX6,
- IMG_BONUS_COMETEX5,
- IMG_BONUS_COMETEX4,
- IMG_BONUS_COMETEX3,
- IMG_BONUS_COMETEX2,
- IMG_BONUS_COMETEX1,
- BONUS_COMET_EXPL_START = IMG_BONUS_COMETEX1,
IMG_NUMS,
IMG_LEDNUMS,
IMG_LED_NEG_SIGN,
@@ -127,7 +74,6 @@
IMG_DEMO_SMALL,
IMG_KEYPAD,
IMG_KEYPAD_NO_NEG,
-// IMG_CONSOLE,
IMG_CONSOLE_LED,
IMG_CONSOLE_BASH,
IMG_TUX_CONSOLE1,
@@ -197,6 +143,15 @@
NUM_IMAGES
};
+/* Names for animated images (sprites) */
+enum {
+ IMG_COMET,
+ IMG_BONUS_COMET,
+ IMG_COMET_EXPL,
+ IMG_BONUS_COMET_EXPL,
+ NUM_SPRITES
+};
+
/* Names for game sounds (formerly in sounds.h): */
enum {
SND_HARP,
Modified: tuxmath/branches/lan/src/fileops_media.c
===================================================================
--- tuxmath/branches/lan/src/fileops_media.c 2009-09-02 10:50:25 UTC (rev 1476)
+++ tuxmath/branches/lan/src/fileops_media.c 2009-09-03 22:06:06 UTC (rev 1477)
@@ -22,150 +22,132 @@
int i;
static char* image_filenames[NUM_IMAGES] = {
- DATA_PREFIX "/images/status/standby.png",
- DATA_PREFIX "/images/title/menu_bkg.jpg",
- DATA_PREFIX "/images/title/title1.png",
- DATA_PREFIX "/images/status/title.png",
- DATA_PREFIX "/images/status/left.png",
- DATA_PREFIX "/images/status/left_gray.png",
- DATA_PREFIX "/images/status/right.png",
- DATA_PREFIX "/images/status/right_gray.png",
- DATA_PREFIX "/images/status/tux4kids.png",
- DATA_PREFIX "/images/status/nbs.png",
- DATA_PREFIX "/images/cities/city-blue.png",
- DATA_PREFIX "/images/cities/csplode-blue-1.png",
- DATA_PREFIX "/images/cities/csplode-blue-2.png",
- DATA_PREFIX "/images/cities/csplode-blue-3.png",
- DATA_PREFIX "/images/cities/csplode-blue-4.png",
- DATA_PREFIX "/images/cities/csplode-blue-5.png",
- DATA_PREFIX "/images/cities/cdead-blue.png",
- DATA_PREFIX "/images/cities/city-green.png",
- DATA_PREFIX "/images/cities/csplode-green-1.png",
- DATA_PREFIX "/images/cities/csplode-green-2.png",
- DATA_PREFIX "/images/cities/csplode-green-3.png",
- DATA_PREFIX "/images/cities/csplode-green-4.png",
- DATA_PREFIX "/images/cities/csplode-green-5.png",
- DATA_PREFIX "/images/cities/cdead-green.png",
- DATA_PREFIX "/images/cities/city-orange.png",
- DATA_PREFIX "/images/cities/csplode-orange-1.png",
- DATA_PREFIX "/images/cities/csplode-orange-2.png",
- DATA_PREFIX "/images/cities/csplode-orange-3.png",
- DATA_PREFIX "/images/cities/csplode-orange-4.png",
- DATA_PREFIX "/images/cities/csplode-orange-5.png",
- DATA_PREFIX "/images/cities/cdead-orange.png",
- DATA_PREFIX "/images/cities/city-red.png",
- DATA_PREFIX "/images/cities/csplode-red-1.png",
- DATA_PREFIX "/images/cities/csplode-red-2.png",
- DATA_PREFIX "/images/cities/csplode-red-3.png",
- DATA_PREFIX "/images/cities/csplode-red-4.png",
- DATA_PREFIX "/images/cities/csplode-red-5.png",
- DATA_PREFIX "/images/cities/cdead-red.png",
- DATA_PREFIX "/images/cities/shields.png",
- DATA_PREFIX "/images/comets/comet1.png",
- DATA_PREFIX "/images/comets/comet2.png",
- DATA_PREFIX "/images/comets/comet3.png",
- DATA_PREFIX "/images/comets/cometex3.png",
- DATA_PREFIX "/images/comets/cometex3.png",
- DATA_PREFIX "/images/comets/cometex2.png",
- DATA_PREFIX "/images/comets/cometex2.png",
- DATA_PREFIX "/images/comets/cometex1a.png",
- DATA_PREFIX "/images/comets/cometex1a.png",
- DATA_PREFIX "/images/comets/cometex1.png",
- DATA_PREFIX "/images/comets/cometex1.png",
- DATA_PREFIX "/images/comets/mini_comet1.png",
- DATA_PREFIX "/images/comets/mini_comet2.png",
- DATA_PREFIX "/images/comets/mini_comet3.png",
- DATA_PREFIX "/images/comets/bonus_comet1.png",
- DATA_PREFIX "/images/comets/bonus_comet2.png",
- DATA_PREFIX "/images/comets/bonus_comet3.png",
- DATA_PREFIX "/images/comets/bonus_cometex3.png",
- DATA_PREFIX "/images/comets/bonus_cometex3.png",
- DATA_PREFIX "/images/comets/bonus_cometex2.png",
- DATA_PREFIX "/images/comets/bonus_cometex2.png",
- DATA_PREFIX "/images/comets/bonus_cometex1a.png",
- DATA_PREFIX "/images/comets/bonus_cometex1a.png",
- DATA_PREFIX "/images/comets/bonus_cometex1.png",
- DATA_PREFIX "/images/comets/bonus_cometex1.png",
- DATA_PREFIX "/images/status/nums.png",
- DATA_PREFIX "/images/status/lednums.png",
- DATA_PREFIX "/images/status/led_neg_sign.png",
- DATA_PREFIX "/images/status/paused.png",
- DATA_PREFIX "/images/status/demo.png",
- DATA_PREFIX "/images/status/demo-small.png",
- DATA_PREFIX "/images/status/keypad.png",
- DATA_PREFIX "/images/status/keypad_no_neg.png",
- DATA_PREFIX "/images/tux/console_led.png",
- DATA_PREFIX "/images/tux/console_bash.png",
- DATA_PREFIX "/images/tux/tux-console1.png",
- DATA_PREFIX "/images/tux/tux-console2.png",
- DATA_PREFIX "/images/tux/tux-console3.png",
- DATA_PREFIX "/images/tux/tux-console4.png",
- DATA_PREFIX "/images/tux/tux-relax1.png",
- DATA_PREFIX "/images/tux/tux-relax2.png",
- DATA_PREFIX "/images/tux/tux-egypt1.png",
- DATA_PREFIX "/images/tux/tux-egypt2.png",
- DATA_PREFIX "/images/tux/tux-egypt3.png",
- DATA_PREFIX "/images/tux/tux-egypt4.png",
- DATA_PREFIX "/images/tux/tux-drat.png",
- DATA_PREFIX "/images/tux/tux-yipe.png",
- DATA_PREFIX "/images/tux/tux-yay1.png",
- DATA_PREFIX "/images/tux/tux-yay2.png",
- DATA_PREFIX "/images/tux/tux-yes1.png",
- DATA_PREFIX "/images/tux/tux-yes2.png",
- DATA_PREFIX "/images/tux/tux-sit.png",
- DATA_PREFIX "/images/tux/tux-fist1.png",
- DATA_PREFIX "/images/tux/tux-fist2.png",
- DATA_PREFIX "/images/penguins/flapdown.png",
- DATA_PREFIX "/images/penguins/flapup.png",
- DATA_PREFIX "/images/penguins/incoming.png",
- DATA_PREFIX "/images/penguins/grumpy.png",
- DATA_PREFIX "/images/penguins/worried.png",
- DATA_PREFIX "/images/penguins/standing-up.png",
- DATA_PREFIX "/images/penguins/sitting-down.png",
- DATA_PREFIX "/images/penguins/walk-on1.png",
- DATA_PREFIX "/images/penguins/walk-on2.png",
- DATA_PREFIX "/images/penguins/walk-on3.png",
- DATA_PREFIX "/images/penguins/walk-off1.png",
- DATA_PREFIX "/images/penguins/walk-off2.png",
- DATA_PREFIX "/images/penguins/walk-off3.png",
- DATA_PREFIX "/images/igloos/melted3.png",
- DATA_PREFIX "/images/igloos/melted2.png",
- DATA_PREFIX "/images/igloos/melted1.png",
- DATA_PREFIX "/images/igloos/half.png",
- DATA_PREFIX "/images/igloos/intact.png",
- DATA_PREFIX "/images/igloos/rebuilding1.png",
- DATA_PREFIX "/images/igloos/rebuilding2.png",
- DATA_PREFIX "/images/igloos/steam1.png",
- DATA_PREFIX "/images/igloos/steam2.png",
- DATA_PREFIX "/images/igloos/steam3.png",
- DATA_PREFIX "/images/igloos/steam4.png",
- DATA_PREFIX "/images/igloos/steam5.png",
- DATA_PREFIX "/images/igloos/cloud.png",
- DATA_PREFIX "/images/igloos/snow1.png",
- DATA_PREFIX "/images/igloos/snow2.png",
- DATA_PREFIX "/images/igloos/snow3.png",
- DATA_PREFIX "/images/igloos/extra_life.png",
- DATA_PREFIX "/images/status/wave.png",
- DATA_PREFIX "/images/status/score.png",
- DATA_PREFIX "/images/status/stop.png",
- DATA_PREFIX "/images/status/numbers.png",
- DATA_PREFIX "/images/status/gameover.png",
- DATA_PREFIX "/images/status/gameover_won.png",
- DATA_PREFIX "/images/factoroids/gbstars.png",
- DATA_PREFIX "/images/factoroids/asteroid1.png",
- DATA_PREFIX "/images/factoroids/asteroid2.png",
- DATA_PREFIX "/images/factoroids/asteroid3.png",
- DATA_PREFIX "/images/factoroids/ship01.png",
- DATA_PREFIX "/images/factoroids/factoroids.png",
- DATA_PREFIX "/images/factoroids/factors.png",
- DATA_PREFIX "/images/factoroids/tux.png",
- DATA_PREFIX "/images/factoroids/good.png"
+ "status/title.png",
+ "status/left.png",
+ "status/left_gray.png",
+ "status/right.png",
+ "status/right_gray.png",
+ "status/tux4kids.png",
+ "status/nbs.png",
+ "cities/city-blue.png",
+ "cities/csplode-blue-1.png",
+ "cities/csplode-blue-2.png",
+ "cities/csplode-blue-3.png",
+ "cities/csplode-blue-4.png",
+ "cities/csplode-blue-5.png",
+ "cities/cdead-blue.png",
+ "cities/city-green.png",
+ "cities/csplode-green-1.png",
+ "cities/csplode-green-2.png",
+ "cities/csplode-green-3.png",
+ "cities/csplode-green-4.png",
+ "cities/csplode-green-5.png",
+ "cities/cdead-green.png",
+ "cities/city-orange.png",
+ "cities/csplode-orange-1.png",
+ "cities/csplode-orange-2.png",
+ "cities/csplode-orange-3.png",
+ "cities/csplode-orange-4.png",
+ "cities/csplode-orange-5.png",
+ "cities/cdead-orange.png",
+ "cities/city-red.png",
+ "cities/csplode-red-1.png",
+ "cities/csplode-red-2.png",
+ "cities/csplode-red-3.png",
+ "cities/csplode-red-4.png",
+ "cities/csplode-red-5.png",
+ "cities/cdead-red.png",
+ "cities/shields.png",
+ "comets/mini_comet1.png",
+ "comets/mini_comet2.png",
+ "comets/mini_comet3.png",
+ "status/nums.png",
+ "status/lednums.png",
+ "status/led_neg_sign.png",
+ "status/paused.png",
+ "status/demo.png",
+ "status/demo-small.png",
+ "status/keypad.png",
+ "status/keypad_no_neg.png",
+ "tux/console_led.png",
+ "tux/console_bash.png",
+ "tux/tux-console1.png",
+ "tux/tux-console2.png",
+ "tux/tux-console3.png",
+ "tux/tux-console4.png",
+ "tux/tux-relax1.png",
+ "tux/tux-relax2.png",
+ "tux/tux-egypt1.png",
+ "tux/tux-egypt2.png",
+ "tux/tux-egypt3.png",
+ "tux/tux-egypt4.png",
+ "tux/tux-drat.png",
+ "tux/tux-yipe.png",
+ "tux/tux-yay1.png",
+ "tux/tux-yay2.png",
+ "tux/tux-yes1.png",
+ "tux/tux-yes2.png",
+ "tux/tux-sit.png",
+ "tux/tux-fist1.png",
+ "tux/tux-fist2.png",
+ "penguins/flapdown.png",
+ "penguins/flapup.png",
+ "penguins/incoming.png",
+ "penguins/grumpy.png",
+ "penguins/worried.png",
+ "penguins/standing-up.png",
+ "penguins/sitting-down.png",
+ "penguins/walk-on1.png",
+ "penguins/walk-on2.png",
+ "penguins/walk-on3.png",
+ "penguins/walk-off1.png",
+ "penguins/walk-off2.png",
+ "penguins/walk-off3.png",
+ "igloos/melted3.png",
+ "igloos/melted2.png",
+ "igloos/melted1.png",
+ "igloos/half.png",
+ "igloos/intact.png",
+ "igloos/rebuilding1.png",
+ "igloos/rebuilding2.png",
+ "igloos/steam1.png",
+ "igloos/steam2.png",
+ "igloos/steam3.png",
+ "igloos/steam4.png",
+ "igloos/steam5.png",
+ "igloos/cloud.png",
+ "igloos/snow1.png",
+ "igloos/snow2.png",
+ "igloos/snow3.png",
+ "igloos/extra_life.png",
+ "status/wave.png",
+ "status/score.png",
+ "status/stop.png",
+ "status/numbers.png",
+ "status/gameover.png",
+ "status/gameover_won.png",
+ "factoroids/gbstars.png",
+ "factoroids/asteroid1.png",
+ "factoroids/asteroid2.png",
+ "factoroids/asteroid3.png",
+ "factoroids/ship01.png",
+ "factoroids/factoroids.png",
+ "factoroids/factors.png",
+ "factoroids/tux.png",
+ "factoroids/good.png"
};
- /* Load images: */
+ static char* sprite_filenames[NUM_IMAGES] = {
+ "comets/comet",
+ "comets/bonus_comet",
+ "comets/cometex",
+ "comets/bonus_cometex"
+ };
+
+ /* Load static images: */
for (i = 0; i < NUM_IMAGES; i++)
{
- images[i] = LoadImageFromFile(image_filenames[i]);
+ images[i] = LoadImage(image_filenames[i], IMG_ALPHA);
if (images[i] == NULL)
{
@@ -178,9 +160,26 @@
}
}
+ /* Load animated graphics: */
+ for (i = 0; i < NUM_SPRITES; i++)
+ {
+ sprites[i] = LoadSprite(sprite_filenames[i], IMG_ALPHA);
+
+ if (sprites[i] == NULL)
+ {
+ fprintf(stderr,
+ "\nError: I couldn't load a graphics file:\n"
+ "%s\n"
+ "The Simple DirectMedia error that occured was:\n"
+ "%s\n\n", sprite_filenames[i], SDL_GetError());
+ return 0;
+ }
+ }
+
+
glyph_offset = 0;
-#ifdef REPLACE_WAVESCORE
+#ifdef REPLACE_WAVESCORE
/* Replace the "WAVE" and "SCORE" with translate-able versions */
SDL_FreeSurface(images[IMG_WAVE]);
images[IMG_WAVE] = SimpleTextWithOffset(_("WAVE"), 28, &white, &glyph_offset);
Modified: tuxmath/branches/lan/src/game.c
===================================================================
--- tuxmath/branches/lan/src/game.c 2009-09-02 10:50:25 UTC (rev 1476)
+++ tuxmath/branches/lan/src/game.c 2009-09-03 22:06:06 UTC (rev 1477)
@@ -221,10 +221,8 @@
/******************************************************/
-#ifdef TUXMATH_DEBUG
static void print_exit_conditions(void);
static void print_status(void);
-#endif
/* --- MAIN GAME FUNCTION!!! --- */
@@ -232,11 +230,10 @@
int game(void)
{
-// Uint32 last_time, now_time;
char buf[NET_BUF_LEN];
char command[NET_BUF_LEN];
- tmdprintf("Entering game():\n");
+ DEBUGMSG(debug_game, "Entering game():\n");
//see if the option matches the actual screen
if (Opts_GetGlobalOpt(FULLSCREEN) == !(screen->flags & SDL_FULLSCREEN) )
@@ -345,9 +342,7 @@
while(GAME_IN_PROGRESS == game_status);
/* END OF MAIN GAME LOOP! */
-#ifdef TUXMATH_DEBUG
- print_exit_conditions();
-#endif
+ DEBUGCODE(debug_game) print_exit_conditions();
/* TODO: need better "victory" screen with animation, special music, etc., */
/* as well as options to review missed questions, play again using missed */
@@ -427,11 +422,7 @@
}
case GAME_OVER_ERROR:
- {
-#ifdef TUXMATH_DEBUG
- printf("\ngame() exiting with error");
-#endif
- }
+ DEBUGMSG(debug_game, "game() exiting with error:\n");
case GAME_OVER_LOST:
case GAME_OVER_OTHER:
{
@@ -706,10 +697,10 @@
void game_set_start_message(const char* m1, const char* m2,
const char* m3, const char* m4)
{
- game_set_message(&s1, m1, -1, RES_Y * 2 / 10);
- game_set_message(&s2, m2, screen->w / 2 - 40, RES_Y * 3 / 10);
- game_set_message(&s3, m3, screen->w / 2 - 40, RES_Y * 4 / 10);
- game_set_message(&s4, m4, screen->w / 2 - 40, RES_Y * 5 / 10);
+ game_set_message(&s1, m1, -1, screen->h * 2 / 10);
+ game_set_message(&s2, m2, screen->w / 2 - 40, screen->h * 3 / 10);
+ game_set_message(&s3, m3, screen->w / 2 - 40, screen->h * 4 / 10);
+ game_set_message(&s4, m4, screen->w / 2 - 40, screen->h * 5 / 10);
start_message_chosen = 1;
}
@@ -719,8 +710,8 @@
{
int i,img;
- tmdprintf("Entering game_initialize()\n");
-
+ DEBUGMSG(debug_game,"Entering game_initialize()\n");
+
/* Clear window: */
SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0));
SDL_Flip(screen);
@@ -745,12 +736,12 @@
if(!Opts_LanMode())
{
- tmdprintf("Calling MC_StartGame()\n");
if (!MC_StartGame())
{
fprintf(stderr, "\nMC_StartGame() failed!");
return 0;
}
+ DEBUGMSG(debug_mathcards | debug_game,"MC_StartGame() finished.\n")
}
/* Start out with our "comets" empty: */
@@ -786,7 +777,8 @@
}
}
}
-
+ DEBUGMSG(debug_game,"Flashcards allocated.\n");
+
cities = (city_type *) malloc(NUM_CITIES * sizeof(city_type));
if (cities == NULL)
{
@@ -881,8 +873,9 @@
if (Opts_BonusCometInterval())
{
bonus_comet_counter = Opts_BonusCometInterval() + 1;
- tmdprintf("\nInitializing with bonus_comet_counter = %d\n",bonus_comet_counter);
+ DEBUGMSG(debug_game,"\nInitializing with bonus_comet_counter = %d\n",bonus_comet_counter);
}
+
extra_life_earned = 0;
cloud.status = EXTRA_LIFE_OFF;
@@ -957,7 +950,7 @@
}
#endif
- tmdprintf("Leaving game():\n");
+ DEBUGMSG(debug_game, "Leaving game():\n");
}
@@ -1052,7 +1045,7 @@
help_add_comet("3 * 3 = ?", "9");
comets[0].y = 2*(screen->h)/3; // start it low down
- while (!(comets[0].expl) && !(quit_help = help_renderframe_exit())); // wait 3 secs
+ while ((comets[0].expl == -1) && !(quit_help = help_renderframe_exit())); // wait 3 secs
if (quit_help)
return;
game_set_message(&s4,_("Notice the answer"),left_edge,comets[0].y-100);
@@ -1180,7 +1173,7 @@
// char ansstr[MC_ANSWER_LEN];
comets[0].alive = 1;
- comets[0].expl = 0;
+ comets[0].expl = -1;
comets[0].answer = atoi(ans_str);
num_comets_alive = 1;
comets[0].city = 0;
@@ -1293,7 +1286,7 @@
picked_comet = (rand() % MAX_COMETS);
if (!(comets[picked_comet].alive &&
- comets[picked_comet].expl < COMET_EXPL_END)
+ comets[picked_comet].expl == -1)
|| comets[picked_comet].y < 80)
{
picked_comet = -1;
@@ -1305,9 +1298,8 @@
if ((rand() % 3) < 1)
demo_answer--; // sometimes get it wrong on purpose
- #ifdef TUXMATH_DEBUG
- printf("Demo mode, comet %d attacked with answer %d\n",picked_comet,demo_answer);
- #endif
+ DEBUGMSG(debug_game, "Demo mode, comet %d attacked with answer %d\n", picked_comet,demo_answer);
+
/* handle negative answer: */
if (demo_answer < 0)
{
@@ -1351,9 +1343,8 @@
else
{
/* "Press Return" */
- #ifdef TUXMATH_DEBUG
- printf("Demo mode firing with these digits: %d%d%d\n",digits[0],digits[1],digits[2]);
- #endif
+ DEBUGMSG(debug_game, "Demo mode firing with these digits: %d%d%d\n",
+ digits[0], digits[1], digits[2]);
doing_answer = 1;
picked_comet = -1;
}
@@ -1394,9 +1385,8 @@
for (i = 0; i < MAX_COMETS; i++)
{
- mcdprintf("Comparing '%s' with '%s'\n", comets[i].flashcard.answer_string, ans);
if (comets[i].alive &&
- comets[i].expl < COMET_EXPL_END &&
+ comets[i].expl == -1 &&
//comets[i].answer == num &&
0 == strncmp(comets[i].flashcard.answer_string, ans, MC_MAX_DIGITS+1) &&
comets[i].y > lowest_y)
@@ -1434,7 +1424,7 @@
/* Destroy comet: */
- comets[lowest].expl = COMET_EXPL_START;
+ comets[lowest].expl = 0;
comets[lowest].zapped = 1;
/* Fire laser: */
laser.alive = LASER_START;
@@ -1597,12 +1587,12 @@
if (comets[i].bonus)
{
comets[i].y += speed * Opts_BonusSpeedRatio() *
- city_expl_height / (RES_Y - images[IMG_CITY_BLUE]->h);
+ city_expl_height / (screen->h - images[IMG_CITY_BLUE]->h);
}
else /* Regular comet: */
{
comets[i].y += speed *
- city_expl_height / (RES_Y - images[IMG_CITY_BLUE]->h);
+ city_expl_height / (screen->h - images[IMG_CITY_BLUE]->h);
}
/* Does it threaten a city? */
@@ -1611,7 +1601,7 @@
/* Did it hit a city? */
if (comets[i].y >= city_expl_height &&
- comets[i].expl < COMET_EXPL_END)
+ comets[i].expl == -1)
{
/* Tell MathCards about it - question not answered correctly: */
if(Opts_LanMode())
@@ -1689,27 +1679,24 @@
tux_anim_frame = ANIM_FRAME_START;
/* Destroy comet: */
- comets[i].expl = COMET_EXPL_START;
+ comets[i].expl = 0;
}
/* Handle comet explosion animation: */
- if (comets[i].expl >= COMET_EXPL_END)
+ if (comets[i].expl >= 0)
{
- comets[i].expl--;
- if (comets[i].expl < COMET_EXPL_END) {
+ comets[i].expl++;
+ if (comets[i].expl >= sprites[IMG_COMET_EXPL]->num_frames * 2) {
comets[i].alive = 0;
+ comets[i].expl = -1;
if (bonus_comet_counter > 1 && comets[i].zapped) {
bonus_comet_counter--;
-#ifdef TUXMATH_DEBUG
- printf("\nbonus_comet_counter is now %d\n",bonus_comet_counter);
-#endif
+ DEBUGMSG(debug_game, "bonus_comet_counter is now %d\n",bonus_comet_counter);
}
if (comets[i].bonus && comets[i].zapped) {
playsound(SND_EXTRA_LIFE);
extra_life_earned = 1;
-#ifdef TUXMATH_DEBUG
- printf("\nExtra life earned!");
-#endif
+ DEBUGMSG(debug_game, "Extra life earned!");
}
}
}
@@ -1978,9 +1965,9 @@
if (cloud.status == EXTRA_LIFE_ON)
return 1;
-#ifdef TUXMATH_DEBUG
- print_status();
-#endif
+ DEBUGCODE(debug_game)
+ print_status();
+
if (extra_life_earned) {
/* Check to see if any ingloo has been hit */
fewest_hits_left = 2;
@@ -1999,9 +1986,9 @@
cloud.y = screen->h/3;
cloud.city = fewest_index;
bonus_comet_counter = Opts_BonusCometInterval()+1;
-#ifdef TUXMATH_DEBUG
- printf("\nBonus comet counter restored to %d\n",bonus_comet_counter);
-#endif
+
+ DEBUGMSG(debug_game, "Bonus comet counter restored to %d\n",bonus_comet_counter);
+
if (cloud.city < NUM_CITIES/2)
cloud.x = -images[IMG_CLOUD]->w/2; /* come in from the left */
else
@@ -2014,27 +2001,29 @@
cloud.snowflake_x[i] = - snow_width/2 + (rand() % snow_width);
cloud.snowflake_size[i] = rand() % 3;
}
-#ifdef TUXMATH_DEBUG
- print_status();
-#endif
+ DEBUGCODE(debug_game)
+ print_status();
return 1;
- } else
+ }
+ else
return 0;
}
+
void game_handle_extra_life(void)
{
// This handles the animation sequence during the rebuilding of an igloo
- int i,igloo_top,num_below_igloo,direction;
+ int i, igloo_top, num_below_igloo, direction;
if (cloud.status == EXTRA_LIFE_ON) {
-#ifdef TUXMATH_DEBUG
- if (penguins[cloud.city].status == PENGUIN_WALKING_OFF) {
- print_status();
- pause_game();
- }
-#endif
+ DEBUGCODE(debug_game)
+ {
+ if (penguins[cloud.city].status == PENGUIN_WALKING_OFF) {
+ print_status();
+ pause_game();
+ }
+ }
// Get the cloud moving in the right direction, if not yet "parked"
direction = 2*(cloud.city < NUM_CITIES/2) - 1;
@@ -2143,13 +2132,13 @@
fgcolor = SDL_MapRGB(screen->format, 64, 96, 64);
if (old_wave != wave)
{
- tmdprintf("Wave %d\n", wave);
+ DEBUGMSG(debug_game,"Wave %d\n", wave);
old_wave = wave;
bgcolor = SDL_MapRGB(screen->format,
64,
64 + ((wave * 32) % 192),
128 - ((wave * 16) % 128) );
- tmdprintf("Filling screen with color %d\n", bgcolor);
+ DEBUGMSG(debug_game,"Filling screen with color %d\n", bgcolor);
}
if (current_bkgd() == NULL || (current_bkgd()->w != screen->w &&
@@ -2183,7 +2172,8 @@
void game_draw_comets(void)
{
- int i, img;
+ int i;
+ SDL_Surface* img = NULL;
SDL_Rect dest;
char* comet_str;
@@ -2192,10 +2182,10 @@
{
if (comets[i].alive && !comets[i].bonus)
{
- if (comets[i].expl < COMET_EXPL_END)
+ if (comets[i].expl == -1)
{
/* Decide which image to display: */
- img = IMG_COMET1 + ((frame + i) % 3);
+ img = sprites[IMG_COMET]->frame[(frame + i) % sprites[IMG_COMET]->num_frames];
/* Display the formula (flashing, in the bottom half
of the screen) */
if (comets[i].y < screen->h / 2 || frame % 8 < 6)
@@ -2209,17 +2199,18 @@
}
else
{
- img = comets[i].expl;
+ /* show each frame of explosion twice */
+ img = sprites[IMG_COMET_EXPL]->frame[comets[i].expl / 2];
comet_str = comets[i].flashcard.answer_string;
}
/* Draw it! */
- dest.x = comets[i].x - (images[img]->w / 2);
- dest.y = comets[i].y - images[img]->h;
- dest.w = images[img]->w;
- dest.h = images[img]->h;
+ dest.x = comets[i].x - (img->w / 2);
+ dest.y = comets[i].y - img->h;
+ dest.w = img->w;
+ dest.h = img->h;
- SDL_BlitSurface(images[img], NULL, screen, &dest);
+ SDL_BlitSurface(img, NULL, screen, &dest);
if (comet_str != NULL)
{
draw_nums(comet_str, comets[i].x, comets[i].y);
@@ -2232,10 +2223,10 @@
{
if (comets[i].alive && comets[i].bonus)
{
- if (comets[i].expl < COMET_EXPL_END)
+ if (comets[i].expl == -1)
{
/* Decide which image to display: */
- img = IMG_COMET1 + ((frame + i) % 3);
+ img = sprites[IMG_BONUS_COMET]->frame[(frame + i) % sprites[IMG_BONUS_COMET]->num_frames];
/* Display the formula (flashing, in the bottom half
of the screen) */
if (comets[i].y < screen->h / 2 || frame % 8 < 6)
@@ -2249,31 +2240,26 @@
}
else
{
- img = comets[i].expl;
+ img = sprites[IMG_BONUS_COMET_EXPL]->frame[comets[i].expl / 2];
comet_str = comets[i].flashcard.answer_string;
}
- /* Move images[] index to bonus range: */
- img += IMG_BONUS_COMET1 - IMG_COMET1;
-
/* Draw it! */
- dest.x = comets[i].x - (images[img]->w / 2);
- dest.y = comets[i].y - images[img]->h;
- dest.w = images[img]->w;
- dest.h = images[img]->h;
-
- SDL_BlitSurface(images[img], NULL, screen, &dest);
+ dest.x = comets[i].x - (img->w / 2);
+ dest.y = comets[i].y - img->h;
+ dest.w = img->w;
+ dest.h = img->h;
+ SDL_BlitSurface(img, NULL, screen, &dest);
if (comet_str != NULL)
{
draw_nums(comet_str, comets[i].x, comets[i].y);
}
}
}
+}
-}
-
void game_draw_cities(void)
{
int i, j, current_layer, max_layer;
@@ -2486,10 +2472,18 @@
{
for (i = 0; i < mp_get_parameter(PLAYERS); ++i)
{
+ SDL_Surface* score;
snprintf(str, 64, "%s: %d", mp_get_player_name(i),mp_get_player_score(i));
- SDL_Surface* score = BlackOutline(str, DEFAULT_MENU_FONT_SIZE, &white);
- SDL_Rect loc = {screen->w - score->w, score->h * (i + 2), 0, 0};
- SDL_BlitSurface(score, NULL, screen, &loc);
+ score = BlackOutline(str, DEFAULT_MENU_FONT_SIZE, &white);
+ if(score)
+ {
+ SDL_Rect loc;
+ loc.w = screen->w - score->w;
+ loc.h = score->h * (i + 2);
+ loc.x = 0;
+ loc.y = 0;
+ SDL_BlitSurface(score, NULL, screen, &loc);
+ }
}
}
@@ -2514,8 +2508,8 @@
user_quit_received != GAME_OVER_ESCAPE &&
user_quit_received != GAME_OVER_CHEATER)
{
- tmdprintf("Unexpected value %d for user_quit_received\n", user_quit_received);
- return GAME_OVER_OTHER;
+ fprintf(stderr, "Unexpected value %d for user_quit_received\n", user_quit_received);
+ return GAME_OVER_OTHER;
}
return user_quit_received;
}
@@ -2540,7 +2534,7 @@
// Should not get here!
if (MC_MissionAccomplished())
{
- tmdprintf("Mission accomplished!\n");
+ DEBUGMSG(debug_game,"Mission accomplished!\n");
return GAME_OVER_WON;
}
#endif
@@ -2549,7 +2543,7 @@
{
if (MC_MissionAccomplished())
{
- tmdprintf("Mission accomplished!\n");
+ DEBUGMSG(debug_game,"Mission accomplished!\n");
return GAME_OVER_WON;
}
}
@@ -2580,19 +2574,15 @@
/* Need to get out if no comets alive and MathCards has no questions left in list, */
/* even though MathCards thinks there are still questions "in play". */
/* This SHOULD NOT HAPPEN and means we have a bug somewhere. */
-// if (!MC_ListQuestionsLeft() && !num_comets_alive)
-// {
-// #ifdef TUXMATH_DEBUG
-// printf("\nListQuestionsLeft() = %d", MC_ListQuestionsLeft());
-// printf("\nnum_comets_alive = %d", num_comets_alive);
-// #endif
-// return GAME_OVER_ERROR;
-// }
+ if (!MC_ListQuestionsLeft() && !num_comets_alive)
+ {
+ fprintf(stderr("Error - no questions left but game not over\n");
+ DEBUGMSG(debug_game, "ListQuestionsLeft() = %d ", MC_ListQuestionsLeft());
+ DEBUGMSG(debug_game, "num_comets_alive = %d", num_comets_alive);
+ return GAME_OVER_ERROR;
+ }
-
-
-
- /* If using demo mode, see if counter has run out: */
+ /* If using demo mode, see if counter has run out: */
if (Opts_DemoMode())
{
if (demo_countdown <= 0 )
@@ -2603,7 +2593,7 @@
return GAME_IN_PROGRESS;
}
-#ifdef TUXMATH_DEBUG
+
void print_exit_conditions(void)
{
printf("\ngame_status:\t");
@@ -2653,8 +2643,8 @@
}
}
}
-#endif
+
/* Reset stuff for the next level! */
void reset_level(void)
{
@@ -2877,7 +2867,7 @@
if(i == TEST_COMETS)
{
- tmdprintf("add_comet() called but no question available in queue\n");
+ DEBUGMSG("add_comet() called but no question available in queue\n");
return 0;
}
#else
@@ -2897,9 +2887,13 @@
return 0;
}
}
- printf("In add_comet(), card is\n");
- print_card(comets[found].flashcard);
+ DEBUGCODE(debug_game)
+ {
+ printf("In add_comet(), card is\n");
+ print_card(comets[found].flashcard);
+ }
+
/* Make sure question is "sane" before we add it: */
if( (comets[found].flashcard.answer > 999)
||(comets[found].flashcard.answer < -999))
@@ -2912,7 +2906,6 @@
/* If we make it to here, create a new comet!*/
comets[found].answer = comets[found].flashcard.answer;
comets[found].alive = 1;
- printf("comet[%d].alive=1\n",found);
num_comets_alive++;
/* Pick a city to attack that was not attacked last time */
@@ -2934,29 +2927,21 @@
/* Should it be a bonus comet? */
comets[found].bonus = 0;
-#ifdef TUXMATH_DEBUG
- printf("\nbonus_comet_counter is %d\n",bonus_comet_counter);
-#endif
+ DEBUGMSG(debug_game, "bonus_comet_counter is %d\n",bonus_comet_counter);
if (bonus_comet_counter == 1)
{
bonus_comet_counter = 0;
comets[found].bonus = 1;
playsound(SND_BONUS_COMET);
-#ifdef TUXMATH_DEBUG
- printf("\nCreated bonus comet");
-#endif
+ DEBUGMSG(debug_game, "Created bonus comet");
}
-#ifdef TUXMATH_DEBUG
- printf ("\nadd_comet(): formula string is: %s",
- comets[found].flashcard.formula_string);
- print_current_quests();
-#endif
-
+ DEBUGMSG(debug_game, "add_comet(): formula string is: %s", comets[found].flashcard.formula_string);
+
/* Record the time at which this comet was created */
comets[found].time_started = SDL_GetTicks();
-// }
+
/* comet slot found and question found so return successfully: */
return 1;
}
@@ -3576,12 +3561,13 @@
/* Escape key - quit! */
user_quit_received = GAME_OVER_ESCAPE;
}
-#ifdef TUXMATH_DEBUG
- if (key == SDLK_LEFTBRACKET) //a nice nonobvious/unused key
+ DEBUGCODE(debug_game)
{
- user_quit_received = GAME_OVER_CHEATER;
+ if (key == SDLK_LEFTBRACKET) //a nice nonobvious/unused key
+ {
+ user_quit_received = GAME_OVER_CHEATER;
+ }
}
-#endif
else if (key == SDLK_TAB
|| key == SDLK_p)
{
@@ -3709,7 +3695,7 @@
void add_score(int inc)
{
score += inc;
- tmdprintf("Score is now: %d\n", score);
+ DEBUGMSG(debug_game,"Score is now: %d\n", score);
}
@@ -3722,13 +3708,11 @@
for (i = 0; i < MAX_COMETS; i++)
{
comets[i].alive = 0;
- comets[i].expl = 0;
+ comets[i].expl = -1;
comets[i].city = 0;
comets[i].x = 0;
comets[i].y = 0;
comets[i].answer = 0;
-// strncpy(comets[i].flashcard.formula_string, " ", max_formula_size);
-// strncpy(comets[i].flashcard.answer_string, " ", max_answer_size);
MC_ResetFlashCard(&(comets[i].flashcard) );
comets[i].bonus = 0;
}
@@ -3746,12 +3730,6 @@
command[i] = buf[i];
}
command[i] = '\0';
-
-//#ifdef LAN_DEBUG
-// printf("buf is %s\n", buf);
-// printf("command is %s\n", command);
-//#endif
-
}
@@ -3793,6 +3771,7 @@
printf("\n");
}
+
void free_on_exit(void)
{
int i;
@@ -3810,8 +3789,8 @@
int i, img;
int old_city_expl_height = city_expl_height;
- tmdprintf("Recalculating positions\n");
-
+ DEBUGMSG(debug_game,"Recalculating positions\n");
+
if (Opts_GetGlobalOpt(USE_IGLOOS))
img = IMG_IGLOO_INTACT;
else
@@ -3824,7 +3803,7 @@
{
cities[i].x = (((screen->w / (NUM_CITIES + 1)) * i) +
((images[img] -> w) / 2));
- tmdprintf("%d,", cities[i].x);
+ DEBUGMSG(debug_game,"%d,", cities[i].x);
}
else
{
@@ -3832,7 +3811,7 @@
(screen->w / (NUM_CITIES + 1) *
(i - NUM_CITIES / 2) +
images[img]->w / 2);
- tmdprintf("%d,", cities[i].x);
+ DEBUGMSG(debug_game,"%d,", cities[i].x);
}
penguins[i].x = cities[i].x;
@@ -3852,6 +3831,4 @@
//else
// comets[i].y = comets[i].y * RES_Y / screen->h;
}
-
-
}
Modified: tuxmath/branches/lan/src/game.h
===================================================================
--- tuxmath/branches/lan/src/game.h 2009-09-02 10:50:25 UTC (rev 1476)
+++ tuxmath/branches/lan/src/game.h 2009-09-03 22:06:06 UTC (rev 1477)
@@ -138,7 +138,6 @@
};
int game(void);
-
void game_set_start_message(const char*, const char*, const char*, const char*);
/* draw_nums() is used in options.c and factoroids.c/h so need extern linkage */
Modified: tuxmath/branches/lan/src/globals.h
===================================================================
--- tuxmath/branches/lan/src/globals.h 2009-09-02 10:50:25 UTC (rev 1476)
+++ tuxmath/branches/lan/src/globals.h 2009-09-03 22:06:06 UTC (rev 1477)
@@ -13,7 +13,7 @@
Part of "Tux4Kids" Project
http://www.tux4kids.org/
-
+
Added March 2, 2006
Copyright: See COPYING file that comes with this distribution
@@ -26,18 +26,42 @@
#define GLOBALS_H
#include "config.h"
-/* for conditional compilation of debugging output */
-//#define TUXMATH_DEBUG
+
+typedef enum { false, true } bool;
+
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+#define max(a,b) (((a) > (b)) ? (a) : (b))
+
/* for Tim's feedback speed control code */
//#define FEEDBACK_DEBUG
//#define LINEBREAK
-/* nice inline debugging macro */
-#ifdef TUXMATH_DEBUG
-#define tmdprintf(...) printf(__VA_ARGS__)
-#else
-#define tmdprintf(...) 0
-#endif
+/* debug data (declared in options.c) */
+extern int debug_status;
+
+/* bitmasks for debugging options (declared in options.c) */
+extern const int debug_setup;
+extern const int debug_fileops;
+extern const int debug_loaders;
+extern const int debug_titlescreen;
+extern const int debug_menu;
+extern const int debug_menu_parser;
+extern const int debug_game;
+extern const int debug_factoroids;
+extern const int debug_lan;
+extern const int debug_mathcards;
+extern const int debug_sdl;
+extern const int debug_lessons;
+extern const int debug_highscore;
+extern const int debug_options;
+extern const int debug_convert_utf;
+extern const int debug_multiplayer;
+extern const int debug_all;
+
+/* debug macros */
+#define DEBUGCODE(mask) if((mask) & debug_status)
+#define DEBUGMSG(mask, ...) if((mask) & debug_status){ fprintf(stderr, __VA_ARGS__); fflush(stderr); }
+
/* Maximum length of file path: */
#define PATH_MAX 4096
@@ -103,11 +127,9 @@
#define REG_RGBA 16,16,96,96
#define SEL_RGBA 16,16,128,128
-#define RES_X 640
-#define RES_Y 480
-#define PIXEL_BITS 32
+#define PIXEL_BITS 32
-enum {
+enum {
CADET_HIGH_SCORE,
SCOUT_HIGH_SCORE,
RANGER_HIGH_SCORE,
@@ -133,3 +155,4 @@
extern int num_lessons;
#endif
+>>>>>>> .merge-right.r1476
Modified: tuxmath/branches/lan/src/highscore.c
===================================================================
--- tuxmath/branches/lan/src/highscore.c 2009-09-02 10:50:25 UTC (rev 1476)
+++ tuxmath/branches/lan/src/highscore.c 2009-09-03 22:06:06 UTC (rev 1477)
@@ -13,13 +13,13 @@
#include "tuxmath.h"
#include "highscore.h"
+#include "menu.h"
#include "titlescreen.h"
#include "fileops.h"
#include "setup.h"
#include "options.h"
#include "SDL_extras.h"
#include "convert_utf.h"
-#include "network.h"
typedef struct high_score_entry {
@@ -39,7 +39,6 @@
{
int i = 0;
int finished = 0;
- int tux_frame = 0;
Uint32 frame = 0;
Uint32 start = 0;
@@ -52,61 +51,20 @@
char score_strings[HIGH_SCORES_SAVED][HIGH_SCORE_NAME_LENGTH + 10] = {{'\0'}};
SDL_Rect score_rects[HIGH_SCORES_SAVED];
- SDL_Rect leftRect, rightRect, stopRect, TuxRect, table_bg;
+ SDL_Rect table_bg;
-
const int max_width = 300;
int score_table_y = 100;
- sprite* Tux = LoadSprite("tux/bigtux", IMG_ALPHA);
const int title_font_size = 32;
const int player_font_size = 14;
-
- /* --- Set up the rects for drawing various things: ----------- */
-
- /* Put arrow buttons in right lower corner, inset by 20 pixels */
- /* with a 10 pixel space between: */
- if (images[IMG_RIGHT])
- {
- rightRect.w = images[IMG_RIGHT]->w;
- rightRect.h = images[IMG_RIGHT]->h;
- rightRect.x = screen->w - images[IMG_RIGHT]->w - 20;
- rightRect.y = screen->h - images[IMG_RIGHT]->h - 20;
- }
-
- if (images[IMG_LEFT])
- {
- leftRect.w = images[IMG_LEFT]->w;
- leftRect.h = images[IMG_LEFT]->h;
- leftRect.x = rightRect.x - 10 - images[IMG_LEFT]->w;
- leftRect.y = screen->h - images[IMG_LEFT]->h - 20;
- }
-
- /* Red "Stop" circle in upper right corner to go back to main menu: */
- if (images[IMG_STOP])
- {
- stopRect.w = images[IMG_STOP]->w;
- stopRect.h = images[IMG_STOP]->h;
- stopRect.x = screen->w - images[IMG_STOP]->w;
- stopRect.y = 0;
- }
-
- if (Tux && Tux->frame[0]) /* make sure sprite has at least one frame */
- {
- TuxRect.w = Tux->frame[0]->w;
- TuxRect.h = Tux->frame[0]->h;
- TuxRect.x = 0;
- TuxRect.y = screen->h - Tux->frame[0]->h;
- }
-
-
while (!finished)
{
start = SDL_GetTicks();
/* Check for user events: */
- while (SDL_PollEvent(&event))
+ while (SDL_PollEvent(&event))
{
switch (event.type)
{
@@ -117,15 +75,15 @@
case SDL_MOUSEBUTTONDOWN:
/* "Stop" button - go to main menu: */
- {
- if (inRect(stopRect, event.button.x, event.button.y ))
+ {
+ if (inRect(stop_rect, event.button.x, event.button.y ))
{
finished = 1;
playsound(SND_TOCK);
}
/* "Left" button - go to previous page: */
- if (inRect(leftRect, event.button.x, event.button.y))
+ if (inRect(prev_rect, event.button.x, event.button.y))
{
if (diff_level > CADET_HIGH_SCORE)
{
@@ -138,7 +96,7 @@
}
/* "Right" button - go to next page: */
- if (inRect( rightRect, event.button.x, event.button.y ))
+ if (inRect(next_rect, event.button.x, event.button.y ))
{
if (diff_level < (NUM_HIGH_SCORE_LEVELS-1))
{
@@ -165,37 +123,31 @@
/* If needed, redraw: */
if (diff_level != old_diff_level)
{
- /* Draw background: */
- if (current_bkg())
- SDL_BlitSurface( current_bkg(), NULL, screen, NULL );
- /* FIXME maybe add image of trophy or similar pic */
- /* Draw Tux: */
- if (Tux && Tux->frame[0]) /* make sure sprite has at least one frame */
- SDL_BlitSurface(Tux->frame[0], NULL, screen, &TuxRect);
+ DrawTitleScreen();
/* Draw controls: */
- if (images[IMG_STOP])
- SDL_BlitSurface(images[IMG_STOP], NULL, screen, &stopRect);
+ if (stop_button)
+ SDL_BlitSurface(stop_button, NULL, screen, &stop_rect);
/* Draw regular or grayed-out left arrow: */
if (diff_level == CADET_HIGH_SCORE)
{
- if (images[IMG_LEFT_GRAY])
- SDL_BlitSurface(images[IMG_LEFT_GRAY], NULL, screen, &leftRect);
+ if (prev_gray)
+ SDL_BlitSurface(prev_gray, NULL, screen, &prev_rect);
}
else
{
- if (images[IMG_LEFT])
- SDL_BlitSurface(images[IMG_LEFT], NULL, screen, &leftRect);
+ if (prev_arrow)
+ SDL_BlitSurface(prev_arrow, NULL, screen, &prev_rect);
}
/* Draw regular or grayed-out right arrow: */
if (diff_level == NUM_HIGH_SCORE_LEVELS - 1)
{
- if (images[IMG_RIGHT_GRAY])
- SDL_BlitSurface(images[IMG_RIGHT_GRAY], NULL, screen, &rightRect);
+ if (next_gray)
+ SDL_BlitSurface(next_gray, NULL, screen, &next_rect);
}
else
{
- if (images[IMG_RIGHT])
- SDL_BlitSurface(images[IMG_RIGHT], NULL, screen, &rightRect);
+ if (next_arrow)
+ SDL_BlitSurface(next_arrow, NULL, screen, &next_rect);
}
/* Draw background shading for table: */
@@ -283,7 +235,6 @@
/* Clear out old surfaces and update: */
if (score_surfs[i]) /* this should not happen! */
SDL_FreeSurface(score_surfs[i]);
-
if (HS_Score(diff_level, i) == Opts_LastScore() && frame % 5 < 2)
score_surfs[i] = BlackOutline(N_(score_strings[i]), player_font_size, &yellow);
else
@@ -292,7 +243,6 @@
/* Get out if BlackOutline() fails: */
if (!score_surfs[i])
continue;
-
/* Set up entries in vertical column: */
if (0 == i)
score_rects[i].y = score_table_y;
@@ -313,26 +263,8 @@
old_diff_level = diff_level;
}
+ HandleTitleScreenAnimations();
- /* --- make tux blink --- */
- switch (frame % TUX6)
- {
- case 0: tux_frame = 1; break;
- case TUX1: tux_frame = 2; break;
- case TUX2: tux_frame = 3; break;
- case TUX3: tux_frame = 4; break;
- case TUX4: tux_frame = 3; break;
- case TUX5: tux_frame = 2; break;
- default: tux_frame = 0;
- }
-
- if (Tux && tux_frame)
- {
- SDL_BlitSurface(Tux->frame[tux_frame - 1], NULL, screen, &TuxRect);
- SDL_UpdateRect(screen, TuxRect.x, TuxRect.y, TuxRect.w, TuxRect.h);
- }
-
-
/* Wait so we keep frame rate constant: */
while ((SDL_GetTicks() - start) < 33)
{
@@ -340,8 +272,6 @@
}
frame++;
} // End of while (!finished) loop
-
- FreeSprite(Tux);
}
@@ -354,21 +284,16 @@
NameEntry(pl_name, _("You Are In The Hall of Fame!"), _("Enter Your Name:"));
}
-
-
void NameEntry(char* pl_name, const char* heading, const char* sub)
{
char UTF8_buf[HIGH_SCORE_NAME_LENGTH * 3] = {'\0'};
SDL_Rect loc;
SDL_Rect redraw_rect;
- SDL_Rect TuxRect,
- stopRect;
int redraw = 0;
int first_draw = 1;
int finished = 0;
- int tux_frame = 0;
Uint32 frame = 0;
Uint32 start = 0;
wchar_t wchar_buf[HIGH_SCORE_NAME_LENGTH + 1] = {'\0'};
@@ -377,42 +302,16 @@
const int BG_WIDTH = 400;
const int BG_HEIGHT = 200;
- sprite* Tux = LoadSprite("tux/bigtux", IMG_ALPHA);
-
if (!pl_name)
return;
-
/* We need to get Unicode vals from SDL keysyms */
SDL_EnableUNICODE(SDL_ENABLE);
-#ifdef TUXMATH_DEBUG
- fprintf(stderr, "\nEnter HighScoreNameEntry()\n" );
-#endif
+ DEBUGMSG(debug_highscore, "Enter HighScoreNameEntry()\n" );
+ DrawTitleScreen();
- /* Draw background: */
- if (current_bkg())
- SDL_BlitSurface(current_bkg(), NULL, screen, NULL);
-
- /* Red "Stop" circle in upper right corner to go back to main menu: */
- if (images[IMG_STOP])
- {
- stopRect.w = images[IMG_STOP]->w;
- stopRect.h = images[IMG_STOP]->h;
- stopRect.x = screen->w - images[IMG_STOP]->w;
- stopRect.y = 0;
- SDL_BlitSurface(images[IMG_STOP], NULL, screen, &stopRect);
- }
-
- if (Tux && Tux->frame[0]) /* make sure sprite has at least one frame */
- {
- TuxRect.w = Tux->frame[0]->w;
- TuxRect.h = Tux->frame[0]->h;
- TuxRect.x = 0;
- TuxRect.y = screen->h - Tux->frame[0]->h;
- }
-
/* Draw translucent background for text: */
{
SDL_Rect bg_rect;
@@ -456,12 +355,11 @@
SDL_UpdateRect(screen, 0, 0, 0, 0);
-
while (!finished)
{
start = SDL_GetTicks();
- while (SDL_PollEvent(&event))
+ while (SDL_PollEvent(&event))
{
switch (event.type)
{
@@ -472,8 +370,8 @@
case SDL_MOUSEBUTTONDOWN:
/* "Stop" button - go to main menu: */
- {
- if (inRect(stopRect, event.button.x, event.button.y ))
+ {
+ if (inRect(stop_rect, event.button.x, event.button.y ))
{
finished = 1;
playsound(SND_TOCK);
@@ -482,10 +380,8 @@
}
case SDL_KEYDOWN:
{
-#ifdef TUXMATH_DEBUG
- fprintf(stderr, "Before keypress, string is %S\tlength = %d\n",
- wchar_buf, (int)wcslen(wchar_buf));
-#endif
+ DEBUGMSG(debug_highscore, "Before keypress, string is %S\tlength = %d\n",
+ wchar_buf, (int)wcslen(wchar_buf));
switch (event.key.keysym.sym)
{
case SDLK_ESCAPE:
@@ -513,14 +409,12 @@
{
wchar_buf[(int)wcslen(wchar_buf)] = event.key.keysym.unicode;
redraw = 1;
- }
+ }
}
} /* end 'switch (event.key.keysym.sym)' */
-#ifdef TUXMATH_DEBUG
- fprintf(stderr, "After keypress, string is %S\tlength = %d\n",
- wchar_buf, (int)wcslen(wchar_buf));
-#endif
+ DEBUGMSG(debug_highscore, "After keypress, string is %S\tlength = %d\n",
+ wchar_buf, (int)wcslen(wchar_buf));
/* Now draw name, if needed: */
if (redraw)
{
@@ -570,24 +464,8 @@
}
}
}
-
- /* --- make tux blink --- */
- switch (frame % TUX6)
- {
- case 0: tux_frame = 1; break;
- case TUX1: tux_frame = 2; break;
- case TUX2: tux_frame = 3; break;
- case TUX3: tux_frame = 4; break;
- case TUX4: tux_frame = 3; break;
- case TUX5: tux_frame = 2; break;
- default: tux_frame = 0;
- }
- if (Tux && tux_frame)
- {
- SDL_BlitSurface(Tux->frame[tux_frame - 1], NULL, screen, &TuxRect);
- SDL_UpdateRect(screen, TuxRect.x, TuxRect.y, TuxRect.w, TuxRect.h);
- }
+ HandleTitleScreenAnimations();
/* Wait so we keep frame rate constant: */
while ((SDL_GetTicks() - start) < 33)
@@ -597,8 +475,6 @@
frame++;
} // End of while (!finished) loop
- FreeSprite(Tux);
-
/* Turn off SDL Unicode lookup (because has some overhead): */
SDL_EnableUNICODE(SDL_DISABLE);
@@ -606,6 +482,240 @@
strncpy((char*)pl_name, (char*)UTF8_buf, HIGH_SCORE_NAME_LENGTH * 3);
}
+
+
+
+/* Zero-out the array before use: */
+void initialize_scores(void)
+{
+ int i, j;
+ for (i = 0; i < NUM_HIGH_SCORE_LEVELS; i++)
+ {
+ for (j = 0; j < HIGH_SCORES_SAVED; j++)
+ {
+ high_scores[i][j].score = 0;
+ strcpy(high_scores[i][j].name, "");
+ }
+ }
+}
+
+/* Test to see where a new score ranks on the list. */
+/* The return value is the index value - add one to get */
+/* the common-language place on the list. */
+int check_score_place(int diff_level, int new_score)
+{
+ int i = 0;
+
+ /* Make sure diff_level is valid: */
+ if (diff_level < 0
+ || diff_level >= NUM_HIGH_SCORE_LEVELS)
+ {
+ fprintf(stderr, "In insert_score(), diff_level invalid!\n");
+ return 0;
+ }
+
+ /* Find correct place in list: */
+ for (i = 0; i < HIGH_SCORES_SAVED; i++)
+ {
+ if (new_score > high_scores[diff_level][i].score)
+ break;
+ }
+
+ return i; /* So if we return HIGH_SCORES_SAVED, the score did not */
+ /* make the list. */
+}
+
+/* Put a new high score entry into the table for the corresponding */
+/* difficulty level - returns 1 if successful. */
+int insert_score(char* playername, int diff_level, int new_score)
+{
+ int i = 0;
+ int insert_place;
+
+ insert_place = check_score_place(diff_level, new_score);
+
+ if (HIGH_SCORES_SAVED == insert_place) /* Score didn't make the top 10 */
+ {
+ return 0;
+ }
+
+ /* Move lower entries down: */
+ for (i = HIGH_SCORES_SAVED - 1; i > insert_place; i--)
+ {
+ high_scores[diff_level][i].score =
+ high_scores[diff_level][i - 1].score;
+ strncpy(high_scores[diff_level][i].name,
+ high_scores[diff_level][i - 1].name,
+ HIGH_SCORE_NAME_LENGTH);
+ }
+
+ /* Now put in new entry: */
+ high_scores[diff_level][insert_place].score = new_score;
+ strncpy(high_scores[diff_level][insert_place].name,
+ playername,
+ HIGH_SCORE_NAME_LENGTH);
+ return 1;
+}
+
+
+void print_high_scores(FILE* fp)
+{
+ int i, j;
+
+ fprintf(fp, "\nHigh Scores:\n");
+
+ for (i = 0; i < NUM_HIGH_SCORE_LEVELS; i++)
+ {
+ switch(i)
+ {
+ case CADET_HIGH_SCORE:
+ {
+ fprintf(fp, "\nSpace Cadet:\n");
+ break;
+ }
+ case SCOUT_HIGH_SCORE:
+ {
+ fprintf(fp, "\nScout:\n");
+ break;
+ }
+ case RANGER_HIGH_SCORE:
+ {
+ fprintf(fp, "\nRanger:\n");
+ break;
+ }
+ case ACE_HIGH_SCORE:
+ {
+ fprintf(fp, "\nAce:\n");
+ break;
+ }
+ case COMMANDO_HIGH_SCORE:
+ {
+ fprintf(fp, "\nCommando:\n");
+ break;
+ }
+ case FACTORS_HIGH_SCORE:
+ {
+ fprintf(fp, "\nFactors:\n");
+ break;
+ }
+ case FRACTIONS_HIGH_SCORE:
+ {
+ fprintf(fp, "\nFractions:\n");
+ break;
+ }
+ }
+
+ for (j = 0; j < HIGH_SCORES_SAVED; j++)
+ {
+ fprintf(fp, "%d.\t%s\t%d\n",
+ j + 1, //Convert to common-language ordinals
+ high_scores[i][j].name,
+ high_scores[i][j].score);
+ }
+ }
+}
+
+
+int read_high_scores_fp(FILE* fp)
+{
+ char buf[PATH_MAX];
+ char* token;
+ const char delimiters[] = "\t";
+
+ char* name_read;
+ int score_read;
+ int diff_level;
+
+ DEBUGMSG(debug_highscore, "Entering read_high_scores_fp()\n");
+
+ /* get out if file pointer invalid: */
+ if(!fp)
+ {
+ fprintf(stderr, "In read_high_scores_fp(), file pointer invalid!\n");
+ return 0;
+ }
+
+ /* make sure we start at beginning: */
+ rewind(fp);
+
+ /* read in a line at a time: */
+ while (fgets (buf, PATH_MAX, fp))
+ {
+ /* Ignore comment lines: */
+ if ((buf[0] == ';') || (buf[0] == '#'))
+ {
+ continue;
+ }
+ /* Split up line with strtok()to get needed values, */
+ /* then call insert_score() for each line. */
+ token = strtok(buf, delimiters);
+ if (!token)
+ continue;
+ diff_level = atoi(token);
+ if (diff_level >= NUM_HIGH_SCORE_LEVELS)
+ continue;
+
+ token = strtok(NULL, delimiters);
+ if (!token)
+ continue;
+ score_read = atoi(token);
+ /* Note that name can contain spaces - \t is only delimiter: */
+ name_read = strtok(NULL, delimiters);
+ /* Now insert entry: */
+ insert_score(name_read, diff_level, score_read);
+ }
+ return 1;
+}
+
+
+/* Return the score associated with a table entry: */
+/* Note: the place is given as the array index, i.e. */
+/* 0 for the top of the list. */
+int HS_Score(int diff_level, int place)
+{
+ /* Make sure diff_level is valid: */
+ if (diff_level < 0
+ || diff_level >= NUM_HIGH_SCORE_LEVELS)
+ {
+ fprintf(stderr, "In HS_Score(), diff_level = %d, invalid!\n", diff_level);
+ return -1;
+ }
+
+ /* Make sure place is valid: */
+ if (place < 0
+ || place >= HIGH_SCORES_SAVED)
+ {
+ fprintf(stderr, "In HS_Score(), place invalid!\n");
+ return -1;
+ }
+
+ return high_scores[diff_level][place].score;
+}
+
+
+/* Return (pointer to) the name associated with a table entry: */
+char* HS_Name(int diff_level, int place)
+{
+ /* Make sure diff_level is valid: */
+ if (diff_level < 0
+ || diff_level >= NUM_HIGH_SCORE_LEVELS)
+ {
+ fprintf(stderr, "In HS_Score(), diff_level invalid!\n");
+ return NULL;
+ }
+
+ /* Make sure place is valid: */
+ if (place < 0
+ || place >= HIGH_SCORES_SAVED)
+ {
+ fprintf(stderr, "In HS_Score(), place invalid!\n");
+ return NULL;
+ }
+
+ return high_scores[diff_level][place].name;
+}
+
+
void Ready(const char* heading)
{
SDL_Rect loc;
@@ -1305,3 +1415,721 @@
return high_scores[diff_level][place].name;
}
+=======
+/*
+* C Implementation: highscore.c
+*
+* Description: Implementation of high score tables for tuxmath.
+*
+*
+* Author: David Bruce <dbruce at tampabay.rr.com>, (C) 2007
+*
+* Copyright: See COPYING file that comes with this distribution
+* (Briefly, GNU GPL version 2 or greater).
+*/
+#include <string.h>
+
+#include "tuxmath.h"
+#include "highscore.h"
+#include "menu.h"
+#include "titlescreen.h"
+#include "fileops.h"
+#include "setup.h"
+#include "options.h"
+#include "SDL_extras.h"
+#include "convert_utf.h"
+
+
+typedef struct high_score_entry {
+ int score;
+ char name[HIGH_SCORE_NAME_LENGTH];
+} high_score_entry;
+
+
+high_score_entry high_scores[NUM_HIGH_SCORE_LEVELS][HIGH_SCORES_SAVED];
+
+/* Local function prototypes: */
+
+
+
+/* Display high scores: */
+void DisplayHighScores(int level)
+{
+ int i = 0;
+ int finished = 0;
+ Uint32 frame = 0;
+ Uint32 start = 0;
+
+ int diff_level = level;
+ int old_diff_level = -1; //So table gets refreshed first time through
+ /* Surfaces, char buffers, and rects for table: */
+ SDL_Surface* score_surfs[HIGH_SCORES_SAVED] = {NULL};
+
+ /* 10 spaces should be enough room for place and score on each line: */
+ char score_strings[HIGH_SCORES_SAVED][HIGH_SCORE_NAME_LENGTH + 10] = {{'\0'}};
+
+ SDL_Rect score_rects[HIGH_SCORES_SAVED];
+ SDL_Rect table_bg;
+
+ const int max_width = 300;
+ int score_table_y = 100;
+
+ const int title_font_size = 32;
+ const int player_font_size = 14;
+
+ while (!finished)
+ {
+ start = SDL_GetTicks();
+
+ /* Check for user events: */
+ while (SDL_PollEvent(&event))
+ {
+ switch (event.type)
+ {
+ case SDL_QUIT:
+ {
+ cleanup();
+ }
+
+ case SDL_MOUSEBUTTONDOWN:
+ /* "Stop" button - go to main menu: */
+ {
+ if (inRect(stop_rect, event.button.x, event.button.y ))
+ {
+ finished = 1;
+ playsound(SND_TOCK);
+ }
+
+ /* "Left" button - go to previous page: */
+ if (inRect(prev_rect, event.button.x, event.button.y))
+ {
+ if (diff_level > CADET_HIGH_SCORE)
+ {
+ diff_level--;
+ if (Opts_GetGlobalOpt(MENU_SOUND))
+ {
+ playsound(SND_TOCK);
+ }
+ }
+ }
+
+ /* "Right" button - go to next page: */
+ if (inRect(next_rect, event.button.x, event.button.y ))
+ {
+ if (diff_level < (NUM_HIGH_SCORE_LEVELS-1))
+ {
+ diff_level++;
+ if (Opts_GetGlobalOpt(MENU_SOUND))
+ {
+ playsound(SND_TOCK);
+ }
+ }
+ }
+ break;
+ }
+
+
+ case SDL_KEYDOWN:
+ {
+ finished = 1;
+ playsound(SND_TOCK);
+ }
+ }
+ }
+
+
+ /* If needed, redraw: */
+ if (diff_level != old_diff_level)
+ {
+ DrawTitleScreen();
+ /* Draw controls: */
+ if (stop_button)
+ SDL_BlitSurface(stop_button, NULL, screen, &stop_rect);
+ /* Draw regular or grayed-out left arrow: */
+ if (diff_level == CADET_HIGH_SCORE)
+ {
+ if (prev_gray)
+ SDL_BlitSurface(prev_gray, NULL, screen, &prev_rect);
+ }
+ else
+ {
+ if (prev_arrow)
+ SDL_BlitSurface(prev_arrow, NULL, screen, &prev_rect);
+ }
+ /* Draw regular or grayed-out right arrow: */
+ if (diff_level == NUM_HIGH_SCORE_LEVELS - 1)
+ {
+ if (next_gray)
+ SDL_BlitSurface(next_gray, NULL, screen, &next_rect);
+ }
+ else
+ {
+ if (next_arrow)
+ SDL_BlitSurface(next_arrow, NULL, screen, &next_rect);
+ }
+
+ /* Draw background shading for table: */
+ table_bg.x = (screen->w)/2 - (max_width + 20)/2 + 50; //don't draw over Tux
+ table_bg.y = 5;
+ table_bg.w = max_width + 20;
+ table_bg.h = screen->h - 10 - images[IMG_RIGHT]->h;
+ DrawButton(&table_bg, 25, SEL_RGBA);
+
+ /* Draw difficulty level heading: */
+ {
+ SDL_Surface* srfc = NULL;
+ SDL_Rect text_rect, button_rect;
+
+ srfc = BlackOutline(_("Hall Of Fame"), title_font_size, &yellow);
+ if (srfc)
+ {
+ button_rect.x = text_rect.x = (screen->w)/2 - (srfc->w)/2 + 50;
+ button_rect.y = text_rect.y = 10;
+ button_rect.w = text_rect.w = srfc->w;
+ button_rect.h = text_rect.h = srfc->h;
+ /* add margin to button and draw: */
+ button_rect.x -= 10;
+ button_rect.w += 20;
+ DrawButton(&button_rect, 15, 0, 0, 32, 192);
+ /* Now blit text and free surface: */
+ SDL_BlitSurface(srfc, NULL, screen, &text_rect);
+ SDL_FreeSurface(srfc);
+ srfc = NULL;
+ }
+
+ switch (diff_level)
+ {
+ case CADET_HIGH_SCORE:
+ srfc = BlackOutline(_("Space Cadet"), title_font_size, &white);
+ break;
+ case SCOUT_HIGH_SCORE:
+ srfc = BlackOutline(_("Scout"), title_font_size, &white);
+ break;
+ case RANGER_HIGH_SCORE:
+ srfc = BlackOutline(_("Ranger"), title_font_size, &white);
+ break;
+ case ACE_HIGH_SCORE:
+ srfc = BlackOutline(_("Ace"), title_font_size, &white);
+ break;
+ case COMMANDO_HIGH_SCORE:
+ srfc = BlackOutline(_("Commando"), title_font_size, &white);
+ break;
+ case FACTORS_HIGH_SCORE:
+ srfc = BlackOutline(_("Factors"), title_font_size, &white);
+ break;
+ case FRACTIONS_HIGH_SCORE:
+ srfc = BlackOutline(_("Fractions"), title_font_size, &white);
+ break;
+ default:
+ srfc = BlackOutline(_("Space Cadet"), title_font_size, &white);
+ }
+
+ if (srfc)
+ {
+ text_rect.x = (screen->w)/2 - (srfc->w)/2 + 50;
+ text_rect.y += text_rect.h; /* go to bottom of first line */
+ text_rect.w = srfc->w;
+ text_rect.h = srfc->h;
+ SDL_BlitSurface(srfc, NULL, screen, &text_rect);
+ SDL_FreeSurface(srfc);
+ srfc = NULL;
+ /* note where score table will start: */
+ score_table_y = text_rect.y + text_rect.h;
+ }
+ }
+
+
+ /* Generate and draw desired table: */
+
+ for (i = 0; i < HIGH_SCORES_SAVED; i++)
+ {
+ /* Get data for entries: */
+ sprintf(score_strings[i],
+ "%d. %d %s",
+ i + 1, /* Add one to get common-language place number */
+ HS_Score(diff_level, i),
+ HS_Name(diff_level, i));
+
+ /* Clear out old surfaces and update: */
+ if (score_surfs[i]) /* this should not happen! */
+ SDL_FreeSurface(score_surfs[i]);
+ if (HS_Score(diff_level, i) == Opts_LastScore() && frame % 5 < 2)
+ score_surfs[i] = BlackOutline(N_(score_strings[i]), player_font_size, &yellow);
+ else
+ score_surfs[i] = BlackOutline(N_(score_strings[i]), player_font_size, &white);
+
+ /* Get out if BlackOutline() fails: */
+ if (!score_surfs[i])
+ continue;
+ /* Set up entries in vertical column: */
+ if (0 == i)
+ score_rects[i].y = score_table_y;
+ else
+ score_rects[i].y = score_rects[i - 1].y + score_rects[i - 1].h;
+
+ score_rects[i].x = (screen->w)/2 - max_width/2 + 50;
+ score_rects[i].h = score_surfs[i]->h;
+ score_rects[i].w = max_width;
+
+ SDL_BlitSurface(score_surfs[i], NULL, screen, &score_rects[i]);
+ SDL_FreeSurface(score_surfs[i]);
+ score_surfs[i] = NULL;
+ }
+ /* Update screen: */
+ SDL_UpdateRect(screen, 0, 0, 0, 0);
+
+ old_diff_level = diff_level;
+ }
+
+ HandleTitleScreenAnimations();
+
+ /* Wait so we keep frame rate constant: */
+ while ((SDL_GetTicks() - start) < 33)
+ {
+ SDL_Delay(20);
+ }
+ frame++;
+ } // End of while (!finished) loop
+}
+
+
+/* Display screen to allow player to enter name for high score table: */
+/* The pl_name argument *must* point to a validly allocated string array */
+/* at least three times HIGH_SCORE_NAME_LENGTH because UTF-8 is a */
+/* multibyte encoding. */
+void HighScoreNameEntry(char* pl_name)
+{
+ NameEntry(pl_name, _("You Are In The Hall of Fame!"), _("Enter Your Name:"));
+}
+
+void NameEntry(char* pl_name, const char* heading, const char* sub)
+{
+ char UTF8_buf[HIGH_SCORE_NAME_LENGTH * 3] = {'\0'};
+
+ SDL_Rect loc;
+ SDL_Rect redraw_rect;
+
+ int redraw = 0;
+ int first_draw = 1;
+ int finished = 0;
+ Uint32 frame = 0;
+ Uint32 start = 0;
+ wchar_t wchar_buf[HIGH_SCORE_NAME_LENGTH + 1] = {'\0'};
+ const int NAME_FONT_SIZE = 32;
+ const int BG_Y = 100;
+ const int BG_WIDTH = 400;
+ const int BG_HEIGHT = 200;
+
+ if (!pl_name)
+ return;
+
+ /* We need to get Unicode vals from SDL keysyms */
+ SDL_EnableUNICODE(SDL_ENABLE);
+
+ DEBUGMSG(debug_highscore, "Enter HighScoreNameEntry()\n" );
+
+ DrawTitleScreen();
+
+ /* Draw translucent background for text: */
+ {
+ SDL_Rect bg_rect;
+ bg_rect.x = (screen->w)/2 - BG_WIDTH/2;
+ bg_rect.y = BG_Y;
+ bg_rect.w = BG_WIDTH;
+ bg_rect.h = BG_HEIGHT;
+ DrawButton(&bg_rect, 15, REG_RGBA);
+
+ bg_rect.x += 10;
+ bg_rect.y += 10;
+ bg_rect.w -= 20;
+ bg_rect.h = 60;
+ DrawButton(&bg_rect, 10, SEL_RGBA);
+ }
+
+ /* Draw heading: */
+ {
+ SDL_Surface* s = BlackOutline(_(heading),
+ DEFAULT_MENU_FONT_SIZE, &white);
+ if (s)
+ {
+ loc.x = (screen->w/2) - (s->w/2);
+ loc.y = 110;
+ SDL_BlitSurface(s, NULL, screen, &loc);
+ SDL_FreeSurface(s);
+ }
+
+ s = BlackOutline(_(sub),
+ DEFAULT_MENU_FONT_SIZE, &white);
+ if (s)
+ {
+ loc.x = (screen->w/2) - (s->w/2);
+ loc.y = 140;
+ SDL_BlitSurface(s, NULL, screen, &loc);
+ SDL_FreeSurface(s);
+ }
+ }
+
+ /* and update: */
+ SDL_UpdateRect(screen, 0, 0, 0, 0);
+
+
+ while (!finished)
+ {
+ start = SDL_GetTicks();
+
+ while (SDL_PollEvent(&event))
+ {
+ switch (event.type)
+ {
+ case SDL_QUIT:
+ {
+ cleanup();
+ }
+
+ case SDL_MOUSEBUTTONDOWN:
+ /* "Stop" button - go to main menu: */
+ {
+ if (inRect(stop_rect, event.button.x, event.button.y ))
+ {
+ finished = 1;
+ playsound(SND_TOCK);
+ break;
+ }
+ }
+ case SDL_KEYDOWN:
+ {
+ DEBUGMSG(debug_highscore, "Before keypress, string is %S\tlength = %d\n",
+ wchar_buf, (int)wcslen(wchar_buf));
+ switch (event.key.keysym.sym)
+ {
+ case SDLK_ESCAPE:
+ case SDLK_RETURN:
+ case SDLK_KP_ENTER:
+ {
+ finished = 1;
+ playsound(SND_TOCK);
+ break;
+ }
+ case SDLK_BACKSPACE:
+ {
+ if (wcslen(wchar_buf) > 0)
+ wchar_buf[(int)wcslen(wchar_buf) - 1] = '\0';
+ redraw = 1;
+ break;
+ }
+
+ /* For any other keys, if the key has a Unicode value, */
+ /* we add it to our string: */
+ default:
+ {
+ if ((event.key.keysym.unicode > 0)
+ && (wcslen(wchar_buf) < HIGH_SCORE_NAME_LENGTH))
+ {
+ wchar_buf[(int)wcslen(wchar_buf)] = event.key.keysym.unicode;
+ redraw = 1;
+ }
+ }
+ } /* end 'switch (event.key.keysym.sym)' */
+
+ DEBUGMSG(debug_highscore, "After keypress, string is %S\tlength = %d\n",
+ wchar_buf, (int)wcslen(wchar_buf));
+ /* Now draw name, if needed: */
+ if (redraw)
+ {
+ SDL_Surface* s = NULL;
+ redraw = 0;
+
+ /* Convert text to UTF-8 so BlackOutline() can handle it: */
+ // wcstombs((char*) UTF8_buf, wchar_buf, HIGH_SCORE_NAME_LENGTH * 3);
+ ConvertToUTF8(wchar_buf, UTF8_buf, HIGH_SCORE_NAME_LENGTH * 3);
+ /* Redraw background and shading in area where we drew text last time: */
+ if (!first_draw)
+ {
+ SDL_BlitSurface(current_bkg(), &redraw_rect, screen, &redraw_rect);
+ DrawButton(&redraw_rect, 0, REG_RGBA);
+ SDL_UpdateRect(screen,
+ redraw_rect.x,
+ redraw_rect.y,
+ redraw_rect.w,
+ redraw_rect.h);
+ }
+
+ s = BlackOutline(UTF8_buf, NAME_FONT_SIZE, &yellow);
+ if (s)
+ {
+ /* set up loc and blit: */
+ loc.x = (screen->w/2) - (s->w/2);
+ loc.y = 200;
+ SDL_BlitSurface(s, NULL, screen, &loc);
+
+ /* Remember where we drew so we can update background next time through: */
+ /* (for some reason we need to update a wider area to get clean image) */
+ redraw_rect.x = loc.x - 20;
+ redraw_rect.y = loc.y - 10;
+ redraw_rect.h = s->h + 20;
+ redraw_rect.w = s->w + 40;
+ first_draw = 0;
+
+ SDL_UpdateRect(screen,
+ redraw_rect.x,
+ redraw_rect.y,
+ redraw_rect.w,
+ redraw_rect.h);
+ SDL_FreeSurface(s);
+ s = NULL;
+ }
+ }
+ }
+ }
+ }
+
+ HandleTitleScreenAnimations();
+
+ /* Wait so we keep frame rate constant: */
+ while ((SDL_GetTicks() - start) < 33)
+ {
+ SDL_Delay(20);
+ }
+ frame++;
+ } // End of while (!finished) loop
+
+ /* Turn off SDL Unicode lookup (because has some overhead): */
+ SDL_EnableUNICODE(SDL_DISABLE);
+
+ /* Now copy name into location pointed to by arg: */
+ strncpy((char*)pl_name, (char*)UTF8_buf, HIGH_SCORE_NAME_LENGTH * 3);
+}
+
+
+
+
+/* Zero-out the array before use: */
+void initialize_scores(void)
+{
+ int i, j;
+ for (i = 0; i < NUM_HIGH_SCORE_LEVELS; i++)
+ {
+ for (j = 0; j < HIGH_SCORES_SAVED; j++)
+ {
+ high_scores[i][j].score = 0;
+ strcpy(high_scores[i][j].name, "");
+ }
+ }
+}
+
+/* Test to see where a new score ranks on the list. */
+/* The return value is the index value - add one to get */
+/* the common-language place on the list. */
+int check_score_place(int diff_level, int new_score)
+{
+ int i = 0;
+
+ /* Make sure diff_level is valid: */
+ if (diff_level < 0
+ || diff_level >= NUM_HIGH_SCORE_LEVELS)
+ {
+ fprintf(stderr, "In insert_score(), diff_level invalid!\n");
+ return 0;
+ }
+
+ /* Find correct place in list: */
+ for (i = 0; i < HIGH_SCORES_SAVED; i++)
+ {
+ if (new_score > high_scores[diff_level][i].score)
+ break;
+ }
+
+ return i; /* So if we return HIGH_SCORES_SAVED, the score did not */
+ /* make the list. */
+}
+
+/* Put a new high score entry into the table for the corresponding */
+/* difficulty level - returns 1 if successful. */
+int insert_score(char* playername, int diff_level, int new_score)
+{
+ int i = 0;
+ int insert_place;
+
+ insert_place = check_score_place(diff_level, new_score);
+
+ if (HIGH_SCORES_SAVED == insert_place) /* Score didn't make the top 10 */
+ {
+ return 0;
+ }
+
+ /* Move lower entries down: */
+ for (i = HIGH_SCORES_SAVED - 1; i > insert_place; i--)
+ {
+ high_scores[diff_level][i].score =
+ high_scores[diff_level][i - 1].score;
+ strncpy(high_scores[diff_level][i].name,
+ high_scores[diff_level][i - 1].name,
+ HIGH_SCORE_NAME_LENGTH);
+ }
+
+ /* Now put in new entry: */
+ high_scores[diff_level][insert_place].score = new_score;
+ strncpy(high_scores[diff_level][insert_place].name,
+ playername,
+ HIGH_SCORE_NAME_LENGTH);
+ return 1;
+}
+
+
+void print_high_scores(FILE* fp)
+{
+ int i, j;
+
+ fprintf(fp, "\nHigh Scores:\n");
+
+ for (i = 0; i < NUM_HIGH_SCORE_LEVELS; i++)
+ {
+ switch(i)
+ {
+ case CADET_HIGH_SCORE:
+ {
+ fprintf(fp, "\nSpace Cadet:\n");
+ break;
+ }
+ case SCOUT_HIGH_SCORE:
+ {
+ fprintf(fp, "\nScout:\n");
+ break;
+ }
+ case RANGER_HIGH_SCORE:
+ {
+ fprintf(fp, "\nRanger:\n");
+ break;
+ }
+ case ACE_HIGH_SCORE:
+ {
+ fprintf(fp, "\nAce:\n");
+ break;
+ }
+ case COMMANDO_HIGH_SCORE:
+ {
+ fprintf(fp, "\nCommando:\n");
+ break;
+ }
+ case FACTORS_HIGH_SCORE:
+ {
+ fprintf(fp, "\nFactors:\n");
+ break;
+ }
+ case FRACTIONS_HIGH_SCORE:
+ {
+ fprintf(fp, "\nFractions:\n");
+ break;
+ }
+ }
+
+ for (j = 0; j < HIGH_SCORES_SAVED; j++)
+ {
+ fprintf(fp, "%d.\t%s\t%d\n",
+ j + 1, //Convert to common-language ordinals
+ high_scores[i][j].name,
+ high_scores[i][j].score);
+ }
+ }
+}
+
+
+int read_high_scores_fp(FILE* fp)
+{
+ char buf[PATH_MAX];
+ char* token;
+ const char delimiters[] = "\t";
+
+ char* name_read;
+ int score_read;
+ int diff_level;
+
+ DEBUGMSG(debug_highscore, "Entering read_high_scores_fp()\n");
+
+ /* get out if file pointer invalid: */
+ if(!fp)
+ {
+ fprintf(stderr, "In read_high_scores_fp(), file pointer invalid!\n");
+ return 0;
+ }
+
+ /* make sure we start at beginning: */
+ rewind(fp);
+
+ /* read in a line at a time: */
+ while (fgets (buf, PATH_MAX, fp))
+ {
+ /* Ignore comment lines: */
+ if ((buf[0] == ';') || (buf[0] == '#'))
+ {
+ continue;
+ }
+ /* Split up line with strtok()to get needed values, */
+ /* then call insert_score() for each line. */
+ token = strtok(buf, delimiters);
+ if (!token)
+ continue;
+ diff_level = atoi(token);
+ if (diff_level >= NUM_HIGH_SCORE_LEVELS)
+ continue;
+
+ token = strtok(NULL, delimiters);
+ if (!token)
+ continue;
+ score_read = atoi(token);
+ /* Note that name can contain spaces - \t is only delimiter: */
+ name_read = strtok(NULL, delimiters);
+ /* Now insert entry: */
+ insert_score(name_read, diff_level, score_read);
+ }
+ return 1;
+}
+
+
+/* Return the score associated with a table entry: */
+/* Note: the place is given as the array index, i.e. */
+/* 0 for the top of the list. */
+int HS_Score(int diff_level, int place)
+{
+ /* Make sure diff_level is valid: */
+ if (diff_level < 0
+ || diff_level >= NUM_HIGH_SCORE_LEVELS)
+ {
+ fprintf(stderr, "In HS_Score(), diff_level = %d, invalid!\n", diff_level);
+ return -1;
+ }
+
+ /* Make sure place is valid: */
+ if (place < 0
+ || place >= HIGH_SCORES_SAVED)
+ {
+ fprintf(stderr, "In HS_Score(), place invalid!\n");
+ return -1;
+ }
+
+ return high_scores[diff_level][place].score;
+}
+
+
+/* Return (pointer to) the name associated with a table entry: */
+char* HS_Name(int diff_level, int place)
+{
+ /* Make sure diff_level is valid: */
+ if (diff_level < 0
+ || diff_level >= NUM_HIGH_SCORE_LEVELS)
+ {
+ fprintf(stderr, "In HS_Score(), diff_level invalid!\n");
+ return NULL;
+ }
+
+ /* Make sure place is valid: */
+ if (place < 0
+ || place >= HIGH_SCORES_SAVED)
+ {
+ fprintf(stderr, "In HS_Score(), place invalid!\n");
+ return NULL;
+ }
+
+ return high_scores[diff_level][place].name;
+}
+>>>>>>> .merge-right.r1476
Modified: tuxmath/branches/lan/src/lessons.c
===================================================================
--- tuxmath/branches/lan/src/lessons.c 2009-09-02 10:50:25 UTC (rev 1476)
+++ tuxmath/branches/lan/src/lessons.c 2009-09-03 22:06:06 UTC (rev 1477)
@@ -35,9 +35,7 @@
const char delimiters[] = "\t\n\r"; /* this will keep newline chars out of string */
int i;
-#ifdef TUXMATH_DEBUG
- printf("\nEntering read_goldstars_fp()\n");
-#endif
+ DEBUGMSG(debug_lessons, "Entering read_goldstars_fp()\n");
/* get out if file pointer invalid: */
if(!fp)
@@ -96,9 +94,7 @@
{
int i = 0;
-#ifdef TUXMATH_DEBUG
- fprintf(stderr, "\nEntering write_goldstars_fp()\n");
-#endif
+ DEBUGMSG(debug_lessons, "Entering write_goldstars_fp()\n");
/* get out if file pointer invalid: */
if(!fp)
@@ -112,11 +108,9 @@
for (i = 0; i < num_lessons; i++)
{
-#ifdef TUXMATH_DEBUG
- printf("i = %d\nfilename = %s\ngoldstar = %d\n",
- i, lesson_list_filenames[i],
- lesson_list_goldstars[i]);
-#endif
+ DEBUGMSG(debug_lessons, "i = %d\nfilename = %s\ngoldstar = %d\n",
+ i, lesson_list_filenames[i],
+ lesson_list_goldstars[i]);
if(lesson_list_goldstars[i] == 1)
{
Modified: tuxmath/branches/lan/src/loaders.c
===================================================================
--- tuxmath/branches/lan/src/loaders.c 2009-09-02 10:50:25 UTC (rev 1476)
+++ tuxmath/branches/lan/src/loaders.c 2009-09-03 22:06:06 UTC (rev 1477)
@@ -1,71 +1,81 @@
-/***************************************************************************
- - file: loaders.c
- - description: Functions to load multimedia for Tux Typing
- -------------------
- begin : Thu May 4 2000
- copyright : (C) 2000 by Sam Hart
- : (C) 2003 by Jesse Andrews
- email : tuxtype-dev at tux4kids.net
+/*
+ loaders.c
- Modified for use in tuxmath by David Bruce - 2006.
- email : <dbruce at tampabay.rr.com>
- <tuxmath-devel at lists.sourceforge.net>
- ***************************************************************************/
+ Functions responsible for loading multimedia.
-/***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
+ begin : Thu May 4 2000
+ copyright : (C) 2000 by Sam Hart
+ : (C) 2003 by Jesse Andrews
+ email : tuxtype-dev at tux4kids.net
-//#include "globals.h"
-//#include "funcs.h"
+ Modified for use in tuxmath by David Bruce - 2006.
+ email : <dbruce at tampabay.rr.com>
+ <tuxmath-devel at lists.sourceforge.net>
-#include "tuxmath.h" // for TUXMATH_DEBUG
+ Modified to support SVG by Boleslaw Kulbabinski - 2009
+ email : <bkulbabinski at gmail.com>
+
+ Part of "Tux4Kids" Project
+ http://www.tux4kids.com/
+
+ Copyright: See COPYING file that comes with this distribution.
+*/
+
#include "loaders.h"
-#include "setup.h" // for cleanup_on_error()
+#include "globals.h"
+#include "tuxmath.h"
+#include "setup.h" // for cleanup_on_error()
#include "SDL_extras.h"
-/* FIXME Doesn't seem to work consistently on all versions of Windows */
+#ifdef HAVE_RSVG
+#include<librsvg/rsvg.h>
+#include<librsvg/rsvg-cairo.h>
+#endif
+
+/* local functions */
+int check_file(const char* file);
+
+#ifdef HAVE_RSVG
+SDL_Surface* load_svg(const char* file_name, int width, int height, const char* layer_name);
+sprite* load_svg_sprite(const char* file_name, int width, int height);
+SDL_Surface* render_svg_from_handle(RsvgHandle* file_handle, int width, int height, const char* layer_name);
+void get_svg_dimensions(const char* file_name, int* width, int* height);
+#endif
+
+SDL_Surface* load_image(const char* file_name, int mode, int w, int h, bool proportional);
+void fit_in_rectangle(int* width, int* height, int max_width, int max_height);
+SDL_Surface* set_format(SDL_Surface* img, int mode);
+sprite* load_sprite(const char* name, int mode, int w, int h, bool proportional);
+
+
+
/* check to see if file exists, if so return true */
// int checkFile( const char *file ) {
// static struct stat fileStats;
-//
// fileStats.st_mode = 0;
-//
// stat( file, &fileStats );
-//
// return (S_IFREG & fileStats.st_mode);
// }
/* Returns 1 if valid file, 2 if valid dir, 0 if neither: */
-int checkFile(const char* file)
+int check_file(const char* file)
{
FILE* fp = NULL;
DIR* dp = NULL;
if (!file)
{
- fprintf(stderr, "CheckFile(): invalid char* argument!");
+ DEBUGMSG(debug_loaders, "check_file(): invalid char* argument!\n");
return 0;
}
-#ifdef TUXMATH_DEBUG
- fprintf(stderr, "CheckFile() - checking: %s\n", file);
-#endif
+ DEBUGMSG(debug_loaders, "check_file(): checking: %s\n", file);
dp = opendir(file);
if (dp)
{
-
-#ifdef TUXMATH_DEBUG
- fprintf(stderr, "Opened successfully as DIR\n");
-#endif
-
+ DEBUGMSG(debug_loaders, "check_file(): Opened successfully as DIR\n");
closedir(dp);
return 2;
}
@@ -73,68 +83,102 @@
fp = fopen(file, "r");
if (fp)
{
-
-#ifdef TUXMATH_DEBUG
- fprintf(stderr, "Opened successfully as FILE\n");
-#endif
-
+ DEBUGMSG(debug_loaders, "check_file(): Opened successfully as FILE\n");
fclose(fp);
return 1;
}
- fprintf(stderr, "Unable to open '%s' as either FILE or DIR\n", file);
+ DEBUGMSG(debug_loaders, "check_file(): Unable to open '%s' as either FILE or DIR\n", file);
return 0;
}
-int max( int n1, int n2 ) {
- return (n1 > n2 ? n1 : n2);
-}
-
#ifdef HAVE_RSVG
-/***********************
- SVG related functions
-************************/
-#include<librsvg/rsvg.h>
-#include<librsvg/rsvg-cairo.h>
-/* Load an SVG file and resize it to given dimensions.
- if width or height is set to 0 no resizing is applied
+/* Load a layer of SVG file and resize it to given dimensions.
+ If width or height is negative no resizing is applied.
+ If layer = NULL then the whole image is loaded.
+ layer_name must be preceded with a '#' symbol.
+ Return NULL on failure.
(partly based on TuxPaint's SVG loading function) */
-SDL_Surface* LoadSVGOfDimensions(char* filename, int width, int height)
+SDL_Surface* load_svg(const char* file_name, int width, int height, const char* layer_name)
{
- cairo_surface_t* temp_surf;
- cairo_t* context;
+ SDL_Surface* dest;
RsvgHandle* file_handle;
- RsvgDimensionData dimensions;
- SDL_Surface* dest;
- float scale_x;
- float scale_y;
- int bpp = 32;
- Uint32 Rmask, Gmask, Bmask, Amask;
-#ifdef TUXMATH_DEBUG
- fprintf(stderr, "LoadSVGOfDimensions(): looking for %s\n", filename);
-#endif
+ DEBUGMSG(debug_loaders, "load_svg(): loading %s\n", file_name);
rsvg_init();
- file_handle = rsvg_handle_new_from_file(filename, NULL);
- if(file_handle == NULL)
+ file_handle = rsvg_handle_new_from_file(file_name, NULL);
+ if(NULL == file_handle)
{
-#ifdef TUXMATH_DEBUG
- fprintf(stderr, "LoadSVGOfDimensions(): file %s not found\n", filename);
-#endif
+ DEBUGMSG(debug_loaders, "load_svg(): file %s not found\n", file_name);
rsvg_term();
return NULL;
}
+ dest = render_svg_from_handle(file_handle, width, height, layer_name);
+
+ g_object_unref(file_handle);
+ rsvg_term();
+
+ return dest;
+}
+
+sprite* load_svg_sprite(const char* file_name, int width, int height)
+{
+ RsvgHandle* file_handle;
+ sprite* new_sprite;
+ char lay_name[20];
+ int i;
+
+ DEBUGMSG(debug_loaders, "load_svg_sprite(): loading sprite from %s\n", file_name);
+
+ rsvg_init();
+
+ file_handle = rsvg_handle_new_from_file(file_name, NULL);
+ if(NULL == file_handle)
+ {
+ DEBUGMSG(debug_loaders, "load_svg_sprite(): file %s not found\n", file_name);
+ rsvg_term();
+ return NULL;
+ }
+
+ new_sprite = malloc(sizeof(sprite));
+ new_sprite->default_img = render_svg_from_handle(file_handle, width, height, "#default");
+
+ /* get number of frames from description */
+ sscanf(rsvg_handle_get_desc(file_handle), "%d", &new_sprite->num_frames);
+ DEBUGMSG(debug_loaders, "load_svg_sprite(): loading %d frames\n", new_sprite->num_frames);
+
+ for(i = 0; i < new_sprite->num_frames; i++)
+ {
+ sprintf(lay_name, "#frame%d", i);
+ new_sprite->frame[i] = render_svg_from_handle(file_handle, width, height, lay_name);
+ }
+
+ g_object_unref(file_handle);
+ rsvg_term();
+
+ return new_sprite;
+}
+
+/* render a layer of SVG file and resize it to given dimensions.
+ If width or height is negative no resizing is applied. */
+SDL_Surface* render_svg_from_handle(RsvgHandle* file_handle, int width, int height, const char* layer_name)
+{
+ RsvgDimensionData dimensions;
+ cairo_surface_t* temp_surf;
+ cairo_t* context;
+ SDL_Surface* dest;
+ float scale_x, scale_y;
+ Uint32 Rmask, Gmask, Bmask, Amask;
+
rsvg_handle_get_dimensions(file_handle, &dimensions);
-#ifdef TUXMATH_DEBUG
- fprintf(stderr, "SVG is %d x %d\n", dimensions.width, dimensions.height);
-#endif
- if(width <= 0 || height <= 0)
+ /* set scale_x and scale_y */
+ if(width < 0 || height < 0)
{
width = dimensions.width;
height = dimensions.height;
@@ -147,17 +191,21 @@
scale_y = (float)height / dimensions.height;
}
- /* FIXME: We assume that our bpp = 32 */
+ /* set color masks */
+ Rmask = screen->format->Rmask;
+ Gmask = screen->format->Gmask;
+ Bmask = screen->format->Bmask;
+ if(screen->format->Amask == 0)
+ /* find a free byte to use for Amask */
+ Amask = ~(Rmask | Gmask | Bmask);
+ else
+ Amask = screen->format->Amask;
- /* rmask, gmask, bmask, amask defined in SDL_extras.h do not work !
- are those (taken from TuxPaint) dependent on endianness ? */
- Rmask = 0x00ff0000;
- Gmask = 0x0000ff00;
- Bmask = 0x000000ff;
- Amask = 0xff000000;
+ DEBUGMSG(debug_loaders, "render_svg_from_handle(): color masks: R=%u, G=%u, B=%u, A=%u\n",
+ Rmask, Gmask, Bmask, Amask);
dest = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCALPHA,
- width, height, bpp, Rmask, Gmask, Bmask, Amask);
+ width, height, screen->format->BitsPerPixel, Rmask, Gmask, Bmask, Amask);
SDL_LockSurface(dest);
temp_surf = cairo_image_surface_create_for_data(dest->pixels,
@@ -166,288 +214,382 @@
context = cairo_create(temp_surf);
if(cairo_status(context) != CAIRO_STATUS_SUCCESS)
{
-#ifdef TUXMATH_DEBUG
- fprintf(stderr, "LoadSVGOfDimensions(): error rendering SVG from %s\n", filename);
-#endif
- g_object_unref(file_handle);
+ DEBUGMSG(debug_loaders, "render_svg_from_handle(): error rendering SVG\n");
cairo_surface_destroy(temp_surf);
- rsvg_term();
return NULL;
}
cairo_scale(context, scale_x, scale_y);
- rsvg_handle_render_cairo(file_handle, context);
+ /* render appropriate layer */
+ rsvg_handle_render_cairo_sub(file_handle, context, layer_name);
+
SDL_UnlockSurface(dest);
-
- g_object_unref(file_handle);
cairo_surface_destroy(temp_surf);
cairo_destroy(context);
- rsvg_term();
return dest;
}
-#endif
-
-/***********************
- LoadImageFromFile : Simply load an image from given file
- or its SVG equivalent (if present). Return NULL if loading failed.
-************************/
-SDL_Surface* LoadImageFromFile(char *datafile)
+void get_svg_dimensions(const char* file_name, int* width, int* height)
{
- SDL_Surface* tmp_pic = NULL;
+ RsvgHandle* file_handle;
+ RsvgDimensionData dimensions;
-#ifdef HAVE_RSVG
- char svgfn[PATH_MAX];
-#endif
+ rsvg_init();
-#ifdef TUXMATH_DEBUG
- fprintf(stderr, "LoadImageFromFile(): looking in %s\n", datafile);
-#endif
+ file_handle = rsvg_handle_new_from_file(file_name, NULL);
+ if(file_handle == NULL)
+ {
+ DEBUGMSG(debug_loaders, "get_svg_dimensions(): file %s not found\n", file_name);
+ rsvg_term();
+ return;
+ }
-#ifdef HAVE_RSVG
- /* This is just an ugly workaround to test SVG
- before any scaling routines are implemented */
+ rsvg_handle_get_dimensions(file_handle, &dimensions);
- /* change extension into .svg */
- char* dotpos = strrchr(datafile, '.');
- strncpy(svgfn, datafile, dotpos - datafile);
- svgfn[dotpos - datafile] = '\0';
- strcat(svgfn, ".svg");
+ *width = dimensions.width;
+ *height = dimensions.height;
- /* try to load an SVG equivalent */
- tmp_pic = LoadSVGOfDimensions(svgfn, 0, 0);
-#endif
+ g_object_unref(file_handle);
+ rsvg_term();
+}
- if(tmp_pic == NULL)
- /* Try to load image with SDL_image: */
- tmp_pic = IMG_Load(datafile);
+#endif /* HAVE_RSVG */
- return tmp_pic;
+/* Load an image without resizing it */
+SDL_Surface* LoadImage(const char* file_name, int mode)
+{
+ return LoadScaledImage(file_name, mode, -1, -1);
}
-/* FIXME checkFile() not working right in Win32 - skipping. */
-/***********************
- LoadImage : Load an image and set transparent if requested
-************************/
-SDL_Surface* LoadImage( char *datafile, int mode )
+/* LoadScaledImage : Load an image and resize it to given dimensions.
+ If width or height is negative no resizing is applied.
+ The loader (load_svg() or IMG_Load()) is chosen depending on file extension,
+ If an SVG file is not found try to load its PNG equivalent
+ (unless IMG_NO_PNG_FALLBACK is set) */
+SDL_Surface* LoadScaledImage(const char* file_name, int mode, int width, int height)
{
- SDL_Surface* tmp_pic = NULL;
+ return load_image(file_name, mode, width, height, false);
+}
+
+/* LoadImageOfBoundingBox : Same as LoadScaledImage but preserve image proportions
+ and fit it into max_width x max_height rectangle.
+ Returned surface is not necessarily max_width x max_height ! */
+SDL_Surface* LoadImageOfBoundingBox(const char* file_name, int mode, int max_width, int max_height)
+{
+ return load_image(file_name, mode, max_width, max_height, true);
+}
+
+
+/* load_image : helper function used by LoadScaledImage and LoadImageOfBoundingBox */
+SDL_Surface* load_image(const char* file_name, int mode, int w, int h, bool proportional)
+{
+ SDL_Surface* loaded_pic = NULL;
SDL_Surface* final_pic = NULL;
-
char fn[PATH_MAX];
+ int fn_len;
+ int width = -1, height = -1;
+ bool is_svg = true;
- sprintf( fn, "%s/images/%s", DATA_PREFIX, datafile );
+ if(NULL == file_name)
+ {
+ DEBUGMSG(debug_loaders, "load_image(): file_name is NULL, exiting.\n");
+ return NULL;
+ }
+ /* run loader depending on file extension */
- tmp_pic = LoadImageFromFile(fn);
+ /* add path prefix */
+ snprintf(fn, PATH_MAX, "%s/images/%s", DATA_PREFIX, file_name);
+ fn_len = strlen(fn);
- if (NULL == tmp_pic) /* Could not load image: */
+ if(strcmp(fn + fn_len - 4, ".svg"))
{
+ DEBUGMSG(debug_loaders, "load_image(): %s is not an SVG, loading using IMG_Load()\n", fn);
+ loaded_pic = IMG_Load(fn);
+ is_svg = false;
+ if (NULL == loaded_pic)
+ {
+ is_svg = true;
+ DEBUGMSG(debug_loaders, "load_image(): Trying to load SVG equivalent of %s\n", fn);
+ sprintf(strrchr(fn, '.'), ".svg");
+ }
+ }
+ if (is_svg)
+ {
+#ifdef HAVE_RSVG
+ DEBUGMSG(debug_loaders, "load_image(): trying to load %s as SVG.\n", fn);
+ if(proportional)
+ {
+ get_svg_dimensions(fn, &width, &height);
+ if(width > 0 && height > 0)
+ fit_in_rectangle(&width, &height, w, h);
+ }
+ else
+ {
+ width = w;
+ height = h;
+ }
+ loaded_pic = load_svg(fn, width, height, NULL);
+#endif
+
+ if(loaded_pic == NULL)
+ {
+#ifdef HAVE_RSVG
+ DEBUGMSG(debug_loaders, "load_image(): failed to load %s as SVG.\n", fn);
+#else
+ DEBUGMSG(debug_loaders, "load_image(): SVG support not available.\n");
+#endif
+ if(mode & IMG_NO_PNG_FALLBACK)
+ {
+ DEBUGMSG(debug_loaders, "load_image(): %s : IMG_NO_PNG_FALLBACK is set.\n", fn);
+ }
+ else
+ {
+ DEBUGMSG(debug_loaders, "load_image(): Trying to load PNG equivalent of %s\n", fn);
+ strcpy(fn + fn_len - 3, "png");
+
+ loaded_pic = IMG_Load(fn);
+ is_svg = false;
+ }
+ }
+ }
+
+ if (NULL == loaded_pic) /* Could not load image: */
+ {
if (mode & IMG_NOT_REQUIRED)
- {
-#ifdef TUXMATH_DEBUG
- fprintf(stderr, "Warning: could not load optional graphics file %s\n", datafile);
-#endif
+ {
+ DEBUGMSG(debug_loaders, "load_image(): Warning: could not load optional graphics file %s\n", file_name);
return NULL; /* Allow program to continue */
}
/* If image was required, exit from program: */
- fprintf(stderr, "ERROR could not load required graphics file %s\n", datafile);
+ fprintf(stderr, "load_image(): ERROR could not load required graphics file %s\n", file_name);
fprintf(stderr, "%s", SDL_GetError() );
cleanup_on_error();
}
+ else if(!is_svg && w > 0 && h > 0)
+ {
+ if(proportional)
+ {
+ width = loaded_pic->w;
+ height = loaded_pic->h;
+ fit_in_rectangle(&width, &height, w, h);
+ }
+ else
+ {
+ width = w;
+ height = h;
+ }
+ final_pic = zoom(loaded_pic, width, height);
+ SDL_FreeSurface(loaded_pic);
+ loaded_pic = final_pic;
+ final_pic = NULL;
+ }
- /* "else" - now setup the image to the proper format */
+ final_pic = set_format(loaded_pic, mode);
+ SDL_FreeSurface(loaded_pic);
+ DEBUGMSG(debug_loaders, "Leaving load_image()\n\n");
+
+ return final_pic;
+}
+
+/* adjust width and height to fit in max_width x max_height rectangle
+ but preserve their proportion */
+void fit_in_rectangle(int* width, int* height, int max_width, int max_height)
+{
+ float scale_w, scale_h;
+
+ if(width != 0 && height != 0)
+ {
+ scale_w = (float) max_width / (*width);
+ scale_h = (float) max_height / (*height);
+ *width *= min(scale_w, scale_h);
+ *height *= min(scale_w, scale_h);
+ }
+}
+
+SDL_Surface* set_format(SDL_Surface* img, int mode)
+{
switch (mode & IMG_MODES)
{
case IMG_REGULAR:
- {
-
- final_pic = SDL_DisplayFormat(tmp_pic);
- SDL_FreeSurface(tmp_pic);
- break;
+ {
+ DEBUGMSG(debug_loaders, "set_format(): handling IMG_REGULAR mode.\n");
+ return SDL_DisplayFormat(img);
}
case IMG_ALPHA:
{
-
- final_pic = SDL_DisplayFormatAlpha(tmp_pic);
- SDL_FreeSurface(tmp_pic);
- break;
+ DEBUGMSG(debug_loaders, "set_format(): handling IMG_ALPHA mode.\n");
+ return SDL_DisplayFormatAlpha(img);
}
case IMG_COLORKEY:
{
-
- SDL_LockSurface(tmp_pic);
- SDL_SetColorKey(tmp_pic, (SDL_SRCCOLORKEY | SDL_RLEACCEL),
- SDL_MapRGB(tmp_pic->format, 255, 255, 0));
- final_pic = SDL_DisplayFormat(tmp_pic);
- SDL_FreeSurface(tmp_pic);
- break;
+ DEBUGMSG(debug_loaders, "set_format(): handling IMG_COLORKEY mode.\n");
+ SDL_LockSurface(img);
+ SDL_SetColorKey(img, (SDL_SRCCOLORKEY | SDL_RLEACCEL),
+ SDL_MapRGB(img->format, 255, 255, 0));
+ return SDL_DisplayFormat(img);
}
default:
{
-#ifdef TUXMATH_DEBUG
- fprintf(stderr, "Image mode not recognized\n");
-#endif
- SDL_FreeSurface(tmp_pic);
+ DEBUGMSG(debug_loaders, "set_format(): Image mode not recognized\n");
}
}
-#ifdef TUXMATH_DEBUG
- fprintf(stderr, "Leaving LoadImage()\n\n");
-#endif
- return final_pic;
+
+ return NULL;
}
-/***********************
- LoadBkgd() : a wrapper for LoadImage() that scales the
- image to the size of the screen using zoom(), taken
- from TuxPaint
-************************/
-SDL_Surface* LoadBkgd(char* datafile)
+
+/* LoadBkgd() : a wrapper for LoadImage() that optimizes
+ the format of background image */
+SDL_Surface* LoadBkgd(const char* file_name, int width, int height)
{
- SDL_Surface* orig;
- orig = IMG_Load(datafile);
+ SDL_Surface* orig = NULL;
+ SDL_Surface* final_pic = NULL;
+ orig = LoadScaledImage(file_name, IMG_REGULAR, width, height);
+
if (!orig)
{
- tmdprintf("In LoadBkgd(), LoadImage() returned NULL on %s\n",
- datafile);
+ DEBUGMSG(debug_loaders, "In LoadBkgd(), LoadImage() returned NULL on %s\n",
+ file_name);
return NULL;
}
- if ((orig->w == screen->w)
- && (orig->h == screen->h))
- {
- tmdprintf("No zoom required - return bkgd as is\n");
- return orig;
- }
- else
- {
- tmdprintf("Image is %dx%d\n", orig->w, orig->h);
- tmdprintf("Screen is %dx%d\n", screen->w, screen->h);
- tmdprintf("Calling zoom() to rescale\n");
- return zoom(orig, screen->w, screen->h);
- }
+ /* turn off transparency, since it's the background */
+ SDL_SetAlpha(orig, SDL_RLEACCEL, SDL_ALPHA_OPAQUE);
+ final_pic = SDL_DisplayFormat(orig); /* optimize the format */
+ SDL_FreeSurface(orig);
+
+ return final_pic;
}
-/**********************
-LoadBothBkgds() : loads two scaled images: one for the user's native
-resolution and one for 640x480 fullscreen.
-Returns: the number of images that were scaled
-Now we also optimize the format for best performance
-**********************/
-int LoadBothBkgds(char* datafile, SDL_Surface** fs_bkgd, SDL_Surface** win_bkgd)
+/* LoadBothBkgds() : loads two scaled images: one for the fullscreen mode
+ (fs_res_x,fs_rex_y) and one for the windowed mode (win_res_x,win_rex_y)
+ Now we also optimize the format for best performance */
+void LoadBothBkgds(const char* file_name, SDL_Surface** fs_bkgd, SDL_Surface** win_bkgd)
{
- int ret = 0;
- SDL_Surface* orig = NULL;
- SDL_Surface* tmp = NULL;
+ DEBUGMSG(debug_loaders, "Entering LoadBothBkgds()\n");
+ *fs_bkgd = LoadBkgd(file_name, fs_res_x, fs_res_y);
+ *win_bkgd = LoadBkgd(file_name, win_res_x, win_res_y);
+}
- tmdprintf("Entering LoadBothBkgds()\n");
- orig = LoadImage(datafile, IMG_REGULAR);
- tmdprintf("Scaling %dx%d to: %dx%d, %dx%d\n",
- orig->w, orig->h, RES_X, RES_Y, fs_res_x, fs_res_y);
- if (orig->w == RES_X && orig->h == RES_Y)
- {
- *win_bkgd = orig;
- }
- else
- {
- *win_bkgd = zoom(orig, RES_X, RES_Y);
- ++ret;
- }
-
- if (orig->w == fs_res_x && orig->h == fs_res_y)
- {
- *fs_bkgd = orig;
- }
- else
- {
- *fs_bkgd = zoom(orig, fs_res_x, fs_res_y);
- ++ret;
- }
-
- if (ret == 2) //orig won't be used at all
- SDL_FreeSurface(orig);
- // Optimize images before we leave:
- // turn off transparency, since it's the background:
- if (*fs_bkgd) //avoid segfault...
- {
- SDL_SetAlpha(*fs_bkgd, SDL_RLEACCEL,SDL_ALPHA_OPAQUE);
- tmp = SDL_DisplayFormat(*fs_bkgd); // optimize the format
- SDL_FreeSurface(*fs_bkgd);
- *fs_bkgd = tmp;
- }
- if (*win_bkgd)
- {
- SDL_SetAlpha(*win_bkgd, SDL_RLEACCEL,SDL_ALPHA_OPAQUE);
- tmp = SDL_DisplayFormat(*win_bkgd); // optimize the format
- SDL_FreeSurface(*win_bkgd);
- *win_bkgd = tmp;
- }
+sprite* LoadSprite(const char* name, int mode)
+{
+ return LoadScaledSprite(name, mode, -1, -1);
+}
- tmdprintf("%d images scaled\nLeaving LoadBothBkgds()\n", ret);
- return ret;
+sprite* LoadScaledSprite(const char* name, int mode, int width, int height)
+{
+ return load_sprite(name, mode, width, height, false);
}
+sprite* LoadSpriteOfBoundingBox(const char* name, int mode, int max_width, int max_height)
+{
+ return load_sprite(name, mode, max_width, max_height, true);
+}
-sprite* FlipSprite( sprite *in, int X, int Y ) {
- sprite *out;
+sprite* load_sprite(const char* name, int mode, int w, int h, bool proportional)
+{
+ sprite *new_sprite = NULL;
+ char fn[PATH_MAX];
+ int i, width, height;
- out = malloc(sizeof(sprite));
- if (in->default_img != NULL)
- out->default_img = Flip( in->default_img, X, Y );
- else
- out->default_img = NULL;
- for ( out->num_frames=0; out->num_frames<in->num_frames; out->num_frames++ )
- out->frame[out->num_frames] = Flip( in->frame[out->num_frames], X, Y );
- out->cur = 0;
- return out;
-}
+#ifdef HAVE_RSVG
+ /* check if SVG sprite file is present */
+ sprintf(fn, "%s/images/%s.svg", DATA_PREFIX, name);
+ if(1 == check_file(fn))
+ {
+ if(proportional)
+ {
+ get_svg_dimensions(fn, &width, &height);
+ if(width > 0 && height > 0)
+ fit_in_rectangle(&width, &height, w, h);
+ }
+ else
+ {
+ width = w;
+ height = h;
+ }
+ new_sprite = load_svg_sprite(fn, width, height);
-sprite* LoadSprite( char* name, int MODE ) {
- sprite *new_sprite;
- char fn[PATH_MAX];
- int x;
+ if(new_sprite)
+ {
+ set_format(new_sprite->default_img, mode);
+ for(i = 0; i < new_sprite->num_frames; i++)
+ set_format(new_sprite->frame[i], mode);
+ new_sprite->cur = 0;
+ }
+ }
+#endif
- /* JA --- HACK check out what has changed with new code */
+ if(!new_sprite)
+ {
+ /* SVG sprite was not loaded, try to load it frame by frame from PNG files */
+ new_sprite = malloc(sizeof(sprite));
- new_sprite = malloc(sizeof(sprite));
+ sprintf(fn, "%sd.png", name); // The 'd' means the default image
+ if(proportional)
+ new_sprite->default_img = LoadImageOfBoundingBox(fn, mode | IMG_NOT_REQUIRED, w, h);
+ else
+ new_sprite->default_img = LoadScaledImage(fn, mode | IMG_NOT_REQUIRED, w, h);
- sprintf(fn, "%sd.png", name); // The 'd' means the default image
- new_sprite->default_img = LoadImage( fn, MODE|IMG_NOT_REQUIRED );
- for (x = 0; x < MAX_SPRITE_FRAMES; x++) {
- sprintf(fn, "%s%d.png", name, x);
- new_sprite->frame[x] = LoadImage( fn, MODE|IMG_NOT_REQUIRED );
- if ( new_sprite->frame[x] == NULL ) {
- new_sprite->cur = 0;
- new_sprite->num_frames = x;
- break;
- }
+ if(!new_sprite->default_img)
+ DEBUGMSG(debug_loaders, "load_sprite(): failed to load default image for %s\n", name);
+
+ for(i = 0; i < MAX_SPRITE_FRAMES; i++)
+ {
+ sprintf(fn, "%s%d.png", name, i);
+ if(proportional)
+ new_sprite->frame[i] = LoadImageOfBoundingBox(fn, mode | IMG_NOT_REQUIRED, w, h);
+ else
+ new_sprite->frame[i] = LoadScaledImage(fn, mode | IMG_NOT_REQUIRED, w, h);
+
+ if(new_sprite->frame[i] == NULL)
+ {
+ new_sprite->cur = 0;
+ new_sprite->num_frames = i;
+ break;
+ }
+ else
+ DEBUGMSG(debug_loaders, "load_sprite(): loaded frame %d of %s\n", i, name);
+ }
}
-
-
return new_sprite;
}
+sprite* FlipSprite(sprite* in, int X, int Y)
+{
+ sprite *out;
+ out = malloc(sizeof(sprite));
+ if (in->default_img != NULL)
+ out->default_img = Flip( in->default_img, X, Y );
+ else
+ out->default_img = NULL;
+ for( out->num_frames=0; out->num_frames<in->num_frames; out->num_frames++ )
+ out->frame[out->num_frames] = Flip( in->frame[out->num_frames], X, Y );
+ out->cur = 0;
+ return out;
+}
-void FreeSprite(sprite* gfx )
+void FreeSprite(sprite* gfx)
{
int x;
if (!gfx)
return;
- tmdprintf("Freeing image at %p", gfx);
+ DEBUGMSG(debug_loaders, "Freeing image at %p", gfx);
for (x = 0; x < gfx->num_frames; x++)
{
- tmdprintf(".");
+ DEBUGMSG(debug_loaders, ".");
if (gfx->frame[x])
{
SDL_FreeSurface(gfx->frame[x]);
@@ -461,21 +603,21 @@
gfx->default_img = NULL;
}
- tmdprintf("FreeSprite() - done\n");
+ DEBUGMSG(debug_loaders, "FreeSprite() - done\n");
free(gfx);
}
-void next_frame(sprite* s)
+void NextFrame(sprite* s)
{
if (s && s->num_frames)
s->cur = (s->cur + 1) % s->num_frames;
}
-/***************************
- LoadSound : Load a sound/music patch from a file.
-****************************/
+
+
+/* LoadSound : Load a sound/music patch from a file. */
Mix_Chunk* LoadSound( char *datafile )
-{
+{
Mix_Chunk* tempChunk = NULL;
char fn[PATH_MAX];
@@ -489,17 +631,14 @@
return tempChunk;
}
-/************************
- LoadMusic : Load
- music from a datafile
-*************************/
-Mix_Music *LoadMusic(char *datafile )
-{
+/* LoadMusic : Load music from a datafile */
+Mix_Music* LoadMusic(char *datafile )
+{
char fn[PATH_MAX];
Mix_Music* tempMusic = NULL;
sprintf( fn , "%s/sounds/%s", DATA_PREFIX, datafile );
- if (1 != checkFile(fn))
+ if (1 != check_file(fn))
{
fprintf(stderr, "LoadMusic(): %s not found\n\n", fn);
return NULL;
@@ -514,3 +653,4 @@
}
return tempMusic;
}
+
Modified: tuxmath/branches/lan/src/loaders.h
===================================================================
--- tuxmath/branches/lan/src/loaders.h 2009-09-02 10:50:25 UTC (rev 1476)
+++ tuxmath/branches/lan/src/loaders.h 2009-09-03 22:06:06 UTC (rev 1477)
@@ -1,17 +1,21 @@
-//
-// C++ Interface: loaders
-//
-// Description:
-//
-//
-// Author: David Bruce <davidstuartbruce at gmail.com>, (C) 2009
-//
-// Copyright: See COPYING file that comes with this distribution
-//
-//
-#ifndef LOADERS_C
-#define LOADERS_C
+/*
+ loaders.h
+ Functions responsible for loading multimedia.
+ (interface)
+
+ Author: David Bruce <davidstuartbruce at gmail.com>, (C) 2009
+ Boleslaw Kulbabinski <bkulbabinski at gmail.com>, (C) 2009
+
+ Part of "Tux4Kids" Project
+ http://www.tux4kids.com/
+
+ Copyright: See COPYING file that comes with this distribution.
+*/
+
+#ifndef LOADERS_H
+#define LOADERS_H
+
#include "tuxmath.h"
#include <string.h>
@@ -22,35 +26,31 @@
#include <sys/stat.h>
#include <dirent.h>
-#define MAX_SPRITE_FRAMES 30
-#define IMG_REGULAR 0x01
-#define IMG_COLORKEY 0x02
-#define IMG_ALPHA 0x04
-#define IMG_MODES 0x07
-#define IMG_NOT_REQUIRED 0x10
-#define IMG_NO_THEME 0x20
+#define IMG_REGULAR 0x01
+#define IMG_COLORKEY 0x02
+#define IMG_ALPHA 0x04
+#define IMG_MODES 0x07
-typedef struct {
- SDL_Surface *frame[MAX_SPRITE_FRAMES];
- SDL_Surface *default_img;
- int num_frames;
- int cur;
-} sprite;
+#define IMG_NOT_REQUIRED 0x10
+#define IMG_NO_PNG_FALLBACK 0x20
-/* in loaders.c (from tuxtype): */
-int checkFile( const char *file );
-Mix_Chunk* LoadSound( char* datafile );
-SDL_Surface* LoadImage( char* datafile, int mode );
-SDL_Surface* LoadBkgd(char* datafile);
-int LoadBothBkgds(char* datafile,
- SDL_Surface** fs_bkgd,
- SDL_Surface** win_bkgd);
-sprite* LoadSprite( char* name, int MODE );
-sprite* FlipSprite( sprite* in, int X, int Y );
-void FreeSprite( sprite* gfx );
-Mix_Music* LoadMusic( char *datafile );
-void next_frame(sprite* s);
+SDL_Surface* LoadImage(const char* file_name, int mode);
+SDL_Surface* LoadScaledImage(const char* file_name, int mode, int width, int height);
+SDL_Surface* LoadImageOfBoundingBox(const char* file_name, int mode, int max_width, int max_height);
-#endif
+SDL_Surface* LoadBkgd(const char* file_name, int width, int height);
+void LoadBothBkgds(const char* file_name, SDL_Surface** fs_bkgd, SDL_Surface** win_bkgd);
+
+sprite* LoadSprite(const char* name, int mode);
+sprite* LoadScaledSprite(const char* name, int mode, int width, int height);
+sprite* LoadSpriteOfBoundingBox(const char* name, int mode, int max_width, int max_height);
+sprite* FlipSprite(sprite* in, int X, int Y);
+void FreeSprite(sprite* gfx);
+void NextFrame(sprite* s);
+
+Mix_Chunk* LoadSound(char* datafile);
+Mix_Music* LoadMusic(char *datafile);
+
+#endif /* LOADERS_H */
Modified: tuxmath/branches/lan/src/mathcards.c
===================================================================
--- tuxmath/branches/lan/src/mathcards.c 2009-09-02 10:50:25 UTC (rev 1476)
+++ tuxmath/branches/lan/src/mathcards.c 2009-09-03 22:06:06 UTC (rev 1477)
@@ -392,11 +392,11 @@
answered_wrong = 0;
questions_pending = 0;
- #ifdef MC_DEBUG
- print_counters();
- #endif
+ if (debug_status & debug_mathcards) {
+ print_counters();
+ }
- /* make sure list now exists and has non-zero length: */
+/* make sure list now exists and has non-zero length: */
if (question_list && quest_list_length)
{
mcdprintf("\nGame set up successfully");
@@ -454,11 +454,11 @@
answered_wrong = 0;
questions_pending = 0;
- #ifdef MC_DEBUG
- print_counters();
- print_list(stdout, question_list);
- printf("\nLeaving MC_StartGameUsingWrongs()\n");
- #endif
+ if (debug_status & debug_mathcards) {
+ print_counters();
+ print_list(stdout, question_list);
+ printf("\nLeaving MC_StartGameUsingWrongs()\n");
+ }
return 1;
}
@@ -515,12 +515,12 @@
questions_pending++;
active_quests = append_node(active_quests, ptr);
- #ifdef MC_DEBUG
- printf("\nnext question is:");
- print_card(*fc);
- print_counters();
- printf("\n\nLeaving MC_NextQuestion()\n");
- #endif
+ if (debug_status & debug_mathcards) {
+ printf("\nnext question is:");
+ print_card(*fc);
+ print_counters();
+ printf("\n\nLeaving MC_NextQuestion()\n");
+ }
return 1;
}
@@ -555,10 +555,10 @@
return 0;
}
-#ifdef MC_DEBUG
- printf("\nMatching question is:");
- print_card(quest->card);
-#endif
+ if (debug_status & debug_mathcards) {
+ printf("\nQuestion was:");
+ print_card(*fc);
+ }
//We found a matching question, now we take it out of the
//"active_quests" list and either put it back into the
@@ -588,11 +588,11 @@
unanswered--;
}
-#ifdef MC_DEBUG
- print_counters();
- printf("\nLeaving MC_AnsweredCorrectly()\n");
-#endif
-
+ if (debug_status & debug_mathcards) {
+ print_counters();
+ printf("\nLeaving MC_AnsweredCorrectly()\n");
+ }
+
return 1;
}
@@ -643,10 +643,10 @@
mcdprintf("\nAdding %d copies to question_list:", math_opts->iopts[COPIES_REPEATED_WRONGS]);
-#ifdef MC_DEBUG
- printf("\nCard to be added is:");
- print_card(quest->card);
-#endif
+ if (debug_status & debug_mathcards) {
+ print_counters();
+ printf("\nLeaving MC_AnsweredCorrectly()\n");
+ }
/* can put in more than one copy (to drive the point home!) */
for (i = 0; i < math_opts->iopts[COPIES_REPEATED_WRONGS]; i++)
@@ -685,10 +685,10 @@
free_node(quest);
}
-#ifdef MC_DEBUG
- print_counters();
- printf("\nLeaving MC_NotAnswered_Correctly()\n");
-#endif
+ if (debug_status & debug_mathcards) {
+ print_counters();
+ printf("\nLeaving MC_NotAnswered_Correctly()\n");
+ }
return 1;
}
@@ -752,9 +752,7 @@
newsize = 100;
newlist = realloc(time_per_question_list, newsize*sizeof(float));
if (newlist == NULL) {
- #ifdef MC_DEBUG
- printf("\nError: allocation for time_per_question_list failed\n");
- #endif
+ DEBUGMSG(debug_mathcards,"\nError: allocation for time_per_question_list failed\n");
return 0;
}
time_per_question_list = newlist;
@@ -1585,9 +1583,10 @@
+ MC_GetOpt(MIN_FORMULA_NUMS);
mcdprintf(" of length %d", length);
ret = generate_random_ooo_card_of_length(length, 1);
- #ifdef MC_DEBUG
- print_card(ret);
- #endif
+
+ if (debug_status & debug_mathcards) {
+ print_card(ret);
+ }
}
//TODO comparison problems (e.g. "6 ? 9", "<")
@@ -1804,9 +1803,8 @@
MC_MathQuestion* end_of_list = NULL;
MC_MathQuestion* tnode = NULL;
-#ifdef MC_DEBUG
- MC_PrintMathOptions(stdout, 0);
-#endif
+ if (debug_status & debug_mathcards)
+ MC_PrintMathOptions(stdout, 0);
if (!(MC_GetOpt(ARITHMETIC_ALLOWED) ||
MC_GetOpt(TYPING_PRACTICE_ALLOWED) ||
Modified: tuxmath/branches/lan/src/mathcards.h
===================================================================
--- tuxmath/branches/lan/src/mathcards.h 2009-09-02 10:50:25 UTC (rev 1476)
+++ tuxmath/branches/lan/src/mathcards.h 2009-09-03 22:06:06 UTC (rev 1477)
@@ -12,6 +12,8 @@
Copyright: See COPYING file that comes with this distribution (briefly, GNU GPL version 2 or later)
*/
+
+
#ifndef MATHCARDS_H
#define MATHCARDS_H
@@ -19,7 +21,7 @@
#define MC_DEBUG
#ifdef MC_DEBUG
-#define mcdprintf(...) printf(__VA_ARGS__)
+#define mcdprintf(...) DEBUGMSG(debug_mathcards,__VA_ARGS__)
#else
#define mcdprintf(...) 0
#endif
@@ -224,7 +226,7 @@
int MC_NextWrongQuest(MC_FlashCard* q);
/* Returns 1 if all have been answered correctly, */
-/* 0 otherwise. */
+/* 0 otherwise. */
int MC_MissionAccomplished(void);
/* Returns number of questions left (either in list */
@@ -281,4 +283,5 @@
/* Reorganize formula_string and answer_string to render the same equation
in a different format */
void reformat_arithmetic(MC_FlashCard* card, MC_Format f);
+
#endif
Added: tuxmath/branches/lan/src/menu.c
===================================================================
--- tuxmath/branches/lan/src/menu.c (rev 0)
+++ tuxmath/branches/lan/src/menu.c 2009-09-03 22:06:06 UTC (rev 1477)
@@ -0,0 +1,1491 @@
+/*
+ menu.c
+
+ Functions responsible for loading, parsing and displaying game menu.
+
+ Part of "Tux4Kids" Project
+ http://www.tux4kids.com/
+
+ Author: Boleslaw Kulbabinski <bkulbabinski at gmail.com>, (C) 2009
+
+ (Functions responsible for running specific activities
+ are moved from titlescreen.c)
+
+ Copyright: See COPYING file that comes with this distribution.
+*/
+
+#include "menu.h"
+#include "SDL_extras.h"
+#include "titlescreen.h"
+#include "highscore.h"
+#include "factoroids.h"
+#include "credits.h"
+#include "multiplayer.h"
+#include "mathcards.h"
+#include "campaign.h"
+#include "game.h"
+#include "options.h"
+#include "fileops.h"
+#include "setup.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+
+/* create string array of activities' names */
+#define X(name) #name
+char* activities[] = { ACTIVITIES };
+#undef X
+
+/* we may use a few separate menu trees */
+typedef enum {
+ MENU_MAIN,
+ MENU_DIFFICULTY,
+ MENU_LESSONS,
+ MENU_LOGIN,
+ N_OF_MENUS
+} MenuType;
+
+MenuNode* menus[N_OF_MENUS];
+
+/* actions available while viewing the menu */
+enum { NONE, CLICK, PAGEUP, PAGEDOWN, STOP_ESC, RESIZED };
+
+/* stop button, left and right arrow positions do not
+ depend on currently displayed menu */
+SDL_Rect menu_rect, stop_rect, prev_rect, next_rect;
+SDL_Surface *stop_button, *prev_arrow, *next_arrow, *prev_gray, *next_gray;
+
+/*TODO: move these constants into a config file (maybe together with
+ titlescreen paths and rects ? ) */
+const float menu_pos[4] = {0.38, 0.23, 0.55, 0.72};
+const float stop_pos[4] = {0.94, 0.0, 0.06, 0.06};
+const float prev_pos[4] = {0.87, 0.93, 0.06, 0.06};
+const float next_pos[4] = {0.94, 0.93, 0.06, 0.06};
+const char* stop_path = "status/stop.svg";
+const char* prev_path = "status/left.svg";
+const char* next_path = "status/right.svg";
+const char* prev_gray_path = "status/left_gray.svg";
+const char* next_gray_path = "status/right_gray.svg";
+const float button_gap = 0.2, text_h_gap = 0.4, text_w_gap = 0.5, button_radius = 0.27;
+const int min_font_size = 8, default_font_size = 20, max_font_size = 40;
+
+/* font size used in current resolution */
+int curr_font_size;
+
+/* menu title rect */
+SDL_Rect menu_title_rect;
+
+/* buffer size used when reading attributes or names */
+const int buf_size = 128;
+
+
+
+/* local functions */
+MenuNode* create_empty_node();
+char* get_attribute_name(const char* token);
+char* get_attribute_value(const char* token);
+void read_attributes(FILE* xml_file, MenuNode* node);
+MenuNode* load_menu_from_file(FILE* xml_file, MenuNode* parent);
+void free_menu(MenuNode* menu);
+MenuNode* create_one_level_menu(int items, char** item_names, char* title, char* trailer);
+
+int handle_activity(int act, int param);
+int run_academy(void);
+int run_arcade(int choice);
+int run_custom_game(void);
+void run_multiplayer(int mode, int difficulty);
+int run_factoroids(int choice);
+
+int run_menu(MenuNode* menu, bool return_choice);
+SDL_Surface** render_buttons(MenuNode* menu, bool selected);
+void prerender_menu(MenuNode* menu);
+char* find_longest_text(MenuNode* menu, int* length);
+void set_font_size();
+void prerender_all();
+
+
+
+/*
+ functions responsible for parsing menu files
+ and creating menu trees
+*/
+
+/* creates new MenuNode struct with all fields set to NULL (or 0) */
+MenuNode* create_empty_node()
+{
+ MenuNode* new_node = malloc(sizeof(MenuNode));
+ new_node->parent = NULL;
+ new_node->title = NULL;
+ new_node->icon_name = NULL;
+ new_node->icon = NULL;
+ new_node->submenu_size = 0;
+ new_node->submenu = NULL;
+ new_node->activity = 0;
+ new_node->param = 0;
+ new_node->first_entry = 0;
+ new_node->show_title = false;
+
+ return new_node;
+}
+
+/* read attributes and fill appropriate node fields */
+void read_attributes(FILE* xml_file, MenuNode* node)
+{
+ char attr_name[buf_size];
+ char attr_val[buf_size];
+ int i;
+
+ /* read tokens until closing '>' is found */
+ do
+ {
+ fscanf(xml_file, " %[^=\n]", attr_name);
+
+ DEBUGMSG(debug_menu_parser, "read_attributes(): read attribute name: %s\n", attr_name);
+ if(strchr(attr_name, '>'))
+ break;
+
+ fscanf(xml_file, "=\"%[^\"]\"", attr_val);
+ DEBUGMSG(debug_menu_parser, "read_attributes(): read attribute value: %s\n", attr_val);
+
+ if(strcmp(attr_name, "title") == 0)
+ node->title = strdup(attr_val);
+ else if(strcmp(attr_name, "entries") == 0)
+ node->submenu_size = atoi(attr_val);
+ else if(strcmp(attr_name, "param") == 0)
+ node->param = atoi(attr_val);
+ else if(strcmp(attr_name, "sprite") == 0)
+ node->icon_name = strdup(attr_val);
+ else if(strcmp(attr_name, "run") == 0)
+ {
+ for(i = 0; i < N_OF_ACTIVITIES; i++)
+ if(strcmp(attr_val, activities[i]) == 0)
+ node->activity = i;
+ }
+ else
+ DEBUGMSG(debug_menu_parser, "read_attributes(): unknown attribute %s , omitting\n", attr_name);
+
+ } while(strchr(attr_val, '>') == NULL);
+}
+
+/* recursively read and parse given xml menu file and create menu tree
+ return NULL in case of problems */
+MenuNode* load_menu_from_file(FILE* xml_file, MenuNode* parent)
+{
+ MenuNode* new_node = create_empty_node();
+ char buffer[buf_size];
+ int i;
+
+ new_node->parent = parent;
+
+ DEBUGMSG(debug_menu_parser, "entering load_menu_from_file()\n");
+ fscanf(xml_file, " < %s", buffer);
+
+ if(strcmp(buffer, "menu") == 0)
+ {
+ read_attributes(xml_file, new_node);
+ if(new_node->title == NULL)
+ {
+ DEBUGMSG(debug_menu_parser, "load_menu_from_file(): no title attribute, exiting\n");
+ return NULL;
+ }
+
+ if(new_node->submenu_size > 0)
+ {
+ new_node->submenu = malloc(new_node->submenu_size * sizeof(MenuNode));
+ for(i = 0; i < new_node->submenu_size; i++)
+ new_node->submenu[i] = load_menu_from_file(xml_file, new_node);
+ }
+
+ fscanf(xml_file, " </%[^>\n]> ", buffer);
+ if(strcmp(buffer, "menu") != 0)
+ DEBUGMSG(debug_menu_parser, "load_menu_from_file(): warning - no closing menu tag, found %s instead\n", buffer);
+ }
+ else if(strcmp(buffer, "item") == 0)
+ {
+ read_attributes(xml_file, new_node);
+ if(new_node->title == NULL)
+ {
+ DEBUGMSG(debug_menu_parser, "load_menu_from_file(): no title attribute, exiting\n");
+ return NULL;
+ }
+ }
+ else
+ {
+ DEBUGMSG(debug_menu_parser, "load_menu_from_file(): unknown tag: %s\n, exiting\n", buffer);
+ return NULL;
+ }
+
+ DEBUGMSG(debug_menu_parser, "load_menu_from_file(): node loaded successfully\n");
+ return new_node;
+}
+
+/* recursively free all non-NULL pointers in a menu tree */
+void free_menu(MenuNode* menu)
+{
+ int i;
+
+ DEBUGMSG(debug_menu, "entering free_menu()\n");
+ if(menu != NULL)
+ {
+ if(menu->title != NULL)
+ free(menu->title);
+ if(menu->icon_name != NULL)
+ free(menu->icon_name);
+ if(menu->icon != NULL)
+ FreeSprite(menu->icon);
+
+ if(menu->submenu != NULL)
+ {
+ for(i = 0; i < menu->submenu_size; i++)
+ if(menu->submenu[i] != NULL)
+ {
+ free_menu(menu->submenu[i]);
+ menu->submenu[i] = NULL;
+ }
+ free(menu->submenu);
+ }
+
+ free(menu);
+ }
+}
+
+/* create a simple one-level menu without sprites.
+ all given strings are copied */
+MenuNode* create_one_level_menu(int items, char** item_names, char* title, char* trailer)
+{
+ MenuNode* menu = create_empty_node();
+ int i;
+
+ if(title)
+ {
+ menu->title = strdup(title);
+ menu->show_title = true;
+ }
+ menu->submenu_size = items + (trailer ? 1 : 0);
+ menu->submenu = (MenuNode**) malloc(menu->submenu_size * sizeof(MenuNode*));
+ for(i = 0; i < items; i++)
+ {
+ menu->submenu[i] = create_empty_node();
+ menu->submenu[i]->title = strdup(item_names[i]);
+ menu->submenu[i]->activity = i;
+ }
+
+ if(trailer)
+ {
+ menu->submenu[items] = create_empty_node();
+ menu->submenu[items]->title = strdup(trailer);
+ menu->submenu[items]->activity = items;
+ }
+
+ return menu;
+}
+
+/*
+ handlers for specific game activities
+*/
+
+/* return QUIT if user decided to quit the application while running an activity
+ return 0 otherwise */
+int handle_activity(int act, int param)
+{
+ DEBUGMSG(debug_menu, "entering handle_activity()\n");
+
+ switch(act)
+ {
+ case RUN_CAMPAIGN:
+ start_campaign();
+ break;
+
+ case RUN_ACADEMY:
+ if(run_academy() == QUIT)
+ return QUIT;
+ break;
+
+ case RUN_ARCADE:
+ run_arcade(param);
+ break;
+
+ case RUN_CUSTOM:
+ run_custom_game();
+ break;
+
+ case RUN_HALL_OF_FAME:
+ DisplayHighScores(CADET_HIGH_SCORE);
+ break;
+
+ case RUN_SCORE_SWEEP:
+ run_multiplayer(0, param);
+ break;
+
+ case RUN_ELIMINATION:
+ run_multiplayer(1, param);
+ break;
+
+ case RUN_HELP:
+ Opts_SetHelpMode(1);
+ Opts_SetDemoMode(0);
+ if (Opts_GetGlobalOpt(MENU_MUSIC)) //Turn menu music off for game
+ {audioMusicUnload();}
+ game();
+ if (Opts_GetGlobalOpt(MENU_MUSIC)) //Turn menu music back on
+ audioMusicLoad( "tuxi.ogg", -1 );
+ Opts_SetHelpMode(0);
+ break;
+
+ case RUN_FACTORS:
+ run_factoroids(0);
+ break;
+
+ case RUN_FRACTIONS:
+ run_factoroids(1);
+ break;
+
+ case RUN_DEMO:
+ if(read_named_config_file("demo"))
+ {
+ audioMusicUnload();
+ game();
+ if (Opts_GetGlobalOpt(MENU_MUSIC))
+ audioMusicLoad( "tuxi.ogg", -1 );
+ }
+ else
+ fprintf(stderr, "\nCould not find demo config file\n");
+ break;
+
+ case RUN_INFO:
+ ShowMessage(_("TuxMath is free and open-source!"),
+ _("You can help make it better by reporting problems,"),
+ _("suggesting improvements, or adding code."),
+ _("Discuss the future at tuxmath-devel at lists.sourceforge.net"));
+ break;
+
+ case RUN_CREDITS:
+ credits();
+ break;
+
+ case RUN_QUIT:
+ return QUIT;
+ }
+
+ return 0;
+}
+
+int run_academy(void)
+{
+ int chosen_lesson = -1;
+
+ chosen_lesson = run_menu(menus[MENU_LESSONS], true);
+ while (chosen_lesson >= 0)
+ {
+ if (Opts_GetGlobalOpt(MENU_SOUND))
+ playsound(SND_POP);
+
+ /* Re-read global settings first in case any settings were */
+ /* clobbered by other lesson or arcade games this session: */
+ read_global_config_file();
+ /* Now read the selected file and play the "mission": */
+ if (read_named_config_file(lesson_list_filenames[chosen_lesson]))
+ {
+ if (Opts_GetGlobalOpt(MENU_MUSIC)) //Turn menu music off for game
+ {audioMusicUnload();}
+
+ game();
+
+ /* If successful, display Gold Star for this lesson! */
+ if (MC_MissionAccomplished())
+ {
+ lesson_list_goldstars[chosen_lesson] = 1;
+ /* and save to disk: */
+ write_goldstars();
+ }
+
+ if (Opts_GetGlobalOpt(MENU_MUSIC)) //Turn menu music back on
+ {audioMusicLoad("tuxi.ogg", -1);}
+ }
+ else // Something went wrong - could not read lesson config file:
+ {
+ fprintf(stderr, "\nCould not find file: %s\n", lesson_list_filenames[chosen_lesson]);
+ chosen_lesson = -1;
+ }
+ // Let the user choose another lesson; start with the screen and
+ // selection that we ended with
+ chosen_lesson = run_menu(menus[MENU_LESSONS], true);
+ }
+ return chosen_lesson;
+}
+
+int run_arcade(int choice)
+{
+ const char* arcade_config_files[5] =
+ {"arcade/space_cadet",
+ "arcade/scout",
+ "arcade/ranger",
+ "arcade/ace",
+ "arcade/commando"
+ };
+
+ const int arcade_high_score_tables[5] =
+ {CADET_HIGH_SCORE,
+ SCOUT_HIGH_SCORE,
+ RANGER_HIGH_SCORE,
+ ACE_HIGH_SCORE,
+ COMMANDO_HIGH_SCORE
+ };
+
+ int hs_table;
+
+ if (choice < NUM_MATH_COMMAND_LEVELS) {
+ // Play arcade game
+ if (read_named_config_file(arcade_config_files[choice]))
+ {
+ audioMusicUnload();
+ game();
+ RenderTitleScreen();
+ if (Opts_GetGlobalOpt(MENU_MUSIC))
+ audioMusicLoad( "tuxi.ogg", -1 );
+ /* See if player made high score list! */
+ read_high_scores(); /* Update, in case other users have added to it */
+ hs_table = arcade_high_score_tables[choice];
+ if (check_score_place(hs_table, Opts_LastScore()) < HIGH_SCORES_SAVED)
+ {
+ char player_name[HIGH_SCORE_NAME_LENGTH * 3];
+
+ /* Get name from player: */
+ HighScoreNameEntry(&player_name[0]);
+ insert_score(player_name, hs_table, Opts_LastScore());
+ /* Show the high scores. Note the user will see his/her */
+ /* achievement even if (in the meantime) another player */
+ /* has in fact already bumped this score off the table. */
+ DisplayHighScores(hs_table);
+ /* save to disk: */
+ /* See "On File Locking" in fileops.c */
+ append_high_score(choice,Opts_LastScore(),&player_name[0]);
+
+ DEBUGCODE(debug_titlescreen)
+ print_high_scores(stderr);
+ }
+ }
+ else {
+ fprintf(stderr, "\nCould not find %s config file\n",arcade_config_files[choice]);
+ }
+ }
+ return 0;
+}
+
+int run_custom_game(void)
+{
+ const char *s1, *s2, *s3, *s4;
+ s1 = _("Edit 'options' file in your home directory");
+ s2 = _("to create customized game!");
+ s3 = _("Press a key or click your mouse to start game.");
+ s4 = _("See README.txt for more information");
+ ShowMessage(s1, s2, s3, s4);
+
+ if (read_user_config_file()) {
+ if (Opts_GetGlobalOpt(MENU_MUSIC))
+ audioMusicUnload();
+
+ game();
+ write_user_config_file();
+
+ if (Opts_GetGlobalOpt(MENU_MUSIC))
+ audioMusicLoad( "tuxi.ogg", -1 );
+ }
+
+ return 0;
+}
+
+void run_multiplayer(int mode, int difficulty)
+{
+ int nplayers = 0;
+ char npstr[HIGH_SCORE_NAME_LENGTH * 3];
+
+ while (nplayers <= 0 || nplayers > MAX_PLAYERS)
+ {
+ NameEntry(npstr, _("How many kids are playing?"),
+ _("(Between 2 and 4 players)"));
+ nplayers = atoi(npstr);
+ }
+
+ mp_set_parameter(PLAYERS, nplayers);
+ mp_set_parameter(MODE, mode);
+ mp_set_parameter(DIFFICULTY, difficulty);
+ mp_run_multiplayer();
+}
+
+int run_factoroids(int choice)
+{
+ const int factoroids_high_score_tables[2] =
+ {FACTORS_HIGH_SCORE, FRACTIONS_HIGH_SCORE};
+ int hs_table;
+
+ audioMusicUnload();
+ if(choice == 0)
+ factors();
+ else
+ fractions();
+
+ if (Opts_GetGlobalOpt(MENU_MUSIC))
+ audioMusicLoad( "tuxi.ogg", -1 );
+
+ hs_table = factoroids_high_score_tables[choice];
+ if (check_score_place(hs_table, Opts_LastScore()) < HIGH_SCORES_SAVED){
+ char player_name[HIGH_SCORE_NAME_LENGTH * 3];
+ /* Get name from player: */
+ HighScoreNameEntry(&player_name[0]);
+ insert_score(player_name, hs_table, Opts_LastScore());
+ /* Show the high scores. Note the user will see his/her */
+ /* achievement even if (in the meantime) another player */
+ /* has in fact already bumped this score off the table. */
+ DisplayHighScores(hs_table);
+ /* save to disk: */
+ /* See "On File Locking" in fileops.c */
+ append_high_score(hs_table,Opts_LastScore(),&player_name[0]);
+ DEBUGCODE(debug_titlescreen)
+ print_high_scores(stderr);
+ }
+ else {
+ fprintf(stderr, "\nCould not find config file\n");
+ }
+
+ return 0;
+}
+
+/* Display the menu and run the event loop.
+ if return_choice = true then return chosen value instead of
+ running handle_activity()
+ this function is a modified copy of choose_menu_item() */
+int run_menu(MenuNode* root, bool return_choice)
+{
+ SDL_Surface** menu_item_unselected = NULL;
+ SDL_Surface** menu_item_selected = NULL;
+ SDL_Surface* title_surf;
+ SDL_Event event;
+ MenuNode* menu = root;
+ MenuNode* tmp_node;
+
+ SDL_Rect tmp_rect;
+ sprite* tmp_sprite;
+ int i;
+ int stop = 0;
+ int items;
+
+ int action = NONE;
+
+ Uint32 frame_start = 0; //For keeping frame rate constant
+ Uint32 frame_now = 0;
+ Uint32 frame_counter = 0;
+ int loc = -1; //The currently selected menu item
+ int old_loc = -1;
+ int click_flag = 1;
+
+ for(;;) /* one loop body execution for one menu page */
+ {
+ DEBUGMSG(debug_menu, "run_menu(): drawing whole new menu page\n");
+
+ DrawTitleScreen();
+ /* render buttons for current menu page */
+ menu_item_unselected = render_buttons(menu, false);
+ menu_item_selected = render_buttons(menu, true);
+ items = min(menu->entries_per_screen, menu->submenu_size - menu->first_entry);
+
+ DEBUGMSG(debug_menu, "run_menu(): drawing %d buttons\n", items);
+ for(i = 0; i < items; i++)
+ {
+ if(loc == i)
+ SDL_BlitSurface(menu_item_selected[i], NULL, screen, &menu->submenu[menu->first_entry + i]->button_rect);
+ else
+ SDL_BlitSurface(menu_item_unselected[i], NULL, screen, &menu->submenu[menu->first_entry + i]->button_rect);
+ if(menu->submenu[menu->first_entry + i]->icon)
+ SDL_BlitSurface(menu->submenu[menu->first_entry + i]->icon->default_img, NULL, screen, &menu->submenu[menu->first_entry + i]->icon_rect);
+ }
+
+ SDL_BlitSurface(stop_button, NULL, screen, &stop_rect);
+
+ if(menu->entries_per_screen < menu->submenu_size)
+ {
+ /* display arrows */
+ if(menu->first_entry > 0)
+ SDL_BlitSurface(prev_arrow, NULL, screen, &prev_rect);
+ else
+ SDL_BlitSurface(prev_gray, NULL, screen, &prev_rect);
+ if(menu->first_entry + items < menu->submenu_size)
+ SDL_BlitSurface(next_arrow, NULL, screen, &next_rect);
+ else
+ SDL_BlitSurface(next_gray, NULL, screen, &next_rect);
+ }
+
+ if(menu->show_title)
+ {
+ menu_title_rect = menu->submenu[0]->button_rect;
+ menu_title_rect.y = menu_rect.y - menu_title_rect.h;
+ title_surf = BlackOutline(_(menu->title), curr_font_size, &red);
+ SDL_BlitSurface(title_surf, NULL, screen, &menu_title_rect);
+ SDL_FreeSurface(title_surf);
+ }
+ SDL_UpdateRect(screen, 0, 0, 0, 0);
+
+ SDL_WM_GrabInput(SDL_GRAB_OFF);
+
+ while (SDL_PollEvent(&event)); // clear pending events
+
+ /******** Main loop: *********/
+ stop = false;
+ DEBUGMSG(debug_menu, "run_menu(): entering menu loop\n");
+ while (!stop)
+ {
+ frame_start = SDL_GetTicks(); /* For keeping frame rate constant.*/
+
+ action = NONE;
+ while (!stop && SDL_PollEvent(&event))
+ {
+ switch (event.type)
+ {
+ case SDL_QUIT:
+ {
+ FreeSurfaceArray(menu_item_unselected, items);
+ FreeSurfaceArray(menu_item_selected, items);
+ return QUIT;
+ }
+
+ case SDL_MOUSEMOTION:
+ {
+ loc = -1;
+ for (i = 0; i < items; i++)
+ {
+ if (inRect(menu->submenu[menu->first_entry + i]->button_rect, event.motion.x, event.motion.y))
+ {
+ if (Opts_GetGlobalOpt(MENU_SOUND) && old_loc != i)
+ playsound(SND_TOCK);
+ loc = i;
+ break; /* from for loop */
+ }
+ }
+
+ /* "Left" button - make click if button active: */
+ if(inRect(prev_rect, event.motion.x, event.motion.y)
+ && menu->first_entry > 0 && Opts_GetGlobalOpt(MENU_SOUND))
+ {
+ if(click_flag)
+ {
+ playsound(SND_TOCK);
+ click_flag = 0;
+ }
+ }
+
+ /* "Right" button - make click if button active: */
+ else if(inRect(next_rect, event.motion.x, event.motion.y)
+ && menu->first_entry + items < menu->submenu_size
+ && Opts_GetGlobalOpt(MENU_SOUND))
+ {
+ if(click_flag)
+ {
+ playsound(SND_TOCK);
+ click_flag = 0;
+ }
+ }
+
+ /* "stop" button */
+ else if (inRect(stop_rect, event.motion.x, event.motion.y )
+ && Opts_GetGlobalOpt(MENU_SOUND))
+ {
+ if(click_flag)
+ {
+ playsound(SND_TOCK);
+ click_flag = 0;
+ }
+ }
+
+ else // Mouse outside of arrow rects - re-enable click sound:
+ click_flag = 1;
+
+ break;
+ }
+
+ case SDL_MOUSEBUTTONDOWN:
+ {
+ loc = -1; // By default, don't be in any entry
+ for (i = 0; i < items; i++)
+ {
+ if (inRect(menu->submenu[menu->first_entry + i]->button_rect, event.motion.x, event.motion.y))
+ {
+ // Play sound if loc is being changed:
+ if (Opts_GetGlobalOpt(MENU_SOUND))
+ playsound(SND_POP);
+ loc = i;
+ action = CLICK;
+ break; /* from for loop */
+ }
+ }
+
+ /* "Left" button */
+ if (inRect(prev_rect, event.motion.x, event.motion.y)
+ && menu->first_entry > 0)
+ {
+ if (Opts_GetGlobalOpt(MENU_SOUND))
+ playsound(SND_POP);
+ action = PAGEUP;
+ }
+
+ /* "Right" button - go to next page: */
+ else if (inRect(next_rect, event.motion.x, event.motion.y )
+ && menu->first_entry + items < menu->submenu_size)
+ {
+ if (Opts_GetGlobalOpt(MENU_SOUND))
+ playsound(SND_POP);
+ action = PAGEDOWN;
+ }
+
+ /* "Stop" button - go to main menu: */
+ else if (inRect(stop_rect, event.button.x, event.button.y ))
+ {
+ if (Opts_GetGlobalOpt(MENU_SOUND))
+ playsound(SND_POP);
+ action = STOP_ESC;
+ }
+
+ break;
+ } /* End of case SDL_MOUSEDOWN */
+
+ case SDL_KEYDOWN:
+ {
+ /* Proceed according to particular key pressed: */
+ switch (event.key.keysym.sym)
+ {
+ case SDLK_ESCAPE:
+ {
+ action = STOP_ESC;
+ break;
+ }
+
+ case SDLK_RETURN:
+ case SDLK_SPACE:
+ case SDLK_KP_ENTER:
+ {
+ if (Opts_GetGlobalOpt(MENU_SOUND))
+ playsound(SND_POP);
+ action = CLICK;
+ break;
+ }
+
+ /* Go to previous page, if present: */
+ case SDLK_LEFT:
+ case SDLK_PAGEUP:
+ {
+ if (Opts_GetGlobalOpt(MENU_SOUND))
+ playsound(SND_TOCK);
+ if (menu->first_entry > 0)
+ action = PAGEUP;
+ break;
+ }
+
+ /* Go to next page, if present: */
+ case SDLK_RIGHT:
+ case SDLK_PAGEDOWN:
+ {
+ if (Opts_GetGlobalOpt(MENU_SOUND))
+ playsound(SND_TOCK);
+ if (menu->first_entry + items < menu->submenu_size)
+ action = PAGEDOWN;
+ break;
+ }
+
+ /* Go up one entry, if present: */
+ case SDLK_UP:
+ {
+ if (Opts_GetGlobalOpt(MENU_SOUND))
+ playsound(SND_TOCK);
+ if (loc > 0)
+ loc--;
+ else if (menu->submenu_size <= menu->entries_per_screen)
+ loc = menu->submenu_size - 1; // wrap around if only 1 screen
+ else if (menu->first_entry > 0)
+ {
+ loc = menu->entries_per_screen - 1;
+ action = PAGEUP;
+ }
+ break;
+ }
+
+ case SDLK_DOWN:
+ {
+ if (Opts_GetGlobalOpt(MENU_SOUND))
+ playsound(SND_TOCK);
+ if (loc + 1 < min(menu->submenu_size, menu->entries_per_screen))
+ loc++;
+ else if (menu->submenu_size <= menu->entries_per_screen)
+ loc = 0; // wrap around if only 1 screen
+ else if (menu->first_entry + menu->entries_per_screen < menu->submenu_size)
+ {
+ loc = 0;
+ action = PAGEDOWN;
+ }
+ break;
+ }
+
+ /* Change window size (used only to debug) */
+ case SDLK_F5:
+ case SDLK_F6:
+ case SDLK_F7:
+ case SDLK_F8:
+ {
+ /* these keys are available only if in debug mode */
+ DEBUGCODE(debug_titlescreen | debug_menu)
+ {
+ switch(event.key.keysym.sym)
+ {
+ case SDLK_F5:
+ {
+ /* decrease screen width */
+ ChangeWindowSize(win_res_x - 50, win_res_y);
+ break;
+ }
+ case SDLK_F6:
+ {
+ /* increase screen width */
+ ChangeWindowSize(win_res_x + 50, win_res_y);
+ break;
+ }
+ case SDLK_F7:
+ {
+ /* decrease screen height */
+ ChangeWindowSize(win_res_x, win_res_y - 50);
+ break;
+ }
+ case SDLK_F8:
+ {
+ /* increase screen height */
+ ChangeWindowSize(win_res_x, win_res_y + 50);
+ break;
+ }
+ default:
+ break;
+ }
+ action = RESIZED;
+ }
+ break;
+ }
+
+ /* Toggle screen mode: */
+ case SDLK_F10:
+ {
+ SwitchScreenMode();
+ action = RESIZED;
+ break;
+ }
+
+ /* Toggle menu music: */
+ case SDLK_F11:
+ {
+ if (Opts_GetGlobalOpt(MENU_MUSIC))
+ {
+ audioMusicUnload( );
+ Opts_SetGlobalOpt(MENU_MUSIC, 0);
+ }
+ else
+ {
+ Opts_SetGlobalOpt(MENU_MUSIC, 1);
+ audioMusicLoad("tuxi.ogg", -1);
+ }
+ break;
+ }
+
+ default:
+ {
+ /* Some other key - do nothing. */
+ }
+
+ break; /* To get out of _outer_ switch/case statement */
+ } /* End of key switch statement */
+ } // End of case SDL_KEYDOWN in outer switch statement
+ } // End event switch statement
+
+ if (old_loc != loc) {
+ DEBUGMSG(debug_menu, "run_menu(): changed button focus, old=%d, new=%d\n", old_loc, loc);
+ if(old_loc >= 0 && old_loc < items)
+ {
+ tmp_rect = menu->submenu[old_loc + menu->first_entry]->button_rect;
+ SDL_BlitSurface(menu_item_unselected[old_loc], NULL, screen, &tmp_rect);
+ if(menu->submenu[menu->first_entry + old_loc]->icon)
+ SDL_BlitSurface(menu->submenu[menu->first_entry + old_loc]->icon->default_img, NULL, screen, &menu->submenu[menu->first_entry + old_loc]->icon_rect);
+ SDL_UpdateRect(screen, tmp_rect.x, tmp_rect.y, tmp_rect.w, tmp_rect.h);
+ }
+ if(loc >= 0 && loc < items)
+ {
+ tmp_rect = menu->submenu[loc + menu->first_entry]->button_rect;
+ SDL_BlitSurface(menu_item_selected[loc], NULL, screen, &tmp_rect);
+ if(menu->submenu[menu->first_entry + loc]->icon)
+ {
+ SDL_BlitSurface(menu->submenu[menu->first_entry + loc]->icon->default_img, NULL, screen, &menu->submenu[menu->first_entry + loc]->icon_rect);
+ menu->submenu[menu->first_entry + loc]->icon->cur = 0;
+ }
+ SDL_UpdateRect(screen, tmp_rect.x, tmp_rect.y, tmp_rect.w, tmp_rect.h);
+ }
+ old_loc = loc;
+ }
+
+ if(HandleTitleScreenEvents(&event))
+ stop = true;
+
+ switch(action)
+ {
+ case RESIZED:
+ RenderTitleScreen();
+ menu->first_entry = 0;
+ prerender_all();
+ stop = true;
+ break;
+
+ case CLICK:
+ if(loc < 0 || loc >= items)
+ {
+ DEBUGMSG(debug_menu, "run_menu(): incorrect location for CLICK action (%d) !\n", loc);
+ }
+ else
+ {
+ tmp_node = menu->submenu[menu->first_entry + loc];
+ if(tmp_node->submenu_size == 0)
+ {
+ if(return_choice)
+ {
+ FreeSurfaceArray(menu_item_unselected, items);
+ FreeSurfaceArray(menu_item_selected, items);
+ return tmp_node->activity;
+ }
+ else
+ {
+ if(tmp_node->activity == RUN_MAIN_MENU)
+ {
+ /* go back to the root of this menu */
+ menu = root;
+ }
+ else
+ {
+ if(handle_activity(tmp_node->activity, tmp_node->param) == QUIT)
+ {
+ DEBUGMSG(debug_menu, "run_menu(): handle_activity() returned QUIT message, exiting.\n");
+ FreeSurfaceArray(menu_item_unselected, items);
+ FreeSurfaceArray(menu_item_selected, items);
+ return QUIT;
+ }
+ }
+ }
+ }
+ else
+ {
+ menu->first_entry = 0;
+ menu = tmp_node;
+ menu->first_entry = 0;
+ }
+ stop = true;
+ }
+ break;
+
+ case STOP_ESC:
+ if(menu->parent == NULL)
+ {
+ FreeSurfaceArray(menu_item_unselected, items);
+ FreeSurfaceArray(menu_item_selected, items);
+ return STOP;
+ }
+ else
+ menu = menu->parent;
+ stop = true;
+ break;
+
+ case PAGEUP:
+ menu->first_entry -= menu->entries_per_screen;
+ stop = true;
+ break;
+
+ case PAGEDOWN:
+ menu->first_entry += menu->entries_per_screen;
+ stop = true;
+ break;
+ }
+
+ } // End of SDL_PollEvent while loop
+
+ if(stop)
+ break;
+
+ if(!stop && frame_counter % 5 == 0 && loc >= 0 && loc < items)
+ {
+ tmp_sprite = menu->submenu[menu->first_entry + loc]->icon;
+ if(tmp_sprite)
+ {
+ SDL_BlitSurface(menu_item_selected[loc], NULL, screen, &menu->submenu[menu->first_entry + loc]->icon_rect);
+ SDL_BlitSurface(tmp_sprite->frame[tmp_sprite->cur], NULL, screen, &menu->submenu[menu->first_entry + loc]->icon_rect);
+ UpdateRect(screen, &menu->submenu[menu->first_entry + loc]->icon_rect);
+ NextFrame(tmp_sprite);
+ }
+ }
+
+ HandleTitleScreenAnimations();
+
+ /* Wait so we keep frame rate constant: */
+ frame_now = SDL_GetTicks();
+ if (frame_now < frame_start)
+ frame_start = frame_now; // in case the timer wraps around
+ if((frame_now - frame_start) < 1000 / MAX_FPS)
+ SDL_Delay(1000 / MAX_FPS - (frame_now - frame_start));
+
+ frame_counter++;
+ } // End of while(!stop) loop
+
+ /* free button surfaces */
+ DEBUGMSG(debug_menu, "run_menu(): freeing %d button surfaces\n", items);
+ FreeSurfaceArray(menu_item_unselected, items);
+ FreeSurfaceArray(menu_item_selected, items);
+ }
+
+ return QUIT;
+}
+
+/* return button surfaces that are currently displayed (without sprites) */
+SDL_Surface** render_buttons(MenuNode* menu, bool selected)
+{
+ SDL_Surface** menu_items = NULL;
+ SDL_Rect curr_rect;
+ SDL_Surface* tmp_surf = NULL;
+ int i;
+ int items = min(menu->entries_per_screen, menu->submenu_size - menu->first_entry);
+
+ menu_items = (SDL_Surface**) malloc(items * sizeof(SDL_Surface*));
+ if(NULL == menu_items)
+ {
+ DEBUGMSG(debug_menu, "render_buttons(): failed to allocate memory for buttons!\n");
+ return NULL; // error
+ }
+
+ for (i = 0; i < items; i++)
+ {
+ curr_rect = menu->submenu[menu->first_entry + i]->button_rect;
+ menu_items[i] = SDL_CreateRGBSurface(SDL_SWSURFACE|SDL_SRCALPHA,
+ curr_rect.w,
+ curr_rect.h,
+ 32,
+ rmask, gmask, bmask, amask);
+
+ SDL_BlitSurface(screen, &curr_rect, menu_items[i], NULL);
+ /* button */
+ if(selected)
+ tmp_surf = CreateButton(curr_rect.w, curr_rect.h, button_radius * curr_rect.h, SEL_RGBA);
+ else
+ tmp_surf = CreateButton(curr_rect.w, curr_rect.h, button_radius * curr_rect.h, REG_RGBA);
+
+ SDL_BlitSurface(tmp_surf, NULL, menu_items[i], NULL);
+ SDL_FreeSurface(tmp_surf);
+
+ /* text */
+ tmp_surf = BlackOutline(_(menu->submenu[menu->first_entry + i]->title),
+ curr_font_size, selected ? &yellow : &white);
+ SDL_BlitSurface(tmp_surf, NULL, menu_items[i], &menu->submenu[menu->first_entry + i]->text_rect);
+ SDL_FreeSurface(tmp_surf);
+ }
+
+ return menu_items;
+}
+
+/* recursively load sprites and calculate button rects
+ to fit into current screen */
+void prerender_menu(MenuNode* menu)
+{
+ SDL_Surface* temp_surf;
+ MenuNode* curr_node;
+ int i, imod, max_text_h = 0, max_text_w = 0;
+ int button_h, button_w;
+ bool found_icons = false;
+ char filename[buf_size];
+
+ if(NULL == menu)
+ {
+ DEBUGMSG(debug_menu, "prerender_menu(): NULL pointer, exiting !\n");
+ return;
+ }
+
+ if(0 == menu->submenu_size)
+ {
+ DEBUGMSG(debug_menu, "prerender_menu(): no submenu, exiting.\n");
+ return;
+ }
+
+ for(i = 0; i < menu->submenu_size; i++)
+ {
+ if(menu->submenu[i]->icon_name)
+ found_icons = true;
+ temp_surf = NULL;
+ temp_surf = SimpleText(_(menu->submenu[i]->title), curr_font_size, &black);
+ if(temp_surf)
+ {
+ max_text_h = max(max_text_h, temp_surf->h);
+ max_text_w = max(max_text_w, temp_surf->w);
+ SDL_FreeSurface(temp_surf);
+ }
+ }
+
+ button_h = (1.0 + 2.0 * text_h_gap) * max_text_h;
+ button_w = max_text_w + ( (found_icons ? 1.0 : 0.0) + 2.0 * text_w_gap) * button_h;
+
+ menu->entries_per_screen = (int) ( (menu_rect.h - button_gap * button_h) /
+ ( (1.0 + button_gap) * button_h ) );
+
+ for(i = 0; i < menu->submenu_size; i++)
+ {
+ curr_node = menu->submenu[i];
+ curr_node->button_rect.x = menu_rect.x;
+ imod = i % menu->entries_per_screen;
+ curr_node->button_rect.y = menu_rect.y + imod * button_h + (imod + 1) * button_gap * button_h;
+ curr_node->button_rect.w = button_w;
+ curr_node->button_rect.h = button_h;
+
+ curr_node->icon_rect = curr_node->button_rect;
+ curr_node->icon_rect.w = curr_node->icon_rect.h;
+
+ curr_node->text_rect.x = ( (found_icons ? 1.0 : 0.0) + text_w_gap) * curr_node->icon_rect.w;
+ curr_node->text_rect.y = text_h_gap * max_text_h;
+ curr_node->text_rect.h = max_text_h;
+ curr_node->text_rect.w = max_text_w;
+
+ if(curr_node->icon)
+ FreeSprite(curr_node->icon);
+
+ if(curr_node->icon_name)
+ {
+ sprintf(filename, "sprites/%s", curr_node->icon_name);
+ DEBUGMSG(debug_menu, "prerender_menu(): loading sprite %s for item #%d.\n", filename, i);
+ curr_node->icon = LoadSpriteOfBoundingBox(filename, IMG_ALPHA, button_h, button_h);
+ }
+ else
+ DEBUGMSG(debug_menu, "prerender_menu(): no sprite for item #%d.\n", i);
+
+ prerender_menu(menu->submenu[i]);
+ }
+}
+
+char* find_longest_text(MenuNode* menu, int* length)
+{
+ SDL_Surface* text = NULL;
+ char *ret = NULL, *temp = NULL;
+ int i;
+
+ if(menu->submenu_size == 0)
+ {
+ text = SimpleText(_(menu->title), curr_font_size, &black);
+ if(text->w > *length)
+ {
+ *length = text->w;
+ ret = menu->title;
+ }
+ SDL_FreeSurface(text);
+ }
+ else
+ {
+ for(i = 0; i < menu->submenu_size; i++)
+ {
+ temp = find_longest_text(menu->submenu[i], length);
+ if(temp)
+ ret = temp;
+ }
+ }
+ return ret;
+}
+
+/* find the longest text in all existing menus and binary search
+ for the best font size */
+void set_font_size()
+{
+ char* longest = NULL;
+ char* temp;
+ SDL_Surface* surf;
+ int length = 0, i, min_f, max_f, mid_f;
+
+ curr_font_size = default_font_size;
+
+ for(i = 0; i < N_OF_MENUS; i++)
+ {
+ if(menus[i])
+ {
+ temp = find_longest_text(menus[i], &length);
+ if(temp)
+ longest = temp;
+ }
+ }
+
+ if(!longest)
+ return;
+
+ min_f = min_font_size;
+ max_f = max_font_size;
+
+ while(min_f < max_f)
+ {
+ mid_f = (min_f + max_f) / 2;
+ surf = SimpleText(_(longest), mid_f, &black);
+ if(surf->w + (1.0 + 2.0 * text_w_gap) * (1.0 + 2.0 * text_h_gap) * surf->h < menu_rect.w)
+ min_f = mid_f + 1;
+ else
+ max_f = mid_f;
+ SDL_FreeSurface(surf);
+ }
+
+ curr_font_size = min_f;
+}
+
+/* prerender arrows, stop button and all non-NULL menus from menus[] array
+ this function should be invoked after every resolution change */
+void prerender_all()
+{
+ int i;
+
+ SetRect(&menu_rect, menu_pos);
+
+ SetRect(&stop_rect, stop_pos);
+ if(stop_button)
+ SDL_FreeSurface(stop_button);
+ stop_button = LoadImageOfBoundingBox(stop_path, IMG_ALPHA, stop_rect.w, stop_rect.h);
+ /* move button to the right */
+ stop_rect.x = screen->w - stop_button->w;
+
+ SetRect(&prev_rect, prev_pos);
+ if(prev_arrow)
+ SDL_FreeSurface(prev_arrow);
+ prev_arrow = LoadImageOfBoundingBox(prev_path, IMG_ALPHA, prev_rect.w, prev_rect.h);
+ if(prev_gray)
+ SDL_FreeSurface(prev_gray);
+ prev_gray = LoadImageOfBoundingBox(prev_gray_path, IMG_ALPHA, prev_rect.w, prev_rect.h);
+ /* move button to the right */
+ prev_rect.x += prev_rect.w - prev_arrow->w;
+
+ SetRect(&next_rect, next_pos);
+ if(next_arrow)
+ SDL_FreeSurface(next_arrow);
+ next_arrow = LoadImageOfBoundingBox(next_path, IMG_ALPHA, next_rect.w, next_rect.h);
+ if(next_gray)
+ SDL_FreeSurface(next_gray);
+ next_gray = LoadImageOfBoundingBox(next_gray_path, IMG_ALPHA, next_rect.w, next_rect.h);
+
+ set_font_size();
+
+ for(i = 0; i < N_OF_MENUS; i++)
+ if(menus[i])
+ prerender_menu(menus[i]);
+}
+
+/* load menu trees from disk and prerender them */
+void LoadMenus(void)
+{
+ FILE* menu_file = NULL;
+ int i;
+
+ for(i = 0; i < N_OF_MENUS; i++)
+ menus[i] = NULL;
+
+ /* main menu */
+ menu_file = fopen(DATA_PREFIX "/menus/main_menu.xml", "r");
+ if(menu_file == NULL)
+ {
+ DEBUGMSG(debug_menu, "LoadMenus(): Could not load main menu file !\n");
+ }
+ else
+ {
+ menus[MENU_MAIN] = load_menu_from_file(menu_file, NULL);
+ fclose(menu_file);
+ }
+
+ /* difficulty menu */
+ menu_file = fopen(DATA_PREFIX "/menus/level_menu.xml", "r");
+ if(menu_file == NULL)
+ {
+ DEBUGMSG(debug_menu, "LoadMenus(): Could not load level menu file !\n");
+ }
+ else
+ {
+ menus[MENU_DIFFICULTY] = load_menu_from_file(menu_file, NULL);
+ fclose(menu_file);
+ }
+
+ prerender_all();
+}
+
+
+
+/* create login menu tree, run it and set the user home directory
+ -1 indicates that the user wants to quit without logging in,
+ 0 indicates that a choice has been made. */
+int RunLoginMenu(void)
+{
+ int n_login_questions = 0;
+ char **user_login_questions = NULL;
+ char *title = NULL;
+ int n_users = 0;
+ char **user_names = NULL;
+ int chosen_login = -1;
+ int level;
+ int i;
+ char *trailer_quit = "Quit";
+ char *trailer_back = "Back";
+ char *trailer = NULL;
+ SDLMod mod;
+
+ DEBUGMSG(debug_menu, "Entering RunLoginMenu()");
+ // Check for & read user_login_questions file
+ n_login_questions = read_user_login_questions(&user_login_questions);
+
+ // Check for & read user_menu_entries file
+ n_users = read_user_menu_entries(&user_names);
+
+ if (n_users == 0)
+ return 0; // a quick exit, there's only one user
+
+ // Check for a highscores file
+ if (high_scores_found_in_user_dir())
+ set_high_score_path();
+
+ level = 0;
+
+ if (n_login_questions > 0)
+ title = user_login_questions[0];
+
+ menus[MENU_LOGIN] = create_one_level_menu(n_users, user_names, title, trailer_quit);
+
+ while (n_users) {
+ // Get the user choice
+ set_font_size();
+ prerender_menu(menus[MENU_LOGIN]);
+ chosen_login = run_menu(menus[MENU_LOGIN], true);
+ // Determine whether there were any modifier (CTRL) keys pressed
+ mod = SDL_GetModState();
+ if (chosen_login < 0 || chosen_login == n_users) {
+ // User pressed escape or selected Quit/Back, handle by quitting
+ // or going up a level
+ if (level == 0) {
+ // We are going to quit without logging in.
+ // Clean up memory (prob. not necessary, but prevents Valgrind errors!)
+ for (i = 0; i < n_login_questions; i++)
+ free(user_login_questions[i]);
+ free(user_login_questions);
+ for (i = 0; i < n_users; i++)
+ free(user_names[i]);
+ free(user_names);
+ free_menu(menus[MENU_LOGIN]);
+ menus[MENU_LOGIN] = NULL;
+ return -1;
+ }
+ else {
+ // Go back up one level of the directory tree
+ user_data_dirname_up();
+ level--;
+ }
+ }
+ else {
+ // User chose an entry, set it up
+ user_data_dirname_down(user_names[chosen_login]);
+ level++;
+ }
+ // Check for a highscores file
+ if (high_scores_found_in_user_dir())
+ set_high_score_path();
+ // Free the entries from the previous menu
+ for (i = 0; i < n_users; i++)
+ free(user_names[i]);
+ free(user_names);
+ user_names = NULL;
+ // If the CTRL key was pressed, choose this as the identity, even
+ // if there is a lower level to the hierarchy
+ if (mod & KMOD_CTRL)
+ break;
+ // Set the title appropriately for the next menu
+ if (level < n_login_questions)
+ title = user_login_questions[level];
+ else
+ title = NULL;
+ if (level == 0)
+ trailer = trailer_quit;
+ else
+ trailer = trailer_back;
+ // Check to see if there are more choices to be made
+ n_users = read_user_menu_entries(&user_names);
+ free_menu(menus[MENU_LOGIN]);
+ menus[MENU_LOGIN] = create_one_level_menu(n_users, user_names, title, trailer);
+ }
+
+ // The user home directory is set, clean up remaining memory
+ for (i = 0; i < n_login_questions; i++)
+ free(user_login_questions[i]);
+ free(user_login_questions);
+ free_menu(menus[MENU_LOGIN]);
+ menus[MENU_LOGIN] = NULL;
+
+ // Signal success
+ return 0;
+}
+
+/* run main menu. If this function ends it means that tuxmath is going to quit */
+void RunMainMenu(void)
+{
+ int i;
+ MenuNode* tmp_node;
+ DEBUGMSG(debug_menu, "Entering RunMainMenu()\n");
+
+ /* lessons menu */
+ DEBUGMSG(debug_menu, "LoadMenus(): Generating lessons submenu. (%d lessons)\n", num_lessons);
+
+ tmp_node = create_empty_node();
+ tmp_node->submenu_size = num_lessons;
+ tmp_node->submenu = (MenuNode**) malloc(num_lessons * sizeof(MenuNode*));
+ for(i = 0; i < num_lessons; i++)
+ {
+ tmp_node->submenu[i] = create_empty_node();
+ tmp_node->submenu[i]->icon_name = strdup(lesson_list_goldstars[i] ? "goldstar" : "no_goldstar");
+ tmp_node->submenu[i]->title = (char*) malloc( (strlen(lesson_list_titles[i]) + 1) * sizeof(char) );
+ strcpy(tmp_node->submenu[i]->title, lesson_list_titles[i]);
+ tmp_node->submenu[i]->activity = i;
+ }
+ menus[MENU_LESSONS] = tmp_node;
+ set_font_size();
+ prerender_menu(menus[MENU_LESSONS]);
+ //prerender_all();
+
+ run_menu(menus[MENU_MAIN], false);
+ DEBUGMSG(debug_menu, "Leaving RunMainMenu()\n");
+}
+
+/* free all loaded menu trees */
+void UnloadMenus(void)
+{
+ int i;
+
+ DEBUGMSG(debug_menu, "entering UnloadMenus()\n");
+
+ if(stop_button)
+ {
+ SDL_FreeSurface(stop_button);
+ stop_button = NULL;
+ }
+
+ if(prev_arrow)
+ {
+ SDL_FreeSurface(prev_arrow);
+ prev_arrow = NULL;
+ }
+
+ if(next_arrow)
+ {
+ SDL_FreeSurface(next_arrow);
+ next_arrow = NULL;
+ }
+
+ for(i = 0; i < N_OF_MENUS; i++)
+ if(menus[i] != NULL)
+ {
+ DEBUGMSG(debug_menu, "UnloadMenus(): freeing menu #%d\n", i);
+ free_menu(menus[i]);
+ }
+
+ DEBUGMSG(debug_menu, "leaving UnloadMenus()\n");
+}
+
Added: tuxmath/branches/lan/src/menu.h
===================================================================
--- tuxmath/branches/lan/src/menu.h (rev 0)
+++ tuxmath/branches/lan/src/menu.h 2009-09-03 22:06:06 UTC (rev 1477)
@@ -0,0 +1,103 @@
+/*
+ menu.h
+
+ Functions responsible for loading, parsing and displaying game menu.
+ (interface)
+
+ Part of "Tux4Kids" Project
+ http://www.tux4kids.com/
+
+ Author: Boleslaw Kulbabinski <bkulbabinski at gmail.com>, (C) 2009
+
+ Copyright: See COPYING file that comes with this distribution.
+*/
+
+#ifndef MENU_H
+#define MENU_H
+
+#include "SDL.h"
+#include "globals.h"
+#include "loaders.h"
+
+/* titlescreen & menu frame rate */
+#define MAX_FPS 30
+/* number of "real" frames per one sprite frame */
+#define SPRITE_FRAME_DELAY 6
+
+/* these are all menu choices that are available in tuxmath.
+ By using a define we can create both an enum and
+ a string array without writing these names twice */
+#define QUIT -2
+#define STOP -1
+
+#define ACTIVITIES \
+ X( RUN_QUIT ),\
+ X( RUN_ACADEMY ),\
+ X( RUN_CAMPAIGN ),\
+ X( RUN_ARCADE ),\
+ X( RUN_CUSTOM ),\
+ X( RUN_MAIN_MENU ),\
+ X( RUN_LAN_HOST ),\
+ X( RUN_LAN_JOIN ),\
+ X( RUN_SCORE_SWEEP ),\
+ X( RUN_ELIMINATION ),\
+ X( RUN_FACTORS ),\
+ X( RUN_FRACTIONS ),\
+ X( RUN_HELP ),\
+ X( RUN_DEMO ),\
+ X( RUN_INFO ),\
+ X( RUN_CREDITS ),\
+ X( RUN_HALL_OF_FAME ),\
+ X( RUN_SPACE_CADET ),\
+ X( RUN_SCOUT ),\
+ X( RUN_RANGER ),\
+ X( RUN_ACE ),\
+ X( RUN_COMMANDO ),\
+ X( N_OF_ACTIVITIES ) /* this one has to be the last one */
+
+/* create enum */
+#define X(name) name
+enum { ACTIVITIES };
+#undef X
+
+struct mNode {
+ struct mNode* parent;
+
+ char* title;
+ int font_size;
+
+ char* icon_name;
+ sprite* icon;
+
+ SDL_Rect button_rect;
+ SDL_Rect icon_rect;
+ SDL_Rect text_rect;
+
+ /* submenu_size = 0 if no submenu */
+ int submenu_size;
+ struct mNode** submenu;
+
+ /* these fields are used only if submenu_size = 0 */
+ int activity;
+ int param;
+
+ /* these fields are used only if submenu_size > 0 */
+ bool show_title;
+ int entries_per_screen;
+ int first_entry;
+};
+
+typedef struct mNode MenuNode;
+
+/* used also by highscore.c */
+extern SDL_Rect menu_rect, stop_rect, prev_rect, next_rect;
+extern SDL_Surface *stop_button, *prev_arrow, *next_arrow, *prev_gray, *next_gray;
+
+/* global functions */
+void LoadMenus(void);
+int RunLoginMenu(void);
+void RunMainMenu(void);
+void UnloadMenus(void);
+
+#endif // MENU_H
+
Modified: tuxmath/branches/lan/src/multiplayer.c
===================================================================
--- tuxmath/branches/lan/src/multiplayer.c 2009-09-02 10:50:25 UTC (rev 1476)
+++ tuxmath/branches/lan/src/multiplayer.c 2009-09-03 22:06:06 UTC (rev 1477)
@@ -32,7 +32,7 @@
{
if (inprogress)
{
- tmdprintf("Oops, tried to set param %d in the middle of a game\n", param);
+ DEBUGMSG(debug_multiplayer, "Oops, tried to set param %d in the middle of a game\n", param);
return;
}
params[param] = value;
@@ -84,7 +84,7 @@
if (activeplayers <= 1) //last man standing!
{
- tmdprintf("%d wins\n", currentplayer);
+ DEBUGMSG(debug_multiplayer, "%d wins\n", currentplayer);
winners[0] = currentplayer;
done = 1;
}
@@ -112,20 +112,22 @@
//sort out winners
for (i = 0; i < params[PLAYERS]; ++i)
{
+ hiscore = 0;
for (currentplayer = 0; currentplayer < params[PLAYERS]; ++currentplayer)
{
- if (pscores[currentplayer] > hiscore)
+ if (pscores[currentplayer] >= hiscore)
{
hiscore = pscores[currentplayer];
currentwinner = currentplayer;
}
winners[i] = currentwinner;
- pscores[currentwinner] = 0;
+ pscores[currentwinner] = -1;
}
}
}
-
- tmdprintf("Game over; showing winners\n");
+
+ DEBUGMSG(debug_multiplayer, "Game over; showing winners\n");
+
showWinners(winners, params[PLAYERS]);
cleanupMP();
}
@@ -134,7 +136,7 @@
{
if (playernum > params[PLAYERS])
{
- tmdprintf("No player %d!\n", playernum);
+ DEBUGMSG(debug_multiplayer, "No player %d!\n", playernum);
return 0;
}
return pscores[playernum];
@@ -144,7 +146,7 @@
{
if (playernum > params[PLAYERS])
{
- tmdprintf("No player %d!\n", playernum);
+ DEBUGMSG(debug_multiplayer, "No player %d!\n", playernum);
return 0;
}
return pnames[playernum];
@@ -164,19 +166,25 @@
void showWinners(int* winners, int num)
{
int skip = 0;
+ int i = 0;
const int boxspeed = 3;
- char text[HIGH_SCORE_NAME_LENGTH + strlen(" wins!")];
+ int sectionlength = num * (HIGH_SCORE_NAME_LENGTH + strlen(" wins!\n"));
+ char text[sectionlength];
SDL_Rect box = {screen->w / 2, screen->h / 2, 0, 0};
SDL_Rect center = box;
SDL_Event evt;
const char* winnername = (winners[0] == -1 ? "Nobody" : pnames[winners[0]] );
- tmdprintf("%s", pnames[winners[0]] );
- tmdprintf("%d\n", snprintf(text, HIGH_SCORE_NAME_LENGTH + strlen(" wins!"),
- "%s wins!", winnername) );
- tmdprintf("Win text: %s\n", text);
+ snprintf(text, HIGH_SCORE_NAME_LENGTH + strlen(" wins!"),
+ "%s wins!\n", winnername);
+ for (i = 1; i < num; ++i)
+ {
+ snprintf(strchr(text, '\0'), sectionlength, _("Then %s\n"), pnames[winners[i]]);
+ }
+ DEBUGMSG(debug_multiplayer, "%s Win text: %s\n", pnames[winners[0]], text);
+
DarkenScreen(1);
while (box.h < screen->h || box.w < screen->w)
@@ -209,6 +217,7 @@
int initMP()
{
int i;
+ int success = 1;
char nrstr[HIGH_SCORE_NAME_LENGTH * 3];
int nplayers = params[PLAYERS];
@@ -220,10 +229,15 @@
"multiplay/commando"
};
- tmdprintf("Reading in difficulty settings...\n");
- if (!read_global_config_file() ||
- !read_named_config_file("multiplay/mpoptions") ||
- !read_named_config_file(config_files[params[DIFFICULTY]]) )
+ DEBUGMSG(debug_multiplayer, "Reading in difficulty settings...\n");
+
+ success *= read_global_config_file();
+
+ success *= read_named_config_file("multiplay/mpoptions");
+
+ success *= read_named_config_file(config_files[params[DIFFICULTY]]);
+
+ if (!success)
{
printf("Couldn't read in settings for %s\n",
config_files[params[DIFFICULTY]] );
Modified: tuxmath/branches/lan/src/options.c
===================================================================
--- tuxmath/branches/lan/src/options.c 2009-09-02 10:50:25 UTC (rev 1476)
+++ tuxmath/branches/lan/src/options.c 2009-09-03 22:06:06 UTC (rev 1477)
@@ -13,7 +13,7 @@
Part of "Tux4Kids" Project
http://www.tux4kids.com
-
+
August 26, 2001 - July 11, 2007
*/
@@ -30,6 +30,7 @@
#include "fileops.h"
#include "setup.h"
#include "game.h"
+#include "globals.h"
//#include "tuxmath.h"
/* FIXME figure out what oper_override is supposed to do and make sure */
@@ -37,6 +38,28 @@
//int opers[NUM_OPERS], range_enabled[NUM_Q_RANGES];
+/* global debug masks */
+int debug_status;
+
+/* bitmasks for debugging options */
+const int debug_setup = 1 << 0;
+const int debug_fileops = 1 << 1;
+const int debug_loaders = 1 << 2;
+const int debug_titlescreen = 1 << 3;
+const int debug_menu = 1 << 4;
+const int debug_menu_parser = 1 << 5;
+const int debug_game = 1 << 6;
+const int debug_factoroids = 1 << 7;
+const int debug_lan = 1 << 8;
+const int debug_mathcards = 1 << 9;
+const int debug_sdl = 1 << 10;
+const int debug_lessons = 1 << 11;
+const int debug_highscore = 1 << 12;
+const int debug_options = 1 << 13;
+const int debug_convert_utf = 1 << 14;
+const int debug_multiplayer = 1 << 15;
+const int debug_all = ~0;
+
/* extern'd constants */
const char* const OPTION_TEXT[NUM_GLOBAL_OPTS+1] = {
@@ -59,8 +82,8 @@
0,
1
};
-
+
/* file scope only now that accessor functions used: */
static game_option_type* game_options;
static global_option_type* global_options;
@@ -96,7 +119,8 @@
global_options->iopts[FULLSCREEN] = DEFAULT_FULLSCREEN;
global_options->iopts[USE_KEYPAD] = DEFAULT_USE_KEYPAD;
global_options->iopts[USE_IGLOOS] = DEFAULT_USE_IGLOOS;
- strncpy(game_options->current_font_name, DEFAULT_FONT_NAME, sizeof(game_options->current_font_name));
+ strncpy(game_options->current_font_name, DEFAULT_FONT_NAME,
+ sizeof(game_options->current_font_name));
game_options->lan_mode = DEFAULT_LAN_MODE;
game_options->use_bkgd = DEFAULT_USE_BKGD;
game_options->help_mode = DEFAULT_HELP_MODE;
@@ -125,9 +149,8 @@
game_options->num_cities = DEFAULT_NUM_CITIES; /* MUST BE AN EVEN NUMBER! */
game_options->max_city_colors = DEFAULT_MAX_CITY_COLORS;
- #ifdef TUXMATH_DEBUG
- print_game_options(stdout, 0);
- #endif
+ DEBUGCODE(debug_options)
+ print_game_options(stdout, 0);
return 1;
}
@@ -152,7 +175,7 @@
if (0 == strcasecmp(text, OPTION_TEXT[i]) )
return i;
}
- tmdprintf("'%s' isn't a global option\n", text);
+ DEBUGMSG(debug_options, "'%s' isn't a global option\n", text);
return -1;
}
@@ -168,8 +191,7 @@
{
if (index < NUM_GLOBAL_OPTS)
return global_options->iopts[index];
-
- tmdprintf("Invalid global option index: %d\n", index);
+ DEBUGMSG(debug_options, "Invalid global option index: %d\n", index);
return 0;
}
@@ -185,7 +207,7 @@
if (index < NUM_GLOBAL_OPTS)
global_options->iopts[index] = val;
else
- tmdprintf("Invalid global option index: %d\n", index);
+ DEBUGMSG(debug_options, "Invalid global option index: %d\n", index);
}
@@ -222,19 +244,18 @@
// global_options->iopts[FULLSCREEN] = int_to_bool(val);
//}
+void Opts_SetLanMode(int val)
+{
+ game_options->lan_mode = int_to_bool(val);
+}
+
+
void Opts_SetFontName(char* font_name)
{
if (font_name && font_name[0] != '\0')
strncpy(game_options->current_font_name, font_name, sizeof(game_options->current_font_name));
}
-
-void Opts_SetLanMode(int val)
-{
- game_options->lan_mode = int_to_bool(val);
-}
-
-
void Opts_SetUseBkgd(int val)
{
game_options->use_bkgd = int_to_bool(val);
@@ -596,28 +617,28 @@
// return global_options->iopts[FULLSCREEN];
//}
-const char* Opts_FontName(void)
+
+int Opts_LanMode(void)
{
if (!game_options)
{
- fprintf(stderr, "\nOpts_FontName(): game_options not valid!\n");
- return NULL;
+ fprintf(stderr, "\nOpts_LanMode(): game_options not valid!\n");
+ return GAME_OPTS_INVALID;
}
- return (const char*) game_options->current_font_name;
+ return game_options->lan_mode;
}
+
-
-int Opts_LanMode(void)
+const char* Opts_FontName(void)
{
if (!game_options)
{
- fprintf(stderr, "\nOpts_LanMode(): game_options not valid!\n");
- return GAME_OPTS_INVALID;
+ fprintf(stderr, "\nOpts_FontName(): game_options not valid!\n");
+ return NULL;
}
- return game_options->lan_mode;
+ return (const char*) game_options->current_font_name;
}
-
int Opts_UseBkgd(void)
{
if (!game_options)
Modified: tuxmath/branches/lan/src/scandir.c
===================================================================
--- tuxmath/branches/lan/src/scandir.c 2009-09-02 10:50:25 UTC (rev 1476)
+++ tuxmath/branches/lan/src/scandir.c 2009-09-03 22:06:06 UTC (rev 1477)
@@ -29,9 +29,9 @@
#include "scandir.h"
/*-----------------------------------------------------------------------
- * Here come alphasort and scandir for BeOS and SunOS
+ * Here come alphasort and scandir for BeOS/Haiku and SunOS
*-----------------------------------------------------------------------*/
-#if defined(__BEOS__) || (defined(__sun) && defined(__SVR4))
+#if defined(__BEOS__) || defined(__HAIKU__) || (defined(__sun) && defined(__SVR4))
#undef DIRSIZ
Modified: tuxmath/branches/lan/src/scandir.h
===================================================================
--- tuxmath/branches/lan/src/scandir.h 2009-09-02 10:50:25 UTC (rev 1476)
+++ tuxmath/branches/lan/src/scandir.h 2009-09-03 22:06:06 UTC (rev 1477)
@@ -19,7 +19,7 @@
#define dirent direct
#endif
-#if defined(__BEOS__) || (defined(__sun) && defined(__SVR4)) || defined(WIN32)
+#if defined(__BEOS__) || defined(__HAIKU__) || (defined(__sun) && defined(__SVR4)) || defined(WIN32)
extern int alphasort(const void *d1, const void *d2);
extern int scandir(const char *dirname, struct dirent ***namelist, int (*sdfilter)(struct dirent *), int (*dcomp)(const void *, const void *));
#endif
Modified: tuxmath/branches/lan/src/setup.c
===================================================================
--- tuxmath/branches/lan/src/setup.c 2009-09-02 10:50:25 UTC (rev 1476)
+++ tuxmath/branches/lan/src/setup.c 2009-09-03 22:06:06 UTC (rev 1477)
@@ -37,7 +37,7 @@
#endif
#include "SDL_image.h"
-#include "transtruct.h"
+
#include "options.h"
#include "tuxmath.h"
#include "mathcards.h"
@@ -45,6 +45,7 @@
#include "fileops.h"
#include "loaders.h"
#include "game.h"
+#include "menu.h"
#include "titlescreen.h"
#include "highscore.h"
#include "SDL_extras.h"
@@ -57,11 +58,17 @@
/* Global data used in setup.c: */
/* (These are now 'extern'd in "tuxmath.h") */
-int fs_res_x = RES_X;
-int fs_res_y = RES_Y;
+/* window size */
+int win_res_x = 640;
+int win_res_y = 480;
+/* full screen size (set in initialize_SDL() ) */
+int fs_res_x = 0;
+int fs_res_y = 0;
+
SDL_Surface* screen;
SDL_Surface* images[NUM_IMAGES];
+sprite* sprites[NUM_SPRITES];
/* Need special handling to generate flipped versions of images. This
is a slightly ugly hack arising from the use of the enum trick for
NUM_IMAGES. */
@@ -85,7 +92,6 @@
Mix_Music* musics[NUM_MUSICS];
#endif
-
/* Local function prototypes: */
void initialize_options(void);
void handle_command_args(int argc, char* argv[]);
@@ -116,7 +122,7 @@
initialize_SDL();
/* Read image and sound files: */
load_data_files();
- /* Generate flipped versions of walking images */
+ /* Generate flipped versions of walking images */
generate_flipped_images();
/* Generate blended images (e.g., igloos) */
generate_blended_images();
@@ -197,9 +203,8 @@
/* (can still proceed). */
}
-#ifdef TUXMATH_DEBUG
- print_high_scores(stdout);
-#endif
+ DEBUGCODE(debug_setup)
+ print_high_scores(stdout);
}
@@ -400,7 +405,66 @@
Opts_SetSpeed(strtod(argv[i + 1], (char **) NULL));
i++;
}
-
+ else if (strcmp(argv[i], "--debug-all") == 0)
+ {
+ debug_status |= debug_all;
+ }
+ else if (strcmp(argv[i], "--debug-setup") == 0)
+ {
+ debug_status |= debug_setup;
+ }
+ else if (strcmp(argv[i], "--debug-fileops") == 0)
+ {
+ debug_status |= debug_fileops;
+ }
+ else if (strcmp(argv[i], "--debug-loaders") == 0)
+ {
+ debug_status |= debug_loaders;
+ }
+ else if (strcmp(argv[i], "--debug-titlescreen") == 0)
+ {
+ debug_status |= debug_titlescreen;
+ }
+ else if (strcmp(argv[i], "--debug-menu") == 0)
+ {
+ debug_status |= debug_menu;
+ }
+ else if (strcmp(argv[i], "--debug-menu-parser") == 0)
+ {
+ debug_status |= debug_menu_parser;
+ }
+ else if (strcmp(argv[i], "--debug-game") == 0)
+ {
+ debug_status |= debug_game;
+ }
+ else if (strcmp(argv[i], "--debug-factoroids") == 0)
+ {
+ debug_status |= debug_factoroids;
+ }
+ else if (strcmp(argv[i], "--debug-lan") == 0)
+ {
+ debug_status |= debug_lan;
+ }
+ else if (strcmp(argv[i], "--debug-mathcards") == 0)
+ {
+ debug_status |= debug_mathcards;
+ }
+ else if (strcmp(argv[i], "--debug-sdl") == 0)
+ {
+ debug_status |= debug_sdl;
+ }
+ else if (strcmp(argv[i], "--debug-lessons") == 0)
+ {
+ debug_status |= debug_lessons;
+ }
+ else if (strcmp(argv[i], "--debug-highscore") == 0)
+ {
+ debug_status |= debug_highscore;
+ }
+ else if (strcmp(argv[i], "--debug-options") == 0)
+ {
+ debug_status |= debug_options;
+ }
else
/* TODO try to match unrecognized strings to config file names */
{
@@ -411,6 +475,7 @@
}
}/* end of command-line args */
+ DEBUGMSG(debug_setup,"debug_status: %x", debug_status);
if (Opts_DemoMode() && Opts_GetGlobalOpt(USE_KEYPAD))
{
@@ -479,11 +544,11 @@
Opts_SetSoundHWAvailable(1);
else
frequency = format = channels = 0; //more helpful than garbage
- tmdprintf("Sound mixer: frequency = %d, "
- "format = %x, "
- "channels = %d, "
- "n_timesopened = %d\n",
- frequency,format,channels,n_timesopened);
+ DEBUGMSG(debug_setup, "Sound mixer: frequency = %d, "
+ "format = %x, "
+ "channels = %d, "
+ "n_timesopened = %d\n",
+ frequency,format,channels,n_timesopened);
}
#endif
@@ -494,17 +559,17 @@
if (videoInfo->hw_available)
{
surfaceMode = SDL_HWSURFACE;
- tmdprintf("HW mode\n");
+ DEBUGMSG(debug_setup, "HW mode\n");
}
else
{
surfaceMode = SDL_SWSURFACE;
- tmdprintf("SW mode\n");
+ DEBUGMSG(debug_setup, "SW mode\n");
}
// Determine the current resolution: this will be used as the
// fullscreen resolution, if the user wants fullscreen.
- tmdprintf("Current resolution: w %d, h %d.\n",videoInfo->current_w,videoInfo->current_h);
+ DEBUGMSG(debug_setup, "Current resolution: w %d, h %d.\n",videoInfo->current_w,videoInfo->current_h);
fs_res_x = videoInfo->current_w;
fs_res_y = videoInfo->current_h;
@@ -523,7 +588,7 @@
if (!Opts_GetGlobalOpt(FULLSCREEN))
{
- screen = SDL_SetVideoMode(RES_X, RES_Y, PIXEL_BITS, surfaceMode);
+ screen = SDL_SetVideoMode(win_res_x, win_res_y, PIXEL_BITS, surfaceMode);
}
if (screen == NULL)
@@ -714,6 +779,7 @@
n_timesopened--;
}
+ UnloadMenus();
// Finally, quit SDL
SDL_Quit();
Modified: tuxmath/branches/lan/src/titlescreen.c
===================================================================
--- tuxmath/branches/lan/src/titlescreen.c 2009-09-02 10:50:25 UTC (rev 1476)
+++ tuxmath/branches/lan/src/titlescreen.c 2009-09-03 22:06:06 UTC (rev 1477)
@@ -1,54 +1,39 @@
-/***************************************************************************
- - file: titlescreen.c
- - description: splash, title and menu screen functionality
- ------------------
- begin : Thur May 4 2000
- copyright : (C) 2000 by Sam Hart
- : (C) 2003 by Jesse Andrews
- email : tuxtype-dev at tux4kids.net
+/*
+ titlescreen.c
- Modified for use in tuxmath by David Bruce - 2006-2007.
- email : <dbruce at tampabay.rr.com>
- <tuxmath-devel at lists.sourceforge.net>
- Also significantly enhanced by Tim Holy - 2007
-***************************************************************************/
+ Splash, background and title screen items.
-/***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
-
-// titlescreen.h has all of the tuxtype-related stuff:
+ begin : Thur May 4 2000
+ copyright : (C) 2000 by Sam Hart
+ : (C) 2003 by Jesse Andrews
+ email : tuxtype-dev at tux4kids.net
+
+ Modified for use in tuxmath by David Bruce - 2006-2007.
+ email : <dbruce at tampabay.rr.com>
+ <tuxmath-devel at lists.sourceforge.net>
+
+ Also significantly enhanced by Tim Holy - 2007
+
+ Part of "Tux4Kids" Project
+ http://www.tux4kids.com/
+
+ Copyright: See COPYING file that comes with this distribution.
+*/
+
#include "titlescreen.h"
-// tuxmath includes:
#include "tuxmath.h"
#include "options.h"
#include "fileops.h"
-#include "game.h"
-#include "campaign.h"
-#include "factoroids.h"
-#include "multiplayer.h"
-#include "transtruct.h"
-#include "mathcards.h"
-#include "setup.h" //for cleanup()
-#include "network.h"
+#include "setup.h"
#include "loaders.h"
-#include "credits.h"
-#include "highscore.h"
-#include "convert_utf.h" // for wide char to UTF-8 conversion
#include "SDL_extras.h"
+#include "menu.h"
/* --- Data Structure for Dirty Blitting --- */
SDL_Rect srcupdate[MAX_UPDATES];
SDL_Rect dstupdate[MAX_UPDATES];
int numupdates = 0; // tracks how many blits to be done
-char host[1024]="NULL";
-char player_name[1024];
// Colors we use:
SDL_Color black;
@@ -58,7 +43,7 @@
SDL_Color white;
SDL_Color yellow;
-// Type needed for TransWipe():
+// Type needed for trans_wipe():
struct blit {
SDL_Surface *src;
SDL_Rect *srcrect;
@@ -70,134 +55,80 @@
char **lesson_list_titles = NULL;
char **lesson_list_filenames = NULL;
int num_lessons = 0;
-//int n=0;
+/*TODO: move these constants into a config file
+ (together with menu.c constants ? ) */
+const float title_pos[4] = {0.0, 0.0, 0.3, 0.25};
+const float tux_pos[4] = {0.0, 0.6, 0.3, 0.4};
+const char* bkg_path = "title/menu_bkg.jpg";
+const char* standby_path = "status/standby.svg";
+const char* title_path = "title/title1.svg";
+const char* egg_path = "title/egg.svg";
+const char* tux_path = "tux/bigtux";
+/* beak coordinates relative to tux rect */
+const float beak_pos[4] = {0.36, 0.21, 0.27, 0.14};
-/* --- media for menus --- */
-enum {
- SPRITE_TRAINING,
- SPRITE_ARCADE,
- SPRITE_HELP,
- SPRITE_CUSTOM,
- SPRITE_OPTIONS,
- SPRITE_CADET,
- SPRITE_SCOUT,
- SPRITE_RANGER,
- SPRITE_ACE,
- SPRITE_COMMANDO,
- SPRITE_QUIT,
- SPRITE_MAIN,
- SPRITE_GOLDSTAR,
- SPRITE_NO_GOLDSTAR,
- SPRITE_TROPHY,
- SPRITE_CREDITS,
- SPRITE_ALONE,
- SPRITE_LAN,
- SPRITE_FRIENDS,
- SPRITE_FACTOROIDS,
- SPRITE_FACTORS,
- SPRITE_FRACTIONS,
- SPRITE_CAMPAIGN,
- SPRITE_SSWEEP,
- SPRITE_ELIMINATION,
- SPRITE_SERVER,
- SPRITE_CLIENT,
- N_SPRITES};
+SDL_Event event;
-const char* menu_sprite_files[N_SPRITES] =
-{
- "lesson",
- "comet",
- "help",
- "tux_config",
- "tux_config_brown",
- "tux_helmet_yellow",
- "tux_helmet_green",
- "tux_helmet_blue",
- "tux_helmet_red",
- "tux_helmet_black",
- "quit",
- "main",
- "goldstar",
- "no_goldstar",
- "trophy",
- "credits",
- "alone",
- "lan",
- "friends",
- "factoroids",
- "factors",
- "fractions",
- "fleet",
- "nums",
- "exclamation"
-};
+/* screen dimensions to which titlescreen graphics are currently rendered */
+int curr_res_x = -1;
+int curr_res_y = -1;
-sprite **sprite_list = NULL;
+/* titlescreen items */
+SDL_Surface* win_bkg = NULL;
+SDL_Surface* fs_bkg = NULL;
+SDL_Surface* logo = NULL;
sprite* Tux = NULL;
+SDL_Surface* title = NULL;
-
-SDL_Event event;
-
-/* --- locations we need --- */
-
-SDL_Rect dest,
- Tuxdest,
- Titledest,
- stopRect,
- Backrect,
- Tuxback,
- Titleback,
- cursor,
- beak;
-
-/* The background image scaled to windowed 640x480 */
-SDL_Surface* bkg = NULL;
-/* The background image scaled to fullscreen dimensions */
-SDL_Surface* scaled_bkg = NULL;
/* "Easter Egg" cursor */
SDL_Surface* egg = NULL;
int egg_active = 0; //are we currently using the egg cursor?
+/* locations we need */
+SDL_Rect bkg_rect,
+ logo_rect,
+ tux_rect,
+ title_rect,
+ cursor,
+ beak;
SDL_Surface* current_bkg()
/* This syntax makes my brain start to explode! */
- { return screen->flags & SDL_FULLSCREEN ? scaled_bkg : bkg; }
+ { return screen->flags & SDL_FULLSCREEN ? fs_bkg : win_bkg; }
+void set_current_bkg(SDL_Surface* new_bkg)
+{
+ if(screen->flags & SDL_FULLSCREEN)
+ {
+ if(fs_bkg != NULL)
+ SDL_FreeSurface(fs_bkg);
+ fs_bkg = new_bkg;
+ }
+ else
+ {
+ if(win_bkg != NULL)
+ SDL_FreeSurface(win_bkg);
+ win_bkg = new_bkg;
+ }
+}
+
/* Local function prototypes: */
-void TitleScreen_load_menu(void);
-void TitleScreen_unload_menu(void);
-int TitleScreen_load_media(void);
-void TitleScreen_unload_media(void);
void NotImplemented(void);
-void TransWipe(SDL_Surface* newbkg, int type, int var1, int var2);
-void UpdateScreen(int* frame);
-void AddRect(SDL_Rect* src, SDL_Rect* dst);
-void InitEngine(void);
-void ShowMessage(const char* str1, const char* str2, const char* str3, const char* str4);
-void RecalcTitlePositions();
-void RecalcMenuPositions(int*, int, menu_options*, void (*)(menu_options*),
- SDL_Rect**, SDL_Rect**, SDL_Rect**,
- SDL_Rect**, SDL_Rect**, SDL_Rect**,
- SDL_Rect*, SDL_Rect*);
-void set_buttons_max_width(SDL_Rect *, SDL_Rect *, int);
-int run_login_menu(void);
-int run_main_menu(void);
-int run_game_menu(void);
-int run_multiplay_menu(void);
-int run_lessons_menu(void);
-int run_arcade_menu(void);
-int run_campaign_menu(void);
-int run_custom_menu(void);
-int run_activities_menu(void);
-int run_options_menu(void);
-int run_lan_menu(void);
-int run_server_menu(void);
+void free_titlescreen(void);
+
+void trans_wipe(SDL_Surface* newbkg, int type, int var1, int var2);
+void init_blits(void);
+void update_screen(int* frame);
+void add_rect(SDL_Rect* src, SDL_Rect* dst);
+
int handle_easter_egg(const SDL_Event* evt);
+
+
/***********************************************************/
/* */
/* "Public functions" (callable throughout program) */
@@ -205,56 +136,64 @@
/***********************************************************/
-
-/****************************************
-* TitleScreen: Display the title screen *
-****************************************/
-
-/* display title screen, get input */
-
+/* Display Tux4Kids logo, then animate title screen
+ items onto the screen and run main menu */
void TitleScreen(void)
{
+ Uint32 start_time = 0;
+ SDL_Rect tux_anim, title_anim;
+ int i, tux_pix_skip, title_pix_skip, curr_time;
- Uint32 start = 0;
-
- int i,TuxPixSkip,TitlePixSkip;
-// int n_subdirs;
-// char **subdir_names;
-
-
if (Opts_UsingSound())
{
Opts_SetGlobalOpt(MENU_SOUND, 1);
Opts_SetGlobalOpt(MENU_MUSIC, 1);
-// menu_music = localsettings.menu_music;
}
- InitEngine(); //set up pointers for blitting structure.
+ start_time = SDL_GetTicks();
+ logo = LoadImage(standby_path, IMG_REGULAR);
- start = SDL_GetTicks();
-
-
- /* StandbyScreen: Display the Standby screen: */
- if (images[IMG_STANDBY])
+ /* display the Standby screen */
+ if(logo)
{
- // Center horizontally
- dest.x = ((screen->w) / 2) - (images[IMG_STANDBY]->w) / 2;
- // Center vertically
- dest.y = ((screen->h) / 2) - (images[IMG_STANDBY]->h) / 2;
- dest.w = images[IMG_STANDBY]->w;
- dest.h = images[IMG_STANDBY]->h;
+ /* Center horizontally and vertically */
+ logo_rect.x = (screen->w - logo->w) / 2;
+ logo_rect.y = (screen->h - logo->h) / 2;
+ logo_rect.w = logo->w;
+ logo_rect.h = logo->h;
+
SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0));
- SDL_BlitSurface(images[IMG_STANDBY], NULL, screen, &dest);
+ SDL_BlitSurface(logo, NULL, screen, &logo_rect);
SDL_UpdateRect(screen, 0, 0, 0, 0);
- // Play "harp" greeting sound lifted from Tux Paint:
+ /* Play "harp" greeting sound lifted from Tux Paint */
playsound(SND_HARP);
- }
+ SDL_FreeSurface(logo);
+ /* load menus */
+ LoadMenus();
+ }
+ /* load backgrounds */
+ LoadBothBkgds(bkg_path, &fs_bkg, &win_bkg);
+ if(fs_bkg == NULL || win_bkg == NULL)
+ {
+ fprintf(stderr, "Backgrounds were not properly loaded, exiting");
+ if(fs_bkg)
+ SDL_FreeSurface(fs_bkg);
+ if(win_bkg)
+ SDL_FreeSurface(win_bkg);
+ return;
+ }
- /* --- wait --- */
+ /* load titlescreen images */
+ if(RenderTitleScreen() == 0)
+ {
+ fprintf(stderr, "Media was not properly loaded, exiting");
+ return;
+ }
- while ((SDL_GetTicks() - start) < 2000)
+ /* --- wait --- */
+ while ((SDL_GetTicks() - start_time) < 2000)
{
/* Check to see if user pressed escape */
if (SDL_PollEvent(&event)
@@ -265,123 +204,72 @@
}
SDL_Delay(50);
}
-#ifndef TUXMATH_DEBUG //in case of a freeze, this traps the cursor
- SDL_WM_GrabInput(SDL_GRAB_ON); // User input goes to TuxMath, not window manager
-#endif
+
+ /* NOTE: do we need this ? */
+ DEBUGCODE(debug_titlescreen)
+ SDL_WM_GrabInput(SDL_GRAB_OFF); /* in case of a freeze, this traps the cursor */
+ else
+ SDL_WM_GrabInput(SDL_GRAB_ON); /* User input goes to TuxMath, not window manager */
SDL_ShowCursor(1);
- /***************************
- * Tux and Title animations *
- ***************************/
+ /* Tux and Title animations */
+ DEBUGMSG(debug_titlescreen, "TitleScreen(): Now Animating Tux and Title onto the screen\n" );
-#ifdef TUXMATH_DEBUG
- fprintf(stderr, "->Now Animating Tux and Title onto the screen\n" );
-#endif
-
- /* Load media and menu data: */
- /* FIXME should get out if needed media not loaded OK */
- if (TitleScreen_load_media() == 0) {
- fprintf(stderr,"Media was not properly loaded, exiting");
- return;
- }
-
- /* Draw background, if it loaded OK: */
- if (current_bkg() )
+ /* Draw background (center it if it's smaller than screen) */
+ if(current_bkg())
{
- Backrect.x = (screen->w - current_bkg()->w) / 2;
- Backrect.y = (screen->h - current_bkg()->h) / 2;
- Backrect.w = current_bkg()->w;
- Backrect.h = current_bkg()->h;
- /* FIXME not sure TransWipe() works in Windows: */
- TransWipe(current_bkg(), RANDOM_WIPE, 10, 20);
- /* Make sure background gets drawn (since TransWipe() doesn't */
+ /* FIXME not sure trans_wipe() works in Windows: */
+ trans_wipe(current_bkg(), RANDOM_WIPE, 10, 20);
+ /* Make sure background gets drawn (since trans_wipe() doesn't */
/* seem to work reliably as of yet): */
- SDL_BlitSurface(current_bkg(), NULL, screen, &Backrect);
-
+ SDL_BlitSurface(current_bkg(), NULL, screen, &bkg_rect);
}
- /* Red "Stop" circle in upper right corner to go back to main menu: */
- if (images[IMG_STOP])
- {
- stopRect.w = images[IMG_STOP]->w;
- stopRect.h = images[IMG_STOP]->h;
- stopRect.x = screen->w - images[IMG_STOP]->w;
- stopRect.y = 0;
- SDL_BlitSurface(images[IMG_STOP], NULL, screen, &stopRect);
- }
- SDL_UpdateRect(screen, 0, 0, 0, 0);
/* --- Pull tux & logo onscreen --- */
- /* NOTE we wind up with Tuxdest.y == (screen->h) - (Tux->frame[0]->h), */
- /* a nd Titledest.x == 0. */
- if (current_bkg()
- && images[IMG_MENU_TITLE]
- && images[IMG_STOP]
- && Tux && Tux->frame[0])
+ if(title && Tux && Tux->frame[0])
{
+ /* final tux & title positioins are already calculated,
+ start outside the screen */
+ tux_anim = tux_rect;
+ tux_anim.y = screen->h;
- Tuxdest.x = 0;
- Tuxdest.y = screen->h;
- /*
- Tuxback.x = Tuxdest.x - Backrect.x;
- Tuxback.y = Tuxdest.y - Backrect.y;
- */
- Tuxdest.w = Tuxback.w = Tux->frame[0]->w;
- Tuxdest.h = Tuxback.h = Tux->frame[0]->h;
+ title_anim = title_rect;
+ title_anim.x = screen->w;
-
- Titledest.x = screen->w;
- Titledest.y = 10;
- /*
- Titleback.x = Titledest.x - Backrect.x;
- Titleback.y = Titledest.y - Backrect.y;
- */
- Titledest.w = Titleback.w = images[IMG_MENU_TITLE]->w;
- Titledest.h = Titleback.h = images[IMG_MENU_TITLE]->h;
-
- TuxPixSkip = Tux->frame[0]->h / (PRE_ANIM_FRAMES * PRE_FRAME_MULT);
- TitlePixSkip = (screen->w) / (PRE_ANIM_FRAMES * PRE_FRAME_MULT);
-
- for (i = 0; i < (PRE_ANIM_FRAMES * PRE_FRAME_MULT); i++)
+ for(i = 0; i < ANIM_FRAMES; i++)
{
- start = SDL_GetTicks();
+ start_time = SDL_GetTicks();
- //Draw the entire background, over a black screen if necessary
- if (current_bkg()->w != screen->w || current_bkg()->h != screen->h)
+ /* Draw the entire background, over a black screen if necessary */
+ if(current_bkg()->w != screen->w || current_bkg()->h != screen->h)
SDL_FillRect(screen, &screen->clip_rect, 0);
- SDL_BlitSurface(current_bkg(), NULL, screen, &Backrect);
- Tuxdest.y -= TuxPixSkip;
- //Tuxback.y -= Tux->frame[0]->h / (PRE_ANIM_FRAMES * PRE_FRAME_MULT);
- Titledest.x -= TitlePixSkip;
- //Titleback.y -= (screen->w) / (PRE_ANIM_FRAMES * PRE_FRAME_MULT);
+ SDL_BlitSurface(current_bkg(), NULL, screen, &bkg_rect);
- SDL_BlitSurface(Tux->frame[0], NULL, screen, &Tuxdest);
- SDL_BlitSurface(images[IMG_MENU_TITLE], NULL, screen, &Titledest);
- SDL_BlitSurface(images[IMG_STOP], NULL, screen, &stopRect);
+ /* calculate shifts */
+ tux_pix_skip = (tux_anim.y - tux_rect.y) / (ANIM_FRAMES - i);
+ tux_anim.y -= tux_pix_skip;
+ title_pix_skip = (title_anim.x - title_rect.x) / (ANIM_FRAMES - i);
+ title_anim.x -= title_pix_skip;
- SDL_UpdateRect(screen, Tuxdest.x, Tuxdest.y, Tuxdest.w, Tuxdest.h);
- SDL_UpdateRect(screen, Titledest.x, Titledest.y, Titledest.w + TitlePixSkip, Titledest.h);
- SDL_UpdateRect(screen, stopRect.x, stopRect.y, stopRect.w, stopRect.h);
+ /* update screen */
+ SDL_BlitSurface(Tux->frame[0], NULL, screen, &tux_anim);
+ SDL_BlitSurface(title, NULL, screen, &title_anim);
- while ((SDL_GetTicks() - start) < 33)
- {
- SDL_Delay(2);
- }
- }
+ SDL_UpdateRect(screen, tux_anim.x, tux_anim.y, tux_anim.w,
+ min(tux_anim.h + tux_pix_skip, screen->h - tux_anim.y));
+ SDL_UpdateRect(screen, title_anim.x, title_anim.y,
+ min(title_anim.w + title_pix_skip, screen->w - title_anim.x), title_anim.h);
-
+ curr_time = SDL_GetTicks();
+ if((curr_time - start_time) < 1000 / ANIM_FPS)
+ SDL_Delay(1000 / ANIM_FPS - (curr_time - start_time));
+ }
}
-#ifdef TUXMATH_DEBUG
- fprintf(stderr, "Tux and Title are in place now\n");
-#endif
+ DEBUGMSG(debug_titlescreen, "TitleScreen(): Tux and Title are in place now\n");
- //location of Tux's beak
- beak.x = Tuxdest.x + 70;
- beak.y = Tuxdest.y + 60;
- beak.w = beak.h = 50;
-
/* Start playing menu music if desired: */
if (Opts_GetGlobalOpt(MENU_MUSIC))
{
@@ -389,101 +277,194 @@
}
/* If necessary, have the user log in */
- if (run_login_menu() != -1) {
+ if (RunLoginMenu() != -1) {
/* Finish parsing user options */
initialize_options_user();
/* Start the main menu */
- run_main_menu();
+ RunMainMenu();
}
/* User has selected quit, clean up */
+ DEBUGMSG(debug_titlescreen, "TitleScreen(): Freeing title screen images\n");
+ free_titlescreen();
-#ifdef TUXMATH_DEBUG
- fprintf(stderr, "->>Freeing title screen images\n");
-#endif
+ DEBUGMSG(debug_titlescreen, "leaving TitleScreen()\n");
+}
- TitleScreen_unload_media();
-
-#ifdef TUXMATH_DEBUG
- fprintf(stderr,"->TitleScreen():END \n");
-#endif
-
+void DrawTitleScreen(void)
+{
+ SDL_BlitSurface(current_bkg(), NULL, screen, &bkg_rect);
+ SDL_BlitSurface(Tux->frame[0], NULL, screen, &tux_rect);
+ SDL_BlitSurface(title, NULL, screen, &title_rect);
+ //SDL_UpdateRect(screen, 0, 0, 0, 0);
}
+/* Render and position all titlescreen items to match current
+ screen size. Rendering is done only if needed.
+ This function must be called after every resolution change
+ returns 1 on success, 0 on failure */
+int RenderTitleScreen(void)
+{
+ SDL_Surface* new_bkg = NULL;
+ if(curr_res_x != screen->w || curr_res_y != screen->h)
+ {
+ /* we need to rerender titlescreen items */
+ DEBUGMSG(debug_titlescreen, "Re-rendering titlescreen items.\n");
+ /* we keep two backgrounds to make screen mode switch faster */
+ if(current_bkg()->w != screen->w || current_bkg()->h != screen->h)
+ {
+ new_bkg = LoadBkgd(bkg_path, screen->w, screen->h);
+ if(new_bkg == NULL)
+ {
+ DEBUGMSG(debug_titlescreen, "RenderTitleScreen(): Failed to load new background.\n");
+ return 0;
+ }
+ else
+ {
+ DEBUGMSG(debug_titlescreen, "RenderTitleScreen(): New background loaded.\n");
+ set_current_bkg(new_bkg);
+ }
+ }
-/***********************************************************/
-/* */
-/* "Private functions" (callable only from this file) */
-/* */
-/***********************************************************/
+ bkg_rect = current_bkg()->clip_rect;
+ bkg_rect.x = (screen->w - bkg_rect.w) / 2;
+ bkg_rect.y = (screen->h - bkg_rect.h) / 2;
+ /* Tux in lower left corner of the screen */
+ SetRect(&tux_rect, tux_pos);
+ Tux = LoadSpriteOfBoundingBox(tux_path, IMG_ALPHA, tux_rect.w, tux_rect.h);
+ if(Tux && Tux->frame[0])
+ {
+ tux_rect.w = Tux->frame[0]->clip_rect.w;
+ tux_rect.h = Tux->frame[0]->clip_rect.h;
+ }
+ else
+ {
+ DEBUGMSG(debug_titlescreen, "RenderTitleScreen(): Failed to load Tux image.\n");
+ return 0;
+ }
-// 1 = success, 0 = failure
-int TitleScreen_load_media(void)
-{
- char fn[PATH_MAX];
- int i;
+ /* "Tux, of math command" title in upper right corner */
+ SetRect(&title_rect, title_pos);
+ title = LoadImageOfBoundingBox(title_path, IMG_ALPHA, title_rect.w, title_rect.h);
+ if(title)
+ {
+ title_rect.w = title->clip_rect.w;
+ title_rect.h = title->clip_rect.h;
+ }
+ else
+ {
+ DEBUGMSG(debug_titlescreen, "RenderTitleScreen(): Failed to load title image.\n");
+ return 0;
+ }
-
-#ifdef TUXMATH_DEBUG
- fprintf(stderr, "Entering TitleScreen_load_media():\n");
+ /* easter egg */
+#ifdef HAVE_RSVG
+ egg = LoadImage(egg_path, IMG_ALPHA | IMG_NOT_REQUIRED);
+#else
+ egg = LoadImage(egg_path, IMG_COLORKEY | IMG_NOT_REQUIRED);
#endif
- Tux = LoadSprite("tux/bigtux", IMG_ALPHA);
+ beak.x = tux_rect.x + beak_pos[0] * tux_rect.w;
+ beak.y = tux_rect.y + beak_pos[1] * tux_rect.h;
+ beak.w = beak_pos[2] * tux_rect.w;
+ beak.h = beak_pos[3] * tux_rect.h;
- SDL_ShowCursor(1);
+ curr_res_x = screen->w;
+ curr_res_y = screen->h;
-#ifdef TUXMATH_DEBUG
- fprintf(stderr, "loading sprites\n");
-#endif
-
- sprite_list = (sprite**) malloc(N_SPRITES*sizeof(sprite*));
- if (sprite_list == NULL)
- return 0;
-
- for (i = 0; i < N_SPRITES; i++) {
- /* --- load animated icon for menu item --- */
- sprintf(fn, "sprites/%s", menu_sprite_files[i]);
- sprite_list[i] = LoadSprite(fn, IMG_ALPHA);
+ DEBUGMSG(debug_titlescreen, "Leaving RenderTitleScreen().\n");
}
- egg = LoadImage("title/egg.png",
- IMG_COLORKEY | IMG_NOT_REQUIRED);
- LoadBothBkgds("title/menu_bkg.jpg", &scaled_bkg, &bkg);
return 1;
}
+/* handle titlescreen events (easter egg)
+ this function should be called from event loops
+ return 1 if events require full redraw */
+int HandleTitleScreenEvents(const SDL_Event* evt)
+{
+ return handle_easter_egg(evt);
+}
-
-void TitleScreen_unload_menu(void)
+/* handle all titlescreen blitting
+ this function should be called after every animation frame */
+void HandleTitleScreenAnimations()
{
- int i;
+ static int frame_counter = 0;
+ int tux_frame;
- for (i = 0; i < N_SPRITES; i++)
+ /* --- make Tux blink --- */
+ switch (frame_counter % TUX6)
{
- tmdprintf("Freeing image %d: ", i);
- FreeSprite(sprite_list[i]);
- sprite_list[i] = NULL;
+ case 0: tux_frame = 1; break;
+ case TUX1: tux_frame = 2; break;
+ case TUX2: tux_frame = 3; break;
+ case TUX3: tux_frame = 4; break;
+ case TUX4: tux_frame = 3; break;
+ case TUX5: tux_frame = 2; break;
+ default: tux_frame = 0;
}
- free(sprite_list);
- tmdprintf("Images freed\n");
- sprite_list = NULL;
+
+ if (Tux && tux_frame)
+ {
+ /* Redraw background to keep edges anti-aliased properly: */
+ SDL_BlitSurface(current_bkg(),&tux_rect, screen, &tux_rect);
+ SDL_BlitSurface(Tux->frame[tux_frame - 1], NULL, screen, &tux_rect);
+ UpdateRect(screen, &tux_rect);
+ }
+
+ if (egg_active) { //if we need to, draw the egg cursor
+ //who knows why GetMouseState() doesn't take Sint16's...
+ SDL_GetMouseState((int*)(&cursor.x), (int*)(&cursor.y));
+ cursor.x -= egg->w / 2; //center vertically
+ SDL_BlitSurface(egg, NULL, screen, &cursor);
+ UpdateRect(screen, &cursor);
+ }
+
+ frame_counter++;
}
+/***********************************************************/
+/* */
+/* "Private functions" (callable only from this file) */
+/* */
+/***********************************************************/
-void TitleScreen_unload_media(void)
+
+void free_titlescreen(void)
{
- tmdprintf("Unloading media\n");
+ DEBUGMSG(debug_titlescreen, "Entering free_titlescreen()\n");
+
FreeSprite(Tux);
Tux = NULL;
- TitleScreen_unload_menu();
- SDL_FreeSurface(egg);
- SDL_FreeSurface(bkg);
- SDL_FreeSurface(scaled_bkg);
+ if(egg)
+ {
+ SDL_FreeSurface(egg);
+ egg = NULL;
+ }
+
+ if(title)
+ {
+ SDL_FreeSurface(title);
+ title = NULL;
+ }
+
+ if(fs_bkg)
+ {
+ SDL_FreeSurface(fs_bkg);
+ fs_bkg = NULL;
+ }
+
+ if(win_bkg)
+ {
+ SDL_FreeSurface(win_bkg);
+ win_bkg = NULL;
+ }
}
@@ -510,15 +491,12 @@
SDL_Surface *s1, *s2, *s3, *s4;
SDL_Rect loc;
int finished = 0;
- int tux_frame = 0;
Uint32 frame = 0;
Uint32 start = 0;
s1 = s2 = s3 = s4 = NULL;
-#ifdef TUXMATH_DEBUG
- fprintf(stderr, "ShowMessage() - creating text\n" );
-#endif
+ DEBUGMSG(debug_titlescreen, "ShowMessage() - creating text\n" );
if (str1)
s1 = BlackOutline(str1, DEFAULT_MENU_FONT_SIZE, &white);
@@ -529,29 +507,13 @@
if (str4)
s4 = BlackOutline(str4, DEFAULT_MENU_FONT_SIZE, &white);
-#ifdef TUXMATH_DEBUG
- fprintf(stderr, "ShowMessage() - drawing screen\n" );
-#endif
+ DEBUGMSG(debug_titlescreen, "ShowMessage() - drawing screen\n" );
- /* Redraw background: */
- if (current_bkg() )
- SDL_BlitSurface( current_bkg(), NULL, screen, &Backrect );
-
+ DrawTitleScreen();
/* Red "Stop" circle in upper right corner to go back to main menu: */
- if (images[IMG_STOP])
- {
- stopRect.w = images[IMG_STOP]->w;
- stopRect.h = images[IMG_STOP]->h;
- stopRect.x = screen->w - images[IMG_STOP]->w;
- stopRect.y = 0;
- SDL_BlitSurface(images[IMG_STOP], NULL, screen, &stopRect);
- }
+ if (stop_button)
+ SDL_BlitSurface(stop_button, NULL, screen, &stop_rect);
- if (Tux && Tux->num_frames) /* make sure sprite has at least one frame */
- {
- SDL_BlitSurface(Tux->frame[0], NULL, screen, &Tuxdest);
- }
-
/* Draw lines of text (do after drawing Tux so text is in front): */
if (s1)
{
@@ -595,7 +557,7 @@
case SDL_MOUSEBUTTONDOWN:
/* "Stop" button - go to main menu: */
{
- if (inRect(stopRect, event.button.x, event.button.y ))
+ if (inRect(stop_rect, event.button.x, event.button.y ))
{
finished = 1;
playsound(SND_TOCK);
@@ -610,25 +572,8 @@
}
}
- /* --- make tux blink --- */
- switch (frame % TUX6)
- {
- case 0: tux_frame = 1; break;
- case TUX1: tux_frame = 2; break;
- case TUX2: tux_frame = 3; break;
- case TUX3: tux_frame = 4; break;
- case TUX4: tux_frame = 3; break;
- case TUX5: tux_frame = 2; break;
- default: tux_frame = 0;
- }
+ HandleTitleScreenAnimations();
- if (Tux && tux_frame)
- {
- SDL_BlitSurface(Tux->frame[tux_frame - 1], NULL, screen, &Tuxdest);
-// SDL_UpdateRect(screen, Tuxdest.x+37, Tuxdest.y+40, 70, 45);
- SDL_UpdateRect(screen, Tuxdest.x, Tuxdest.y, Tuxdest.w, Tuxdest.h);
-
- }
/* Wait so we keep frame rate constant: */
while ((SDL_GetTicks() - start) < 33)
{
@@ -643,1805 +588,202 @@
SDL_FreeSurface(s4);
}
+/* Was in playgame.c in tuxtype: */
-void main_scmo(menu_options* mo) //set custom menu opts for main
+/* trans_wipe: Performs various wipes to new bkgs
+ Given a wipe request type, and any variables
+ that wipe requires, will perform a wipe from
+ the current screen image to a new one. */
+void trans_wipe(SDL_Surface* newbkg, int type, int var1, int var2)
{
- mo->ygap = 15;
-}
+ int i, j, x1, x2, y1, y2;
+ int step1, step2, step3, step4;
+ int frame;
+ SDL_Rect src;
+ SDL_Rect dst;
-int run_main_menu(void)
-{
- const char* menu_text[7] =
- {N_("Play Alone"),
- N_("LAN Game"),
- N_("Play With Friends"),
- N_("Factoroids!"),
- N_("Help"),
- N_("More Options"),
- N_("Quit")};
- sprite* sprites[7] =
- {NULL, NULL, NULL, NULL, NULL, NULL,NULL};
- menu_options menu_opts;
- int choice,ret;
-
- // Set up the sprites
- sprites[0] = sprite_list[SPRITE_ALONE];
- sprites[1] = sprite_list[SPRITE_LAN];
- sprites[2] = sprite_list[SPRITE_FRIENDS];
- sprites[3] = sprite_list[SPRITE_FACTOROIDS];
- sprites[4] = sprite_list[SPRITE_HELP];
- sprites[5] = sprite_list[SPRITE_OPTIONS];
- sprites[6] = sprite_list[SPRITE_QUIT];
-
- //set_default_menu_options(&menu_opts);
- //menu_opts.ytop = 100;
- //menu_opts.ygap = 15;
-
- //This function takes care of all the drawing and receives
- //user input:
- choice = choose_menu_item(menu_text,sprites,7,NULL,main_scmo);
-
- while (choice >= 0) {
- switch (choice) {
- case 0: {
- // All single player modes
- ret = run_game_menu();
- break;
- }
- case 1: {
- ret = run_lan_menu();
- break;
- }
- case 2: {
- // Multiplayer games
- ret = run_multiplay_menu();
- break;
- }
- case 3: {
- // Factroids et. al.
- ret = run_activities_menu();
- break;
- }
- case 4: {
- // Help
- Opts_SetHelpMode(1);
- Opts_SetDemoMode(0);
- if (Opts_GetGlobalOpt(MENU_MUSIC)) //Turn menu music off for game
- {audioMusicUnload();}
- game();
- RecalcTitlePositions();
- if (Opts_GetGlobalOpt(MENU_MUSIC)) //Turn menu music back on
- {audioMusicLoad( "tuxi.ogg", -1 );}
- Opts_SetHelpMode(0);
- break;
- }
- case 5: {
- // More options
- ret = run_options_menu();
- break;
- }
- case 6: {
- // Quit
- tmdprintf("Exiting main menu\n");
- return 0;
- }
- }
- menu_opts.starting_entry = choice;
- choice = choose_menu_item(menu_text,sprites,7,NULL,main_scmo);
+ if (!screen)
+ {
+ DEBUGMSG(debug_titlescreen, "trans_wipe(): screen not valid!\n");
+ return;
}
- return 0;
-}
-
-#define NUM_GAME_MENU_ITEMS 5
-int run_game_menu(void)
-{
- const char* menu_text[NUM_GAME_MENU_ITEMS] =
- {N_("Math Command Training Academy"),
- N_("Math Command Fleet Missions"),
- N_("Play Arcade Game"),
- N_("Play Custom Game"),
- N_("Main menu")};
- sprite* sprites[NUM_GAME_MENU_ITEMS] = {NULL, NULL, NULL, NULL, NULL};
-
- int ret, choice = 0;
-
- sprites[0] = sprite_list[SPRITE_TRAINING];
- sprites[1] = sprite_list[SPRITE_CAMPAIGN];
- sprites[2] = sprite_list[SPRITE_ARCADE];
- sprites[3] = sprite_list[SPRITE_CUSTOM];
- sprites[4] = sprite_list[SPRITE_MAIN];
-
- while (choice >= 0) {
- choice = choose_menu_item(menu_text,sprites,NUM_GAME_MENU_ITEMS,NULL,NULL);
- switch (choice) {
- case 0:
- ret = run_lessons_menu();
- break;
- case 1:
- ret = start_campaign();
- break;
- case 2:
- ret = run_arcade_menu();
- break;
- case 3:
- ret = run_custom_menu();
- break;
- case 4:
- return 0;
- default:
- tmdprintf("choose_menu_item() returned %d--returning\n", choice);
- return 0;
- }
- }
- return 0;
-}
-
-/*
-Set up and start a turn-based multiplayer game. Some funky heap issues so
-quarantine it behind the return for the time being.
-*/
-int run_multiplay_menu(void)
-{
- int nplayers = 0;
- int mode = -1;
- int difficulty = -1;
- char npstr[HIGH_SCORE_NAME_LENGTH * 3];
-
-
- const char* menu_text[3] =
- {N_("Score Sweep"),
- N_("Elimination"),
- N_("Main menu")};
-
- //just leech settings from arcade modes
- const char* diff_menu_text[NUM_MATH_COMMAND_LEVELS + 1] =
- {N_("Space Cadet"),
- N_("Scout"),
- N_("Ranger"),
- N_("Ace"),
- N_("Commando"),
- N_("Main menu")};
-
-
- sprite* modesprites[3] = {NULL, NULL, NULL};
- sprite* diffsprites[6] = {NULL, NULL, NULL, NULL, NULL, NULL};
- // Set up the sprites
- modesprites[0] = sprite_list[SPRITE_SSWEEP];
- modesprites[1] = sprite_list[SPRITE_ELIMINATION];
- modesprites[2] = sprite_list[SPRITE_MAIN];
-
- diffsprites[0] = sprite_list[SPRITE_CADET];
- diffsprites[1] = sprite_list[SPRITE_SCOUT];
- diffsprites[2] = sprite_list[SPRITE_RANGER];
- diffsprites[3] = sprite_list[SPRITE_ACE];
- diffsprites[4] = sprite_list[SPRITE_COMMANDO];
- diffsprites[5] = sprite_list[SPRITE_MAIN];
-
- while (1)
+ if (!newbkg)
{
- //choose difficulty
- difficulty = choose_menu_item(diff_menu_text, diffsprites,
- NUM_MATH_COMMAND_LEVELS + 1, NULL, NULL);
-
- if (difficulty == -1 || difficulty >= NUM_MATH_COMMAND_LEVELS)
- break; //user chose main menu or hit escape
-
- //choose mode
- mode = choose_menu_item(menu_text,modesprites,3,NULL,NULL);
- if (mode == 2 || mode == -1)
- break;
-
- //ask how many players
- while (nplayers <= 0 || nplayers > MAX_PLAYERS)
- {
- NameEntry(npstr, _("How many kids are playing?"),
- _("(Between 2 and 4 players)"));
- nplayers = atoi(npstr);
- }
-
-
- mp_set_parameter(PLAYERS, nplayers);
- mp_set_parameter(MODE, mode);
- mp_set_parameter(DIFFICULTY, difficulty);
-
- //RUN!
- mp_run_multiplayer();
+ DEBUGMSG(debug_titlescreen, "trans_wipe(): newbkg not valid!\n");
+ return;
}
- return 0;
-}
+ init_blits();
-/////////////////////////// LAN game menu()////////////
+ numupdates = 0;
+ frame = 0;
+ if(newbkg->w == screen->w && newbkg->h == screen->h) {
+ if( type == RANDOM_WIPE )
+ type = (RANDOM_WIPE * ((float) rand()) / (RAND_MAX+1.0));
-int run_lan_menu(void)
-{
- int mode = -1;
- int servers_found = 0;
+ switch( type ) {
+ case WIPE_BLINDS_VERT: {
+ DEBUGMSG(debug_titlescreen, "trans_wipe(): Doing 'WIPE_BLINDS_VERT'\n");
+ /*var1 isnum ofdivisions
+ var2is howmany framesanimation shouldtake */
+ if(var1 <1 )var1 =1;
+ if( var2< 1) var2= 1;
+ step1= screen->w/ var1;
+ step2= step1/ var2;
- const char* menu_text[3] =
- {N_("Host"),
- N_("Join"),
- N_("Main menu")};
-
- sprite* modesprites[3] = {NULL, NULL, NULL};
- // Set up the sprites
- modesprites[0] = sprite_list[SPRITE_SERVER];
- modesprites[1] = sprite_list[SPRITE_CLIENT];
- modesprites[2] = sprite_list[SPRITE_MAIN];
-
- while (1)
- {
- //choose mode
- mode = choose_menu_item(menu_text, modesprites, 3, NULL, NULL);
- if (mode == 2 || mode == -1)
- break;
-
-// if(mode == 0) //chooses Host
-// run_server_menu();
-
- if(mode == 1)
- {
- if(detecting_servers(_("Detecting Servers"), _("Please Wait")))
- {
- int stdby;
- char buf[256];
- snprintf(buf, 256, _("Connected to server: %s"), LAN_ConnectedServerName());
- NameEntry(player_name, buf, _("Enter your Name:"));
- LAN_SetName(player_name);
- Ready(_("Click OK when Ready"));
- LAN_StartGame();
- stdby = Standby(_("Waiting For Other Players"),_("To Connect"));
- if (stdby == 1)
+ for(i= 0;i <=var2; i++)
{
- Opts_SetLanMode(1); // Tells game() we are playing over network
- game();
- Opts_SetLanMode(0); // Go back to local play
- }
- else
- {
- ShowMessage(NULL, _("Sorry, game already in progress."), NULL, NULL);
- }
- }
- else
- {
- ShowMessage(NULL, _("Sorry, no server could be found."), NULL, NULL);
- break;
- }
- }
- }
+ for(j= 0;j <=var1; j++)
+ {
+ x1= step1* (j- 0.5)- i* step2+ 1;
+ x2= step1* (j- 0.5)+ i* step2+ 1;
+ src.x= x1;
+ src.y= 0;
+ src.w= step2;
+ src.h= screen->h;
+ dst.x= x2;
+ dst.y= 0;
+ dst.w= step2;
+ dst.h= screen->h;
- return 0;
+ SDL_BlitSurface(newbkg,&src, screen,&src);
+ SDL_BlitSurface(newbkg, &dst,screen, &dst);
-}
-
-/*Dont think we need this..*/
-//int run_server_menu(void)
-//{
-
-// int difficulty = -1;
- // n=1;
-// int g;
- //just leech settings from arcade modes
-// const char* diff_menu_text[NUM_MATH_COMMAND_LEVELS + 1] =
-// {N_("Space Cadet"),
-// N_("Scout"),
-// N_("Ranger"),
-// N_("Ace"),
-// N_("Commando"),
-// N_("Main menu")};
-
-
-
-// sprite* diffsprites[6] = {NULL, NULL, NULL, NULL, NULL, NULL};
-
-
-// diffsprites[0] = sprite_list[SPRITE_CADET];
-// diffsprites[1] = sprite_list[SPRITE_SCOUT];
-// diffsprites[2] = sprite_list[SPRITE_RANGER];
-// diffsprites[3] = sprite_list[SPRITE_ACE];
-// diffsprites[4] = sprite_list[SPRITE_COMMANDO];
-// diffsprites[5] = sprite_list[SPRITE_MAIN];
-
-// while (1)
-// {
- //choose difficulty
-// difficulty = choose_menu_item(diff_menu_text,diffsprites,6,NULL,NULL);
-// if (difficulty == -1 || difficulty >= NUM_MATH_COMMAND_LEVELS)
-// { break;} //user chose main menu or hit escape
-// else
-// {NameEntry(port, _("Enter the PORT"),
-// _(""));
-
-// game();}
-// break;
-// }
-// return 0;
-
-
-//}
-
-
-
-
-int run_arcade_menu(void)
-{
- const char* menu_text[7] =
- {N_("Space Cadet"),
- N_("Scout"),
- N_("Ranger"),
- N_("Ace"),
- N_("Commando"),
- N_("Hall Of Fame"),
- N_("Main menu")};
- const char* arcade_config_files[5] =
- {"arcade/space_cadet",
- "arcade/scout",
- "arcade/ranger",
- "arcade/ace",
- "arcade/commando"
- };
-
- const int arcade_high_score_tables[5] =
- {CADET_HIGH_SCORE,
- SCOUT_HIGH_SCORE,
- RANGER_HIGH_SCORE,
- ACE_HIGH_SCORE,
- COMMANDO_HIGH_SCORE
- };
- sprite* sprites[7] =
- {NULL, NULL, NULL, NULL, NULL, NULL, NULL};
- menu_options menu_opts;
- int choice,hs_table;
-
- // Set up the sprites
- sprites[0] = sprite_list[SPRITE_CADET];
- sprites[1] = sprite_list[SPRITE_SCOUT];
- sprites[2] = sprite_list[SPRITE_RANGER];
- sprites[3] = sprite_list[SPRITE_ACE];
- sprites[4] = sprite_list[SPRITE_COMMANDO];
- sprites[5] = sprite_list[SPRITE_TROPHY];
- sprites[6] = sprite_list[SPRITE_MAIN];
-
-// set_default_menu_options(&menu_opts);
-// menu_opts.ytop = 100;
-
- //This function takes care of all the drawing and receives
- //user input:
- choice = choose_menu_item(menu_text, sprites, 7, NULL, NULL);
-
- while (choice >= 0) {
- if (choice < NUM_MATH_COMMAND_LEVELS) {
- // Play arcade game
- if (read_named_config_file(arcade_config_files[choice]))
- {
- audioMusicUnload();
- Opts_SetLanMode(0);
- game();
- RecalcTitlePositions();
- if (Opts_GetGlobalOpt(MENU_MUSIC)) {
- audioMusicLoad( "tuxi.ogg", -1 );
+ add_rect(&src,&src);
+ add_rect(&dst, &dst);
+ }
+ update_screen(&frame);
}
- /* See if player made high score list! */
- read_high_scores(); /* Update, in case other users have added to it */
- hs_table = arcade_high_score_tables[choice];
- if (check_score_place(hs_table, Opts_LastScore()) < HIGH_SCORES_SAVED){
- char player_name[HIGH_SCORE_NAME_LENGTH * 3];
+ src.x= 0;
+ src.y= 0;
+ src.w= screen->w;
+ src.h= screen->h;
+ SDL_BlitSurface(newbkg,NULL, screen,&src);
+ SDL_Flip(screen);
- /* Get name from player: */
- HighScoreNameEntry(&player_name[0]);
- insert_score(player_name, hs_table, Opts_LastScore());
- /* Show the high scores. Note the user will see his/her */
- /* achievement even if (in the meantime) another player */
- /* has in fact already bumped this score off the table. */
- DisplayHighScores(hs_table);
- /* save to disk: */
- /* See "On File Locking" in fileops.c */
- append_high_score(choice,Opts_LastScore(),&player_name[0]);
-
-#ifdef TUXMATH_DEBUG
- print_high_scores(stderr);
-#endif
- }
- } else {
- fprintf(stderr, "\nCould not find %s config file\n",arcade_config_files[choice]);
+ break;
}
+ case WIPE_BLINDS_HORIZ:{
+ DEBUGMSG(debug_titlescreen, "trans_wipe(): Doing 'WIPE_BLINDS_HORIZ'\n");
+ /* var1is numof divisions
+ var2 ishow manyframes animationshould take*/
+ if( var1< 1) var1= 1;
+ if(var2 <1 )var2 =1;
+ step1 =screen->h /var1;
+ step2 =step1 /var2;
- } else if (choice == NUM_MATH_COMMAND_LEVELS) {
- // Display the Hall of Fame
- DisplayHighScores(CADET_HIGH_SCORE);
- }
- else {
- // Return to main menu
- return 0;
- }
- set_default_menu_options(&menu_opts);
- menu_opts.starting_entry = choice;
- choice = choose_menu_item(menu_text,sprites,7,NULL, NULL);
- }
+ for(i =0; i<= var2;i++) {
+ for(j= 0;j <=var1; j++){
+ y1 =step1 *(j -0.5) -i *step2 +1;
+ y2 =step1 *(j -0.5) +i *step2 +1;
+ src.x =0;
+ src.y =y1;
+ src.w =screen->w;
+ src.h =step2;
+ dst.x =0;
+ dst.y =y2;
+ dst.w =screen->w;
+ dst.h =step2;
- return 0;
-}
+ SDL_BlitSurface(newbkg, &src,screen, &src);
+ SDL_BlitSurface(newbkg,&dst, screen,&dst);
-
-int run_custom_menu(void)
-{
- const char *s1, *s2, *s3, *s4;
- s1 = _("Edit 'options' file in your home directory");
- s2 = _("to create customized game!");
- s3 = _("Press a key or click your mouse to start game.");
- s4 = _("See README.txt for more information");
- ShowMessage(s1, s2, s3, s4);
-
- if (read_user_config_file()) {
- if (Opts_GetGlobalOpt(MENU_MUSIC))
- audioMusicUnload();
-
- game();
- RecalcTitlePositions();
- write_user_config_file();
-
- if (Opts_GetGlobalOpt(MENU_MUSIC))
- audioMusicLoad( "tuxi.ogg", -1 );
- }
-
- return 0;
-}
-
-int run_activities_menu(void)
-{
- const char* menu_text[3] =
- {N_("Factors"),
- N_("Fractions"),
- N_("Main menu")};
- const int factoroids_high_score_tables[2] =
- {FACTORS_HIGH_SCORE, FRACTIONS_HIGH_SCORE};
- sprite* sprites[3] =
- {NULL, NULL, NULL};
- menu_options menu_opts;
- int choice, hs_table;
-
- // Set up the sprites
- sprites[0] = sprite_list[SPRITE_FACTORS];
- sprites[1] = sprite_list[SPRITE_FRACTIONS];
- sprites[2] = sprite_list[SPRITE_MAIN];
-
- set_default_menu_options(&menu_opts);
- menu_opts.ytop = 100;
-
- //This function takes care of all the drawing and receives
- //user input:
- choice = choose_menu_item(menu_text, sprites, 3, NULL, NULL);
-
- while (choice >= 0) {
- switch(choice){
- case 0:
- audioMusicUnload();
- factors();
-
- if (Opts_GetGlobalOpt(MENU_MUSIC)) {
- audioMusicLoad( "tuxi.ogg", -1 );
- }
- break;
- case 1:
- audioMusicUnload();
- fractions();
-
- if (Opts_GetGlobalOpt(MENU_MUSIC)) {
- audioMusicLoad( "tuxi.ogg", -1 );
- }
- break;
- case 2:
- // Return to main menu
- return 0;
- }
-
- hs_table = factoroids_high_score_tables[choice];
- if (check_score_place(hs_table, Opts_LastScore()) < HIGH_SCORES_SAVED){
-
- char player_name[HIGH_SCORE_NAME_LENGTH * 3];
-
- /* Get name from player: */
- HighScoreNameEntry(&player_name[0]);
- insert_score(player_name, hs_table, Opts_LastScore());
- /* Show the high scores. Note the user will see his/her */
- /* achievement even if (in the meantime) another player */
- /* has in fact already bumped this score off the table. */
- DisplayHighScores(hs_table);
- /* save to disk: */
- /* See "On File Locking" in fileops.c */
- append_high_score(hs_table,Opts_LastScore(),&player_name[0]);
-
-#ifdef TUXMATH_DEBUG
- print_high_scores(stderr);
-#endif
- }
- else {
- fprintf(stderr, "\nCould not find config file\n");
- }
-
- menu_opts.starting_entry = choice;
- choice = choose_menu_item(menu_text,sprites,3,NULL,NULL);
-
-
- }
-
-
- return 0;
-}
-
-
-int run_options_menu(void)
-{
- /*
- // Use the following version if we get "Settings" implemented
- const unsigned char* menu_text[5] =
- {(const unsigned char*)N_("Settings"),
- (const unsigned char*)N_("Demo"),
- (const unsigned char*)N_("Credits"),
- (const unsigned char*)N_("Project Info"),
- (const unsigned char*)N_("Main Menu")};
- sprite* sprites[5] =
- {NULL, NULL, NULL, NULL, NULL};
- */
- const char* menu_text[4] =
- {N_("Demo"),
- N_("Project Info"),
- N_("Credits"),
- N_("Main Menu")};
-
- sprite* sprites[4] =
- {NULL, NULL, NULL, NULL};
- int n_menu_entries = 4;
- menu_options menu_opts;
- int choice;
-
- // Set up the sprites
- sprites[0] = sprite_list[SPRITE_ARCADE];
- sprites[1] = sprite_list[SPRITE_HELP];
- sprites[2] = sprite_list[SPRITE_CREDITS];
- sprites[3] = sprite_list[SPRITE_MAIN];
-
- //set_default_menu_options(&menu_opts);
- //menu_opts.ytop = 100;
-
- //This function takes care of all the drawing and receives
- //user input:
- choice = choose_menu_item(menu_text, sprites, n_menu_entries, NULL, NULL);
-
- while (choice >= 0) {
- switch (choice) {
- /*
- case 0: {
- // Settings
- NotImplemented();
- break;
- }*/
- case 0: {
- // Demo
- if (read_named_config_file("demo"))
- {
- audioMusicUnload();
- game();
- RecalcTitlePositions();
- if (Opts_GetGlobalOpt(MENU_MUSIC)) {
- audioMusicLoad( "tuxi.ogg", -1 );
+ add_rect(&src, &src);
+ add_rect(&dst,&dst);
+ }
+ update_screen(&frame);
}
- } else {
- fprintf(stderr, "\nCould not find demo config file\n");
- }
- break;
- }
- case 1: {
- // Project Info
- //NotImplemented();
- ShowMessage(_("TuxMath is free and open-source!"),
- _("You can help make it better by reporting problems,"),
- _("suggesting improvements, or adding code."),
- _("Discuss the future at tuxmath-devel at lists.sourceforge.net"));
- break;
- }
- case 2: {
- // Credits
- //TitleScreen_unload_media();
- credits();
- //TitleScreen_load_media();
- break;
- }
- case 3: {
- // Main menu
- return 0;
- }
- }
+ src.x =0;
+ src.y =0;
+ src.w =screen->w;
+ src.h =screen->h;
+ SDL_BlitSurface(newbkg, NULL,screen, &src);
+ SDL_Flip(screen);
- set_default_menu_options(&menu_opts);
- menu_opts.starting_entry = choice;
- choice = choose_menu_item(menu_text,sprites,n_menu_entries,NULL,NULL);
- }
-
- return 0;
-}
-
-
-void lessons_scmo(menu_options* mo)
-{
-mo->ytop = 30;
-}
-/* Display a list of tuxmath config files in the missions directory */
-/* and allow the player to pick one (AKA "Lessons"). */
-
-/* returns 0 if user pressed escape
- * 1 if config was set correctly
- */
-int run_lessons_menu(void)
-{
- int chosen_lesson = -1;
- menu_options menu_opts;
- sprite** star_sprites = NULL;
-
- /* Set up sprites (as long as gold star list is valid) */
- if (lesson_list_goldstars != NULL)
- {
- int i;
- star_sprites = (sprite**)malloc(num_lessons * sizeof(sprite*));
- for (i = 0; i < num_lessons; i++)
- {
- if (lesson_list_goldstars[i])
- star_sprites[i] = sprite_list[SPRITE_GOLDSTAR];
- else
- star_sprites[i] = sprite_list[SPRITE_NO_GOLDSTAR];
- }
- }
-// set_default_menu_options(&menu_opts);
-// ytop = 30;
-
- //This function takes care of all the drawing and receives
- //user input:
- chosen_lesson = choose_menu_item((const char**)lesson_list_titles, star_sprites, num_lessons, NULL, &lessons_scmo);
-
- while (chosen_lesson >= 0)
- {
- if (Opts_GetGlobalOpt(MENU_SOUND))
- playsound(SND_POP);
-
- /* Re-read global settings first in case any settings were */
- /* clobbered by other lesson or arcade games this session: */
- read_global_config_file();
- /* Now read the selected file and play the "mission": */
- if (read_named_config_file(lesson_list_filenames[chosen_lesson]))
- {
- if (Opts_GetGlobalOpt(MENU_MUSIC)) //Turn menu music off for game
- {audioMusicUnload();}
-
- Opts_SetLanMode(0);
- game();
- RecalcTitlePositions();
-
- /* If successful, display Gold Star for this lesson! */
- if (MC_MissionAccomplished())
- {
- lesson_list_goldstars[chosen_lesson] = 1;
- star_sprites[chosen_lesson] = sprite_list[SPRITE_GOLDSTAR];
- /* and save to disk: */
- write_goldstars();
+ break;
}
+ case WIPE_BLINDS_BOX:{
+ DEBUGMSG(debug_titlescreen, "trans_wipe(): Doing 'WIPE_BLINDS_BOX'\n");
+ /* var1is numof divisions
+ var2 ishow manyframes animationshould take*/
+ if( var1< 1) var1= 1;
+ if(var2 <1 )var2 =1;
+ step1 =screen->w /var1;
+ step2 =step1 /var2;
+ step3 =screen->h /var1;
+ step4 =step1 /var2;
- if (Opts_GetGlobalOpt(MENU_MUSIC)) //Turn menu music back on
- {audioMusicLoad("tuxi.ogg", -1);}
- }
- else // Something went wrong - could not read lesson config file:
- {
- fprintf(stderr, "\nCould not find file: %s\n", lesson_list_filenames[chosen_lesson]);
- chosen_lesson = -1;
- }
- // Let the user choose another lesson; start with the screen and
- // selection that we ended with
- set_default_menu_options(&menu_opts);
- menu_opts.starting_entry = chosen_lesson;
- chosen_lesson = choose_menu_item((const char**)lesson_list_titles, star_sprites, num_lessons, &menu_opts, &lessons_scmo);
- }
- if (star_sprites)
- {
- free(star_sprites);
- star_sprites = NULL;
- }
+ for(i =0; i<= var2;i++) {
+ for(j= 0;j <=var1; j++){
+ x1 =step1 *(j -0.5) -i *step2 +1;
+ x2 =step1 *(j -0.5) +i *step2 +1;
+ src.x =x1;
+ src.y =0;
+ src.w =step2;
+ src.h =screen->h;
+ dst.x =x2;
+ dst.y =0;
+ dst.w =step2;
+ dst.h =screen->h;
- if (chosen_lesson < 0)
- return 0;
- else
- return 1;
-}
+ SDL_BlitSurface(newbkg, &src,screen, &src);
+ SDL_BlitSurface(newbkg,&dst, screen,&dst);
-
-/* Sets the user home directory in a tree of possible users */
-/* -1 indicates that the user wants to quit without logging in, */
-/* 0 indicates that a choice has been made. */
-int run_login_menu(void)
-{
- int n_login_questions = 0;
- char **user_login_questions = NULL;
- int n_users = 0;
- char **user_names = NULL;
- menu_options menu_opts;
- int chosen_login = -1;
- int level;
- int i;
- char *trailer_quit = "Quit";
- char *trailer_back = "Back";
- SDLMod mod;
-
- // Check for & read user_login_questions file
- n_login_questions = read_user_login_questions(&user_login_questions);
-
- // Check for & read user_menu_entries file
- n_users = read_user_menu_entries(&user_names);
-
- if (n_users == 0)
- return 0; // a quick exit, there's only one user
-
- // Check for a highscores file
- if (high_scores_found_in_user_dir())
- set_high_score_path();
-
- level = 0;
- set_default_menu_options(&menu_opts);
- if (n_login_questions > 0)
- menu_opts.title = user_login_questions[0];
- menu_opts.trailer = trailer_quit;
-
- while (n_users) {
- // Get the user choice
- chosen_login = choose_menu_item((const char**)user_names, NULL, n_users, &menu_opts, NULL);
- // Determine whether there were any modifier (CTRL) keys pressed
- mod = SDL_GetModState();
- if (chosen_login == -1 || chosen_login == n_users) {
- // User pressed escape or selected Quit/Back, handle by quitting
- // or going up a level
- if (level == 0) {
- // We are going to quit without logging in.
- // Clean up memory (prob. not necessary, but prevents Valgrind errors!)
- for (i = 0; i < n_login_questions; i++)
- free(user_login_questions[i]);
- free(user_login_questions);
- for (i = 0; i < n_users; i++)
- free(user_names[i]);
- free(user_names);
- return -1;
- }
- else {
- // Go back up one level of the directory tree
- user_data_dirname_up();
- level--;
- menu_opts.starting_entry = -1;
- }
- }
- else {
- // User chose an entry, set it up
- user_data_dirname_down(user_names[chosen_login]);
- level++;
- menu_opts.starting_entry = 0;
- }
- // Check for a highscores file
- if (high_scores_found_in_user_dir())
- set_high_score_path();
- // Free the entries from the previous menu
- for (i = 0; i < n_users; i++)
- free(user_names[i]);
- free(user_names);
- user_names = NULL;
- // If the CTRL key was pressed, choose this as the identity, even
- // if there is a lower level to the hierarchy
- if (mod & KMOD_CTRL)
- break;
- // Set the title appropriately for the next menu
- if (level < n_login_questions)
- menu_opts.title = user_login_questions[level];
- else
- menu_opts.title = NULL;
- if (level == 0)
- menu_opts.trailer = trailer_quit;
- else
- menu_opts.trailer = trailer_back;
- // Check to see if there are more choices to be made
- n_users = read_user_menu_entries(&user_names);
- }
-
- // The user home directory is set, clean up remaining memory
- for (i = 0; i < n_login_questions; i++)
- free(user_login_questions[i]);
- free(user_login_questions);
-
- // Signal success
- return 0;
-}
-
-
-/****************************************************************/
-/* choose_menu_item: menu navigation utility function */
-/* (the function returns the index for the selected menu item) */
-/* -1 indicates that the user pressed escape */
-/****************************************************************/
-int choose_menu_item(const char **menu_text, sprite **menu_sprites, int n_menu_entries, menu_options* custom_mo, void (*set_custom_menu_opts)(menu_options*) )
-{
- // Pixel renderings of menu text choices
- SDL_Surface **menu_item_unselected = NULL;
- SDL_Surface **menu_item_selected = NULL;
- // Display region for menu choices
- SDL_Rect *menu_text_rect = NULL;
- // Translucent mouse "buttons" around menu text
- SDL_Rect *menu_button_rect = NULL;
- // Menu sprite locations
- SDL_Rect *menu_sprite_rect = NULL;
-
- // The section of the background that the menu rects actually cover
- SDL_Rect *back_text_rect = NULL,
- *back_button_rect = NULL,
- *back_sprite_rect = NULL;
- SDL_Rect left_arrow_rect, right_arrow_rect;
- SDL_Rect temp_rect; //temporary copy of a dest rect that may be written to by SDL_BlitSurface
-
- menu_options menu_opts;
-
- Uint32 frame_counter = 0;
- Uint32 frame_start = 0; //For keeping frame rate constant
- Uint32 frame_now = 0;
- int stop = 0;
- int loc = 0; //The currently selected menu item
- int old_loc = 1;
- int loc_screen_start = 0; //The number of the top entry on current screen
- int old_loc_screen_start = 0;
- int redraw = 0;
- int n_entries_per_screen = 0;
- int buttonheight = 0;
- int i = 0;
- int imod = 0; // i % n_entries_per_screen
- int tux_frame = 0;
- int click_flag = 1;
- int use_sprite = 0;
- int warp_mouse = 0;
- int title_offset = 0;
- int have_trailer = 0;
-
-#ifdef TUXMATH_DEBUG
- fprintf(stderr, "Entering choose_menu_item():\n");
-#endif
-
-#ifdef TUXMATH_DEBUG
- fprintf(stderr,"%d menu entries:\n",n_menu_entries);
- for (i = 0; i < n_menu_entries; i++)
- fprintf(stderr,"%s\n",menu_text[i]);
-#endif
-
- if (custom_mo == NULL)
- set_default_menu_options(&menu_opts);
- else
- menu_opts = *custom_mo;
- if (set_custom_menu_opts != NULL)
- set_custom_menu_opts(&menu_opts);
-
- tmdprintf("Allocating memory\n");
- /**** Memory allocation for menu text ****/
- title_offset = 0;
- if (menu_opts.title != NULL)
- title_offset = 1;
- if (menu_opts.trailer != NULL)
- have_trailer = 1;
- menu_item_unselected = (SDL_Surface**)malloc((n_menu_entries+title_offset+have_trailer) * sizeof(SDL_Surface*));
- menu_item_selected = (SDL_Surface**)malloc((n_menu_entries+title_offset+have_trailer) * sizeof(SDL_Surface*));
- if (menu_item_unselected == NULL || menu_item_selected == NULL) {
- free(menu_item_unselected);
- free(menu_item_selected);
- return -2; // error
- }
-
- /**** Render the menu choices ****/
- if (title_offset)
- {
- menu_item_unselected[0] = BlackOutline( _(menu_opts.title), DEFAULT_MENU_FONT_SIZE, &red);
- // It will never be selected, so we don't have to do anything for selected.
- menu_item_selected[0] = NULL;
- }
- for (i = 0; i < n_menu_entries; i++)
- {
- menu_item_unselected[i+title_offset] = BlackOutline( _(menu_text[i]), DEFAULT_MENU_FONT_SIZE, &white );
- menu_item_selected[i+title_offset] = BlackOutline( _(menu_text[i]), DEFAULT_MENU_FONT_SIZE, &yellow);
- }
- if (have_trailer) {
- menu_item_unselected[n_menu_entries+title_offset] = BlackOutline( _(menu_opts.trailer), DEFAULT_MENU_FONT_SIZE, &white );
- menu_item_selected[n_menu_entries+title_offset] = BlackOutline( _(menu_opts.trailer), DEFAULT_MENU_FONT_SIZE, &yellow);
- }
- // We won't need the menu_text again, so now we can keep track of
- // the total entries including the title & trailer
- n_menu_entries += title_offset+have_trailer;
-
-// recalcMenuPositions();
-
- /**** Calculate the menu item heights and the number of ****/
- /**** entries per screen ****/
- if (menu_opts.buttonheight <= 0) {
- buttonheight = 0;
- for (i = 0; i < n_menu_entries; i++)
- if (buttonheight < menu_item_unselected[i]->h)
- buttonheight = menu_item_unselected[i]->h;
- buttonheight += 10;
- } else
- buttonheight = menu_opts.buttonheight;
-
- // First try using the whole screen; if we need more than one
- // screen, then we have to save space for the arrows by respecting
- // ybottom
- n_entries_per_screen = (int) (screen->h - menu_opts.ytop+menu_opts.ygap)/(buttonheight + menu_opts.ygap);
- if (n_entries_per_screen < n_menu_entries)
- n_entries_per_screen = (int) (menu_opts.ybottom - menu_opts.ytop+menu_opts.ygap)/(buttonheight + menu_opts.ygap);
-
- if (n_entries_per_screen > n_menu_entries)
- n_entries_per_screen = n_menu_entries;
-
- /**** Memory allocation for current screen rects ****/
- menu_text_rect = (SDL_Rect*) malloc(n_entries_per_screen * sizeof(SDL_Rect));
- menu_button_rect = (SDL_Rect*) malloc(n_entries_per_screen * sizeof(SDL_Rect));
- back_text_rect = (SDL_Rect*) malloc(n_entries_per_screen * sizeof(SDL_Rect));
- back_button_rect = (SDL_Rect*) malloc(n_entries_per_screen * sizeof(SDL_Rect));
- if (menu_text_rect == NULL || menu_button_rect == NULL ||
- back_text_rect == NULL || back_button_rect == NULL) {
- free(menu_text_rect);
- free(menu_button_rect);
- free(back_text_rect);
- free(back_button_rect);
- return -2;
- }
- if (menu_sprites != NULL) {
- menu_sprite_rect = (SDL_Rect*) malloc(n_entries_per_screen * sizeof(SDL_Rect));
- back_sprite_rect = (SDL_Rect*) malloc(n_entries_per_screen * sizeof(SDL_Rect));
- if (menu_sprite_rect == NULL || back_sprite_rect == NULL) {
- free(menu_sprite_rect);
- free(back_sprite_rect);
- return -2;
- }
- }
-
- /**** Define the locations of graphical elements on the screen ****/
- /* Arrow buttons in right lower corner, inset by 20 pixels */
- /* with a 10 pixel space between: */
- if (images[IMG_RIGHT])
- {
- right_arrow_rect.w = images[IMG_RIGHT]->w;
- right_arrow_rect.h = images[IMG_RIGHT]->h;
- right_arrow_rect.x = screen->w - images[IMG_RIGHT]->w - 20;
- right_arrow_rect.y = screen->h - images[IMG_RIGHT]->h - 20;
- }
-
- if (images[IMG_LEFT])
- {
- left_arrow_rect.w = images[IMG_LEFT]->w;
- left_arrow_rect.h = images[IMG_LEFT]->h;
- left_arrow_rect.x = right_arrow_rect.x - 10 - images[IMG_LEFT]->w;
- left_arrow_rect.y = screen->h - images[IMG_LEFT]->h - 20;
- }
- /* Red "Stop" circle in upper right corner to go back to main menu: */
- if (images[IMG_STOP])
- {
- stopRect.w = images[IMG_STOP]->w;
- stopRect.h = images[IMG_STOP]->h;
- stopRect.x = screen->w - images[IMG_STOP]->w;
- stopRect.y = 0;
- }
-
- /* Set initial menu rect sizes. The widths will change depending */
- /* on the size of the text displayed in each rect. Set the widths */
- /* for the current screen of menu items. */
- loc = menu_opts.starting_entry + title_offset; // Initially selected item
- loc_screen_start = loc - (loc % n_entries_per_screen);
- if (loc_screen_start < 0 || loc_screen_start*n_entries_per_screen > n_menu_entries)
- loc_screen_start = 0; // in case starting_entry was -1 (or wasn't set)
- imod = loc-loc_screen_start;
- for (i = 0; i < n_entries_per_screen; i++)
- {
- menu_button_rect[i].x = menu_opts.xleft;
- menu_text_rect[i].x = menu_opts.xleft + 15; // 15 is left gap
- if (menu_sprites != NULL)
- menu_text_rect[i].x += 60; // 40 is sprite width, 20 is gap
- if (i > 0)
- menu_text_rect[i].y = menu_text_rect[i - 1].y + buttonheight + menu_opts.ygap;
- else
- menu_text_rect[i].y = menu_opts.ytop;
- menu_button_rect[i].y = menu_text_rect[i].y-5;
- menu_text_rect[i].h = buttonheight-10;
- menu_button_rect[i].h = buttonheight;
- menu_button_rect[i].w = menu_text_rect[i].w = 0;
- if (i + loc_screen_start < n_menu_entries) {
- menu_text_rect[i].w = menu_item_unselected[i+loc_screen_start]->w;
- menu_button_rect[i].w = menu_text_rect[i].w + 30;
- }
- if (menu_sprite_rect != NULL) {
- menu_sprite_rect[i].x = menu_button_rect[i].x+3;
- menu_sprite_rect[i].y = menu_button_rect[i].y+3;
- menu_sprite_rect[i].w = 40;
- menu_sprite_rect[i].h = 50;
- }
- }
-
- if (menu_opts.button_same_width)
- set_buttons_max_width(menu_button_rect,back_button_rect,n_entries_per_screen);
-
- for (i = 0; i < n_entries_per_screen; ++i)
- {
- if (menu_button_rect)
- {
- back_button_rect[i] = menu_button_rect[i];
- back_button_rect[i].x -= Backrect.x;
- back_button_rect[i].y -= Backrect.y;
- }
- if (menu_text_rect)
- {
- back_text_rect[i] = menu_text_rect[i];
- back_text_rect[i].x -= Backrect.x;
- back_text_rect[i].y -= Backrect.y;
- }
- if (menu_sprite_rect)
- {
- back_sprite_rect[i] = menu_sprite_rect[i];
- back_sprite_rect[i].x -= Backrect.x;
- back_sprite_rect[i].y -= Backrect.y;
- }
- }
-
- /**** Draw background, title, and Tux: ****/
- if (current_bkg() )
- SDL_BlitSurface(current_bkg(), NULL, screen, &Backrect);
- if (images[IMG_MENU_TITLE])
- SDL_BlitSurface(images[IMG_MENU_TITLE], NULL, screen, &Titledest);
- if (Tux && Tux->frame[0])
- SDL_BlitSurface(Tux->frame[0], NULL, screen, &Tuxdest);
- SDL_UpdateRect(screen, 0, 0, 0 ,0);
-
- /* Move mouse to current button: */
- cursor.x = menu_button_rect[imod].x + menu_button_rect[imod].w/2;
- cursor.y = menu_button_rect[imod].y + menu_button_rect[imod].h/2;
-// SDL_WarpMouse(cursor.x, cursor.y);
- SDL_WM_GrabInput(SDL_GRAB_OFF);
-
-
- /******** Main loop: *********/
- redraw = 1; // force a full redraw on first pass
- old_loc_screen_start = loc_screen_start;
- while (SDL_PollEvent(&event)); // clear pending events
- while (!stop)
- {
- frame_start = SDL_GetTicks(); /* For keeping frame rate constant.*/
-
- while (SDL_PollEvent(&event))
- {
- switch (event.type)
- {
- case SDL_QUIT:
- {
- cleanup();
- //exit(0);
- break;
- }
-
- case SDL_MOUSEMOTION:
- {
- loc = -1; // By default, don't be in any entry
- for (i = 0; (i < n_entries_per_screen) && (loc_screen_start + i < n_menu_entries); i++)
- {
- if (inRect(menu_button_rect[i], event.motion.x, event.motion.y))
- {
- // Play sound if loc is being changed:
- if (Opts_GetGlobalOpt(MENU_SOUND) && (old_loc != loc_screen_start + i))
- {
- playsound(SND_TOCK);
- }
- loc = loc_screen_start + i;
- break; /* from for loop */
- }
+ add_rect(&src, &src);
+ add_rect(&dst,&dst);
+ y1 =step3 *(j -0.5) -i *step4 +1;
+ y2 =step3 *(j -0.5) +i *step4 +1;
+ src.x =0;
+ src.y =y1;
+ src.w =screen->w;
+ src.h =step4;
+ dst.x =0;
+ dst.y =y2;
+ dst.w =screen->w;
+ dst.h =step4;
+ SDL_BlitSurface(newbkg, &src,screen, &src);
+ SDL_BlitSurface(newbkg,&dst, screen,&dst);
+ add_rect(&src, &src);
+ add_rect(&dst,&dst);
}
-
- /* "Left" button - make click if button active: */
- if (inRect(left_arrow_rect, event.motion.x, event.motion.y))
- {
- if (loc_screen_start - n_entries_per_screen >= 0)
- {
- if (Opts_GetGlobalOpt(MENU_SOUND) && click_flag)
- {
- playsound(SND_TOCK);
- click_flag = 0;
- }
- }
- break; /* from case switch */
- }
-
- /* "Right" button - go to next page: */
- else if (inRect(right_arrow_rect, event.motion.x, event.motion.y ))
- {
- if (loc_screen_start + n_entries_per_screen < n_menu_entries)
- {
- if (Opts_GetGlobalOpt(MENU_SOUND) && click_flag)
- {
- playsound(SND_TOCK);
- click_flag = 0;
- }
- }
- break; /* from case switch */
- }
-
- else // Mouse outside of arrow rects - re-enable click sound:
- {
- click_flag = 1;
- break; /* from case switch */
- }
+ update_screen(&frame);
}
- case SDL_MOUSEBUTTONDOWN:
- {
- /* Choose a menu entry by mouse click */
- for (i = 0; (i < n_entries_per_screen) && (loc_screen_start + i < n_menu_entries); i++)
- {
- if (inRect(menu_button_rect[i], event.button.x, event.button.y))
- {
- if (Opts_GetGlobalOpt(MENU_SOUND))
- {
- playsound(SND_POP);
- }
+ src.x =0;
+ src.y =0;
+ src.w =screen->w;
+ src.h =screen->h;
+ SDL_BlitSurface(newbkg, NULL,screen, &src);
+ SDL_Flip(screen);
- loc = loc_screen_start + i;
- stop = 1;
- break;
- }
- }
-
- /* "Left" button - go to previous page: */
- if (inRect(left_arrow_rect, event.button.x, event.button.y))
- {
- if (loc_screen_start - n_entries_per_screen >= 0)
- {
- //loc = loc_screen_start - n_entries_per_screen;
- loc_screen_start -= n_entries_per_screen;
- loc = -1; // nothing selected
- if (Opts_GetGlobalOpt(MENU_SOUND))
- {
- playsound(SND_TOCK);
- }
- break;
- }
- }
-
- /* "Right" button - go to next page: */
- if (inRect( right_arrow_rect, event.button.x, event.button.y ))
- {
- if (loc_screen_start + n_entries_per_screen < n_menu_entries)
- {
- //loc = loc_screen_start + n_entries_per_screen;
- loc_screen_start += n_entries_per_screen;
- loc = -1; // nothing selected
- if (Opts_GetGlobalOpt(MENU_SOUND))
- {
- playsound(SND_TOCK);
- }
- break;
- }
- }
-
- /* "Stop" button - go to main menu: */
- if (inRect(stopRect, event.button.x, event.button.y ))
- {
- stop = 2;
- playsound(SND_TOCK);
- break;
- }
- } /* End of case SDL_MOUSEDOWN */
-
-
- case SDL_KEYDOWN:
- {
- /* Proceed according to particular key pressed: */
- switch (event.key.keysym.sym)
- {
- case SDLK_ESCAPE:
- {
- stop = 2;
- break;
- }
-
- case SDLK_RETURN:
- case SDLK_SPACE:
- case SDLK_KP_ENTER:
- {
- if (Opts_GetGlobalOpt(MENU_SOUND))
- playsound(SND_POP);
- stop = 1;
- break;
- }
-
-
- /* Go to previous page, if present: */
- case SDLK_LEFT:
- case SDLK_PAGEUP:
- {
- if (Opts_GetGlobalOpt(MENU_SOUND))
- playsound(SND_TOCK);
- if (loc_screen_start - n_entries_per_screen >= 0) {
- loc_screen_start -= n_entries_per_screen;
- loc = -1;
- }
- // {loc = loc_screen_start - n_entries_per_screen;}
- break;
- }
-
-
- /* Go to next page, if present: */
- case SDLK_RIGHT:
- case SDLK_PAGEDOWN:
- {
- if (Opts_GetGlobalOpt(MENU_SOUND))
- playsound(SND_TOCK);
- if (loc_screen_start + n_entries_per_screen < n_menu_entries) {
- loc_screen_start += n_entries_per_screen;
- loc = -1;
- }
- // {loc = (loc_screen_start + n_entries_per_screen);}
- break;
- }
-
- /* Go up one entry, if present: */
- case SDLK_UP:
- {
- if (Opts_GetGlobalOpt(MENU_SOUND))
- playsound(SND_TOCK);
- if (loc > title_offset)
- {loc--;}
- else if (n_menu_entries <= n_entries_per_screen) {
- loc = n_menu_entries-1; // wrap around if only 1 screen
- }
- else if (loc == -1 && loc_screen_start > 0) {
- loc = loc_screen_start-1;
- loc_screen_start -= n_entries_per_screen;
- }
- if (loc != old_loc)
- warp_mouse = 1;
- break;
- }
-
-
- /* Go down one entry, if present: */
- case SDLK_DOWN:
- {
- if (Opts_GetGlobalOpt(MENU_SOUND))
- playsound(SND_TOCK);
- if (loc >= 0 && loc + 1 < n_menu_entries)
- {loc++;}
- else if (n_menu_entries <= n_entries_per_screen)
- loc = title_offset; // wrap around if only 1 screen
- else if (loc == -1)
- loc = loc_screen_start;
- if (loc != old_loc)
- warp_mouse = 1;
- break;
- }
-
-
- /* Toggle screen mode: */
- case SDLK_F10:
- {
- SwitchScreenMode();
- RecalcTitlePositions();
- RecalcMenuPositions(&n_entries_per_screen,
- n_menu_entries,
- &menu_opts,
- set_custom_menu_opts,
- &menu_button_rect,
- &menu_sprite_rect,
- &menu_text_rect,
- &back_button_rect,
- &back_sprite_rect,
- &back_text_rect,
- &left_arrow_rect,
- &right_arrow_rect);
- //we're unsure how the entries might shuffle, so return to start
- loc_screen_start = 0;
- redraw = 1;
- break;
- }
-
- /* Toggle menu music: */
- case SDLK_F11:
- {
- if (Opts_GetGlobalOpt(MENU_MUSIC))
- {
- audioMusicUnload( );
- Opts_SetGlobalOpt(MENU_MUSIC, 0);
- }
- else
- {
- Opts_SetGlobalOpt(MENU_MUSIC, 1);
- audioMusicLoad("tuxi.ogg", -1);
- }
- break;
- }
-#ifdef TESTING_CAMPAIGN
- case SDLK_c:
- {
- start_campaign();
- RecalcTitlePositions();
- RecalcMenuPositions(&n_entries_per_screen,
- n_menu_entries,
- &menu_opts,
- set_custom_menu_opts,
- &menu_button_rect,
- &menu_sprite_rect,
- &menu_text_rect,
- &back_button_rect,
- &back_sprite_rect,
- &back_text_rect,
- &left_arrow_rect,
- &right_arrow_rect);
- redraw = 1;
- }
-
-#endif
- default:
- {
- /* Some other key - do nothing. */
- }
-
- break; /* To get out of _outer_ switch/case statement */
- } /* End of key switch statement */
- } // End of case SDL_KEYDOWN in outer switch statement
- } // End event switch statement
- if (handle_easter_egg(&event) )
- redraw = 1;
- else
- ; //egg_active = 0;
- } // End SDL_PollEvent while loop
-
-
-
- // Make sure the menu title is not selected
- if (loc == 0 && title_offset)
- loc = title_offset;
-
- /* Redraw screen: */
- if (loc >= 0)
- loc_screen_start = loc - (loc % n_entries_per_screen);
- if (old_loc_screen_start != loc_screen_start)
- redraw = 1;
- if (redraw)
- {
- tmdprintf("Updating entire screen\n");
- /* This is a full-screen redraw */
- /* Redraw background, title, stop button, and Tux: */
- if (!current_bkg() || screen->flags & SDL_FULLSCREEN )
- SDL_FillRect(screen, &screen->clip_rect, 0); //clear to black
- if (current_bkg())
- SDL_BlitSurface(current_bkg(), NULL, screen, &Backrect);
- if (images[IMG_MENU_TITLE])
- SDL_BlitSurface(images[IMG_MENU_TITLE], NULL, screen, &Titledest);
- if (images[IMG_STOP])
- SDL_BlitSurface(images[IMG_STOP], NULL, screen, &stopRect);
- if (Tux->frame[0])
- SDL_BlitSurface(Tux->frame[0], NULL, screen, &Tuxdest);
- /* Redraw the menu entries */
- for (imod = 0; imod < n_entries_per_screen; imod++)
- menu_button_rect[imod].w = 0; // so undrawn buttons don't affect width
- for (i = loc_screen_start, imod = 0; i < loc_screen_start+n_entries_per_screen && i < n_menu_entries; i++, imod++) {
- menu_text_rect[imod].w = menu_item_unselected[i]->w;
- if (i >= title_offset) {
- menu_button_rect[imod].w = menu_text_rect[imod].w + 30;
- if (menu_sprites != NULL)
- menu_button_rect[imod].w += 60;
- }
+ break;
}
-
- if (menu_opts.button_same_width)
- set_buttons_max_width(menu_button_rect,back_button_rect,n_entries_per_screen);
- // Make sure the menu title mouse button didn't get turned on
- if (loc_screen_start == 0 && title_offset)
- menu_button_rect[0].w = 0;
- for (i = loc_screen_start, imod = 0; i < loc_screen_start+n_entries_per_screen && i < n_menu_entries; i++, imod++) {
- if (i == loc) { //Draw text in yellow
- DrawButton(&menu_button_rect[imod], 10, SEL_RGBA);
- SDL_BlitSurface(menu_item_selected[loc], NULL, screen, &menu_text_rect[imod]);
- }
- else { //Draw text in white
- if (menu_button_rect[imod].w > 0)
- DrawButton(&menu_button_rect[imod], 10, REG_RGBA);
- SDL_BlitSurface(menu_item_unselected[i], NULL, screen, &menu_text_rect[imod]);
- }
- if (menu_sprites != NULL && (i >= title_offset) && menu_sprites[i-title_offset] != NULL)
- SDL_BlitSurface(menu_sprites[i-title_offset]->default_img, NULL, screen, &menu_sprite_rect[imod]);
- }
-
- /* --- draw 'left' and 'right' buttons --- */
- if (n_menu_entries > n_entries_per_screen) {
- if (loc_screen_start > 0) // i.e. not on first page
- {
- SDL_BlitSurface(images[IMG_LEFT], NULL, screen, &left_arrow_rect);
- }
- else /* Draw grayed-out left button: */
- {
- SDL_BlitSurface(images[IMG_LEFT_GRAY], NULL, screen, &left_arrow_rect);
- }
-
- if (loc_screen_start + n_entries_per_screen < n_menu_entries) // not on last page
- {
- SDL_BlitSurface(images[IMG_RIGHT], NULL, screen, &right_arrow_rect);
- }
- else /* Draw grayed-out right button: */
- {
- SDL_BlitSurface(images[IMG_RIGHT_GRAY], NULL, screen, &right_arrow_rect);
- }
- }
-
- SDL_Flip(screen);//SDL_UpdateRect(screen, 0, 0, 0 ,0);
- } else if (old_loc != loc) {
- // This is not a full redraw, but the selected entry did change.
- // By just redrawing the old and new selections, we avoid flickering.
- if (old_loc >= 0) {
- imod = old_loc-loc_screen_start;
- use_sprite = (menu_sprites != NULL && old_loc >= title_offset && menu_sprites[old_loc-title_offset] != NULL);
- temp_rect = menu_button_rect[imod];
- SDL_FillRect(screen, &temp_rect, 0);
- SDL_BlitSurface(current_bkg(), &back_button_rect[imod], screen, &temp_rect); // redraw background
- if (use_sprite) {
- // Some of the sprites extend beyond the menu button, so we
- // have to make sure we redraw in the sprite rects, too
- SDL_BlitSurface(current_bkg(), &back_sprite_rect[imod], screen, &temp_rect);
- }
- DrawButton(&menu_button_rect[imod], 10, REG_RGBA); // draw button
- //temp_rect = menu_text_rect[imod];
- SDL_BlitSurface(menu_item_unselected[old_loc], NULL, screen, &menu_text_rect[imod]); // draw text
- if (use_sprite) {
- temp_rect = menu_sprite_rect[imod];
- tmdprintf("Sprite %d at (%d %d)\n", imod, temp_rect.x, temp_rect.y);
- SDL_BlitSurface(menu_sprites[old_loc-title_offset]->default_img, NULL, screen, &temp_rect);
- // Also update the sprite rect (in some cases the sprite
- // extends beyond the menu button)
- SDL_UpdateRect(screen, menu_sprite_rect[imod].x, menu_sprite_rect[imod].y, menu_sprite_rect[imod].w, menu_sprite_rect[imod].h);
- }
- SDL_UpdateRect(screen, menu_button_rect[imod].x, menu_button_rect[imod].y, menu_button_rect[imod].w, menu_button_rect[imod].h);
- }
- if (loc >= 0) {
- imod = loc-loc_screen_start;
- use_sprite = (menu_sprites != NULL && loc >= title_offset && menu_sprites[loc] != NULL);
- temp_rect = menu_button_rect[imod];
- SDL_BlitSurface(current_bkg(), &(back_button_rect[imod]), screen, &temp_rect);
- if (use_sprite)
- {
- temp_rect = menu_sprite_rect[imod];
- SDL_BlitSurface(current_bkg(), &(back_sprite_rect[imod]), screen, &temp_rect);
- }
- DrawButton(&menu_button_rect[imod], 10, SEL_RGBA);
- SDL_BlitSurface(menu_item_selected[loc], NULL, screen, &menu_text_rect[imod]);
- if (use_sprite) {
- menu_sprites[loc-title_offset]->cur = 0; // start at beginning of animation sequence
- SDL_BlitSurface(menu_sprites[loc-title_offset]->frame[menu_sprites[loc-title_offset]->cur], NULL, screen, &menu_sprite_rect[imod]);
- SDL_UpdateRect(screen, menu_sprite_rect[imod].x, menu_sprite_rect[imod].y, menu_sprite_rect[imod].w, menu_sprite_rect[imod].h);
- next_frame(menu_sprites[loc-title_offset]);
- }
- SDL_UpdateRect(screen, menu_button_rect[imod].x, menu_button_rect[imod].y, menu_button_rect[imod].w, menu_button_rect[imod].h);
- tmdprintf("Updating rect: %d %d %d %d\n", menu_button_rect[imod].x, menu_button_rect[imod].y, menu_button_rect[imod].w, menu_button_rect[imod].h);
- }
- } else if (frame_counter % 5 == 0 && loc >= 0) {
- // No user input changed anything, but check to see if we need to
- // animate the sprite
- if (menu_sprites != NULL && loc >= title_offset && menu_sprites[loc-title_offset] != NULL) {
- imod = loc-loc_screen_start;
- //SDL_BlitSurface(current_bkg, &menu_button_rect[imod], screen, &menu_button_rect[imod]);
- temp_rect = menu_sprite_rect[imod];
- SDL_BlitSurface(current_bkg(), &back_sprite_rect[imod], screen, &temp_rect);
- DrawButton(&menu_button_rect[imod], 10, SEL_RGBA);
- //SDL_BlitSurface(menu_item_selected[loc], NULL, screen, &menu_text_rect[imod]);
- // Note: even though the whole button was redrawn, we don't
- // have to redraw the text & background as long as we don't
- // update that rect. If something else changes and we go to
- // full-screen updates, then remove the "commenting-out" on
- // the two lines above
- SDL_BlitSurface(menu_sprites[loc-title_offset]->frame[menu_sprites[loc-title_offset]->cur], NULL, screen, &menu_sprite_rect[imod]);
- SDL_UpdateRect(screen, menu_sprite_rect[imod].x, menu_sprite_rect[imod].y, menu_sprite_rect[imod].w, menu_sprite_rect[imod].h);
- next_frame(menu_sprites[loc-title_offset]);
- }
+ default:
+ break;
}
-
- redraw = 0;
-
- /* Move the mouse pointer if there is only a single screen */
- if (warp_mouse && n_menu_entries <= n_entries_per_screen) {
- imod = loc - loc_screen_start;
- cursor.x = menu_button_rect[imod].x + (menu_button_rect[imod].w / 2);
- cursor.y = menu_button_rect[imod].y + (3 * menu_button_rect[imod].h / 4);
-// SDL_WarpMouse(cursor.x, cursor.y);
- warp_mouse = 0;
- }
-
- old_loc = loc;
- old_loc_screen_start = loc_screen_start;
-
-
-
- /* --- make Tux blink --- */
- switch (frame_counter % TUX6)
- {
- case 0: tux_frame = 1; break;
- case TUX1: tux_frame = 2; break;
- case TUX2: tux_frame = 3; break;
- case TUX3: tux_frame = 4; break;
- case TUX4: tux_frame = 3; break;
- case TUX5: tux_frame = 2; break;
- default: tux_frame = 0;
- }
-
- if (Tux && tux_frame)
- {
- /* Redraw background to keep edges anti-aliased properly: */
- SDL_BlitSurface(current_bkg(),&Tuxdest, screen, &Tuxdest);
- SDL_BlitSurface(Tux->frame[tux_frame - 1], NULL, screen, &Tuxdest);
- SDL_UpdateRect(screen, Tuxdest.x, Tuxdest.y, Tuxdest.w, Tuxdest.h);
- //SDL_UpdateRect(screen, 0, 0, 0, 0);
- }
-
- if (egg_active) { //if we need to, draw the egg cursor
- //who knows why GetMouseState() doesn't take Sint16's...
- SDL_GetMouseState((int*)(&cursor.x), (int*)(&cursor.y));
- cursor.x -= egg->w / 2; //center vertically
- SDL_BlitSurface(egg, NULL, screen, &cursor);
- SDL_UpdateRect(screen, cursor.x, cursor.y, cursor.w, cursor.h);
- }
-
- /* Wait so we keep frame rate constant: */
- frame_now = SDL_GetTicks();
- if (frame_now < frame_start)
- frame_start = frame_now; // in case the timer wraps around
- if (frame_now - frame_start < 33)
- SDL_Delay(33-(frame_now-frame_start));
-
- frame_counter++;
- } // End !stop while loop
-
-
- /***** User made a choice, clean up and return the choice. ******/
-
- /* --- clear graphics before leaving function --- */
- for (i = 0; i < n_menu_entries; i++)
- {
- SDL_FreeSurface(menu_item_unselected[i]);
- SDL_FreeSurface(menu_item_selected[i]);
}
- free(menu_item_unselected);
- free(menu_item_selected);
- free(menu_text_rect);
- free(menu_button_rect);
- free(back_text_rect);
- free(back_button_rect);
- free(menu_sprite_rect);
- free(back_sprite_rect);
-
- /* Return the value of the chosen item (-1 indicates escape) */
- if (stop == 2)
- return -1;
- else
- return loc - title_offset;
+ DEBUGMSG(debug_titlescreen, "trans_wipe(): FINISH\n");
}
+/* InitEngine - Set up the update rectangle pointers
+ (user by trans_wipe() ) */
+void init_blits(void) {
+ int i;
-
-void set_buttons_max_width(SDL_Rect *menu_button_rect,
- SDL_Rect *back_button_rect, int n)
-{
- int i,max;
-
- max = 0;
- for (i = 0; i < n; i++)
- if (max < menu_button_rect[i].w)
- max = menu_button_rect[i].w;
-
- for (i = 0; i < n; i++)
- menu_button_rect[i].w = back_button_rect[i].w = max;
-
- tmdprintf("All buttons at width %d\n", max);
+ for (i = 0; i < MAX_UPDATES; ++i) {
+ blits[i].srcrect = &srcupdate[i];
+ blits[i].dstrect = &dstupdate[i];
+ }
}
-// Was in playgame.c in tuxtype:
-/*************************************************/
-/* TransWipe: Performs various wipes to new bkgs */
-/*************************************************/
-/*
- * Given a wipe request type, and any variables
- * that wipe requires, will perform a wipe from
- * the current screen image to a new one.
- */
-void TransWipe(SDL_Surface* newbkg, int type, int var1, int var2)
-{
- int i, j, x1, x2, y1, y2;
- int step1, step2, step3, step4;
- int frame;
- SDL_Rect src;
- SDL_Rect dst;
-
- if (!screen)
- {
-#ifdef TUXMATH_DEBUG
- fprintf(stderr, "TransWipe(): screen not valid!\n");
-#endif
- return;
- }
-
- if (!newbkg)
- {
-#ifdef TUXMATH_DEBUG
- fprintf(stderr, "TransWipe(): newbkg not valid!\n");
-#endif
- return;
- }
-
- numupdates = 0;
- frame = 0;
-
- if(newbkg->w == screen->w && newbkg->h == screen->h) {
- if( type == RANDOM_WIPE )
- type = (RANDOM_WIPE * ((float) rand()) / (RAND_MAX+1.0));
-
- switch( type ) {
- case WIPE_BLINDS_VERT: {
- #ifdef TUXMATH_DEBUG
- fprintf(stderr, "--+ Doing 'WIPE_BLINDS_VERT'\n");
-#endif
- /* var1 is num of divisions
- var2 is how many frames animation should take */
- if( var1 < 1 ) var1 = 1;
- if( var2 < 1 ) var2 = 1;
- step1 = screen->w / var1;
- step2 = step1 / var2;
-
- for(i = 0; i <= var2; i++)
- {
- for(j = 0; j <= var1; j++)
- {
- x1 = step1 * (j - 0.5) - i * step2 + 1;
- x2 = step1 * (j - 0.5) + i * step2 + 1;
- src.x = x1;
- src.y = 0;
- src.w = step2;
- src.h = screen->h;
- dst.x = x2;
- dst.y = 0;
- dst.w = step2;
- dst.h = screen->h;
-
- SDL_BlitSurface(newbkg, &src, screen, &src);
- SDL_BlitSurface(newbkg, &dst, screen, &dst);
-
- AddRect(&src, &src);
- AddRect(&dst, &dst);
- }
- UpdateScreen(&frame);
- }
-
- src.x = 0;
- src.y = 0;
- src.w = screen->w;
- src.h = screen->h;
- SDL_BlitSurface(newbkg, NULL, screen, &src);
- SDL_Flip(screen);
-
- break;
- } case WIPE_BLINDS_HORIZ: {
-#ifdef TUXMATH_DEBUG
- fprintf(stderr, "--+ Doing 'WIPE_BLINDS_HORIZ'\n");
-#endif
- /* var1 is num of divisions
- var2 is how many frames animation should take */
- if( var1 < 1 ) var1 = 1;
- if( var2 < 1 ) var2 = 1;
- step1 = screen->h / var1;
- step2 = step1 / var2;
-
- for(i = 0; i <= var2; i++) {
- for(j = 0; j <= var1; j++) {
- y1 = step1 * (j - 0.5) - i * step2 + 1;
- y2 = step1 * (j - 0.5) + i * step2 + 1;
- src.x = 0;
- src.y = y1;
- src.w = screen->w;
- src.h = step2;
- dst.x = 0;
- dst.y = y2;
- dst.w = screen->w;
- dst.h = step2;
-
- SDL_BlitSurface(newbkg, &src, screen, &src);
- SDL_BlitSurface(newbkg, &dst, screen, &dst);
-
- AddRect(&src, &src);
- AddRect(&dst, &dst);
- }
- UpdateScreen(&frame);
- }
-
- src.x = 0;
- src.y = 0;
- src.w = screen->w;
- src.h = screen->h;
- SDL_BlitSurface(newbkg, NULL, screen, &src);
- SDL_Flip(screen);
-
- break;
- } case WIPE_BLINDS_BOX: {
-#ifdef TUXMATH_DEBUG
- fprintf(stderr, "--+ Doing 'WIPE_BLINDS_BOX'\n");
-#endif
- /* var1 is num of divisions
- var2 is how many frames animation should take */
- if( var1 < 1 ) var1 = 1;
- if( var2 < 1 ) var2 = 1;
- step1 = screen->w / var1;
- step2 = step1 / var2;
- step3 = screen->h / var1;
- step4 = step1 / var2;
-
- for(i = 0; i <= var2; i++) {
- for(j = 0; j <= var1; j++) {
- x1 = step1 * (j - 0.5) - i * step2 + 1;
- x2 = step1 * (j - 0.5) + i * step2 + 1;
- src.x = x1;
- src.y = 0;
- src.w = step2;
- src.h = screen->h;
- dst.x = x2;
- dst.y = 0;
- dst.w = step2;
- dst.h = screen->h;
-
- SDL_BlitSurface(newbkg, &src, screen, &src);
- SDL_BlitSurface(newbkg, &dst, screen, &dst);
-
- AddRect(&src, &src);
- AddRect(&dst, &dst);
- y1 = step3 * (j - 0.5) - i * step4 + 1;
- y2 = step3 * (j - 0.5) + i * step4 + 1;
- src.x = 0;
- src.y = y1;
- src.w = screen->w;
- src.h = step4;
- dst.x = 0;
- dst.y = y2;
- dst.w = screen->w;
- dst.h = step4;
- SDL_BlitSurface(newbkg, &src, screen, &src);
- SDL_BlitSurface(newbkg, &dst, screen, &dst);
- AddRect(&src, &src);
- AddRect(&dst, &dst);
- }
- UpdateScreen(&frame);
- }
-
- src.x = 0;
- src.y = 0;
- src.w = screen->w;
- src.h = screen->h;
- SDL_BlitSurface(newbkg, NULL, screen, &src);
- SDL_Flip(screen);
-
- break;
- } default:
- break;
- }
- }
-#ifdef TUXMATH_DEBUG
- fprintf(stderr, "->TransWipe(): FINISH\n");
-#endif
-}
-
-
-
-/************************
-UpdateScreen : Update the screen and increment the frame num
-***************************/
-void UpdateScreen(int *frame) {
+/* update_screen : Update the screen and increment the frame num
+ (used by trans_wipe() ) */
+void update_screen(int *frame) {
int i;
/* -- First erase everything we need to -- */
@@ -2467,212 +809,31 @@
}
-/******************************
-AddRect: Don't actually blit a surface,
- but add a rect to be updated next
- update
-*******************************/
-void AddRect(SDL_Rect* src, SDL_Rect* dst) {
- /*borrowed from SL's alien (and modified)*/
+/* add_rect: Don't actually blit a surface,
+ but add a rect to be updated next update
+ (used by trans_wipe() ) */
+void add_rect(SDL_Rect* src, SDL_Rect* dst) {
+ /*borrowed from SL's alien (and modified)*/
- struct blit *update;
+ struct blit *update;
- if (!src || !dst)
- {
-#ifdef TUXMATH_DEBUG
- fprintf(stderr, "AddRect(): src or dst invalid!\n");
-#endif
- return;
- }
-
- update = &blits[numupdates++];
-
- update->srcrect->x = src->x;
- update->srcrect->y = src->y;
- update->srcrect->w = src->w;
- update->srcrect->h = src->h;
- update->dstrect->x = dst->x;
- update->dstrect->y = dst->y;
- update->dstrect->w = dst->w;
- update->dstrect->h = dst->h;
- update->type = 'I';
-}
-
-/***********************
- InitEngine
- ***********************/
-void InitEngine(void) {
- int i;
-
- /* --- Set up the update rectangle pointers --- */
-
- for (i = 0; i < MAX_UPDATES; ++i) {
- blits[i].srcrect = &srcupdate[i];
- blits[i].dstrect = &dstupdate[i];
- }
-}
-
-
-void set_default_menu_options(menu_options *menu_opts)
-{
- menu_opts->starting_entry = 0;
- menu_opts->xleft = screen->w / 2 - screen->w * 3 / 32;
- menu_opts->ytop = screen->h / 2 - 140;
- // Leave room for arrows at the bottom:
- menu_opts->ybottom = screen->h - images[IMG_LEFT]->h - 20;
- menu_opts->buttonheight = -1;
- menu_opts->ygap = 10;
- menu_opts->button_same_width = 1;
- menu_opts->title = NULL;
- menu_opts->trailer = NULL;
-}
-
-/* Recalculate on-screen locations for title screen elements */
-void RecalcTitlePositions()
-{
- Backrect = current_bkg()->clip_rect;
- Backrect.x = (screen->w - Backrect.w) / 2;
- Backrect.y = (screen->h - Backrect.h) / 2;
-
- Titledest.x = 0;
- Titledest.y = 0;
-
- Tuxdest.x = 0;
- Tuxdest.y = screen->h - Tuxdest.h;
-
- beak.x = Tuxdest.x + 70;
- beak.y = Tuxdest.y + 60;
- beak.w = beak.h = 50;
-
- stopRect.x = screen->w - stopRect.w;
- stopRect.y = 0;
-}
-
-/* Recalculate on-screen locations for menus when screen dimensions change */
-/* Perhaps consider generalizing this for use in initial menu calculations? */
-void RecalcMenuPositions(int* numentries,
- int totalentries,
- menu_options* mo,
- void (*set_custom_menu_opts)(menu_options*),
- SDL_Rect** menu_button_rect,
- SDL_Rect** menu_sprite_rect,
- SDL_Rect** menu_text_rect,
- SDL_Rect** back_button_rect,
- SDL_Rect** back_sprite_rect,
- SDL_Rect** back_text_rect,
- SDL_Rect* left_arrow_rect,
- SDL_Rect* right_arrow_rect)
-{
- int i;
- SDL_Rect* old_mbr = *menu_button_rect;
- SDL_Rect* old_msr = *menu_sprite_rect;
- SDL_Rect* old_mtr = *menu_text_rect;
- SDL_Rect* old_bbr = *back_button_rect;
- SDL_Rect* old_bsr = *back_sprite_rect;
- SDL_Rect* old_btr = *back_text_rect;
-
- int old_ne = *numentries;
- int buttonheight = old_mbr->h; //height shouldn't change
- int textwidth = old_mtr->w; //neither should width =P
-
- right_arrow_rect->x = screen->w - images[IMG_RIGHT]->w - 20;
- right_arrow_rect->y = screen->h - images[IMG_RIGHT]->h - 20;
- left_arrow_rect->x = right_arrow_rect->x - 10 - images[IMG_LEFT]->w;
- left_arrow_rect->y = screen->h - images[IMG_LEFT]->h - 20;
-
- set_default_menu_options(mo);
- if (set_custom_menu_opts != NULL)
- set_custom_menu_opts(mo);
-
- *numentries = (int)(screen->h - mo->ytop+mo->ygap)/(buttonheight + mo->ygap);
- if (*numentries < totalentries)
- *numentries = (int)(mo->ybottom - mo->ytop+mo->ygap)/(buttonheight + mo->ygap);
- if (*numentries > totalentries)
- *numentries = totalentries;
-
-
-
-
- /**** Memory allocation for new screen rects ****/
- *menu_text_rect = (SDL_Rect*) malloc(*numentries * sizeof(SDL_Rect));
- *menu_button_rect = (SDL_Rect*) malloc(*numentries * sizeof(SDL_Rect));
- *menu_sprite_rect = (SDL_Rect*) malloc(*numentries * sizeof(SDL_Rect));
- *back_text_rect = (SDL_Rect*) malloc(*numentries * sizeof(SDL_Rect));
- *back_button_rect = (SDL_Rect*) malloc(*numentries * sizeof(SDL_Rect));
- *back_sprite_rect = (SDL_Rect*) malloc(*numentries * sizeof(SDL_Rect));
- if (*menu_text_rect == NULL ||
- *back_text_rect == NULL ||
- *menu_button_rect == NULL ||
- *back_button_rect == NULL ||
- *menu_sprite_rect == NULL ||
- *back_sprite_rect == NULL) {
- free(*menu_text_rect);
- free(*menu_button_rect);
- free(*menu_sprite_rect);
- free(*back_text_rect);
- free(*back_button_rect);
- free(*back_sprite_rect);
- *menu_text_rect = old_mtr;
- *menu_button_rect = old_mbr;
- *menu_sprite_rect = old_msr;
- *numentries = old_ne;
+ if (!src || !dst)
+ {
+ DEBUGMSG(debug_titlescreen, "add_rect(): src or dst invalid!\n");
return;
}
- else {
- free(old_mtr);
- free(old_mbr);
- free(old_msr);
- free(old_btr);
- free(old_bbr);
- free(old_bsr);
- }
+ update = &blits[numupdates++];
- //note: the [0] notation is merely to avoid typing out (*menu_xxx_rect)[i]
- for (i = 0; i < *numentries; i++)
- {
- menu_button_rect[0][i].x = mo->xleft;
- menu_text_rect[0][i].x = mo->xleft + 15; // 15 is left gap
- menu_text_rect[0][i].x += 60; // for now, assume we have a sprite
- if (i > 0)
- menu_text_rect[0][i].y = menu_text_rect[0][i - 1].y + buttonheight + mo->ygap;
- else
- menu_text_rect[0][i].y = mo->ytop;
-
- menu_button_rect[0][i].y = menu_text_rect[0][i].y - 5;
- menu_text_rect[0][i].h = buttonheight - 10;
- menu_button_rect[0][i].h = buttonheight;
-
- menu_text_rect[0][i].w = textwidth;
- menu_button_rect[0][i].w = menu_text_rect[0][i].w + 30;
-
- if (menu_sprite_rect != NULL) {
- menu_sprite_rect[0][i].x = menu_button_rect[0][i].x + 3;
- menu_sprite_rect[0][i].y = menu_button_rect[0][i].y + 3;
- menu_sprite_rect[0][i].w = 40;
- menu_sprite_rect[0][i].h = 50;
- }
- tmdprintf("***Rects[%d]****\n", i);
- tmdprintf("%3d %3d %3d %3d\n", menu_button_rect[0][i].x, menu_button_rect[0][i].y, menu_button_rect[0][i].w, menu_button_rect[0][i].h);
- tmdprintf("%3d %3d %3d %3d\n", menu_text_rect[0][i].x, menu_text_rect[0][i].y, menu_text_rect[0][i].w, menu_text_rect[0][i].h);
- tmdprintf("%3d %3d %3d %3d\n", menu_sprite_rect[0][i].x, menu_sprite_rect[0][i].y, menu_sprite_rect[0][i].w, menu_sprite_rect[0][i].h);
- tmdprintf("***************\n");
- }
- for (i = 0; i < *numentries; ++i)
- {
- back_button_rect[0][i] = menu_button_rect[0][i];
- back_button_rect[0][i].x -= Backrect.x;
- back_button_rect[0][i].y -= Backrect.y;
-
- back_text_rect[0][i] = menu_text_rect[0][i];
- back_text_rect[0][i].x -= Backrect.x;
- back_text_rect[0][i].y -= Backrect.y;
-
- back_sprite_rect[0][i] = menu_sprite_rect[0][i];
- back_sprite_rect[0][i].x -= Backrect.x;
- back_sprite_rect[0][i].y -= Backrect.y;
- }
-
+ update->srcrect->x = src->x;
+ update->srcrect->y = src->y;
+ update->srcrect->w = src->w;
+ update->srcrect->h = src->h;
+ update->dstrect->x = dst->x;
+ update->dstrect->y = dst->y;
+ update->dstrect->w = dst->w;
+ update->dstrect->h = dst->h;
+ update->type = 'I';
}
int handle_easter_egg(const SDL_Event* evt)
@@ -2699,7 +860,7 @@
{
SDL_ShowCursor(SDL_ENABLE);
//SDL_FillRect(screen, &cursor, 0);
- SDL_BlitSurface(current_bkg(), NULL, screen, &Backrect); //cover egg up once more
+ SDL_BlitSurface(current_bkg(), NULL, screen, &bkg_rect); //cover egg up once more
SDL_WarpMouse(cursor.x, cursor.y);
SDL_UpdateRect(screen, cursor.x, cursor.y, cursor.w, cursor.h); //egg->x, egg->y, egg->w, egg->h);
egg_active = 0;
@@ -2717,19 +878,18 @@
//animate
while (tuxframe != 0)
{
- SDL_BlitSurface(Tux->frame[--tuxframe], NULL, screen, &Tuxdest);
- SDL_UpdateRect(screen, Tuxdest.x, Tuxdest.y, Tuxdest.w, Tuxdest.h);
+ SDL_BlitSurface(current_bkg(), &tux_rect, screen, &tux_rect);
+ SDL_BlitSurface(Tux->frame[--tuxframe], NULL, screen, &tux_rect);
+ SDL_UpdateRect(screen, tux_rect.x, tux_rect.y, tux_rect.w, tux_rect.h);
SDL_Delay(GOBBLE_ANIM_MS / Tux->num_frames);
}
eggtimer = SDL_GetTicks() + EASTER_EGG_MS;
egg_active = 1;
- SDL_WarpMouse(Tuxdest.x + Tuxdest.w / 2, Tuxdest.y + Tuxdest.h - egg->h);
+ SDL_WarpMouse(tux_rect.x + tux_rect.w / 2, tux_rect.y + tux_rect.h - egg->h);
}
return 0;
}
}
-
-
Added: tuxmath/branches/lan/src/titlescreen.c.old
===================================================================
--- tuxmath/branches/lan/src/titlescreen.c.old (rev 0)
+++ tuxmath/branches/lan/src/titlescreen.c.old 2009-09-03 22:06:06 UTC (rev 1477)
@@ -0,0 +1,2735 @@
+/***************************************************************************
+ - file: titlescreen.c
+ - description: splash, title and menu screen functionality
+ ------------------
+ begin : Thur May 4 2000
+ copyright : (C) 2000 by Sam Hart
+ : (C) 2003 by Jesse Andrews
+ email : tuxtype-dev at tux4kids.net
+
+ Modified for use in tuxmath by David Bruce - 2006-2007.
+ email : <dbruce at tampabay.rr.com>
+ <tuxmath-devel at lists.sourceforge.net>
+ Also significantly enhanced by Tim Holy - 2007
+***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+// titlescreen.h has all of the tuxtype-related stuff:
+#include "titlescreen.h"
+
+// tuxmath includes:
+#include "tuxmath.h"
+#include "options.h"
+#include "fileops.h"
+#include "game.h"
+#include "campaign.h"
+#include "factoroids.h"
+#include "multiplayer.h"
+#include "transtruct.h"
+#include "mathcards.h"
+#include "setup.h" //for cleanup()
+#include "network.h"
+#include "loaders.h"
+#include "credits.h"
+#include "highscore.h"
+#include "convert_utf.h" // for wide char to UTF-8 conversion
+#include "SDL_extras.h"
+
+/* --- Data Structure for Dirty Blitting --- */
+SDL_Rect srcupdate[MAX_UPDATES];
+SDL_Rect dstupdate[MAX_UPDATES];
+int numupdates = 0; // tracks how many blits to be done
+char host[1024]="NULL";
+char player_name[1024];
+
+// Colors we use:
+SDL_Color black;
+SDL_Color gray;
+SDL_Color dark_blue;
+SDL_Color red;
+SDL_Color white;
+SDL_Color yellow;
+
+// Type needed for TransWipe():
+struct blit {
+ SDL_Surface *src;
+ SDL_Rect *srcrect;
+ SDL_Rect *dstrect;
+ unsigned char type;
+} blits[MAX_UPDATES];
+
+// Lessons available for play
+char **lesson_list_titles = NULL;
+char **lesson_list_filenames = NULL;
+int num_lessons = 0;
+//int n=0;
+
+
+/* --- media for menus --- */
+
+enum {
+ SPRITE_TRAINING,
+ SPRITE_ARCADE,
+ SPRITE_HELP,
+ SPRITE_CUSTOM,
+ SPRITE_OPTIONS,
+ SPRITE_CADET,
+ SPRITE_SCOUT,
+ SPRITE_RANGER,
+ SPRITE_ACE,
+ SPRITE_COMMANDO,
+ SPRITE_QUIT,
+ SPRITE_MAIN,
+ SPRITE_GOLDSTAR,
+ SPRITE_NO_GOLDSTAR,
+ SPRITE_TROPHY,
+ SPRITE_CREDITS,
+ SPRITE_ALONE,
+ SPRITE_LAN,
+ SPRITE_FRIENDS,
+ SPRITE_FACTOROIDS,
+ SPRITE_FACTORS,
+ SPRITE_FRACTIONS,
+ SPRITE_CAMPAIGN,
+ SPRITE_SSWEEP,
+ SPRITE_ELIMINATION,
+ SPRITE_SERVER,
+ SPRITE_CLIENT,
+ N_SPRITES};
+
+const char* menu_sprite_files[N_SPRITES] =
+{
+ "lesson",
+ "comet",
+ "help",
+ "tux_config",
+ "tux_config_brown",
+ "tux_helmet_yellow",
+ "tux_helmet_green",
+ "tux_helmet_blue",
+ "tux_helmet_red",
+ "tux_helmet_black",
+ "quit",
+ "main",
+ "goldstar",
+ "no_goldstar",
+ "trophy",
+ "credits",
+ "alone",
+ "lan",
+ "friends",
+ "factoroids",
+ "factors",
+ "fractions",
+ "fleet",
+ "nums",
+ "exclamation"
+};
+
+sprite **sprite_list = NULL;
+
+sprite* Tux = NULL;
+
+
+SDL_Event event;
+
+/* --- locations we need --- */
+
+SDL_Rect dest,
+ Tuxdest,
+ Titledest,
+ stopRect,
+ Backrect,
+ Tuxback,
+ Titleback,
+ cursor,
+ beak;
+
+/* The background image scaled to windowed 640x480 */
+SDL_Surface* bkg = NULL;
+/* The background image scaled to fullscreen dimensions */
+SDL_Surface* scaled_bkg = NULL;
+/* "Easter Egg" cursor */
+SDL_Surface* egg = NULL;
+int egg_active = 0; //are we currently using the egg cursor?
+
+
+SDL_Surface* current_bkg()
+ /* This syntax makes my brain start to explode! */
+ { return screen->flags & SDL_FULLSCREEN ? scaled_bkg : bkg; }
+
+/* Local function prototypes: */
+void TitleScreen_load_menu(void);
+void TitleScreen_unload_menu(void);
+int TitleScreen_load_media(void);
+void TitleScreen_unload_media(void);
+void NotImplemented(void);
+void TransWipe(SDL_Surface* newbkg, int type, int var1, int var2);
+void UpdateScreen(int* frame);
+void AddRect(SDL_Rect* src, SDL_Rect* dst);
+void InitEngine(void);
+void ShowMessage(const char* str1, const char* str2, const char* str3, const char* str4);
+void RecalcTitlePositions();
+void RecalcMenuPositions(int*, int, menu_options*, void (*)(menu_options*),
+ SDL_Rect**, SDL_Rect**, SDL_Rect**,
+ SDL_Rect**, SDL_Rect**, SDL_Rect**,
+ SDL_Rect*, SDL_Rect*);
+void set_buttons_max_width(SDL_Rect *, SDL_Rect *, int);
+
+int run_login_menu(void);
+int run_main_menu(void);
+int run_game_menu(void);
+int run_multiplay_menu(void);
+int run_lessons_menu(void);
+int run_arcade_menu(void);
+int run_campaign_menu(void);
+int run_custom_menu(void);
+int run_activities_menu(void);
+int run_options_menu(void);
+int run_lan_menu(void);
+int run_server_menu(void);
+int handle_easter_egg(const SDL_Event* evt);
+
+/***********************************************************/
+/* */
+/* "Public functions" (callable throughout program) */
+/* */
+/***********************************************************/
+
+
+
+/****************************************
+* TitleScreen: Display the title screen *
+****************************************/
+
+/* display title screen, get input */
+
+void TitleScreen(void)
+{
+
+ Uint32 start = 0;
+
+ int i,TuxPixSkip,TitlePixSkip;
+// int n_subdirs;
+// char **subdir_names;
+
+
+ if (Opts_UsingSound())
+ {
+ Opts_SetGlobalOpt(MENU_SOUND, 1);
+ Opts_SetGlobalOpt(MENU_MUSIC, 1);
+// menu_music = localsettings.menu_music;
+ }
+
+ InitEngine(); //set up pointers for blitting structure.
+
+ start = SDL_GetTicks();
+
+
+ /* StandbyScreen: Display the Standby screen: */
+ if (images[IMG_STANDBY])
+ {
+ // Center horizontally
+ dest.x = ((screen->w) / 2) - (images[IMG_STANDBY]->w) / 2;
+ // Center vertically
+ dest.y = ((screen->h) / 2) - (images[IMG_STANDBY]->h) / 2;
+ dest.w = images[IMG_STANDBY]->w;
+ dest.h = images[IMG_STANDBY]->h;
+
+ SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0));
+ SDL_BlitSurface(images[IMG_STANDBY], NULL, screen, &dest);
+ SDL_UpdateRect(screen, 0, 0, 0, 0);
+ // Play "harp" greeting sound lifted from Tux Paint:
+ playsound(SND_HARP);
+ }
+
+
+ /* --- wait --- */
+
+ while ((SDL_GetTicks() - start) < 2000)
+ {
+ /* Check to see if user pressed escape */
+ if (SDL_PollEvent(&event)
+ && event.type==SDL_KEYDOWN
+ && event.key.keysym.sym == SDLK_ESCAPE)
+ {
+ return;
+ }
+ SDL_Delay(50);
+ }
+#ifndef TUXMATH_DEBUG //in case of a freeze, this traps the cursor
+ SDL_WM_GrabInput(SDL_GRAB_ON); // User input goes to TuxMath, not window manager
+#endif
+ SDL_ShowCursor(1);
+
+
+ /***************************
+ * Tux and Title animations *
+ ***************************/
+
+#ifdef TUXMATH_DEBUG
+ fprintf(stderr, "->Now Animating Tux and Title onto the screen\n" );
+#endif
+
+ /* Load media and menu data: */
+ /* FIXME should get out if needed media not loaded OK */
+ if (TitleScreen_load_media() == 0) {
+ fprintf(stderr,"Media was not properly loaded, exiting");
+ return;
+ }
+
+ /* Draw background, if it loaded OK: */
+ if (current_bkg() )
+ {
+ Backrect.x = (screen->w - current_bkg()->w) / 2;
+ Backrect.y = (screen->h - current_bkg()->h) / 2;
+ Backrect.w = current_bkg()->w;
+ Backrect.h = current_bkg()->h;
+ /* FIXME not sure TransWipe() works in Windows: */
+ TransWipe(current_bkg(), RANDOM_WIPE, 10, 20);
+ /* Make sure background gets drawn (since TransWipe() doesn't */
+ /* seem to work reliably as of yet): */
+ SDL_BlitSurface(current_bkg(), NULL, screen, &Backrect);
+
+ }
+ /* Red "Stop" circle in upper right corner to go back to main menu: */
+ if (images[IMG_STOP])
+ {
+ stopRect.w = images[IMG_STOP]->w;
+ stopRect.h = images[IMG_STOP]->h;
+ stopRect.x = screen->w - images[IMG_STOP]->w;
+ stopRect.y = 0;
+ SDL_BlitSurface(images[IMG_STOP], NULL, screen, &stopRect);
+ }
+ SDL_UpdateRect(screen, 0, 0, 0, 0);
+
+ /* --- Pull tux & logo onscreen --- */
+ /* NOTE we wind up with Tuxdest.y == (screen->h) - (Tux->frame[0]->h), */
+ /* a nd Titledest.x == 0. */
+ if (current_bkg()
+ && images[IMG_MENU_TITLE]
+ && images[IMG_STOP]
+ && Tux && Tux->frame[0])
+ {
+
+ Tuxdest.x = 0;
+ Tuxdest.y = screen->h;
+ /*
+ Tuxback.x = Tuxdest.x - Backrect.x;
+ Tuxback.y = Tuxdest.y - Backrect.y;
+ */
+ Tuxdest.w = Tuxback.w = Tux->frame[0]->w;
+ Tuxdest.h = Tuxback.h = Tux->frame[0]->h;
+
+
+ Titledest.x = screen->w;
+ Titledest.y = 10;
+ /*
+ Titleback.x = Titledest.x - Backrect.x;
+ Titleback.y = Titledest.y - Backrect.y;
+ */
+ Titledest.w = Titleback.w = images[IMG_MENU_TITLE]->w;
+ Titledest.h = Titleback.h = images[IMG_MENU_TITLE]->h;
+
+ TuxPixSkip = Tux->frame[0]->h / (PRE_ANIM_FRAMES * PRE_FRAME_MULT);
+ TitlePixSkip = (screen->w) / (PRE_ANIM_FRAMES * PRE_FRAME_MULT);
+
+ for (i = 0; i < (PRE_ANIM_FRAMES * PRE_FRAME_MULT); i++)
+ {
+ start = SDL_GetTicks();
+
+ //Draw the entire background, over a black screen if necessary
+ if (current_bkg()->w != screen->w || current_bkg()->h != screen->h)
+ SDL_FillRect(screen, &screen->clip_rect, 0);
+ SDL_BlitSurface(current_bkg(), NULL, screen, &Backrect);
+
+ Tuxdest.y -= TuxPixSkip;
+ //Tuxback.y -= Tux->frame[0]->h / (PRE_ANIM_FRAMES * PRE_FRAME_MULT);
+ Titledest.x -= TitlePixSkip;
+ //Titleback.y -= (screen->w) / (PRE_ANIM_FRAMES * PRE_FRAME_MULT);
+
+ SDL_BlitSurface(Tux->frame[0], NULL, screen, &Tuxdest);
+ SDL_BlitSurface(images[IMG_MENU_TITLE], NULL, screen, &Titledest);
+ SDL_BlitSurface(images[IMG_STOP], NULL, screen, &stopRect);
+
+ SDL_UpdateRect(screen, Tuxdest.x, Tuxdest.y, Tuxdest.w, Tuxdest.h);
+ SDL_UpdateRect(screen, Titledest.x, Titledest.y, Titledest.w + TitlePixSkip, Titledest.h);
+ SDL_UpdateRect(screen, stopRect.x, stopRect.y, stopRect.w, stopRect.h);
+
+ while ((SDL_GetTicks() - start) < 33)
+ {
+ SDL_Delay(2);
+ }
+ }
+
+
+ }
+
+#ifdef TUXMATH_DEBUG
+ fprintf(stderr, "Tux and Title are in place now\n");
+#endif
+
+ //location of Tux's beak
+ beak.x = Tuxdest.x + 70;
+ beak.y = Tuxdest.y + 60;
+ beak.w = beak.h = 50;
+
+ /* Start playing menu music if desired: */
+ if (Opts_GetGlobalOpt(MENU_MUSIC))
+ {
+ audioMusicLoad("tuxi.ogg", -1);
+ }
+
+ /* If necessary, have the user log in */
+ if (run_login_menu() != -1) {
+ /* Finish parsing user options */
+ initialize_options_user();
+ /* Start the main menu */
+ run_main_menu();
+ }
+
+ /* User has selected quit, clean up */
+
+#ifdef TUXMATH_DEBUG
+ fprintf(stderr, "->>Freeing title screen images\n");
+#endif
+
+ TitleScreen_unload_media();
+
+#ifdef TUXMATH_DEBUG
+ fprintf(stderr,"->TitleScreen():END \n");
+#endif
+
+}
+
+
+
+
+/***********************************************************/
+/* */
+/* "Private functions" (callable only from this file) */
+/* */
+/***********************************************************/
+
+
+// 1 = success, 0 = failure
+int TitleScreen_load_media(void)
+{
+ char fn[PATH_MAX];
+ int i;
+
+
+#ifdef TUXMATH_DEBUG
+ fprintf(stderr, "Entering TitleScreen_load_media():\n");
+#endif
+
+ Tux = LoadSprite("tux/bigtux", IMG_ALPHA);
+
+ SDL_ShowCursor(1);
+
+#ifdef TUXMATH_DEBUG
+ fprintf(stderr, "loading sprites\n");
+#endif
+
+ sprite_list = (sprite**) malloc(N_SPRITES*sizeof(sprite*));
+ if (sprite_list == NULL)
+ return 0;
+
+ for (i = 0; i < N_SPRITES; i++) {
+ /* --- load animated icon for menu item --- */
+ sprintf(fn, "sprites/%s", menu_sprite_files[i]);
+ sprite_list[i] = LoadSprite(fn, IMG_ALPHA);
+ }
+ egg = LoadImage("title/egg.png",
+ IMG_COLORKEY | IMG_NOT_REQUIRED);
+ LoadBothBkgds("title/menu_bkg.jpg", &scaled_bkg, &bkg);
+ return 1;
+}
+
+
+
+
+void TitleScreen_unload_menu(void)
+{
+ int i;
+
+ for (i = 0; i < N_SPRITES; i++)
+ {
+ tmdprintf("Freeing image %d: ", i);
+ FreeSprite(sprite_list[i]);
+ sprite_list[i] = NULL;
+ }
+ free(sprite_list);
+ tmdprintf("Images freed\n");
+ sprite_list = NULL;
+}
+
+
+
+void TitleScreen_unload_media(void)
+{
+ tmdprintf("Unloading media\n");
+ FreeSprite(Tux);
+ Tux = NULL;
+ TitleScreen_unload_menu();
+
+ SDL_FreeSurface(egg);
+ SDL_FreeSurface(bkg);
+ SDL_FreeSurface(scaled_bkg);
+}
+
+
+
+void NotImplemented(void)
+{
+ const char *s1, *s2, *s3, *s4;
+
+ s1 = _("Work In Progress!");
+ s2 = _("This feature is not ready yet");
+ s3 = _("Discuss the future of TuxMath at");
+ s4 = N_("tuxmath-devel at lists.sourceforge.net");
+
+ ShowMessage(s1, s2, s3, s4);
+}
+
+
+
+
+
+/* FIXME add some background shading to improve legibility */
+void ShowMessage(const char* str1, const char* str2, const char* str3, const char* str4)
+{
+ SDL_Surface *s1, *s2, *s3, *s4;
+ SDL_Rect loc;
+ int finished = 0;
+ int tux_frame = 0;
+ Uint32 frame = 0;
+ Uint32 start = 0;
+
+ s1 = s2 = s3 = s4 = NULL;
+
+#ifdef TUXMATH_DEBUG
+ fprintf(stderr, "ShowMessage() - creating text\n" );
+#endif
+
+ if (str1)
+ s1 = BlackOutline(str1, DEFAULT_MENU_FONT_SIZE, &white);
+ if (str2)
+ s2 = BlackOutline(str2, DEFAULT_MENU_FONT_SIZE, &white);
+ if (str3)
+ s3 = BlackOutline(str3, DEFAULT_MENU_FONT_SIZE, &white);
+ if (str4)
+ s4 = BlackOutline(str4, DEFAULT_MENU_FONT_SIZE, &white);
+
+#ifdef TUXMATH_DEBUG
+ fprintf(stderr, "ShowMessage() - drawing screen\n" );
+#endif
+
+ /* Redraw background: */
+ if (current_bkg() )
+ SDL_BlitSurface( current_bkg(), NULL, screen, &Backrect );
+
+ /* Red "Stop" circle in upper right corner to go back to main menu: */
+ if (images[IMG_STOP])
+ {
+ stopRect.w = images[IMG_STOP]->w;
+ stopRect.h = images[IMG_STOP]->h;
+ stopRect.x = screen->w - images[IMG_STOP]->w;
+ stopRect.y = 0;
+ SDL_BlitSurface(images[IMG_STOP], NULL, screen, &stopRect);
+ }
+
+ if (Tux && Tux->num_frames) /* make sure sprite has at least one frame */
+ {
+ SDL_BlitSurface(Tux->frame[0], NULL, screen, &Tuxdest);
+ }
+
+ /* Draw lines of text (do after drawing Tux so text is in front): */
+ if (s1)
+ {
+ loc.x = (screen->w / 2) - (s1->w/2); loc.y = 10;
+ SDL_BlitSurface( s1, NULL, screen, &loc);
+ }
+ if (s2)
+ {
+ loc.x = (screen->w / 2) - (s2->w/2); loc.y = 60;
+ SDL_BlitSurface( s2, NULL, screen, &loc);
+ }
+ if (s3)
+ {
+ //loc.x = 320 - (s3->w/2); loc.y = 300;
+ loc.x = (screen->w / 2) - (s3->w/2); loc.y = 110;
+ SDL_BlitSurface( s3, NULL, screen, &loc);
+ }
+ if (s4)
+ {
+ //loc.x = 320 - (s4->w/2); loc.y = 340;
+ loc.x = (screen->w / 2) - (s4->w/2); loc.y = 200;
+ SDL_BlitSurface( s4, NULL, screen, &loc);
+ }
+
+ /* and update: */
+ SDL_UpdateRect(screen, 0, 0, 0, 0);
+
+ while (!finished)
+ {
+ start = SDL_GetTicks();
+
+ while (SDL_PollEvent(&event))
+ {
+ switch (event.type)
+ {
+ case SDL_QUIT:
+ {
+ cleanup();
+ }
+
+ case SDL_MOUSEBUTTONDOWN:
+ /* "Stop" button - go to main menu: */
+ {
+ if (inRect(stopRect, event.button.x, event.button.y ))
+ {
+ finished = 1;
+ playsound(SND_TOCK);
+ break;
+ }
+ }
+ case SDL_KEYDOWN:
+ {
+ finished = 1;
+ playsound(SND_TOCK);
+ }
+ }
+ }
+
+ /* --- make tux blink --- */
+ switch (frame % TUX6)
+ {
+ case 0: tux_frame = 1; break;
+ case TUX1: tux_frame = 2; break;
+ case TUX2: tux_frame = 3; break;
+ case TUX3: tux_frame = 4; break;
+ case TUX4: tux_frame = 3; break;
+ case TUX5: tux_frame = 2; break;
+ default: tux_frame = 0;
+ }
+
+ if (Tux && tux_frame)
+ {
+ SDL_BlitSurface(Tux->frame[tux_frame - 1], NULL, screen, &Tuxdest);
+// SDL_UpdateRect(screen, Tuxdest.x+37, Tuxdest.y+40, 70, 45);
+ SDL_UpdateRect(screen, Tuxdest.x, Tuxdest.y, Tuxdest.w, Tuxdest.h);
+
+ }
+ /* Wait so we keep frame rate constant: */
+ while ((SDL_GetTicks() - start) < 33)
+ {
+ SDL_Delay(20);
+ }
+ frame++;
+ } // End of while (!finished) loop
+
+ SDL_FreeSurface(s1);
+ SDL_FreeSurface(s2);
+ SDL_FreeSurface(s3);
+ SDL_FreeSurface(s4);
+}
+
+
+void main_scmo(menu_options* mo) //set custom menu opts for main
+{
+ mo->ygap = 15;
+}
+
+int run_main_menu(void)
+{
+ const char* menu_text[7] =
+ {N_("Play Alone"),
+ N_("LAN Game"),
+ N_("Play With Friends"),
+ N_("Factoroids!"),
+ N_("Help"),
+ N_("More Options"),
+ N_("Quit")};
+ sprite* sprites[7] =
+ {NULL, NULL, NULL, NULL, NULL, NULL,NULL};
+ menu_options menu_opts;
+ int choice,ret;
+
+ // Set up the sprites
+ sprites[0] = sprite_list[SPRITE_ALONE];
+ sprites[1] = sprite_list[SPRITE_LAN];
+ sprites[2] = sprite_list[SPRITE_FRIENDS];
+ sprites[3] = sprite_list[SPRITE_FACTOROIDS];
+ sprites[4] = sprite_list[SPRITE_HELP];
+ sprites[5] = sprite_list[SPRITE_OPTIONS];
+ sprites[6] = sprite_list[SPRITE_QUIT];
+
+ //set_default_menu_options(&menu_opts);
+ //menu_opts.ytop = 100;
+ //menu_opts.ygap = 15;
+
+ //This function takes care of all the drawing and receives
+ //user input:
+ choice = choose_menu_item(menu_text,sprites,7,NULL,main_scmo);
+
+ while (choice >= 0) {
+ switch (choice) {
+ case 0: {
+ // All single player modes
+ ret = run_game_menu();
+ break;
+ }
+ case 1: {
+ ret = run_lan_menu();
+ break;
+ }
+ case 2: {
+ // Multiplayer games
+ ret = run_multiplay_menu();
+ break;
+ }
+ case 3: {
+ // Factroids et. al.
+ ret = run_activities_menu();
+ break;
+ }
+ case 4: {
+ // Help
+ Opts_SetHelpMode(1);
+ Opts_SetDemoMode(0);
+ if (Opts_GetGlobalOpt(MENU_MUSIC)) //Turn menu music off for game
+ {audioMusicUnload();}
+ game();
+ RecalcTitlePositions();
+ if (Opts_GetGlobalOpt(MENU_MUSIC)) //Turn menu music back on
+ {audioMusicLoad( "tuxi.ogg", -1 );}
+ Opts_SetHelpMode(0);
+ break;
+ }
+ case 5: {
+ // More options
+ ret = run_options_menu();
+ break;
+ }
+ case 6: {
+ // Quit
+ tmdprintf("Exiting main menu\n");
+ return 0;
+ }
+ }
+ menu_opts.starting_entry = choice;
+ choice = choose_menu_item(menu_text,sprites,7,NULL,main_scmo);
+ }
+ return 0;
+}
+
+#define NUM_GAME_MENU_ITEMS 5
+int run_game_menu(void)
+{
+ const char* menu_text[NUM_GAME_MENU_ITEMS] =
+ {N_("Math Command Training Academy"),
+ N_("Math Command Fleet Missions"),
+ N_("Play Arcade Game"),
+ N_("Play Custom Game"),
+ N_("Main menu")};
+
+ sprite* sprites[NUM_GAME_MENU_ITEMS] = {NULL, NULL, NULL, NULL, NULL};
+
+ int ret, choice = 0;
+
+ sprites[0] = sprite_list[SPRITE_TRAINING];
+ sprites[1] = sprite_list[SPRITE_CAMPAIGN];
+ sprites[2] = sprite_list[SPRITE_ARCADE];
+ sprites[3] = sprite_list[SPRITE_CUSTOM];
+ sprites[4] = sprite_list[SPRITE_MAIN];
+
+ while (choice >= 0) {
+ choice = choose_menu_item(menu_text,sprites,NUM_GAME_MENU_ITEMS,NULL,NULL);
+ switch (choice) {
+ case 0:
+ ret = run_lessons_menu();
+ break;
+ case 1:
+ ret = start_campaign();
+ break;
+ case 2:
+ ret = run_arcade_menu();
+ break;
+ case 3:
+ ret = run_custom_menu();
+ break;
+ case 4:
+ return 0;
+ default:
+ tmdprintf("choose_menu_item() returned %d--returning\n", choice);
+ return 0;
+ }
+ }
+ return 0;
+}
+
+/*
+Set up and start a turn-based multiplayer game. Some funky heap issues so
+quarantine it behind the return for the time being.
+*/
+int run_multiplay_menu(void)
+{
+ int nplayers = 0;
+ int mode = -1;
+ int difficulty = -1;
+ char npstr[HIGH_SCORE_NAME_LENGTH * 3];
+
+
+ const char* menu_text[3] =
+ {N_("Score Sweep"),
+ N_("Elimination"),
+ N_("Main menu")};
+
+ //just leech settings from arcade modes
+ const char* diff_menu_text[NUM_MATH_COMMAND_LEVELS + 1] =
+ {N_("Space Cadet"),
+ N_("Scout"),
+ N_("Ranger"),
+ N_("Ace"),
+ N_("Commando"),
+ N_("Main menu")};
+
+
+ sprite* modesprites[3] = {NULL, NULL, NULL};
+ sprite* diffsprites[6] = {NULL, NULL, NULL, NULL, NULL, NULL};
+ // Set up the sprites
+ modesprites[0] = sprite_list[SPRITE_SSWEEP];
+ modesprites[1] = sprite_list[SPRITE_ELIMINATION];
+ modesprites[2] = sprite_list[SPRITE_MAIN];
+
+ diffsprites[0] = sprite_list[SPRITE_CADET];
+ diffsprites[1] = sprite_list[SPRITE_SCOUT];
+ diffsprites[2] = sprite_list[SPRITE_RANGER];
+ diffsprites[3] = sprite_list[SPRITE_ACE];
+ diffsprites[4] = sprite_list[SPRITE_COMMANDO];
+ diffsprites[5] = sprite_list[SPRITE_MAIN];
+
+ while (1)
+ {
+ //choose difficulty
+ difficulty = choose_menu_item(diff_menu_text, diffsprites,
+ NUM_MATH_COMMAND_LEVELS + 1, NULL, NULL);
+
+ if (difficulty == -1 || difficulty >= NUM_MATH_COMMAND_LEVELS)
+ break; //user chose main menu or hit escape
+
+ //choose mode
+ mode = choose_menu_item(menu_text,modesprites,3,NULL,NULL);
+ if (mode == 2 || mode == -1)
+ break;
+
+ //ask how many players
+ while (nplayers <= 0 || nplayers > MAX_PLAYERS)
+ {
+ NameEntry(npstr, _("How many kids are playing?"),
+ _("(Between 2 and 4 players)"));
+ nplayers = atoi(npstr);
+ }
+
+
+ mp_set_parameter(PLAYERS, nplayers);
+ mp_set_parameter(MODE, mode);
+ mp_set_parameter(DIFFICULTY, difficulty);
+
+ //RUN!
+ mp_run_multiplayer();
+ }
+
+ return 0;
+}
+
+/////////////////////////// LAN game menu()////////////
+
+
+int run_lan_menu(void)
+{
+ int mode = -1;
+ int servers_found = 0;
+
+ const char* menu_text[3] =
+ {N_("Host"),
+ N_("Join"),
+ N_("Main menu")};
+
+ sprite* modesprites[3] = {NULL, NULL, NULL};
+ // Set up the sprites
+ modesprites[0] = sprite_list[SPRITE_SERVER];
+ modesprites[1] = sprite_list[SPRITE_CLIENT];
+ modesprites[2] = sprite_list[SPRITE_MAIN];
+
+ while (1)
+ {
+ //choose mode
+ mode = choose_menu_item(menu_text, modesprites, 3, NULL, NULL);
+ if (mode == 2 || mode == -1)
+ break;
+
+// if(mode == 0) //chooses Host
+// run_server_menu();
+
+ if(mode == 1)
+ {
+ if(detecting_servers(_("Detecting Servers"), _("Please Wait")))
+ {
+ int stdby;
+ char buf[256];
+ snprintf(buf, 256, _("Connected to server: %s"), LAN_ConnectedServerName());
+ NameEntry(player_name, buf, _("Enter your Name:"));
+ LAN_SetName(player_name);
+ Ready(_("Click OK when Ready"));
+ LAN_StartGame();
+ stdby = Standby(_("Waiting For Other Players"),_("To Connect"));
+ if (stdby == 1)
+ {
+ Opts_SetLanMode(1); // Tells game() we are playing over network
+ game();
+ Opts_SetLanMode(0); // Go back to local play
+ }
+ else
+ {
+ ShowMessage(NULL, _("Sorry, game already in progress."), NULL, NULL);
+ }
+ }
+ else
+ {
+ ShowMessage(NULL, _("Sorry, no server could be found."), NULL, NULL);
+ break;
+ }
+ }
+ }
+
+ return 0;
+
+}
+
+/*Dont think we need this..*/
+//int run_server_menu(void)
+//{
+
+// int difficulty = -1;
+ // n=1;
+// int g;
+ //just leech settings from arcade modes
+// const char* diff_menu_text[NUM_MATH_COMMAND_LEVELS + 1] =
+// {N_("Space Cadet"),
+// N_("Scout"),
+// N_("Ranger"),
+// N_("Ace"),
+// N_("Commando"),
+// N_("Main menu")};
+
+
+
+// sprite* diffsprites[6] = {NULL, NULL, NULL, NULL, NULL, NULL};
+
+
+// diffsprites[0] = sprite_list[SPRITE_CADET];
+// diffsprites[1] = sprite_list[SPRITE_SCOUT];
+// diffsprites[2] = sprite_list[SPRITE_RANGER];
+// diffsprites[3] = sprite_list[SPRITE_ACE];
+// diffsprites[4] = sprite_list[SPRITE_COMMANDO];
+// diffsprites[5] = sprite_list[SPRITE_MAIN];
+
+// while (1)
+// {
+ //choose difficulty
+// difficulty = choose_menu_item(diff_menu_text,diffsprites,6,NULL,NULL);
+// if (difficulty == -1 || difficulty >= NUM_MATH_COMMAND_LEVELS)
+// { break;} //user chose main menu or hit escape
+// else
+// {NameEntry(port, _("Enter the PORT"),
+// _(""));
+
+// game();}
+// break;
+// }
+// return 0;
+
+
+//}
+
+
+
+
+int run_arcade_menu(void)
+{
+ const char* menu_text[7] =
+ {N_("Space Cadet"),
+ N_("Scout"),
+ N_("Ranger"),
+ N_("Ace"),
+ N_("Commando"),
+ N_("Hall Of Fame"),
+ N_("Main menu")};
+ const char* arcade_config_files[5] =
+ {"arcade/space_cadet",
+ "arcade/scout",
+ "arcade/ranger",
+ "arcade/ace",
+ "arcade/commando"
+ };
+
+ const int arcade_high_score_tables[5] =
+ {CADET_HIGH_SCORE,
+ SCOUT_HIGH_SCORE,
+ RANGER_HIGH_SCORE,
+ ACE_HIGH_SCORE,
+ COMMANDO_HIGH_SCORE
+ };
+ sprite* sprites[7] =
+ {NULL, NULL, NULL, NULL, NULL, NULL, NULL};
+ menu_options menu_opts;
+ int choice,hs_table;
+
+ // Set up the sprites
+ sprites[0] = sprite_list[SPRITE_CADET];
+ sprites[1] = sprite_list[SPRITE_SCOUT];
+ sprites[2] = sprite_list[SPRITE_RANGER];
+ sprites[3] = sprite_list[SPRITE_ACE];
+ sprites[4] = sprite_list[SPRITE_COMMANDO];
+ sprites[5] = sprite_list[SPRITE_TROPHY];
+ sprites[6] = sprite_list[SPRITE_MAIN];
+
+// set_default_menu_options(&menu_opts);
+// menu_opts.ytop = 100;
+
+ //This function takes care of all the drawing and receives
+ //user input:
+ choice = choose_menu_item(menu_text, sprites, 7, NULL, NULL);
+
+ while (choice >= 0) {
+ if (choice < NUM_MATH_COMMAND_LEVELS) {
+ // Play arcade game
+ if (read_named_config_file(arcade_config_files[choice]))
+ {
+ audioMusicUnload();
+ Opts_SetLanMode(0);
+ game();
+ RecalcTitlePositions();
+ if (Opts_GetGlobalOpt(MENU_MUSIC)) {
+ audioMusicLoad( "tuxi.ogg", -1 );
+ }
+ /* See if player made high score list! */
+ read_high_scores(); /* Update, in case other users have added to it */
+ hs_table = arcade_high_score_tables[choice];
+ if (check_score_place(hs_table, Opts_LastScore()) < HIGH_SCORES_SAVED){
+
+ char player_name[HIGH_SCORE_NAME_LENGTH * 3];
+
+ /* Get name from player: */
+ HighScoreNameEntry(&player_name[0]);
+ insert_score(player_name, hs_table, Opts_LastScore());
+ /* Show the high scores. Note the user will see his/her */
+ /* achievement even if (in the meantime) another player */
+ /* has in fact already bumped this score off the table. */
+ DisplayHighScores(hs_table);
+ /* save to disk: */
+ /* See "On File Locking" in fileops.c */
+ append_high_score(choice,Opts_LastScore(),&player_name[0]);
+
+#ifdef TUXMATH_DEBUG
+ print_high_scores(stderr);
+#endif
+ }
+ } else {
+ fprintf(stderr, "\nCould not find %s config file\n",arcade_config_files[choice]);
+ }
+
+ } else if (choice == NUM_MATH_COMMAND_LEVELS) {
+ // Display the Hall of Fame
+ DisplayHighScores(CADET_HIGH_SCORE);
+ }
+ else {
+ // Return to main menu
+ return 0;
+ }
+ set_default_menu_options(&menu_opts);
+ menu_opts.starting_entry = choice;
+ choice = choose_menu_item(menu_text,sprites,7,NULL, NULL);
+ }
+
+ return 0;
+}
+
+
+int run_custom_menu(void)
+{
+ const char *s1, *s2, *s3, *s4;
+ s1 = _("Edit 'options' file in your home directory");
+ s2 = _("to create customized game!");
+ s3 = _("Press a key or click your mouse to start game.");
+ s4 = _("See README.txt for more information");
+ ShowMessage(s1, s2, s3, s4);
+
+ if (read_user_config_file()) {
+ if (Opts_GetGlobalOpt(MENU_MUSIC))
+ audioMusicUnload();
+
+ game();
+ RecalcTitlePositions();
+ write_user_config_file();
+
+ if (Opts_GetGlobalOpt(MENU_MUSIC))
+ audioMusicLoad( "tuxi.ogg", -1 );
+ }
+
+ return 0;
+}
+
+int run_activities_menu(void)
+{
+ const char* menu_text[3] =
+ {N_("Factors"),
+ N_("Fractions"),
+ N_("Main menu")};
+ const int factoroids_high_score_tables[2] =
+ {FACTORS_HIGH_SCORE, FRACTIONS_HIGH_SCORE};
+ sprite* sprites[3] =
+ {NULL, NULL, NULL};
+ menu_options menu_opts;
+ int choice, hs_table;
+
+ // Set up the sprites
+ sprites[0] = sprite_list[SPRITE_FACTORS];
+ sprites[1] = sprite_list[SPRITE_FRACTIONS];
+ sprites[2] = sprite_list[SPRITE_MAIN];
+
+ set_default_menu_options(&menu_opts);
+ menu_opts.ytop = 100;
+
+ //This function takes care of all the drawing and receives
+ //user input:
+ choice = choose_menu_item(menu_text, sprites, 3, NULL, NULL);
+
+ while (choice >= 0) {
+ switch(choice){
+ case 0:
+ audioMusicUnload();
+ factors();
+
+ if (Opts_GetGlobalOpt(MENU_MUSIC)) {
+ audioMusicLoad( "tuxi.ogg", -1 );
+ }
+ break;
+ case 1:
+ audioMusicUnload();
+ fractions();
+
+ if (Opts_GetGlobalOpt(MENU_MUSIC)) {
+ audioMusicLoad( "tuxi.ogg", -1 );
+ }
+ break;
+ case 2:
+ // Return to main menu
+ return 0;
+ }
+
+ hs_table = factoroids_high_score_tables[choice];
+ if (check_score_place(hs_table, Opts_LastScore()) < HIGH_SCORES_SAVED){
+
+ char player_name[HIGH_SCORE_NAME_LENGTH * 3];
+
+ /* Get name from player: */
+ HighScoreNameEntry(&player_name[0]);
+ insert_score(player_name, hs_table, Opts_LastScore());
+ /* Show the high scores. Note the user will see his/her */
+ /* achievement even if (in the meantime) another player */
+ /* has in fact already bumped this score off the table. */
+ DisplayHighScores(hs_table);
+ /* save to disk: */
+ /* See "On File Locking" in fileops.c */
+ append_high_score(hs_table,Opts_LastScore(),&player_name[0]);
+
+#ifdef TUXMATH_DEBUG
+ print_high_scores(stderr);
+#endif
+ }
+ else {
+ fprintf(stderr, "\nCould not find config file\n");
+ }
+
+ menu_opts.starting_entry = choice;
+ choice = choose_menu_item(menu_text,sprites,3,NULL,NULL);
+
+
+ }
+
+
+ return 0;
+}
+
+
+int run_options_menu(void)
+{
+ /*
+ // Use the following version if we get "Settings" implemented
+ const unsigned char* menu_text[5] =
+ {(const unsigned char*)N_("Settings"),
+ (const unsigned char*)N_("Demo"),
+ (const unsigned char*)N_("Credits"),
+ (const unsigned char*)N_("Project Info"),
+ (const unsigned char*)N_("Main Menu")};
+ sprite* sprites[5] =
+ {NULL, NULL, NULL, NULL, NULL};
+ */
+ const char* menu_text[4] =
+ {N_("Demo"),
+ N_("Project Info"),
+ N_("Credits"),
+ N_("Main Menu")};
+
+ sprite* sprites[4] =
+ {NULL, NULL, NULL, NULL};
+ int n_menu_entries = 4;
+ menu_options menu_opts;
+ int choice;
+
+ // Set up the sprites
+ sprites[0] = sprite_list[SPRITE_ARCADE];
+ sprites[1] = sprite_list[SPRITE_HELP];
+ sprites[2] = sprite_list[SPRITE_CREDITS];
+ sprites[3] = sprite_list[SPRITE_MAIN];
+
+ //set_default_menu_options(&menu_opts);
+ //menu_opts.ytop = 100;
+
+ //This function takes care of all the drawing and receives
+ //user input:
+ choice = choose_menu_item(menu_text, sprites, n_menu_entries, NULL, NULL);
+
+ while (choice >= 0) {
+ switch (choice) {
+ /*
+ case 0: {
+ // Settings
+ NotImplemented();
+ break;
+ }*/
+ case 0: {
+ // Demo
+ if (read_named_config_file("demo"))
+ {
+ audioMusicUnload();
+ game();
+ RecalcTitlePositions();
+ if (Opts_GetGlobalOpt(MENU_MUSIC)) {
+ audioMusicLoad( "tuxi.ogg", -1 );
+ }
+ } else {
+ fprintf(stderr, "\nCould not find demo config file\n");
+ }
+
+ break;
+ }
+ case 1: {
+ // Project Info
+ //NotImplemented();
+ ShowMessage(_("TuxMath is free and open-source!"),
+ _("You can help make it better by reporting problems,"),
+ _("suggesting improvements, or adding code."),
+ _("Discuss the future at tuxmath-devel at lists.sourceforge.net"));
+ break;
+ }
+ case 2: {
+ // Credits
+ //TitleScreen_unload_media();
+ credits();
+ //TitleScreen_load_media();
+ break;
+ }
+ case 3: {
+ // Main menu
+ return 0;
+ }
+ }
+
+ set_default_menu_options(&menu_opts);
+ menu_opts.starting_entry = choice;
+ choice = choose_menu_item(menu_text,sprites,n_menu_entries,NULL,NULL);
+ }
+
+ return 0;
+}
+
+
+void lessons_scmo(menu_options* mo)
+{
+mo->ytop = 30;
+}
+/* Display a list of tuxmath config files in the missions directory */
+/* and allow the player to pick one (AKA "Lessons"). */
+
+/* returns 0 if user pressed escape
+ * 1 if config was set correctly
+ */
+int run_lessons_menu(void)
+{
+ int chosen_lesson = -1;
+ menu_options menu_opts;
+ sprite** star_sprites = NULL;
+
+ /* Set up sprites (as long as gold star list is valid) */
+ if (lesson_list_goldstars != NULL)
+ {
+ int i;
+ star_sprites = (sprite**)malloc(num_lessons * sizeof(sprite*));
+ for (i = 0; i < num_lessons; i++)
+ {
+ if (lesson_list_goldstars[i])
+ star_sprites[i] = sprite_list[SPRITE_GOLDSTAR];
+ else
+ star_sprites[i] = sprite_list[SPRITE_NO_GOLDSTAR];
+ }
+ }
+// set_default_menu_options(&menu_opts);
+// ytop = 30;
+
+ //This function takes care of all the drawing and receives
+ //user input:
+ chosen_lesson = choose_menu_item((const char**)lesson_list_titles, star_sprites, num_lessons, NULL, &lessons_scmo);
+
+ while (chosen_lesson >= 0)
+ {
+ if (Opts_GetGlobalOpt(MENU_SOUND))
+ playsound(SND_POP);
+
+ /* Re-read global settings first in case any settings were */
+ /* clobbered by other lesson or arcade games this session: */
+ read_global_config_file();
+ /* Now read the selected file and play the "mission": */
+ if (read_named_config_file(lesson_list_filenames[chosen_lesson]))
+ {
+ if (Opts_GetGlobalOpt(MENU_MUSIC)) //Turn menu music off for game
+ {audioMusicUnload();}
+
+ Opts_SetLanMode(0);
+ game();
+ RecalcTitlePositions();
+
+ /* If successful, display Gold Star for this lesson! */
+ if (MC_MissionAccomplished())
+ {
+ lesson_list_goldstars[chosen_lesson] = 1;
+ star_sprites[chosen_lesson] = sprite_list[SPRITE_GOLDSTAR];
+ /* and save to disk: */
+ write_goldstars();
+ }
+
+ if (Opts_GetGlobalOpt(MENU_MUSIC)) //Turn menu music back on
+ {audioMusicLoad("tuxi.ogg", -1);}
+ }
+ else // Something went wrong - could not read lesson config file:
+ {
+ fprintf(stderr, "\nCould not find file: %s\n", lesson_list_filenames[chosen_lesson]);
+ chosen_lesson = -1;
+ }
+ // Let the user choose another lesson; start with the screen and
+ // selection that we ended with
+ set_default_menu_options(&menu_opts);
+ menu_opts.starting_entry = chosen_lesson;
+ chosen_lesson = choose_menu_item((const char**)lesson_list_titles, star_sprites, num_lessons, &menu_opts, &lessons_scmo);
+ }
+ if (star_sprites)
+ {
+ free(star_sprites);
+ star_sprites = NULL;
+ }
+
+ if (chosen_lesson < 0)
+ return 0;
+ else
+ return 1;
+}
+
+
+/* Sets the user home directory in a tree of possible users */
+/* -1 indicates that the user wants to quit without logging in, */
+/* 0 indicates that a choice has been made. */
+int run_login_menu(void)
+{
+ int n_login_questions = 0;
+ char **user_login_questions = NULL;
+ int n_users = 0;
+ char **user_names = NULL;
+ menu_options menu_opts;
+ int chosen_login = -1;
+ int level;
+ int i;
+ char *trailer_quit = "Quit";
+ char *trailer_back = "Back";
+ SDLMod mod;
+
+ // Check for & read user_login_questions file
+ n_login_questions = read_user_login_questions(&user_login_questions);
+
+ // Check for & read user_menu_entries file
+ n_users = read_user_menu_entries(&user_names);
+
+ if (n_users == 0)
+ return 0; // a quick exit, there's only one user
+
+ // Check for a highscores file
+ if (high_scores_found_in_user_dir())
+ set_high_score_path();
+
+ level = 0;
+ set_default_menu_options(&menu_opts);
+ if (n_login_questions > 0)
+ menu_opts.title = user_login_questions[0];
+ menu_opts.trailer = trailer_quit;
+
+ while (n_users) {
+ // Get the user choice
+ chosen_login = choose_menu_item((const char**)user_names, NULL, n_users, &menu_opts, NULL);
+ // Determine whether there were any modifier (CTRL) keys pressed
+ mod = SDL_GetModState();
+ if (chosen_login == -1 || chosen_login == n_users) {
+ // User pressed escape or selected Quit/Back, handle by quitting
+ // or going up a level
+ if (level == 0) {
+ // We are going to quit without logging in.
+ // Clean up memory (prob. not necessary, but prevents Valgrind errors!)
+ for (i = 0; i < n_login_questions; i++)
+ free(user_login_questions[i]);
+ free(user_login_questions);
+ for (i = 0; i < n_users; i++)
+ free(user_names[i]);
+ free(user_names);
+ return -1;
+ }
+ else {
+ // Go back up one level of the directory tree
+ user_data_dirname_up();
+ level--;
+ menu_opts.starting_entry = -1;
+ }
+ }
+ else {
+ // User chose an entry, set it up
+ user_data_dirname_down(user_names[chosen_login]);
+ level++;
+ menu_opts.starting_entry = 0;
+ }
+ // Check for a highscores file
+ if (high_scores_found_in_user_dir())
+ set_high_score_path();
+ // Free the entries from the previous menu
+ for (i = 0; i < n_users; i++)
+ free(user_names[i]);
+ free(user_names);
+ user_names = NULL;
+ // If the CTRL key was pressed, choose this as the identity, even
+ // if there is a lower level to the hierarchy
+ if (mod & KMOD_CTRL)
+ break;
+ // Set the title appropriately for the next menu
+ if (level < n_login_questions)
+ menu_opts.title = user_login_questions[level];
+ else
+ menu_opts.title = NULL;
+ if (level == 0)
+ menu_opts.trailer = trailer_quit;
+ else
+ menu_opts.trailer = trailer_back;
+ // Check to see if there are more choices to be made
+ n_users = read_user_menu_entries(&user_names);
+ }
+
+ // The user home directory is set, clean up remaining memory
+ for (i = 0; i < n_login_questions; i++)
+ free(user_login_questions[i]);
+ free(user_login_questions);
+
+ // Signal success
+ return 0;
+}
+
+
+/****************************************************************/
+/* choose_menu_item: menu navigation utility function */
+/* (the function returns the index for the selected menu item) */
+/* -1 indicates that the user pressed escape */
+/****************************************************************/
+int choose_menu_item(const char **menu_text, sprite **menu_sprites, int n_menu_entries, menu_options* custom_mo, void (*set_custom_menu_opts)(menu_options*) )
+{
+ // Pixel renderings of menu text choices
+ SDL_Surface **menu_item_unselected = NULL;
+ SDL_Surface **menu_item_selected = NULL;
+ // Display region for menu choices
+ SDL_Rect *menu_text_rect = NULL;
+ // Translucent mouse "buttons" around menu text
+ SDL_Rect *menu_button_rect = NULL;
+ // Menu sprite locations
+ SDL_Rect *menu_sprite_rect = NULL;
+
+ // The section of the background that the menu rects actually cover
+ SDL_Rect *back_text_rect = NULL,
+ *back_button_rect = NULL,
+ *back_sprite_rect = NULL;
+ SDL_Rect left_arrow_rect, right_arrow_rect;
+ SDL_Rect temp_rect; //temporary copy of a dest rect that may be written to by SDL_BlitSurface
+
+ menu_options menu_opts;
+
+ Uint32 frame_counter = 0;
+ Uint32 frame_start = 0; //For keeping frame rate constant
+ Uint32 frame_now = 0;
+ int stop = 0;
+ int loc = 0; //The currently selected menu item
+ int old_loc = 1;
+ int loc_screen_start = 0; //The number of the top entry on current screen
+ int old_loc_screen_start = 0;
+ int redraw = 0;
+ int n_entries_per_screen = 0;
+ int buttonheight = 0;
+ int i = 0;
+ int imod = 0; // i % n_entries_per_screen
+ int tux_frame = 0;
+ int click_flag = 1;
+ int use_sprite = 0;
+ int warp_mouse = 0;
+ int title_offset = 0;
+ int have_trailer = 0;
+
+#ifdef TUXMATH_DEBUG
+ fprintf(stderr, "Entering choose_menu_item():\n");
+#endif
+
+#ifdef TUXMATH_DEBUG
+ fprintf(stderr,"%d menu entries:\n",n_menu_entries);
+ for (i = 0; i < n_menu_entries; i++)
+ fprintf(stderr,"%s\n",menu_text[i]);
+#endif
+
+ if (custom_mo == NULL)
+ set_default_menu_options(&menu_opts);
+ else
+ menu_opts = *custom_mo;
+ if (set_custom_menu_opts != NULL)
+ set_custom_menu_opts(&menu_opts);
+
+ tmdprintf("Allocating memory\n");
+ /**** Memory allocation for menu text ****/
+ title_offset = 0;
+ if (menu_opts.title != NULL)
+ title_offset = 1;
+ if (menu_opts.trailer != NULL)
+ have_trailer = 1;
+ menu_item_unselected = (SDL_Surface**)malloc((n_menu_entries+title_offset+have_trailer) * sizeof(SDL_Surface*));
+ menu_item_selected = (SDL_Surface**)malloc((n_menu_entries+title_offset+have_trailer) * sizeof(SDL_Surface*));
+ if (menu_item_unselected == NULL || menu_item_selected == NULL) {
+ free(menu_item_unselected);
+ free(menu_item_selected);
+ return -2; // error
+ }
+
+ /**** Render the menu choices ****/
+ if (title_offset)
+ {
+ menu_item_unselected[0] = BlackOutline( _(menu_opts.title), DEFAULT_MENU_FONT_SIZE, &red);
+ // It will never be selected, so we don't have to do anything for selected.
+ menu_item_selected[0] = NULL;
+ }
+ for (i = 0; i < n_menu_entries; i++)
+ {
+ menu_item_unselected[i+title_offset] = BlackOutline( _(menu_text[i]), DEFAULT_MENU_FONT_SIZE, &white );
+ menu_item_selected[i+title_offset] = BlackOutline( _(menu_text[i]), DEFAULT_MENU_FONT_SIZE, &yellow);
+ }
+ if (have_trailer) {
+ menu_item_unselected[n_menu_entries+title_offset] = BlackOutline( _(menu_opts.trailer), DEFAULT_MENU_FONT_SIZE, &white );
+ menu_item_selected[n_menu_entries+title_offset] = BlackOutline( _(menu_opts.trailer), DEFAULT_MENU_FONT_SIZE, &yellow);
+ }
+ // We won't need the menu_text again, so now we can keep track of
+ // the total entries including the title & trailer
+ n_menu_entries += title_offset+have_trailer;
+
+// recalcMenuPositions();
+
+ /**** Calculate the menu item heights and the number of ****/
+ /**** entries per screen ****/
+ if (menu_opts.buttonheight <= 0) {
+ buttonheight = 0;
+ for (i = 0; i < n_menu_entries; i++)
+ if (buttonheight < menu_item_unselected[i]->h)
+ buttonheight = menu_item_unselected[i]->h;
+ buttonheight += 10;
+ } else
+ buttonheight = menu_opts.buttonheight;
+
+ // First try using the whole screen; if we need more than one
+ // screen, then we have to save space for the arrows by respecting
+ // ybottom
+ n_entries_per_screen = (int) (screen->h - menu_opts.ytop+menu_opts.ygap)/(buttonheight + menu_opts.ygap);
+ if (n_entries_per_screen < n_menu_entries)
+ n_entries_per_screen = (int) (menu_opts.ybottom - menu_opts.ytop+menu_opts.ygap)/(buttonheight + menu_opts.ygap);
+
+ if (n_entries_per_screen > n_menu_entries)
+ n_entries_per_screen = n_menu_entries;
+
+ /**** Memory allocation for current screen rects ****/
+ menu_text_rect = (SDL_Rect*) malloc(n_entries_per_screen * sizeof(SDL_Rect));
+ menu_button_rect = (SDL_Rect*) malloc(n_entries_per_screen * sizeof(SDL_Rect));
+ back_text_rect = (SDL_Rect*) malloc(n_entries_per_screen * sizeof(SDL_Rect));
+ back_button_rect = (SDL_Rect*) malloc(n_entries_per_screen * sizeof(SDL_Rect));
+ if (menu_text_rect == NULL || menu_button_rect == NULL ||
+ back_text_rect == NULL || back_button_rect == NULL) {
+ free(menu_text_rect);
+ free(menu_button_rect);
+ free(back_text_rect);
+ free(back_button_rect);
+ return -2;
+ }
+ if (menu_sprites != NULL) {
+ menu_sprite_rect = (SDL_Rect*) malloc(n_entries_per_screen * sizeof(SDL_Rect));
+ back_sprite_rect = (SDL_Rect*) malloc(n_entries_per_screen * sizeof(SDL_Rect));
+ if (menu_sprite_rect == NULL || back_sprite_rect == NULL) {
+ free(menu_sprite_rect);
+ free(back_sprite_rect);
+ return -2;
+ }
+ }
+
+ /**** Define the locations of graphical elements on the screen ****/
+ /* Arrow buttons in right lower corner, inset by 20 pixels */
+ /* with a 10 pixel space between: */
+ if (images[IMG_RIGHT])
+ {
+ right_arrow_rect.w = images[IMG_RIGHT]->w;
+ right_arrow_rect.h = images[IMG_RIGHT]->h;
+ right_arrow_rect.x = screen->w - images[IMG_RIGHT]->w - 20;
+ right_arrow_rect.y = screen->h - images[IMG_RIGHT]->h - 20;
+ }
+
+ if (images[IMG_LEFT])
+ {
+ left_arrow_rect.w = images[IMG_LEFT]->w;
+ left_arrow_rect.h = images[IMG_LEFT]->h;
+ left_arrow_rect.x = right_arrow_rect.x - 10 - images[IMG_LEFT]->w;
+ left_arrow_rect.y = screen->h - images[IMG_LEFT]->h - 20;
+ }
+ /* Red "Stop" circle in upper right corner to go back to main menu: */
+ if (images[IMG_STOP])
+ {
+ stopRect.w = images[IMG_STOP]->w;
+ stopRect.h = images[IMG_STOP]->h;
+ stopRect.x = screen->w - images[IMG_STOP]->w;
+ stopRect.y = 0;
+ }
+
+ /* Set initial menu rect sizes. The widths will change depending */
+ /* on the size of the text displayed in each rect. Set the widths */
+ /* for the current screen of menu items. */
+ loc = menu_opts.starting_entry + title_offset; // Initially selected item
+ loc_screen_start = loc - (loc % n_entries_per_screen);
+ if (loc_screen_start < 0 || loc_screen_start*n_entries_per_screen > n_menu_entries)
+ loc_screen_start = 0; // in case starting_entry was -1 (or wasn't set)
+ imod = loc-loc_screen_start;
+ for (i = 0; i < n_entries_per_screen; i++)
+ {
+ menu_button_rect[i].x = menu_opts.xleft;
+ menu_text_rect[i].x = menu_opts.xleft + 15; // 15 is left gap
+ if (menu_sprites != NULL)
+ menu_text_rect[i].x += 60; // 40 is sprite width, 20 is gap
+ if (i > 0)
+ menu_text_rect[i].y = menu_text_rect[i - 1].y + buttonheight + menu_opts.ygap;
+ else
+ menu_text_rect[i].y = menu_opts.ytop;
+ menu_button_rect[i].y = menu_text_rect[i].y-5;
+ menu_text_rect[i].h = buttonheight-10;
+ menu_button_rect[i].h = buttonheight;
+ menu_button_rect[i].w = menu_text_rect[i].w = 0;
+ if (i + loc_screen_start < n_menu_entries) {
+ menu_text_rect[i].w = menu_item_unselected[i+loc_screen_start]->w;
+ menu_button_rect[i].w = menu_text_rect[i].w + 30;
+ }
+ if (menu_sprite_rect != NULL) {
+ menu_sprite_rect[i].x = menu_button_rect[i].x+3;
+ menu_sprite_rect[i].y = menu_button_rect[i].y+3;
+ menu_sprite_rect[i].w = 40;
+ menu_sprite_rect[i].h = 50;
+ }
+ }
+
+ if (menu_opts.button_same_width)
+ set_buttons_max_width(menu_button_rect,back_button_rect,n_entries_per_screen);
+
+ for (i = 0; i < n_entries_per_screen; ++i)
+ {
+ if (menu_button_rect)
+ {
+ back_button_rect[i] = menu_button_rect[i];
+ back_button_rect[i].x -= Backrect.x;
+ back_button_rect[i].y -= Backrect.y;
+ }
+ if (menu_text_rect)
+ {
+ back_text_rect[i] = menu_text_rect[i];
+ back_text_rect[i].x -= Backrect.x;
+ back_text_rect[i].y -= Backrect.y;
+ }
+ if (menu_sprite_rect)
+ {
+ back_sprite_rect[i] = menu_sprite_rect[i];
+ back_sprite_rect[i].x -= Backrect.x;
+ back_sprite_rect[i].y -= Backrect.y;
+ }
+ }
+
+ /**** Draw background, title, and Tux: ****/
+ if (current_bkg() )
+ SDL_BlitSurface(current_bkg(), NULL, screen, &Backrect);
+ if (images[IMG_MENU_TITLE])
+ SDL_BlitSurface(images[IMG_MENU_TITLE], NULL, screen, &Titledest);
+ if (Tux && Tux->frame[0])
+ SDL_BlitSurface(Tux->frame[0], NULL, screen, &Tuxdest);
+ SDL_UpdateRect(screen, 0, 0, 0 ,0);
+
+ /* Move mouse to current button: */
+ cursor.x = menu_button_rect[imod].x + menu_button_rect[imod].w/2;
+ cursor.y = menu_button_rect[imod].y + menu_button_rect[imod].h/2;
+// SDL_WarpMouse(cursor.x, cursor.y);
+ SDL_WM_GrabInput(SDL_GRAB_OFF);
+
+
+ /******** Main loop: *********/
+ redraw = 1; // force a full redraw on first pass
+ old_loc_screen_start = loc_screen_start;
+ while (SDL_PollEvent(&event)); // clear pending events
+ while (!stop)
+ {
+ frame_start = SDL_GetTicks(); /* For keeping frame rate constant.*/
+
+ while (SDL_PollEvent(&event))
+ {
+ switch (event.type)
+ {
+ case SDL_QUIT:
+ {
+ cleanup();
+ //exit(0);
+ break;
+ }
+
+ case SDL_MOUSEMOTION:
+ {
+ loc = -1; // By default, don't be in any entry
+ for (i = 0; (i < n_entries_per_screen) && (loc_screen_start + i < n_menu_entries); i++)
+ {
+ if (inRect(menu_button_rect[i], event.motion.x, event.motion.y))
+ {
+ // Play sound if loc is being changed:
+ if (Opts_GetGlobalOpt(MENU_SOUND) && (old_loc != loc_screen_start + i))
+ {
+ playsound(SND_TOCK);
+ }
+ loc = loc_screen_start + i;
+ break; /* from for loop */
+ }
+ }
+
+ /* "Left" button - make click if button active: */
+ if (inRect(left_arrow_rect, event.motion.x, event.motion.y))
+ {
+ if (loc_screen_start - n_entries_per_screen >= 0)
+ {
+ if (Opts_GetGlobalOpt(MENU_SOUND) && click_flag)
+ {
+ playsound(SND_TOCK);
+ click_flag = 0;
+ }
+ }
+ break; /* from case switch */
+ }
+
+ /* "Right" button - go to next page: */
+ else if (inRect(right_arrow_rect, event.motion.x, event.motion.y ))
+ {
+ if (loc_screen_start + n_entries_per_screen < n_menu_entries)
+ {
+ if (Opts_GetGlobalOpt(MENU_SOUND) && click_flag)
+ {
+ playsound(SND_TOCK);
+ click_flag = 0;
+ }
+ }
+ break; /* from case switch */
+ }
+
+ else // Mouse outside of arrow rects - re-enable click sound:
+ {
+ click_flag = 1;
+ break; /* from case switch */
+ }
+ }
+
+ case SDL_MOUSEBUTTONDOWN:
+ {
+ /* Choose a menu entry by mouse click */
+ for (i = 0; (i < n_entries_per_screen) && (loc_screen_start + i < n_menu_entries); i++)
+ {
+ if (inRect(menu_button_rect[i], event.button.x, event.button.y))
+ {
+ if (Opts_GetGlobalOpt(MENU_SOUND))
+ {
+ playsound(SND_POP);
+ }
+
+ loc = loc_screen_start + i;
+ stop = 1;
+ break;
+ }
+ }
+
+ /* "Left" button - go to previous page: */
+ if (inRect(left_arrow_rect, event.button.x, event.button.y))
+ {
+ if (loc_screen_start - n_entries_per_screen >= 0)
+ {
+ //loc = loc_screen_start - n_entries_per_screen;
+ loc_screen_start -= n_entries_per_screen;
+ loc = -1; // nothing selected
+ if (Opts_GetGlobalOpt(MENU_SOUND))
+ {
+ playsound(SND_TOCK);
+ }
+ break;
+ }
+ }
+
+ /* "Right" button - go to next page: */
+ if (inRect( right_arrow_rect, event.button.x, event.button.y ))
+ {
+ if (loc_screen_start + n_entries_per_screen < n_menu_entries)
+ {
+ //loc = loc_screen_start + n_entries_per_screen;
+ loc_screen_start += n_entries_per_screen;
+ loc = -1; // nothing selected
+ if (Opts_GetGlobalOpt(MENU_SOUND))
+ {
+ playsound(SND_TOCK);
+ }
+ break;
+ }
+ }
+
+ /* "Stop" button - go to main menu: */
+ if (inRect(stopRect, event.button.x, event.button.y ))
+ {
+ stop = 2;
+ playsound(SND_TOCK);
+ break;
+ }
+ } /* End of case SDL_MOUSEDOWN */
+
+
+ case SDL_KEYDOWN:
+ {
+ /* Proceed according to particular key pressed: */
+ switch (event.key.keysym.sym)
+ {
+ case SDLK_ESCAPE:
+ {
+ stop = 2;
+ break;
+ }
+
+ case SDLK_RETURN:
+ case SDLK_SPACE:
+ case SDLK_KP_ENTER:
+ {
+ if (Opts_GetGlobalOpt(MENU_SOUND))
+ playsound(SND_POP);
+ stop = 1;
+ break;
+ }
+
+
+ /* Go to previous page, if present: */
+ case SDLK_LEFT:
+ case SDLK_PAGEUP:
+ {
+ if (Opts_GetGlobalOpt(MENU_SOUND))
+ playsound(SND_TOCK);
+ if (loc_screen_start - n_entries_per_screen >= 0) {
+ loc_screen_start -= n_entries_per_screen;
+ loc = -1;
+ }
+ // {loc = loc_screen_start - n_entries_per_screen;}
+ break;
+ }
+
+
+ /* Go to next page, if present: */
+ case SDLK_RIGHT:
+ case SDLK_PAGEDOWN:
+ {
+ if (Opts_GetGlobalOpt(MENU_SOUND))
+ playsound(SND_TOCK);
+ if (loc_screen_start + n_entries_per_screen < n_menu_entries) {
+ loc_screen_start += n_entries_per_screen;
+ loc = -1;
+ }
+ // {loc = (loc_screen_start + n_entries_per_screen);}
+ break;
+ }
+
+ /* Go up one entry, if present: */
+ case SDLK_UP:
+ {
+ if (Opts_GetGlobalOpt(MENU_SOUND))
+ playsound(SND_TOCK);
+ if (loc > title_offset)
+ {loc--;}
+ else if (n_menu_entries <= n_entries_per_screen) {
+ loc = n_menu_entries-1; // wrap around if only 1 screen
+ }
+ else if (loc == -1 && loc_screen_start > 0) {
+ loc = loc_screen_start-1;
+ loc_screen_start -= n_entries_per_screen;
+ }
+ if (loc != old_loc)
+ warp_mouse = 1;
+ break;
+ }
+
+
+ /* Go down one entry, if present: */
+ case SDLK_DOWN:
+ {
+ if (Opts_GetGlobalOpt(MENU_SOUND))
+ playsound(SND_TOCK);
+ if (loc >= 0 && loc + 1 < n_menu_entries)
+ {loc++;}
+ else if (n_menu_entries <= n_entries_per_screen)
+ loc = title_offset; // wrap around if only 1 screen
+ else if (loc == -1)
+ loc = loc_screen_start;
+ if (loc != old_loc)
+ warp_mouse = 1;
+ break;
+ }
+
+
+ /* Toggle screen mode: */
+ case SDLK_F10:
+ {
+ SwitchScreenMode();
+ RecalcTitlePositions();
+ RecalcMenuPositions(&n_entries_per_screen,
+ n_menu_entries,
+ &menu_opts,
+ set_custom_menu_opts,
+ &menu_button_rect,
+ &menu_sprite_rect,
+ &menu_text_rect,
+ &back_button_rect,
+ &back_sprite_rect,
+ &back_text_rect,
+ &left_arrow_rect,
+ &right_arrow_rect);
+ //we're unsure how the entries might shuffle, so return to start
+ loc_screen_start = 0;
+ redraw = 1;
+ break;
+ }
+
+ /* Toggle menu music: */
+ case SDLK_F11:
+ {
+ if (Opts_GetGlobalOpt(MENU_MUSIC))
+ {
+ audioMusicUnload( );
+ Opts_SetGlobalOpt(MENU_MUSIC, 0);
+ }
+ else
+ {
+ Opts_SetGlobalOpt(MENU_MUSIC, 1);
+ audioMusicLoad("tuxi.ogg", -1);
+ }
+ break;
+ }
+#ifdef TESTING_CAMPAIGN
+ case SDLK_c:
+ {
+ start_campaign();
+ RecalcTitlePositions();
+ RecalcMenuPositions(&n_entries_per_screen,
+ n_menu_entries,
+ &menu_opts,
+ set_custom_menu_opts,
+ &menu_button_rect,
+ &menu_sprite_rect,
+ &menu_text_rect,
+ &back_button_rect,
+ &back_sprite_rect,
+ &back_text_rect,
+ &left_arrow_rect,
+ &right_arrow_rect);
+ redraw = 1;
+ }
+
+#endif
+ default:
+ {
+ /* Some other key - do nothing. */
+ }
+
+ break; /* To get out of _outer_ switch/case statement */
+ } /* End of key switch statement */
+ } // End of case SDL_KEYDOWN in outer switch statement
+ } // End event switch statement
+ if (handle_easter_egg(&event) )
+ redraw = 1;
+ else
+ ; //egg_active = 0;
+ } // End SDL_PollEvent while loop
+
+
+
+ // Make sure the menu title is not selected
+ if (loc == 0 && title_offset)
+ loc = title_offset;
+
+ /* Redraw screen: */
+ if (loc >= 0)
+ loc_screen_start = loc - (loc % n_entries_per_screen);
+ if (old_loc_screen_start != loc_screen_start)
+ redraw = 1;
+ if (redraw)
+ {
+ tmdprintf("Updating entire screen\n");
+ /* This is a full-screen redraw */
+ /* Redraw background, title, stop button, and Tux: */
+ if (!current_bkg() || screen->flags & SDL_FULLSCREEN )
+ SDL_FillRect(screen, &screen->clip_rect, 0); //clear to black
+ if (current_bkg())
+ SDL_BlitSurface(current_bkg(), NULL, screen, &Backrect);
+ if (images[IMG_MENU_TITLE])
+ SDL_BlitSurface(images[IMG_MENU_TITLE], NULL, screen, &Titledest);
+ if (images[IMG_STOP])
+ SDL_BlitSurface(images[IMG_STOP], NULL, screen, &stopRect);
+ if (Tux->frame[0])
+ SDL_BlitSurface(Tux->frame[0], NULL, screen, &Tuxdest);
+ /* Redraw the menu entries */
+ for (imod = 0; imod < n_entries_per_screen; imod++)
+ menu_button_rect[imod].w = 0; // so undrawn buttons don't affect width
+ for (i = loc_screen_start, imod = 0; i < loc_screen_start+n_entries_per_screen && i < n_menu_entries; i++, imod++) {
+ menu_text_rect[imod].w = menu_item_unselected[i]->w;
+ if (i >= title_offset) {
+ menu_button_rect[imod].w = menu_text_rect[imod].w + 30;
+ if (menu_sprites != NULL)
+ menu_button_rect[imod].w += 60;
+ }
+ }
+
+ if (menu_opts.button_same_width)
+ set_buttons_max_width(menu_button_rect,back_button_rect,n_entries_per_screen);
+ // Make sure the menu title mouse button didn't get turned on
+ if (loc_screen_start == 0 && title_offset)
+ menu_button_rect[0].w = 0;
+ for (i = loc_screen_start, imod = 0; i < loc_screen_start+n_entries_per_screen && i < n_menu_entries; i++, imod++) {
+ if (i == loc) { //Draw text in yellow
+ DrawButton(&menu_button_rect[imod], 10, SEL_RGBA);
+ SDL_BlitSurface(menu_item_selected[loc], NULL, screen, &menu_text_rect[imod]);
+ }
+ else { //Draw text in white
+ if (menu_button_rect[imod].w > 0)
+ DrawButton(&menu_button_rect[imod], 10, REG_RGBA);
+ SDL_BlitSurface(menu_item_unselected[i], NULL, screen, &menu_text_rect[imod]);
+ }
+ if (menu_sprites != NULL && (i >= title_offset) && menu_sprites[i-title_offset] != NULL)
+ SDL_BlitSurface(menu_sprites[i-title_offset]->default_img, NULL, screen, &menu_sprite_rect[imod]);
+ }
+
+ /* --- draw 'left' and 'right' buttons --- */
+ if (n_menu_entries > n_entries_per_screen) {
+ if (loc_screen_start > 0) // i.e. not on first page
+ {
+ SDL_BlitSurface(images[IMG_LEFT], NULL, screen, &left_arrow_rect);
+ }
+ else /* Draw grayed-out left button: */
+ {
+ SDL_BlitSurface(images[IMG_LEFT_GRAY], NULL, screen, &left_arrow_rect);
+ }
+
+ if (loc_screen_start + n_entries_per_screen < n_menu_entries) // not on last page
+ {
+ SDL_BlitSurface(images[IMG_RIGHT], NULL, screen, &right_arrow_rect);
+ }
+ else /* Draw grayed-out right button: */
+ {
+ SDL_BlitSurface(images[IMG_RIGHT_GRAY], NULL, screen, &right_arrow_rect);
+ }
+ }
+
+ SDL_Flip(screen);//SDL_UpdateRect(screen, 0, 0, 0 ,0);
+ } else if (old_loc != loc) {
+ // This is not a full redraw, but the selected entry did change.
+ // By just redrawing the old and new selections, we avoid flickering.
+ if (old_loc >= 0) {
+ imod = old_loc-loc_screen_start;
+ use_sprite = (menu_sprites != NULL && old_loc >= title_offset && menu_sprites[old_loc-title_offset] != NULL);
+ temp_rect = menu_button_rect[imod];
+ SDL_FillRect(screen, &temp_rect, 0);
+ SDL_BlitSurface(current_bkg(), &back_button_rect[imod], screen, &temp_rect); // redraw background
+ if (use_sprite) {
+ // Some of the sprites extend beyond the menu button, so we
+ // have to make sure we redraw in the sprite rects, too
+ SDL_BlitSurface(current_bkg(), &back_sprite_rect[imod], screen, &temp_rect);
+ }
+ DrawButton(&menu_button_rect[imod], 10, REG_RGBA); // draw button
+ //temp_rect = menu_text_rect[imod];
+ SDL_BlitSurface(menu_item_unselected[old_loc], NULL, screen, &menu_text_rect[imod]); // draw text
+ if (use_sprite) {
+ temp_rect = menu_sprite_rect[imod];
+ tmdprintf("Sprite %d at (%d %d)\n", imod, temp_rect.x, temp_rect.y);
+ SDL_BlitSurface(menu_sprites[old_loc-title_offset]->default_img, NULL, screen, &temp_rect);
+ // Also update the sprite rect (in some cases the sprite
+ // extends beyond the menu button)
+ SDL_UpdateRect(screen, menu_sprite_rect[imod].x, menu_sprite_rect[imod].y, menu_sprite_rect[imod].w, menu_sprite_rect[imod].h);
+ }
+ SDL_UpdateRect(screen, menu_button_rect[imod].x, menu_button_rect[imod].y, menu_button_rect[imod].w, menu_button_rect[imod].h);
+ }
+ if (loc >= 0) {
+ imod = loc-loc_screen_start;
+ use_sprite = (menu_sprites != NULL && loc >= title_offset && menu_sprites[loc] != NULL);
+ temp_rect = menu_button_rect[imod];
+ SDL_BlitSurface(current_bkg(), &(back_button_rect[imod]), screen, &temp_rect);
+ if (use_sprite)
+ {
+ temp_rect = menu_sprite_rect[imod];
+ SDL_BlitSurface(current_bkg(), &(back_sprite_rect[imod]), screen, &temp_rect);
+ }
+ DrawButton(&menu_button_rect[imod], 10, SEL_RGBA);
+ SDL_BlitSurface(menu_item_selected[loc], NULL, screen, &menu_text_rect[imod]);
+ if (use_sprite) {
+ menu_sprites[loc-title_offset]->cur = 0; // start at beginning of animation sequence
+ SDL_BlitSurface(menu_sprites[loc-title_offset]->frame[menu_sprites[loc-title_offset]->cur], NULL, screen, &menu_sprite_rect[imod]);
+ SDL_UpdateRect(screen, menu_sprite_rect[imod].x, menu_sprite_rect[imod].y, menu_sprite_rect[imod].w, menu_sprite_rect[imod].h);
+ next_frame(menu_sprites[loc-title_offset]);
+ }
+ SDL_UpdateRect(screen, menu_button_rect[imod].x, menu_button_rect[imod].y, menu_button_rect[imod].w, menu_button_rect[imod].h);
+ tmdprintf("Updating rect: %d %d %d %d\n", menu_button_rect[imod].x, menu_button_rect[imod].y, menu_button_rect[imod].w, menu_button_rect[imod].h);
+ }
+ } else if (frame_counter % 5 == 0 && loc >= 0) {
+ // No user input changed anything, but check to see if we need to
+ // animate the sprite
+ if (menu_sprites != NULL && loc >= title_offset && menu_sprites[loc-title_offset] != NULL) {
+ imod = loc-loc_screen_start;
+ //SDL_BlitSurface(current_bkg, &menu_button_rect[imod], screen, &menu_button_rect[imod]);
+ temp_rect = menu_sprite_rect[imod];
+ SDL_BlitSurface(current_bkg(), &back_sprite_rect[imod], screen, &temp_rect);
+ DrawButton(&menu_button_rect[imod], 10, SEL_RGBA);
+ //SDL_BlitSurface(menu_item_selected[loc], NULL, screen, &menu_text_rect[imod]);
+ // Note: even though the whole button was redrawn, we don't
+ // have to redraw the text & background as long as we don't
+ // update that rect. If something else changes and we go to
+ // full-screen updates, then remove the "commenting-out" on
+ // the two lines above
+ SDL_BlitSurface(menu_sprites[loc-title_offset]->frame[menu_sprites[loc-title_offset]->cur], NULL, screen, &menu_sprite_rect[imod]);
+ SDL_UpdateRect(screen, menu_sprite_rect[imod].x, menu_sprite_rect[imod].y, menu_sprite_rect[imod].w, menu_sprite_rect[imod].h);
+ next_frame(menu_sprites[loc-title_offset]);
+ }
+ }
+
+ redraw = 0;
+
+ /* Move the mouse pointer if there is only a single screen */
+ if (warp_mouse && n_menu_entries <= n_entries_per_screen) {
+ imod = loc - loc_screen_start;
+ cursor.x = menu_button_rect[imod].x + (menu_button_rect[imod].w / 2);
+ cursor.y = menu_button_rect[imod].y + (3 * menu_button_rect[imod].h / 4);
+// SDL_WarpMouse(cursor.x, cursor.y);
+ warp_mouse = 0;
+ }
+
+ old_loc = loc;
+ old_loc_screen_start = loc_screen_start;
+
+
+
+ /* --- make Tux blink --- */
+ switch (frame_counter % TUX6)
+ {
+ case 0: tux_frame = 1; break;
+ case TUX1: tux_frame = 2; break;
+ case TUX2: tux_frame = 3; break;
+ case TUX3: tux_frame = 4; break;
+ case TUX4: tux_frame = 3; break;
+ case TUX5: tux_frame = 2; break;
+ default: tux_frame = 0;
+ }
+
+ if (Tux && tux_frame)
+ {
+ /* Redraw background to keep edges anti-aliased properly: */
+ SDL_BlitSurface(current_bkg(),&Tuxdest, screen, &Tuxdest);
+ SDL_BlitSurface(Tux->frame[tux_frame - 1], NULL, screen, &Tuxdest);
+ SDL_UpdateRect(screen, Tuxdest.x, Tuxdest.y, Tuxdest.w, Tuxdest.h);
+ //SDL_UpdateRect(screen, 0, 0, 0, 0);
+ }
+
+ if (egg_active) { //if we need to, draw the egg cursor
+ //who knows why GetMouseState() doesn't take Sint16's...
+ SDL_GetMouseState((int*)(&cursor.x), (int*)(&cursor.y));
+ cursor.x -= egg->w / 2; //center vertically
+ SDL_BlitSurface(egg, NULL, screen, &cursor);
+ SDL_UpdateRect(screen, cursor.x, cursor.y, cursor.w, cursor.h);
+ }
+
+ /* Wait so we keep frame rate constant: */
+ frame_now = SDL_GetTicks();
+ if (frame_now < frame_start)
+ frame_start = frame_now; // in case the timer wraps around
+ if (frame_now - frame_start < 33)
+ SDL_Delay(33-(frame_now-frame_start));
+
+ frame_counter++;
+ } // End !stop while loop
+
+
+ /***** User made a choice, clean up and return the choice. ******/
+
+ /* --- clear graphics before leaving function --- */
+ for (i = 0; i < n_menu_entries; i++)
+ {
+ SDL_FreeSurface(menu_item_unselected[i]);
+ SDL_FreeSurface(menu_item_selected[i]);
+ }
+ free(menu_item_unselected);
+ free(menu_item_selected);
+ free(menu_text_rect);
+ free(menu_button_rect);
+ free(back_text_rect);
+ free(back_button_rect);
+ free(menu_sprite_rect);
+ free(back_sprite_rect);
+
+ /* Return the value of the chosen item (-1 indicates escape) */
+ if (stop == 2)
+ return -1;
+ else
+ return loc - title_offset;
+}
+
+
+
+void set_buttons_max_width(SDL_Rect *menu_button_rect,
+ SDL_Rect *back_button_rect, int n)
+{
+ int i,max;
+
+ max = 0;
+ for (i = 0; i < n; i++)
+ if (max < menu_button_rect[i].w)
+ max = menu_button_rect[i].w;
+
+ for (i = 0; i < n; i++)
+ menu_button_rect[i].w = back_button_rect[i].w = max;
+
+ tmdprintf("All buttons at width %d\n", max);
+}
+
+// Was in playgame.c in tuxtype:
+
+/*************************************************/
+/* TransWipe: Performs various wipes to new bkgs */
+/*************************************************/
+/*
+ * Given a wipe request type, and any variables
+ * that wipe requires, will perform a wipe from
+ * the current screen image to a new one.
+ */
+void TransWipe(SDL_Surface* newbkg, int type, int var1, int var2)
+{
+ int i, j, x1, x2, y1, y2;
+ int step1, step2, step3, step4;
+ int frame;
+ SDL_Rect src;
+ SDL_Rect dst;
+
+ if (!screen)
+ {
+#ifdef TUXMATH_DEBUG
+ fprintf(stderr, "TransWipe(): screen not valid!\n");
+#endif
+ return;
+ }
+
+ if (!newbkg)
+ {
+#ifdef TUXMATH_DEBUG
+ fprintf(stderr, "TransWipe(): newbkg not valid!\n");
+#endif
+ return;
+ }
+
+ numupdates = 0;
+ frame = 0;
+
+ if(newbkg->w == screen->w && newbkg->h == screen->h) {
+ if( type == RANDOM_WIPE )
+ type = (RANDOM_WIPE * ((float) rand()) / (RAND_MAX+1.0));
+
+ switch( type ) {
+ case WIPE_BLINDS_VERT: {
+ #ifdef TUXMATH_DEBUG
+ fprintf(stderr, "--+ Doing 'WIPE_BLINDS_VERT'\n");
+#endif
+ /* var1 is num of divisions
+ var2 is how many frames animation should take */
+ if( var1 < 1 ) var1 = 1;
+ if( var2 < 1 ) var2 = 1;
+ step1 = screen->w / var1;
+ step2 = step1 / var2;
+
+ for(i = 0; i <= var2; i++)
+ {
+ for(j = 0; j <= var1; j++)
+ {
+ x1 = step1 * (j - 0.5) - i * step2 + 1;
+ x2 = step1 * (j - 0.5) + i * step2 + 1;
+ src.x = x1;
+ src.y = 0;
+ src.w = step2;
+ src.h = screen->h;
+ dst.x = x2;
+ dst.y = 0;
+ dst.w = step2;
+ dst.h = screen->h;
+
+ SDL_BlitSurface(newbkg, &src, screen, &src);
+ SDL_BlitSurface(newbkg, &dst, screen, &dst);
+
+ AddRect(&src, &src);
+ AddRect(&dst, &dst);
+ }
+ UpdateScreen(&frame);
+ }
+
+ src.x = 0;
+ src.y = 0;
+ src.w = screen->w;
+ src.h = screen->h;
+ SDL_BlitSurface(newbkg, NULL, screen, &src);
+ SDL_Flip(screen);
+
+ break;
+ } case WIPE_BLINDS_HORIZ: {
+#ifdef TUXMATH_DEBUG
+ fprintf(stderr, "--+ Doing 'WIPE_BLINDS_HORIZ'\n");
+#endif
+ /* var1 is num of divisions
+ var2 is how many frames animation should take */
+ if( var1 < 1 ) var1 = 1;
+ if( var2 < 1 ) var2 = 1;
+ step1 = screen->h / var1;
+ step2 = step1 / var2;
+
+ for(i = 0; i <= var2; i++) {
+ for(j = 0; j <= var1; j++) {
+ y1 = step1 * (j - 0.5) - i * step2 + 1;
+ y2 = step1 * (j - 0.5) + i * step2 + 1;
+ src.x = 0;
+ src.y = y1;
+ src.w = screen->w;
+ src.h = step2;
+ dst.x = 0;
+ dst.y = y2;
+ dst.w = screen->w;
+ dst.h = step2;
+
+ SDL_BlitSurface(newbkg, &src, screen, &src);
+ SDL_BlitSurface(newbkg, &dst, screen, &dst);
+
+ AddRect(&src, &src);
+ AddRect(&dst, &dst);
+ }
+ UpdateScreen(&frame);
+ }
+
+ src.x = 0;
+ src.y = 0;
+ src.w = screen->w;
+ src.h = screen->h;
+ SDL_BlitSurface(newbkg, NULL, screen, &src);
+ SDL_Flip(screen);
+
+ break;
+ } case WIPE_BLINDS_BOX: {
+#ifdef TUXMATH_DEBUG
+ fprintf(stderr, "--+ Doing 'WIPE_BLINDS_BOX'\n");
+#endif
+ /* var1 is num of divisions
+ var2 is how many frames animation should take */
+ if( var1 < 1 ) var1 = 1;
+ if( var2 < 1 ) var2 = 1;
+ step1 = screen->w / var1;
+ step2 = step1 / var2;
+ step3 = screen->h / var1;
+ step4 = step1 / var2;
+
+ for(i = 0; i <= var2; i++) {
+ for(j = 0; j <= var1; j++) {
+ x1 = step1 * (j - 0.5) - i * step2 + 1;
+ x2 = step1 * (j - 0.5) + i * step2 + 1;
+ src.x = x1;
+ src.y = 0;
+ src.w = step2;
+ src.h = screen->h;
+ dst.x = x2;
+ dst.y = 0;
+ dst.w = step2;
+ dst.h = screen->h;
+
+ SDL_BlitSurface(newbkg, &src, screen, &src);
+ SDL_BlitSurface(newbkg, &dst, screen, &dst);
+
+ AddRect(&src, &src);
+ AddRect(&dst, &dst);
+ y1 = step3 * (j - 0.5) - i * step4 + 1;
+ y2 = step3 * (j - 0.5) + i * step4 + 1;
+ src.x = 0;
+ src.y = y1;
+ src.w = screen->w;
+ src.h = step4;
+ dst.x = 0;
+ dst.y = y2;
+ dst.w = screen->w;
+ dst.h = step4;
+ SDL_BlitSurface(newbkg, &src, screen, &src);
+ SDL_BlitSurface(newbkg, &dst, screen, &dst);
+ AddRect(&src, &src);
+ AddRect(&dst, &dst);
+ }
+ UpdateScreen(&frame);
+ }
+
+ src.x = 0;
+ src.y = 0;
+ src.w = screen->w;
+ src.h = screen->h;
+ SDL_BlitSurface(newbkg, NULL, screen, &src);
+ SDL_Flip(screen);
+
+ break;
+ } default:
+ break;
+ }
+ }
+#ifdef TUXMATH_DEBUG
+ fprintf(stderr, "->TransWipe(): FINISH\n");
+#endif
+}
+
+
+
+/************************
+UpdateScreen : Update the screen and increment the frame num
+***************************/
+void UpdateScreen(int *frame) {
+ int i;
+
+ /* -- First erase everything we need to -- */
+ for (i = 0; i < numupdates; i++)
+ if (blits[i].type == 'E')
+ SDL_LowerBlit(blits[i].src, blits[i].srcrect, screen, blits[i].dstrect);
+// SNOW_erase();
+
+ /* -- then draw -- */
+ for (i = 0; i < numupdates; i++)
+ if (blits[i].type == 'D')
+ SDL_BlitSurface(blits[i].src, blits[i].srcrect, screen, blits[i].dstrect);
+// SNOW_draw();
+
+/* -- update the screen only where we need to! -- */
+// if (SNOW_on)
+// SDL_UpdateRects(screen, SNOW_add( (SDL_Rect*)&dstupdate, numupdates ), SNOW_rects);
+// else
+ SDL_UpdateRects(screen, numupdates, dstupdate);
+
+ numupdates = 0;
+ *frame = *frame + 1;
+}
+
+
+/******************************
+AddRect: Don't actually blit a surface,
+ but add a rect to be updated next
+ update
+*******************************/
+void AddRect(SDL_Rect* src, SDL_Rect* dst) {
+ /*borrowed from SL's alien (and modified)*/
+
+ struct blit *update;
+
+ if (!src || !dst)
+ {
+#ifdef TUXMATH_DEBUG
+ fprintf(stderr, "AddRect(): src or dst invalid!\n");
+#endif
+ return;
+ }
+
+ update = &blits[numupdates++];
+
+ update->srcrect->x = src->x;
+ update->srcrect->y = src->y;
+ update->srcrect->w = src->w;
+ update->srcrect->h = src->h;
+ update->dstrect->x = dst->x;
+ update->dstrect->y = dst->y;
+ update->dstrect->w = dst->w;
+ update->dstrect->h = dst->h;
+ update->type = 'I';
+}
+
+/***********************
+ InitEngine
+ ***********************/
+void InitEngine(void) {
+ int i;
+
+ /* --- Set up the update rectangle pointers --- */
+
+ for (i = 0; i < MAX_UPDATES; ++i) {
+ blits[i].srcrect = &srcupdate[i];
+ blits[i].dstrect = &dstupdate[i];
+ }
+}
+
+
+void set_default_menu_options(menu_options *menu_opts)
+{
+ menu_opts->starting_entry = 0;
+ menu_opts->xleft = screen->w / 2 - screen->w * 3 / 32;
+ menu_opts->ytop = screen->h / 2 - 140;
+ // Leave room for arrows at the bottom:
+ menu_opts->ybottom = screen->h - images[IMG_LEFT]->h - 20;
+ menu_opts->buttonheight = -1;
+ menu_opts->ygap = 10;
+ menu_opts->button_same_width = 1;
+ menu_opts->title = NULL;
+ menu_opts->trailer = NULL;
+}
+
+/* Recalculate on-screen locations for title screen elements */
+void RecalcTitlePositions()
+{
+ Backrect = current_bkg()->clip_rect;
+ Backrect.x = (screen->w - Backrect.w) / 2;
+ Backrect.y = (screen->h - Backrect.h) / 2;
+
+ Titledest.x = 0;
+ Titledest.y = 0;
+
+ Tuxdest.x = 0;
+ Tuxdest.y = screen->h - Tuxdest.h;
+
+ beak.x = Tuxdest.x + 70;
+ beak.y = Tuxdest.y + 60;
+ beak.w = beak.h = 50;
+
+ stopRect.x = screen->w - stopRect.w;
+ stopRect.y = 0;
+}
+
+/* Recalculate on-screen locations for menus when screen dimensions change */
+/* Perhaps consider generalizing this for use in initial menu calculations? */
+void RecalcMenuPositions(int* numentries,
+ int totalentries,
+ menu_options* mo,
+ void (*set_custom_menu_opts)(menu_options*),
+ SDL_Rect** menu_button_rect,
+ SDL_Rect** menu_sprite_rect,
+ SDL_Rect** menu_text_rect,
+ SDL_Rect** back_button_rect,
+ SDL_Rect** back_sprite_rect,
+ SDL_Rect** back_text_rect,
+ SDL_Rect* left_arrow_rect,
+ SDL_Rect* right_arrow_rect)
+{
+ int i;
+ SDL_Rect* old_mbr = *menu_button_rect;
+ SDL_Rect* old_msr = *menu_sprite_rect;
+ SDL_Rect* old_mtr = *menu_text_rect;
+ SDL_Rect* old_bbr = *back_button_rect;
+ SDL_Rect* old_bsr = *back_sprite_rect;
+ SDL_Rect* old_btr = *back_text_rect;
+
+ int old_ne = *numentries;
+ int buttonheight = old_mbr->h; //height shouldn't change
+ int textwidth = old_mtr->w; //neither should width =P
+
+ right_arrow_rect->x = screen->w - images[IMG_RIGHT]->w - 20;
+ right_arrow_rect->y = screen->h - images[IMG_RIGHT]->h - 20;
+ left_arrow_rect->x = right_arrow_rect->x - 10 - images[IMG_LEFT]->w;
+ left_arrow_rect->y = screen->h - images[IMG_LEFT]->h - 20;
+
+ set_default_menu_options(mo);
+ if (set_custom_menu_opts != NULL)
+ set_custom_menu_opts(mo);
+
+ *numentries = (int)(screen->h - mo->ytop+mo->ygap)/(buttonheight + mo->ygap);
+ if (*numentries < totalentries)
+ *numentries = (int)(mo->ybottom - mo->ytop+mo->ygap)/(buttonheight + mo->ygap);
+ if (*numentries > totalentries)
+ *numentries = totalentries;
+
+
+
+
+ /**** Memory allocation for new screen rects ****/
+ *menu_text_rect = (SDL_Rect*) malloc(*numentries * sizeof(SDL_Rect));
+ *menu_button_rect = (SDL_Rect*) malloc(*numentries * sizeof(SDL_Rect));
+ *menu_sprite_rect = (SDL_Rect*) malloc(*numentries * sizeof(SDL_Rect));
+ *back_text_rect = (SDL_Rect*) malloc(*numentries * sizeof(SDL_Rect));
+ *back_button_rect = (SDL_Rect*) malloc(*numentries * sizeof(SDL_Rect));
+ *back_sprite_rect = (SDL_Rect*) malloc(*numentries * sizeof(SDL_Rect));
+ if (*menu_text_rect == NULL ||
+ *back_text_rect == NULL ||
+ *menu_button_rect == NULL ||
+ *back_button_rect == NULL ||
+ *menu_sprite_rect == NULL ||
+ *back_sprite_rect == NULL) {
+ free(*menu_text_rect);
+ free(*menu_button_rect);
+ free(*menu_sprite_rect);
+ free(*back_text_rect);
+ free(*back_button_rect);
+ free(*back_sprite_rect);
+ *menu_text_rect = old_mtr;
+ *menu_button_rect = old_mbr;
+ *menu_sprite_rect = old_msr;
+ *numentries = old_ne;
+ return;
+ }
+ else {
+ free(old_mtr);
+ free(old_mbr);
+ free(old_msr);
+ free(old_btr);
+ free(old_bbr);
+ free(old_bsr);
+ }
+
+
+ //note: the [0] notation is merely to avoid typing out (*menu_xxx_rect)[i]
+ for (i = 0; i < *numentries; i++)
+ {
+ menu_button_rect[0][i].x = mo->xleft;
+ menu_text_rect[0][i].x = mo->xleft + 15; // 15 is left gap
+ menu_text_rect[0][i].x += 60; // for now, assume we have a sprite
+ if (i > 0)
+ menu_text_rect[0][i].y = menu_text_rect[0][i - 1].y + buttonheight + mo->ygap;
+ else
+ menu_text_rect[0][i].y = mo->ytop;
+
+ menu_button_rect[0][i].y = menu_text_rect[0][i].y - 5;
+ menu_text_rect[0][i].h = buttonheight - 10;
+ menu_button_rect[0][i].h = buttonheight;
+
+ menu_text_rect[0][i].w = textwidth;
+ menu_button_rect[0][i].w = menu_text_rect[0][i].w + 30;
+
+ if (menu_sprite_rect != NULL) {
+ menu_sprite_rect[0][i].x = menu_button_rect[0][i].x + 3;
+ menu_sprite_rect[0][i].y = menu_button_rect[0][i].y + 3;
+ menu_sprite_rect[0][i].w = 40;
+ menu_sprite_rect[0][i].h = 50;
+ }
+ tmdprintf("***Rects[%d]****\n", i);
+ tmdprintf("%3d %3d %3d %3d\n", menu_button_rect[0][i].x, menu_button_rect[0][i].y, menu_button_rect[0][i].w, menu_button_rect[0][i].h);
+ tmdprintf("%3d %3d %3d %3d\n", menu_text_rect[0][i].x, menu_text_rect[0][i].y, menu_text_rect[0][i].w, menu_text_rect[0][i].h);
+ tmdprintf("%3d %3d %3d %3d\n", menu_sprite_rect[0][i].x, menu_sprite_rect[0][i].y, menu_sprite_rect[0][i].w, menu_sprite_rect[0][i].h);
+ tmdprintf("***************\n");
+ }
+ for (i = 0; i < *numentries; ++i)
+ {
+ back_button_rect[0][i] = menu_button_rect[0][i];
+ back_button_rect[0][i].x -= Backrect.x;
+ back_button_rect[0][i].y -= Backrect.y;
+
+ back_text_rect[0][i] = menu_text_rect[0][i];
+ back_text_rect[0][i].x -= Backrect.x;
+ back_text_rect[0][i].y -= Backrect.y;
+
+ back_sprite_rect[0][i] = menu_sprite_rect[0][i];
+ back_sprite_rect[0][i].x -= Backrect.x;
+ back_sprite_rect[0][i].y -= Backrect.y;
+ }
+
+}
+
+int handle_easter_egg(const SDL_Event* evt)
+ {
+ static int eggtimer = 0;
+ int tuxframe;
+
+ // Avoid segfaults if needed images not available:
+ if (!Tux || !egg)
+ {
+ fprintf(stderr,
+ "handle_easter_egg() - needed images not avail, bailing out\n");
+ egg_active = 0;
+ return 1;
+ }
+
+ tuxframe = Tux->num_frames;
+
+
+ if (egg_active) //are we using the egg cursor?
+ {
+
+ if (eggtimer < SDL_GetTicks() ) //time's up
+ {
+ SDL_ShowCursor(SDL_ENABLE);
+ //SDL_FillRect(screen, &cursor, 0);
+ SDL_BlitSurface(current_bkg(), NULL, screen, &Backrect); //cover egg up once more
+ SDL_WarpMouse(cursor.x, cursor.y);
+ SDL_UpdateRect(screen, cursor.x, cursor.y, cursor.w, cursor.h); //egg->x, egg->y, egg->w, egg->h);
+ egg_active = 0;
+ }
+ return 1;
+ }
+ else //if not, see if the user clicked Tux's beak
+ {
+ eggtimer = 0;
+ if (evt->type == SDL_MOUSEBUTTONDOWN &&
+ inRect(beak, evt->button.x, evt->button.y) )
+ {
+ SDL_ShowCursor(SDL_DISABLE);
+
+ //animate
+ while (tuxframe != 0)
+ {
+ SDL_BlitSurface(Tux->frame[--tuxframe], NULL, screen, &Tuxdest);
+ SDL_UpdateRect(screen, Tuxdest.x, Tuxdest.y, Tuxdest.w, Tuxdest.h);
+ SDL_Delay(GOBBLE_ANIM_MS / Tux->num_frames);
+ }
+
+ eggtimer = SDL_GetTicks() + EASTER_EGG_MS;
+ egg_active = 1;
+ SDL_WarpMouse(Tuxdest.x + Tuxdest.w / 2, Tuxdest.y + Tuxdest.h - egg->h);
+
+ }
+
+ return 0;
+ }
+ }
+
+
Property changes on: tuxmath/branches/lan/src/titlescreen.c.old
___________________________________________________________________
Added: svn:mergeinfo
+
Modified: tuxmath/branches/lan/src/titlescreen.h
===================================================================
--- tuxmath/branches/lan/src/titlescreen.h 2009-09-02 10:50:25 UTC (rev 1476)
+++ tuxmath/branches/lan/src/titlescreen.h 2009-09-03 22:06:06 UTC (rev 1477)
@@ -1,25 +1,26 @@
-/***************************************************************************
- - file: titlescreen.h
- - description: header for the tuxtype-derived files in tuxmath
- ------------------
+/*
+ titlescreen.h
- David Bruce - 2006.
- email : <dbruce at tampabay.rr.com>
- <tuxmath-devel at lists.sourceforge.net>
-***************************************************************************/
+ Splash, background and title screen items.
+ (interface)
-/***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
+ begin : Thur May 4 2000
+ copyright : (C) 2000 by Sam Hart
+ : (C) 2003 by Jesse Andrews
+ email : tuxtype-dev at tux4kids.net
+ Modified for use in tuxmath by David Bruce - 2006-2007.
+ email : <dbruce at tampabay.rr.com>
+ <tuxmath-devel at lists.sourceforge.net>
+ Also significantly enhanced by Tim Holy - 2007
+ Part of "Tux4Kids" Project
+ http://www.tux4kids.com/
+ Copyright: See COPYING file that comes with this distribution.
+*/
+
#ifndef TITLESCREEN_H
#define TITLESCREEN_H
@@ -48,47 +49,27 @@
#include "tuxmath.h"
#include "loaders.h"
+#define MAX_LESSONS 100
+#define MAX_NUM_WORDS 500
+#define MAX_WORD_SIZE 8
-// Options that affect how menus are presented
-typedef struct {
- int starting_entry;
- int xleft, ytop, ybottom; // left, top, and bottom borders
- int buttonheight; // size of menu item button (-1 if calculated)
- int ygap; // vertical gap between entries
- int button_same_width; // should all buttons have the same width?
- char *title;
- char *trailer;
-} menu_options;
-
-
-#define MAX_LESSONS 100
-#define MAX_NUM_WORDS 500
-#define MAX_WORD_SIZE 8
-
//MAX_UPDATES needed for TransWipe() and friends:
-#define MAX_UPDATES 180
+#define MAX_UPDATES 180
+#define WAIT_MS 2500
+#define FRAMES_PER_SEC 50
+#define FULL_CIRCLE 140
-#define WAIT_MS 2500
-#define FRAMES_PER_SEC 50
-#define FULL_CIRCLE 140
+/* trans_wipe() animation constants */
+#define ANIM_FRAMES 30 /* frames to be displayed */
+#define ANIM_FPS 25 /* max fps */
-/* Title sequence constants */
-#define PRE_ANIM_FRAMES 10
-#define PRE_FRAME_MULT 3
-#define MENU_SEP 20
-/* paths */
-
-
-
-
-
extern SDL_Event event;
-#define MUSIC_FADE_OUT_MS 80
+#define MUSIC_FADE_OUT_MS 80
enum {
WIPE_BLINDS_VERT,
@@ -100,18 +81,6 @@
};
// End of code from tuxtype's globals.h
-
-/* --- SETUP MENU OPTIONS --- */
-
-#define TITLE_MENU_ITEMS 5
-#define TITLE_MENU_DEPTH 4
-
-#define OPTIONS_SUBMENU 4
-#define GAME_OPTIONS_SUBMENU 3
-#define ARCADE_SUBMENU 2
-#define ROOTMENU 1
-
-
/* --- timings for tux blinking --- */
#define TUX1 115
#define TUX2 118
@@ -120,30 +89,27 @@
#define TUX5 127
#define TUX6 130
-#define EASTER_EGG_MS 5000 //length of time to replace cursor
-#define GOBBLE_ANIM_MS 1000 //duration of the gobbling animation
+#define EASTER_EGG_MS 5000 //length of time to replace cursor
+#define GOBBLE_ANIM_MS 1000 //duration of the gobbling animation
/********************************/
/* "Global" Function Prototypes */
/********************************/
/*In titlescreen.c */
-void TitleScreen(void);
-int ChooseMission(void); //FIXME really should be in fileops.c
-int choose_menu_item(const char **menu_text,
- sprite **menu_sprites,
- int n_menu_entries,
- menu_options* custom_mo,
- void (*set_custom_menu_opts)(menu_options*) );
-void set_default_menu_options(menu_options *);
-SDL_Surface* current_bkg(); //appropriate background for current video mode
+void TitleScreen(void);
+int RenderTitleScreen(void);
+void DrawTitleScreen(void);
+int HandleTitleScreenEvents(const SDL_Event* evt);
+void HandleTitleScreenAnimations();
+void ShowMessage(const char* str1, const char* str2, const char* str3, const char* str4);
+SDL_Surface* current_bkg(); //appropriate background for current video mode
-
/* in audio.c (from tuxtype): */
-void playsound(int snd);
-void audioMusicLoad(char* musicFilename, int repeatQty);
-void audioMusicUnload(void);
-void audioMusicPlay(Mix_Music* musicData, int repeatQty);
+void playsound(int snd);
+void audioMusicLoad(char* musicFilename, int repeatQty);
+void audioMusicUnload(void);
+void audioMusicPlay(Mix_Music* musicData, int repeatQty);
#endif //TITLESCREEN_H
Modified: tuxmath/branches/lan/src/tuxmath.c
===================================================================
--- tuxmath/branches/lan/src/tuxmath.c 2009-09-02 10:50:25 UTC (rev 1476)
+++ tuxmath/branches/lan/src/tuxmath.c 2009-09-03 22:06:06 UTC (rev 1477)
@@ -46,16 +46,14 @@
s3 = bind_textdomain_codeset(PACKAGE, "UTF-8");
s4 = textdomain(PACKAGE);
-#ifdef TUXMATH_DEBUG
- fprintf(stderr, "PACKAGE = %s\n", PACKAGE);
- fprintf(stderr, "TUXLOCALE = %s\n", TUXLOCALE);
- fprintf(stderr, "setlocale(LC_ALL, \"\") returned: %s\n", s1);
- fprintf(stderr, "bindtextdomain(PACKAGE, TUXLOCALE) returned: %s\n", s2);
- fprintf(stderr, "bind_textdomain_codeset(PACKAGE, \"UTF-8\") returned: %s\n", s3);
- fprintf(stderr, "textdomain(PACKAGE) returned: %s\n", s4);
- fprintf(stderr, "gettext(\"Help\"): %s\n\n", gettext("Help"));
- fprintf(stderr, "After gettext() call\n");
-#endif
+ DEBUGMSG(debug_setup, "PACKAGE = %s\n", PACKAGE);
+ DEBUGMSG(debug_setup, "TUXLOCALE = %s\n", TUXLOCALE);
+ DEBUGMSG(debug_setup, "setlocale(LC_ALL, \"\") returned: %s\n", s1);
+ DEBUGMSG(debug_setup, "bindtextdomain(PACKAGE, TUXLOCALE) returned: %s\n", s2);
+ DEBUGMSG(debug_setup, "bind_textdomain_codeset(PACKAGE, \"UTF-8\") returned: %s\n", s3);
+ DEBUGMSG(debug_setup, "textdomain(PACKAGE) returned: %s\n", s4);
+ DEBUGMSG(debug_setup, "gettext(\"Help\"): %s\n\n", gettext("Help"));
+ DEBUGMSG(debug_setup, "After gettext() call\n");
setup(argc, argv);
TitleScreen(); /* Run the game! */
Modified: tuxmath/branches/lan/src/tuxmath.h
===================================================================
--- tuxmath/branches/lan/src/tuxmath.h 2009-09-02 10:50:25 UTC (rev 1476)
+++ tuxmath/branches/lan/src/tuxmath.h 2009-09-03 22:06:06 UTC (rev 1477)
@@ -43,8 +43,23 @@
//#define NOSOUND
#include "globals.h"
+#define MAX_SPRITE_FRAMES 30
+typedef struct {
+ SDL_Surface *frame[MAX_SPRITE_FRAMES];
+ SDL_Surface *default_img;
+ int num_frames;
+ int cur;
+} sprite;
+
/* Global data gets 'externed' here: */
+
+/* declared in setup.c */
+/* windowed mode screen size */
+extern int win_res_x;
+extern int win_res_y;
+
+/* full screen size */
extern int fs_res_x;
extern int fs_res_y;
@@ -57,6 +72,7 @@
extern SDL_Surface* screen; /* declared in setup.c; also used in game.c, options.c, fileops.c, credits.c, titlescreen.c */
extern SDL_Surface* images[]; /* declared in setup.c, used in same files as screen */
+extern sprite* sprites[];
extern SDL_Surface* flipped_images[];
#define NUM_BLENDED_IGLOOS 15
extern SDL_Surface* blended_igloos[];
More information about the Tux4kids-commits
mailing list