1
1
mirror of https://github.com/tstellar/bygfoot.git synced 2025-03-09 15:20:08 +01:00

Load/save implemented.

This commit is contained in:
gyboth 2005-04-04 10:36:04 +00:00
parent 27efe36a8f
commit b7159723a2
44 changed files with 874 additions and 426 deletions

View File

@ -774,13 +774,13 @@
</child>
</widget>
<widget class="GtkFileSelection" id="fsel_window">
<widget class="GtkFileSelection" id="window_file_sel">
<property name="border_width">10</property>
<property name="visible">True</property>
<property name="title" translatable="yes">Choose file</property>
<property name="type">GTK_WINDOW_TOPLEVEL</property>
<property name="window_position">GTK_WIN_POS_CENTER</property>
<property name="modal">False</property>
<property name="modal">True</property>
<property name="resizable">True</property>
<property name="destroy_with_parent">False</property>
<property name="show_fileops">True</property>

View File

@ -10,7 +10,7 @@ bin_PROGRAMS = bygfoot
bygfoot_SOURCES = \
callback_func.c callback_func.h callbacks.h cup.h finance.h fixture.h game_gui.h league.h live_game.h maths.h misc.h option.h player.h start_end.h team.h transfer.h treeview.h user.h window.h \
callbacks.c callbacks.h callback_func.h game_gui.h main.h option.h player.h team.h transfer.h treeview.h user.h window.h \
callbacks.c callbacks.h callback_func.h game_gui.h load_save.h main.h option.h player.h team.h transfer.h treeview.h user.h window.h \
cup.c cup.h free.h main.h maths.h misc.h team.h variables.h xml_league.h \
file.c file.h free.h main.h misc.h option.h support.h variables.h \
finance.c callbacks.h finance.h game_gui.h maths.h option.h player.h team.h user.h \
@ -20,13 +20,13 @@ bygfoot_SOURCES = \
game_gui.c file.h game_gui.h gui.h league.h live_game.h maths.h misc.h option.h treeview.h support.h team.h user.h variables.h window.h \
gui.c gui.h misc.h support.h variables.h window.h \
interface.c callbacks.h interface.h support.h \
league.c cup.h league.h team.h variables.h \
league.c cup.h league.h table.h team.h variables.h \
live_game.c fixture.h free.h game.h game_gui.h live_game.h maths.h misc_callback_func.h option.h player.h support.h team.h treeview.h user.h variables.h window.h \
load_save.c load_save.h \
main.c misc_callbacks.h file.h free.h main.h transfer_struct.h variables.h window.h \
load_save.c file.h gui.h load_save.h option.h support.h variables.h xml_loadsave_misc.h xml_loadsave_cup.h xml_loadsave_league.h xml_loadsave_transfers.h xml_loadsave_users.h xml.h \
main.c misc_callbacks.h file.h free.h live_game.h main.h transfer_struct.h variables.h window.h \
maths.c maths.h misc.h \
misc.c main.h maths.h misc.h \
misc_callbacks.c free.h misc_callback_func.h misc_callbacks.h \
misc_callbacks.c callbacks.h callback_func.h game.h game_gui.h live_game.h load_save.h main.h misc_callback_func.h misc_callbacks.h option.h user.h variables.h window.h \
misc_callback_func.c misc_callback_func.h start_end.h support.h team.h treeview.h user.h variables.h xml_country.h \
misc_interface.c misc_interface.h misc_callbacks.h support.h \
misc2_callbacks.c finance.h game_gui.h main.h misc2_callbacks.h misc2_callback_func.h misc2_interface.h player.h support.h transfer.h treeview.h user.h window.h \
@ -34,7 +34,7 @@ bygfoot_SOURCES = \
misc2_interface.c misc2_interface.h misc2_callbacks.h support.h \
option.c option.h variables.h \
option_gui.c file.h option_gui.h option.h support.h user.h variables.h \
options_callbacks.c file.h options_callbacks.h options_interface.h option_gui.h support.h variables.h window.h \
options_callbacks.c file.h options_callbacks.h options_interface.h option_gui.h support.h user.h variables.h window.h \
options_interface.c options_interface.h options_callbacks.h support.h \
player.c cup.h free.h game_gui.h league.h maths.h misc.h option.h player.h team.h user.h \
start_end.c cup.h file.h finance.h fixture.h game_gui.h gui.h league.h live_game.h main.h maths.h start_end.h table.h team.h transfer.h user.h variables.h xml_name.h \
@ -44,8 +44,18 @@ bygfoot_SOURCES = \
transfer.c finance.h free.h game_gui.h maths.h option.h player.h support.h team.h transfer.h treeview.h user.h \
treeview.c cup.h file.h finance.h fixture.h free.h game.h league.h live_game.h maths.h misc.h player.h option.h support.h team.h transfer.h treeview.h treeview_cell.h user.h \
treeview_cell.c misc.h option.h player.h team.h treeview.h treeview_cell.h user.h variables.h \
user.c fixture.h free.h game_gui.h maths.h misc.h option.h player.h team.h transfer.h user.h window.h \
user.c fixture.h free.h game_gui.h live_game.h maths.h misc.h option.h player.h team.h transfer.h user.h window.h \
window.c file.h finance.h free.h game_gui.h gui.h interface.h misc_interface.h misc2_interface.h option.h support.h user.h window.h \
xml.c cup.h file.h free.h gui.h league.h misc.h support.h table.h transfer_struct.h user.h variables.h xml.h xml_loadsave_cup.h xml_loadsave_league.h xml_loadsave_teams.h xml_loadsave_fixtures.h xml_loadsave_table.h xml_loadsave_transfers.h xml_loadsave_users.h \
xml_loadsave_misc.c file.h misc.h variables.h xml.h xml_loadsave_misc.h xml_loadsave_cup.h xml_loadsave_league.h \
xml_loadsave_cup.c cup.h file.h misc.h team.h xml.h xml_loadsave_cup.h xml_loadsave_fixtures.h xml_loadsave_table.h xml_loadsave_teams.h \
xml_loadsave_fixtures.c file.h fixture.h misc.h team.h xml.h xml_loadsave_fixtures.h \
xml_loadsave_league.c file.h league.h misc.h xml.h xml_loadsave_fixtures.h xml_loadsave_league.h xml_loadsave_table.h xml_loadsave_teams.h \
xml_loadsave_live_game.c cup.h file.h fixture.h league.h live_game.h misc.h variables.h xml.h xml_loadsave_live_game.h \
xml_loadsave_table.c file.h misc.h team.h xml.h xml_loadsave_table.h \
xml_loadsave_teams.c file.h misc.h player.h team.h xml.h xml_loadsave_teams.h \
xml_loadsave_transfers.c file.h misc.h team.h transfer.h xml.h xml_loadsave_transfers.h \
xml_loadsave_users.c file.h misc.h team.h user.h variables.h xml.h xml_loadsave_users.h \
xml_cup.c cup.h file.h misc.h xml_cup.h \
xml_country.c file.h free.h misc.h variables.h xml_cup.h xml_country.h xml_league.h \
xml_league.c cup_struct.h file.h free.h league.h misc.h team.h table.h variables.h xml_league.h xml_cup.h \

View File

@ -18,6 +18,9 @@
*/
#define VERS "1.9.0"
/** Home dir name */
#define HOMEDIRNAME ".bygfoot-1.9"
/**
* Convenience macros, used for string sizes (typically buf[SMALL]).
*/
@ -96,16 +99,9 @@ typedef struct
*yesno,
*options,
*font_sel,
*file_sel,
*contract,
*menu_player,
*user_management;
} Windows;
/** A struct representing an option or a constant. */
typedef struct
{
GString *name, *string_value;
gint value;
} Option;
#endif

View File

