v04i083: 3demo program - part 1 of 4
Leo de Wit
leo at philmds.UUCP
Tue Sep 20 11:14:39 AEST 1988
Posting-number: Volume 4, Issue 83
Submitted-by: "Leo de Wit" <leo at 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
More information about the Comp.sources.misc
mailing list