/* sprite.c moving pieces */ /* * xcheckers: a point and click checkerboard * (C): 1999, 2000 Peter Chiocchetti */ #include #include #include "xcheckers.h" #include "board.h" #include "sprite.h" #define TGCMASK (GCBackground | GCForeground | GCGraphicsExposures) int sx, sy; /* drag start position, nodes */ int cx, cy; /* current position, pixels */ int picked; /* 1 while moving a sprite */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Animated Pieces * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* prepare GC and pixmap for moving sprites across the board */ void initSprite(void) { bpix = XCreatePixmap(dpy, win, width, height, DefaultDepth(dpy, screen)); tgc = XCreateGC(dpy, win, 0, NULL); XCopyGC(dpy, gc, TGCMASK, tgc); XSetClipMask(dpy, tgc, clip); } /* draw a stone, while it flies over the board, no flicker */ void drawSprite(XMotionEvent * e) { int dx, dy; /* delta, pixels */ int px = cx; /* previous position, pixels */ int py = cy; if (!picked) return; cx = e->x - width / 2; cy = e->y - height / 2; dx = cx - px; dy = cy - py; /* this paints the same thing twice , i. e. the region where the new position of the stone overlaps the rectangle around the old position - probably use a third gc with clip inverted */ /* restore board */ XCopyArea(dpy, fpix, bpix, gc, px, py, width, height, 0, 0); XSetClipOrigin(dpy, tgc, dx - width * saved[sx][sy].colour, dy); XCopyArea(dpy, scene, bpix, tgc, width * saved[sx][sy].colour, 0, width, height, dx, dy); XCopyArea(dpy, bpix, win, gc, 0, 0, width, height, px, py); /* paint stone */ XSetClipOrigin(dpy, tgc, cx - width * saved[sx][sy].colour, cy); XCopyArea(dpy, scene, win, tgc, saved[sx][sy].colour * width, 0, width, height, cx, cy); } /* pick a stone from the board */ void pickSprite(XButtonEvent * e) { sx = e->x / width; sy = e->y / height; board[sx][sy].colour = n; drawCell(sx, sy); picked = 1; cx = e->x - width / 2; cy = e->y - height / 2; drawSprite((XMotionEvent *) e); } /* drop a stone to the board */ void dropSprite(XButtonEvent * e) { int tx, ty; /* current position, nodes */ if (!picked) return; XCopyArea(dpy, fpix, win, gc, cx, cy, width, height, cx, cy); tx = e->x / width; ty = e->y / height; board[tx][ty].colour = saved[sx][sy].colour; saveBoard(); drawCell(tx, ty); XFlush(dpy); picked = 0; } /* put a stone back to its previous place while its moved */ void cancelSprite(void) { if (!picked) return; XCopyArea(dpy, fpix, win, gc, cx, cy, width, height, cx, cy); board[sx][sy].colour = saved[sx][sy].colour; saveBoard(); drawCell(sx, sy); picked = 0; }