@ -122,7 +122,7 @@ callback_show_last_match(void)
{
gint i;
if(current_user.live_game.units == NULL)
if(current_user.live_game.units->len == 0)
{
game_gui_show_warning("No match to show.");
return;

View File

@ -1,6 +1,7 @@
#include "callbacks.h"
#include "callback_func.h"
#include "game_gui.h"
#include "load_save.h"
#include "main.h"
#include "option.h"
#include "player.h"
@ -33,7 +34,8 @@ void
on_menu_open_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
stat1 = STATUS_LOAD_GAME;
window_show_file_sel();
}
@ -41,7 +43,11 @@ void
on_menu_save_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
if(!opt_int("int_opt_save_will_overwrite") ||
strlen(save_file->str) == 0)
on_menu_save_as_activate(NULL, NULL);
else
load_save_save_game(save_file->str);
}
@ -49,7 +55,8 @@ void
on_menu_save_as_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
stat1 = STATUS_SAVE_GAME;
window_show_file_sel();
}
void
@ -72,7 +79,7 @@ void
on_button_load_clicked (GtkButton *button,
gpointer user_data)
{
on_menu_open_activate(NULL, NULL);
}
@ -80,7 +87,7 @@ void
on_button_save_clicked (GtkButton *button,
gpointer user_data)
{
on_menu_save_activate(NULL, NULL);
}
@ -376,10 +383,15 @@ on_treeview_right_button_press_event (GtkWidget *widget,
{
gint idx;
if(gtk_tree_selection_get_mode(
gtk_tree_view_get_selection(GTK_TREE_VIEW(widget))) ==
GTK_SELECTION_NONE)
return TRUE;
if(treeview_select_row(GTK_TREE_VIEW(widget), event))
idx = treeview_get_index(GTK_TREE_VIEW(widget), 0);
else
return FALSE;
return TRUE;
switch(stat0)
{
@ -406,7 +418,7 @@ on_treeview_right_button_press_event (GtkWidget *widget,
break;
}
return FALSE;
return TRUE;
}
void

View File

@ -161,7 +161,7 @@ cup_load_choose_teams(Cup *cup)
{
g_array_append_val(cup->teams, g_array_index(teams, Team, permutation[j]));
g_array_index(cup->teams, Team, cup->teams->len - 1).clid = cup->id;
g_array_index(cup->teams, Team, cup->teams->len - 1).id = cup->teams->len;
g_array_index(cup->teams, Team, cup->teams->len - 1).id = cup->teams->len - 1;
number_of_teams++;
}

View File

@ -91,6 +91,11 @@ typedef struct
gint skill_diff;
/** Array with rules how teams are chosen.
@see #CupChooseTeam */
/** The week and week_round at the beginning of which the fixtures
have to be updated. */
gint next_fixture_update_week;
gint next_fixture_update_week_round;
GArray *choose_teams;
/** The ChooseTeam rule according to which
the participant from the user's league is chosen.
@ -111,10 +116,6 @@ typedef struct
GArray *tables;
/** The fixtures of a season for the cup. */
GArray *fixtures;
/** The week and week_round at the beginning of which the fixtures
have to be updated. */
gint next_fixture_update_week;
gint next_fixture_update_week_round;
} Cup;
#endif

View File

@ -72,6 +72,8 @@ enum Status0Value
STATUS_FIRE_PLAYER,
STATUS_USER_MANAGEMENT,
STATUS_SHOW_PREVIEW,
STATUS_SAVE_GAME,
STATUS_LOAD_GAME,
STATUS_END
};

View File

