#include <math.h>
#include <malloc.h>
#include <stdlib.h>
#include <direct.h>
#include <string.h>
#include <conio.h>
#include <i86.h>

#include <pr.h>
#include <prgui.h>


typedef struct
{
  PR_CAMERA *basecam;
  PR_CAMERA *leftcam;
  PR_CAMERA *rightcam;

  PR_REAL eye_distance;
} PR_STEREOCAMERA;
PR_STEREOCAMERA *stereocam;
PR_REAL stereo_distance = 13;
PR_REAL focal_distance = 1225;

#define LEFT_EYE 0
#define RIGHT_EYE 1


PR_DWORD     device;
PR_DWORD     current_mode;          /* Current video mode */
PR_DWORD     vwidth;                /* Viewport size */
PR_DWORD     vheight;
PR_DWORD     view_opened = 0;       /* 0 for first initialization */
PR_VIEWPORT  viewport;              /* Our viewport structure */
PR_LIGHTLIST userlights;            /* We only use 1 light */
PR_CAMERA *  newcam;                /* One camera */


PR_REAL speeddiv = 350;             /* Speed divisor */
PR_REAL dx, dy, dz;                 /* Delta rotation */
PR_REAL scale;                  
PR_DWORD force_vga = 0;

PR_OBJECT *test;                    /* The shape loaded */
PR_ENTITY *obj1;                    /* A single entity of the shape */


/* Frame Rate Control  */
PR_DWORD ticks;                     /* Total number of ticks passed */

PR_DWORD kf_delay = 0;
PR_DWORD kf_ticks = 0;





PR_STEREOCAMERA *PR_AllocStereoCamera (void)
/* -----------------------------------------------------------------------
   Function:   PR_AllocStereoCamera
   Purpose:    Allocates space for a new stereo camera 
   Parameters: None
   Return:     Pointer to the new camera structure
   ----------------------------------------------------------------------- */
{
PR_STEREOCAMERA *cam;

  cam = malloc (sizeof (PR_STEREOCAMERA));

  if (cam != NULL)
    {
     cam->leftcam = PR_AllocCamera ();
     cam->rightcam = PR_AllocCamera ();

     if (cam->leftcam != NULL)
       PR_InitializeCamera (cam->leftcam);
     if (cam->rightcam != NULL)
       PR_InitializeCamera (cam->rightcam);
    }

  cam->eye_distance = 150;  /* some value.. depends on scale of scene */

  return (cam);
}


void PR_SetStereoCameraBase (PR_STEREOCAMERA *cam, PR_CAMERA *basecam)
/* -----------------------------------------------------------------------
   Function:   PR_SetStereoCameraBase
   Purpose:    Sets the base camera pointer
   Parameters: cam - Pointer to the stereo camera
               basecam - Pointer to the player's camera (origin)
   Return:     None
   ----------------------------------------------------------------------- */
{
  cam->basecam = basecam;
}


void PR_SetStereoCameraEyeDistance (PR_STEREOCAMERA *cam, PR_REAL distance)
/* -----------------------------------------------------------------------
   Function:   PR_SetStereoCameraEyeDistance
   Purpose:    Sets the distance between left and right cameras
   Parameters: cam - Pointer to the stereo camera
               distance - Distance between eyes
   Return:     None
   ----------------------------------------------------------------------- */
{
  cam->eye_distance = distance;
}


void PR_SetStereoCameraFocalDistance (PR_STEREOCAMERA *cam, PR_REAL distance)
/* -----------------------------------------------------------------------
   Function:   PR_SetStereoCameraFocalDistance
   Purpose:    Sets the distance between the eye and the focal point
   Parameters: cam - Pointer to the stereo camera
               distance - Distance between eyes
   Return:     None
   ----------------------------------------------------------------------- */
{
  cam->basecam->distance = distance;
}


