Only in dsw2: DSWCHANGES
diff -C 2 -b orig/express.c dsw2/express.c
*** orig/express.c	Mon Aug 31 15:33:20 1998
--- dsw2/express.c	Sun Nov 29 02:03:08 1998
***************
*** 40,43 ****
--- 40,53 ----
  
  
+ /* NOTE: find the proper constant in math.h - too lazy for now */
+ #define RAD_PER_DEG  (3.1415926/180.0)
+ #define DEG_PER_RAD  (180.0/3.1415926)
+ 
+ 
+ /* NOTE: find the proper constant in math.h - too lazy for now */
+ #define RAD_PER_DEG  (3.1415926/180.0)
+ #define DEG_PER_RAD  (180.0/3.1415926)
+ 
+ 
  /*****************************************************************************
  * Local preprocessor defines
***************
*** 256,259 ****
--- 266,277 ----
              break;
  
+           case ACOSD_TOKEN:
+             Val = DEG_PER_RAD*acos(Parse_Float_Param());
+             break;
+ 
+           case ACOSD_TOKEN:
+             Val = DEG_PER_RAD*acos(Parse_Float_Param());
+             break;
+ 
            case VAL_TOKEN:
              GET (LEFT_PAREN_TOKEN);
***************
*** 276,279 ****
--- 294,305 ----
              break;
  
+           case ASIND_TOKEN:
+             Val = DEG_PER_RAD*asin(Parse_Float_Param());
+             break;
+ 
+           case ASIND_TOKEN:
+             Val = DEG_PER_RAD*asin(Parse_Float_Param());
+             break;
+ 
            case ATAN2_TOKEN:
              Parse_Float_Param2(&Val,&Val2);
***************
*** 288,291 ****
--- 314,341 ----
              break;
  
+           case ATAN2D_TOKEN:
+             Parse_Float_Param2(&Val,&Val2);
+             if (ftrue(Val) || ftrue(Val2))
+             {
+                Val=DEG_PER_RAD*atan2(Val,Val2);
+             }
+             else
+             {
+                Error("Domain error in atan2\n");
+             }
+             break;
+ 
+           case ATAN2D_TOKEN:
+             Parse_Float_Param2(&Val,&Val2);
+             if (ftrue(Val) || ftrue(Val2))
+             {
+                Val=DEG_PER_RAD*atan2(Val,Val2);
+             }
+             else
+             {
+                Error("Domain error in atan2\n");
+             }
+             break;
+ 
            case CEIL_TOKEN:
              Val = ceil(Parse_Float_Param());
***************
*** 300,303 ****
--- 350,361 ----
              break;
  
+           case COSD_TOKEN:
+             Val = cos(RAD_PER_DEG*Parse_Float_Param());
+             break;
+ 
+           case COSD_TOKEN:
+             Val = cos(RAD_PER_DEG*Parse_Float_Param());
+             break;
+ 
            case DEFINED_TOKEN:
              Val = Parse_Ifdef_Param();
***************
*** 386,389 ****
--- 444,457 ----
              break;
  
+           case SIND_TOKEN:
+             Val = sin(RAD_PER_DEG*Parse_Float_Param());
+             break;
+ 
+ 
+           case SIND_TOKEN:
+             Val = sin(RAD_PER_DEG*Parse_Float_Param());
+             break;
+ 
+ 
            case SQRT_TOKEN:
              Val = Parse_Float_Param();
***************
*** 421,424 ****
--- 489,500 ----
              break;
  
+           case TAND_TOKEN:
+             Val = tan(RAD_PER_DEG*Parse_Float_Param());
+             break;
+ 
+           case TAND_TOKEN:
+             Val = tan(RAD_PER_DEG*Parse_Float_Param());
+             break;
+ 
            case VDOT_TOKEN:
              Parse_Vector_Param2(Vect,Vect2);
Only in dsw2: express.c.orig
diff -C 2 -b orig/frame.h dsw2/frame.h
*** orig/frame.h	Sat Oct  3 01:59:33 1998
--- dsw2/frame.h	Sat Nov 28 20:44:44 1998
***************
*** 727,730 ****
--- 727,731 ----
  #define TRANSM 4
  
+ 
  /* Macros to manipulate scalars, vectors, and colors. */
  
***************
*** 940,944 ****
    long References;
    int  hollow;
!   SNGL IOR;
    SNGL Caustics, Old_Refract;
    SNGL Fade_Distance, Fade_Power;
--- 941,946 ----
    long References;
    int  hollow;
!   SNGL IOR, Dispersion;
!   int  Disp_NElems;
    SNGL Caustics, Old_Refract;
    SNGL Fade_Distance, Fade_Power;
***************
*** 1123,1127 ****
    SNGL Irid, Irid_Film_Thickness, Irid_Turb;
    SNGL Crand, Metallic;
!   SNGL Temp_Caustics, Temp_IOR, Temp_Refract, Reflect_Exp;
    RGB  Ambient, Reflection;
  };
--- 1125,1130 ----
    SNGL Irid, Irid_Film_Thickness, Irid_Turb;
    SNGL Crand, Metallic;
!   SNGL Temp_Caustics, Temp_IOR, Temp_Dispersion, Temp_Refract, Reflect_Exp;
!   int  Temp_NElems;
    RGB  Ambient, Reflection;
  };
diff -C 2 -b orig/interior.c dsw2/interior.c
*** orig/interior.c	Mon Aug 31 19:45:52 1998
--- dsw2/interior.c	Sat Nov 28 23:00:38 1998
***************
*** 132,135 ****
--- 132,138 ----
  
    New->IOR = 0.0;
+   New->Dispersion = 1.0;
+   New->Disp_NElems = 7 /* DEFAULT_DISP_NELEMS */;
+           
    New->Old_Refract = 1.0;
  