@ -6,14 +6,6 @@
#include "support.h"
#include "variables.h"
/**
The list of directories the file_find_support_file() function
searches for support files (e.g. pixmaps or text files).
@see file_find_support_file()
@see file_add_support_directory_recursive()
*/
static GList *support_directories = NULL;
/**
Add the specified directory to the list of directories file_find_support_file()
searches for support files.
@ -36,6 +28,7 @@ file_add_support_directory_recursive (const gchar *directo
add_pixmap_directory(directory);
support_directories = g_list_prepend (support_directories,
g_strdup (directory));
while(TRUE)
{
file = g_dir_read_name(newdir);
@ -68,10 +61,8 @@ file_add_support_directory_recursive (const gchar *directo
gchar*
file_find_support_file (const gchar *filename)
{
GList *elem;
GList *elem = support_directories;
/* We step through each of the pixmaps directory to find it. */
elem = support_directories;
while (elem)
{
gchar *pathname = g_strdup_printf ("%s%s%s", (gchar*)elem->data,
@ -82,9 +73,27 @@ file_find_support_file (const gchar *filename)
g_free (pathname);
elem = elem->next;
}
/* if(opt_int("int_opt_debug")) */
/* g_warning("file_find_support_file: file '%s' not found.", filename); */
return NULL;
}
/** Execute command with 'system' and give a warning if return value is -1.
@return TRUE on success, FALSE, otherwise. */
gboolean
file_my_system(const gchar *command)
{
if(system(command) == -1)
{
g_warning("file_my_system: system returned -1 when executing '%s'.", command);
return FALSE;
}
return TRUE;
}
/** A custom function opening files.
@param filename The full path to the file or a file name from the support files.
@param bits The mode we use, e.g. "r" or "w". @see fopen()
@ -114,8 +123,6 @@ file_my_fopen(const gchar *filename, gchar *bits, FILE **fil, gboolean abort_pro
sprintf(buf, "Could not open file '%s' in mode '%s'.\n", filename, bits);
g_warning(buf);
/*d*/
/* show_popup_window(buf, NULL); */
if(abort_program)
main_exit_program(EXIT_FILE_OPEN_FAILED, NULL);
@ -123,18 +130,112 @@ file_my_fopen(const gchar *filename, gchar *bits, FILE **fil, gboolean abort_pro
return FALSE;
}
/** Create a $HOME/.bygfoot dir and other stuff if necessary. */
void
file_check_home_dir_create_dirs(void)
{
gint i;
gchar *dirs[3] =
{HOMEDIRNAME,
HOMEDIRNAME"/definitions",
HOMEDIRNAME"/saves"};
const gchar *home = g_get_home_dir();
gchar buf[SMALL];
for(i=0;i<3;i++)
{
sprintf(buf, "%s/%s", home, dirs[i]);
if(!g_file_test(buf, G_FILE_TEST_EXISTS))
{
sprintf(buf, "mkdir -v %s/%s", home, dirs[i]);
file_my_system(buf);
}
}
}
/** Copy the basic config files into the user home dir. */
void
file_check_home_dir_copy_conf_files(void)
{
gint i;
gchar *conf_files[3] =
{"bygfoot.conf",
"bygfoot_user.conf",
"bygfoot_constants"};
const gchar *home = g_get_home_dir();
gchar *conf_file = NULL;
gchar buf[SMALL];
for(i=0;i<3;i++)
{
sprintf(buf, "%s/%s/%s", home, HOMEDIRNAME, conf_files[i]);
if(!g_file_test(buf, G_FILE_TEST_EXISTS))
{
conf_file = file_find_support_file(conf_files[i]);
sprintf(buf, "cp -v %s %s/%s/%s", conf_file, home, HOMEDIRNAME, conf_files[i]);
file_my_system(buf);
}
}
}
/** Copy the xml definition files into the home dir. */
void
file_check_home_dir_copy_definition_files(void)
{
gint i;
gchar buf[SMALL];
const gchar *home = g_get_home_dir();
GPtrArray *dir_contents = NULL;
GList *elem = support_directories;
while(elem != NULL)
{
if(g_str_has_suffix((gchar*)elem->data, "definitions"))
{
dir_contents = file_dir_get_contents((gchar*)elem->data, "", ".xml");
for(i=0;i<dir_contents->len;i++)
{
sprintf(buf, "%s/%s/definitions/%s", home, HOMEDIRNAME,
((GString*)g_ptr_array_index(dir_contents, i))->str);
if(!g_file_test(buf, G_FILE_TEST_EXISTS))
{
sprintf(buf, "cp -v %s/%s %s/%s/definitions/%s", (gchar*)elem->data,
((GString*)g_ptr_array_index(dir_contents, i))->str,
home, HOMEDIRNAME, ((GString*)g_ptr_array_index(dir_contents, i))->str);
file_my_system(buf);
}
}
free_g_string_array(&dir_contents);
}
elem = elem->next;
}
}
/** Copy some files into the user's home directory. */
void
file_check_home_dir(void)
{
file_check_home_dir_create_dirs();
file_check_home_dir_copy_conf_files();
file_check_home_dir_copy_definition_files();
}
/**
Retrieve those files in the given directory
that start with the given prefix. The file names are stored
that start with the given prefix and suffix. The file names are stored
in an array of GStrings.
@param dir_name The full path to the directory.
@param prefix The prefix that files must have to be included.
@param suffix The suffix that files must have to be included.
@return A GPtrArray with pointers to the GStrings of the file
names. The GStrings and the array must be freed with file_dir_free_contents().
@see file_dir_free_contents()
names. The GStrings and the array must be freed with free_g_string_array().
@see free_g_string_array()
*/
GPtrArray*
file_dir_get_contents(const gchar *dir_name, const gchar *prefix)
file_dir_get_contents(const gchar *dir_name, const gchar *prefix, const gchar *suffix)
{
GError *error = NULL;
GDir *dir = g_dir_open(dir_name, 0, &error);
@ -154,7 +255,8 @@ file_dir_get_contents(const gchar *dir_name, const gchar *prefix)
while(file != NULL)
{
if(g_str_has_prefix(file, prefix))
if(g_str_has_prefix(file, prefix) &&
g_str_has_suffix(file, suffix))
{
new = g_string_new(file);
g_ptr_array_add(contents, (gpointer)new);
@ -167,33 +269,26 @@ file_dir_get_contents(const gchar *dir_name, const gchar *prefix)
return contents;
}
/** Write the first directory called 'definitions' from the support
directories array into the buffer.
@param dir The string buffer we write the directory path into. */
void
file_get_definitions_dir(gchar *dir)
/** Return the first directory called 'definitions' from the support
directories array. */
const gchar*
file_get_definitions_dir(void)
{
GList *elem;
strcpy(dir, "");
elem = support_directories;
GList *elem = support_directories;
while(elem != NULL)
{
if(g_str_has_suffix((gchar*)elem->data, "definitions") ||
g_str_has_suffix((gchar*)elem->data, "definitions/"))
{
strcpy(dir, (gchar*)elem->data);
break;
}
return (gchar*)elem->data;
elem = elem->next;
}
if(strlen(dir) == 0)
main_exit_program(EXIT_DIR_OPEN_FAILED,
"Didn't find definitions directory.\n");
main_exit_program(EXIT_DIR_OPEN_FAILED,
"Didn't find definitions directory.\n");
return NULL;
}
/** Read the file until the next line that's not a comment or
@ -240,23 +335,46 @@ file_get_next_opt_line(FILE *fil, gchar *opt_name, gchar *opt_value)
else
break;
sscanf(buf, "%[^ \t]%[^a-zA-Z0-9_-]%[^\n]", opt_name, trash, opt_value);
sscanf(buf, "%[^ \t]%[ \t]%[^\n]", opt_name, trash, opt_value);
}
return (feof(fil) == 0);
}
/** Save an optionlist to a file. */
void
file_save_opt_file(const gchar *filename, OptionList *optionlist)
{
gint i;
FILE *fil = NULL;
file_my_fopen(filename, "w", &fil, TRUE);
for(i=0;i<optionlist->list->len;i++)
if(g_str_has_prefix(g_array_index(optionlist->list, Option, i).name->str, "string_"))
fprintf(fil, "%s %s\n", g_array_index(optionlist->list, Option, i).name->str,
g_array_index(optionlist->list, Option, i).string_value->str);
else
fprintf(fil, "%s %d\n", g_array_index(optionlist->list, Option, i).name->str,
g_array_index(optionlist->list, Option, i).value);
fclose(fil);
}
/** Load a file containing name - value pairs into
the specified array. */
void
file_load_opt_file(FILE *fil, OptionList *optionlist)
file_load_opt_file(const gchar *filename, OptionList *optionlist)
{
gint i;
gchar opt_name[SMALL], opt_value[SMALL];
Option new;
FILE *fil = NULL;
free_option_list(optionlist, TRUE);
file_my_fopen(filename, "r", &fil, TRUE);
while(file_get_next_opt_line(fil, opt_name, opt_value))
{
new.name = g_string_new(opt_name);
@ -286,25 +404,12 @@ file_load_opt_file(FILE *fil, OptionList *optionlist)
void
file_load_conf_files(void)
{
FILE *fil = NULL;
gchar *conf_file = file_find_support_file("bygfoot.conf");
file_my_fopen(conf_file, "r", &fil, TRUE);
file_load_opt_file(conf_file, &options);
g_free(conf_file);
file_load_opt_file(fil, &options);
file_load_constants_file(opt_str("string_opt_constants_file"));
}
/** Load the constants from the given file. */
void
file_load_constants_file(const gchar* file_name)
{
FILE *fil = NULL;
file_my_fopen(file_name, "r", &fil, TRUE);
file_load_opt_file(fil, &constants);
file_load_opt_file(opt_str("string_opt_constants_file"), &constants);
}
/** Load a user-specific conf file.
@ -323,8 +428,79 @@ file_load_user_conf_file(User *user)
{
g_free(conf_file);
conf_file = file_find_support_file(opt_str("string_opt_default_user_conf_file"));
file_my_fopen(conf_file, "r", &fil, TRUE);
}
file_load_opt_file(fil, &user->options);
file_load_opt_file(conf_file, &user->options);
g_free(conf_file);
}
/** Return the primary support dir (probably './support_files' or
the Bygfoot dir in $HOME). */
const gchar*
file_get_first_support_dir(void)
{
GList *elem = support_directories;
while (elem)
{
if(g_str_has_suffix((gchar*)elem->data, HOMEDIRNAME) ||
g_str_has_suffix((gchar*)elem->data, "support_files"))
return (const gchar*)elem->data;
elem = elem->next;
}
g_warning("file_get_first_support_dir: no primary support dir found.");
return NULL;
}
/** Compress the files starting with the prefix.
@param destfile The name of the file to create. */
void
file_compress_files(const gchar *destfile, const gchar *prefix)
{
gint i;
gchar buf[SMALL];
gchar *basename = g_path_get_basename(prefix),
*dirname = g_path_get_dirname(prefix),
*zipbasename = g_path_get_basename(destfile);
GPtrArray *files = file_dir_get_contents(dirname, basename, "");
sprintf(buf, "pushd 1> /dev/null %s; %s %s", dirname,
const_str("string_save_compress_command"), zipbasename);
for(i=0;i<files->len;i++)
{
strcat(buf, " ");
strcat(buf, ((GString*)g_ptr_array_index(files, i))->str);
}
strcat(buf, "; popd 1> /dev/null");
file_my_system(buf);
sprintf(buf, "rm -rf %s/%s*", dirname, basename);
file_my_system(buf);
free_g_string_array(&files);
g_free(basename);
g_free(dirname);
g_free(zipbasename);
}
/** Decompress the specified file. */
void
file_decompress(const gchar *filename)
{
gchar buf[SMALL];
gchar *dirname = g_path_get_dirname(filename),
*basename = g_path_get_basename(filename);
sprintf(buf, "pushd %s 1> /dev/null; %s %s", dirname,
const_str("string_save_uncompress_command"), basename);
file_my_system(buf);
g_free(dirname);
}

View File

@ -14,8 +14,14 @@ file_find_support_file (const gchar *filename);
gboolean
file_get_next_opt_line(FILE *fil, gchar *opt_name, gchar *opt_value);
void
file_load_opt_file(const gchar *filename, OptionList *optionlist);
void
file_save_opt_file(const gchar *filename, OptionList *optionlist);
GPtrArray*
file_dir_get_contents(const gchar *dir_name, const gchar *prefix);
file_dir_get_contents(const gchar *dir_name, const gchar *prefix, const gchar *suffix);
void
file_get_player_names(gint number_of_names);
@ -23,26 +29,34 @@ file_get_player_names(gint number_of_names);
gboolean
file_my_fopen(const gchar *filename, gchar *bits, FILE **fil, gboolean abort_program);
void
file_get_definitions_dir(gchar *dir);
void
file_write_opt_names(gchar opt_names[][50], gchar conf_file_names[][100]);
void
file_write_user_opt_names(gchar user_opt_names[][50],
gchar player_list_att_names[][PLAYER_LIST_ATTRIBUTE_END][50]);
const gchar*
file_get_definitions_dir(void);
void
file_load_conf_files(void);
void
file_save_conf(void);
void
file_load_user_conf_file(User *user);
void
file_load_constants_file(const gchar* file_name);
file_check_home_dir(void);
void
file_check_home_dir_copy_conf_files(void);
void
file_check_home_dir_copy_definition_files(void);
gboolean
file_my_system(const gchar *command);
const gchar*
file_get_first_support_dir(void);
void
file_compress_files(const gchar *destfile, const gchar *prefix);
void
file_decompress(const gchar *filename);
#endif

View File

@ -9,6 +9,29 @@
#include "team.h"
#include "variables.h"
/** Return a fixture with default values. */
Fixture
fixture_new(void)
{
gint i;
Fixture new;
new.clid = new.round = -1;
new.replay_number = 0;
new.week_number = new.week_round_number = -1;
new.teams[0] = new.teams[1] = NULL;
for(i=0;i<3;i++)
new.result[0][i] = new.result[1][i] = 0;
new.home_advantage = 1;
new.second_leg = 0;
new.decisive = 0;
new.attendance = -1;
return new;
}
/** Write the fixtures for the given league
at the beginning of a new season.
@param league The league we write the fixtures for. */
@ -1004,3 +1027,19 @@ fixture_get_league_matches(const Team *tm1, const Team *tm2)
return matches;
}
/** Return the index of the fixture in the fixtures array. */
gint
fixture_get_index(const Fixture *fix)
{
gint i;
const GArray *fixtures = league_cup_get_fixtures(fix->clid);
for(i=0;i<fixtures->len;i++)
if(fix == &g_array_index(fixtures, Fixture, i))
return i;
g_warning("fixture_get_index: fixture not found.\n");
return -1;
}

View File

@ -12,6 +12,9 @@ enum FixtureCompare
FIXTURE_COMPARE_END
};
Fixture
fixture_new(void);
void
fixture_write_league_fixtures(League *league);
@ -109,4 +112,7 @@ fixture_get_league_matches(const Team *tm1, const Team *tm2);
GPtrArray*
fixture_get_coming(const Team *tm);
gint
fixture_get_index(const Fixture *fix);
#endif

View File

@ -11,23 +11,31 @@ free_memory(void)
{
free_variables();
free_country();
free_users();
free_users(FALSE);
free_live_game(&live_game_temp);
free_support_dirs();
}
/** Free the users array. */
void
free_users(void)
free_users(gboolean reset)
{
gint i;
if(users == NULL)
{
if(reset)
users = g_array_new(FALSE, FALSE, sizeof(User));
return;
}
for(i=0;i<users->len;i++)
free_user(&usr(i));
free_g_array(&users);
if(reset)
users = g_array_new(FALSE, FALSE, sizeof(User));
}
/** Free the memory the user occupies.
@ -129,9 +137,9 @@ free_country(void)
for(i=0;i<3;i++)
free_g_string(strings[i]);
free_leagues_array(&ligs);
free_leagues_array(&ligs, FALSE);
free_cups_array(&cps);
free_cups_array(&cps, FALSE);
}
/**
@ -139,17 +147,24 @@ free_country(void)
@param leagues The pointer to the array we free.
*/
void
free_leagues_array(GArray **leagues)
free_leagues_array(GArray **leagues, gboolean reset)
{
gint i;
if(*leagues == NULL)
{
if(reset)
*leagues = g_array_new(FALSE, FALSE, sizeof(League));
return;
}
for(i=0;i<(*leagues)->len;i++)
free_league(&g_array_index(*leagues, League, i));
free_g_array(leagues);
if(reset)
*leagues = g_array_new(FALSE, FALSE, sizeof(League));
}
/**
@ -237,17 +252,24 @@ free_player(Player *pl)
@param cups The pointer to the array we free.
*/
void
free_cups_array(GArray **cups)
free_cups_array(GArray **cups, gboolean reset)
{
gint i;
if(*cups == NULL)
{
if(reset)
*cups = g_array_new(FALSE, FALSE, sizeof(Cup));
return;
}
for(i=0;i<(*cups)->len;i++)
free_cup(&g_array_index(*cups, Cup, i));
free_g_array(cups);
if(reset)
*cups = g_array_new(FALSE, FALSE, sizeof(Cup));
}
/**
@ -330,6 +352,8 @@ free_variables(void)
free_option_list(&options, FALSE);
free_option_list(&constants, FALSE);
free_g_string(&save_file);
}
/**
@ -388,3 +412,22 @@ free_g_ptr_array(GPtrArray **array)
*array = NULL;
}
/** Free the glist containing the support directories. */
void
free_support_dirs(void)
{
GList *elem = support_directories;
if(elem == NULL)
return;
while(elem)
{
g_free ((gchar*)elem->data);
elem = elem->next;
}
g_list_free(support_directories);
support_directories = NULL;
}

View File

@ -22,7 +22,7 @@ void
free_memory(void);
void
free_users(void);
free_users(gboolean reset);
void
free_user(User *user);
@ -31,7 +31,7 @@ void
free_country(void);
void
free_leagues_array(GArray **leagues);
free_leagues_array(GArray **leagues, gboolean reset);
void
free_league(League *league);
@ -43,7 +43,7 @@ void
free_team(Team *team);
void
free_cups_array(GArray **cups);
free_cups_array(GArray **cups, gboolean reset);
void
free_cup(Cup *cup);
@ -72,4 +72,7 @@ free_option_list(OptionList *optionlist, gboolean reset);
void
free_event(Event *event);
void
free_support_dirs(void);
#endif

View File

@ -709,204 +709,6 @@ game_decrease_fitness(const Fixture *fix)
}
}
/** Assemble some stats like ball possession or shots
on goal.
@param live_game The pointer to the match.
@see #LiveGameStats */
void
game_create_stats(gpointer live_game)
{
LiveGame *match = (LiveGame*)live_game;
gint i, possession[2] = {0, 0}, reg_goals[2] = {0, 0};
LiveGameStats *stat = &match->stats;
game_create_stats_players(live_game);
for(i=0;i<LIVE_GAME_STAT_VALUE_END;i++)
stat->values[0][i] =
stat->values[1][i] = 0;
for(i=0;i<2;i++)
stat->values[i][LIVE_GAME_STAT_VALUE_GOALS_REGULAR] =
math_sum_int_array(match->fix->result[i], 2);
for(i=0;i<match->units->len;i++)
{
if(g_array_index(match->units, LiveGameUnit, i).event.type ==
LIVE_GAME_EVENT_PENALTIES)
break;
if(g_array_index(match->units, LiveGameUnit, i).minute != -1)
possession[g_array_index(match->units, LiveGameUnit, i).possession]++;
if(g_array_index(match->units, LiveGameUnit, i).event.type == LIVE_GAME_EVENT_SCORING_CHANCE ||
g_array_index(match->units, LiveGameUnit, i).event.type == LIVE_GAME_EVENT_FREE_KICK)
stat->values[g_array_index(match->units, LiveGameUnit, i).possession][LIVE_GAME_STAT_VALUE_SHOTS]++;
else if(g_array_index(match->units, LiveGameUnit, i).event.type == LIVE_GAME_EVENT_PENALTY)
stat->values[g_array_index(match->units, LiveGameUnit, i).possession]
[LIVE_GAME_STAT_VALUE_PENALTIES]++;
else if(g_array_index(match->units, LiveGameUnit, i).event.type == LIVE_GAME_EVENT_INJURY)
stat->values[g_array_index(match->units, LiveGameUnit, i).event.values[LIVE_GAME_EVENT_VALUE_TEAM]]
[LIVE_GAME_STAT_VALUE_INJURIES]++;
else if(g_array_index(match->units, LiveGameUnit, i).event.type == LIVE_GAME_EVENT_FOUL ||
g_array_index(match->units, LiveGameUnit, i).event.type == LIVE_GAME_EVENT_FOUL_YELLOW ||
g_array_index(match->units, LiveGameUnit, i).event.type == LIVE_GAME_EVENT_FOUL_RED ||
g_array_index(match->units, LiveGameUnit, i).event.type == LIVE_GAME_EVENT_FOUL_RED_INJURY)
{
stat->values[g_array_index(match->units, LiveGameUnit, i).event.values[LIVE_GAME_EVENT_VALUE_TEAM]]
[LIVE_GAME_STAT_VALUE_FOULS]++;
if(g_array_index(match->units, LiveGameUnit, i).event.type == LIVE_GAME_EVENT_FOUL_YELLOW)
stat->values[g_array_index(match->units, LiveGameUnit, i).
event.values[LIVE_GAME_EVENT_VALUE_TEAM]][LIVE_GAME_STAT_VALUE_CARDS]++;
}
else if(g_array_index(match->units, LiveGameUnit, i).event.type == LIVE_GAME_EVENT_SEND_OFF)
stat->values[g_array_index(match->units, LiveGameUnit, i).event.values[LIVE_GAME_EVENT_VALUE_TEAM]]
[LIVE_GAME_STAT_VALUE_REDS]++;
else if(g_array_index(match->units, LiveGameUnit, i).event.type == LIVE_GAME_EVENT_GOAL &&
g_array_index(match->units, LiveGameUnit, i - 1).event.type != LIVE_GAME_EVENT_PENALTY)
reg_goals[g_array_index(match->units, LiveGameUnit, i).
event.values[LIVE_GAME_EVENT_VALUE_TEAM]]++;
}
for(i=0;i<2;i++)
{
stat->values[i][LIVE_GAME_STAT_VALUE_POSSESSION] =
(gint)rint((gfloat)possession[i] / (gfloat)(possession[0] + possession[1]) * 100);
stat->values[i][LIVE_GAME_STAT_VALUE_SHOT_PERCENTAGE] =
(stat->values[i][LIVE_GAME_STAT_VALUE_SHOTS] > 0) ?
(gint)rint(((gfloat)reg_goals[i] / (gfloat)stat->values[i][LIVE_GAME_STAT_VALUE_SHOTS])
* 100) : 0;
}
/*d*/
printf("goals reg\t %d \t %d\n", stat->values[0][LIVE_GAME_STAT_VALUE_GOALS_REGULAR],
stat->values[1][LIVE_GAME_STAT_VALUE_GOALS_REGULAR]);
printf("shots\t %d \t %d\n", stat->values[0][LIVE_GAME_STAT_VALUE_SHOTS],
stat->values[1][LIVE_GAME_STAT_VALUE_SHOTS]);
printf("shotperc\t %d%% \t %d%%\n", stat->values[0][LIVE_GAME_STAT_VALUE_SHOT_PERCENTAGE],
stat->values[1][LIVE_GAME_STAT_VALUE_SHOT_PERCENTAGE]);
printf("poss\t %d%% \t %d%%\n", stat->values[0][LIVE_GAME_STAT_VALUE_POSSESSION],
stat->values[1][LIVE_GAME_STAT_VALUE_POSSESSION]);
printf("pen.\t %d \t %d\n", stat->values[0][LIVE_GAME_STAT_VALUE_PENALTIES],
stat->values[1][LIVE_GAME_STAT_VALUE_PENALTIES]);
printf("fouls\t %d \t %d\n", stat->values[0][LIVE_GAME_STAT_VALUE_FOULS],
stat->values[1][LIVE_GAME_STAT_VALUE_FOULS]);
printf("cards\t %d \t %d\n", stat->values[0][LIVE_GAME_STAT_VALUE_CARDS],
stat->values[1][LIVE_GAME_STAT_VALUE_CARDS]);
printf("reds\t %d \t %d\n", stat->values[0][LIVE_GAME_STAT_VALUE_REDS],
stat->values[1][LIVE_GAME_STAT_VALUE_REDS]);
printf("inj.\t %d \t %d\n", stat->values[0][LIVE_GAME_STAT_VALUE_INJURIES],
stat->values[1][LIVE_GAME_STAT_VALUE_INJURIES]);
}
/** Create arrays containing the names of the
goal scorers and sent off and injured players.
@param live_game The live game we examine. */
void
game_create_stats_players(gpointer live_game)
{
gint i, j;
LiveGame *match = (LiveGame*)live_game;
LiveGameStats *stats = &match->stats;
gint limit = const_int("int_team_max_players");
gint scorer_ids[2][limit];
gint cnt[2] = {0, 0};
gint team, player, player2, array_index;
gint minute = 0;
gchar buf[SMALL], buf2[SMALL];
GString *new = NULL;
gboolean own_goal;
GPtrArray *players = NULL;
for(i=0;i<limit;i++)
scorer_ids[0][i] = scorer_ids[1][i] = -1;
for(i=0;i<match->units->len;i++)
{
if(g_array_index(match->units, LiveGameUnit, i).event.type == LIVE_GAME_EVENT_PENALTIES)
return;
minute = MAX(minute, g_array_index(match->units, LiveGameUnit, i).minute);
team = g_array_index(match->units, LiveGameUnit, i).event.values[LIVE_GAME_EVENT_VALUE_TEAM];
player = g_array_index(match->units, LiveGameUnit, i).event.values[LIVE_GAME_EVENT_VALUE_PLAYER];
player2 = g_array_index(match->units, LiveGameUnit, i).event.values[LIVE_GAME_EVENT_VALUE_PLAYER2];
if(g_array_index(match->units, LiveGameUnit, i).event.type == LIVE_GAME_EVENT_GOAL ||
g_array_index(match->units, LiveGameUnit, i).event.type == LIVE_GAME_EVENT_OWN_GOAL)
{
own_goal = (g_array_index(match->units, LiveGameUnit, i).event.type == LIVE_GAME_EVENT_OWN_GOAL);
array_index = (own_goal) ? !team : team;
if(g_array_index(match->units, LiveGameUnit, i - 1).event.type == LIVE_GAME_EVENT_PENALTY)
strcpy(buf2, " (P)");
else if(g_array_index(match->units, LiveGameUnit, i - 1).event.type == LIVE_GAME_EVENT_FREE_KICK)
strcpy(buf2, " (FK)");
else if(g_array_index(match->units, LiveGameUnit, i).event.type == LIVE_GAME_EVENT_OWN_GOAL)
strcpy(buf2, " (OG)");
else
strcpy(buf2, "");
if(query_integer_is_in_array(player + (100 * own_goal), scorer_ids[array_index], 0, limit))
{
for(j=0;j<stats->players[LIVE_GAME_STAT_ARRAY_SCORERS][array_index]->len;j++)
{
if(g_str_has_prefix(((GString*)g_ptr_array_index(
stats->players[LIVE_GAME_STAT_ARRAY_SCORERS][array_index], j))->str,
player_of_id(match->fix->teams[team], player)->name->str))
{
sprintf(buf, "%s %d%s",
((GString*)g_ptr_array_index(
stats->players[LIVE_GAME_STAT_ARRAY_SCORERS][array_index], j))->str,
minute, buf2);
g_string_printf(((GString*)g_ptr_array_index(
stats->players[LIVE_GAME_STAT_ARRAY_SCORERS][array_index], j)),
"%s", buf);
break;
}
if(j == stats->players[LIVE_GAME_STAT_ARRAY_SCORERS][array_index]->len)
g_warning("game_create_stats_scorers: didn't find scorer %d (team %d)\n",
player, team);
}
}
else
{
sprintf(buf, "%s %d%s", player_of_id(match->fix->teams[team], player)->name->str,
minute, buf2);
new = g_string_new(buf);
g_ptr_array_add(stats->players[LIVE_GAME_STAT_ARRAY_SCORERS][array_index], new);
scorer_ids[array_index][cnt[array_index]] = player + (100 * own_goal);
cnt[array_index]++;
}
}
else
{
strcpy(buf, "");
if(g_array_index(match->units, LiveGameUnit, i).event.type == LIVE_GAME_EVENT_INJURY)
{
sprintf(buf, "%s", player_of_id(match->fix->teams[team], player)->name->str);
players = stats->players[LIVE_GAME_STAT_ARRAY_INJURED][team];
}
else if(g_array_index(match->units, LiveGameUnit, i).event.type == LIVE_GAME_EVENT_FOUL_YELLOW)
{
sprintf(buf, "%s", player_of_id(match->fix->teams[team], player2)->name->str);
players = stats->players[LIVE_GAME_STAT_ARRAY_YELLOWS][team];
}
else if(g_array_index(match->units, LiveGameUnit, i).event.type == LIVE_GAME_EVENT_SEND_OFF)
{
sprintf(buf, "%s", player_of_id(match->fix->teams[team], player)->name->str);
players = stats->players[LIVE_GAME_STAT_ARRAY_REDS][team];
}
if(strlen(buf) > 0)
{
new = g_string_new(buf);
g_ptr_array_add(players, new);
}
}
}
}
/** Update the live game stats using the live game unit.
@param live_game_stats Pointer to the live game.
@param live_game_unit The live game unit. */
@ -947,13 +749,15 @@ game_update_stats(gpointer live_game, gconstpointer live_game_unit)
stats->values[unit->event.values[LIVE_GAME_EVENT_VALUE_TEAM]][LIVE_GAME_STAT_VALUE_REDS]++;
game_update_stats_player(live_game, live_game_unit);
}
else if(unit->event.type == LIVE_GAME_EVENT_GOAL)
else if(unit->event.type == LIVE_GAME_EVENT_GOAL ||
unit->event.type == LIVE_GAME_EVENT_OWN_GOAL)
{
if(live_game_unit_before(unit, -1)->event.type != LIVE_GAME_EVENT_PENALTY)
if(live_game_unit_before(unit, -1)->event.type != LIVE_GAME_EVENT_PENALTY &&
unit->event.type != LIVE_GAME_EVENT_OWN_GOAL)
stats->values[unit->event.values[LIVE_GAME_EVENT_VALUE_TEAM]][LIVE_GAME_STAT_VALUE_GOALS_REGULAR]++;
game_update_stats_player(live_game, live_game_unit);
}
for(i=0;i<2;i++)
stats->values[i][LIVE_GAME_STAT_VALUE_SHOT_PERCENTAGE] =
(stats->values[i][LIVE_GAME_STAT_VALUE_SHOTS] > 0) ?

