home *** CD-ROM | disk | FTP | other *** search
- /*
- * xfish.c - serves no useful purpose whatsoever
- *
- * Author: John H. Bradley, University of Pennsylvania
- * (bradley@cis.upenn.edu)
- * October, 1987
- *
- * For 4.3ish Unix systems running X V11
- *
- * Modified by Jon Greenblatt (jonnyg@rover.umd.edu):
- *
- * 1: Improved event handeling.
- * 2: Added the -root option (xerror occurs with window managers running).
- * 3: Added the -rv reverse video option.
- *
- * Modified by Lars Huttar (huttar@svax.cs.cornell.edu) 7/89:
- *
- * 1: Added the -nobell option.
- * 2: Allowed for two fish to be hit by one shot.
- * 3: Added the -bitmap option for using your own bitmaps.
- *
- */
-
-
- #include <stdio.h>
- #include <math.h>
- #include <strings.h>
- #include <signal.h>
- #include <X11/Xlib.h>
- #include <X11/Xutil.h>
- #include <X11/cursorfont.h>
- #include <sys/time.h>
- #include <sys/types.h>
- #include <sys/timeb.h>
-
- #define DEFAULTDIR "/usr/public/sun3/games/lib/xfish_bitmaps/"
-
- /* handy-dandy functions */
- #define max(a, b) ((a) > (b) ? (a) : (b))
- #define min(a, b) ((a) < (b) ? (a) : (b))
- #define abs(a) ((a) < 0 ? -(a) : (a))
-
-
- /* objects */
- Display *disp;
- Window theWindow;
- Pixmap stipP, lfishP, rfishP, lfishmaskP, rfishmaskP;
- GC gc,lgc,rgc;
- XGCValues xgcv;
- XSetWindowAttributes xswa;
- #define root_weave_width 16
- #define root_weave_height 16
- static char root_weave_bits[] = {
- 0x77, 0x77, 0xdd, 0xdd, 0xbb, 0xbb, 0xee, 0xee, 0x77, 0x77, 0xdd, 0xdd,
- 0xbb, 0xbb, 0xee, 0xee, 0x77, 0x77, 0xdd, 0xdd, 0xbb, 0xbb, 0xee, 0xee,
- 0x77, 0x77, 0xdd, 0xdd, 0xbb, 0xbb, 0xee, 0xee};
-
- static char iroot_weave_bits[] = {
- 0x88, 0x88, 0x22, 0x22, 0x44, 0x44, 0x11, 0x11, 0x88, 0x88, 0x22, 0x22,
- 0x44, 0x44, 0x11, 0x11, 0x88, 0x88, 0x22, 0x22, 0x44, 0x44, 0x11, 0x11,
- 0x88, 0x88, 0x22, 0x22, 0x44, 0x44, 0x11, 0x11};
-
- int fish_width=32, fish_height=16;
-
- static char lfish_bits[] = {
- 0x00, 0xc0, 0x07, 0x00, 0x00, 0xb0, 0x06, 0x00, 0x80, 0x7f, 0x03, 0xe0,
- 0x60, 0x82, 0x03, 0xb0, 0x18, 0x00, 0x0c, 0x68, 0x64, 0x02, 0xf0, 0x37,
- 0x62, 0x00, 0x00, 0x28, 0x01, 0xaa, 0xaa, 0x36, 0x46, 0x00, 0x00, 0x28,
- 0x38, 0x03, 0xc0, 0x5f, 0xb0, 0x28, 0x30, 0xb0, 0xc0, 0x39, 0x0e, 0xe0,
- 0x00, 0xee, 0x01, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00,
- 0x00, 0xc0, 0x00, 0x00};
-
- static char lfishmask_bits[] = {
- 0x00, 0xc0, 0x07, 0x00, 0x00, 0xf0, 0x07, 0x00, 0x80, 0xff, 0x03, 0xe0,
- 0xe0, 0xff, 0x03, 0xf0, 0xf8, 0xff, 0x0f, 0x78, 0xfc, 0xff, 0xff, 0x3f,
- 0xfe, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0x3f, 0xfe, 0xff, 0xff, 0x3f,
- 0xf8, 0xff, 0xff, 0x7f, 0xf0, 0xff, 0x3f, 0xf0, 0xc0, 0xff, 0x0f, 0xe0,
- 0x00, 0xfe, 0x01, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00,
- 0x00, 0xc0, 0x00, 0x00};
-
- static char rfish_bits[] = {
- 0x00, 0xe0, 0x03, 0x00, 0x00, 0x60, 0x0d, 0x00, 0x07, 0xc0, 0xfe, 0x01,
- 0x0d, 0xc0, 0x41, 0x06, 0x12, 0x30, 0x00, 0x18, 0xec, 0x0f, 0x40, 0x26,
- 0x14, 0x00, 0x00, 0x46, 0xac, 0xaa, 0x4a, 0x80, 0x14, 0x00, 0x00, 0x62,
- 0xfa, 0x03, 0xc0, 0x1c, 0x0d, 0x0c, 0x14, 0x0d, 0x07, 0x70, 0x9c, 0x03,
- 0x00, 0x80, 0x77, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x05, 0x00,
- 0x00, 0x00, 0x03, 0x00};
-
- static char rfishmask_bits[] = {
- 0x00, 0xe0, 0x03, 0x00, 0x00, 0xe0, 0x0f, 0x00, 0x07, 0xc0, 0xff, 0x01,
- 0x0f, 0xc0, 0xff, 0x07, 0x1e, 0xf0, 0xff, 0x1f, 0xfc, 0xff, 0xff, 0x3f,
- 0xfc, 0xff, 0xff, 0x7f, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0x7f,
- 0xfe, 0xff, 0xff, 0x1f, 0x0f, 0xfc, 0xff, 0x0f, 0x07, 0xf0, 0xff, 0x03,
- 0x00, 0x80, 0x7f, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x07, 0x00,
- 0x00, 0x00, 0x03, 0x00};
-
-
- #define MAXFISH 100
- struct fishstr { short x,y,dx,dy; } fish[MAXFISH];
-
- int NUMFISH=20, startnfish=20, shots=0, no_bell=0, use_root=0,
- reverse_video=0, load_bitmap=0, screen;
- #define MAXFNLEN 51
- char filename[MAXFNLEN];
-
-
- long starttime;
-
- /**************/
- main(argc, argv)
- int argc;
- char *argv[];
- /**************/
- {
- int i,dpcs,n,fcnt;
- char *strind;
-
- char *fc, *bc;
- char *display = NULL;
-
- char *def;
- short bot,right;
- XSizeHints xsh;
-
-
- /*********************Options*********************/
-
- for (i = 1; i < argc; i++) {
-
- strind = index(argv[i], ':'); /* is it display address? */
- if(strind != NULL) {
- display = argv[i];
- continue;
- }
-
- if (n=atoi(argv[i])) {
- if (n<1) n=1;
- if (n>100) n=100;
- NUMFISH=startnfish=n;
- continue;
- }
-
- if (*argv[i] == '-') {
- if (strcmp(argv[i],"-root") == 0) {
- use_root = 1;
- continue;
- }
- if (strcmp(argv[i],"-rv") == 0) {
- reverse_video = 1;
- continue;
- }
- if (strncmp(argv[i],"-n",2) == 0) { /* -nobell */
- no_bell = 1;
- continue;
- }
- if (strncmp(argv[i],"-b",2) == 0 && argc>i+1 /* -bitmap */
- && sscanf(argv[++i], "%50s", filename)==1) {
- load_bitmap = 1;
- continue;
- }
- }
-
- Syntax(argv[0]);
- }
-
-
- /*****************************************************/
-
- /* Open up the display. */
-
- if ((disp=XOpenDisplay(display)) == NULL) {
- fprintf(stderr, "%s: Can't open display ''\n",argv[0],display);
- exit(1);
- }
-
-
- bot =DisplayHeight(disp,DefaultScreen(disp));
- right=DisplayWidth (disp,DefaultScreen(disp));
-
- xsh.flags = USSize | USPosition;
- xsh.x = xsh.y = 0;
- xsh.width = right;
- xsh.height= bot;
-
- xswa.event_mask = ButtonPressMask;
- if (use_root)
- theWindow = RootWindow(disp,DefaultScreen(disp));
- else
- theWindow = XCreateWindow(disp, DefaultRootWindow(disp), 0,0,
- right,bot,0,1,InputOutput,
- DefaultVisual(disp,DefaultScreen(disp)),
- CWEventMask,&xswa);
-
-
- stipP=XCreateBitmapFromData(disp,theWindow,
- iroot_weave_bits, root_weave_width, root_weave_height);
-
- if (load_bitmap) load_bitmaps();
- else {
- lfishP=XCreateBitmapFromData(disp,theWindow,
- lfish_bits,fish_width,fish_height);
- rfishP=XCreateBitmapFromData(disp,theWindow,
- rfish_bits,fish_width,fish_height);
- lfishmaskP=XCreateBitmapFromData(disp,theWindow,
- lfishmask_bits,fish_width,fish_height);
- rfishmaskP=XCreateBitmapFromData(disp,theWindow,
- rfishmask_bits,fish_width,fish_height);
- }
-
- if (!use_root) {
- XSetWindowBackgroundPixmap(disp,theWindow,stipP);
- XSetNormalHints(disp,theWindow,&xsh);
- XSetStandardProperties(disp,theWindow,"fish","fish",None,0,0,&xsh);
- XMapWindow(disp,theWindow);
- XLowerWindow(disp, theWindow);
- }
-
- /* init fish */
- for (i=0; i<NUMFISH; i++) {
- fish[i].x=rand()%(right-100)+50;
- fish[i].y=rand()%(bot-100)+50;
- fish[i].dx = (abs(rand()%10)+4);
-
- /* switch direction based on a higher-order bit. the low-order bit
- tended to be useless */
- if (rand()&0x10) fish[i].dx = -fish[i].dx;
-
- fish[i].dy=rand()%7-3; if (fish[i].dy==0) fish[i].dy=1;
- }
-
-
- xgcv.tile=stipP;
- xgcv.graphics_exposures = False;
-
- gc = XCreateGC(disp,theWindow,GCTile|GCGraphicsExposures,&xgcv);
- lgc= XCreateGC(disp,theWindow,GCTile|GCGraphicsExposures,&xgcv);
- rgc= XCreateGC(disp,theWindow,GCTile|GCGraphicsExposures,&xgcv);
-
- xgcv.fill_style= FillTiled;
-
- xgcv.clip_mask = None;
-
- screen = DefaultScreen(disp);
- if (reverse_video) {
- xgcv.foreground = WhitePixel(disp,screen);
- xgcv.background = BlackPixel(disp,screen);
- }
- else {
- xgcv.foreground = BlackPixel(disp,screen);
- xgcv.background = WhitePixel(disp,screen);
- }
- xgcv.clip_mask = lfishmaskP;
- XChangeGC(disp,lgc,GCClipMask|GCFillStyle|GCForeground|GCBackground,&xgcv);
-
- xgcv.clip_mask = rfishmaskP;
- XChangeGC(disp,rgc,GCClipMask|GCFillStyle|GCForeground|GCBackground,&xgcv);
-
- starttime=time(0);
-
-
- /**************** Main loop *****************/
-
- fcnt = 0;
- if (use_root)
- XSelectInput(disp,theWindow,ButtonPressMask);
- while (1) {
- XEvent event;
- short x,y,bnum;
-
- if (XCheckMaskEvent(disp,ButtonPressMask,&event)) {
- if (event.type == ButtonPress) {
- XButtonEvent *butevent = (XButtonEvent *) &event;
-
- bnum = butevent->button;
- if ((bnum == Button1) || (bnum == Button3)) {
-
- if (bnum == Button3) shots++;
-
- x = butevent->x; y = butevent->y;
- for (i=0; i<NUMFISH; i++) {
- if ( (x >= fish[i].x) &&
- (x <= fish[i].x+fish_width) &&
- (y >= fish[i].y) &&
- (y <= fish[i].y+fish_height) )
-
- if (i!=NUMFISH) {
- if (!no_bell) XBell(disp,25);
- EraseFish(i);
- if (bnum == Button1) {
- fish[i].dx = -fish[i].dx;
- fish[i].dy = -fish[i].dy;
- DrawFish(i);
- }
- else {
- if (NUMFISH==1) Stats();
- bcopy(&fish[NUMFISH-1],&fish[i],
- sizeof(struct fishstr));
- NUMFISH--;
- }
- }
- }
- }
- }
- }
-
- if (fcnt>=NUMFISH) fcnt=0; /* since it's possible NUMFISH decreased */
-
- EraseFish(fcnt);
-
- fish[fcnt].x += fish[fcnt].dx;
- fish[fcnt].y += fish[fcnt].dy;
- if (fish[fcnt].x < -50 || fish[fcnt].x > (right+50))
- fish[fcnt].dx = -fish[fcnt].dx;
- if (fish[fcnt].y < 0 || fish[fcnt].y > (bot-16))
- fish[fcnt].dy = -fish[fcnt].dy;
-
- DrawFish(fcnt);
-
- fcnt++;
- if (fcnt>=NUMFISH) { fcnt=0; Timer(250000L); }
-
- } /* end main loop */
- }
-
- /*****************/
- EraseFish(i)
- int i;
- {
- XClearArea(disp,theWindow,fish[i].x,fish[i].y,fish_width,fish_height,0);
- }
-
- /*****************/
- DrawFish(i)
- int i;
- {
- xgcv.clip_x_origin = fish[i].x;
- xgcv.clip_y_origin = fish[i].y;
-
- if (fish[i].dx<0) {
- XChangeGC(disp,lgc,GCClipXOrigin|GCClipYOrigin,&xgcv);
- XCopyPlane(disp,lfishP,theWindow,lgc,0,0,fish_width,fish_height,
- fish[i].x,fish[i].y,1);
- }
- else {
- XChangeGC(disp,rgc,GCClipXOrigin|GCClipYOrigin,&xgcv);
- XCopyPlane(disp,rfishP,theWindow,rgc,0,0,fish_width,fish_height,
- fish[i].x,fish[i].y,1);
- }
- }
-
-
- /***********************************/
- Syntax(call)
- char *call;
- {
- printf ("Usage: %s [-root -rv -nobell -bitmap bitmapfile]\n",call);
- puts("\t\t[host:display] [number of fish]\n");
- exit(1);
- }
-
-
- /***********************************/
- XFishError (identifier)
- char *identifier;
- {
- fprintf(stderr, "xfish: %s\n", identifier);
- exit(1);
- }
-
-
-
- /*******/
- Stats()
- {
- long curtime;
- float acc;
-
- curtime=time(0);
- acc = (float) shots / (float) startnfish;
- if (!no_bell) puts("\007\007\007");
- printf("You used %d shots to hit %d fish. (in %d seconds)\n",
- shots,startnfish,curtime-starttime);
- printf(" For an accuracy ratio of: %f\n", acc);
-
- if (acc < 1.0) printf("Tex, you're a whiz!\n");
- else if (acc < 1.5) printf("Nice shootin', Tex!\n");
- XPending(disp);
- exit(0);
- }
-
-
-
- static int timerdone;
-
- /*******/
- onalarm()
- /*******/
- {
- timerdone=1;
- }
-
- /*******/
- Timer(val,n)
- long val;
- /*******/
- {
- /* waits 'val' microseconds */
-
- struct itimerval it;
-
- bzero(&it, sizeof(it));
- it.it_value.tv_usec = val;
- timerdone=0;
- signal(SIGALRM,onalarm);
- setitimer(ITIMER_REAL, &it, (struct itimerval *)0);
- while (1) {
- sigblock(sigmask(SIGALRM)); /* note: have to block, so that ALRM */
- if (timerdone) break; /* doesn't occur between 'if (timerdone)'*/
- else sigpause(0); /* and calling sigpause(0) */
- }
- sigblock(0); /* turn ALRM blocking off */
- signal(SIGALRM,SIG_DFL);
- }
-
- load_bitmaps()
- { int dummy;
- register int i, status;
- char nufilename[MAXFNLEN+3], temp[MAXFNLEN+3];
- static char extensions[4][4]={".li", ".lm", ".ri", ".rm"};
- static Pixmap *pixmaps[4] = {&lfishP, &lfishmaskP, &rfishP, &rfishmaskP};
-
- for (i=0; i<4; i++) {
- strcpy(nufilename, filename);
- strcat(nufilename, extensions[i]); /* Add extension... */
-
- /* Load in the bitmap. If unsuccessful... */
- if ((status=XReadBitmapFile(disp, RootWindow(disp, DefaultScreen(disp)),
- nufilename, &fish_width, &fish_height, pixmaps[i],
- &dummy, &dummy)) != BitmapSuccess) {
-
- /* If the file couldn't be opened, try the default directory. */
- if (status==BitmapOpenFailed && filename[0]!='/') {
- strcpy(nufilename, DEFAULTDIR);
- strcat(nufilename, filename); /* Add default path to front */
- strcpy(filename, nufilename); /* of filename. */
- strcat(nufilename, extensions[i]);
- if ((status=XReadBitmapFile(disp,
- RootWindow(disp, DefaultScreen(disp)),
- nufilename, &fish_width, &fish_height, pixmaps[i],
- &dummy, &dummy)) == BitmapSuccess) continue;
- /* If the default dir worked, go load next bitmap. */
- }
-
- /* Explain failure and quit. */
- fputs("Invalid bitmap files. There should be four,\n", stderr);
- fputs("with extensions .li, .lm, .ri, and .rm.\n", stderr);
- fputs("They are used for left and right images ", stderr);
- fputs("and masks.\n", stderr);
- exit(1);
- }
- }
- }
-