home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / games / volume18 / threedee / part01 < prev    next >
Encoding:
Internet Message Format  |  1993-09-13  |  53.1 KB

  1. Path: uunet!news.tek.com!news.cna.tek.com!not-for-mail
  2. From: billr@saab.cna.tek.com (Bill Randle)
  3. Newsgroups: comp.sources.games
  4. Subject: v18i056:  threedee - two 3d tetris games for X, Part01/04
  5. Date: 30 Aug 1993 08:34:42 -0700
  6. Organization: Tektronix, Inc., Redmond, OR
  7. Lines: 1955
  8. Approved: billr@saab.CNA.TEK.COM
  9. Message-ID: <25t6mi$fm0@saab.cna.tek.com>
  10. NNTP-Posting-Host: saab.cna.tek.com
  11. Xref: uunet comp.sources.games:1856
  12.  
  13. Submitted-by: "Andrew C. Plotkin" <ap1i+@andrew.cmu.edu>
  14. Posting-number: Volume 18, Issue 56
  15. Archive-name: threedee/part01
  16. Environment: X11, Xlib
  17.  
  18. [This is two games; tetris on a sane, cubical 3-d lattice, and tetris on
  19. a close-packed 3-d lattice of spheres. -br]
  20.  
  21. #! /bin/sh
  22. # This is a shell archive.  Remove anything before this line, then unpack
  23. # it by saving it into a file and typing "sh file".  To overwrite existing
  24. # files, type "sh file -c".  You can also feed this as standard input via
  25. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  26. # will see the following message at the end:
  27. #        "End of archive 1 (of 4)."
  28. # Contents:  README MANIFEST spatial spatial/disp.c spatial/rots.c
  29. #   spheral spheral/Makefile spheral/intro.c spheral/rots.c
  30. # Wrapped by billr@saab on Mon Aug 30 08:05:07 1993
  31. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  32. if test -f 'README' -a "${1}" != "-c" ; then 
  33.   echo shar: Will not clobber existing file \"'README'\"
  34. else
  35. echo shar: Extracting \"'README'\" \(554 characters\)
  36. sed "s/^X//" >'README' <<'END_OF_FILE'
  37. XThis is two games; tetris on a sane, cubical 3-d lattice, and tetris on
  38. Xa close-packed 3-d lattice of spheres.
  39. X
  40. XThe code of the two games is similar enough that any porting changes you
  41. Xmake to one will probably be applicable to the other.
  42. X
  43. XIf you grabbed the beta version of these games from my account, note the
  44. Xfollowing changes: the "sqrt domain error" has been fixed, and spatial
  45. Xis now in color. (Unfortunately, due to X's peculiar ideas, spheral
  46. Xcannot be displayed correctly in color. If you manage to hack this to
  47. Xwork, please let me know.)
  48. X
  49. X--Z
  50. END_OF_FILE
  51. if test 554 -ne `wc -c <'README'`; then
  52.     echo shar: \"'README'\" unpacked with wrong size!
  53. fi
  54. # end of 'README'
  55. fi
  56. if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  57.   echo shar: Will not clobber existing file \"'MANIFEST'\"
  58. else
  59. echo shar: Extracting \"'MANIFEST'\" \(2129 characters\)
  60. sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
  61. X   File Name        Archive #    Description
  62. X-----------------------------------------------------------
  63. X MANIFEST                   1    This shipping list
  64. X README                     1    
  65. X spatial                    1    
  66. X spatial/Makefile           3    
  67. X spatial/README             3    
  68. X spatial/deco.c             3    
  69. X spatial/disp.c             1    
  70. X spatial/game.c             2    
  71. X spatial/grey01.bm          3    
  72. X spatial/grey02.bm          3    
  73. X spatial/grey03.bm          3    
  74. X spatial/grey04.bm          3    
  75. X spatial/grey05.bm          3    
  76. X spatial/grey06.bm          3    
  77. X spatial/grey07.bm          3    
  78. X spatial/grey08.bm          3    
  79. X spatial/grey09.bm          3    
  80. X spatial/grey10.bm          3    
  81. X spatial/grey11.bm          3    
  82. X spatial/grey12.bm          3    
  83. X spatial/grey13.bm          3    
  84. X spatial/grey14.bm          3    
  85. X spatial/grey15.bm          3    
  86. X spatial/grey16.bm          3    
  87. X spatial/intro.c            2    
  88. X spatial/patchlevel.h       4    
  89. X spatial/rots.c             1    
  90. X spatial/score.c            3    
  91. X spatial/spatial.6          3    
  92. X spatial/spatial.c          3    
  93. X spatial/spatial.h          3    
  94. X spatial/spatial.shp        2    
  95. X spheral                    1    
  96. X spheral/Makefile           1    
  97. X spheral/README             3    
  98. X spheral/deco.c             3    
  99. X spheral/disp.c             2    
  100. X spheral/errdi.c            3    
  101. X spheral/game.c             2    
  102. X spheral/gcgrey.c           3    
  103. X spheral/grey01.bm          3    
  104. X spheral/grey02.bm          3    
  105. X spheral/grey03.bm          3    
  106. X spheral/grey04.bm          3    
  107. X spheral/grey05.bm          3    
  108. X spheral/grey06.bm          3    
  109. X spheral/grey07.bm          3    
  110. X spheral/grey08.bm          3    
  111. X spheral/grey09.bm          3    
  112. X spheral/grey10.bm          3    
  113. X spheral/grey11.bm          3    
  114. X spheral/grey12.bm          3    
  115. X spheral/grey13.bm          3    
  116. X spheral/grey14.bm          3    
  117. X spheral/grey15.bm          3    
  118. X spheral/grey16.bm          3    
  119. X spheral/intro.c            1    
  120. X spheral/patchlevel.h       2    
  121. X spheral/rots.c             1    
  122. X spheral/score.c            2    
  123. X spheral/spheral.6          2    
  124. X spheral/spheral.c          3    
  125. X spheral/spheral.h          3    
  126. X spheral/spheral.shp        3    
  127. X spheral/test.c             3    
  128. END_OF_FILE
  129. if test 2129 -ne `wc -c <'MANIFEST'`; then
  130.     echo shar: \"'MANIFEST'\" unpacked with wrong size!
  131. fi
  132. # end of 'MANIFEST'
  133. fi
  134. if test ! -d 'spatial' ; then
  135.     echo shar: Creating directory \"'spatial'\"
  136.     mkdir 'spatial'
  137. fi
  138. if test -f 'spatial/disp.c' -a "${1}" != "-c" ; then 
  139.   echo shar: Will not clobber existing file \"'spatial/disp.c'\"
  140. else
  141. echo shar: Extracting \"'spatial/disp.c'\" \(13176 characters\)
  142. sed "s/^X//" >'spatial/disp.c' <<'END_OF_FILE'
  143. X/* (C) Copyright 1991 Andrew Plotkin. Permission is
  144. X given to copy and use, as long as this copyright
  145. X notice is retained. */
  146. X
  147. X#include <stdio.h>
  148. X#include <X11/Xlib.h>
  149. X#include <X11/Xutil.h>
  150. X#include "spatial.h"
  151. X#include "grey01.bm"
  152. X#include "grey02.bm"
  153. X#include "grey03.bm"
  154. X#include "grey04.bm"
  155. X#include "grey05.bm"
  156. X#include "grey06.bm"
  157. X#include "grey07.bm"
  158. X#include "grey08.bm"
  159. X#include "grey09.bm"
  160. X#include "grey10.bm"
  161. X#include "grey11.bm"
  162. X#include "grey12.bm"
  163. X#include "grey13.bm"
  164. X#include "grey14.bm"
  165. X#include "grey15.bm"
  166. X#include "grey16.bm"
  167. X
  168. XDisplay *dpy;
  169. XWindow win;
  170. XPixmap backpm, fieldpm;
  171. XGC gcblack, gcwhite, gcinv, gccopy, gcline,
  172. Xgcfield, gccubes[16]; /* graphics contexts */
  173. Xint scn;
  174. Xint scndepth;
  175. Xint forcemono = 0;
  176. X
  177. Xpiecelist pieces[MAXPIECES];
  178. X
  179. Xshort numpieces;
  180. Xshort curpiece;
  181. X
  182. Xint dispx, dispy; /* size of window */
  183. Xint shapex1, shapex2, shapey1, shapey2;
  184. X/* coords of rectangle of backpm that is different from fieldpm */
  185. Xint ddispx1, ddispx2, ddispy1, ddispy2;
  186. X/* coords of rectangle of display that is different from fieldpm */
  187. X
  188. Xextern void dumppiece(), setup_fieldpm(),
  189. Xsetup_one_fieldpm(), draw_curpiece();
  190. X
  191. Xvoid xinit() /* using dispx, dispy */
  192. X{
  193. X    register int ix;
  194. X    XSetWindowAttributes attr;
  195. X    XGCValues gcvalues;
  196. X    static char dashes[2] = {1, 1};
  197. X    Pixmap greypm[16];
  198. X    XSizeHints hints;
  199. X    Status res;
  200. X    XColor col, sccol;
  201. X    static unsigned short colvalues[16][3] = {
  202. X    {0x0000, 0x0000, 0x0000},
  203. X    {0x6000, 0xA000, 0x6000}, /* green grey */
  204. X    {0x0000, 0x0000, 0x0000},
  205. X    {0x6000, 0x6000, 0xA000}, /* blue grey */
  206. X    {0xC000, 0x0000, 0x0000}, /* red */
  207. X    {0x0000, 0x0000, 0x0000},
  208. X    {0x0000, 0x0000, 0x0000},
  209. X    {0xAA00, 0x8000, 0x0000}, /* orange */
  210. X    {0x0000, 0x0000, 0x0000},
  211. X    {0xC000, 0xC000, 0x0000}, /* yellow */
  212. X    {0x0000, 0xC000, 0x0000}, /* green */
  213. X    {0x0000, 0x0000, 0xFF00}, /* blue */
  214. X    {0x8000, 0x0000, 0xC000}, /* purple */
  215. X    {0xFF00, 0x6000, 0x6000}, /* light red */
  216. X    {0x8000, 0x8000, 0xFF00}, /* light blue */
  217. X    {0xC000, 0xC000, 0xC000}  /* light grey */
  218. X    };
  219. X
  220. X    dpy = XOpenDisplay((char *) NULL);
  221. X    if ((Display *) NULL == dpy) {
  222. X    fprintf(stderr, "spatial: could not open display.\n");
  223. X    exit(-1);
  224. X    }
  225. X
  226. X    scn = DefaultScreen(dpy);
  227. X    scndepth = DefaultDepth(dpy, scn);
  228. X
  229. X    win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy),
  230. X    100, 100, dispx, dispy, 1, BlackPixel(dpy, scn),
  231. X    WhitePixel(dpy, scn));
  232. X
  233. X    hints.min_width = 100;
  234. X    hints.min_height = 100;
  235. X    hints.width = dispx;
  236. X    hints.height = dispy;
  237. X    hints.flags = PMinSize | PSize;
  238. X    XSetWMNormalHints(dpy, win, &hints);
  239. X
  240. X    XStoreName(dpy, win, "Spatial");
  241. X
  242. X    attr.event_mask = (KeyPressMask | ExposureMask | StructureNotifyMask);
  243. X    XChangeWindowAttributes(dpy, win, CWEventMask, &attr);
  244. X
  245. X    XSetWindowBackground(dpy, win, BlackPixel(dpy, scn));
  246. X
  247. X    XMapWindow(dpy, win);
  248. X
  249. X    gcvalues.foreground = WhitePixel(dpy, scn);
  250. X    gcvalues.background = BlackPixel(dpy, scn);
  251. X    gcwhite = XCreateGC(dpy, win, GCForeground|GCBackground,
  252. X    &gcvalues);
  253. X
  254. X    if (forcemono || DefaultDepth(dpy, scn)==1) {
  255. X
  256. X    greypm[0] = XCreatePixmapFromBitmapData(dpy, win,
  257. X    grey01_bits, grey01_width, grey01_height, 0, 1, 1);
  258. X    greypm[1] = XCreatePixmapFromBitmapData(dpy, win,
  259. X    grey02_bits, grey02_width, grey02_height, 0, 1, 1);
  260. X    greypm[2] = XCreatePixmapFromBitmapData(dpy, win,
  261. X    grey03_bits, grey03_width, grey03_height, 0, 1, 1);
  262. X    greypm[3] = XCreatePixmapFromBitmapData(dpy, win,
  263. X    grey04_bits, grey04_width, grey04_height, 0, 1, 1);
  264. X    greypm[4] = XCreatePixmapFromBitmapData(dpy, win,
  265. X    grey05_bits, grey05_width, grey05_height, 0, 1, 1);
  266. X    greypm[5] = XCreatePixmapFromBitmapData(dpy, win,
  267. X    grey06_bits, grey06_width, grey06_height, 0, 1, 1);
  268. X    greypm[6] = XCreatePixmapFromBitmapData(dpy, win,
  269. X    grey07_bits, grey07_width, grey07_height, 0, 1, 1);
  270. X    greypm[7] = XCreatePixmapFromBitmapData(dpy, win,
  271. X    grey08_bits, grey08_width, grey08_height, 0, 1, 1);
  272. X    greypm[8] = XCreatePixmapFromBitmapData(dpy, win,
  273. X    grey09_bits, grey09_width, grey09_height, 0, 1, 1);
  274. X    greypm[9] = XCreatePixmapFromBitmapData(dpy, win,
  275. X    grey10_bits, grey10_width, grey10_height, 0, 1, 1);
  276. X    greypm[10] = XCreatePixmapFromBitmapData(dpy, win,
  277. X     grey11_bits, grey11_width, grey11_height, 0, 1, 1);
  278. X    greypm[11] = XCreatePixmapFromBitmapData(dpy, win,
  279. X     grey12_bits, grey12_width, grey12_height, 0, 1, 1);
  280. X    greypm[12] = XCreatePixmapFromBitmapData(dpy, win,
  281. X     grey13_bits, grey13_width, grey13_height, 0, 1, 1);
  282. X    greypm[13] = XCreatePixmapFromBitmapData(dpy, win,
  283. X     grey14_bits, grey14_width, grey14_height, 0, 1, 1);
  284. X    greypm[14] = XCreatePixmapFromBitmapData(dpy, win,
  285. X     grey15_bits, grey15_width, grey15_height, 0, 1, 1);
  286. X    greypm[15] = XCreatePixmapFromBitmapData(dpy, win,
  287. X     grey16_bits, grey16_width, grey16_height, 0, 1, 1);
  288. X
  289. X    gcvalues.fill_style = FillOpaqueStippled;
  290. X    for (ix=0; ix<16; ix++) {
  291. X        gcvalues.stipple = greypm[ix];
  292. X        gccubes[ix] = XCreateGC(dpy, win,
  293. X        GCForeground|GCBackground|GCFillStyle|GCStipple,
  294. X        &gcvalues);
  295. X    };
  296. X    }
  297. X    else {
  298. X    for (ix=0; ix<16; ix++) {
  299. X        col.red = colvalues[ix][0];
  300. X        col.green = colvalues[ix][1];
  301. X        col.blue = colvalues[ix][2];
  302. X        res = XAllocColor(dpy, DefaultColormap(dpy, scn),
  303. X        &col);
  304. X        if (!res) {
  305. X        fprintf(stderr, "spatial: unable to allocate colors\n");
  306. X        exit(-1);
  307. X        }
  308. X        gcvalues.foreground = col.pixel;
  309. X        gccubes[ix] = XCreateGC(dpy, win, GCForeground,
  310. X        &gcvalues);
  311. X    }
  312. X
  313. X    }
  314. X
  315. X    gcvalues.foreground = WhitePixel(dpy, scn);
  316. X    gcvalues.background = BlackPixel(dpy, scn);
  317. X
  318. X    gcvalues.line_style = LineOnOffDash;
  319. X    gcfield = XCreateGC(dpy, win, GCForeground|GCLineStyle,
  320. X    &gcvalues);
  321. X
  322. X    XSetDashes(dpy, gcfield, 0, dashes, 2);
  323. X    gcvalues.line_width = 2;
  324. X    gcline = XCreateGC(dpy, win, GCForeground|GCLineWidth,
  325. X    &gcvalues);
  326. X
  327. X    gcvalues.foreground = BlackPixel(dpy, scn);
  328. X    gcblack = XCreateGC(dpy, win, GCForeground, &gcvalues);
  329. X
  330. X    gcvalues.function = GXinvert;
  331. X    gcinv = XCreateGC(dpy, win, GCForeground|GCFunction, &gcvalues);
  332. X
  333. X    gcvalues.background = WhitePixel(dpy, scn);
  334. X    gccopy = XCreateGC(dpy, win, GCForeground|GCBackground, &gcvalues);
  335. X    XSetGraphicsExposures(dpy, gccopy, 0);
  336. X
  337. X    backpm = XCreatePixmap(dpy, win, dispx, dispy, scndepth);   
  338. X    fieldpm = XCreatePixmap(dpy, win, dispx, dispy, scndepth);   
  339. X}
  340. X
  341. Xvoid setup_fieldpm() /* clear, draw field box and side
  342. X text. Also set shape{x,y}{1,2} to window size */
  343. X{
  344. X    XFillRectangle(dpy, fieldpm, gcblack, 0, 0, dispx, dispy);
  345. X    XDrawImageString(dpy, fieldpm, gcwhite, 50,
  346. X    (int)boardscale+20, "Score: ", 7); 
  347. X
  348. X    setup_one_fieldpm(fieldpts);
  349. X    if (stereo)
  350. X    setup_one_fieldpm(fieldpts2);
  351. X
  352. X    shapex1 = 0;
  353. X    shapex2 = dispx-1;
  354. X    shapey1 = 0;
  355. X    shapey2 = dispy-1;
  356. X    ddispx1 = 0;
  357. X    ddispx2 = dispx-1;
  358. X    ddispy1 = 0;
  359. X    ddispy2 = dispy-1;
  360. X    meteroldlev = 0;
  361. X}
  362. X
  363. Xvoid setup_one_fieldpm(fips)
  364. Xfieldplist fips;
  365. X{
  366. X    register int ix, iy, iz;
  367. X
  368. X    for (iz=0; iz<=fieldz; iz++) {
  369. X    XDrawLine(dpy, fieldpm, gcfield, fips[0][0][iz].x,
  370. X          fips[0][0][iz].y, fips[fieldx][0][iz].x,
  371. X          fips[fieldx][0][iz].y);
  372. X    XDrawLine(dpy, fieldpm, gcfield,
  373. X          fips[fieldx][fieldy][iz].x, fips[fieldx][fieldy][iz].y,
  374. X          fips[fieldx][0][iz].x, fips[fieldx][0][iz].y);
  375. X    XDrawLine(dpy, fieldpm, gcfield, fips[0][0][iz].x,
  376. X          fips[0][0][iz].y, fips[0][fieldy][iz].x, fips[0][fieldy][iz].y);
  377. X    XDrawLine(dpy, fieldpm, gcfield,
  378. X          fips[fieldx][fieldy][iz].x, fips[fieldx][fieldy][iz].y,
  379. X          fips[0][fieldy][iz].x, fips[0][fieldy][iz].y);
  380. X    };
  381. X    for (ix=0; ix<=fieldx; ix++) {
  382. X    XDrawLine(dpy, fieldpm, gcfield, fips[ix][0][0].x,
  383. X          fips[ix][0][0].y, fips[ix][0][fieldz].x,
  384. X          fips[ix][0][fieldz].y);
  385. X    XDrawLine(dpy, fieldpm, gcfield, fips[ix][0][0].x,
  386. X          fips[ix][0][0].y, fips[ix][fieldy][0].x, fips[ix][fieldy][0].y);
  387. X    XDrawLine(dpy, fieldpm, gcfield,
  388. X          fips[ix][fieldy][fieldz].x, fips[ix][fieldy][fieldz].y,
  389. X          fips[ix][fieldy][0].x, fips[ix][fieldy][0].y);
  390. X    }
  391. X    for (iy=1; iy<fieldy; iy++) {
  392. X    XDrawLine(dpy, fieldpm, gcfield, fips[0][iy][0].x,
  393. X          fips[0][iy][0].y, fips[0][iy][fieldz].x,
  394. X          fips[0][iy][fieldz].y);
  395. X    XDrawLine(dpy, fieldpm, gcfield, fips[fieldx][iy][0].x,
  396. X          fips[fieldx][iy][0].y, fips[0][iy][0].x,
  397. X          fips[0][iy][0].y);
  398. X    XDrawLine(dpy, fieldpm, gcfield, fips[fieldx][iy][0].x,
  399. X          fips[fieldx][iy][0].y, fips[fieldx][iy][fieldz].x,
  400. X          fips[fieldx][iy][fieldz].y);
  401. X    };
  402. X}
  403. X
  404. Xvoid draw_score(drw)
  405. XDrawable drw;
  406. X{
  407. X    static char buf[32];
  408. X    register int ix;
  409. X    long sc;
  410. X
  411. X    if (score==0) {
  412. X    XDrawImageString(dpy, drw, gcwhite, 106,
  413. X             (int)boardscale+20, "0         ", 10);
  414. X    }
  415. X    else {
  416. X    sc = score;
  417. X    ix = 32;
  418. X    buf[--ix] = '\0';
  419. X    while (sc) {
  420. X        buf[--ix] = (sc%10) + '0';
  421. X        sc /= 10;
  422. X    };
  423. X    XDrawImageString(dpy, drw, gcwhite, 106,
  424. X             (int)boardscale+20, buf+ix, 31-ix);
  425. X    }
  426. X}
  427. X
  428. Xvoid update_meter() /* on fieldpm */
  429. X{
  430. X    register int ix;
  431. X    int x1, y1, width, heigh;
  432. X    GC *gcc;
  433. X
  434. X    if (meterlev > meteroldlev) {
  435. X    for (ix=meteroldlev; ix<meterlev; ix++) {
  436. X        gcc = &(gccubes[colors[ix]]);
  437. X        x1 = meterx + metersize*ix;
  438. X        y1 = metery;
  439. X        width = metersize-1;
  440. X        heigh = 20;
  441. X        XFillRectangle(dpy, fieldpm, *gcc, x1, y1, width, heigh);
  442. X        XDrawRectangle(dpy, fieldpm, gcwhite, x1, y1,
  443. X               width, heigh);
  444. X        if (stereo) {
  445. X        x1 = meterx2 + metersize*ix;
  446. X        XFillRectangle(dpy, fieldpm, *gcc, x1, y1,
  447. X                   width, heigh);
  448. X        XDrawRectangle(dpy, fieldpm, gcwhite, x1, y1,
  449. X                   width, heigh);
  450. X        }
  451. X    }
  452. X    }
  453. X    else {
  454. X    x1 = meterx + metersize*meterlev + 1;
  455. X    y1 = metery;
  456. X    width = (meteroldlev - meterlev) * metersize;
  457. X    heigh = 20;
  458. X    XFillRectangle(dpy, fieldpm, gcblack, x1, y1, width, heigh);
  459. X    if (stereo) {
  460. X        x1 = meterx2 + metersize*meterlev + 1;
  461. X        XFillRectangle(dpy, fieldpm, gcblack, x1, y1,
  462. X               width, heigh);
  463. X    }
  464. X    }
  465. X    meteroldlev = meterlev;
  466. X    meter_f_b = 1;
  467. X}
  468. X
  469. Xvoid setup_backpm() 
  470. X{
  471. X    XCopyArea(dpy, fieldpm, backpm, gccopy, shapex1, shapey1,
  472. X          shapex2-shapex1+1, shapey2-shapey1+1, shapex1, shapey1);
  473. X    
  474. X    if (shapey2 > (int)boardscale && shapex1 < 300) {
  475. X    draw_score(backpm);
  476. X    }
  477. X
  478. X    if (meter_f_b) {
  479. X    XCopyArea(dpy, fieldpm, backpm, gccopy, meterx,
  480. X          metery, metersize*fieldz+1, 21, meterx, metery);
  481. X    if (stereo) {
  482. X        XCopyArea(dpy, fieldpm, backpm, gccopy, meterx2,
  483. X              metery, metersize*fieldz+1, 21, meterx2, metery);
  484. X    }
  485. X    meter_f_b = 0;
  486. X    meter_b_d = 1;
  487. X    }
  488. X
  489. X    if (curpiece != (-1)) {
  490. X    /* draw current piece on backpm, storing
  491. X     shape{x,y}{1,2} limits */
  492. X    draw_curpiece(backpm);
  493. X    }
  494. X}
  495. X
  496. Xvoid back_to_disp(all)
  497. Xint all; 
  498. X{
  499. X    if (all) {
  500. X    XCopyArea(dpy, backpm, win, gccopy, 0, 0,
  501. X          dispx, dispy, 0, 0);
  502. X    }
  503. X    else {
  504. X    /* copy from backpm to display; area is
  505. X     max{shape, ddisp}; */
  506. X    if (ddispx1 > shapex1) ddispx1 = shapex1;
  507. X    if (ddispy1 > shapey1) ddispy1 = shapey1;
  508. X    if (ddispx2 < shapex2) ddispx2 = shapex2;
  509. X    if (ddispy2 < shapey2) ddispy2 = shapey2;
  510. X    XCopyArea(dpy, backpm, win, gccopy, ddispx1, ddispy1,
  511. X          ddispx2-ddispx1+1, ddispy2-ddispy1+1, ddispx1, ddispy1);
  512. X
  513. X    if (meter_b_d) {
  514. X        XCopyArea(dpy, backpm, win, gccopy, meterx, metery,
  515. X              metersize*fieldz+1, 21, meterx, metery);
  516. X        if (stereo) {
  517. X        XCopyArea(dpy, backpm, win, gccopy, meterx2,
  518. X              metery, metersize*fieldz+1, 21, meterx2, metery);
  519. X        }
  520. X        meter_b_d = 0;
  521. X    }
  522. X
  523. X    /* set ddisp limits to shape limits; */
  524. X    ddispx1 = shapex1;
  525. X    ddispy1 = shapey1;
  526. X    ddispx2 = shapex2;
  527. X    ddispy2 = shapey2;
  528. X    }
  529. X}
  530. X
  531. Xvoid loadpieces(flname)
  532. Xchar *flname;
  533. X{
  534. X    register int jx, ix;
  535. X    FILE *fl;
  536. X    int res;
  537. X
  538. X    fl = fopen(flname, "r");
  539. X    if (fl==NULL) {
  540. X    fprintf(stderr, "spatial: could not open shape file.\n");
  541. X    exit(-1);
  542. X    };
  543. X
  544. X    res=fscanf(fl, "%hd\n", &numpieces);
  545. X    if (res!=1) {
  546. X    fprintf(stderr, "spatial: error 0 in shape file.\n");
  547. X    exit(-1);
  548. X    };
  549. X
  550. X    for (ix=0; ix<numpieces; ix++) {
  551. X    int in1, in2, in3;
  552. X    res=fscanf(fl, "%d, %d, %d\n", &in1, &in2, &in3);
  553. X    if (res!=3) {
  554. X        fprintf(stderr, "spatial: error 1 in shape file.\n");
  555. X        exit(-1);
  556. X    };
  557. X    pieces[ix].numcubes=in1;
  558. X    pieces[ix].numverts=in2;
  559. X    pieces[ix].numedges=in3;
  560. X    pieces[ix].numpoints=in1+in2;
  561. X    if (pieces[ix].numpoints>MAXPOINTS || pieces[ix].numedges>MAXEDGES) {
  562. X        fprintf(stderr, "spatial: shape %d is too complex.\n", ix);
  563. X        exit(-1);
  564. X    };
  565. X    for (jx=0; jx<pieces[ix].numpoints; jx++) {
  566. X        point *p = &(pieces[ix].points[jx]);
  567. X        res=fscanf(fl, "%lf, %lf, %lf\n",
  568. X               &(p->x), &(p->y), &(p->z));
  569. X        if (res!=3) {
  570. X        fprintf(stderr, "spatial: error 2 in shape file.\n");
  571. X        exit(-1);
  572. X        };
  573. X        p->w = 1.0;
  574. X    };
  575. X    pieces[ix].verts =
  576. X      &(pieces[ix].points[pieces[ix].numcubes]);
  577. X    for (jx=0; jx<pieces[ix].numedges; jx++) {
  578. X        res=fscanf(fl, "%d,%d\n", &in1, &in2);
  579. X        if (res!=2) {
  580. X        fprintf(stderr, "spatial: error 3 in shape file.\n");
  581. X        exit(-1);
  582. X        };
  583. X        pieces[ix].edges[jx].head = in1;
  584. X        pieces[ix].edges[jx].tail = in2;
  585. X    }
  586. X    }
  587. X}
  588. X
  589. Xvoid dumppiece(pnum)
  590. Xshort pnum;
  591. X{
  592. X    piecelist *p = &(pieces[pnum]);
  593. X    register int ix;
  594. X
  595. X    printf("%d cubes, %d verts, %d edges\n",
  596. X       p->numcubes, p->numverts, p->numedges);
  597. X    for (ix=0; ix<p->numpoints; ix++) {
  598. X    printf("%5.1f, %5.1f, %5.1f, %5.1f\n",
  599. X           p->points[ix].x, p->points[ix].y,
  600. X           p->points[ix].z, p->points[ix].w);
  601. X    }
  602. X    for (ix=0; ix<p->numedges; ix++) {
  603. X    printf("%d,%d\n", p->edges[ix].head,
  604. X           p->edges[ix].tail);
  605. X    };
  606. X    printf("\n");
  607. X}
  608. END_OF_FILE
  609. if test 13176 -ne `wc -c <'spatial/disp.c'`; then
  610.     echo shar: \"'spatial/disp.c'\" unpacked with wrong size!
  611. fi
  612. # end of 'spatial/disp.c'
  613. fi
  614. if test -f 'spatial/rots.c' -a "${1}" != "-c" ; then 
  615.   echo shar: Will not clobber existing file \"'spatial/rots.c'\"
  616. else
  617. echo shar: Extracting \"'spatial/rots.c'\" \(12975 characters\)
  618. sed "s/^X//" >'spatial/rots.c' <<'END_OF_FILE'
  619. X/* (C) Copyright 1991 Andrew Plotkin. Permission is
  620. X given to copy and use, as long as this copyright
  621. X notice is retained. */
  622. X
  623. X#include <stdio.h>
  624. X#include <math.h>    
  625. X#include <X11/Xlib.h>
  626. X#include "spatial.h"
  627. X
  628. Xtypedef struct _cubep {
  629. X    int x, y, z;
  630. X} cubep;
  631. X
  632. Xpoint plist[MAXPOINTS];        /* shape, arbitrarily rotated */
  633. Xpoint traplist[MAXPOINTS];  /* plist + offsets */
  634. Xpoint templist[MAXCUBES];   /* temporary version */
  635. Xdouble offx, offy, offz;
  636. Xdouble focallen, boardscale;
  637. Xint halfboard, halfboard2;
  638. Xfieldplist fieldpts;
  639. Xfieldplist fieldpts2;
  640. X
  641. Xint colors[11] = {1, 3, 4, 7, 9, 10, 11, 12, 13, 14, 15};
  642. X
  643. Xextern GC gcblack, gcwhite, gcinv, gccopy, gcline, gccubes[]; 
  644. X
  645. Xextern void updatepiece(), setup_fieldpm();
  646. Xextern void add_one_cubie(), update_meter();
  647. X
  648. Xvoid startpiece()
  649. X{
  650. X    piecelist *p;
  651. X    register int ix;
  652. X    int res;
  653. X    double flix, fliy, fliz;
  654. X
  655. X    curpiece = random() % numpieces;
  656. X    flix = (random()%2)*2-1;
  657. X    fliy = (random()%2)*2-1;
  658. X    fliz = (random()%2)*2-1;
  659. X
  660. X    p = &(pieces[curpiece]);
  661. X    for (ix=0; ix<p->numpoints; ix++) {
  662. X    plist[ix].x = flix*p->points[ix].x;
  663. X    plist[ix].y = fliy*p->points[ix].y;
  664. X    plist[ix].z = fliz*p->points[ix].z;
  665. X    plist[ix].w = p->points[ix].w;
  666. X    traplist[ix].w = plist[ix].w;
  667. X    };
  668. X    offx=0.0;
  669. X    offy=0.0;
  670. X    offz=(double)fieldz+5.0;
  671. X    updatepiece();
  672. X    res = collision(0);
  673. X    while (res>=1 && res<=6) {
  674. X    switch (res) {
  675. X        case 1:
  676. X        offz = floor(offz - 1.0 + 0.5);
  677. X        break;
  678. X        case 2:
  679. X        fprintf(stderr,
  680. X            "spatial: piece too long for board\n");
  681. X        exit(-1);
  682. X        break;
  683. X        case 3:
  684. X        offy = floor(offy + 1.0 + 0.5);
  685. X        break;
  686. X        case 4:
  687. X        offy = floor(offy - 1.0 + 0.5);
  688. X        break;
  689. X        case 5:
  690. X        offx = floor(offx - 1.0 + 0.5);
  691. X        break;
  692. X        case 6:
  693. X        offx = floor(offx + 1.0 + 0.5);
  694. X        break;
  695. X    }
  696. X    updatepiece();
  697. X    res = collision(0);
  698. X    };
  699. X    if (res==(-1)) curpiece = (-2);
  700. X}
  701. X
  702. Xvoid rotate_piece(axis, theta) /* works on plist */
  703. Xint axis;
  704. Xdouble theta;
  705. X{
  706. X    register int ix;
  707. X    double t1, t2;
  708. X    double sinth = sin(theta);
  709. X    double costh = cos(theta);
  710. X
  711. X    switch (axis) {
  712. X    case 1:
  713. X        for (ix=0; ix<pieces[curpiece].numpoints; ix++) {
  714. X        t1 = plist[ix].y;
  715. X        t2 = plist[ix].z;
  716. X        plist[ix].y = costh*t1 - sinth*t2;
  717. X        plist[ix].z = sinth*t1 + costh*t2;
  718. X        }
  719. X        break;
  720. X    case 2:
  721. X        for (ix=0; ix<pieces[curpiece].numpoints; ix++) {
  722. X        t1 = plist[ix].x;
  723. X        t2 = plist[ix].z;
  724. X        plist[ix].x = costh*t1 - sinth*t2;
  725. X        plist[ix].z = sinth*t1 + costh*t2;
  726. X        }
  727. X        break;
  728. X    case 3:
  729. X        for (ix=0; ix<pieces[curpiece].numpoints; ix++) {
  730. X        t1 = plist[ix].x;
  731. X        t2 = plist[ix].y;
  732. X        plist[ix].x = costh*t1 - sinth*t2;
  733. X        plist[ix].y = sinth*t1 + costh*t2;
  734. X        }
  735. X        break;
  736. X    }
  737. X}
  738. X
  739. Xvoid updatepiece() /* create traplist from plist+offsets */
  740. X{
  741. X    register int ix;
  742. X
  743. X    for (ix=0; ix<pieces[curpiece].numpoints; ix++) {
  744. X    traplist[ix].x = plist[ix].x + offx;
  745. X    traplist[ix].y = plist[ix].y + offy;
  746. X    traplist[ix].z = plist[ix].z + offz;
  747. X    };
  748. X}
  749. X
  750. Xvoid updatetemp_tra(xa, ya, za, taxi, tdir)
  751. Xshort xa, ya, za, taxi, tdir;
  752. X{
  753. X    register int ix;
  754. X
  755. X    switch (taxi) {
  756. X    case 0:
  757. X        for (ix=0; ix<pieces[curpiece].numcubes; ix++) {
  758. X        templist[ix].x = traplist[ix].x;
  759. X        templist[ix].y = traplist[ix].y;
  760. X        templist[ix].z = traplist[ix].z;
  761. X        };
  762. X        break;
  763. X    case 1:
  764. X        for (ix=0; ix<pieces[curpiece].numcubes; ix++) {
  765. X        templist[ix].x = plist[ix].x + offx;
  766. X        templist[ix].y = -tdir*plist[ix].z + offy;
  767. X        templist[ix].z = tdir*plist[ix].y + offz;
  768. X        };
  769. X        break;
  770. X    case 2:
  771. X        for (ix=0; ix<pieces[curpiece].numcubes; ix++) {
  772. X        templist[ix].x = -tdir*plist[ix].z + offx;
  773. X        templist[ix].y = plist[ix].y + offy;
  774. X        templist[ix].z = tdir*plist[ix].x + offz;
  775. X        };
  776. X        break;
  777. X    case 3:
  778. X        for (ix=0; ix<pieces[curpiece].numcubes; ix++) {
  779. X        templist[ix].x = -tdir*plist[ix].y + offx;
  780. X        templist[ix].y = tdir*plist[ix].x + offy;
  781. X        templist[ix].z = plist[ix].z + offz;
  782. X        };
  783. X        break;
  784. X    }
  785. X
  786. X    for (ix=0; ix<pieces[curpiece].numcubes; ix++) {
  787. X    templist[ix].x += (double)xa;
  788. X    templist[ix].y += (double)ya;
  789. X    templist[ix].z += (double)za;
  790. X    };
  791. X}
  792. X
  793. Xvoid round_piece() /* round off piece to int
  794. X offsets, halfint coords */
  795. X{
  796. X    register int ix;
  797. X
  798. X    offx = floor(offx+0.5);
  799. X    offy = floor(offy+0.5);
  800. X    offz = floor(offz+0.5);
  801. X
  802. X    for (ix=0; ix<pieces[curpiece].numpoints; ix++) {
  803. X    plist[ix].x = floor(2.0*plist[ix].x + 0.5)/2.0;
  804. X    plist[ix].y = floor(2.0*plist[ix].y + 0.5)/2.0;
  805. X    plist[ix].z = floor(2.0*plist[ix].z + 0.5)/2.0;
  806. X    };
  807. X}
  808. X
  809. Xint collision(listflag)
  810. X/* returns (in this priority)
  811. X 1: out-of-field up;
  812. X 2: ...down;
  813. X 3: ...north;
  814. X 4: ...south;
  815. X 5: ...east;
  816. X 6: ...west;
  817. X -1 for cube overlap; 
  818. X 0 for ok; 
  819. X */
  820. Xint listflag;
  821. X{
  822. X    register int ix;
  823. X    cubep cubes[MAXCUBES];
  824. X    point *pls;
  825. X
  826. X    if (listflag==0) pls = traplist;
  827. X    else pls = templist;
  828. X
  829. X    for (ix=0; ix<pieces[curpiece].numcubes; ix++) {
  830. X    cubes[ix].x = (int)(pls[ix].x+100.0) - 100;
  831. X    cubes[ix].y = (int)(pls[ix].y+100.0) - 100;
  832. X    cubes[ix].z = (int)(pls[ix].z+100.0) - 100;
  833. X
  834. X    if (cubes[ix].z < 0) return 2;
  835. X    if (cubes[ix].z >= fieldz) return 1;
  836. X    if (cubes[ix].y < 0) return 3;
  837. X    if (cubes[ix].y >= fieldy) return 4;
  838. X    if (cubes[ix].x >= fieldx) return 5;
  839. X    if (cubes[ix].x < 0) return 6;
  840. X    };
  841. X    for (ix=0; ix<pieces[curpiece].numcubes; ix++) {
  842. X    if (field[cubes[ix].x][cubes[ix].y][cubes[ix].z] & F_ON)
  843. X        return (-1);
  844. X    };
  845. X    return 0;
  846. X}
  847. X
  848. Xvoid setup_cubies()
  849. X{
  850. X    register int ix, iy, iz;
  851. X    double wcoord;
  852. X
  853. X    for (ix=0; ix<=fieldx; ix++)
  854. X    for (iy=0; iy<=fieldy; iy++)
  855. X        for (iz=0; iz<=fieldz; iz++) {
  856. X        wcoord = -((double)iz+fieldoffz)/focallen + 1.0;
  857. X        fieldpts[ix][iy][iz].x = halfboard +
  858. X          (int)(boardscale*((double)ix+fieldoffx)/wcoord);
  859. X        fieldpts[ix][iy][iz].y = halfboard +
  860. X          (int)(boardscale*((double)iy+fieldoffy)/wcoord);
  861. X        }
  862. X
  863. X    if (stereo) {
  864. X    for (ix=0; ix<=fieldx; ix++)
  865. X        for (iy=0; iy<=fieldy; iy++)
  866. X        for (iz=0; iz<=fieldz; iz++) {
  867. X            wcoord = -((double)iz+fieldoffz)/focallen + 1.0;
  868. X            fieldpts2[ix][iy][iz].x = halfboard2 +
  869. X              (int)(boardscale*((double)ix+fieldoffx2) / wcoord);
  870. X            fieldpts2[ix][iy][iz].y = halfboard +
  871. X              (int)(boardscale*((double)iy+fieldoffy) / wcoord);
  872. X        }
  873. X    }
  874. X}
  875. X
  876. Xvoid add_cubie(cx, cy, cz)
  877. Xint cx, cy, cz;
  878. X{
  879. X    add_one_cubie(fieldpts, cx, cy, cz);
  880. X    if (stereo)
  881. X    add_one_cubie(fieldpts2, cx, cy, cz);
  882. X}
  883. X
  884. Xvoid add_one_cubie(fips, cx, cy, cz)
  885. Xfieldplist fips;
  886. Xint cx, cy, cz;
  887. X{
  888. X    int x1, y1, width, heigh;
  889. X    XPoint face[5];
  890. X    GC *gcc;
  891. X
  892. X    gcc = &(gccubes[colors[cz]]);
  893. X    x1 = fips[cx][cy][cz+1].x;
  894. X    y1 = fips[cx][cy][cz+1].y;
  895. X    width = fips[cx+1][cy+1][cz+1].x - x1 + 1;
  896. X    heigh = fips[cx+1][cy+1][cz+1].y - y1 + 1;
  897. X    XFillRectangle(dpy, fieldpm, *gcc, x1, y1, width, heigh);
  898. X    XDrawRectangle(dpy, fieldpm, gcwhite, x1, y1, width, heigh);
  899. X
  900. X    x1 = cx - fieldx/2;
  901. X    if (x1<0) {
  902. X    face[0].x = fips[cx+1][cy][cz+1].x;
  903. X    face[0].y = fips[cx+1][cy][cz+1].y;
  904. X    face[1].x = fips[cx+1][cy][cz].x;
  905. X    face[1].y = fips[cx+1][cy][cz].y;
  906. X    face[2].x = fips[cx+1][cy+1][cz].x;
  907. X    face[2].y = fips[cx+1][cy+1][cz].y;
  908. X    face[3].x = fips[cx+1][cy+1][cz+1].x;
  909. X    face[3].y = fips[cx+1][cy+1][cz+1].y;
  910. X    face[4].x = face[0].x;
  911. X    face[4].y = face[0].y;
  912. X    XFillPolygon(dpy, fieldpm, *gcc, face, 4,
  913. X             Convex, CoordModeOrigin);
  914. X    XDrawLines(dpy, fieldpm, gcwhite, face, 5,
  915. X           CoordModeOrigin);
  916. X    }
  917. X    else if (x1>0) {
  918. X    face[0].x = fips[cx][cy][cz+1].x;
  919. X    face[0].y = fips[cx][cy][cz+1].y;
  920. X    face[1].x = fips[cx][cy][cz].x;
  921. X    face[1].y = fips[cx][cy][cz].y;
  922. X    face[2].x = fips[cx][cy+1][cz].x;
  923. X    face[2].y = fips[cx][cy+1][cz].y;
  924. X    face[3].x = fips[cx][cy+1][cz+1].x;
  925. X    face[3].y = fips[cx][cy+1][cz+1].y;
  926. X    face[4].x = face[0].x;
  927. X    face[4].y = face[0].y;
  928. X    XFillPolygon(dpy, fieldpm, *gcc, face, 4,
  929. X             Convex, CoordModeOrigin);
  930. X    XDrawLines(dpy, fieldpm, gcwhite, face, 5,
  931. X           CoordModeOrigin);
  932. X    };
  933. X
  934. X    y1 = cy - fieldy/2;
  935. X    if (y1>0) {
  936. X    face[0].x = fips[cx][cy][cz+1].x;
  937. X    face[0].y = fips[cx][cy][cz+1].y;
  938. X    face[1].x = fips[cx][cy][cz].x;
  939. X    face[1].y = fips[cx][cy][cz].y;
  940. X    face[2].x = fips[cx+1][cy][cz].x;
  941. X    face[2].y = fips[cx+1][cy][cz].y;
  942. X    face[3].x = fips[cx+1][cy][cz+1].x;
  943. X    face[3].y = fips[cx+1][cy][cz+1].y;
  944. X    face[4].x = face[0].x;
  945. X    face[4].y = face[0].y;
  946. X    XFillPolygon(dpy, fieldpm, *gcc, face, 4,
  947. X             Convex, CoordModeOrigin);
  948. X    XDrawLines(dpy, fieldpm, gcwhite, face, 5,
  949. X           CoordModeOrigin);
  950. X    }
  951. X    else if (y1<0) {
  952. X    face[0].x = fips[cx][cy+1][cz+1].x;
  953. X    face[0].y = fips[cx][cy+1][cz+1].y;
  954. X    face[1].x = fips[cx][cy+1][cz].x;
  955. X    face[1].y = fips[cx][cy+1][cz].y;
  956. X    face[2].x = fips[cx+1][cy+1][cz].x;
  957. X    face[2].y = fips[cx+1][cy+1][cz].y;
  958. X    face[3].x = fips[cx+1][cy+1][cz+1].x;
  959. X    face[3].y = fips[cx+1][cy+1][cz+1].y;
  960. X    face[4].x = face[0].x;
  961. X    face[4].y = face[0].y;
  962. X    XFillPolygon(dpy, fieldpm, *gcc, face, 4,
  963. X             Convex, CoordModeOrigin);
  964. X    XDrawLines(dpy, fieldpm, gcwhite, face, 5,
  965. X           CoordModeOrigin);
  966. X    };
  967. X}
  968. X
  969. Xvoid add_cubies(lev)
  970. Xint lev;
  971. X{
  972. X    register int ix, iy, iz;
  973. X
  974. X    for (iz=lev; iz<fieldz; iz++) {
  975. X    for (ix=0; ix<fieldx/2; ix++) {
  976. X        for (iy=0; iy<fieldy/2; iy++) {
  977. X        if (field[ix][iy][iz] & F_ON) {
  978. X            add_cubie(ix, iy, iz);
  979. X        }
  980. X        }
  981. X        for (iy=fieldy-1; iy>=fieldy/2; iy--) {        
  982. X        if (field[ix][iy][iz] & F_ON) {
  983. X            add_cubie(ix, iy, iz);
  984. X        }
  985. X        }
  986. X    }
  987. X    for (ix=fieldx-1; ix>=fieldx/2; ix--) {
  988. X        for (iy=0; iy<fieldy/2; iy++) {
  989. X        if (field[ix][iy][iz] & F_ON) {
  990. X            add_cubie(ix, iy, iz);
  991. X        }
  992. X        }
  993. X        for (iy=fieldy-1; iy>=fieldy/2; iy--) {
  994. X        if (field[ix][iy][iz] & F_ON) {
  995. X            add_cubie(ix, iy, iz);
  996. X        }
  997. X        }
  998. X    }
  999. X    };
  1000. X    if (meterlev != meteroldlev) {
  1001. X    update_meter();
  1002. X    }
  1003. X}
  1004. X
  1005. Xvoid redraw_cubies()
  1006. X{
  1007. X    register int ix, iy, iz;
  1008. X
  1009. X    for (iz=0; iz<fieldz; iz++) {
  1010. X    for (ix=0; ix<fieldx/2; ix++) {
  1011. X        for (iy=0; iy<fieldy/2; iy++) {
  1012. X        if (field[ix][iy][iz] & F_ON) {
  1013. X            add_cubie(ix, iy, iz);
  1014. X        }
  1015. X        }
  1016. X        for (iy=fieldy-1; iy>=fieldy/2; iy--) {        
  1017. X        if (field[ix][iy][iz] & F_ON) {
  1018. X            add_cubie(ix, iy, iz);
  1019. X        }
  1020. X        }
  1021. X    }
  1022. X    for (ix=fieldx-1; ix>=fieldx/2; ix--) {
  1023. X        for (iy=0; iy<fieldy/2; iy++) {
  1024. X        if (field[ix][iy][iz] & F_ON) {
  1025. X            add_cubie(ix, iy, iz);
  1026. X        }
  1027. X        }
  1028. X        for (iy=fieldy-1; iy>=fieldy/2; iy--) {
  1029. X        if (field[ix][iy][iz] & F_ON) {
  1030. X            add_cubie(ix, iy, iz);
  1031. X        }
  1032. X        }
  1033. X    }
  1034. X    }
  1035. X    if (meterlev != meteroldlev) {
  1036. X    update_meter();
  1037. X    }
  1038. X}
  1039. X
  1040. Xvoid plop_piece()
  1041. X{
  1042. X    register int ix, iy, iz;
  1043. X    int cubx, cuby, cubz;
  1044. X    int dirx, diry;
  1045. X    int lev = fieldz+1;
  1046. X
  1047. X    for (ix=0; ix<pieces[curpiece].numcubes; ix++) {
  1048. X    cubx = (int)(traplist[ix].x+100.0) - 100;
  1049. X    cuby = (int)(traplist[ix].y+100.0) - 100;
  1050. X    cubz = (int)(traplist[ix].z+100.0) - 100;
  1051. X    if (cubz < lev) lev = cubz;
  1052. X    if (cubz+1 > meterlev) meterlev = cubz+1;
  1053. X    field[cubx][cuby][cubz] |= F_ON;
  1054. X    };
  1055. X    add_cubies(lev);
  1056. X
  1057. X    /* settle */
  1058. X    while (1) {
  1059. X    int full;
  1060. X    for (iz=fieldz-1; iz>=0; iz--) {
  1061. X        full=1;
  1062. X        for (ix=0; full && (ix<fieldx); ix++) {
  1063. X        for (iy=0; full && (iy<fieldy); iy++) {
  1064. X            if (!(field[ix][iy][iz] & F_ON)) full = 0;
  1065. X        }
  1066. X        }
  1067. X        if (full) break;
  1068. X    }
  1069. X    if (iz<0) break;
  1070. X    for (; iz<fieldz-1; iz++) 
  1071. X        for (ix=0; ix<fieldx; ix++)
  1072. X        for (iy=0; iy<fieldy; iy++)
  1073. X            field[ix][iy][iz] = field[ix][iy][iz+1];
  1074. X    for (ix=0; ix<fieldx; ix++)
  1075. X        for (iy=0; iy<fieldy; iy++)
  1076. X        field[ix][iy][fieldz-1] = 0;
  1077. X    score += 20*fieldx*fieldy;
  1078. X    if (dropticks > 10) dropticks -= 6;
  1079. X    meterlev--;
  1080. X    setup_fieldpm();
  1081. X    redraw_cubies();
  1082. X    }
  1083. X}
  1084. X
  1085. Xvoid draw_curpiece(drw)
  1086. XDrawable drw;
  1087. X{
  1088. X    register int ix;
  1089. X    static point scoor[MAXVERTS];
  1090. X    static point scoor2[MAXVERTS];
  1091. X    static XSegment xpl[MAXEDGES*2];
  1092. X    double wcoord;
  1093. X    int poff = pieces[curpiece].numcubes;
  1094. X    int nume = pieces[curpiece].numedges;
  1095. X    edge *e = pieces[curpiece].edges;
  1096. X
  1097. X    shapex1 = dispx;
  1098. X    shapex2 = 0;
  1099. X    shapey1 = dispy;
  1100. X    shapey2 = 0;
  1101. X    for (ix=0; ix<pieces[curpiece].numverts; ix++) {
  1102. X    wcoord = -(traplist[ix+poff].z+fieldoffz)/focallen + 1.0;
  1103. X    scoor[ix].x = halfboard +
  1104. X      (int)(boardscale*(traplist[ix+poff].x+fieldoffx)/wcoord);
  1105. X    scoor[ix].y = halfboard +
  1106. X      (int)(boardscale*(traplist[ix+poff].y+fieldoffy)/wcoord);
  1107. X    if (shapex1>scoor[ix].x-1) shapex1=scoor[ix].x-1;
  1108. X    if (shapey1>scoor[ix].y-1) shapey1=scoor[ix].y-1;
  1109. X    if (shapex2<scoor[ix].x+1) shapex2=scoor[ix].x+1;
  1110. X    if (shapey2<scoor[ix].y+1) shapey2=scoor[ix].y+1;
  1111. X    if (stereo) {
  1112. X        scoor2[ix].x = halfboard2 +
  1113. X          (int)(boardscale*(traplist[ix+poff].x+fieldoffx2)
  1114. X            / wcoord);
  1115. X        if (shapex2<scoor2[ix].x+1) shapex2=scoor2[ix].x+1;
  1116. X    }
  1117. X    }
  1118. X
  1119. X    if (!stereo) {
  1120. X    for (ix=0; ix<nume; ix++) {
  1121. X        xpl[ix].x1 = scoor[e[ix].head].x;
  1122. X        xpl[ix].y1 = scoor[e[ix].head].y;
  1123. X        xpl[ix].x2 = scoor[e[ix].tail].x;
  1124. X        xpl[ix].y2 = scoor[e[ix].tail].y;
  1125. X    }
  1126. X    XDrawSegments(dpy, drw, gcline, xpl, nume);
  1127. X    }
  1128. X    else {
  1129. X    for (ix=0; ix<nume; ix++) {
  1130. X        xpl[ix].x1 = scoor[e[ix].head].x;
  1131. X        xpl[ix].y1 = scoor[e[ix].head].y;
  1132. X        xpl[ix].x2 = scoor[e[ix].tail].x;
  1133. X        xpl[ix].y2 = scoor[e[ix].tail].y;
  1134. X        xpl[nume+ix].x1 = scoor2[e[ix].head].x;
  1135. X        xpl[nume+ix].y1 = xpl[ix].y1;
  1136. X        xpl[nume+ix].x2 = scoor2[e[ix].tail].x;
  1137. X        xpl[nume+ix].y2 = xpl[ix].y2;
  1138. X    }
  1139. X    XDrawSegments(dpy, drw, gcline, xpl, 2*nume);
  1140. X    }
  1141. X}
  1142. END_OF_FILE
  1143. if test 12975 -ne `wc -c <'spatial/rots.c'`; then
  1144.     echo shar: \"'spatial/rots.c'\" unpacked with wrong size!
  1145. fi
  1146. # end of 'spatial/rots.c'
  1147. fi
  1148. if test ! -d 'spheral' ; then
  1149.     echo shar: Creating directory \"'spheral'\"
  1150.     mkdir 'spheral'
  1151. fi
  1152. if test -f 'spheral/Makefile' -a "${1}" != "-c" ; then 
  1153.   echo shar: Will not clobber existing file \"'spheral/Makefile'\"
  1154. else
  1155. echo shar: Extracting \"'spheral/Makefile'\" \(1471 characters\)
  1156. sed "s/^X//" >'spheral/Makefile' <<'END_OF_FILE'
  1157. X# The next lines define the directories where the executable, piece file,
  1158. X# and score file are installed. Change them to whatever is appropriate.
  1159. XDESTDIR = /tmp/dest
  1160. XDESTLIBDIR = $(DESTDIR)/lib
  1161. XDESTBINDIR = $(DESTDIR)/bin
  1162. XDESTMANDIR = $(DESTDIR)/man
  1163. X
  1164. XSCOREFILE = $(DESTLIBDIR)/spheral.sco
  1165. XPIECEFILE = $(DESTLIBDIR)/spheral.shp
  1166. X
  1167. XDEFINES =
  1168. X
  1169. X# uncomment the next line if your system doesn't have
  1170. X# random() and srandom()
  1171. X#DEFINES = -Drandom=lrand48 -Dsrandom=srand48
  1172. X
  1173. X# uncomment the next line for Solaris, which has neither
  1174. X# flock() nor random().
  1175. X#DEFINES = -DUSELOCKF -Drandom=lrand48 -Dsrandom=srand48
  1176. X
  1177. XINCLUDES = -I/usr/local/include
  1178. XXLIBS = -L/usr/local/lib -lX11
  1179. X
  1180. XOBJS = spheral.o disp.o game.o rots.o intro.o   \
  1181. X   deco.o score.o gcgrey.o errdi.o
  1182. X
  1183. XCFLAGS= -O $(DEFINES) $(INCLUDES)  \
  1184. X   -DSCOREFILENAME=\"$(SCOREFILE)\"  \
  1185. X   -DPIECEFILENAME=\"$(PIECEFILE)\"
  1186. X
  1187. Xall: spheral
  1188. X
  1189. Xspheral: $(OBJS)
  1190. X    $(CC) $(CFLAGS) $(OBJS) -o spheral $(XLIBS) -lm 
  1191. X
  1192. Xspheral.o: spheral.c spheral.h
  1193. Xdisp.o: disp.c spheral.h
  1194. Xgame.o: game.c spheral.h
  1195. Xrots.o: rots.c spheral.h
  1196. Xintro.o: intro.c spheral.h
  1197. Xdeco.o: deco.c spheral.h
  1198. Xgcgrey.o: gcgrey.c spheral.h
  1199. Xerrdi.o: errdi.c spheral.h
  1200. Xscore.o: score.c spheral.h
  1201. X
  1202. Xtargetdirs:
  1203. X    -mkdir $(DESTLIBDIR)
  1204. X    -mkdir $(DESTBINDIR)
  1205. X    -mkdir $(DESTMANDIR)
  1206. X    -mkdir $(DESTMANDIR)/man6
  1207. X
  1208. Xinstall: spheral  targetdirs
  1209. X    install -c -s spheral $(DESTBINDIR)
  1210. X    install -c spheral.shp  $(PIECEFILE)
  1211. X    install -c spheral.6 $(DESTMANDIR)/man6
  1212. X
  1213. Xclean: 
  1214. X    rm -f *.o spheral
  1215. X
  1216. END_OF_FILE
  1217. if test 1471 -ne `wc -c <'spheral/Makefile'`; then
  1218.     echo shar: \"'spheral/Makefile'\" unpacked with wrong size!
  1219. fi
  1220. # end of 'spheral/Makefile'
  1221. fi
  1222. if test -f 'spheral/intro.c' -a "${1}" != "-c" ; then 
  1223.   echo shar: Will not clobber existing file \"'spheral/intro.c'\"
  1224. else
  1225. echo shar: Extracting \"'spheral/intro.c'\" \(5768 characters\)
  1226. sed "s/^X//" >'spheral/intro.c' <<'END_OF_FILE'
  1227. X/* (C) Copyright 1991 Andrew Plotkin. Permission is
  1228. X given to copy and use, as long as this copyright
  1229. X notice is retained. */
  1230. X
  1231. X#include <stdio.h>
  1232. X#include <sys/time.h>
  1233. X#include <X11/Xlib.h>
  1234. X#include <X11/keysym.h>
  1235. X#include "spheral.h"
  1236. X
  1237. X#define TICKLENGTH (50000)
  1238. X#define xputs(x, y, str)  \
  1239. XXDrawImageString(dpy, win, gcwhite, x, y, str, strlen(str))
  1240. X#define xline(x1, y1, x2, y2)  \
  1241. XXDrawLine(dpy, win, gcwhite, x1, y1, x2, y2) 
  1242. X#define xlineo(x1, y1, x2, y2)  \
  1243. XXDrawLine(dpy, win, gcocto, x1, y1, x2, y2) 
  1244. X
  1245. Xextern gamer hscores[NUMGAMERS];
  1246. Xextern GC gcblack, gcwhite, gccopy, gcline, gcfield, gcocto; 
  1247. Xextern int errdiflag;
  1248. X
  1249. Xextern void intro_redraw(), redo_board_globals();
  1250. X
  1251. Xvoid initintro()
  1252. X{
  1253. X    intro_redraw();
  1254. X}
  1255. X
  1256. Xvoid introloop()
  1257. X{
  1258. X    short status, res;
  1259. X    Bool eventp;
  1260. X    XEvent event, nextevent;
  1261. X    long evmasks;
  1262. X    char key;
  1263. X    KeySym ksym;
  1264. X    long lasttime;
  1265. X    struct timeval tv;
  1266. X    fd_set readbits;
  1267. X
  1268. X    while (1) {
  1269. X    tv.tv_sec = 0;
  1270. X    tv.tv_usec = TICKLENGTH;
  1271. X    FD_ZERO(&readbits);
  1272. X    FD_SET(ConnectionNumber(dpy), &readbits);
  1273. X    (void)select(1+ConnectionNumber(dpy), &readbits, 0, 0, &tv);
  1274. X
  1275. X    evmasks = (KeyPressMask | ExposureMask
  1276. X           | StructureNotifyMask);
  1277. X    eventp = XCheckWindowEvent(dpy, win, evmasks, &event);
  1278. X    if (eventp) switch (event.type) {
  1279. X        case Expose:
  1280. X        eventp = XCheckWindowEvent(dpy, win,
  1281. X            evmasks, &nextevent);
  1282. X        while (eventp && nextevent.type == Expose) {
  1283. X            eventp = XCheckWindowEvent(dpy, win,
  1284. X            evmasks, &nextevent);
  1285. X        };
  1286. X        if (eventp) {
  1287. X            XPutBackEvent(dpy, &nextevent);
  1288. X        };
  1289. X        intro_redraw();
  1290. X        break;
  1291. X        case KeyPress:
  1292. X        XLookupString(&event, &key, 1, &ksym, NULL);
  1293. X        /*printf("got '%s'\n", XKeysymToString(ksym));*/
  1294. X        switch (ksym) {
  1295. X            case XK_q:
  1296. X            case XK_Q:
  1297. X            exit(0);
  1298. X            break;
  1299. X            case XK_c:
  1300. X            case XK_C:
  1301. X            errdiflag = !errdiflag;
  1302. X            intro_redraw();
  1303. X            break;
  1304. X            case XK_s:
  1305. X            case XK_S:
  1306. X            return;
  1307. X        };
  1308. X        break;
  1309. X        case ConfigureNotify:
  1310. X        if (event.xconfigure.width != dispx
  1311. X            || event.xconfigure.height != dispy) {
  1312. X            dispx = event.xconfigure.width;
  1313. X            dispy = event.xconfigure.height;
  1314. X            redo_board_globals();
  1315. X            XFreePixmap(dpy, backpm);
  1316. X            XFreePixmap(dpy, fieldpm);
  1317. X            backpm = XCreatePixmap(dpy, win, dispx,
  1318. X            dispy, scndepth);   
  1319. X            fieldpm = XCreatePixmap(dpy, win, dispx,
  1320. X            dispy, scndepth);   
  1321. X        }
  1322. X        break;
  1323. X    }
  1324. X    }
  1325. X}
  1326. X
  1327. Xvoid intro_redraw()
  1328. X{
  1329. X    register int ix;
  1330. X    char buf[255];
  1331. X
  1332. X    XFillRectangle(dpy, win, gcblack, 0, 0, dispx, dispy);
  1333. X    xputs(50, 50, "Spheral");
  1334. X    xputs(50, 100, "A Sadistic Software Production");
  1335. X    xputs(50, 120, "(C) Copyright 1991-3 Andrew Plotkin");
  1336. X    xputs(50, 140, " (ap1i@andrew.cmu.edu)");
  1337. X    if (score!=(-1)) {
  1338. X    sprintf(buf, "Your score: %d", score);
  1339. X    xputs(50, 160, buf);
  1340. X    }
  1341. X
  1342. X    xputs(50, 180, "Commands:");
  1343. X    xputs(70, 200, "s: start game");
  1344. X    xputs(70, 220, "Escape: pause");
  1345. X    if (!errdiflag)
  1346. X    xputs(70, 240, "c: change display mode (now boring)");
  1347. X    else
  1348. X    xputs(70, 240, "c: change display mode (now neato)");
  1349. X    xputs(70, 260, "Q: quit program");
  1350. X
  1351. X    xputs(350, 150, "High Scores:");
  1352. X    for (ix=0; ix<NUMGAMERS; ix++) {
  1353. X    xputs(390, 170+20*ix, hscores[ix].name);
  1354. X    xputs(490, 170+20*ix, hscores[ix].userid);
  1355. X    xputs(590, 170+20*ix, hscores[ix].scoret);
  1356. X    };
  1357. X
  1358. X    xline(50, 320, 190, 320);
  1359. X    xline(90, 290, 165, 360);
  1360. X    xline(75, 360, 150, 290);
  1361. X    xputs(64, 325, "4j");
  1362. X    xputs(163, 325, "6l");
  1363. X    xputs(96, 304, "7u");
  1364. X    xputs(135, 304, "9o");
  1365. X    xputs(84, 346, "1m");
  1366. X    xputs(145, 346, "3.");
  1367. X
  1368. X    xline(70, 385, 170, 385);
  1369. X    xline(75, 385, 70, 390);
  1370. X    xline(75, 385, 70, 380);
  1371. X    xline(165, 385, 170, 390);
  1372. X    xline(165, 385, 170, 380);
  1373. X    xputs(111, 390, " v ");
  1374. X
  1375. X    XDrawArc(dpy, win, gcfield, 50, 410, 140, 140, 0, 23040);
  1376. X
  1377. X    XDrawArc(dpy, win, gcfield, 50, 470, 140, 20, 0, 23040);
  1378. X    XDrawArc(dpy, win, gcfield, 50, 469, 140, 22, 11520, 11520);
  1379. X
  1380. X    XDrawArc(dpy, win, gcwhite, 50, 480, 140, 20, 18000, 2880);
  1381. X    XDrawArc(dpy, win, gcwhite, 50, 480, 140, 20, 13680, 2880);
  1382. X    XDrawArc(dpy, win, gcwhite, 50, 482, 140, 20, 18000, 2880);
  1383. X    XDrawArc(dpy, win, gcwhite, 50, 482, 140, 20, 13680, 2880);
  1384. X    xline(59, 496, 65, 502);
  1385. X    xline(59, 496, 65, 492);
  1386. X    xline(181, 496, 175, 502);
  1387. X    xline(181, 496, 175, 492);
  1388. X
  1389. X    XDrawArc(dpy, win, gcfield, 70, 410, 100, 140, 0, 23040);
  1390. X    XDrawArc(dpy, win, gcfield, 69, 410, 102, 140, 5760, 11520);
  1391. X    XDrawArc(dpy, win, gcfield, 69, 410, 102, 140, 17280, 11520);
  1392. X
  1393. X    XDrawArc(dpy, win, gcwhite, 110, 410, 100, 140, 18720, 2880);
  1394. X    XDrawArc(dpy, win, gcwhite, 110, 410, 100, 140, 1440, 2880);
  1395. X    XDrawArc(dpy, win, gcwhite, 114, 410, 92, 140, 18720, 2880);
  1396. X    XDrawArc(dpy, win, gcwhite, 114, 410, 92, 140, 1440, 2880);
  1397. X    xline(177, 415, 190, 420);
  1398. X    xline(177, 415, 180, 420);
  1399. X    xline(177, 545, 190, 540);
  1400. X    xline(177, 545, 180, 540);
  1401. X
  1402. X    XDrawArc(dpy, win, gcwhite, 30, 410, 100, 140, 12960, 2880);
  1403. X    XDrawArc(dpy, win, gcwhite, 30, 410, 100, 140, 7200, 2880);
  1404. X    XDrawArc(dpy, win, gcwhite, 34, 410, 92, 140, 12960, 2880);
  1405. X    XDrawArc(dpy, win, gcwhite, 34, 410, 92, 140, 7200, 2880);
  1406. X    xline(63, 415, 50, 420);
  1407. X    xline(63, 415, 60, 420);
  1408. X    xline(63, 545, 50, 540);
  1409. X    xline(63, 545, 60, 540);
  1410. X
  1411. X    XDrawArc(dpy, win, gcfield, 90, 410, 60, 140, 0, 23040);
  1412. X
  1413. X    xlineo(70, 486, 90, 472);
  1414. X    xlineo(72, 486, 168, 486);
  1415. X    xlineo(90, 472, 150, 472);
  1416. X    xlineo(168, 486, 150, 472);
  1417. X
  1418. X    xputs(112, 504, "s g");
  1419. X    xputs(32, 500, "d");
  1420. X    xputs(32, 468, "r");
  1421. X    xputs(204, 500, "f");
  1422. X    xputs(204, 468, "e");
  1423. X
  1424. X    /*xlineo(120, 410, 70, 486);
  1425. X    xlineo(120, 410, 90, 472);
  1426. X    xlineo(120, 410, 150, 472);
  1427. X    xlineo(120, 410, 168, 486);
  1428. X    xlineo(120, 550, 70, 486);
  1429. X    xlineo(120, 550, 90, 472);
  1430. X    xlineo(120, 550, 150, 472);
  1431. X    xlineo(120, 550, 168, 486);*/
  1432. X}
  1433. END_OF_FILE
  1434. if test 5768 -ne `wc -c <'spheral/intro.c'`; then
  1435.     echo shar: \"'spheral/intro.c'\" unpacked with wrong size!
  1436. fi
  1437. # end of 'spheral/intro.c'
  1438. fi
  1439. if test -f 'spheral/rots.c' -a "${1}" != "-c" ; then 
  1440.   echo shar: Will not clobber existing file \"'spheral/rots.c'\"
  1441. else
  1442. echo shar: Extracting \"'spheral/rots.c'\" \(11934 characters\)
  1443. sed "s/^X//" >'spheral/rots.c' <<'END_OF_FILE'
  1444. X/* (C) Copyright 1991 Andrew Plotkin. Permission is
  1445. X given to copy and use, as long as this copyright
  1446. X notice is retained. */
  1447. X
  1448. X#include <stdio.h>
  1449. X#include <math.h>    
  1450. X#include <X11/Xlib.h>
  1451. X#include "spheral.h"
  1452. X
  1453. Xtypedef struct _ballp {
  1454. X    int x, y, z;
  1455. X} ballp;
  1456. X
  1457. Xpoint plist[MAXBALLS];        
  1458. Xpoint traplist[MAXBALLS];   
  1459. Xpoint templist[MAXBALLS];   
  1460. Xint aspectflag = 0;
  1461. Xdouble aspect;
  1462. Xdouble offx, offy, offz;
  1463. Xdouble focallen, boardscale;
  1464. Xint halfboardx, halfboardy;
  1465. Xfieldplist fieldpts;
  1466. Xfieldrlist fieldrads;
  1467. X
  1468. Xint colors[12] = {1, 3, 7, 15, 1, 3, 7, 15, 1, 3, 7, 15};
  1469. X
  1470. Xextern GC gcwhite, gcblack, gcfield, gcadd,
  1471. Xgccopy, gcballs[];
  1472. Xextern Pixmap ballpm[NUMBALLSIZES][NUMSHADES];
  1473. Xextern short ballpmflag[NUMBALLSIZES][NUMSHADES];
  1474. Xextern int errdiflag; 
  1475. X
  1476. Xextern void updatepiece(), round_piece(), measure_curpiece(),
  1477. Xrotate_axis();
  1478. Xextern void create_ballpm();
  1479. X
  1480. Xvoid startpiece()
  1481. X{
  1482. X    register int ix;
  1483. X    int res;
  1484. X    piecelist *p;
  1485. X    int flix = (random() % 2)*2-1;
  1486. X    int fliy = (random() % 2)*2-1;
  1487. X    int fliz = (random() % 2)*2-1;
  1488. X
  1489. X    curpiece = random() % numpieces;
  1490. X
  1491. X    p = &(pieces[curpiece]);
  1492. X    for (ix=0; ix<p->numballs; ix++) {
  1493. X    plist[ix].x = flix*p->points[ix].x;
  1494. X    plist[ix].y = fliy*p->points[ix].y;
  1495. X    plist[ix].z = fliz*p->points[ix].z;
  1496. X    plist[ix].w = p->points[ix].w;
  1497. X    traplist[ix].w = plist[ix].w;
  1498. X    };
  1499. X    {
  1500. X    int initx = fieldx/4;
  1501. X    int inity = initx;
  1502. X    int initz = fieldz+4;
  1503. X    offz = ((double)initz) - 0.5*inity - 0.5;
  1504. X    offy = ROOTHALF*((double)inity);
  1505. X    offx = ((double)initx) + 0.5*inity + 0.5;
  1506. X    }
  1507. X    updatepiece();
  1508. X
  1509. X    res = collision(0);
  1510. X    while (res!=OUT_NOT && res!=OUT_COLLIDE) {
  1511. X    switch (res) {
  1512. X        case OUT_UP:
  1513. X        offz = offz - 1.0 ;
  1514. X        break;
  1515. X        case OUT_DOWN:
  1516. X        fprintf(stderr,
  1517. X            "spheral: piece too long for board\n");
  1518. X        exit(-1);
  1519. X        break;
  1520. X        case OUT_NORTHEAST:
  1521. X        offx = offx - 0.5;
  1522. X        offy = offy - ROOTHALF;
  1523. X        offz = offz + 0.5;
  1524. X        break;
  1525. X        case OUT_SOUTH:
  1526. X        offx = offx + 0.5;
  1527. X        offy = offy + ROOTHALF;
  1528. X        offz = offz - 0.5;
  1529. X        break;
  1530. X        case OUT_NORTHWEST:
  1531. X        offx = offx + 1.0;
  1532. X        break;
  1533. X    }
  1534. X    updatepiece();
  1535. X    res = collision(0);
  1536. X    };
  1537. X    if (res==(OUT_COLLIDE)) curpiece = (-2);
  1538. X}
  1539. X
  1540. Xvoid rotate_piece(pls, axis, theta)
  1541. X/* works on plist */
  1542. Xpoint pls[];
  1543. Xint axis;   /* 4-axis system */
  1544. Xdouble theta;
  1545. X{
  1546. X#define PHI (0.7853981634)
  1547. X    switch (axis) {
  1548. X    case 1:
  1549. X        rotate_axis(pls, 2, theta);
  1550. X        break;
  1551. X    case 2:
  1552. X        rotate_axis(pls, 2, PHI);
  1553. X        rotate_axis(pls, 1, theta);
  1554. X        rotate_axis(pls, 2, -PHI);
  1555. X        break;
  1556. X    case 3:
  1557. X    case 4:
  1558. X        rotate_axis(pls, 2, -PHI);
  1559. X        rotate_axis(pls, 1, -theta);
  1560. X        rotate_axis(pls, 2, PHI);
  1561. X        break;
  1562. X    }
  1563. X}
  1564. X
  1565. Xvoid reverse_piece(pls, axis)
  1566. Xpoint pls[];
  1567. Xint axis;
  1568. X{
  1569. X    register int ix;
  1570. X
  1571. X    switch (axis) {
  1572. X    case -1:
  1573. X        for (ix=0; ix<pieces[curpiece].numballs; ix++) {
  1574. X        pls[ix].x = (-pls[ix].x);
  1575. X        }
  1576. X        break;
  1577. X    }
  1578. X}
  1579. X
  1580. Xvoid rotate_axis(pls, axis, theta)
  1581. Xpoint pls[];
  1582. Xint axis;   /* 3-axis system */
  1583. Xdouble theta;
  1584. X{
  1585. X    register int ix;
  1586. X    double t1, t2;
  1587. X    double sinth = sin(theta);
  1588. X    double costh = cos(theta);
  1589. X
  1590. X    switch (axis) {
  1591. X    case 1:
  1592. X        for (ix=0; ix<pieces[curpiece].numballs; ix++) {
  1593. X        t1 = pls[ix].y;
  1594. X        t2 = pls[ix].z;
  1595. X        pls[ix].y = costh*t1 - sinth*t2;
  1596. X        pls[ix].z = sinth*t1 + costh*t2;
  1597. X        }
  1598. X        break;
  1599. X    case 2:
  1600. X        for (ix=0; ix<pieces[curpiece].numballs; ix++) {
  1601. X        t1 = pls[ix].x;
  1602. X        t2 = pls[ix].z;
  1603. X        pls[ix].x = costh*t1 - sinth*t2;
  1604. X        pls[ix].z = sinth*t1 + costh*t2;
  1605. X        }
  1606. X        break;
  1607. X    case 3:
  1608. X        for (ix=0; ix<pieces[curpiece].numballs; ix++) {
  1609. X        t1 = pls[ix].x;
  1610. X        t2 = pls[ix].y;
  1611. X        pls[ix].x = costh*t1 - sinth*t2;
  1612. X        pls[ix].y = sinth*t1 + costh*t2;
  1613. X        }
  1614. X        break;
  1615. X    }
  1616. X}
  1617. X
  1618. Xvoid updatepiece()
  1619. X/* create traplist from plist+offsets */
  1620. X{
  1621. X    register int ix;
  1622. X
  1623. X    if (!aspectflag) {
  1624. X    for (ix=0; ix<pieces[curpiece].numballs; ix++) {
  1625. X        traplist[ix].x = plist[ix].x + offx;
  1626. X        traplist[ix].y = plist[ix].y + offy;
  1627. X        traplist[ix].z = plist[ix].z + offz;
  1628. X    };
  1629. X    }
  1630. X    else {
  1631. X    for (ix=0; ix<pieces[curpiece].numballs; ix++) {
  1632. X        traplist[ix].x = aspect*plist[ix].x + offx;
  1633. X        traplist[ix].y = plist[ix].y + offy;
  1634. X        traplist[ix].z = plist[ix].z + offz;
  1635. X    };
  1636. X    }
  1637. X}
  1638. X
  1639. Xvoid updatetemp_tra(xa, ya, za, taxi, tdir)
  1640. X/* create templist from traplist, adding (whole)
  1641. X moves and turns */
  1642. Xdouble xa, ya, za;
  1643. Xint taxi; /* positive for rotation;
  1644. X negative for reflection */
  1645. Xint tdir;
  1646. X{
  1647. X    register int ix;
  1648. X
  1649. X    if (taxi==0) {
  1650. X    for (ix=0; ix<pieces[curpiece].numballs; ix++) {
  1651. X        templist[ix].x = traplist[ix].x + xa;
  1652. X        templist[ix].y = traplist[ix].y + ya;
  1653. X        templist[ix].z = traplist[ix].z + za;
  1654. X    };
  1655. X    }
  1656. X    else if (taxi<0) {
  1657. X    switch (taxi) {
  1658. X        case -1:
  1659. X        for (ix=0; ix<pieces[curpiece].numballs; ix++) {
  1660. X            templist[ix].x = -plist[ix].x;
  1661. X            templist[ix].y = plist[ix].y;
  1662. X            templist[ix].z = plist[ix].z;
  1663. X        };
  1664. X        for (ix=0; ix<pieces[curpiece].numballs; ix++) {
  1665. X            templist[ix].x += offx + xa;
  1666. X            templist[ix].y += offy + ya;
  1667. X            templist[ix].z += offz + za;
  1668. X        };        
  1669. X        break;
  1670. X    }
  1671. X    }
  1672. X    else {
  1673. X    for (ix=0; ix<pieces[curpiece].numballs; ix++) {
  1674. X        templist[ix].x = plist[ix].x;
  1675. X        templist[ix].y = plist[ix].y;
  1676. X        templist[ix].z = plist[ix].z;
  1677. X    };
  1678. X    rotate_piece(templist, taxi, ((double)(tdir))*PI/2.0);
  1679. X    for (ix=0; ix<pieces[curpiece].numballs; ix++) {
  1680. X        templist[ix].x += offx + xa;
  1681. X        templist[ix].y += offy + ya;
  1682. X        templist[ix].z += offz + za;
  1683. X    };
  1684. X    }
  1685. X}
  1686. X
  1687. Xvoid round_piece() /* round off piece (plist) to grid */
  1688. X{
  1689. X    register int ix;
  1690. X
  1691. X    offx = floor(offx*2.0 + 0.5) / 2.0;
  1692. X    offy = floor(offy/(0.5*ROOTHALF) + 0.5) * (0.5*ROOTHALF);
  1693. X    offz = floor(offz*2.0 + 0.5) / 2.0;
  1694. X
  1695. X    for (ix=0; ix<pieces[curpiece].numballs; ix++) {
  1696. X    plist[ix].x = floor(2.0*plist[ix].x + 0.5)/2.0;
  1697. X    plist[ix].y = floor(plist[ix].y/(0.5*ROOTHALF) + 0.5) * (0.5*ROOTHALF);
  1698. X    plist[ix].z = floor(2.0*plist[ix].z + 0.5)/2.0;
  1699. X    };
  1700. X}
  1701. X
  1702. Xint collision(listflag)
  1703. X/* Check a list for collision. Check traplist if
  1704. X listflag=0, templist if listflag=1.
  1705. X Returns (in this priority)
  1706. X 1: out-of-field up;
  1707. X 2: ...down;
  1708. X 3: ...northeast;
  1709. X 4: ...south;
  1710. X 6: ...northwest;
  1711. X -1 for ball overlap; 
  1712. X 0 for ok; 
  1713. X */
  1714. Xint listflag;
  1715. X{
  1716. X    register int ix;
  1717. X    static ballp balls[MAXBALLS];
  1718. X    point *pls;
  1719. X
  1720. X    if (listflag==0) pls = traplist;
  1721. X    else pls = templist;
  1722. X
  1723. X    for (ix=0; ix<pieces[curpiece].numballs; ix++) {
  1724. X    balls[ix].y = (int)(pls[ix].y/ROOTHALF+100.5) - 100;
  1725. X    balls[ix].z = (int)(pls[ix].z+0.5*balls[ix].y+100.5) - 100;
  1726. X    balls[ix].x = (int)(pls[ix].x-0.5*balls[ix].y+100.5) - 100;
  1727. X    /*printf("%.3f, %.3f, %.3f == %d, %d, %d\n", pls[ix].x,
  1728. X     pls[ix].y, pls[ix].z, balls[ix].x, balls[ix].y, balls[ix].z);*/
  1729. X
  1730. X    if (balls[ix].z < 0) return OUT_DOWN;
  1731. X    if (balls[ix].z >= fieldz) return OUT_UP;
  1732. X    if (balls[ix].y < 0) return OUT_SOUTH;
  1733. X    if (balls[ix].y >= fieldx-balls[ix].x) return OUT_NORTHEAST;
  1734. X    if (balls[ix].x < 0) return OUT_NORTHWEST;
  1735. X    };
  1736. X    for (ix=0; ix<pieces[curpiece].numballs; ix++) {
  1737. X    if (field[balls[ix].x][balls[ix].y][balls[ix].z] & F_ON)
  1738. X        return (OUT_COLLIDE);
  1739. X    };
  1740. X
  1741. X    return OUT_NOT;
  1742. X}
  1743. X
  1744. Xvoid setup_fieldpts() /* just that */
  1745. X{
  1746. X    register int ix, iy, iz;
  1747. X    double xc, yc, zc, wcoord;
  1748. X
  1749. X    if (errdiflag) {
  1750. X    XClearWindow(dpy, win);
  1751. X    XDrawImageString(dpy, win, gcwhite, 50, 50,
  1752. X    "Please wait about 15 seconds; computing pixmaps",
  1753. X    strlen("Please wait about 15 seconds; computing pixmaps"));
  1754. X    }
  1755. X
  1756. X    for (iz=0; iz<fieldz; iz++)
  1757. X    for (ix=0; ix<fieldx; ix++)
  1758. X        for (iy=0; iy<fieldx-ix; iy++) {
  1759. X        zc = (double)iz - 0.5*iy;
  1760. X        yc = ROOTHALF*iy;
  1761. X        xc = (double)ix + 0.5*iy;
  1762. X
  1763. X        wcoord = -(zc+fieldoffz)/focallen + 1.0;
  1764. X        fieldpts[ix][iy][iz].x = halfboardx +
  1765. X          (int)(boardscale*(xc+fieldoffx)/wcoord);
  1766. X        fieldpts[ix][iy][iz].y = halfboardy -
  1767. X          (int)(boardscale*(yc+fieldoffy)/wcoord);
  1768. X        fieldrads[ix][iy][iz] = (int)(0.5*boardscale/wcoord);
  1769. X
  1770. X        if (errdiflag &&
  1771. X            !ballpmflag[fieldrads[ix][iy][iz]][iz%NUMSHADES]) {
  1772. X            create_ballpm(fieldrads[ix][iy][iz], iz%NUMSHADES);
  1773. X        }
  1774. X        }
  1775. X    
  1776. X}
  1777. X
  1778. Xvoid add_ball(cx, cy, cz) /* draw a ball on fieldpm */
  1779. Xint cx, cy, cz;
  1780. X{
  1781. X    int rad = fieldrads[cx][cy][cz];
  1782. X    int x1 = fieldpts[cx][cy][cz].x;
  1783. X    int y1 = fieldpts[cx][cy][cz].y;
  1784. X
  1785. X    if (!errdiflag) {
  1786. X    GC gcball, gcrim;
  1787. X
  1788. X    if (monomode) {
  1789. X        gcball = (gcballs[colors[cz]]);
  1790. X        gcrim = (colors[cz]<8) ? (gcfield) : (gcwhite);
  1791. X    }
  1792. X    else {
  1793. X        gcball = (gcballs[cz]);
  1794. X        gcrim = (gcwhite);
  1795. X    }
  1796. X
  1797. X    XFillArc(dpy, fieldpm, gcball, x1-rad, y1-rad,
  1798. X         rad*2, rad*2, 0, 23040); 
  1799. X    /*XFillArc(dpy, fieldpm, gcspot, fieldpts[cx][cy][cz].x,
  1800. X     fieldpts[cx][cy][cz].y, rad*2/3, rad*2/3, 0, 23040); */
  1801. X    XDrawArc(dpy, fieldpm, gcrim, x1-rad, y1-rad,
  1802. X         rad*2, rad*2, 0, 23040); 
  1803. X    }
  1804. X    else {
  1805. X    if (!ballpmflag[rad][cz%NUMSHADES]) {
  1806. X        fprintf(stderr,
  1807. X            "spheral: missing ball pixmap (%d, %d)\n",
  1808. X            rad, cz%NUMSHADES);
  1809. X        exit(-1);
  1810. X    }
  1811. X    XFillArc(dpy, fieldpm, gcblack, x1-rad, y1-rad,
  1812. X        rad*2, rad*2, 0, 23040); 
  1813. X    XCopyArea(dpy, ballpm[rad][cz%NUMSHADES], fieldpm,
  1814. X        gcadd, 0, 0, rad*2, rad*2, x1-rad, y1-rad);
  1815. X    }
  1816. X}
  1817. X
  1818. Xvoid add_balls(lev)
  1819. X/* add balls to fieldpm. lev is the smallest z-coord affected */
  1820. Xint lev;
  1821. X{
  1822. X    register int ix, iy, iz;
  1823. X    int div;
  1824. X
  1825. X    for (iz=lev; iz<fieldz; iz++) 
  1826. X    for (iy=fieldx-1; iy>=0; iy--) {
  1827. X        div = (fieldx-iy)/2;
  1828. X        for (ix=0; ix<div; ix++) {
  1829. X        if (field[ix][iy][iz] & F_ON) {
  1830. X            add_ball(ix, iy, iz);
  1831. X        }
  1832. X        }
  1833. X        for (ix=(fieldx-iy-1); ix>=div; ix--) {        
  1834. X        if (field[ix][iy][iz] & F_ON) {
  1835. X            add_ball(ix, iy, iz);
  1836. X        }
  1837. X        }
  1838. X
  1839. X    }
  1840. X}
  1841. X
  1842. Xvoid plop_piece() /* plop traplist onto fieldpm. */
  1843. X{
  1844. X    register int ix, iy, iz;
  1845. X    int cubx, cuby, cubz;
  1846. X    int dirx, diry;
  1847. X    int lev = fieldz+1;
  1848. X    int full;
  1849. X
  1850. X    for (ix=0; ix<pieces[curpiece].numballs; ix++) {
  1851. X    cuby = (int)(traplist[ix].y/ROOTHALF+100.5) - 100;
  1852. X    cubz = (int)(traplist[ix].z+0.5*cuby+100.5) - 100;
  1853. X    cubx = (int)(traplist[ix].x-0.5*cuby+100.5) - 100;
  1854. X    if (cubz < lev) lev = cubz;
  1855. X    /*if (cubz+1 > meterlev) meterlev = cubz+1;*/
  1856. X    field[cubx][cuby][cubz] |= F_ON;
  1857. X    };
  1858. X    add_balls(lev);
  1859. X
  1860. X    /* check settling */
  1861. X    while (1) {
  1862. X    for (iz=fieldz-1; iz>=0; iz--) {
  1863. X        full=1;
  1864. X        for (ix=0; full && (ix<fieldx); ix++) {
  1865. X        for (iy=0; full && (iy<fieldx-ix); iy++) {
  1866. X            if (!(field[ix][iy][iz] & F_ON)) full = 0;
  1867. X        }
  1868. X        }
  1869. X        if (full) break;
  1870. X    }
  1871. X    if (iz<0) break;
  1872. X    for (; iz<fieldz-1; iz++) 
  1873. X        for (ix=0; ix<fieldx; ix++)
  1874. X        for (iy=0; iy<fieldx-ix; iy++)
  1875. X            field[ix][iy][iz] = field[ix][iy][iz+1];
  1876. X    for (ix=0; ix<fieldx; ix++)
  1877. X        for (iy=0; iy<fieldx-ix; iy++)
  1878. X        field[ix][iy][fieldz-1] = 0;
  1879. X    score += 15*fieldx*fieldx;
  1880. X    if (dropticks > 10) dropticks -= 6;
  1881. X    /*meterlev--;*/
  1882. X    setup_fieldpm();
  1883. X    add_balls(0);
  1884. X    }
  1885. X}
  1886. X
  1887. Xvoid measure_curpiece(psum)
  1888. X/* locate balls (from traplist) in screen coords */
  1889. Xpiecesum *psum;
  1890. X{
  1891. X    register int ix, jx;
  1892. X    int numballs;
  1893. X    double wcoord;
  1894. X    double dist[MAXBALLS], lowdist;
  1895. X    short arr[MAXBALLS], lowval, temp;
  1896. X
  1897. X    numballs = pieces[curpiece].numballs;
  1898. X    psum->numballs = numballs;
  1899. X
  1900. X    if (!aspectflag) {
  1901. X    psum->scalex = 1.0;
  1902. X    psum->scaley = 1.0;
  1903. X    }
  1904. X    else {
  1905. X    psum->scalex = aspect;
  1906. X    psum->scaley = 1.0;
  1907. X    }
  1908. X
  1909. X    for (ix=0; ix<numballs; ix++) {
  1910. X    arr[ix] = ix;
  1911. X    dist[ix] = (traplist[ix].z+fieldoffz)*(traplist[ix].z+fieldoffz) +
  1912. X      (traplist[ix].x+fieldoffx)*(traplist[ix].x+fieldoffx) +
  1913. X      (traplist[ix].y+fieldoffy)*(traplist[ix].y+fieldoffy);
  1914. X    /*printf("%.3f, %.3f, %.3f = %.3f\n",
  1915. X     (traplist[ix].z+fieldoffz), */
  1916. X    };
  1917. X    
  1918. X    for (ix=0; ix<numballs-1; ix++) {
  1919. X    lowdist = dist[arr[ix]];
  1920. X    lowval = ix;
  1921. X    for (jx=ix+1; jx<numballs; jx++) {
  1922. X        if (dist[arr[jx]] > lowdist) {
  1923. X        lowdist = dist[arr[jx]];
  1924. X        lowval = jx;
  1925. X        };
  1926. X    };
  1927. X    if (ix!=lowval) {
  1928. X        temp = arr[ix];
  1929. X        arr[ix] = arr[lowval];
  1930. X        arr[lowval] = temp;
  1931. X    }
  1932. X    }
  1933. X
  1934. X    for (ix=0; ix<numballs; ix++) {
  1935. X    jx = arr[ix];
  1936. X    wcoord = -(traplist[jx].z+fieldoffz)/focallen + 1.0;
  1937. X    psum->p[ix].x = halfboardx +
  1938. X      (int)(boardscale*(traplist[jx].x+fieldoffx)/wcoord);
  1939. X    psum->p[ix].y = halfboardy -
  1940. X      (int)(boardscale*(traplist[jx].y+fieldoffy)/wcoord);    
  1941. X    psum->rad[ix] = (int)(0.5*boardscale/wcoord);
  1942. X    };
  1943. X}
  1944. X
  1945. END_OF_FILE
  1946. if test 11934 -ne `wc -c <'spheral/rots.c'`; then
  1947.     echo shar: \"'spheral/rots.c'\" unpacked with wrong size!
  1948. fi
  1949. # end of 'spheral/rots.c'
  1950. fi
  1951. echo shar: End of archive 1 \(of 4\).
  1952. cp /dev/null ark1isdone
  1953. MISSING=""
  1954. for I in 1 2 3 4 ; do
  1955.     if test ! -f ark${I}isdone ; then
  1956.     MISSING="${MISSING} ${I}"
  1957.     fi
  1958. done
  1959. if test "${MISSING}" = "" ; then
  1960.     echo You have unpacked all 4 archives.
  1961.     rm -f ark[1-9]isdone
  1962. else
  1963.     echo You still need to unpack the following archives:
  1964.     echo "        " ${MISSING}
  1965. fi
  1966. ##  End of shell archive.
  1967. exit 0
  1968.