View File

@ -67,12 +67,6 @@ game_decrease_fitness(const Fixture *fix);
gint
game_player_get_ban_duration(void);
void
game_create_stats(gpointer live_game);
void
game_create_stats_players(gpointer live_game);
void
game_update_stats(gpointer live_game, gconstpointer live_game_unit);

View File

@ -62,8 +62,7 @@ game_gui_live_game_show_unit(const LiveGameUnit *unit)
if(unit->event.type == LIVE_GAME_EVENT_START_MATCH)
{
gtk_widget_set_sensitive(button_live_close, FALSE);
if(stat0 != STATUS_SHOW_LAST_MATCH)
gtk_widget_set_sensitive(button_pause, TRUE);
gtk_widget_set_sensitive(button_pause, (stat0 != STATUS_SHOW_LAST_MATCH));
gtk_widget_set_sensitive(button_resume, FALSE);
}
else if(unit->event.type == LIVE_GAME_EVENT_END_MATCH)

View File

@ -1,5 +1,6 @@
#include "cup.h"
#include "league.h"
#include "table.h"
#include "team.h"
#include "variables.h"
@ -29,10 +30,8 @@ league_new(void)
new.fixtures = g_array_new(FALSE, FALSE, sizeof(Fixture));
new.table.name = g_string_new("");
new.table = table_new();
new.table.clid = new.id;
new.table.round = -1;
new.table.elements = g_array_new(FALSE, FALSE, sizeof(TableElement));
new.first_week = new.week_gap = 1;
new.yellow_red = 1000;
@ -110,7 +109,7 @@ league_cup_get_index_from_clid(gint clid)
}
if(index == -1)
g_warning("league_cup_get_index_from_clid: couldn't find league or cup with index %d\n", clid);
g_warning("league_cup_get_index_from_clid: couldn't find league or cup with id %d\n", clid);
return index;
}