void PR_MakeRotationViewMatrix (PR_CAMERA *cam)
/* -----------------------------------------------------------------------
   Function:   PR_MakeRotationViewMatrix
   Purpose:    Makes a matrix for a given camera which will transform
               vertices from world space into view space.
   Parameters: cam - Pointer to the camera
   Return:     None
   ----------------------------------------------------------------------- */
{
PR_POINT tmp;
PR_MATRIX mz, mt;
PR_REAL radtilt;
PR_REAL costilt;
PR_REAL sintilt;
PR_POINT yaxis, xaxis;


  if (!(cam->flags & CAMFLAG_FREEMATRIX))
    {
     PR_VecSubtract (tmp, cam->dest, cam->source);
     PR_Normalize (&tmp);

     if (!tmp.x && !tmp.z)
       {
        yaxis.x = -tmp.y;
        yaxis.y = 0.0;
        yaxis.z = 0.0;
       }
     else
       {
        yaxis.x = cam->up.x;
        yaxis.y = cam->up.y;
        yaxis.z = cam->up.z;
       }

     PR_VecCrossProduct (xaxis, yaxis, tmp);
     PR_Normalize (&xaxis);

     PR_VecCrossProduct (yaxis, xaxis, tmp);
     PR_Normalize (&yaxis);


     PR_MatrixClear (PR_ViewMatrix);
     PR_ViewMatrix[0] = xaxis.x;
     PR_ViewMatrix[4] = xaxis.y;
     PR_ViewMatrix[8] = xaxis.z;
     PR_ViewMatrix[1] = -yaxis.x;
     PR_ViewMatrix[5] = -yaxis.y;
     PR_ViewMatrix[9] = -yaxis.z;
     PR_ViewMatrix[2] = tmp.x;
     PR_ViewMatrix[6] = tmp.y;
     PR_ViewMatrix[10] = tmp.z;


     /* Rotate by tilt */
     memcpy (mt, PR_ViewMatrix, sizeof (PR_MATRIX));
     PR_MatrixIdentity (mz);

     radtilt = RADIANS (cam->tilt_angle);
     sintilt = (float)sin (radtilt);
     costilt = (float)cos (radtilt);

     mz[0] = costilt; mz[4] = -sintilt;
     mz[1] = sintilt; mz[5] =  costilt;
     PR_MatrixMultiply (mz, mt, PR_ViewMatrix);


     PR_ViewMatrix[12] = cam->source.x;
     PR_ViewMatrix[13] = cam->source.y;
     PR_ViewMatrix[14] = cam->source.z;
    }
}






void PR_SetActiveStereoCamera (PR_STEREOCAMERA *cam)
/* -----------------------------------------------------------------------
   Function:   PR_SetActiveStereoCamera
   Purpose:    Prepares the left and right cameras for viewing
   Parameters: cam - Pointer to the stereo camera
   Return:     None
   ----------------------------------------------------------------------- */
{
  /* Make the left and right cameras use the same viewing mode
     (aim_target or angle_based) */
  cam->leftcam->flags = cam->basecam->flags;
  cam->rightcam->flags = cam->basecam->flags;

  /* Make the rotation matrix for the base camera */
  PR_MakeRotationViewMatrix (cam->basecam);

  /* Find the left and right eye locations by rotating
     their vectors around the base camera's location */

  /* Left camera */
  tvector[0] = cam->eye_distance;
  tvector[1] = 0;
  tvector[2] = 0;
  PR_Transform (PR_ViewMatrix);
  PR_PositionCameraSource (cam->leftcam, tvector[0], tvector[1], tvector[2]);

  /* Right camera */
  tvector[0] = -cam->eye_distance;
  tvector[1] = 0;
  tvector[2] = 0;
  PR_Transform (PR_ViewMatrix);
  PR_PositionCameraSource (cam->rightcam, tvector[0], tvector[1], tvector[2]);

  /* Now we have the left and right camera source positions. */
  /* Set the target the same place as the base camera
     (non parallel cameras) */
  PR_PositionCameraTarget (cam->leftcam,
    cam->basecam->dest.x, cam->basecam->dest.y, cam->basecam->dest.z);
  PR_PositionCameraTarget (cam->rightcam,
    cam->basecam->dest.x, cam->basecam->dest.y, cam->basecam->dest.z);
}



void PR_StartLeftCamera (void)
{
  abuf += WGT_SYS.xres;
  WGT_SYS.xres *= 2;
}

void PR_EndLeftCamera (void)
{
  WGT_SYS.xres /= 2;
  abuf -= WGT_SYS.xres;
}

void PR_StartRightCamera (void)
{
  WGT_SYS.xres *= 2;
}

void PR_EndRightCamera (void)
{
  WGT_SYS.xres /= 2;
}



int PR_Detect3DMAX (void)
{
union REGS maxreg;

  maxreg.w.ax = 0x4ED0;
  int386 (0x10, &maxreg, &maxreg);

  if (maxreg.w.dx == 0x3344)
    return 1;

  return 0;
}


