/* Adapted to write Targa 24 .TGA files (24 bits/pixel) */
/* based on filename being .TGA or not, Aaron A. Collins */

#include "header.h"

/**********************************************************

               Test routine - unused

 **********************************************************/

#ifdef TESTS

Tree_Walker(obj,num)
  OBJ_PTR obj;
  int num;
{
  int x;

  for (x=0; x<num; x++) printf(" ");
  printf("%d\n",obj->type);

  if (obj->child!=NULL)
    Tree_Walker(obj->child,num+2);

  if (obj->nextobj!=NULL)
    Tree_Walker(obj->nextobj,num);
}

#endif


/**********************************************************

    Initialize some observer data, like up and right
    vectors, focal length, etc.

 **********************************************************/

void Setup_Observer(void) {

  if (THEWORLD.observer==NULL) Error(NO_OBSERVER,1);

  Normalize(&((THEWORLD.observer)->vect1));
  VectEQ(&(THEWORLD.obsup),&((THEWORLD.observer)->vect2));

  CrossProd(&(THEWORLD.obsright),             /* right = up x dir */
            &(THEWORLD.obsup),
            &((THEWORLD.observer)->vect1));

  CrossProd(&(THEWORLD.obsup),                /* up = dir x right */
            &((THEWORLD.observer)->vect1),
            &(THEWORLD.obsright));

  Normalize(&(THEWORLD.obsup));
  Normalize(&(THEWORLD.obsright));

}


/**********************************************************

         Initialize the world and assign defaults

 **********************************************************/

void init_world(void) {                     /* make a universe */
  THEWORLD.stack      =
  THEWORLD.observer   =
  THEWORLD.instances  =
  THEWORLD.sky        =
  THEWORLD.lamps      = NULL;
  THEWORLD.patlist    = NULL;
  THEWORLD.outfile    = NULL;
  THEWORLD.objcount   = 0;
  THEWORLD.lampcount  = 0;
  THEWORLD.flength    = 50;

  THEWORLD.skycolor_zenith.r =
  THEWORLD.skycolor_zenith.b =
  THEWORLD.skycolor_zenith.g =
  THEWORLD.skycolor_horiz.r  =
  THEWORLD.skycolor_horiz.g  =
  THEWORLD.skycolor_horiz.b  = 0;

  THEWORLD.ray_intersects  =
  THEWORLD.pixels_hit      =
  THEWORLD.primary_traced  =
  THEWORLD.to_lamp         =
  THEWORLD.refl_trans      =
  THEWORLD.bbox_intersects =
  THEWORLD.pattern_matches =
  THEWORLD.intersect_tests = 0;

  THEWORLD.globindex = 1.00;   /* global index of refraction */

  def.cinfo.trans.r  =         /* default transmittion */
  def.cinfo.trans.g  =
  def.cinfo.trans.b  = 0;

  def.cinfo.mirror.r =         /* default reflection */
  def.cinfo.mirror.g =
  def.cinfo.mirror.b = 0;

  def.cinfo.amb.r    =         /* default ambiant light */
  def.cinfo.amb.g    =
  def.cinfo.amb.b    = 25;

  def.cinfo.diff.r   =         /* default diffuse light */
  def.cinfo.diff.g   =
  def.cinfo.diff.b   = CNUM;

  def.cinfo.density.x=
  def.cinfo.density.y=
  def.cinfo.density.z= .01;    /* default glass density */

  def.cinfo.fuzz     = 0;
  def.cinfo.index    = CNUM;
  def.cinfo.dither   = 3;
  def.cinfo.reflect  = 0;
  def.cinfo.sreflect = 10;

  def.shadow        = TRUE;    /* shadows */
  def.vlamp         = TRUE;    /* visible lamps */
  def.int_x         =          /* no interpolation */
  def.int_y         = 1;
  def.threshold     = .1;      /* threshold at 10 percent */
  def.ithreshold    = def.threshold * CNUM;

# ifdef AMIGA
    def.x_res       = 320;     /* AMIGA 4096 color mode */
    def.y_res       = 400;
    def.aspect      = .56;
# endif

# ifdef UNIX
    def.x_res       = 720;     /* UNIX medium sized window (768) */
    def.y_res       = 640;
    def.aspect      = .89;
# endif

# ifdef UNIX_HIRES
    def.x_res       = 1280;    /* HP hi-res workstation */
    def.y_res       = 1024;
    def.aspect      = .89;
# endif

# ifdef MAC_II
    def.x_res       = 640;     /* MAC II full screen */
    def.y_res       = 480;
    def.aspect      = 1.0;     /* is this right? */
# endif

# ifdef ATARI_ST
    def.x_res       = 640;     /* ATARI ST full screen */
    def.y_res       = 200;     /* don't know aspect */
# endif

# ifdef IBM_OR_CLONE
    def.x_res	    = 640;	/* IBM Sort-Of-Super-VGA Res */
    def.y_res	    = 400;
    def.aspect	    = .60;	/* right on Multisync 3-D, 1/2 of calc'd */
# endif

}


/**********************************************************

     Call other stuff to load world and generate image

     Changed 12 Mar 88 to add command line arguments.

 **********************************************************/

main(argc,argv)
  int argc; char *argv[];
{

  printf("\nQuick Ray Trace: Copyright 1988, 1989 Steve Koren\nVersion 1.6\n");

  printf("IBM conversion w/ TARGA output by Aaron A. Collins\n\n");

  init_world();

  if (!LoadWorld()) Error(SYNTAX_ERROR,2);

  Parse_CL_Args(argc,argv);

  Make_Bbox(THEWORLD.stack);     /* make bboxes */
  Do_Precomp(THEWORLD.stack);    /* precompute stuff */

  fclose(stdin);

  Setup_Observer();

  Open_File();
  Screen_Trace();
  Close_File();

  World_Stats();
/*  fclose(stdout); */
  return(0);
}


/**********************************************************

  Added 12 Mar 88 to parse command line arguments.

  Command line arguments are optional as follows:

   -xres int -yres int -aspect double -foclen double

  The command line arguments take precidence over the
  DEFAULT() command values.

 **********************************************************/

void Parse_CL_Args(ac,av)
  int ac;
  char *av[];
{
  int x, found;
/* int atoi(); */
  
  for (x=1; x<ac; x++) {       /* parse command line args */
    found = FALSE;

    if (strcmp(av[x],"-xres")==0) {

      if (++x >= ac)
        Error(TOO_FEW_PARMS,3);

      if ((def.x_res = atoi(av[x])) <= 0)
        Error(LESS_THAN_ZERO,4);

      found        = TRUE;
    }

    if (strcmp(av[x],"-yres")==0) {

      if (++x >= ac)
        Error(TOO_FEW_PARMS,5);

      if ((def.y_res = atoi(av[x])) <= 0)
        Error(LESS_THAN_ZERO,6);

      found        = TRUE;
    }

    if (strcmp(av[x],"-aspect")==0) {

      if (++x >= ac)
        Error(TOO_FEW_PARMS,7);

      if ((def.aspect = atof(av[x])) <= 0)
        Error(LESS_THAN_ZERO,8);

      found        = TRUE;
    }

    if (strcmp(av[x],"-foclen")==0) {

      if (++x >= ac)
        Error(TOO_FEW_PARMS,9);

      if ((THEWORLD.flength = atoi(av[x])) <=0)
        Error(LESS_THAN_ZERO,010);

      found        = TRUE;
    }

    if (!found) {
      printf("Usage: %s [-xres n] [-yres n] [-aspect n] [-foclen n]\n\n",
             av[0]);
      Error(ILLEGAL_OPTION,011);
    }

  }
}