View File

@ -37,7 +37,18 @@ live_game_calculate_fixture(Fixture *fix)
{
if(stat0 != STATUS_LIVE_GAME_PAUSE)
{
live_game_reset(fix);
match = (fixture_user_team_involved(fix) != -1) ?
&usr(fixture_user_team_involved(fix)).live_game : &live_game_temp;
show = (fixture_user_team_involved(fix) != -1 &&
option_int("int_opt_user_show_live_game",
&usr(fixture_user_team_involved(fix)).options));
stat2 = fixture_user_team_involved(fix);
if(show && window.live == NULL)
window.live = window_create(WINDOW_LIVE);
live_game_reset(match, fix, TRUE);
game_initialize(fix);
}
else
@ -1145,46 +1156,6 @@ live_game_unit_before(const LiveGameUnit* unit, gint gap)
return NULL;
}
/** Free the live game variable before we begin a new live game.
@param fix The fixture we'll show. */
void
live_game_reset(Fixture *fix)
{
gint i;
match = (fixture_user_team_involved(fix) != -1) ?
&usr(fixture_user_team_involved(fix)).live_game : &live_game_temp;
show = (fixture_user_team_involved(fix) != -1 &&
option_int("int_opt_user_show_live_game",
&usr(fixture_user_team_involved(fix)).options));
stat2 = fixture_user_team_involved(fix);
if(show && window.live == NULL)
window.live = window_create(WINDOW_LIVE);
free_live_game(match);
unis = g_array_new(FALSE, FALSE, sizeof(LiveGameUnit));
for(i=0;i<LIVE_GAME_STAT_ARRAY_END;i++)
{
match->stats.players[0][i] = g_ptr_array_new();
match->stats.players[1][i] = g_ptr_array_new();
}
for(i=0;i<LIVE_GAME_STAT_VALUE_END;i++)
match->stats.values[0][i] =
match->stats.values[1][i] = 0;
match->fix = fix;
match->subs_left[0] = match->subs_left[1] = 3;
match->stadium_event = -1;
if(fix->home_advantage)
match->home_advantage =
math_rnd(const_float("float_game_home_advantage_lower"),
const_float("float_game_home_advantage_upper"));
}
/** Generate commentary for the live game event in the unit
and show the unit in the live game window.
@param unit The unit we comment. */
@ -1558,3 +1529,39 @@ live_game_set_match(LiveGame *live_game)
{
match = live_game;
}
/** Reset the live game variable before we begin a new live game.
@param live_game The pointer to the live game.
@param fix The fixture we'll show.
@param free Whether or not to free the variable before resetting. */
void
live_game_reset(LiveGame *live_game, Fixture *fix, gboolean free_variable)
{
gint i;
if(free_variable)
free_live_game(live_game);
live_game->units = g_array_new(FALSE, FALSE, sizeof(LiveGameUnit));
for(i=0;i<LIVE_GAME_STAT_ARRAY_END;i++)
{
live_game->stats.players[0][i] = g_ptr_array_new();
live_game->stats.players[1][i] = g_ptr_array_new();
}
for(i=0;i<LIVE_GAME_STAT_VALUE_END;i++)
live_game->stats.values[0][i] =
live_game->stats.values[1][i] = 0;
live_game->fix = fix;
live_game->subs_left[0] = live_game->subs_left[1] = 3;
live_game->stadium_event = -1;
if(fix != NULL && fix->home_advantage)
live_game->home_advantage =
math_rnd(const_float("float_game_home_advantage_lower"),
const_float("float_game_home_advantage_upper"));
else
live_game->home_advantage = 0;
}