int PR_3DMAX_On (void)
{
union REGS maxreg;

  maxreg.w.ax = 0x4FD0;
  maxreg.w.bx = 0x3D03;
  int386 (0x10, &maxreg, &maxreg);


  return (maxreg.w.ax);
}


int PR_3DMAX_InterlaceOn (void)
{
union REGS maxreg;

  maxreg.w.ax = 0x4FD0;
  maxreg.w.bx = 0x3D01;
  int386 (0x10, &maxreg, &maxreg);


  return (maxreg.w.ax);
}



int PR_3DMAX_Off (void)
{
union REGS maxreg;

  maxreg.w.ax = 0x4FD0;
  maxreg.w.bx = 0x3D02;
  int386 (0x10, &maxreg, &maxreg);

  return (maxreg.w.ax);
}



/* ---------------------------------------------------------------------- */
/* Timer Interrupt */
/* ---------------------------------------------------------------------- */
void timerproc (void)
{
  ticks++;
  if (ticks > kf_delay)
    kf_ticks++;
}                




/* ---------------------------------------------------------------------- */
/* Cycles through 3 video modes (320x200, 640x480, 800x600) */
/* ---------------------------------------------------------------------- */
PR_DWORD SetVideoMode (void)
{
  /* Cycle through all the modes */

  do {
   current_mode++;
   if (PR_VideoModes[current_mode].mode_number == -1)
     current_mode = 0;
   } while ((PR_VideoModes[current_mode].pages <= 1) && (force_vga == 0));

  vwidth = PR_VideoModes[current_mode].width;
  vheight = PR_VideoModes[current_mode].height;

  PR_SetMode (vwidth, vheight, 60);

  if (view_opened)
    PR_CloseViewport (&viewport);

  PR_OpenViewport (&viewport, 0, 0, vwidth-1, (vheight-1)/2, VIEW_PLAIN);

  PR_SetViewport (&viewport);
  PRGFX_Clip (active_viewport.topx,
              active_viewport.topy,
              active_viewport.bottomx,
              active_viewport.bottomy);
  view_opened = 1;

  wsetpalette (0, 255, global_palette);

  PR_3DMAX_On ();
  PR_3DMAX_InterlaceOn ();

  return (1);
}




/* ---------------------------------------------------------------------- */
/* Move the camera and rotate the object based on the user input */
/* ---------------------------------------------------------------------- */
void UserInput (void)
{
PR_DWORD dummy = 0;

  PR_ReadInput ();              

  /* This uses the inspect model.  Below we have some additional input
     controls */

  PR_CameraDirection (newcam);
  PR_DollyCamera (newcam, currentspeed);

  /* Object Rotation */
  if (mouse.but == 1)
    {
     dx = (PR_REAL)(mouse.my - 100) / 5;
     dy = (PR_REAL)(mouse.mx - 160) / 5;
     msetxy (160, 100);
    }
  else if (mouse.but == 2)
    {
     dz = (PR_REAL)(mouse.mx - 160) / 5;
     msetxy (160, 100);
    }

  msetxy (160, 100);
  mouse.mx = 160;
  mouse.my = 100;

  /* Keyboard input */
  if (kbdon[KEY_F1])
    {
     if (device != DEVICE_3DFX)
       while (!SetVideoMode ());
     while (kbdon[KEY_F1]) 
       { 
        dummy++;
       }           /* Wait for user to release key */
    }


  if (kbdon[KEY_LBRACE])
    stereo_distance += 0.1;

  if (kbdon[KEY_RBRACE])
    stereo_distance -= 0.1;

  if (kbdon[KEY_O])
    focal_distance += speeddiv;

  if (kbdon[KEY_P])
    focal_distance -= speeddiv;

  /* Change movement speed */
  if (kbdon[KEY_GREY_MINUS])
    {
     speeddiv += 5;
     TRANSLATE_SPEED    = test->bbox.radius / (speeddiv*10);
     MAX_TRANSLATE_SPEED= test->bbox.radius / speeddiv;
     TRANSLATE_DRAG     = test->bbox.radius / (speeddiv*5);
    }
  else if (kbdon[KEY_GREY_PLUS])
    {
     speeddiv -= 5;
     if (speeddiv < 2)
       speeddiv = 1;
     TRANSLATE_SPEED    = test->bbox.radius / (speeddiv*10);
     MAX_TRANSLATE_SPEED= test->bbox.radius / speeddiv;
     TRANSLATE_DRAG     = test->bbox.radius / (speeddiv*5);
    }
}



