home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / compsrcs / misc / volume04 / crumble < prev    next >
Encoding:
Text File  |  1991-08-27  |  15.7 KB  |  615 lines

  1. Path: uunet!husc6!spdcc!ima!necntc!ncoast!allbery
  2. From: argv@island.UUCP (Dan Heller)
  3. Newsgroups: comp.sources.misc
  4. Subject: v04i012: *crumble* do interesting things to a Sun console
  5. Message-ID: <8807011715.AA08852@maui>
  6. Date: 3 Aug 88 23:01:32 GMT
  7. Sender: allbery@ncoast.UUCP
  8. Reply-To: argv@island.UUCP (Dan Heller)
  9. Lines: 603
  10. Approved: allbery@ncoast.UUCP
  11.  
  12. Posting-number: Volume 4, Issue 12
  13. Submitted-by: "Dan Heller" <argv@island.UUCP>
  14. Archive-name: crumble
  15.  
  16. #! /bin/sh
  17. echo extracting crumble.c via dumbshar
  18. sed 's/^X//' << \EOF > crumble.c
  19. X/*
  20. X * Crumble your screen.
  21. X *
  22. X * This program must be run on a SUN workstation only.  However, you can
  23. X * run it under either X or Suntools or on a bare sun monitor.  If you want
  24. X * to do all out war (see below) or use the -w option, you must use suntools.
  25. X *
  26. X * Written by:
  27. X *
  28. X *    Don Hatch        Dan Heller
  29. X *  splat@ucscb.ucsc.edu   island!argv@sun.com
  30. X *
  31. X * common usage:
  32. X *   subtle (rlogin somewhere else and run this)
  33. X *     crumble -hf
  34. X *     crumble -hf
  35. X *   fun and cute (let these run all night)
  36. X *     crumble -d
  37. X *     crumble -d -c
  38. X *   destructive (but fun)
  39. X *     crumble -C -c
  40. X *     crumble -f -d -c
  41. X *   all out WAR (and *LOTS* of fun! mwahahahaha!!)
  42. X *     crumble -C -f -m 200 | rsh other_sun crumble -C -f (suntools required)
  43. X *   (note: you should be able to _see_ the victim's console for best effect)
  44. X *
  45. X * \fBPlease send creative ideas for more usage to the authors!\fR
  46. X *
  47. X * compile: (triple click the next line and stuff it)
  48. X    cc -O -s crumble.c -lsuntool -lsunwindow -lpixrect -o crumble
  49. X *
  50. X * Command line options:
  51. X *
  52. X * -v        verbose
  53. X * -vf        flip chars vertically
  54. X * -hf        swap chars horizontally
  55. X * -s timeout    sleep between each char
  56. X * -a timeout   I forget what this is for
  57. X * -m number    max pixels to try to blow up
  58. X * -u useconds  before explosion, flash this fast
  59. X * -t        testing
  60. X * -b        start at bottom of screen and eat up
  61. X * -B        same, but grab the whole character
  62. X * -c        blow up letters on contact
  63. X * -f [N]    show target on fire button (default 1000)
  64. X * -d        drop characters without crumbling
  65. X *        note, if -c specified, chars drop until contact with something
  66. X * -w        just do stuff in a window
  67. X * -C        grab chunks of screen and obliterate them
  68. X * -r        reverse video for monochrome monitors
  69. X * -value    value is a color value for "off" pixels (color displays only)
  70. X * +value    value is a color value for "on" pixels (color displays only)
  71. X *
  72. X * If there are remaining args (one is checked), it is the display device name.
  73. X * For example, on a Sun3-110, you might want to use your greyscale screen,
  74. X * not your monochrome screen.  So, you could specify:
  75. X * crumble -255 +254 /dev/fb
  76. X * for color, or:
  77. X * crumble /dev/bwtwo0
  78. X * for monochrome.
  79. X *
  80. X * Obviously, you can't mix some of these arguments.  Trail and error
  81. X * is the best way to figure out which don't work.
  82. X *
  83. X * Environment variable: DEV_FB to default to a frame buffer.
  84. X */
  85. X#include <stdio.h>
  86. X#include <sys/file.h>
  87. X#include <suntool/sunview.h>
  88. X#include <suntool/canvas.h>
  89. X#include <math.h>
  90. X#include <signal.h>
  91. X#include <ctype.h>
  92. X#include <suntool/fullscreen.h>
  93. X
  94. X#define round(x) floor((x)+.5)
  95. X#define ison(x,y) (pr_get(pr,x,y) == ON)
  96. X#define isoff(x,y) (pr_get(pr,x,y) == OFF)
  97. X#define put(x,y,z) pr_put(pr,x,y,z)
  98. X#define swap(a,b) (a ^= b ^= a ^= b)
  99. X
  100. Xint ON = 1, OFF = 0;
  101. Xstruct pixrect *pr, *pr2;
  102. Xint MAX = 300;
  103. Xint n;
  104. Xstruct pr_pos A[10000];
  105. Xint verbose, sleepytime, usleepytime, alarmtime, testing, hflip, vflip,
  106. X    do_crumble, bottom_up, bottom_up_2, do_drop, do_chunks, do_window,
  107. X    do_focus, getting, putting;
  108. Xchar *device = NULL;
  109. X#define DEFAULT_DEVICE "/dev/fb"
  110. X
  111. X#define append(x,y) (n>=MAX ? 0 : (A[n].x=x,A[n].y=y,n++,1))
  112. X#define when break; case
  113. X#define otherwise break; default
  114. Xchar *getenv();
  115. X
  116. X#define XOR (PIX_SRC ^ PIX_DST)
  117. X
  118. Xmain(argc, argv)
  119. Xchar **argv;
  120. X{
  121. X    Canvas canvas;
  122. X    int catch();
  123. X    register int x,y,y2,y3;
  124. X    register int this, this3;
  125. X    int val, sum;
  126. X    register int a,b;
  127. X
  128. X    putting = !isatty(1);
  129. X    getting = !isatty(0);
  130. X
  131. X    while (*++argv) {
  132. X    if (!strcmp(*argv, "-v"))
  133. X        verbose = 1;
  134. X    else if (!strcmp(*argv, "-vf")) /* flip chars vertically */
  135. X        vflip = 1;
  136. X    else if (!strcmp(*argv, "-hf")) /* swap chars horizontally */
  137. X        hflip = 1;
  138. X    else if (!strcmp(*argv, "-s"))  /* be subtle, sleep between chars */
  139. X        sleepytime = atoi(*++argv);
  140. X    else if (!strcmp(*argv, "-a"))  /* i forget what this is for */
  141. X        alarmtime = atoi(*++argv);
  142. X    else if (!strcmp(*argv, "-m"))  /* max pixels to try to blow up */
  143. X        MAX = atoi(*++argv);
  144. X    else if (!strcmp(*argv, "-u"))  /* before explosion, flash this fast */
  145. X        usleepytime = atoi(*++argv);
  146. X    else if (!strcmp(*argv, "-t"))
  147. X        testing = 1;
  148. X    else if (!strcmp(*argv, "-b"))  /* start at the bottom and eat up */
  149. X        bottom_up = 1;
  150. X    else if (!strcmp(*argv, "-B"))  /* same, but grab the whole character */
  151. X        bottom_up_2 = 1;
  152. X    else if (!strcmp(*argv, "-c"))  /* blow up (crumble) on contact */
  153. X        do_crumble = 1;
  154. X    else if (!strcmp(*argv, "-f")) { /* show target on fire button */
  155. X        if (argv[1] && isdigit(argv[1][0]))
  156. X        do_focus = atoi(*++argv);
  157. X        else
  158. X            do_focus = 1000;
  159. X    }
  160. X    else if (!strcmp(*argv, "-d"))  /* drop characters without crumbling */
  161. X        do_drop = 1;  /* note, if -c specified, chars drop until contact */
  162. X    else if (!strcmp(*argv, "-w"))  /* just do stuff in a window */
  163. X        do_window = 1;
  164. X    else if (!strcmp(*argv, "-C"))  /* grab chunks of screen */
  165. X        do_chunks = 1;
  166. X    else if (!strcmp(*argv, "-r"))  /* reverse video for monochrome */
  167. X        OFF = !(ON = !ON);
  168. X    else if (**argv == '-' && isdigit(argv[0][1]))
  169. X        OFF = atoi(*argv + 1); /* set off pixels explicitly */
  170. X    else if (**argv == '+' && isdigit(argv[0][1]))
  171. X        ON = atoi(*argv + 1); /* set on pixels explicitly */
  172. X    else
  173. X        device = *argv; /* if other than /dev/fb */
  174. X    }
  175. X    if (!device && !(device = getenv("DEV_FB")))
  176. X    device = DEFAULT_DEVICE;
  177. X
  178. X    if (!(pr = pr_open(device)))
  179. X    exit(1); /* pr_open does a perror anyway! how stupid */
  180. X
  181. X    if (!(pr2 = mem_create(pr->pr_width, pr->pr_height, 1)))
  182. X    perror("mem_create"), exit(1);
  183. X
  184. X    pr_rop(pr2,0,0,pr2->pr_width, pr2->pr_height,PIX_NOT(PIX_DST),NULL,0,0);
  185. X
  186. X    if (do_window || putting) {
  187. X    int catch_events();
  188. X    Frame frame;
  189. X    Canvas canvas;
  190. X    Pixwin *pw;
  191. X    struct fullscreen *fs;
  192. X    int fd;
  193. X    setbuf(stdout, 0);
  194. X    frame = window_create(0, FRAME,
  195. X        WIN_X, 0, WIN_Y, 0,
  196. X        WIN_WIDTH, 30, WIN_HEIGHT, 30,
  197. X        0);
  198. X    canvas = window_create(frame, CANVAS,
  199. X        WIN_CONSUME_PICK_EVENTS,
  200. X        WIN_NO_EVENTS,
  201. X        WIN_MOUSE_BUTTONS,
  202. X        LOC_MOVE,
  203. X        0,
  204. X        WIN_EVENT_PROC, catch_events,
  205. X        0);
  206. X    pw = canvas_pixwin(canvas);
  207. X    fd = (int) window_get(canvas, WIN_FD);
  208. X    if (alarmtime)
  209. X        alarm(alarmtime);
  210. X    win_grabio(fd);
  211. X    if (getenv("OFF")) {
  212. X        Cursor cursor = window_get(canvas, WIN_CURSOR);
  213. X        cursor_set(cursor, CURSOR_SHOW_CURSOR, 0, 0);
  214. X        window_set(canvas, WIN_CURSOR, cursor, 0);
  215. X    }
  216. X    window_main_loop(frame);
  217. X    win_releaseio(fd);
  218. X    exit(0);
  219. X    }
  220. X    srandom(getpid());
  221. X    if (getting) {
  222. X    int ID, x, y;
  223. X    while (scanf("%d %d %d", &ID, &x, &y) == 3)
  224. X        do_event(ID,x,y);
  225. X    } else if (bottom_up) {
  226. X    for (y = pr->pr_height-1; y >= 0; --y) {
  227. X        n = 0;
  228. X        for (x = 0; x < pr->pr_width; ++x)
  229. X        if (ison(x,y)) {
  230. X            A[n].x = x;
  231. X            A[n].y = y;
  232. X            n++;
  233. X        }
  234. X        crumble(pr);
  235. X    }
  236. X    } else if (bottom_up_2)
  237. X    while (1)
  238. X    for (y = pr->pr_height-1; y >= 0; y -= 2)
  239. X        for (x = 0; x < pr->pr_width; ++x)
  240. X        do_letter(x,y);
  241. X    else
  242. X    while (1) {
  243. X        y = random()% (pr->pr_height-1);
  244. X        x = random()% (pr->pr_width-1);
  245. X        do_letter(x,y);
  246. X    }
  247. X}
  248. X
  249. Xdo_letter(x,y)
  250. Xregister int x,y;
  251. X{
  252. X    if (testing) {
  253. X    printf("%d ", pr_get(pr,x,y));
  254. X    return;
  255. X    }
  256. X    n = 0;
  257. X    if (ison(x,y) && fetch(pr,x,y) == 1) {
  258. X    unfetch();
  259. X    if (verbose)
  260. X        printf("%d ", n);
  261. X    putlist();
  262. X    if (sleepytime)
  263. X        sleep(sleepytime);
  264. X    } else
  265. X        unfetch();
  266. X}
  267. X
  268. Xint edge_ok = 1;
  269. X/*
  270. X * return 1 on success (got something)
  271. X * 0 if got nothing,
  272. X * -1 if went off edge
  273. X */
  274. Xfetch(pr,x,y)
  275. Xstruct pixrect *pr;
  276. X{
  277. X    if (!ison(x,y))
  278. X    return 0;
  279. X    if (do_chunks && ison(x,y))
  280. X    while (ison(x,y+1))
  281. X        y++;
  282. X    return _fetch(x,y);
  283. X}
  284. X/*
  285. X * return 1 if stayed on screen, -1 if went off screen or got too big.
  286. X */
  287. X_fetch(x,y)
  288. Xregister int x,y;
  289. X{
  290. X    int i;
  291. X    char ind[8];
  292. X    static struct pr_pos dirs[8] = {
  293. X    {-1,0}, {1,0}, {0,-1}, {0,1}, {-1,-1}, {-1,1}, {1,-1}, {1,1}
  294. X    };
  295. X    if (pr_get(pr,x,y) == PIX_ERR)
  296. X    return edge_ok ? 0 : -1;
  297. X    if (isoff(x,y) || !pr_get(pr2, x,y))
  298. X    return 0;
  299. X    for (i = 1; i < 8; ++i)
  300. X    ind[i] = i;
  301. X    if (append(x,y)) {
  302. X    pr_put(pr2,x,y,0);
  303. X    if (do_chunks) {
  304. X        register int i1, i2;
  305. X        for (i = 1; i <= 5; ++i) {
  306. X            i1 = random() % 4;
  307. X            i2 = random() % 4;    /* scramble first four directions */
  308. X        if (i1 != i2)
  309. X            swap(ind[i1], ind[i2]);
  310. X        }
  311. X    }
  312. X    for (i = 0; i < 8; ++i)
  313. X        if (_fetch(x+dirs[ind[i]].x, y+dirs[ind[i]].y) == -1)
  314. X        return -1;
  315. X    return 1;
  316. X    } else
  317. X    return do_chunks ? 1 : -1; /* if do_chunks, then return the chunk */
  318. X}
  319. Xunfetch()
  320. X{
  321. X    int i;
  322. X    for (i=0; i < n; ++i) {
  323. X    pr_put(pr2, A[i].x,A[i].y,1);
  324. X    }
  325. X}
  326. Xputlist()
  327. X{
  328. X    int i;
  329. X    int x,y;
  330. X    struct pr_pos dest, drop();
  331. X    struct pixrect *make_letter_pr();
  332. X    struct pixrect *p = make_letter_pr(&x, &y);
  333. X    if (verbose)
  334. X    dump(p);
  335. X    if (do_focus) {
  336. X    focus(pr, A[0].x, A[0].y);
  337. X    buzz(pr, p, x, y);
  338. X    }
  339. X    if (hflip || vflip)
  340. X    reverse(pr, p, x, y, p->pr_width, p->pr_height);
  341. X    if (do_drop) {
  342. X        dest = drop(pr, p, x, y, p->pr_width, p->pr_height);
  343. X    for (i = 0; i < n; ++i)
  344. X        A[i].y += dest.y - y;
  345. X    }
  346. X    if (do_crumble)
  347. X    crumble(pr);
  348. X    pr_destroy(p);
  349. X}
  350. X#define max4(a,b,c,d) max(max(max(a,b),c),d)
  351. X#define min4(a,b,c,d) min(min(min(a,b),c),d)
  352. X
  353. Xbuzz(pr, p, off_x, off_y)
  354. Xstruct pixrect *pr, *p;
  355. Xregister int off_x,off_y;
  356. X{
  357. X    int size = max4(off_x, pr->pr_width-off_x, off_y, pr->pr_height-off_x);
  358. X    size = min(size, do_focus);
  359. X    if (p)
  360. X    for (; size >= 0; --size) {
  361. X    pr_rop(pr, off_x, off_y, p->pr_width, p->pr_height, PIX_NOT(PIX_DST),
  362. X                            NULL, 0,0);
  363. X    if (usleepytime)
  364. X        usleep(usleepytime);
  365. X    pr_rop(pr, off_x, off_y, p->pr_width, p->pr_height, PIX_NOT(PIX_DST),
  366. X                            NULL, 0,0);
  367. X    if (usleepytime)
  368. X        usleep(usleepytime);
  369. X    }
  370. X}
  371. Xfocus(pr, x,y)
  372. Xstruct pixrect *pr;
  373. Xregister int x,y;
  374. X{
  375. X    int size = max4(x, pr->pr_width-x, y, pr->pr_height-y);
  376. X    size = min(size, do_focus);
  377. X    for (; size >= 0; --size) {
  378. X    frame(pr, x-size, y-size, x+size, y+size, PIX_NOT(PIX_DST));
  379. X    frame(pr, x-size, y-size, x+size, y+size, PIX_NOT(PIX_DST));
  380. X    }
  381. X}
  382. Xframe(pr, xmin, ymin, xmax, ymax, op, value)
  383. Xstruct pixrect *pr;
  384. Xregister int xmin, xmax, ymin, ymax, op, value;
  385. X{
  386. X    pr_vector(pr, xmin, ymin, xmax, ymin, op, 1);
  387. X    pr_vector(pr, xmax, ymin, xmax, ymax, op, 1);
  388. X    pr_vector(pr, xmax, ymax, xmin, ymax, op, 1);
  389. X    pr_vector(pr, xmin, ymax, xmin, ymin, op, 1);
  390. X}
  391. X/*
  392. X * Make a small pixrect containing the points currently stored in the A array.
  393. X * Coordinates of the new pixrect with respect to the global pr are returned
  394. X * in *x, *y.
  395. X */
  396. Xstruct pixrect *
  397. Xmake_letter_pr(x, y)
  398. Xint *x, *y;
  399. X{
  400. X    int i;
  401. X    struct pr_pos dest, drop();
  402. X    register int minx,maxx,miny,maxy;
  403. X    struct pixrect *p;
  404. X    minx=maxx=A[0].x;
  405. X    miny=maxy=A[0].y;
  406. X    for (i=1; i < n; ++i) {
  407. X    minx = min(minx, A[i].x);
  408. X    miny = min(miny, A[i].y);
  409. X    maxx = max(maxx, A[i].x);
  410. X    maxy = max(maxy, A[i].y);
  411. X    }
  412. X    *x = minx-1;
  413. X    *y = miny-1;
  414. X    p = mem_create(maxx-minx+3, maxy-miny+3, pr->pr_depth);
  415. X    for (i=0; i < n; ++i) {
  416. X    pr_put(p, A[i].x - *x, A[i].y - *y, ON);
  417. X    }
  418. X    return p;
  419. X}
  420. Xcrumble(pr)
  421. Xstruct pixrect *pr;
  422. X{
  423. X    int moved, i;
  424. X    do {
  425. X    moved = 0;
  426. X    for (i = 0; i < n; ++i) {
  427. X        struct pr_pos pos, newpos;
  428. X        pos = newpos = A[i];
  429. X        if (random() % 30 && isoff(pos.x, pos.y+1))
  430. X        newpos.y = pos.y+1;
  431. X        else
  432. X        switch(random() % 2) {
  433. X            when 0:
  434. X            if (isoff(pos.x+1, pos.y+1)) {
  435. X                newpos.x = pos.x+1;
  436. X                newpos.y = pos.y+1;
  437. X            } else goto defaul;
  438. X            when 1:
  439. X            if (isoff(pos.x-1, pos.y+1)) {
  440. X                newpos.x = pos.x-1;
  441. X                newpos.y = pos.y+1;
  442. X            } else goto defaul;
  443. X            otherwise:
  444. X            defaul:
  445. X            if (isoff(pos.x, pos.y+1))
  446. X                newpos.y = pos.y+1;
  447. X        }
  448. X        if (newpos.x != pos.x || newpos.y != pos.y) {
  449. X        moved = 1;
  450. X        if (random() % 30) {
  451. X            pr_put(pr, pos.x, pos.y, OFF);
  452. X            pr_put(pr, newpos.x, newpos.y, ON);
  453. X            A[i] = newpos;
  454. X        }
  455. X        }
  456. X    }
  457. X    } while (moved);
  458. X}
  459. Xreverse(pr,p,x,y,w,h)
  460. Xstruct pixrect *pr, *p;
  461. X{
  462. X    pr_rop(pr,x,y,w,h,XOR,p,0,0);
  463. X    pr_reverse_rop(pr,x,y,w,h,XOR,p,0,0);
  464. X}
  465. Xpr_reverse_rop(dpr,dx,dy,w,h,op,spr,sx,sy)
  466. Xstruct pixrect *spr, *dpr;
  467. X{
  468. X    int x,y;
  469. X    for (y=0;y<h;++y)
  470. X    for (x=0;x<w;++x)
  471. X        pr_rop(dpr, dx+x, dy+y, 1, 1, op, spr, sx + (vflip? w-1-x : x),
  472. X                           sy + (hflip? h-1-y : y));
  473. X}
  474. Xstruct pr_pos
  475. Xdrop(pr,p,x,y,w,h)
  476. Xstruct pixrect *pr, *p;
  477. X{
  478. X    register int X,Y;
  479. X    struct pr_pos dest;
  480. X    while (canfall(pr,p,x,y+1,w,h)) {
  481. X    for (Y=h-1; Y >= 0; Y--)
  482. X        for (X=0; X < w; X++)
  483. X        if (pr_get(p, X, Y) == ON) {
  484. X            pr_put(pr, X+x, Y+y, OFF);
  485. X            pr_put(pr, X+x, Y+y+1, ON);
  486. X        }
  487. X    y++;
  488. X    }
  489. X    dest.x = x;
  490. X    dest.y = y;
  491. X    return dest;
  492. X}
  493. Xcanfall(pr,p,x,y,w,h)
  494. Xstruct pixrect *pr, *p;
  495. X{
  496. X    int i,j;
  497. X    for (j=0;j<h;++j)
  498. X    for (i=0;i<w;++i)
  499. X    if (pr_get(p,i,j) == ON && pr_get(p,i,j+1) != ON)
  500. X        if (pr_get(pr,x+i,y+j) != OFF)
  501. X        return 0;
  502. X    return 1;
  503. X}
  504. Xdump(p)
  505. Xstruct pixrect *p;
  506. X{
  507. X    int x,y;
  508. X    printf("size=%d,%d\n",p->pr_width, p->pr_height);
  509. X    puts("=================================");
  510. X    for (y=0; y < p->pr_height; ++y) {
  511. X        for (x=0; x < p->pr_width; ++x)
  512. X        printf("%c ", (pr_get(p,x,y) == ON) ? '*' : ' ');
  513. X    puts("");
  514. X    }
  515. X    puts("=================================");
  516. X}
  517. Xshoot(x,y)
  518. Xint *x, *y;
  519. X{
  520. X    while (1) {
  521. X    if (!isoff(*x,*y))
  522. X        break;
  523. X    if (verbose)
  524. X        pr_put(pr,*x,*y,ON);
  525. X    --*x;
  526. X    if (!isoff(*x,*y))
  527. X        break;
  528. X    if (verbose)
  529. X        pr_put(pr,*x,*y,ON);
  530. X    --*y;
  531. X    }
  532. X}
  533. Xcatch_events(canvas, event, data)
  534. Xregister Canvas canvas;
  535. Xregister Event *event;
  536. X{
  537. X    register int ID = event->ie_code;
  538. X    register Pixrect *newicon = NULL;
  539. X    int fd = (int) window_get(canvas, WIN_FD);
  540. X    int x,y;
  541. X    static start_fast;
  542. X
  543. X    if (!event_is_down(event) && ID != LOC_MOVE)
  544. X    return;
  545. X    x = event_x(event);
  546. X    y = event_y(event);
  547. X    if (getenv("Y"))
  548. X    y += atoi(getenv("Y"));
  549. X    else
  550. X        y += 18;
  551. X    if (getenv("X"))
  552. X    x += atoi(getenv("X"));
  553. X    else
  554. X        x += 5;
  555. X
  556. X    if (ID != MS_RIGHT && putting) {
  557. X    send(ID,x,y);
  558. X    return;
  559. X    }
  560. X    if (verbose)
  561. X        printf("Got %d (%d,%d)\n", ID,x,y);
  562. X    win_releaseio(fd);
  563. X    do_event(ID,x,y);
  564. X    if (ID != MS_RIGHT)
  565. X        win_grabio(fd);
  566. X}
  567. Xsend(ID, x,y)
  568. X{
  569. X    printf("%d %d %d\n", ID, x,y);
  570. X}
  571. Xdo_event(ID,x,y)
  572. X{
  573. X    if (verbose)
  574. X        printf("Got %d (%d,%d)\n", ID,x,y);
  575. X    switch(ID) {
  576. X    when LOC_MOVE:  unshow_target();
  577. X            show_target(x,y);
  578. X            shoot(&x, &y);
  579. X    when MS_LEFT:
  580. X            unshow_target();
  581. X            if (putting)
  582. X                send(x,y);
  583. X            else {
  584. X                shoot(&x,&y);
  585. X                do_letter(x,y);
  586. X            }
  587. X    }
  588. X}
  589. Xshort bullseye_image[] = {
  590. X/* Format_version=1, Width=16, Height=16, Depth=1, Valid_bits_per_item=16
  591. X */
  592. X    0x07C0,0x1830,0x2008,0x4384,0x4C64,0x8822,0x9012,0x9112,
  593. X    0x9012,0x8822,0x4C64,0x4384,0x2008,0x1830,0x07C0,0x0000
  594. X};
  595. Xmpr_static(bullseye, 16, 16, 1, bullseye_image);
  596. Xint prevx = -1, prevy = -1;
  597. Xint target_on = 0;
  598. Xshow_target(x,y)
  599. X{
  600. X    if (target_on)
  601. X    unshow_target();
  602. X    pr_rop(pr, x-7,y-7,bullseye.pr_width,bullseye.pr_height,XOR,&bullseye,0,0);
  603. X    prevx = x;
  604. X    prevy = y;
  605. X    target_on = 1;
  606. X}
  607. Xunshow_target()
  608. X{
  609. X    if (target_on)
  610. X    pr_rop(pr, prevx-7,prevy-7,bullseye.pr_width,bullseye.pr_height,XOR,&bullseye,0,0);
  611. X    target_on = 0;
  612. X}
  613. EOF
  614. exit 0
  615.