home *** CD-ROM | disk | FTP | other *** search
Text File | 1986-09-08 | 7.3 KB | 254 lines | [TEXT/MACA] |
- /*
- * anim.c - animation routines for Tablut.
- *
- */
-
- #include <quickdraw.h>
- #include <window.h>
- #include <event.h>
- #include <desk.h>
- #include <toolutil.h>
- #define watchCursor 4 /* Should be in toolutil.h but isn't */
- #include <memory.h>
- #include "tablut.h"
-
- #define DRAGTICKS 4 /* number of ticks per drag animation frame */
- #define SWEEPTICKS 4 /* ticks per sweep animation frame */
- #define VELOCITY 40 /* distance to cover per sweep frame */
- #define FRAC 32 /* fraction of a pixel error in sweep delta */
- #define BLINKCOUNT 3 /* # of times to blink a thing */
- #define BLINKTICKS 15 /* duration of 1/2 of a blink */
-
- #define CURSWHITE 129 /* Resource ID for the white cursor */
- #define CURSBLACK 130 /* Resource ID for the black cursor */
-
- CursHandle curswhite; /* the "it's white's move" cursor */
- CursHandle cursblack; /* the "it's black's move" cursor */
- CursHandle cursnorm; /* a placeholder for the normal cursor */
-
- /*
- * dragpiece() - given a piece index & an initial mouse position,
- * follow the mouse with the piece until the mouse button is released.
- */
- dragpiece(pidx, startp)
- int pidx; /* index of point to drag */
- Point *startp; /* starting mouse position */
- {
- Point startc; /* piece center starting point */
- Point minloc, maxloc; /* bounds of the tracking */
- int horzhold; /* if true, we are only moving vertically */
- Point adelta; /* absolute difference between two points */
- Point mtocent; /* offset from mouse to center of piece */
- Point loc; /* current mouse location */
- long nexttick; /* when to take another look at the mouse */
- struct pieceimage *p; /* pointer to the piece being dragged */
-
- p = &piece[pidx];
- horzhold = 0;
- startc.h = p->prevlook.bounds.left;
- startc.v = p->prevlook.bounds.top;
- AddPt(pass(p->class->etoc), &startc);
- mtocent.h = startc.h - startp->h; mtocent.v = startc.v - startp->v;
-
- if (!insetup) {
- findbounds(pidx, &minloc, &maxloc);
- gridtopoint(&minloc);
- gridtopoint(&maxloc);
- }
-
- nexttick = TickCount();
- while (StillDown()) {
- GetMouse(&loc);
- SystemTask(); /* give those desk accessories a moment */
- if (TickCount() >= nexttick) {
- nexttick += DRAGTICKS;
- AddPt(pass(mtocent), &loc);
- if (!insetup) {
- adelta.h = startc.h - loc.h;
- adelta.v = startc.v - loc.v;
- if (adelta.h < 0) adelta.h = -adelta.h;
- if (adelta.v < 0) adelta.v = -adelta.v;
- if ((horzhold && adelta.v <= p->class->etoc.v) ||
- (!horzhold && adelta.h <= p->class->etoc.h)) {
- horzhold = adelta.v > adelta.h;
- }
- if (horzhold) {
- /* constrain the vertical */
- loc.h = startc.h;
- if (loc.v > maxloc.v) loc.v = maxloc.v;
- if (loc.v < minloc.v) loc.v = minloc.v;
- } else {
- /* constrain the horizontal */
- loc.v = startc.v;
- if (loc.h > maxloc.h) loc.h = maxloc.h;
- if (loc.h < minloc.h) loc.h = minloc.h;
- }
- }
- drawpiece(pidx, loc.h, loc.v);
- }
- }
- }
-
- /*
- * sweeppiece() - sweep the given piece from its current position
- * to the given destination.
- */
- sweeppiece(pidx, destp)
- int pidx; /* index of the piece to move */
- Point *destp; /* where to move to */
- {
- struct pieceimage *p;
- Point delta; /* (signed) distance to cover (in some sense)*/
- Point absdelta; /* absolute distance (temporary) */
- int count; /* number of updates remaining in the move */
- Point loc; /* current location (as the move progresses) */
- Point nxtloc; /* next real location to move to */
- long nexttick; /* when to make another part of the move */
-
- p = &piece[pidx];
- if (!onscreen(p)) {
- drawpiece(pidx, destp->h, destp->v);
- return;
- }
- loc.h = p->prevlook.bounds.left + p->class->etoc.h;
- loc.v = p->prevlook.bounds.top + p->class->etoc.v;
- delta.h = (destp->h - loc.h) * FRAC; /* fixed-point total delta */
- delta.v = (destp->v - loc.v) * FRAC;
- absdelta.h = (delta.h < 0) ? -delta.h : delta.h;
- absdelta.v = (delta.v < 0) ? -delta.v : delta.v;
- if (absdelta.h > absdelta.v) count = absdelta.h / (VELOCITY * FRAC);
- else count = absdelta.v / (VELOCITY * FRAC);
- if (count > 0) {
- delta.h /= count; /* fixed-point delta per frame */
- delta.v /= count;
- loc.h *= FRAC;
- loc.v *= FRAC;
- nexttick = TickCount();
- while (count > 0) {
- SystemTask();
- if (TickCount() >= nexttick) {
- nexttick += SWEEPTICKS;
- --count;
- AddPt(pass(delta), &loc);
- nxtloc.h = loc.h / FRAC;
- nxtloc.v = loc.v / FRAC;
- drawpiece(pidx, nxtloc.h, nxtloc.v);
- }
- }
- }
- drawpiece(pidx, destp->h, destp->v);
- }
-
- /*
- * blinksquares() - given a list of board-squares, blink the set on and
- * off BLINKCOUNT times.
- */
- blinksquares(first, last)
- Point *first, *last; /* first and last squares (in an array) */
- {
- int i,j;
- Point *p;
- Rect r;
- long nexttick;
-
- nexttick = TickCount() + 1;
- while (TickCount() < nexttick) {
- SystemTask();
- }
- nexttick += BLINKTICKS;
- for (i = 0; i < BLINKCOUNT; ++i) {
- for (j = 0; j < 2; ++j) {
- for (p = first; p <= last; ++p) {
- gridtorect(p, &r);
- lightrect(&r);
- }
- while (TickCount() < nexttick) {
- SystemTask();
- }
- nexttick += BLINKTICKS;
- }
- }
- }
-
- /*
- * findbounds() - given a piece index and where to put the results,
- * find the grid-coordinate limits to the legal movement of that piece.
- */
- findbounds(pidx, minp, maxp)
- int pidx; /* index of the piece to examine */
- Point *minp, *maxp; /* where to put the min & max grid limits */
- {
- struct pieceimage *p;
- struct pieceimage *tp;
-
- p = &piece[pidx];
- SetPt(minp, -4, -4); SetPt(maxp, 4, 4); /* board boundaries */
- for (tp = &piece[0]; tp < &piece[NUMPIECES]; ++tp) {
- if (!onboard(tp) || tp == p) {
- continue;
- }
- if (tp->grid.h == p->grid.h) { /* same column (vertical) */
- if (tp->grid.v < p->grid.v) {
- if (tp->grid.v >= minp->v) minp->v = tp->grid.v + 1;
- } else {
- if (tp->grid.v <= maxp->v) maxp->v = tp->grid.v - 1;
- }
- } else if (tp->grid.v == p->grid.v) { /* same row (horizontal) */
- if (tp->grid.h < p->grid.h) {
- if (tp->grid.h >= minp->h) minp->h = tp->grid.h + 1;
- } else {
- if (tp->grid.h <= maxp->h) maxp->h = tp->grid.h - 1;
- }
- }
- }
- }
-
- /*
- * getcursors() - read the cursor resources for Tablut
- */
- getcursors()
- {
- curswhite = GetCursor(CURSWHITE);
- cursblack = GetCursor(CURSBLACK);
- cursnorm = (CursHandle) -1;
- }
-
- /*
- * fixcursor() - given the location of the mouse, set the cursor
- * appropriately
- * (assuming that the cursor hasn't been tampered with).
- * GetPort() is used here rather than FrontWindow() because this routine
- * can be called between events (when the newly-selected front window
- * may not yet be active).
- */
- fixcursor(wherep, keys)
- Point *wherep; /* where the mouse currently is */
- KeyMap keys; /* what keys are down (e.g., option or command keys) */
- {
- static CursHandle prevc = (CursHandle) -1; /* "normal" to start with */
- CursHandle newc; /* what the new cursor is */
- WindowPtr whichwindow; /* the currently active window */
-
- GetPort(&whichwindow);
- if (insetup || whichwindow != mywindow ||
- !PtInRect(pass(*wherep), &boardrect)) {
- newc = cursnorm;
- } else {
- if (blacksmove()) {
- newc = cursblack;
- } else {
- newc = curswhite;
- }
- }
- if (newc != prevc) {
- if (newc == cursnorm) {
- InitCursor();
- } else {
- HLock((Handle) newc);
- SetCursor(*newc);
- HUnlock((Handle) newc);
- }
- prevc = newc;
- }
- }
-