/* ---------------------------------------------------------------------- */
/* Initialize Power Render and allocate room for data */
/* ---------------------------------------------------------------------- */
void InitializeProgram (void)
{
  PR_AllocMaterials (512);
  PR_AllocTextures (256);
  PR_AllocShadeTables (32);
}



/* ---------------------------------------------------------------------- */
/* Make one light which will follow the camera */
/* ---------------------------------------------------------------------- */
void InitializeLights (void)
{
  /* Initialize the lights */
  PR_AllocLights (&userlights, 1);      /* User lights */
  PR_AllocLights (&scenelights, 1);     /* Master scene light list */

  PR_SetLightPosition (&userlights, 0, 0, 0, 10000);
  /* Doesn't matter because we set it to the camera location every frame */

  PR_SetLightOn (&userlights, 0);
  PR_SetLightType (&userlights, 0, DIRECTIONAL_LIGHT);
  PR_SetLightStrength (&userlights, 0, 1.0);
  PR_SetLightColor (&userlights, 0, 1.0, 1.0, 1.0);

  userlights.NumLights = 1;     /* This sets how many lights are actually used */
}



void Fix_EnvMap (PR_OBJECT *obj)
{
PR_SEGMENT *segptr;
PR_MATERIAL *matptr;
PR_FACE *faceptr;
PR_DWORD seg, face;
  
  for (seg = 0; seg < obj->num_segments; seg++)
    { /* For every segment */

     segptr = &obj->segment_list[seg];
     segptr->flags &= ~FLAG_NORMALS;    /* Clear out the normals flag */

     for (face = 0; face < segptr->num_faces; face++)
       { /* For every face */

        faceptr = &segptr->face_list[face];
        matptr = &PR_ObjectMaterialList[faceptr->material];


        if (matptr->environment_map)
          segptr->flags |= FLAG_NORMALS;

        matptr = &PR_ObjectMaterialList[faceptr->backmaterial];
        if (matptr->environment_map)
          segptr->flags |= FLAG_NORMALS;
       }
    }

}



/* ---------------------------------------------------------------------- */
/* Loads a 3DS LWO, or PRO file */
/* ---------------------------------------------------------------------- */
void LoadFile (char *filename, PR_DWORD loadmode)
{
char path[_MAX_PATH];
char drive[_MAX_DRIVE],dir[_MAX_DIR],name[_MAX_NAME],ext[_MAX_EXT];

  strupr (filename);
  _makepath (path, drive, dir, filename,"");
  _splitpath (path, drive, dir, name, ext);

  if (!strcmp(ext,".3DS"))
    {
     PR_BaseMaterialNumber = 0;
     test = PR_Load3DS (filename, scale, loadmode);

     PR_Settings.FrontToBack = 0;
     if (test == NULL)
       {
        PR_FatalError ("Could not open the 3DS file", "PRVIEW");
       }

     PR_CreateMaterialPalette ();
     wsetpalette (0, 255, global_palette);
     PR_SetObjectFaceFlags (test, FFLAG_FRONT_VISIBLE, FLAG_SET);
     PR_InitializeFaceNormals (test);
     PR_InitializeVertexNormals (test);
     Fix_EnvMap (test);
    }
  else if (!strcmp(ext,".LWO"))
    {
     PR_BaseMaterialNumber = 0;
     test = PR_LoadLWO (filename, scale, loadmode);

     PR_Settings.FrontToBack = 0;
     if (test == NULL)
       {
        PR_FatalError ("Could not open the LWO file", "PRVIEW");
       }

     PR_CreateMaterialPalette ();
     wsetpalette (0, 255, global_palette);
     PR_InitializeFaceNormals (test);
     PR_InitializeVertexNormals (test);
     Fix_EnvMap (test);
    }
  else if (!strcmp(ext,".PRO"))
    {
     test = (PR_OBJECT *)PR_LoadPRO (filename, LOAD_NORMAL);

     PR_Settings.FrontToBack = 0;
     if (test == NULL)
       {
        PR_FatalError ("Could not open the PRO file", "PRVIEW");
       }
     
     wsetpalette (0, 255, global_palette);
    }
   else
     {
      PR_FatalError ("Unknown file format", "PRVIEW");
     }

  obj1 = PR_CreateEntity (test, "OBJ1");
  PR_ScaleEntityAbs (obj1, 1, 1, 1);
}




