/*--------------------------------------------------------------------------
 * File: l_blit2d.c
 * Written by: Alexander Boczar, 1997-03-30
 * Description: "Blitter" for lookup color based drivers
 *
 * Updates:
 * -- Date -- | ----- Name ----- |-- Did what....
 * 1997-03-31 | Alexander Boczar | Fixade bug i storleks hanteringen
 * 1997-04-02 | Alexander Boczar | Snabbade upp innerloopen
 *
 * Todo:
 *
 * M”jlighet till transparency
 * Val av transparent f„rg.
 -------------------------------------------------------------------------------*/

#include "drivers/drv8.h"
#include "system/xmath.h"

void blit( BUFF *buff, XYZ p, BYTE *image, int *zimage, int width, int height)
{
	int sxs,ixs,xlen;
	int sys,iys,ylen;
	register int i,j;
	register BYTE c;
	register float z;
	BYTE *lighttab = buff->lighttab;
	BYTE *transtab = buff->transtab;
	BYTE *csrc;
  int *zsrc;
	BYTE *cdst;
  int *zdst;

	// Check X

	if ( p.x >= buff->minx )
	{
		sxs = (int)p.x;
		ixs = 0;
		if ( (p.x + width) <= buff->maxx)
			xlen = width;
		else
			xlen = buff->maxx - (int)p.x;
	}
	else
	{
		sxs = 0;
		ixs = buff->minx - (int)p.x;
		if ( (p.x + width) <= buff->maxx)
			xlen = ((int)p.x + width) - buff->minx;
		else
			xlen = buff->maxx - buff->minx;
	}

	// Check Y

	if ( p.y >= buff->miny )
	{
		sys = (int)p.y;
		iys = 0;
		if ( (p.y + height) <= buff->maxy)
			ylen = height;
		else
			ylen = buff->maxy - (int)p.y;
	}
	else
	{
		sys = 0;
		iys = buff->miny - (int)p.y;
		if ( (p.y + height) <= buff->maxy)
			ylen = ((int)p.y + height) - buff->miny;
		else
			ylen = buff->maxy - buff->miny;
	}


	if( buff->zbuffer != NULL)
	{
		if( zimage != NULL)
		{
			if( lighttab != NULL)
			{
				lighttab += fchop(p.l) << 8;
				if( transtab != NULL)
				{
					for ( j=0; j<ylen; j++) // ZB,ZI,L,T
					{
						csrc = &image[ ixs + width * (j + iys)];
						zsrc = &zimage[ ixs + width * (j + iys)];
						cdst = &buff->image[ sxs + buff->ytab[j + sys]];
						zdst = &buff->zbuffer[ sxs + buff->ytab[j + sys]];
						for ( i=0; i<xlen; i++)
						{
							c = *csrc;
							if ( c != 0)
							{
								c = lighttab[ c];
								z = *zsrc + p.z;
								if ( z > *zdst)
								{
									*cdst = transtab[ (c << 8) + *cdst];
									*zdst = z;
								}
							}
							csrc++;
							zsrc++;
							cdst++;
							zdst++;
						}
					}
				}
				else
				{
					for ( j=0; j<ylen; j++) // ZB,ZI,L
					{
						csrc = &image[ ixs + width * (j + iys)];
						zsrc = &zimage[ ixs + width * (j + iys)];
						cdst = &buff->image[ sxs + buff->ytab[j + sys]];
						zdst = &buff->zbuffer[ sxs + buff->ytab[j + sys]];
						for ( i=0; i<xlen; i++)
						{
							c = *csrc;
							if ( c != 0)
							{
								c = lighttab[ c];
								z = *zsrc + p.z;
								if ( z > *zdst)
								{
									*cdst = c;
									*zdst = z;
								}
							}
							csrc++;
							zsrc++;
							cdst++;
							zdst++;
						}
					}
				}
			}
			else
			{
				if( transtab != NULL)
				{
					for ( j=0; j<ylen; j++) // ZB,ZI,T
					{
						csrc = &image[ ixs + width * (j + iys)];
						zsrc = &zimage[ ixs + width * (j + iys)];
						cdst = &buff->image[ sxs + buff->ytab[j + sys]];
						zdst = &buff->zbuffer[ sxs + buff->ytab[j + sys]];
						for ( i=0; i<xlen; i++)
						{
							c = *csrc;
							if ( c != 0)
							{
								z = *zsrc + p.z;
								if ( z > *zdst)
								{
									*cdst = transtab[ (c << 8) + *cdst];
									*zdst = z;
								}
							}
							csrc++;
							zsrc++;
							cdst++;
							zdst++;
						}
					}
				}
				else
				{
					for ( j=0; j<ylen; j++) // ZB,ZI
					{
						csrc = &image[ ixs + width * (j + iys)];
						zsrc = &zimage[ ixs + width * (j + iys)];
						cdst = &buff->image[ sxs + buff->ytab[j + sys]];
						zdst = &buff->zbuffer[ sxs + buff->ytab[j + sys]];
						for ( i=0; i<xlen; i++)
						{
							c = *csrc;
							if ( c != 0)
							{
								z = *zsrc + p.z;
								if ( z > *zdst)
								{
									*cdst = c;
									*zdst = z;
								}
							}
							csrc++;
							zsrc++;
							cdst++;
							zdst++;
						}
					}
				}
			}
		}
		else
		{
			if( lighttab != NULL)
			{
				lighttab += fchop(p.l) << 8;
				if( transtab != NULL)
				{
					for ( j=0; j<ylen; j++) // ZB,L,T
					{
						csrc = &image[ ixs + width * (j + iys)];
						cdst = &buff->image[ sxs + buff->ytab[j + sys]];
						zdst = &buff->zbuffer[ sxs + buff->ytab[j + sys]];
						for ( i=0; i<xlen; i++)
						{
							c = *csrc;
							if ( c != 0)
							{
								c = lighttab[ c];
								if ( p.z > *zdst)
								{
									*cdst = transtab[ (c << 8) + *cdst];
									*zdst = p.z;
								}
							}
							csrc++;
							cdst++;
							zdst++;
						}
					}
				}
				else
				{
					for ( j=0; j<ylen; j++) // ZB,L
					{
						csrc = &image[ ixs + width * (j + iys)];
						cdst = &buff->image[ sxs + buff->ytab[j + sys]];
						zdst = &buff->zbuffer[ sxs + buff->ytab[j + sys]];
						for ( i=0; i<xlen; i++)
						{
							c = *csrc;
							if ( c != 0)
							{
								c = lighttab[ c];
								if ( p.z > *zdst)
								{
									*cdst = c;
									*zdst = p.z;
								}
							}
							csrc++;
							cdst++;
							zdst++;
						}
					}
				}
			}
			else
			{
				if( transtab != NULL)
				{
					for ( j=0; j<ylen; j++) // ZB,T
					{
						csrc = &image[ ixs + width * (j + iys)];
						cdst = &buff->image[ sxs + buff->ytab[j + sys]];
						zdst = &buff->zbuffer[ sxs + buff->ytab[j + sys]];
						for ( i=0; i<xlen; i++)
						{
							c = *csrc;
							if ( c != 0)
							{
								if ( p.z > *zdst)
								{
									*cdst = transtab[ (c << 8) + *cdst];
									*zdst = p.z;
								}
							}
							csrc++;
							cdst++;
							zdst++;
						}
					}
				}
				else
				{
					for ( j=0; j<ylen; j++) // ZB
					{
						csrc = &image[ ixs + width * (j + iys)];
						cdst = &buff->image[ sxs + buff->ytab[j + sys]];
						zdst = &buff->zbuffer[ sxs + buff->ytab[j + sys]];
						for ( i=0; i<xlen; i++)
						{
							c = *csrc;
							if ( c != 0)
							{
								if ( p.z > *zdst)
								{
									*cdst = c;
									*zdst = p.z;
								}
							}
							csrc++;
							cdst++;
							zdst++;
						}
					}
				}
			}
		}
	}
	else
	{
		if( lighttab != NULL)
		{
			lighttab += fchop(p.l) << 8;
			if( transtab != NULL)
			{
				for ( j=0; j<ylen; j++) // L,T
				{
					csrc = &image[ ixs + width * (j + iys)];
					cdst = &buff->image[ sxs + buff->ytab[j + sys]];
					for ( i=0; i<xlen; i++)
					{
						c = *csrc;
						if ( c != 0)
						{
							c = lighttab[ c];
							*cdst = transtab[ (c << 8) + *cdst];
						}
						csrc++;
						cdst++;
					}
				}
			}
			else
			{
				for ( j=0; j<ylen; j++) // L
				{
					csrc = &image[ ixs + width * (j + iys)];
					cdst = &buff->image[ sxs + buff->ytab[j + sys]];
					for ( i=0; i<xlen; i++)
					{
						c = *csrc;
						if ( c != 0)
						{
							c = lighttab[ c];
							*cdst = c;
						}
						csrc++;
						cdst++;
					}
				}
			}
		}
		else
		{
			if( transtab != NULL)
			{
				for ( j=0; j<ylen; j++) // T
				{
					csrc = &image[ ixs + width * (j + iys)];
					cdst = &buff->image[ sxs + buff->ytab[j + sys]];
					for ( i=0; i<xlen; i++)
					{
						c = *csrc;
						if ( c != 0)
							*cdst = transtab[ (c << 8) + *cdst];
						csrc++;
						cdst++;
					}
				}
			}
			else
			{
				for ( j=0; j<ylen; j++) //
				{
					csrc = &image[ ixs + width * (j + iys)];
					cdst = &buff->image[ sxs + buff->ytab[j + sys]];
					for ( i=0; i<xlen; i++)
					{
						c = *csrc;
						if ( c != 0)
							*cdst = c;
						csrc++;
						cdst++;
					}
				}
			}
		}
	}
}

