/* board.c drawing, board setup */ /* * xcheckers: a point and click checkerboard * (C): 1999, 2000, 2003 Peter Chiocchetti */ #include #include #include #include #include #include #include "xcheckers.h" #include "board.h" #include "status.h" #include "sprite.h" #include "resource.h" static int numbered; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * General Drawing * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* draw a single node in the grid */ void drawCell(int x, int y) { if (board[x][y].colour > n) { XCopyArea(dpy, scene, fpix, gc, width, 0, width, height, width * x, height * y); XSetClipOrigin(dpy, tgc, (x - board[x][y].colour) * width, y * height); XCopyArea(dpy, scene, fpix, tgc, board[x][y].colour * width, 0, width, height, width * x, height * y); } else { XCopyArea(dpy, scene, fpix, gc, board[x][y].colour * width, 0, width, height, width * x, height * y); } XCopyArea(dpy, fpix, win, gc, width * x, height * y, width, height, width * x, height * y); } /* fully redraw the main window */ void repaint(void) { int x, y; { for (y = 0; y < cells; y++) for (x = 0; x < cells; x++) drawCell(x, y); XFlush(dpy); } } /* redraw an exposed part of the main window */ void paint(XExposeEvent * e) { if (numbered) { repaint(); numbered = 0; return; } XCopyArea(dpy, fpix, win, gc, e->x, e->y, e->width, e->height, e->x, e->y); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * A Grid * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* put board state into backup array to later recall */ void saveBoard(void) { int x, y; for (y = 0; y < cells; y++) for (x = 0; x < cells; x++) { saved[x][y].colour = board[x][y].colour; saved[x][y].number = board[x][y].number; } } /* prepare an empty board with numbered nodes */ void initBoard(int gametype) { int x, y, r, s; int num = 0; r = gametype == ITALIAN ? 1 : 0; // 90 degrees rotation s = gametype == MAFIERZ || gametype == RUSSIAN ? 1 : 0; // 180 degrees rot. //printf("XXX g=%d, r=%d, s=%d\n", gametype, r, s); fpix = XCreatePixmap(dpy, win, board_width, board_height, DefaultDepth(dpy, screen)); for (y = 0; y < cells; y++) { for (x = 0; x < cells; x++) { if ((x + y) % 2 == r) { // ITALIAN y/n board[x][y].number = 0; board[x][y].colour = o; } else { board[x][y].colour = n; if (r) // RUSSIAN, ITALIAN, XXX untested! continue; else if (s) // MAFIERZ, numbered l2r board[cells-x-y%2*2][y].number = direction == NORTH ? cells * cells / 2 - num : num + 1; else // ENGLISH, numbered r2l board[x][y].number = direction == NORTH ? cells * cells / 2 - num : num + 1; num++; } XCopyArea(dpy, scene, fpix, gc, board[x][y].colour * width, 0, width, height, width * x, height * y); } } saveBoard(); repaint(); } /* draw the nodes that changed after a move from engine */ void freshenBoard(void) { int x, y; if (numbered) { numbered = 0; repaint(); } else { for (y = 0; y < cells; y++) for (x = 0; x < cells; x++) if (board[x][y].colour != saved[x][y].colour) drawCell(x, y); } saveBoard(); XFlush(dpy); } /* turn the board to the other players view */ void swapBoard(int orientation) { int x, y; if (orientation == direction) return; direction = orientation; for (y = 0; y < cells; y++) { for (x = 0; x < cells; x++) { board[x][y].colour = saved[cells - x - 1][cells - y - 1].colour; board[x][y].number = saved[cells - x - 1][cells - y - 1].number; } } freshenBoard(); } /* change between english, italian and polish board */ void changeBoard(int gametype) { XSizeHints *sizehints; static int lastgame = 0; int n; n = gametype == INTERNL ? 10 : 8; if (cells == n && lastgame == gametype) return; cells = n; lastgame = gametype; if ((sizehints = XAllocSizeHints()) == NULL) { fprintf(stderr, "%s: Error, could not allocate size hints\n", progname); exit(1); } sizehints->width = sizehints->min_width = sizehints->max_width = board_width; sizehints->height = sizehints->min_height = sizehints->max_height = board_height + status_height; sizehints->flags = PSize | PMinSize | PMaxSize; initBoard(gametype); XResizeWindow(dpy, win, board_width, board_height + status_height); resizeStatus(); XSetWMNormalHints(dpy, win, sizehints); } /* draw the numbers on the nodes */ void drawNumbers(void) { int x, y; char c[4]; if (!numbered) { for (y = 0; y < cells; y++) { for (x = 0; x < cells; x++) { //if ((x + y) % 2 == 1) { if (board[x][y].number) { if (numbered) drawCell(x, y); else { sprintf(c, "%2d ", board[x][y].number); XDrawImageString(dpy, win, gc, width * x + 2, height * (y + 1) - font->descent - 1, c, strlen(c)); } } } } numbered = 1; } else { repaint(); numbered = 0; } }