void InitializeDevices (void)
{
  if ((device == DEVICE_SVGA) || (device == DEVICE_ANY))
    device = PR_DetectSVGA ();   /* Attempt to find the device */

  if ((device == DEVICE_VGA) || (device == DEVICE_ANY))
    device = PR_DetectVGA ();   /* Attempt to find the device */

  if (device == DEVICE_SVGA)
    {
     PR_InitializeSVGA ();
     atexit (PR_ShutdownSVGA);
    }
  else if (device == DEVICE_VGA)
    {
     PR_InitializeVGA ();
    }
}



void DrawScene (PR_STEREOCAMERA *cam, PR_DWORD eyenum)
{
  PR_OpenScreen (PR_BACKBUFFER);
  PR_NewFrame ();                         /* Begin a new frame */

  PR_SetLightPosition (&userlights, 0,
                       newcam->source.x,
                       newcam->source.y,
                       newcam->source.z);
  PR_AddLightsToScene (&userlights);

  if (eyenum == LEFT_EYE)
    PR_SetActiveCamera (cam->leftcam);
  else
    PR_SetActiveCamera (cam->rightcam);

  PRGFX_Clip (active_viewport.topx,
              active_viewport.topy,
              active_viewport.bottomx,
              active_viewport.bottomy);

  if (eyenum == LEFT_EYE)
    PR_StartLeftCamera ();
  else
    PR_StartRightCamera ();


  /* Render all the objects */

  PR_TransformEntity (obj1);
  PR_RenderEntity (obj1);

  PR_RenderFrame ();


  if (eyenum == LEFT_EYE)
    PR_EndLeftCamera ();
  else
    PR_EndRightCamera ();
}





