[Tux4kids-commits] r1449 - branches/commonification/tuxtype/trunk/src
Bolesław Kulbabiński
bolekk-guest at alioth.debian.org
Sun Aug 16 20:04:34 UTC 2009
Author: bolekk-guest
Date: 2009-08-16 20:04:34 +0000 (Sun, 16 Aug 2009)
New Revision: 1449
Modified:
branches/commonification/tuxtype/trunk/src/SDL_extras.h
branches/commonification/tuxtype/trunk/src/audio.c
branches/commonification/tuxtype/trunk/src/fileops_media.h
branches/commonification/tuxtype/trunk/src/funcs.h
branches/commonification/tuxtype/trunk/src/menu.c
branches/commonification/tuxtype/trunk/src/menu.h
Log:
moved the latest versions of tux4kids-common files into TuxType
Modified: branches/commonification/tuxtype/trunk/src/SDL_extras.h
===================================================================
--- branches/commonification/tuxtype/trunk/src/SDL_extras.h 2009-08-16 19:49:23 UTC (rev 1448)
+++ branches/commonification/tuxtype/trunk/src/SDL_extras.h 2009-08-16 20:04:34 UTC (rev 1449)
@@ -94,12 +94,12 @@
#endif
/* the colors we use throughout the game */
-static const SDL_Color black = {0x00, 0x00, 0x00, 0x00};
-static const SDL_Color gray = {0x80, 0x80, 0x80, 0x00};
-static const SDL_Color dark_blue = {0x00, 0x00, 0x60, 0x00};
-static const SDL_Color red = {0xff, 0x00, 0x00, 0x00};
-static const SDL_Color white = {0xff, 0xff, 0xff, 0x00};
-static const SDL_Color yellow = {0xff, 0xff, 0x00, 0x00};
+static const SDL_Color black = {0x00, 0x00, 0x00, 0x00};
+static const SDL_Color gray = {0x80, 0x80, 0x80, 0x00};
+static const SDL_Color dark_blue = {0x00, 0x00, 0x60, 0x00};
+static const SDL_Color red = {0xff, 0x00, 0x00, 0x00};
+static const SDL_Color white = {0xff, 0xff, 0xff, 0x00};
+static const SDL_Color yellow = {0xff, 0xff, 0x00, 0x00};
/*Text rendering functions: */
int Setup_SDL_Text(void);
Modified: branches/commonification/tuxtype/trunk/src/audio.c
===================================================================
--- branches/commonification/tuxtype/trunk/src/audio.c 2009-08-16 19:49:23 UTC (rev 1448)
+++ branches/commonification/tuxtype/trunk/src/audio.c 2009-08-16 20:04:34 UTC (rev 1449)
@@ -20,21 +20,21 @@
#include "funcs.h"
#ifndef HAVE_LIBT4KCOMMON
-static Mix_Music* defaultMusic = NULL; // holds music for audioMusicLoad/unload
+static Mix_Music* default_music = NULL;
-void PlaySound(Mix_Chunk* snd)
+void PlaySound(Mix_Chunk* sound)
{
- if(!snd) return;
- if (!settings.sys_sound) return;
-
- Mix_PlayChannel(-1, snd, 0);
+ if(!settings.sys_sound)
+ return;
+ if(sound)
+ Mix_PlayChannel(-1, sound, 0);
}
-/* MusicLoad attempts to load and play the music file
+/* MusicLoad attempts to load and play the music file
* Note: loops == -1 means forever
*/
-void AudioMusicLoad(const char* musicFilename, int loops)
+void AudioMusicLoad(char* musicFilename, int loops)
{
Mix_Music* tmp_music = NULL;
@@ -46,8 +46,8 @@
if (tmp_music)
{
AudioMusicUnload(); //Unload previous defaultMusic
- defaultMusic = tmp_music;
- Mix_PlayMusic(defaultMusic, loops);
+ default_music = tmp_music;
+ Mix_PlayMusic(default_music, loops);
}
}
@@ -59,31 +59,31 @@
{
if (!settings.sys_sound) return;
- if (defaultMusic)
+ if(default_music)
{
- Mix_FreeMusic(defaultMusic);
- defaultMusic = NULL;
+ Mix_FreeMusic(default_music);
+ default_music = NULL;
}
}
bool IsPlayingMusic()
{
- return (defaultMusic != NULL);
+ return (default_music != NULL);
}
#endif //HAVE_LIBT4KCOMMON
-/* audioMusicPlay attempts to play the passed music data.
+/* audioMusicPlay attempts to play the passed music data.
* if a music file was loaded using the audioMusicLoad
* it will be stopped and unloaded
* Note: loops == -1 means forever
*/
void MusicPlay(Mix_Music* musicData, int loops)
-{
+{
if (!settings.sys_sound) return;
if (!musicData) return;
/* Stop previous music before playing new one: */
- AudioMusicUnload();
+ AudioMusicUnload();
Mix_PlayMusic(musicData, loops);
}
Modified: branches/commonification/tuxtype/trunk/src/fileops_media.h
===================================================================
--- branches/commonification/tuxtype/trunk/src/fileops_media.h 2009-08-16 19:49:23 UTC (rev 1448)
+++ branches/commonification/tuxtype/trunk/src/fileops_media.h 2009-08-16 20:04:34 UTC (rev 1449)
@@ -2,6 +2,7 @@
#define FILEOPS_MEDIA_H
#include "globals.h"
+#include "SDL_extras.h"
#include "SDL.h"
#include "SDL_mixer.h"
Modified: branches/commonification/tuxtype/trunk/src/funcs.h
===================================================================
--- branches/commonification/tuxtype/trunk/src/funcs.h 2009-08-16 19:49:23 UTC (rev 1448)
+++ branches/commonification/tuxtype/trunk/src/funcs.h 2009-08-16 20:04:34 UTC (rev 1449)
@@ -56,7 +56,7 @@
#ifndef HAVE_LIBT4KCOMMON
/* In audio.c: */
void PlaySound(Mix_Chunk* snd);
-void AudioMusicLoad(const char* musicFilename, int repeatQty);
+void AudioMusicLoad(char* musicFilename, int repeatQty);
void AudioMusicUnload(void);
bool IsPlayingMusic();
Modified: branches/commonification/tuxtype/trunk/src/menu.c
===================================================================
--- branches/commonification/tuxtype/trunk/src/menu.c 2009-08-16 19:49:23 UTC (rev 1448)
+++ branches/commonification/tuxtype/trunk/src/menu.c 2009-08-16 20:04:34 UTC (rev 1449)
@@ -1,7 +1,10 @@
/*
- t4k-menu.c
+ menu.c
Functions responsible for loading, parsing and displaying game menu.
+ This file is almost identical to t4k-menu.c from tux4kids-common library.
+ The only differences are button paths and data_prefix in PrerenderAll().
+ Please copy any changes done to t4kcommon here.
Part of "Tux4Kids" Project
http://www.tux4kids.com/
@@ -22,6 +25,10 @@
#ifndef HAVE_LIBT4KCOMMON
+/*
+ representation of a menu tree node
+*/
+
struct mNode {
struct mNode* parent;
@@ -51,38 +58,52 @@
typedef struct mNode MenuNode;
-#define QUIT -2
-#define STOP -1
-#define RUN_MAIN_MENU -3
-int n_of_activities;
+/*
+ menu globals
+*/
+
+/* activities array is used to parse xml menu files */
+static int n_of_activities;
static char** activities;
-char* data_prefix;
+/* prefix that is added to sprite paths */
+static char* data_prefix;
-Mix_Chunk* snd_click;
-Mix_Chunk* snd_hover;
-char* music_path;
+static Mix_Chunk* snd_click;
+static Mix_Chunk* snd_hover;
+static char* music_path;
-#define N_OF_MENUS 10
-MenuNode* menus[N_OF_MENUS];
-
/* font size used in current resolution */
-int curr_font_size;
+static int curr_font_size;
/* buffer size used when reading attributes or names */
-const int buf_size = 512;
+static const int buf_size = 512;
+/* maximum menu buttons per page */
+static const int MAX_PAGE_SIZE = 8;
+
/* actions available while viewing the menu */
enum { NONE, CLICK, PAGEUP, PAGEDOWN, STOP_ESC, RESIZED };
+/* menus is a global array when user can save up to 10 loaded menus.
+ From outside this file we identify menu trees by their ids (indexes in this array)
+ so as not to expose MenuNode struct to the user */
+#define N_OF_MENUS 10
+static 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, menu_title_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 ? ) */
+
+/*
+ positioning constants
+*/
+
+/* NOTE: maybe it is better to move these constants into a config file ? */
+/* X Y W H */
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};
@@ -92,12 +113,15 @@
const char* next_path = "/images/status/right.svg";
const char* prev_gray_path = "/images/status/left_gray.svg";
const char* next_gray_path = "/images/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 float button_gap = 0.18, text_h_gap = 0.35, text_w_gap = 0.5, button_radius = 0.27;
const int min_font_size = 8, default_font_size = 20, max_font_size = 40;
-/* local functions */
+/*
+ local functions
+*/
+
MenuNode* create_empty_node();
char* get_attribute_name(const char* token);
char* get_attribute_value(const char* token);
@@ -107,11 +131,16 @@
SDL_Surface** render_buttons(MenuNode* menu, bool selected);
char* find_longest_text(MenuNode* menu, int* length);
+int find_longest_menu_page(MenuNode* menu);
void set_font_size();
void prerender_menu(MenuNode* menu);
-/* initialization of menu module */
+/*
+ functions initializing the menu module
+ (they shoul be called before any other menu activity)
+*/
+
void SetActivitiesList(int num, char** acts)
{
n_of_activities = num;
@@ -125,6 +154,7 @@
music_path = mus_path;
}
+/* prefix that is used whe loading menu sprites */
void SetImagePathPrefix(char* pref)
{
data_prefix = pref;
@@ -182,6 +212,7 @@
node->icon_name = strdup(attr_val);
else if(strcmp(attr_name, "run") == 0)
{
+ /* special activity - should be handled separately */
if(strcmp(attr_val, "RUN_MAIN_MENU") == 0)
node->activity = RUN_MAIN_MENU;
else
@@ -310,12 +341,72 @@
menus[index] = menu;
}
+/* load menu from given XML file and store its tree under given index
+ in "menus" array */
+void LoadMenu(int index, const char* file_name)
+{
+ FILE* menu_file = NULL;
+ if(menus[index])
+ {
+ free_menu(menus[index]);
+ menus[index] = NULL;
+ }
-/* Display the menu and run the event loop.
+ menu_file = fopen(file_name, "r");
+ if(menu_file == NULL)
+ {
+ DEBUGMSG(debug_menu, "LoadMenu(): Could not load %s !\n", file_name);
+ }
+ else
+ {
+ menus[index] = load_menu_from_file(menu_file, NULL);
+ fclose(menu_file);
+ }
+}
+
+/* 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");
+}
+
+
+/*
+ RunMenu - main function to 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() */
+ this function is a modified copy of choose_menu_item()
+*/
int RunMenu(int index, bool return_choice, void (*draw_background)(), int (*handle_event)(SDL_Event*), void (*handle_animations)(), int (*handle_activity)(int, int))
{
SDL_Surface** menu_item_unselected = NULL;
@@ -351,6 +442,7 @@
menu_item_selected = render_buttons(menu, true);
items = min(menu->entries_per_screen, menu->submenu_size - menu->first_entry);
+ /* draw buttons */
DEBUGMSG(debug_menu, "run_menu(): drawing %d buttons\n", items);
for(i = 0; i < items; i++)
{
@@ -364,6 +456,7 @@
SDL_BlitSurface(stop_button, NULL, GetScreen(), &stop_rect);
+ /* check if there is a need to draw menu arrows */
if(menu->entries_per_screen < menu->submenu_size)
{
/* display arrows */
@@ -377,6 +470,7 @@
SDL_BlitSurface(next_gray, NULL, GetScreen(), &next_rect);
}
+ /* display red menu title (if present) */
if(menu->show_title)
{
menu_title_rect = menu->submenu[0]->button_rect;
@@ -403,6 +497,7 @@
{
switch (event.type)
{
+ /* user decided to quit the application (for example by closing the window) */
case SDL_QUIT:
{
FreeSurfaceArray(menu_item_unselected, items);
@@ -618,6 +713,7 @@
} // End of case SDL_KEYDOWN in outer switch statement
} // End event switch statement
+ /* handle button focus */
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)
@@ -625,7 +721,8 @@
tmp_rect = menu->submenu[old_loc + menu->first_entry]->button_rect;
SDL_BlitSurface(menu_item_unselected[old_loc], NULL, GetScreen(), &tmp_rect);
if(menu->submenu[menu->first_entry + old_loc]->icon)
- SDL_BlitSurface(menu->submenu[menu->first_entry + old_loc]->icon->default_img, NULL, GetScreen(), &menu->submenu[menu->first_entry + old_loc]->icon_rect);
+ SDL_BlitSurface(menu->submenu[menu->first_entry + old_loc]->icon->default_img,
+ NULL, GetScreen(), &menu->submenu[menu->first_entry + old_loc]->icon_rect);
SDL_UpdateRect(GetScreen(), tmp_rect.x, tmp_rect.y, tmp_rect.w, tmp_rect.h);
}
if(loc >= 0 && loc < items)
@@ -634,7 +731,8 @@
SDL_BlitSurface(menu_item_selected[loc], NULL, GetScreen(), &tmp_rect);
if(menu->submenu[menu->first_entry + loc]->icon)
{
- SDL_BlitSurface(menu->submenu[menu->first_entry + loc]->icon->default_img, NULL, GetScreen(), &menu->submenu[menu->first_entry + loc]->icon_rect);
+ SDL_BlitSurface(menu->submenu[menu->first_entry + loc]->icon->default_img,
+ NULL, GetScreen(), &menu->submenu[menu->first_entry + loc]->icon_rect);
menu->submenu[menu->first_entry + loc]->icon->cur = 0;
}
SDL_UpdateRect(GetScreen(), tmp_rect.x, tmp_rect.y, tmp_rect.w, tmp_rect.h);
@@ -642,9 +740,12 @@
old_loc = loc;
}
+ /* check if catched event causes any changes to titlescreen,
+ if handle_event() returns 1, menu should be redrawn */
if(handle_event(&event))
stop = true;
+ /* handle special action that was caused by an event */
switch(action)
{
case RESIZED:
@@ -665,6 +766,7 @@
{
if(return_choice)
{
+ /* return choice instead of running a handler function */
FreeSurfaceArray(menu_item_unselected, items);
FreeSurfaceArray(menu_item_selected, items);
return tmp_node->activity;
@@ -678,17 +780,20 @@
}
else
{
+ /* we are going to run a handler function that probably will run a game,
+ save current screen resolution in case it is changed while running a game */
old_w = GetScreen()->w;
old_h = GetScreen()->h;
if(handle_activity(tmp_node->activity, tmp_node->param) == QUIT)
{
+ /* user decided to quit while playing a game */
DEBUGMSG(debug_menu, "run_menu(): handle_activity() returned QUIT message, exiting.\n");
FreeSurfaceArray(menu_item_unselected, items);
FreeSurfaceArray(menu_item_selected, items);
return QUIT;
}
if(old_w != GetScreen()->w || old_h != GetScreen()->h)
- PrerenderAll();
+ PrerenderAll(); /* resolution has changed */
}
}
}
@@ -728,8 +833,10 @@
} // End of SDL_PollEvent while loop
if(stop)
+ /* whole menu will be redrawn so there is no need to draw anything now */
break;
+ /* handle icon animation of selected button */
if(!stop && frame_counter % 5 == 0 && loc >= 0 && loc < items)
{
tmp_sprite = menu->submenu[menu->first_entry + loc]->icon;
@@ -742,6 +849,7 @@
}
}
+ /* handle titlescreen animations */
handle_animations();
/* Wait so we keep frame rate constant: */
@@ -763,6 +871,10 @@
return QUIT;
}
+/*
+ functins responsible for rendering menus
+*/
+
/* return button surfaces that are currently displayed (without sprites) */
SDL_Surface** render_buttons(MenuNode* menu, bool selected)
{
@@ -894,6 +1006,8 @@
prerender_menu(menus[index]);
}
+/* recursively search for longest menu caption in currently
+ used menus and in current language */
char* find_longest_text(MenuNode* menu, int* length)
{
SDL_Surface* text = NULL;
@@ -924,6 +1038,21 @@
return ret;
}
+/* recursively search for longest (sub)menu that is not longer
+ than MAX_PAGE_SIZE to ensure better menu outlook */
+int find_longest_menu_page(MenuNode* menu)
+{
+ int longest = 0, i;
+
+ if(menu->submenu_size <= MAX_PAGE_SIZE)
+ longest = menu->submenu_size;
+
+ for(i = 0; i < menu->submenu_size; i++)
+ longest = max(longest, find_longest_menu_page(menu->submenu[i]));
+
+ return longest;
+}
+
/* find the longest text in all existing menus and binary search
for the best font size */
void set_font_size()
@@ -931,7 +1060,7 @@
char* longest = NULL;
char* temp;
SDL_Surface* surf;
- int length = 0, i, min_f, max_f, mid_f;
+ int length = 0, i, min_f, max_f, mid_f, max_buttons = 0;
curr_font_size = default_font_size;
@@ -939,6 +1068,7 @@
{
if(menus[i])
{
+ max_buttons = max(max_buttons, find_longest_menu_page(menus[i]));
temp = find_longest_text(menus[i], &length);
if(temp)
longest = temp;
@@ -951,11 +1081,13 @@
min_f = min_font_size;
max_f = max_font_size;
+ /* run binary search */
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)
+ if(surf->w + (1.0 + 2.0 * text_w_gap) * (1.0 + 2.0 * text_h_gap) * surf->h < menu_rect.w
+ && (1.0 + button_gap) * (max_buttons + 1) + (1.5 + 2.0 * text_h_gap) * surf->h * max_buttons < menu_rect.h)
min_f = mid_f + 1;
else
max_f = mid_f;
@@ -1011,63 +1143,4 @@
PrerenderMenu(i);
}
-void LoadMenu(int index, const char* file_name)
-{
- FILE* menu_file = NULL;
-
- if(menus[index])
- {
- free_menu(menus[index]);
- menus[index] = NULL;
- }
-
- menu_file = fopen(file_name, "r");
- if(menu_file == NULL)
- {
- DEBUGMSG(debug_menu, "LoadMenu(): Could not load %s !\n", file_name);
- }
- else
- {
- menus[index] = load_menu_from_file(menu_file, NULL);
- fclose(menu_file);
- }
-}
-
-
-
-/* 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");
-}
-
#endif //HAVE_LIBT4KCOMMON
Modified: branches/commonification/tuxtype/trunk/src/menu.h
===================================================================
--- branches/commonification/tuxtype/trunk/src/menu.h 2009-08-16 19:49:23 UTC (rev 1448)
+++ branches/commonification/tuxtype/trunk/src/menu.h 2009-08-16 20:04:34 UTC (rev 1449)
@@ -20,6 +20,12 @@
#ifndef HAVE_LIBT4KCOMMON
#define MAX_FPS 30
+/* special values used by RunMenu. RUN_MAIN_MENU is a special
+ activity that can be used in .xml menu structures but should not
+ be declared in activities' lists.
+ RunMenu returning QUIT indicates that user decided to quit application while
+ running the menu. Returning STOP indicates that user pressed stop button. */
+enum { RUN_MAIN_MENU = -3, QUIT = -2, STOP = -1 };
extern SDL_Rect menu_rect, stop_rect, prev_rect, next_rect;
extern SDL_Surface *stop_button, *prev_arrow, *next_arrow, *prev_gray, *next_gray;
More information about the Tux4kids-commits
mailing list