#include "standard.h"
#include "global.h"
#include "drawprimitive.h"
#include "scanlines.h"

#define PIXELOUT(x)	PIXELOUT555(x)


#define PIXELOUT555(x) {unsigned short texel,alpha;\
					    long tr,tg,tb;\
					    long ro,go,bo;\
					    long ar,ag,ab;\
					    texel = *(Texture +((u>>16))+((v>>16)<<8));\
						if(texel != 0)\
						{\
							alpha = *(pDestination+x);\
							ar = ((alpha))&0x7c00;\
							ag = ((alpha))&0x3e0;\
							ab = ((alpha))&0x1f;\
							tr = ((texel>>5)&0x3e0);\
							tg = ((texel)&0x3e0);\
							tb = (texel&0x1f)<<5;\
							ro = *(RGBTable+(tr+(redleft>>16+3)))<<10;\
							go = *(RGBTable+(tg+(greenleft>>16+3)))<<5;\
							bo = *(RGBTable+(tb+(blueleft>>16+3)));\
							ro += ar;\
							go += ag;\
							bo += ab;\
							if(ro > 0x7c00) ro = 0x7c00;\
							if(go > 0x3e0) go = 0x3e0;\
							if(bo > 0x1f) bo = 0x1f;\
							*(pDestination+x) = ro|go|bo;}\
							v += dv;\
							u += du;\
	 						redleft += dr;\
							greenleft += dg;\
							blueleft += db;};



/*
	Function : ScanLinesTGAlphaAffine
	Useage	 : Textured Goruaud Alpha Affine 
*/

void ScanLinesTGAlphaDecalAffine(GRADIENT* Gradients,EDGE* pLeft,EDGE* pRight,EDGE* StepLeft,EDGE* StepRight)
{
	int Width;
	unsigned short* pDestination;
	long u,v,du,dv;
	long yline;
	float oowidth;
	short subdivcnt;
	short texel;
	long redleft,greenleft,blueleft;
	short tr,tg,tb;
	long dr,dg,db;
	short ro,go,bo;
	double fconv;

	yline = long(Output)+YTable[pLeft->y];
	
	while(StepLeft->height--)
	{
		Width  = pRight->x;
		Width -= pLeft->x;

		if(Width > 0)
		{
			pDestination = (unsigned short*) yline + pLeft->x;
			
			u = pLeft->uozf;
			v = pLeft->vozf;
			
			redleft   = pLeft->rf;
			greenleft = pLeft->gf;
			blueleft  = pLeft->bf;

			oowidth = WidthTable[Width];

			du = (pRight->uozf - pLeft->uozf);
			du = FTOL(float(du)*oowidth);
			dv = (pRight->vozf - pLeft->vozf);
			dv = FTOL(float(dv)*oowidth);
			dr = (pRight->rf - pLeft->rf);			
			dr = FTOL(float(dr)*oowidth);
			dg = (pRight->gf - pLeft->gf);			
			dg = FTOL(float(dg)*oowidth);
			db = (pRight->bf - pLeft->bf);			
			db = FTOL(float(db)*oowidth);
			
			subdivcnt = Width>>4;
			Width = Width-(subdivcnt<<4);
			
			while(subdivcnt--)
			{
				PIXELOUT(0);
				PIXELOUT(1);
				PIXELOUT(2);
				PIXELOUT(3);
				PIXELOUT(4);
				PIXELOUT(5);
				PIXELOUT(6);
				PIXELOUT(7);
				PIXELOUT(8);
				PIXELOUT(9);
				PIXELOUT(10);
				PIXELOUT(11);
				PIXELOUT(12);
				PIXELOUT(13);
				PIXELOUT(14);
				PIXELOUT(15);

				pDestination += 16;
			}

			for(int n=0;n<Width;n++)
			{
				PIXELOUT(0);
				pDestination++;
			}
		}

		yline += bytepitch;

		StepLeft->uozf += StepLeft->uozstepf;
		StepLeft->vozf += StepLeft->vozstepf;
		StepLeft->x    += StepLeft->xstep;
		StepLeft->y++;
		
		StepLeft->rf   += StepLeft->rstepf;
		StepLeft->gf   += StepLeft->gstepf;
		StepLeft->bf   += StepLeft->bstepf;

		StepLeft->ErrorTerm += StepLeft->Numerator;

		if(StepLeft->ErrorTerm >= StepLeft->Denominator)
		{
			StepLeft->x++;
			StepLeft->uozf += StepLeft->uozxtraf;
			StepLeft->vozf += StepLeft->vozxtraf;
			StepLeft->ErrorTerm -= StepLeft->Denominator;
	
			StepLeft->rf += StepLeft->rxtraf;
			StepLeft->gf += StepLeft->gxtraf;
			StepLeft->bf += StepLeft->bxtraf;
		}

		StepRight->x    += StepRight->xstep;
		StepRight->uozf += StepRight->uozstepf;
		StepRight->vozf += StepRight->vozstepf;
		StepRight->y++;

		StepRight->rf   += StepRight->rstepf;
		StepRight->gf   += StepRight->gstepf;
		StepRight->bf   += StepRight->bstepf;

		StepRight->ErrorTerm += StepRight->Numerator;

		if(StepRight->ErrorTerm >= StepRight->Denominator)
		{
			StepRight->x++;
			StepRight->uozf += StepRight->uozxtraf;
			StepRight->vozf += StepRight->vozxtraf;
			StepRight->ErrorTerm -= StepRight->Denominator;

			StepRight->rf += StepRight->rxtraf;
			StepRight->gf += StepRight->gxtraf;
			StepRight->bf += StepRight->bxtraf;
		}
	}
}


// EOF : ScanLinesTGAlphaAffine