/* ---------------------------------------------------------------------- */
/* Main program */
/* ---------------------------------------------------------------------- */
void main (int argc, char *argv[])
{
PR_DWORD argnum;
PR_DWORD loadmode = 0;
PR_DWORD sky_color;
PR_DWORD flip_delay = 0;
PR_DWORD frame = 1;

  scale = 1;

  device = DEVICE_VGA;
  loadmode = LOAD_IGNORE_TEXTURES;

  PRGUI_InitPath (argv[0]);
  PRGUI_SetUserPath ();

  printf ("PRVIEW Utility    version ");
  printf (PR_VERSION_NUMBER);
  printf ("\nCopyright 1997 Egerter Software\n\n");

  if (argc < 2)
    {
	 PR_FatalError ("Usage: \n"
             "PRVIEW filename.[PRO/3DS/LWO] [options]\n"
             "\n"
             "Options:\n"
             "-s scale      Changes scaling factor\n"
             "-t ext        Imports textures from 3DS, using extension\n"
             "              ext = [PCX, 3DF, IFF, BLK, PAK]\n"
             "-v            Uses standard 320x200 VGA mode instead of VESA\n", "PRVIEW");
    }



  argnum = 2;
  while (argnum < argc)
    {
     if (!strcmp (argv[argnum], "-s"))
       if (argc > argnum)
         {
          scale = atof (argv[argnum+1]);
          printf ("Scaling Factor: %f\n", scale);
          argnum++;
         }

     if (!strcmp (argv[argnum], "-e"))
       if (argc > argnum)
         {
          stereo_distance = atof (argv[argnum+1]);
          printf ("Eye Distance: %f\n", stereo_distance);
          argnum++;
         }

     if (!strcmp (argv[argnum], "-f"))
       if (argc > argnum)
         {
          focal_distance = atof (argv[argnum+1]);
          printf ("Focal Distance: %f\n", focal_distance);
          argnum++;
         }

     if (!strcmp (argv[argnum], "-v"))
       if (argc > argnum)
         {
          force_vga = 1;
          argnum++;
         }

     if (!strcmp (argv[argnum], "-t"))
       if (argc > argnum)
         {
          strcpy (L3DS_TextureExtension, argv[argnum+1]);
          if (strcmp (L3DS_TextureExtension, "3DF") == 0)
            device = DEVICE_3DFX;
          printf ("Textures Enabled\nTexture Extension: %s\n", L3DS_TextureExtension);
          loadmode = LOAD_NORMAL;
          argnum++;
         }

     argnum++;
    }

 
  while (kbhit ())                       /* Clear the keyboard buffer */
    getch ();


  if (!PR_Detect3DMAX ())
    {
     printf ("3DMAX not found, or 3DBIOS not loaded");
     exit (1);
    }



  if (force_vga)
    device = DEVICE_VGA;
  else
    device = DEVICE_SVGA;


  PRGUI_GoStartPath ();
  PR_Initialize (7500);
  
  vga256 ();
  minit ();


  InitializeDevices ();
  InitializeProgram ();
  InitializeLights ();


  /* Initialize the graphics mode */
  current_mode = -1;
  while (!SetVideoMode ());

  if (PR_VideoModes[current_mode].pages > 1)
    flip_delay = 0;

  PR_SetTextureFormat (TEXTURE_XRAY);

  PR_Settings.HardwareMipmaps = MIPMAP_ALL_LEVELS;
  
  PRGUI_GoUserPath ();
  LoadFile (argv[1], loadmode);
  
  /* Get colors closest to white and black */
  PR_BackgroundColor = PR_ClosestColor (24, 24, 24, global_palette);
  
  /* Initialize the camera */
  newcam = PR_AllocCamera ();
  PR_InitializeCamera (newcam);
  PR_PositionCameraSource (newcam, 0, 0, test->bbox.radius * 2);
//  PR_PositionCameraTarget (newcam, obj1->segment_orientation[7].location.x,
//                                   obj1->segment_orientation[7].location.y - 10,
//                                   obj1->segment_orientation[7].location.z);

  newcam->rotation.y = 0;
  PR_SetCameraMode (newcam, CAMFLAG_ANGLE_BASED);
//  PR_SetCameraMode (newcam, CAMFLAG_AIM_TARGET);

  stereocam = PR_AllocStereoCamera ();
  PR_SetStereoCameraBase (stereocam, newcam);
  PR_SetStereoCameraEyeDistance (stereocam, stereo_distance);
  PR_SetStereoCameraFocalDistance (stereocam, focal_distance);

  /* Initialize the input devices */
  installkbd ();
  winittimer ();
  wstarttimer (timerproc, TICKS(60));
  msetxy (160, 100);

  PR_SetInputDevice (INPUT_MOUSE);
  PR_SetInputModel (MODEL_INSPECT);
  PR_SetInputEntity (NO_ENTITY, NO_SEGMENT);
  PR_SetInputCamera (newcam);

  TRANSLATE_SPEED    = test->bbox.radius / (speeddiv*10);
  MAX_TRANSLATE_SPEED= test->bbox.radius / speeddiv;
  TRANSLATE_DRAG     = test->bbox.radius / (speeddiv*5);


  /* Number of perspective texture subdivisions */
  PR_SetPerspectiveDivisions (TEXTURE_DIVISION_16);

  PR_OpenScreen (PR_BACKBUFFER);

  PRGFX_SetTextForeground (PRGFX_MakeColor (63,63,63));
  PRGFX_SetTextBackground (PRGFX_MakeColor (32,32,32));
  PRGFX_SetTextTransparent (TEXTFGBG);

  sky_color = PRGFX_MakeColor (0, 0, 0);

  PR_3DMAX_On ();
  PR_3DMAX_InterlaceOn ();

  /* main program loop */
  while (!kbdon[KEY_ESC])
    {
     UserInput ();
     PR_SetStereoCameraEyeDistance (stereocam, stereo_distance);
     PR_SetStereoCameraFocalDistance (stereocam, focal_distance);

     PRGFX_SetColor (sky_color);
     PR_OpenScreen (PR_BACKBUFFER);
     PRGFX_ClearScreen ();

     PR_RotateEntity (obj1, dx, dy, dz);

     if (obj1->shape->num_frames > 0)
       {
        frame++;
        kf_ticks = 0;
        if (frame >= obj1->shape->num_frames)
          frame = 0;
        PR_AnimateEntity (obj1, frame);
       }

     PR_SetActiveStereoCamera (stereocam);
     DrawScene (stereocam, LEFT_EYE);
     DrawScene (stereocam, RIGHT_EYE);

     PRGUI_printf (10, 10, "Eye Dist: %f", stereo_distance);
     PRGUI_printf (10, 20, "Focal Dist: %f", focal_distance);

     PRGFX_Clip (0, 0, vwidth-1, vheight-1);
     PR_Flip (flip_delay);
    }

  uninstallkbd ();
  mdeinit ();

  wstoptimer ();
  wdonetimer ();

  PR_3DMAX_Off ();

  wsetmode (3);
  printf ("Eye Distance: %f\n", stereo_distance);
  printf ("Focal Distance: %f\n", focal_distance);
  getch ();
}




