/* interp.h */

/*
 * Mesa 3-D graphics library
 * Version:  1.2
 * Copyright (C) 1995  Brian Paul  (brianp@ssec.wisc.edu)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */


/*
$Id: interp.h,v 1.6 1995/10/23 21:27:54 brianp Exp $

$Log: interp.h,v $
 * Revision 1.6  1995/10/23  21:27:54  brianp
 * new GLubyte interpolation using fixed point arithmetic
 *
 * Revision 1.5  1995/06/12  15:43:57  brianp
 * separate GLint and GLubyte interpolation functions
 *
 * Revision 1.4  1995/06/02  13:59:01  brianp
 * faster GL_INTERPOLATE() macro
 *
 * Revision 1.3  1995/05/22  20:59:34  brianp
 * Release 1.2
 *
 * Revision 1.2  1995/03/04  19:25:29  brianp
 * 1.1 beta revision
 *
 * Revision 1.1  1995/02/27  22:20:16  brianp
 * Initial revision
 *
 */


#ifndef INTERP_H
#define INTERP_H



extern void gl_interpolate_i( GLint n, GLint y0, GLint y1, GLint yspan[] );


extern void gl_interpolate_ub( GLint n, GLint y0, GLint y1, GLubyte yspan[] );


extern void gl_interpolate_4ub( GLint n,
                                GLint a0, GLint a1, GLubyte aspan[],
                                GLint b0, GLint b1, GLubyte bspan[],
                                GLint c0, GLint c1, GLubyte cspan[],
                                GLint d0, GLint d1, GLubyte dspan[] );


extern void gl_interp_texcoords( GLuint n,
				 GLfloat eyez0, GLfloat eyez1,
				 GLfloat winz0, GLfloat winz1,
				 GLfloat s0, GLfloat s1,
				 GLfloat t0, GLfloat t1,
				 GLfloat s[], GLfloat t[], GLfloat *z );


#ifdef DEBUG

#define GL_INTERPOLATE_I(N,Y0,Y1,YSPAN)   gl_interpolate_i(N,Y0,Y1,YSPAN)

#define GL_INTERPOLATE_UB(N,Y0,Y1,YSPAN)  gl_interpolate_ub(N,Y0,Y1,YSPAN)

#else

#define GL_INTERPOLATE_I(N,Y0,Y1,YSPAN)	\
{					\
   switch (N) {				\
      case 1:				\
	 YSPAN[0] = Y0;			\
	 break;				\
      case 2:				\
	 YSPAN[0] = Y0;			\
	 YSPAN[1] = Y1;			\
	 break;				\
      case 3:				\
	 YSPAN[0] = Y0;			\
	 YSPAN[1] = ((Y0)+(Y1)) >> 1;	\
	 YSPAN[2] = Y1;			\
	 break;				\
      default:				\
	 if (Y0==Y1) {			\
	    register GLint i;		\
	    for (i=0;i<(N);i++) {	\
	       YSPAN[i] = Y0;		\
	    }				\
	 }				\
	 else {				\
	    register GLint i;		\
	    register GLint dx, dy;	\
	    register GLint a, b, d;	\
	    register GLint yy;		\
	    register GLint qa, qb;	\
	    dx = (N)-1;			\
	    dy = (Y1) - (Y0);		\
	    qa = dy / dx;		\
	    dy = dy % dx;		\
	    if (dy<0) {			\
	       dy = -dy;		\
	       qb = qa - 1;		\
	    }				\
	    else {			\
	       qb = qa + 1;		\
	    }				\
	    a = dy + dy;		\
	    d = a - dx;			\
	    b = d - dx;			\
	    yy = Y0;			\
	    for (i=0;i<(N);i++) {	\
	       YSPAN[i] = yy;		\
	       if (d<0) {		\
		  d += a;		\
		  yy += qa;		\
	       }			\
	       else {			\
		  d += b;		\
		  yy += qb;		\
	       }			\
	    }				\
	 }				\
   }					\
}



#define GL_INTERPOLATE_UB(N,Y0,Y1,YSPAN)	\
	if ((N)>1) {				\
	   int yy0 = (Y0) << 8;			\
	   int yy1 = (Y1) << 8;			\
	   int dyy = (yy1-yy0) / ((int)(N)-1);	\
	   int ii;				\
	   for (ii=0;ii<(N);ii++) {		\
	      YSPAN[ii] = yy0 >> 8;		\
	      yy0 += dyy;			\
	   }					\
	}					\
	else {					\
	   YSPAN[0] = Y0;			\
	}



#endif  /*DEBUG*/



#define GL_INTERPOLATE_4UB( N, A0,A1,A, B0,B1,B, C0,C1,C, D0,D1,D )	\
	if ((N)<2) {				\
	   A[0] = A0;				\
	   B[0] = B0;				\
	   C[0] = C0;				\
	   D[0] = D0;				\
	}					\
	else if ((N)==2) {			\
	   A[0] = A0;  A[1] = A1;		\
	   B[0] = B0;  B[1] = B1;		\
	   C[0] = C0;  C[1] = C1;		\
	   D[0] = D0;  D[1] = D1;		\
	}					\
	else {					\
	   int a0, da, b0, db, c0, dc, d0,dd;	\
	   int ii, nn = (int) (N) - 1;		\
	   a0 = (A0) << 8;			\
	   da = (((A1)<<8)-a0) / nn;		\
	   b0 = (B0) << 8;			\
	   db = (((B1)<<8)-b0) / nn;		\
	   c0 = (C0) << 8;			\
	   dc = (((C1)<<8)-c0) / nn;		\
	   d0 = (D0) << 8;			\
	   dd = (((D1)<<8)-d0) / nn;		\
	   for (ii=0;ii<(N);ii++) {		\
	      A[ii] = a0 >> 8;	a0+=da;		\
	      B[ii] = b0 >> 8;	b0+=db;		\
	      C[ii] = c0 >> 8;	c0+=dc;		\
	      D[ii] = d0 >> 8;	d0+=dd;		\
	   }					\
	}


#endif  /* INTERP_H */