diff -C 2 -b orig/interior.h dsw2/interior.h
*** orig/interior.h	Mon Aug 31 19:45:48 1998
--- dsw2/interior.h	Sat Nov 28 22:59:59 1998
***************
*** 33,36 ****
--- 33,37 ----
  
  
+ 
  /*****************************************************************************
  * Global typedefs
diff -C 2 -b orig/lighting.c dsw2/lighting.c
*** orig/lighting.c	Thu Jul 23 12:43:56 1998
--- dsw2/lighting.c	Sat Nov 28 22:04:31 1998
***************
*** 1905,1939 ****
  ******************************************************************************/
  
  static int Refract(INTERIOR *Interior, VECTOR IPoint, RAY *Ray, VECTOR Normal, COLOUR Colour, DBL Weight)
  {
    int nr;
!   DBL n, t, ior;
    VECTOR Local_Normal;
    RAY NRay;
  
!   /* Set up new ray. */
! 
    Copy_Ray_Containers(&NRay, Ray);
- 
    Assign_Vector(NRay.Initial, IPoint);
  
-   /* Get ratio of iors depending on the interiors the ray is traversing. */
  
    if (Ray->Index == -1)
    {
      /* The ray is entering from the atmosphere. */
- 
      Ray_Enter(&NRay, Interior);
- 
      ior = Frame.Atmosphere_IOR / Interior->IOR;
    }
    else
    {
      /* The ray is currently inside an object. */
- 
      if ((nr = Interior_In_Ray_Container(&NRay, Interior)) >= 0)
      {
        /* The ray is leaving the current object. */
- 
        Ray_Exit(&NRay, nr);
  
--- 1905,2058 ----
  ******************************************************************************/
  
+ 
+ 
+ /* Global vars to remember which colour component is being traced */
+ 
+ int disp_elem;        /* 0=normal, 1..nelems=we're tracing elements */
+ int disp_nelems;
+ 
+ 
+ 
+ __inline  double sqr(double x)  { return x*x; }
+ 
+ 
+ 
+ 
+ void Dispersion_Element_Hue(COLOUR Hue, int elem, int nelems)
+ {
+ 	
+ 	/* 
+ 	  Gives color to a dispersion element.
+ 
+ 	  Requirements:
+ 	    * Sum of all hues must add to white (or white*constand)
+ 		  (white tiles seen through glass should still be white)
+ 		  
+ 		* Each hue must be maximally saturated, bright
+ 		  (The code shown here cheats a little)
+ 		  
+ 		* colors must range from red at h=0 to violet at h=1
+ 
+ 	  This code is not necessarily the best, just proof-of-concept      
+ 	  EXPERIMENTAL AND DELICATE
+ 	  Better code could be written with look-up tables of the 
+ 	  famous CIE colour matching functions.
+ 	*/
+ 	
+ 	float h, coh;
+ 	float ybulge;
+ 	
+ 	/* h goes from 0 at red end to 1.0 at blue end */
+ 	h = (elem-1)*1.0/(nelems-1);
+ 
+ 	/* co-h goes from 1.0 at red end to 0.0 at blue end */
+ 	coh = 1.0 - h; 
+ 	
+ 	Hue[RED] = 0.9 - (h/0.5);
+ 	Hue[BLUE] = 1.0 - (coh/0.6);
+ 
+ 	if (Hue[RED] < 0.0)  Hue[RED] = 0.0;
+ 	if (Hue[BLUE] < 0.0)  Hue[BLUE] = 0.0;
+ 
+ 
+ 	Hue[RED]=1.0 - sqr(1.0-Hue[RED]);  
+ 	Hue[BLUE]=1.0-sqr(1.0-Hue[BLUE]); 
+ 	
+ 	
+ 	Hue[GREEN] = 1.0 - Hue[RED] - Hue[BLUE];
+ 
+ 	if (h>0.85)
+ 		Hue[RED] = 4*(h-0.85);
+ 
+ 	ybulge =  -4.0*(h-0.1)*(h-0.6);
+ 	if (ybulge<0) ybulge=0;
+ 	Hue[RED] += ybulge;
+ 	Hue[GREEN] += ybulge;
+ }
+ 
+ 
+ static
+ double Element_IOR(double ior, double disp,  int e, int nelems)
+ {
+ 	return ior * pow(disp, (e-1)*1.0/(nelems-1)-0.5);
+ }
+ 
+ 
+ 
+ 
+ static
+ int Refract_Guts(COLOUR Colour,  
+ 		DBL ior,
+ 		VECTOR IPoint,
+ 		VECTOR Normal, VECTOR Local_Normal,
+ 		DBL n,
+ 		RAY *Ray, RAY *NRay,
+ 		DBL Weight
+ 		)
+ {
+ 	/* Adds result of refracted ray to Colour            */
+ 	/* All other args are input args - don't change them */
+ 	/* Pass by value the RAYs and maybe make local copy of normals? */
+ 	
+ 	DBL t;
+ 	
+     /* Compute refrated ray direction using Heckbert's method. */
+     t = 1.0 + Sqr(ior) * (Sqr(n) - 1.0);
+ 
+     if (t < 0.0)
+     {
+       /* Total internal reflection occures. */
+       Increase_Counter(stats[Internal_Reflected_Rays_Traced]);
+       Reflect(IPoint, /*N?*/ Ray, /*L?*/ Normal, Colour, Weight);
+       return 1;
+     }
+ 
+     t = ior * n - sqrt(t);
+ 
+     VLinComb2(NRay->Direction, ior, /*N?*/Ray->Direction, t, Local_Normal);
+ 
+     /* Trace a refracted ray. */
+     Increase_Counter(stats[Refracted_Rays_Traced]);
+     
+ 	Trace_Level++;
+     Trace(NRay, Colour, Weight);
+     Trace_Level--;
+ 	
+ 	return 0;
+ }
+ 
+ 
+ 
  static int Refract(INTERIOR *Interior, VECTOR IPoint, RAY *Ray, VECTOR Normal, COLOUR Colour, DBL Weight)
  {
    int nr;
!   DBL n, t, ior, disp, ior_mult;
    VECTOR Local_Normal;
    RAY NRay;
+   COLOUR Hue, Sum, Elem;
  
!   /* Set up new ray, starting at the point of incidence */
    Copy_Ray_Containers(&NRay, Ray);
    Assign_Vector(NRay.Initial, IPoint);
  
  
+   disp_nelems = Interior->Disp_NElems;
+   
+   
+   /* Get ratio of iors depending on the interiors the ray is traversing. */
    if (Ray->Index == -1)
    {
      /* The ray is entering from the atmosphere. */
      Ray_Enter(&NRay, Interior);
      ior = Frame.Atmosphere_IOR / Interior->IOR;
+     disp = Frame.Atmosphere_Dispersion / Interior->Dispersion;
    }
+   
    else
    {
      /* The ray is currently inside an object. */
      if ((nr = Interior_In_Ray_Container(&NRay, Interior)) >= 0)
      {
        /* The ray is leaving the current object. */
        Ray_Exit(&NRay, nr);
  
***************
*** 1941,1952 ****
        {
          /* The ray is leaving into the atmosphere. */
- 
          ior = Interior->IOR / Frame.Atmosphere_IOR;
        }
        else
        {
          /* The ray is leaving into another object. */
- 
          ior = Interior->IOR / NRay.Interiors[NRay.Index]->IOR;
        }
      }
--- 2060,2075 ----
        {
          /* The ray is leaving into the atmosphere. */
          ior = Interior->IOR / Frame.Atmosphere_IOR;
+         disp = Interior->Dispersion / Frame.Atmosphere_Dispersion;
        }
        else
        {
          /* The ray is leaving into another object. */
          ior = Interior->IOR / NRay.Interiors[NRay.Index]->IOR;
+         disp = Interior->Dispersion / NRay.Interiors[NRay.Index]->Dispersion;
+ 		
+ 		/* Use the largest disp_nelems of the two interiors */
+ 	    if (NRay.Interiors[NRay.Index]->Disp_NElems > disp_nelems)
+ 	  	 disp_nelems = NRay.Interiors[NRay.Index]->Disp_NElems;
        }
      }
***************
*** 1954,1981 ****
      {
        /* The ray is entering a new object. */
- 
        ior = NRay.Interiors[NRay.Index]->IOR / Interior->IOR;
  
!       Ray_Enter(&NRay, Interior);
  
      }
    }
  
    /* Do the two mediums traversed have the sampe indices of refraction? */
  
-   if (fabs(ior - 1.0) < EPSILON)
    {
      /* Only transmit the ray. */
- 
      Assign_Vector(NRay.Direction, Ray->Direction);
  
      /* Trace a transmitted ray. */
- 
      Increase_Counter(stats[Transmitted_Rays_Traced]);
    }
!   else
    {
      /* Refract the ray. */
- 
      VDot(n, Ray->Direction, Normal);
  
--- 2077,2114 ----
      {
        /* The ray is entering a new object. */
        ior = NRay.Interiors[NRay.Index]->IOR / Interior->IOR;
+       disp = NRay.Interiors[NRay.Index]->Dispersion / Interior->Dispersion;
        
! 	  /* Use the largest disp_nelems of the two interiors */
! 	  if (NRay.Interiors[NRay.Index]->Disp_NElems > disp_nelems)
! 	  	 disp_nelems = NRay.Interiors[NRay.Index]->Disp_NElems;
        
+ 	  Ray_Enter(&NRay, Interior);
      }
    }
  
+ 
+ 
    /* Do the two mediums traversed have the sampe indices of refraction? */
+   /* DSW: they must also match in dispersion ratios                     */
+ 
+   if (fabs(ior - 1.0) < EPSILON
+    && fabs(disp - 1.0) < EPSILON)
  
    {
      /* Only transmit the ray. */
      Assign_Vector(NRay.Direction, Ray->Direction);
  
      /* Trace a transmitted ray. */
      Increase_Counter(stats[Transmitted_Rays_Traced]);
+     
+ 	Trace_Level++;
+     Trace(&NRay, Colour, Weight);
+     Trace_Level--;
    }
! 
!   else    /* different media */
    {
      /* Refract the ray. */
      VDot(n, Ray->Direction, Normal);
  
***************
*** 1983,1987 ****
      {
        Assign_Vector(Local_Normal, Normal);
- 
        n = -n;
      }
--- 2116,2119 ----
***************
*** 1993,2031 ****
      }
  
!     /* Compute refrated ray direction using Heckbert's method. */
  
!     t = 1.0 + Sqr(ior) * (Sqr(n) - 1.0);
  
!     if (t < 0.0)
      {
!       /* Total internal reflection occures. */
  
!       Increase_Counter(stats[Internal_Reflected_Rays_Traced]);
  
!       Reflect(IPoint, Ray, Normal, Colour, Weight);
  
!       return(1);
!     }
  
!     t = ior * n - sqrt(t);
  
!     VLinComb2(NRay.Direction, ior, Ray->Direction, t, Local_Normal);
  
!     /* Trace a refracted ray. */
  
!     Increase_Counter(stats[Refracted_Rays_Traced]);
    }
  
!   Trace_Level++;
  
!   Trace(&NRay, Colour, Weight);
  
-   Trace_Level--;
  
!   return(0);
  }
  
  
  
  /*****************************************************************************
  *
--- 2125,2192 ----
      }
  
! 	/* DSW: If this is the first time this ray is encountering          */
! 	/* a dispersive medium, we need to loop over the color components.  */
! 	/* If the ray has already been dispersed, use trace a monochromatic */
! 	/* ray, with no further looping.                                    */
  
! 	if (disp_elem>0)    
! 		{
! 		/* We're already tracing an element */
! 		ior = Element_IOR(ior, disp, disp_elem, disp_nelems);
  		
! 		Refract_Guts(Colour, ior, IPoint, Normal, Local_Normal, n, Ray, &NRay, Weight);
! 		}
! 		
! 	else
  		{
! 		/* An undispersed ray needs to be broken into elements */
  		
! 		if (disp_nelems==0) disp_nelems = DEFAULT_DISP_NELEMS;
! 		/* or use an adaptive formula? */
  		
! 		ior = ior /sqrt(disp);
! 		ior_mult = pow(disp, 1.0/(disp_nelems-1));
  
! 		Sum[RED]=0.0f;		
! 		Sum[GREEN]=0.0f;		
! 		Sum[BLUE]=0.0f;		
  
! 		/* Trace each element */
! 		for (disp_elem = 1;  disp_elem < disp_nelems;  disp_elem++)
! 			{
! 		    /* Call an arbitrary C lib function,  to avoid a GCC 2.8.1 optimizer bug */
! 			strchr("A", 'A');
  
! 			Refract_Guts(Elem, ior, IPoint, Normal, Local_Normal, n, Ray, &NRay, Weight);
  			
! 			Dispersion_Element_Hue(Hue, disp_elem, disp_nelems);
! 			/* speed it up by building a lookup table at povray init */
! 			/* or no: need to recalc if disp_nelems is adaptive,     */
! 			/* then we'd need a bunch of tables or calc fresh        */
  			
! 			Sum[RED]   += Elem[RED]   * Hue[RED];
! 			Sum[GREEN] += Elem[GREEN] * Hue[GREEN];
! 			Sum[BLUE]  += Elem[BLUE]  * Hue[BLUE];
! 			
! 			ior *= ior_mult;
  			}
  			
! 		/* compute final color, with fudge factor */
! 		Colour[RED]   = Sum[RED]   /disp_nelems *3.0;
! 		Colour[GREEN] = Sum[GREEN] /disp_nelems *3.0;
! 		Colour[BLUE]  = Sum[BLUE]  /disp_nelems *3.0;
  		
! 		disp_elem = 0;   /* reset this for next pixel's tracing */
! 		}
  
  
!   }    /* end of different media */
! 
!   return 0;
  }
  
  
  
