v04i012: *crumble* do interesting things to a Sun console
Dan Heller
argv at island.UUCP
Thu Aug 4 09:01:32 AEST 1988
Posting-number: Volume 4, Issue 12
Submitted-by: "Dan Heller" <argv at island.UUCP>
Archive-name: crumble
#! /bin/sh
echo extracting crumble.c via dumbshar
sed 's/^X//' << \EOF > crumble.c
X/*
X * Crumble your screen.
X *
X * This program must be run on a SUN workstation only. However, you can
X * run it under either X or Suntools or on a bare sun monitor. If you want
X * to do all out war (see below) or use the -w option, you must use suntools.
X *
X * Written by:
X *
X * Don Hatch Dan Heller
X * splat at ucscb.ucsc.edu island!argv at sun.com
X *
X * common usage:
X * subtle (rlogin somewhere else and run this)
X * crumble -hf
X * crumble -hf
X * fun and cute (let these run all night)
X * crumble -d
X * crumble -d -c
X * destructive (but fun)
X * crumble -C -c
X * crumble -f -d -c
X * all out WAR (and *LOTS* of fun! mwahahahaha!!)
X * crumble -C -f -m 200 | rsh other_sun crumble -C -f (suntools required)
X * (note: you should be able to _see_ the victim's console for best effect)
X *
X * \fBPlease send creative ideas for more usage to the authors!\fR
X *
X * compile: (triple click the next line and stuff it)
X cc -O -s crumble.c -lsuntool -lsunwindow -lpixrect -o crumble
X *
X * Command line options:
X *
X * -v verbose
X * -vf flip chars vertically
X * -hf swap chars horizontally
X * -s timeout sleep between each char
X * -a timeout I forget what this is for
X * -m number max pixels to try to blow up
X * -u useconds before explosion, flash this fast
X * -t testing
X * -b start at bottom of screen and eat up
X * -B same, but grab the whole character
X * -c blow up letters on contact
X * -f [N] show target on fire button (default 1000)
X * -d drop characters without crumbling
X * note, if -c specified, chars drop until contact with something
X * -w just do stuff in a window
X * -C grab chunks of screen and obliterate them
X * -r reverse video for monochrome monitors
X * -value value is a color value for "off" pixels (color displays only)
X * +value value is a color value for "on" pixels (color displays only)
X *
X * If there are remaining args (one is checked), it is the display device name.
X * For example, on a Sun3-110, you might want to use your greyscale screen,
X * not your monochrome screen. So, you could specify:
X * crumble -255 +254 /dev/fb
X * for color, or:
X * crumble /dev/bwtwo0
X * for monochrome.
X *
X * Obviously, you can't mix some of these arguments. Trail and error
X * is the best way to figure out which don't work.
X *
X * Environment variable: DEV_FB to default to a frame buffer.
X */
X#include <stdio.h>
X#include <sys/file.h>
X#include <suntool/sunview.h>
X#include <suntool/canvas.h>
X#include <math.h>
X#include <signal.h>
X#include <ctype.h>
X#include <suntool/fullscreen.h>
X
X#define round(x) floor((x)+.5)
X#define ison(x,y) (pr_get(pr,x,y) == ON)
X#define isoff(x,y) (pr_get(pr,x,y) == OFF)
X#define put(x,y,z) pr_put(pr,x,y,z)
X#define swap(a,b) (a ^= b ^= a ^= b)
X
Xint ON = 1, OFF = 0;
Xstruct pixrect *pr, *pr2;
Xint MAX = 300;
Xint n;
Xstruct pr_pos A[10000];
Xint verbose, sleepytime, usleepytime, alarmtime, testing, hflip, vflip,
X do_crumble, bottom_up, bottom_up_2, do_drop, do_chunks, do_window,
X do_focus, getting, putting;
Xchar *device = NULL;
X#define DEFAULT_DEVICE "/dev/fb"
X
X#define append(x,y) (n>=MAX ? 0 : (A[n].x=x,A[n].y=y,n++,1))
X#define when break; case
X#define otherwise break; default
Xchar *getenv();
X
X#define XOR (PIX_SRC ^ PIX_DST)
X
Xmain(argc, argv)
Xchar **argv;
X{
X Canvas canvas;
X int catch();
X register int x,y,y2,y3;
X register int this, this3;
X int val, sum;
X register int a,b;
X
X putting = !isatty(1);
X getting = !isatty(0);
X
X while (*++argv) {
X if (!strcmp(*argv, "-v"))
X verbose = 1;
X else if (!strcmp(*argv, "-vf")) /* flip chars vertically */
X vflip = 1;
X else if (!strcmp(*argv, "-hf")) /* swap chars horizontally */
X hflip = 1;
X else if (!strcmp(*argv, "-s")) /* be subtle, sleep between chars */
X sleepytime = atoi(*++argv);
X else if (!strcmp(*argv, "-a")) /* i forget what this is for */
X alarmtime = atoi(*++argv);
X else if (!strcmp(*argv, "-m")) /* max pixels to try to blow up */
X MAX = atoi(*++argv);
X else if (!strcmp(*argv, "-u")) /* before explosion, flash this fast */
X usleepytime = atoi(*++argv);
X else if (!strcmp(*argv, "-t"))
X testing = 1;
X else if (!strcmp(*argv, "-b")) /* start at the bottom and eat up */
X bottom_up = 1;
X else if (!strcmp(*argv, "-B")) /* same, but grab the whole character */
X bottom_up_2 = 1;
X else if (!strcmp(*argv, "-c")) /* blow up (crumble) on contact */
X do_crumble = 1;
X else if (!strcmp(*argv, "-f")) { /* show target on fire button */
X if (argv[1] && isdigit(argv[1][0]))
X do_focus = atoi(*++argv);
X else
X do_focus = 1000;
X }
X else if (!strcmp(*argv, "-d")) /* drop characters without crumbling */
X do_drop = 1; /* note, if -c specified, chars drop until contact */
X else if (!strcmp(*argv, "-w")) /* just do stuff in a window */
X do_window = 1;
X else if (!strcmp(*argv, "-C")) /* grab chunks of screen */
X do_chunks = 1;
X else if (!strcmp(*argv, "-r")) /* reverse video for monochrome */
X OFF = !(ON = !ON);
X else if (**argv == '-' && isdigit(argv[0][1]))
X OFF = atoi(*argv + 1); /* set off pixels explicitly */
X else if (**argv == '+' && isdigit(argv[0][1]))
X ON = atoi(*argv + 1); /* set on pixels explicitly */
X else
X device = *argv; /* if other than /dev/fb */
X }
X if (!device && !(device = getenv("DEV_FB")))
X device = DEFAULT_DEVICE;
X
X if (!(pr = pr_open(device)))
X exit(1); /* pr_open does a perror anyway! how stupid */
X
X if (!(pr2 = mem_create(pr->pr_width, pr->pr_height, 1)))
X perror("mem_create"), exit(1);
X
X pr_rop(pr2,0,0,pr2->pr_width, pr2->pr_height,PIX_NOT(PIX_DST),NULL,0,0);
X
X if (do_window || putting) {
X int catch_events();
X Frame frame;
X Canvas canvas;
X Pixwin *pw;
X struct fullscreen *fs;
X int fd;
X setbuf(stdout, 0);
X frame = window_create(0, FRAME,
X WIN_X, 0, WIN_Y, 0,
X WIN_WIDTH, 30, WIN_HEIGHT, 30,
X 0);
X canvas = window_create(frame, CANVAS,
X WIN_CONSUME_PICK_EVENTS,
X WIN_NO_EVENTS,
X WIN_MOUSE_BUTTONS,
X LOC_MOVE,
X 0,
X WIN_EVENT_PROC, catch_events,
X 0);
X pw = canvas_pixwin(canvas);
X fd = (int) window_get(canvas, WIN_FD);
X if (alarmtime)
X alarm(alarmtime);
X win_grabio(fd);
X if (getenv("OFF")) {
X Cursor cursor = window_get(canvas, WIN_CURSOR);
X cursor_set(cursor, CURSOR_SHOW_CURSOR, 0, 0);
X window_set(canvas, WIN_CURSOR, cursor, 0);
X }
X window_main_loop(frame);
X win_releaseio(fd);
X exit(0);
X }
X srandom(getpid());
X if (getting) {
X int ID, x, y;
X while (scanf("%d %d %d", &ID, &x, &y) == 3)
X do_event(ID,x,y);
X } else if (bottom_up) {
X for (y = pr->pr_height-1; y >= 0; --y) {
X n = 0;
X for (x = 0; x < pr->pr_width; ++x)
X if (ison(x,y)) {
X A[n].x = x;
X A[n].y = y;
X n++;
X }
X crumble(pr);
X }
X } else if (bottom_up_2)
X while (1)
X for (y = pr->pr_height-1; y >= 0; y -= 2)
X for (x = 0; x < pr->pr_width; ++x)
X do_letter(x,y);
X else
X while (1) {
X y = random()% (pr->pr_height-1);
X x = random()% (pr->pr_width-1);
X do_letter(x,y);
X }
X}
X
Xdo_letter(x,y)
Xregister int x,y;
X{
X if (testing) {
X printf("%d ", pr_get(pr,x,y));
X return;
X }
X n = 0;
X if (ison(x,y) && fetch(pr,x,y) == 1) {
X unfetch();
X if (verbose)
X printf("%d ", n);
X putlist();
X if (sleepytime)
X sleep(sleepytime);
X } else
X unfetch();
X}
X
Xint edge_ok = 1;
X/*
X * return 1 on success (got something)
X * 0 if got nothing,
X * -1 if went off edge
X */
Xfetch(pr,x,y)
Xstruct pixrect *pr;
X{
X if (!ison(x,y))
X return 0;
X if (do_chunks && ison(x,y))
X while (ison(x,y+1))
X y++;
X return _fetch(x,y);
X}
X/*
X * return 1 if stayed on screen, -1 if went off screen or got too big.
X */
X_fetch(x,y)
Xregister int x,y;
X{
X int i;
X char ind[8];
X static struct pr_pos dirs[8] = {
X {-1,0}, {1,0}, {0,-1}, {0,1}, {-1,-1}, {-1,1}, {1,-1}, {1,1}
X };
X if (pr_get(pr,x,y) == PIX_ERR)
X return edge_ok ? 0 : -1;
X if (isoff(x,y) || !pr_get(pr2, x,y))
X return 0;
X for (i = 1; i < 8; ++i)
X ind[i] = i;
X if (append(x,y)) {
X pr_put(pr2,x,y,0);
X if (do_chunks) {
X register int i1, i2;
X for (i = 1; i <= 5; ++i) {
X i1 = random() % 4;
X i2 = random() % 4; /* scramble first four directions */
X if (i1 != i2)
X swap(ind[i1], ind[i2]);
X }
X }
X for (i = 0; i < 8; ++i)
X if (_fetch(x+dirs[ind[i]].x, y+dirs[ind[i]].y) == -1)
X return -1;
X return 1;
X } else
X return do_chunks ? 1 : -1; /* if do_chunks, then return the chunk */
X}
Xunfetch()
X{
X int i;
X for (i=0; i < n; ++i) {
X pr_put(pr2, A[i].x,A[i].y,1);
X }
X}
Xputlist()
X{
X int i;
X int x,y;
X struct pr_pos dest, drop();
X struct pixrect *make_letter_pr();
X struct pixrect *p = make_letter_pr(&x, &y);
X if (verbose)
X dump(p);
X if (do_focus) {
X focus(pr, A[0].x, A[0].y);
X buzz(pr, p, x, y);
X }
X if (hflip || vflip)
X reverse(pr, p, x, y, p->pr_width, p->pr_height);
X if (do_drop) {
X dest = drop(pr, p, x, y, p->pr_width, p->pr_height);
X for (i = 0; i < n; ++i)
X A[i].y += dest.y - y;
X }
X if (do_crumble)
X crumble(pr);
X pr_destroy(p);
X}
X#define max4(a,b,c,d) max(max(max(a,b),c),d)
X#define min4(a,b,c,d) min(min(min(a,b),c),d)
X
Xbuzz(pr, p, off_x, off_y)
Xstruct pixrect *pr, *p;
Xregister int off_x,off_y;
X{
X int size = max4(off_x, pr->pr_width-off_x, off_y, pr->pr_height-off_x);
X size = min(size, do_focus);
X if (p)
X for (; size >= 0; --size) {
X pr_rop(pr, off_x, off_y, p->pr_width, p->pr_height, PIX_NOT(PIX_DST),
X NULL, 0,0);
X if (usleepytime)
X usleep(usleepytime);
X pr_rop(pr, off_x, off_y, p->pr_width, p->pr_height, PIX_NOT(PIX_DST),
X NULL, 0,0);
X if (usleepytime)
X usleep(usleepytime);
X }
X}
Xfocus(pr, x,y)
Xstruct pixrect *pr;
Xregister int x,y;
X{
X int size = max4(x, pr->pr_width-x, y, pr->pr_height-y);
X size = min(size, do_focus);
X for (; size >= 0; --size) {
X frame(pr, x-size, y-size, x+size, y+size, PIX_NOT(PIX_DST));
X frame(pr, x-size, y-size, x+size, y+size, PIX_NOT(PIX_DST));
X }
X}
Xframe(pr, xmin, ymin, xmax, ymax, op, value)
Xstruct pixrect *pr;
Xregister int xmin, xmax, ymin, ymax, op, value;
X{
X pr_vector(pr, xmin, ymin, xmax, ymin, op, 1);
X pr_vector(pr, xmax, ymin, xmax, ymax, op, 1);
X pr_vector(pr, xmax, ymax, xmin, ymax, op, 1);
X pr_vector(pr, xmin, ymax, xmin, ymin, op, 1);
X}
X/*
X * Make a small pixrect containing the points currently stored in the A array.
X * Coordinates of the new pixrect with respect to the global pr are returned
X * in *x, *y.
X */
Xstruct pixrect *
Xmake_letter_pr(x, y)
Xint *x, *y;
X{
X int i;
X struct pr_pos dest, drop();
X register int minx,maxx,miny,maxy;
X struct pixrect *p;
X minx=maxx=A[0].x;
X miny=maxy=A[0].y;
X for (i=1; i < n; ++i) {
X minx = min(minx, A[i].x);
X miny = min(miny, A[i].y);
X maxx = max(maxx, A[i].x);
X maxy = max(maxy, A[i].y);
X }
X *x = minx-1;
X *y = miny-1;
X p = mem_create(maxx-minx+3, maxy-miny+3, pr->pr_depth);
X for (i=0; i < n; ++i) {
X pr_put(p, A[i].x - *x, A[i].y - *y, ON);
X }
X return p;
X}
Xcrumble(pr)
Xstruct pixrect *pr;
X{
X int moved, i;
X do {
X moved = 0;
X for (i = 0; i < n; ++i) {
X struct pr_pos pos, newpos;
X pos = newpos = A[i];
X if (random() % 30 && isoff(pos.x, pos.y+1))
X newpos.y = pos.y+1;
X else
X switch(random() % 2) {
X when 0:
X if (isoff(pos.x+1, pos.y+1)) {
X newpos.x = pos.x+1;
X newpos.y = pos.y+1;
X } else goto defaul;
X when 1:
X if (isoff(pos.x-1, pos.y+1)) {
X newpos.x = pos.x-1;
X newpos.y = pos.y+1;
X } else goto defaul;
X otherwise:
X defaul:
X if (isoff(pos.x, pos.y+1))
X newpos.y = pos.y+1;
X }
X if (newpos.x != pos.x || newpos.y != pos.y) {
X moved = 1;
X if (random() % 30) {
X pr_put(pr, pos.x, pos.y, OFF);
X pr_put(pr, newpos.x, newpos.y, ON);
X A[i] = newpos;
X }
X }
X }
X } while (moved);
X}
Xreverse(pr,p,x,y,w,h)
Xstruct pixrect *pr, *p;
X{
X pr_rop(pr,x,y,w,h,XOR,p,0,0);
X pr_reverse_rop(pr,x,y,w,h,XOR,p,0,0);
X}
Xpr_reverse_rop(dpr,dx,dy,w,h,op,spr,sx,sy)
Xstruct pixrect *spr, *dpr;
X{
X int x,y;
X for (y=0;y<h;++y)
X for (x=0;x<w;++x)
X pr_rop(dpr, dx+x, dy+y, 1, 1, op, spr, sx + (vflip? w-1-x : x),
X sy + (hflip? h-1-y : y));
X}
Xstruct pr_pos
Xdrop(pr,p,x,y,w,h)
Xstruct pixrect *pr, *p;
X{
X register int X,Y;
X struct pr_pos dest;
X while (canfall(pr,p,x,y+1,w,h)) {
X for (Y=h-1; Y >= 0; Y--)
X for (X=0; X < w; X++)
X if (pr_get(p, X, Y) == ON) {
X pr_put(pr, X+x, Y+y, OFF);
X pr_put(pr, X+x, Y+y+1, ON);
X }
X y++;
X }
X dest.x = x;
X dest.y = y;
X return dest;
X}
Xcanfall(pr,p,x,y,w,h)
Xstruct pixrect *pr, *p;
X{
X int i,j;
X for (j=0;j<h;++j)
X for (i=0;i<w;++i)
X if (pr_get(p,i,j) == ON && pr_get(p,i,j+1) != ON)
X if (pr_get(pr,x+i,y+j) != OFF)
X return 0;
X return 1;
X}
Xdump(p)
Xstruct pixrect *p;
X{
X int x,y;
X printf("size=%d,%d\n",p->pr_width, p->pr_height);
X puts("=================================");
X for (y=0; y < p->pr_height; ++y) {
X for (x=0; x < p->pr_width; ++x)
X printf("%c ", (pr_get(p,x,y) == ON) ? '*' : ' ');
X puts("");
X }
X puts("=================================");
X}
Xshoot(x,y)
Xint *x, *y;
X{
X while (1) {
X if (!isoff(*x,*y))
X break;
X if (verbose)
X pr_put(pr,*x,*y,ON);
X --*x;
X if (!isoff(*x,*y))
X break;
X if (verbose)
X pr_put(pr,*x,*y,ON);
X --*y;
X }
X}
Xcatch_events(canvas, event, data)
Xregister Canvas canvas;
Xregister Event *event;
X{
X register int ID = event->ie_code;
X register Pixrect *newicon = NULL;
X int fd = (int) window_get(canvas, WIN_FD);
X int x,y;
X static start_fast;
X
X if (!event_is_down(event) && ID != LOC_MOVE)
X return;
X x = event_x(event);
X y = event_y(event);
X if (getenv("Y"))
X y += atoi(getenv("Y"));
X else
X y += 18;
X if (getenv("X"))
X x += atoi(getenv("X"));
X else
X x += 5;
X
X if (ID != MS_RIGHT && putting) {
X send(ID,x,y);
X return;
X }
X if (verbose)
X printf("Got %d (%d,%d)\n", ID,x,y);
X win_releaseio(fd);
X do_event(ID,x,y);
X if (ID != MS_RIGHT)
X win_grabio(fd);
X}
Xsend(ID, x,y)
X{
X printf("%d %d %d\n", ID, x,y);
X}
Xdo_event(ID,x,y)
X{
X if (verbose)
X printf("Got %d (%d,%d)\n", ID,x,y);
X switch(ID) {
X when LOC_MOVE: unshow_target();
X show_target(x,y);
X shoot(&x, &y);
X when MS_LEFT:
X unshow_target();
X if (putting)
X send(x,y);
X else {
X shoot(&x,&y);
X do_letter(x,y);
X }
X }
X}
Xshort bullseye_image[] = {
X/* Format_version=1, Width=16, Height=16, Depth=1, Valid_bits_per_item=16
X */
X 0x07C0,0x1830,0x2008,0x4384,0x4C64,0x8822,0x9012,0x9112,
X 0x9012,0x8822,0x4C64,0x4384,0x2008,0x1830,0x07C0,0x0000
X};
Xmpr_static(bullseye, 16, 16, 1, bullseye_image);
Xint prevx = -1, prevy = -1;
Xint target_on = 0;
Xshow_target(x,y)
X{
X if (target_on)
X unshow_target();
X pr_rop(pr, x-7,y-7,bullseye.pr_width,bullseye.pr_height,XOR,&bullseye,0,0);
X prevx = x;
X prevy = y;
X target_on = 1;
X}
Xunshow_target()
X{
X if (target_on)
X pr_rop(pr, prevx-7,prevy-7,bullseye.pr_width,bullseye.pr_height,XOR,&bullseye,0,0);
X target_on = 0;
X}
EOF
exit 0
More information about the Comp.sources.misc
mailing list