View File

@ -74,7 +74,7 @@ gboolean
query_live_game_second_yellow(gint team, gint player);
void
live_game_reset(Fixture *fix);
live_game_reset(LiveGame *live_game, Fixture *fix, gboolean free_variable);
gint
live_game_unit_get_minute(const LiveGameUnit *unit);

View File

@ -0,0 +1,148 @@
#include "file.h"
#include "gui.h"
#include "load_save.h"
#include "option.h"
#include "support.h"
#include "variables.h"
#include "xml_loadsave_misc.h"
#include "xml_loadsave_cup.h"
#include "xml_loadsave_league.h"
#include "xml_loadsave_users.h"
#include "xml_loadsave_transfers.h"
#include "xml.h"
#define PROGRESS_MAX 6
/** Save the game to the specified file. */
void
load_save_save_game(const gchar *filename)
{
gint i;
gchar buf[SMALL];
gchar *prefix = (g_str_has_suffix(filename, const_str("string_save_suffix"))) ?
g_strndup(filename, strlen(filename) - strlen(const_str("string_save_suffix"))) :
g_strdup(filename);
gchar *fullname = (g_str_has_suffix(filename, const_str("string_save_suffix"))) ?
g_strdup(filename) :
g_strdup_printf("%s%s", filename, const_str("string_save_suffix"));
g_string_printf(save_file, "%s", fullname);
if(g_file_test(fullname, G_FILE_TEST_EXISTS))
{
/*todo: replace with g_remove*/
sprintf(buf, "rm -rf %s", fullname);
file_my_system(buf);
}
gui_show_progress(0, "Saving miscellaneous...");
xml_loadsave_misc_write(prefix);
gui_show_progress(
((PROGRESS_MAX * gtk_progress_bar_get_fraction(
GTK_PROGRESS_BAR(lookup_widget(window.progress, "progressbar")))) + 1) / PROGRESS_MAX,
"Saving leagues...");
for(i=0;i<ligs->len;i++)
xml_loadsave_league_write(prefix, &lig(i));
gui_show_progress(
((PROGRESS_MAX * gtk_progress_bar_get_fraction(
GTK_PROGRESS_BAR(lookup_widget(window.progress, "progressbar")))) + 1) / PROGRESS_MAX,
"Saving cups...");
for(i=0;i<cps->len;i++)
xml_loadsave_cup_write(prefix, &cp(i));
gui_show_progress(
((PROGRESS_MAX * gtk_progress_bar_get_fraction(
GTK_PROGRESS_BAR(lookup_widget(window.progress, "progressbar")))) + 1) / PROGRESS_MAX,
"Saving users...");
xml_loadsave_users_write(prefix);
gui_show_progress(
((PROGRESS_MAX * gtk_progress_bar_get_fraction(
GTK_PROGRESS_BAR(lookup_widget(window.progress, "progressbar")))) + 1) / PROGRESS_MAX,
"Saving transfer list...");
xml_loadsave_transfers_write(prefix);
gui_show_progress(
((PROGRESS_MAX * gtk_progress_bar_get_fraction(
GTK_PROGRESS_BAR(lookup_widget(window.progress, "progressbar")))) + 1) / PROGRESS_MAX,
"Compressing savegame...");
sprintf(buf, "%s___", prefix);
file_compress_files(fullname, buf);
gui_show_progress(1, "Done.");
g_free(prefix);
g_free(fullname);
gui_show_progress(-1, "");
}
/** Load the game from the specified file. */
void
load_save_load_game(const gchar* filename)
{
gchar buf[SMALL];
gchar *basename = g_path_get_basename(filename),
*dirname = g_path_get_dirname(filename);
gchar *prefix = g_strndup(basename, strlen(basename) - strlen(const_str("string_save_suffix")));
gui_show_progress(0, "Uncompressing savegame...");
file_decompress(filename);
gui_show_progress(
((PROGRESS_MAX * gtk_progress_bar_get_fraction(
GTK_PROGRESS_BAR(lookup_widget(window.progress, "progressbar")))) + 1) / PROGRESS_MAX,
"Loading miscellaneous...");
xml_loadsave_misc_read(dirname, prefix);
gui_show_progress(
((PROGRESS_MAX * gtk_progress_bar_get_fraction(
GTK_PROGRESS_BAR(lookup_widget(window.progress, "progressbar")))) + 1) / PROGRESS_MAX,
"Loading leagues...");
xml_load_leagues(dirname, prefix);
gui_show_progress(
((PROGRESS_MAX * gtk_progress_bar_get_fraction(
GTK_PROGRESS_BAR(lookup_widget(window.progress, "progressbar")))) + 1) / PROGRESS_MAX,
"Loading cups...");
xml_load_cups(dirname, prefix);
gui_show_progress(
((PROGRESS_MAX * gtk_progress_bar_get_fraction(
GTK_PROGRESS_BAR(lookup_widget(window.progress, "progressbar")))) + 1) / PROGRESS_MAX,
"Loading users...");
xml_load_users(dirname, prefix);
gui_show_progress(
((PROGRESS_MAX * gtk_progress_bar_get_fraction(
GTK_PROGRESS_BAR(lookup_widget(window.progress, "progressbar")))) + 1) / PROGRESS_MAX,
"Loading transfer list...");
xml_load_transfers(dirname, prefix);
gui_show_progress(1, "Done.");
sprintf(buf, "rm -rf %s/%s___*", dirname, prefix);
file_my_system(buf);
g_free(basename);
g_free(dirname);
g_free(prefix);
g_string_printf(save_file, "%s", filename);
gui_show_progress(-1, "");
}

View File

@ -0,0 +1,13 @@
#ifndef LOAD_SAVE_H
#define LOAD_SAVE_H
#include "bygfoot.h"
void
load_save_save_game(const gchar* filename);
void
load_save_load_game(const gchar* filename);
#endif

View File

@ -8,6 +8,7 @@
#include "misc_callbacks.h"
#include "file.h"
#include "free.h"
#include "live_game.h"
#include "main.h"
#include "transfer_struct.h"
#include "variables.h"
@ -27,14 +28,16 @@ main_init_variables(void)
window.main = window.startup =
window.live = window.warning = window.progress = window.digits =
window.stadium = window.job_offer = window.yesno =
window.options = window.font_sel = window.contract =
window.options = window.font_sel = window.file_sel = window.contract =
window.menu_player = window.user_management = NULL;
live_game_temp.units = NULL;
live_game_reset(&live_game_temp, NULL, FALSE);
users = g_array_new(FALSE, FALSE, sizeof(User));
transfer_list = g_array_new(FALSE, FALSE, sizeof(Transfer));
save_file = g_string_new("");
constants.list = options.list = NULL;
constants.datalist = options.datalist = NULL;
@ -60,14 +63,19 @@ main_init(gint argc, gchar *argv[])
gchar *pwd = g_get_current_dir();
/* initialize the random nr generator */
srandom((unsigned)time(NULL));
rand_generator = g_rand_new();
support_directories = NULL;
file_add_support_directory_recursive(PACKAGE_DATA_DIR "/" PACKAGE "/support_files");
sprintf(buf, "%s/.bygfoot", g_get_home_dir());
sprintf(buf, "%s/%s", g_get_home_dir(), HOMEDIRNAME);
file_add_support_directory_recursive(buf);
sprintf(buf, "%s/support_files", pwd);
g_free(pwd);
file_add_support_directory_recursive(buf);
file_check_home_dir();
main_init_variables();
}

View File

