This is the doxygen documentation for gtkboard.

.
Main Page   Data Structures   File List   Data Fields   Globals  

board.c

Go to the documentation of this file.
00001 /*  This file is a part of gtkboard, a board games system.
00002     Copyright (C) 2003, Arvind Narayanan <arvindn@users.sourceforge.net>
00003 
00004     This program is free software; you can redistribute it and/or modify
00005     it under the terms of the GNU General Public License as published by
00006     the Free Software Foundation; either version 2 of the License, or
00007     (at your option) any later version.
00008 
00009     This program is distributed in the hope that it will be useful,
00010     but WITHOUT ANY WARRANTY; without even the implied warranty of
00011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012     GNU General Public License for more details.
00013 
00014     You should have received a copy of the GNU General Public License
00015     along with this program; if not, write to the Free Software
00016     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
00017 
00018 */
00022 #include <stdlib.h>
00023 #include <assert.h>
00024 
00025 #include <glib.h>
00026 #include <gtk/gtk.h>
00027 #include <gdk/gdk.h>
00028 #include <gdk/gdkkeysyms.h>
00029 
00030 #include "board.h"
00031 #include "ui_common.h"
00032 #include "ui.h"
00033 #include "menu.h"
00034 
00036 static GtkWidget *board_rowbox_real = NULL, *board_colbox_real = NULL;
00037 
00039 GdkColor board_colors[6];
00040 
00042 GdkColor board_highlight_colors[3];
00043 
00045 GdkColor board_buttonize_colors[2];
00046 
00048 GdkGC *board_gcs[3] = {NULL, NULL, NULL};
00049 
00051 GdkGC *board_highlight_gcs[3] = {NULL, NULL, NULL};
00052 
00054 GdkGC *board_buttonize_gcs[3] = {NULL, NULL, NULL};
00055 
00057 static GdkPixmap **pieces = NULL;
00058 
00060 // *sigh* I wish we had a _high-level_ widget set
00061 static GdkBitmap **piece_masks = NULL;
00062 
00064 static GdkPixmap *board_bgimage = NULL;
00065 
00067 gboolean board_suspended = FALSE;
00068 
00070 gboolean state_board_flipped = FALSE;
00071 
00073 char board_default_colors [9] = {215, 215, 215, 215, 215, 215, 0, 0, 0};
00074 
00075 static int cell_size, num_pieces;
00076 
00077 extern void ui_make_human_move (byte *move, int *rmove);
00078 
00079 void board_set_game_params ()
00080 {
00081         cell_size = opt_game->cell_size;
00082         num_pieces = opt_game->num_pieces;
00083 }
00084 
00085 void board_set_cell (int x, int y, byte val)
00086 {
00087         cur_pos.board[y * board_wid + x] = val;
00088 }
00089 
00090 void board_apply_refresh (byte *move, int *rmove)
00091 {
00092         int i, x, y;
00093         byte *board = cur_pos.board;
00094         int *rmove_tmp = NULL;
00095         
00096         if (move && game_get_render)
00097                 game_get_render (&cur_pos, move, &rmove);
00098         
00099         if (move)
00100         {
00101                 for (i=0; move[3*i] != -1; i++)
00102                 {
00103                         x = move[3*i]; y = move[3*i+1];
00104                         cur_pos.board[y * board_wid + x] = move [3*i+2];
00105                         board_refresh_cell (x, y);
00106                 }
00107         }
00108         
00109         if (rmove)
00110         {
00111                 for (i=0; rmove[3*i] != -1; i++)
00112                 {
00113                         x = rmove[3*i]; y = rmove[3*i+1];
00114                         cur_pos.render[y * board_wid + x] = rmove [3*i+2];
00115                         board_refresh_cell (x, y);
00116                 }
00117         }
00118 
00119         if (rmove_tmp)
00120         {
00121                 for (i=0; rmove[3*i] != -1; i++)
00122                 {
00123                         x = rmove_tmp[3*i]; y = rmove_tmp[3*i+1];
00124                         cur_pos.render[y * board_wid + x] = rmove_tmp[3*i+2];
00125                         board_refresh_cell (x, y);
00126                 }
00127         }
00128 
00129 }
00130 
00132 void board_refresh_cell_real (int x, int y, int real_x, int real_y)
00133 {
00134         GdkGC *gc;
00135         int parity = (board_wid * board_heit + x + y + 1) % 2;
00136         int thepiece;
00137         if (opt_quiet) return;
00138         gc = board_area->style->bg_gc[GTK_STATE_NORMAL];
00139         gdk_gc_set_clip_mask (gc, NULL);
00140         gdk_gc_set_clip_origin (gc, real_x * cell_size, real_y * cell_size);
00141         thepiece = cur_pos.board[y * board_wid + x] -1 + num_pieces * parity;
00142         if ((cur_pos.render[y * board_wid + x] & 0xFF) == RENDER_REPLACE)
00143                 thepiece = (cur_pos.render[y * board_wid + x] >> 8) -1 + num_pieces * parity;
00144         if ((cur_pos.board[y * board_wid + x] != 0
00145                         || (cur_pos.render[y * board_wid + x] & 0xFF) == RENDER_REPLACE)
00146                         && !board_suspended)
00147         {
00148                 /* FIXME: current impl is that if bgimage is set then bgcolor is irrelevant. Maybe we should change it so that bgimage is layered on top of bgcolor */
00149                 if (board_bgimage)
00150                 {
00151                         gdk_draw_pixmap (board_area->window,
00152                                         gc, (GdkDrawable *) board_bgimage,
00153                                         real_x * cell_size, real_y * cell_size,
00154                                         real_x * cell_size, real_y * cell_size,
00155                                         cell_size, cell_size
00156                                         );
00157                         gdk_gc_set_clip_mask (gc, piece_masks [thepiece]);
00158                         gdk_gc_set_clip_origin (gc, real_x * cell_size, real_y * cell_size);
00159                 }
00160                 gdk_draw_pixmap (board_area->window, 
00161                                 gc, (GdkDrawable *) pieces [thepiece],
00162                                 0, 0, real_x * cell_size, real_y * cell_size, 
00163                                 -1, -1);
00164         }
00165         else
00166         {
00167                 if (board_bgimage)
00168                 {
00169                         gdk_draw_pixmap (board_area->window,
00170                                         gc, (GdkDrawable *) board_bgimage,
00171                                         real_x * cell_size, real_y * cell_size,
00172                                         real_x * cell_size, real_y * cell_size,
00173                                         cell_size, cell_size
00174                                         );
00175                 }
00176                 else
00177                         gdk_draw_rectangle (board_area->window, board_gcs[parity], 1, 
00178                                         real_x * cell_size, real_y * cell_size,
00179                                         cell_size, cell_size);
00180         }
00181 
00182         if (cur_pos.render[y * board_wid + x] == RENDER_SHADE1                  
00183                         && cur_pos.board[y * board_wid + x] != 0
00184                         && !board_suspended)
00185         {
00186 #if GTK_MAJOR_VERSION > 1
00187                 GdkPixbuf *pixbuf;
00188                 int i;
00189                 guchar *pixels;
00190                 pixbuf = gdk_pixbuf_get_from_drawable (NULL, pieces[thepiece], NULL,
00191                                 0, 0, 0, 0, cell_size, cell_size);
00192                 pixels = gdk_pixbuf_get_pixels (pixbuf);
00193                 for (i=0; i<3*cell_size*cell_size; i++)
00194                         pixels[i] = (pixels[i] + 127)/2;
00195                 gdk_pixbuf_render_to_drawable (pixbuf, board_area->window, gc, 0, 0,
00196                                 real_x * cell_size, real_y * cell_size, cell_size, cell_size,
00197                                 GDK_RGB_DITHER_NONE, 0, 0);
00198                 // FIXME: find out the  correct way to free it
00199                 g_free (pixels);
00200                 g_free (pixbuf);
00201 #else
00202                 fprintf (stderr, "Warning: RENDER_SHADE currently unimplemented in gtk1 version\n");
00203 #endif
00204         }
00205 
00206         
00207         if (game_draw_cell_boundaries)
00208         {
00209                 if (real_x > 0)
00210                         gdk_draw_line (board_area->window, board_gcs[2],
00211                                 real_x * cell_size, real_y * cell_size,
00212                                 real_x * cell_size, (real_y + 1) * cell_size);
00213                 if (real_y > 0)
00214                         gdk_draw_line (board_area->window, board_gcs[2],
00215                                 real_x * cell_size, real_y * cell_size,
00216                                 (real_x + 1) * cell_size, real_y * cell_size);
00217         }
00218         
00219         // TODO: do HIGHLIGHT2 and 3 also
00220         if (cur_pos.render[y * board_wid + x] == RENDER_HIGHLIGHT1 && !board_suspended)
00221         {
00222                 int incr = game_draw_cell_boundaries ? 1 : 0;
00223                 gdk_draw_line (board_area->window, board_highlight_gcs[0],
00224                         real_x * cell_size + incr, real_y * cell_size + incr,
00225                         real_x * cell_size + incr, (real_y + 1) * cell_size - 1);
00226                 gdk_draw_line (board_area->window, board_highlight_gcs[0],
00227                         real_x * cell_size + incr, real_y * cell_size + incr,
00228                         (real_x + 1) * cell_size - 1, real_y * cell_size + incr);
00229                 gdk_draw_line (board_area->window, board_highlight_gcs[0],
00230                         (real_x + 1) * cell_size - 1, real_y * cell_size + incr,
00231                         (real_x + 1) * cell_size - 1, (real_y + 1) * cell_size - 1);
00232                 gdk_draw_line (board_area->window, board_highlight_gcs[0],
00233                         real_x * cell_size + incr, (real_y + 1) * cell_size - 1,
00234                         (real_x + 1) * cell_size - 1, (real_y + 1) * cell_size - 1);
00235         }
00236         
00237         if (cur_pos.render[y * board_wid + x] == RENDER_BUTTONIZE && !board_suspended)
00238         {
00239                 int incr = game_draw_cell_boundaries ? 1 : 0;
00240                 gdk_draw_line (board_area->window, board_buttonize_gcs[0],
00241                         real_x * cell_size + incr, real_y * cell_size + incr,
00242                         real_x * cell_size + incr, (real_y + 1) * cell_size - 1);
00243                 gdk_draw_line (board_area->window, board_buttonize_gcs[0],
00244                         real_x * cell_size + incr, real_y * cell_size + incr,
00245                         (real_x + 1) * cell_size - 1, real_y * cell_size + incr);
00246                 gdk_draw_line (board_area->window, board_buttonize_gcs[1],
00247                         (real_x + 1) * cell_size - 1, real_y * cell_size + incr,
00248                         (real_x + 1) * cell_size - 1, (real_y + 1) * cell_size - 1);
00249                 gdk_draw_line (board_area->window, board_buttonize_gcs[1],
00250                         real_x * cell_size + incr, (real_y + 1) * cell_size - 1,
00251                         (real_x + 1) * cell_size - 1, (real_y + 1) * cell_size - 1);
00252         }
00253         
00254 }
00255 
00257 void board_refresh_cell (int x, int y)
00258 {
00259         int real_x = (state_board_flipped ? board_wid - 1 - x : x);
00260         int real_y = (state_board_flipped ? y : board_heit - 1 - y);
00261         board_refresh_cell_real (x, y, real_x, real_y);
00262 }
00263 
00264 
00265 
00267 gboolean board_redraw (GtkWidget *widget, GdkEventExpose *event)
00268 {
00269         int x, y;
00270         int xmin = 0, ymin = 0, xmax = board_wid, ymax = board_heit;
00271         if (!opt_game) return TRUE;
00272         if (event)
00273         {
00274                 xmin = event->area.x / cell_size;
00275                 ymin = event->area.y / cell_size;
00276                 xmax = (event->area.x + event->area.width) / cell_size + 1;
00277                 ymax = (event->area.y + event->area.height) / cell_size + 1;
00278                 if (ymin < 0) ymin = 0;
00279                 if (xmax > board_wid) xmax = board_wid;
00280                 if (ymax > board_heit) ymax = board_heit;
00281         }
00282         for (x=xmin; x<xmax; x++)
00283                 for (y=ymin; y<ymax; y++)
00284                                 board_refresh_cell_real (
00285                                                 state_board_flipped ? board_wid - 1 - x : x, 
00286                                                 state_board_flipped ? y : (board_heit - 1 - y), 
00287                                                 x, y);
00288         return TRUE;
00289 }
00290 
00292 void board_redraw_all ()
00293 {
00294         board_redraw (main_window, NULL);
00295 }
00296 
00298 void board_show ()
00299 {
00300         if (!board_suspended) return;
00301         board_suspended = FALSE;
00302         board_redraw_all ();
00303 }
00304 
00306 void board_hide ()
00307 {
00308 //      GdkGC *def_gc = gdk_gc_new ((GdkWindow *)board_area->window);
00309         g_assert (opt_game);
00310         board_suspended = TRUE;
00311 /*      gdk_draw_rectangle ((GdkDrawable *)board_area->window, def_gc, TRUE, 0, 0, board_wid * cell_size, board_heit * cell_size);
00312         gdk_gc_destroy (def_gc);*/
00313         // FIXME: how do we get this screen to be the default background color?
00314         board_redraw_all();
00315 }
00316 
00317 static void board_get_cell (GdkEventButton *event, 
00318                 int *row, int *col, int *pixel_x, int *pixel_y)
00319 {
00320         *row = ((int)event->x / cell_size);
00321         *col = board_heit - 1 - ((int)event->y / cell_size);
00322         *pixel_x = (int)event->x;
00323         *pixel_y = board_heit * cell_size - 1 - (int)event->y;
00324         if (state_board_flipped) 
00325         {
00326                 *row = board_wid - 1 - *row;
00327                 *col = board_heit - 1 - *col;
00328                 *pixel_x = board_wid * cell_size - 1 - *pixel_x;
00329                 *pixel_y = board_heit * cell_size - 1 - *pixel_y;
00330         }
00331 }
00332 
00334 gint board_signal_handler (GtkWidget *widget, GdkEventButton *event, 
00335                 gpointer data)
00336 /* FIXME: clean up this function */
00337 {
00338         int row, col, pixel_x, pixel_y, type;
00339         int status = 0;
00340         byte *move = NULL;
00341         int *rmove = NULL;
00342         GtkboardEvent our_event;
00343         MoveInfo minfo = {NULL, NULL, NULL, NULL, NULL};
00344         if (!opt_game) return FALSE;
00345         if (ui_gameover) return FALSE;
00346         if (event->type == GDK_KEY_PRESS && 
00347                         !(((GdkEventKey *)event)->state & (GDK_CONTROL_MASK | GDK_MOD1_MASK)))
00348         {
00349                 if (!game_getmove_kb && !game_event_handler) return FALSE;
00350                 if (game_event_handler) 
00351                 {
00352                         our_event.type = GTKBOARD_KEY_PRESS;
00353                         our_event.key = ((GdkEventKey *)event)->keyval;
00354                         status = game_event_handler (&cur_pos, &our_event, &minfo);
00355                         move = minfo.move;
00356                         rmove = minfo.rmove;
00357                 }
00358                 else //(if game_getmove_kb)
00359                         status = game_getmove_kb (&cur_pos, 
00360                                 ((GdkEventKey *)event)->keyval, cur_pos.player, &move, &rmove);
00361         }
00362         else
00363         {
00364                 if (event->type == GDK_BUTTON_PRESS || event->type == GDK_BUTTON_RELEASE)
00365                 {
00366                         if (player_to_play != HUMAN)
00367                         {
00368                                 sb_message ("Machine's turn", FALSE);
00369                                 return FALSE;
00370                         }
00371                         if (!impl_check()) { sb_error ("Not yet implemented", TRUE); 
00372                                 return FALSE; }
00373                 }
00374                 if (!game_getmove && !game_event_handler) {return FALSE;}
00375                 board_get_cell (event, &row, &col, &pixel_x, &pixel_y);
00376                 if (!(row >= 0 && row < board_wid)) return FALSE;
00377                 if (!(col >= 0 && col < board_heit)) return FALSE;
00378                 switch (event->type)
00379                 {
00380                         case GDK_BUTTON_PRESS:
00381                                 type = GTKBOARD_BUTTON_PRESS; break;
00382                         case GDK_BUTTON_RELEASE:
00383                                 type = GTKBOARD_BUTTON_RELEASE; break;
00384                         case GDK_MOTION_NOTIFY:
00385                                 type = GTKBOARD_MOTION_NOTIFY; break;
00386                         case GDK_LEAVE_NOTIFY:
00387                                 type = GTKBOARD_LEAVE_NOTIFY; break;
00388                         default:
00389                                 return FALSE;
00390                 }
00391                 if (game_event_handler)
00392                 {
00393                         our_event.type = type;
00394                         our_event.x = row;
00395                         our_event.y = col;
00396                         our_event.pixel_x = pixel_x;
00397                         our_event.pixel_y = pixel_y;
00398                         status = game_event_handler (&cur_pos, &our_event, &minfo);
00399                         move = minfo.move;
00400                         rmove = minfo.rmove;
00401                 }
00402                 else
00403                         status = game_getmove (&cur_pos, row, col, 
00404                                         type, cur_pos.player, &move, &rmove);
00405                 if (status < 0)
00406                 {
00407                         gchar *tmpstr = minfo.help_message ? 
00408                                 g_strdup_printf ("Illegal move: %s", minfo.help_message) 
00409                                 : "Illegal move";
00410                         sb_error (tmpstr, FALSE);
00411                         g_free (tmpstr);
00412                 }
00413         }
00414         if (status <= 0)
00415         {
00416                 ui_make_human_move (NULL, rmove);
00417                 if (rmove)
00418                         menu_start_stop_game (NULL, MENU_START_GAME); 
00419                 return FALSE;
00420         }
00421         menu_start_stop_game (NULL, MENU_START_GAME); 
00422         ui_make_human_move (move, rmove);
00423         return FALSE;
00424 }
00425 
00427 void board_free ()
00428 {
00429         int i;
00430         if (pieces)
00431         {
00432                 /* It may be the case that the latter half of pieces[] is a copy
00433                    of the first half */
00434                 for (i=0; i<num_pieces; i++)
00435                 {
00436                         if (pieces[i] == pieces[i + num_pieces])
00437                                 pieces[i] = NULL;
00438                         if (piece_masks[i] == piece_masks[i + num_pieces])
00439                                 piece_masks[i] = NULL;
00440                 }
00441                 for (i=0; i<2*num_pieces; i++)
00442                 {
00443                         if (pieces[i]) 
00444                         {
00445                                 gdk_pixmap_unref (pieces[i]);
00446                                 pieces[i] = NULL;
00447                         }
00448                         if (piece_masks[i]) 
00449                         {
00450                                 gdk_pixmap_unref (piece_masks[i]);
00451                                 piece_masks[i] = NULL;
00452                         }
00453                 }
00454                 free (pieces);
00455                 free (piece_masks);
00456                 pieces = NULL;
00457                 piece_masks = NULL;
00458         }
00459         if (board_bgimage)
00460         {
00461                 free (board_bgimage);
00462                 board_bgimage = NULL;
00463         }
00464         if (board_rowbox_real)
00465         {
00466                 gtk_widget_destroy (board_rowbox_real);
00467                 board_rowbox_real = NULL;
00468         }
00469         if (board_colbox_real)
00470         {
00471                 gtk_widget_destroy (board_colbox_real);
00472                 board_colbox_real = NULL;
00473         }
00474 }
00475 
00476 static gchar *board_get_filerank_label_str (int label, int idx)
00477         // callers must free returned string
00478 {
00479         static gchar tempstr[8];
00480         int tmp = label & FILERANK_LABEL_TYPE_MASK;
00481         if (tmp == FILERANK_LABEL_TYPE_NUM) 
00482                 snprintf (tempstr, 8, " %d ", idx + 1);
00483         if (tmp == FILERANK_LABEL_TYPE_ALPHA) 
00484                 snprintf (tempstr, 8, " %c ", 'a' + idx);
00485         if (tmp == FILERANK_LABEL_TYPE_ALPHA_CAPS) 
00486                 snprintf (tempstr, 8, " %c ", 'A' + idx);
00487         return tempstr;
00488 }
00489 
00490 static gchar *board_get_file_label_str (int label, int idx)
00491 {
00492         if (label & FILERANK_LABEL_DESC) idx = board_wid - 1 - idx;
00493         return board_get_filerank_label_str (label, idx);
00494 }
00495 
00496 static gchar *board_get_rank_label_str (int label, int idx)
00497 {
00498         if (label & FILERANK_LABEL_DESC) idx = board_heit - 1 - idx;
00499         return board_get_filerank_label_str (label, idx);
00500 }
00501 
00502 static void board_color_init (char *color, GdkColor *gdkcolor, GdkGC **gc, GdkColormap *cmap, GtkWidget *board_area)
00503 {
00504         gdkcolor->red = 256 * (color ? color[0] : 215);
00505         gdkcolor->green = 256 * (color ? color[1] : 215);
00506         gdkcolor->blue = 256 * (color ? color[2] : 215);
00507         gdk_color_alloc (cmap, gdkcolor);
00508         if (*gc) 
00509                 gdk_gc_unref (*gc);
00510         *gc = gdk_gc_new(board_area->window);
00511         gdk_gc_set_foreground (*gc, gdkcolor);
00512 
00513 }
00514 
00516 void board_init ()
00517 {
00518         int i;
00519         GdkColormap *board_colormap;
00520         Game *game = opt_game;
00521         GdkGC *def_gc = gdk_gc_new ((GdkWindow *)board_area->window);
00522 //      GtkWidget *hbox, *vbox;
00523 
00524         if (!game)
00525         {
00526 #if GTK_MAJOR_VERSION == 1
00527                 gtk_drawing_area_size (GTK_DRAWING_AREA (board_area), 300, 300);
00528 #else
00529                 gtk_widget_set_size_request (GTK_WIDGET (board_area), 300, 300);
00530 #endif
00531                 gdk_draw_rectangle ((GdkDrawable *)board_area->window, def_gc, TRUE, 0, 0, 300, 300);
00532                 return;
00533         }
00534         
00535 #if GTK_MAJOR_VERSION == 1
00536         gtk_drawing_area_size (GTK_DRAWING_AREA (board_area), 
00537                         cell_size * board_wid, cell_size * board_heit);
00538 #else
00539         gtk_widget_set_size_request (GTK_WIDGET (board_area), 
00540                         cell_size * board_wid, cell_size * board_heit);
00541 #endif
00542         pieces = (GdkPixmap **) malloc (2 * num_pieces * sizeof (GdkPixmap *));
00543         g_assert (pieces);
00544         piece_masks = (GdkBitmap **) malloc (2 * num_pieces * sizeof (GdkBitmap *));
00545         g_assert (piece_masks);
00546         for (i=0; i<2*num_pieces; i++)
00547                 pieces[i] = NULL;
00548 
00549         if (game_file_label)
00550         {
00551                 board_rowbox_real = gtk_hbox_new (TRUE, 0);
00552                 gtk_box_pack_end (GTK_BOX (board_rowbox), board_rowbox_real, FALSE, FALSE, 0);
00553 #if GTK_MAJOR_VERSION == 1
00554                 gtk_widget_set_usize (GTK_WIDGET (board_rowbox_real),
00555                                 cell_size * board_wid, -1);
00556 #else
00557                 gtk_widget_set_size_request 
00558                         (GTK_WIDGET (board_rowbox_real), cell_size * board_wid, -1);
00559 #endif
00560                 for (i=0; i<board_wid; i++)
00561                         gtk_container_add (GTK_CONTAINER (board_rowbox_real), 
00562                                 gtk_label_new (board_get_file_label_str (game_file_label, i)));
00563                 gtk_widget_show_all (board_rowbox);
00564         }
00565         if (game_rank_label)
00566         {
00567                 board_colbox_real = gtk_vbox_new (TRUE, 0);
00568                 gtk_box_pack_start (GTK_BOX (board_colbox), board_colbox_real, FALSE, FALSE, 0);
00569 #if GTK_MAJOR_VERSION == 1
00570                 gtk_widget_set_usize (GTK_WIDGET (board_colbox_real),
00571                                 -1, cell_size * board_heit);
00572 #else
00573                 gtk_widget_set_size_request 
00574                         (GTK_WIDGET (board_colbox_real), -1, cell_size * board_heit);
00575 #endif
00576                 for (i=0; i<board_heit; i++)
00577                         gtk_container_add (GTK_CONTAINER (board_colbox_real), 
00578                                 gtk_label_new (board_get_rank_label_str 
00579                                         (game_rank_label, i)));
00580                 gtk_widget_show_all (board_colbox);
00581         }
00582         
00583         
00584         if (game->colors == NULL) game->colors = board_default_colors;
00585         board_colormap = gdk_colormap_get_system ();
00586 
00587         board_color_init (&game->colors[0], 
00588                         &board_colors[0], &board_gcs[0], board_colormap, board_area);
00589         board_color_init (&game->colors[3], 
00590                         &board_colors[1], &board_gcs[1], board_colormap, board_area);
00591         if (game_draw_cell_boundaries)
00592                 board_color_init (&game->colors[6], 
00593                                 &board_colors[2], &board_gcs[2], board_colormap, board_area);
00594         if (game_highlight_colors)
00595                 for (i=0; i<3; i++)
00596                         board_color_init (&game_highlight_colors[3*i],
00597                                         &board_highlight_colors[i], &board_highlight_gcs[i], 
00598                                         board_colormap, board_area);
00599         {
00600         char buttonize_colors [6] = {240, 240, 240, 128, 128, 128};
00601         for (i=0; i<2; i++)
00602         board_color_init (&buttonize_colors[3*i], &board_buttonize_colors[i],
00603                         &board_buttonize_gcs[i], board_colormap, board_area);
00604         }
00605 
00606         g_assert (num_pieces);
00607         for (i=0; i<2*num_pieces; i++)
00608         {
00609                 char **pixmap = NULL;
00610                 guchar *rgbbuf = NULL;
00611                 {
00612                         byte *colors = game->colors;
00613                         if (i >= num_pieces && colors[0] == colors[3] && colors[1] == colors[4] 
00614                                         && colors[2] == colors[5])
00615                         {
00616                                 pieces[i] = pieces[i-num_pieces];
00617                                 piece_masks[i] = piece_masks[i-num_pieces];
00618                                 continue;
00619                         }
00620                 }
00621                 if (game_get_rgbmap)
00622                 {
00623                         rgbbuf = game_get_rgbmap(1+i%num_pieces, i < num_pieces ? WHITE: BLACK);
00624                         if (rgbbuf)
00625                         {
00626                                 pieces[i] = gdk_pixmap_new (
00627                                                 board_area->window, cell_size, cell_size, -1);
00628                                 gdk_draw_rgb_image ((GdkDrawable *)pieces[i], 
00629                                                 def_gc, 0, 0, 
00630                                                 cell_size, cell_size, GDK_RGB_DITHER_MAX,
00631                                                 rgbbuf, cell_size * 3);
00632                         }
00633                         piece_masks[i] = NULL;
00634                 }                       
00635                 else 
00636                 {
00637                         if (game_get_pixmap)
00638                                 pixmap = game_get_pixmap
00639                                         (1+i%num_pieces, i < num_pieces ? WHITE: BLACK);
00640                         else 
00641                                 pixmap = game->pixmaps [i%num_pieces];
00642                         if (pixmap)
00643                         {
00644                                 pieces[i] = gdk_pixmap_colormap_create_from_xpm_d (NULL,
00645                                         board_colormap, &piece_masks[i], 
00646                                         board_colors + i / num_pieces, pixmap);
00647                                 assert (pieces[i]);
00648                         }
00649                         else piece_masks[i] = NULL;
00650                 }
00651         }
00652 
00653         if (game_bg_pixmap)
00654         {
00655                 board_bgimage = gdk_pixmap_colormap_create_from_xpm_d (NULL,
00656                         board_colormap, NULL, board_colors, game_bg_pixmap);
00657                 assert (board_bgimage);
00658         }
00659 
00660         gdk_gc_destroy (def_gc);
00661 }
00662 
00663