home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
x
/
volume16
/
x3d
/
part02
< prev
next >
Wrap
Internet Message Format
|
1992-02-05
|
57KB
Path: uunet!think.com!mips!msi!dcmartin
From: spy@castlab.engr.wisc.edu (Mark Spychalla)
Newsgroups: comp.sources.x
Subject: v16i047: 3D Wireframe viewer, Part02/06
Message-ID: <1992Feb6.143929.29285@msi.com>
Date: 6 Feb 92 14:39:29 GMT
References: <csx-16i046-x3d@uunet.UU.NET>
Sender: dcmartin@msi.com (David C. Martin - Moderator)
Organization: Molecular Simulations, Inc.
Lines: 1713
Approved: dcmartin@msi.com
Originator: dcmartin@fascet
Submitted-by: spy@castlab.engr.wisc.edu (Mark Spychalla)
Posting-number: Volume 16, Issue 47
Archive-name: x3d/part02
# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sources-unix@uunet.uu.net if you want that tool.
# If this archive is complete, you will see the following message at the end:
# "End of archive 2 (of 6)."
# Contents: Imakefile Makefile con/Imakefile con/Makefile.sav
# con/cube.obj con/cube.segs gi.c
# Wrapped by dcmartin@fascet on Thu Feb 6 06:38:05 1992
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'Imakefile' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Imakefile'\"
else
echo shar: Extracting \"'Imakefile'\" \(181 characters\)
sed "s/^X//" >'Imakefile' <<'END_OF_FILE'
XIMAKE_DEFINES= -DManSuffix=6
X
XDEFINES = -DFAST_FLOATS #-D_POSIX_SOURCE -DPROTOTYPES
XDEPLIBS = $(DEPXLIB)
XLOCAL_LIBRARIES = $(XLIB)
XEXTRA_LIBRARIES = -lm
X
XSimpleProgramTarget(x3d)
X
END_OF_FILE
if test 181 -ne `wc -c <'Imakefile'`; then
echo shar: \"'Imakefile'\" unpacked with wrong size!
fi
# end of 'Imakefile'
fi
if test -f 'Makefile' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(10370 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
X# Makefile generated by imake - do not edit!
X# $XConsortium: imake.c,v 1.65 91/07/25 17:50:17 rws Exp $
X#
X# The cpp used on this machine replaces all newlines and multiple tabs and
X# spaces in a macro expansion with a single space. Imake tries to compensate
X# for this, but is not always successful.
X#
X
X# -------------------------------------------------------------------------
X# Makefile generated from "Imake.tmpl" and <Imakefile>
X# $XConsortium: Imake.tmpl,v 1.139 91/09/16 08:52:48 rws Exp $
X#
X# Platform-specific parameters may be set in the appropriate <vendor>.cf
X# configuration files. Site-specific parameters should be set in the file
X# site.def. Full rebuilds are recommended if any parameters are changed.
X#
X# If your C preprocessor does not define any unique symbols, you will need
X# to set BOOTSTRAPCFLAGS when rebuilding imake (usually when doing
X# "make World" the first time).
X#
X
X# -------------------------------------------------------------------------
X# site-specific configuration parameters that need to come before
X# the platform-specific parameters - edit site.def to change
X
X# site: $XConsortium: site.def,v 1.2 91/07/30 20:26:44 rws Exp $
X
X# -------------------------------------------------------------------------
X# platform-specific configuration parameters - edit sun.cf to change
X
X# platform: $XConsortium: sun.cf,v 1.68 91/07/30 11:34:39 rws Exp $
X
X# operating system: SunOS 4.1.1
X
X# $XConsortium: sunLib.rules,v 1.6 91/03/24 17:55:58 rws Exp $
X
X# -------------------------------------------------------------------------
X# site-specific configuration parameters that go after
X# the platform-specific parameters - edit site.def to change
X
X# site: $XConsortium: site.def,v 1.2 91/07/30 20:26:44 rws Exp $
X
X SHELL = /bin/sh
X
X TOP = .
X CURRENT_DIR = .
X
X AR = ar clq
X BOOTSTRAPCFLAGS =
X CC = cc
X AS = as
X
X COMPRESS = compress
X CPP = /lib/cpp $(STD_CPP_DEFINES)
X PREPROCESSCMD = cc -E $(STD_CPP_DEFINES)
X INSTALL = install
X LD = ld
X LINT = lint
X LINTLIBFLAG = -C
X LINTOPTS = -axz
X LN = ln -s
X MAKE = make
X MV = mv
X CP = cp
X
X RANLIB = ranlib
X RANLIBINSTFLAGS =
X
X RM = rm -f
X TROFF = psroff
X MSMACROS = -ms
X TBL = tbl
X EQN = eqn
X STD_INCLUDES =
X STD_CPP_DEFINES =
X STD_DEFINES =
X EXTRA_LOAD_FLAGS =
X EXTRA_LIBRARIES =
X TAGS = ctags
X
X SHAREDCODEDEF = -DSHAREDCODE
X SHLIBDEF = -DSUNSHLIB
X
X PROTO_DEFINES =
X
X INSTPGMFLAGS =
X
X INSTBINFLAGS = -m 0755
X INSTUIDFLAGS = -m 4755
X INSTLIBFLAGS = -m 0644
X INSTINCFLAGS = -m 0444
X INSTMANFLAGS = -m 0444
X INSTDATFLAGS = -m 0444
X INSTKMEMFLAGS = -m 4755
X
X PROJECTROOT = /usr/X11/R5
X
X TOP_INCLUDES = -I$(INCROOT)
X
X CDEBUGFLAGS = -O
X CCOPTIONS = -pipe
X
X ALLINCLUDES = $(INCLUDES) $(EXTRA_INCLUDES) $(TOP_INCLUDES) $(STD_INCLUDES)
X ALLDEFINES = $(ALLINCLUDES) $(STD_DEFINES) $(EXTRA_DEFINES) $(PROTO_DEFINES) $(DEFINES)
X CFLAGS = $(CDEBUGFLAGS) $(CCOPTIONS) $(ALLDEFINES)
X LINTFLAGS = $(LINTOPTS) -DLINT $(ALLDEFINES)
X
X LDLIBS = $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
X
X LDOPTIONS = $(CDEBUGFLAGS) $(CCOPTIONS) $(LOCAL_LDFLAGS) -L$(USRLIBDIR)
X
X LDCOMBINEFLAGS = -X -r
X DEPENDFLAGS =
X
X MACROFILE = sun.cf
X RM_CMD = $(RM) *.CKP *.ln *.BAK *.bak *.o core errs ,* *~ *.a .emacs_* tags TAGS make.log MakeOut
X
X IMAKE_DEFINES =
X
X IRULESRC = $(CONFIGDIR)
X IMAKE_CMD = $(IMAKE) -DUseInstalled -I$(IRULESRC) $(IMAKE_DEFINES)
X
X ICONFIGFILES = $(IRULESRC)/Imake.tmpl $(IRULESRC)/Imake.rules \
X $(IRULESRC)/Project.tmpl $(IRULESRC)/site.def \
X $(IRULESRC)/$(MACROFILE) $(EXTRA_ICONFIGFILES)
X
X# -------------------------------------------------------------------------
X# X Window System Build Parameters
X# $XConsortium: Project.tmpl,v 1.138 91/09/10 09:02:12 rws Exp $
X
X# -------------------------------------------------------------------------
X# X Window System make variables; this need to be coordinated with rules
X
X PATHSEP = /
X USRLIBDIR = /usr/X11/R5/lib
X BINDIR = /usr/X11/R5/bin
X INCROOT = /usr/X11/R5/include
X BUILDINCROOT = $(TOP)
X BUILDINCDIR = $(BUILDINCROOT)/X11
X BUILDINCTOP = ..
X INCDIR = $(INCROOT)/X11
X ADMDIR = /usr/adm
X LIBDIR = $(USRLIBDIR)/X11
X CONFIGDIR = $(LIBDIR)/config
X LINTLIBDIR = $(USRLIBDIR)/lint
X
X FONTDIR = $(LIBDIR)/fonts
X XINITDIR = $(LIBDIR)/xinit
X XDMDIR = $(LIBDIR)/xdm
X TWMDIR = $(LIBDIR)/twm
X MANPATH = /usr/X11/R5/man
X MANSOURCEPATH = $(MANPATH)/man
X MANSUFFIX = n
X LIBMANSUFFIX = 3
X MANDIR = $(MANSOURCEPATH)$(MANSUFFIX)
X LIBMANDIR = $(MANSOURCEPATH)$(LIBMANSUFFIX)
X NLSDIR = $(LIBDIR)/nls
X PEXAPIDIR = $(LIBDIR)/PEX
X XAPPLOADDIR = $(LIBDIR)/app-defaults
X FONTCFLAGS = -t
X
X INSTAPPFLAGS = $(INSTDATFLAGS)
X
X IMAKE = imake
X DEPEND = makedepend
X RGB = rgb
X
X FONTC = bdftopcf
X
X MKFONTDIR = mkfontdir
X MKDIRHIER = /bin/sh $(BINDIR)/mkdirhier
X
X CONFIGSRC = $(TOP)/config
X DOCUTILSRC = $(TOP)/doc/util
X CLIENTSRC = $(TOP)/clients
X DEMOSRC = $(TOP)/demos
X LIBSRC = $(TOP)/lib
X FONTSRC = $(TOP)/fonts
X INCLUDESRC = $(TOP)/X11
X SERVERSRC = $(TOP)/server
X UTILSRC = $(TOP)/util
X SCRIPTSRC = $(UTILSRC)/scripts
X EXAMPLESRC = $(TOP)/examples
X CONTRIBSRC = $(TOP)/../contrib
X DOCSRC = $(TOP)/doc
X RGBSRC = $(TOP)/rgb
X DEPENDSRC = $(UTILSRC)/makedepend
X IMAKESRC = $(CONFIGSRC)
X XAUTHSRC = $(LIBSRC)/Xau
X XLIBSRC = $(LIBSRC)/X
X XMUSRC = $(LIBSRC)/Xmu
X TOOLKITSRC = $(LIBSRC)/Xt
X AWIDGETSRC = $(LIBSRC)/Xaw
X OLDXLIBSRC = $(LIBSRC)/oldX
X XDMCPLIBSRC = $(LIBSRC)/Xdmcp
X BDFTOSNFSRC = $(FONTSRC)/bdftosnf
X BDFTOSNFSRC = $(FONTSRC)/clients/bdftosnf
X BDFTOPCFSRC = $(FONTSRC)/clients/bdftopcf
X MKFONTDIRSRC = $(FONTSRC)/clients/mkfontdir
X FSLIBSRC = $(FONTSRC)/lib/fs
X FONTSERVERSRC = $(FONTSRC)/server
X EXTENSIONSRC = $(TOP)/extensions
X XILIBSRC = $(EXTENSIONSRC)/lib/xinput
X PHIGSLIBSRC = $(EXTENSIONSRC)/lib/PEX
X
X# $XConsortium: sunLib.tmpl,v 1.11 91/07/31 11:32:08 rws Exp $
X
XSHLIBLDFLAGS = -assert pure-text
XPICFLAGS = -pic
X
X DEPEXTENSIONLIB =
X EXTENSIONLIB = -lXext
X
X DEPXLIB = $(DEPEXTENSIONLIB)
X XLIB = $(EXTENSIONLIB) -lX11
X
X DEPXMULIB = $(USRLIBDIR)/libXmu.sa.$(SOXMUREV)
X XMULIB = -lXmu
X
X DEPOLDXLIB =
X OLDXLIB = -loldX
X
X DEPXTOOLLIB = $(USRLIBDIR)/libXt.sa.$(SOXTREV)
X XTOOLLIB = -lXt
X
X DEPXAWLIB = $(USRLIBDIR)/libXaw.sa.$(SOXAWREV)
X XAWLIB = -lXaw
X
X DEPXILIB =
X XILIB = -lXi
X
X SOXLIBREV = 4.10
X SOXTREV = 4.10
X SOXAWREV = 5.0
X SOOLDXREV = 4.10
X SOXMUREV = 4.10
X SOXEXTREV = 4.10
X SOXINPUTREV = 4.10
X
X DEPXAUTHLIB = $(USRLIBDIR)/libXau.a
X XAUTHLIB = -lXau
X DEPXDMCPLIB = $(USRLIBDIR)/libXdmcp.a
X XDMCPLIB = -lXdmcp
X
X DEPPHIGSLIB = $(USRLIBDIR)/libphigs.a
X PHIGSLIB = -lphigs
X
X DEPXBSDLIB = $(USRLIBDIR)/libXbsd.a
X XBSDLIB = -lXbsd
X
X LINTEXTENSIONLIB = $(LINTLIBDIR)/llib-lXext.ln
X LINTXLIB = $(LINTLIBDIR)/llib-lX11.ln
X LINTXMU = $(LINTLIBDIR)/llib-lXmu.ln
X LINTXTOOL = $(LINTLIBDIR)/llib-lXt.ln
X LINTXAW = $(LINTLIBDIR)/llib-lXaw.ln
X LINTXI = $(LINTLIBDIR)/llib-lXi.ln
X LINTPHIGS = $(LINTLIBDIR)/llib-lphigs.ln
X
X DEPLIBS = $(DEPXAWLIB) $(DEPXMULIB) $(DEPXTOOLLIB) $(DEPXLIB)
X
X DEPLIBS1 = $(DEPLIBS)
X DEPLIBS2 = $(DEPLIBS)
X DEPLIBS3 = $(DEPLIBS)
X
X# -------------------------------------------------------------------------
X# Imake rules for building libraries, programs, scripts, and data files
X# rules: $XConsortium: Imake.rules,v 1.123 91/09/16 20:12:16 rws Exp $
X
X# -------------------------------------------------------------------------
X# start of Imakefile
X
XIMAKE_DEFINES= -DManSuffix=6
X
XDEFINES = -DFAST_FLOATS #-D_POSIX_SOURCE -DPROTOTYPES
XDEPLIBS = $(DEPXLIB)
XLOCAL_LIBRARIES = $(XLIB)
XEXTRA_LIBRARIES = -lm
X
X OBJS = x3d.o
X SRCS = x3d.c
X
X PROGRAM = x3d
X
Xall:: x3d
X
Xx3d: $(OBJS) $(DEPLIBS)
X $(RM) $@
X $(CC) -o $@ $(OBJS) $(LDOPTIONS) $(LOCAL_LIBRARIES) $(LDLIBS) $(EXTRA_LOAD_FLAGS)
X
Xsaber_x3d:: $(SRCS)
X # load $(ALLDEFINES) $(SRCS) $(LOCAL_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
X
Xosaber_x3d:: $(OBJS)
X # load $(ALLDEFINES) $(OBJS) $(LOCAL_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
X
Xinstall:: x3d
X @if [ -d $(DESTDIR)$(BINDIR) ]; then set +x; \
X else (set -x; $(MKDIRHIER) $(DESTDIR)$(BINDIR)); fi
X $(INSTALL) -c $(INSTPGMFLAGS) x3d $(DESTDIR)$(BINDIR)
X
Xinstall.man:: x3d.man
X @if [ -d $(DESTDIR)$(MANDIR) ]; then set +x; \
X else (set -x; $(MKDIRHIER) $(DESTDIR)$(MANDIR)); fi
X $(INSTALL) -c $(INSTMANFLAGS) x3d.man $(DESTDIR)$(MANDIR)/x3d.$(MANSUFFIX)
X
Xdepend::
X $(DEPEND) $(DEPENDFLAGS) -s "# DO NOT DELETE" -- $(ALLDEFINES) -- $(SRCS)
X
Xlint:
X $(LINT) $(LINTFLAGS) $(SRCS) $(LINTLIBS)
Xlint1:
X $(LINT) $(LINTFLAGS) $(FILE) $(LINTLIBS)
X
Xclean::
X $(RM) $(PROGRAM)
X
X# -------------------------------------------------------------------------
X# common rules for all Makefiles - do not edit
X
Xemptyrule::
X
Xclean::
X $(RM_CMD) "#"*
X
XMakefile::
X -@if [ -f Makefile ]; then set -x; \
X $(RM) Makefile.bak; $(MV) Makefile Makefile.bak; \
X else exit 0; fi
X $(IMAKE_CMD) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT_DIR)
X
Xtags::
X $(TAGS) -w *.[ch]
X $(TAGS) -xw *.[ch] > TAGS
X
Xsaber:
X # load $(ALLDEFINES) $(SRCS)
X
Xosaber:
X # load $(ALLDEFINES) $(OBJS)
X
X# -------------------------------------------------------------------------
X# empty rules for directories that do not have SUBDIRS - do not edit
X
Xinstall::
X @echo "install in $(CURRENT_DIR) done"
X
Xinstall.man::
X @echo "install.man in $(CURRENT_DIR) done"
X
XMakefiles::
X
Xincludes::
X
X# -------------------------------------------------------------------------
X# dependencies generated by makedepend
X
END_OF_FILE
if test 10370 -ne `wc -c <'Makefile'`; then
echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'con/Imakefile' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'con/Imakefile'\"
else
echo shar: Extracting \"'con/Imakefile'\" \(76 characters\)
sed "s/^X//" >'con/Imakefile' <<'END_OF_FILE'
XIMAKE_DEFINES= -DManSuffix=6
XEXTRA_LIBRARIES = -lm
XSimpleProgramTarget(con)
END_OF_FILE
if test 76 -ne `wc -c <'con/Imakefile'`; then
echo shar: \"'con/Imakefile'\" unpacked with wrong size!
fi
# end of 'con/Imakefile'
fi
if test -f 'con/Makefile.sav' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'con/Makefile.sav'\"
else
echo shar: Extracting \"'con/Makefile.sav'\" \(122 characters\)
sed "s/^X//" >'con/Makefile.sav' <<'END_OF_FILE'
XCFLAGS = -pipe -O4 -fsingle
XLIBS = -lm
X CC = cc
X
Xcon: con.c
X $(CC) $(CFLAGS) -o con con.c $(LIBS)
X
Xclean:
X rm con
END_OF_FILE
if test 122 -ne `wc -c <'con/Makefile.sav'`; then
echo shar: \"'con/Makefile.sav'\" unpacked with wrong size!
fi
# end of 'con/Makefile.sav'
fi
if test -f 'con/cube.obj' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'con/cube.obj'\"
else
echo shar: Extracting \"'con/cube.obj'\" \(202 characters\)
sed "s/^X//" >'con/cube.obj' <<'END_OF_FILE'
X9 12
X-1000 -1000 -1000
X-1000 1000 -1000
X-1000 -1000 1000
X-1000 1000 -1000
X-1000 1000 1000
X1000 -1000 -1000
X1000 1000 -1000
X1000 -1000 1000
X1000 1000 1000
X0 5
X0 3
X0 2
X5 7
X2 7
X7 8
X2 4
X3 4
X4 8
X5 6
X1 6
X6 8
END_OF_FILE
if test 202 -ne `wc -c <'con/cube.obj'`; then
echo shar: \"'con/cube.obj'\" unpacked with wrong size!
fi
# end of 'con/cube.obj'
fi
if test -f 'con/cube.segs' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'con/cube.segs'\"
else
echo shar: Extracting \"'con/cube.segs'\" \(473 characters\)
sed "s/^X//" >'con/cube.segs' <<'END_OF_FILE'
X -1000 -1000 -1000 1000 -1000 -1000
X -1000 -1000 -1000 -1000 1000 -1000
X -1000 -1000 -1000 -1000 -1000 1000
X 1000 -1000 1000 1000 -1000 -1000
X 1000 -1000 1000 -1000 -1000 1000
X 1000 -1000 1000 1000 1000 1000
X -1000 1000 1000 -1000 -1000 1000
X -1000 1000 1000 -1000 1000 -1000
X -1000 1000 1000 1000 1000 1000
X 1000 1000 -1000 1000 -1000 -1000
X 1000 1000 -1000 -1000 1000 -1000
X 1000 1000 -1000 1000 1000 1000
END_OF_FILE
if test 473 -ne `wc -c <'con/cube.segs'`; then
echo shar: \"'con/cube.segs'\" unpacked with wrong size!
fi
# end of 'con/cube.segs'
fi
if test -f 'gi.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'gi.c'\"
else
echo shar: Extracting \"'gi.c'\" \(39449 characters\)
sed "s/^X//" >'gi.c' <<'END_OF_FILE'
X
X/*
X Copyright 1992 Mark Spychalla
X
X Permission to use, copy, modify, distribute, and sell this software and
X its documentation for any purpose is hereby granted without fee,
X provided that the above copyright notice appear in all copies and that
X both that copyright notice and this permission notice appear in
X supporting documentation, and that the name of Mark Spychalla not be used
X in advertising or publicity pertaining to distribution of the software
X without specific, written prior permission. Mark Spychalla makes no
X representations about the suitability of this software for any purpose.
X It is provided "as is" without express or implied warranty.
X
X Mark Spychalla disclaims all warranties with regard to this software,
X including all implied warranties of merchantability and fitness, in no
X event shall Mark Spychalla be liable for any special, indirect or
X consequential damages or any damages whatsoever resulting from loss of use,
X data or profits, whether in an action of contract, negligence or other
X tortious action, arising out of or in connection with the use or performance
X of this software.
X*/
X
X#include <stdio.h>
X#include "gi.h"
X#include "char.h"
X
X
Xint GIerrno = GIE_OK;
X
X
X/* Graphics interface functions */
X
X
Xvoid GI_Rotate(points, cx, cy, cz, sx, sy, sz)
XanglePoint *points;
Xdouble cx, cy, cz, sx, sy, sz;
X/******************************************************************************
X Rotate about Z, X, then Y, for two points.
X******************************************************************************/
X{
Xint index;
Xdouble x, y, z, t;
X
X for(index = 0; index < 2; index++){
X x = points[index].x;
X y = points[index].y;
X z = points[index].z;
X
X t = x * cz + y * sz;
X y = y * cz - x * sz;
X x = t;
X
X points[index].y = y * cx + z * sx;
X
X z = z * cx - y * sx;
X
X points[index].x = x * cy + z * sy;
X points[index].z = z * cy - x * sy;
X }
X}
X
X
X
Xdouble GI_DotProduct(x1, Y1, x2, y2)
Xdouble x1, Y1, x2, y2;
X/******************************************************************************
X Dot product (calculate the cosine of the angle between two vectors).
X******************************************************************************/
X{
Xdouble temp;
X
X if((x1 == 0.0 && Y1 == 0.0)){
X return 1.0;
X }
X
X temp = sqrt(x1 * x1 + Y1 * Y1);
X x1 = x1 / temp;
X Y1 = Y1 / temp;
X
X temp = x1 * x2 + Y1 * y2;
X
X if(temp > 1.0)
X temp = fmod(temp, 1.0);
X
X if(temp < -1.0)
X temp = -fmod(-temp, 1.0);
X
X return(temp);
X}
X
X
X
Xvoid GI_CalculateAngles(X, Y, Z, X1, Y1, Z1)
Xdouble *X, *Y, *Z;
Xdouble X1, Y1, Z1;
X/******************************************************************************
X Calculate what the result of the angle changes of X1, Y1, and Z1 are
X in my weird coordinate system.
X******************************************************************************/
X{
XanglePoint points[2];
X
X points[0].x = 0.0; points[0].y = 0.0; points[0].z = 1.0;
X points[1].x = 1.0; points[1].y = 0.0; points[1].z = 0.0;
X
X GI_Rotate(points, cos(*X), cos(*Y), cos(*Z), sin(*X), sin(*Y), sin(*Z));
X GI_Rotate(points, cos(X1), cos(Y1), cos(Z1), sin(X1), sin(Y1), sin(Z1));
X
X *Y = acos(GI_DotProduct(points[0].x, points[0].z, 0.0, 1.0));
X
X if(points[0].x < 0.0)
X *Y = -*Y;
X
X GI_Rotate(points, 1.0, cos(-*Y), 1.0, 0.0, sin(-*Y), 0.0);
X *X = acos(GI_DotProduct(points[0].y, points[0].z, 0.0, 1.0));
X
X if(points[0].y < 0.0)
X *X = -*X;
X
X GI_Rotate(points, cos(-*X), 1.0, 1.0, sin(-*X), 0.0, 0.0);
X *Z = acos(GI_DotProduct(points[1].x, points[1].y, 1.0, 0.0));
X
X if(!(points[1].y < 0.0))
X *Z = -*Z;
X}
X
X
X
Xvoid GI_ParseCommandLine(argc, argv, filename, scale, gi)
Xint argc;
Xchar *argv[];
Xchar **filename;
Xdouble *scale;
XGIinfo *gi;
X/******************************************************************************
X Parse the command line set the filename and the appropriate flags
X******************************************************************************/
X{
Xstatic char *options[] = {
X "-help",
X "-display",
X "-geometry",
X "-flicker",
X "-menu",
X "-stats",
X "-stereo",
X "-controls",
X "-scale"
X};
Xint NUMOPTIONS = 9;
Xint filenameValid = 0;
Xint index, option;
Xfloat temp;
X
X gi->Flicker = 0;
X gi->Menu = gi->Stats = gi->Stereo = 1;
X gi->DisplayName = gi->Geometry = NULL;
X *scale = 1.0;
X
X for(index = 1; index < argc; index++){
X for(option = 0; option < NUMOPTIONS; option++)
X if(!strcmp(argv[index], options[option]))
X break;
X
X switch(option){
X
X case 0:
X fprintf(stderr, "Options:\n");
X fprintf(stderr, "-display <display> X display name\n");
X fprintf(stderr, "-flicker Make window flicker\n");
X fprintf(stderr, "-geometry <geometry> Window geometry\n");
X fprintf(stderr, "-help Print this message\n");
X fprintf(stderr, "-menu Turn off menu\n");
X fprintf(stderr, "-stats Turn off stats\n");
X fprintf(stderr, "-stereo Turn off stereo\n");
X fprintf(stderr, "-controls Switch controls style\n");
X fprintf(stderr, "-scale <amount> Scale object by amount\n");
X exit(0);
X break;
X
X case 1:
X gi->DisplayName = argv[++index];
X break;
X
X case 2:
X gi->Geometry = argv[++index];
X break;
X
X case 3:
X gi->Flicker = 1;
X break;
X
X case 4:
X gi->Menu = 0;
X break;
X
X case 5:
X gi->Stats = 0;
X break;
X
X case 6:
X gi->Stereo = 0;
X break;
X
X case 7:
X gi->Relative = 0;
X break;
X
X case 8:
X if(!sscanf(argv[++index], "%f\n", &temp)){
X fprintf(stderr, "Bad scale argument\n");
X exit(1);
X }
X *scale = (double)temp;
X break;
X
X default:
X if(!filenameValid){
X *filename = (char *)(argv[index]);
X filenameValid = 1;
X }else{
X fprintf(stderr,"usage: %s <object file>\n", argv[0]);
X fprintf(stderr,"%s -help for a list of options\n", argv[0]);
X exit(1);
X }
X break;
X }
X }
X
X if(!filenameValid){
X fprintf(stderr,"usage: %s <object file>\n", argv[0]);
X fprintf(stderr,"%s -help for a list of options\n", argv[0]);
X exit(1);
X }
X}
X
X
X
Xvoid GI_ResizeFont(gi)
XGIinfo *gi;
X/******************************************************************************
X Resize the font according to the current window dimensions.
X******************************************************************************/
X{
Xint index;
Xfloat xFontScale, yFontScale;
X
X xFontScale = (float)gi->winX / (float)(NUMCOLS * XLENGTH);
X yFontScale = (float)gi->winY / (float)(NUMROWS * YLENGTH);
X
X if(xFontScale < yFontScale)
X gi->fontScale = xFontScale;
X else
X gi->fontScale = yFontScale;
X
X gi->xCharacterLength = (number)((float)XLENGTH * GAPFACTOR * gi->fontScale);
X gi->yCharacterLength = (number)((float)YLENGTH * GAPFACTOR * gi->fontScale);
X
X for(index = 0; index < NUMLINES; index++){
X Lines[index].x1=(number)((float)lines[index].x1 * gi->fontScale)+ xOffset;
X Lines[index].y1=(number)((float)lines[index].y1 * gi->fontScale)+ yOffset;
X Lines[index].x2=(number)((float)lines[index].x2 * gi->fontScale)+ xOffset;
X Lines[index].y2=(number)((float)lines[index].y2 * gi->fontScale)+ yOffset;
X }
X}
X
X
X
Xvoid GI_PrintString(string, gi)
Xchar *string;
XGIinfo *gi;
X/******************************************************************************
X Print the string specified in the vector font at the current cursor
X position.
X******************************************************************************/
X{
Xint index, x1, Y1, x2, y2, stringIndex;
Xint charNo;
Xchar c;
X
X if(string){
X
X stringIndex = 0;
X
X while(c = string[stringIndex++]){
X
X switch(c){
X case '\n': charNo = 0; gi->cursorX = (number)-1;
X gi->cursorY += (number)1; break;
X case 'A' : charNo = 1; break;
X case 'B' : charNo = 2; break;
X case 'C' : charNo = 3; break;
X case 'D' : charNo = 4; break;
X case 'E' : charNo = 5; break;
X case 'F' : charNo = 6; break;
X case 'G' : charNo = 7; break;
X case 'H' : charNo = 8; break;
X case 'I' : charNo = 9; break;
X case 'J' : charNo = 10; break;
X case 'K' : charNo = 11; break;
X case 'L' : charNo = 12; break;
X case 'M' : charNo = 13; break;
X case 'N' : charNo = 14; break;
X case 'O' : charNo = 15; break;
X case 'P' : charNo = 16; break;
X case 'Q' : charNo = 17; break;
X case 'R' : charNo = 18; break;
X case 'S' : charNo = 19; break;
X case 'T' : charNo = 20; break;
X case 'U' : charNo = 21; break;
X case 'V' : charNo = 22; break;
X case 'W' : charNo = 23; break;
X case 'X' : charNo = 24; break;
X case 'Y' : charNo = 25; break;
X case 'Z' : charNo = 26; break;
X case '0' : charNo = 27; break;
X case '1' : charNo = 28; break;
X case '2' : charNo = 29; break;
X case '3' : charNo = 30; break;
X case '4' : charNo = 31; break;
X case '5' : charNo = 32; break;
X case '6' : charNo = 33; break;
X case '7' : charNo = 34; break;
X case '8' : charNo = 35; break;
X case '9' : charNo = 36; break;
X case '-' : charNo = 37; break;
X case '.' : charNo = 38; break;
X default : charNo = 0; break;
X }
X
X if(charNo){
X
X for(index = 0; index < numLines[charNo]; index++){
X
X x1 = (int)Lines[chars[charNo][index]].x1 +
X gi->cursorX * gi->xCharacterLength;
X
X Y1 = (int)Lines[chars[charNo][index]].y1 +
X gi->cursorY * gi->yCharacterLength;
X
X x2 = (int)Lines[chars[charNo][index]].x2 +
X gi->cursorX * gi->xCharacterLength;
X
X y2 = (int)Lines[chars[charNo][index]].y2 +
X gi->cursorY * gi->yCharacterLength;
X
X GI_AddMenuRedSegment(x1, Y1, x2, y2, gi)
X
X if((!gi->Monochrome) || (!gi->Stereo)){
X GI_AddMenuBlueSegment(x1, Y1, x2, y2, gi)
X }
X }
X }
X
X gi->cursorX += (number)1;
X }
X }
X}
X
X
X
Xvoid GI_DisplayMenu(gi)
XGIinfo *gi;
X/******************************************************************************
X Display the controls menu.
X******************************************************************************/
X{
Xchar buf[256];
X
X GI_Print(buf, gi,"\n\n");
X GI_Print(buf, gi," O O OOOOO OOOO\n");
X GI_Print(buf, gi," O O O O O\n");
X GI_Print(buf, gi," O OOO O O\n");
X GI_Print(buf, gi," O O O O O\n");
X GI_Print(buf, gi," O O OOOOO OOOO\n");
X GI_Print(buf, gi," VERSION 1.1\n");
X GI_Print(buf, gi,"\n");
X GI_Print(buf, gi," CONTROLS SUMMARY\n");
X GI_Print(buf, gi,"\n");
X GI_Print(buf, gi," QUIT UPPERCASE AND LOWERCASE Q\n");
X GI_Print(buf, gi," TOGGLE CONTROLS MENU UPPERCASE AND LOWERCASE M\n");
X GI_Print(buf, gi," TOGGLE POSITION DISPLAY UPPERCASE AND LOWERCASE P\n");
X GI_Print(buf, gi," TOGGLE STEREO DISPLAY UPPERCASE AND LOWERCASE S\n");
X GI_Print(buf, gi," TOGGLE FLICKER UPPERCASE AND LOWERCASE F\n");
X GI_Print(buf, gi," TOGGLE CONTROLS STYLE UPPERCASE AND LOWERCASE R\n");
X GI_Print(buf, gi," ROTATE OBJECT ABOUT X VERTICAL POINTER MOVEMENT WHILE HOLDING LEFT BUTTON \n");
X GI_Print(buf, gi," ROTATE OBJECT ABOUT Z HORIZONTAL POINTER MOVEMENT WHILE HOLDING LEFT BUTTON \n");
X GI_Print(buf, gi," MOVE OBJECT BACKWARD UPPERCASE AND LOWERCASE J\n");
X GI_Print(buf, gi," MOVE OBJECT FOREWARD UPPERCASE AND LOWERCASE K\n");
X GI_Print(buf, gi," MOVE OBJECT RIGHT UPPERCASE AND LOWERCASE H\n");
X GI_Print(buf, gi," MOVE OBJECT LEFT UPPERCASE AND LOWERCASE L\n");
X GI_Print(buf, gi," MOVE OBJECT UP UPPERCASE AND LOWERCASE I\n");
X GI_Print(buf, gi," MOVE OBJECT DOWN UPPERCASE AND LOWERCASE U\n");
X GI_Print(buf, gi," ROTATE ABOUT X UPPERCASE AND LOWERCASE X A\n");
X GI_Print(buf, gi," ROTATE ABOUT Y UPPERCASE AND LOWERCASE Y B\n");
X GI_Print(buf, gi," ROTATE ABOUT Z UPPERCASE AND LOWERCASE Z C\n");
X GI_Print(buf, gi," AUTOROTATE ABOUT X 1 2 3\n");
X GI_Print(buf, gi," AUTOROTATE ABOUT Y 4 5 6\n");
X GI_Print(buf, gi," AUTOROTATE ABOUT Z 7 8 9\n");
X GI_Print(buf, gi," ADJUST FOCUS SQUARE AND CURLY BRACKETS\n");
X}
X
X
X
Xvoid GI_ResetPurpleRectangle(XL, YL, XH, YH, gi)
Xint XL, YL, XH, YH;
XGIinfo *gi;
X/******************************************************************************
X Reset the vertices of the purple rectangle.
X******************************************************************************/
X{
X gi->redSegments[3].x1 = (XL + MARGIN);
X gi->blueSegments[3].x1 = (XL + MARGIN);
X gi->redSegments[3].y1 = (YL + MARGIN);
X gi->blueSegments[3].y1 = (YL + MARGIN);
X gi->redSegments[3].x2 = (XH - MARGIN);
X gi->blueSegments[3].x2 = (XH - MARGIN);
X gi->redSegments[3].y2 = (YL + MARGIN);
X gi->blueSegments[3].y2 = (YL + MARGIN);
X gi->redSegments[2].x1 = (XH - MARGIN);
X gi->blueSegments[2].x1 = (XH - MARGIN);
X gi->redSegments[2].y1 = (YH - MARGIN);
X gi->blueSegments[2].y1 = (YH - MARGIN);
X gi->redSegments[2].x2 = (XL + MARGIN);
X gi->blueSegments[2].x2 = (XL + MARGIN);
X gi->redSegments[2].y2 = (YH - MARGIN);
X gi->blueSegments[2].y2 = (YH - MARGIN);
X gi->redSegments[1].x1 = (XH - MARGIN);
X gi->blueSegments[1].x1 = (XH - MARGIN);
X gi->redSegments[1].y1 = (YL + MARGIN);
X gi->blueSegments[1].y1 = (YL + MARGIN);
X gi->redSegments[1].x2 = (XH - MARGIN);
X gi->blueSegments[1].x2 = (XH - MARGIN);
X gi->redSegments[1].y2 = (YH - MARGIN);
X gi->blueSegments[1].y2 = (YH - MARGIN);
X gi->redSegments[0].x1 = (XL + MARGIN);
X gi->blueSegments[0].x1 = (XL + MARGIN);
X gi->redSegments[0].y1 = (YL + MARGIN);
X gi->blueSegments[0].y1 = (YL + MARGIN);
X gi->redSegments[0].x2 = (XL + MARGIN);
X gi->blueSegments[0].x2 = (XL + MARGIN);
X gi->redSegments[0].y2 = (YH - MARGIN);
X gi->blueSegments[0].y2 = (YH - MARGIN);
X}
X
X
X
Xint GI_InitDisplay(gi, numSegments)
XGIinfo *gi;
Xint numSegments;
X/******************************************************************************
X Set up an X window and our colormap. We rely on X's own error handling and
X reporting for most bad X calls because X buffers requests.
X
X Returns GIE_OK if successful, an GI error otherwise.
X******************************************************************************/
X{
XXColor BLACK, BLUE, RED, PURPLE, oldColormap[NUMCOLORS];
XXWindowAttributes attributes;
XXSetWindowAttributes attribs;
Xint index, screen;
XXVisualInfo vInfo;
XXSizeHints sizehint;
Xint x, y;
Xunsigned int width, height;
X
X/*
X Allocate memory for the XSegments.
X Note: We will crash if we try to draw too many segments.
X The best way to handle this would be the flush the segment
X buffers when they get full. As a current fix just allocate
X LOTS of memory when this gives you trouble.
X */
X
X if((gi->redSegments = (XSegment *)malloc((numSegments + 4) *
X sizeof(XSegment))) == (XSegment *)NULL){
X fprintf(stderr, "Unable to allocate memory for redSegments\n"); exit(1);}
X
X if((gi->blueSegments = (XSegment *)malloc((numSegments + 4) *
X sizeof(XSegment))) == (XSegment *)NULL){
X fprintf(stderr, "Unable to allocate memory for blueSegments\n"); exit(1);}
X
X if((gi->menuRedSegments = (XSegment *)malloc(NUMSEGMENTS * sizeof(XSegment))
X ) == (XSegment *)NULL){
X fprintf(stderr, "Unable to allocate memory for menuRedSegments\n");
X exit(1);}
X
X if((gi->menuBlueSegments = (XSegment *)malloc(NUMSEGMENTS * sizeof(XSegment)
X )) == (XSegment *)NULL){
X fprintf(stderr, "Unable to allocate memory for menuBlueSegments\n");
X exit(1);}
X
X/* Can we connect with the server? */
X
X if((gi->dpy = XOpenDisplay(gi->DisplayName)) == NULL)
X GI_ERROR(NO_CONNECT);
X
X screen = DefaultScreen(gi->dpy);
X
X XSynchronize(gi->dpy, 1);
X
X/* Initialize various flags and default values */
X
X gi->dpyX = DisplayWidth(gi->dpy, screen);
X gi->dpyY = DisplayHeight(gi->dpy, screen);
X gi->winX = gi->dpyX;
X gi->winY = gi->dpyY - 25;
X gi->ColorSelect = gi->oldPointerX = gi->oldPointerY = 0;
X gi->Block = gi->Monochrome = gi->Order = gi->Relative = 1;
X
X/* Initialize the font */
X
X GI_ResizeFont(gi);
X
X/* Which visual do we get? */
X
X gi->trueColor = gi->pseudoColor = 0;
X
X/* An 8 bit PseudoColor ? */
X
X if(XMatchVisualInfo(gi->dpy, screen, 8, PseudoColor, &vInfo))
X gi->pseudoColor = 1;
X else
X
X/* A 24 bit TrueColor ? */
X
X if(XMatchVisualInfo(gi->dpy, screen, 24, TrueColor, &vInfo))
X gi->trueColor = 1;
X
X/* Everything else we treat as monochrome whether or not
X something better may be supported */
X
X/* Make a vanilla window */
X
X gi->win = XCreateSimpleWindow(gi->dpy, RootWindow(gi->dpy,screen), 0, 0,
X gi->winX, gi->winY, 0, 0, 0);
X
X if(X_ERROR(gi->win))
X GI_ERROR(NO_CREATE_WINDOW)
X
X/* Any user geometry? */
X
X if(gi->Geometry){
X
X x = 0;
X y = 0;
X width = gi->winX;
X height = gi->winY;
X sizehint.flags = USPosition | USSize;
X
X XParseGeometry(gi->Geometry, &x, &y, &width, &height);
X
X sizehint.x = x;
X sizehint.y = y;
X sizehint.width = width;
X sizehint.height = height;
X gi->winX = width;
X gi->winY = height;
X
X XResizeWindow(gi->dpy, gi->win, width, height);
X XSetNormalHints(gi->dpy, gi->win, &sizehint);
X }
X
X/* Set horizontal and vertical ranges */
X
X gi->winH = (int)(gi->winX / 2.0);
X gi->winV = (int)(gi->winY / 2.0);
X
X/* Make our graphics context */
X
X gi->gc = XCreateGC(gi->dpy, gi->win, 0x0, NULL);
X
X if(X_ERROR((int)gi->gc))
X GI_ERROR(NO_CREATE_GC)
X
X/* We want to have the input focus if we can */
X
X XSetInputFocus(gi->dpy, PointerRoot, RevertToNone, CurrentTime);
X
X/* Please do not do backing store on the contents of our window */
X
X attribs.backing_store = NotUseful;
X XChangeWindowAttributes(gi->dpy, gi->win, CWBackingStore, &attribs);
X
X/* We only want certain kinds of events */
X
X XSelectInput(gi->dpy, gi->win, ButtonPressMask | ButtonReleaseMask |
X KeyPressMask | Button1MotionMask | Button2MotionMask |
X StructureNotifyMask | ExposureMask | ColormapChangeMask);
X
X/* Do not generate expose events */
X
X XSetGraphicsExposures(gi->dpy,gi->gc, 0);
X
X/* Name our window */
X
X XStoreName(gi->dpy, gi->win, "X3D");
X
X if(gi->pseudoColor){
X
X/* Make our colormap */
X
X gi->colormap = XCreateColormap(gi->dpy, gi->win, DefaultVisual(gi->dpy,
X DefaultScreen(gi->dpy)), AllocAll);
X
X if(X_ERROR(gi->colormap))
X GI_ERROR(NO_CREATE_COLORMAP)
X
X/* Get the current colormap */
X
X XGetWindowAttributes(gi->dpy, RootWindow(gi->dpy,screen), &attributes);
X
X/* Since we only use 16 colors, set all our other entries to the old values.
X Hopefully some other windows might display in true colors */
X
X for(index = 0; index < NUMCOLORS; index++)
X oldColormap[index].pixel = index;
X
X XQueryColors(gi->dpy, attributes.colormap, oldColormap, NUMCOLORS);
X XStoreColors(gi->dpy, gi->colormap, oldColormap, NUMCOLORS);
X
X/* Initialize the two sets of color values we switch between */
X
X BLACK.red = 0 ; BLACK.green = 0; BLACK.blue = 0 ;
X BLUE.red = 0 ; BLUE.green = 0; BLUE.blue = 255 << 8;
X RED.red = 255 << 8; RED.green = 0; RED.blue = 0 ;
X PURPLE.red = 255 << 8; PURPLE.green = 0; PURPLE.blue = 255 << 8;
X
X BLACK.flags = DoRed | DoGreen | DoBlue;
X BLUE.flags = DoRed | DoGreen | DoBlue;
X RED.flags = DoRed | DoGreen | DoBlue;
X PURPLE.flags = DoRed | DoGreen | DoBlue;
X
X/* These colors never change */
X
X BLACK.pixel = COLOROFFSET + 0;
X BLUE.pixel = COLOROFFSET + 5 ;
X RED.pixel = COLOROFFSET + 10;
X PURPLE.pixel = COLOROFFSET + 15;
X
X XStoreColor(gi->dpy, gi->colormap, &BLACK);
X XStoreColor(gi->dpy, gi->colormap, &BLUE);
X XStoreColor(gi->dpy, gi->colormap, &RED);
X XStoreColor(gi->dpy, gi->colormap, &PURPLE);
X
X/* Set up the color values we switch between */
X
X BLACK.pixel = COLOROFFSET + 1 ; gi->colors[0][0] = BLACK;
X BLACK.pixel = COLOROFFSET + 2 ; gi->colors[0][1] = BLACK;
X BLACK.pixel = COLOROFFSET + 3 ; gi->colors[0][2] = BLACK;
X BLUE.pixel = COLOROFFSET + 4 ; gi->colors[0][3] = BLUE;
X BLUE.pixel = COLOROFFSET + 6 ; gi->colors[0][4] = BLUE;
X BLUE.pixel = COLOROFFSET + 7 ; gi->colors[0][5] = BLUE;
X RED.pixel = COLOROFFSET + 8 ; gi->colors[0][6] = RED;
X RED.pixel = COLOROFFSET + 9 ; gi->colors[0][7] = RED;
X RED.pixel = COLOROFFSET + 11; gi->colors[0][8] = RED;
X PURPLE.pixel = COLOROFFSET + 12; gi->colors[0][9] = PURPLE;
X PURPLE.pixel = COLOROFFSET + 13; gi->colors[0][10] = PURPLE;
X PURPLE.pixel = COLOROFFSET + 14; gi->colors[0][11] = PURPLE;
X
X BLUE.pixel = COLOROFFSET + 1 ; gi->colors[1][0] = BLUE;
X RED.pixel = COLOROFFSET + 2 ; gi->colors[1][1] = RED;
X PURPLE.pixel = COLOROFFSET + 3 ; gi->colors[1][2] = PURPLE;
X BLACK.pixel = COLOROFFSET + 4 ; gi->colors[1][3] = BLACK;
X RED.pixel = COLOROFFSET + 6 ; gi->colors[1][4] = RED;
X PURPLE.pixel = COLOROFFSET + 7 ; gi->colors[1][5] = PURPLE;
X BLACK.pixel = COLOROFFSET + 8 ; gi->colors[1][6] = BLACK;
X BLUE.pixel = COLOROFFSET + 9 ; gi->colors[1][7] = BLUE;
X PURPLE.pixel = COLOROFFSET + 11; gi->colors[1][8] = PURPLE;
X BLACK.pixel = COLOROFFSET + 12; gi->colors[1][9] = BLACK;
X BLUE.pixel = COLOROFFSET + 13; gi->colors[1][10] = BLUE;
X RED.pixel = COLOROFFSET + 14; gi->colors[1][11] = RED;
X
X/* Set our special 12 colors to something */
X
X XStoreColors(gi->dpy, gi->colormap, gi->colors[0], 12);
X XSetWindowColormap(gi->dpy, gi->win, gi->colormap);
X }
X
X/* Make the purple rectangle */
X
X GI_ResetPurpleRectangle(0, 0, gi->winX, gi->winY, gi);
X
X/*
X Make the window appear.
X*/
X XMapWindow(gi->dpy, gi->win);
X
X return GIE_OK;
X}
X
X
X
Xvoid GI_MakeImageCurrent(gi)
XGIinfo *gi;
X/******************************************************************************
X Flush the remaining contents of the line segment buffers out onto the
X screen. Toggle the colors. Erase the old lines.
X******************************************************************************/
X{
X
X/* Pretend we are a monochrome display */
X
X if((gi->Monochrome) || ((!(gi->pseudoColor)) && (!(gi->trueColor)))){
X XSetPlaneMask (gi->dpy, gi->gc, AllPlanes);
X XSetForeground(gi->dpy, gi->gc, BlackPixel(gi->dpy,
X DefaultScreen(gi->dpy)));
X XFillRectangle(gi->dpy, gi->win, gi->gc, 0, 0, gi->winX, gi->winY);
X XSetForeground(gi->dpy, gi->gc, WhitePixel(gi->dpy,
X DefaultScreen(gi->dpy)));
X XDrawSegments(gi->dpy, gi->win, gi->gc, gi->redSegments, gi->numberRed);
X
X if(gi->menuNumberRed){
X XDrawSegments(gi->dpy, gi->win, gi->gc, gi->menuRedSegments,
X gi->menuNumberRed);
X gi->menuNumberRed = 0;
X gi->menuNumberBlue = 0;
X }
X XSync(gi->dpy, 0);
X gi->ColorSelect = 1;
X }else{
X
X/* We want to flicker with the current color values */
X
X if((gi->Flicker) || (gi->trueColor)){
X gi->Order = !gi->Order;
X
X if(gi->pseudoColor){
X gi->ColorSelect = 1;
X XStoreColors(gi->dpy, gi->colormap, gi->colors[gi->ColorSelect],12);
X gi->red = COLOROFFSET + 2;
X gi->blue = COLOROFFSET + 1;
X gi->mask = COLOROFFSET + 15;
X XSetPlaneMask (gi->dpy, gi->gc, gi->mask);
X XSetForeground(gi->dpy, gi->gc, COLOROFFSET);
X XFillRectangle(gi->dpy, gi->win, gi->gc, 0, 0, gi->winX, gi->winY);
X }else{
X gi->red = 255 << 16;
X gi->blue = 255;
X }
X
X/* Alternate line display order because it helps even out the amount
X of time red and blue lines are displayed */
X
X if(gi->Order){
X XSetForeground(gi->dpy, gi->gc, gi->red);
X XDrawSegments (gi->dpy, gi->win, gi->gc, gi->redSegments,
X gi->numberRed);
X if(gi->menuNumberRed){
X XDrawSegments(gi->dpy, gi->win, gi->gc, gi->menuRedSegments,
X gi->menuNumberRed);
X gi->menuNumberRed = 0;
X }
X XSetFunction (gi->dpy, gi->gc, GXor);
X }
X
X if(gi->Stereo){
X XSetForeground(gi->dpy, gi->gc, gi->blue);
X XDrawSegments (gi->dpy, gi->win, gi->gc, gi->blueSegments,
X gi->numberBlue);
X if(gi->menuNumberBlue){
X XDrawSegments(gi->dpy, gi->win, gi->gc, gi->menuBlueSegments,
X gi->menuNumberBlue);
X gi->menuNumberBlue = 0;
X }
X }
X
X if(!gi->Order){
X XSetFunction (gi->dpy, gi->gc, GXor);
X XSetForeground(gi->dpy, gi->gc, gi->red);
X XDrawSegments (gi->dpy, gi->win, gi->gc, gi->redSegments,
X gi->numberRed);
X if(gi->menuNumberRed){
X XDrawSegments(gi->dpy, gi->win, gi->gc, gi->menuRedSegments,
X gi->menuNumberRed);
X gi->menuNumberRed = 0;
X }
X }
X
X XSetFunction (gi->dpy, gi->gc, GXcopy);
X XSync(gi->dpy, 0);
X }else{
X
X/* Do our wonderful flicker free screen update */
X
X XSetForeground(gi->dpy, gi->gc, COLOROFFSET);
X XFillRectangle(gi->dpy, gi->win, gi->gc, 0, 0, gi->winX, gi->winY);
X
X gi->ColorSelect = !gi->ColorSelect;
X
X if(gi->ColorSelect){
X gi->red = COLOROFFSET + 2;
X gi->blue = COLOROFFSET + 1;
X gi->mask = COLOROFFSET + 12;
X }else{
X gi->red = COLOROFFSET + 8;
X gi->blue = COLOROFFSET + 4;
X gi->mask = COLOROFFSET + 3;
X }
X
X XSetForeground(gi->dpy, gi->gc, gi->red);
X XDrawSegments (gi->dpy, gi->win, gi->gc, gi->redSegments,
X gi->numberRed);
X if(gi->menuNumberRed){
X XDrawSegments(gi->dpy, gi->win, gi->gc, gi->menuRedSegments,
X gi->menuNumberRed);
X gi->menuNumberRed = 0;
X }
X XSetFunction (gi->dpy, gi->gc, GXor);
X
X if(gi->Stereo){
X XSetForeground(gi->dpy, gi->gc, gi->blue);
X XDrawSegments (gi->dpy, gi->win, gi->gc, gi->blueSegments,
X gi->numberBlue);
X if(gi->menuNumberBlue){
X XDrawSegments(gi->dpy, gi->win, gi->gc, gi->menuBlueSegments,
X gi->menuNumberBlue);
X gi->menuNumberBlue = 0;
X }
X }
X
X XSetFunction (gi->dpy, gi->gc, GXcopy);
X XSetPlaneMask(gi->dpy, gi->gc, gi->mask);
X XStoreColors(gi->dpy, gi->colormap, gi->colors[gi->ColorSelect],12);
X XSync(gi->dpy,0);
X }
X }
X
X/* Reset the number of lines (We always keep the purple rectangle) */
X
X gi->numberRed = 4;
X gi->numberBlue = 4;
X gi->menuNumberRed = 0;
X gi->menuNumberBlue = 0;
X}
X
X
X
Xint GI_CheckEvent(display, event, arg)
XDisplay *display;
XXEvent *event;
Xchar *arg;
X/******************************************************************************
X Check an event to see if it is one we are interested in.
X
X Returns: 1 if we are interested, 0 if we are not.
X******************************************************************************/
X{
X if((event->type == MotionNotify) || (event->type == KeyPress) ||
X (event->type == ConfigureNotify) || (event->type == Expose) ||
X (event->type == ColormapNotify))
X return 1;
X
X return 0;
X}
X
X
X
Xvoid GI_GetInput(pointerX, pointerY, command, same, gi)
Xint *pointerX, *pointerY;
Xchar *command;
Xint *same;
XGIinfo *gi;
X/******************************************************************************
X Get an interesting event and update the user input information.
X
X The routine will eventually block waiting for an event if block is 1
X and the no events of interest have shown up.
X
X Returns: GIE_OK if successful, an GI error code otherwise.
X******************************************************************************/
X{
XXEvent event;
XXSizeHints sizehint;
Xint numEvents, block, count;
Xchar string[TMPSTRLEN];
X
X block = 0;
X count = 0;
X
X/* set command to a meaningless value (hopefully) */
X
X *command = '\0';
X
X do{
X
X/* If the user falls asleep stop using CPU cycles */
X
X if(count++ > BLOCKCOUNT)
X if(gi->Block)
X block = 1;
X
X string[0] = '\0';
X
X/* How many events? */
X
X numEvents = XEventsQueued(gi->dpy,QueuedAfterFlush);
X
X/* Block to obtain an event yet? */
X
X if((numEvents == 0) && (block)){
X XIfEvent(gi->dpy, &event, GI_CheckEvent, NULL);
X numEvents = 1;
X }else{
X
X/* If we have at least one event , fetch the first event off the queue*/
X
X if(numEvents)
X XNextEvent(gi->dpy,&event);
X }
X
X }while((numEvents == 0) && (gi->Block));
X
X/* Process the events we have obtained (if any) */
X
X while(numEvents){
X
X switch(event.type){
X
X case MotionNotify :
X if(numEvents == 1){
X *pointerX = (int)event.xmotion.x;
X *pointerY = (int)event.xmotion.y;
X }
X break;
X
X case KeyPress :
X if(numEvents == 1){
X XLookupString(&event.xkey,string,TMPSTRLEN,NULL,NULL);
X *command = string[0];
X }
X break;
X
X case ConfigureNotify :
X if(event.xconfigure.window == gi->win){
X gi->winX = event.xconfigure.width;
X gi->winY = event.xconfigure.height;
X gi->winH = (int)(gi->winX / 2.0);
X gi->winV = (int)(gi->winY / 2.0);
X GI_ResetPurpleRectangle(0, 0, gi->winX, gi->winY, gi);
X GI_ResizeFont(gi);
X sizehint.flags = USSize;
X sizehint.width = gi->winX;
X sizehint.height = gi->winY;
X XSetNormalHints(gi->dpy, gi->win, &sizehint);
X }
X *same = 0;
X break;
X
X case Expose :
X *same = 0;
X break;
X
X case ColormapNotify :
X
X if(event.xcolormap.colormap == gi->colormap){
X
X if(event.xcolormap.state == ColormapInstalled){
X gi->Monochrome = 0;
X }else{
X gi->Monochrome = 1;
X }
X
X *same = 0;
X }
X break;
X
X default :
X break;
X }
X
X numEvents--;
X
X if(numEvents)
X XNextEvent(gi->dpy,&event);
X }
X}
X
X
X
Xvoid GI_UpdatePosition(obj, gi)
XObjectInfo *obj;
XGIinfo *gi;
X/******************************************************************************
X Update the scene position information using user input.
X
X The routine will eventually block waiting for an event if block is True
X and the no events of interest show up due to the call to GI_GetInput()
X******************************************************************************/
X{
Xint same, pointerX, pointerY, dx, dy;
Xchar buffer[128], command;
Xdouble X, Y, Z;
X
X X = Y = Z = 0.0;
X
X same = 1;
X
X pointerX = gi->oldPointerX;
X pointerY = gi->oldPointerY;
X
X while(same) {
X
X/* dx, dy, dz are the amount to step about each axis every frame
X We want the scene to continue to rotate even if the user does
X not give any new input */
X
X/* Do not forget to put your automatic update variables into this if
X statement. Be careful somehow you can get MANY bugs with these! */
X
X if((obj->dX) || (obj->dY) || (obj->dZ)){
X same = 0;
X gi->Block = 0;
X }else
X gi->Block = 1;
X
X/* Get the input */
X
X GI_GetInput(&pointerX, &pointerY, &command, &same, gi);
X
X/* Fill in code for your favorite keyboard and pointer controls */
X
X/* My default controls */
X
X/* Note: I do not move the origin which the scene is rotated about around.
X You may want to do originX += ???; originY += ???; originZ += ??? */
X
X switch(command){
X case ' ' : break;
X case 'm' : same = 0; gi->Menu = !gi->Menu; break;
X case 'M' : same = 0; gi->Menu = !gi->Menu; break;
X case 'p' : same = 0; gi->Stats = !gi->Stats; break;
X case 'P' : same = 0; gi->Stats = !gi->Stats; break;
X case 's' : same = 0; gi->Stereo = !gi->Stereo; break;
X case 'S' : same = 0; gi->Stereo = !gi->Stereo; break;
X case 'f' : same = 0; gi->Flicker = !gi->Flicker; break;
X case 'F' : same = 0; gi->Flicker = !gi->Flicker; break;
X case 'r' : same = 0; gi->Relative = !gi->Relative; break;
X case 'R' : same = 0; gi->Relative = !gi->Relative; break;
X case 'h' : same = 0; obj->translateX -= (number) 100; break;
X case 'j' : same = 0; obj->translateY -= (number) 100; break;
X case 'k' : same = 0; obj->translateY += (number) 100; break;
X case 'l' : same = 0; obj->translateX += (number) 100; break;
X case 'u' : same = 0; obj->translateZ += (number) 100; break;
X case 'i' : same = 0; obj->translateZ -= (number) 100; break;
X case 'H' : same = 0; obj->translateX -= (number)1500; break;
X case 'J' : same = 0; obj->translateY -= (number)1500; break;
X case 'K' : same = 0; obj->translateY += (number)1500; break;
X case 'L' : same = 0; obj->translateX += (number)1500; break;
X case 'U' : same = 0; obj->translateZ += (number)1500; break;
X case 'I' : same = 0; obj->translateZ -= (number)1500; break;
X case '1' : same = 0; obj->dX = -0.09; break;
X case '2' : same = 0; obj->dX = 0.0 ; break;
X case '3' : same = 0; obj->dX = 0.09; break;
X case '4' : same = 0; obj->dY = -0.09; break;
X case '5' : same = 0; obj->dY = 0.0 ; break;
X case '6' : same = 0; obj->dY = 0.09; break;
X case '7' : same = 0; obj->dZ = -0.09; break;
X case '8' : same = 0; obj->dZ = 0.0 ; break;
X case '9' : same = 0; obj->dZ = 0.09; break;
X case 'x' : same = 0; X += 0.03; break;
X case 'X' : same = 0; X -= 0.03; break;
X case 'y' : same = 0; Y += 0.03; break;
X case 'Y' : same = 0; Y -= 0.03; break;
X case 'z' : same = 0; Z += 0.03; break;
X case 'Z' : same = 0; Z -= 0.03; break;
X case 'a' : same = 0; X += 0.05; break;
X case 'A' : same = 0; X -= 0.05; break;
X case 'b' : same = 0; Y += 0.05; break;
X case 'B' : same = 0; Y -= 0.05; break;
X case 'c' : same = 0; Z += 0.05; break;
X case 'C' : same = 0; Z -= 0.05; break;
X case '[' : same = 0;
X obj->focus = obj->focus += 0.1;
X if((obj->focus > 1.8))
X obj->focus = 1.8;
X break;
X case ']' : same = 0;
X obj->focus = obj->focus -= 0.1;
X if((obj->focus < -0.8))
X obj->focus = -0.8;
X break;
X case '{' : same = 0; obj->BViewpointX -= (number)4; break;
X case '}' : same = 0; obj->BViewpointX += (number)4; break;
X case 'q' : exit(0);
X case 'Q' : exit(0);
X
X default : {
X
X/* My pointer movement stuff */
X
X/* Only update if the movement was reasonably small */
X
X dx = pointerX - gi->oldPointerX;
X dy = pointerY - gi->oldPointerY;
X
X if((dy * dy <= SMALLMOVEMENT) &&
X (dx * dx <= SMALLMOVEMENT)){
X
X/* Rotate proportionally with the amount the pointer moved */
X/* Note: I only control the X and Z axes by the pointer */
X
X X += (dy * POINTERRATIO);
X Z += (dx * POINTERRATIO);
X same = 0;
X }
X
X gi->oldPointerY = pointerY;
X gi->oldPointerX = pointerX;
X }
X }
X }
X
X/* Keep angles 0 - 6.28 */
X
X X = fmod(X + obj->dX, TWOPI);
X Y = fmod(Y + obj->dY, TWOPI);
X Z = fmod(Z + obj->dZ, TWOPI);
X
X/* Fix up the angles */
X
X if(gi->Relative){
X obj->X = fmod(X + obj->X, TWOPI);
X obj->Y = fmod(Y + obj->Y, TWOPI);
X obj->Z = fmod(Z + obj->Z, TWOPI);
X }else{
X GI_CalculateAngles(&(obj->X), &(obj->Y), &(obj->Z), X, Y, Z);
X }
X
X gi->cursorX = (number)0;
X gi->cursorY = (number)0;
X
X/* Display our stats? */
X
X if(gi->Stats){
X sprintf(buffer, "OX %6d OY %6d OZ %6d X %3d Y %3d Z %3d",
X (int)-obj->translateX, (int)obj->translateY,
X -(int)obj->translateZ, (int)(obj->X * 57.32),
X (int)(obj->Y * 57.32), (int)(obj->Z * 57.32));
X
X GI_PrintString(buffer, gi);
X }
X
X/* Display Menu? */
X
X if(gi->Menu)
X GI_DisplayMenu(gi);
X}
X
X
X
Xvoid GI_PrintError(errString)
Xchar *errString;
X/******************************************************************************
X Write the string errString onto stderr, then write the last error message
X produced by the GI layer onto stderr as well.
X
X Returns: no return value.
X******************************************************************************/
X{
X/* List of strings for error reporting */
X
Xstatic char *ErrMsgList[] = {
X "No error", /* errno = 0 */
X "Unable to connect with server", /* errno = -1 */
X "Unable to create window", /* errno = -2 */
X "Unable to create gc", /* errno = -2 */
X "Unable to create colormap", /* errno = -3 */
X "Unknown error code" /* last errno */
X};
X
X/* Instead of doing a switch on all the error codes we set up our array of
X strings so that GIerrno corresponds to ErrMsgList[-GIerrno] */
X
X/* Prints errString given by user, and then the error message
X corresponding to the currently set GIerrno */
X
X if(errString)
X fprintf(stderr, "%s ", errString);
X
X if((GIerrno > GIE_LASTERRNO) && (GIerrno <= 0))
X fprintf(stderr, "%s\n", ErrMsgList[-GIerrno]);
X else
X fprintf(stderr, "%s %d ***\n", ErrMsgList[-(GIE_LASTERRNO)], GIerrno);
X
X fflush(stderr);
X
X} /* GI_PrintError() */
END_OF_FILE
if test 39449 -ne `wc -c <'gi.c'`; then
echo shar: \"'gi.c'\" unpacked with wrong size!
fi
# end of 'gi.c'
fi
echo shar: End of archive 2 \(of 6\).
cp /dev/null ark2isdone
MISSING=""
for I in 1 2 3 4 5 6 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 6 archives.
rm -f ark[1-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0
--
Molecular Simulations, Inc. mail: dcmartin@msi.com
796 N. Pastoria Avenue uucp: uunet!dcmartin
Sunnyvale, California 94086 at&t: 408/522-9236