commit
f96b8abc49
204
src/child.c
204
src/child.c
@ -22,120 +22,126 @@
|
||||
volatile sig_atomic_t _child_writer_alive = 0;
|
||||
gboolean _child_writer_dead_warned = 0;
|
||||
|
||||
int child_writer_alive(void) {
|
||||
return _child_writer_alive;
|
||||
int child_writer_alive(void){
|
||||
return _child_writer_alive;
|
||||
}
|
||||
|
||||
int child_writer_dead_handler(void) {
|
||||
if(_child_writer_alive == 0 && _child_writer_dead_warned == 0) {
|
||||
_child_writer_dead_warned = 1;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
if (_child_writer_alive == 0 && _child_writer_dead_warned == 0) {
|
||||
_child_writer_dead_warned = 1;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void child_process_score_writer(int chfd, gchar *score_file) {
|
||||
fd_set rfds;
|
||||
int i;
|
||||
int fd=-1;
|
||||
gchar *buf;
|
||||
size_t sz;
|
||||
sigset_t sset;
|
||||
struct flock lockinfo;
|
||||
gchar *score_file_full = g_strconcat(LOCALSTATEDIR, score_file, NULL);
|
||||
void child_process_score_writer(int chfd, gchar *score_file)
|
||||
{
|
||||
fd_set rfds;
|
||||
int i;
|
||||
int fd=-1;
|
||||
gchar *buf;
|
||||
size_t sz;
|
||||
sigset_t sset;
|
||||
struct flock lockinfo;
|
||||
gchar *score_file_full = g_strconcat(LOCALSTATEDIR, score_file, NULL);
|
||||
|
||||
while(1) {
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(chfd, &rfds);
|
||||
if(select(chfd + 1, &rfds, NULL, NULL, NULL) > 0) {
|
||||
if(read(chfd, &sz, sizeof(sz)) <= 0) {
|
||||
exit(0);
|
||||
}
|
||||
/* block signals before writing, to prevent possible file corruption */
|
||||
sigemptyset(&sset);
|
||||
sigaddset(&sset, SIGHUP);
|
||||
sigaddset(&sset, SIGINT);
|
||||
sigaddset(&sset, SIGQUIT);
|
||||
sigaddset(&sset, SIGTERM);
|
||||
sigprocmask(SIG_BLOCK, &sset, NULL);
|
||||
fd = open(score_file_full, O_WRONLY | O_TRUNC);
|
||||
if(fd != -1) {
|
||||
/* get write lock before writing scores */
|
||||
lockinfo.l_whence = SEEK_SET;
|
||||
lockinfo.l_start = 0;
|
||||
lockinfo.l_len = 0;
|
||||
while (1)
|
||||
{
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(chfd, &rfds);
|
||||
if (select(chfd + 1, &rfds, NULL, NULL, NULL) > 0)
|
||||
{
|
||||
if (read(chfd, &sz, sizeof(sz)) <= 0) {
|
||||
exit(0);
|
||||
}
|
||||
/* block signals before writing, to prevent possible file corruption */
|
||||
sigemptyset(&sset);
|
||||
sigaddset(&sset, SIGHUP);
|
||||
sigaddset(&sset, SIGINT);
|
||||
sigaddset(&sset, SIGQUIT);
|
||||
sigaddset(&sset, SIGTERM);
|
||||
sigprocmask(SIG_BLOCK, &sset, NULL);
|
||||
fd = open(score_file_full, O_WRONLY | O_TRUNC);
|
||||
if (fd != -1) {
|
||||
/* get write lock before writing scores */
|
||||
lockinfo.l_whence = SEEK_SET;
|
||||
lockinfo.l_start = 0;
|
||||
lockinfo.l_len = 0;
|
||||
|
||||
i = 0;
|
||||
while(1) {
|
||||
lockinfo.l_type=F_WRLCK;
|
||||
if(!fcntl(fd, F_SETLK, &lockinfo)) break;
|
||||
if(i >= 3) {
|
||||
close(fd);
|
||||
fd = -1;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
while(sz > 0) {
|
||||
buf=g_malloc(sz);
|
||||
read(chfd, buf, sz);
|
||||
if(fd != -1) {
|
||||
write(fd, buf, sz);
|
||||
}
|
||||
g_free(buf);
|
||||
read(chfd, &sz, sizeof(sz));
|
||||
}
|
||||
i = 0;
|
||||
while (1) {
|
||||
lockinfo.l_type=F_WRLCK;
|
||||
if (!fcntl(fd, F_SETLK, &lockinfo)) {
|
||||
break;
|
||||
}
|
||||
if (i >= 3) {
|
||||
close(fd);
|
||||
fd = -1;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
while (sz > 0) {
|
||||
buf=g_malloc(sz);
|
||||
read(chfd, buf, sz);
|
||||
if (fd != -1) {
|
||||
write(fd, buf, sz);
|
||||
}
|
||||
g_free(buf);
|
||||
read(chfd, &sz, sizeof(sz));
|
||||
}
|
||||
|
||||
if(fd != -1) {
|
||||
close(fd);
|
||||
} else {
|
||||
/* FIXME: here should be some sort of error
|
||||
reporting to parent */
|
||||
}
|
||||
sigprocmask(SIG_UNBLOCK, &sset, NULL);
|
||||
}
|
||||
}
|
||||
if (fd != -1) {
|
||||
close(fd);
|
||||
} else {
|
||||
/* FIXME: here should be some sort of error reporting to parent */
|
||||
}
|
||||
sigprocmask(SIG_UNBLOCK, &sset, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void sigchld_handler(int param) {
|
||||
pid_t ret = waitpid(0, NULL, WNOHANG);
|
||||
static void sigchld_handler(int param)
|
||||
{
|
||||
pid_t ret = waitpid(0, NULL, WNOHANG);
|
||||
|
||||
if(ret > 0) { /* score writer process killed by bastards! */
|
||||
_child_writer_alive = 0;
|
||||
}
|
||||
if (ret > 0) { /* score writer process killed by bastards! */
|
||||
_child_writer_alive = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int child_setup(gchar *score_file) {
|
||||
pid_t pid;
|
||||
struct sigaction sact;
|
||||
int sfds[2];
|
||||
int child_setup(gchar *score_file)
|
||||
{
|
||||
pid_t pid;
|
||||
struct sigaction sact;
|
||||
int sfds[2];
|
||||
|
||||
/* set up SIGCHLD handler, so we can know if our score writer process
|
||||
terminated while we run... */
|
||||
sact.sa_handler = sigchld_handler;
|
||||
sigemptyset(&sact.sa_mask);
|
||||
sact.sa_flags = 0;
|
||||
/* set up SIGCHLD handler, so we can know if our score writer process
|
||||
terminated while we run... */
|
||||
sact.sa_handler = sigchld_handler;
|
||||
sigemptyset(&sact.sa_mask);
|
||||
sact.sa_flags = 0;
|
||||
#ifdef SA_RESTART
|
||||
sact.sa_flags |= SA_RESTART;
|
||||
sact.sa_flags |= SA_RESTART;
|
||||
#endif
|
||||
if(sigaction(SIGCHLD, &sact, NULL) < 0) {
|
||||
printf("cannot setup SIGCHLD handler.\n");
|
||||
return -1;
|
||||
}
|
||||
if(pipe(sfds) == -1) {
|
||||
printf("pipe() failed: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
pid = fork();
|
||||
if(pid == -1) {
|
||||
printf("cannot fork: %s\n", strerror(errno));
|
||||
return -1;
|
||||
} else if(pid == 0) {
|
||||
close(sfds[1]);
|
||||
child_process_score_writer(sfds[0], score_file);
|
||||
}
|
||||
close(sfds[0]);
|
||||
_child_writer_alive = 1;
|
||||
if (sigaction(SIGCHLD, &sact, NULL) < 0) {
|
||||
printf("cannot setup SIGCHLD handler.\n");
|
||||
return -1;
|
||||
}
|
||||
if (pipe(sfds) == -1) {
|
||||
printf("pipe() failed: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
pid = fork();
|
||||
if (pid == -1) {
|
||||
printf("cannot fork: %s\n", strerror(errno));
|
||||
return -1;
|
||||
} else if (pid == 0) {
|
||||
close(sfds[1]);
|
||||
child_process_score_writer(sfds[0], score_file);
|
||||
}
|
||||
close(sfds[0]);
|
||||
_child_writer_alive = 1;
|
||||
|
||||
return sfds[1];
|
||||
return sfds[1];
|
||||
}
|
||||
|
627
src/game.c
627
src/game.c
@ -21,11 +21,11 @@
|
||||
typedef struct _GtkbGameRules GtkbGameRules;
|
||||
|
||||
struct _GtkbGameRules {
|
||||
gint width; /* width of the boards in "cells" */
|
||||
gint height; /* height of the boards in "cells" */
|
||||
gint colors; /* number of different colors */
|
||||
gint next; /* number of colors appearing on the next turn */
|
||||
gint destroy; /* number of same colors in line to destroy */
|
||||
gint width; /* width of the boards in "cells" */
|
||||
gint height; /* height of the boards in "cells" */
|
||||
gint colors; /* number of different colors */
|
||||
gint next; /* number of colors appearing on the next turn */
|
||||
gint destroy; /* number of same colors in line to destroy */
|
||||
};
|
||||
|
||||
GtkbGameRules _rules = {9, 9, 7, 3, 5};
|
||||
@ -64,464 +64,501 @@ gint _hi_score_undo = -1;
|
||||
gint _actions_locked = 0;
|
||||
|
||||
gint is_actions_locked(void) {
|
||||
return _actions_locked;
|
||||
return _actions_locked;
|
||||
}
|
||||
|
||||
void lock_actions(gint lock) {
|
||||
_actions_locked = lock;
|
||||
menu_set_sensitive_all(1 - lock);
|
||||
_actions_locked = lock;
|
||||
menu_set_sensitive_all(1 - lock);
|
||||
}
|
||||
|
||||
gint rules_get_width(void) {
|
||||
return _rules.width;
|
||||
return _rules.width;
|
||||
}
|
||||
|
||||
gint rules_get_height(void) {
|
||||
return _rules.height;
|
||||
return _rules.height;
|
||||
}
|
||||
|
||||
gint rules_get_colors(void) {
|
||||
return _rules.colors;
|
||||
return _rules.colors;
|
||||
}
|
||||
|
||||
gint rules_get_next(void) {
|
||||
return _rules.next;
|
||||
return _rules.next;
|
||||
}
|
||||
|
||||
gint rules_get_destroy(void) {
|
||||
return _rules.destroy;
|
||||
return _rules.destroy;
|
||||
}
|
||||
|
||||
gint rules_get_classic_width(void) {
|
||||
return _classic_rules.width;
|
||||
return _classic_rules.width;
|
||||
}
|
||||
|
||||
gint rules_get_classic_height(void) {
|
||||
return _classic_rules.height;
|
||||
return _classic_rules.height;
|
||||
}
|
||||
|
||||
gint rules_get_classic_colors(void) {
|
||||
return _classic_rules.colors;
|
||||
return _classic_rules.colors;
|
||||
}
|
||||
|
||||
gint rules_get_classic_next(void) {
|
||||
return _classic_rules.next;
|
||||
return _classic_rules.next;
|
||||
}
|
||||
|
||||
gint rules_get_classic_destroy(void) {
|
||||
return _classic_rules.destroy;
|
||||
return _classic_rules.destroy;
|
||||
}
|
||||
|
||||
void rules_set_width(gint width) {
|
||||
_rules.width = width;
|
||||
_rules.width = width;
|
||||
}
|
||||
|
||||
void rules_set_height(gint height) {
|
||||
_rules.height = height;
|
||||
_rules.height = height;
|
||||
}
|
||||
|
||||
void rules_set_colors(gint colors) {
|
||||
_rules.colors = colors;
|
||||
_rules.colors = colors;
|
||||
}
|
||||
|
||||
void rules_set_next(gint next) {
|
||||
_rules.next = next;
|
||||
_rules.next = next;
|
||||
}
|
||||
|
||||
void rules_set_destroy(gint destroy) {
|
||||
_rules.destroy = destroy;
|
||||
_rules.destroy = destroy;
|
||||
}
|
||||
|
||||
void rules_set(gint width, gint height, gint colors, gint next, gint destroy) {
|
||||
_rules.width = width;
|
||||
_rules.height = height;
|
||||
_rules.colors = colors;
|
||||
_rules.next = next;
|
||||
_rules.destroy = destroy;
|
||||
_rules.width = width;
|
||||
_rules.height = height;
|
||||
_rules.colors = colors;
|
||||
_rules.next = next;
|
||||
_rules.destroy = destroy;
|
||||
}
|
||||
|
||||
gboolean _rules_check_rules(GtkbGameRules r) {
|
||||
if((r.width < 4 || r.width > 99) ||
|
||||
(r.height < 4 || r.height > 99) ||
|
||||
(r.colors < 3 || r.colors > 99) ||
|
||||
(r.next < 2 || r.next > 99) ||
|
||||
(r.destroy < 3 || r.destroy > 99))
|
||||
return 0;
|
||||
return 1;
|
||||
if ((r.width < 4 || r.width > 99)
|
||||
|| (r.height < 4 || r.height > 99)
|
||||
|| (r.colors < 3 || r.colors > 99)
|
||||
|| (r.next < 2 || r.next > 99)
|
||||
|| (r.destroy < 3 || r.destroy > 99))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
gchar *_rules_to_str(GtkbGameRules r) {
|
||||
if(!_rules_check_rules(r))
|
||||
return NULL;
|
||||
return g_strdup_printf(_save_fmt, r.width, r.height, r.colors, r.next, r.destroy);
|
||||
if (!_rules_check_rules(r)) {
|
||||
return NULL;
|
||||
}
|
||||
return g_strdup_printf(_save_fmt, r.width, r.height, r.colors, r.next, r.destroy);
|
||||
}
|
||||
|
||||
gchar *rules_get_classic_as_str() {
|
||||
return _rules_to_str(_classic_rules);
|
||||
return _rules_to_str(_classic_rules);
|
||||
}
|
||||
|
||||
gchar *rules_get_as_str() {
|
||||
return _rules_to_str(_rules);
|
||||
return _rules_to_str(_rules);
|
||||
}
|
||||
|
||||
gint rules_get_str_len(void) {
|
||||
return _save_fmt_len;
|
||||
return _save_fmt_len;
|
||||
}
|
||||
|
||||
gboolean rules_check_str(gchar *rstr) {
|
||||
GtkbGameRules r;
|
||||
GtkbGameRules r;
|
||||
|
||||
if(strlen(rstr) != _save_fmt_len ||
|
||||
strstr(rstr, " ") ||
|
||||
strstr(rstr, "\t") ||
|
||||
strstr(rstr, "\r") ||
|
||||
strstr(rstr, "\n") ||
|
||||
sscanf(rstr, _save_fmt, &r.width, &r.height, &r.colors, &r.next, &r.destroy) != 5 ||
|
||||
!_rules_check_rules(r))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
if (strlen(rstr) != _save_fmt_len ||
|
||||
strstr(rstr, " ") ||
|
||||
strstr(rstr, "\t") ||
|
||||
strstr(rstr, "\r") ||
|
||||
strstr(rstr, "\n") ||
|
||||
sscanf(rstr, _save_fmt, &r.width, &r.height, &r.colors, &r.next, &r.destroy) != 5 ||
|
||||
!_rules_check_rules(r))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
gboolean rules_get_from_str(gchar *s, gint *width, gint *height, gint *colors, gint *next, gint *destroy) {
|
||||
if(!rules_check_str(s))
|
||||
return 0;
|
||||
sscanf(s, _save_fmt, width, height, colors, next, destroy);
|
||||
return 1;
|
||||
if (!rules_check_str(s)) {
|
||||
return 0;
|
||||
}
|
||||
sscanf(s, _save_fmt, width, height, colors, next, destroy);
|
||||
return 1;
|
||||
}
|
||||
|
||||
gchar *rules_conv_3_0_to_str(gchar *w, gchar *h, gchar *c, gchar *n, gchar *d) {
|
||||
GtkbGameRules r;
|
||||
GtkbGameRules r;
|
||||
|
||||
if(!w[0] || !h[0] || !c[0] || !n[0] || !d[0])
|
||||
return NULL;
|
||||
if (!w[0] || !h[0] || !c[0] || !n[0] || !d[0]) {
|
||||
return NULL;
|
||||
}
|
||||
r.width = strtol(w, NULL, 10);
|
||||
r.height = strtol(h, NULL, 10);
|
||||
r.colors = strtol(c, NULL, 10);
|
||||
r.next = strtol(n, NULL, 10);
|
||||
r.destroy = strtol(d, NULL, 10);
|
||||
|
||||
r.width = strtol(w, NULL, 10);
|
||||
r.height = strtol(h, NULL, 10);
|
||||
r.colors = strtol(c, NULL, 10);
|
||||
r.next = strtol(n, NULL, 10);
|
||||
r.destroy = strtol(d, NULL, 10);
|
||||
|
||||
return _rules_to_str(r);
|
||||
return _rules_to_str(r);
|
||||
}
|
||||
|
||||
gboolean rules_is_current_str(gchar *r) {
|
||||
gboolean rval = 0;
|
||||
gchar *cur = _rules_to_str(_rules);
|
||||
gboolean rval = 0;
|
||||
gchar *cur = _rules_to_str(_rules);
|
||||
|
||||
if(strcmp(r, cur) == 0)
|
||||
rval = 1;
|
||||
g_free(cur);
|
||||
if (strcmp(r, cur) == 0) {
|
||||
rval = 1;
|
||||
}
|
||||
g_free(cur);
|
||||
|
||||
return rval;
|
||||
return rval;
|
||||
}
|
||||
|
||||
gint game_get_score(void) {
|
||||
return _score;
|
||||
return _score;
|
||||
}
|
||||
|
||||
void game_set_score(gint score) {
|
||||
_score = score;
|
||||
_score = score;
|
||||
}
|
||||
|
||||
gint game_get_hi_score(void) {
|
||||
return _hi_score;
|
||||
return _hi_score;
|
||||
}
|
||||
|
||||
void game_set_hi_score(gint score) {
|
||||
_hi_score = score;
|
||||
_hi_score = score;
|
||||
}
|
||||
|
||||
void game_save_state_for_undo(void) {
|
||||
memcpy(_board_undo, _board, sizeof(gint) * _rules.width * _rules.height);
|
||||
memcpy(_next_colors_undo, _next_colors, sizeof(gint) * _rules.next);
|
||||
_score_undo = _score;
|
||||
_hi_score_undo = _hi_score;
|
||||
memcpy(_board_undo, _board, sizeof(gint) * _rules.width * _rules.height);
|
||||
memcpy(_next_colors_undo, _next_colors, sizeof(gint) * _rules.next);
|
||||
_score_undo = _score;
|
||||
_hi_score_undo = _hi_score;
|
||||
}
|
||||
|
||||
void game_restore_state_from_undo(void) {
|
||||
if(_score_undo == -1 || _hi_score_undo == -1)
|
||||
/* cannot undo */
|
||||
return;
|
||||
memcpy(_board, _board_undo, sizeof(gint) * _rules.width * _rules.height);
|
||||
memcpy(_next_colors, _next_colors_undo, sizeof(gint) * _rules.next);
|
||||
_score = _score_undo;
|
||||
_hi_score = _hi_score_undo;
|
||||
if (_score_undo == -1 || _hi_score_undo == -1) {
|
||||
/* cannot undo */
|
||||
return;
|
||||
}
|
||||
memcpy(_board, _board_undo, sizeof(gint) * _rules.width * _rules.height);
|
||||
memcpy(_next_colors, _next_colors_undo, sizeof(gint) * _rules.next);
|
||||
_score = _score_undo;
|
||||
_hi_score = _hi_score_undo;
|
||||
}
|
||||
|
||||
void game_init_game(gint *balls, gint *nextballs) {
|
||||
if(_board)
|
||||
g_free(_board);
|
||||
if(_board_undo)
|
||||
g_free(_board_undo);
|
||||
if(_board_destroys)
|
||||
g_free(_board_destroys);
|
||||
if(_next_colors)
|
||||
g_free(_next_colors);
|
||||
if(_next_colors_undo)
|
||||
g_free(_next_colors_undo);
|
||||
_board = g_malloc0(sizeof(gint) * _rules.width * _rules.height);
|
||||
_board_destroys = g_malloc0(sizeof(gint) * _rules.width * _rules.height);
|
||||
if(balls) {
|
||||
memcpy(_board, balls, sizeof(gint) * _rules.width * _rules.height);
|
||||
}
|
||||
_board_undo = g_malloc0(sizeof(gint) * _rules.width * _rules.height);
|
||||
_next_colors = g_malloc0(sizeof(gint) * _rules.next);
|
||||
if(nextballs) {
|
||||
memcpy(_next_colors, nextballs, sizeof(gint) * _rules.next);
|
||||
}
|
||||
_next_colors_undo = g_malloc0(sizeof(gint) * _rules.next);
|
||||
_score = 0;
|
||||
_score_undo = -1;
|
||||
_hi_score_undo = -1;
|
||||
void game_init_game(gint *balls, gint *nextballs)
|
||||
{
|
||||
if (_board) {
|
||||
g_free(_board);
|
||||
}
|
||||
if (_board_undo) {
|
||||
g_free(_board_undo);
|
||||
}
|
||||
if (_board_destroys) {
|
||||
g_free(_board_destroys);
|
||||
}
|
||||
if (_next_colors) {
|
||||
g_free(_next_colors);
|
||||
}
|
||||
if (_next_colors_undo) {
|
||||
g_free(_next_colors_undo);
|
||||
}
|
||||
_board = g_malloc0(sizeof(gint) * _rules.width * _rules.height);
|
||||
_board_destroys = g_malloc0(sizeof(gint) * _rules.width * _rules.height);
|
||||
if (balls) {
|
||||
memcpy(_board, balls, sizeof(gint) * _rules.width * _rules.height);
|
||||
}
|
||||
_board_undo = g_malloc0(sizeof(gint) * _rules.width * _rules.height);
|
||||
_next_colors = g_malloc0(sizeof(gint) * _rules.next);
|
||||
if (nextballs) {
|
||||
memcpy(_next_colors, nextballs, sizeof(gint) * _rules.next);
|
||||
}
|
||||
_next_colors_undo = g_malloc0(sizeof(gint) * _rules.next);
|
||||
_score = 0;
|
||||
_score_undo = -1;
|
||||
_hi_score_undo = -1;
|
||||
}
|
||||
|
||||
gint game_count_free_cells(void) {
|
||||
gint i, counter = 0;
|
||||
gint *bp = _board;
|
||||
gint i, counter = 0;
|
||||
gint *bp = _board;
|
||||
|
||||
for(i = 0; i < _rules.width * _rules.height; i++)
|
||||
if(*bp++ == 0)
|
||||
counter++;
|
||||
|
||||
return counter;
|
||||
for (i = 0; i < _rules.width * _rules.height; i++) {
|
||||
if (*bp++ == 0)
|
||||
counter++;
|
||||
}
|
||||
return counter;
|
||||
}
|
||||
|
||||
gint *game_get_board_as_int_arr(void) {
|
||||
gint *b;
|
||||
gint *b;
|
||||
|
||||
b = g_malloc(sizeof(gint) * _rules.width * _rules.height);
|
||||
memcpy(b, _board, sizeof(gint) * _rules.width * _rules.height);
|
||||
return b;
|
||||
b = g_malloc(sizeof(gint) * _rules.width * _rules.height);
|
||||
memcpy(b, _board, sizeof(gint) * _rules.width * _rules.height);
|
||||
return b;
|
||||
}
|
||||
|
||||
gint *game_get_next_as_int_arr(void) {
|
||||
gint *n;
|
||||
gint *n;
|
||||
|
||||
n = g_malloc(sizeof(gint) * _rules.next);
|
||||
memcpy(n, _next_colors, sizeof(gint) * _rules.next);
|
||||
return n;
|
||||
n = g_malloc(sizeof(gint) * _rules.next);
|
||||
memcpy(n, _next_colors, sizeof(gint) * _rules.next);
|
||||
return n;
|
||||
}
|
||||
|
||||
gint board_get_at_node(gint node) {
|
||||
if(node >= _rules.width * _rules.height)
|
||||
return 0;
|
||||
return _board[node];
|
||||
if (node >= _rules.width * _rules.height) {
|
||||
return 0;
|
||||
}
|
||||
return _board[node];
|
||||
}
|
||||
|
||||
gint board_get_at_xy(gint x, gint y) {
|
||||
if(x >= _rules.width || y > _rules.height)
|
||||
return 0;
|
||||
return _board[y * _rules.width + x];
|
||||
if (x >= _rules.width || y > _rules.height) {
|
||||
return 0;
|
||||
}
|
||||
return _board[y * _rules.width + x];
|
||||
}
|
||||
|
||||
gint board_get_destroy_at_xy(gint x, gint y) {
|
||||
if(x >= _rules.width || y > _rules.height)
|
||||
return 0;
|
||||
return _board_destroys[y * _rules.width + x];
|
||||
if (x >= _rules.width || y > _rules.height) {
|
||||
return 0;
|
||||
}
|
||||
return _board_destroys[y * _rules.width + x];
|
||||
}
|
||||
|
||||
void board_set_at_node(gint node, gint col) {
|
||||
if(node >= _rules.width * _rules.height)
|
||||
return;
|
||||
_board[node] = col;
|
||||
if (node >= _rules.width * _rules.height) {
|
||||
return;
|
||||
}
|
||||
_board[node] = col;
|
||||
}
|
||||
|
||||
void board_set_at_xy(gint x, gint y, gint col) {
|
||||
if(x >= _rules.width || y > _rules.height)
|
||||
return;
|
||||
_board[y * _rules.width + x] = col;
|
||||
if (x >= _rules.width || y > _rules.height) {
|
||||
return;
|
||||
}
|
||||
_board[y * _rules.width + x] = col;
|
||||
}
|
||||
|
||||
gint next_get(gint num) {
|
||||
if(num >= _rules.next)
|
||||
return 0;
|
||||
return _next_colors[num];
|
||||
if (num >= _rules.next) {
|
||||
return 0;
|
||||
}
|
||||
return _next_colors[num];
|
||||
}
|
||||
|
||||
void next_set(gint num, gint col) {
|
||||
if(num >= _rules.next)
|
||||
return;
|
||||
_next_colors[num] = col;
|
||||
if (num >= _rules.next) {
|
||||
return;
|
||||
}
|
||||
_next_colors[num] = col;
|
||||
}
|
||||
|
||||
void timer_start(void) {
|
||||
_timer_start_time = time(NULL);
|
||||
_timer_start_time = time(NULL);
|
||||
}
|
||||
|
||||
gboolean timer_is_running(void) {
|
||||
if(_timer_start_time == -1 || _timer_limit <= 0)
|
||||
return 0;
|
||||
return 1;
|
||||
if (_timer_start_time == -1 || _timer_limit <= 0) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
gboolean timer_is_expired(void) {
|
||||
time_t nowt = time(NULL);
|
||||
time_t nowt = time(NULL);
|
||||
|
||||
if(nowt - _timer_start_time >= _timer_limit)
|
||||
return 1;
|
||||
return 0;
|
||||
if (nowt - _timer_start_time >= _timer_limit) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
gint timer_get_remaining(void) {
|
||||
time_t nowt = time(NULL);
|
||||
time_t nowt = time (NULL);
|
||||
|
||||
return _timer_limit + _timer_start_time - nowt;
|
||||
return _timer_limit + _timer_start_time - nowt;
|
||||
}
|
||||
|
||||
void timer_set_limit(gint limit) {
|
||||
_timer_limit =limit;
|
||||
_timer_limit =limit;
|
||||
}
|
||||
|
||||
gint timer_get_limit(void) {
|
||||
return _timer_limit;
|
||||
return _timer_limit;
|
||||
}
|
||||
|
||||
struct gtkb_animarray {
|
||||
gint color, x, y, phase, time;
|
||||
gint color, x, y, phase, time;
|
||||
};
|
||||
|
||||
int animsort(const void *a, const void *b) {
|
||||
if(((const struct gtkb_animarray *)a)->time == ((const struct gtkb_animarray *)b)->time) return 0;
|
||||
if(((const struct gtkb_animarray *)a)->time > ((const struct gtkb_animarray *)b)->time) return 1;
|
||||
return -1;
|
||||
int animsort(const void *a, const void *b)
|
||||
{
|
||||
if (((const struct gtkb_animarray *)a)->time == ((const struct gtkb_animarray *)b)->time) {
|
||||
return 0;
|
||||
}
|
||||
if (((const struct gtkb_animarray *)a)->time > ((const struct gtkb_animarray *)b)->time) {
|
||||
return 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
gint game_destroy_lines(gboolean count_score) {
|
||||
gint x, y, i, j;
|
||||
gint *del, have_del = 0;
|
||||
|
||||
if(rules_get_width() < rules_get_destroy() &&
|
||||
rules_get_height() < rules_get_destroy()) { /* destroy is impossible */
|
||||
return 0;
|
||||
}
|
||||
gint game_destroy_lines(gboolean count_score)
|
||||
{
|
||||
gint x, y, i, j;
|
||||
gint *del, have_del = 0;
|
||||
|
||||
del = g_malloc0(rules_get_width() * rules_get_height() * sizeof(gint));
|
||||
if (rules_get_width() < rules_get_destroy() &&
|
||||
rules_get_height() < rules_get_destroy()) { /* destroy is impossible */
|
||||
return 0;
|
||||
}
|
||||
|
||||
for(y = 0; y < rules_get_height(); y++) {
|
||||
for(x = 0; x < rules_get_width(); x++) {
|
||||
if(board_get_at_xy(x, y) != 0) {
|
||||
/* horizontal */
|
||||
if(rules_get_width() - x >= rules_get_destroy()) {
|
||||
for(i = 1;
|
||||
i < rules_get_width() - x &&
|
||||
board_get_at_xy(x + i, y) == board_get_at_xy(x, y);
|
||||
i++);
|
||||
if(i >= rules_get_destroy()) {
|
||||
have_del = 1;
|
||||
for(j = 0; j < i; j ++) {
|
||||
del[y * rules_get_width() + x + j] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* vertical */
|
||||
if(rules_get_height() - y >= rules_get_destroy()) {
|
||||
for(i = 1;
|
||||
i < rules_get_height() - y &&
|
||||
board_get_at_xy(x, y + i) == board_get_at_xy(x, y);
|
||||
i++);
|
||||
if(i >= rules_get_destroy()) {
|
||||
have_del = 1;
|
||||
for(j = 0; j < i; j ++) {
|
||||
del[(y + j) * rules_get_width() + x] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* diagonal left -> right */
|
||||
if(rules_get_width() - x >= rules_get_destroy() &&
|
||||
rules_get_height() - y >= rules_get_destroy()) {
|
||||
for(i = 1;
|
||||
i < rules_get_width() - x &&
|
||||
i < rules_get_height() - y &&
|
||||
board_get_at_xy(x + i, y + i) == board_get_at_xy(x, y);
|
||||
i++);
|
||||
if(i >= rules_get_destroy()) {
|
||||
have_del = 1;
|
||||
for(j = 0; j < i; j ++) {
|
||||
del[(y + j) * rules_get_width() + x + j] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* diagonal right -> left */
|
||||
if(x + 1 >= rules_get_destroy() &&
|
||||
rules_get_height() - y >= rules_get_destroy()) {
|
||||
for(i = 1;
|
||||
i <= x &&
|
||||
i < rules_get_height() - y &&
|
||||
board_get_at_xy(x - i, y + i) == board_get_at_xy(x, y);
|
||||
i++);
|
||||
if(i >= rules_get_destroy()) {
|
||||
have_del = 1;
|
||||
for(j = 0; j < i; j ++) {
|
||||
del[(y + j) * rules_get_width() + x - j] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
i = 0;
|
||||
if(have_del) {
|
||||
if(pref_get_show_destroy()) {
|
||||
gint animcadres = 0, animpos = 0, animtime;
|
||||
struct gtkb_animarray *animarray;
|
||||
struct timeval tvs, tve;
|
||||
del = g_malloc0(rules_get_width() * rules_get_height() * sizeof(gint));
|
||||
|
||||
animarray = g_new0(struct gtkb_animarray, rules_get_width() * rules_get_height() * gtkbTheme->maxdestphases);
|
||||
for(y = 0; y < rules_get_height(); y++) {
|
||||
for(x = 0; x < rules_get_width(); x++) {
|
||||
if(del[y * rules_get_width() + x] == 1) {
|
||||
gint color = board_get_at_xy(x, y);
|
||||
for (y = 0; y < rules_get_height(); y++)
|
||||
{
|
||||
for (x = 0; x < rules_get_width(); x++)
|
||||
{
|
||||
if (board_get_at_xy(x, y) != 0) {
|
||||
/* horizontal */
|
||||
if (rules_get_width() - x >= rules_get_destroy()) {
|
||||
for (i = 1;
|
||||
i < rules_get_width() - x &&
|
||||
board_get_at_xy(x + i, y) == board_get_at_xy(x, y);
|
||||
i++);
|
||||
if (i >= rules_get_destroy()) {
|
||||
have_del = 1;
|
||||
for (j = 0; j < i; j ++) {
|
||||
del[y * rules_get_width() + x + j] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* vertical */
|
||||
if (rules_get_height() - y >= rules_get_destroy()) {
|
||||
for (i = 1;
|
||||
i < rules_get_height() - y &&
|
||||
board_get_at_xy(x, y + i) == board_get_at_xy(x, y);
|
||||
i++);
|
||||
if (i >= rules_get_destroy()) {
|
||||
have_del = 1;
|
||||
for (j = 0; j < i; j ++) {
|
||||
del[(y + j) * rules_get_width() + x] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* diagonal left -> right */
|
||||
if (rules_get_width() - x >= rules_get_destroy() &&
|
||||
rules_get_height() - y >= rules_get_destroy()) {
|
||||
for (i = 1;
|
||||
i < rules_get_width() - x &&
|
||||
i < rules_get_height() - y &&
|
||||
board_get_at_xy(x + i, y + i) == board_get_at_xy(x, y);
|
||||
i++);
|
||||
if (i >= rules_get_destroy()) {
|
||||
have_del = 1;
|
||||
for (j = 0; j < i; j ++) {
|
||||
del[(y + j) * rules_get_width() + x + j] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* diagonal right -> left */
|
||||
if (x + 1 >= rules_get_destroy() &&
|
||||
rules_get_height() - y >= rules_get_destroy()) {
|
||||
for (i = 1;
|
||||
i <= x &&
|
||||
i < rules_get_height() - y &&
|
||||
board_get_at_xy(x - i, y + i) == board_get_at_xy(x, y);
|
||||
i++);
|
||||
if (i >= rules_get_destroy()) {
|
||||
have_del = 1;
|
||||
for (j = 0; j < i; j ++) {
|
||||
del[(y + j) * rules_get_width() + x - j] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
animcadres += gtkbTheme->balls[color - 1].destroyphases + 1;
|
||||
for(j = 0, animtime = 0; j <= gtkbTheme->balls[color - 1].destroyphases; j++) {
|
||||
if(j != gtkbTheme->balls[color - 1].destroyphases) {
|
||||
animarray[animpos].color = color;
|
||||
animarray[animpos].phase = j;
|
||||
animtime += gtkbTheme->balls[color - 1].destroydelays[j];
|
||||
} else {
|
||||
animarray[animpos].color = 0;
|
||||
animarray[animpos].phase = 0;
|
||||
}
|
||||
animarray[animpos].x = x;
|
||||
animarray[animpos].y = y;
|
||||
animarray[animpos].time = animtime;
|
||||
animpos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
qsort(animarray, animcadres, sizeof(struct gtkb_animarray), animsort);
|
||||
lock_actions(1);
|
||||
draw_board();
|
||||
for(animtime = 0, i = 0; i < animcadres;) {
|
||||
gettimeofday(&tvs, NULL);
|
||||
gint isav = i;
|
||||
for(; animtime == animarray[i].time && i < animcadres; i++) {
|
||||
draw_ball(animarray[i].color, animarray[i].x, animarray[i].y, 0, animarray[i].phase + 1);
|
||||
_board_destroys[animarray[i].y * rules_get_width() + animarray[i].x] = animarray[i].phase + 1;
|
||||
}
|
||||
do {
|
||||
gtk_main_iteration_do(0);
|
||||
gettimeofday(&tve, NULL);
|
||||
} while((tve.tv_sec - tvs.tv_sec) * 1000000 + tve.tv_usec - tvs.tv_usec < (animarray[i].time - animtime) * 1000);
|
||||
animtime = animarray[isav].time;
|
||||
}
|
||||
g_free(animarray);
|
||||
memset(_board_destroys, 0, rules_get_width() * rules_get_height() * sizeof(gint));
|
||||
lock_actions(0);
|
||||
}
|
||||
i = 0;
|
||||
if (have_del)
|
||||
{
|
||||
if (pref_get_show_destroy())
|
||||
{
|
||||
gint animcadres = 0, animpos = 0, animtime;
|
||||
struct gtkb_animarray *animarray;
|
||||
struct timeval tvs, tve;
|
||||
|
||||
for(i = 0, y = 0; y < rules_get_height(); y++) {
|
||||
for(x = 0; x < rules_get_width(); x++) {
|
||||
if(del[y * rules_get_width() + x] == 1) {
|
||||
i++;
|
||||
board_set_at_xy(x, y, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
animarray = g_new0(struct gtkb_animarray, rules_get_width() * rules_get_height() * gtkbTheme->maxdestphases);
|
||||
for (y = 0; y < rules_get_height(); y++)
|
||||
{
|
||||
for (x = 0; x < rules_get_width(); x++)
|
||||
{
|
||||
if (del[y * rules_get_width() + x] == 1) {
|
||||
gint color = board_get_at_xy(x, y);
|
||||
|
||||
g_free(del);
|
||||
return i;
|
||||
animcadres += gtkbTheme->balls[color - 1].destroyphases + 1;
|
||||
for (j = 0, animtime = 0; j <= gtkbTheme->balls[color - 1].destroyphases; j++) {
|
||||
if (j != gtkbTheme->balls[color - 1].destroyphases) {
|
||||
animarray[animpos].color = color;
|
||||
animarray[animpos].phase = j;
|
||||
animtime += gtkbTheme->balls[color - 1].destroydelays[j];
|
||||
} else {
|
||||
animarray[animpos].color = 0;
|
||||
animarray[animpos].phase = 0;
|
||||
}
|
||||
animarray[animpos].x = x;
|
||||
animarray[animpos].y = y;
|
||||
animarray[animpos].time = animtime;
|
||||
animpos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
qsort(animarray, animcadres, sizeof(struct gtkb_animarray), animsort);
|
||||
lock_actions(1);
|
||||
draw_board();
|
||||
for (animtime = 0, i = 0; i < animcadres;)
|
||||
{
|
||||
gettimeofday(&tvs, NULL);
|
||||
gint isav = i;
|
||||
for (; animtime == animarray[i].time && i < animcadres; i++) {
|
||||
draw_ball(animarray[i].color, animarray[i].x, animarray[i].y, 0, animarray[i].phase + 1);
|
||||
_board_destroys[animarray[i].y * rules_get_width() + animarray[i].x] = animarray[i].phase + 1;
|
||||
}
|
||||
do {
|
||||
gtk_main_iteration_do(0);
|
||||
gettimeofday(&tve, NULL);
|
||||
} while((tve.tv_sec - tvs.tv_sec) * 1000000 + tve.tv_usec - tvs.tv_usec < (animarray[i].time - animtime) * 1000);
|
||||
animtime = animarray[isav].time;
|
||||
}
|
||||
g_free(animarray);
|
||||
memset(_board_destroys, 0, rules_get_width() * rules_get_height() * sizeof(gint));
|
||||
lock_actions(0);
|
||||
}
|
||||
|
||||
for (i = 0, y = 0; y < rules_get_height(); y++) {
|
||||
for (x = 0; x < rules_get_width(); x++) {
|
||||
if (del[y * rules_get_width() + x] == 1) {
|
||||
i++;
|
||||
board_set_at_xy(x, y, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_free(del);
|
||||
return i;
|
||||
}
|
||||
|
717
src/gfx.c
717
src/gfx.c
@ -19,7 +19,7 @@
|
||||
#include "mainwin.h"
|
||||
#include "game.h"
|
||||
|
||||
GdkPixmap *_pixmap=NULL;
|
||||
GdkPixmap *_pixmap = NULL;
|
||||
|
||||
/* x and y of cell "under pointer" */
|
||||
gint _pointer_x = 0, _pointer_y = 0;
|
||||
@ -42,453 +42,470 @@ gboolean have_path(gint source_ball, gint target_ball);
|
||||
void move_ball(gint source_ball, gint target_ball);
|
||||
|
||||
gint xy_to_cell_number(gint x, gint y) {
|
||||
return find_node_of_x_y(x, y, rules_get_width());
|
||||
return find_node_of_x_y(x, y, rules_get_width());
|
||||
}
|
||||
|
||||
|
||||
gint get_jump_phase(gint x, gint y) {
|
||||
if(!_animation_in_progress || xy_to_cell_number(x, y) != _jumping_ball)
|
||||
return 0;
|
||||
return _phase;
|
||||
if (!_animation_in_progress || xy_to_cell_number(x, y) != _jumping_ball) {
|
||||
return 0;
|
||||
}
|
||||
return _phase;
|
||||
}
|
||||
|
||||
void set_jump_phase(gint p) {
|
||||
if(!_animation_in_progress)
|
||||
return;
|
||||
_phase = p;
|
||||
if (!_animation_in_progress) {
|
||||
return;
|
||||
}
|
||||
_phase = p;
|
||||
}
|
||||
|
||||
gint get_destroy_phase(gint x, gint y) {
|
||||
return board_get_destroy_at_xy(x, y);
|
||||
return board_get_destroy_at_xy(x, y);
|
||||
}
|
||||
|
||||
void update_rectangle(gint x, gint y, gint w, gint h) {
|
||||
GtkWidget *widget = mw_get_da();
|
||||
GtkWidget *widget = mw_get_da();
|
||||
|
||||
if(!widget || !_pixmap) {
|
||||
return;
|
||||
}
|
||||
gdk_draw_drawable (gtk_widget_get_window (widget),
|
||||
widget->style->fg_gc[gtk_widget_get_state(widget)],
|
||||
_pixmap, x, y, x, y, w, h);
|
||||
if (!widget || !_pixmap) {
|
||||
return;
|
||||
}
|
||||
gdk_draw_drawable (gtk_widget_get_window (widget),
|
||||
widget->style->fg_gc[gtk_widget_get_state(widget)],
|
||||
_pixmap, x, y, x, y, w, h);
|
||||
}
|
||||
|
||||
void draw_ball_no_update(gint ballcolor, gint x, gint y, gint jumpnum, gint destroynum) {
|
||||
GtkWidget *widget = mw_get_da();
|
||||
GdkGC *gc = widget->style->fg_gc[gtk_widget_get_state(widget)];
|
||||
gint cxs = gtkbTheme->emptycell.xsize;
|
||||
gint cys = gtkbTheme->emptycell.ysize;
|
||||
GtkbPixmap *obj;
|
||||
gint xr, yr;
|
||||
void draw_ball_no_update(gint ballcolor, gint x, gint y, gint jumpnum, gint destroynum)
|
||||
{
|
||||
GtkWidget *widget = mw_get_da();
|
||||
GdkGC *gc = widget->style->fg_gc[gtk_widget_get_state(widget)];
|
||||
gint cxs = gtkbTheme->emptycell.xsize;
|
||||
gint cys = gtkbTheme->emptycell.ysize;
|
||||
GtkbPixmap *obj;
|
||||
gint xr, yr;
|
||||
|
||||
if(!widget || !_pixmap) {
|
||||
return;
|
||||
}
|
||||
if (!widget || !_pixmap) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(pref_get_show_highlight() && x == _pointer_x && y == _pointer_y) {
|
||||
obj = >kbTheme->hemptycell;
|
||||
} else {
|
||||
obj = >kbTheme->emptycell;
|
||||
}
|
||||
gdk_draw_pixbuf (_pixmap,
|
||||
gc,
|
||||
obj->pixbuf,
|
||||
0, 0,
|
||||
x * cxs, y * cys,
|
||||
cxs, cys,
|
||||
GDK_RGB_DITHER_NONE, 0, 0);
|
||||
if (pref_get_show_highlight() && x == _pointer_x && y == _pointer_y) {
|
||||
obj = >kbTheme->hemptycell;
|
||||
} else {
|
||||
obj = >kbTheme->emptycell;
|
||||
}
|
||||
gdk_draw_pixbuf (_pixmap,
|
||||
gc,
|
||||
obj->pixbuf,
|
||||
0, 0,
|
||||
x * cxs, y * cys,
|
||||
cxs, cys,
|
||||
GDK_RGB_DITHER_NONE, 0, 0);
|
||||
|
||||
if(ballcolor > 0) { /* ball */
|
||||
if(!jumpnum && !destroynum) { /* still ball */
|
||||
obj = >kbTheme->balls[ballcolor - 1].ball;
|
||||
} else if(jumpnum) { /* jumping ball */
|
||||
obj = >kbTheme->balls[ballcolor - 1].jump[jumpnum - 1];
|
||||
} else { /* disappearing ball */
|
||||
obj = >kbTheme->balls[ballcolor - 1].destroy[destroynum - 1];
|
||||
}
|
||||
} else if(ballcolor < 0) { /* paw */
|
||||
obj = >kbTheme->paws[-1 - ballcolor];
|
||||
} else { /* empty cell */
|
||||
return;
|
||||
}
|
||||
if (ballcolor > 0) { /* ball */
|
||||
if (!jumpnum && !destroynum) { /* still ball */
|
||||
obj = >kbTheme->balls[ballcolor - 1].ball;
|
||||
} else if (jumpnum) { /* jumping ball */
|
||||
obj = >kbTheme->balls[ballcolor - 1].jump[jumpnum - 1];
|
||||
} else { /* disappearing ball */
|
||||
obj = >kbTheme->balls[ballcolor - 1].destroy[destroynum - 1];
|
||||
}
|
||||
} else if (ballcolor < 0) { /* paw */
|
||||
obj = >kbTheme->paws[-1 - ballcolor];
|
||||
} else { /* empty cell */
|
||||
return;
|
||||
}
|
||||
|
||||
xr = x * cxs + (cxs - obj->xsize) / 2;
|
||||
yr = y * cys + (cys - obj->ysize) / 2;
|
||||
gdk_draw_pixbuf (_pixmap,
|
||||
gc,
|
||||
obj->pixbuf,
|
||||
0, 0,
|
||||
xr, yr,
|
||||
obj->xsize, obj->ysize,
|
||||
GDK_RGB_DITHER_NONE, 0, 0);
|
||||
xr = x * cxs + (cxs - obj->xsize) / 2;
|
||||
yr = y * cys + (cys - obj->ysize) / 2;
|
||||
gdk_draw_pixbuf (_pixmap,
|
||||
gc,
|
||||
obj->pixbuf,
|
||||
0, 0,
|
||||
xr, yr,
|
||||
obj->xsize, obj->ysize,
|
||||
GDK_RGB_DITHER_NONE, 0, 0);
|
||||
}
|
||||
|
||||
void draw_ball(gint ballcolor, gint x, gint y, gint jumpnum, gint destroynum) {
|
||||
gint cxs = gtkbTheme->emptycell.xsize;
|
||||
gint cys = gtkbTheme->emptycell.ysize;
|
||||
gint cxs = gtkbTheme->emptycell.xsize;
|
||||
gint cys = gtkbTheme->emptycell.ysize;
|
||||
|
||||
draw_ball_no_update(ballcolor, x, y, jumpnum, destroynum);
|
||||
update_rectangle(x * cxs, y * cys, cxs, cys);
|
||||
draw_ball_no_update(ballcolor, x, y, jumpnum, destroynum);
|
||||
update_rectangle(x * cxs, y * cys, cxs, cys);
|
||||
}
|
||||
|
||||
void redraw_ball(gint x, gint y) {
|
||||
draw_ball(board_get_at_xy(x, y), x, y, get_jump_phase(x, y), get_destroy_phase(x, y));
|
||||
draw_ball(board_get_at_xy(x, y), x, y, get_jump_phase(x, y), get_destroy_phase(x, y));
|
||||
}
|
||||
|
||||
void redraw_pointer(void) {
|
||||
draw_ball(board_get_at_xy(_pointer_x, _pointer_y),
|
||||
_pointer_x, _pointer_y,
|
||||
get_jump_phase(_pointer_x, _pointer_y),
|
||||
get_destroy_phase(_pointer_x, _pointer_y));
|
||||
draw_ball(board_get_at_xy(_pointer_x, _pointer_y),
|
||||
_pointer_x, _pointer_y,
|
||||
get_jump_phase(_pointer_x, _pointer_y),
|
||||
get_destroy_phase(_pointer_x, _pointer_y));
|
||||
}
|
||||
|
||||
void draw_board(void) {
|
||||
gint i, j;
|
||||
gint i, j;
|
||||
|
||||
if(!mw_get_da()) {
|
||||
return;
|
||||
}
|
||||
for(j = 0; j < rules_get_height(); j++) {
|
||||
for(i = 0; i < rules_get_width(); i++) {
|
||||
if(!_animation_in_progress || ((xy_to_cell_number(i, j)) != _jumping_ball)) {
|
||||
draw_ball_no_update(board_get_at_xy(i, j), i, j, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
update_rectangle(0, 0, -1, -1);
|
||||
if (!mw_get_da()) {
|
||||
return;
|
||||
}
|
||||
for (j = 0; j < rules_get_height(); j++) {
|
||||
for (i = 0; i < rules_get_width(); i++) {
|
||||
if (!_animation_in_progress || ((xy_to_cell_number(i, j)) != _jumping_ball)) {
|
||||
draw_ball_no_update(board_get_at_xy(i, j), i, j, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
update_rectangle(0, 0, -1, -1);
|
||||
}
|
||||
|
||||
gint inc_with_limit(gint val, gint lim) {
|
||||
if(val < lim)
|
||||
return val + 1;
|
||||
return lim;
|
||||
if (val < lim) {
|
||||
return val + 1;
|
||||
}
|
||||
return lim;
|
||||
}
|
||||
|
||||
gint dec_with_limit(gint val, gint lim) {
|
||||
if(val > lim)
|
||||
return val - 1;
|
||||
return lim;
|
||||
if (val > lim) {
|
||||
return val - 1;
|
||||
}
|
||||
return lim;
|
||||
}
|
||||
|
||||
gboolean animate_ball(gpointer data) {
|
||||
GtkWidget *widget = GTK_WIDGET(data);
|
||||
int x, y, bc = board_get_at_node(_jumping_ball);
|
||||
GtkWidget *widget = GTK_WIDGET(data);
|
||||
int x, y, bc = board_get_at_node(_jumping_ball);
|
||||
|
||||
find_x_y_of_the_node(&x, &y, _jumping_ball, rules_get_width(), rules_get_height());
|
||||
if(widget != NULL) {
|
||||
draw_ball(bc, x, y, _phase + 1, 0);
|
||||
}
|
||||
find_x_y_of_the_node(&x, &y, _jumping_ball, rules_get_width(), rules_get_height());
|
||||
if (widget != NULL) {
|
||||
draw_ball(bc, x, y, _phase + 1, 0);
|
||||
}
|
||||
|
||||
++_phase;
|
||||
if(_phase >= gtkbTheme->balls[bc - 1].jumpphases) {
|
||||
_phase = 0;
|
||||
}
|
||||
_timer_tag = g_timeout_add(gtkbTheme->balls[bc - 1].jumpdelays[_phase], animate_ball, widget);
|
||||
++_phase;
|
||||
if (_phase >= gtkbTheme->balls[bc - 1].jumpphases) {
|
||||
_phase = 0;
|
||||
}
|
||||
_timer_tag = g_timeout_add (gtkbTheme->balls[bc - 1].jumpdelays[_phase], animate_ball, widget);
|
||||
|
||||
return FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void stop_jumping_animation(void) {
|
||||
if(_animation_in_progress) {
|
||||
g_source_remove(_timer_tag);
|
||||
_animation_in_progress = FALSE;
|
||||
}
|
||||
if (_animation_in_progress) {
|
||||
g_source_remove (_timer_tag);
|
||||
_animation_in_progress = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
void move_pointer_to(gint x, gint y) {
|
||||
gint i, jp, dp, xc = _pointer_x, yc = _pointer_y;
|
||||
void move_pointer_to(gint x, gint y)
|
||||
{
|
||||
gint i, jp, dp, xc = _pointer_x, yc = _pointer_y;
|
||||
|
||||
if(x >= rules_get_width() || y >= rules_get_height() || x < 0 || y < 0)
|
||||
/* "boundary check" */
|
||||
return;
|
||||
if(_pointer_x == x && _pointer_y == y)
|
||||
return;
|
||||
|
||||
_pointer_x = x;
|
||||
_pointer_y = y;
|
||||
for(i = 0; i < 2; i++) {
|
||||
if(i) {
|
||||
xc = _pointer_x;
|
||||
yc = _pointer_y;
|
||||
}
|
||||
jp = get_jump_phase(xc, yc);
|
||||
dp = get_destroy_phase(xc, yc);
|
||||
draw_ball(board_get_at_xy(xc, yc), xc, yc, jp, dp);
|
||||
}
|
||||
if (x >= rules_get_width() || y >= rules_get_height() || x < 0 || y < 0) {
|
||||
/* "boundary check" */
|
||||
return;
|
||||
}
|
||||
if (_pointer_x == x && _pointer_y == y) {
|
||||
return;
|
||||
}
|
||||
_pointer_x = x;
|
||||
_pointer_y = y;
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (i) {
|
||||
xc = _pointer_x;
|
||||
yc = _pointer_y;
|
||||
}
|
||||
jp = get_jump_phase(xc, yc);
|
||||
dp = get_destroy_phase(xc, yc);
|
||||
draw_ball(board_get_at_xy(xc, yc), xc, yc, jp, dp);
|
||||
}
|
||||
}
|
||||
|
||||
void move_pointer(Direction dir) {
|
||||
gint xn = _pointer_x, yn = _pointer_y;
|
||||
gint xn = _pointer_x, yn = _pointer_y;
|
||||
|
||||
if(dir == DIR_LEFT || dir == DIR_UP_LEFT || dir == DIR_DOWN_LEFT)
|
||||
xn = dec_with_limit(_pointer_x, 0);
|
||||
if(dir == DIR_RIGHT || dir == DIR_UP_RIGHT || dir == DIR_DOWN_RIGHT)
|
||||
xn = inc_with_limit(_pointer_x, rules_get_width() - 1);
|
||||
if(dir == DIR_UP || dir == DIR_UP_LEFT || dir == DIR_UP_RIGHT)
|
||||
yn = dec_with_limit(_pointer_y, 0);
|
||||
if(dir == DIR_DOWN || dir == DIR_DOWN_LEFT || dir == DIR_DOWN_RIGHT)
|
||||
yn = inc_with_limit(_pointer_y, rules_get_height() - 1);
|
||||
if (dir == DIR_LEFT || dir == DIR_UP_LEFT || dir == DIR_DOWN_LEFT) {
|
||||
xn = dec_with_limit(_pointer_x, 0);
|
||||
}
|
||||
if (dir == DIR_RIGHT || dir == DIR_UP_RIGHT || dir == DIR_DOWN_RIGHT) {
|
||||
xn = inc_with_limit(_pointer_x, rules_get_width() - 1);
|
||||
}
|
||||
if (dir == DIR_UP || dir == DIR_UP_LEFT || dir == DIR_UP_RIGHT) {
|
||||
yn = dec_with_limit(_pointer_y, 0);
|
||||
}
|
||||
if (dir == DIR_DOWN || dir == DIR_DOWN_LEFT || dir == DIR_DOWN_RIGHT) {
|
||||
yn = inc_with_limit(_pointer_y, rules_get_height() - 1);
|
||||
}
|
||||
if (xn == _pointer_x && yn == _pointer_y) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(xn == _pointer_x && yn == _pointer_y)
|
||||
return;
|
||||
|
||||
move_pointer_to(xn, yn);
|
||||
move_pointer_to(xn, yn);
|
||||
}
|
||||
|
||||
void pointer_pressed(gint x, gint y) {
|
||||
gint xn, yn, node, bc;
|
||||
gint xn, yn, node, bc;
|
||||
|
||||
if(x == -1 || y == -1) {
|
||||
x = _pointer_x;
|
||||
y = _pointer_y;
|
||||
}
|
||||
node = xy_to_cell_number(x, y);
|
||||
if (x == -1 || y == -1) {
|
||||
x = _pointer_x;
|
||||
y = _pointer_y;
|
||||
}
|
||||
node = xy_to_cell_number(x, y);
|
||||
|
||||
if(_animation_in_progress && node == _jumping_ball) {
|
||||
/* already selected ball clicked */
|
||||
return;
|
||||
}
|
||||
if (_animation_in_progress && node == _jumping_ball) {
|
||||
/* already selected ball clicked */
|
||||
return;
|
||||
}
|
||||
|
||||
if(board_get_at_node(node) > 0) {
|
||||
/* cell with ball pressed */
|
||||
if(_animation_in_progress) {
|
||||
/* another ball already jumping, stop him */
|
||||
stop_jumping_animation();
|
||||
find_x_y_of_the_node(&xn, &yn, _jumping_ball, rules_get_width(), rules_get_height());
|
||||
draw_ball(board_get_at_node(_jumping_ball), xn, yn, 0, 0);
|
||||
}
|
||||
/* select ball at x,y and start it jumping */
|
||||
_jumping_ball = node;
|
||||
bc = board_get_at_node(node);
|
||||
_animation_in_progress = TRUE;
|
||||
_phase = 0;
|
||||
_timer_tag = g_timeout_add(gtkbTheme->balls[bc - 1].jumpdelays[_phase], animate_ball, mw_get_da());
|
||||
} else if(_animation_in_progress && have_path(_jumping_ball, node)) {
|
||||
/* cell without ball pressed while ball selected */
|
||||
game_save_state_for_undo();
|
||||
menu_set_sensitive_undo(TRUE);
|
||||
stop_jumping_animation();
|
||||
move_ball(_jumping_ball, node);
|
||||
if(!destroy_lines(TRUE)) {
|
||||
new_turn(rules_get_next(), FALSE);
|
||||
}
|
||||
timer_start();
|
||||
}
|
||||
if (board_get_at_node(node) > 0) {
|
||||
/* cell with ball pressed */
|
||||
if (_animation_in_progress) {
|
||||
/* another ball already jumping, stop him */
|
||||
stop_jumping_animation();
|
||||
find_x_y_of_the_node(&xn, &yn, _jumping_ball, rules_get_width(), rules_get_height());
|
||||
draw_ball(board_get_at_node(_jumping_ball), xn, yn, 0, 0);
|
||||
}
|
||||
/* select ball at x,y and start it jumping */
|
||||
_jumping_ball = node;
|
||||
bc = board_get_at_node(node);
|
||||
_animation_in_progress = TRUE;
|
||||
_phase = 0;
|
||||
_timer_tag = g_timeout_add(gtkbTheme->balls[bc - 1].jumpdelays[_phase], animate_ball, mw_get_da());
|
||||
} else if (_animation_in_progress && have_path(_jumping_ball, node)) {
|
||||
/* cell without ball pressed while ball selected */
|
||||
game_save_state_for_undo();
|
||||
menu_set_sensitive_undo(TRUE);
|
||||
stop_jumping_animation();
|
||||
move_ball(_jumping_ball, node);
|
||||
if (!destroy_lines(TRUE)) {
|
||||
new_turn(rules_get_next(), FALSE);
|
||||
}
|
||||
timer_start();
|
||||
}
|
||||
}
|
||||
|
||||
void reinit_board(gint *newboard, gint *newnext, gint score, gint oldnext) {
|
||||
struct score_board sb[10];
|
||||
gint cells = rules_get_width() * rules_get_height() - 1;
|
||||
struct score_board sb[10];
|
||||
gint cells = rules_get_width() * rules_get_height() - 1;
|
||||
|
||||
stop_jumping_animation();
|
||||
if(_pointer_x >= rules_get_width()) {
|
||||
_pointer_x = rules_get_width() - 1;
|
||||
}
|
||||
if(_pointer_y >= rules_get_height()) {
|
||||
_pointer_y = rules_get_height() - 1;
|
||||
}
|
||||
if(rules_get_destroy() > cells) {
|
||||
rules_set_destroy(cells);
|
||||
}
|
||||
if(rules_get_next() > cells) {
|
||||
rules_set_next(cells);
|
||||
}
|
||||
game_init_game(newboard, newnext);
|
||||
read_score(sb, NULL, NULL);
|
||||
mw_set_hi_score(score > sb[0].score ? score : sb[0].score);
|
||||
mw_set_user_score(score);
|
||||
remake_board(oldnext, newnext ? 1 : 0);
|
||||
if(!newboard) {
|
||||
new_game();
|
||||
} else {
|
||||
menu_set_sensitive_undo(FALSE);
|
||||
draw_next_balls();
|
||||
}
|
||||
stop_jumping_animation();
|
||||
if (_pointer_x >= rules_get_width()) {
|
||||
_pointer_x = rules_get_width() - 1;
|
||||
}
|
||||
if (_pointer_y >= rules_get_height()) {
|
||||
_pointer_y = rules_get_height() - 1;
|
||||
}
|
||||
if (rules_get_destroy() > cells) {
|
||||
rules_set_destroy(cells);
|
||||
}
|
||||
if (rules_get_next() > cells) {
|
||||
rules_set_next(cells);
|
||||
}
|
||||
game_init_game(newboard, newnext);
|
||||
read_score(sb, NULL, NULL);
|
||||
mw_set_hi_score(score > sb[0].score ? score : sb[0].score);
|
||||
mw_set_user_score(score);
|
||||
remake_board(oldnext, newnext ? 1 : 0);
|
||||
if (!newboard) {
|
||||
new_game();
|
||||
} else {
|
||||
menu_set_sensitive_undo(FALSE);
|
||||
draw_next_balls();
|
||||
}
|
||||
}
|
||||
|
||||
void remake_board(gint numoldchilds, gboolean isnextvalid) {
|
||||
gint cxs, cys, i;
|
||||
gint cxs, cys, i;
|
||||
|
||||
if(numoldchilds && numoldchilds != rules_get_next()) {
|
||||
if(_small_balls) {
|
||||
for(i = 0; i < numoldchilds; i++) {
|
||||
gtk_widget_destroy(_small_balls[i]);
|
||||
}
|
||||
}
|
||||
_small_balls = g_realloc(_small_balls, rules_get_next() * sizeof(GtkWidget *));
|
||||
for(i = 0; i < rules_get_next(); i++) {
|
||||
if(isnextvalid) {
|
||||
_small_balls[i] = gtk_image_new_from_pixbuf(gtkbTheme->balls[next_get(i) - 1].small.pixbuf);
|
||||
} else {
|
||||
_small_balls[i] = gtk_image_new_from_pixbuf(gtkbTheme->balls[0].small.pixbuf);
|
||||
}
|
||||
mw_small_balls_add(_small_balls[i]);
|
||||
}
|
||||
mw_show_hide_next_balls(pref_get_show_next_colors());
|
||||
}
|
||||
if (numoldchilds && numoldchilds != rules_get_next())
|
||||
{
|
||||
if (_small_balls) {
|
||||
for (i = 0; i < numoldchilds; i++) {
|
||||
gtk_widget_destroy(_small_balls[i]);
|
||||
}
|
||||
}
|
||||
_small_balls = g_realloc(_small_balls, rules_get_next() * sizeof(GtkWidget *));
|
||||
for (i = 0; i < rules_get_next(); i++) {
|
||||
if (isnextvalid) {
|
||||
_small_balls[i] = gtk_image_new_from_pixbuf(gtkbTheme->balls[next_get(i) - 1].small.pixbuf);
|
||||
} else {
|
||||
_small_balls[i] = gtk_image_new_from_pixbuf(gtkbTheme->balls[0].small.pixbuf);
|
||||
}
|
||||
mw_small_balls_add(_small_balls[i]);
|
||||
}
|
||||
mw_show_hide_next_balls(pref_get_show_next_colors());
|
||||
}
|
||||
|
||||
cxs = gtkbTheme->emptycell.xsize;
|
||||
cys = gtkbTheme->emptycell.ysize;
|
||||
gtk_widget_set_size_request(mw_get_da(), rules_get_width() * cxs, rules_get_height() * cys);
|
||||
if(_pixmap) {
|
||||
g_object_unref(_pixmap);
|
||||
}
|
||||
_pixmap = gdk_pixmap_new(mw_get_da()->window, rules_get_width() * cxs, rules_get_height() * cys, -1);
|
||||
draw_board();
|
||||
cxs = gtkbTheme->emptycell.xsize;
|
||||
cys = gtkbTheme->emptycell.ysize;
|
||||
gtk_widget_set_size_request(mw_get_da(), rules_get_width() * cxs, rules_get_height() * cys);
|
||||
if (_pixmap) {
|
||||
g_object_unref(_pixmap);
|
||||
}
|
||||
_pixmap = gdk_pixmap_new(mw_get_da()->window, rules_get_width() * cxs, rules_get_height() * cys, -1);
|
||||
draw_board();
|
||||
}
|
||||
|
||||
void draw_next_balls(void) {
|
||||
gint i;
|
||||
gint i;
|
||||
|
||||
for(i = 0; i < rules_get_next(); i++) {
|
||||
gtk_image_set_from_pixbuf(GTK_IMAGE(_small_balls[i]), gtkbTheme->balls[next_get(i) - 1].small.pixbuf);
|
||||
}
|
||||
for (i = 0; i < rules_get_next(); i++) {
|
||||
gtk_image_set_from_pixbuf(GTK_IMAGE(_small_balls[i]), gtkbTheme->balls[next_get(i) - 1].small.pixbuf);
|
||||
}
|
||||
}
|
||||
|
||||
/* Refill the screen from the backing pixmap */
|
||||
gint expose_event(GtkWidget *widget, GdkEventExpose *event) {
|
||||
GdkRectangle *rects;
|
||||
int n_rects;
|
||||
int i;
|
||||
GdkRectangle *rects;
|
||||
int n_rects;
|
||||
int i;
|
||||
|
||||
gdk_region_get_rectangles(event->region, &rects, &n_rects);
|
||||
gdk_region_get_rectangles(event->region, &rects, &n_rects);
|
||||
|
||||
for(i = 0; i < n_rects; i++) {
|
||||
gdk_draw_drawable (gtk_widget_get_window (widget),
|
||||
widget->style->fg_gc[gtk_widget_get_state(widget)],
|
||||
_pixmap, rects[i].x, rects[i].y, rects[i].x, rects[i].y,
|
||||
rects[i].width, rects[i].height);
|
||||
}
|
||||
for (i = 0; i < n_rects; i++) {
|
||||
gdk_draw_drawable (gtk_widget_get_window (widget),
|
||||
widget->style->fg_gc[gtk_widget_get_state(widget)],
|
||||
_pixmap, rects[i].x, rects[i].y, rects[i].x, rects[i].y,
|
||||
rects[i].width, rects[i].height);
|
||||
}
|
||||
|
||||
g_free (rects);
|
||||
g_free (rects);
|
||||
|
||||
return FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void find_pawnum_and_direction(gint pawx, gint pawy, gint x, gint y, gint *pawnum, gint *direction) {
|
||||
if(pawy < y) {
|
||||
*pawnum = 2;
|
||||
if(*direction == 1) *pawnum = 6;
|
||||
if(*direction == 3) *pawnum = 7;
|
||||
*direction = 2; /* up */
|
||||
} else if(pawy > y) {
|
||||
*pawnum = 0;
|
||||
if(*direction == 1) *pawnum = 4;
|
||||
if(*direction == 3) *pawnum = 5;
|
||||
*direction = 0; /* down */
|
||||
} else if(pawx < x) {
|
||||
*pawnum = 1;
|
||||
if(*direction == 0) *pawnum = 4;
|
||||
if(*direction == 2) *pawnum = 6;
|
||||
*direction = 1; /* left */
|
||||
} else if(pawx > x) {
|
||||
*pawnum = 3;
|
||||
if(*direction == 0) *pawnum = 5;
|
||||
if(*direction == 2) *pawnum = 7;
|
||||
*direction = 3; /* right */
|
||||
}
|
||||
void find_pawnum_and_direction(gint pawx, gint pawy, gint x, gint y, gint *pawnum, gint *direction)
|
||||
{
|
||||
if (pawy < y) {
|
||||
*pawnum = 2;
|
||||
if (*direction == 1) *pawnum = 6;
|
||||
if (*direction == 3) *pawnum = 7;
|
||||
*direction = 2; /* up */
|
||||
} else if (pawy > y) {
|
||||
*pawnum = 0;
|
||||
if (*direction == 1) *pawnum = 4;
|
||||
if (*direction == 3) *pawnum = 5;
|
||||
*direction = 0; /* down */
|
||||
} else if (pawx < x) {
|
||||
*pawnum = 1;
|
||||
if (*direction == 0) *pawnum = 4;
|
||||
if (*direction == 2) *pawnum = 6;
|
||||
*direction = 1; /* left */
|
||||
} else if (pawx > x) {
|
||||
*pawnum = 3;
|
||||
if (*direction == 0) *pawnum = 5;
|
||||
if (*direction == 2) *pawnum = 7;
|
||||
*direction = 3; /* right */
|
||||
}
|
||||
}
|
||||
|
||||
gint find_direction(gint pawx, gint pawy, gint x, gint y) {
|
||||
if(pawy < y) return 2; /* up */
|
||||
if(pawy > y) return 0; /* down */
|
||||
if(pawx < x) return 1; /* left */
|
||||
if(pawx > x) return 3; /* right */
|
||||
return -1; /* should never happens */
|
||||
if (pawy < y) return 2; /* up */
|
||||
if (pawy > y) return 0; /* down */
|
||||
if (pawx < x) return 1; /* left */
|
||||
if (pawx > x) return 3; /* right */
|
||||
return -1; /* should never happens */
|
||||
}
|
||||
|
||||
/* FIXME: remake it properly =/ */
|
||||
gboolean have_path(gint source_ball, gint target_ball) {
|
||||
gint nodes[rules_get_width() * rules_get_height()];
|
||||
gint path[rules_get_width() * rules_get_height()];
|
||||
gint *np = nodes;
|
||||
gint i;
|
||||
gint nodes[rules_get_width() * rules_get_height()];
|
||||
gint path[rules_get_width() * rules_get_height()];
|
||||
gint *np = nodes;
|
||||
gint i;
|
||||
|
||||
for(i = 0; i < rules_get_height() * rules_get_width(); i++) {
|
||||
*np++ = board_get_at_node(i) > 0 ? -1 : 0;
|
||||
}
|
||||
nodes[source_ball] = nodes[target_ball] = 0;
|
||||
if(!find_path(nodes, source_ball, target_ball, path, rules_get_width(), rules_get_height())) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
for (i = 0; i < rules_get_height() * rules_get_width(); i++) {
|
||||
*np++ = board_get_at_node(i) > 0 ? -1 : 0;
|
||||
}
|
||||
nodes[source_ball] = nodes[target_ball] = 0;
|
||||
if (!find_path(nodes, source_ball, target_ball, path, rules_get_width(), rules_get_height())) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void move_ball(gint source_ball, gint target_ball) {
|
||||
gint nodes[rules_get_width() * rules_get_height()];
|
||||
gint path[rules_get_width() * rules_get_height()];
|
||||
gint pawx = -1, pawy = -1;
|
||||
gint i, j, k, phase, blah;
|
||||
gint x, y, color, tbx, tby, bc = board_get_at_node(_jumping_ball);
|
||||
gint direction, pawnum;
|
||||
gint *np = nodes;
|
||||
struct timeval tvs, tve;
|
||||
void move_ball(gint source_ball, gint target_ball)
|
||||
{
|
||||
gint nodes[rules_get_width() * rules_get_height()];
|
||||
gint path[rules_get_width() * rules_get_height()];
|
||||
gint pawx = -1, pawy = -1;
|
||||
gint i, j, k, phase, blah;
|
||||
gint x, y, color, tbx, tby, bc = board_get_at_node(_jumping_ball);
|
||||
gint direction, pawnum;
|
||||
gint *np = nodes;
|
||||
struct timeval tvs, tve;
|
||||
|
||||
g_assert(board_get_at_node(target_ball) == 0);
|
||||
find_x_y_of_the_node(&tbx, &tby, target_ball, rules_get_width(), rules_get_height());
|
||||
g_assert(board_get_at_node(target_ball) == 0);
|
||||
find_x_y_of_the_node(&tbx, &tby, target_ball, rules_get_width(), rules_get_height());
|
||||
|
||||
for(blah = 0; blah < rules_get_height() * rules_get_width(); blah++) {
|
||||
*np++ = board_get_at_node(blah) > 0 ? -1 : 0;
|
||||
}
|
||||
for (blah = 0; blah < rules_get_height() * rules_get_width(); blah++) {
|
||||
*np++ = board_get_at_node(blah) > 0 ? -1 : 0;
|
||||
}
|
||||
|
||||
nodes[source_ball] = nodes[target_ball] = 0;
|
||||
g_assert(find_path(nodes, source_ball, target_ball, path, rules_get_width(), rules_get_height()) == 1);
|
||||
nodes[source_ball] = nodes[target_ball] = 0;
|
||||
g_assert(find_path(nodes, source_ball, target_ball, path, rules_get_width(), rules_get_height()) == 1);
|
||||
|
||||
find_x_y_of_the_node(&x, &y, source_ball, rules_get_width(), rules_get_height());
|
||||
color = board_get_at_node(source_ball);
|
||||
board_set_at_node(source_ball, 0);
|
||||
phase = 0;
|
||||
find_x_y_of_the_node(&x, &y, source_ball, rules_get_width(), rules_get_height());
|
||||
color = board_get_at_node(source_ball);
|
||||
board_set_at_node(source_ball, 0);
|
||||
phase = 0;
|
||||
|
||||
draw_ball(0, x, y, 0, 0);
|
||||
if(pref_get_show_path()) {
|
||||
lock_actions(1);
|
||||
for(k = path[0] - 1; k; k--) {
|
||||
gettimeofday(&tvs, NULL);
|
||||
find_x_y_of_the_node(&i, &j, path[k], rules_get_width(), rules_get_height());
|
||||
if(k == path[0] - 1) {
|
||||
/* x and y are the coordinates of starting position */
|
||||
pawx = x;
|
||||
pawy = y;
|
||||
} else {
|
||||
find_x_y_of_the_node(&pawx, &pawy, path[k + 1], rules_get_width(), rules_get_height());
|
||||
}
|
||||
if(k != path[0] - 1) {
|
||||
find_pawnum_and_direction(pawx, pawy, i, j, &pawnum, &direction);
|
||||
} else {
|
||||
pawnum = direction = find_direction(pawx, pawy, i, j);
|
||||
}
|
||||
if(pref_get_show_footprints()) {
|
||||
board_set_at_xy(pawx, pawy, -1 - pawnum);
|
||||
draw_ball(-1 - pawnum, pawx, pawy, 0, 0);
|
||||
}
|
||||
board_set_at_xy(i, j, bc);
|
||||
draw_ball(bc, i, j, 0, 0);
|
||||
do {
|
||||
gtk_main_iteration_do(0);
|
||||
gettimeofday(&tve, NULL);
|
||||
} while((tve.tv_sec - tvs.tv_sec) * 1000000 + tve.tv_usec - tvs.tv_usec < 100000);
|
||||
board_set_at_xy(i, j, 0);
|
||||
draw_ball(0, i, j, 0, 0);
|
||||
}
|
||||
lock_actions(0);
|
||||
if(k == path[0] - 1) {
|
||||
/* x and y are the coordinates of starting position */
|
||||
pawx = x;
|
||||
pawy = y;
|
||||
} else {
|
||||
find_x_y_of_the_node(&pawx, &pawy, path[k + 1], rules_get_width(), rules_get_height());
|
||||
}
|
||||
if (pref_get_show_footprints()) {
|
||||
find_pawnum_and_direction(pawx, pawy, tbx, tby, &pawnum, &direction);
|
||||
board_set_at_xy(pawx, pawy, -1 - pawnum);
|
||||
draw_ball(-1 - pawnum, pawx, pawy, 0, 0);
|
||||
}
|
||||
}
|
||||
if(pref_get_show_path() && pref_get_show_footprints()) {
|
||||
board_set_at_node(source_ball, 0);
|
||||
for(k = path[0] - 1; k; k--) {
|
||||
board_set_at_node(path[k], 0);
|
||||
}
|
||||
}
|
||||
board_set_at_node(target_ball, color);
|
||||
draw_ball(color, tbx, tby, 0, 0);
|
||||
draw_ball(0, x, y, 0, 0);
|
||||
if (pref_get_show_path())
|
||||
{
|
||||
lock_actions(1);
|
||||
for (k = path[0] - 1; k; k--)
|
||||
{
|
||||
gettimeofday(&tvs, NULL);
|
||||
find_x_y_of_the_node(&i, &j, path[k], rules_get_width(), rules_get_height());
|
||||
if (k == path[0] - 1) {
|
||||
/* x and y are the coordinates of starting position */
|
||||
pawx = x;
|
||||
pawy = y;
|
||||
} else {
|
||||
find_x_y_of_the_node(&pawx, &pawy, path[k + 1], rules_get_width(), rules_get_height());
|
||||
}
|
||||
if (k != path[0] - 1) {
|
||||
find_pawnum_and_direction(pawx, pawy, i, j, &pawnum, &direction);
|
||||
} else {
|
||||
pawnum = direction = find_direction(pawx, pawy, i, j);
|
||||
}
|
||||
if (pref_get_show_footprints()) {
|
||||
board_set_at_xy(pawx, pawy, -1 - pawnum);
|
||||
draw_ball(-1 - pawnum, pawx, pawy, 0, 0);
|
||||
}
|
||||
board_set_at_xy(i, j, bc);
|
||||
draw_ball(bc, i, j, 0, 0);
|
||||
do {
|
||||
gtk_main_iteration_do(0);
|
||||
gettimeofday(&tve, NULL);
|
||||
} while ((tve.tv_sec - tvs.tv_sec) * 1000000 + tve.tv_usec - tvs.tv_usec < 100000);
|
||||
board_set_at_xy(i, j, 0);
|
||||
draw_ball(0, i, j, 0, 0);
|
||||
}
|
||||
lock_actions(0);
|
||||
if (k == path[0] - 1) {
|
||||
/* x and y are the coordinates of starting position */
|
||||
pawx = x;
|
||||
pawy = y;
|
||||
} else {
|
||||
find_x_y_of_the_node(&pawx, &pawy, path[k + 1], rules_get_width(), rules_get_height());
|
||||
}
|
||||
if (pref_get_show_footprints()) {
|
||||
find_pawnum_and_direction(pawx, pawy, tbx, tby, &pawnum, &direction);
|
||||
board_set_at_xy(pawx, pawy, -1 - pawnum);
|
||||
draw_ball(-1 - pawnum, pawx, pawy, 0, 0);
|
||||
}
|
||||
}
|
||||
if (pref_get_show_path() && pref_get_show_footprints()) {
|
||||
board_set_at_node(source_ball, 0);
|
||||
for (k = path[0] - 1; k; k--) {
|
||||
board_set_at_node(path[k], 0);
|
||||
}
|
||||
}
|
||||
board_set_at_node(target_ball, color);
|
||||
draw_ball(color, tbx, tby, 0, 0);
|
||||
}
|
||||
|
16
src/gfx.h
16
src/gfx.h
@ -2,14 +2,14 @@
|
||||
#define __GFX__H
|
||||
|
||||
typedef enum {
|
||||
DIR_LEFT,
|
||||
DIR_RIGHT,
|
||||
DIR_UP,
|
||||
DIR_DOWN,
|
||||
DIR_UP_LEFT,
|
||||
DIR_DOWN_LEFT,
|
||||
DIR_UP_RIGHT,
|
||||
DIR_DOWN_RIGHT
|
||||
DIR_LEFT,
|
||||
DIR_RIGHT,
|
||||
DIR_UP,
|
||||
DIR_DOWN,
|
||||
DIR_UP_LEFT,
|
||||
DIR_DOWN_LEFT,
|
||||
DIR_UP_RIGHT,
|
||||
DIR_DOWN_RIGHT
|
||||
} Direction;
|
||||
|
||||
void draw_next_balls(void);
|
||||
|
249
src/gtkballs.c
249
src/gtkballs.c
@ -24,161 +24,166 @@
|
||||
#include "mainwin.h"
|
||||
|
||||
gint destroy_lines(gboolean count_score) {
|
||||
gint i = game_destroy_lines(count_score);
|
||||
if(count_score && i) {
|
||||
gint ml = rules_get_destroy();
|
||||
gint sc = game_get_score();
|
||||
gint nsc = sc + ml * 2 + (i - ml) * (i - ml) * 2 + (1 - pref_get_show_next_colors());
|
||||
mw_set_user_score(nsc);
|
||||
}
|
||||
draw_board();
|
||||
return i;
|
||||
gint i = game_destroy_lines(count_score);
|
||||
if (count_score && i) {
|
||||
gint ml = rules_get_destroy();
|
||||
gint sc = game_get_score();
|
||||
gint nsc = sc + ml * 2 + (i - ml) * (i - ml) * 2 + (1 - pref_get_show_next_colors());
|
||||
mw_set_user_score(nsc);
|
||||
}
|
||||
draw_board();
|
||||
return i;
|
||||
}
|
||||
|
||||
void undo_move(GtkWidget *widget, gpointer data) {
|
||||
game_restore_state_from_undo();
|
||||
stop_jumping_animation();
|
||||
mw_set_hi_score(game_get_hi_score());
|
||||
mw_set_user_score(game_get_score());
|
||||
menu_set_sensitive_undo(FALSE);
|
||||
draw_board();
|
||||
draw_next_balls();
|
||||
game_restore_state_from_undo();
|
||||
stop_jumping_animation();
|
||||
mw_set_hi_score(game_get_hi_score());
|
||||
mw_set_user_score(game_get_score());
|
||||
menu_set_sensitive_undo(FALSE);
|
||||
draw_board();
|
||||
draw_next_balls();
|
||||
}
|
||||
|
||||
gint random_color(void) {
|
||||
return (gint)(((gfloat)rules_get_colors()) * rand() / (RAND_MAX + 1.0));
|
||||
return (gint)(((gfloat)rules_get_colors()) * rand() / (RAND_MAX + 1.0));
|
||||
}
|
||||
|
||||
gint random_cell(void) {
|
||||
return (gint)(((gfloat)rules_get_width() * rules_get_height()) * rand() / (RAND_MAX + 1.0));
|
||||
return (gint)(((gfloat)rules_get_width() * rules_get_height()) * rand() / (RAND_MAX + 1.0));
|
||||
}
|
||||
|
||||
void new_turn(gint number, gboolean first) {
|
||||
gint i, k = 0, free_cells_number, c;
|
||||
struct score_board scoreboard[10];
|
||||
void new_turn(gint number, gboolean first)
|
||||
{
|
||||
gint i, k = 0, free_cells_number, c;
|
||||
struct score_board scoreboard[10];
|
||||
|
||||
do {
|
||||
timer_start();
|
||||
do {
|
||||
timer_start();
|
||||
|
||||
k = 0;
|
||||
if(number < rules_get_next()) {
|
||||
number = rules_get_next();
|
||||
}
|
||||
k = 0;
|
||||
if (number < rules_get_next()) {
|
||||
number = rules_get_next();
|
||||
}
|
||||
|
||||
if((free_cells_number = game_count_free_cells()) <= number) {
|
||||
if(!read_score(scoreboard, NULL, NULL) ||
|
||||
game_get_score() > scoreboard[9].score) {
|
||||
input_name_dialog();
|
||||
}
|
||||
new_game();
|
||||
return;
|
||||
}
|
||||
if ((free_cells_number = game_count_free_cells()) <= number) {
|
||||
if (!read_score(scoreboard, NULL, NULL) ||
|
||||
game_get_score() > scoreboard[9].score) {
|
||||
input_name_dialog();
|
||||
}
|
||||
new_game();
|
||||
return;
|
||||
}
|
||||
|
||||
do {
|
||||
i = random_cell();
|
||||
if(board_get_at_node(i) < 1) {
|
||||
if(first) {
|
||||
c = 1 + random_color();
|
||||
board_set_at_node(i, c);
|
||||
} else {
|
||||
board_set_at_node(i, next_get(k));
|
||||
}
|
||||
k++;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
/* I hope that k!=0 */
|
||||
if(k <= rules_get_next()) {
|
||||
next_set(k - 1, 1 + random_color());
|
||||
}
|
||||
} while(k < ((number < free_cells_number) ? number : free_cells_number));
|
||||
do {
|
||||
i = random_cell();
|
||||
if (board_get_at_node(i) < 1) {
|
||||
if (first) {
|
||||
c = 1 + random_color();
|
||||
board_set_at_node(i, c);
|
||||
} else {
|
||||
board_set_at_node(i, next_get(k));
|
||||
}
|
||||
k++;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
/* I hope that k!=0 */
|
||||
if (k <= rules_get_next()) {
|
||||
next_set(k - 1, 1 + random_color());
|
||||
}
|
||||
} while (k < ((number < free_cells_number) ? number : free_cells_number));
|
||||
|
||||
if(!first) {
|
||||
draw_next_balls();
|
||||
/* if line complete, don't increase user's score--it's not his merit */
|
||||
destroy_lines(FALSE);
|
||||
}
|
||||
} while((free_cells_number = game_count_free_cells()) == rules_get_width() * rules_get_height());
|
||||
if (!first) {
|
||||
draw_next_balls();
|
||||
/* if line complete, don't increase user's score--it's not his merit */
|
||||
destroy_lines(FALSE);
|
||||
}
|
||||
} while ((free_cells_number = game_count_free_cells()) == rules_get_width() * rules_get_height());
|
||||
}
|
||||
|
||||
void new_game(void){
|
||||
stop_jumping_animation();
|
||||
game_init_game(NULL, NULL);
|
||||
menu_set_sensitive_undo(FALSE);
|
||||
new_turn(rules_get_destroy(), TRUE);
|
||||
mw_set_user_score(0);
|
||||
draw_next_balls();
|
||||
draw_board();
|
||||
void new_game(void)
|
||||
{
|
||||
stop_jumping_animation();
|
||||
game_init_game(NULL, NULL);
|
||||
menu_set_sensitive_undo(FALSE);
|
||||
new_turn(rules_get_destroy(), TRUE);
|
||||
mw_set_user_score(0);
|
||||
draw_next_balls();
|
||||
draw_board();
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
gint i;
|
||||
struct timeval tv;
|
||||
struct timezone tz;
|
||||
struct score_board scoreboard[10];
|
||||
gchar *err, *mapfile;
|
||||
|
||||
/* setup all i18n stuff */
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
gint i;
|
||||
struct timeval tv;
|
||||
struct timezone tz;
|
||||
struct score_board scoreboard[10];
|
||||
gchar *err, *mapfile;
|
||||
|
||||
/* setup all i18n stuff */
|
||||
#ifdef ENABLE_NLS
|
||||
bindtextdomain (PACKAGE, LOCALEDIR);
|
||||
textdomain (PACKAGE);
|
||||
bind_textdomain_codeset(PACKAGE, "UTF8");
|
||||
bindtextdomain (PACKAGE, LOCALEDIR);
|
||||
textdomain (PACKAGE);
|
||||
bind_textdomain_codeset(PACKAGE, "UTF8");
|
||||
#endif /* ENABLE_NLS */
|
||||
|
||||
/* drop privileges after spawning child with extra privs */
|
||||
if(score_setup() == -1) return 1;
|
||||
setregid(getgid(), getgid());
|
||||
/* drop privileges after spawning child with extra privs */
|
||||
if (score_setup() == -1)
|
||||
return 1;
|
||||
setregid(getgid(), getgid());
|
||||
|
||||
/* initialize random seed */
|
||||
gettimeofday(&tv, &tz);
|
||||
srand((unsigned int)tv.tv_usec);
|
||||
/* initialize random seed */
|
||||
gettimeofday(&tv, &tz);
|
||||
srand((unsigned int)tv.tv_usec);
|
||||
|
||||
/* load user's preferences */
|
||||
load_preferences();
|
||||
/* load user's preferences */
|
||||
load_preferences();
|
||||
|
||||
/* initialize gtk */
|
||||
gtk_init(&argc, &argv);
|
||||
/* initialize gtk */
|
||||
gtk_init (&argc, &argv);
|
||||
|
||||
/* load theme, fallback to default if specifed theme cannot be loaded */
|
||||
if(!(i = load_theme(pref_get_theme_name()))) {
|
||||
if(strcmp(pref_get_theme_name(), pref_get_default_theme_name()) != 0) {
|
||||
err = g_strdup_printf(_("Failed loading theme \"%s\"! Trying \"%s\"\n"), pref_get_theme_name(), pref_get_default_theme_name());
|
||||
ut_simple_message_box(err);
|
||||
g_free(err);
|
||||
pref_set_theme_name(pref_get_default_theme_name());
|
||||
i = load_theme(pref_get_theme_name());
|
||||
}
|
||||
if(!i) {
|
||||
err = g_strdup_printf(_("Failed loading theme \"%s\"! Exiting.\n"), pref_get_theme_name());
|
||||
ut_simple_message_box(err);
|
||||
g_free(err);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
/* load theme, fallback to default if specifed theme cannot be loaded */
|
||||
if (!(i = load_theme(pref_get_theme_name()))) {
|
||||
if (strcmp(pref_get_theme_name(), pref_get_default_theme_name()) != 0) {
|
||||
err = g_strdup_printf(_("Failed loading theme \"%s\"! Trying \"%s\"\n"), pref_get_theme_name(), pref_get_default_theme_name());
|
||||
ut_simple_message_box(err);
|
||||
g_free(err);
|
||||
pref_set_theme_name(pref_get_default_theme_name());
|
||||
i = load_theme(pref_get_theme_name());
|
||||
}
|
||||
if (!i) {
|
||||
err = g_strdup_printf(_("Failed loading theme \"%s\"! Exiting.\n"), pref_get_theme_name());
|
||||
ut_simple_message_box(err);
|
||||
g_free(err);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* create main application window */
|
||||
mw_create(rules_get_width() * theme_get_width(), rules_get_height() * theme_get_height());
|
||||
/* create main application window */
|
||||
mw_create(rules_get_width() * theme_get_width(), rules_get_height() * theme_get_height());
|
||||
|
||||
/* initialize and start new game */
|
||||
game_init_game(NULL, NULL);
|
||||
new_turn(rules_get_destroy(), TRUE);
|
||||
remake_board(-1, 1);
|
||||
/* initialize and start new game */
|
||||
game_init_game(NULL, NULL);
|
||||
new_turn(rules_get_destroy(), TRUE);
|
||||
remake_board(-1, 1);
|
||||
|
||||
/* read and set scores */
|
||||
if(!read_score(scoreboard, NULL, NULL)) {
|
||||
ut_simple_message_box(_("Unable to read score.\n"));
|
||||
}
|
||||
mw_set_hi_score(scoreboard[0].score);
|
||||
mw_set_user_score(0);
|
||||
/* read and set scores */
|
||||
if (!read_score(scoreboard, NULL, NULL)) {
|
||||
ut_simple_message_box(_("Unable to read score.\n"));
|
||||
}
|
||||
mw_set_hi_score(scoreboard[0].score);
|
||||
mw_set_user_score(0);
|
||||
|
||||
mapfile = g_strconcat(getenv("HOME"), G_DIR_SEPARATOR_S, ".gtkballs",
|
||||
G_DIR_SEPARATOR_S, "accel.map", NULL);
|
||||
gtk_accel_map_load(mapfile);
|
||||
mapfile = g_strconcat(getenv("HOME"), G_DIR_SEPARATOR_S, ".gtkballs",
|
||||
G_DIR_SEPARATOR_S, "accel.map", NULL);
|
||||
gtk_accel_map_load (mapfile);
|
||||
|
||||
/* enter main application loop */
|
||||
gtk_main();
|
||||
/* enter main application loop */
|
||||
gtk_main();
|
||||
|
||||
gtk_accel_map_save(mapfile);
|
||||
gtk_accel_map_save (mapfile);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
169
src/gtkutils.c
169
src/gtkutils.c
@ -8,121 +8,138 @@
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
|
||||
gboolean ut_key_pressed_cb(GtkWidget *widget, GdkEventKey *event) {
|
||||
if(widget && event && event->keyval == GDK_Escape) {
|
||||
gtk_widget_destroy(widget);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
gboolean ut_key_pressed_cb(GtkWidget *widget, GdkEventKey *event)
|
||||
{
|
||||
if(widget && event && event->keyval == GDK_Escape) {
|
||||
gtk_widget_destroy(widget);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
GtkWidget *ut_window_new(gchar *title, gchar *wmname, gchar *wmclass,
|
||||
gboolean escaable, gboolean modal, gboolean resizable,
|
||||
gint border) {
|
||||
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_modal(GTK_WINDOW(window), modal);
|
||||
gtk_window_set_resizable(GTK_WINDOW(window), resizable);
|
||||
gtk_window_set_title(GTK_WINDOW(window), title);
|
||||
gtk_window_set_role(GTK_WINDOW(window), wmname);
|
||||
if(escaable) {
|
||||
g_signal_connect(G_OBJECT(window), "key_press_event", G_CALLBACK(ut_key_pressed_cb), NULL);
|
||||
}
|
||||
gtk_container_set_border_width(GTK_CONTAINER(window), border);
|
||||
return window;
|
||||
gboolean escaable, gboolean modal, gboolean resizable,
|
||||
gint border)
|
||||
{
|
||||
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_modal(GTK_WINDOW(window), modal);
|
||||
gtk_window_set_resizable(GTK_WINDOW(window), resizable);
|
||||
gtk_window_set_title(GTK_WINDOW(window), title);
|
||||
gtk_window_set_role(GTK_WINDOW(window), wmname);
|
||||
if(escaable) {
|
||||
g_signal_connect(G_OBJECT(window), "key_press_event", G_CALLBACK(ut_key_pressed_cb), NULL);
|
||||
}
|
||||
gtk_container_set_border_width(GTK_CONTAINER(window), border);
|
||||
return window;
|
||||
}
|
||||
|
||||
GtkWidget *ut_check_button_new(gchar *label, gboolean active, GtkWidget *parent) {
|
||||
GtkWidget *button;
|
||||
|
||||
button = gtk_check_button_new_with_label(label);
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), active);
|
||||
gtk_box_pack_start(GTK_BOX(parent), button, FALSE, FALSE, 0);
|
||||
GtkWidget *ut_check_button_new(gchar *label, gboolean active, GtkWidget *parent)
|
||||
{
|
||||
GtkWidget *button;
|
||||
|
||||
return button;
|
||||
button = gtk_check_button_new_with_label(label);
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), active);
|
||||
gtk_box_pack_start(GTK_BOX(parent), button, FALSE, FALSE, 0);
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
GtkWidget *ut_button_new(gchar *label, gpointer func, gpointer func_data, GtkWidget *parent) {
|
||||
GtkWidget *button;
|
||||
|
||||
button = gtk_button_new_with_label(label);
|
||||
g_signal_connect(G_OBJECT(button), "clicked", func, func_data);
|
||||
gtk_box_pack_start(GTK_BOX(parent), button, TRUE, TRUE, 0);
|
||||
gtk_widget_set_can_default (button, TRUE);
|
||||
GtkWidget *ut_button_new(gchar *label, gpointer func, gpointer func_data, GtkWidget *parent)
|
||||
{
|
||||
GtkWidget *button;
|
||||
|
||||
return button;
|
||||
button = gtk_button_new_with_label(label);
|
||||
g_signal_connect(G_OBJECT(button), "clicked", func, func_data);
|
||||
gtk_box_pack_start(GTK_BOX(parent), button, TRUE, TRUE, 0);
|
||||
gtk_widget_set_can_default (button, TRUE);
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
GtkWidget *ut_button_new_stock(const gchar *stock_id, gpointer func, gpointer func_data, GtkWidget *parent) {
|
||||
GtkWidget *button;
|
||||
|
||||
button = gtk_button_new_from_stock(stock_id);
|
||||
g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(func), func_data);
|
||||
gtk_box_pack_start(GTK_BOX(parent), button, TRUE, TRUE, 0);
|
||||
gtk_widget_set_can_default (button, TRUE);
|
||||
GtkWidget *ut_button_new_stock(const gchar *stock_id, gpointer func, gpointer func_data, GtkWidget *parent)
|
||||
{
|
||||
GtkWidget *button;
|
||||
|
||||
return button;
|
||||
button = gtk_button_new_from_stock(stock_id);
|
||||
g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(func), func_data);
|
||||
gtk_box_pack_start(GTK_BOX(parent), button, TRUE, TRUE, 0);
|
||||
gtk_widget_set_can_default (button, TRUE);
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
GtkWidget *ut_button_new_stock_swap(const gchar *stock_id, gpointer func, gpointer func_data, GtkWidget *parent) {
|
||||
GtkWidget *button;
|
||||
|
||||
button = gtk_button_new_from_stock(stock_id);
|
||||
g_signal_connect_swapped(G_OBJECT(button), "clicked", G_CALLBACK(func), func_data);
|
||||
gtk_box_pack_start(GTK_BOX(parent), button, TRUE, TRUE, 0);
|
||||
gtk_widget_set_can_default (button, TRUE);
|
||||
GtkWidget *ut_button_new_stock_swap(const gchar *stock_id, gpointer func, gpointer func_data, GtkWidget *parent)
|
||||
{
|
||||
GtkWidget *button;
|
||||
|
||||
return button;
|
||||
button = gtk_button_new_from_stock(stock_id);
|
||||
g_signal_connect_swapped(G_OBJECT(button), "clicked", G_CALLBACK(func), func_data);
|
||||
gtk_box_pack_start(GTK_BOX(parent), button, TRUE, TRUE, 0);
|
||||
gtk_widget_set_can_default (button, TRUE);
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
GtkWidget *ut_spin_button_new(gchar *label, gint min, gint max, gint val, GtkWidget *parent) {
|
||||
GtkAdjustment *adj;
|
||||
GtkWidget *button, *hbox, *labelw;
|
||||
|
||||
hbox = gtk_hbox_new(FALSE, 0);
|
||||
gtk_box_pack_start(GTK_BOX(parent), hbox, TRUE, TRUE, 2);
|
||||
GtkWidget *ut_spin_button_new(gchar *label, gint min, gint max, gint val, GtkWidget *parent)
|
||||
{
|
||||
GtkAdjustment *adj;
|
||||
GtkWidget *button, *hbox, *labelw;
|
||||
|
||||
labelw = gtk_label_new(label);
|
||||
gtk_box_pack_start(GTK_BOX(hbox), labelw, FALSE, FALSE, 5);
|
||||
hbox = gtk_hbox_new(FALSE, 0);
|
||||
gtk_box_pack_start(GTK_BOX(parent), hbox, TRUE, TRUE, 2);
|
||||
|
||||
adj = GTK_ADJUSTMENT (gtk_adjustment_new(val, min, max, 1, 10, 10));
|
||||
button = gtk_spin_button_new(adj, 1, 0);
|
||||
gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(button), TRUE);
|
||||
gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 5);
|
||||
labelw = gtk_label_new(label);
|
||||
gtk_box_pack_start(GTK_BOX(hbox), labelw, FALSE, FALSE, 5);
|
||||
|
||||
return button;
|
||||
adj = GTK_ADJUSTMENT (gtk_adjustment_new(val, min, max, 1, 10, 10));
|
||||
button = gtk_spin_button_new(adj, 1, 0);
|
||||
gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(button), TRUE);
|
||||
gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 5);
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
|
||||
GtkWidget *ut_spin_button_start_new(gchar *label, gint min, gint max, gint val, GtkWidget *parent)
|
||||
{
|
||||
GtkAdjustment *adj;
|
||||
GtkWidget *button, *hbox, *labelw;
|
||||
GtkAdjustment *adj;
|
||||
GtkWidget *button, *hbox, *labelw;
|
||||
|
||||
hbox = gtk_hbox_new(FALSE, 0);
|
||||
gtk_box_pack_start(GTK_BOX(parent), hbox, TRUE, TRUE, 2);
|
||||
hbox = gtk_hbox_new(FALSE, 0);
|
||||
gtk_box_pack_start(GTK_BOX(parent), hbox, TRUE, TRUE, 2);
|
||||
|
||||
labelw = gtk_label_new(label);
|
||||
gtk_box_pack_start(GTK_BOX(hbox), labelw, FALSE, FALSE, 5);
|
||||
labelw = gtk_label_new(label);
|
||||
gtk_box_pack_start(GTK_BOX(hbox), labelw, FALSE, FALSE, 5);
|
||||
|
||||
adj = GTK_ADJUSTMENT (gtk_adjustment_new(val, min, max, 1, 10, 10));
|
||||
button = gtk_spin_button_new(adj, 1, 0);
|
||||
gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(button), TRUE);
|
||||
gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 5);
|
||||
adj = GTK_ADJUSTMENT (gtk_adjustment_new(val, min, max, 1, 10, 10));
|
||||
button = gtk_spin_button_new(adj, 1, 0);
|
||||
gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(button), TRUE);
|
||||
gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 5);
|
||||
|
||||
return button;
|
||||
return button;
|
||||
}
|
||||
|
||||
|
||||
/* shows simple message box */
|
||||
void ut_simple_message_box(gchar *message) {
|
||||
GtkWidget *dialog = gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, message);
|
||||
gtk_dialog_run(GTK_DIALOG(dialog));
|
||||
gtk_widget_destroy(dialog);
|
||||
void ut_simple_message_box(gchar *message)
|
||||
{
|
||||
GtkWidget *dialog = gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, message);
|
||||
gtk_dialog_run(GTK_DIALOG(dialog));
|
||||
gtk_widget_destroy(dialog);
|
||||
}
|
||||
|
||||
|
||||
/* shows simple message box */
|
||||
void ut_simple_message_box_with_title(gchar *message, gchar *title) {
|
||||
GtkWidget *dialog = gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, message);
|
||||
gtk_window_set_title(GTK_WINDOW(dialog), title);
|
||||
gtk_dialog_run(GTK_DIALOG(dialog));
|
||||
gtk_widget_destroy(dialog);
|
||||
GtkWidget *dialog = gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, message);
|
||||
gtk_window_set_title(GTK_WINDOW(dialog), title);
|
||||
gtk_dialog_run(GTK_DIALOG(dialog));
|
||||
gtk_widget_destroy(dialog);
|
||||
}
|
||||
|
||||
|
@ -1,49 +1,48 @@
|
||||
#ifndef __GTKUTILS_H
|
||||
#define __GTKUTILS_H
|
||||
gboolean ut_key_pressed_cb (GtkWidget *widget,
|
||||
GdkEventKey *event);
|
||||
gboolean ut_key_pressed_cb (GtkWidget *widget, GdkEventKey *event);
|
||||
|
||||
GtkWidget *ut_window_new (gchar *title,
|
||||
gchar *wmname,
|
||||
gchar *wmclass,
|
||||
gboolean escaable,
|
||||
gboolean modal,
|
||||
gboolean resizable,
|
||||
gint border);
|
||||
GtkWidget *ut_window_new (gchar *title,
|
||||
gchar *wmname,
|
||||
gchar *wmclass,
|
||||
gboolean escaable,
|
||||
gboolean modal,
|
||||
gboolean resizable,
|
||||
gint border);
|
||||
|
||||
GtkWidget *ut_check_button_new (gchar *label,
|
||||
gboolean active,
|
||||
GtkWidget *parent);
|
||||
GtkWidget *ut_check_button_new (gchar *label,
|
||||
gboolean active,
|
||||
GtkWidget *parent);
|
||||
|
||||
GtkWidget *ut_button_new (gchar *label,
|
||||
gpointer func,
|
||||
gpointer func_data,
|
||||
GtkWidget *parent);
|
||||
GtkWidget *ut_button_new (gchar *label,
|
||||
gpointer func,
|
||||
gpointer func_data,
|
||||
GtkWidget *parent);
|
||||
|
||||
GtkWidget *ut_button_new_stock (const gchar *stock_id,
|
||||
gpointer func,
|
||||
gpointer func_data,
|
||||
GtkWidget *parent);
|
||||
GtkWidget *ut_button_new_stock (const gchar *stock_id,
|
||||
gpointer func,
|
||||
gpointer func_data,
|
||||
GtkWidget *parent);
|
||||
|
||||
GtkWidget *ut_button_new_stock_swap (const gchar *stock_id,
|
||||
gpointer func,
|
||||
gpointer func_data,
|
||||
GtkWidget *parent);
|
||||
GtkWidget *ut_button_new_stock_swap (const gchar *stock_id,
|
||||
gpointer func,
|
||||
gpointer func_data,
|
||||
GtkWidget *parent);
|
||||
|
||||
GtkWidget *ut_spin_button_new (gchar *label,
|
||||
gint min,
|
||||
gint max,
|
||||
gint val,
|
||||
GtkWidget *parent);
|
||||
GtkWidget *ut_spin_button_new (gchar *label,
|
||||
gint min,
|
||||
gint max,
|
||||
gint val,
|
||||
GtkWidget *parent);
|
||||
|
||||
GtkWidget *ut_spin_button_start_new (gchar *label,
|
||||
gint min,
|
||||
gint max,
|
||||
gint val,
|
||||
GtkWidget *parent);
|
||||
void ut_simple_message_box (gchar *message);
|
||||
GtkWidget *ut_spin_button_start_new (gchar *label,
|
||||
gint min,
|
||||
gint max,
|
||||
gint val,
|
||||
GtkWidget *parent);
|
||||
|
||||
void ut_simple_message_box_with_title (gchar *message,
|
||||
gchar *title);
|
||||
void ut_simple_message_box (gchar *message);
|
||||
|
||||
void ut_simple_message_box_with_title (gchar *message, gchar *title);
|
||||
|
||||
#endif
|
||||
|
156
src/halloffame.c
156
src/halloffame.c
@ -11,91 +11,97 @@
|
||||
#include "gtkutils.h"
|
||||
#include "scoreboard.h"
|
||||
|
||||
void show_hall_of_fame(GtkWidget *widget, gpointer data, struct score_board b[10]) {
|
||||
GtkWidget *hall_of_fame;
|
||||
GtkWidget *frame, *sw, *tv;
|
||||
GtkWidget *vbox, *button_box;
|
||||
GtkWidget *close_button;
|
||||
gint i;
|
||||
struct score_board *bs = b;
|
||||
struct score_board bn[10];
|
||||
GtkListStore *store;
|
||||
GtkTreeIter iter;
|
||||
GtkCellRenderer *renderer;
|
||||
GtkTreeViewColumn *column;
|
||||
gchar *str;
|
||||
GtkTreePath *path;
|
||||
void show_hall_of_fame (GtkWidget *widget, gpointer data, struct score_board b[10])
|
||||
{
|
||||
GtkWidget * hall_of_fame;
|
||||
GtkWidget * frame, * sw, * tv;
|
||||
GtkWidget * vbox, * button_box;
|
||||
GtkWidget * close_button;
|
||||
gint i;
|
||||
struct score_board *bs = b;
|
||||
struct score_board bn[10];
|
||||
GtkListStore *store;
|
||||
GtkTreeIter iter;
|
||||
GtkCellRenderer *renderer;
|
||||
GtkTreeViewColumn *column;
|
||||
gchar *str;
|
||||
GtkTreePath *path;
|
||||
|
||||
if(data == NULL) {
|
||||
if(!read_score(bn, NULL, NULL)) {
|
||||
ut_simple_message_box(_("Unable to read score.\n"));
|
||||
return;
|
||||
}
|
||||
bs = bn;
|
||||
}
|
||||
hall_of_fame = ut_window_new(_("Hall of Fame"), "GtkBalls_Scores", "GtkBalls", TRUE, TRUE, FALSE, 5);
|
||||
if (data == NULL) {
|
||||
if (!read_score(bn, NULL, NULL)) {
|
||||
ut_simple_message_box(_("Unable to read score.\n"));
|
||||
return;
|
||||
}
|
||||
bs = bn;
|
||||
}
|
||||
hall_of_fame = ut_window_new(_("Hall of Fame"), "GtkBalls_Scores", "GtkBalls", TRUE, TRUE, FALSE, 5);
|
||||
|
||||
vbox = gtk_vbox_new(FALSE, 0);
|
||||
gtk_container_set_border_width(GTK_CONTAINER(vbox), 1);
|
||||
gtk_container_add(GTK_CONTAINER(hall_of_fame), vbox);
|
||||
vbox = gtk_vbox_new(FALSE, 0);
|
||||
gtk_container_set_border_width(GTK_CONTAINER(vbox), 1);
|
||||
gtk_container_add(GTK_CONTAINER(hall_of_fame), vbox);
|
||||
|
||||
frame = gtk_frame_new(_("Hall of Fame"));
|
||||
gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0);
|
||||
frame = gtk_frame_new(_("Hall of Fame"));
|
||||
gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0);
|
||||
|
||||
sw = gtk_scrolled_window_new(NULL, NULL);
|
||||
gtk_container_set_border_width(GTK_CONTAINER(sw), 5);
|
||||
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_NEVER, GTK_POLICY_NEVER);
|
||||
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_ETCHED_IN);
|
||||
gtk_container_add(GTK_CONTAINER(frame), sw);
|
||||
sw = gtk_scrolled_window_new(NULL, NULL);
|
||||
gtk_container_set_border_width(GTK_CONTAINER(sw), 5);
|
||||
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_NEVER, GTK_POLICY_NEVER);
|
||||
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_ETCHED_IN);
|
||||
gtk_container_add(GTK_CONTAINER(frame), sw);
|
||||
|
||||
store = gtk_list_store_new(3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
|
||||
for(i = 0; bs[i].score && i < 10; i++) {
|
||||
gtk_list_store_append(store, &iter);
|
||||
str = g_strdup_printf("%d", bs[i].score);
|
||||
gtk_list_store_set(store, &iter, 0, bs[i].name, 1, str, 2, bs[i].date, -1);
|
||||
g_free(str);
|
||||
}
|
||||
if(i == 0) {
|
||||
gtk_list_store_append(store, &iter);
|
||||
gtk_list_store_set(store, &iter, 0, _("No scores"), 1, "", 2, "", -1);
|
||||
}
|
||||
store = gtk_list_store_new (3,
|
||||
G_TYPE_STRING,
|
||||
G_TYPE_STRING,
|
||||
G_TYPE_STRING);
|
||||
for (i = 0; bs[i].score && i < 10; i++) {
|
||||
gtk_list_store_append(store, &iter);
|
||||
str = g_strdup_printf("%d", bs[i].score);
|
||||
gtk_list_store_set(store, &iter, 0, bs[i].name, 1, str, 2, bs[i].date, -1);
|
||||
g_free(str);
|
||||
}
|
||||
if (i == 0) {
|
||||
gtk_list_store_append (store, &iter);
|
||||
gtk_list_store_set (store, &iter, 0, _("No scores"), 1, "", 2, "", -1);
|
||||
}
|
||||
|
||||
tv = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
|
||||
gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(tv), TRUE);
|
||||
gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(tv)), GTK_SELECTION_BROWSE);
|
||||
g_object_unref(G_OBJECT(store));
|
||||
renderer = gtk_cell_renderer_text_new();
|
||||
column = gtk_tree_view_column_new_with_attributes(_("Name"), renderer, "text", 0, NULL);
|
||||
gtk_tree_view_append_column(GTK_TREE_VIEW(tv), column);
|
||||
renderer = gtk_cell_renderer_text_new();
|
||||
column = gtk_tree_view_column_new_with_attributes(_("Score"), renderer, "text", 1, NULL);
|
||||
gtk_tree_view_append_column(GTK_TREE_VIEW(tv), column);
|
||||
renderer = gtk_cell_renderer_text_new();
|
||||
column = gtk_tree_view_column_new_with_attributes(_("Date"), renderer, "text", 2, NULL);
|
||||
gtk_tree_view_append_column(GTK_TREE_VIEW(tv), column);
|
||||
gtk_container_add(GTK_CONTAINER(sw), tv);
|
||||
tv = gtk_tree_view_new_with_model (GTK_TREE_MODEL(store));
|
||||
gtk_tree_view_set_rules_hint (GTK_TREE_VIEW(tv), TRUE);
|
||||
gtk_tree_selection_set_mode (gtk_tree_view_get_selection(GTK_TREE_VIEW(tv)), GTK_SELECTION_BROWSE);
|
||||
g_object_unref (G_OBJECT(store));
|
||||
renderer = gtk_cell_renderer_text_new ();
|
||||
column = gtk_tree_view_column_new_with_attributes (_("Name"), renderer, "text", 0, NULL);
|
||||
gtk_tree_view_append_column(GTK_TREE_VIEW(tv), column);
|
||||
renderer = gtk_cell_renderer_text_new ();
|
||||
column = gtk_tree_view_column_new_with_attributes (_("Score"), renderer, "text", 1, NULL);
|
||||
gtk_tree_view_append_column(GTK_TREE_VIEW(tv), column);
|
||||
renderer = gtk_cell_renderer_text_new ();
|
||||
column = gtk_tree_view_column_new_with_attributes (_("Date"), renderer, "text", 2, NULL);
|
||||
gtk_tree_view_append_column(GTK_TREE_VIEW(tv), column);
|
||||
gtk_container_add(GTK_CONTAINER(sw), tv);
|
||||
|
||||
if(data) {
|
||||
str = g_strdup_printf("%u", (gint)data - 1);
|
||||
if((path = gtk_tree_path_new_from_string(str))) {
|
||||
gtk_tree_selection_select_path(gtk_tree_view_get_selection(GTK_TREE_VIEW(tv)), path);
|
||||
gtk_tree_view_set_cursor(GTK_TREE_VIEW(tv), path, NULL, FALSE);
|
||||
gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(tv), path, NULL, TRUE, 0, 0);
|
||||
gtk_tree_path_free(path);
|
||||
}
|
||||
g_free(str);
|
||||
}
|
||||
if (data) {
|
||||
str = g_strdup_printf("%u", (gint)data - 1);
|
||||
if ((path = gtk_tree_path_new_from_string(str))) {
|
||||
gtk_tree_selection_select_path(gtk_tree_view_get_selection(GTK_TREE_VIEW(tv)), path);
|
||||
gtk_tree_view_set_cursor(GTK_TREE_VIEW(tv), path, NULL, FALSE);
|
||||
gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(tv), path, NULL, TRUE, 0, 0);
|
||||
gtk_tree_path_free(path);
|
||||
}
|
||||
g_free(str);
|
||||
}
|
||||
|
||||
button_box = gtk_hbox_new(TRUE, 0);
|
||||
gtk_box_pack_start(GTK_BOX(vbox), button_box, FALSE, FALSE, 4);
|
||||
button_box = gtk_hbox_new(TRUE, 0);
|
||||
gtk_box_pack_start(GTK_BOX(vbox), button_box, FALSE, FALSE, 4);
|
||||
|
||||
close_button = ut_button_new_stock_swap(GTK_STOCK_CLOSE, gtk_widget_destroy, hall_of_fame, button_box);
|
||||
close_button = ut_button_new_stock_swap(GTK_STOCK_CLOSE, gtk_widget_destroy, hall_of_fame, button_box);
|
||||
|
||||
gtk_widget_grab_focus(close_button);
|
||||
gtk_widget_grab_default(close_button);
|
||||
gtk_widget_show_all(hall_of_fame);
|
||||
gtk_widget_grab_focus (close_button);
|
||||
gtk_widget_grab_default (close_button);
|
||||
gtk_widget_show_all (hall_of_fame);
|
||||
}
|
||||
|
||||
void show_hall_of_fame_cb(void) {
|
||||
show_hall_of_fame(NULL, NULL, NULL);
|
||||
|
||||
void show_hall_of_fame_cb(void)
|
||||
{
|
||||
show_hall_of_fame(NULL, NULL, NULL);
|
||||
}
|
||||
|
158
src/inputname.c
158
src/inputname.c
@ -21,95 +21,99 @@ static GtkWidget *_dialog = NULL;
|
||||
static gchar _last_player_name[15] = "";
|
||||
static gint _saved_score = 0;
|
||||
|
||||
void read_entry(GtkWidget *widget, gpointer data) {
|
||||
struct score_board current_entry;
|
||||
time_t current_time;
|
||||
struct tm *timeptr;
|
||||
gint pos, fbn;
|
||||
gsize br, bw;
|
||||
gchar *tstr = NULL;
|
||||
struct score_board b[10];
|
||||
struct score_board_full *bf = NULL;
|
||||
void read_entry(GtkWidget *widget, gpointer data)
|
||||
{
|
||||
struct score_board current_entry;
|
||||
time_t current_time;
|
||||
struct tm *timeptr;
|
||||
gint pos, fbn;
|
||||
gsize br, bw;
|
||||
gchar *tstr = NULL;
|
||||
struct score_board b[10];
|
||||
struct score_board_full *bf = NULL;
|
||||
|
||||
tstr = (gchar*)gtk_entry_get_text(GTK_ENTRY(data));
|
||||
strncpy(current_entry.name, tstr && *tstr ? tstr : _("Anonymous"), sizeof(current_entry.name));
|
||||
strncpy(_last_player_name, current_entry.name, sizeof(_last_player_name));
|
||||
current_entry.score = _saved_score;
|
||||
current_time = time(NULL);
|
||||
timeptr = localtime(¤t_time);
|
||||
if(!timeptr) {
|
||||
ut_simple_message_box(_("Unable to determine current date.\n"));
|
||||
strncpy(current_entry.date, _("Unknown"), sizeof(current_entry.date));
|
||||
} else {
|
||||
if(!strftime(current_entry.date, sizeof(current_entry.date), _("%a %b %d %H:%M %Y"), timeptr)) {
|
||||
ut_simple_message_box(_("Unable to determine current date.\n"));
|
||||
strncpy(current_entry.date, _("Unknown"), sizeof(current_entry.date));
|
||||
} else {
|
||||
tstr = g_locale_to_utf8(current_entry.date, -1, &br, &bw, NULL);
|
||||
if(!tstr) {
|
||||
strncpy(current_entry.date, _("Unknown"), sizeof(current_entry.date));
|
||||
} else {
|
||||
strncpy(current_entry.date, tstr, sizeof(current_entry.date));
|
||||
g_free(tstr);
|
||||
}
|
||||
}
|
||||
}
|
||||
tstr = (gchar*)gtk_entry_get_text(GTK_ENTRY(data));
|
||||
strncpy(current_entry.name, tstr && *tstr ? tstr : _("Anonymous"), sizeof(current_entry.name));
|
||||
strncpy(_last_player_name, current_entry.name, sizeof(_last_player_name));
|
||||
current_entry.score = _saved_score;
|
||||
current_time = time(NULL);
|
||||
timeptr = localtime(¤t_time);
|
||||
|
||||
if(!read_score(b, &bf, &fbn)) {
|
||||
ut_simple_message_box (_("Unable to read score.\n"));
|
||||
} else {
|
||||
pos = insert_entry_in_score_board(b, current_entry);
|
||||
if(!write_score(b, bf, fbn)) {
|
||||
ut_simple_message_box(_("Unable to save score.\n"));
|
||||
}
|
||||
/*FIXME: free bf here */
|
||||
free_score_board_full(bf, fbn);
|
||||
if(pos != -1) {
|
||||
pos++;
|
||||
show_hall_of_fame(NULL, (gpointer)pos, b);
|
||||
}
|
||||
}
|
||||
if (!timeptr) {
|
||||
ut_simple_message_box(_("Unable to determine current date.\n"));
|
||||
strncpy(current_entry.date, _("Unknown"), sizeof(current_entry.date));
|
||||
} else {
|
||||
if (!strftime(current_entry.date, sizeof(current_entry.date), _("%a %b %d %H:%M %Y"), timeptr)) {
|
||||
ut_simple_message_box(_("Unable to determine current date.\n"));
|
||||
strncpy(current_entry.date, _("Unknown"), sizeof(current_entry.date));
|
||||
} else {
|
||||
tstr = g_locale_to_utf8(current_entry.date, -1, &br, &bw, NULL);
|
||||
if (!tstr) {
|
||||
strncpy(current_entry.date, _("Unknown"), sizeof(current_entry.date));
|
||||
} else {
|
||||
strncpy(current_entry.date, tstr, sizeof(current_entry.date));
|
||||
g_free(tstr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gtk_widget_destroy(_dialog);
|
||||
/* show scores to let user see if (s)he's on top ;) */
|
||||
if (!read_score(b, &bf, &fbn)) {
|
||||
ut_simple_message_box (_("Unable to read score.\n"));
|
||||
} else {
|
||||
pos = insert_entry_in_score_board(b, current_entry);
|
||||
if (!write_score(b, bf, fbn)) {
|
||||
ut_simple_message_box(_("Unable to save score.\n"));
|
||||
}
|
||||
/*FIXME: free bf here */
|
||||
free_score_board_full(bf, fbn);
|
||||
if (pos != -1) {
|
||||
pos++;
|
||||
show_hall_of_fame(NULL, (gpointer)pos, b);
|
||||
}
|
||||
}
|
||||
|
||||
gtk_widget_destroy(_dialog);
|
||||
/* show scores to let user see if (s)he's on top ;) */
|
||||
}
|
||||
|
||||
void input_name_dialog(void) {
|
||||
GtkWidget *prompt_label, * vbox;
|
||||
GtkWidget *name;
|
||||
GtkWidget *button;
|
||||
gchar *s;
|
||||
|
||||
/* we have to save score, because they will be set to 0 in new_game() */
|
||||
_saved_score = game_get_score();
|
||||
void input_name_dialog(void)
|
||||
{
|
||||
GtkWidget * prompt_label, * vbox;
|
||||
GtkWidget * name;
|
||||
GtkWidget * button;
|
||||
gchar * s;
|
||||
|
||||
_dialog = gtk_dialog_new();
|
||||
gtk_window_set_role(GTK_WINDOW(_dialog), "GtkBalls_Inputname");
|
||||
/* we have to save score, because they will be set to 0 in new_game() */
|
||||
_saved_score = game_get_score();
|
||||
|
||||
vbox = gtk_dialog_get_content_area (GTK_DIALOG (_dialog));
|
||||
gtk_container_set_border_width(GTK_CONTAINER(vbox), 2);
|
||||
_dialog = gtk_dialog_new();
|
||||
gtk_window_set_role(GTK_WINDOW(_dialog), "GtkBalls_Inputname");
|
||||
|
||||
prompt_label = gtk_label_new(_("Enter your name"));
|
||||
gtk_box_pack_start (GTK_BOX(vbox), prompt_label, TRUE, TRUE, 0);
|
||||
vbox = gtk_dialog_get_content_area (GTK_DIALOG (_dialog));
|
||||
gtk_container_set_border_width(GTK_CONTAINER(vbox), 2);
|
||||
|
||||
name = gtk_entry_new();
|
||||
gtk_entry_set_max_length(GTK_ENTRY(name), 14);
|
||||
g_signal_connect(G_OBJECT(name), "activate", G_CALLBACK(read_entry), name);
|
||||
prompt_label = gtk_label_new(_("Enter your name"));
|
||||
gtk_box_pack_start (GTK_BOX(vbox), prompt_label, TRUE, TRUE, 0);
|
||||
|
||||
/* restore the last player's name */
|
||||
if(!(*_last_player_name)) {
|
||||
if((s = getenv("USER"))) {
|
||||
strncpy(_last_player_name, s, sizeof(_last_player_name));
|
||||
}
|
||||
}
|
||||
gtk_entry_set_text(GTK_ENTRY(name), _last_player_name);
|
||||
gtk_editable_select_region(GTK_EDITABLE(name), 0, -1);
|
||||
gtk_box_pack_start (GTK_BOX(vbox), name, TRUE, TRUE, 5);
|
||||
name = gtk_entry_new();
|
||||
gtk_entry_set_max_length(GTK_ENTRY(name), 14);
|
||||
g_signal_connect(G_OBJECT(name), "activate", G_CALLBACK(read_entry), name);
|
||||
|
||||
button=ut_button_new_stock(GTK_STOCK_OK, read_entry, name, GTK_DIALOG(_dialog)->action_area);
|
||||
/* restore the last player's name */
|
||||
if (!(*_last_player_name)) {
|
||||
if ((s = getenv("USER"))) {
|
||||
strncpy(_last_player_name, s, sizeof(_last_player_name));
|
||||
}
|
||||
}
|
||||
gtk_entry_set_text(GTK_ENTRY(name), _last_player_name);
|
||||
gtk_editable_select_region(GTK_EDITABLE(name), 0, -1);
|
||||
gtk_box_pack_start (GTK_BOX(vbox), name, TRUE, TRUE, 5);
|
||||
|
||||
gtk_widget_grab_focus(name);
|
||||
button=ut_button_new_stock(GTK_STOCK_OK, read_entry, name, GTK_DIALOG(_dialog)->action_area);
|
||||
|
||||
gtk_widget_grab_default(button);
|
||||
gtk_widget_show_all(_dialog);
|
||||
gtk_widget_grab_focus(name);
|
||||
|
||||
gtk_widget_grab_default(button);
|
||||
gtk_widget_show_all(_dialog);
|
||||
}
|
||||
|
@ -17,20 +17,20 @@
|
||||
#include "rulesdialog.h" /* rules_dialog() */
|
||||
|
||||
static GtkActionEntry _menu_entries[] = {
|
||||
{ "GameMenu", NULL, N_("_Game") },
|
||||
{ "EditMenu", NULL, N_("_Edit") },
|
||||
{ "SettingsMenu", NULL, N_("_Settings") },
|
||||
{ "HelpMenu", NULL, N_("_Help") },
|
||||
{ "New", GTK_STOCK_NEW, N_("_New"), "<control>N", N_("Start new game"), G_CALLBACK(new_game)},
|
||||
{ "Rules", GTK_STOCK_PROPERTIES, N_("_Rules"), "<control>R", N_("Change game rules"), G_CALLBACK(rules_dialog)},
|
||||
{ "Save", GTK_STOCK_SAVE, N_("_Save"), "<control>S", N_("Save game"), G_CALLBACK(save_game_cb)},
|
||||
{ "Load", GTK_STOCK_OPEN, N_("_Load"), "<control>L", N_("Load game"), G_CALLBACK(load_game_cb)},
|
||||
{ "HallOfFame", NULL, N_("_Hall of fame"), "<control>H", N_("Show Hall of Fame"), G_CALLBACK(show_hall_of_fame_cb)},
|
||||
{ "Quit", GTK_STOCK_QUIT, N_("_Quit"), "<control>Q", N_("Quit program"), G_CALLBACK(gtk_main_quit)},
|
||||
{ "Undo", GTK_STOCK_UNDO, N_("_Undo"), "<control>U", N_("Undo last move"), G_CALLBACK(undo_move)},
|
||||
{ "Preferences", GTK_STOCK_PREFERENCES, N_("_Preferences"), "<control>P", N_("Change game settings"), G_CALLBACK(preferences_dialog)},
|
||||
{ "RulesHelp", GTK_STOCK_HELP, N_("_Rules"), "F1", N_("Display help about game rules"), G_CALLBACK(show_rules)},
|
||||
{ "About", NULL, N_("_About"), "<control>A", N_("Show information about program"), G_CALLBACK(about)}
|
||||
{ "GameMenu", NULL, N_("_Game") },
|
||||
{ "EditMenu", NULL, N_("_Edit") },
|
||||
{ "SettingsMenu", NULL, N_("_Settings") },
|
||||
{ "HelpMenu", NULL, N_("_Help") },
|
||||
{ "New", GTK_STOCK_NEW, N_("_New"), "<control>N", N_("Start new game"), G_CALLBACK(new_game)},
|
||||
{ "Rules", GTK_STOCK_PROPERTIES, N_("_Rules"), "<control>R", N_("Change game rules"), G_CALLBACK(rules_dialog)},
|
||||
{ "Save", GTK_STOCK_SAVE, N_("_Save"), "<control>S", N_("Save game"), G_CALLBACK(save_game_cb)},
|
||||
{ "Load", GTK_STOCK_OPEN, N_("_Load"), "<control>L", N_("Load game"), G_CALLBACK(load_game_cb)},
|
||||
{ "HallOfFame", NULL, N_("_Hall of fame"), "<control>H", N_("Show Hall of Fame"), G_CALLBACK(show_hall_of_fame_cb)},
|
||||
{ "Quit", GTK_STOCK_QUIT, N_("_Quit"), "<control>Q", N_("Quit program"), G_CALLBACK(gtk_main_quit)},
|
||||
{ "Undo", GTK_STOCK_UNDO, N_("_Undo"), "<control>U", N_("Undo last move"), G_CALLBACK(undo_move)},
|
||||
{ "Preferences", GTK_STOCK_PREFERENCES, N_("_Preferences"), "<control>P", N_("Change game settings"), G_CALLBACK(preferences_dialog)},
|
||||
{ "RulesHelp", GTK_STOCK_HELP, N_("_Rules"), "F1", N_("Display help about game rules"), G_CALLBACK(show_rules)},
|
||||
{ "About", NULL, N_("_About"), "<control>A", N_("Show information about program"), G_CALLBACK(about)}
|
||||
};
|
||||
|
||||
static const char *_ui_description =
|
||||
@ -65,35 +65,38 @@ GtkActionGroup *_action_group;
|
||||
GtkUIManager *_ui_manager;
|
||||
|
||||
static gchar *_menu_translate(const gchar *path, gpointer data) {
|
||||
return gettext(path);
|
||||
return gettext(path);
|
||||
}
|
||||
|
||||
void menu_get_main(GtkWidget *window, GtkWidget **menubar) {
|
||||
GtkAccelGroup *accel_group;
|
||||
void menu_get_main(GtkWidget *window, GtkWidget **menubar)
|
||||
{
|
||||
GtkAccelGroup *accel_group;
|
||||
|
||||
_action_group = gtk_action_group_new("MenuActions");
|
||||
gtk_action_group_set_translate_func(_action_group, _menu_translate, NULL, NULL);
|
||||
gtk_action_group_add_actions(_action_group, _menu_entries, G_N_ELEMENTS(_menu_entries), window);
|
||||
_ui_manager = gtk_ui_manager_new();
|
||||
gtk_ui_manager_set_add_tearoffs(_ui_manager, 1);
|
||||
gtk_ui_manager_insert_action_group(_ui_manager, _action_group, 0);
|
||||
accel_group = gtk_ui_manager_get_accel_group(_ui_manager);
|
||||
gtk_window_add_accel_group(GTK_WINDOW(window), accel_group);
|
||||
gtk_ui_manager_add_ui_from_string(_ui_manager, _ui_description, -1, NULL);
|
||||
*menubar = gtk_ui_manager_get_widget(_ui_manager, "/MainMenu");
|
||||
_action_group = gtk_action_group_new("MenuActions");
|
||||
gtk_action_group_set_translate_func(_action_group, _menu_translate, NULL, NULL);
|
||||
gtk_action_group_add_actions(_action_group, _menu_entries, G_N_ELEMENTS(_menu_entries), window);
|
||||
_ui_manager = gtk_ui_manager_new();
|
||||
gtk_ui_manager_set_add_tearoffs(_ui_manager, 1);
|
||||
gtk_ui_manager_insert_action_group(_ui_manager, _action_group, 0);
|
||||
accel_group = gtk_ui_manager_get_accel_group(_ui_manager);
|
||||
gtk_window_add_accel_group(GTK_WINDOW(window), accel_group);
|
||||
gtk_ui_manager_add_ui_from_string(_ui_manager, _ui_description, -1, NULL);
|
||||
*menubar = gtk_ui_manager_get_widget(_ui_manager, "/MainMenu");
|
||||
}
|
||||
|
||||
void _menu_set_sensitive(const gchar *path, gboolean sensitive) {
|
||||
GtkWidget *widget;
|
||||
void _menu_set_sensitive(const gchar *path, gboolean sensitive)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
|
||||
widget = gtk_ui_manager_get_widget(_ui_manager, path);
|
||||
gtk_widget_set_sensitive(widget, sensitive);
|
||||
widget = gtk_ui_manager_get_widget(_ui_manager, path);
|
||||
gtk_widget_set_sensitive(widget, sensitive);
|
||||
}
|
||||
|
||||
void menu_set_sensitive_undo(gboolean sensitive) {
|
||||
_menu_set_sensitive("/MainMenu/EditMenu/Undo", sensitive);
|
||||
void menu_set_sensitive_undo(gboolean sensitive)
|
||||
{
|
||||
_menu_set_sensitive("/MainMenu/EditMenu/Undo", sensitive);
|
||||
}
|
||||
|
||||
void menu_set_sensitive_all(gboolean sensitive) {
|
||||
gtk_action_group_set_sensitive(_action_group, sensitive);
|
||||
gtk_action_group_set_sensitive(_action_group, sensitive);
|
||||
}
|
||||
|
257
src/mainwin.c
257
src/mainwin.c
@ -29,173 +29,178 @@ GtkWidget *_small_balls_box;
|
||||
GtkWidget *_drawing_area = NULL;
|
||||
|
||||
GtkWidget *mw_get_da(void) {
|
||||
return _drawing_area;
|
||||
return _drawing_area;
|
||||
}
|
||||
|
||||
/* add child widget to "next balls" display area */
|
||||
void mw_small_balls_add(GtkWidget *child) {
|
||||
gtk_box_pack_start(GTK_BOX(_small_balls_box), child, FALSE, FALSE, 0);
|
||||
gtk_box_pack_start(GTK_BOX(_small_balls_box), child, FALSE, FALSE, 0);
|
||||
}
|
||||
|
||||
void mw_show_hide_next_balls(gboolean show) {
|
||||
if(show) {
|
||||
gtk_widget_show_all(_small_balls_box);
|
||||
} else {
|
||||
gtk_widget_hide(_small_balls_box);
|
||||
}
|
||||
if (show) {
|
||||
gtk_widget_show_all(_small_balls_box);
|
||||
} else {
|
||||
gtk_widget_hide(_small_balls_box);
|
||||
}
|
||||
}
|
||||
|
||||
/* set and draw High Score */
|
||||
void mw_set_hi_score(gint score) {
|
||||
gchar *str;
|
||||
gchar *str;
|
||||
|
||||
game_set_hi_score(score);
|
||||
str = g_strdup_printf(_("Hi-score: %i"), score);
|
||||
gtk_label_set_text(GTK_LABEL(_hi_score_label), str);
|
||||
g_free(str);
|
||||
game_set_hi_score(score);
|
||||
str = g_strdup_printf(_("Hi-score: %i"), score);
|
||||
gtk_label_set_text(GTK_LABEL(_hi_score_label), str);
|
||||
g_free(str);
|
||||
}
|
||||
|
||||
/* set and draw Users Score */
|
||||
void mw_set_user_score(gint score) {
|
||||
gchar *str;
|
||||
gchar *str;
|
||||
|
||||
game_set_score(score);
|
||||
if(score > game_get_hi_score()) {
|
||||
mw_set_hi_score(score);
|
||||
}
|
||||
str = g_strdup_printf(_("Your score: %i"), score);
|
||||
gtk_label_set_text(GTK_LABEL(_user_score_label), str);
|
||||
g_free(str);
|
||||
game_set_score(score);
|
||||
if (score > game_get_hi_score()) {
|
||||
mw_set_hi_score(score);
|
||||
}
|
||||
str = g_strdup_printf(_("Your score: %i"), score);
|
||||
gtk_label_set_text(GTK_LABEL(_user_score_label), str);
|
||||
g_free(str);
|
||||
}
|
||||
|
||||
gboolean _countdown_timer(gpointer data) {
|
||||
gchar *text;
|
||||
GtkLabel *label = data;
|
||||
gint trem;
|
||||
gboolean _countdown_timer(gpointer data)
|
||||
{
|
||||
gchar *text;
|
||||
GtkLabel *label = data;
|
||||
gint trem;
|
||||
|
||||
if(child_writer_dead_handler()) {
|
||||
ut_simple_message_box_with_title(_("Score writer process died unexpectedly. No scores will be writen!\n" \
|
||||
"Save your game and restart programm.\n"),
|
||||
_("Who Killed Bambi?"));
|
||||
}
|
||||
if (child_writer_dead_handler()) {
|
||||
ut_simple_message_box_with_title(_("Score writer process died unexpectedly. No scores will be writen!\n" \
|
||||
"Save your game and restart programm.\n"),
|
||||
_("Who Killed Bambi?"));
|
||||
}
|
||||
|
||||
if(!timer_is_running()) {
|
||||
gtk_label_set_text(label, _("Time is unlimited"));
|
||||
return TRUE;
|
||||
}
|
||||
if(timer_is_expired()) {
|
||||
new_turn(rules_get_next(), FALSE);
|
||||
}
|
||||
trem = timer_get_remaining();
|
||||
text = g_strdup_printf(_("Remaining time: %02d:%02d"), trem / 60, trem % 60);
|
||||
gtk_label_set_text(label, text);
|
||||
g_free(text);
|
||||
if (!timer_is_running()) {
|
||||
gtk_label_set_text(label, _("Time is unlimited"));
|
||||
return TRUE;
|
||||
}
|
||||
if (timer_is_expired()) {
|
||||
new_turn(rules_get_next(), FALSE);
|
||||
}
|
||||
trem = timer_get_remaining();
|
||||
text = g_strdup_printf(_("Remaining time: %02d:%02d"), trem / 60, trem % 60);
|
||||
gtk_label_set_text(label, text);
|
||||
g_free(text);
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gint _user_action_event(GtkWidget *w, GdkEvent *ev) {
|
||||
if(ev->type == GDK_MOTION_NOTIFY) {
|
||||
move_pointer_to(gtkb_theme_get_coord_at_x(ev->motion.x),
|
||||
gtkb_theme_get_coord_at_y(ev->motion.y));
|
||||
}
|
||||
gint _user_action_event(GtkWidget *w, GdkEvent *ev)
|
||||
{
|
||||
if (ev->type == GDK_MOTION_NOTIFY) {
|
||||
move_pointer_to(gtkb_theme_get_coord_at_x(ev->motion.x),
|
||||
gtkb_theme_get_coord_at_y(ev->motion.y));
|
||||
}
|
||||
|
||||
if(ev->type == GDK_KEY_PRESS) {
|
||||
if(ev->key.keyval == GDK_Left || ev->key.keyval == GDK_KP_Left) {
|
||||
move_pointer(DIR_LEFT);
|
||||
} else if(ev->key.keyval == GDK_Right || ev->key.keyval == GDK_KP_Right) {
|
||||
move_pointer(DIR_RIGHT);
|
||||
} else if(ev->key.keyval == GDK_Up || ev->key.keyval == GDK_KP_Up) {
|
||||
move_pointer(DIR_UP);
|
||||
} else if(ev->key.keyval == GDK_Down || ev->key.keyval == GDK_KP_Down) {
|
||||
move_pointer(DIR_DOWN);
|
||||
} else if(ev->key.keyval == GDK_KP_Home) {
|
||||
move_pointer(DIR_UP_LEFT);
|
||||
} else if(ev->key.keyval == GDK_KP_Page_Up) {
|
||||
move_pointer(DIR_UP_RIGHT);
|
||||
} else if(ev->key.keyval == GDK_KP_End) {
|
||||
move_pointer(DIR_DOWN_LEFT);
|
||||
} else if(ev->key.keyval == GDK_KP_Page_Down) {
|
||||
move_pointer(DIR_DOWN_RIGHT);
|
||||
} else if(ev->key.keyval == GDK_Return ||
|
||||
ev->key.keyval == GDK_KP_Space ||
|
||||
ev->key.keyval == GDK_KP_Enter ||
|
||||
ev->key.keyval == GDK_space) {
|
||||
if(is_actions_locked()) {
|
||||
return FALSE;
|
||||
}
|
||||
pointer_pressed(-1, -1);
|
||||
}
|
||||
} else if(ev->type == GDK_BUTTON_PRESS && ev->button.button == 1) {
|
||||
if(is_actions_locked()) {
|
||||
return FALSE;
|
||||
}
|
||||
pointer_pressed(gtkb_theme_get_coord_at_x(ev->button.x),
|
||||
gtkb_theme_get_coord_at_y(ev->button.y));
|
||||
}
|
||||
if (ev->type == GDK_KEY_PRESS) {
|
||||
if (ev->key.keyval == GDK_Left || ev->key.keyval == GDK_KP_Left) {
|
||||
move_pointer(DIR_LEFT);
|
||||
} else if (ev->key.keyval == GDK_Right || ev->key.keyval == GDK_KP_Right) {
|
||||
move_pointer(DIR_RIGHT);
|
||||
} else if (ev->key.keyval == GDK_Up || ev->key.keyval == GDK_KP_Up) {
|
||||
move_pointer(DIR_UP);
|
||||
} else if (ev->key.keyval == GDK_Down || ev->key.keyval == GDK_KP_Down) {
|
||||
move_pointer(DIR_DOWN);
|
||||
} else if (ev->key.keyval == GDK_KP_Home) {
|
||||
move_pointer(DIR_UP_LEFT);
|
||||
} else if (ev->key.keyval == GDK_KP_Page_Up) {
|
||||
move_pointer(DIR_UP_RIGHT);
|
||||
} else if (ev->key.keyval == GDK_KP_End) {
|
||||
move_pointer(DIR_DOWN_LEFT);
|
||||
} else if (ev->key.keyval == GDK_KP_Page_Down) {
|
||||
move_pointer(DIR_DOWN_RIGHT);
|
||||
} else if (ev->key.keyval == GDK_Return ||
|
||||
ev->key.keyval == GDK_KP_Space ||
|
||||
ev->key.keyval == GDK_KP_Enter ||
|
||||
ev->key.keyval == GDK_space) {
|
||||
if (is_actions_locked()) {
|
||||
return FALSE;
|
||||
}
|
||||
pointer_pressed(-1, -1);
|
||||
}
|
||||
} else if (ev->type == GDK_BUTTON_PRESS && ev->button.button == 1) {
|
||||
if (is_actions_locked()) {
|
||||
return FALSE;
|
||||
}
|
||||
pointer_pressed(gtkb_theme_get_coord_at_x(ev->button.x),
|
||||
gtkb_theme_get_coord_at_y(ev->button.y));
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
static void main_window_destroy_cb (GtkWidget * w, gpointer user_data)
|
||||
{
|
||||
gtkb_theme_free_handler (NULL, NULL);
|
||||
gtk_main_quit ();
|
||||
}
|
||||
|
||||
void mw_create(gint da_width, gint da_height) {
|
||||
GtkWidget *mainwin;
|
||||
GtkWidget *menubar;
|
||||
GtkWidget *vbox, *hbox, *hbox1, *drawing_area_box;
|
||||
GtkWidget *timer_label;
|
||||
GdkPixbuf *icon;
|
||||
GError *error=NULL;
|
||||
|
||||
mainwin = ut_window_new(_("GtkBalls"), "GtkBalls_Main", "GtkBalls", FALSE, FALSE, FALSE, 0);
|
||||
main_window = GTK_WINDOW (mainwin);
|
||||
g_signal_connect (G_OBJECT(mainwin), "destroy", G_CALLBACK(main_window_destroy_cb), mainwin);
|
||||
void mw_create(gint da_width, gint da_height)
|
||||
{
|
||||
GtkWidget * mainwin;
|
||||
GtkWidget * menubar;
|
||||
GtkWidget * vbox, * hbox, * hbox1, * drawing_area_box;
|
||||
GtkWidget * timer_label;
|
||||
GdkPixbuf * icon;
|
||||
GError *error = NULL;
|
||||
|
||||
icon = gdk_pixbuf_new_from_file(DATADIR "/gtkballs/gtkballs_16x16.png", &error);
|
||||
if(icon) {
|
||||
gtk_window_set_icon(GTK_WINDOW(mainwin), icon);
|
||||
} else {
|
||||
g_error_free(error);
|
||||
}
|
||||
mainwin = ut_window_new (_("GtkBalls"), "GtkBalls_Main", "GtkBalls", FALSE, FALSE, FALSE, 0);
|
||||
main_window = GTK_WINDOW (mainwin);
|
||||
g_signal_connect (G_OBJECT (mainwin), "destroy", G_CALLBACK(main_window_destroy_cb), mainwin);
|
||||
|
||||
vbox = gtk_vbox_new(FALSE, 5);
|
||||
gtk_container_add(GTK_CONTAINER(mainwin), vbox);
|
||||
icon = gdk_pixbuf_new_from_file (DATADIR "/gtkballs/gtkballs_16x16.png", &error);
|
||||
if (icon) {
|
||||
gtk_window_set_icon (GTK_WINDOW(mainwin), icon);
|
||||
} else {
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
menu_get_main(mainwin, &menubar);
|
||||
menu_set_sensitive_undo(FALSE);
|
||||
gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, TRUE, 0);
|
||||
vbox = gtk_vbox_new (FALSE, 5);
|
||||
gtk_container_add (GTK_CONTAINER(mainwin), vbox);
|
||||
|
||||
hbox = gtk_hbox_new(FALSE, 0);
|
||||
_hi_score_label = gtk_label_new("");
|
||||
gtk_box_pack_start(GTK_BOX(hbox), _hi_score_label, FALSE, FALSE, 5);
|
||||
_user_score_label = gtk_label_new("");
|
||||
gtk_box_pack_end(GTK_BOX(hbox), _user_score_label, FALSE, FALSE, 5);
|
||||
gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(hbox), FALSE, FALSE, 0);
|
||||
menu_get_main (mainwin, &menubar);
|
||||
menu_set_sensitive_undo (FALSE);
|
||||
gtk_box_pack_start (GTK_BOX(vbox), menubar, FALSE, TRUE, 0);
|
||||
|
||||
_small_balls_box = gtk_hbox_new(TRUE, 0);
|
||||
gtk_box_pack_start(GTK_BOX(hbox), _small_balls_box, TRUE, FALSE, 0);
|
||||
hbox = gtk_hbox_new (FALSE, 0);
|
||||
_hi_score_label = gtk_label_new ("");
|
||||
gtk_box_pack_start (GTK_BOX(hbox), _hi_score_label, FALSE, FALSE, 5);
|
||||
_user_score_label = gtk_label_new("");
|
||||
gtk_box_pack_end (GTK_BOX(hbox), _user_score_label, FALSE, FALSE, 5);
|
||||
gtk_box_pack_start (GTK_BOX(vbox), GTK_WIDGET(hbox), FALSE, FALSE, 0);
|
||||
|
||||
hbox1 = gtk_hbox_new(FALSE, 0);
|
||||
timer_label = gtk_label_new(NULL);
|
||||
gtk_box_pack_start(GTK_BOX(hbox1), timer_label, TRUE, TRUE, 5);
|
||||
g_timeout_add(250, _countdown_timer, timer_label);
|
||||
gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(hbox1), FALSE, FALSE, 0);
|
||||
_small_balls_box = gtk_hbox_new(TRUE, 0);
|
||||
gtk_box_pack_start (GTK_BOX(hbox), _small_balls_box, TRUE, FALSE, 0);
|
||||
|
||||
drawing_area_box = gtk_hbox_new(FALSE, 0);
|
||||
gtk_box_pack_start(GTK_BOX(vbox), drawing_area_box, FALSE, FALSE, 10);
|
||||
_drawing_area = gtk_drawing_area_new();
|
||||
gtk_widget_set_size_request(_drawing_area, da_width, da_height);
|
||||
gtk_box_pack_start(GTK_BOX(drawing_area_box), _drawing_area, TRUE, FALSE, 10);
|
||||
gtk_widget_set_events(_drawing_area, GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_KEY_PRESS_MASK | GDK_POINTER_MOTION_MASK);
|
||||
g_signal_connect(G_OBJECT(_drawing_area), "expose_event", G_CALLBACK(expose_event), NULL);
|
||||
g_signal_connect(G_OBJECT(_drawing_area), "button_press_event", G_CALLBACK(_user_action_event), NULL);
|
||||
g_signal_connect(G_OBJECT(_drawing_area), "motion_notify_event", G_CALLBACK(_user_action_event), NULL);
|
||||
/* FIXME: imho catching keypress on whole window is stupid... */
|
||||
g_signal_connect(G_OBJECT(mainwin), "key_press_event", G_CALLBACK(_user_action_event), NULL);
|
||||
hbox1 = gtk_hbox_new (FALSE, 0);
|
||||
timer_label = gtk_label_new (NULL);
|
||||
gtk_box_pack_start (GTK_BOX(hbox1), timer_label, TRUE, TRUE, 5);
|
||||
g_timeout_add(250, _countdown_timer, timer_label);
|
||||
gtk_box_pack_start (GTK_BOX(vbox), GTK_WIDGET(hbox1), FALSE, FALSE, 0);
|
||||
|
||||
gtk_widget_show_all(mainwin);
|
||||
drawing_area_box = gtk_hbox_new(FALSE, 0);
|
||||
gtk_box_pack_start (GTK_BOX(vbox), drawing_area_box, FALSE, FALSE, 10);
|
||||
_drawing_area = gtk_drawing_area_new();
|
||||
gtk_widget_set_size_request (_drawing_area, da_width, da_height);
|
||||
gtk_box_pack_start (GTK_BOX(drawing_area_box), _drawing_area, TRUE, FALSE, 10);
|
||||
gtk_widget_set_events (_drawing_area, GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_KEY_PRESS_MASK | GDK_POINTER_MOTION_MASK);
|
||||
g_signal_connect (G_OBJECT(_drawing_area), "expose_event", G_CALLBACK(expose_event), NULL);
|
||||
g_signal_connect (G_OBJECT(_drawing_area), "button_press_event", G_CALLBACK(_user_action_event), NULL);
|
||||
g_signal_connect (G_OBJECT(_drawing_area), "motion_notify_event", G_CALLBACK(_user_action_event), NULL);
|
||||
/* FIXME: imho catching keypress on whole window is stupid... */
|
||||
g_signal_connect (G_OBJECT(mainwin), "key_press_event", G_CALLBACK(_user_action_event), NULL);
|
||||
|
||||
gtk_widget_show_all (mainwin);
|
||||
}
|
||||
|
157
src/path.c
157
src/path.c
@ -13,33 +13,33 @@
|
||||
/* returns x coordinate of the node
|
||||
number_of_cells: number of cells in the row */
|
||||
int __find_x_of_the_node(int node, int number_of_x_cells, int number_of_y_cells) {
|
||||
assert(number_of_x_cells > 0);
|
||||
return node % number_of_x_cells;
|
||||
assert(number_of_x_cells > 0);
|
||||
return node % number_of_x_cells;
|
||||
}
|
||||
|
||||
/* returns y coordinate of the node
|
||||
number_of_cells: number of cells in the row
|
||||
*/
|
||||
int __find_y_of_the_node(int node, int number_of_x_cells, int number_of_y_cells) {
|
||||
assert(number_of_x_cells > 0);
|
||||
return node / number_of_x_cells;
|
||||
assert(number_of_x_cells > 0);
|
||||
return node / number_of_x_cells;
|
||||
}
|
||||
|
||||
/* returns x and y coordinates of the node */
|
||||
void find_x_y_of_the_node(int *x, int *y, int node, int number_of_x_cells, int number_of_y_cells) {
|
||||
*x = __find_x_of_the_node(node, number_of_x_cells, number_of_y_cells);
|
||||
*y = __find_y_of_the_node(node, number_of_x_cells, number_of_y_cells);
|
||||
*x = __find_x_of_the_node(node, number_of_x_cells, number_of_y_cells);
|
||||
*y = __find_y_of_the_node(node, number_of_x_cells, number_of_y_cells);
|
||||
}
|
||||
|
||||
/* returns node at x and y coordinates */
|
||||
int find_node_of_x_y(int x, int y, int number_of_x_cells) {
|
||||
return y * number_of_x_cells + x;
|
||||
return y * number_of_x_cells + x;
|
||||
}
|
||||
|
||||
/* find number of the node by its coordinates
|
||||
number_of_cells: number of cells in the row */
|
||||
int find_node_by_coords(int x, int y, int number_of_x_cells, int number_of_y_cells) {
|
||||
return y * number_of_x_cells + x;
|
||||
return y * number_of_x_cells + x;
|
||||
}
|
||||
|
||||
/* mark all neighbouring nodes of the nodes
|
||||
@ -48,86 +48,93 @@ int find_node_by_coords(int x, int y, int number_of_x_cells, int number_of_y_cel
|
||||
mark: number to mark neighbours
|
||||
number_of_cells: number of cells in the row
|
||||
returns number of marked nodes */
|
||||
int mark_neighbours_of_the_nodes(int *nodes, int *source_nodes, int *neighbours, int mark,
|
||||
int number_of_x_cells, int number_of_y_cells) {
|
||||
int i, j, neighbours_count = 0;
|
||||
int x, y, node;
|
||||
int xses[4] = { 0, 0, 1, -1};
|
||||
int yses[4] = {-1, 1, 0, 0};
|
||||
int mark_neighbours_of_the_nodes (int *nodes, int *source_nodes, int *neighbours, int mark,
|
||||
int number_of_x_cells, int number_of_y_cells)
|
||||
{
|
||||
int i, j, neighbours_count = 0;
|
||||
int x, y, node;
|
||||
int xses[4] = { 0, 0, 1, -1};
|
||||
int yses[4] = {-1, 1, 0, 0};
|
||||
|
||||
for(i = 1; i <= source_nodes[0]; i++) {
|
||||
find_x_y_of_the_node(&x, &y, source_nodes[i], number_of_x_cells, number_of_y_cells);
|
||||
if(x != -1 && y != -1) {
|
||||
for(j = 0; j < 4; j++) {
|
||||
if(x + xses[j] >= 0 && x + xses[j] < number_of_x_cells &&
|
||||
y + yses[j] >= 0 && y + yses[j] < number_of_y_cells) {
|
||||
node = find_node_by_coords(x + xses[j], y + yses[j], number_of_x_cells, number_of_y_cells);
|
||||
if((node != -1) && nodes[node] == 0) {
|
||||
nodes[node] = mark;
|
||||
neighbours[++neighbours_count] = node;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
neighbours[0] = neighbours_count;
|
||||
return neighbours_count;
|
||||
for (i = 1; i <= source_nodes[0]; i++)
|
||||
{
|
||||
find_x_y_of_the_node(&x, &y, source_nodes[i], number_of_x_cells, number_of_y_cells);
|
||||
if (x != -1 && y != -1) {
|
||||
for (j = 0; j < 4; j++) {
|
||||
if (x + xses[j] >= 0 && x + xses[j] < number_of_x_cells &&
|
||||
y + yses[j] >= 0 && y + yses[j] < number_of_y_cells) {
|
||||
node = find_node_by_coords(x + xses[j], y + yses[j], number_of_x_cells, number_of_y_cells);
|
||||
if ((node != -1) && nodes[node] == 0) {
|
||||
nodes[node] = mark;
|
||||
neighbours[++neighbours_count] = node;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
neighbours[0] = neighbours_count;
|
||||
return neighbours_count;
|
||||
}
|
||||
|
||||
/* check if nodes are neighbours */
|
||||
int is_neighbours(int node1, int node2, int xn, int yn) {
|
||||
int x1, y1, x2, y2;
|
||||
int is_neighbours(int node1, int node2, int xn, int yn)
|
||||
{
|
||||
int x1, y1, x2, y2;
|
||||
|
||||
find_x_y_of_the_node(&x1, &y1, node1, xn, yn);
|
||||
find_x_y_of_the_node(&x2, &y2, node2, xn, yn);
|
||||
find_x_y_of_the_node(&x1, &y1, node1, xn, yn);
|
||||
find_x_y_of_the_node(&x2, &y2, node2, xn, yn);
|
||||
|
||||
if((x1 == x2) && ((y1 == y2 + 1) || (y2 == y1 + 1))) {
|
||||
return 1;
|
||||
} else if((y1 == y2) && ((x1 == x2 + 1) || (x2 == x1 + 1))) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
if ((x1 == x2) && ((y1 == y2 + 1) || (y2 == y1 + 1))) {
|
||||
return 1;
|
||||
} else if ((y1 == y2) && ((x1 == x2 + 1) || (x2 == x1 + 1))) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* find the path between source_node and the target_node
|
||||
result stored in path
|
||||
returns 0 on failure and 1 on success */
|
||||
int find_path(int *nodes, int source_node, int target_node, int *path,
|
||||
int number_of_x_cells, int number_of_y_cells) {
|
||||
int waves[number_of_x_cells * number_of_y_cells][number_of_x_cells * number_of_y_cells];
|
||||
int i, j, k = 1, finish = 0;
|
||||
int find_path (int *nodes, int source_node, int target_node, int *path,
|
||||
int number_of_x_cells, int number_of_y_cells)
|
||||
{
|
||||
int waves[number_of_x_cells * number_of_y_cells][number_of_x_cells * number_of_y_cells];
|
||||
int i, j, k = 1, finish = 0;
|
||||
|
||||
waves[0][0] = 1;
|
||||
waves[0][1] = source_node;
|
||||
waves[0][0] = 1;
|
||||
waves[0][1] = source_node;
|
||||
|
||||
nodes[source_node] = -1;
|
||||
while(!finish) {
|
||||
if(!mark_neighbours_of_the_nodes(nodes, waves[k - 1], waves[k], k,
|
||||
number_of_x_cells, number_of_y_cells)) {
|
||||
/* the destination can never be reached */
|
||||
return 0;
|
||||
}
|
||||
for(i = 1; i <= waves[k][0]; i++) {
|
||||
if(waves[k][i] == target_node) {
|
||||
finish = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
k++;
|
||||
}
|
||||
nodes[source_node] = -1;
|
||||
while (!finish)
|
||||
{
|
||||
if (!mark_neighbours_of_the_nodes(nodes, waves[k - 1], waves[k], k,
|
||||
number_of_x_cells, number_of_y_cells)) {
|
||||
/* the destination can never be reached */
|
||||
return 0;
|
||||
}
|
||||
for (i = 1; i <= waves[k][0]; i++) {
|
||||
if (waves[k][i] == target_node) {
|
||||
finish = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
k++;
|
||||
}
|
||||
|
||||
path[0] = k;
|
||||
path[1] = waves[k - 1][i];
|
||||
for(j = k - 2; j > 0; j--) {
|
||||
finish = 0;
|
||||
for(i = 1; i <= waves[j][0]; i++) {
|
||||
if(is_neighbours(waves[j][i], path[k - j - 1],
|
||||
number_of_x_cells, number_of_y_cells)) {
|
||||
path[k - j] = waves[j][i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
path[0] = k;
|
||||
path[1] = waves[k - 1][i];
|
||||
for (j = k - 2; j > 0; j--)
|
||||
{
|
||||
finish = 0;
|
||||
for (i = 1; i <= waves[j][0]; i++) {
|
||||
if (is_neighbours(waves[j][i], path[k - j - 1],
|
||||
number_of_x_cells, number_of_y_cells)) {
|
||||
path[k - j] = waves[j][i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
12
src/path.h
12
src/path.h
@ -1,10 +1,12 @@
|
||||
#ifndef __GTKBALLS_PATH_H
|
||||
#define __GTKBALLS_PATH_H
|
||||
|
||||
int find_path (int *nodes, int source_node, int target_node, int *path,
|
||||
int number_of_x_cells, int number_of_y_cells);
|
||||
void find_x_y_of_the_node (int *x, int *y,
|
||||
int node, int number_of_x_cells, int number_of_y_cells);
|
||||
int find_node_of_x_y (int x, int y, int number_of_x_cells);
|
||||
int find_path (int *nodes, int source_node, int target_node, int *path,
|
||||
int number_of_x_cells, int number_of_y_cells);
|
||||
|
||||
void find_x_y_of_the_node (int *x, int *y,
|
||||
int node, int number_of_x_cells, int number_of_y_cells);
|
||||
|
||||
int find_node_of_x_y (int x, int y, int number_of_x_cells);
|
||||
|
||||
#endif
|
||||
|
@ -16,205 +16,212 @@
|
||||
#include "game.h"
|
||||
#include "mainwin.h"
|
||||
|
||||
enum {
|
||||
PR_DIALOG,
|
||||
PR_SHOW_NEXT,
|
||||
PR_SHOW_PATH,
|
||||
PR_SHOW_PAWS,
|
||||
PR_SHOW_ANIM,
|
||||
PR_SHOW_HL,
|
||||
PR_HL_DR,
|
||||
PR_HL_DG,
|
||||
PR_HL_DB,
|
||||
PR_TIME_LIMIT,
|
||||
PR_TIME_VALUE,
|
||||
PR_THEME_LIST,
|
||||
PR_SIZE
|
||||
enum
|
||||
{
|
||||
PR_DIALOG,
|
||||
PR_SHOW_NEXT,
|
||||
PR_SHOW_PATH,
|
||||
PR_SHOW_PAWS,
|
||||
PR_SHOW_ANIM,
|
||||
PR_SHOW_HL,
|
||||
PR_HL_DR,
|
||||
PR_HL_DG,
|
||||
PR_HL_DB,
|
||||
PR_TIME_LIMIT,
|
||||
PR_TIME_VALUE,
|
||||
PR_THEME_LIST,
|
||||
PR_SIZE
|
||||
};
|
||||
|
||||
void parent_toggled(GtkToggleButton *togglebutton, gpointer data) {
|
||||
gtk_widget_set_sensitive(GTK_WIDGET(data), gtk_toggle_button_get_active(togglebutton));
|
||||
gtk_widget_set_sensitive(GTK_WIDGET(data), gtk_toggle_button_get_active(togglebutton));
|
||||
}
|
||||
|
||||
void preferences_destroy_cb(GtkWidget *widget, gpointer data) {
|
||||
g_free(data);
|
||||
g_free(data);
|
||||
}
|
||||
|
||||
void preferences_cancel(GtkWidget *widget, gpointer data) {
|
||||
GtkWidget **buttons = data;
|
||||
gtk_widget_destroy(buttons[PR_DIALOG]);
|
||||
GtkWidget **buttons = data;
|
||||
gtk_widget_destroy(buttons[PR_DIALOG]);
|
||||
}
|
||||
|
||||
gboolean fix_draw_next_balls(gpointer data) {
|
||||
draw_next_balls();
|
||||
return FALSE;
|
||||
draw_next_balls();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void preferences_apply(GtkWidget *widget, gpointer data) {
|
||||
GtkWidget **buttons = data;
|
||||
GtkTreeModel *model;
|
||||
GtkTreeIter iter;
|
||||
gchar *msg, *save, *themename;
|
||||
|
||||
gtk_tree_selection_get_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(buttons[PR_THEME_LIST])), &model, &iter);
|
||||
gtk_tree_model_get(model, &iter, 0, &themename, -1);
|
||||
void preferences_apply(GtkWidget *widget, gpointer data)
|
||||
{
|
||||
GtkWidget **buttons = data;
|
||||
GtkTreeModel *model;
|
||||
GtkTreeIter iter;
|
||||
gchar *msg, *save, *themename;
|
||||
|
||||
if(strcmp(themename, pref_get_theme_name()) != 0) {
|
||||
save = g_strdup(pref_get_theme_name());
|
||||
pref_set_theme_name(themename);
|
||||
if(!load_theme(pref_get_theme_name())) {
|
||||
msg = g_strconcat(_("Failed loading theme \""), pref_get_theme_name(), "\"!\n", NULL);
|
||||
ut_simple_message_box(msg);
|
||||
g_free(msg);
|
||||
pref_set_theme_name(save);
|
||||
} else {
|
||||
set_jump_phase(0);
|
||||
remake_board(0, 1);
|
||||
draw_next_balls();
|
||||
}
|
||||
g_free(save);
|
||||
}
|
||||
g_free(themename);
|
||||
gtk_tree_selection_get_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(buttons[PR_THEME_LIST])), &model, &iter);
|
||||
gtk_tree_model_get(model, &iter, 0, &themename, -1);
|
||||
|
||||
pref_set_show_next_colors(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(buttons[PR_SHOW_NEXT])));
|
||||
mw_show_hide_next_balls(pref_get_show_next_colors());
|
||||
g_timeout_add(50, fix_draw_next_balls, NULL);
|
||||
pref_set_show_path(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(buttons[PR_SHOW_PATH])));
|
||||
pref_set_show_footprints(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(buttons[PR_SHOW_PAWS])));
|
||||
pref_set_show_destroy(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(buttons[PR_SHOW_ANIM])));
|
||||
if (strcmp(themename, pref_get_theme_name()) != 0) {
|
||||
save = g_strdup(pref_get_theme_name());
|
||||
pref_set_theme_name(themename);
|
||||
if (!load_theme(pref_get_theme_name())) {
|
||||
msg = g_strconcat(_("Failed loading theme \""), pref_get_theme_name(), "\"!\n", NULL);
|
||||
ut_simple_message_box(msg);
|
||||
g_free(msg);
|
||||
pref_set_theme_name(save);
|
||||
} else {
|
||||
set_jump_phase(0);
|
||||
remake_board(0, 1);
|
||||
draw_next_balls();
|
||||
}
|
||||
g_free(save);
|
||||
}
|
||||
g_free(themename);
|
||||
|
||||
pref_set_show_highlight(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(buttons[PR_SHOW_HL])));
|
||||
pref_set_show_next_colors(gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(buttons[PR_SHOW_NEXT])));
|
||||
mw_show_hide_next_balls(pref_get_show_next_colors());
|
||||
g_timeout_add(50, fix_draw_next_balls, NULL);
|
||||
pref_set_show_path(gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(buttons[PR_SHOW_PATH])));
|
||||
pref_set_show_footprints(gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(buttons[PR_SHOW_PAWS])));
|
||||
pref_set_show_destroy (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(buttons[PR_SHOW_ANIM])));
|
||||
|
||||
prefs_set_hl_dr(gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(buttons[PR_HL_DR])));
|
||||
prefs_set_hl_dg(gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(buttons[PR_HL_DG])));
|
||||
prefs_set_hl_db(gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(buttons[PR_HL_DB])));
|
||||
pref_set_show_highlight (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(buttons[PR_SHOW_HL])));
|
||||
|
||||
gtkb_make_hl_pixmap(gtkbTheme);
|
||||
prefs_set_hl_dr(gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(buttons[PR_HL_DR])));
|
||||
prefs_set_hl_dg(gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(buttons[PR_HL_DG])));
|
||||
prefs_set_hl_db(gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(buttons[PR_HL_DB])));
|
||||
|
||||
redraw_pointer();
|
||||
if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(buttons[PR_TIME_LIMIT]))) {
|
||||
timer_start();
|
||||
timer_set_limit(gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(buttons[PR_TIME_VALUE])));
|
||||
} else {
|
||||
timer_set_limit(-1);
|
||||
}
|
||||
msg = save_preferences();
|
||||
if(msg) {
|
||||
ut_simple_message_box(msg);
|
||||
g_free(msg);
|
||||
}
|
||||
gtkb_make_hl_pixmap (gtkbTheme);
|
||||
|
||||
redraw_pointer();
|
||||
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(buttons[PR_TIME_LIMIT]))) {
|
||||
timer_start();
|
||||
timer_set_limit(gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(buttons[PR_TIME_VALUE])));
|
||||
} else {
|
||||
timer_set_limit(-1);
|
||||
}
|
||||
msg = save_preferences();
|
||||
if (msg) {
|
||||
ut_simple_message_box(msg);
|
||||
g_free(msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void preferences_ok(GtkWidget *widget, gpointer data) {
|
||||
GtkWidget **buttons = data;
|
||||
preferences_apply(widget, buttons);
|
||||
gtk_widget_destroy(buttons[PR_DIALOG]);
|
||||
GtkWidget **buttons = data;
|
||||
preferences_apply(widget, buttons);
|
||||
gtk_widget_destroy(buttons[PR_DIALOG]);
|
||||
}
|
||||
|
||||
void preferences_dialog(void) {
|
||||
GtkWidget **buttons;
|
||||
GtkWidget *frame;
|
||||
GtkWidget *big_vbox, *vbox, *buttons_box;
|
||||
GtkWidget *theme_scrolled_window;
|
||||
GtkWidget *separator;
|
||||
gint i, st;
|
||||
GtkListStore *store;
|
||||
GtkTreeIter iter;
|
||||
GtkTreePath *path;
|
||||
GtkCellRenderer *renderer;
|
||||
GtkTreeViewColumn *column;
|
||||
gchar *pathstr;
|
||||
gchar **themelist;
|
||||
|
||||
if(!(themelist = get_available_themes())) {
|
||||
ut_simple_message_box(_("No themes available! =(\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
buttons = g_malloc(PR_SIZE * sizeof(GtkWidget));
|
||||
void preferences_dialog (void)
|
||||
{
|
||||
GtkWidget ** buttons;
|
||||
GtkWidget * frame;
|
||||
GtkWidget * big_vbox, * vbox, * buttons_box;
|
||||
GtkWidget * theme_scrolled_window;
|
||||
GtkWidget * separator;
|
||||
gint i, st;
|
||||
GtkListStore * store;
|
||||
GtkTreeIter iter;
|
||||
GtkTreePath * path;
|
||||
GtkCellRenderer * renderer;
|
||||
GtkTreeViewColumn * column;
|
||||
gchar * pathstr;
|
||||
gchar ** themelist;
|
||||
|
||||
buttons[PR_DIALOG] = ut_window_new(_("Preferences"), "GtkBalls_Preferences", "GtkBalls", TRUE, TRUE, TRUE, 5);
|
||||
g_signal_connect(G_OBJECT(buttons[PR_DIALOG]), "destroy", G_CALLBACK(preferences_destroy_cb), buttons);
|
||||
if (!(themelist = get_available_themes())) {
|
||||
ut_simple_message_box(_("No themes available! =(\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
big_vbox = gtk_vbox_new(FALSE, 0);
|
||||
gtk_container_add(GTK_CONTAINER(buttons[PR_DIALOG]), big_vbox);
|
||||
buttons = g_malloc (PR_SIZE * sizeof(GtkWidget));
|
||||
|
||||
frame = gtk_frame_new(_("Preferences"));
|
||||
gtk_box_pack_start(GTK_BOX(big_vbox), frame, FALSE, FALSE, 0);
|
||||
buttons[PR_DIALOG] = ut_window_new(_("Preferences"), "GtkBalls_Preferences", "GtkBalls", TRUE, TRUE, TRUE, 5);
|
||||
g_signal_connect (G_OBJECT(buttons[PR_DIALOG]), "destroy", G_CALLBACK(preferences_destroy_cb), buttons);
|
||||
|
||||
vbox = gtk_vbox_new(FALSE, 0);
|
||||
gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
|
||||
gtk_container_add(GTK_CONTAINER(frame), vbox);
|
||||
big_vbox = gtk_vbox_new (FALSE, 0);
|
||||
gtk_container_add (GTK_CONTAINER(buttons[PR_DIALOG]), big_vbox);
|
||||
|
||||
buttons[PR_SHOW_NEXT] = ut_check_button_new(_("Show colors that will appear on next turn"), pref_get_show_next_colors(), vbox);
|
||||
buttons[PR_SHOW_PATH] = ut_check_button_new(_("Show path of the ball"), pref_get_show_path(), vbox);
|
||||
buttons[PR_SHOW_PAWS] = ut_check_button_new(_("Show footprints of the ball"), pref_get_show_footprints(), vbox);
|
||||
buttons[PR_SHOW_ANIM] = ut_check_button_new(_("Show animation of disappearing of the ball"), pref_get_show_destroy(), vbox);
|
||||
buttons[PR_SHOW_HL] = ut_check_button_new(_("Highlight \"active\" cell"), pref_get_show_highlight(), vbox);
|
||||
frame = gtk_frame_new (_("Preferences"));
|
||||
gtk_box_pack_start (GTK_BOX(big_vbox), frame, FALSE, FALSE, 0);
|
||||
|
||||
buttons[PR_HL_DR] = ut_spin_button_start_new(_("Highlight red value: "), -128, 128, prefs_get_hl_dr(), vbox);
|
||||
buttons[PR_HL_DG] = ut_spin_button_start_new(_("Highlight green value: "), -128, 128, prefs_get_hl_dg(), vbox);
|
||||
buttons[PR_HL_DB] = ut_spin_button_start_new(_("Highlight blue value: "), -128, 128, prefs_get_hl_db(), vbox);
|
||||
g_signal_connect(G_OBJECT(buttons[PR_SHOW_HL]), "toggled", G_CALLBACK(parent_toggled), buttons[PR_HL_DR]);
|
||||
g_signal_connect(G_OBJECT(buttons[PR_SHOW_HL]), "toggled", G_CALLBACK(parent_toggled), buttons[PR_HL_DG]);
|
||||
g_signal_connect(G_OBJECT(buttons[PR_SHOW_HL]), "toggled", G_CALLBACK(parent_toggled), buttons[PR_HL_DB]);
|
||||
gtk_widget_set_sensitive(buttons[PR_HL_DR], pref_get_show_highlight());
|
||||
gtk_widget_set_sensitive(buttons[PR_HL_DG], pref_get_show_highlight());
|
||||
gtk_widget_set_sensitive(buttons[PR_HL_DB], pref_get_show_highlight());
|
||||
vbox = gtk_vbox_new (FALSE, 0);
|
||||
gtk_container_set_border_width (GTK_CONTAINER(vbox), 5);
|
||||
gtk_container_add (GTK_CONTAINER(frame), vbox);
|
||||
|
||||
buttons[PR_TIME_LIMIT] = ut_check_button_new(_("Enable time limit"), timer_get_limit() > 0 ? 1 : 0, vbox);
|
||||
buttons[PR_TIME_VALUE] = ut_spin_button_start_new(_("Time limit (seconds): "), 1, 3600, timer_get_limit() > 0 ? timer_get_limit() : 60, vbox);
|
||||
g_signal_connect(G_OBJECT(buttons[PR_TIME_LIMIT]), "toggled", G_CALLBACK(parent_toggled), buttons[PR_TIME_VALUE]);
|
||||
gtk_widget_set_sensitive(buttons[PR_TIME_VALUE], timer_get_limit() > 0 ? 1 : 0);
|
||||
buttons[PR_SHOW_NEXT] = ut_check_button_new(_("Show colors that will appear on next turn"), pref_get_show_next_colors(), vbox);
|
||||
buttons[PR_SHOW_PATH] = ut_check_button_new(_("Show path of the ball"), pref_get_show_path(), vbox);
|
||||
buttons[PR_SHOW_PAWS] = ut_check_button_new(_("Show footprints of the ball"), pref_get_show_footprints(), vbox);
|
||||
buttons[PR_SHOW_ANIM] = ut_check_button_new(_("Show animation of disappearing of the ball"), pref_get_show_destroy(), vbox);
|
||||
buttons[PR_SHOW_HL] = ut_check_button_new(_("Highlight \"active\" cell"), pref_get_show_highlight(), vbox);
|
||||
|
||||
theme_scrolled_window = gtk_scrolled_window_new(NULL, NULL);
|
||||
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(theme_scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
|
||||
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(theme_scrolled_window), GTK_SHADOW_ETCHED_IN);
|
||||
gtk_box_pack_start(GTK_BOX(vbox), theme_scrolled_window, FALSE, FALSE, 5);
|
||||
buttons[PR_HL_DR] = ut_spin_button_start_new(_("Highlight red value: "), -128, 128, prefs_get_hl_dr(), vbox);
|
||||
buttons[PR_HL_DG] = ut_spin_button_start_new(_("Highlight green value: "), -128, 128, prefs_get_hl_dg(), vbox);
|
||||
buttons[PR_HL_DB] = ut_spin_button_start_new(_("Highlight blue value: "), -128, 128, prefs_get_hl_db(), vbox);
|
||||
g_signal_connect (G_OBJECT(buttons[PR_SHOW_HL]), "toggled", G_CALLBACK(parent_toggled), buttons[PR_HL_DR]);
|
||||
g_signal_connect (G_OBJECT(buttons[PR_SHOW_HL]), "toggled", G_CALLBACK(parent_toggled), buttons[PR_HL_DG]);
|
||||
g_signal_connect (G_OBJECT(buttons[PR_SHOW_HL]), "toggled", G_CALLBACK(parent_toggled), buttons[PR_HL_DB]);
|
||||
gtk_widget_set_sensitive (buttons[PR_HL_DR], pref_get_show_highlight());
|
||||
gtk_widget_set_sensitive (buttons[PR_HL_DG], pref_get_show_highlight());
|
||||
gtk_widget_set_sensitive (buttons[PR_HL_DB], pref_get_show_highlight());
|
||||
|
||||
store = gtk_list_store_new(1, G_TYPE_STRING);
|
||||
for(i = 0, st = 0; themelist[i] != NULL; i++) {
|
||||
gtk_list_store_append(store, &iter);
|
||||
gtk_list_store_set(store, &iter, 0, themelist[i], -1);
|
||||
if(!strcmp(themelist[i], pref_get_theme_name())) {
|
||||
st = i;
|
||||
}
|
||||
g_free(themelist[i]);
|
||||
}
|
||||
g_free(themelist);
|
||||
buttons[PR_TIME_LIMIT] = ut_check_button_new(_("Enable time limit"), timer_get_limit() > 0 ? 1 : 0, vbox);
|
||||
buttons[PR_TIME_VALUE] = ut_spin_button_start_new(_("Time limit (seconds): "), 1, 3600, timer_get_limit() > 0 ? timer_get_limit() : 60, vbox);
|
||||
g_signal_connect (G_OBJECT(buttons[PR_TIME_LIMIT]), "toggled", G_CALLBACK(parent_toggled), buttons[PR_TIME_VALUE]);
|
||||
gtk_widget_set_sensitive (buttons[PR_TIME_VALUE], timer_get_limit() > 0 ? 1 : 0);
|
||||
|
||||
buttons[PR_THEME_LIST] = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
|
||||
gtk_widget_set_size_request(buttons[PR_THEME_LIST], -1, 150);
|
||||
g_object_unref(G_OBJECT(store));
|
||||
gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(buttons[PR_THEME_LIST]), TRUE);
|
||||
gtk_tree_view_set_search_column(GTK_TREE_VIEW(buttons[PR_THEME_LIST]), 0);
|
||||
gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(buttons[PR_THEME_LIST])), GTK_SELECTION_BROWSE);
|
||||
gtk_container_add(GTK_CONTAINER(theme_scrolled_window), buttons[PR_THEME_LIST]);
|
||||
theme_scrolled_window = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(theme_scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
|
||||
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(theme_scrolled_window), GTK_SHADOW_ETCHED_IN);
|
||||
gtk_box_pack_start (GTK_BOX(vbox), theme_scrolled_window, FALSE, FALSE, 5);
|
||||
|
||||
renderer = gtk_cell_renderer_text_new();
|
||||
column = gtk_tree_view_column_new_with_attributes(_("Select Theme"), renderer, "text", 0, NULL);
|
||||
gtk_tree_view_column_set_sort_column_id(column, 0);
|
||||
gtk_tree_view_append_column(GTK_TREE_VIEW(buttons[PR_THEME_LIST]), column);
|
||||
store = gtk_list_store_new (1, G_TYPE_STRING);
|
||||
for (i = 0, st = 0; themelist[i] != NULL; i++) {
|
||||
gtk_list_store_append (store, &iter);
|
||||
gtk_list_store_set (store, &iter, 0, themelist[i], -1);
|
||||
if (!strcmp(themelist[i], pref_get_theme_name())) {
|
||||
st = i;
|
||||
}
|
||||
g_free (themelist[i]);
|
||||
}
|
||||
g_free (themelist);
|
||||
|
||||
pathstr = g_strdup_printf("%u", st);
|
||||
if((path = gtk_tree_path_new_from_string(pathstr))) {
|
||||
gtk_tree_selection_select_path(gtk_tree_view_get_selection(GTK_TREE_VIEW(buttons[PR_THEME_LIST])), path);
|
||||
gtk_tree_view_set_cursor(GTK_TREE_VIEW(buttons[PR_THEME_LIST]), path, NULL, FALSE);
|
||||
gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(buttons[PR_THEME_LIST]), path, NULL, TRUE, 0, 0);
|
||||
gtk_tree_path_free(path);
|
||||
}
|
||||
g_free(pathstr);
|
||||
buttons[PR_THEME_LIST] = gtk_tree_view_new_with_model (GTK_TREE_MODEL(store));
|
||||
gtk_widget_set_size_request (buttons[PR_THEME_LIST], -1, 150);
|
||||
g_object_unref (G_OBJECT(store));
|
||||
gtk_tree_view_set_rules_hint (GTK_TREE_VIEW(buttons[PR_THEME_LIST]), TRUE);
|
||||
gtk_tree_view_set_search_column (GTK_TREE_VIEW(buttons[PR_THEME_LIST]), 0);
|
||||
gtk_tree_selection_set_mode (gtk_tree_view_get_selection(GTK_TREE_VIEW(buttons[PR_THEME_LIST])), GTK_SELECTION_BROWSE);
|
||||
gtk_container_add (GTK_CONTAINER(theme_scrolled_window), buttons[PR_THEME_LIST]);
|
||||
|
||||
separator = gtk_hseparator_new();
|
||||
gtk_box_pack_start(GTK_BOX(big_vbox), separator, FALSE, FALSE, 5);
|
||||
renderer = gtk_cell_renderer_text_new ();
|
||||
column = gtk_tree_view_column_new_with_attributes (_("Select Theme"), renderer, "text", 0, NULL);
|
||||
gtk_tree_view_column_set_sort_column_id (column, 0);
|
||||
gtk_tree_view_append_column (GTK_TREE_VIEW(buttons[PR_THEME_LIST]), column);
|
||||
|
||||
buttons_box = gtk_hbutton_box_new();
|
||||
gtk_button_box_set_layout(GTK_BUTTON_BOX(buttons_box), GTK_BUTTONBOX_SPREAD);
|
||||
gtk_box_pack_start(GTK_BOX(big_vbox), buttons_box, TRUE, TRUE, 0);
|
||||
pathstr = g_strdup_printf ("%u", st);
|
||||
if ((path = gtk_tree_path_new_from_string (pathstr))) {
|
||||
gtk_tree_selection_select_path (gtk_tree_view_get_selection(GTK_TREE_VIEW(buttons[PR_THEME_LIST])), path);
|
||||
gtk_tree_view_set_cursor (GTK_TREE_VIEW(buttons[PR_THEME_LIST]), path, NULL, FALSE);
|
||||
gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW(buttons[PR_THEME_LIST]), path, NULL, TRUE, 0, 0);
|
||||
gtk_tree_path_free (path);
|
||||
}
|
||||
g_free (pathstr);
|
||||
|
||||
gtk_widget_grab_default(ut_button_new_stock(GTK_STOCK_OK, preferences_ok, buttons, buttons_box));
|
||||
ut_button_new_stock(GTK_STOCK_CANCEL, preferences_cancel, buttons, buttons_box);
|
||||
ut_button_new_stock(GTK_STOCK_APPLY, preferences_apply, buttons, buttons_box);
|
||||
separator = gtk_hseparator_new ();
|
||||
gtk_box_pack_start (GTK_BOX(big_vbox), separator, FALSE, FALSE, 5);
|
||||
|
||||
gtk_widget_show_all(buttons[PR_DIALOG]);
|
||||
buttons_box = gtk_hbutton_box_new ();
|
||||
gtk_button_box_set_layout (GTK_BUTTON_BOX(buttons_box), GTK_BUTTONBOX_SPREAD);
|
||||
gtk_box_pack_start (GTK_BOX(big_vbox), buttons_box, TRUE, TRUE, 0);
|
||||
|
||||
gtk_widget_grab_default (ut_button_new_stock(GTK_STOCK_OK, preferences_ok, buttons, buttons_box));
|
||||
ut_button_new_stock (GTK_STOCK_CANCEL, preferences_cancel, buttons, buttons_box);
|
||||
ut_button_new_stock (GTK_STOCK_APPLY, preferences_apply, buttons, buttons_box);
|
||||
|
||||
gtk_widget_show_all (buttons[PR_DIALOG]);
|
||||
}
|
||||
|
243
src/prefs.c
243
src/prefs.c
@ -34,207 +34,212 @@ gchar _default_theme_name[] = "Default";
|
||||
gchar *_theme_name = NULL;
|
||||
|
||||
gint pref_get_show_next_colors(void) {
|
||||
return _show_next_colors;
|
||||
return _show_next_colors;
|
||||
}
|
||||
|
||||
void pref_set_show_next_colors(gint val) {
|
||||
_show_next_colors = val;
|
||||
_show_next_colors = val;
|
||||
}
|
||||
|
||||
gint pref_get_show_path(void) {
|
||||
return _show_path;
|
||||
return _show_path;
|
||||
}
|
||||
|
||||
void pref_set_show_path(gint val) {
|
||||
_show_path = val;
|
||||
_show_path = val;
|
||||
}
|
||||
|
||||
gint pref_get_show_footprints(void) {
|
||||
return _show_footprints;
|
||||
return _show_footprints;
|
||||
}
|
||||
|
||||
void pref_set_show_footprints(gint val) {
|
||||
_show_footprints = val;
|
||||
_show_footprints = val;
|
||||
}
|
||||
|
||||
gint pref_get_show_destroy(void) {
|
||||
return _show_destroy;
|
||||
return _show_destroy;
|
||||
}
|
||||
|
||||
void pref_set_show_destroy(gint val) {
|
||||
_show_destroy = val;
|
||||
_show_destroy = val;
|
||||
}
|
||||
|
||||
gint pref_get_show_highlight(void) {
|
||||
return _show_highlight;
|
||||
return _show_highlight;
|
||||
}
|
||||
|
||||
void pref_set_show_highlight(gint val) {
|
||||
_show_highlight = val;
|
||||
_show_highlight = val;
|
||||
}
|
||||
|
||||
gint prefs_get_hl_dr(void) {
|
||||
return _hl_dr;
|
||||
return _hl_dr;
|
||||
}
|
||||
|
||||
void prefs_set_hl_dr(gint dr) {
|
||||
_hl_dr = dr;
|
||||
_hl_dr = dr;
|
||||
}
|
||||
|
||||
gint prefs_get_hl_dg(void) {
|
||||
return _hl_dg;
|
||||
return _hl_dg;
|
||||
}
|
||||
|
||||
void prefs_set_hl_dg(gint dg) {
|
||||
_hl_dg = dg;
|
||||
_hl_dg = dg;
|
||||
}
|
||||
|
||||
gint prefs_get_hl_db(void) {
|
||||
return _hl_db;
|
||||
return _hl_db;
|
||||
}
|
||||
|
||||
void prefs_set_hl_db(gint db) {
|
||||
_hl_db = db;
|
||||
_hl_db = db;
|
||||
}
|
||||
|
||||
gchar *pref_get_theme_name(void) {
|
||||
return _theme_name;
|
||||
return _theme_name;
|
||||
}
|
||||
|
||||
gchar *pref_get_default_theme_name(void) {
|
||||
return _default_theme_name;
|
||||
return _default_theme_name;
|
||||
}
|
||||
|
||||
void pref_set_theme_name(gchar *name) {
|
||||
if(_theme_name) {
|
||||
g_free(_theme_name);
|
||||
}
|
||||
_theme_name = g_strdup(name);
|
||||
if (_theme_name) {
|
||||
g_free(_theme_name);
|
||||
}
|
||||
_theme_name = g_strdup(name);
|
||||
}
|
||||
|
||||
gchar *find_rc_file(void) {
|
||||
gchar *rc_file = NULL;
|
||||
gchar *rc_file = NULL;
|
||||
|
||||
if(getenv("HOME")) {
|
||||
rc_file = g_strdup_printf("%s/%s", getenv ("HOME"), CONFIG_FILE_NAME);
|
||||
} else { /* unable to find $HOME, assuming current directory */
|
||||
rc_file = g_strdup(CONFIG_FILE_NAME);
|
||||
}
|
||||
if (getenv("HOME")) {
|
||||
rc_file = g_strdup_printf("%s/%s", getenv ("HOME"), CONFIG_FILE_NAME);
|
||||
} else { /* unable to find $HOME, assuming current directory */
|
||||
rc_file = g_strdup(CONFIG_FILE_NAME);
|
||||
}
|
||||
|
||||
return rc_file;
|
||||
return rc_file;
|
||||
}
|
||||
|
||||
/* converts string to TRUE/FALSE. "true", "yes" or "1" is TRUE, otherwise - FALSE */
|
||||
gboolean pref_str_to_bool(gchar *val) {
|
||||
if(!g_ascii_strcasecmp(val, "true") ||
|
||||
!g_ascii_strcasecmp(val, "yes") ||
|
||||
!g_ascii_strcasecmp(val, "1")) {
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
if (!g_ascii_strcasecmp(val, "true") ||
|
||||
!g_ascii_strcasecmp(val, "yes") ||
|
||||
!g_ascii_strcasecmp(val, "1")) {
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* converts boolean to string
|
||||
returns _pointer_ to "yes" or "no". returned string should NOT be free()'d! */
|
||||
gchar *pref_bool_to_str(gboolean val) {
|
||||
return val ? "yes" : "no";
|
||||
return val ? "yes" : "no";
|
||||
}
|
||||
|
||||
/* we use very lame preferences file format: ``property=value\n''.
|
||||
so - there must be no whitespaces on begin/end of line =) */
|
||||
void load_preferences(void) {
|
||||
FILE *fp;
|
||||
gchar *rc_file;
|
||||
gchar buffer[BUFFER_SIZE];
|
||||
gchar **prop_val;
|
||||
void load_preferences(void)
|
||||
{
|
||||
FILE *fp;
|
||||
gchar *rc_file;
|
||||
gchar buffer[BUFFER_SIZE];
|
||||
gchar **prop_val;
|
||||
|
||||
if(!_theme_name) {
|
||||
_theme_name = g_strdup(_default_theme_name);
|
||||
}
|
||||
rc_file = find_rc_file();
|
||||
if((fp = fopen(rc_file, "r"))) {
|
||||
while(fgets(buffer, BUFFER_SIZE, fp)) {
|
||||
g_strchomp(buffer);
|
||||
prop_val = g_strsplit(buffer, "=", 2);
|
||||
if(prop_val[0] && prop_val[0][0] && prop_val[1] && prop_val[1][0]) {
|
||||
if(!g_ascii_strcasecmp(prop_val[0], "show_hints")) {
|
||||
_show_next_colors = pref_str_to_bool(prop_val[1]);
|
||||
} else if(!g_ascii_strcasecmp(prop_val[0], "show_path")) {
|
||||
_show_path = pref_str_to_bool(prop_val[1]);
|
||||
} else if(!g_ascii_strcasecmp(prop_val[0], "show_footprints")) {
|
||||
_show_footprints = pref_str_to_bool(prop_val[1]);
|
||||
} else if(!g_ascii_strcasecmp(prop_val[0], "show_destroy")) {
|
||||
_show_destroy = pref_str_to_bool(prop_val[1]);
|
||||
} else if(!g_ascii_strcasecmp(prop_val[0], "show_highlight")) {
|
||||
_show_highlight = pref_str_to_bool(prop_val[1]);
|
||||
} else if(!g_ascii_strcasecmp(prop_val[0], "theme_name")) {
|
||||
if(_theme_name) {
|
||||
g_free(_theme_name);
|
||||
}
|
||||
_theme_name = g_strdup(prop_val[1]);
|
||||
} else if(!g_ascii_strcasecmp(prop_val[0], "rules_xsize")) {
|
||||
rules_set_width(atoi(prop_val[1]));
|
||||
} else if(!g_ascii_strcasecmp(prop_val[0], "rules_ysize")) {
|
||||
rules_set_height(atoi(prop_val[1]));
|
||||
} else if(!g_ascii_strcasecmp(prop_val[0], "rules_colors")) {
|
||||
rules_set_colors(atoi(prop_val[1]));
|
||||
} else if(!g_ascii_strcasecmp(prop_val[0], "rules_next")) {
|
||||
rules_set_next(atoi(prop_val[1]));
|
||||
} else if(!g_ascii_strcasecmp(prop_val[0], "rules_destroy")) {
|
||||
rules_set_destroy(atoi(prop_val[1]));
|
||||
} else if(!g_ascii_strcasecmp(prop_val[0], "time_limit")) {
|
||||
timer_set_limit(atoi(prop_val[1]));
|
||||
} else if(!g_ascii_strcasecmp(prop_val[0], "highlight_dr")) {
|
||||
prefs_set_hl_dr(atoi(prop_val[1]));
|
||||
} else if(!g_ascii_strcasecmp(prop_val[0], "highlight_dg")) {
|
||||
prefs_set_hl_dg(atoi(prop_val[1]));
|
||||
} else if(!g_ascii_strcasecmp(prop_val[0], "highlight_db")) {
|
||||
prefs_set_hl_db(atoi(prop_val[1]));
|
||||
}
|
||||
}
|
||||
g_strfreev(prop_val);
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
g_free(rc_file);
|
||||
if (!_theme_name) {
|
||||
_theme_name = g_strdup(_default_theme_name);
|
||||
}
|
||||
rc_file = find_rc_file();
|
||||
if ((fp = fopen(rc_file, "r")))
|
||||
{
|
||||
while(fgets(buffer, BUFFER_SIZE, fp))
|
||||
{
|
||||
g_strchomp(buffer);
|
||||
prop_val = g_strsplit(buffer, "=", 2);
|
||||
if (prop_val[0] && prop_val[0][0] && prop_val[1] && prop_val[1][0])
|
||||
{
|
||||
if (!g_ascii_strcasecmp(prop_val[0], "show_hints")) {
|
||||
_show_next_colors = pref_str_to_bool(prop_val[1]);
|
||||
} else if (!g_ascii_strcasecmp(prop_val[0], "show_path")) {
|
||||
_show_path = pref_str_to_bool(prop_val[1]);
|
||||
} else if (!g_ascii_strcasecmp(prop_val[0], "show_footprints")) {
|
||||
_show_footprints = pref_str_to_bool(prop_val[1]);
|
||||
} else if (!g_ascii_strcasecmp(prop_val[0], "show_destroy")) {
|
||||
_show_destroy = pref_str_to_bool(prop_val[1]);
|
||||
} else if (!g_ascii_strcasecmp(prop_val[0], "show_highlight")) {
|
||||
_show_highlight = pref_str_to_bool(prop_val[1]);
|
||||
} else if (!g_ascii_strcasecmp(prop_val[0], "theme_name")) {
|
||||
if (_theme_name) {
|
||||
g_free(_theme_name);
|
||||
}
|
||||
_theme_name = g_strdup(prop_val[1]);
|
||||
} else if (!g_ascii_strcasecmp(prop_val[0], "rules_xsize")) {
|
||||
rules_set_width(atoi(prop_val[1]));
|
||||
} else if (!g_ascii_strcasecmp(prop_val[0], "rules_ysize")) {
|
||||
rules_set_height(atoi(prop_val[1]));
|
||||
} else if (!g_ascii_strcasecmp(prop_val[0], "rules_colors")) {
|
||||
rules_set_colors(atoi(prop_val[1]));
|
||||
} else if (!g_ascii_strcasecmp(prop_val[0], "rules_next")) {
|
||||
rules_set_next(atoi(prop_val[1]));
|
||||
} else if (!g_ascii_strcasecmp(prop_val[0], "rules_destroy")) {
|
||||
rules_set_destroy(atoi(prop_val[1]));
|
||||
} else if (!g_ascii_strcasecmp(prop_val[0], "time_limit")) {
|
||||
timer_set_limit(atoi(prop_val[1]));
|
||||
} else if (!g_ascii_strcasecmp(prop_val[0], "highlight_dr")) {
|
||||
prefs_set_hl_dr(atoi(prop_val[1]));
|
||||
} else if (!g_ascii_strcasecmp(prop_val[0], "highlight_dg")) {
|
||||
prefs_set_hl_dg(atoi(prop_val[1]));
|
||||
} else if (!g_ascii_strcasecmp(prop_val[0], "highlight_db")) {
|
||||
prefs_set_hl_db(atoi(prop_val[1]));
|
||||
}
|
||||
}
|
||||
g_strfreev(prop_val);
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
g_free(rc_file);
|
||||
}
|
||||
|
||||
/* writes ``property=value\n'' to fp.
|
||||
why i made it separate function? for "feature purposes" =) */
|
||||
void write_pref_string(FILE *fp, gchar *property, gchar *value) {
|
||||
fprintf(fp, "%s=%s\n", property, value);
|
||||
fprintf (fp, "%s=%s\n", property, value);
|
||||
}
|
||||
|
||||
void write_pref_int(FILE *fp, gchar *property, gint value) {
|
||||
fprintf(fp, "%s=%d\n", property, value);
|
||||
fprintf (fp, "%s=%d\n", property, value);
|
||||
}
|
||||
|
||||
gchar *save_preferences(void) {
|
||||
FILE *fp;
|
||||
gchar *rc_file/*, *err*/;
|
||||
gchar *ret = NULL;
|
||||
gchar *save_preferences (void)
|
||||
{
|
||||
FILE *fp;
|
||||
gchar *rc_file/*, *err*/;
|
||||
gchar *ret = NULL;
|
||||
|
||||
rc_file = find_rc_file();
|
||||
if((fp = fopen(rc_file, "w"))) {
|
||||
write_pref_string(fp, "show_hints", pref_bool_to_str(_show_next_colors));
|
||||
write_pref_string(fp, "show_path", pref_bool_to_str(_show_path));
|
||||
write_pref_string(fp, "show_footprints", pref_bool_to_str(_show_footprints));
|
||||
write_pref_string(fp, "show_destroy", pref_bool_to_str(_show_destroy));
|
||||
write_pref_string(fp, "show_highlight", pref_bool_to_str(_show_highlight));
|
||||
write_pref_string(fp, "theme_name", _theme_name);
|
||||
write_pref_int(fp, "rules_xsize", rules_get_width());
|
||||
write_pref_int(fp, "rules_ysize", rules_get_height());
|
||||
write_pref_int(fp, "rules_colors", rules_get_colors());
|
||||
write_pref_int(fp, "rules_next", rules_get_next());
|
||||
write_pref_int(fp, "rules_destroy", rules_get_destroy());
|
||||
write_pref_int(fp, "time_limit", timer_get_limit());
|
||||
write_pref_int(fp, "highlight_dr", prefs_get_hl_dr());
|
||||
write_pref_int(fp, "highlight_dg", prefs_get_hl_dg());
|
||||
write_pref_int(fp, "highlight_db", prefs_get_hl_db());
|
||||
fclose(fp);
|
||||
} else {
|
||||
ret = g_strdup_printf(_("Can't write to %s: %s"), rc_file, strerror(errno));
|
||||
}
|
||||
g_free(rc_file);
|
||||
return ret;
|
||||
rc_file = find_rc_file();
|
||||
if ((fp = fopen(rc_file, "w"))) {
|
||||
write_pref_string(fp, "show_hints", pref_bool_to_str(_show_next_colors));
|
||||
write_pref_string(fp, "show_path", pref_bool_to_str(_show_path));
|
||||
write_pref_string(fp, "show_footprints", pref_bool_to_str(_show_footprints));
|
||||
write_pref_string(fp, "show_destroy", pref_bool_to_str(_show_destroy));
|
||||
write_pref_string(fp, "show_highlight", pref_bool_to_str(_show_highlight));
|
||||
write_pref_string(fp, "theme_name", _theme_name);
|
||||
write_pref_int(fp, "rules_xsize", rules_get_width());
|
||||
write_pref_int(fp, "rules_ysize", rules_get_height());
|
||||
write_pref_int(fp, "rules_colors", rules_get_colors());
|
||||
write_pref_int(fp, "rules_next", rules_get_next());
|
||||
write_pref_int(fp, "rules_destroy", rules_get_destroy());
|
||||
write_pref_int(fp, "time_limit", timer_get_limit());
|
||||
write_pref_int(fp, "highlight_dr", prefs_get_hl_dr());
|
||||
write_pref_int(fp, "highlight_dg", prefs_get_hl_dg());
|
||||
write_pref_int(fp, "highlight_db", prefs_get_hl_db());
|
||||
fclose(fp);
|
||||
} else {
|
||||
ret = g_strdup_printf(_("Can't write to %s: %s"), rc_file, strerror(errno));
|
||||
}
|
||||
g_free(rc_file);
|
||||
return ret;
|
||||
}
|
||||
|
107
src/rules.c
107
src/rules.c
@ -11,66 +11,67 @@
|
||||
#include "gtkutils.h"
|
||||
|
||||
/* Show dialog box with game rules*/
|
||||
void show_rules(GtkWidget *widget, gpointer data) {
|
||||
GtkWidget *window;
|
||||
GtkWidget *vbox, *hbox, *button_box;
|
||||
GtkWidget *label;
|
||||
GtkWidget *frame;
|
||||
GtkWidget *separator;
|
||||
GtkWidget *ok_button;
|
||||
void show_rules (GtkWidget *widget, gpointer data)
|
||||
{
|
||||
GtkWidget * window;
|
||||
GtkWidget * vbox, * hbox, * button_box;
|
||||
GtkWidget * label;
|
||||
GtkWidget * frame;
|
||||
GtkWidget * separator;
|
||||
GtkWidget * ok_button;
|
||||
|
||||
window=ut_window_new(_("Rules"), "GtkBalls_Rules", "GtkBalls", TRUE, FALSE, FALSE, 5);
|
||||
window = ut_window_new(_("Rules"), "GtkBalls_Rules", "GtkBalls", TRUE, FALSE, FALSE, 5);
|
||||
|
||||
vbox=gtk_vbox_new(FALSE, 0);
|
||||
gtk_container_add(GTK_CONTAINER(window), vbox);
|
||||
vbox = gtk_vbox_new (FALSE, 0);
|
||||
gtk_container_add (GTK_CONTAINER(window), vbox);
|
||||
|
||||
frame=gtk_frame_new(_("Rules"));
|
||||
gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 3);
|
||||
frame = gtk_frame_new (_("Rules"));
|
||||
gtk_box_pack_start (GTK_BOX(vbox), frame, TRUE, TRUE, 3);
|
||||
|
||||
hbox=gtk_hbox_new(FALSE, 0);
|
||||
gtk_container_set_border_width(GTK_CONTAINER(hbox), 10);
|
||||
gtk_container_add(GTK_CONTAINER(frame), hbox);
|
||||
hbox = gtk_hbox_new (FALSE, 0);
|
||||
gtk_container_set_border_width (GTK_CONTAINER(hbox), 10);
|
||||
gtk_container_add (GTK_CONTAINER(frame), hbox);
|
||||
|
||||
label=gtk_label_new(_("The standard play area of GtkBalls is a 9x9\n" \
|
||||
"grid (it can be changed through \"Rules\"\n" \
|
||||
"option in ingame menu). When GtkBalls is\n" \
|
||||
"first started a number of balls are placed\n" \
|
||||
"in a random manner on the grid. Balls are\n" \
|
||||
"in different colors (and/or shape). You may\n" \
|
||||
"move balls on the grid by selecting them and\n" \
|
||||
"selecting an empty square on the grid as\n" \
|
||||
"destination for the ball you selected. Balls\n" \
|
||||
"will only move if they are not blocked by\n" \
|
||||
"other balls. Each time you move a ball,\n" \
|
||||
"unless you score some points, new balls\n" \
|
||||
"appear in a random manner on the grid. If\n" \
|
||||
"the grid is full then the game is lost.\n" \
|
||||
"However this is bound to happen, your goal\n" \
|
||||
"is to make the highest score. In order to do\n" \
|
||||
"this you must make lines in a vertical,\n" \
|
||||
"horizontal or diagonal way with balls of the\n" \
|
||||
"same color. By default a line must have at\n" \
|
||||
"least five balls of the same color (it can\n" \
|
||||
"also be changed through \"Rules\" option in\n" \
|
||||
"ingame menu). Making a line of minimum amount\n" \
|
||||
"of the balls, specifed in rules, will earn you\n" \
|
||||
"twice the points for your score. If you make\n" \
|
||||
"lines over minimum amount of the balls it will\n" \
|
||||
"earn you even more points. In order to help you\n" \
|
||||
"decide which ball you are going to move, there\n" \
|
||||
"is an indicator on top of the grid that shows\n" \
|
||||
"what colors the next balls that will appear on\n" \
|
||||
"the grid will be."));
|
||||
gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 5);
|
||||
label = gtk_label_new (_("The standard play area of GtkBalls is a 9x9\n" \
|
||||
"grid (it can be changed through \"Rules\"\n" \
|
||||
"option in ingame menu). When GtkBalls is\n" \
|
||||
"first started a number of balls are placed\n" \
|
||||
"in a random manner on the grid. Balls are\n" \
|
||||
"in different colors (and/or shape). You may\n" \
|
||||
"move balls on the grid by selecting them and\n" \
|
||||
"selecting an empty square on the grid as\n" \
|
||||
"destination for the ball you selected. Balls\n" \
|
||||
"will only move if they are not blocked by\n" \
|
||||
"other balls. Each time you move a ball,\n" \
|
||||
"unless you score some points, new balls\n" \
|
||||
"appear in a random manner on the grid. If\n" \
|
||||
"the grid is full then the game is lost.\n" \
|
||||
"However this is bound to happen, your goal\n" \
|
||||
"is to make the highest score. In order to do\n" \
|
||||
"this you must make lines in a vertical,\n" \
|
||||
"horizontal or diagonal way with balls of the\n" \
|
||||
"same color. By default a line must have at\n" \
|
||||
"least five balls of the same color (it can\n" \
|
||||
"also be changed through \"Rules\" option in\n" \
|
||||
"ingame menu). Making a line of minimum amount\n" \
|
||||
"of the balls, specifed in rules, will earn you\n" \
|
||||
"twice the points for your score. If you make\n" \
|
||||
"lines over minimum amount of the balls it will\n" \
|
||||
"earn you even more points. In order to help you\n" \
|
||||
"decide which ball you are going to move, there\n" \
|
||||
"is an indicator on top of the grid that shows\n" \
|
||||
"what colors the next balls that will appear on\n" \
|
||||
"the grid will be."));
|
||||
gtk_box_pack_start (GTK_BOX(hbox), label, TRUE, TRUE, 5);
|
||||
|
||||
separator=gtk_hseparator_new();
|
||||
gtk_box_pack_start(GTK_BOX(vbox), separator, FALSE, FALSE, 5);
|
||||
separator = gtk_hseparator_new ();
|
||||
gtk_box_pack_start (GTK_BOX(vbox), separator, FALSE, FALSE, 5);
|
||||
|
||||
button_box=gtk_hbox_new(FALSE, 0);
|
||||
gtk_box_pack_start(GTK_BOX(vbox), button_box, TRUE, TRUE, 2);
|
||||
button_box = gtk_hbox_new (FALSE, 0);
|
||||
gtk_box_pack_start (GTK_BOX(vbox), button_box, TRUE, TRUE, 2);
|
||||
|
||||
ok_button=ut_button_new_stock_swap(GTK_STOCK_CLOSE, gtk_widget_destroy, window, button_box);
|
||||
ok_button = ut_button_new_stock_swap (GTK_STOCK_CLOSE, gtk_widget_destroy, window, button_box);
|
||||
|
||||
gtk_widget_grab_default(ok_button);
|
||||
gtk_widget_show_all(window);
|
||||
gtk_widget_grab_default (ok_button);
|
||||
gtk_widget_show_all (window);
|
||||
}
|
||||
|
@ -15,81 +15,86 @@
|
||||
#include "game.h" /* rules stuff */
|
||||
|
||||
struct _gtkb_rules_dialog {
|
||||
GtkWidget *xrange, *yrange, *crange, *nrange, *drange;
|
||||
GtkWidget *xrange, *yrange, *crange, *nrange, *drange;
|
||||
};
|
||||
|
||||
struct _gtkb_rules_dialog _rd;
|
||||
|
||||
void rules_ok(GtkWidget *widget, gpointer data) {
|
||||
gint oldnext = rules_get_next();
|
||||
gchar *msg;
|
||||
void rules_ok(GtkWidget *widget, gpointer data)
|
||||
{
|
||||
gint oldnext = rules_get_next();
|
||||
gchar *msg;
|
||||
|
||||
rules_set_width(gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(_rd.xrange)));
|
||||
rules_set_height(gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(_rd.yrange)));
|
||||
rules_set_colors(gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(_rd.crange)));
|
||||
rules_set_next(gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(_rd.nrange)));
|
||||
rules_set_destroy(gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(_rd.drange)));
|
||||
rules_set_width (gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(_rd.xrange)));
|
||||
rules_set_height (gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(_rd.yrange)));
|
||||
rules_set_colors (gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(_rd.crange)));
|
||||
rules_set_next (gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(_rd.nrange)));
|
||||
rules_set_destroy (gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(_rd.drange)));
|
||||
|
||||
reinit_board(NULL, NULL, 0, oldnext);
|
||||
reinit_board (NULL, NULL, 0, oldnext);
|
||||
|
||||
if(data) {
|
||||
gtk_widget_destroy(GTK_WIDGET(data));
|
||||
}
|
||||
msg = save_preferences();
|
||||
if(msg) {
|
||||
ut_simple_message_box(msg);
|
||||
g_free(msg);
|
||||
}
|
||||
if(data) {
|
||||
gtk_widget_destroy (GTK_WIDGET(data));
|
||||
}
|
||||
msg = save_preferences ();
|
||||
if(msg) {
|
||||
ut_simple_message_box (msg);
|
||||
g_free (msg);
|
||||
}
|
||||
}
|
||||
|
||||
void rules_classic(void) {
|
||||
gtk_spin_button_set_value(GTK_SPIN_BUTTON(_rd.xrange), rules_get_classic_width());
|
||||
gtk_spin_button_set_value(GTK_SPIN_BUTTON(_rd.yrange), rules_get_classic_height());
|
||||
gtk_spin_button_set_value(GTK_SPIN_BUTTON(_rd.crange), rules_get_classic_colors());
|
||||
gtk_spin_button_set_value(GTK_SPIN_BUTTON(_rd.nrange), rules_get_classic_next());
|
||||
gtk_spin_button_set_value(GTK_SPIN_BUTTON(_rd.drange), rules_get_classic_destroy());
|
||||
|
||||
void rules_classic(void)
|
||||
{
|
||||
gtk_spin_button_set_value(GTK_SPIN_BUTTON(_rd.xrange), rules_get_classic_width());
|
||||
gtk_spin_button_set_value(GTK_SPIN_BUTTON(_rd.yrange), rules_get_classic_height());
|
||||
gtk_spin_button_set_value(GTK_SPIN_BUTTON(_rd.crange), rules_get_classic_colors());
|
||||
gtk_spin_button_set_value(GTK_SPIN_BUTTON(_rd.nrange), rules_get_classic_next());
|
||||
gtk_spin_button_set_value(GTK_SPIN_BUTTON(_rd.drange), rules_get_classic_destroy());
|
||||
}
|
||||
|
||||
void rules_dialog(void) {
|
||||
GtkWidget *dialog;
|
||||
GtkWidget *frame;
|
||||
GtkWidget *big_vbox, *vbox, *buttons_box;
|
||||
GtkWidget *separator;
|
||||
GtkWidget *ok_button, *cancel_button, *classic_button;
|
||||
|
||||
void rules_dialog (void)
|
||||
{
|
||||
GtkWidget * dialog;
|
||||
GtkWidget * frame;
|
||||
GtkWidget * big_vbox, * vbox, * buttons_box;
|
||||
GtkWidget * separator;
|
||||
GtkWidget * ok_button, * cancel_button, * classic_button;
|
||||
|
||||
|
||||
dialog = ut_window_new(_("Game rules"), "GtkBalls_Rules", "GtkBalls", TRUE, TRUE, TRUE, 5);
|
||||
dialog = ut_window_new(_("Game rules"), "GtkBalls_Rules", "GtkBalls", TRUE, TRUE, TRUE, 5);
|
||||
|
||||
big_vbox = gtk_vbox_new(FALSE, 5);
|
||||
gtk_container_add(GTK_CONTAINER(dialog), big_vbox);
|
||||
big_vbox = gtk_vbox_new (FALSE, 5);
|
||||
gtk_container_add (GTK_CONTAINER(dialog), big_vbox);
|
||||
|
||||
frame = gtk_frame_new(_("Game rules"));
|
||||
gtk_box_pack_start(GTK_BOX(big_vbox), frame, FALSE, FALSE, 0);
|
||||
frame = gtk_frame_new (_("Game rules"));
|
||||
gtk_box_pack_start (GTK_BOX(big_vbox), frame, FALSE, FALSE, 0);
|
||||
|
||||
vbox = gtk_vbox_new(FALSE, 0);
|
||||
gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
|
||||
gtk_container_add(GTK_CONTAINER(frame), vbox);
|
||||
vbox = gtk_vbox_new (FALSE, 0);
|
||||
gtk_container_set_border_width (GTK_CONTAINER(vbox), 5);
|
||||
gtk_container_add (GTK_CONTAINER(frame), vbox);
|
||||
|
||||
_rd.xrange = ut_spin_button_new(_("Board width"), 4, 99, rules_get_width(), vbox);
|
||||
_rd.yrange = ut_spin_button_new(_("Board height"), 4, 99, rules_get_height(), vbox);
|
||||
_rd.crange = ut_spin_button_new(_("Number of different objects"),
|
||||
3, gtkb_theme_get_balls_num(), rules_get_colors(), vbox);
|
||||
_rd.nrange = ut_spin_button_new(_("Number of 'next' objects"), 2, 99, rules_get_next(), vbox);
|
||||
_rd.drange = ut_spin_button_new(_("How many balls at line eliminate it"),
|
||||
3, 99, rules_get_destroy(), vbox);
|
||||
_rd.xrange = ut_spin_button_new (_("Board width"), 4, 99, rules_get_width(), vbox);
|
||||
_rd.yrange = ut_spin_button_new (_("Board height"), 4, 99, rules_get_height(), vbox);
|
||||
_rd.crange = ut_spin_button_new (_("Number of different objects"),
|
||||
3, gtkb_theme_get_balls_num(), rules_get_colors(), vbox);
|
||||
_rd.nrange = ut_spin_button_new (_("Number of 'next' objects"), 2, 99, rules_get_next(), vbox);
|
||||
_rd.drange = ut_spin_button_new (_("How many balls at line eliminate it"),
|
||||
3, 99, rules_get_destroy(), vbox);
|
||||
|
||||
classic_button = ut_button_new(_("Classic rules"), rules_classic, dialog, big_vbox);
|
||||
classic_button = ut_button_new (_("Classic rules"), rules_classic, dialog, big_vbox);
|
||||
|
||||
separator = gtk_hseparator_new();
|
||||
gtk_box_pack_start(GTK_BOX(big_vbox), separator, FALSE, FALSE, 5);
|
||||
separator = gtk_hseparator_new ();
|
||||
gtk_box_pack_start (GTK_BOX(big_vbox), separator, FALSE, FALSE, 5);
|
||||
|
||||
buttons_box = gtk_hbutton_box_new();
|
||||
gtk_button_box_set_layout(GTK_BUTTON_BOX(buttons_box), GTK_BUTTONBOX_SPREAD);
|
||||
gtk_box_pack_start(GTK_BOX(big_vbox), buttons_box, TRUE, TRUE, 0);
|
||||
buttons_box = gtk_hbutton_box_new ();
|
||||
gtk_button_box_set_layout (GTK_BUTTON_BOX(buttons_box), GTK_BUTTONBOX_SPREAD);
|
||||
gtk_box_pack_start (GTK_BOX(big_vbox), buttons_box, TRUE, TRUE, 0);
|
||||
|
||||
ok_button = ut_button_new_stock(GTK_STOCK_OK, rules_ok, dialog, buttons_box);
|
||||
cancel_button = ut_button_new_stock_swap(GTK_STOCK_CANCEL, gtk_widget_destroy, dialog, buttons_box);
|
||||
ok_button = ut_button_new_stock (GTK_STOCK_OK, rules_ok, dialog, buttons_box);
|
||||
cancel_button = ut_button_new_stock_swap (GTK_STOCK_CANCEL, gtk_widget_destroy, dialog, buttons_box);
|
||||
|
||||
gtk_widget_grab_default(ok_button);
|
||||
gtk_widget_show_all(dialog);
|
||||
gtk_widget_grab_default (ok_button);
|
||||
gtk_widget_show_all (dialog);
|
||||
}
|
||||
|
438
src/savedialog.c
438
src/savedialog.c
@ -20,271 +20,279 @@
|
||||
gchar *_selected_save_load = NULL;
|
||||
|
||||
void do_load_game(GtkWidget *widget, gpointer data) {
|
||||
gint score, *board = NULL, *next = NULL, oldnext;
|
||||
gchar *errormsg = NULL;
|
||||
gchar *rules = NULL;
|
||||
gint w, h, c, n, d;
|
||||
gint score, *board = NULL, *next = NULL, oldnext;
|
||||
gchar *errormsg = NULL;
|
||||
gchar *rules = NULL;
|
||||
gint w, h, c, n, d;
|
||||
|
||||
if(!_selected_save_load) {
|
||||
ut_simple_message_box(_("No game selected for load.\n"));
|
||||
return;
|
||||
}
|
||||
if(!parse_save_game(_selected_save_load, &rules, &score, &board, &next)) {
|
||||
errormsg = g_strdup_printf(_("Cannot load game from:\n%s\n"), _selected_save_load);
|
||||
} else {
|
||||
rules_get_from_str(rules, &w, &h, &c, &n, &d);
|
||||
if(c > gtkb_theme_get_balls_num()) {
|
||||
errormsg = g_strdup_printf(_("Not enough balls(%d) in current theme.\nWe need %d balls.\nLoad another theme and try again."),
|
||||
gtkb_theme_get_balls_num(), c);
|
||||
g_free(rules);
|
||||
g_free(board);
|
||||
g_free(next);
|
||||
}
|
||||
}
|
||||
g_free(_selected_save_load);
|
||||
if(errormsg) {
|
||||
ut_simple_message_box(errormsg);
|
||||
g_free(errormsg);
|
||||
return;
|
||||
}
|
||||
oldnext = rules_get_next();
|
||||
rules_set(w, h, c, n, d);
|
||||
g_free(rules);
|
||||
reinit_board(board, next, score, oldnext);
|
||||
g_free(board);
|
||||
g_free(next);
|
||||
if(data) {
|
||||
gtk_widget_destroy(GTK_WIDGET(data));
|
||||
}
|
||||
if (!_selected_save_load) {
|
||||
ut_simple_message_box(_("No game selected for load.\n"));
|
||||
return;
|
||||
}
|
||||
if (!parse_save_game(_selected_save_load, &rules, &score, &board, &next)) {
|
||||
errormsg = g_strdup_printf(_("Cannot load game from:\n%s\n"), _selected_save_load);
|
||||
} else {
|
||||
rules_get_from_str(rules, &w, &h, &c, &n, &d);
|
||||
if (c > gtkb_theme_get_balls_num()) {
|
||||
errormsg = g_strdup_printf(_("Not enough balls(%d) in current theme.\nWe need %d balls.\nLoad another theme and try again."),
|
||||
gtkb_theme_get_balls_num(), c);
|
||||
g_free(rules);
|
||||
g_free(board);
|
||||
g_free(next);
|
||||
}
|
||||
}
|
||||
g_free(_selected_save_load);
|
||||
if (errormsg) {
|
||||
ut_simple_message_box(errormsg);
|
||||
g_free(errormsg);
|
||||
return;
|
||||
}
|
||||
oldnext = rules_get_next();
|
||||
rules_set(w, h, c, n, d);
|
||||
g_free(rules);
|
||||
reinit_board(board, next, score, oldnext);
|
||||
g_free(board);
|
||||
g_free(next);
|
||||
if (data) {
|
||||
gtk_widget_destroy(GTK_WIDGET(data));
|
||||
}
|
||||
}
|
||||
|
||||
void do_delete_game(GtkWidget *widget, GtkWidget *treeview) {
|
||||
GtkTreeModel *model;
|
||||
GtkTreeIter iter, nextiter;
|
||||
GValue value = {0, };
|
||||
GtkTreeModel *model;
|
||||
GtkTreeIter iter, nextiter;
|
||||
GValue value = {0, };
|
||||
|
||||
if(gtk_tree_selection_get_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)),
|
||||
&model, &iter)) {
|
||||
gtk_tree_model_get_value(model, &iter, 1, &value);
|
||||
if(g_value_get_string(&value)) {
|
||||
unlink(g_value_get_string(&value));
|
||||
gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
|
||||
if(iter.stamp == 0) {
|
||||
if(gtk_tree_model_get_iter_first(model, &iter)) {
|
||||
do {
|
||||
nextiter = iter;
|
||||
} while(gtk_tree_model_iter_next(model, &iter));
|
||||
iter = nextiter;
|
||||
}
|
||||
}
|
||||
if(iter.stamp != 0) {
|
||||
gtk_tree_selection_select_iter(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)), &iter);
|
||||
}
|
||||
}
|
||||
g_value_unset(&value);
|
||||
}
|
||||
if (gtk_tree_selection_get_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)),&model, &iter))
|
||||
{
|
||||
gtk_tree_model_get_value(model, &iter, 1, &value);
|
||||
if (g_value_get_string(&value)) {
|
||||
unlink(g_value_get_string(&value));
|
||||
gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
|
||||
if (iter.stamp == 0) {
|
||||
if (gtk_tree_model_get_iter_first(model, &iter)) {
|
||||
do {
|
||||
nextiter = iter;
|
||||
} while (gtk_tree_model_iter_next(model, &iter));
|
||||
iter = nextiter;
|
||||
}
|
||||
}
|
||||
if (iter.stamp != 0) {
|
||||
gtk_tree_selection_select_iter(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)), &iter);
|
||||
}
|
||||
}
|
||||
g_value_unset(&value);
|
||||
}
|
||||
}
|
||||
|
||||
void do_save_game(GtkWidget *widget, gpointer data) {
|
||||
gchar *fname = NULL, *errormsg, *rules;
|
||||
gint *b, *n;
|
||||
gchar *fname = NULL, *errormsg, *rules;
|
||||
gint *b, *n;
|
||||
|
||||
if(_selected_save_load) {
|
||||
/* TODO: alert stupid user about erasing file... */
|
||||
unlink(_selected_save_load);
|
||||
g_free(_selected_save_load);
|
||||
}
|
||||
if (_selected_save_load) {
|
||||
/* TODO: alert stupid user about erasing file... */
|
||||
unlink(_selected_save_load);
|
||||
g_free(_selected_save_load);
|
||||
}
|
||||
|
||||
rules = rules_get_as_str();
|
||||
b = game_get_board_as_int_arr();
|
||||
n = game_get_next_as_int_arr();
|
||||
fname = save_game(rules, game_get_score(), b, n);
|
||||
g_free(n);
|
||||
g_free(b);
|
||||
g_free(rules);
|
||||
rules = rules_get_as_str();
|
||||
b = game_get_board_as_int_arr();
|
||||
n = game_get_next_as_int_arr();
|
||||
fname = save_game(rules, game_get_score(), b, n);
|
||||
g_free(n);
|
||||
g_free(b);
|
||||
g_free(rules);
|
||||
|
||||
if(fname != NULL) {
|
||||
errormsg = g_strdup_printf(_("Cannot save game to:\n%s\n%s"), fname, strerror(errno));
|
||||
ut_simple_message_box(errormsg);
|
||||
g_free(fname);
|
||||
g_free(errormsg);
|
||||
}
|
||||
if(data) {
|
||||
gtk_widget_destroy(GTK_WIDGET(data));
|
||||
}
|
||||
if (fname != NULL) {
|
||||
errormsg = g_strdup_printf(_("Cannot save game to:\n%s\n%s"), fname, strerror(errno));
|
||||
ut_simple_message_box(errormsg);
|
||||
g_free(fname);
|
||||
g_free(errormsg);
|
||||
}
|
||||
if (data) {
|
||||
gtk_widget_destroy(GTK_WIDGET(data));
|
||||
}
|
||||
}
|
||||
|
||||
void save_row_activated_cb(GtkTreeView *treeview, gpointer arg1, GtkTreeViewColumn *arg2, gpointer data) {
|
||||
do_save_game(GTK_WIDGET(treeview), data);
|
||||
do_save_game(GTK_WIDGET(treeview), data);
|
||||
}
|
||||
|
||||
void load_row_activated_cb(GtkTreeView *treeview, gpointer arg1, GtkTreeViewColumn *arg2, gpointer data) {
|
||||
do_load_game(GTK_WIDGET(treeview), data);
|
||||
do_load_game(GTK_WIDGET(treeview), data);
|
||||
}
|
||||
|
||||
void sl_row_activated(GtkTreeSelection *selection, GtkTreeModel *model) {
|
||||
GtkTreeIter iter;
|
||||
GValue value = {0, };
|
||||
GtkTreeIter iter;
|
||||
GValue value = {0, };
|
||||
|
||||
if(gtk_tree_selection_get_selected(selection, NULL, &iter)) {
|
||||
if(_selected_save_load) {
|
||||
g_free(_selected_save_load);
|
||||
}
|
||||
gtk_tree_model_get_value(model, &iter, 1, &value);
|
||||
if(g_value_get_string(&value)) {
|
||||
_selected_save_load = g_strdup((gchar *)g_value_get_string(&value));
|
||||
} else {
|
||||
_selected_save_load = NULL;
|
||||
}
|
||||
g_value_unset(&value);
|
||||
}
|
||||
if (gtk_tree_selection_get_selected(selection, NULL, &iter)) {
|
||||
if (_selected_save_load) {
|
||||
g_free(_selected_save_load);
|
||||
}
|
||||
gtk_tree_model_get_value(model, &iter, 1, &value);
|
||||
if (g_value_get_string(&value)) {
|
||||
_selected_save_load = g_strdup((gchar *)g_value_get_string(&value));
|
||||
} else {
|
||||
_selected_save_load = NULL;
|
||||
}
|
||||
g_value_unset(&value);
|
||||
}
|
||||
}
|
||||
|
||||
void free_gamelist(gchar **gamelist, gint num) {
|
||||
gint i;
|
||||
gint i;
|
||||
|
||||
for(i = 0; i < num * 2; i++) {
|
||||
g_free(gamelist[i]);
|
||||
}
|
||||
g_free(gamelist);
|
||||
for (i = 0; i < num * 2; i++) {
|
||||
g_free(gamelist[i]);
|
||||
}
|
||||
g_free(gamelist);
|
||||
}
|
||||
|
||||
gint game_compare_func(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data) {
|
||||
GValue value_a = {0, };
|
||||
GValue value_b = {0, };
|
||||
gchar *str_a, *str_b;
|
||||
gint r = 0, i;
|
||||
gint sort_pos[] = { 6, 7, 8, 9, 3, 4, 0, 1, 11, 12, 14, 15, 17, 18};
|
||||
|
||||
gtk_tree_model_get_value(model, a, 0, &value_a);
|
||||
gtk_tree_model_get_value(model, b, 0, &value_b);
|
||||
if((str_a = (gchar *)g_value_get_string(&value_a)) && (str_b = (gchar *)g_value_get_string(&value_b))) {
|
||||
for(i = 0; i < sizeof(sort_pos) / sizeof(gint); i++) {
|
||||
if(str_a[sort_pos[i]] != str_b[sort_pos[i]]) {
|
||||
r = str_a[sort_pos[i]] < str_b[sort_pos[i]] ? 1 : -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
g_value_unset(&value_a);
|
||||
g_value_unset(&value_b);
|
||||
gint game_compare_func(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data)
|
||||
{
|
||||
GValue value_a = {0, };
|
||||
GValue value_b = {0, };
|
||||
gchar *str_a, *str_b;
|
||||
gint r = 0, i;
|
||||
gint sort_pos[] = { 6, 7, 8, 9, 3, 4, 0, 1, 11, 12, 14, 15, 17, 18};
|
||||
|
||||
return r;
|
||||
gtk_tree_model_get_value(model, a, 0, &value_a);
|
||||
gtk_tree_model_get_value(model, b, 0, &value_b);
|
||||
if ((str_a = (gchar *)g_value_get_string(&value_a)) && (str_b = (gchar *)g_value_get_string(&value_b))) {
|
||||
for (i = 0; i < sizeof(sort_pos) / sizeof(gint); i++) {
|
||||
if (str_a[sort_pos[i]] != str_b[sort_pos[i]]) {
|
||||
r = str_a[sort_pos[i]] < str_b[sort_pos[i]] ? 1 : -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
g_value_unset(&value_a);
|
||||
g_value_unset(&value_b);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void save_load_game_dialog(gboolean is_save) {
|
||||
GtkListStore *store;
|
||||
GtkTreeIter iter;
|
||||
GtkWidget *treeview;
|
||||
GtkCellRenderer *renderer;
|
||||
GtkTreeViewColumn *column;
|
||||
GtkTreePath *path;
|
||||
GtkWidget *window, *swindow;
|
||||
GtkWidget *vbox, *button_box;
|
||||
GtkWidget *ok_button, *cancel_button, *delete_button;
|
||||
gint i, num;
|
||||
gchar **gamelist, str1[20], *str2;
|
||||
|
||||
_selected_save_load = NULL;
|
||||
|
||||
num = get_saved_games(&gamelist);
|
||||
if(!is_save && !num) {
|
||||
ut_simple_message_box(_("No saved games found.\n"));
|
||||
return;
|
||||
}
|
||||
void save_load_game_dialog(gboolean is_save)
|
||||
{
|
||||
GtkListStore * store;
|
||||
GtkTreeIter iter;
|
||||
GtkWidget * treeview;
|
||||
GtkCellRenderer * renderer;
|
||||
GtkTreeViewColumn * column;
|
||||
GtkTreePath * path;
|
||||
GtkWidget * window, * swindow;
|
||||
GtkWidget * vbox, * button_box;
|
||||
GtkWidget * ok_button, * cancel_button, *delete_button;
|
||||
gint i, num;
|
||||
gchar ** gamelist, str1[20], * str2;
|
||||
|
||||
window = ut_window_new(is_save ? _("Save game") : _("Load game"),
|
||||
is_save ? "GtkBalls_Save" : "GtkBalls_Load",
|
||||
"GtkBalls", TRUE, TRUE, TRUE, 5);
|
||||
_selected_save_load = NULL;
|
||||
|
||||
vbox = gtk_vbox_new(FALSE, 0);
|
||||
gtk_container_set_border_width(GTK_CONTAINER(vbox), 1);
|
||||
gtk_container_add(GTK_CONTAINER(window), vbox);
|
||||
num = get_saved_games (&gamelist);
|
||||
if (!is_save && !num) {
|
||||
ut_simple_message_box(_("No saved games found.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
swindow = gtk_scrolled_window_new(NULL, NULL);
|
||||
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swindow), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
|
||||
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(swindow), GTK_SHADOW_ETCHED_IN);
|
||||
gtk_box_pack_start(GTK_BOX(vbox), swindow, TRUE, TRUE, 0);
|
||||
window = ut_window_new(is_save ? _("Save game") : _("Load game"),
|
||||
is_save ? "GtkBalls_Save" : "GtkBalls_Load",
|
||||
"GtkBalls", TRUE, TRUE, TRUE, 5);
|
||||
|
||||
store = gtk_list_store_new(3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
|
||||
for(i = 0; i < num; i++) {
|
||||
gtk_list_store_append(store, &iter);
|
||||
memcpy(str1, gamelist[i * 2], 19 * sizeof(gchar));
|
||||
str1[19] = '\0';
|
||||
str2 = g_strndup(gamelist[i * 2] + 21 * sizeof(gchar),
|
||||
(strlen(gamelist[i * 2]) - 22) * sizeof(gchar));
|
||||
gtk_list_store_set(store, &iter, 0, str1, 1, (GValue *)gamelist[i * 2 + 1], 2, str2, -1);
|
||||
g_free(str2);
|
||||
}
|
||||
if(is_save) {
|
||||
gtk_list_store_append(store, &iter);
|
||||
gtk_list_store_set(store, &iter, 0, _("Empty"), -1);
|
||||
}
|
||||
free_gamelist(gamelist, num);
|
||||
vbox = gtk_vbox_new (FALSE, 0);
|
||||
gtk_container_set_border_width (GTK_CONTAINER(vbox), 1);
|
||||
gtk_container_add (GTK_CONTAINER(window), vbox);
|
||||
|
||||
treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
|
||||
gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(treeview), TRUE);
|
||||
gtk_tree_view_set_search_column(GTK_TREE_VIEW(treeview), 0);
|
||||
gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)), GTK_SELECTION_BROWSE);
|
||||
g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview))),
|
||||
"changed", G_CALLBACK(sl_row_activated), store);
|
||||
gtk_container_add(GTK_CONTAINER(swindow), treeview);
|
||||
swindow = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(swindow), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
|
||||
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(swindow), GTK_SHADOW_ETCHED_IN);
|
||||
gtk_box_pack_start (GTK_BOX(vbox), swindow, TRUE, TRUE, 0);
|
||||
|
||||
renderer = gtk_cell_renderer_text_new();
|
||||
g_object_set(G_OBJECT(renderer), "xpad", 5, NULL);
|
||||
column = gtk_tree_view_column_new_with_attributes(_("Date"), renderer, "text", 0, NULL);
|
||||
gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
|
||||
store = gtk_list_store_new (3,
|
||||
G_TYPE_STRING,
|
||||
G_TYPE_STRING,
|
||||
G_TYPE_STRING);
|
||||
for (i = 0; i < num; i++) {
|
||||
gtk_list_store_append (store, &iter);
|
||||
memcpy (str1, gamelist[i * 2], 19 * sizeof(gchar));
|
||||
str1[19] = '\0';
|
||||
str2 = g_strndup (gamelist[i * 2] + 21 * sizeof(gchar),
|
||||
(strlen(gamelist[i * 2]) - 22) * sizeof(gchar));
|
||||
gtk_list_store_set (store, &iter, 0, str1, 1, (GValue *)gamelist[i * 2 + 1], 2, str2, -1);
|
||||
g_free (str2);
|
||||
}
|
||||
if (is_save) {
|
||||
gtk_list_store_append (store, &iter);
|
||||
gtk_list_store_set (store, &iter, 0, _("Empty"), -1);
|
||||
}
|
||||
free_gamelist(gamelist, num);
|
||||
|
||||
gtk_tree_view_column_set_sort_column_id(column, 0);
|
||||
gtk_tree_view_column_set_sort_order(column, GTK_SORT_DESCENDING);
|
||||
gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store), 0, game_compare_func, NULL, NULL);
|
||||
gtk_tree_view_column_clicked(column);
|
||||
treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL(store));
|
||||
gtk_tree_view_set_rules_hint (GTK_TREE_VIEW(treeview), TRUE);
|
||||
gtk_tree_view_set_search_column (GTK_TREE_VIEW(treeview), 0);
|
||||
gtk_tree_selection_set_mode (gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)), GTK_SELECTION_BROWSE);
|
||||
g_signal_connect (G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview))),
|
||||
"changed", G_CALLBACK(sl_row_activated), store);
|
||||
gtk_container_add (GTK_CONTAINER(swindow), treeview);
|
||||
|
||||
renderer = gtk_cell_renderer_text_new();
|
||||
g_object_set(G_OBJECT(renderer), "xalign", 1.0, NULL);
|
||||
g_object_set(G_OBJECT(renderer), "xpad", 5, NULL);
|
||||
column = gtk_tree_view_column_new_with_attributes(_("Score"), renderer, "text", 2, NULL);
|
||||
gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
|
||||
renderer = gtk_cell_renderer_text_new ();
|
||||
g_object_set (G_OBJECT(renderer), "xpad", 5, NULL);
|
||||
column = gtk_tree_view_column_new_with_attributes (_("Date"), renderer, "text", 0, NULL);
|
||||
gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
|
||||
|
||||
if(iter.stamp == store->stamp) {
|
||||
if(is_save) {
|
||||
path = gtk_tree_model_get_path(GTK_TREE_MODEL(store), &iter);
|
||||
} else {
|
||||
path = gtk_tree_path_new_from_string("0");
|
||||
}
|
||||
if(path) {
|
||||
gtk_tree_selection_select_path(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)), path);
|
||||
gtk_tree_view_set_cursor(GTK_TREE_VIEW(treeview), path, NULL, FALSE);
|
||||
gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(treeview), path, NULL, TRUE, 0, 0);
|
||||
gtk_tree_path_free(path);
|
||||
}
|
||||
}
|
||||
g_object_unref(G_OBJECT(store));
|
||||
gtk_tree_view_column_set_sort_column_id (column, 0);
|
||||
gtk_tree_view_column_set_sort_order (column, GTK_SORT_DESCENDING);
|
||||
gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE(store), 0, game_compare_func, NULL, NULL);
|
||||
gtk_tree_view_column_clicked (column);
|
||||
|
||||
button_box = gtk_hbox_new(TRUE, 10);
|
||||
if(is_save) {
|
||||
ok_button = ut_button_new(_("Save game"), do_save_game, window, button_box);
|
||||
g_signal_connect(G_OBJECT(treeview), "row_activated", G_CALLBACK(save_row_activated_cb), window);
|
||||
} else {
|
||||
ok_button = ut_button_new(_("Load game"), do_load_game, window, button_box);
|
||||
g_signal_connect(G_OBJECT(treeview), "row_activated", G_CALLBACK(load_row_activated_cb), window);
|
||||
}
|
||||
delete_button = ut_button_new(_("Delete game"), do_delete_game, treeview, button_box);
|
||||
renderer = gtk_cell_renderer_text_new ();
|
||||
g_object_set (G_OBJECT(renderer), "xalign", 1.0, NULL);
|
||||
g_object_set (G_OBJECT(renderer), "xpad", 5, NULL);
|
||||
column = gtk_tree_view_column_new_with_attributes (_("Score"), renderer, "text", 2, NULL);
|
||||
gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
|
||||
|
||||
cancel_button = ut_button_new_stock_swap(GTK_STOCK_CANCEL, gtk_widget_destroy, window, button_box);
|
||||
gtk_box_pack_start(GTK_BOX(vbox), button_box, FALSE, FALSE, 4);
|
||||
if (iter.stamp == store->stamp) {
|
||||
if (is_save) {
|
||||
path = gtk_tree_model_get_path (GTK_TREE_MODEL(store), &iter);
|
||||
} else {
|
||||
path = gtk_tree_path_new_from_string ("0");
|
||||
}
|
||||
if (path) {
|
||||
gtk_tree_selection_select_path (gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)), path);
|
||||
gtk_tree_view_set_cursor (GTK_TREE_VIEW(treeview), path, NULL, FALSE);
|
||||
gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW(treeview), path, NULL, TRUE, 0, 0);
|
||||
gtk_tree_path_free (path);
|
||||
}
|
||||
}
|
||||
g_object_unref (G_OBJECT(store));
|
||||
|
||||
gtk_widget_grab_default(ok_button);
|
||||
gtk_widget_grab_focus(ok_button);
|
||||
button_box = gtk_hbox_new (TRUE, 10);
|
||||
if (is_save) {
|
||||
ok_button = ut_button_new (_("Save game"), do_save_game, window, button_box);
|
||||
g_signal_connect (G_OBJECT(treeview), "row_activated", G_CALLBACK(save_row_activated_cb), window);
|
||||
} else {
|
||||
ok_button = ut_button_new (_("Load game"), do_load_game, window, button_box);
|
||||
g_signal_connect(G_OBJECT(treeview), "row_activated", G_CALLBACK(load_row_activated_cb), window);
|
||||
}
|
||||
delete_button = ut_button_new (_("Delete game"), do_delete_game, treeview, button_box);
|
||||
|
||||
gtk_window_set_default_size(GTK_WINDOW(window), -1, 300);
|
||||
gtk_widget_show_all(window);
|
||||
cancel_button = ut_button_new_stock_swap (GTK_STOCK_CANCEL, gtk_widget_destroy, window, button_box);
|
||||
gtk_box_pack_start (GTK_BOX(vbox), button_box, FALSE, FALSE, 4);
|
||||
|
||||
gtk_widget_grab_default (ok_button);
|
||||
gtk_widget_grab_focus (ok_button);
|
||||
|
||||
gtk_window_set_default_size (GTK_WINDOW(window), -1, 300);
|
||||
gtk_widget_show_all (window);
|
||||
}
|
||||
|
||||
void save_game_cb(GtkWidget *widget, gpointer data) {
|
||||
save_load_game_dialog(TRUE);
|
||||
save_load_game_dialog (TRUE);
|
||||
}
|
||||
|
||||
void load_game_cb(GtkWidget *widget, gpointer data) {
|
||||
save_load_game_dialog(FALSE);
|
||||
save_load_game_dialog (FALSE);
|
||||
}
|
||||
|
271
src/savegame.c
271
src/savegame.c
@ -17,169 +17,176 @@
|
||||
|
||||
#include "game.h"
|
||||
|
||||
gint parse_save_game(gchar *sgame, gchar **rules, gint *score, gint **board, gint **next) {
|
||||
struct stat buf;
|
||||
gchar *sdata, *psdata, *srules;
|
||||
FILE *f;
|
||||
gint i, val;
|
||||
gint rw, rh, rc, rn, rd, rlen;
|
||||
gint parse_save_game(gchar *sgame, gchar **rules, gint *score, gint **board, gint **next)
|
||||
{
|
||||
struct stat buf;
|
||||
gchar *sdata, *psdata, *srules;
|
||||
FILE *f;
|
||||
gint i, val;
|
||||
gint rw, rh, rc, rn, rd, rlen;
|
||||
|
||||
if(stat(sgame, &buf) != 0 || !S_ISREG(buf.st_mode) || buf.st_size < 20 ||
|
||||
(f = fopen(sgame, "r")) == NULL) {
|
||||
return 0;
|
||||
}
|
||||
if (stat(sgame, &buf) != 0 || !S_ISREG(buf.st_mode) || buf.st_size < 20 || (f = fopen(sgame, "r")) == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
sdata = g_malloc(buf.st_size);
|
||||
sdata = g_malloc(buf.st_size);
|
||||
|
||||
if(fread(sdata, 1, buf.st_size, f) != buf.st_size) {
|
||||
g_free(sdata);
|
||||
return 0;
|
||||
}
|
||||
if (fread(sdata, 1, buf.st_size, f) != buf.st_size) {
|
||||
g_free (sdata);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
fclose(f);
|
||||
|
||||
rlen = rules_get_str_len();
|
||||
srules = g_malloc(rlen + 1);
|
||||
srules[rlen] = 0;
|
||||
memcpy(srules, sdata, rlen);
|
||||
rlen = rules_get_str_len();
|
||||
srules = g_malloc(rlen + 1);
|
||||
srules[rlen] = 0;
|
||||
memcpy(srules, sdata, rlen);
|
||||
|
||||
if(!rules_get_from_str(srules, &rw, &rh, &rc, &rn, &rd) ||
|
||||
sscanf(sdata + rlen, "%010u", score) != 1 ||
|
||||
buf.st_size != rlen + 10 + rw * rh * 2 + rn * 2) {
|
||||
printf("[%s]\n", srules);
|
||||
g_free(srules);
|
||||
g_free(sdata);
|
||||
return 0;
|
||||
}
|
||||
if (!rules_get_from_str(srules, &rw, &rh, &rc, &rn, &rd) ||
|
||||
sscanf(sdata + rlen, "%010u", score) != 1 ||
|
||||
buf.st_size != rlen + 10 + rw * rh * 2 + rn * 2) {
|
||||
printf("[%s]\n", srules);
|
||||
g_free (srules);
|
||||
g_free (sdata);
|
||||
return 0;
|
||||
}
|
||||
|
||||
g_free(srules);
|
||||
g_free (srules);
|
||||
|
||||
*board = g_malloc(rw * rh * sizeof(gint));
|
||||
*next = g_malloc(rn * sizeof(gint));
|
||||
*board = g_malloc(rw * rh * sizeof(gint));
|
||||
*next = g_malloc(rn * sizeof(gint));
|
||||
|
||||
psdata = sdata + rlen + 10;
|
||||
for(i = 0; i < rw * rh; i++, psdata += 2) {
|
||||
if(sscanf(psdata, "%02d", &val) != 1 || val < 0 || val > rc) {
|
||||
g_free(*next);
|
||||
g_free(*board);
|
||||
g_free(sdata);
|
||||
return 0;
|
||||
}
|
||||
(*board)[i] = val;
|
||||
}
|
||||
psdata = sdata + rlen + 10;
|
||||
for (i = 0; i < rw * rh; i++, psdata += 2) {
|
||||
if (sscanf(psdata, "%02d", &val) != 1 || val < 0 || val > rc) {
|
||||
g_free (*next);
|
||||
g_free (*board);
|
||||
g_free (sdata);
|
||||
return 0;
|
||||
}
|
||||
(*board)[i] = val;
|
||||
}
|
||||
|
||||
for(i = 0; i < rn; i++, psdata += 2) {
|
||||
if(sscanf(psdata, "%02d", &val) != 1 || val < 0 || val > rc) {
|
||||
g_free(*next);
|
||||
g_free(*board);
|
||||
g_free(sdata);
|
||||
return 0;
|
||||
}
|
||||
(*next)[i] = val;
|
||||
}
|
||||
for (i = 0; i < rn; i++, psdata += 2) {
|
||||
if (sscanf(psdata, "%02d", &val) != 1 || val < 0 || val > rc) {
|
||||
g_free (*next);
|
||||
g_free (*board);
|
||||
g_free (sdata);
|
||||
return 0;
|
||||
}
|
||||
(*next)[i] = val;
|
||||
}
|
||||
|
||||
*rules = g_strndup(sdata, rlen);
|
||||
g_free(sdata);
|
||||
*rules = g_strndup(sdata, rlen);
|
||||
g_free (sdata);
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* check that save game name is in form YYYY-MM-DD-HHMMSS.sav and have correct content
|
||||
return string "DD.MM.YYYY HH:MM:SS (score)" on success, NULL on failure */
|
||||
gchar *is_valid_save_game(gchar *name, gchar *path) {
|
||||
guint i, y, m, d, h, min, s;
|
||||
gint score, *board, *next;
|
||||
gchar *sgame;
|
||||
gchar *rules;
|
||||
gchar *is_valid_save_game(gchar *name, gchar *path)
|
||||
{
|
||||
guint i, y, m, d, h, min, s;
|
||||
gint score, *board, *next;
|
||||
gchar *sgame;
|
||||
gchar *rules;
|
||||
|
||||
if((i = sscanf(name, "%04u-%02u-%02u-%02u%02u%02u", &y, &m, &d, &h, &min, &s)) != 6 ||
|
||||
!m || m > 12 || !d || d > 31 || h > 23 || min > 59 || s > 61 ||
|
||||
(strcmp(name + strlen(name) - 4, ".sav") != 0)) {
|
||||
return NULL;
|
||||
}
|
||||
if ((i = sscanf(name, "%04u-%02u-%02u-%02u%02u%02u", &y, &m, &d, &h, &min, &s)) != 6 ||
|
||||
!m || m > 12 || !d || d > 31 || h > 23 || min > 59 || s > 61 ||
|
||||
(strcmp(name + strlen(name) - 4, ".sav") != 0)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sgame=g_strconcat(path, G_DIR_SEPARATOR_S, name, NULL);
|
||||
sgame=g_strconcat(path, G_DIR_SEPARATOR_S, name, NULL);
|
||||
|
||||
i = parse_save_game(sgame, &rules, &score, &board, &next);
|
||||
g_free(sgame);
|
||||
i = parse_save_game(sgame, &rules, &score, &board, &next);
|
||||
g_free (sgame);
|
||||
|
||||
if(!i) return NULL;
|
||||
if (!i) return NULL;
|
||||
|
||||
g_free(rules);
|
||||
g_free(board);
|
||||
g_free(next);
|
||||
g_free (rules);
|
||||
g_free (board);
|
||||
g_free (next);
|
||||
|
||||
return g_strdup_printf("%02d.%02d.%04d %02d:%02d:%02d (%d)",
|
||||
d, m, y, h, min, s, score);
|
||||
return g_strdup_printf("%02d.%02d.%04d %02d:%02d:%02d (%d)",
|
||||
d, m, y, h, min, s, score);
|
||||
/* FIXME: return rules back
|
||||
return g_strdup_printf("%02d.%02d.%04d %02d:%02d:%02d (%d [%dx%d %d %d %d])",
|
||||
d, m, y, h, min, s, score,
|
||||
rules.xsize, rules.ysize, rules.colors, rules.next, rules.destroy);
|
||||
d, m, y, h, min, s, score,
|
||||
rules.xsize, rules.ysize, rules.colors, rules.next, rules.destroy);
|
||||
*/
|
||||
}
|
||||
|
||||
gint get_saved_games(gchar ***gamelist) {
|
||||
gchar *datapath;
|
||||
struct stat buf;
|
||||
struct dirent *dir_entry;
|
||||
DIR *directory;
|
||||
gchar **games = NULL, *game;
|
||||
gint num = 0;
|
||||
|
||||
datapath = g_strconcat(getenv("HOME"), G_DIR_SEPARATOR_S, ".gtkballs", NULL);
|
||||
if(stat(datapath, &buf) != 0) { /* no ~/.gtkballs */
|
||||
if(mkdir(datapath, 0700) != 0) { /* and cannot create it... */
|
||||
g_free(datapath);
|
||||
return -1;
|
||||
}
|
||||
} else if(!S_ISDIR(buf.st_mode)) { /* ~/.gtkballs is not a directory */
|
||||
g_free(datapath);
|
||||
return -1;
|
||||
}
|
||||
if((directory = opendir(datapath))) {
|
||||
while((dir_entry = readdir(directory))) {
|
||||
if((game = is_valid_save_game(dir_entry->d_name, datapath)) != NULL) {
|
||||
num++;
|
||||
games = g_realloc(games, sizeof(gchar *) * num * 2);
|
||||
games[(num - 1) * 2] = game;
|
||||
games[(num - 1) * 2 + 1] = g_strdup_printf("%s%s%s", datapath, G_DIR_SEPARATOR_S, dir_entry->d_name);
|
||||
}
|
||||
}
|
||||
closedir(directory);
|
||||
}
|
||||
g_free(datapath);
|
||||
*gamelist = games;
|
||||
return num;
|
||||
gint get_saved_games(gchar ***gamelist)
|
||||
{
|
||||
gchar *datapath;
|
||||
struct stat buf;
|
||||
struct dirent *dir_entry;
|
||||
DIR *directory;
|
||||
gchar **games = NULL, *game;
|
||||
gint num = 0;
|
||||
|
||||
datapath = g_strconcat(getenv("HOME"), G_DIR_SEPARATOR_S, ".gtkballs", NULL);
|
||||
if (stat(datapath, &buf) != 0) { /* no ~/.gtkballs */
|
||||
if (mkdir(datapath, 0700) != 0) { /* and cannot create it... */
|
||||
g_free (datapath);
|
||||
return -1;
|
||||
}
|
||||
} else if (!S_ISDIR(buf.st_mode)) { /* ~/.gtkballs is not a directory */
|
||||
g_free (datapath);
|
||||
return -1;
|
||||
}
|
||||
if ((directory = opendir(datapath)))
|
||||
{
|
||||
while ((dir_entry = readdir(directory))) {
|
||||
if ((game = is_valid_save_game(dir_entry->d_name, datapath)) != NULL) {
|
||||
num++;
|
||||
games = g_realloc(games, sizeof(gchar *) * num * 2);
|
||||
games[(num - 1) * 2] = game;
|
||||
games[(num - 1) * 2 + 1] = g_strdup_printf("%s%s%s", datapath, G_DIR_SEPARATOR_S, dir_entry->d_name);
|
||||
}
|
||||
}
|
||||
closedir(directory);
|
||||
}
|
||||
g_free (datapath);
|
||||
*gamelist = games;
|
||||
return num;
|
||||
}
|
||||
|
||||
gchar *save_game(gchar *rules, gint score, gint *board, gint *nextcolors) {
|
||||
FILE *f;
|
||||
gchar *fname;
|
||||
time_t nowtime;
|
||||
gchar ftime[]="0000-00-00-000000";
|
||||
gint i;
|
||||
|
||||
nowtime = time(NULL);
|
||||
strftime(ftime, sizeof(ftime), "%Y-%m-%d-%H%M%S", localtime(&nowtime));
|
||||
fname = g_strconcat(getenv("HOME"), G_DIR_SEPARATOR_S, ".gtkballs",
|
||||
G_DIR_SEPARATOR_S, ftime, ".sav", NULL);
|
||||
if((f = fopen(fname, "w")) != NULL) {
|
||||
chmod(fname, 0600);
|
||||
/* TODO: check for errors ! */
|
||||
fprintf(f, rules);
|
||||
fprintf(f, "%010d", score);
|
||||
for(i = 0; i < rules_get_width() * rules_get_height(); i++) {
|
||||
fprintf(f, "%02d", board[i]);
|
||||
}
|
||||
for(i = 0; i < rules_get_next(); i++) {
|
||||
fprintf(f, "%02d", nextcolors[i]);
|
||||
}
|
||||
fclose(f);
|
||||
} else {
|
||||
return fname;
|
||||
}
|
||||
gchar *save_game(gchar *rules, gint score, gint *board, gint *nextcolors)
|
||||
{
|
||||
FILE *f;
|
||||
gchar *fname;
|
||||
time_t nowtime;
|
||||
gchar ftime[]="0000-00-00-000000";
|
||||
gint i;
|
||||
|
||||
g_free(fname);
|
||||
nowtime = time(NULL);
|
||||
strftime(ftime, sizeof(ftime), "%Y-%m-%d-%H%M%S", localtime(&nowtime));
|
||||
fname = g_strconcat(getenv("HOME"), G_DIR_SEPARATOR_S, ".gtkballs",
|
||||
G_DIR_SEPARATOR_S, ftime, ".sav", NULL);
|
||||
if ((f = fopen(fname, "w")) != NULL) {
|
||||
chmod(fname, 0600);
|
||||
/* TODO: check for errors ! */
|
||||
fprintf(f, rules);
|
||||
fprintf(f, "%010d", score);
|
||||
for (i = 0; i < rules_get_width() * rules_get_height(); i++) {
|
||||
fprintf(f, "%02d", board[i]);
|
||||
}
|
||||
for (i = 0; i < rules_get_next(); i++) {
|
||||
fprintf(f, "%02d", nextcolors[i]);
|
||||
}
|
||||
fclose(f);
|
||||
} else {
|
||||
return fname;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
g_free (fname);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
360
src/scoreboard.c
360
src/scoreboard.c
@ -1,7 +1,7 @@
|
||||
/* scoreboard.c - save/load scores
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* modif (y it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*/
|
||||
@ -23,204 +23,218 @@
|
||||
|
||||
int _score_fd = -1;
|
||||
|
||||
gint score_setup(void) {
|
||||
_score_fd = child_setup(SCORE_FILE);
|
||||
return _score_fd;
|
||||
gint score_setup(void)
|
||||
{
|
||||
_score_fd = child_setup(SCORE_FILE);
|
||||
return _score_fd;
|
||||
}
|
||||
|
||||
void free_score_board_full(struct score_board_full *bf, gint nbf) {
|
||||
gint i;
|
||||
|
||||
for(i = 0; i < nbf; i++) {
|
||||
g_free(bf[i].rules);
|
||||
}
|
||||
g_free(bf);
|
||||
void free_score_board_full(struct score_board_full *bf, gint nbf)
|
||||
{
|
||||
gint i;
|
||||
|
||||
for (i = 0; i < nbf; i++) {
|
||||
g_free(bf[i].rules);
|
||||
}
|
||||
g_free(bf);
|
||||
}
|
||||
|
||||
gint write_score(struct score_board *b, struct score_board_full *bf, gint nbf) {
|
||||
gint i;
|
||||
gchar *buf, *tname, *tdate, *rules;
|
||||
size_t sz;
|
||||
|
||||
if(child_writer_alive() == 0) {
|
||||
return FALSE;
|
||||
}
|
||||
gint write_score(struct score_board *b, struct score_board_full *bf, gint nbf)
|
||||
{
|
||||
gint i;
|
||||
gchar *buf, *tname, *tdate, *rules;
|
||||
size_t sz;
|
||||
|
||||
for(i = 0; i < 10; i++) {
|
||||
if(strlen(b[i].name)) {
|
||||
tname = g_strdup(b[i].name);
|
||||
if(!tname) {
|
||||
tname = g_strdup(_("Unknown"));
|
||||
}
|
||||
tdate = g_strdup(b[i].date);
|
||||
if(!tdate) {
|
||||
tdate = g_strdup(_("Unknown"));
|
||||
}
|
||||
rules = rules_get_as_str();
|
||||
buf = g_strdup_printf("%s\t%i\t%s\t%s\n", tname, b[i].score, tdate, rules);
|
||||
sz = strlen(buf);
|
||||
write(_score_fd, &sz, sizeof(sz));
|
||||
write(_score_fd, buf, strlen(buf));
|
||||
g_free(rules);
|
||||
g_free(tdate);
|
||||
g_free(tname);
|
||||
g_free(buf);
|
||||
}
|
||||
}
|
||||
for(i = 0; i < nbf; i++) {
|
||||
if(strlen(bf[i].name)) {
|
||||
buf = g_strdup_printf("%s\t%i\t%s\t%s\n", bf[i].name, bf[i].score, bf[i].date, bf[i].rules);
|
||||
sz = strlen(buf);
|
||||
write(_score_fd, &sz, sizeof(sz));
|
||||
write(_score_fd, buf, strlen(buf));
|
||||
g_free(buf);
|
||||
}
|
||||
}
|
||||
sz = 0;
|
||||
write(_score_fd, &sz, sizeof(sz));
|
||||
if (child_writer_alive() == 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
if (strlen(b[i].name)) {
|
||||
tname = g_strdup(b[i].name);
|
||||
if (!tname) {
|
||||
tname = g_strdup(_("Unknown"));
|
||||
}
|
||||
tdate = g_strdup(b[i].date);
|
||||
if (!tdate) {
|
||||
tdate = g_strdup(_("Unknown"));
|
||||
}
|
||||
rules = rules_get_as_str();
|
||||
buf = g_strdup_printf("%s\t%i\t%s\t%s\n", tname, b[i].score, tdate, rules);
|
||||
sz = strlen(buf);
|
||||
write(_score_fd, &sz, sizeof(sz));
|
||||
write(_score_fd, buf, strlen(buf));
|
||||
g_free(rules);
|
||||
g_free(tdate);
|
||||
g_free(tname);
|
||||
g_free(buf);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < nbf; i++) {
|
||||
if (strlen(bf[i].name)) {
|
||||
buf = g_strdup_printf("%s\t%i\t%s\t%s\n", bf[i].name, bf[i].score, bf[i].date, bf[i].rules);
|
||||
sz = strlen(buf);
|
||||
write(_score_fd, &sz, sizeof(sz));
|
||||
write(_score_fd, buf, strlen(buf));
|
||||
g_free(buf);
|
||||
}
|
||||
}
|
||||
sz = 0;
|
||||
write(_score_fd, &sz, sizeof(sz));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int score_sort(const void *a, const void *b) {
|
||||
if(((const struct score_board *)a)->score == ((const struct score_board *)b)->score) return 0;
|
||||
if(((const struct score_board *)a)->score < ((const struct score_board *)b)->score) return 1;
|
||||
return -1;
|
||||
|
||||
int score_sort(const void *a, const void *b)
|
||||
{
|
||||
if (((const struct score_board *)a)->score == ((const struct score_board *)b)->score) return 0;
|
||||
if (((const struct score_board *)a)->score < ((const struct score_board *)b)->score) return 1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
gint read_score(struct score_board *b, struct score_board_full **bf, gint *nbf) {
|
||||
FILE *fp;
|
||||
gchar buffer[BUFFER_SIZE];
|
||||
gchar **str_val, *tstr, **tstr_val;
|
||||
gint valid, sc, fsc;
|
||||
gsize br, bw;
|
||||
struct flock lockinfo;
|
||||
|
||||
gchar *g_rules = NULL;
|
||||
gint read_score(struct score_board *b, struct score_board_full **bf, gint *nbf)
|
||||
{
|
||||
FILE *fp;
|
||||
gchar buffer[BUFFER_SIZE];
|
||||
gchar **str_val, *tstr, **tstr_val;
|
||||
gint valid, sc, fsc;
|
||||
gsize br, bw;
|
||||
struct flock lockinfo;
|
||||
|
||||
memset(b, 0, sizeof(struct score_board) * 10);
|
||||
gchar *g_rules = NULL;
|
||||
|
||||
if(!(fp = fopen(LOCALSTATEDIR SCORE_FILE, "r"))) {
|
||||
return FALSE;
|
||||
}
|
||||
memset(b, 0, sizeof(struct score_board) * 10);
|
||||
|
||||
do {
|
||||
lockinfo.l_whence = SEEK_SET;
|
||||
lockinfo.l_start = 0;
|
||||
lockinfo.l_len = 0;
|
||||
lockinfo.l_type = F_WRLCK;
|
||||
fcntl(fileno(fp), F_GETLK, &lockinfo);
|
||||
} while(lockinfo.l_type != F_UNLCK);
|
||||
if (!(fp = fopen(LOCALSTATEDIR SCORE_FILE, "r"))) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
sc = 0;
|
||||
fsc = 0;
|
||||
while(fgets(buffer, BUFFER_SIZE, fp)) {
|
||||
g_strchomp(buffer);
|
||||
str_val = g_strsplit(buffer, "\t", 4);
|
||||
if(str_val[0] && str_val[0][0] &&
|
||||
str_val[1] && str_val[1][0] &&
|
||||
str_val[2] && str_val[2][0]) {
|
||||
valid = 0;
|
||||
if(!str_val[3]) { /* < 2.2.0 file format */
|
||||
g_rules = rules_get_classic_as_str();
|
||||
valid = 1;
|
||||
} else {
|
||||
if((valid = rules_check_str(str_val[3]))) {
|
||||
g_rules = g_strdup(str_val[3]);
|
||||
} else { /* > 2.2.0 && < 3.0.2 file format ? */
|
||||
tstr_val = g_strsplit(str_val[3], "\t", 5);
|
||||
if(tstr_val[0] && tstr_val[1] && tstr_val[2] &&
|
||||
tstr_val[3] && tstr_val[4]) {
|
||||
g_rules = rules_conv_3_0_to_str(tstr_val[0], tstr_val[1], tstr_val[2], tstr_val[3], tstr_val[4]);
|
||||
if(g_rules) { /* yes. its < 3.0.2 format */
|
||||
valid = 1;
|
||||
} else { /* nope. just piece of shit. */
|
||||
g_rules = g_strdup("");
|
||||
}
|
||||
}
|
||||
g_strfreev(tstr_val);
|
||||
}
|
||||
}
|
||||
if(valid && g_ascii_strcasecmp(str_val[0], "<none>")) {
|
||||
if(rules_is_current_str(g_rules)) {
|
||||
if(g_utf8_validate(str_val[0], -1, NULL)) {
|
||||
tstr = g_strdup(str_val[0]);
|
||||
} else {
|
||||
tstr = g_locale_to_utf8(str_val[0], -1, &br, &bw, NULL);
|
||||
}
|
||||
if(tstr) {
|
||||
strncpy(b[sc].name, tstr, sizeof(b[sc].name));
|
||||
g_free(tstr);
|
||||
} else {
|
||||
strncpy(b[sc].name, _("Unknown"), sizeof(b[sc].name));
|
||||
}
|
||||
b[sc].score = strtol(str_val[1], NULL, 10);
|
||||
if((b[sc].score == LONG_MIN) || (b[sc].score == LONG_MAX)) {
|
||||
b[sc].score = 0;
|
||||
}
|
||||
if(g_utf8_validate(str_val[2], -1, NULL)) {
|
||||
tstr = g_strdup(str_val[2]);
|
||||
} else {
|
||||
tstr = g_locale_to_utf8(str_val[2], -1, &br, &bw, NULL);
|
||||
}
|
||||
if(tstr) {
|
||||
strncpy(b[sc].date, tstr, sizeof(b[sc].date));
|
||||
g_free(tstr);
|
||||
} else {
|
||||
strncpy(b[sc].date, _("Unknown"), sizeof(b[sc].date));
|
||||
}
|
||||
sc++;
|
||||
} else if(bf) {
|
||||
*bf = g_realloc(*bf, sizeof(struct score_board_full) * (fsc + 1));
|
||||
strncpy((*bf)[fsc].name, str_val[0], sizeof((*bf)[fsc].name));
|
||||
(*bf)[fsc].score = strtol(str_val[1], NULL, 10);
|
||||
if(((*bf)[fsc].score == LONG_MIN) || ((*bf)[fsc].score == LONG_MAX)) {
|
||||
(*bf)[fsc].score = 0;
|
||||
}
|
||||
strncpy((*bf)[fsc].date, str_val[2], sizeof((*bf)[fsc].date));
|
||||
(*bf)[fsc].rules = g_strdup(g_rules);
|
||||
fsc++;
|
||||
}
|
||||
}
|
||||
g_free(g_rules);
|
||||
}
|
||||
g_strfreev(str_val);
|
||||
}
|
||||
fclose(fp);
|
||||
do {
|
||||
lockinfo.l_whence = SEEK_SET;
|
||||
lockinfo.l_start = 0;
|
||||
lockinfo.l_len = 0;
|
||||
lockinfo.l_type = F_WRLCK;
|
||||
fcntl(fileno(fp), F_GETLK, &lockinfo);
|
||||
} while (lockinfo.l_type != F_UNLCK);
|
||||
|
||||
qsort(b, 10, sizeof(struct score_board), score_sort);
|
||||
sc = 0;
|
||||
fsc = 0;
|
||||
while (fgets(buffer, BUFFER_SIZE, fp))
|
||||
{
|
||||
g_strchomp(buffer);
|
||||
str_val = g_strsplit(buffer, "\t", 4);
|
||||
if (str_val[0] && str_val[0][0] &&
|
||||
str_val[1] && str_val[1][0] &&
|
||||
str_val[2] && str_val[2][0])
|
||||
{
|
||||
valid = 0;
|
||||
if (!str_val[3]) { /* < 2.2.0 file for mat */
|
||||
g_rules = rules_get_classic_as_str();
|
||||
valid = 1;
|
||||
} else {
|
||||
if ((valid = rules_check_str(str_val[3]))) {
|
||||
g_rules = g_strdup(str_val[3]);
|
||||
} else { /* > 2.2.0 && < 3.0.2 file for mat ? */
|
||||
tstr_val = g_strsplit(str_val[3], "\t", 5);
|
||||
if (tstr_val[0] && tstr_val[1] && tstr_val[2] &&
|
||||
tstr_val[3] && tstr_val[4]) {
|
||||
g_rules = rules_conv_3_0_to_str(tstr_val[0], tstr_val[1], tstr_val[2], tstr_val[3], tstr_val[4]);
|
||||
if (g_rules) { /* yes. its < 3.0.2 for mat */
|
||||
valid = 1;
|
||||
} else { /* nope. just piece of shit. */
|
||||
g_rules = g_strdup("");
|
||||
}
|
||||
}
|
||||
g_strfreev(tstr_val);
|
||||
}
|
||||
}
|
||||
if (valid && g_ascii_strcasecmp(str_val[0], "<none>")) {
|
||||
if (rules_is_current_str(g_rules)) {
|
||||
if (g_utf8_validate(str_val[0], -1, NULL)) {
|
||||
tstr = g_strdup(str_val[0]);
|
||||
} else {
|
||||
tstr = g_locale_to_utf8(str_val[0], -1, &br, &bw, NULL);
|
||||
}
|
||||
if (tstr) {
|
||||
strncpy(b[sc].name, tstr, sizeof(b[sc].name));
|
||||
g_free(tstr);
|
||||
} else {
|
||||
strncpy(b[sc].name, _("Unknown"), sizeof(b[sc].name));
|
||||
}
|
||||
b[sc].score = strtol(str_val[1], NULL, 10);
|
||||
if ((b[sc].score == LONG_MIN) || (b[sc].score == LONG_MAX)) {
|
||||
b[sc].score = 0;
|
||||
}
|
||||
if (g_utf8_validate(str_val[2], -1, NULL)) {
|
||||
tstr = g_strdup(str_val[2]);
|
||||
} else {
|
||||
tstr = g_locale_to_utf8(str_val[2], -1, &br, &bw, NULL);
|
||||
}
|
||||
if (tstr) {
|
||||
strncpy(b[sc].date, tstr, sizeof(b[sc].date));
|
||||
g_free(tstr);
|
||||
} else {
|
||||
strncpy(b[sc].date, _("Unknown"), sizeof(b[sc].date));
|
||||
}
|
||||
sc++;
|
||||
} else if (bf) {
|
||||
*bf = g_realloc(*bf, sizeof(struct score_board_full) * (fsc + 1));
|
||||
strncpy((*bf)[fsc].name, str_val[0], sizeof((*bf)[fsc].name));
|
||||
(*bf)[fsc].score = strtol(str_val[1], NULL, 10);
|
||||
if (((*bf)[fsc].score == LONG_MIN) || ((*bf)[fsc].score == LONG_MAX)) {
|
||||
(*bf)[fsc].score = 0;
|
||||
}
|
||||
strncpy((*bf)[fsc].date, str_val[2], sizeof((*bf)[fsc].date));
|
||||
(*bf)[fsc].rules = g_strdup(g_rules);
|
||||
fsc++;
|
||||
}
|
||||
}
|
||||
g_free(g_rules);
|
||||
}
|
||||
g_strfreev(str_val);
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
if(nbf) {
|
||||
*nbf = fsc;
|
||||
}
|
||||
qsort(b, 10, sizeof(struct score_board), score_sort);
|
||||
|
||||
return TRUE;
|
||||
if (nbf) {
|
||||
*nbf = fsc;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gint insert_entry_in_score_board(struct score_board *board, struct score_board entry) {
|
||||
gint i=0,j;
|
||||
|
||||
if(entry.score <= 0) {
|
||||
return -1;
|
||||
}
|
||||
gint insert_entry_in_score_board(struct score_board *board, struct score_board entry)
|
||||
{
|
||||
gint i=0,j;
|
||||
|
||||
while(i < 10 && board[i].score > entry.score) {
|
||||
i++;
|
||||
}
|
||||
if (entry.score <= 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(i > 9) {
|
||||
return -1;
|
||||
}
|
||||
while (i < 10 && board[i].score > entry.score) {
|
||||
i++;
|
||||
}
|
||||
|
||||
for(j = 8;j >= i; j--) {
|
||||
strncpy(board[j + 1].name, board[j].name, sizeof(board[j + 1].name));
|
||||
strncpy(board[j + 1].date, board[j].date, sizeof(board[j + 1].date));
|
||||
board[j + 1].score = board[j].score;
|
||||
}
|
||||
if (i > 9) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
strncpy(board[i].name, entry.name, sizeof(board[i].name));
|
||||
strncpy(board[i].date, entry.date, sizeof(board[i].date));
|
||||
board[i].score = entry.score;
|
||||
for (j = 8;j >= i; j--) {
|
||||
strncpy(board[j + 1].name, board[j].name, sizeof(board[j + 1].name));
|
||||
strncpy(board[j + 1].date, board[j].date, sizeof(board[j + 1].date));
|
||||
board[j + 1].score = board[j].score;
|
||||
}
|
||||
|
||||
return i;
|
||||
strncpy(board[i].name, entry.name, sizeof(board[i].name));
|
||||
strncpy(board[i].date, entry.date, sizeof(board[i].date));
|
||||
board[i].score = entry.score;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
@ -4,16 +4,16 @@
|
||||
#define SCORE_FILE "/gtkballs-scores"
|
||||
|
||||
struct score_board {
|
||||
gchar name[30];
|
||||
gint score;
|
||||
gchar date[60];
|
||||
gchar name[30];
|
||||
gint score;
|
||||
gchar date[60];
|
||||
};
|
||||
|
||||
struct score_board_full {
|
||||
gchar name[30];
|
||||
gint score;
|
||||
gchar date[60];
|
||||
gchar *rules;
|
||||
gchar name[30];
|
||||
gint score;
|
||||
gchar date[60];
|
||||
gchar *rules;
|
||||
};
|
||||
|
||||
gint score_setup(void);
|
||||
@ -22,6 +22,6 @@ void free_score_board_full(struct score_board_full *bf, gint nbf);
|
||||
gint write_score(struct score_board *, struct score_board_full *, gint);
|
||||
gint read_score(struct score_board *, struct score_board_full **, gint *);
|
||||
gint insert_entry_in_score_board(struct score_board *board,
|
||||
struct score_board entry);
|
||||
struct score_board entry);
|
||||
|
||||
#endif /* __SCOREBOARD_H__ */
|
||||
|
592
src/theme.c
592
src/theme.c
@ -1,7 +1,7 @@
|
||||
/* theme.c - functions related to theme handling
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* modif (y it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*/
|
||||
@ -30,343 +30,379 @@ gchar *THEMEPREFIX="/.gtkballs/themes/";
|
||||
#define DELTA(d, h) \
|
||||
d = h < 0 ? (d > -h ? d + h : 0) : (d + h < 255 ? d + h : 255)
|
||||
|
||||
void hilight_pixbuff8(GdkPixbuf *pb, gint dr, gint dg, gint db) {
|
||||
/* pb created with 8b/rgb without alpha */
|
||||
gint i;
|
||||
gint nc = gdk_pixbuf_get_n_channels(pb);
|
||||
gint delta = nc - 3;
|
||||
gint w = gdk_pixbuf_get_width(pb);
|
||||
gint l = w * gdk_pixbuf_get_height(pb);
|
||||
gint d = gdk_pixbuf_get_rowstride(pb) - w * nc;
|
||||
guchar *data = gdk_pixbuf_get_pixels(pb);
|
||||
|
||||
for(i = 0; i < l; i++) {
|
||||
if(i && (i%w == 0)) {
|
||||
data += d;
|
||||
}
|
||||
DELTA(*data, dr);
|
||||
data++;
|
||||
DELTA(*data, dg);
|
||||
data++;
|
||||
DELTA(*data, db);
|
||||
data += delta + 1;
|
||||
}
|
||||
void hilight_pixbuff8(GdkPixbuf *pb, gint dr, gint dg, gint db)
|
||||
{
|
||||
/* pb created with 8b/rgb without alpha */
|
||||
gint i;
|
||||
gint nc = gdk_pixbuf_get_n_channels(pb);
|
||||
gint delta = nc - 3;
|
||||
gint w = gdk_pixbuf_get_width(pb);
|
||||
gint l = w * gdk_pixbuf_get_height(pb);
|
||||
gint d = gdk_pixbuf_get_rowstride(pb) - w * nc;
|
||||
guchar *data = gdk_pixbuf_get_pixels(pb);
|
||||
|
||||
for (i = 0; i < l; i++) {
|
||||
if (i && (i%w == 0)) {
|
||||
data += d;
|
||||
}
|
||||
DELTA(*data, dr);
|
||||
data++;
|
||||
DELTA(*data, dg);
|
||||
data++;
|
||||
DELTA(*data, db);
|
||||
data += delta + 1;
|
||||
}
|
||||
}
|
||||
|
||||
gchar *find_theme_path(gchar *themename) {
|
||||
gchar *homedir;
|
||||
gchar *themepath;
|
||||
struct stat buf;
|
||||
|
||||
if((homedir = getenv("HOME")) &&
|
||||
(themepath = g_strconcat(homedir, THEMEPREFIX, themename, G_DIR_SEPARATOR_S, NULL))) {
|
||||
if(!stat(themepath, &buf) && S_ISDIR(buf.st_mode)) {
|
||||
return themepath;
|
||||
}
|
||||
g_free(themepath);
|
||||
}
|
||||
if((themepath = g_strconcat(INSTALLPATH, themename, G_DIR_SEPARATOR_S, NULL))) {
|
||||
if(!stat(themepath, &buf) && S_ISDIR(buf.st_mode)) {
|
||||
return themepath;
|
||||
}
|
||||
g_free(themepath);
|
||||
}
|
||||
return NULL;
|
||||
gchar *find_theme_path(gchar *themename)
|
||||
{
|
||||
gchar *homedir;
|
||||
gchar *themepath;
|
||||
struct stat buf;
|
||||
|
||||
if ((homedir = getenv("HOME")) &&
|
||||
(themepath = g_strconcat(homedir, THEMEPREFIX, themename, G_DIR_SEPARATOR_S, NULL))) {
|
||||
if (!stat(themepath, &buf) && S_ISDIR(buf.st_mode)) {
|
||||
return themepath;
|
||||
}
|
||||
g_free (themepath);
|
||||
}
|
||||
if ((themepath = g_strconcat(INSTALLPATH, themename, G_DIR_SEPARATOR_S, NULL))) {
|
||||
if (!stat(themepath, &buf) && S_ISDIR(buf.st_mode)) {
|
||||
return themepath;
|
||||
}
|
||||
g_free (themepath);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gint gtkb_load_pixmap(GtkbPixmap *pixmap, gchar *path, gchar *pixmapname) {
|
||||
gchar *fname;
|
||||
GError *error = NULL;
|
||||
gint rv = 1;
|
||||
|
||||
if(!(fname = g_strconcat(path, pixmapname, NULL))) {
|
||||
return 0;
|
||||
}
|
||||
if(pixmap->pixbuf) g_object_unref(pixmap->pixbuf);
|
||||
pixmap->pixbuf = gdk_pixbuf_new_from_file(fname, &error);
|
||||
if(!pixmap->pixbuf) {
|
||||
ut_simple_message_box(error->message);
|
||||
g_error_free(error);
|
||||
rv = 0;
|
||||
} else {
|
||||
pixmap->xsize = gdk_pixbuf_get_width(pixmap->pixbuf);
|
||||
pixmap->ysize = gdk_pixbuf_get_height(pixmap->pixbuf);
|
||||
}
|
||||
g_free(fname);
|
||||
return rv;
|
||||
gint gtkb_load_pixmap(GtkbPixmap *pixmap, gchar *path, gchar *pixmapname)
|
||||
{
|
||||
gchar *fname;
|
||||
GError *error = NULL;
|
||||
gint rv = 1;
|
||||
|
||||
if (!(fname = g_strconcat(path, pixmapname, NULL))) {
|
||||
return 0;
|
||||
}
|
||||
if (pixmap->pixbuf) {
|
||||
g_object_unref(pixmap->pixbuf);
|
||||
}
|
||||
pixmap->pixbuf = gdk_pixbuf_new_from_file(fname, &error);
|
||||
if (!pixmap->pixbuf) {
|
||||
ut_simple_message_box(error->message);
|
||||
g_error_free (error);
|
||||
rv = 0;
|
||||
} else {
|
||||
pixmap->xsize = gdk_pixbuf_get_width (pixmap->pixbuf);
|
||||
pixmap->ysize = gdk_pixbuf_get_height (pixmap->pixbuf);
|
||||
}
|
||||
g_free (fname);
|
||||
return rv;
|
||||
}
|
||||
|
||||
void gtkb_pixmap_free(GtkbPixmap pixmap) {
|
||||
if(pixmap.pixbuf) {
|
||||
g_object_unref(pixmap.pixbuf);
|
||||
}
|
||||
if (pixmap.pixbuf) {
|
||||
g_object_unref(pixmap.pixbuf);
|
||||
}
|
||||
}
|
||||
|
||||
void gtkb_theme_free(GtkbTheme *theme) {
|
||||
gint i, j;
|
||||
|
||||
if(!theme) {
|
||||
return;
|
||||
}
|
||||
gtkb_pixmap_free(theme->emptycell);
|
||||
gtkb_pixmap_free(theme->hemptycell);
|
||||
for(i = 0; i < 8; i++) {
|
||||
gtkb_pixmap_free(theme->paws[i]);
|
||||
}
|
||||
if(theme->balls) {
|
||||
for(i = 0; i < theme->numballs; i++) {
|
||||
gtkb_pixmap_free(theme->balls[i].ball);
|
||||
gtkb_pixmap_free(theme->balls[i].small);
|
||||
if(theme->balls[i].jump) {
|
||||
for(j = 0; j < theme->balls[i].jumpphases; j++) {
|
||||
gtkb_pixmap_free(theme->balls[i].jump[j]);
|
||||
}
|
||||
g_free(theme->balls[i].jump);
|
||||
if(theme->balls[i].jumpdelays) {
|
||||
g_free(theme->balls[i].jumpdelays);
|
||||
}
|
||||
}
|
||||
if(theme->balls[i].destroy) {
|
||||
for(j = 0; j < theme->balls[i].destroyphases; j++) {
|
||||
gtkb_pixmap_free(theme->balls[i].destroy[j]);
|
||||
}
|
||||
g_free(theme->balls[i].destroy);
|
||||
if(theme->balls[i].destroydelays) {
|
||||
g_free(theme->balls[i].destroydelays);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
g_free(theme->balls);
|
||||
g_free(theme);
|
||||
void gtkb_theme_free(GtkbTheme *theme)
|
||||
{
|
||||
gint i, j;
|
||||
|
||||
if (!theme) {
|
||||
return;
|
||||
}
|
||||
gtkb_pixmap_free(theme->emptycell);
|
||||
gtkb_pixmap_free(theme->hemptycell);
|
||||
for (i = 0; i < 8; i++) {
|
||||
gtkb_pixmap_free(theme->paws[i]);
|
||||
}
|
||||
if (theme->balls) {
|
||||
for (i = 0; i < theme->numballs; i++) {
|
||||
gtkb_pixmap_free(theme->balls[i].ball);
|
||||
gtkb_pixmap_free(theme->balls[i].small);
|
||||
if (theme->balls[i].jump) {
|
||||
for (j = 0; j < theme->balls[i].jumpphases; j++) {
|
||||
gtkb_pixmap_free(theme->balls[i].jump[j]);
|
||||
}
|
||||
g_free (theme->balls[i].jump);
|
||||
if (theme->balls[i].jumpdelays) {
|
||||
g_free (theme->balls[i].jumpdelays);
|
||||
}
|
||||
}
|
||||
if (theme->balls[i].destroy) {
|
||||
for (j = 0; j < theme->balls[i].destroyphases; j++) {
|
||||
gtkb_pixmap_free(theme->balls[i].destroy[j]);
|
||||
}
|
||||
g_free (theme->balls[i].destroy);
|
||||
if (theme->balls[i].destroydelays) {
|
||||
g_free (theme->balls[i].destroydelays);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
g_free (theme->balls);
|
||||
g_free (theme);
|
||||
}
|
||||
|
||||
|
||||
/* warning! tmpname will be free()'d! */
|
||||
gint gtkb_load_pixmap_from(gchar **trc, gchar *themepath, gchar *tmpname, GtkbPixmap *pixmap) {
|
||||
gchar *val;
|
||||
gint ret;
|
||||
gint gtkb_load_pixmap_from(gchar **trc, gchar *themepath, gchar *tmpname, GtkbPixmap *pixmap)
|
||||
{
|
||||
gchar *val;
|
||||
gint ret;
|
||||
|
||||
val = trc_get_str(trc, tmpname);
|
||||
g_free(tmpname);
|
||||
if(val == NULL) return 0;
|
||||
ret = gtkb_load_pixmap(pixmap, themepath, val);
|
||||
g_free(val);
|
||||
val = trc_get_str(trc, tmpname);
|
||||
g_free (tmpname);
|
||||
if (val == NULL) {
|
||||
return 0;
|
||||
}
|
||||
ret = gtkb_load_pixmap(pixmap, themepath, val);
|
||||
g_free (val);
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define CHECKRET(ret, cond) \
|
||||
if(ret == cond) { \
|
||||
gtkb_theme_free(theme); \
|
||||
trc_close(trc); \
|
||||
return NULL; \
|
||||
}
|
||||
if (ret == cond) { \
|
||||
gtkb_theme_free(theme); \
|
||||
trc_close(trc); \
|
||||
return NULL; \
|
||||
}
|
||||
|
||||
void gtkb_make_hl_pixmap(GtkbTheme *theme) {
|
||||
if(theme->hemptycell.pixbuf) {
|
||||
gtkb_pixmap_free(theme->hemptycell);
|
||||
}
|
||||
theme->hemptycell.pixbuf = gdk_pixbuf_copy(theme->emptycell.pixbuf);
|
||||
theme->hemptycell.xsize = theme->emptycell.xsize;
|
||||
theme->hemptycell.ysize = theme->emptycell.ysize;
|
||||
hilight_pixbuff8(theme->hemptycell.pixbuf, prefs_get_hl_dr(), prefs_get_hl_dg(), prefs_get_hl_db());
|
||||
if (theme->hemptycell.pixbuf) {
|
||||
gtkb_pixmap_free(theme->hemptycell);
|
||||
}
|
||||
theme->hemptycell.pixbuf = gdk_pixbuf_copy(theme->emptycell.pixbuf);
|
||||
theme->hemptycell.xsize = theme->emptycell.xsize;
|
||||
theme->hemptycell.ysize = theme->emptycell.ysize;
|
||||
hilight_pixbuff8(theme->hemptycell.pixbuf, prefs_get_hl_dr(), prefs_get_hl_dg(), prefs_get_hl_db());
|
||||
}
|
||||
|
||||
GtkbTheme *gtkb_load_theme(gchar *themepath) {
|
||||
gchar **trc, *opt;
|
||||
gchar *paws[] = {"down_up", "left_right", "up_down", "right_left",
|
||||
"down_right", "down_left", "up_right", "up_left", NULL};
|
||||
gint i, j, ret;
|
||||
GtkbTheme *theme;
|
||||
|
||||
opt = g_strconcat(themepath, "themerc", NULL);
|
||||
trc = trc_open(opt); /* open theme description file */
|
||||
g_free(opt);
|
||||
if(!trc) {
|
||||
return NULL;
|
||||
}
|
||||
theme = g_new0(GtkbTheme, 1);
|
||||
GtkbTheme *gtkb_load_theme(gchar *themepath)
|
||||
{
|
||||
gchar **trc, *opt;
|
||||
gchar *paws[] = {"down_up", "left_right", "up_down", "right_left",
|
||||
"down_right", "down_left", "up_right", "up_left", NULL};
|
||||
gint i, j, ret;
|
||||
GtkbTheme *theme;
|
||||
|
||||
/* find and load "empty cell" pixmap. */
|
||||
opt = trc_get_str(trc, "cell");
|
||||
CHECKRET(opt, NULL);
|
||||
ret = gtkb_load_pixmap(&theme->emptycell, themepath, opt);
|
||||
g_free(opt);
|
||||
CHECKRET(ret, 0);
|
||||
opt = g_strconcat(themepath, "themerc", NULL);
|
||||
trc = trc_open(opt); /* open theme description file */
|
||||
g_free (opt);
|
||||
if (!trc) {
|
||||
return NULL;
|
||||
}
|
||||
theme = g_new0(GtkbTheme, 1);
|
||||
|
||||
/* find and load "empty cell" pixmap. */
|
||||
opt = trc_get_str(trc, "cell");
|
||||
CHECKRET(opt, NULL);
|
||||
ret = gtkb_load_pixmap(&theme->emptycell, themepath, opt);
|
||||
g_free (opt);
|
||||
CHECKRET(ret, 0);
|
||||
/*
|
||||
theme->hemptycell.pixbuf = gdk_pixbuf_copy(theme->emptycell.pixbuf);
|
||||
theme->hemptycell.xsize = theme->emptycell.xsize;
|
||||
theme->hemptycell.ysize = theme->emptycell.ysize;
|
||||
CHECKRET(theme->hemptycell.pixbuf, NULL);
|
||||
hilight_pixbuff8(theme->hemptycell.pixbuf, prefs_get_hl_dr(), prefs_get_hl_dg(), prefs_get_hl_db());
|
||||
theme->hemptycell.pixbuf = gdk_pixbuf_copy(theme->emptycell.pixbuf);
|
||||
theme->hemptycell.xsize = theme->emptycell.xsize;
|
||||
theme->hemptycell.ysize = theme->emptycell.ysize;
|
||||
CHECKRET(theme->hemptycell.pixbuf, NULL);
|
||||
hilight_pixbuff8(theme->hemptycell.pixbuf, prefs_get_hl_dr(), prefs_get_hl_dg(), prefs_get_hl_db());
|
||||
*/
|
||||
gtkb_make_hl_pixmap(theme);
|
||||
gtkb_make_hl_pixmap(theme);
|
||||
|
||||
/* find and load "footprints" pixmaps. */
|
||||
for(i = 0; paws[i]; i++) {
|
||||
CHECKRET(gtkb_load_pixmap_from(trc, themepath, g_strconcat("paw.", paws[i], NULL),
|
||||
&theme->paws[i]),
|
||||
0);
|
||||
}
|
||||
/* find and load "footprints" pixmaps. */
|
||||
for (i = 0; paws[i]; i++) {
|
||||
CHECKRET(gtkb_load_pixmap_from(trc, themepath, g_strconcat("paw.", paws[i], NULL),
|
||||
&theme->paws[i]), 0);
|
||||
}
|
||||
|
||||
/* query number of available balls in theme */
|
||||
theme->numballs = trc_get_uint(trc, "ball.numbers");
|
||||
CHECKRET(theme->numballs, -1);
|
||||
if(theme->numballs < rules_get_colors()) CHECKRET(0, 0); /* yes, i know. its ugly =) */
|
||||
theme->balls = g_new0(GtkbBall, theme->numballs);
|
||||
/* query number of available balls in theme */
|
||||
theme->numballs = trc_get_uint(trc, "ball.numbers");
|
||||
CHECKRET(theme->numballs, -1);
|
||||
if (theme->numballs < rules_get_colors()) {
|
||||
CHECKRET(0, 0); /* yes, i know. its ugly =) */
|
||||
}
|
||||
theme->balls = g_new0(GtkbBall, theme->numballs);
|
||||
|
||||
/* find and load all balls data. */
|
||||
for(i = 0; i < theme->numballs; i++) {
|
||||
CHECKRET(gtkb_load_pixmap_from(trc, themepath, g_strdup_printf("ball.%d.still", i + 1),
|
||||
&theme->balls[i].ball),
|
||||
0);
|
||||
CHECKRET(gtkb_load_pixmap_from(trc, themepath, g_strdup_printf("ball.%d.small", i + 1),
|
||||
&theme->balls[i].small),
|
||||
0);
|
||||
/* find and load all balls data. */
|
||||
for (i = 0; i < theme->numballs; i++) {
|
||||
CHECKRET(gtkb_load_pixmap_from(trc, themepath, g_strdup_printf("ball.%d.still", i + 1),
|
||||
&theme->balls[i].ball), 0);
|
||||
CHECKRET(gtkb_load_pixmap_from(trc, themepath, g_strdup_printf("ball.%d.small", i + 1),
|
||||
&theme->balls[i].small), 0);
|
||||
|
||||
opt = g_strdup_printf("ball.%d.jump.numbers", i + 1);
|
||||
theme->balls[i].jumpphases = trc_get_uint(trc, opt);
|
||||
g_free(opt);
|
||||
CHECKRET(theme->balls[i].jumpphases, -1);
|
||||
if(theme->balls[i].jumpphases < 2) CHECKRET(0, 0); /* yes, i know. its ugly =) */
|
||||
theme->balls[i].jump = g_new0(GtkbPixmap, theme->balls[i].jumpphases);
|
||||
theme->balls[i].jumpdelays = g_new0(gint, theme->balls[i].jumpphases);
|
||||
opt = g_strdup_printf("ball.%d.jump.numbers", i + 1);
|
||||
theme->balls[i].jumpphases = trc_get_uint(trc, opt);
|
||||
g_free (opt);
|
||||
CHECKRET(theme->balls[i].jumpphases, -1);
|
||||
if (theme->balls[i].jumpphases < 2) {
|
||||
CHECKRET(0, 0); /* yes, i know. its ugly =) */
|
||||
}
|
||||
theme->balls[i].jump = g_new0(GtkbPixmap, theme->balls[i].jumpphases);
|
||||
theme->balls[i].jumpdelays = g_new0(gint, theme->balls[i].jumpphases);
|
||||
|
||||
for(j = 0; j < theme->balls[i].jumpphases; j++) {
|
||||
CHECKRET(gtkb_load_pixmap_from(trc, themepath,
|
||||
g_strdup_printf("ball.%d.jump.%d", i + 1, j + 1),
|
||||
&theme->balls[i].jump[j]),
|
||||
0);
|
||||
opt = g_strdup_printf("ball.%d.jump.%d.usec", i + 1, j + 1);
|
||||
theme->balls[i].jumpdelays[j] = trc_get_uint(trc, opt);
|
||||
g_free(opt);
|
||||
CHECKRET(theme->balls[i].jumpdelays[j], -1);
|
||||
}
|
||||
for (j = 0; j < theme->balls[i].jumpphases; j++) {
|
||||
CHECKRET(gtkb_load_pixmap_from(trc, themepath,
|
||||
g_strdup_printf("ball.%d.jump.%d", i + 1, j + 1),
|
||||
&theme->balls[i].jump[j]), 0);
|
||||
opt = g_strdup_printf("ball.%d.jump.%d.usec", i + 1, j + 1);
|
||||
theme->balls[i].jumpdelays[j] = trc_get_uint(trc, opt);
|
||||
g_free (opt);
|
||||
CHECKRET(theme->balls[i].jumpdelays[j], -1);
|
||||
}
|
||||
|
||||
opt = g_strdup_printf("ball.%d.destroy.numbers", i + 1);
|
||||
theme->balls[i].destroyphases = trc_get_uint(trc, opt);
|
||||
g_free(opt);
|
||||
CHECKRET(theme->balls[i].destroyphases, -1);
|
||||
if(theme->balls[i].destroyphases < 2) CHECKRET(0, 0); /* yes, i know. its ugly =) */
|
||||
if(theme->balls[i].destroyphases > theme->maxdestphases) {
|
||||
theme->maxdestphases = theme->balls[i].destroyphases;
|
||||
}
|
||||
theme->balls[i].destroy = g_new0(GtkbPixmap, theme->balls[i].destroyphases);
|
||||
theme->balls[i].destroydelays = g_new0(gint, theme->balls[i].destroyphases);
|
||||
opt = g_strdup_printf("ball.%d.destroy.numbers", i + 1);
|
||||
theme->balls[i].destroyphases = trc_get_uint(trc, opt);
|
||||
g_free (opt);
|
||||
CHECKRET(theme->balls[i].destroyphases, -1);
|
||||
if (theme->balls[i].destroyphases < 2) {
|
||||
CHECKRET(0, 0); /* yes, i know. its ugly =) */
|
||||
}
|
||||
if (theme->balls[i].destroyphases > theme->maxdestphases) {
|
||||
theme->maxdestphases = theme->balls[i].destroyphases;
|
||||
}
|
||||
theme->balls[i].destroy = g_new0(GtkbPixmap, theme->balls[i].destroyphases);
|
||||
theme->balls[i].destroydelays = g_new0(gint, theme->balls[i].destroyphases);
|
||||
for (j = 0; j < theme->balls[i].destroyphases; j++) {
|
||||
CHECKRET(gtkb_load_pixmap_from(trc, themepath,
|
||||
g_strdup_printf("ball.%d.destroy.%d", i + 1, j + 1),
|
||||
&theme->balls[i].destroy[j]), 0);
|
||||
opt = g_strdup_printf("ball.%d.destroy.%d.usec", i + 1, j + 1);
|
||||
theme->balls[i].destroydelays[j] = trc_get_uint(trc, opt);
|
||||
g_free (opt);
|
||||
CHECKRET(theme->balls[i].destroydelays[j], -1);
|
||||
}
|
||||
}
|
||||
trc_close(trc);
|
||||
|
||||
for(j = 0; j < theme->balls[i].destroyphases; j++) {
|
||||
CHECKRET(gtkb_load_pixmap_from(trc, themepath,
|
||||
g_strdup_printf("ball.%d.destroy.%d", i + 1, j + 1),
|
||||
&theme->balls[i].destroy[j]),
|
||||
0);
|
||||
opt = g_strdup_printf("ball.%d.destroy.%d.usec", i + 1, j + 1);
|
||||
theme->balls[i].destroydelays[j] = trc_get_uint(trc, opt);
|
||||
g_free(opt);
|
||||
CHECKRET(theme->balls[i].destroydelays[j], -1);
|
||||
}
|
||||
}
|
||||
trc_close(trc);
|
||||
|
||||
return theme;
|
||||
return theme;
|
||||
}
|
||||
|
||||
gint load_theme(gchar *themename) {
|
||||
gchar *themepath;
|
||||
GtkbTheme *theme;
|
||||
|
||||
if(!(themepath = find_theme_path(themename))) return 0;
|
||||
gint load_theme(gchar *themename)
|
||||
{
|
||||
gchar *themepath;
|
||||
GtkbTheme *theme;
|
||||
|
||||
theme = gtkb_load_theme(themepath);
|
||||
g_free(themepath);
|
||||
if (!(themepath = find_theme_path(themename))) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(!theme) return 0;
|
||||
theme = gtkb_load_theme(themepath);
|
||||
g_free (themepath);
|
||||
|
||||
gtkb_theme_free(gtkbTheme);
|
||||
gtkbTheme = theme;
|
||||
if (!theme) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
gtkb_theme_free(gtkbTheme);
|
||||
gtkbTheme = theme;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
gint gtkb_theme_free_handler(GtkWidget *widget, gpointer data) {
|
||||
gtkb_theme_free(gtkbTheme);
|
||||
gtkbTheme = NULL;
|
||||
return 0;
|
||||
|
||||
gint gtkb_theme_free_handler(GtkWidget *widget, gpointer data)
|
||||
{
|
||||
gtkb_theme_free(gtkbTheme);
|
||||
gtkbTheme = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
gint gtkb_theme_get_balls_num(void) {
|
||||
return gtkbTheme ? gtkbTheme->numballs : 0;
|
||||
|
||||
gint gtkb_theme_get_balls_num(void)
|
||||
{
|
||||
return gtkbTheme ? gtkbTheme->numballs : 0;
|
||||
}
|
||||
|
||||
|
||||
/* returns board coordinate of the pointer */
|
||||
gint gtkb_theme_get_coord_at_x(gint x) {
|
||||
if(gtkbTheme) {
|
||||
return (x - 1) / gtkbTheme->emptycell.xsize;
|
||||
}
|
||||
return -1;
|
||||
gint gtkb_theme_get_coord_at_x(gint x)
|
||||
{
|
||||
if (gtkbTheme) {
|
||||
return (x - 1) / gtkbTheme->emptycell.xsize;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
gint gtkb_theme_get_coord_at_y(gint y) {
|
||||
if(gtkbTheme) {
|
||||
return (y - 1) / gtkbTheme->emptycell.ysize;
|
||||
}
|
||||
return -1;
|
||||
|
||||
gint gtkb_theme_get_coord_at_y(gint y)
|
||||
{
|
||||
if (gtkbTheme) {
|
||||
return (y - 1) / gtkbTheme->emptycell.ysize;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
gint theme_get_width(void) {
|
||||
return gtkbTheme->emptycell.xsize;
|
||||
return gtkbTheme->emptycell.xsize;
|
||||
}
|
||||
|
||||
gint theme_get_height(void) {
|
||||
return gtkbTheme->emptycell.xsize;
|
||||
return gtkbTheme->emptycell.xsize;
|
||||
}
|
||||
|
||||
|
||||
/* find all available themes. */
|
||||
gchar **get_available_themes(void) {
|
||||
DIR *directory;
|
||||
struct dirent *dir_entry;
|
||||
struct stat entry_stat;
|
||||
gchar *entry, *currdir, *hdir, *rcentry;
|
||||
gint i, j, num, flag;
|
||||
gchar **tlist = NULL;
|
||||
gchar **get_available_themes(void)
|
||||
{
|
||||
DIR *directory;
|
||||
struct dirent *dir_entry;
|
||||
struct stat entry_stat;
|
||||
gchar *entry, *currdir, *hdir, *rcentry;
|
||||
gint i, j, num, flag;
|
||||
gchar **tlist = NULL;
|
||||
|
||||
if(getenv("HOME")) {
|
||||
hdir = g_strconcat(getenv("HOME"), THEMEPREFIX, NULL);
|
||||
} else {
|
||||
hdir = g_strdup("./"); /* FIXME: does it work on non unix os? */
|
||||
}
|
||||
for(j = 0, currdir = INSTALLPATH, num = 0; j < 2; j++, currdir = hdir) {
|
||||
if(!(directory = opendir(currdir))) {
|
||||
continue;
|
||||
}
|
||||
while((dir_entry = readdir(directory))) {
|
||||
if(!strncmp(dir_entry->d_name, ".", 2) ||
|
||||
!strncmp(dir_entry->d_name, "..", 3)) {
|
||||
continue;
|
||||
}
|
||||
entry = g_strconcat(currdir, dir_entry->d_name, NULL);
|
||||
if(!stat(entry, &entry_stat) && S_ISDIR(entry_stat.st_mode)) {
|
||||
rcentry = g_strconcat(entry, G_DIR_SEPARATOR_S, "themerc", NULL);
|
||||
if(!stat(rcentry, &entry_stat)) {
|
||||
flag = 0;
|
||||
for(i=0; i < num && !flag; i++) {
|
||||
if(!strcmp(tlist[i], dir_entry->d_name)) {
|
||||
flag++;
|
||||
}
|
||||
}
|
||||
if(!flag) {
|
||||
num++;
|
||||
tlist = g_realloc(tlist, num * sizeof(gchar *));
|
||||
tlist[num-1] = g_strdup(dir_entry->d_name);
|
||||
}
|
||||
}
|
||||
g_free(rcentry);
|
||||
}
|
||||
g_free(entry);
|
||||
}
|
||||
closedir(directory);
|
||||
}
|
||||
g_free(hdir);
|
||||
tlist = g_realloc(tlist, (num + 1) * sizeof(gchar *));
|
||||
tlist[num] = NULL;
|
||||
return tlist;
|
||||
if (getenv("HOME")) {
|
||||
hdir = g_strconcat(getenv("HOME"), THEMEPREFIX, NULL);
|
||||
} else {
|
||||
hdir = g_strdup("./"); /* FIXME: does it work on non unix os? */
|
||||
}
|
||||
|
||||
for (j = 0, currdir = INSTALLPATH, num = 0; j < 2; j++, currdir = hdir)
|
||||
{
|
||||
if (!(directory = opendir(currdir))) {
|
||||
continue;
|
||||
}
|
||||
while((dir_entry = readdir(directory)))
|
||||
{
|
||||
if (!strncmp(dir_entry->d_name, ".", 2) ||
|
||||
!strncmp(dir_entry->d_name, "..", 3)) {
|
||||
continue;
|
||||
}
|
||||
entry = g_strconcat(currdir, dir_entry->d_name, NULL);
|
||||
if (!stat(entry, &entry_stat) && S_ISDIR(entry_stat.st_mode)) {
|
||||
rcentry = g_strconcat(entry, G_DIR_SEPARATOR_S, "themerc", NULL);
|
||||
if (!stat(rcentry, &entry_stat)) {
|
||||
flag = 0;
|
||||
for (i=0; i < num && !flag; i++) {
|
||||
if (!strcmp(tlist[i], dir_entry->d_name)) {
|
||||
flag++;
|
||||
}
|
||||
}
|
||||
if (!flag) {
|
||||
num++;
|
||||
tlist = g_realloc(tlist, num * sizeof(gchar *));
|
||||
tlist[num-1] = g_strdup(dir_entry->d_name);
|
||||
}
|
||||
}
|
||||
g_free (rcentry);
|
||||
}
|
||||
g_free (entry);
|
||||
}
|
||||
closedir(directory);
|
||||
}
|
||||
|
||||
g_free (hdir);
|
||||
tlist = g_realloc(tlist, (num + 1) * sizeof(gchar *));
|
||||
tlist[num] = NULL;
|
||||
return tlist;
|
||||
}
|
||||
|
32
src/theme.h
32
src/theme.h
@ -6,28 +6,28 @@ typedef struct _GtkbPixmap GtkbPixmap;
|
||||
typedef struct _GtkbBall GtkbBall;
|
||||
|
||||
struct _GtkbPixmap {
|
||||
GdkPixbuf *pixbuf;
|
||||
gint xsize, ysize;
|
||||
GdkPixbuf *pixbuf;
|
||||
gint xsize, ysize;
|
||||
};
|
||||
|
||||
struct _GtkbBall {
|
||||
GtkbPixmap ball; /* still picture of ball */
|
||||
GtkbPixmap small; /* small picture of ball */
|
||||
gint jumpphases;
|
||||
GtkbPixmap *jump;
|
||||
gint *jumpdelays;
|
||||
gint destroyphases;
|
||||
GtkbPixmap *destroy;
|
||||
gint *destroydelays;
|
||||
GtkbPixmap ball; /* still picture of ball */
|
||||
GtkbPixmap small; /* small picture of ball */
|
||||
gint jumpphases;
|
||||
GtkbPixmap *jump;
|
||||
gint *jumpdelays;
|
||||
gint destroyphases;
|
||||
GtkbPixmap *destroy;
|
||||
gint *destroydelays;
|
||||
};
|
||||
|
||||
struct _GtkbTheme {
|
||||
GtkbPixmap emptycell; /* pixmap for empty cell */
|
||||
GtkbPixmap hemptycell; /* highlighted pixmap for empty cell */
|
||||
GtkbPixmap paws[8]; /* 8 pixmaps for footprints */
|
||||
gint numballs; /* number of balls */
|
||||
GtkbBall *balls; /* array of balls */
|
||||
gint maxdestphases; /* maximal number of destroy phases */
|
||||
GtkbPixmap emptycell; /* pixmap for empty cell */
|
||||
GtkbPixmap hemptycell; /* highlighted pixmap for empty cell */
|
||||
GtkbPixmap paws[8]; /* 8 pixmaps for footprints */
|
||||
gint numballs; /* number of balls */
|
||||
GtkbBall *balls; /* array of balls */
|
||||
gint maxdestphases; /* maximal number of destroy phases */
|
||||
};
|
||||
|
||||
|
||||
|
144
src/themerc.c
144
src/themerc.c
@ -18,88 +18,92 @@
|
||||
#include <errno.h>
|
||||
|
||||
/* read contents of fname into gchar * */
|
||||
gchar **trc_open(gchar *fname) {
|
||||
gint fd;
|
||||
struct stat fds;
|
||||
ssize_t rb;
|
||||
gchar *rc,**rcs;
|
||||
gchar **trc_open(gchar *fname)
|
||||
{
|
||||
gint fd;
|
||||
struct stat fds;
|
||||
ssize_t rb;
|
||||
gchar *rc, **rcs;
|
||||
|
||||
if((fd=open(fname, O_RDONLY))==-1) {
|
||||
fprintf(stderr, "%s: open() %s failed: %s\n", __FUNCTION__, fname, strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
if((fstat(fd, &fds))==-1) {
|
||||
close(fd);
|
||||
fprintf(stderr, "%s: fstat() failed: %s\n", __FUNCTION__, strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
if(!(fds.st_size)) {
|
||||
close(fd);
|
||||
fprintf(stderr, "%s: zero length file.\n", __FUNCTION__);
|
||||
return NULL;
|
||||
}
|
||||
if(!(rc=malloc(fds.st_size+1))) {
|
||||
close(fd);
|
||||
fprintf(stderr, "%s: malloc() failed: cannot alloc %d bytes\n", __FUNCTION__, (int)fds.st_size);
|
||||
return NULL;
|
||||
}
|
||||
if((rb=read(fd, rc, fds.st_size))!=fds.st_size) {
|
||||
free(rc);
|
||||
close(fd);
|
||||
if(rb==-1) {
|
||||
fprintf(stderr, "%s: read() failed: %s\n", __FUNCTION__, strerror(errno));
|
||||
} else {
|
||||
fprintf(stderr, "%s: read() reads less bytes than expected =/\n", __FUNCTION__);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
rc[fds.st_size]=0;
|
||||
close(fd);
|
||||
rcs=g_strsplit(rc, "\n", 0);
|
||||
free(rc);
|
||||
return rcs;
|
||||
if ((fd=open(fname, O_RDONLY)) == -1) {
|
||||
fprintf(stderr, "%s: open() %s failed: %s\n", __FUNCTION__, fname, strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
if ((fstat(fd, &fds)) == -1) {
|
||||
close(fd);
|
||||
fprintf(stderr, "%s: fstat() failed: %s\n", __FUNCTION__, strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
if (!(fds.st_size)) {
|
||||
close(fd);
|
||||
fprintf(stderr, "%s: zero length file.\n", __FUNCTION__);
|
||||
return NULL;
|
||||
}
|
||||
if (!(rc=malloc(fds.st_size+1))) {
|
||||
close(fd);
|
||||
fprintf(stderr, "%s: malloc() failed: cannot alloc %d bytes\n", __FUNCTION__, (int)fds.st_size);
|
||||
return NULL;
|
||||
}
|
||||
if ((rb=read(fd, rc, fds.st_size)) != fds.st_size) {
|
||||
free(rc);
|
||||
close(fd);
|
||||
if (rb == -1) {
|
||||
fprintf(stderr, "%s: read() failed: %s\n", __FUNCTION__, strerror(errno));
|
||||
} else {
|
||||
fprintf(stderr, "%s: read() reads less bytes than expected =/\n", __FUNCTION__);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
rc[fds.st_size]=0;
|
||||
close(fd);
|
||||
rcs=g_strsplit(rc, "\n", 0);
|
||||
free(rc);
|
||||
return rcs;
|
||||
}
|
||||
|
||||
/* free rc... */
|
||||
void trc_close(gchar **rcs) {
|
||||
if(rcs) {
|
||||
g_strfreev(rcs);
|
||||
}
|
||||
if (rcs) {
|
||||
g_strfreev(rcs);
|
||||
}
|
||||
}
|
||||
|
||||
/* return string value for given parameter. if not found retun NULL */
|
||||
gchar *trc_get_str(gchar **rcs, gchar *param) {
|
||||
gint i;
|
||||
gchar **strval,*val;
|
||||
gchar *trc_get_str(gchar **rcs, gchar *param)
|
||||
{
|
||||
gint i;
|
||||
gchar **strval,*val;
|
||||
|
||||
if(!rcs) {
|
||||
fprintf(stderr, "%s called with uninitialised rcs. strange. \n", __FUNCTION__);
|
||||
return NULL;
|
||||
}
|
||||
if(!param) {
|
||||
fprintf(stderr, "%s called with NULL param. strange. \n", __FUNCTION__);
|
||||
return NULL;
|
||||
}
|
||||
for(i=0;rcs[i];i++) {
|
||||
if(rcs[i][0] && rcs[i][0]!='#' && (strval=g_strsplit(rcs[i],"=",2)) && strval[0] && strval[1]) {
|
||||
if(!(strcmp(g_strstrip(strval[0]),param))) {
|
||||
val=g_strdup(g_strstrip(strval[1]));
|
||||
g_strfreev(strval);
|
||||
return val;
|
||||
}
|
||||
g_strfreev(strval);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
if (!rcs) {
|
||||
fprintf(stderr, "%s called with uninitialised rcs. strange. \n", __FUNCTION__);
|
||||
return NULL;
|
||||
}
|
||||
if (!param) {
|
||||
fprintf(stderr, "%s called with NULL param. strange. \n", __FUNCTION__);
|
||||
return NULL;
|
||||
}
|
||||
for (i=0;rcs[i];i++) {
|
||||
if (rcs[i][0] && rcs[i][0]!='#' && (strval=g_strsplit(rcs[i],"=",2)) && strval[0] && strval[1]) {
|
||||
if (!(strcmp(g_strstrip(strval[0]),param))) {
|
||||
val=g_strdup(g_strstrip(strval[1]));
|
||||
g_strfreev(strval);
|
||||
return val;
|
||||
}
|
||||
g_strfreev(strval);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* return unsigned integer value for given parameter. if not found retun -1 */
|
||||
gint trc_get_uint(gchar **rcs, gchar *param) {
|
||||
gchar *val;
|
||||
gint ret;
|
||||
gchar *val;
|
||||
gint ret;
|
||||
|
||||
if(!(val=trc_get_str(rcs, param))) return -1;
|
||||
ret=atoi(val);
|
||||
g_free(val);
|
||||
return ret;
|
||||
if (!(val=trc_get_str(rcs, param))) {
|
||||
return -1;
|
||||
}
|
||||
ret = atoi(val);
|
||||
g_free (val);
|
||||
return ret;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user