From: ssubram2@uoft02.utoledo.edu
Newsgroups: comp.sys.sgi
Subject: A game for the SGI PI
Date: 15 Dec 92 13:25:00 EST
Organization: University of Toledo, Computer Services



Hi,

Sometime back I saw a request for games written for SGI GL.
So here is a simple 3-d dog-fight game.  I wrote it a couple of weeks
back in a fit of extreme boredom. A large part of the game was
written within a period of 3 days ... so don't expect it to be a
beautiful, efficiently written program. I wrote this on a SGI PI 4D/20
and I don't know how fast/slow it will run on other SGI m/c's.

Game description :
You are in a ship with lot of "enemies" around who fire at you and
whom you have to destroy.  (simple, isn't it ? :)
Game gets over if you collide with a wall or ship damage is 100%
or fuel or torpedos runneth out.

Types of enemies :
(1) Ordinary : Dull boring enemies who die on the first shot
(2) Tough    : Change color when hit and move faster and make life
               miserable for you.
(3) Cloaked  : these don't show up unless you are holding down the
               cloak detector button.
(4) Cloaked and tough : Really painful enemies.

Game controls :

ship movement :
--------------
S key : increase forward ship thrust
A key : increase backward ship thrust
Z key : full brakes .. ship halt

ship direction :
---------------
Leftarrow, Rightarrow : Turn ship left, rite
Uparrow, Downarrow    :    Turn ship up, down
Comma, Period         : Turn ship's "UP vector"
PADENTER              : increase ship's rotation step
PAD0                  : decrease ship's rotation step

weapons :
--------
Spacebar : Fire torpedo or laser guided missile (according
           to context)
T key    : Target enemy (toggle) which is completely inside 
           the targeting brackets. (enemy changes color to CYAN 
           to show that it has been targeted). Once targeted,
           you can destroy that enemy whenever you want (with space
           bar) and you need not even be looking at him.

Misc :
-----
D key : Turn on cloak detector (uses up lots of fuel)
C key : Toggle crosswire (who would want to turn off the crosswire ?)
Esc   : Exit

An on-board "flight computer" informs you of most things.


Playing hints : 
------------
If you ever halt the ship you are a sitting duck
for the enemy so always keep moving. To kill very fast enemies
you might have to use the laser targeting instrument (T key) and 
then fire ... but laser guided missiles are very few.

When you are approaching a wall at moderate speeds, 
you will have to increase the ship's rotation speed and turn in order
to avoid hitting the wall. But a high rotation speed will hinder
your enemy targeting capacity so decrease rotation speed as soon as
you turn away from the wall. (PAD0,PADENTER)


The main program is vr1.c. One more thing : I have used 
/usr/NeWS/bin/keywarp to increase the keyboard's repeat rate.


Send all comments/flames/questions/curses to :
ssubrama@jupiter.cse.utoledo.edu

/Srikanth Subramanian (alias Cado)


--------------CUT HERE--------------------------------------------
#!/bin/sh
# shar:	Shell Archiver  (v1.22)
#
#	Run the following text with /bin/sh to create:
#	  vector.h
#	  vr.h
#	  vr1.c
#
sed 's/^X//' << 'SHAR_EOF' > vector.h &&
X/*
X::::::::::::::
Xvector.h for VR
X::::::::::::::
X*/
X
X#include <stdio.h>
X#include <math.h>
X#include <gl/gl.h>
X#include <gl/device.h>
X
X#define   NN(x)     (((x) < 0) ?   0  : (x) )
X#define   ABS(x)    (((x) < 0) ? -(x) : (x) ) 
X#define   SQR(x)    ((x)*(x))
X#define   SQRT(x)   ((float)(sqrt((double)(x))))
X#define   COS(x)    ((float)(cos((double)(x))))
X#define   ACOS(x)   ((float)(acos((double)(x))))
X#define   SIN(x)    ((float)(sin((double)(x))))
X#define   POW(x,y)  ((float)(pow((double)(x),(double)(y))))
X#define   ATAN(x)   ((float)(atan((double)(x))))
X#define   TAN(x)    ((float)(tan((double)(x))))
X#define   ZERO(x)   ((ABS(x)<1.0e-10)?1:0)
X
X#define    EPSILON   (1.0e-6)
X
X/* Vector type  --- any point repr. as PV */
Xtypedef struct {
X   float x,y,z   ;
X}  VEC           ;
X
X
X/* Vector type used by GL : */
Xtypedef float  VEC3[3] ; 
X
X
X/* Modulus and Dot Product defs */
X#define mod(a)      SQRT(a.x*a.x + a.y*a.y + a.z*a.z)
X#define dot_p(a,b)  (a.x*b.x + a.y*b.y + a.z*b.z)
X
X/* Cross product :  c = a x b   */
X#define cross_p(a,b,c)       {                   \
X   c.x = (a.y*b.z - b.y*a.z) ;                   \
X   c.y = (b.x*a.z - a.x*b.z) ;                   \
X   c.z = (a.x*b.y - b.x*a.y) ;                   \
X} 
X
X/* Cos(theta) where theta is the angle between vects. a,b */
X#define cos_thet(a,b)  (dot_p(a,b)/(mod(a)*mod(b)))
X
X/* Distance between two position vectors */
X#define   DIST(a,b) SQRT(SQR(a.x-b.x)+SQR(a.y-b.y)+SQR(a.z-b.z))
X
X/* A fast matrix multiplication def for (3x3)(3x1) mult */
X#define mat_mul(a,b,c) { \
X   c[0] = a[0][0]*b[0] + a[0][1]*b[1] + a[0][2]*b[2] ; \
X   c[1] = a[1][0]*b[0] + a[1][1]*b[1] + a[1][2]*b[2] ; \
X   c[2] = a[2][0]*b[0] + a[2][1]*b[1] + a[2][2]*b[2] ; \
X}
X
X
X/* Some simple vec operations */
X
X#define    NORM(vec)                {            \
X           float  md = mod(vec)     ;            \
X           if (md>EPSILON) {                     \
X              vec.x    /= md           ;         \
X              vec.y    /= md           ;         \
X              vec.z    /= md           ;         \
X           }                                     \
X}
X
X#define    REVERSE_VEC(vec)         {            \
X           vec.x = -vec.x           ;            \
X           vec.y = -vec.y           ;            \
X           vec.z = -vec.z           ;            \
X}
X
X
X#define    INIT_VEC(pvdest,xi,yi,zi)  {  \
X           pvdest.x = xi      ;          \
X           pvdest.y = yi      ;          \
X           pvdest.z = zi      ;          \
X}
X           
X   
X#define    COPY_VEC(pvdest,pvsource)  {          \
X           pvdest.x = pvsource.x      ;          \
X           pvdest.y = pvsource.y      ;          \
X           pvdest.z = pvsource.z      ;          \
X}
X
X
X#define    COPY_VEC3(pvdest,pvsource) {          \
X           pvdest[0] = pvsource[0]    ;          \
X           pvdest[1] = pvsource[1]    ;          \
X           pvdest[2] = pvsource[2]    ;          \
X}
X
X
X#define    ADD_VEC(pvdest,pvsource)  {          \
X           pvdest.x += pvsource.x      ;        \
X           pvdest.y += pvsource.y      ;        \
X           pvdest.z += pvsource.z      ;        \
X}
X
X
X#define    SCALE_VEC(pvdest,pvsource,sc)  {     \
X           pvdest.x = sc*pvsource.x      ;      \
X           pvdest.y = sc*pvsource.y      ;      \
X           pvdest.z = sc*pvsource.z      ;      \
X}
X
X
X/* Given two pv's get the vec */
X#define    GET_VEC(pvto,pvfrom,vec)   {      \
X           vec.x  = pvto.x - pvfrom.x ;      \
X           vec.y  = pvto.y - pvfrom.y ;      \
X           vec.z  = pvto.z - pvfrom.z ;      \
X}
X
X#define    VEC3TOVEC(vec,vec3)        {      \
X           vec.x = vec3[0]            ;      \
X           vec.y = vec3[1]            ;      \
X           vec.z = vec3[2]            ;      \
X}
X
X#define    VECTOVEC3(vec3,vec)        {      \
X            vec3[0] = vec.x           ;      \
X            vec3[1] = vec.y           ;      \
X            vec3[2] = vec.z           ;      \
X}
X
X
X/* 
X   REFL_RAY calculates the reflected ray direction at a point given
X   the incident ray direction, the point of incidence and the normal to 
X   the surface at that point. 
X   The reflected ray direction is stored in a var passed as the 
X   last parm to the macro.
X   Note : All input directions and dir output by the macro are
X   taken to be in the outward direction from the point of incidence.
X */
X
X#define    REFL_RAY(indir,sp,un,outdir)   {      \
X           float  ct              ;              \
X           VEC    pn, pi, pr, pin ;              \
X                                                 \
X           pn.x = sp.x + un.x ;                  \
X           pn.y = sp.y + un.y ;                  \
X           pn.z = sp.z + un.z ;                  \
X                                                 \
X           pi.x = sp.x + indir.x ;               \
X           pi.y = sp.y + indir.y ;               \
X           pi.z = sp.z + indir.z ;               \
X                                                 \
X           ct =  cos_thet ( indir, un ) ;        \
X                                                 \
X           pin.x =  sp.x + un.x*ct ;             \
X           pin.y =  sp.y + un.y*ct ;             \
X           pin.z =  sp.z + un.z*ct ;             \
X                                                 \
X           pr.x  =  pin.x + (pin.x-pi.x) ;       \
X           pr.y  =  pin.y + (pin.y-pi.y) ;       \
X           pr.z  =  pin.z + (pin.z-pi.z) ;       \
X                                                 \
X           outdir.x = pr.x - sp.x ;              \
X           outdir.y = pr.y - sp.y ;              \
X           outdir.z = pr.z - sp.z ;              \
X           NORM ( outdir )        ;              \
X}
X
X
X#define    MED_RAY(dir1,dir2,sp,outdir)   {      \
X           VEC    p1, p2, pm ;                   \
X                                                 \
X           COPY_VEC ( p1, sp ) ;                 \
X           COPY_VEC ( p2, sp ) ;                 \
X                                                 \
X           ADD_VEC  ( p1, dir1 ) ;               \
X           ADD_VEC  ( p2, dir2 ) ;               \
X                                                 \
X           pm.x = (p1.x + p2.x)/2 ;              \
X           pm.y = (p1.y + p2.y)/2 ;              \
X           pm.z = (p1.z + p2.z)/2 ;              \
X                                                 \
X           outdir.x = pm.x - sp.x ;              \
X           outdir.y = pm.y - sp.y ;              \
X           outdir.z = pm.z - sp.z ;              \
X           NORM ( outdir )        ;              \
X}
X
X
SHAR_EOF
chmod 0666 vector.h || echo "restore of vector.h fails"
sed 's/^X//' << 'SHAR_EOF' > vr.h &&
X/* VR configuration :
X * The Virtual world setup.
X * Sizes and speeds are in virtual world scale units.
X */
X
X#define ON    1
X#define OFF   0
X
X/* Some color defs : these are dependent on the default
X * color map (can be obtained by a "makemap")
X */
X#define WORLDBGCOLOR BLACK
X#define PANELBGCOLOR 35
X#define PANELTHRCOLOR   138
X#define PANELROTCOLOR   59
X#define PANELFUECOLOR   138
X#define PANELTORCOLOR   138
X#define PANELDAMCOLOR   RED
X
X/* World limits */
X#define CUBEMAX   10000.0
X#define CUBEMIN   (-CUBEMAX)
X#define WORLDDIVS 21
X
X#define SHIPSIZ   500
X
X/* Ship's maximum forward, reverse and step thrust */
X#define MAXTHRUST  500.0
X#define STEPTHRUST 5.0
X
X/* Ship's maximum and minimum rotation speeds 
X * (in 10'ths of degrees ie. GL "Angle" type values) 
X */
X#define MAXROT    450
X#define MINROT    10
X
X/* Initial Fuel */
X#define MAXFUEL 600000.0
X
X/* Phaser torpedos and tracking laser info in ship */
X#define MAXTORP  800
X/* Maximum no. of phaser torpedos firable at any given time */
X#define MAXTORPFIRE   30
X
X#define TORPSPEED 600.0
X#define TORPLEN   1000.0
X#define MAXTRACKERS  5
X
X/* Explosion size */
X#define EXPSIZ    200.0
X
X/* Enemy definitions */
X#define MAXENEM   20
X#define ENEMSIZ   500
X#define ENEMSPEED  100
X#define ENEMMISSPEED  1000.0
X#define TOUGHENEMSPEEDFACT 1.5
X
SHAR_EOF
chmod 0666 vr.h || echo "restore of vr.h fails"
sed 's/^X//' << 'SHAR_EOF' > vr1.c &&
X/* VR : A Reality Game by Cado <12/3/92> */
X
X#include "vector.h"
X#include "vr.h"
X#include <string.h>
X
X#define  X  0
X#define  Y  1
X#define  Z  2
X#define  W  3
X
X/* :) */
X#define fr(v,s,e) for(v=s;v<e;v++) 
X
X/* VR globals */
Xint gov ;
Xchar  gamename[100] ;
Xlong  xorg, yorg, xsiz, ysiz ;
XScreencoord vpst, conslower, consupper ;
Xint   consdispwidth, conslabels[4] ;
Xfloat xmid, ymid ;
Xint   crosswiresiz, crosswiregap ;
Xint   crosswire, cloakdetector ;
X
Xfloat thrust, stepthrust, steprot ;
Xint   xrot, yrot, zrot ;
XVEC   shipmov, shippos[2] ;
XVEC   shipx, shipy, shipz ;
X
Xchar  consolemsg[100] ;
Xint   consolemsgcolor ;
Xint   mainloopcycles = 19 ;
X
Xint   torpleft, ntorp, enemleft, enemymissileshit ;
Xfloat fuelleft, damage ;
X
Xfloat points ;
X
Xshort fovy = 900 ;
Xfloat tanfovyrad ;
X
X/* VR objects */
XObject  vr_world_object ;
X
X/* Torpedo launcher cross-wire */
XObject  crosswire_object ;
X
X/* Individual torpedo information */
Xstruct  {
X   int     fired ;
X   VEC     torpedopos, torpedodir ;
X}  torpinfo[MAXTORPFIRE] ;
X
X
X/* Enemy info */
Xstruct  {
X   int     tough, cloaked ;
X   int     level ;
X   int     destroyed, exploding ;
X   float   speed ;
X   VEC     pos, dir ;
X}  enemyinfo[MAXENEM] ;
X
X
X/* Enemy missile */
Xstruct {
X   float   msiz ;
X   float   distfromship ;
X   int destroyed ;
X   VEC pos, dir ;
X}  enemymissile ;
X
X
X/* Tracker beam */
Xint enemynum, prevstate, trackertoggle, ntrackersleft ;
Xfloat beaminc = 100.0 ;
X
X
Xinit_stat ()
X{
X   gov = FALSE ;
X   thrust = 0 ;
X   stepthrust = STEPTHRUST ;
X   steprot = 10 ;
X   xrot = yrot = 0 ;
X   torpleft = MAXTORP ;
X   ntrackersleft = MAXTRACKERS ;
X   ntorp = 0 ;
X   fuelleft = MAXFUEL ;
X   damage = 0 ;
X   enemleft = MAXENEM ;
X   enemymissileshit = 0 ;
X   enemymissile.destroyed = TRUE ;
X   enemymissile.msiz = ENEMSIZ ;
X
X   crosswire = ON ;
X   cloakdetector = OFF ;
X
X   points = 0 ;
X   shippos[0].x = shippos[1].x = 0 ;
X   shippos[0].y = shippos[1].y = 0 ;
X   shippos[0].z = shippos[1].z = 0 ;
X
X   /* Initially ship is oriented along -ve Z axis */
X   shipx.x = 1.0 ;
X   shipx.y = shipx.z = 0 ;
X   shipy.y = 1.0 ;
X   shipy.x = shipy.z = 0 ;
X   shipz.z = -1.0 ;
X   shipz.x = shipz.y = 0 ;
X}
X
X
X
Xinit_world_view ()
X{
X   color ( PANELBGCOLOR ) ;
X   clear () ;
X   swapbuffers () ;
X   color ( PANELBGCOLOR ) ;
X   clear () ;
X}
X
X
Xinit_gfx ()
X{
X   int i, j, k, cx, cy ;
X   VEC3 v ;
X   float lx, ly, lz, worldinc ;
X   int  vc[2], v1[2], v2[2], v3[2], v4[2] ;
X
X   keepaspect ( 4, 5 ) ;
X   minsize ( 588L, 735L ) ;
X   winopen ( "VR" ) ;
X   doublebuffer () ;
X   gconfig () ;
X   init_world_view () ;
X
X   getorigin ( &xorg, &yorg ) ;
X   getsize ( &xsiz, &ysiz ) ;
X
X   vpst = ysiz*0.2 ;
X   conslower = (vpst-vpst*0.80) ;
X   consupper = (vpst-vpst*0.1) ;
X   consdispwidth = xsiz/15.0 ;
X
X   conslabels[0] = consdispwidth/2.0 - strwidth("Thrust")/2.0  ;
X   conslabels[1] = consdispwidth/2.0 - strwidth("Rotate")/2.0  ;
X   conslabels[2] = consdispwidth/2.0 - strwidth("Fuel")/2.0    ;
X   conslabels[3] = consdispwidth/2.0 - strwidth("Torpedo")/2.0 ;
X
X   xmid = xsiz/2.0 ;
X   ymid = vpst + (ysiz-vpst)/2.0 ;
X   crosswiregap = (crosswiresiz = (ysiz-vpst)/20.0)/5.0 ;
X
X   tanfovyrad = TAN((fovy/10.0)*(M_PI/180.0)*
X                    (crosswiresiz+crosswiregap)/xsiz) ;
X
X   viewport ( (Screencoord) 40, (Screencoord) (xsiz-40), 
X              (Screencoord) vpst+40, (Screencoord) (ysiz-40) ) ;
X   perspective ( fovy, (double)xsiz/(double)(ysiz-vpst), 0.001, 5000000.0 );
X   /* zbuffer ( TRUE ) ;
X   lsetdepth ( 0, 500000 ) ;
X	zclear () ; */
X
X   qdevice ( ESCKEY ) ;
X   qdevice ( LEFTARROWKEY ) ;
X   qdevice ( RIGHTARROWKEY ) ;
X   qdevice ( UPARROWKEY ) ;
X   qdevice ( DOWNARROWKEY ) ;
X   qdevice ( PAD0 ) ;
X   qdevice ( PADENTER ) ;
X   qdevice ( COMMAKEY ) ;
X   qdevice ( PERIODKEY ) ;
X   qdevice ( AKEY ) ;
X   qdevice ( CKEY ) ;
X   qdevice ( DKEY ) ;
X   qdevice ( SKEY ) ;
X   qdevice ( ZKEY ) ;
X   qdevice ( RKEY ) ;
X   qdevice ( PKEY ) ;
X   qdevice ( TKEY ) ;
X   qdevice ( SPACEKEY ) ;
X
X   worldinc = (CUBEMAX-CUBEMIN)/((float)(WORLDDIVS-1)) ;
X
X   vr_world_object = genobj () ;
X   makeobj ( vr_world_object ) ;
X
X   color ( RED ) ;
X   fr ( k, 0, WORLDDIVS ) {
X      bgnline () ;
X      fr ( i, 0, WORLDDIVS ) {
X         v[0] = CUBEMIN + i*worldinc ;
X         v[1] = CUBEMIN ;
X         v[2] = CUBEMIN + k*worldinc ;
X         v3f ( v ) ;
X      }
X      endline () ;
X   }
X   for ( i = 0 ; i < WORLDDIVS ; i++ ) {
X      bgnline () ;
X      for ( k = 0 ; k < WORLDDIVS ; k++ ) {
X         v[0] = CUBEMIN + i*worldinc ;
X         v[1] = CUBEMIN ;
X         v[2] = CUBEMIN + k*worldinc ;
X         v3f ( v ) ;
X      }
X      endline () ;
X   }
X
X   color ( YELLOW ) ;
X   for ( k = 0 ; k < WORLDDIVS ; k++ ) {
X      bgnline () ;
X      for ( i = 0 ; i < WORLDDIVS ; i++ ) {
X         v[0] = CUBEMIN + i*worldinc ;
X         v[1] = CUBEMAX ;
X         v[2] = CUBEMIN + k*worldinc ;
X         v3f ( v ) ;
X      }
X      endline () ;
X   }
X   for ( i = 0 ; i < WORLDDIVS ; i++ ) {
X      bgnline () ;
X      for ( k = 0 ; k < WORLDDIVS ; k++ ) {
X         v[0] = CUBEMIN + i*worldinc ;
X         v[1] = CUBEMAX ;
X         v[2] = CUBEMIN + k*worldinc ;
X         v3f ( v ) ;
X      }
X      endline () ;
X   }
X
X   color ( BLUE ) ;
X   for ( k = 0 ; k < WORLDDIVS ; k++ ) {
X      bgnline () ;
X      for ( j = 0 ; j < WORLDDIVS ; j++ ) {
X         v[0] = CUBEMIN ;
X         v[1] = CUBEMIN + j*worldinc ;
X         v[2] = CUBEMIN + k*worldinc ;
X         v3f ( v ) ;
X      }
X      endline () ;
X   }
X   for ( j = 0 ; j < WORLDDIVS ; j++ ) {
X      bgnline () ;
X      for ( k = 0 ; k < WORLDDIVS ; k++ ) {
X         v[0] = CUBEMIN ;
X         v[1] = CUBEMIN + j*worldinc ;
X         v[2] = CUBEMIN + k*worldinc ;
X         v3f ( v ) ;
X      }
X      endline () ;
X   }
X
X   color ( GREEN ) ;
X   for ( k = 0 ; k < WORLDDIVS ; k++ ) {
X      bgnline () ;
X      for ( j = 0 ; j < WORLDDIVS ; j++ ) {
X         v[0] = CUBEMAX ;
X         v[1] = CUBEMIN + j*worldinc ;
X         v[2] = CUBEMIN + k*worldinc ;
X         v3f ( v ) ;
X      }
X      endline () ;
X   }
X   for ( j = 0 ; j < WORLDDIVS ; j++ ) {
X      bgnline () ;
X      for ( k = 0 ; k < WORLDDIVS ; k++ ) {
X         v[0] = CUBEMAX ;
X         v[1] = CUBEMIN + j*worldinc ;
X         v[2] = CUBEMIN + k*worldinc ;
X         v3f ( v ) ;
X      }
X      endline () ;
X   }
X
X   color ( WHITE ) ;
X   for ( j = 0 ; j < WORLDDIVS ; j++ ) {
X      bgnline () ;
X      for ( i = 0 ; i < WORLDDIVS ; i++ ) {
X         v[0] = CUBEMIN + i*worldinc ;
X         v[1] = CUBEMIN + j*worldinc ;
X         v[2] = CUBEMIN ;
X         v3f ( v ) ;
X      }
X      endline () ;
X   }
X   for ( i = 0 ; i < WORLDDIVS ; i++ ) {
X      bgnline () ;
X      for ( j = 0 ; j < WORLDDIVS ; j++ ) {
X         v[0] = CUBEMIN + i*worldinc ;
X         v[1] = CUBEMIN + j*worldinc ;
X         v[2] = CUBEMIN ;
X         v3f ( v ) ;
X      }
X      endline () ;
X   }
X
X   color ( CYAN ) ;
X   for ( j = 0 ; j < WORLDDIVS ; j++ ) {
X      bgnline () ;
X      for ( i = 0 ; i < WORLDDIVS ; i++ ) {
X         v[0] = CUBEMIN + i*worldinc ;
X         v[1] = CUBEMIN + j*worldinc ;
X         v[2] = CUBEMAX ;
X         v3f ( v ) ;
X      }
X      endline () ;
X   }
X   for ( i = 0 ; i < WORLDDIVS ; i++ ) {
X      bgnline () ;
X      for ( j = 0 ; j < WORLDDIVS ; j++ ) {
X         v[0] = CUBEMIN + i*worldinc ;
X         v[1] = CUBEMIN + j*worldinc ;
X         v[2] = CUBEMAX ;
X         v3f ( v ) ;
X      }
X      endline () ;
X   }
X   closeobj () ;
X
X   crosswire_object = genobj () ;
X   makeobj ( crosswire_object ) ;
X   color ( RED ) ;
X   linewidth ( 3 ) ;
X   vc[0] = cx = xsiz/2.0 ;
X   vc[1] = cy = (ysiz-vpst)/2.0 + vpst ;
X
X   v1[0] = cx - crosswiresiz ;
X   v1[1] = cy ;
X   v2[0] = cx - crosswiregap ;
X   v2[1] = cy ;
X   v3[0] = cx + crosswiregap ;
X   v3[1] = cy ;
X   v4[0] = cx + crosswiresiz ;
X   v4[1] = cy ;
X   bgnline () ;
X      v2i ( v1 ) ;
X      v2i ( v2 ) ;
X   endline () ;
X   bgnline () ;
X      v2i ( v3 ) ;
X      v2i ( v4 ) ;
X   endline () ;
X   v1[0] = cx ;
X   v1[1] = cy - crosswiresiz ;
X   v2[0] = cx ;
X   v2[1] = cy - crosswiregap ;
X   v3[0] = cx ;
X   v3[1] = cy + crosswiregap ;
X   v4[0] = cx ;
X   v4[1] = cy + crosswiresiz ;
X   bgnline () ;
X      v2i ( v1 ) ;
X      v2i ( v2 ) ;
X   endline () ;
X   bgnline () ;
X      v2i ( v3 ) ;
X      v2i ( v4 ) ;
X   endline () ;
X
X   v1[0] = cx - crosswiresiz - crosswiregap ;
X   v1[1] = cy - crosswiresiz - crosswiregap ;
X   v2[0] = cx - crosswiresiz - crosswiregap ;
X   v2[1] = cy + crosswiresiz + crosswiregap ;
X   bgnline () ;
X      v2i ( v1 ) ;
X      v2i ( v2 ) ;
X   endline () ;
X   v1[0] = cx + crosswiresiz + crosswiregap ;
X   v1[1] = cy - crosswiresiz - crosswiregap ;
X   v2[0] = cx + crosswiresiz + crosswiregap ;
X   v2[1] = cy + crosswiresiz + crosswiregap ;
X   bgnline () ;
X      v2i ( v1 ) ;
X      v2i ( v2 ) ;
X   endline () ;
X   v3[0] = cx + crosswiresiz + crosswiregap ;
X   v3[1] = cy - crosswiresiz - crosswiregap ;
X   v4[0] = cx + crosswiresiz - crosswiregap ;
X   v4[1] = cy - crosswiresiz - crosswiregap ;
X   bgnline () ;
X      v2i ( v3 ) ;
X      v2i ( v4 ) ;
X   endline () ;
X   v3[0] = cx + crosswiresiz + crosswiregap ;
X   v3[1] = cy + crosswiresiz + crosswiregap ;
X   v4[0] = cx + crosswiresiz - crosswiregap ;
X   v4[1] = cy + crosswiresiz + crosswiregap ;
X   bgnline () ;
X      v2i ( v3 ) ;
X      v2i ( v4 ) ;
X   endline () ;
X   v3[0] = cx - crosswiresiz - crosswiregap ;
X   v3[1] = cy - crosswiresiz - crosswiregap ;
X   v4[0] = cx - crosswiresiz + crosswiregap ;
X   v4[1] = cy - crosswiresiz - crosswiregap ;
X   bgnline () ;
X      v2i ( v3 ) ;
X      v2i ( v4 ) ;
X   endline () ;
X   v3[0] = cx - crosswiresiz - crosswiregap ;
X   v3[1] = cy + crosswiresiz + crosswiregap ;
X   v4[0] = cx - crosswiresiz + crosswiregap ;
X   v4[1] = cy + crosswiresiz + crosswiregap ;
X   bgnline () ;
X      v2i ( v3 ) ;
X      v2i ( v4 ) ;
X   endline () ;
X   linewidth ( 1 ) ;
X
X   closeobj () ;
X
X   for ( i = 0 ; i < MAXENEM ; i++ ) {
X      enemyinfo[i].destroyed = FALSE ;
X      lx = enemyinfo[i].pos.x = (2*drand48()-1.0)*CUBEMAX ;
X      ly = enemyinfo[i].pos.y = (2*drand48()-1.0)*CUBEMAX ;
X      lz = enemyinfo[i].pos.z = (2*drand48()-1.0)*CUBEMAX ;
X      enemyinfo[i].dir.x = (2*drand48()-1.0) ;
X      enemyinfo[i].dir.y = (2*drand48()-1.0) ;
X      enemyinfo[i].dir.z = (2*drand48()-1.0) ;
X      NORM ( enemyinfo[i].dir ) ;
X
X      /* Tough enemy */
X      enemyinfo[i].tough = ( drand48 () > 0.5 ) ? TRUE : FALSE ;
X
X      /* Cloaked enemy */
X      enemyinfo[i].cloaked = ( drand48 () > 0.9 ) ? TRUE : FALSE ;
X
X      enemyinfo[i].level = WHITE ;
X      if ( drand48 () > 0.9 )
X      /* Stationary enemy */
X         enemyinfo[i].speed = 0.0 ;
X      else
X         enemyinfo[i].speed = ENEMSPEED ;
X
X      if ( enemyinfo[i].cloaked == FALSE )
X         draw_one_enemy ( lx, ly, lz, enemyinfo[i].level ) ;
X   }
X}
X
X
X
Xdraw_window ()
X{
X   color ( WORLDBGCOLOR ) ;
X   clear () ;
X   /* czclear ( BLACK, 500000 ) ; */
X
X   draw_world () ;
X   draw_enemies () ;
X   draw_torpedos () ;
X   if ( crosswire == ON ) draw_crosswire () ;
X}
X
X
X
X
Xdraw_enemies ()
X{
X   int i ;
X
X   for ( i = 0 ; i < MAXENEM ; i++ ) {
X      if ( enemyinfo[i].destroyed == TRUE ) {
X         if ( enemyinfo[i].exploding == TRUE ) {
X            draw_one_exploding_enemy ( enemyinfo[i].pos.x,
X                                        enemyinfo[i].pos.y,
X                                        enemyinfo[i].pos.z, 
X                                        enemyinfo[i].level ) ;
X            enemyinfo[i].exploding = FALSE ;
X         }
X         else
X            continue ;
X      }
X      check_for_enemy_bounce ( i ) ;
X      enemyinfo[i].pos.x += enemyinfo[i].dir.x*enemyinfo[i].speed ;
X      enemyinfo[i].pos.y += enemyinfo[i].dir.y*enemyinfo[i].speed ;
X      enemyinfo[i].pos.z += enemyinfo[i].dir.z*enemyinfo[i].speed ;
X
X      if ( enemyinfo[i].cloaked == FALSE || cloakdetector == ON )
X      draw_one_enemy ( enemyinfo[i].pos.x,
X                       enemyinfo[i].pos.y,
X                       enemyinfo[i].pos.z, enemyinfo[i].level ) ;
X      if ( enemymissile.destroyed == TRUE )
X         launch_enemy_missile ( i ) ;
X   }
X
X   if ( enemymissile.destroyed == FALSE )
X      draw_enemy_missile () ;
X}
X
X
X
Xdraw_one_enemy ( lx, ly, lz, level )
Xfloat lx, ly, lz ;
Xint   level      ;
X{
X   VEC3 v1, v2, v3, v4, v5, v6, v7, v8 ;
X
X   v1[0] = lx ;
X   v1[1] = ly ;
X   v1[2] = lz ;
X   v2[0] = lx + ENEMSIZ ;
X   v2[1] = ly ;
X   v2[2] = lz ;
X   v3[0] = lx + ENEMSIZ ;
X   v3[1] = ly + ENEMSIZ ;
X   v3[2] = lz ;
X   v4[0] = lx ;
X   v4[1] = ly + ENEMSIZ ;
X   v4[2] = lz ;
X   v5[0] = lx ;
X   v5[1] = ly ;
X   v5[2] = lz + ENEMSIZ ;
X   v6[0] = lx + ENEMSIZ ;
X   v6[1] = ly ;
X   v6[2] = lz + ENEMSIZ ;
X   v7[0] = lx + ENEMSIZ ;
X   v7[1] = ly + ENEMSIZ ;
X   v7[2] = lz + ENEMSIZ ;
X   v8[0] = lx ;
X   v8[1] = ly + ENEMSIZ ;
X   v8[2] = lz + ENEMSIZ ;
X   color ( level ) ;
X   bgnpolygon () ;
X   v3f ( v1 ) ;
X   v3f ( v2 ) ;
X   v3f ( v3 ) ;
X   v3f ( v4 ) ;
X   endpolygon () ;
X   bgnpolygon () ;
X   v3f ( v2 ) ;
X   v3f ( v6 ) ;
X   v3f ( v7 ) ;
X   v3f ( v3 ) ;
X   endpolygon () ;
X   bgnpolygon () ;
X   v3f ( v4 ) ;
X   v3f ( v3 ) ;
X   v3f ( v7 ) ;
X   v3f ( v8 ) ;
X   endpolygon () ;
X   bgnpolygon () ;
X   v3f ( v5 ) ;
X   v3f ( v1 ) ;
X   v3f ( v4 ) ;
X   v3f ( v8 ) ;
X   endpolygon () ;
X   bgnpolygon () ;
X   v3f ( v5 ) ;
X   v3f ( v6 ) ;
X   v3f ( v2 ) ;
X   v3f ( v1 ) ;
X   endpolygon () ;
X   bgnpolygon () ;
X   v3f ( v6 ) ;
X   v3f ( v5 ) ;
X   v3f ( v8 ) ;
X   v3f ( v7 ) ;
X   endpolygon () ;
X   color ( RED ) ;
X   bgnline () ;
X   v3f ( v1 ) ;
X   v3f ( v2 ) ;
X   v3f ( v3 ) ;
X   v3f ( v4 ) ;
X   v3f ( v1 ) ;
X   endline () ;
X   bgnline () ;
X   v3f ( v2 ) ;
X   v3f ( v6 ) ;
X   v3f ( v7 ) ;
X   v3f ( v3 ) ;
X   v3f ( v2 ) ;
X   endline () ;
X   bgnline () ;
X   v3f ( v4 ) ;
X   v3f ( v3 ) ;
X   v3f ( v7 ) ;
X   v3f ( v8 ) ;
X   v3f ( v4 ) ;
X   endline () ;
X   bgnline () ;
X   v3f ( v5 ) ;
X   v3f ( v1 ) ;
X   v3f ( v4 ) ;
X   v3f ( v8 ) ;
X   v3f ( v5 ) ;
X   endline () ;
X   bgnline () ;
X   v3f ( v5 ) ;
X   v3f ( v6 ) ;
X   v3f ( v2 ) ;
X   v3f ( v1 ) ;
X   v3f ( v5 ) ;
X   endline () ;
X   bgnline () ;
X   v3f ( v6 ) ;
X   v3f ( v5 ) ;
X   v3f ( v8 ) ;
X   v3f ( v7 ) ;
X   v3f ( v6 ) ;
X   endline () ;
X}
X
X
Xdraw_one_exploding_enemy ( lx, ly, lz, level )
Xfloat lx, ly, lz ;
Xint   level      ;
X{
X   VEC3 v1, v2, v3, v4, v5, v6, v7, v8 ;
X   VEC3 v9, v10, v11, v12 ;
X
X   v1[0] = lx ;
X   v1[1] = ly ;
X   v1[2] = lz ;
X   v2[0] = lx + ENEMSIZ ;
X   v2[1] = ly ;
X   v2[2] = lz ;
X   v3[0] = lx + ENEMSIZ ;
X   v3[1] = ly + ENEMSIZ ;
X   v3[2] = lz ;
X   v4[0] = lx ;
X   v4[1] = ly + ENEMSIZ ;
X   v4[2] = lz ;
X   v5[0] = lx ;
X   v5[1] = ly ;
X   v5[2] = lz + ENEMSIZ ;
X   v6[0] = lx + ENEMSIZ ;
X   v6[1] = ly ;
X   v6[2] = lz + ENEMSIZ ;
X   v7[0] = lx + ENEMSIZ ;
X   v7[1] = ly + ENEMSIZ ;
X   v7[2] = lz + ENEMSIZ ;
X   v8[0] = lx ;
X   v8[1] = ly + ENEMSIZ ;
X   v8[2] = lz + ENEMSIZ ;
X   v9[0] = lx - ENEMSIZ ;
X   v9[1] = ly+ENEMSIZ/2.0 ;
X   v9[2] = lz+ENEMSIZ/2.0 ;
X   v10[0] = lx+ENEMSIZ/2.0 ;
X   v10[1] = ly - ENEMSIZ ;
X   v10[2] = lz+ENEMSIZ/2.0 ;
X   v11[0] = lx + 2*ENEMSIZ ;
X   v11[1] = ly+ENEMSIZ/2.0 ;
X   v11[2] = lz+ENEMSIZ/2.0 ;
X   v12[0] = lx+ENEMSIZ/2.0 ;
X   v12[1] = ly + 2*ENEMSIZ ;
X   v12[2] = lz+ENEMSIZ/2.0 ;
X   color ( RED ) ;
X   bgnpolygon () ;
X   v3f ( v1 ) ;
X   v3f ( v4 ) ;
X   v3f ( v9 ) ;
X   endpolygon () ;
X   bgnpolygon () ;
X   v3f ( v9 ) ;
X   v3f ( v4 ) ;
X   v3f ( v8 ) ;
X   endpolygon () ;
X   bgnpolygon () ;
X   v3f ( v8 ) ;
X   v3f ( v5 ) ;
X   v3f ( v9 ) ;
X   endpolygon () ;
X   bgnpolygon () ;
X   v3f ( v9 ) ;
X   v3f ( v5 ) ;
X   v3f ( v1 ) ;
X   endpolygon () ;
X   color ( RED ) ;
X   bgnclosedline () ;
X   v3f ( v1 ) ;
X   v3f ( v4 ) ;
X   v3f ( v9 ) ;
X   endclosedline () ;
X   bgnclosedline () ;
X   v3f ( v9 ) ;
X   v3f ( v4 ) ;
X   v3f ( v8 ) ;
X   endclosedline () ;
X   bgnclosedline () ;
X   v3f ( v8 ) ;
X   v3f ( v5 ) ;
X   v3f ( v9 ) ;
X   endclosedline () ;
X   bgnclosedline () ;
X   v3f ( v9 ) ;
X   v3f ( v5 ) ;
X   v3f ( v1 ) ;
X   endclosedline () ;
X   color ( RED ) ;
X   bgnpolygon () ;
X   v3f ( v4 ) ;
X   v3f ( v3 ) ;
X   v3f ( v12 ) ;
X   endpolygon () ;
X   bgnpolygon () ;
X   v3f ( v12 ) ;
X   v3f ( v3 ) ;
X   v3f ( v7 ) ;
X   endpolygon () ;
X   bgnpolygon () ;
X   v3f ( v7 ) ;
X   v3f ( v8 ) ;
X   v3f ( v12 ) ;
X   endpolygon () ;
X   bgnpolygon () ;
X   v3f ( v12 ) ;
X   v3f ( v8 ) ;
X   v3f ( v4 ) ;
X   endpolygon () ;
X   color ( RED ) ;
X   bgnclosedline () ;
X   v3f ( v4 ) ;
X   v3f ( v3 ) ;
X   v3f ( v12 ) ;
X   endclosedline () ;
X   bgnclosedline () ;
X   v3f ( v12 ) ;
X   v3f ( v3 ) ;
X   v3f ( v7 ) ;
X   endclosedline () ;
X   bgnclosedline () ;
X   v3f ( v7 ) ;
X   v3f ( v8 ) ;
X   v3f ( v12 ) ;
X   endclosedline () ;
X   bgnclosedline () ;
X   v3f ( v12 ) ;
X   v3f ( v8 ) ;
X   v3f ( v4 ) ;
X   endclosedline () ;
X   color ( RED ) ;
X   bgnpolygon () ;
X   v3f ( v11 ) ;
X   v3f ( v3 ) ;
X   v3f ( v2 ) ;
X   endpolygon () ;
X   bgnpolygon () ;
X   v3f ( v2 ) ;
X   v3f ( v6 ) ;
X   v3f ( v11 ) ;
X   endpolygon () ;
X   bgnpolygon () ;
X   v3f ( v11 ) ;
X   v3f ( v6 ) ;
X   v3f ( v7 ) ;
X   endpolygon () ;
X   bgnpolygon () ;
X   v3f ( v7 ) ;
X   v3f ( v3 ) ;
X   v3f ( v11 ) ;
X   endpolygon () ;
X   color ( RED ) ;
X   bgnclosedline () ;
X   v3f ( v11 ) ;
X   v3f ( v3 ) ;
X   v3f ( v2 ) ;
X   endclosedline () ;
X   bgnclosedline () ;
X   v3f ( v2 ) ;
X   v3f ( v6 ) ;
X   v3f ( v11 ) ;
X   endclosedline () ;
X   bgnclosedline () ;
X   v3f ( v11 ) ;
X   v3f ( v6 ) ;
X   v3f ( v7 ) ;
X   endclosedline () ;
X   bgnclosedline () ;
X   v3f ( v7 ) ;
X   v3f ( v3 ) ;
X   v3f ( v11 ) ;
X   endclosedline () ;
X   color ( RED ) ;
X   bgnpolygon () ;
X   v3f ( v10 ) ;
X   v3f ( v2 ) ;
X   v3f ( v1 ) ;
X   endpolygon () ;
X   bgnpolygon () ;
X   v3f ( v1 ) ;
X   v3f ( v5 ) ;
X   v3f ( v10 ) ;
X   endpolygon () ;
X   bgnpolygon () ;
X   v3f ( v10 ) ;
X   v3f ( v5 ) ;
X   v3f ( v6 ) ;
X   endpolygon () ;
X   bgnpolygon () ;
X   v3f ( v6 ) ;
X   v3f ( v2 ) ;
X   v3f ( v10 ) ;
X   endpolygon () ;
X   color ( RED ) ;
X   bgnclosedline () ;
X   v3f ( v10 ) ;
X   v3f ( v2 ) ;
X   v3f ( v1 ) ;
X   endclosedline () ;
X   bgnclosedline () ;
X   v3f ( v1 ) ;
X   v3f ( v5 ) ;
X   v3f ( v10 ) ;
X   endclosedline () ;
X   bgnclosedline () ;
X   v3f ( v10 ) ;
X   v3f ( v5 ) ;
X   v3f ( v6 ) ;
X   endclosedline () ;
X   bgnclosedline () ;
X   v3f ( v6 ) ;
X   v3f ( v2 ) ;
X   v3f ( v10 ) ;
X   endclosedline () ;
X}
X
X
Xdraw_enemy_missile ()
X{
X   float lx, ly, lz ;
X   VEC3 v1, v2, v3, v4, v5, v6, v7, v8 ;
X
X   v1[0] = enemymissile.pos.x += enemymissile.dir.x*ENEMMISSPEED ;
X   v1[1] = enemymissile.pos.y += enemymissile.dir.y*ENEMMISSPEED ;
X   v1[2] = enemymissile.pos.z += enemymissile.dir.z*ENEMMISSPEED ;
X   v2[0] = v1[0] + enemymissile.dir.x*enemymissile.msiz ;
X   v2[1] = v1[1] + enemymissile.dir.y*enemymissile.msiz ;
X   v2[2] = v1[2] + enemymissile.dir.z*enemymissile.msiz ;
X   color ( MAGENTA ) ;
X   linewidth ( 5 ) ;
X   bgnline () ;
X      v3f ( v1 ) ;
X      v3f ( v2 ) ;
X   endline () ;
X   linewidth ( 1 ) ;
X   check_for_enemy_missile_collision () ;
X}
X
X
X
Xdraw_crosswire ()
X/* Draw cross-wire at the center of the world viewport */
X{
X   pushmatrix () ;
X   ortho2 ( (Coord)0, (Coord)xsiz, (Coord)vpst, (Coord)ysiz ) ;
X   callobj ( crosswire_object ) ;
X   popmatrix () ;
X}
X
X
Xmove_ship ()
X{
X   SCALE_VEC ( shipmov, shipz, thrust ) ;
X   COPY_VEC ( shippos[0], shippos[1] ) ;
X   ADD_VEC  ( shippos[1], shipmov ) ;
X   translate ( -shipmov.x, -shipmov.y, -shipmov.z ) ;
X   fuelleft -= ABS(thrust) ;
X}
X
X
Xdraw_world ()
X{
X   xrotate () ;
X   yrotate () ;
X   zrotate () ;
X
X   move_ship () ;
X   check_for_ship_collision () ;
X
X   callobj ( vr_world_object ) ;
X}
X
X
Xyrotate ()
X{
X   Matrix mx ;
X
X   if ( yrot != 0 ) {
X      lib_create_axis_rotate_matrix ( mx, shipy, (float)-yrot/10.0 ) ;
X      translate ( shippos[1].x, shippos[1].y, shippos[1].z ) ;
X      multmatrix ( mx ) ;
X      translate ( -shippos[1].x, -shippos[1].y, -shippos[1].z ) ;
X      mat_transform ( mx, &shipz ) ;
X      mat_transform ( mx, &shipx ) ;
X      yrot = 0 ;
X      fuelleft -= ABS(yrot) ;
X   }
X}
X
X
X
Xxrotate ()
X{
X   Matrix mx ;
X
X   if ( xrot != 0 ) {
X      lib_create_axis_rotate_matrix ( mx, shipx, (float)-xrot/10.0 ) ;
X      translate ( shippos[1].x, shippos[1].y, shippos[1].z ) ;
X      multmatrix ( mx ) ;
X      translate ( -shippos[1].x, -shippos[1].y, -shippos[1].z ) ;
X      mat_transform ( mx, &shipy ) ;
X      mat_transform ( mx, &shipz ) ;
X      xrot = 0 ;
X      fuelleft -= ABS(xrot) ;
X   }
X}
X
X
Xzrotate ()
X{
X   Matrix mx ;
X
X   if ( zrot != 0 ) {
X      lib_create_axis_rotate_matrix ( mx, shipz, (float)-zrot/10.0 ) ;
X      translate ( shippos[1].x, shippos[1].y, shippos[1].z ) ;
X      multmatrix ( mx ) ;
X      translate ( -shippos[1].x, -shippos[1].y, -shippos[1].z ) ;
X      mat_transform ( mx, &shipx ) ;
X      mat_transform ( mx, &shipy ) ;
X      zrot = 0 ;
X      fuelleft -= ABS(zrot) ;
X   }
X}
X
X
X
Xfire_torpedo ()
X{
X   int  i ;
X   VEC3 v1, v2 ;
X
X   if ( torpleft == 0 ) return ;
X
X   for ( i = 0  ; i < MAXTORPFIRE ; i++ )
X      if ( torpinfo[i].fired == FALSE ) break ;
X
X   torpinfo[i].fired = TRUE ;
X   COPY_VEC ( torpinfo[i].torpedopos, shippos[1] ) ; 
X   COPY_VEC ( torpinfo[i].torpedodir, shipz ) ; 
X
X   v1[0] = shippos[1].x ;
X   v1[1] = shippos[1].y ;
X   v1[2] = shippos[1].z ;
X   v2[0] = v1[0] + shipz.x*TORPLEN ;
X   v2[1] = v1[1] + shipz.y*TORPLEN ;
X   v2[2] = v1[2] + shipz.z*TORPLEN ;
X
X   color ( MAGENTA ) ;
X   linewidth ( 3 ) ;
X   bgnline () ;
X      v3f ( v1 ) ;
X      v3f ( v2 ) ;
X   endline () ;
X   linewidth ( 1 ) ;
X
X   ntorp++ ;
X   torpleft-- ;
X}
X
X
X
Xlaunch_enemy_missile ( eni )
X{
X   enemymissile.destroyed = FALSE ;
X   COPY_VEC ( enemymissile.pos, enemyinfo[eni].pos ) ;
X   GET_VEC ( shippos[1], enemyinfo[eni].pos, enemymissile.dir ) ; 
X   NORM ( enemymissile.dir ) ;
X   draw_enemy_missile () ;
X}
X
X
X
Xdraw_torpedos ()
X{
X   int i ;
X   VEC3 v1, v2 ;
X
X   for ( i = 0  ; i < MAXTORPFIRE ; i++ ) {
X      if ( torpinfo[i].fired == FALSE ) continue ;
X
X      v1[0] = torpinfo[i].torpedopos.x += torpinfo[i].torpedodir.x*TORPSPEED ;
X      v1[1] = torpinfo[i].torpedopos.y += torpinfo[i].torpedodir.y*TORPSPEED ;
X      v1[2] = torpinfo[i].torpedopos.z += torpinfo[i].torpedodir.z*TORPSPEED ;
X
X      v2[0] = v1[0] + torpinfo[i].torpedodir.x*TORPLEN ;
X      v2[1] = v1[1] + torpinfo[i].torpedodir.y*TORPLEN ;
X      v2[2] = v1[2] + torpinfo[i].torpedodir.z*TORPLEN ;
X
X      check_for_torpedo_collision ( i ) ;
X
X      color ( MAGENTA ) ;
X      linewidth ( 3 ) ;
X      bgnline () ;
X         v3f ( v1 ) ;
X         v3f ( v2 ) ;
X      endline () ;
X      linewidth ( 1 ) ;
X   }
X}
X
X
Xupdate_console_panels ()
X{
X   int v1[3], v2[3], v3[3], v4[3], left, rite, i ;
X   char buff[100] ;
X   float divht, idivht, smalldivwidth, largedivwidth, damlower, damupper ;
X
X   pushmatrix () ;
X   pushviewport () ;
X   viewport ( (Screencoord) 0, (Screencoord) xsiz, (Screencoord) 0, 
X      (Screencoord) (vpst) ) ;
X   color ( PANELBGCOLOR ) ;
X   clear () ;
X   ortho2 ( (Coord)0, (Coord)xsiz, (Coord)0, (Coord)vpst ) ;
X
X   divht = (consupper-conslower)/8.0 ;
X   smalldivwidth = consdispwidth/8.0 ;
X   largedivwidth = consdispwidth/4.0 ;
X
X   /* Update thrust */
X   left = 10 ;
X   rite = left + consdispwidth ;
X   v1[0] = left-1 ;
X   v1[1] = conslower-1 ;
X   v2[0] = rite ;
X   v2[1] = conslower-1 ;
X   v3[0] = rite ;
X   v3[1] = consupper+1 ;
X   v4[0] = left-1 ;
X   v4[1] = consupper+1 ;
X   color ( YELLOW ) ;
X   bgnclosedline () ;
X   v2i ( v1 ) ;
X   v2i ( v2 ) ;
X   v2i ( v3 ) ;
X   v2i ( v4 ) ;
X   endclosedline () ;
X   if ( thrust < 0.0  )
X      color ( RED ) ;
X   else
X      color ( PANELTHRCOLOR ) ;
X   v1[0] = left ;
X   v1[1] = conslower ;
X   v2[0] = rite ;
X   v2[1] = conslower ;
X   v3[0] = rite ;
X   v3[1] = (ABS(thrust)/MAXTHRUST)*(consupper-conslower) + conslower ;
X   v4[0] = left ;
X   v4[1] = v3[1] ;
X   bgnpolygon () ;
X   v2i ( v1 ) ;
X   v2i ( v2 ) ;
X   v2i ( v3 ) ;
X   v2i ( v4 ) ;
X   endpolygon () ;
X   color ( YELLOW ) ;
X   for ( i = 1 ; i <= 7 ; i++ ) {
X      idivht = divht*i+conslower ;
X      v1[0] = left ;
X      v1[1] = idivht ;
X      v2[0] = (i%2 == 1) ? left + smalldivwidth : left + largedivwidth ;
X      v2[1] = idivht ;
X      bgnline () ;
X         v2i ( v1 ) ;
X         v2i ( v2 ) ;
X      endline () ;
X      v1[0] = rite ;
X      v1[1] = idivht ;
X      v2[0] = rite - ((i%2 == 1) ? smalldivwidth : largedivwidth) ;
X      v2[1] = idivht ;
X      bgnline () ;
X         v2i ( v1 ) ;
X         v2i ( v2 ) ;
X      endline () ;
X   }
X   cmov2i ( left+conslabels[0], conslower-15 ) ;
X   color ( WHITE ) ;
X   charstr ( "Thrust" ) ;
X
X   /* Update Rotation Speed */
X   left = rite+consdispwidth ;
X   rite = left+consdispwidth ;
X   v1[0] = left-1 ;
X   v1[1] = conslower-1 ;
X   v2[0] = rite ;
X   v2[1] = conslower-1 ;
X   v3[0] = rite ;
X   v3[1] = consupper+1 ;
X   v4[0] = left-1 ;
X   v4[1] = consupper+1 ;
X   color ( YELLOW ) ;
X   bgnclosedline () ;
X   v2i ( v1 ) ;
X   v2i ( v2 ) ;
X   v2i ( v3 ) ;
X   v2i ( v4 ) ;
X   endclosedline () ;
X   color ( PANELROTCOLOR ) ;
X   v1[0] = left ;
X   v1[1] = conslower ;
X   v2[0] = rite ;
X   v2[1] = conslower ;
X   v3[0] = rite ;
X   v3[1] = (ABS(steprot)/(float)MAXROT)*(consupper-conslower) + conslower ;
X   v4[0] = left ;
X   v4[1] = v3[1] ;
X   bgnpolygon () ;
X   v2i ( v1 ) ;
X   v2i ( v2 ) ;
X   v2i ( v3 ) ;
X   v2i ( v4 ) ;
X   endpolygon () ;
X   color ( YELLOW ) ;
X   for ( i = 1 ; i <= 7 ; i++ ) {
X      idivht = divht*i+conslower ;
X      v1[0] = left ;
X      v1[1] = idivht ;
X      v2[0] = (i%2 == 1) ? left + smalldivwidth : left + largedivwidth ;
X      v2[1] = idivht ;
X      bgnline () ;
X         v2i ( v1 ) ;
X         v2i ( v2 ) ;
X      endline () ;
X      v1[0] = rite ;
X      v1[1] = idivht ;
X      v2[0] = rite - ((i%2 == 1) ? smalldivwidth : largedivwidth) ;
X      v2[1] = idivht ;
X      bgnline () ;
X         v2i ( v1 ) ;
X         v2i ( v2 ) ;
X      endline () ;
X   }
X   cmov2i ( left+conslabels[1], conslower-15 ) ;
X   color ( WHITE ) ;
X   charstr ( "Rotate" ) ;
X
X   /* Update Fuel */
X   left = rite+consdispwidth ;
X   rite = left+consdispwidth ;
X   v1[0] = left-1 ;
X   v1[1] = conslower-1 ;
X   v2[0] = rite ;
X   v2[1] = conslower-1 ;
X   v3[0] = rite ;
X   v3[1] = consupper+1 ;
X   v4[0] = left-1 ;
X   v4[1] = consupper+1 ;
X   color ( YELLOW ) ;
X   bgnclosedline () ;
X   v2i ( v1 ) ;
X   v2i ( v2 ) ;
X   v2i ( v3 ) ;
X   v2i ( v4 ) ;
X   endclosedline () ;
X   if ( fuelleft <= 0.2*MAXFUEL )
X      color ( RED ) ;
X   else
X      color ( PANELFUECOLOR ) ;
X   v1[0] = left ;
X   v1[1] = conslower ;
X   v2[0] = rite ;
X   v2[1] = conslower ;
X   v3[0] = rite ;
X   v3[1] = (fuelleft/MAXFUEL)*(consupper-conslower) + conslower ;
X   v4[0] = left ;
X   v4[1] = v3[1] ;
X   bgnpolygon () ;
X   v2i ( v1 ) ;
X   v2i ( v2 ) ;
X   v2i ( v3 ) ;
X   v2i ( v4 ) ;
X   endpolygon () ;
X   color ( YELLOW ) ;
X   for ( i = 1 ; i <= 7 ; i++ ) {
X      idivht = divht*i+conslower ;
X      v1[0] = left ;
X      v1[1] = idivht ;
X      v2[0] = (i%2 == 1) ? left + smalldivwidth : left + largedivwidth ;
X      v2[1] = idivht ;
X      bgnline () ;
X         v2i ( v1 ) ;
X         v2i ( v2 ) ;
X      endline () ;
X      v1[0] = rite ;
X      v1[1] = idivht ;
X      v2[0] = rite - ((i%2 == 1) ? smalldivwidth : largedivwidth) ;
X      v2[1] = idivht ;
X      bgnline () ;
X         v2i ( v1 ) ;
X         v2i ( v2 ) ;
X      endline () ;
X   }
X   cmov2i ( left+conslabels[2], conslower-15 ) ;
X   color ( WHITE ) ;
X   charstr ( "Fuel" ) ;
X
X   /* Update No. of torpedos left */
X   left = rite+consdispwidth ;
X   rite = left+consdispwidth ;
X   v1[0] = left-1 ;
X   v1[1] = conslower-1 ;
X   v2[0] = rite+1 ;
X   v2[1] = conslower-1 ;
X   v3[0] = rite+1 ;
X   v3[1] = consupper+1 ;
X   v4[0] = left-1 ;
X   v4[1] = consupper+1 ;
X   color ( YELLOW ) ;
X   bgnclosedline () ;
X   v2i ( v1 ) ;
X   v2i ( v2 ) ;
X   v2i ( v3 ) ;
X   v2i ( v4 ) ;
X   endclosedline () ;
X   if ( torpleft <= 0.2*MAXTORP )
X      color ( RED ) ;
X   else
X      color ( PANELTORCOLOR ) ;
X   v1[0] = left ;
X   v1[1] = conslower ;
X   v2[0] = rite ;
X   v2[1] = conslower ;
X   v3[0] = rite ;
X   v3[1] = ((float)torpleft/(float)MAXTORP)*(consupper-conslower) 
X           + conslower ;
X   v4[0] = left ;
X   v4[1] = v3[1] ;
X   bgnpolygon () ;
X   v2i ( v1 ) ;
X   v2i ( v2 ) ;
X   v2i ( v3 ) ;
X   v2i ( v4 ) ;
X   endpolygon () ;
X   color ( YELLOW ) ;
X   for ( i = 1 ; i <= 7 ; i++ ) {
X      idivht = divht*i+conslower ;
X      v1[0] = left ;
X      v1[1] = idivht ;
X      v2[0] = (i%2 == 1) ? left + smalldivwidth : left + largedivwidth ;
X      v2[1] = idivht ;
X      bgnline () ;
X         v2i ( v1 ) ;
X         v2i ( v2 ) ;
X      endline () ;
X      v1[0] = rite ;
X      v1[1] = idivht ;
X      v2[0] = rite - ((i%2 == 1) ? smalldivwidth : largedivwidth) ;
X      v2[1] = idivht ;
X      bgnline () ;
X         v2i ( v1 ) ;
X         v2i ( v2 ) ;
X      endline () ;
X   }
X   cmov2i ( left+conslabels[3], conslower-15 ) ;
X   color ( WHITE ) ;
X   charstr ( "Torpedo" ) ;
X
X   /* Update damage report */
X   left = rite+20 ;
X   cmov2i ( left, consupper-10 ) ;
X   color ( WHITE ) ;
X   charstr ( "Damage" ) ;
X
X   damlower = consupper-10 ;
X   damupper = (consupper-conslower)/10.0 + damlower ;
X   left = rite+consdispwidth +40;
X   rite = xsiz-10 ;
X   v1[0] = left-1 ;
X   v1[1] = damlower-1 ;
X   v2[0] = rite+1 ;
X   v2[1] = damlower-1 ;
X   v3[0] = rite+1 ;
X   v3[1] = damupper+1 ;
X   v4[0] = left-1 ;
X   v4[1] = damupper+1 ;
X   color ( YELLOW ) ;
X   bgnclosedline () ;
X   v2i ( v1 ) ;
X   v2i ( v2 ) ;
X   v2i ( v3 ) ;
X   v2i ( v4 ) ;
X   endclosedline () ;
X   if ( damage > 100.0 ) damage = 100.0 ;
X   color ( PANELDAMCOLOR ) ;
X   v1[0] = left ;
X   v1[1] = damlower ;
X   v2[0] = (damage/100.0)*(rite-left)+left  ;
X   v2[1] = damlower ;
X   v3[0] = v2[0] ;
X   v3[1] = damupper ;
X   v4[0] = left ;
X   v4[1] = v3[1] ;
X   bgnpolygon () ;
X   v2i ( v1 ) ;
X   v2i ( v2 ) ;
X   v2i ( v3 ) ;
X   v2i ( v4 ) ;
X   endpolygon () ;
X   color ( YELLOW ) ;
X   for ( i = 1 ; i <= 9 ; i++ ) {
X      v1[0] = left + (rite-left)/10.0*i ;
X      v1[1] = damlower ;
X      v2[0] = v1[0] ;
X      v2[1] = damupper ;
X      bgnline () ;
X         v2i ( v1 ) ;
X         v2i ( v2 ) ;
X      endline () ;
X   }
X
X   /* Update console message window */
X   damlower -= 20 ;
X   damupper = (consupper-conslower)/10.0 + damlower ;
X   v1[0] = left-1 ;
X   v1[1] = damlower-1 ;
X   v2[0] = rite+1 ;
X   v2[1] = damlower-1 ;
X   v3[0] = rite+1 ;
X   v3[1] = damupper+1 ;
X   v4[0] = left-1 ;
X   v4[1] = damupper+1 ;
X   color ( WORLDBGCOLOR ) ;
X   bgnpolygon () ;
X   v2i ( v1 ) ;
X   v2i ( v2 ) ;
X   v2i ( v3 ) ;
X   v2i ( v4 ) ;
X   endpolygon () ;
X   cmov2i ( left+1, damlower+1 ) ;
X   color ( consolemsgcolor ) ;
X   charstr ( consolemsg ) ;
X
X   /* Update No. of enemies left */
X   color ( YELLOW ) ;
X   sprintf ( buff, "Enemies Left : %d", enemleft ) ;
X   cmov2i ( left, (int)((float)(consupper-conslower)/2.0+conslower)-30 ) ;
X   charstr ( buff ) ;
X
X   /* Update no. of cloaked enemies */
X   sprintf ( buff, "Missile dist : %-9.2f", enemymissile.distfromship ) ;
X   cmov2i ( left, (int)((float)(consupper-conslower)*3.0/4.0+conslower)-30 ) ;
X   charstr ( buff ) ;
X
X   /* Update Points */
X   sprintf ( buff, "Points       : %-9.0f", points ) ;
X   cmov2i ( left, (int)((float)(consupper-conslower)/4.0+conslower)-30 ) ;
X   charstr ( buff ) ;
X
X   /* Print Version */
X   cmov2i ( left, conslower-25 ) ;
X   color ( GREEN ) ;
X   charstr ( "VR v1.0 (c) 1992 - Cado" ) ;
X
X   popviewport () ;
X   popmatrix () ;
X}
X
X
Xcheck_game ()
X{
X   if ( damage >= 100 ) game_over ( "100% Ship damage" ) ;
X   if ( fuelleft < 0 )  game_over ( "Ran out of fuel" ) ;
X   if ( torpleft <= 0 ) game_over ( "Ran out of torpedos" ) ;
X   if ( enemleft == 0 ) {
X      ringbell () ;
X      ringbell () ;
X      ringbell () ;
X      ringbell () ;
X      game_over ( "Congrats !!" ) ;
X   }
X}
X
X
X
Xclear_console_message ()
X{
X   mainloopcycles++ ;
X   if ( mainloopcycles%20 == 0 ) {
X      mainloopcycles = 0 ;
X      consmsg ( "All Systems Normal", WHITE ) ;
X   }
X}
X
X
X
Xconsmsg ( msg, col )
Xchar *msg ;
Xint  col ;
X{
X   mainloopcycles = 0 ;
X   consolemsgcolor = col ;
X   strcpy ( consolemsg, msg ) ;
X}
X
X
Xmain ( c, v )
Xint  c   ;
Xchar **v ;
X{
X   short val ;
X   char  buff[100] ;
X   int qt ;
X
X   printf ( "\n\n\nVR v1.0 by Cado <12/3/92>\n\n" ) ;
X   system ( "/usr/NeWS/bin/keywarp 10 1" ) ;
X
X   /* Seed random no. generator */
X   srand48 ( time ( 0 ) ) ;
X
X   init_stat () ;
X   init_gfx ();
X   pushmatrix () ;
X
X   /* Main Game Loop */
X   while ( TRUE ) { 
X      draw_window () ;
X      update_console_panels () ;
X      swapbuffers () ;
X      check_game () ;
X      
X      clear_console_message () ;
X
X      if ( cloakdetector == ON ) {
X         fuelleft -= MAXFUEL*0.005 ;
X         cloakdetector = OFF ;
X         consmsg ( "All Systems Normal", WHITE ) ;
X      }
X
X      while ( qtest() ) {
X         switch ( qread ( &val ) ) {
X         case SKEY :
X         /* Increase forward ship thrust */
X            if ( thrust < MAXTHRUST )
X               thrust += stepthrust ;
X            else
X               consmsg ( "Reached WARP 9", YELLOW ) ;
X            break ;
X         case AKEY :
X         /* Increase backward ship thrust */
X            if ( thrust > -MAXTHRUST )
X               thrust -= stepthrust ;
X            else
X               consmsg ( "Reached WARP 9", YELLOW ) ;
X            break ;
X         case ZKEY :
X         /* Full brakes -- halt ship */
X            consmsg ( "Ship Halt", YELLOW ) ;
X            thrust = 0 ;
X            break ;
X
X         case CKEY :
X         /* Torpedo firing cross wire toggle */
X            crosswire = ! crosswire ;
X            sprintf ( buff, "Torpedo Targeting %s",
X               (crosswire==ON)? "ON":"OFF" ) ;
X            consmsg ( buff, YELLOW ) ;
X            while ( qtest() ) qread ( &val ) ;
X            break ;
X
X         case DKEY :
X         /* Cloaked enemy detector button */
X            cloakdetector = ON ;
X            consmsg ( "Cloak Detector ON", 128 ) ;
X            break ;
X
X         /* Ship rotation keys */
X         case LEFTARROWKEY : 
X            yrot = steprot ;
X            break ;
X         case RIGHTARROWKEY : 
X            yrot = -steprot ;
X            break ;
X         case UPARROWKEY : 
X            xrot = steprot ;
X            break ;
X         case DOWNARROWKEY : 
X            xrot = -steprot ;
X            break ;
X         case COMMAKEY : 
X            zrot = -steprot ;
X            break ;
X         case PERIODKEY : 
X            zrot = steprot ;
X            break ;
X
X         /* Ship rotation control keys */
X         case PADENTER :
X            if ( steprot < MAXROT )
X               steprot += 10 ;
X            break ;
X         case PAD0 :
X            if ( steprot > MINROT )
X               steprot -= 10 ;
X            break ;
X
X         case SPACEKEY :
X         /* Fire torpedo or laser tracker */
X            if ( trackertoggle == ON ) {
X               enemyinfo[enemynum].destroyed = TRUE ;
X               enemyinfo[enemynum].exploding = TRUE ;
X               consmsg ( "Laser tracker success", GREEN ) ;
X               trackertoggle = OFF ;
X               ntrackersleft-- ;
X               enemleft-- ;
X               points += 1000.0 ;
X            }
X            else if ( ntorp < MAXTORPFIRE )
X               fire_torpedo () ;
X            break ;
X
X         case TKEY :
X         /* Laser tracker targeting instrument */
X            qreset () ;
X            if ( trackertoggle == ON ) {
X               trackertoggle = OFF ;
X               consmsg ( "Targeting OFF", WHITE ) ;
X               enemyinfo[enemynum].level = prevstate ;
X            }
X            else {
X               if ( ntrackersleft > 0 ) {
X                  consmsg ( "Targeting ...", WHITE ) ;
X                  target_enemy () ;
X               }
X               else
X                  consmsg ( "No tracer lasers left", YELLOW ) ;
X            }
X            break ;
X
X
X         case ESCKEY :
X            exit_game () ;
X         }
X      }
X   }
X}
X
X
Xpr ( v )
XVEC v ;
X{
X   printf ( "%f %f %f\n", v.x, v.y, v.z ) ;
X}
X
X
Xmat_transform ( a, v )
XMatrix a  ;
XVEC    *v ;
X{
X   VEC vn ;
X
X   vn.x = a[0][0]*v->x + a[0][1]*v->y + a[0][2]*v->z ;
X   vn.y = a[1][0]*v->x + a[1][1]*v->y + a[1][2]*v->z ;
X   vn.z = a[2][0]*v->x + a[2][1]*v->y + a[2][2]*v->z ;
X   COPY_VEC ( (*v), vn ) ;
X}
X
X
X
Xcheck_for_ship_collision ()
X{
X   int i ;
X   VEC tdir, un, refdir, olddir, expsite ;
X   int chdir ;
X   Matrix mx  ;
X   VEC    n   ;
X   float  ang ;
X
X   if ( shippos[1].x <= CUBEMIN ||
X        shippos[1].y <= CUBEMIN ||
X        shippos[1].z <= CUBEMIN ||
X        shippos[1].x >= CUBEMAX ||
X        shippos[1].y >= CUBEMAX ||
X        shippos[1].z >= CUBEMAX )
X      game_over ( "Collided with wall" ) ;
X
X   for ( i = 0 ; i < MAXENEM ; i++ ) {
X      if ( enemyinfo[i].destroyed == FALSE )
X      if ( DIST ( shippos[1], enemyinfo[i].pos )
X           < ENEMSIZ ) {
X         damage += (ABS(thrust)/MAXTHRUST) ;
X         collided ( "enemy" ) ;
X         COPY_VEC ( expsite, shippos[1] ) ;
X         expsite.x += shipz.x*5.0 ;
X         expsite.y += shipz.y*5.0 ;
X         expsite.z += shipz.z*5.0 ;
X         big_explosion ( expsite ) ;
X      }
X   }
X
X   if ( enemymissile.destroyed == FALSE )
X   if ( (enemymissile.distfromship = DIST ( shippos[1], enemymissile.pos ))
X        < SHIPSIZ/2.0 ) {
X      damage += 10 ;
X      collided ( "enemy missile" ) ;
X      COPY_VEC ( expsite, shippos[1] ) ;
X      expsite.x += shipz.x*5.0 ;
X      expsite.y += shipz.y*5.0 ;
X      expsite.z += shipz.z*5.0 ;
X      big_explosion ( expsite ) ;
X   }
X}
X
X
X
Xcheck_for_torpedo_collision ( torpnum )
Xint torpnum ;
X{
X   int i ;
X   float dist, pfact ;
X
X   if ( torpinfo[torpnum].torpedopos.x <= CUBEMIN || 
X        torpinfo[torpnum].torpedopos.x >= CUBEMAX ||
X        torpinfo[torpnum].torpedopos.y <= CUBEMIN || 
X        torpinfo[torpnum].torpedopos.y >= CUBEMAX ||
X        torpinfo[torpnum].torpedopos.z <= CUBEMIN || 
X        torpinfo[torpnum].torpedopos.z >= CUBEMAX ) {
X      torpinfo[torpnum].fired = FALSE ;
X      ntorp-- ;
X      explosion ( torpinfo[torpnum].torpedopos ) ;
X   }
X
X   for ( i = 0 ; i < MAXENEM ; i++ ) {
X      if ( ( enemyinfo[i].destroyed == FALSE ) && 
X           (dist = DIST ( torpinfo[torpnum].torpedopos, 
X                          enemyinfo[i].pos ))
X           < ENEMSIZ ) {
X         torpinfo[torpnum].fired = FALSE ;
X         ntorp-- ;
X         big_explosion ( torpinfo[torpnum].torpedopos ) ;
X         pfact = 1.0 ;
X         dist = DIST ( enemyinfo[i].pos, shippos[1] ) ;
X
X         if ( enemyinfo[i].tough == TRUE ) {
X         /* Tough enemy needs to be shot multiple times */
X            switch ( enemyinfo[i].level ) {
X            case BLUE :
X               pfact = 2.5 ;
X               enemyinfo[i].destroyed = TRUE ;
X               enemyinfo[i].exploding = TRUE ;
X               enemleft-- ;
X               consmsg ( 
X                  (enemyinfo[i].cloaked == TRUE) ?
X                  "Cloaked Enemy destroyed" : "Enemy destroyed", 
X                  GREEN 
X               ) ;
X               break ;
X            case YELLOW :
X               pfact = 2.0 ;
X               if ( drand48() > 0.95 ) {
X               /* Terrible luck !! */
X                  consmsg ( "Enemy cloaked", RED ) ;
X                  enemyinfo[i].cloaked = TRUE ;
X               }
X               else {
X                  enemyinfo[i].level = BLUE ;
X                  enemyinfo[i].speed *= TOUGHENEMSPEEDFACT ;
X                  consmsg ( "Enemy hit", GREEN ) ;
X               }
X               break ;
X            case GREEN :
X               pfact = 1.5 ;
X               enemyinfo[i].level = YELLOW ;
X               enemyinfo[i].speed *= TOUGHENEMSPEEDFACT ;
X               consmsg ( "Enemy hit", GREEN ) ;
X               break ;
X            case WHITE :
X               pfact = 1.0 ;
X               enemyinfo[i].level = GREEN ;
X               enemyinfo[i].speed *= TOUGHENEMSPEEDFACT ;
X               consmsg ( "Enemy hit", GREEN ) ;
X               break ;
X            case CYAN :
X            /* Marked by tracker beam */ 
X               pfact = 0.0 ;
X               break ;
X            }
X         }
X         else {
X            if ( enemyinfo[i].level == CYAN )
X               pfact = 0.0 ;
X            else {
X               enemyinfo[i].destroyed = TRUE ;
X               enemyinfo[i].exploding = TRUE ;
X               enemleft-- ;
X               consmsg ( "Enemy destroyed", GREEN ) ;
X            }
X         }
X         points += pfact*dist ;
X      }
X   }
X
X   if ( enemymissile.destroyed == FALSE ) 
X   if ( DIST ( enemymissile.pos, torpinfo[torpnum].torpedopos ) < 
X               enemymissile.msiz ) {
X   /* Destroyed an enemy missile */
X      points += 10000.0 ;
X      enemymissileshit++ ;
X      consmsg ( "Missile destroyed", GREEN ) ;
X      enemymissile.destroyed = TRUE ;
X      big_explosion ( torpinfo[torpnum].torpedopos ) ;
X   }
X}
X
X
X
Xcheck_for_enemy_bounce ( eni )
Xint eni ;
X{
X   VEC tdir, un, refdir ;
X   int chdir ;
X
X   chdir = FALSE ;
X
X   if ( enemyinfo[eni].pos.x <= CUBEMIN ) {
X      un.x = 1  ;
X      un.y = 0  ;
X      un.z = 0  ;
X      chdir = TRUE ;
X   }
X   if ( enemyinfo[eni].pos.x >= CUBEMAX ) {
X      un.x = -1  ;
X      un.y = 0  ;
X      un.z = 0  ;
X      chdir = TRUE ;
X   }
X   if ( enemyinfo[eni].pos.y <= CUBEMIN ) {
X      un.x = 0  ;
X      un.y = 1  ;
X      un.z = 0  ;
X      chdir = TRUE ;
X   }
X   if ( enemyinfo[eni].pos.y >= CUBEMAX ) {
X      un.x = 0  ;
X      un.y = -1  ;
X      un.z = 0  ;
X      chdir = TRUE ;
X   }
X   if ( enemyinfo[eni].pos.z <= CUBEMIN ) {
X      un.x = 0  ;
X      un.y = 0  ;
X      un.z = 1  ;
X      chdir = TRUE ;
X   }
X   if ( enemyinfo[eni].pos.z >= CUBEMAX ) {
X      un.x = 0  ;
X      un.y = 0  ;
X      un.z = -1  ;
X      chdir = TRUE ;
X   }
X
X   if ( chdir == TRUE ) {
X      SCALE_VEC ( enemyinfo[eni].dir, enemyinfo[eni].dir, -1.0 ) ;
X      REFL_RAY ( enemyinfo[eni].dir, enemyinfo[eni].pos, un, refdir ) ;
X      COPY_VEC ( enemyinfo[eni].dir, refdir ) ;
X   }
X}
X
X
Xcheck_for_enemy_missile_collision ()
X{
X   if ( enemymissile.pos.x <= CUBEMIN || 
X        enemymissile.pos.x >= CUBEMAX ||
X        enemymissile.pos.y <= CUBEMIN || 
X        enemymissile.pos.y >= CUBEMAX ||
X        enemymissile.pos.z <= CUBEMIN || 
X        enemymissile.pos.z >= CUBEMAX ) {
X      enemymissile.destroyed = TRUE ;
X      explosion ( enemymissile.pos ) ;
X   }
X}
X
X
X
Xexplosion ( v )
XVEC v ;
X{
X   int i ;
X   VEC3 v1, vp ;
X   VEC  r      ;
X
X   linewidth ( 2 ) ;
X   color ( RED ) ;
X
X   VECTOVEC3 ( vp, v ) ;
X   for ( i = 0 ; i < 10 ; i++ ) {
X   r.x = ( 2*drand48 () - 1 ) ;
X   r.y = ( 2*drand48 () - 1 ) ;
X   r.z = ( 2*drand48 () - 1 ) ;
X   NORM ( r ) ;
X   v1[0] = v.x+r.x*EXPSIZ ;
X   v1[1] = v.y+r.y*EXPSIZ ;
X   v1[2] = v.z+r.z*EXPSIZ ;
X   bgnline () ;
X      v3f ( vp ) ;
X      v3f ( v1 ) ;
X   endline ;
X   }
X   linewidth ( 1 ) ;
X}
X
X
Xbig_explosion ( v )
XVEC v ;
X{
X   int i ;
X   VEC3 v1, vp ;
X   VEC  r      ;
X
X   linewidth ( 4 ) ;
X   color ( RED ) ;
X
X   VECTOVEC3 ( vp, v ) ;
X   for ( i = 0 ; i < 30 ; i++ ) {
X   r.x = ( 2*drand48 () - 1 ) ;
X   r.y = ( 2*drand48 () - 1 ) ;
X   r.z = ( 2*drand48 () - 1 ) ;
X   NORM ( r ) ;
X   v1[0] = v.x+r.x*EXPSIZ ;
X   v1[1] = v.y+r.y*EXPSIZ ;
X   v1[2] = v.z+r.z*EXPSIZ ;
X   bgnline () ;
X      v3f ( vp ) ;
X      v3f ( v1 ) ;
X   endline ;
X   }
X   linewidth ( 1 ) ;
X}
X
X
Xcollided ( withwhat )
Xchar *withwhat ;
X{
X   char buff[100] ;
X   ringbell () ;
X   sprintf ( buff, "Hit by %s", withwhat ) ;
X   consmsg ( buff, RED ) ;
X}
X
X
Xgame_over ( msg )
Xchar *msg ;
X{
X   int   key, i ;
X   short val    ;
X
X   ortho2 ( (Coord)0, (Coord)xsiz, (Coord)vpst, (Coord)ysiz ) ;
X   cmov2 ( xsiz/2.0-strwidth("Game Over")/2.0, (ysiz-vpst)/3.0+vpst ) ;
X   color ( WHITE ) ;
X   charstr ( "Game Over" ) ;
X   gov = TRUE ;
X   consmsg ( msg, WHITE  ) ;
X   update_console_panels () ;
X   swapbuffers () ;
X   while ( TRUE )
X   if ( qtest () ) {
X      key = qread (&val) ;
X      if ( key == ESCKEY ) exit_game () ;
X      else if ( key == RKEY ) break ;
X   }
X}
X
X
X
Xrestart ()
X/* Restart the game */
X{
X   int i ;
X
X   init_stat () ;
X   for ( i = 0 ; i < MAXENEM ; i++ ) {
X      enemyinfo[i].destroyed = FALSE ;
X      enemyinfo[i].level     = WHITE ;
X      enemyinfo[i].level     = WHITE ;
X      if ( drand48 () > 0.9 )
X      /* Stationary enemy */
X         enemyinfo[i].speed = 0.0 ;
X      else
X         enemyinfo[i].speed = ENEMSPEED ;
X   }
X   popmatrix () ;
X   pushmatrix () ;
X   consmsg ( "RESTART", YELLOW ) ;
X}
X
X
X
X/*
X * Create a rotation matrix along the given axis by the given angle 
X * in degrees.  The axis is a set of direction cosines.
X * This is originally from Eric Haines' SPD package.
X */
Xlib_create_axis_rotate_matrix( mx, vaxis, angle )
XMatrix	mx ;
XVEC   	vaxis ;
Xfloat 	angle ;
X{
X   float cosine, one_minus_cosine, sine ;
X   int   i, j ;
X   VEC3  axis ;
X
X   angle *= M_PI/180.0 ;
X   VECTOVEC3 ( axis, vaxis ) ;
X
X   for ( j = 0 ; j < 4 ; j++ )
X   for ( i = 0 ; i < 4 ; i++ )
X      mx[j][i] = 0 ;
X
X   cosine = COS( angle ) ;
X   sine = SIN ( angle ) ;
X   one_minus_cosine = 1.0 - cosine ;
X
X   mx[0][0] = SQR(axis[X]) + (1.0 - SQR(axis[X])) * cosine ;
X   mx[0][1] = axis[X] * axis[Y] * one_minus_cosine + axis[Z] * sine ;
X   mx[0][2] = axis[X] * axis[Z] * one_minus_cosine - axis[Y] * sine ;
X
X   mx[1][0] = axis[X] * axis[Y] * one_minus_cosine - axis[Z] * sine ;
X   mx[1][1] = SQR(axis[Y]) + (1.0 - SQR(axis[Y])) * cosine ;
X   mx[1][2] = axis[Y] * axis[Z] * one_minus_cosine + axis[X] * sine ;
X
X   mx[2][0] = axis[X] * axis[Z] * one_minus_cosine + axis[Y] * sine ;
X   mx[2][1] = axis[Y] * axis[Z] * one_minus_cosine - axis[X] * sine ;
X   mx[2][2] = SQR(axis[Z]) + (1.0 - SQR(axis[Z])) * cosine ;
X
X   mx[3][3] = 1.0 ;
X}
X
X
Xexit_game ()
X{
X   system ( "/usr/NeWS/bin/keywarp 25 1" ) ;
X   exit ( 0 ) ;
X}
X
X
X
Xtarget_enemy ()
X/* Laser targeting */
X{
X   float  beam, dist, bbt, dr1[3], dr2[3] ;
X   VEC    trackerbeampos, beammov ;
X   int i ;
X
X   COPY_VEC ( trackerbeampos, shippos[1] ) ;
X   INIT_VEC ( beammov, shipz.x*beaminc, shipz.y*beaminc, shipz.z*beaminc ) ;
X   for ( beam = 0 ; beam <= (CUBEMAX-CUBEMIN) ; beam += beaminc ) {
X      ADD_VEC ( trackerbeampos, beammov ) ;
X      bbt = beam*tanfovyrad ;
X      for ( i = 0 ; i < MAXENEM ; i++ ) {
X         if ( enemyinfo[i].destroyed == FALSE ) {
X            dist = DIST ( trackerbeampos, enemyinfo[i].pos ) ;
X            if ( dist < bbt ) {
X               prevstate = enemyinfo[i].level ;
X               enemyinfo[i].level = CYAN ;
X               consmsg ( "Laser Locked ON", GREEN ) ;
X               enemynum = i ;
X               trackertoggle = ON ;
X               return ;
X            }
X         }
X      }
X   }
X   consmsg ( "Laser NOT Locked ON", YELLOW ) ;
X}
X
SHAR_EOF
chmod 0666 vr1.c || echo "restore of vr1.c fails"
exit 0
Newsgroups: comp.sys.sgi