@ -1,22 +1,23 @@
#include "maths.h"
#include "misc.h"
#include "variables.h"
/**
Generate a Gauss-distributed (pseudo)random number.
"By Box and Muller, and recommended by Knuth".
@return A Gauss-distributed random number.
*/
gfloat
gdouble
math_gaussrand(void)
{
static gfloat V1, V2, S;
static gdouble V1, V2, S;
static gint phase = 0;
gfloat X;
gdouble X;
if(phase == 0) {
do {
gfloat U1 = (gfloat)rand() / RAND_MAX;
gfloat U2 = (gfloat)rand() / RAND_MAX;
gdouble U1 = g_rand_double(rand_generator);
gdouble U2 = g_rand_double(rand_generator);
V1 = 2 * U1 - 1;
V2 = 2 * U2 - 1;
@ -42,13 +43,13 @@ math_gaussrand(void)
@param upper Upper cutoff boundary.
@return A Gauss-distributed number
*/
gfloat
math_gauss_dist(gfloat lower, gfloat upper)
gdouble
math_gauss_dist(gdouble lower, gdouble upper)
{
gfloat result;
gdouble result;
result = (gfloat)(upper - lower) / 6 * math_gaussrand()
+ (gfloat)(upper + lower) / 2;
result = (upper - lower) / 6 * math_gaussrand()
+ (upper + lower) / 2;
if(result < lower)
result = lower;

View File

@ -8,15 +8,15 @@
/**
Macros for random number generation (#rnd for float, #rndi and #gauss_disti for integer).
*/
#define math_rnd(lower,upper) ((gfloat)random()/(gfloat)0x7fffffff*((upper)-(lower))+(lower))
#define math_rndi(lower,upper) ((gint)rint( math_rnd((gfloat)(lower) - 0.499, (gfloat)(upper) + 0.499) ))
#define math_rnd(lower,upper) g_rand_double_range(rand_generator, lower, upper)
#define math_rndi(lower,upper) g_rand_int_range(rand_generator, lower, upper + 1)
#define math_gauss_disti(lower, upper) ((gint)rint( math_gauss_dist((gfloat)lower - 0.499, (gfloat)upper + 0.499)))
gfloat
gdouble
math_gaussrand(void);
gfloat
math_gauss_dist(gfloat lower, gfloat upper);
gdouble
math_gauss_dist(gdouble lower, gdouble upper);
gint
math_get_place(gint value, gint place);

View File

@ -20,8 +20,6 @@ misc_print_error(GError **error, gboolean abort_program)
sprintf(buf, "%s", (*error)->message);
g_warning("error message: %s\n", buf);
/*d*/
/* show_popup_window(buf); */
g_error_free(*error);
*error = NULL;
@ -207,3 +205,52 @@ misc_float_compare(gfloat first, gfloat second)
return 0;
}
/** Remove some of the first or last characters from src and copy
the rest to dest; no error-checking is done. */
void
misc_truncate_string(const gchar *src, gchar *dest, gint number_of_chars)
{
gint i;
gint num = ABS(number_of_chars);
if(number_of_chars >= 0)
{
strncpy(dest, src, strlen(src) - num);
dest[strlen(src) - num] = '\0';
return;
}
for(i=0;i<strlen(src);i++)
if(i >= num)
dest[i - num] = src[i];
dest[i - num] = '\0';
}
/** Find out whether the first string contains the second string. */
gboolean
misc_string_contains(const gchar *string, const gchar *text)
{
gint i, j;
gint lens = strlen(string),
lent = strlen(text);
if(lent > lens)
return FALSE;
if(lent == lens)
return (strcmp(text, string) == 0);
for(i=0;i<lens - lent + 1;i++)
{
for(j=0;j<lent;j++)
if(string[i + j] != text[j])
break;
if(j == lent)
return TRUE;
}
return FALSE;
}

View File

@ -30,4 +30,10 @@ misc_int_compare(gint first, gint second);
gint
misc_float_compare(gfloat first, gfloat second);
void
misc_truncate_string(const gchar *src, gchar *dest, gint number_of_chars);
gboolean
misc_string_contains(const gchar *string, const gchar *text);
#endif

View File

@ -1,7 +1,10 @@
#include "callbacks.h"
#include "callback_func.h"
#include "game.h"
#include "game_gui.h"
#include "gui.h"
#include "live_game.h"
#include "load_save.h"
#include "main.h"
#include "misc_callback_func.h"
#include "misc_callbacks.h"
@ -70,8 +73,9 @@ on_fsel_window_delete_event (GtkWidget *widget,
GdkEvent *event,
gpointer user_data)
{
on_button_fsel_cancel_clicked(NULL, NULL);
return FALSE;
return FALSE;
}
@ -79,7 +83,24 @@ void
on_button_fsel_ok_clicked (GtkButton *button,
gpointer user_data)
{
const gchar *filename =
gtk_file_selection_get_filename(GTK_FILE_SELECTION(window.file_sel));
if(stat1 == STATUS_SAVE_GAME)
load_save_save_game(filename);
else if(stat1 == STATUS_LOAD_GAME)
{
if(!g_file_test(filename, G_FILE_TEST_EXISTS))
game_gui_show_warning("File not found.");
else
{
load_save_load_game(filename);
cur_user = 0;
on_button_back_to_main_clicked(NULL, NULL);
}
}
window_destroy(&window.file_sel, FALSE);
}
@ -87,6 +108,7 @@ void
on_button_fsel_cancel_clicked (GtkButton *button,
gpointer user_data)
{
window_destroy(&window.file_sel, FALSE);
}

View File

@ -447,9 +447,9 @@ create_window_startup (void)
}
GtkWidget*
create_fsel_window (void)
create_window_file_sel (void)
{
GtkWidget *fsel_window;
GtkWidget *window_file_sel;
GtkWidget *button_fsel_ok;
GtkWidget *button_fsel_cancel;
GtkAccelGroup *accel_group;
@ -459,11 +459,12 @@ create_fsel_window (void)
accel_group = gtk_accel_group_new ();
fsel_window = gtk_file_selection_new (_("Choose file"));
gtk_container_set_border_width (GTK_CONTAINER (fsel_window), 10);
gtk_window_set_position (GTK_WINDOW (fsel_window), GTK_WIN_POS_CENTER);
window_file_sel = gtk_file_selection_new (_("Choose file"));
gtk_container_set_border_width (GTK_CONTAINER (window_file_sel), 10);
gtk_window_set_position (GTK_WINDOW (window_file_sel), GTK_WIN_POS_CENTER);
gtk_window_set_modal (GTK_WINDOW (window_file_sel), TRUE);
button_fsel_ok = GTK_FILE_SELECTION (fsel_window)->ok_button;
button_fsel_ok = GTK_FILE_SELECTION (window_file_sel)->ok_button;
gtk_widget_show (button_fsel_ok);
GTK_WIDGET_SET_FLAGS (button_fsel_ok, GTK_CAN_DEFAULT);
gtk_tooltips_set_tip (tooltips, button_fsel_ok, _("Return"), NULL);
@ -471,7 +472,7 @@ create_fsel_window (void)
GDK_Return, 0,
GTK_ACCEL_VISIBLE);
button_fsel_cancel = GTK_FILE_SELECTION (fsel_window)->cancel_button;
button_fsel_cancel = GTK_FILE_SELECTION (window_file_sel)->cancel_button;
gtk_widget_show (button_fsel_cancel);
GTK_WIDGET_SET_FLAGS (button_fsel_cancel, GTK_CAN_DEFAULT);
gtk_tooltips_set_tip (tooltips, button_fsel_cancel, _("Esc"), NULL);
@ -479,7 +480,7 @@ create_fsel_window (void)
GDK_Escape, 0,
GTK_ACCEL_VISIBLE);
g_signal_connect ((gpointer) fsel_window, "delete_event",
g_signal_connect ((gpointer) window_file_sel, "delete_event",
G_CALLBACK (on_fsel_window_delete_event),
NULL);
g_signal_connect ((gpointer) button_fsel_ok, "clicked",
@ -490,14 +491,14 @@ create_fsel_window (void)
NULL);
/* Store pointers to all widgets, for use by lookup_widget(). */
GLADE_HOOKUP_OBJECT_NO_REF (fsel_window, fsel_window, "fsel_window");
GLADE_HOOKUP_OBJECT_NO_REF (fsel_window, button_fsel_ok, "button_fsel_ok");
GLADE_HOOKUP_OBJECT_NO_REF (fsel_window, button_fsel_cancel, "button_fsel_cancel");
GLADE_HOOKUP_OBJECT_NO_REF (fsel_window, tooltips, "tooltips");
GLADE_HOOKUP_OBJECT_NO_REF (window_file_sel, window_file_sel, "window_file_sel");
GLADE_HOOKUP_OBJECT_NO_REF (window_file_sel, button_fsel_ok, "button_fsel_ok");
GLADE_HOOKUP_OBJECT_NO_REF (window_file_sel, button_fsel_cancel, "button_fsel_cancel");
GLADE_HOOKUP_OBJECT_NO_REF (window_file_sel, tooltips, "tooltips");
gtk_window_add_accel_group (GTK_WINDOW (fsel_window), accel_group);
gtk_window_add_accel_group (GTK_WINDOW (window_file_sel), accel_group);
return fsel_window;
return window_file_sel;
}
GtkWidget*

View File

@ -3,7 +3,7 @@
*/
GtkWidget* create_window_startup (void);
GtkWidget* create_fsel_window (void);
GtkWidget* create_window_file_sel (void);
GtkWidget* create_window_font_sel (void);
GtkWidget* create_window_live (void);
GtkWidget* create_help_window (void);

View File

@ -389,7 +389,7 @@ option_gui_write_options(void)
{
if(i == ENTRY_OPT_CONSTANTS &&
strcmp(gtk_entry_get_text(entry_widgets[i]), opt_str("string_opt_constants_file" )) != 0)
file_load_constants_file(gtk_entry_get_text(entry_widgets[i]));
file_load_opt_file(gtk_entry_get_text(entry_widgets[i]), &constants);
g_string_printf(entry_options[i], "%s", gtk_entry_get_text(entry_widgets[i]));
}

View File

@ -1,6 +1,13 @@
#ifndef OPTION_STRUCT_H
#define OPTION_STRUCT_H
/** A struct representing an option or a constant. */
typedef struct
{
GString *name, *string_value;
gint value;
} Option;
/** An array of name-value pairs with an associated keyed data list for
quick access. */
typedef struct

View File

@ -9,6 +9,7 @@
#include "options_interface.h"
#include "option_gui.h"
#include "support.h"
#include "user.h"
#include "variables.h"
#include "window.h"
@ -16,8 +17,33 @@ void
on_button_options_ok_clicked (GtkButton *button,
gpointer user_data)
{
gboolean save_global =
gtk_toggle_button_get_active(
GTK_TOGGLE_BUTTON(lookup_widget(window.options, "checkbutton_save_global"))),
save_user =
gtk_toggle_button_get_active(
GTK_TOGGLE_BUTTON(lookup_widget(window.options, "checkbutton_save_user")));
const gchar *conf_dir = file_get_first_support_dir();
gchar buf[SMALL];
option_gui_write_options();
if(save_global)
{
sprintf(buf, "%s/bygfoot.conf", conf_dir);
file_save_opt_file(buf, &options);
}
if(save_user)
{
if(strcmp(current_user.name->str, "NONAME") == 0)
sprintf(buf, "%s/bygfoot_user.conf", conf_dir);
else
sprintf(buf, "%s/bygfoot_%s.conf", conf_dir, current_user.name->str);
file_save_opt_file(buf, &current_user.options);
}
window_destroy(&window.options, TRUE);
}
@ -45,6 +71,6 @@ on_button_reload_constants_clicked (GtkButton *button,
const gchar *constants_file =
gtk_entry_get_text(GTK_ENTRY(lookup_widget(window.options, "entry_constants_file")));
file_load_constants_file(constants_file);
file_load_opt_file(constants_file, &constants);
}

View File

@ -54,7 +54,6 @@ player_new(Team *tm, gfloat average_skill)
new.fitness = math_rnd(const_float("float_player_fitness_lower"),
const_float("float_player_fitness_upper"));
new.health = new.recovery = 0;
new.games_goals = g_array_new(FALSE, FALSE, sizeof(PlayerGamesGoals));
new.value = player_assign_value(&new);
new.wage = player_assign_wage(&new);
new.contract = math_rnd(const_float("float_player_contract_lower"),
@ -62,6 +61,7 @@ player_new(Team *tm, gfloat average_skill)
new.lsu = math_rnd(const_float("float_player_lsu_lower"),
const_float("float_player_lsu_upper"));
new.cards = g_array_new(FALSE, FALSE, sizeof(PlayerCard));
new.games_goals = g_array_new(FALSE, FALSE, sizeof(PlayerGamesGoals));
new.team = tm;
new.participation = FALSE;

View File

@ -101,7 +101,7 @@ start_generate_league_teams(void)
void
start_load_cup_teams(void)
{
gint i, j, k;
gint i;
for(i=0;i<cps->len;i++)
if(cp(i).type == CUP_TYPE_INTERNATIONAL)

View File

@ -3,6 +3,20 @@
#include "table.h"
#include "variables.h"
/** Return a newly allocated empty table. */
Table
table_new(void)
{
Table new;
new.name = g_string_new("");
new.clid = -1;
new.round = -1;
new.elements = g_array_new(FALSE, FALSE, sizeof(TableElement));
return new;
}
/** Return a nullified table element.
@param team The team pointer of the element.
@param clid The cup/league id.

View File

@ -5,6 +5,9 @@
#include "fixture_struct.h"
#include "table_struct.h"
Table
table_new(void);
TableElement
table_element_new(Team *team);

View File

@ -361,10 +361,17 @@ team_get_pointers_from_choose_teams(const GArray *choose_teams)
Team*
team_get_pointer_from_ids(gint clid, gint id)
{
if(clid < ID_CUP_START)
return &g_array_index(lig(league_cup_get_index_from_clid(clid)).teams, Team, id);
else
return &g_array_index(cp(league_cup_get_index_from_clid(clid)).teams, Team, id);
gint i;
const GArray *teams = league_cup_get_teams(clid);
for(i=0;i<teams->len;i++)
if(g_array_index(teams, Team, i).id == id)
return &g_array_index(teams, Team, i);
g_warning("team_get_pointer_from_ids: team with clid %d id %d not found.",
clid, id);
return NULL;
}
/** Return the players of the team in a pointer array.

View File

@ -1,6 +1,7 @@
#include "fixture.h"
#include "free.h"
#include "game_gui.h"
#include "live_game.h"
#include "maths.h"
#include "misc.h"
#include "option.h"
@ -14,18 +15,12 @@
User
user_new(void)
{
gint i;
User new;
new.name = g_string_new("NONAME");
new.tm = NULL;
new.live_game.units = NULL;
new.live_game.fix = NULL;
for(i=0;i<LIVE_GAME_STAT_ARRAY_END;i++)
new.live_game.stats.players[i][0] =
new.live_game.stats.players[i][1] = NULL;
live_game_reset(&new.live_game, NULL, FALSE);
new.events = g_array_new(FALSE, FALSE, sizeof(Event));
new.options.list = NULL;

View File

@ -71,15 +71,9 @@ typedef struct
the current and the past week. */
gint money, debt, money_in[2][MON_IN_END],
money_out[2][MON_OUT_END];
/** The attributes shown in the player lists.
@see #PlayerListAttribute
@see #PlayerListAttributeValue */
PlayerListAttribute player_list_attributes[3];
/** The user's scout and physio qualities.
@see #Quality */
gint scout, physio;
/** The font used in treeviews. */
GString *font_name;
/** The variable for the latest user live game. @see #Game */
LiveGame live_game;
} User;

View File

@ -12,6 +12,9 @@
*/
Country country;
/** The array of human players. @see #User */
GArray *users;
/** The season, week and week round numbers.
We keep track of the time in the game with these variables. */
gint season, week, week_round;
@ -50,10 +53,20 @@ gint popups_active;
/** The variable for non-user games (which aren't shown). */
LiveGame live_game_temp;
/** The array of human players. @see #User */
GArray *users;
/** The index of the current user in the #users array. */
gint cur_user;
gint timeout_id;
GRand *rand_generator;
/**
The list of directories the file_find_support_file() function
searches for support files (e.g. pixmaps or text files).
@see file_find_support_file()
@see file_add_support_directory_recursive()
*/
GList *support_directories;
/** The name of the current save file (gets updated when a game is
saved or loaded). */
GString *save_file;

View File

@ -24,14 +24,14 @@ window_show_startup(void)
window_create(WINDOW_STARTUP);
GtkWidget *combo_country =
lookup_widget(window_startup, "combo_country");
gchar country_dir[SMALL];
const gchar *country_dir;
GPtrArray *dir_contents = NULL;
GList *combo_strings = NULL;
gint i;
file_get_definitions_dir(country_dir);
country_dir = file_get_definitions_dir();
dir_contents = file_dir_get_contents((const gchar*)country_dir, "country_");
dir_contents = file_dir_get_contents(country_dir, "country_", "");
for(i=0;i<dir_contents->len;i++)
combo_strings = g_list_append(combo_strings,
@ -42,6 +42,25 @@ window_show_startup(void)
free_g_string_array(&dir_contents);
}
/** Show the file selection window. */
void
window_show_file_sel(void)
{
gchar buf[SMALL];
const gchar *home = g_get_home_dir();
window_create(WINDOW_FILE_SEL);
if(strlen(save_file->str) > 0)
gtk_file_selection_set_filename(GTK_FILE_SELECTION(window.file_sel),
save_file->str);
else
{
sprintf(buf, "%s/%s/saves/", home, HOMEDIRNAME);
gtk_file_selection_set_filename(GTK_FILE_SELECTION(window.file_sel), buf);
}
}
/** Show the options window. */
void
window_show_options(void)
@ -325,6 +344,14 @@ window_create(gint window_type)
wind = window.font_sel;
strcpy(buf, "Select font");
break;
case WINDOW_FILE_SEL:
if(window.file_sel != NULL)
g_warning("window_create: called on already existing window\n");
else
window.file_sel = create_window_file_sel();
wind = window.file_sel;
strcpy(buf, "Select file");
break;
case WINDOW_CONTRACT:
if(window.contract != NULL)
g_warning("window_create: called on already existing window\n");

View File

@ -18,6 +18,7 @@ enum Windows
WINDOW_YESNO,
WINDOW_OPTIONS,
WINDOW_FONT_SEL,
WINDOW_FILE_SEL,
WINDOW_CONTRACT,
WINDOW_USER_MANAGEMENT,
WINDOW_END
@ -35,6 +36,9 @@ window_destroy(GtkWidget **wind, gboolean count_popups);
void
window_show_digits(gchar *text_main, gchar* text1, gint value1, gchar* text2, gint value2);
void
window_show_file_sel(void);
void
window_show_stadium(void);

View File

@ -1,6 +1,13 @@
#### float constants get divided by 10000 and loaded as floats
#### so we write 5000 if we'd like to have 0.5
# commands to compress and uncompress save files
string_save_compress_command zip -q
string_save_uncompress_command unzip -qq
# suffix of compressed files
string_save_suffix .zip
# number of seconds until messages disappear
int_game_gui_message_duration 5