koreth@ssyx.ucsc.edu.ucsc.edu (Steven Grimm) (12/20/88)
Submitted-by: aking@bbn.com (Allen King) Posting-number: Volume 1, Issue 79 Archive-name: raymovi2/part02 #!/bin/sh # this is part 2 of a multipart archive # do not concatenate these parts, unpack them in order with /bin/sh # file RAYMOVI.DOK continued # CurArch=2 if test ! -r s2_seq_.tmp then echo "Please unpack part 1 first!" exit 1; fi ( read Scheck if test "$Scheck" != $CurArch then echo "Please unpack part $Scheck next!" exit 1; else exit 0; fi ) < s2_seq_.tmp || exit 1 sed 's/^X//' << 'SHAR_EOF' >> RAYMOVI.DOK XThus following the completion of every frame, RAYMOVI saves the current Xconfiguration on the disk so that if the computation of the next frame Xis interupted, it may be restarted. The checkpointing information Xis written in a file named CHECKPT, in configuration file format. Starting XRAYMOVI with CHECKPT will continue an interupted computation, redoing Xonly any work which was in progress on the interupted frame. X X X X CONFIGURATION FILE FORMAT X X X The following section discusses the format of the configuration files, Xwhich specify initial ball positions, velocities and optical properties, Xas well as lighting and viewing perspectives, picture resolution, and gravity. XThe configuration file name to be used is specified initially with a dialog. XThe file is then read line at a time. The character in column 1 specifies the Xmeaning of the rest of each line. Lines may be up to 200 characters long. Lines Xbeginning with whitespace are comments. The following other formats are Xsupported: X X X X - - - 'p' Format: - - - X Xspecifies the physical size and velocity of a ball. There are 7 properties Xrequired for each ball, and they all must be specified on one line in the Xfollowing order: X X (1) x coordinate of center (2) x velocity X (3) y coordinate (4) y velocity X (5) z coordinate (6) z velocity X (7) radius X XSome Notes: X A) In the coordinate system used, Y is upward, X is to the right, and Z X is depth (increasing Z moves farthur away). X B) Balls will bounce off the floor (the plane Y == 0) and an invisible X viewing port (the plane Z==0). Be sure to start them so that the whole X extent of the ball is above the floor and farther away than the X invisible viewing port. X C) If balls start out overlapping, they will stick together. X This turned out to be a serendipitous bug in the bounce algorithm, X and produces the string of pearls from which PEARLS gets its name. X D) The current version is compiled for up to 15 balls maximum. X X The first p-format statement in the file defines the "first" ball RAYMOVI Xknows about, the second the second and so on. Here are 6 balls which Xform an interesting scene: X X x vx y vy z vz radius X (1) (2) (3) (4) (5) (6) (7) (see (1)-(7) above) Xp 195.0,-20, 130.0, 0, 250.0, 10, 30.0 these are the 4 linked balls: Xp 150.0, -5, 100.0, 20, 250.0, 10, 30.0 " Xp 105.0, 5, 70.0, 20, 250.0,-20, 30.0 " Xp 60.0, 20, 40.0, 0, 250.0,-20, 30.0 " Xp 0.0,-10, 300.0, 20, 600.0, 0, 300.0 this is the big ball Xp 200.0, 2, 50.0, 5, 60.0, 30, 50.0 a medium size (lone) ball X X X X X - - - 'o' Format: - - - X Xspecifies the optical properties of a ball. The following 8 properties Xmust be put on one line, and in order: X X (1) index of refraction X X (2) amount of refraction (transparent) X (3) amount of reflection (mirror) X (4) amount of diffuse light (omnidirectional) X (5) amount of ambient light (from light source) X X (6) surface color redness X (7) surface color greenness X (8) surface color blueness X X XSome notes are in order to make realistic objects: X A) All parameters should be positive or zero. X B) Items (2) through (5) should sum to less than 1.0 X C) Surface colors (6) through (8) modulate the effect the diffuse and ambient X reflective properties defined by (4) and (5). None should be greater than X 1.0. X C) Due to the size of the ST's color palette, surface color items (6) X through (8) are constrained to be patterns corresponding to one of the X following three colors: X X white: (6) == (7) == (8) == 1.0 X red: (6) == (7) == 1.0, (8) == 0.0 X blue: (6) == 0.0, (7) == (8) == 1.0 X X X The i'th 'o' Format line refers to the same ball as the i'th 'p' Format line. XHere are the optical properties for the scene: X X (1) (2) (3) (4) (5) (6) (7) (8) Xo 0.0, 0.0, 0.3, 0.6, 0.1, 1.0,0.0,0.0 diffuse red, somewhat reflective Xo 0.0, 0.0, 0.6, 0.3, 0.1, 1.0,1.0,1.0 reflective, somewhat white Xo 0.0, 0.0, 0.9, 0.0, 0.1, 1.0,1.0,1.0 reflective, some ambient Xo 0.0, 0.0, 0.0, 0.8, 0.2, 1.0,0.0,0.0 diffuse red, some ambient Xo 0.0, 0.0, 0.7, 0.1, 0.2, 1.0,1.0,1.0 reflective and ambient (the big one) Xo 1.6, 0.8, 0.0, 0.0, 0.2, 1.0,1.0,1.0 refractive X X X X X - - - 'v' Format: - - - X Xspecifies the viewpoint of the display. x, y, and z values are required. X Xv 215.0, 100.0, -550.0 X | | z coordinate of viewpoint X | y coordinate of viewpoint X x coordinate of viewpoint X XAll rays start at the viewpoint and pass through a rectangle in the Z=0 Xplane. The rectangle is sized according to the size of the screen -- namely Xon a 320x200 low resolution screen, it is defined by 0.0 < X < 320.0 and X0.0 < Y < 200.0. (Actually, borders eat a few pixels on all sides.) X X X - - - 'l' Format: - - - X X specifies the location of the lightsource, and its diameter. Like before Xits x, y, and z coordinates, now followed by the diameter of the light. X Xl 150.0, 950.0, 0.0, 100.0 X X X - - - 'r' Format: - - - X Xspecifies the resolution of the picture to be produced, in Rays projected Xthrough each Pixel, followed by the color schema index, a number from 1 Xthrough 3. X Xr .20, 3 X X The inputted value of Rays Per Pixel will be rounded up to the next Xgreater power of 4.0. Thus in the line above, the .20 will be rounded up Xto (4.0)**(-1) = .25. X X The time to compute images varies linearly with the resolution (Rays Per XPixel) chosen. The constant of proportionality varies greatly depending on Xthe complication of the scene, but for the 6-ball scene here on a 520ST: X X .0625 rays per pixel 4 min X .25 rays per pixel 15 min X 1.0 rays per pixel 1 hr X 4.0 rays per pixel 4 hrs X 16.0 rays per pixel 16 hrs X XI tend to use .25 rays per pixel to experiment with positions and velocities, Xsince one can generate a couple dozen frames overnight. Once the positions Xlook good, a few nights of 4.0 rays per pixel produces good looking images. XI can tell the difference between 16.0 and 4.0 rays per pixel (sort of) but Xit is hardly worth the time it takes. 0.625 is skimping, but its quick. X X X The color index specifies how the 16 colors of the low resolution monitor Xare divided amongst hues and saturation. Three values are accepted currently: X X 1: white 16 saturations X 2: white, red 8 saturations each X 3: white, red, blue 6 saturations each X XAlthough the ray tracing algorithm computes arbitrary red/green/blue hues, Xthe palate limitations of the ST prohibit their display. X X X X X - - - 'g' Format: - - - X Xspecifies the strength of gravity, the mutual attraction between balls, Xand if balls bounce (in order). The following is realistic: X Xg 32.0, 0.3, 1 X X(Note: if balls do not bounce, they may occupy the same space. In that case Xthe current the ray tracing algorithm does not properly render refractive Xobjects.) X X - - - 'f' Format: - - - X Xspecifies the first 5 characters of the filename to be used to save Xcompleted pictures. (The rest of the name is the frame sequence number, Xand the suffix .PI1) Also specified are the starting and ending frame Xnumbers to be computed (positive integers less than 999). X Xf pearl, 1, 20 X Xgenerates 20 frames on the disk, labeled PEARLL001.PI1 through PEARL020.PI1. XAt 32K per frame, that will just about fill a double sided drive. X X X X -------------- X X Thats it for now. Tell me of you ventures, send me interesting Xconfigurations you find, and enjoy! X X X X Allen King aking bfly-vax.bbn.com ucbvax X 30 Gibson St 1-617-449-3359 evenings X Needham Ma. X 02192 SHAR_EOF chmod 0600 RAYMOVI.DOK || echo "restore of RAYMOVI.DOK fails" sed 's/^X//' << 'SHAR_EOF' > RAYMOVI.LNK && X\include\gemstart.o main.o wndows.o movie.o file.o shade.o find.o support.o X\include\aesbind \include\vdibind \include\gemlib \include\osbind.o X\include\libf SHAR_EOF chmod 0600 RAYMOVI.LNK || echo "restore of RAYMOVI.LNK fails" sed 's/^X//' << 'SHAR_EOF' > README && X RAYMOVI.PRG X X RAYMOVI.PRG renders 3-dimensional scenes in a world of reflective and Xrefractive spheres, using ray tracing techniques. Animated sequences of Xframes can be generated, showing reflective balls linked and bouncing in Xa gravitational field. They resemble a string of bouncing pearls. X X RAYMOVI.PRG runs only on a color ST in low resolution. 1 Meg is required Xto generate images with resolutions greater than one ray per pixel or for Xreplay of movies from RAM. Operation with only 512K is possible, but will Xproduce slightly aliased pictures (one ray per pixel) which can only be Xdisplayed statically, slowly from floppy, or from hard disk (if you have Xa disk blaster program). X X -------------------------------------------------- X X The files in RAYMOV2S.ARC, the source arc, are: X XC Sources: BLASTRAM.C, MAIN.C, WNDOWS.C, FILE.C, MOVIE.C, SHADE.C, X FIND.C, SUPPORT.C XInclude files: RTD.H, STYLE.H, COLORS.H, EXTERN.H XPgm Generation: MAKEFILE, BLASTRAM.LNK, RAYMOVI.LNK XRAYMOVI.DOK documentation XPEARLS the numeric description of an interesting scene X X RAYMOVI was last compiled with ALCYON. The MAKEFILE and *.LNK are X(therefore) pretty crufty. Use them accordingly. X X RAYMOVI requires an 8K stack. Modify your copy of gemstart.s (or Xwhatever defines your stack size) appropriately. X X X Allen King aking pebbles.bbn.com ucbvax X 30 Gibson St 1-617-449-3359 evenings X Needham Ma. X 02192 X X X SHAR_EOF chmod 0600 README || echo "restore of README fails" sed 's/^X//' << 'SHAR_EOF' > RTD.H && X#define NCOLORS 3 X#define HUGE 1e15 X#define EPSILON 1e-3 X Xstruct vector X { X double x; X double y; X double z; X double l; X double xzl; X } ; X Xstruct ray X { X struct vector org; X struct vector dir; X } ; X Xstruct sphere X { X struct vector cent; X double rad; X } ; X Xstruct ball X { X struct sphere s; X double ior; X double rfr; X double rfl; X double dif; X double amb; X double red; X double green; X double blue; X struct vector v; X }; X Xstruct mat X { X struct vector x; /* first !row! */ X struct vector y; /*second !row! */ X struct vector z; /* third !row! */ X }; X SHAR_EOF chmod 0600 RTD.H || echo "restore of RTD.H fails" sed 's/^X//' << 'SHAR_EOF' > SHADE.C && X/* XFrom harvard!husc6!caip!nike!ucbcad!ucbvax!sdcsvax!net1!fritzz 25 Jul 86 21:35:59 GMT XArticle 2915 of net.sources: XRelay-Version: version B 2.10.2 9/18/84; site bbnccv.UUCP XPath: bbnccv!harvard!husc6!caip!nike!ucbcad!ucbvax!sdcsvax!net1!fritzz X>From: fritzz@net1.UCSD.EDU (Friedrich Knauss) XNewsgroups: net.sources XSubject: basic ray tracing: part 1 (tracer.c) XMessage-ID: <190@net1.UCSD.EDU> XDate: 25 Jul 86 21:35:59 GMT XDate-Received: 27 Jul 86 01:07:29 GMT XReply-To: fritzz@net1.UUCP (Friedrich Knauss) XOrganization: University of California, San Diego X*/ X/* X * this subroutine does all the gritty work- it calculates X * what shade each pixel should be. I like recursion. X */ X X#include <math.h> X#include "rtd.h" X#include "extern.h" X#define time(x) 0 X X/* LEVEL defines number of levels of recursion */ X#define LEVEL 5 Xint debug; X#define dprintf if (debug) printf X Xshade (r, red, green, blue) Xstruct ray *r; Xdouble *red, *green, *blue; X{ int i, c, X refract (); X struct ray refr; X double rd, gn, blu, tmp; X double lght_red, lght_green, lght_blue, X x, y, z, X l, k, X dot (), find (), findo (); X struct vector new, norm; X struct mat trans; X struct sphere ss; X X if (++level <= LEVEL) X { c = -1; X l = HUGE; X X dprintf("LEVEL %d: ", level); X /* get vector length and xz component for mt() */ X vecl (&r->dir); X vexzl (&r->dir); X X /* make a transform matrix that rotates something in space so X that the ray will be aligned with the x axis */ X X mt (&r->dir, &trans); X X /* for starters we find out whether we hit anything. */ X X for (i = 0; i < nob; i++) X { ss.rad = bl[i].s.rad; X sv (&ss.cent, &bl[i].s.cent, &r->org); X if ((k = find (&trans, &ss)) > 0.0 && k < l) X { c = i; X l = k; X } X } X if (c >= 0.0) /* WE HIT SOMETHING */ X { x = l * trans.x.x; X y = l * trans.x.y; X z = l * trans.x.z; X mv (x, y, z, &new); X X /* move the new orgin of the ray to the intersection */ X X av (&refr.org, &new, &r->org); X av (&r->org, &new, &r->org); X mv (r->dir.x, r->dir.y, r->dir.z, &refr.dir); X X /* get a normal vector for the intersection point */ X X sv (&norm, &r->org, &bl[c].s.cent); X vecl (&norm); X X /* ambient lighting */ X X tmp = 255.0 * bl[c].amb; X lght_red = tmp * bl[c].red; X lght_green = tmp * bl[c].green; X lght_blue = tmp * bl[c].blue; X dprintf(" ball[%d]", c); X dprintf(", ambient=%d,%d,%d\n", X (int)lght_red, (int)lght_green, (int)lght_blue); X X /* shaded lighting (diffuse). subroutine shadow is in find.c */ X X if (bl[c].dif != 0.0) X { sv (&new, &ls.cent, &r->org); X vecl (&new); X if ((k = dot (&new, &norm)) > 0.0) X { shadow (&r->org, &rd, &gn, &blu); X dprintf("diffuse = %d, %d, %d\n",(int)rd,(int)gn,(int)blu); X tmp = bl[c].dif * k / (new.l * norm.l); X lght_red += tmp * rd * bl[c].red; X lght_green += tmp * rd * bl[c].green; X lght_blue += tmp * rd * bl[c].blue; X } } X X /*reflection... easy */ X X if (bl[c].rfl != 0.0) X { vecl (&norm); X /* make the normal unit length */ X scamult ((1.0 / norm.l), &norm); X /* get the length of the ray's component in the normal direction */ X x = 2.0 * dot (&norm, &r->dir); X scamult (x, &norm); X /* subtract double the normal component- !reflection! */ X sv (&r->dir, &r->dir, &norm); X shade (r, &rd, &gn, &blu); X dprintf("reflection = %d, %d, %d, tmp=%d\n", X (int)rd, (int)gn, (int)blu, (int)tmp); X tmp = bl[c].rfl; X lght_red += tmp * rd; X lght_green += tmp * gn; X lght_blue += tmp * blu; X } X X /* refraction. this is ugly, which is why I choose to deal with X it in it's own subroutine which comes after this one */ X X if (bl[c].rfr != 0.0) X { dprintf(" refraction\n"); X refract (&refr, &bl[c], &rd, &gn, &blu); X tmp = bl[c].rfr; X dprintf("refraction = %d, %d, %d\n",(int)rd,(int)gn,(int)blu); X lght_red += tmp * rd; X lght_green += tmp * gn; X lght_blue += tmp * blu; X } } X else /* hit no objects... */ X { if ((r->dir.y) < 0.0) /* crosses floor */ X { z = -(r->org.y) / (r->dir.y); X (r->org.x) += z * (r->dir.x); X (r->org.z) += z * (r->dir.z); X (r->org.y) = 0.0; X dprintf("floor (%d, %d): ", (int)r->org.x, (int)r->org.z); X if ( ((int) ((r->org.x) / 9.0) % 8 == 0) X || ((int) ((r->org.z) / 9.0) % 8 == 0)) X { lght_red = lght_green = lght_blue = 0.0; X dprintf("black. 0,0,0\n"); X } /* this is for texture, grid on the ground */ X else /* get shading for the squares... */ X { sv (&new, &ls.cent, &r->org); X vecl (&new); X shadow (&r->org, &rd, &gn, &blu); X tmp = 0.6 * new.y / new.l; X lght_blue = tmp * blu + 100.0; /* tile pattern: */ X if ((int)r->org.x/72 & (int)r->org.z/72 & 0x15) X { lght_red = lght_green = 0.0; /* blue */ X dprintf("blue. %d, %d, %d\n", X (int)lght_red, (int)lght_green, (int)lght_blue); X } X else X { lght_red = tmp * rd + 100.0; /* white */ X lght_green = tmp * gn + 100.0; X dprintf("white. %d,%d,%d\n", X (int)lght_red, (int)lght_green, (int)lght_blue); X } } } X else /* didn't hit ground... sky */ X { lght_red = lght_green = lght_blue = 0.0; X dprintf("sky. %d,%d,%d\n", X (int)lght_red, (int)lght_green, (int)lght_blue); X } X dprintf("lght_= %d,%d,%d\n", X (int)lght_red, (int)lght_green, (int)lght_blue); X } } X /* to many levels return 0 cause it shouldn't matter */ X else X { lght_red = lght_green = lght_blue = 0.0; X dprintf(">5 levels. 0, 0, 0\n"); X } X level--; X X if (lght_red < 0.0) lght_red = 0.0; X if (lght_red > 255.0) lght_red = 255.0; X X if (lght_green < 0.0) lght_green = 0.0; X if (lght_green > 255.0) lght_green = 255.0; X X if (lght_blue < 0.0) lght_blue = 0.0; X if (lght_blue > 255.0) lght_blue = 255.0; X X *red = lght_red; X *green = lght_green; X *blue = lght_blue; X X dprintf("returned: %d, %d, %d\n", (int)*red, (int)*green, (int)*blue); X} X Xint refract (r, bll, red, green, blue) Xstruct ray *r; Xstruct ball *bll; Xdouble *red, *green, *blue; X{ X struct vector new, norm; X struct mat trans; X double l, X refk (); X struct sphere ss; X X sv (&norm, &r->org, &bll->s.cent); X vecl (&norm); X vecl (&r->dir); X X /* get the addition factor for the normal */ X X scamult (refk (&norm, &r->dir, bll->ior), &norm); X av (&r->dir, &r->dir, &norm); X X /* find the point where the ray leaves the sphere. just like shade. */ X X vexzl (&r->dir); X vecl (&r->dir); X mt (&r->dir, &trans); X ss.rad = bll->s.rad; X sv (&ss.cent, &bll->s.cent, &r->org); X l = findo (&trans, &ss); X mv (l * trans.x.x, l * trans.x.y, l * trans.x.z, &new); X av (&r->org, &r->org, &new); X X /* redirect the ray and continue tracing */ X X sv (&norm, &r->org, &bll->s.cent); X vecl (&norm); X vecl (&r->dir); X scamult (refk (&norm, &r->dir, 1.0 / bll->ior), &norm); X av (&r->dir, &r->dir, &norm); X X shade (r, red, green, blue); X} X X Xdouble refk (nrm, in, ior) Xstruct vector *nrm, *in; Xdouble ior; X{ double dt, ln, li, ret; X X dt = dot (nrm, in); X ln = nrm->x * nrm->x + nrm->y * nrm->y + nrm->z * nrm->z; X li = in->x * in->x + in->y * in->y + in->z * in->z; X ret = dt * dt - ln * li * (1 - ior); X if (ret < 0.0) X ret = 0.0; X if (dt < 0) X ret = (-dt - sqrt (ret)) / ln; X else X ret = (-dt + sqrt (ret)) / ln; X return (ret); X} X Xprintv(s, v) Xchar *s; Xstruct vector *v; X{ printf("%s.x = %f, .y = %f, .z = %f\n", s, v->x, v->y, v->z); X} SHAR_EOF chmod 0600 SHADE.C || echo "restore of SHADE.C fails" sed 's/^X//' << 'SHAR_EOF' > STYLE.H && X/* cosmetic C definitions */ X X#define EQ == X#define IS == X#define NEQ != X#define ISNT != X#define AND && X#define OR || X#define NOT ! X#define NULL 0 X#define TRUE 1 X#define FALSE 0 X#define TRUE_STRING(i) (i IS TRUE ? "TRUE" : "FALSE") X X#define u unsigned X Xtypedef char boolean; Xtypedef char *string; X X#define plural(i) ( ((i) EQ 1) ? "":"s") X SHAR_EOF chmod 0600 STYLE.H || echo "restore of STYLE.H fails" sed 's/^X//' << 'SHAR_EOF' > SUPPORT.C && X/* X * supportive subroutines... X */ X#include <math.h> X#include <stdio.h> X#undef min X#include "rtd.h" X#include "extern.h" X#define time(x) 0 X X/* returns dot product of two vectors */ X Xdouble dot (v1, v2) X struct vector *v1, X *v2; X{ X double r; X r = v1->x * v2->x + v1->y * v2->y + v1->z * v2->z; X return (r); X} X X X/* multiplies a vector by a scalar */ X Xscamult (scal, vect) X double scal; X struct vector *vect; X{ X vect->x *= scal; X vect->y *= scal; X vect->z *= scal; X vect->l *= scal; X vect->xzl *= scal; X} X X X/* loads a vector with given x,y,z values */ X Xmv (x, y, z, _vp) X double x, X y, X z; X struct vector *_vp; X{ X _vp->x = x; X _vp->y = y; X _vp->z = z; X} X X X/* vector subtraction: v1 = v2 - v3 */ X Xsv (v1, v2, v3) X struct vector *v1, X *v2, X *v3; X{ X v1->x = v2->x - v3->x; X v1->y = v2->y - v3->y; X v1->z = v2->z - v3->z; X} X X X X/* vector addition: v1 = v2 + v3 */ X Xav (v1, v2, v3) X struct vector *v1, X *v2, X *v3; X{ X v1->x = v2->x + v3->x; X v1->y = v2->y + v3->y; X v1->z = v2->z + v3->z; X} X X X/* loads a transform matrix so that when vec is multiplied by it, X the result is (1,0,0). it does so with out deforming space */ X Xmt (vec, trans) X struct vector *vec; X struct mat *trans; X{ X vecl (vec); X vexzl (vec); X X if (vec->xzl == 0.0) { X trans->x.x = 0.0; X trans->x.y = 1.0; X trans->x.z = 0.0; X trans->y.x = -1.0; X trans->y.y = 0.0; X trans->y.z = 0.0; X trans->z.x = 0.0; X trans->z.y = 0.0; X trans->z.z = 1.0; X } X else { X trans->x.x = (vec->x) / (vec->l); X trans->x.y = (vec->y) / (vec->l); X trans->x.z = (vec->z) / (vec->l); X trans->y.x = -(vec->x) * (vec->y) / ((vec->l) * (vec->xzl)); X trans->y.y = (vec->xzl) / (vec->l); X trans->y.z = -(vec->z) * (vec->y) / ((vec->l) * (vec->xzl)); X trans->z.x = -(vec->z) / (vec->xzl); X trans->z.y = 0; X trans->z.z = (vec->x) / (vec->xzl); X } X} X X/* multiply vector by matrix: vc1 = m*vc2 */ X Xmt_vec (vc1, m, vc2) X struct vector *vc1, X *vc2; X struct mat *m; X{ X double x, X y, X z; X X x = dot (&(m->x), vc2); X y = dot (&(m->y), vc2); X z = dot (&(m->z), vc2); X mv (x, y, z, vc1); X} X X X X/* will update a file containing information on Xhow we are coming along... useful for long runs*/ X Xupdate (x, xmin, xmax) X float x, X xmin, X xmax; X{ X FILE * fff; X static int t; X static double size, X xm; X int tt, X ttt, X hr, X min, X sec; X X X fprintf (stderr, "%d\n", (int) x); X return; X X X if (x == xmin) { X/* fff = fopen ("time.update", "w"); */ X fff = stderr; X fprintf (fff, "starting...\n"); X/* fclose (fff); */ X t = time (0); X xm = xmin; X size = (xmax - xmin); X } X else { X x -= xm; X tt = time (0) - t; X ttt = (double) tt * size / x; X tt = (double) tt * (size - x) / x; X hr = tt / 3600; X min = (tt % 3600) / 60; X sec = tt % 60; X/* fff = fopen ("time.update", "w"); */ X fff = stderr; X fprintf (fff, "%5.1f%% done.\n", 100.0 * x / size); X fprintf (fff, "%d:%2d:%2d left.\n", hr, min, sec); X hr = ttt / 3600; X min = (ttt % 3600) / 60; X sec = ttt % 60; X fprintf (fff, "%d:%2d:%2d total estimate.\n", hr, min, sec); X/* fclose (fff); */ X } X} X X X/* loads a vectors length... saves time to do this only when needed */ X Xvecl (v) X struct vector *v; X{ X v->l = sqrt ((v->x) * (v->x) + (v->y) * (v->y) + (v->z) * (v->z)); X} X X X/* loads a vectors xz component. needed for mt */ X Xvexzl (v) X struct vector *v; X{ X v->xzl = sqrt ((v->x) * (v->x) + (v->z) * (v->z)); X} X X SHAR_EOF chmod 0600 SUPPORT.C || echo "restore of SUPPORT.C fails" sed 's/^X//' << 'SHAR_EOF' > WNDOWS.C && X/* wndows.c X * manage the interface to GEM windows X XEntry Points: X w_open(type,name) *** X w_close() X w_lClut(new, old) X XOutward Calls: X wOnewSize() X X */ X X#include <obdefs.h> X#include <define.h> X#include <gemdefs.h> X#include <vdibind.h> X#include <osbind.h> X X#define MIN_WIDTH (2*gl_wbox) X#define MIN_HEIGHT (3*gl_hbox) Xint gl_hchar, gl_wchar, gl_wbox, gl_hbox; /* system sizes */ X Xint ps_handle; /* physical screen (workstation) handle */ Xint vs_handle; /* virtual screen (workstation) handle */ Xint wi_handle; /* window handle */ X Xint xdesk,ydesk,hdesk,wdesk; /* size of whole desktop */ Xint xwork,ywork,hwork,wwork; /* size of current working window */ Xint xold,yold,hold,wold; /* size of screen before FULL cmd */ X Xint contrl[12], intin[128], ptsin[128], intout[128]; Xint ptsout[128]; /* storage for gem bindings */ X Xchar *p_menu; Xint WiKind; X Xw_open(kind, name, menue_id) Xint kind; /* properties of window (e.g. MOVER|CLOSER|...) */ Xchar *name; Xint menue_id; /* open menue? */ X{ char n2[30]; X appl_init(); X open_vwork(); X open_window(kind, name); X WiKind = kind; X sprintf(n2, "%s.rsc", name); X open_rsc(n2, menue_id); X graf_mouse(ARROW,0x0L); X return (wi_handle); X} X Xw_close() X{ if (p_menu) X menu_bar(p_menu, FALSE); X wind_close(wi_handle); X graf_shrinkbox(xwork+wwork/2,ywork+hwork/2,gl_wbox,gl_hbox,xwork,ywork,wwork,hwork); X wind_delete(wi_handle); X v_clsvwk(vs_handle); X appl_exit(); X} X Xint work_in[11]; /* Input to GSX parameter array */ Xint work_out[57]; /* Output from GSX parameter array */ X Xopen_vwork() X{ int i; X X ps_handle=graf_handle(&gl_wchar,&gl_hchar,&gl_wbox,&gl_hbox); X for(i=0;i<10;work_in[i++]=1); X work_in[10]=2; X vs_handle=ps_handle; X v_opnvwk(work_in,&vs_handle,work_out); X if (vs_handle == 0) X panic("v_opnvwk couldn't open window",0L,0L); X} X Xopen_window(kind, name) Xint kind; Xchar *name; X{ wind_get(0/*whole screen*/,WF_WORKXYWH, &xdesk, &ydesk, &wdesk, &hdesk); X wi_handle=wind_create(kind,xdesk,ydesk,wdesk,hdesk); X X wind_set(wi_handle, WF_NAME,name, 0,0); X graf_growbox(xdesk+wdesk/2,ydesk+hdesk/2,gl_wbox,gl_hbox,xdesk,ydesk,wdesk,hdesk); X wind_open(wi_handle,xdesk,ydesk,wdesk,hdesk); X wind_get(wi_handle,WF_WORKXYWH,&xwork,&ywork,&wwork,&hwork); X wwork--; /* ywork--;/**/ hwork--; X set_clip(xwork, ywork, wwork, hwork); X wOnewSize(xwork, ywork, wwork, hwork); X if (wdesk>500 && 2 != form_alert(1,"[3][16 Colors Required.|\ XSet Preferences to Low|Resolution and Restart.][okay|ignore warning]")) X exit();/**/ X} X Xopen_rsc(myname, menue) Xchar *myname; Xint menue; X{ if (menue) X { if (rsrc_load(myname)==0) panic("File %s missing!",myname,0L); X if (rsrc_gaddr(R_TREE, menue, &p_menu)==0) X panic ("AES/rsrc_gaddr() error",0L,0L); X if (menu_bar(p_menu, TRUE)==0) panic ("AES/menu_bar() error",0L,0L); X} } X Xtypedef int CLUT[16][3]; XCLUT (*clut_current); X Xw_lClut(new, old) XCLUT new, old; X{ int i; X clut_current = new; X for (i=0; i<16; i++) X { if (old) X vq_color(vs_handle, i, 0, old[i]); X if (new) X vs_color(vs_handle, i, new[i]); X} } X Xdi_header(dx, str) Xint dx; Xchar *str; X{ set_clip(xdesk, ydesk, wdesk, hdesk); X/* v_gtext(vs_handle, ((dx>0)? Wx0: Wx1) +dx, Wy0-3, str);/**/ X v_gtext(vs_handle, xdesk + (dx<0)*wdesk + dx, ydesk-3, str); X set_clip(xwork, ywork, wwork, hwork); X} X Xdi_bg(dx, clr) Xint dx, clr; X{ int pxy[4]; X set_clip(xdesk, ydesk, wdesk, hdesk); X vsf_color(wi_handle, clr); X pxy[0] = xdesk+dx; pxy[2] = pxy[0] + 8; X pxy[1] = ydesk-10/*3*/; pxy[3] = pxy[1] + 18; X v_bar(wi_handle, pxy); X set_clip(xwork, ywork, wwork, hwork); X} Xset_clip(x,y,w,h) Xint x,y,w,h; X{ int clip[4]; X X clip[0]=x; /* set vdi's clip rectangle */ X clip[1]=y; X clip[2]=x+w; X clip[3]=y+h; X vs_clip(wi_handle,1,clip); X} SHAR_EOF chmod 0600 WNDOWS.C || echo "restore of WNDOWS.C fails" rm -f s2_seq_.tmp echo "You have unpacked the last part" exit 0