+ 
  /*****************************************************************************
  *
***************
*** 2193,2197 ****
          Texture = material_map(TPoint, Texture);
  
!         do_texture_map(Result_Colour, Texture, TPoint, Raw_Normal, Ray, Weight, Ray_Intersection, Shadow_Flag);
  
          break;
--- 2354,2359 ----
          Texture = material_map(TPoint, Texture);
  
!         do_texture_map(Result_Colour, Texture, TPoint, Raw_Normal, Ray, Weight, 
! 				Ray_Intersection, Shadow_Flag);
  
          break;
***************
*** 2223,2231 ****
      Warp_EPoint (TPoint, IPoint, (TPATTERN *)Texture);
  
!     do_texture_map(Result_Colour, Cur->Vals.Texture, TPoint, Raw_Normal, Ray, Weight, Ray_Intersection, Shadow_Flag);
  
      if (Prev != Cur)
      {
!       do_texture_map(C2, Prev->Vals.Texture, TPoint, Raw_Normal, Ray, Weight, Ray_Intersection, Shadow_Flag);
  
        value1 = (value1 - Prev->value) / (Cur->value - Prev->value);
--- 2385,2395 ----
      Warp_EPoint (TPoint, IPoint, (TPATTERN *)Texture);
  
!     do_texture_map(Result_Colour, Cur->Vals.Texture, TPoint, Raw_Normal, Ray, Weight, 
! 			Ray_Intersection, Shadow_Flag);
  
      if (Prev != Cur)
      {
!       do_texture_map(C2, Prev->Vals.Texture, TPoint, Raw_Normal, Ray, Weight, 
! 	  		Ray_Intersection, Shadow_Flag);
  
        value1 = (value1 - Prev->value) / (Cur->value - Prev->value);
***************
*** 2309,2312 ****
--- 2473,2477 ----
    COLOUR ListReflec[MAX_LAYERS];
  
+   
    /*
     * ResCol builds up the apparent visible color of the point.
***************
*** 2886,2890 ****
  ******************************************************************************/
  
