[comp.sources.misc] v04i083: 3demo program - part 1 of 4

leo@philmds.UUCP (Leo de Wit) (09/20/88)

Posting-number: Volume 4, Issue 83
Submitted-by: "Leo de Wit" <leo@philmds.UUCP>
Archive-name: 3demo/Part01

[PLEASE don't ask me what this is -- I have no more idea than you do!  ++bsa]

: This is a shar archive.  Extract with sh, not csh.
: This archive ends with exit, so do not worry about trailing junk.
echo 'Extracting 3demo.c'
sed 's/^X//' > 3demo.c << '+ END-OF-FILE 3demo.c'
X/*
X ******************************************************************************
X *                                                                            *
X *    3demo.c     version 1.1 of 17 July 1988    (C) L.J.M. de Wit 1988       *
X *                                                                            *
X * This software may be used and distributed freely if not used commercially  *
X * and the originator (me) is mentioned.                                      *
X *                                                                            *
X ******************************************************************************
X *
X * 3demo.c: the main part of the 3demo.prg program.
X * It initializes the workstation, memory and contains the diverse demo
X * functions - each demo function representing a complete demo.
X */
X
X#include <stdio.h>
X#include <osbind.h>
X#include <portab.h>
X#include <math.h>
X#include "matricks.h"
X
X#define HELP_KEY 0x620000              /* Help key code */
X#define NSTEPS 120                     /* # of steps for a complete turn */
X#ifndef Wvbl()                         /* some osbind.h's don't contain  */
X#define Wvbl() xbios(37)               /* this entry, so add it          */
X#endif  Wvbl
X
X#define DT_REAL     0                  /* demotype 'real time' */
X#define DT_COORDRES 1                  /* demotype use saved coords */
X#define DT_IMGSAV   2                  /* demotype save images */
X#define DT_IMGRES   3                  /* demotype use saved images */
X#define DT_MAX      4                  /* upper limit demotype range */
X
Xstatic double dist = 5,                /* distance eye from screen */
X              scale_x,                 /* scale factor in x direction */
X              scale_y;                 /* scale factor in y direction */
X
X                                       /* For each direction and axis: */
Xstatic WORD rotobject[2][3][4][4];     /* rotation matrices for object */
Xstatic WORD rotobserv[2][3][4][4];     /* rotation matrices for observer */
Xstatic WORD traobserv[2][3][4][4];     /* translation matrices for observer */
X
Xstatic double idmat[][3] = {           /* identity matrix */
X   1,0,0,
X   0,1,0,
X   0,0,1
X};
Xstatic double tl0[3] = {               /* translation vector */
X   0,0,0
X};
Xstatic double tl1[] = {                /* another one */
X   0.5,0.5,0.5
X};
Xstatic double tl2[] = {                /* and yet another one */
X   0,0,0
X};
X
Xstatic void st_demo(),                 /* demo using ST as logo */
X            house_demo(),              /* demo with street of houses */
X            globe_demo(),              /* demo with globe skeleton */
X            move_it();                 /* move item using user input */
X
Xmain(argc,argv)
Xint argc;
Xchar *argv[];
X{
X   int i, j;
X   double lambda = 0.1, alpha = 0.05;
X
X                                       /* Initialize matrices for small */
X                                       /* movements. */
X   for (i = 0; i < 2; i++) {           /* 0: forward, 1: backward */
X      for (j = 0; j < 3; j++) {        /* 0, 1, 2: x, y, z direction */
X         matident(4,traobserv[i][j]);
X         matapply(traobserv[i][j],mattlate,idmat[j],  /* translation observer*/
X            (i == 0) ? lambda : -lambda);
X
X         matident(4,rotobserv[i][j]);
X         matapply(rotobserv[i][j],matrotate,idmat[j], /* rotation observer */
X            (i == 0) ? alpha : -alpha);
X
X         matident(4,rotobject[i][j]);
X         matapply(rotobject[i][j],mattlate,tl1,-1.0);
X         matapply(rotobject[i][j],matrotate,idmat[j],
X            (i == 0) ? alpha : -alpha);
X         matapply(rotobject[i][j],mattlate,tl1,1.0);  /* rotation object */
X      }
X   }
X
X   gem_init();                         /* initializations */
X   scale_x = 13600/pixwidth;           /* scale factors depend on pixel sizes */
X   scale_y = 13600/pixheight;          /* which are determined upon v_openvwk */
X   st_demo();                          /* Demo 1 */
X   house_demo();                       /* Demo 2 */
X   globe_demo();                       /* Demo 3 */
X   gem_exit(0);
X}
X
Xstatic void st_demo()
X{
X   static short lists[][2] = {         /* coordinates for letter 'S' */
X      -4,0,-2,0,-1,1,-1,2,
X      -2,3,-3,3,-3,4,-1,4,
X      -1,5,-3,5,-4,4,-4,3,
X      -3,2,-2,2,-2,1,-4,1,
X      -4,0
X   };
X   static short listt[][2] = {         /* coordinates for letter 'T' */
X      2,0,3,0,3,4,4,4,
X      4,5,1,5,1,4,2,4,
X      2,0
X   };
X   int npoints,                        /* # of points in logo */
X      i, j, n, mode0 = 1, demotype;
X   double (*st_coords)[3],             /* ptr to array of coordinates of */
X                                       /* vertices of original image */
X          (*stp)[3];                   /* to point into this array */
X   short (*shp)[2];                    /* ptr into lists or listt */
X   short *order,                       /* ptr to array of indices */
X         *op;                          /* to point into this array */
X   item it;                            /* the item */
X   instance ins;                       /* the (1) instance of the item */
X   static WORD neweye[][4] = {         /* transformation matrix that puts */
X      3978, 0, 0, 0,                   /* observer in its place the first time*/
X      0, 3978, 0, 0,
X      0, 0, 3978, 0,
X      29769, 10022, -25047, 3978
X   };
X   static WORD newtrans[][4] = {       /* Transformation that puts the logo */
X      17405, 0, 0, 0,                  /* in its place the first time */
X      0, -18175, -51, 0,
X      0, 49, -18245, 0,
X      -56, 17745, 17889, 17405
X   };
X   WORD *eye,                          /* ptr to eye coordin. tranformation */
X        *savarr;                       /* ptr to all coordinates of the */
X                                       /* vertices of the logo for 120 images*/
X   bool done = FALSE;
X   char c;
X   static uchar *sinfo[NSTEPS];        /* array of ptrs to compressed screen */
X                                       /* strings */
X
X   /* shorthands for # of points */
X#define S_POINTS (sizeof(lists)/sizeof(short[2]))
X#define T_POINTS (sizeof(listt)/sizeof(short[2]))
X
X   npoints = 2 * (S_POINTS + T_POINTS);
X   savarr = (WORD *)malloc(NSTEPS*2*npoints*sizeof(WORD));
X   st_coords = (double (*)[3])malloc(npoints * sizeof(double[3]));
X   order = (short *)malloc(
X             (S_POINTS + T_POINTS + 1) * 5 * sizeof(short));
X
X   stp = st_coords; op = order;        /* init S coordinates and ordering */
X   for (shp = lists, i = 0; shp < lists + S_POINTS; shp++) {
X      (*stp)[0] = (*shp)[0];
X      (*stp)[1] = (*shp)[1] - 2.5;
X      (*stp)[2] = 0;
X      stp++;
X      (*stp)[0] = (*shp)[0];
X      (*stp)[1] = (*shp)[1] - 2.5;
X      (*stp)[2] = 1;
X      stp++;
X      *op++ = i++;
X      *op++ = i++;
X      *op++ = SV;
X   }
X
X   for (shp = lists, i = 0; shp < lists + S_POINTS; shp++) {
X      *op++ = i++;
X      i++;
X   }
X   *op++ = SV;
X   for (shp = lists, i = 0; shp < lists + S_POINTS; shp++) {
X      i++;
X      *op++ = i++;
X   }
X   *op++ = SV;
X   n = i;
X
X                                       /* init T coordinates and ordering */
X   for (shp = listt, i = n; shp < listt + T_POINTS; shp++) {
X      (*stp)[0] = (*shp)[0];
X      (*stp)[1] = (*shp)[1] - 2.5;
X      (*stp)[2] = 0;
X      stp++;
X      (*stp)[0] = (*shp)[0];
X      (*stp)[1] = (*shp)[1] - 2.5;
X      (*stp)[2] = 1;
X      stp++;
X      *op++ = i++;
X      *op++ = i++;
X      *op++ = SV;
X   }
X
X   for (shp = listt, i = n; shp < listt + T_POINTS; shp++) {
X      *op++ = i++;
X      i++;
X   }
X   *op++ = SV;
X   for (shp = listt, i = n; shp < listt + T_POINTS; shp++) {
X      i++;
X      *op++ = i++;
X   }
X   *op++ = SV;
X   *op++ = SV;
X
X   it = matcrit(npoints,st_coords,order); /* create item */
X   ins = matcrins(it,idmat,tl0);       /* Create instance of this item */
X   eye = matseteye(idmat,tl2,          /* To make eye point to the */
X         dist,scale_x,scale_y);        /* correct static array */
X   for (i = 0; i < 4; i++) {           /* Use these (empiric) values instead */
X      for (j = 0; j < 4; j++) {
X         eye[4*i + j] = neweye[i][j];
X         ins->trans[i][j] = newtrans[i][j];
X      }
X   }
X
X   printf("%s\n\n\t%s\n\n\t\t- Press any key to start -\n\n",
X          CLS,"Demo 1: ST (press q to quit)");
X   swapscreen();                       /* Show text & */
X   Crawcin();                          /* wait for key press */
X
X   for ( ; !done; ) {                  /* while 'q' not pressed */
X      for (i = 0; !done && i < 3; i++) { /* for each axis */
X         for (demotype = 0; !done && demotype < DT_MAX; demotype++) { /* 4 x */
X            static char *text[] = {
X               "real time calculation",
X               "using saved coordinates",
X               "saving images",
X               "using saved images"
X            };
X
X            printf("%s\n\n\tDemo 1: %s\n\n",CLS,text[demotype]);
X            swapscreen();              /* Show this text */
X            for (j = 0; j < 100; j++) {/* wait some time */
X               Wvbl();
X            }
X            for (j = 0; !done && j < NSTEPS; j++) {
X               v_clrwk(handle);
X               switch (demotype) {
X               case DT_REAL:
X                  matproject(ins);
X                  insstore(ins,savarr,j);
X                  matfdraw(ins,mode0);
X                  break;
X               case DT_COORDRES:
X                  insload(ins,savarr,j);
X                  matfdraw(ins,mode0);
X                  break;
X               case DT_IMGSAV:
X                  insload(ins,savarr,j);
X                  matfdraw(ins,mode0);
X                  sinfo[j] = matscr_to_str((bool)TRUE);
X                  break;
X               case DT_IMGRES:
X                  matstr_to_scr(sinfo[j],(bool)TRUE);
X                  break;
X               }
X               swapscreen();
X               c = Crawio(0xff) & 0xff;
X               done = c == 'q';
X               if (demotype == 0) {
X                  matcompose(ins->trans,rotobject[0][i]);
X               }
X            }
X            if (demotype == DT_IMGRES) {
X               for (j = NSTEPS; --j >= 0; ) {
X                  free(sinfo[j]);
X               }
X            }
X         }
X      }
X   }
X                                       /* Now free any occupied storages: */
X   matfrit(it);                        /* the item */
X   matfrins(ins);                      /* the instance */
X
X   free(savarr);                       /* the coordinates work space */
X   free(st_coords);                    /* the real (initial) coordinates */
X   free(order);                        /* the index array for the ordering seq*/
X}
X
Xstatic void house_demo()
X{
X   int nhouses = 4;                    /* street of 4 houses */
X   static double a[][3] = {            /* real coordinates of one house */
X      0,0,0,         /*  0  */
X      1,0,0,         /*  1  */
X      1,1,0,         /*  2  */
X      0,1,0,         /*  3  */
X      0,0,1,         /*  4  */
X      1,0,1,         /*  5  */
X      1,1,1,         /*  6  */
X      0,1,1,         /*  7  */
X      0.5,0.5,1.5    /*  8  */
X   };
X
X   static short order[] = {            /* ordering of indices: 3 polygons */
X      0,1,2,3,0,4,5,1,SV,
X      2,6,5,8,4,7,3,SV,
X      8,6,7,8,SV,
X      SV
X   };
X   item it;                            /* The item */
X   instance *insp;                     /* ptr to the (nhouses) instances */
X   int i;
X                                       /* allocate space for instances */
X   insp = (instance *)malloc(nhouses * sizeof(instance));
X
X   it = matcrit(sizeof(a)/sizeof(a[0]),a,order); /* create the item */
X   for (i = 0; i < nhouses; i++) {     /* Create (nhouses) instances */
X      tl0[0] = i * 2;
X      insp[i] = matcrins(it,idmat,tl0);
X   }
X   move_it("Demo 2: houses (press Help for keys)",insp,nhouses);
X   matfrit(it);                        /* free item storage */
X   for (i = 0; i < nhouses; i++) {
X      matfrins(insp[i]);               /* free each instance storage */
X   }
X   free(insp);                         /* and the storage for the pointers */
X}
X
Xstatic void globe_demo()               /* Demo 3: globe */
X{
X   static double rad = 1;              /* radius of globe */
X   int maxt = 12,                      /* # of 'tropics' */
X       maxf = 16;                      /* # of meridians */
X   int f, t;
X   double (*sphere)[3], (*sp)[3];      /* ptrs to array of initial coordinates*/
X   double st, ct;
X   short *plist, *pl;                  /* list of indexes */
X   item it;                            /* the item */
X   instance ins;                       /* the instance */
X
X/* Create space for coordinates and index list */
X   sphere = (double (*)[3])malloc((maxt + 1) * (maxf + 1) * sizeof(double[3]));
X   plist = (short *)malloc(sizeof(short) * ((2 * maxt + 1) * (maxf + 1) - 2));
X   if (sphere == (double (*)[3])0 || plist == (short *)0) {
X      fprintf(stderr,"Memory allocation failed\n");
X      return;
X   }
X
X   for (t = 0; t <= maxt; t++) {       /* Calculate coordinates */
X      st = rad * mysin(t * PI / maxt);
X      ct = rad * mycos(t * PI / maxt);
X      for (f = 0; f <= maxf; f++) {
X         sp = sphere + (maxf + 1) * t + f;
X         (*sp)[0] = st * mycos(f * 2 * PI / maxf);
X         (*sp)[1] = st * mysin(f * 2 * PI / maxf);
X         (*sp)[2] = ct;
X      }
X   }
X
X   pl = plist;
X   for (t = 1; t <= maxt - 1; t++) {   /* Calculate index list: 'tropics' */
X      for (f = 0; f <= maxf; f++) {
X         *pl++ = (maxf + 1) * t + f;
X      }
X      *pl++ = SV;
X   }
X   for (f = 0; f <= maxf - 1; f++) {   /* Calculate index list; meridians */
X      for (t = 0; t <= maxt; t++) {
X         *pl++ = (maxf + 1) * t + f;
X      }
X      *pl++ = SV;
X   }
X   *pl++ = SV;
X
X   it = matcrit((maxf + 1) * (maxt + 1),sphere,plist); /* create the item */
X   tl0[0] = 0;
X   ins = matcrins(it,idmat,tl0);       /* create instance */
X   move_it("Demo 3: globe (press Help for keys)",&ins,1); /* move on input */
X   matfrit(it);   matfrins(ins);       /* free item and instance */
X}
X
Xstatic void move_it(title,insp,inscnt) /* move inscnt instances */
Xchar *title;                           /* Title to be displayed */
Xinstance *insp;                        /* ptr to array of instances */
Xint inscnt;                            /* # of instances */
X{
X   bool drawfast = TRUE;               /* toggle to switch between drawing */ 
X                                       /* algorithms */
X   char c;
X   int i,
X       times,                          /* # of steps to take */
X       mode0 = 1,                      /* OR drawing mode; ignored by fastdraw*/
X       axis;                           /* axis: 0, 1, 2 = x, y, z */
X   bool forward;                       /* direction: forward versus backward */
X   long inkey;                         /* key pressed code */
X   WORD *eye;                          /* observer transformation array ptr */
X
X   printf("%s\n\n\t%s\n\n\t\t- Press any key to start -\n\n",CLS,title);
X   swapscreen();                       /* Show title */
X   Crawcin();                          /* Wait for keypress */
X
X   eye = matseteye(idmat,tl2,dist,scale_x,scale_y); /* Set observer tranform. */
X
X   times = 1;
X   for (c = '\0'; c != 'q'; ) {
X      v_clrwk(handle);                 /* clear logical screen */
X      for (i = 0; i < inscnt; i++) {
X         matproject(insp[i]);          /* project each instance */
X         if (drawfast) {               /* and draw it */
X            matfdraw(insp[i],mode0);   /* either fast */
X         } else {
X            matdraw(insp[i],mode0);    /* or standard */
X         }
X      }
X      swapscreen();                    /* Show (make logical screen physical) */
X      inkey = Crawcin();               /* Wait for a key */
X      if (inkey == HELP_KEY) {         /* After Help key show help info */
X         help();
X         continue;
X      }
X      c = inkey;
X      if (c > '0' && c <= '9') {       /* If numeric key */
X         times = c - '0';              /* Number of steps at a time (def. 1) */
X         continue;
X      }
X
X      switch (c) {
X         case 's':                     /* Switch draw algorithm */
X            drawfast = !drawfast;
X            break;
X         case 'x':                     /* Translations */
X         case 'X':
X         case 'y':
X         case 'Y':
X         case 'z':
X         case 'Z':
X            forward = c < 'x';
X            if (forward) {
X               axis = c - 'X';
X            } else {
X               axis = c - 'x';
X            }
X            while (times--) {          /* Apply them to the observer transf. */
X               matcompose(eye,traobserv[forward][axis]);
X            }
X            break;
X         case 'a':                     /* Rotations observer */
X         case 'A':
X         case 'b':
X         case 'B':
X         case 'c':
X         case 'C':
X            forward = c < 'a';
X            if (forward) {
X               axis = c - 'A';
X            } else {
X               axis = c - 'a';
X            }
X            while (times--) {          /* Apply them to the observer transf. */
X               matcompose(eye,rotobserv[forward][axis]);
X            }
X            break;
X         case 'k':                     /* Rotations object */
X         case 'K':
X         case 'l':
X         case 'L':
X         case 'm':
X         case 'M':
X            forward = c < 'k';
X            if (forward) {
X               axis = c - 'K';
X            } else {
X               axis = c - 'k';
X            }
X            while (times--) {          /* Apply them to each object transf. */
X               for (i = 0; i < inscnt; i++) {
X                  matcompose(insp[i]->trans,rotobject[forward][axis]);
X               }
X            }
X            break;
X      }
X      times = 1;                       /* # steps back to default value */
X   }
X}
+ END-OF-FILE 3demo.c
chmod 'u=rw,g=r,o=' '3demo.c'
echo 'SENT: -rw-r-----  1 leo         17621 Aug 21 14:33 3demo.c'
echo -n 'RCVD: '
/bin/ls -l 3demo.c
echo 'Extracting gemfuncs.c'
sed 's/^X//' > gemfuncs.c << '+ END-OF-FILE gemfuncs.c'
X/*
X ******************************************************************************
X *                                                                            *
X *    gemfuncs.c  version 1.0 of 17 July 1988    (C) L.J.M. de Wit 1988       *
X *                                                                            *
X * This software may be used and distributed freely if not used commercially  *
X * and the originator (me) is mentioned.                                      *
X *                                                                            *
X ******************************************************************************
X *
X * gemfuncs.c: graphics part of 3demo.prg. For O.S's without GEM an
X *     alternative module should be made. It includes the following functions:
X *
X * gem_init() :
X *     opens a virtual workstation and allocates extra screen memory for
X *     smooth drawing.
X * gem_exit() :
X *     closes a virtual workstation, restores screen location and exits.
X *     The allocated memory for a screen is automatically returned to the
X *     system.
X * swapscreen() :
X *     switches the logical and physical screens. Drawing takes place on the
X *     logical screen, while the physical screen is displayed. This ensures
X *     that movement is smooth. 
X * help() :
X *     Display help info about key use.
X */
X
X#include <osbind.h>
X#include <portab.h>
X#include <gemlib.h>
X#include "matricks.h"
X
XWORD handle,                                 /* Handle of virt. workstation */
X     maxx,                                   /* Max. x coordinate */
X     maxy,                                   /* Max. y coordinate */
X     ncolor,                                 /* # of colours: 2, 4, 16 */
X     pixwidth,                               /* Pixel width in microns */
X     pixheight;                              /* Pixel height in microns */
XLONG _mneed = 400000;                        /* Memory needed by this program */
X
Xstatic WORD dummy;
Xstatic LONG physbase,                        /* Physical screen base address */
X            logbase;                         /* Logical screen base address */
X
Xvoid gem_init()                              /* Init the vwk and screen mem */
X{
X   int i;
X   short work_in[11], work_out[57];
X
X   physbase = Physbase();                    /* Get physical base address */
X   logbase = (Malloc(32256) + 255) & ~255;   /* Allocate 32000 bytes */
X                                             /*   at 256 bytes boundary */
X   printf(CLS);                              /* Clear both screens */
X   swapscreen();
X   printf(CLS);
X   swapscreen();
X
X   appl_init();                              /* Administrate application */
X   handle = graf_handle(&dummy,&dummy,&dummy,&dummy);
X
X   for (i = 0; i < 10; i++) {
X      work_in[i] = 1;
X   }
X   work_in[10] = 2;
X
X   v_opnvwk(work_in,&handle,work_out);       /* Open virt. workstation */
X   maxx = work_out[0];                       /* Get some return parameters*/
X   maxy = work_out[1];
X   pixwidth = work_out[3];
X   pixheight = work_out[4];
X   ncolor = work_out[13];
X   printf("\33f");                           /* Cursor off */
X}
X
Xvoid gem_exit(code)                          /* Exit, returning this code */
Xint code;
X{
X   logbase = physbase;                       /* Next call to swapscreen */
X                                             /*    restores things to normal */
X   v_clsvwk(handle);                         /* Close the vwk */
X   appl_exit();                              /* Exit application */
X   swapscreen();                             /* Standard screen addresses */
X   exit(code);                               /* Finally exit with the code*/
X}
X
Xvoid swapscreen()                            /* Swap the two screens */
X{
X   static int which = 0;                     /* Toggle to select screens */
X
X   if (!which) {
X      Setscreen(logbase,physbase,-1);
X   } else {
X      Setscreen(physbase,logbase,-1);
X   }
X   which = !which;                           /* Toggle it */
X}
X
Xvoid help()                                  /* Show help info */
X{
X   printf(CLS);
X   printf("\n      ========  Keys to manipulate object  ========\n\n");
X   printf("a/A\tTurn around observer x-axis back-/forwards\n");
X   printf("b/B\tTurn around observer y-axis back-/forwards\n");
X   printf("c/C\tTurn around observer z-axis back-/forwards\n\n");
X   printf("k/K\tTurn around object   x-axis back-/forwards\n");
X   printf("l/L\tTurn around object   y-axis back-/forwards\n");
X   printf("m/M\tTurn around object   z-axis back-/forwards\n\n");
X   printf("x/X\tMove along  observer x-axis back-/forwards\n");
X   printf("y/Y\tMove along  observer y-axis back-/forwards\n");
X   printf("z/Z\tMove along  observer z-axis back-/forwards\n\n");
X   printf("q\tQuit this demo\n\n");
X   printf("Hit any key to continue...\n");
X   swapscreen();                             /* Now show it */
X   Crawcin();                                /* Wait for key press */
X   swapscreen();                             /* Get old screen back */
X}
+ END-OF-FILE gemfuncs.c
chmod 'u=rw,g=r,o=' 'gemfuncs.c'
echo 'SENT: -rw-r-----  1 leo          5015 Aug 21 14:36 gemfuncs.c'
echo -n 'RCVD: '
/bin/ls -l gemfuncs.c
exit 0