[Tux4kids-commits] r1157 - tuxmath/trunk/src
Bolesław Kulbabiński
bolekk-guest at alioth.debian.org
Tue Jul 7 13:48:57 UTC 2009
Author: bolekk-guest
Date: 2009-07-07 13:48:56 +0000 (Tue, 07 Jul 2009)
New Revision: 1157
Modified:
tuxmath/trunk/src/loaders.c
tuxmath/trunk/src/loaders.h
tuxmath/trunk/src/menu.c
Log:
added menu arrows' functionality and corrected menu re-rendering after resolution change
Modified: tuxmath/trunk/src/loaders.c
===================================================================
--- tuxmath/trunk/src/loaders.c 2009-07-07 13:25:12 UTC (rev 1156)
+++ tuxmath/trunk/src/loaders.c 2009-07-07 13:48:56 UTC (rev 1157)
@@ -33,14 +33,14 @@
int check_file(const char* file);
#ifdef HAVE_RSVG
-SDL_Surface* load_svg(char* file_name, int width, int height, char* layer_name);
-void get_svg_dimensions(char* file_name, int* width, int* height);
+SDL_Surface* load_svg(const char* file_name, 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(char* file_name, int mode, int w, int h, bool proportional);
+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(char* name, int mode, int width, int height, bool proportional);
+sprite* load_sprite(const char* name, int mode, int width, int height, bool proportional);
@@ -98,7 +98,7 @@
If layer = NULL then the whole image is loaded.
Return NULL on failure.
(partly based on TuxPaint's SVG loading function) */
-SDL_Surface* load_svg(char* file_name, int width, int height, char* layer_name)
+SDL_Surface* load_svg(const char* file_name, int width, int height, const char* layer_name)
{
cairo_surface_t* temp_surf;
cairo_t* context;
@@ -195,7 +195,7 @@
return dest;
}
-void get_svg_dimensions(char* file_name, int* width, int* height)
+void get_svg_dimensions(const char* file_name, int* width, int* height)
{
RsvgHandle* file_handle;
RsvgDimensionData dimensions;
@@ -227,7 +227,7 @@
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(char* file_name, int mode, int width, int height)
+SDL_Surface* LoadScaledImage(const char* file_name, int mode, int width, int height)
{
return load_image(file_name, mode, width, height, false);
}
@@ -235,14 +235,14 @@
/* 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(char* file_name, int mode, int max_width, int 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(char* file_name, int mode, int w, int h, bool proportional)
+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;
@@ -392,7 +392,7 @@
}
/* Load an image without scaling it */
-SDL_Surface* LoadImage(char* file_name, int mode)
+SDL_Surface* LoadImage(const char* file_name, int mode)
{
return LoadScaledImage(file_name, mode, -1, -1);
}
@@ -400,7 +400,7 @@
/* LoadBkgd() : a wrapper for LoadImage() that optimizes
the format of background image */
-SDL_Surface* LoadBkgd(char* file_name, int width, int height)
+SDL_Surface* LoadBkgd(const char* file_name, int width, int height)
{
SDL_Surface* orig = NULL;
SDL_Surface* final_pic = NULL;
@@ -425,7 +425,7 @@
/* 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(char* file_name, SDL_Surface** fs_bkgd, SDL_Surface** win_bkgd)
+void LoadBothBkgds(const char* file_name, SDL_Surface** fs_bkgd, SDL_Surface** win_bkgd)
{
DEBUGMSG(debug_loaders, "Entering LoadBothBkgds()\n");
*fs_bkgd = LoadBkgd(file_name, fs_res_x, fs_res_y);
@@ -433,22 +433,22 @@
}
-sprite* LoadSprite(char* name, int mode)
+sprite* LoadSprite(const char* name, int mode)
{
return LoadScaledSprite(name, mode, -1, -1);
}
-sprite* LoadScaledSprite(char* name, int mode, int width, int height)
+sprite* LoadScaledSprite(const char* name, int mode, int width, int height)
{
return load_sprite(name, mode, width, height, false);
}
-sprite* LoadSpriteOfBoundingBox(char* name, int mode, int max_width, int max_height)
+sprite* LoadSpriteOfBoundingBox(const char* name, int mode, int max_width, int max_height)
{
return load_sprite(name, mode, max_width, max_height, true);
}
-sprite* load_sprite(char* name, int mode, int width, int height, bool proportional)
+sprite* load_sprite(const char* name, int mode, int width, int height, bool proportional)
{
sprite *new_sprite;
char fn[PATH_MAX];
Modified: tuxmath/trunk/src/loaders.h
===================================================================
--- tuxmath/trunk/src/loaders.h 2009-07-07 13:25:12 UTC (rev 1156)
+++ tuxmath/trunk/src/loaders.h 2009-07-07 13:48:56 UTC (rev 1157)
@@ -44,16 +44,16 @@
} sprite;
-SDL_Surface* LoadImage(char* file_name, int mode);
-SDL_Surface* LoadScaledImage(char* file_name, int mode, int width, int height);
-SDL_Surface* LoadImageOfBoundingBox(char* file_name, int mode, int max_width, int max_height);
+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);
-SDL_Surface* LoadBkgd(char* file_name, int width, int height);
-void LoadBothBkgds(char* file_name, SDL_Surface** fs_bkgd, SDL_Surface** win_bkgd);
+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(char* name, int mode);
-sprite* LoadScaledSprite(char* name, int mode, int width, int height);
-sprite* LoadSpriteOfBoundingBox(char* name, int mode, int max_width, int max_height);
+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);
Modified: tuxmath/trunk/src/menu.c
===================================================================
--- tuxmath/trunk/src/menu.c 2009-07-07 13:25:12 UTC (rev 1156)
+++ tuxmath/trunk/src/menu.c 2009-07-07 13:48:56 UTC (rev 1157)
@@ -37,14 +37,36 @@
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, RESIZED };
-MenuNode* menus[N_OF_MENUS];
+/* 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;
+/*TODO: move these constants into a config file (maybe together with
+ titlescreen paths and rects ? ) */
+const float menu_pos[4] = {0.4, 0.25, 0.55, 0.7};
+const float stop_pos[4] = {0.95, 0.0, 0.05, 0.05};
+const float prev_pos[4] = {0.9, 0.95, 0.05, 0.05};
+const float next_pos[4] = {0.95, 0.95, 0.05, 0.05};
+const char* stop_path = "status/stop.png";
+const char* prev_path = "status/left.png";
+const char* next_path = "status/right.png";
+const float button_gap = 0.2, text_h_gap = 0.25, text_w_gap = 0.5;
+
+/* menu title rect */
+SDL_Rect title_rect;
+
+
+
/* buffer size used when reading attributes or names */
const int buf_size = 128;
@@ -63,6 +85,7 @@
int run_menu(MenuNode* menu, bool return_choice);
void prerender_menu(MenuNode* menu);
+void prerender_all();
SDL_Surface** render_buttons(MenuNode* menu, bool selected);
MenuNode* create_one_level_menu(int items, char** item_names, char* title, char* trailer);
@@ -288,7 +311,7 @@
MenuNode* menu = root;
MenuNode* tmp_node;
- SDL_Rect left_arrow_rect, right_arrow_rect, stopRect, tmp_rect;
+ SDL_Rect tmp_rect;
sprite* tmp_sprite;
int i;
int stop = 0;
@@ -313,33 +336,6 @@
menu_item_selected = render_buttons(menu, true);
items = min(menu->entries_per_screen, menu->submenu_size - menu->first_entry);
- /* 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;
- }
-
-
DEBUGMSG(debug_menu, "run_menu(): drawing %d buttons\n", items);
for(i = 0; i < items; i++)
{
@@ -350,11 +346,13 @@
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->first_entry > 0)
+ SDL_BlitSurface(prev_arrow, NULL, screen, &prev_rect);
+ if(menu->first_entry + items < menu->submenu_size)
+ SDL_BlitSurface(next_arrow, NULL, screen, &next_rect);
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_WM_GrabInput(SDL_GRAB_OFF);
/******** Main loop: *********/
@@ -396,7 +394,7 @@
}
/* "Left" button - make click if button active: */
- if (inRect(left_arrow_rect, event.motion.x, event.motion.y))
+ if (inRect(prev_rect, event.motion.x, event.motion.y))
{
if (menu->first_entry > 0)
{
@@ -410,7 +408,7 @@
}
/* "Right" button - go to next page: */
- else if (inRect(right_arrow_rect, event.motion.x, event.motion.y ))
+ else if (inRect(next_rect, event.motion.x, event.motion.y ))
{
if (menu->first_entry + items < menu->submenu_size)
{
@@ -447,31 +445,31 @@
}
/* "Left" button */
- if (inRect(left_arrow_rect, event.motion.x, event.motion.y))
+ if (inRect(prev_rect, event.motion.x, event.motion.y))
{
if (menu->first_entry > 0)
{
if (Opts_GetGlobalOpt(MENU_SOUND))
playsound(SND_POP);
- action = PAGEDOWN;
+ action = PAGEUP;
}
break; /* from case switch */
}
/* "Right" button - go to next page: */
- else if (inRect(right_arrow_rect, event.motion.x, event.motion.y ))
+ else if (inRect(next_rect, event.motion.x, event.motion.y ))
{
if (menu->first_entry + items < menu->submenu_size)
{
- if (Opts_GetGlobalOpt(MENU_SOUND) && click_flag)
+ if (Opts_GetGlobalOpt(MENU_SOUND))
playsound(SND_POP);
- action = PAGEUP;
+ action = PAGEDOWN;
}
break; /* from case switch */
}
- /* "Stop" button - go to main menu: */
- else if (inRect(stopRect, event.button.x, event.button.y ))
+ /* "Stop" button - go to main menu: */
+ else if (inRect(stop_rect, event.button.x, event.button.y ))
{
playsound(SND_TOCK);
action = STOP;
@@ -508,7 +506,7 @@
if (Opts_GetGlobalOpt(MENU_SOUND))
playsound(SND_TOCK);
if (menu->first_entry > 0)
- action = PAGEDOWN;
+ action = PAGEUP;
break;
}
@@ -519,7 +517,7 @@
if (Opts_GetGlobalOpt(MENU_SOUND))
playsound(SND_TOCK);
if (menu->first_entry + items < menu->submenu_size)
- action = PAGEUP;
+ action = PAGEDOWN;
break;
}
@@ -597,7 +595,7 @@
default:
break;
}
- prerender_menu(menu);
+ prerender_all();
action = RESIZED;
}
break;
@@ -608,7 +606,7 @@
{
SwitchScreenMode();
RenderTitleScreen();
- prerender_menu(menu);
+ prerender_all();
action = RESIZED;
break;
}
@@ -701,6 +699,16 @@
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
@@ -775,7 +783,7 @@
/* text */
tmp_surf = BlackOutline(_(menu->submenu[menu->first_entry + i]->title),
- DEFAULT_MENU_FONT_SIZE, selected ? &yellow : &white);
+ menu->submenu[menu->first_entry + i]->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);
}
@@ -787,12 +795,10 @@
to fit into current screen */
void prerender_menu(MenuNode* menu)
{
- SDL_Rect menu_rect;
SDL_Surface* temp_surf;
MenuNode* curr_node;
int i, imod, max_text_h = 0, max_text_w = 0;
int button_h, button_w;
- float gap;
char filename[buf_size];
if(NULL == menu)
@@ -807,11 +813,6 @@
return;
}
- menu_rect.x = 0.4 * screen->w;
- menu_rect.y = 0.25 * screen->h;
- menu_rect.w = 0.55 * screen->w;
- menu_rect.h = 0.7 * screen->h;
-
for(i = 0; i < menu->submenu_size; i++)
{
temp_surf = NULL;
@@ -824,29 +825,28 @@
}
}
- button_h = 2 * max_text_h;
- button_w = max_text_w + 3 * max_text_h;
+ button_h = (1.0 + 2.0 * text_h_gap) * max_text_h;
+ button_w = max_text_w + (1.0 + 2.0 * text_w_gap) * button_h;
- gap = 0.2;
- menu->entries_per_screen = (int) ( (menu_rect.h - gap * button_h) / ( (1.0 + 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) * gap * button_h;
+ 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 = curr_node->button_rect;
- curr_node->text_rect.y = 0.25 * button_h;
- curr_node->text_rect.x = (1.0 + gap) * button_h;
- curr_node->text_rect.h -= 0.25 * button_h;
- curr_node->text_rect.w -= (1.0 + gap) * button_h;
+ curr_node->text_rect.x = (1.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;
curr_node->font_size = DEFAULT_MENU_FONT_SIZE;
@@ -864,14 +864,56 @@
prerender_menu(menu->submenu[i]);
}
+}
+void set_rect(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;
}
+/* 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;
+
+ set_rect(&menu_rect, menu_pos);
+
+ set_rect(&stop_rect, stop_pos);
+ if(stop_button)
+ SDL_FreeSurface(stop_button);
+ stop_button = LoadImageOfBoundingBox(stop_path, IMG_ALPHA, stop_rect.w, stop_rect.h);
+ stop_rect.x = screen->w - stop_button->w;
+
+ set_rect(&prev_rect, prev_pos);
+ if(prev_arrow)
+ SDL_FreeSurface(prev_arrow);
+ prev_arrow = LoadImageOfBoundingBox(prev_path, IMG_ALPHA, prev_rect.w, prev_rect.h);
+
+ set_rect(&next_rect, next_pos);
+ if(next_arrow)
+ SDL_FreeSurface(next_arrow);
+ next_arrow = LoadImageOfBoundingBox(next_path, IMG_ALPHA, next_rect.w, next_rect.h);
+
+ 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 */
- FILE* menu_file = fopen(DATA_PREFIX "/menus/main_menu.xml", "r");
+ 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");
@@ -879,7 +921,6 @@
else
{
menus[MENU_MAIN] = load_menu_from_file(menu_file, NULL);
- prerender_menu(menus[MENU_MAIN]);
fclose(menu_file);
}
@@ -892,9 +933,10 @@
else
{
menus[MENU_DIFFICULTY] = load_menu_from_file(menu_file, NULL);
- prerender_menu(menus[MENU_DIFFICULTY]);
fclose(menu_file);
}
+
+ prerender_all();
}
/* create a simple one-level menu without sprites.
@@ -941,7 +983,6 @@
char *trailer_quit = "Quit";
char *trailer_back = "Back";
char *trailer = NULL;
- MenuNode* menu;
SDLMod mod;
DEBUGMSG(debug_menu, "Entering RunLoginMenu()");
@@ -964,12 +1005,12 @@
if (n_login_questions > 0)
title = user_login_questions[0];
- menu = create_one_level_menu(n_users, user_names, title, trailer_quit);
+ menus[MENU_LOGIN] = create_one_level_menu(n_users, user_names, title, trailer_quit);
while (n_users) {
// Get the user choice
- prerender_menu(menu);
- chosen_login = run_menu(menu, true);
+ 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 == -1 || chosen_login == n_users) {
@@ -984,7 +1025,8 @@
for (i = 0; i < n_users; i++)
free(user_names[i]);
free(user_names);
- free_menu(menu);
+ free_menu(menus[MENU_LOGIN]);
+ menus[MENU_LOGIN] = NULL;
return -1;
}
else {
@@ -1021,16 +1063,16 @@
trailer = trailer_back;
// Check to see if there are more choices to be made
n_users = read_user_menu_entries(&user_names);
- DEBUGMSG(debug_menu, "aa");
- free_menu(menu);
- menu = create_one_level_menu(n_users, user_names, title, trailer);
+ 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(menu);
+ free_menu(menus[MENU_LOGIN]);
+ menus[MENU_LOGIN] = NULL;
// Signal success
return 0;
More information about the Tux4kids-commits
mailing list