! static void filter_shadow_ray(INTERSECTION *Ray_Intersection, RAY *Light_Source_Ray, COLOUR Colour)
  {
    int i, Texture_Count;
--- 3051,3056 ----
  ******************************************************************************/
  
! static void filter_shadow_ray(INTERSECTION *Ray_Intersection, 
! 		RAY *Light_Source_Ray, COLOUR Colour)
  {
    int i, Texture_Count;
***************
*** 2951,2955 ****
      Texture = Texture_List[i];
  
!     do_texture_map(FC1, Texture, IPoint, Raw_Normal, Light_Source_Ray, 0.0, Ray_Intersection, TRUE);
  
      Temp_Colour[RED]     += Weight_List[i] * FC1[RED];
--- 3117,3122 ----
      Texture = Texture_List[i];
  
!     do_texture_map(FC1, Texture, IPoint, Raw_Normal, Light_Source_Ray,  0.0, 
! 			Ray_Intersection, TRUE);
  
      Temp_Colour[RED]     += Weight_List[i] * FC1[RED];
***************
*** 3162,3166 ****
       Value = Map->Blend_Map_Entries[i].value;
  
!      do_texture_map (LC,Map->Blend_Map_Entries[i].Vals.Texture, IPoint,Raw_Normal,Ray,Weight,Ray_Intersection,Shadow_Flag);
  
       Result_Colour[RED]   += LC[RED]   *Value;
--- 3329,3334 ----
       Value = Map->Blend_Map_Entries[i].value;
  
!      do_texture_map (LC,Map->Blend_Map_Entries[i].Vals.Texture, IPoint,Raw_Normal,Ray,Weight,
! 	 		Ray_Intersection,Shadow_Flag);
  
       Result_Colour[RED]   += LC[RED]   *Value;
diff -C 2 -b orig/lighting.h dsw2/lighting.h
*** orig/lighting.h	Fri May 22 17:48:04 1998
--- dsw2/lighting.h	Sat Nov 28 23:00:46 1998
***************
*** 35,38 ****
--- 35,41 ----
  
  
+ /* How many subrays to trace for dispersive media */
+ #define DEFAULT_DISP_NELEMS  7
+ 
  
  
Only in dsw2: linuxdsw
Only in orig: lowercase.py
Only in orig: msdos
diff -C 2 -b orig/optout.c dsw2/optout.c
*** orig/optout.c	Sun Aug  9 22:53:14 1998
--- dsw2/optout.c	Tue Oct 13 12:44:04 1998
***************
*** 489,493 ****
  void Print_Credits()
  {
!   Banner ("Persistence of Vision(tm) Ray Tracer Version %s%s\n", POV_RAY_VERSION, COMPILER_VER);
    Banner ("  %s\n", DISTRIBUTION_MESSAGE_1);
    Banner ("  %s\n", DISTRIBUTION_MESSAGE_2);
--- 489,493 ----
  void Print_Credits()
  {
!   Banner ("Persistence of Vision(tm) Ray Tracer Version %s%s\n", POV_RAY_VERSION, " gcc?");
    Banner ("  %s\n", DISTRIBUTION_MESSAGE_1);
    Banner ("  %s\n", DISTRIBUTION_MESSAGE_2);
diff -C 2 -b orig/optout.h dsw2/optout.h
*** orig/optout.h	Sun Sep 13 15:22:40 1998
--- dsw2/optout.h	Tue Oct 13 12:36:24 1998
***************
*** 36,41 ****
  #define POV_RAY_VERSION "3.1"
  
! #define DISTRIBUTION_MESSAGE_1 "This is an unofficial version compiled by:"
! #define DISTRIBUTION_MESSAGE_2 "FILL IN NAME HERE........................."
  #define DISTRIBUTION_MESSAGE_3 "The POV-Ray Team(tm) is not responsible for supporting this version."
  
--- 36,41 ----
  #define POV_RAY_VERSION "3.1"
  
! #define DISTRIBUTION_MESSAGE_1 "Unofficial version: MSDOS->Linux"
! #define DISTRIBUTION_MESSAGE_2 "Compiled by Daren Scot Wilson"
  #define DISTRIBUTION_MESSAGE_3 "The POV-Ray Team(tm) is not responsible for supporting this version."
  
diff -C 2 -b orig/parse.c dsw2/parse.c
*** orig/parse.c	Sat Oct  3 01:54:02 1998
--- dsw2/parse.c	Sat Nov 21 04:45:58 1998
***************
*** 242,245 ****
--- 242,246 ----
     Frame.Objects = NULL;
     Frame.Atmosphere_IOR = 1.0;
+    Frame.Atmosphere_Dispersion = 1.0;
     Frame.Antialias_Threshold = opts.Antialias_Threshold;
  
***************
*** 5413,5421 ****
  ******************************************************************************/
  
  char *Get_Token_String (TOKEN Token_Id)
  {
!   register int i;
  
!   for (i = 0 ; i < LAST_TOKEN ; i++)
       if (Reserved_Words[i].Token_Number == Token_Id)
          return (Reserved_Words[i].Token_Name);
--- 5414,5424 ----
  ******************************************************************************/
  
+ extern int n_words;
+ 
  char *Get_Token_String (TOKEN Token_Id)
  {
!   int i;
  
!   for (i = 0 ; i < n_words;  i++)
       if (Reserved_Words[i].Token_Number == Token_Id)
          return (Reserved_Words[i].Token_Name);
***************
*** 5764,5768 ****
--- 5767,5773 ----
            {
              Object->Interior->IOR = Finish->Temp_IOR;
+ 			Object->Interior->Dispersion = Finish->Temp_Dispersion;
            }
+ 
            if (Finish->Temp_Caustics >= 0.0)
            {
***************
*** 5780,5783 ****
--- 5785,5789 ----
      {
        Object->Interior->IOR = Frame.Atmosphere_IOR;
+ 	  Object->Interior->Dispersion = Frame.Atmosphere_Dispersion;
      }
    }
diff -C 2 -b orig/parse.h dsw2/parse.h
*** orig/parse.h	Sat Oct  3 01:58:17 1998
--- dsw2/parse.h	Sat Nov 28 20:28:59 1998
***************
*** 67,73 ****
--- 67,75 ----
    ABS_TOKEN = 0,
    ATAN2_TOKEN,
+   ATAN2D_TOKEN,
    CEIL_TOKEN,
    CLOCK_TOKEN,
    COS_TOKEN,
+   COSD_TOKEN,
    DEGREES_TOKEN,
    DIV_TOKEN,
***************
*** 85,88 ****
--- 87,91 ----
    RADIANS_TOKEN,
    SIN_TOKEN,
+   SIND_TOKEN,
    SQRT_TOKEN,
    VDOT_TOKEN,
***************
*** 96,101 ****
--- 99,107 ----
    NO_TOKEN,
    ACOS_TOKEN,
+   ACOSD_TOKEN,
    ASIN_TOKEN,
+   ASIND_TOKEN,
    TAN_TOKEN,
+   TAND_TOKEN,
    ASC_TOKEN,
    STRLEN_TOKEN,
***************
*** 137,140 ****
--- 143,148 ----
    RGBT_TOKEN,
    RGB_TOKEN,
+   RRRGGGBBB_TOKEN,
+   ROYGBIV_TOKEN,
    COLOUR_KEY_TOKEN,
  
***************
*** 217,220 ****
--- 225,230 ----
    INVERSE_TOKEN,
    IOR_TOKEN,
+   DISP_NELEMS_TOKEN,
+   DISPERSION_TOKEN,
    JITTER_TOKEN,
    LAMBDA_TOKEN,
***************
*** 502,506 ****
    MATERIAL_TOKEN,
    MATERIAL_ID_TOKEN,
!   LAST_TOKEN
  };
  
--- 512,516 ----
    MATERIAL_TOKEN,
    MATERIAL_ID_TOKEN,
!   WMO_TOKEN
  };
  
diff -C 2 -b orig/parstxtr.c dsw2/parstxtr.c
*** orig/parstxtr.c	Mon Aug 31 20:02:32 1998
--- dsw2/parstxtr.c	Sat Nov 28 20:52:25 1998
***************
*** 1195,1198 ****
--- 1195,1208 ----
       END_CASE
  	 
+ 	 CASE (DISPERSION_TOKEN)
+ 	 	New->Temp_Dispersion = Parse_Float();
+         Warn_Interior("Index of refraction value");
+ 	 END_CASE
+ 
+ 	 CASE (DISP_NELEMS_TOKEN)
+ 	 	New->Temp_NElems = (int)Parse_Float();
+         Warn_Interior("Index of refraction value");
+ 	 END_CASE
+ 
       CASE (CAUSTICS_TOKEN)
         New->Temp_Caustics = Parse_Float();
***************
*** 1977,1980 ****
--- 1987,2002 ----
           END_CASE
  
+          CASE (DISPERSION_TOKEN)
+            Warn_State(Token.Token_Id, INTERIOR_TOKEN);
+            Finish->Temp_Dispersion = (int)Parse_Float();
+            Warn_Interior("Index of refraction value");
+          END_CASE
+ 
+          CASE (DISP_NELEMS_TOKEN)
+            Warn_State(Token.Token_Id, INTERIOR_TOKEN);
+            Finish->Temp_NElems = (int)Parse_Float();
+            Warn_Interior("Index of refraction value");
+          END_CASE
+ 
           CASE (REFRACTION_TOKEN)
             Warn_State(Token.Token_Id, INTERIOR_TOKEN);
***************
*** 2342,2345 ****
--- 2364,2375 ----
      END_CASE
  
+     CASE (DISPERSION_TOKEN)
+       Interior->Dispersion = Parse_Float();
+     END_CASE
+ 
+     CASE (DISP_NELEMS_TOKEN)
+       Interior->Disp_NElems = (int)Parse_Float();
+     END_CASE
+ 
      CASE (CAUSTICS_TOKEN)
        Interior->Caustics = Parse_Float() * 45.0;
Only in dsw2: pool
diff -C 2 -b orig/povray.c dsw2/povray.c
*** orig/povray.c	Mon Jun  1 19:12:34 1998
--- dsw2/povray.c	Sat Nov 28 20:40:10 1998
***************
*** 166,170 ****
  static void variable_store (int Flag);
  static int Has_Extension (char *name);
- static unsigned closest_power_of_2 (unsigned theNumber);
  static void init_shellouts (void);
  static void destroy_shellouts (void);
--- 166,169 ----
***************
*** 212,216 ****
  #endif            /* ...would be a lot less hassle!! :-) AAC */
  {
!   register int i;
    int Diff_Frame;
    DBL Diff_Clock;
--- 211,215 ----
  #endif            /* ...would be a lot less hassle!! :-) AAC */
  {
!   int i;
    int Diff_Frame;
    DBL Diff_Clock;
***************
*** 732,746 ****
    opts.PreviewGridSize_End=max(1,opts.PreviewGridSize_End);
  
!   if ((temp=closest_power_of_2((unsigned)opts.PreviewGridSize_Start))!=opts.PreviewGridSize_Start)
!   {
!      Warning(0.0,"Preview_Start_Size must be a power of 2. Changing to %d.\n",temp);
!      opts.PreviewGridSize_Start=temp;
!   }
! 
!   if ((temp=closest_power_of_2((unsigned)opts.PreviewGridSize_End))!=opts.PreviewGridSize_End)
!   {
!      Warning(0.0,"Preview_End_Size must be a power of 2. Changing to %d.\n",temp);
!      opts.PreviewGridSize_End=temp;
!   }
  
    /* End must be less than or equal to start */
--- 731,735 ----
    opts.PreviewGridSize_End=max(1,opts.PreviewGridSize_End);
  
!   /* DSW: removed power-of-two check for preview sizes */
    
    /* End must be less than or equal to start */
***************
*** 2180,2252 ****
  
  
- /*****************************************************************************
- *
- * FUNCTION
- *
- *   closest_power_of_2
- *
- * INPUT
- *
- *   theNumber - the value to determine closest power of 2 for.
- *
- * OUTPUT
- *
- * RETURNS
- *
- *   The closest power of two is returned, or zero if the
- *   argument is less than or equal to zero.
- *
- * AUTHOR
- *
- *   Eduard Schwan
- *
- * DESCRIPTION
- *
- *   Decription: Find the highest positive power of 2 that is
- *   less than or equal to the number passed.
- *
- *   Input  Output
- *   -----  ------
- *     0      0
- *     1      1
- *     2      2
- *     3      2
- *     8      8
- *     9      8
- *
- * CHANGES
- *
- *   Aug 1994 : Created by Eduard.
- *
- ******************************************************************************/
  
- static unsigned closest_power_of_2(unsigned theNumber)
- {
-   int PowerOf2Counter;
  
-   /* do not handle zero or negative numbers for now */
  
-   if (theNumber <= 0)
-   {
-     return(0);
-   }
- 
-   /* count the number in question down as we count up a power of 2 */
- 
-   PowerOf2Counter = 1;
- 
-   while (theNumber > 1)
-   {
-     /* move our power of 2 counter bit up... */
  
-     PowerOf2Counter <<= 1;
- 
-     /* and reduce our test number by a factor of 2 two */
- 
-     theNumber >>= 1;
-   }
- 
-   return(PowerOf2Counter);
- }
  
  /*****************************************************************************
--- 2169,2176 ----
diff -C 2 -b orig/povray.h dsw2/povray.h
*** orig/povray.h	Mon Jun  1 19:12:42 1998
--- dsw2/povray.h	Sat Nov 21 04:34:59 1998
***************
*** 118,122 ****
    LIGHT_SOURCE *Light_Sources;
    OBJECT *Objects;
!   DBL Atmosphere_IOR, Antialias_Threshold;
    COLOUR Background_Colour;
    COLOUR Ambient_Light;
--- 118,122 ----
    LIGHT_SOURCE *Light_Sources;
    OBJECT *Objects;
!   DBL Atmosphere_IOR, Atmosphere_Dispersion,  Antialias_Threshold;
    COLOUR Background_Colour;
    COLOUR Ambient_Light;
Only in dsw2: refract-t.c
diff -C 2 -b orig/render.c dsw2/render.c
*** orig/render.c	Sat Oct  3 02:11:22 1998
--- dsw2/render.c	Sat Nov 21 13:33:55 1998
***************
*** 864,883 ****
    /* do each pass of the image */
    /* increment pass counter and divide PixelSize & PreviewStep by 2 */
- 
    for (PreviewPass = 1, PixelSize = StartPixelSize;
          PixelSize >= EndPixelSize;
!         PreviewPass++, PixelSize >>= 1, PreviewStep >>= 1)
    {
-     /* do each row */
  
      for (y = opts.First_Line; y < opts.Last_Line; y += PreviewStep)
      {
        /* show some status information */
        /* note, this fn should change to show new style for preview */
- 
        check_stats(y, 1, PixelSize);
  
        /* do each column/pixel on a row */
- 
        for (x = opts.First_Column; x < opts.Last_Column; x += PreviewStep)
        {
--- 864,880 ----
    /* do each pass of the image */
    /* increment pass counter and divide PixelSize & PreviewStep by 2 */
    for (PreviewPass = 1, PixelSize = StartPixelSize;
          PixelSize >= EndPixelSize;
!         PreviewPass++, PixelSize/=3, PreviewStep/=3 )
    {
  
+     /* do each row */
      for (y = opts.First_Line; y < opts.Last_Line; y += PreviewStep)
      {
        /* show some status information */
        /* note, this fn should change to show new style for preview */
        check_stats(y, 1, PixelSize);
  
        /* do each column/pixel on a row */
        for (x = opts.First_Column; x < opts.Last_Column; x += PreviewStep)
        {
***************
*** 890,900 ****
           * there is nothing to skip.
           */
- 
          AlreadyPainted = FALSE;
  
          if (PreviewPass > 1)
          {
!           if ( ((x-opts.First_Column) % (PreviewStep*2) == 0) &&
!                ((y-opts.First_Line) % (PreviewStep*2) == 0) )
            {
              AlreadyPainted = TRUE;
--- 887,896 ----
           * there is nothing to skip.
           */
          AlreadyPainted = FALSE;
  
          if (PreviewPass > 1)
          {
!           if ( ((x-opts.First_Column) % (PreviewStep*3) == 0) &&
!                ((y-opts.First_Line) % (PreviewStep*3) == 0) )
            {
              AlreadyPainted = TRUE;
***************
*** 905,913 ****
          {
            /* OK, it is safe to draw this pixel */
- 
            trace_pixel(x, y, Colour);
- 
            extract_colors(Colour, &Red, &Green, &Blue, &Alpha, &grey);
- 
            y2 = min(y + PixelSize - 1, opts.Last_Line-1);
            x2 = min(x + PixelSize - 1, opts.Last_Column-1);
--- 901,906 ----
diff -C 2 -b orig/texture.c dsw2/texture.c
*** orig/texture.c	Mon Aug 31 19:51:48 1998
--- dsw2/texture.c	Sat Nov 21 02:49:44 1998
***************
*** 827,830 ****
--- 827,831 ----
    New->Temp_Caustics = -1.0;
    New->Temp_IOR     = -1.0;
+   New->Temp_Dispersion  = 1.0;
    New->Temp_Refract =  1.0;
    New->Reflect_Exp  =  1.0;
diff -C 2 -b orig/tokenize.c dsw2/tokenize.c
*** orig/tokenize.c	Sat Oct  3 01:53:51 1998
--- dsw2/tokenize.c	Sat Nov 28 20:46:53 1998
***************
*** 139,147 ****
   */
  
! RESERVED_WORD Reserved_Words [LAST_TOKEN] = {
    {ABSORPTION_TOKEN, "absorption"},
    {ABS_TOKEN, "abs"},
    {ACOSH_TOKEN, "acosh"},
    {ACOS_TOKEN, "acos"},
    {ADAPTIVE_TOKEN, "adaptive"},
    {ADC_BAILOUT_TOKEN, "adc_bailout"},
--- 139,148 ----
   */
  
! RESERVED_WORD Reserved_Words [ ] = {
    {ABSORPTION_TOKEN, "absorption"},
    {ABS_TOKEN, "abs"},
    {ACOSH_TOKEN, "acosh"},
    {ACOS_TOKEN, "acos"},
+   {ACOSD_TOKEN, "acosd"},
    {ADAPTIVE_TOKEN, "adaptive"},
    {ADC_BAILOUT_TOKEN, "adc_bailout"},
***************
*** 163,168 ****
--- 164,171 ----
    {ASINH_TOKEN, "asinh"},
    {ASIN_TOKEN, "asin"},
+   {ASIND_TOKEN, "asind"},
    {ASSUMED_GAMMA_TOKEN, "assumed_gamma"},
    {ATAN2_TOKEN, "atan2"},
+   {ATAN2D_TOKEN, "atan2d"},
    {ATANH_TOKEN, "atanh"},
    {ATAN_TOKEN, "atan"},
***************
*** 220,223 ****
--- 223,227 ----
    {COSH_TOKEN, "cosh"},
    {COS_TOKEN, "cos"},
+   {COSD_TOKEN, "cosd"},
    {COUNT_TOKEN, "count" },
    {CRACKLE_TOKEN, "crackle"},
***************
*** 248,251 ****
--- 252,257 ----
    {DIRECTION_TOKEN, "direction"},
    {DISC_TOKEN, "disc"},
+   {DISP_NELEMS_TOKEN, "disp_nelems"},
+   {DISPERSION_TOKEN, "dispersion"},
    {DISTANCE_MAXIMUM_TOKEN, "distance_maximum" },
    {DISTANCE_TOKEN, "distance"},
***************
*** 258,261 ****
--- 264,269 ----
    {END_OF_FILE_TOKEN, "End of File"},
    {END_TOKEN, "end"},
+   {END_TOKEN, "endif"},
+   {END_TOKEN, "endwhile"},
    {EQUALS_TOKEN, "="},
    {ERROR_BOUND_TOKEN, "error_bound" },
***************
*** 444,447 ****
--- 452,457 ----
    {RGBT_TOKEN, "rgbt"},
    {RGB_TOKEN, "rgb"},
+   {RRRGGGBBB_TOKEN, "rrrgggbbb"},
+   {ROYGBIV_TOKEN, "roygbiv"},
    {RIGHT_ANGLE_TOKEN, ">"},
    {RIGHT_CURLY_TOKEN, "}"},
***************
*** 462,465 ****
--- 472,476 ----
    {SINH_TOKEN, "sinh"},
    {SIN_TOKEN, "sin"},
+   {SIND_TOKEN, "sind"},
    {SKYSPHERE_ID_TOKEN, "sky_sphere identifier"},
    {SKYSPHERE_TOKEN, "sky_sphere"},
***************
*** 498,501 ****
--- 509,513 ----
    {TANH_TOKEN, "tanh"},
    {TAN_TOKEN, "tan"},
+   {TAND_TOKEN, "tand"},
    {TEXTURE_ID_TOKEN, "texture identifier"},
    {TEXTURE_MAP_ID_TOKEN, "texture_map identifier"},
***************
*** 550,553 ****
--- 562,566 ----
    {WARNING_TOKEN, "warning"},
    {WARP_TOKEN, "warp"},
+   {WMO_TOKEN,  "warp_map_only"},
    {WATER_LEVEL_TOKEN, "water_level"},
    {WAVES_TOKEN, "waves"},
***************
*** 564,567 ****
--- 577,585 ----
  
  
+ int n_words = sizeof(Reserved_Words) / sizeof(Reserved_Words[0]);
+ 
+ 
+ 
+ 
  
  /*****************************************************************************
***************
*** 1885,1888 ****
--- 1903,1907 ----
  }
  
+ 
  void Write_Token (TOKEN Token_Id)
  {
***************
*** 2900,2904 ****
    Add_Sym_Table("reserved words");
  
!   for (i = 0; i < LAST_TOKEN; i++)
    {
      Add_Symbol(0,Reserved_Words[i].Token_Name,Reserved_Words[i].Token_Number);
--- 2919,2923 ----
    Add_Sym_Table("reserved words");
  
!   for (i = 0; i < n_words; i++)
    {
      Add_Symbol(0,Reserved_Words[i].Token_Name,Reserved_Words[i].Token_Number);
diff -C 2 -b orig/tokenize.h dsw2/tokenize.h
*** orig/tokenize.h	Sat Oct  3 01:53:34 1998
--- dsw2/tokenize.h	Sat Nov 21 04:27:26 1998
***************
*** 95,99 ****
  extern struct Token_Struct Token;
  
! extern struct Reserved_Word_Struct Reserved_Words [LAST_TOKEN];
  extern int Table_Index;
  extern int token_count;
--- 95,99 ----
  extern struct Token_Struct Token;
  
! extern struct Reserved_Word_Struct Reserved_Words [];
  extern int Table_Index;
  extern int token_count;
diff -C 2 -b orig/userio.c dsw2/userio.c
*** orig/userio.c	Mon Aug 31 18:19:22 1998
--- dsw2/userio.c	Sat Nov 21 14:06:49 1998
***************
*** 435,438 ****
--- 435,440 ----
  }
  
+ 
+ 
  /****************************************************************************/
  void POV_Std_Fatal(char *s)
***************
*** 442,445 ****
--- 444,449 ----
  }
  
+ 
+ 
  /****************************************************************************/
  void POV_Std_Statistics(char *s)
***************
*** 449,452 ****
--- 453,458 ----
  }
  
+ 
+ 
  /****************************************************************************/
  void Terminate_POV(int i)
***************
*** 461,464 ****
--- 467,474 ----
  }
  
+ 
+ 
+ 
+ 
  /***************************************************************************
   *
***************
*** 470,473 ****
--- 480,484 ----
  static int Prev_X, Prev_Y;
  
+ 
  /****************************************************************************/
  void POV_Std_Display_Init(int w, int  h)
***************
*** 480,483 ****
--- 491,496 ----
  }
  
+ 
+ 
  /****************************************************************************/
  void POV_Std_Display_Finished()
***************
*** 492,495 ****
--- 505,510 ----
  }
  
+ 
+ 
  /****************************************************************************/
  void POV_Std_Display_Close()
***************
*** 498,501 ****
--- 513,518 ----
  }
  
+ 
+ 
  /****************************************************************************/
  void POV_Std_Display_Plot(int x, int y, unsigned int r, unsigned int g, unsigned int b, unsigned int a)
***************
*** 525,534 ****
  }
  
  /****************************************************************************/
  void POV_Std_Display_Plot_Rect(int x1, int y1, int x2, int y2, unsigned int r, unsigned int g, unsigned int b, unsigned int a)
  {
!   POV_Std_Display_Plot(x1, y1, r, g, b, a);
  }
  
  /*****************************************************************************
  *
--- 542,559 ----
  }
  
+ 
+ 
  /****************************************************************************/
  void POV_Std_Display_Plot_Rect(int x1, int y1, int x2, int y2, unsigned int r, unsigned int g, unsigned int b, unsigned int a)
  {
! 	int x,y;
!      for (x = x1; x <= x2; x++)
!      for (y = y1; y <= y2; y++)
!        POV_DISPLAY_PLOT(x, y, r, g, b, a);
! 
  }
  
+ 
+ 
  /*****************************************************************************
  *
