home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / games / volume15 / xballs / part01 < prev    next >
Encoding:
Internet Message Format  |  1993-01-26  |  13.0 KB

  1. Path: uunet!news.tek.com!master!saab!billr
  2. From: billr@saab.CNA.TEK.COM (Bill Randle)
  3. Newsgroups: comp.sources.games
  4. Subject: v15i042:  xballs - bouncing balls on the background window, Part01/01
  5. Message-ID: <4198@master.CNA.TEK.COM>
  6. Date: 14 Jan 93 03:35:00 GMT
  7. Sender: news@master.CNA.TEK.COM
  8. Lines: 663
  9. Approved: billr@saab.CNA.TEK.COM
  10. Xref: uunet comp.sources.games:1541
  11.  
  12. Submitted-by: bmh@terminus.ericsson.se (Bernard Hatt)
  13. Posting-number: Volume 15, Issue 42
  14. Archive-name: xballs/Part01
  15. Environment: X11, Xlib
  16.  
  17.     [More of a novelty than a game. It does work with olvwm 3.3.  -br]
  18.  
  19. #! /bin/sh
  20. # This is a shell archive.  Remove anything before this line, then unpack
  21. # it by saving it into a file and typing "sh file".  To overwrite existing
  22. # files, type "sh file -c".  You can also feed this as standard input via
  23. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  24. # will see the following message at the end:
  25. #        "End of archive 1 (of 1)."
  26. # Contents:  README MANIFEST Makefile xballs.c
  27. # Wrapped by billr@saab on Wed Jan 13 19:32:01 1993
  28. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  29. if test -f 'README' -a "${1}" != "-c" ; then 
  30.   echo shar: Will not clobber existing file \"'README'\"
  31. else
  32. echo shar: Extracting \"'README'\" \(860 characters\)
  33. sed "s/^X//" >'README' <<'END_OF_FILE'
  34. X
  35. XBouncing balls for an X windows background.
  36. X
  37. XKnown not work to with tvtwm, may not work with other virtual desktop
  38. Xsystems.  Works with twm and olwm. 
  39. X
  40. XCan take a lot of cpu and X bandwidth.
  41. X
  42. XAlter the Makefile as appropriate and type:
  43. X    make
  44. X
  45. XTo run type:
  46. X    xballs
  47. X    
  48. XOptions are:
  49. X    -d hostname    display on hostname
  50. X    -n number    number of balls (6 by default)
  51. X    -r radius    radius of balls
  52. X    -c coeff    coefficient of restitution (sp?)
  53. X    -t percent    percentage of balls generated at the to of the screen
  54. X
  55. XThe program is a bit 'rough round the edges'
  56. X
  57. XThe balls interact with the mouse pointer, but not with each other (I'm
  58. Xsure there is a simple method for this using matrices but I havn't been
  59. Xable to find it)
  60. X
  61. XThe more balls you have, the more cpu power used.  (I would suggest a
  62. Xmaximum of about 6 for a Sun 3 and 12 for a Sun 4)
  63. X
  64. XBernard Hatt
  65. Xbmh@terminus.ericsson.se
  66. END_OF_FILE
  67. if test 860 -ne `wc -c <'README'`; then
  68.     echo shar: \"'README'\" unpacked with wrong size!
  69. fi
  70. # end of 'README'
  71. fi
  72. if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  73.   echo shar: Will not clobber existing file \"'MANIFEST'\"
  74. else
  75. echo shar: Extracting \"'MANIFEST'\" \(238 characters\)
  76. sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
  77. X   File Name        Archive #    Description
  78. X-----------------------------------------------------------
  79. X MANIFEST                   1    This shipping list
  80. X Makefile                   1    
  81. X README                     1    
  82. X xballs.c                   1    
  83. END_OF_FILE
  84. if test 238 -ne `wc -c <'MANIFEST'`; then
  85.     echo shar: \"'MANIFEST'\" unpacked with wrong size!
  86. fi
  87. # end of 'MANIFEST'
  88. fi
  89. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  90.   echo shar: Will not clobber existing file \"'Makefile'\"
  91. else
  92. echo shar: Extracting \"'Makefile'\" \(147 characters\)
  93. sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  94. X
  95. Xxballs:    xballs.c
  96. X    cc xballs.c -O -o xballs -lX11 -I/usr/openwin/include
  97. X
  98. Xshar: xballs.c README Makefile
  99. X    shar README xballs.c Makefile >xballs.sh
  100. END_OF_FILE
  101. if test 147 -ne `wc -c <'Makefile'`; then
  102.     echo shar: \"'Makefile'\" unpacked with wrong size!
  103. fi
  104. # end of 'Makefile'
  105. fi
  106. if test -f 'xballs.c' -a "${1}" != "-c" ; then 
  107.   echo shar: Will not clobber existing file \"'xballs.c'\"
  108. else
  109. echo shar: Extracting \"'xballs.c'\" \(8589 characters\)
  110. sed "s/^X//" >'xballs.c' <<'END_OF_FILE'
  111. X/*
  112. X * Simple demo, animated (bouncing balls) background.
  113. X *
  114. X * Author: Bernard Hatt (bmh@terminus.ericsson.se)
  115. X *
  116. X * Camtec Electronics (Ericsson), Leicester, England, LE1 4SA
  117. X *
  118. X */
  119. X
  120. X#include <stdio.h>
  121. X#include <signal.h>
  122. X#include <ctype.h>
  123. X#include <sys/time.h>
  124. X
  125. X#include <X11/X.h>
  126. X#include <X11/Xlib.h>
  127. X#include <X11/cursorfont.h>
  128. X
  129. XDisplay *Disp;
  130. Xint Scr;
  131. XWindow Root;
  132. XGC GcF,GcB;
  133. X
  134. X#define NONE    0    /* not in a window */
  135. X#define V    1    /* vertical */
  136. X#define H    2    /* horizontal */
  137. X#define B    3    /* ball */
  138. X
  139. X#define MOUSEH    24
  140. X#define MOUSEW    24
  141. X
  142. X#define DEFRAD    16    /* default diameter */
  143. X#define DEFNO    6
  144. X#define SPEED    128
  145. X#define SQLIMIT    (SPEED*SPEED/(20*20))    /* square of lower speed limit */
  146. X
  147. Xint dispx,dispy;
  148. X
  149. Xtypedef struct rectangle_struct
  150. X{
  151. X    int x1,y1;    /* x and y coords top left */
  152. X    int x2,y2;    /* x and y coords bottom right */
  153. X} RECTANGLE;
  154. X
  155. Xint nor;
  156. XRECTANGLE *rp=NULL;
  157. X
  158. Xtypedef struct ball_struct
  159. X{
  160. X    int x,y;    /* x and y coords */
  161. X    int dx,dy;    /* x and y velocity */
  162. X} BALL;
  163. X
  164. Xint noballs=DEFNO;
  165. Xint radius=DEFRAD;
  166. XBALL *bp;
  167. Xint coeff=85;
  168. Xint attop=100;
  169. X
  170. Xint backflag=0;
  171. Xint invertflag=0;
  172. Xint trailflag=0;
  173. Xint mouseflag=1;
  174. Xint sizeflag=0;
  175. Xint momentumflag=0;
  176. Xint interact=0;
  177. Xint mx,my,mn,mdx,mdy;
  178. Xint failed=0;
  179. Xint currmax=0;        /* current maximum number of windows */
  180. X
  181. Xchar *getenv();
  182. X
  183. Xint lasttime;
  184. X
  185. X
  186. Xlong lastsec=0;
  187. Xstruct timezone tz={0,0};
  188. Xstruct timeval tv;
  189. Xstruct timeval tv2;
  190. X
  191. Xint
  192. Xrnd(n)
  193. Xint n;
  194. X{
  195. X    return((rand()/153)%n);
  196. X}
  197. X
  198. X
  199. Xvoid    /* because Ultrix doesn't provide the nice SunOS usleep() */
  200. Xmyusleep(val)
  201. Xint val;
  202. X{
  203. X    tv2.tv_sec=0;
  204. X    tv2.tv_usec=val;
  205. X
  206. X    select(0,NULL,NULL,NULL,&tv2);
  207. X}
  208. X
  209. Xvoid
  210. Xdointr()
  211. X{
  212. X    clearballs();
  213. X    exit(1);
  214. X}
  215. X
  216. Xvoid
  217. XXerr()
  218. X{
  219. X    failed++;
  220. X}
  221. X
  222. Xvoid
  223. XXfatal()
  224. X{
  225. X    exit(1);
  226. X}
  227. X
  228. Xvoid
  229. Xrandomball(i)
  230. Xint i;
  231. X{
  232. X    int x,y;
  233. X    int dum;
  234. X    int attempts;
  235. X    attempts=0;
  236. X    do
  237. X    {
  238. X        x=rnd(dispx);
  239. X        y=rnd(dispy);
  240. X        if(rnd(100)<attop)
  241. X            y=0;
  242. X        attempts++;
  243. X        if(attempts>2000)
  244. X        {
  245. X            clearballs();
  246. X            exit(1);
  247. X        }
  248. X    }
  249. X    while(inwin(x,y,0,0,&dum)!=NONE);
  250. X        bp[i].x=x;
  251. X    bp[i].y=y;
  252. X    bp[i].dx=rnd(SPEED)+(SPEED/2);
  253. X    bp[i].dy=rnd(SPEED)+(SPEED/2);
  254. X    switch(rnd(4))
  255. X    {
  256. X    case 0:
  257. X        break;
  258. X    case 1:
  259. X        bp[i].dx=(0-bp[i].dx);
  260. X        break;
  261. X    case 2:
  262. X        bp[i].dy=(0-bp[i].dy);
  263. X        break;
  264. X    case 3:
  265. X        bp[i].dx=(0-bp[i].dx);
  266. X        bp[i].dy=(0-bp[i].dy);
  267. X        break;
  268. X    }
  269. X}
  270. X
  271. Xint
  272. Xgettime()
  273. X{
  274. X    gettimeofday(&tv,&tz);
  275. X    if(lastsec==0)
  276. X        lastsec=tv.tv_sec;
  277. X    return((tv.tv_sec-lastsec)*100+(tv.tv_usec/10000));
  278. X}
  279. X
  280. Xint
  281. Xinwin(x,y,dx,dy,n)
  282. Xint x,y,dx,dy;
  283. Xint *n;
  284. X{
  285. X    int i,diffx,diffy;
  286. X    int coln;
  287. X    coln=(-1);
  288. X    if((x<0)||(x>dispx))
  289. X        return(V);
  290. X    if((y<0)||(y>dispy))
  291. X        return(H);
  292. X    for(i=0;i<nor;i++)
  293. X    {
  294. X        if((x<rp[i].x1)||(y<rp[i].y1)||(y>rp[i].y2)||(x>rp[i].x2))
  295. X            continue;
  296. X        coln=i;
  297. X        break;
  298. X    }
  299. X    if(coln==(-1))
  300. X    {
  301. X        if(!interact)
  302. X            return(NONE);
  303. X        for(i=0;i<noballs;i++)
  304. X        {
  305. X            if(i==(*n))
  306. X                break;
  307. X            diffx=(bp[i].x-x);
  308. X            diffy=(bp[i].y-y);
  309. X            if((diffx*diffx+diffy*diffy)<(radius*radius*4))
  310. X            {
  311. X                (*n)=i;
  312. X                return(B);
  313. X            }
  314. X        }
  315. X        return(NONE);
  316. X    }
  317. X    *n=coln;
  318. X    x-=dx;
  319. X    if((x<rp[i].x1)||(y<rp[i].y1)||(y>rp[i].y2)||(x>rp[i].x2))
  320. X        return(V);
  321. X    return(H);
  322. X}
  323. X
  324. Xclearballs()
  325. X{
  326. X    int i;
  327. X    XClearWindow(Disp,Root);
  328. X    XFlush(Disp);
  329. X}
  330. X
  331. Xvoid
  332. Xdoballs()
  333. X{
  334. X    int i,n;
  335. X    int newtime,td;
  336. X    int dx,dy,x,y,nx,ny;
  337. X    int redo;
  338. X    int diffx,diffy;
  339. X    int dumint;
  340. X    Window dumwin;
  341. X
  342. X    newtime=gettime();
  343. X    td=newtime-lasttime;
  344. X    if(td>20)
  345. X        td=20;
  346. X
  347. X    if(mouseflag)
  348. X    {
  349. X        XQueryPointer(Disp,Root,&dumwin,&dumwin,&nx,&ny,&dumint,&dumint,&dumint);
  350. X        mdx=nx-mx;
  351. X        mx=nx;
  352. X        mdy=ny-my;
  353. X        my=ny;
  354. X        rp[mn].x1=mx-(MOUSEW/2);
  355. X        rp[mn].y1=my-(MOUSEH/2);
  356. X        rp[mn].x2=mx+(MOUSEW/2);
  357. X        rp[mn].y2=my+(MOUSEH/2);
  358. X    }
  359. X
  360. X    for(i=0;i<noballs;i++)
  361. X    {
  362. X        if(backflag||trailflag)
  363. X            XFillArc(Disp,Root,GcB,bp[i].x-(radius/2),bp[i].y-(radius/2),radius,radius,0,360*64);
  364. X        else
  365. X            XClearArea(Disp,Root,bp[i].x-(radius/2),bp[i].y-(radius/2),radius,radius,0);
  366. X        redo=0;
  367. X        if((bp[i].dx*bp[i].dx+bp[i].dy*bp[i].dy)<SQLIMIT)
  368. X            redo=10;
  369. X        do
  370. X        {
  371. X            dx=(td*bp[i].dx)/100;
  372. X            dy=(td*bp[i].dy)/100;
  373. X            if(redo>5)
  374. X            {
  375. X                redo=0;
  376. X                randomball(i);
  377. X            }
  378. X
  379. X
  380. X/*            printf("coords are %d,%d [%d,%d]\n",bp[i].x,bp[i].y,bp[i].dx,bp[i].dy);*/
  381. X            n=i;
  382. X            switch(inwin(dx+bp[i].x,dy+bp[i].y,dx,dy,&n))
  383. X            {
  384. X            case NONE:
  385. X                bp[i].x+=dx;
  386. X                bp[i].y+=dy;
  387. X                redo=0;
  388. X                break;
  389. X            case V:
  390. X                if((n==mn)&momentumflag)
  391. X                {
  392. X                    bp[i].dx=mdx;
  393. X                    bp[i].dy=mdy;
  394. X                    bp[i].x+=dx;
  395. X                    bp[i].y+=dy;
  396. X                }
  397. X                else
  398. X                    bp[i].dx=(coeff*bp[i].dx)/100;
  399. X
  400. X                redo++;
  401. X                break;
  402. X            case H:
  403. X                if((n==mn)&momentumflag)
  404. X                {
  405. X                    bp[i].dy=mdy;
  406. X                    bp[i].dx=mdx;
  407. X                    bp[i].x+=dx;
  408. X                    bp[i].y+=dy;
  409. X                }
  410. X                else
  411. X                    bp[i].dy=(coeff*bp[i].dy)/100;
  412. X
  413. X                if(coeff!=100)
  414. X                {
  415. X/*                    printf("[%d] y=%d dy=%d\n",i,bp[i].y,dy);*/
  416. X                    if((bp[i].y>=(dispy-3))&&(dy<=5))
  417. X                        redo=10;
  418. X                    if((dx==0)&&(dy<=3))
  419. X                        redo=10;
  420. X                }
  421. X    
  422. X                redo++;
  423. X                break;
  424. X            case B:
  425. X                diffx=bp[i].x-bp[n].x;
  426. X                diffy=bp[i].y-bp[n].y;
  427. X                
  428. X                break;
  429. X            }
  430. X            if(n==mn)
  431. X                redo=0;
  432. X        }
  433. X        while(redo);
  434. X        bp[i].dy+=td;
  435. X        
  436. X        XFillArc(Disp,Root,GcF,bp[i].x-(radius/2),bp[i].y-(radius/2),radius,radius,0,360*64);
  437. X        XFlush(Disp);
  438. X    }
  439. X    lasttime=newtime;
  440. X}
  441. X
  442. X
  443. Xint
  444. Xgetwins()
  445. X{
  446. X    int i;
  447. X    Window dummy1,dummy2,*list;
  448. X    XWindowAttributes WAttrib;
  449. X    XEvent Event;
  450. X
  451. X    unsigned int listsize;
  452. X
  453. X    XQueryTree(Disp,Root,&dummy1,&dummy2,&list,&listsize);
  454. X
  455. X    if((listsize+2)>currmax)
  456. X    {
  457. X        if(rp!=NULL)
  458. X            free(rp);
  459. X        currmax=listsize+20;
  460. X/*        printf("currmax=%d\n",currmax);*/
  461. X        rp=(RECTANGLE*)malloc(sizeof(RECTANGLE)*currmax);
  462. X    }
  463. X    else
  464. X    {
  465. X        while(XCheckWindowEvent(Disp,Root,SubstructureNotifyMask,&Event))
  466. X        {
  467. X            while(XCheckWindowEvent(Disp,Root,SubstructureNotifyMask,&Event));
  468. X            lasttime=gettime();
  469. X            myusleep(50*1000);
  470. X        }
  471. X    }
  472. X    if(rp==NULL)
  473. X    {
  474. X        fprintf(stderr,"Failed to malloc %d bytes\n",sizeof(RECTANGLE)*listsize*2);
  475. X        exit(1);
  476. X    }
  477. X
  478. X    nor=0;
  479. X    for(i=0;i<listsize;i++)
  480. X    {
  481. X        failed=0;
  482. X        XGetWindowAttributes(Disp,list[i],&WAttrib);
  483. X        if((!failed)&&WAttrib.map_state==IsViewable)
  484. X        {
  485. X            rp[nor].x1=WAttrib.x;
  486. X            rp[nor].y1=WAttrib.y;
  487. X            rp[nor].x2=WAttrib.x+WAttrib.width;
  488. X            rp[nor].y2=WAttrib.y+WAttrib.height;
  489. X/*            printf("Window id 0x%x, x1=%d,y1=%d,x2=%d,y2=%d\n",list[nor],rp[nor].x1,rp[nor].y1,rp[nor].x2,rp[nor].y2);*/
  490. X            nor++;
  491. X        }
  492. X    }
  493. X    if(mouseflag)
  494. X    {
  495. X        mn=nor;
  496. X        nor++;
  497. X    }
  498. X    XFree(list);
  499. X}
  500. X
  501. Xmain(argc,argv)
  502. Xint argc;
  503. Xchar *argv[];
  504. X{
  505. X    unsigned long bg,fg;
  506. X    char *dispname;
  507. X    int i,j;
  508. X    int x,y;
  509. X    char *p;
  510. X    XEvent Event;
  511. X
  512. X    srand(time(0));
  513. X    dispname=getenv("DISPLAY");
  514. X    for(i=1;i<argc;i++)
  515. X    {
  516. X        p=argv[i];
  517. X        if(*p++=='-')
  518. X        {
  519. X            switch(*p++)
  520. X            {
  521. X            case 'd':
  522. X                if(*p=='\0')
  523. X                    dispname=argv[++i];
  524. X                else
  525. X                    dispname=p;
  526. X                break;
  527. X            case 'n':
  528. X                if(*p=='\0')
  529. X                    noballs=atoi(argv[++i]);
  530. X                else
  531. X                    noballs=atoi(p);
  532. X                break;
  533. X            case 'r':
  534. X                if(*p=='\0')
  535. X                    radius=atoi(argv[++i]);
  536. X                else
  537. X                    radius=atoi(p);
  538. X                break;
  539. X            case 'c':
  540. X                if(*p=='\0')
  541. X                    coeff=atoi(argv[++i]);
  542. X                else
  543. X                    coeff=atoi(p);
  544. X                break;
  545. X            case 't':
  546. X                if(*p=='\0')
  547. X                    attop=atoi(argv[++i]);
  548. X                else
  549. X                    attop=atoi(p);
  550. X                break;
  551. X            case 'b':
  552. X                backflag=(!backflag);
  553. X                break;
  554. X            case 'i':
  555. X                invertflag=(!invertflag);
  556. X                break;
  557. X            case 'm':
  558. X                mouseflag=(!mouseflag);
  559. X                break;
  560. X            case 'M':
  561. X                momentumflag=(!momentumflag);
  562. X                break;
  563. X            case 'I':
  564. X                interact=(!interact);
  565. X                break;
  566. X            case 'l':
  567. X                trailflag=(!trailflag);
  568. X                break;
  569. X            case 's':
  570. X                sizeflag=(!sizeflag);
  571. X                break;
  572. X            default:
  573. X                /* usage */
  574. X                break;
  575. X            }
  576. X        }
  577. X    }
  578. X    if(coeff>100)
  579. X        coeff=100;
  580. X    if(coeff<0)
  581. X        coeff=0;
  582. X    coeff=(0-coeff);
  583. X    bp=(BALL*)malloc(sizeof(BALL)*noballs);
  584. X    if(bp==NULL)
  585. X    {
  586. X        fprintf(stderr,"Failed to malloc %d bytes\n",sizeof(BALL)*noballs);
  587. X        exit(1);
  588. X    }
  589. X    Disp=XOpenDisplay(dispname);
  590. X
  591. X    Root=XDefaultRootWindow(Disp);
  592. X    Scr=DefaultScreen(Disp);
  593. X
  594. X    clearballs();
  595. X    if(noballs==0)
  596. X        exit(0);
  597. X
  598. X
  599. X    if(invertflag)
  600. X    {
  601. X        fg=BlackPixel(Disp,Scr);
  602. X        bg=WhitePixel(Disp,Scr);
  603. X    }
  604. X    else
  605. X    {
  606. X        bg=BlackPixel(Disp,Scr);
  607. X        fg=WhitePixel(Disp,Scr);
  608. X    }
  609. X
  610. X    GcF=XCreateGC(Disp,Root,0,0);
  611. X    GcB=XCreateGC(Disp,Root,0,0);
  612. X    XSetForeground(Disp,GcF,fg);
  613. X    XSetForeground(Disp,GcB,bg);
  614. X
  615. X    dispx=XDisplayWidth(Disp,Scr);
  616. X    dispy=XDisplayHeight(Disp,Scr);
  617. X
  618. X    if(sizeflag)
  619. X        fprintf(stderr,"Screen size is %dX by %dY\n",dispx,dispy);
  620. X
  621. X    if(backflag)
  622. X    {
  623. X        XSetWindowBackground(Disp,Root,bg);
  624. X        XClearWindow(Disp,Root);
  625. X    }
  626. X    XSelectInput(Disp,Root,SubstructureNotifyMask);
  627. X
  628. X/*    printf("Width and Height are %d,%d\n",dispx,dispy);*/
  629. X    getwins();
  630. X    XFlush(Disp);
  631. X    for(i=0;i<noballs;i++)
  632. X    {
  633. X        randomball(i);
  634. X    }
  635. X    lasttime=gettime();
  636. X    signal(SIGINT,dointr);
  637. X    signal(SIGHUP,dointr);
  638. X    signal(SIGTERM,dointr);
  639. X    XSetErrorHandler(Xerr);
  640. X    XSetIOErrorHandler(Xfatal);
  641. X    while(1)
  642. X    {
  643. X        if(XCheckWindowEvent(Disp,Root,SubstructureNotifyMask,&Event))
  644. X        {
  645. X            getwins();
  646. X        }
  647. X        doballs();
  648. X        myusleep(50*1000);
  649. X    }
  650. X}
  651. X
  652. END_OF_FILE
  653. if test 8589 -ne `wc -c <'xballs.c'`; then
  654.     echo shar: \"'xballs.c'\" unpacked with wrong size!
  655. fi
  656. # end of 'xballs.c'
  657. fi
  658. echo shar: End of archive 1 \(of 1\).
  659. cp /dev/null ark1isdone
  660. MISSING=""
  661. for I in 1 ; do
  662.     if test ! -f ark${I}isdone ; then
  663.     MISSING="${MISSING} ${I}"
  664.     fi
  665. done
  666. if test "${MISSING}" = "" ; then
  667.     echo You have the archive.
  668.     rm -f ark[1-9]isdone
  669. else
  670.     echo You still need to unpack the following archives:
  671.     echo "        " ${MISSING}
  672. fi
  673. ##  End of shell archive.
  674. exit 0
  675.