#include "CompostHeaders.hpp"
#include <MLR\MLRTexture.hpp>
#include <MLR\MLRTexturePool.hpp>

unsigned char FeatureGrid::depthColors[16][3] = {
	{0x00, 0x00, 0x00},
	{0x10, 0x20, 0xe0},
	{0x20, 0x40, 0xd0},
	{0x30, 0x60, 0xc0},
	{0x40, 0x80, 0xb0},
	{0x50, 0xa0, 0xa0},
	{0x60, 0xc0, 0x90},
	{0x70, 0xe0, 0x80},
	{0x80, 0xff, 0x70},
	{0x90, 0xc0, 0x60},
	{0xa0, 0xa0, 0x50},
	{0xb0, 0x80, 0x40},
	{0xc0, 0x60, 0x30},
	{0xd0, 0x40, 0x20},
	{0xe0, 0x20, 0x10},
	{0xff, 0x00, 0x00}
};

const int colorDepth = 4;

#undef BUG_HUNT
#undef USE_TRACE

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	FeatureInstance::LoadInstance(
		Stuff::MemoryStream *stream,
		FeaturePool *fp,
		int version
	)
{
	
	int index;
	*stream >> index;

	MString feature_name;
	if(version>5)
	{
		if(index>0)
		{

			*stream >> feature_name;
			feature_name.ToLower();

			index = feature_name.GetHashValue();
		}
		else
		{
			*stream >> index;
		}
	}

	unsigned short x, z;
	*stream >> x >> z;

	feature_x_pos = x;
	feature_z_pos = z;

	if(version>1)
	{
		*stream >> StatFlags >> Tag;
	}
	else
	{
		StatFlags=0;
		Tag=0;
	}


	if(version>2)
	{
		*stream >> texture_x_pos >> texture_z_pos;
	}
	else
	{
		texture_x_pos=texture_z_pos=0;
	}

	feature = fp->GetFeature(index);
	if(feature==NULL)
	{
		STOP(("Feature \"%s\" is missing", (const char *)feature_name));
	}

	position = fp->GetFeaturePosition(feature);

	if(feature->GetFeatureTexture()==NULL)
	{
		STOP(("In feature \"%s\" the feature texture is missing", (const char *)feature_name));
	}

	TexturePool::Instance->Load(feature->GetFeatureTexture());

	if(feature->GetFeatureMask0()!=NULL)
	{
		TexturePool::Instance->Load(feature->GetFeatureMask0());
	}
	if(feature->GetFeatureMask1()!=NULL)
	{
		TexturePool::Instance->Load(feature->GetFeatureMask1());
	}
}

void
	FeatureInstance::LoadInstance(
			Stuff::Page *inst_page,
			FeaturePool*fp,
			int version
		)
{
	const char *fet_name;

	inst_page->GetEntry("Feature",&fet_name);
	inst_page->GetEntry("XPos",&feature_x_pos);
	inst_page->GetEntry("ZPos",&feature_z_pos);
	inst_page->GetEntry("TextureXPos",&texture_x_pos);
	inst_page->GetEntry("TextureZPos",&texture_z_pos);
	int tflag,ttag;
	inst_page->GetEntry("StatFlags",&tflag); 
	inst_page->GetEntry("Tag",&ttag); 
	StatFlags=(unsigned char)tflag;
	Tag=(unsigned char)ttag;

	feature = fp->GetFeature(fet_name);
	Verify(feature);
	position = fp->GetFeaturePosition(feature);

	Verify(feature->GetFeatureTexture());
	TexturePool::Instance->Load(feature->GetFeatureTexture());

	if(feature->GetFeatureMask0()!=NULL)
	{
		TexturePool::Instance->Load(feature->GetFeatureMask0());
	}
	if(feature->GetFeatureMask1()!=NULL)
	{
		TexturePool::Instance->Load(feature->GetFeatureMask1());
	}


}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	FeatureInstance::SaveInstance(
		Stuff::MemoryStream *stream, int xoffset, int zoffset
	)
{
	if(feature->GetName()!=NULL)
	{
		Tool_Feature *tool_fet=(Tool_Feature *)feature;

		*stream << 1 << *tool_fet->GetName();
	}
	else
	{
		*stream << 0 << feature->GetIndex();
	}

	*stream	<< static_cast<unsigned short>(feature_x_pos-xoffset) << static_cast<unsigned short>(feature_z_pos-zoffset);
	*stream << StatFlags << Tag;
	*stream << texture_x_pos << texture_z_pos;
}

void
	FeatureInstance::SaveInstance(
		Stuff::Page *inst_page,int xoffset,int zoffset
		)
{
	Verify(feature->GetName()!=NULL);

	Tool_Feature *tool_fet=(Tool_Feature *)feature;

	int adjx,adjz;
	adjx=feature_x_pos-xoffset;
	adjz=feature_z_pos-zoffset;
	inst_page->SetEntry("Feature",*(tool_fet->GetName()));
	inst_page->SetEntry("XPos",adjx);
	inst_page->SetEntry("ZPos",adjz);
	inst_page->SetEntry("TextureXPos",texture_x_pos);
	inst_page->SetEntry("TextureZPos",texture_z_pos);

	int tflag,ttag;
	tflag=StatFlags;
	ttag=Tag;
	inst_page->SetEntry("StatFlags",tflag); 
	inst_page->SetEntry("Tag",ttag); 

}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	FeatureInstance::CalculateCurrentPtr(int x, int z, int downScale)
{
	countDownToBorder = 0;

	Check_Pointer(this);
	int flipMode = feature->GetFlipMode();

	int tex_x;
	int tex_z;
	int extraSize = 0;

	Verify(feature);

	if(feature->GetBlendMode()!=Feature::StretchMultiply && feature->GetBlendMode()!=Feature::StretchPaste)
	{
		Verify(feature->featureTexture);

		tex_x = ((x-feature_x_pos-texture_x_pos) >> downScale) & (feature->featureTexture->width_mask >> downScale);

		countDownToBorder = (feature->featureTexture->width >> downScale) - tex_x;

		tex_z = ((z-feature_z_pos-texture_z_pos) >> downScale) & (feature->featureTexture->height_mask >> downScale);

		if(flipMode & Feature::Flip_Mode::Texture_Vertical_Flip)
		{
			tex_z = (feature->featureTexture->height >> downScale) - tex_z;
			tex_z--;
		}

		if(flipMode & Feature::Flip_Mode::Texture_Horizontal_Flip)
		{
			tex_x = (feature->featureTexture->width >> downScale) - tex_x;
			tex_x--;
		}

		if(downScale==1)
		{
			extraSize = feature->featureTexture->depth*(feature->featureTexture->width+2)*(feature->featureTexture->height+2);
		}
		if(downScale==2)
		{
			extraSize = feature->featureTexture->depth*(feature->featureTexture->width+2)*(feature->featureTexture->height+2) + 
						feature->featureTexture->depth*(feature->featureTexture->width/2+2)*(feature->featureTexture->height/2+2);
		}

		currentTexturePtr = feature->featureTexture->data + extraSize +
							feature->featureTexture->depth*((tex_z+1)*( (feature->featureTexture->width >> downScale)+2) + tex_x + 1);
				
#ifdef LAB_ONLY
		if(!(currentTexturePtr>=feature->featureTexture->data && currentTexturePtr<=feature->featureTexture->data+feature->featureTexture->dataSize))
		{
			return false;
		}
#endif
	}
	if(feature->featureMask0!=NULL)
	{
		if(feature->GetBlendMode()!=Feature::Blend555_1_S)
		{
			int mask0_x = (x-feature_x_pos) >> feature->GetXMask0Scale();
			int mask0_z = (z-feature_z_pos) >> feature->GetZMask0Scale();
			mask0_x_off = (x-feature_x_pos) & ((1<<feature->GetXMask0Scale())-1);
			mask0_z_off = (z-feature_z_pos) & ((1<<feature->GetZMask0Scale())-1);

	//		Verify(mask0_x<feature->featureMask0->width+1);
	//		Verify(mask0_z<feature->featureMask0->height+1);

#ifdef LAB_ONLY
			if(! (mask0_x<feature->featureMask0->width) )
			{
//				SPEW(("micgaert", "Whats going on in here ?"));
				return false;
			}
			if(! (mask0_z<feature->featureMask0->height) )
			{
//				SPEW(("micgaert", "Whats going on in here ?"));
				return false;
			}
#endif

			if(flipMode & Feature::Flip_Mode::Mask0_Vertical_Flip)
			{
				mask0_z = feature->featureMask0->height - mask0_z;
				mask0_z -= 1;
				
				mask0_z_off = (1<<feature->GetZMask0Scale()) - 1 - mask0_z_off;
			}

			if(flipMode & Feature::Flip_Mode::Mask0_Horizontal_Flip)
			{
				mask0_x = feature->featureMask0->width - mask0_x;
				mask0_x -= 1;
				
				mask0_x_off = (1<<feature->GetXMask0Scale()) - 1 - mask0_x_off;
			}

			currentMask0Ptr = feature->featureMask0->data + feature->featureMask0->depth*((mask0_z+1)*(feature->featureMask0->width+2) + mask0_x + 1);

#ifdef LAB_ONLY
			
			if(!(currentMask0Ptr>=feature->featureMask0->data &&
				currentMask0Ptr+feature->featureMask0->width + 3<=feature->featureMask0->data+feature->featureMask0->dataSize))
			{
				return false;
			}
#endif
		}
		else
		{

			if(downScale==1)
			{
				extraSize = feature->featureMask0->depth*(feature->featureMask0->width+2)*(feature->featureMask0->height+2);
			}
			if(downScale==2)
			{
				extraSize = feature->featureMask0->depth*(feature->featureMask0->width+2)*(feature->featureMask0->height+2) + 
							feature->featureMask0->depth*(feature->featureMask0->width/2+2)*(feature->featureMask0->height/2+2);
			}

			int  mask0_x = ((x-feature_x_pos) >> downScale) & (feature->featureMask0->width_mask >> downScale);
			int mask0_z = ((z-feature_z_pos) >> downScale) & (feature->featureMask0->height_mask >> downScale);

			if(flipMode & Feature::Flip_Mode::Mask0_Vertical_Flip)
			{
				mask0_z = (feature->featureMask0->height >> downScale) - mask0_z;
				mask0_z -= 1;
			}

			if(flipMode & Feature::Flip_Mode::Mask0_Horizontal_Flip)
			{
				mask0_x = (feature->featureMask0->width >> downScale) - mask0_x;
				mask0_x -= 1;
			}
			
			currentMask0Ptr = feature->featureMask0->data + extraSize +
							feature->featureMask0->depth*((mask0_z+1)*( (feature->featureMask0->width >> downScale)+2) + mask0_x + 1);

#ifdef LAB_ONLY
			if(!(currentMask0Ptr>=feature->featureMask0->data && currentMask0Ptr<=feature->featureMask0->data+feature->featureMask0->dataSize))
			{
				return false;
			}
#endif
		}
	}

	if(feature->featureMask1!=NULL)
	{
		int mask1_x = (x-feature_x_pos) >> feature->GetXMask1Scale();
		int mask1_z = (z-feature_z_pos) >> feature->GetZMask1Scale();
		mask1_x_off = (x-feature_x_pos) & ((1<<feature->GetXMask1Scale())-1);
		mask1_z_off = (z-feature_z_pos) & ((1<<feature->GetZMask1Scale())-1);

		Verify(mask1_x<feature->featureMask1->width+1);
		Verify(mask1_z<feature->featureMask1->height+1);

		if(flipMode & Feature::Flip_Mode::Mask1_Vertical_Flip)
		{
			mask1_z = feature->featureMask1->height - mask1_z;
			mask1_z -= 1;
			
			mask1_z_off = (1<<feature->GetZMask1Scale()) - 1 - mask1_z_off;
		}

		if(flipMode & Feature::Flip_Mode::Mask1_Horizontal_Flip)
		{
			mask1_x = feature->featureMask1->width - mask1_x;
			mask1_x -= 1;
			
			mask1_x_off = (1<<feature->GetXMask0Scale()) - 1 - mask1_x_off;
		}

		currentMask1Ptr = feature->featureMask1->data + feature->featureMask1->depth*((mask1_z+1)*(feature->featureMask1->width+2) + mask1_x + 1);

#ifdef LAB_ONLY
		if(!(currentMask1Ptr>=feature->featureMask1->data && currentMask1Ptr<=feature->featureMask1->data+feature->featureMask1->dataSize))
		{
			return false;
		}
#endif
	}
	return true;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/*
void
	FeatureInstance::AdvanceCurrentPtr()
{
	int flipMode = feature->GetFlipMode();

	if(flipMode & Feature::Flip_Mode::Texture_Horizontal_Flip)
	{
		currentTexturePtr -= feature->featureTexture->depth;
	}
	else
	{
		currentTexturePtr += feature->featureTexture->depth;
	}

	if(feature->featureMask0!=NULL)
	{
		if(flipMode & Feature::Flip_Mode::Mask0_Horizontal_Flip)
		{
			if(--mask0_x_off < 0)
			{
				mask0_x_off = (1<<feature->GetXMask0Scale()) - 1;
				currentMask0Ptr -= feature->featureMask0->depth;
			}
		}
		else
		{
			if(++mask0_x_off & ~((1<<feature->GetXMask0Scale())-1))
			{
				mask0_x_off = 0;
				currentMask0Ptr += feature->featureMask0->depth;
			}
		}
	}

	if(feature->featureMask1!=NULL)
	{
		if(flipMode & Feature::Flip_Mode::Mask1_Horizontal_Flip)
		{
			if(--mask1_x_off < 0)
			{
				mask1_x_off = (1<<feature->GetXMask1Scale()) - 1;
				currentMask1Ptr -= feature->featureMask1->depth;
			}
		}
		else
		{
			if(++mask1_x_off & ~((1<<feature->GetXMask1Scale())-1))
			{
				mask1_x_off = 0;
				currentMask1Ptr += feature->featureMask1->depth;
			}
		}
	}
}
*/

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
FeatureInstance&
	FeatureInstance::operator=(FeatureInstance& fi)
{
	feature = fi.feature;

	feature_x_pos= fi.feature_x_pos;
	feature_z_pos= fi.feature_z_pos;
	position= fi.position;

	return *this;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
EdgeListPlug::EdgeListPlug()
{
	x_pos_start = 0;
	x_pos_end = 0;
	z_pos = 0;
	count = 0;
	featureInstance = NULL;
	key = false;
	next = NULL;
	prev = NULL;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
EdgeListPlug::~EdgeListPlug()
{
	if(next!=NULL)
	{
		Unregister_Pointer(next);
		delete next;
		next = NULL;
		prev = NULL;
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	EdgeListPlug::AddUp(FeatureInstance *fi, int row, int column, int gridSize)
{
	count = (fi->feature->GetFeatureHeight());

	int k = fi->feature_x_pos-gridSize*column;
	x_pos_start = (k<0 ? 0 : k);

	k = fi->feature_x_pos-gridSize*column+fi->feature->GetFeatureWidth();

	if(k>gridSize)
	{
		x_pos_end = gridSize;
	}
	else
	{
		x_pos_end = (k<0 ? 0:k);
	}

	if(x_pos_start==x_pos_end)
	{
		return false;
	}

	k = fi->feature_z_pos-gridSize*row;

	if(k<0)
	{
		count = (count + k);
		z_pos = 0;
	}
	else
	{
		z_pos = (k);
	}

	if(z_pos+count > gridSize)
	{
		count = (gridSize - z_pos);
	}

	if(count==0)
	{
		return false;
	}

	featureInstance = fi;
	key = true;

	return true;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	TextureHolder::ShutDown()
{
	if(textureHandle>0)
	{
		MidLevelRenderer::MLRTexture *texture = (*MidLevelRenderer::MLRTexturePool::Instance)[textureHandle];
		if(texture!=NULL)
		{
			MidLevelRenderer::GOSImage *image = texture->GetImage();

			image->UnlockImage();
		}
		textureHandle = -1;
	}

	if(aelp!=NULL)
	{
		aelp_ptr = aelp;

		
		while(aelp_ptr->next!=NULL)
		{
			aelp_ptr = aelp_ptr->next;
		}

		while(aelp_ptr->prev!=NULL)
		{
			taelp = aelp_ptr->prev;

			Unregister_Pointer(aelp_ptr);
			delete aelp_ptr;

			aelp_ptr = taelp;
			aelp_ptr->next = NULL;
		}
		Unregister_Pointer(aelp_ptr);
		delete aelp_ptr;
		aelp_ptr = NULL;

		aelp = NULL;
	}

	flags = Free;

	lastLine = -1;
	pix_dest = NULL;

	linesToProcess = 16;

	elp = NULL;
	nextLineElp = NULL;

	aelp_ptr = NULL;
	taelp = NULL;

	return true;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
FeatureGrid::FeatureGrid(int c, int r, FeaturePool *f, bool hires)
{
	Verify(gos_GetCurrentHeap() == Heap);
	featurePool = f;

	columns = c;
	rows = r;

	int i;

	if(hires==false)
	{
		gridSize = 256;
		gridSizeShift = 8;
	}
	else
	{
		gridSize = 512;
		gridSizeShift = 9;
	}
		
	featureInstance = new DynamicArrayOf<FeatureInstance*> [rows*columns];
	Register_Pointer(featureInstance);
	for(i=0;i<rows*columns;i++)
	{
		featureInstance[i].SetLength(0);
	}

	edgeList.SetLength(rows*columns);
	for(i=0;i<rows*columns;i++)
	{
		edgeList[i] = NULL;
	}

	max = 100;
	used = 0;

	uniqueFeatureInstance.SetLength(max);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
FeatureGrid::FeatureGrid(Stuff::MemoryStream *stream, FeaturePool *f)
{
	Verify(gos_GetCurrentHeap() == Heap);
	featurePool = f;

	LoadGrid(stream);
}

FeatureGrid::FeatureGrid(Stuff::NotationFile *note_file, FeaturePool*f)
{
	Verify(gos_GetCurrentHeap() == Heap);
	featurePool = f;

	LoadGrid(note_file);

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
FeatureGrid::~FeatureGrid()
{
	int i;

	for(i=0;i<used;i++)
	{
		Unregister_Pointer(uniqueFeatureInstance[i]);
		delete uniqueFeatureInstance[i];
		uniqueFeatureInstance[i] = NULL;
	}
	uniqueFeatureInstance.SetLength(0);

	for(i=0;i<rows*columns;i++)
	{
		featureInstance[i].SetLength(0);

		if(edgeList[i] != NULL)
		{
			Unregister_Pointer(edgeList[i]);
			delete edgeList[i];
			edgeList[i] = NULL;
		}
	}

	Unregister_Pointer(featureInstance);
	delete [] featureInstance;
	featureInstance = NULL;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	FeatureGrid::LoadGrid(
		Stuff::MemoryStream *stream
	)
{
	Verify(gos_GetCurrentHeap() == Heap);
	int version;

	*stream >> version;

	if(version<6)
	{
		STOP(("The current fgd-file is a version lower than 6. Not supported anymore ! Content error !"));
	}

	if(version>0)
	{
		*stream >> gridSizeShift;
	}
	else
	{
		gridSizeShift = 8;
	}
	gridSize = 1<<gridSizeShift;

	*stream >> rows >> columns >> used;

	max = 100*(1+(used/100));
	int i;
	featureInstance = new DynamicArrayOf<FeatureInstance*> [rows*columns];
	Register_Pointer(featureInstance);

	edgeList.SetLength(rows*columns);
	for(i=0;i<rows*columns;i++)
	{
		edgeList[i] = NULL;
	}

	uniqueFeatureInstance.SetLength(max);

	for(i=0;i<used;i++)
	{
		uniqueFeatureInstance[i] = new FeatureInstance();
		Register_Pointer(uniqueFeatureInstance[i]);
		uniqueFeatureInstance[i]->LoadInstance(stream, featurePool, version);
	}
	for(;i<max;i++)
	{
		uniqueFeatureInstance[i] = NULL;
	}

	LoadGridFromUnique();
}



void
	FeatureGrid::LoadGrid(Stuff::NotationFile *note_file)
{
	Verify(gos_GetCurrentHeap() == Heap);
	int version;

	Stuff::Page *page=note_file->GetPage("FeatureGrid");
	Check_Object(page);

	page->GetEntry("CompostVersion",&version);
	page->GetEntry("GridShift",&gridSizeShift);
	page->GetEntry("Rows",&rows);
	page->GetEntry("Columns",&columns);
	page->GetEntry("InstanceCount",&used);

	NotationFile instance_list;
	page->GetEntry("Instances",&instance_list);

	gridSize = 1<<gridSizeShift;
	max = 100*(1+(used/100));
	featureInstance = new DynamicArrayOf<FeatureInstance*> [rows*columns];
	Register_Pointer(featureInstance);

	edgeList.SetLength(rows*columns);
	int i;
	for(i=0;i<rows*columns;i++)
	{
		edgeList[i] = NULL;
	}

	uniqueFeatureInstance.SetLength(max);

	NotationFile::PageIterator *page_list=instance_list.MakePageIterator();
	Check_Object(page_list);
	Page *inst_page;	
	i=0;
	while((inst_page = page_list->ReadAndNext()) != NULL)
	{
		Check_Object(inst_page);
		uniqueFeatureInstance[i] = new FeatureInstance();
		Register_Pointer(uniqueFeatureInstance[i]);
		uniqueFeatureInstance[i]->LoadInstance(inst_page, featurePool, version);
		i++;
	}

	for(;i<max;i++)
	{
		uniqueFeatureInstance[i] = NULL;
	}

	LoadGridFromUnique();
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	FeatureGrid::SaveGrid(
		Stuff::MemoryStream *stream,int xoffset,int zoffset
	)
{
	*stream << static_cast<int>(Current_Compost_Version);
	*stream << gridSizeShift << rows << columns << used;

	int i;

	for(i=0;i<used;i++)
	{
		uniqueFeatureInstance[i]->SaveInstance(stream,xoffset,zoffset);
	}
}

void
	FeatureGrid::SaveGrid(
			Stuff::NotationFile *note_file,int xoffset,int zoffset
			)
{
	Stuff::Page *page=note_file->SetPage("FeatureGrid");
	Check_Object(page);
	page->SetEntry("CompostVersion",Current_Compost_Version);
	page->SetEntry("GridShift",gridSizeShift);
	page->SetEntry("Rows",rows);
	page->SetEntry("Columns",columns);
	page->SetEntry("InstanceCount",used);

	NotationFile instance_list;
	Page *inst_page;	
	char buffer[64];

	int i;
	MString str;
	for(i=0;i<used;i++)
	{
		sprintf(buffer,"FeatureInstance%04i",i);
		inst_page=instance_list.SetPage(buffer);
		uniqueFeatureInstance[i]->SaveInstance(inst_page,xoffset,zoffset);
	}

	page->SetEntry("Instances",&instance_list);
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
FeatureInstance *
	FeatureGrid::Add(Feature* feature, unsigned short x_pos, unsigned short z_pos)
{
	Verify(gos_GetCurrentHeap() == Heap);
	FeatureInstance *fI = new FeatureInstance;
	Register_Pointer(fI);
	
	fI->feature = feature;
	fI->feature_x_pos = x_pos;
	fI->feature_z_pos = z_pos;
	fI->position = featurePool->GetFeaturePosition(feature);

	if(used>=max)
	{
		max+=100;
		uniqueFeatureInstance.SetLength(max);
	}
	uniqueFeatureInstance[used++] = fI;
	Verify(TexturePool::Instance);

	Verify(fI->feature->GetFeatureTexture());
	TexturePool::Instance->Load(fI->feature->GetFeatureTexture());
	if(fI->feature->GetFeatureMask0())
		TexturePool::Instance->Load(fI->feature->GetFeatureMask0());
	if(fI->feature->GetFeatureMask1())
		TexturePool::Instance->Load(fI->feature->GetFeatureMask1());

	RedoFeaturePosition();
	LoadEdgeListFromGrid();

	return fI;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	FeatureGrid::Remove(FeatureInstance* feature)
{
	int i;

	for(i=0;i<used;i++)
	{
		if(uniqueFeatureInstance[i]==feature)
		{
			break;
		}
	}
	if(i<used)
	{
		Unregister_Pointer(feature);

		for(;i<used-1;i++)
		{
			uniqueFeatureInstance[i] = uniqueFeatureInstance[i+1];
		}
		used--;
	}

	LoadGridFromUnique();
	LoadEdgeListFromGrid();
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	FeatureGrid::LoadGridFromUnique()
{
	Verify(gos_GetCurrentHeap() == Heap);
	int i, j, k, len;
	int r_start, r_end, c_start, c_end;

	for(j=0;j<rows;j++)
	{
		for(i=0;i<columns;i++)
		{
			featureInstance[j*columns+i].SetLength(0);
		}
	}

	for(k=0;k<used;k++)
	{
		r_start = uniqueFeatureInstance[k]->feature_z_pos>>gridSizeShift;
		r_start = r_start<0 ? 0 : r_start;
		r_end = ((uniqueFeatureInstance[k]->feature_z_pos + uniqueFeatureInstance[k]->feature->feature_height)>>gridSizeShift)+1;
		r_end = r_end>rows ? rows : r_end;
		c_start = uniqueFeatureInstance[k]->feature_x_pos>>gridSizeShift;
		c_start = c_start<0 ? 0 : c_start;
		c_end = ((uniqueFeatureInstance[k]->feature_x_pos + uniqueFeatureInstance[k]->feature->feature_width)>>gridSizeShift)+1;
		c_end = c_end>columns ? columns : c_end;
		
		for(j=r_start;j<r_end;j++)
		{
			for(i=c_start;i<c_end;i++)
			{
				len = featureInstance[j*columns+i].GetLength();
				featureInstance[j*columns+i].SetLength(len+1);

				featureInstance[j*columns+i][len] = uniqueFeatureInstance[k];
			}
		}
	}
	for(j=0;j<rows;j++)
	{
		for(i=0;i<columns;i++)
		{
			len = featureInstance[j*columns+i].GetLength();

			// do a shell sort

			int ii, jj, hh;

			FeatureInstance *tempFeatureInstance;
			Stuff::DynamicArrayOf<FeatureInstance*>
				*featureInstanceArray;

			featureInstanceArray = &featureInstance[j*columns+i];

			for(hh=1;hh<len/9;hh=3*hh+1);

			for(;hh>0;hh/=3)
			{
				for(ii=hh;ii<len;ii++)
				{
					tempFeatureInstance = (*featureInstanceArray)[ii];

					jj = ii;

					while(jj>=hh && (*featureInstanceArray)[jj-hh]->position > tempFeatureInstance->position)
					{
						(*featureInstanceArray)[jj] = (*featureInstanceArray)[jj-hh];
						jj -= hh;
					}
					(*featureInstanceArray)[jj] = tempFeatureInstance;
				}
			}
		}
	}
	LoadEdgeListFromGrid();
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	FeatureGrid::LoadGridFromUnique(int row, int column)
{
	Verify(gos_GetCurrentHeap() == Heap);
	int k, len;
	int r_start, r_end, c_start, c_end;

	featureInstance[row*columns+column].SetLength(0);

	for(k=0;k<used;k++)
	{
		r_start = uniqueFeatureInstance[k]->feature_z_pos>>gridSizeShift;
		r_start = r_start<0 ? 0 : r_start;
		r_end = ((uniqueFeatureInstance[k]->feature_z_pos + uniqueFeatureInstance[k]->feature->feature_height)>>gridSizeShift)+1;
		r_end = r_end>rows ? rows : r_end;
		c_start = uniqueFeatureInstance[k]->feature_x_pos>>gridSizeShift;
		c_start = c_start<0 ? 0 : c_start;
		c_end = ((uniqueFeatureInstance[k]->feature_x_pos + uniqueFeatureInstance[k]->feature->feature_width)>>gridSizeShift)+1;
		c_end = c_end>rows ? columns : c_end;
		
		if(row>=r_start && row<r_end && column>=c_start && column<c_end)
		{
			len = featureInstance[row*columns+column].GetLength();
			featureInstance[row*columns+column].SetLength(len+1);

			featureInstance[row*columns+column][len] = uniqueFeatureInstance[k];
		}
	}

	len = featureInstance[row*columns+column].GetLength();

	// do a shell sort

	int ii, jj, hh;

	FeatureInstance *tempFeatureInstance;
	Stuff::DynamicArrayOf<FeatureInstance*>
		*featureInstanceArray;

	featureInstanceArray = &featureInstance[row*columns+column];

	for(hh=1;hh<len/9;hh=3*hh+1);

	for(;hh>0;hh/=3)
	{
		for(ii=hh;ii<len;ii++)
		{
			tempFeatureInstance = (*featureInstanceArray)[ii];

			jj = ii;

			while(jj>=hh && (*featureInstanceArray)[jj-hh]->position > tempFeatureInstance->position)
			{
				(*featureInstanceArray)[jj] = (*featureInstanceArray)[jj-hh];
				jj -= hh;
			}
			(*featureInstanceArray)[jj] = tempFeatureInstance;
		}
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	FeatureGrid::LoadEdgeListFromGrid()
{
	Verify(gos_GetCurrentHeap() == Heap);
	int i, j, k, len, index;

	for(j=0;j<rows;j++)
	{
		for(i=0;i<columns;i++)
		{
			index = j*columns+i;

			if(edgeList[index]!=NULL)
			{
				Unregister_Pointer(edgeList[index]);
				delete edgeList[index];
				edgeList[index] = NULL;
			}

			len = featureInstance[index].GetLength();

			if(len==0)
			{
				continue;
			}

			edgeList[index] = new EdgeListPlug;
			Register_Pointer(edgeList[index]);

			bool addUpKey = false;
			addUpKey = edgeList[index]->AddUp(featureInstance[index][0], j, i, gridSize);

			Verify(addUpKey==true);	//	Background should be always there and cover everything

			EdgeListPlug *elp = NULL, *elp_ptr;
			for(k=1;k<len;k++)
			{
				elp = new EdgeListPlug;
				Register_Pointer(elp);

				while(k<len && !elp->AddUp(featureInstance[index][k], j, i, gridSize))
				{
					k++;
				}

				if(k==len)
				{
					Unregister_Pointer(elp);
					delete elp;
					break;
				}

				elp_ptr = edgeList[index];
				if(elp_ptr->z_pos>elp->z_pos)
				{
					elp->next = elp_ptr;
					elp_ptr->prev = elp;
					edgeList[index] = elp;
				}
				else
				{
					while(elp_ptr->next!=NULL && elp_ptr->next->z_pos<=elp->z_pos)
					{
						elp_ptr = elp_ptr->next;
					}
					if(elp_ptr->next==NULL)
					{
						elp_ptr->next = elp;
						elp->prev = elp_ptr;
					}
					else
					{
						elp->next = elp_ptr->next;
						elp->next->prev = elp;
						elp->prev = elp_ptr;
						elp_ptr->next = elp;
					}
				}
			}
		}
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	FeatureGrid::RedoFeaturePosition()
{
	for(int k=0;k<used;k++)
	{
		uniqueFeatureInstance[k]->position = featurePool->GetFeaturePosition(uniqueFeatureInstance[k]->feature);
	}
	LoadGridFromUnique();
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
	FeatureGrid::ShootRay(unsigned short x, unsigned short z)
{
	int hit=0;
	int row = z>>gridSizeShift;
	int column = x>>gridSizeShift; 
	
	if(rows*columns<=(row*columns+column))
		return 0;

	int k, used = featureInstance[row*columns+column].GetLength();

	FeatureInstance **f = &featureInstance[row*columns+column][0];

	if(*f==NULL)
	{
		return 0;
	}
	for(k=0;k<used;k++,f++)
	{
		if(	(*f)->feature_x_pos<=x && (*f)->feature_x_pos+(*f)->feature->feature_width>=x &&
			(*f)->feature_z_pos<=z && (*f)->feature_z_pos+(*f)->feature->feature_height>=z
		)
		{
			Verify(hit<MAX_NUMBER_LAYERS);
			rayCollect[hit++] = *f;
		}
	}

	return hit;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
	FeatureGrid::ShootRectangle(
		DynamicArrayOf<FeatureInstance*>& list,
		unsigned short x, 
		unsigned short z,
		unsigned short width,
		unsigned short height
	)
{
	Verify(gos_GetCurrentHeap() == Heap);
	int i, j, k, l, r_start, r_end, c_start, c_end, len = 0, count = 0;

	r_start = z>>gridSizeShift;
	r_start = r_start<0 ? 0 : r_start;

	r_end = ((z+height)>>gridSizeShift)+1;
	r_end = r_end>rows ? rows : r_end;

	c_start = x>>gridSizeShift;
	c_start = c_start<0 ? 0 : c_start;

	c_end = ((x+width)>>gridSizeShift)+1;
	c_end = c_end>columns ? columns : c_end;
	
	for(j=r_start;j<r_end;j++)
	{
		for(i=c_start;i<c_end;i++)
		{
			len += featureInstance[j*columns+i].GetLength();
		}
	}

	list.SetLength(len);

	for(j=r_start;j<r_end;j++)
	{
		for(i=c_start;i<c_end;i++)
		{
			len = featureInstance[j*columns+i].GetLength();

			for(k=0;k<len;k++)
			{
				FeatureInstance *fI = featureInstance[j*columns+i][k];
				if(
					fI->feature_x_pos >= x &&
					fI->feature_z_pos >= z &&
					(fI->feature_x_pos + fI->feature->feature_width) <= (x + width)&&
					(fI->feature_z_pos + fI->feature->feature_height) <= (z + height)
				)
				{
					for(l=0;l<count;l++)
					{
						if(fI==list[l])
						{
							break;
						}
					}
					if(l==count)
					{
						list[count++] = fI;
					}
				}
			}
		}
	}

	list.SetLength(count);

	return count;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int 
	FeatureGrid::CountFeature(Feature *f)
{
	int i, j, k, len, count = 0;

	for(j=0;j<rows;j++)
	{
		for(i=0;i<columns;i++)
		{
			len = featureInstance[j*columns+i].GetLength();

			for(k=0;k<len;k++)
			{
				if(f == featureInstance[j*columns+i][k]->feature)
				{
					count++;
				}
			}
		}
	}

	return count;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	FeatureGrid::AddToRayCollect(FeatureInstance *fi, unsigned short& count)
{
//	SPEW(("micgaert", "Add: 0x%x", fi));
	int k, l;

	for(k=0;k<count;k++)
	{
		if(rayCollect[k]->position > fi->position)
		{
			break;
		}
	}

	for(l=count;l>k;l--)
	{
		rayCollect[l] = rayCollect[l-1];
	}

	rayCollect[k] = fi;
	count++;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	FeatureGrid::DeleteFromRayCollect(FeatureInstance *fi, unsigned short& count)
{
//	SPEW(("micgaert", "Delete: 0x%x", fi));
	for(int k=0;k<count;k++)
	{
		if(rayCollect[k]==fi)
		{
			break;
		}
	}

	Verify(k<count);

	for(;k<count-1;k++)
	{
		rayCollect[k] = rayCollect[k+1];
	}
	count--;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	FeatureGrid::AddToActiveEdgeList(ActiveEdgeListPlug **list, EdgeListPlug *plug)
{
	Verify(gos_GetCurrentHeap() == Heap);
	ActiveEdgeListPlug *aelp_ptr = NULL;
	ActiveEdgeListPlug *taelp = new ActiveEdgeListPlug;
	Register_Pointer(taelp);
			
	taelp->elp = plug;
	taelp->counter = plug->count;
			
	if(*list!=NULL)
	{
		aelp_ptr = *list;

		while(aelp_ptr->next!=NULL && aelp_ptr->next->elp->featureInstance->position<taelp->elp->featureInstance->position)
		{
			aelp_ptr = aelp_ptr->next;
		}

		if(aelp_ptr->next==NULL)
		{
			aelp_ptr->next = taelp;
			taelp->prev = aelp_ptr;
		}
		else
		{
			taelp->next = aelp_ptr->next;
			taelp->next->prev = taelp;

			aelp_ptr->next = taelp;
			taelp->prev = aelp_ptr;
		}
	}
	else
	{
		*list = taelp;
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	FeatureGrid::ComposeGrid(
		int row,
		int column,
		unsigned char *dest,
		int downScale,
		int type
	)
{
	Verify(downScale>=0 && downScale<3);

	if(!(row>=0 && row<rows))
	{
		return false;
	}
	if(!(column>=0 && column<columns))
	{
		return false;
	}

	int i, j, count;
	int used;
	int start_i = column<<gridSizeShift;
	int start_j = row<<gridSizeShift;

	used = featureInstance[row*columns+column].GetLength();

	if(used==0)
	{
		return false;
	}

	EdgeListPlug *elp = edgeList[row*columns+column];
	EdgeListPlug *nextLineElp = elp;

	ActiveEdgeListPlug *aelp = NULL, *aelp_ptr = NULL, *taelp = NULL;

	unsigned char pixel_buffer[512*colorDepth];

//	memset(pixel_buffer,512*colorDepth,0);
	
	unsigned char *pix_buf = NULL;
	unsigned char *pix_dest = dest;

	int lineMask = (1<<downScale) - 1;

#ifdef BUG_HUNT
	SPEW(("micgaert", "Row: %d Col: %d", row, column));
#endif

	for(j=0;j<gridSize;j++)
	{
#ifdef BUG_HUNT
		SPEW(("micgaert", "==="));
#endif
		while(nextLineElp!=NULL && nextLineElp->z_pos == j)
		{
			AddToActiveEdgeList(&aelp, nextLineElp);

			nextLineElp = nextLineElp->next;
		}
	
		if((j & lineMask) == 0)
		{
			pix_buf = pixel_buffer;

			if(aelp==NULL)
			{
				for(i=0;i<gridSize*colorDepth;i++)
				{
					*pix_buf++ = 0;
				}
			}
			else
			{
				aelp_ptr = aelp;
				
				count = 0;
//				memset(pixel_buffer, 0, 512*colorDepth);
				while(aelp_ptr!=NULL)
				{
#ifdef BUG_HUNT
					SPEW(("micgaert", "---"));
#endif
					int start_span, end_span;

					start_span = aelp_ptr->elp->x_pos_start;
					end_span = aelp_ptr->elp->x_pos_end;
					pix_buf = pixel_buffer + colorDepth*(start_span>>downScale);

					Feature *feature;

					switch(type)
					{
						case 0:
						{
							feature = aelp_ptr->elp->featureInstance->feature;
							
	#ifdef LAB_ONLY
							if(!
	#endif
								aelp_ptr->elp->featureInstance->CalculateCurrentPtr(start_span+start_i, j+start_j, downScale)
	#ifdef LAB_ONLY
							)
							{
								start_span >>= downScale;
								end_span >>= downScale;

								for(i=start_span;i<end_span;i++)
								{
									*pix_buf = 0xff;
									*(pix_buf+1) = 0;
									*(pix_buf+2) = 0;

									pix_buf += colorDepth;
								}
								aelp_ptr = aelp_ptr->next;
								continue;
							}
	#else
							;
	#endif

							unsigned char *data_ptr = aelp_ptr->elp->featureInstance->currentTexturePtr;
							int depth = 1;

							start_span >>= downScale;
							end_span >>= downScale;

							switch(
								feature->GetBlendMode() | 
								(feature->GetFlipMode() & ~(
									Feature::Flip_Mode::Texture_Vertical_Flip |
									Feature::Flip_Mode::Mask0_Vertical_Flip |
									Feature::Flip_Mode::Mask1_Vertical_Flip
									)
								)
							)
							{
								case Feature::Blend_Mode::Paste:
								{
									depth = feature->featureTexture->depth;
									int texture_width = depth * ((aelp_ptr->elp->featureInstance->feature->featureTexture->width) >> downScale);
									int count_down = aelp_ptr->elp->featureInstance->countDownToBorder;

									for(i=start_span;i<end_span;i++)
									{
										*pix_buf = static_cast<unsigned char>((*data_ptr & 0x1f) << 3);
										*(pix_buf+1) = static_cast<unsigned char>((*(int *)data_ptr & 0x3e0) >> 2);
										*(pix_buf+2) = static_cast<unsigned char>((*(int *)data_ptr) >> 7);

										pix_buf += colorDepth;

										data_ptr += depth;

										if(--count_down <= 0)
										{
											data_ptr -= texture_width;
											count_down = texture_width;
										}
									}
								}
								break;
								case Feature::Blend_Mode::Paste | Feature::Flip_Mode::Texture_Horizontal_Flip:
								{
									depth = feature->featureTexture->depth;
									int texture_width = depth * ((aelp_ptr->elp->featureInstance->feature->featureTexture->width) >> downScale);
									int count_down = aelp_ptr->elp->featureInstance->countDownToBorder;

									for(i=start_span;i<end_span;i++)
									{
										*pix_buf = static_cast<unsigned char>((*data_ptr & 0x1f) << 3);
										*(pix_buf+1) = static_cast<unsigned char>((*(int *)data_ptr & 0x3e0) >> 2);
										*(pix_buf+2) = static_cast<unsigned char>((*(int *)data_ptr) >> 7);

										pix_buf += colorDepth;

										data_ptr -= depth;

										if(--count_down <= 0)
										{
											data_ptr += texture_width;
											count_down = texture_width;
										}
									}
								}
								break;
								case Feature::Blend_Mode::Added:
								{
									depth = feature->featureTexture->depth;
									WORD *data_ptr_word = (WORD *)data_ptr;
									for(i=0;i<end_span-start_span;i++)
									{
										int col = *pix_buf + ((data_ptr_word[i] & 0x1f) << 3);
										*pix_buf = static_cast<unsigned char>((col & 0xffffff00) ? 0xff : col);

										col = *(pix_buf+1) + ((data_ptr_word[i] & 0x3e0) >> 2);
										*(pix_buf+1) = static_cast<unsigned char>((col & 0xffffff00) ? 0xff : col);

										col = *(pix_buf+2) + ((data_ptr_word[i] & 0x7c00) >> 7);
										*(pix_buf+2) = static_cast<unsigned char>((col & 0xffffff00) ? 0xff : col);

										pix_buf += colorDepth;
									}
								}
								break;
								case Feature::Blend_Mode::Added | Feature::Flip_Mode::Texture_Horizontal_Flip:
								{
									depth = feature->featureTexture->depth;
									for(i=start_span;i<end_span;i++)
									{
										int col = *pix_buf + ((*data_ptr & 0x1f) << 3);
										*pix_buf = static_cast<unsigned char>((col & 0xffffff00) ? 0xff : col);

										col = *(pix_buf+1) + ((*(int *)data_ptr & 0x3e0) >> 2);
										*(pix_buf+1) = static_cast<unsigned char>((col & 0xffffff00) ? 0xff : col);

										col = *(pix_buf+2) + ((*(int *)data_ptr & 0x7c00) >> 7);
										*(pix_buf+2) = static_cast<unsigned char>((col & 0xffffff00) ? 0xff : col);

										pix_buf += colorDepth;

										data_ptr -= depth;
									}
								}
								break;
								case Feature::Blend_Mode::Multiply:
								{
									depth = feature->featureTexture->depth;
									for(i=start_span;i<end_span;i++)
									{
										int col = *pix_buf * ((*data_ptr & 0x1f) << 3);
										*pix_buf = static_cast<unsigned char>(col>>8);

										col = *(pix_buf+1) * ((*(int *)data_ptr & 0x3e0) >> 2);
										*(pix_buf+1) = static_cast<unsigned char>(col>>8);

										col = *(pix_buf+2) * ((*(int *)data_ptr & 0x7c00) >> 7);
										*(pix_buf+2) = static_cast<unsigned char>(col>>8);

										pix_buf += colorDepth;

										data_ptr += depth;
									}
								}
								break;
								case Feature::Blend_Mode::Multiply | Feature::Flip_Mode::Texture_Horizontal_Flip:
								{
									depth = feature->featureTexture->depth;
									for(i=start_span;i<end_span;i++)
									{
										int col = *pix_buf * ((*data_ptr & 0x1f) << 3);
										*pix_buf = static_cast<unsigned char>(col>>8);

										col = *(pix_buf+1) * ((*(int *)data_ptr & 0x3e0) >> 2);
										*(pix_buf+1) = static_cast<unsigned char>(col>>8);

										col = *(pix_buf+2) * ((*(int *)data_ptr & 0x7c00) >> 7);
										*(pix_buf+2) = static_cast<unsigned char>(col>>8);

										pix_buf += colorDepth;

										data_ptr -= depth;
									}
								}
								break;
								case Feature::Blend_Mode::Blend555_1:
									Blend555_1(aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, downScale);
								break;
								case Feature::Blend_Mode::Blend555_1 | Feature::Flip_Mode::Texture_Horizontal_Flip:
									Blend555_1_TH(aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, downScale);
								break;
								case Feature::Blend_Mode::Blend555_1 | Feature::Flip_Mode::Mask0_Horizontal_Flip:
									Blend555_1_M0H(aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, downScale);
								break;
								case Feature::Blend_Mode::Blend555_1 | Feature::Flip_Mode::Texture_Horizontal_Flip | Feature::Flip_Mode::Mask0_Horizontal_Flip:
									Blend555_1_TH_M0H(aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, downScale);
								break;
								case Feature::Blend_Mode::Blend555_2:
									Blend555_2(aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, downScale);
								break;
								case Feature::Blend_Mode::Blend555_2 | Feature::Flip_Mode::Texture_Horizontal_Flip:
									Blend555_2_TH(aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, downScale);
								break;
								case Feature::Blend_Mode::Blend555_2 | Feature::Flip_Mode::Mask0_Horizontal_Flip:
									Blend555_2_M0H(aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, downScale);
								break;
								case Feature::Blend_Mode::Blend555_2 | Feature::Flip_Mode::Texture_Horizontal_Flip | Feature::Flip_Mode::Mask0_Horizontal_Flip:
									Blend555_2_TH_M0H(aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, downScale);
								break;
								case Feature::Blend_Mode::Blend555_2 | Feature::Flip_Mode::Mask1_Horizontal_Flip:
									Blend555_2_M1H(aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, downScale);
								break;
								case Feature::Blend_Mode::Blend555_2 | Feature::Flip_Mode::Texture_Horizontal_Flip | Feature::Flip_Mode::Mask1_Horizontal_Flip:
									Blend555_2_TH_M1H(aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, downScale);
								break;
								case Feature::Blend_Mode::Blend555_2 | Feature::Flip_Mode::Mask0_Horizontal_Flip | Feature::Flip_Mode::Mask1_Horizontal_Flip:
									Blend555_2_M0H_M1H(aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, downScale);
								break;
								case Feature::Blend_Mode::Blend555_2 | Feature::Flip_Mode::Texture_Horizontal_Flip | Feature::Flip_Mode::Mask0_Horizontal_Flip | Feature::Flip_Mode::Mask1_Horizontal_Flip:
									Blend555_2_TH_M0H_M1H(aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, downScale);
								break;
								case Feature::Blend_Mode::Blend4444:
									Blend4444(aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, downScale);
								break;
								case Feature::Blend_Mode::Blend4444 | Feature::Flip_Mode::Texture_Horizontal_Flip:
									Blend4444_TH(aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, downScale);
								break;
								case Feature::Blend_Mode::StretchMultiply:
									BlendSM(aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, downScale);
								break;
								case Feature::Blend_Mode::StretchMultiply | Feature::Flip_Mode::Mask0_Horizontal_Flip:
									BlendSM_M0H(aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, downScale);
								break;
								case Feature::Blend_Mode::Blend555_1_1:
									Blend555_1_1(aelp_ptr->elp->featureInstance, pix_buf, start_span+start_i, j+start_j, start_span, end_span, downScale);
								break;
								case Feature::Blend_Mode::Blend555_1_1 | Feature::Flip_Mode::Texture_Horizontal_Flip:
									Blend555_1_1_TH(aelp_ptr->elp->featureInstance, pix_buf, start_span+start_i, j+start_j, start_span, end_span, downScale);
								break;
								case Feature::Blend_Mode::Blend555_1_1 | Feature::Flip_Mode::Mask0_Horizontal_Flip:
									Blend555_1_1_M0H(aelp_ptr->elp->featureInstance, pix_buf, start_span+start_i, j+start_j, start_span, end_span, downScale);
								break;
								case Feature::Blend_Mode::Blend555_1_1 | Feature::Flip_Mode::Texture_Horizontal_Flip | Feature::Flip_Mode::Mask0_Horizontal_Flip:
									Blend555_1_1_TH_M0H(aelp_ptr->elp->featureInstance, pix_buf, start_span+start_i, j+start_j, start_span, end_span, downScale);
								break;
								case Feature::Blend_Mode::Blend555_1_S:
									Blend555_1_S(aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, downScale);
								break;
								case Feature::Blend_Mode::Blend555_1_S | Feature::Flip_Mode::Texture_Horizontal_Flip:
									Blend555_1_S_TH(aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, downScale);
								break;
								case Feature::Blend_Mode::Blend555_1_S | Feature::Flip_Mode::Mask0_Horizontal_Flip:
									Blend555_1_S_M0H(aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, downScale);
								break;
								case Feature::Blend_Mode::Blend555_1_S | Feature::Flip_Mode::Texture_Horizontal_Flip | Feature::Flip_Mode::Mask0_Horizontal_Flip:
									Blend555_1_S_TH_M0H(aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, downScale);
								break;
								case Feature::Blend_Mode::StretchPaste:
									BlendSS(aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, downScale);
								break;
							}
						}
						break;
						case 1:
						{
							Verify(count<16);

							start_span >>= downScale;
							end_span >>= downScale;

							count++;
							for(i=start_span;i<end_span;i++)
							{
								*pix_buf = depthColors[count][2];
								*(pix_buf+1) = depthColors[count][1];
								*(pix_buf+2) = depthColors[count][0];

								pix_buf += colorDepth;
							}

						}
						break;
						case 2:	
						{
							feature = aelp_ptr->elp->featureInstance->feature;

							DWORD mat_color = 0;
							if(feature->GetName()!=NULL)
							{
								Tool_Feature *tool_fet=(Tool_Feature *)feature;
								mat_color = MaterialEntries[tool_fet->material].color;

							}
							else
							{
								break;
							}

							aelp_ptr->elp->featureInstance->CalculateCurrentPtr(start_span+start_i, j+start_j, downScale);

#ifdef BUG_HUNT
							if(row==rowToWatch && column==columnToWatch)
							{
								SPEWALWAYS(("micgaert", "-%s-%s", (const char *)(*((Tool_Feature*)feature)->GetName()), Feature::GetBlendModeName(feature->GetBlendMode()) ));
							}

							if(row==rowToWatch && column==columnToWatch && feature->GetBlendMode() == Feature::Blend_Mode::Blend4444)
							{
								int w = aelp_ptr->elp->featureInstance->feature->featureTexture->width;
								int h = aelp_ptr->elp->featureInstance->feature->featureTexture->height;
								unsigned char *data_ptr = aelp_ptr->elp->featureInstance->feature->featureTexture->data;

								WORD *data_ptr_word = (WORD *)data_ptr;

								if(downScale)
								{
									data_ptr_word += (w+2)*(h+2);
									w /= 2;
									h /= 2;

									int ii, jj, kk=0;
									for(ii=0;ii<h+2;ii++)
									{
										for(jj=0;jj<w+2;jj++)
										{
											p0[kk++] = (data_ptr_word[ii*(w+2)+jj] & 0xf) << 4;
											p0[kk++] = (data_ptr_word[ii*(w+2)+jj] & 0xf0);
											p0[kk++] = (data_ptr_word[ii*(w+2)+jj] & 0xf00)>>4;
											p0[kk++] = (data_ptr_word[ii*(w+2)+jj] & 0xf000)>>8;
										}
									}

									FILE *hd = fopen("test.raw", "wb");

									fwrite(p0, kk, 1, hd);
									fclose(hd);
								}
								else
								{
									int ii, jj, kk=0;
									for(ii=0;ii<h+2;ii++)
									{
										for(jj=0;jj<w+2;jj++)
										{
											p0[kk++] = (data_ptr_word[ii*(w+2)+jj] & 0xf) << 4;
											p0[kk++] = (data_ptr_word[ii*(w+2)+jj] & 0xf0);
											p0[kk++] = (data_ptr_word[ii*(w+2)+jj] & 0xf00)>>4;
											p0[kk++] = (data_ptr_word[ii*(w+2)+jj] & 0xf000)>>8;
										}
									}

									FILE *hd = fopen("test1.raw", "wb");

									fwrite(p0, kk, 1, hd);
									fclose(hd);
								}
							}
#endif

							unsigned char *data_ptr = aelp_ptr->elp->featureInstance->currentTexturePtr;
							int depth = 1;

							start_span >>= downScale;
							end_span >>= downScale;

							int combinedVal = (downScale << 24) | mat_color;
							switch(
								feature->GetBlendMode() | 
								(feature->GetFlipMode() & ~(
									Feature::Flip_Mode::Texture_Vertical_Flip |
									Feature::Flip_Mode::Mask0_Vertical_Flip |
									Feature::Flip_Mode::Mask1_Vertical_Flip
									)
								)
							)
							{
								case Feature::Blend_Mode::Paste:
								{
									depth = feature->featureTexture->depth;

									for(i=start_span;i<end_span;i++)
									{
										*(DWORD *)pix_buf = mat_color;

										pix_buf += colorDepth;

										data_ptr += depth;
									}
								}
								break;
								case Feature::Blend_Mode::Blend555_1:
									Blend555_1_MAT(aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, combinedVal);
								break;
								case Feature::Blend_Mode::Blend555_1 | Feature::Flip_Mode::Texture_Horizontal_Flip:
									Blend555_1_TH_MAT(aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, combinedVal);
								break;
								case Feature::Blend_Mode::Blend555_1 | Feature::Flip_Mode::Mask0_Horizontal_Flip:
									Blend555_1_M0H_MAT(aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, combinedVal);
								break;
								case Feature::Blend_Mode::Blend555_1 | Feature::Flip_Mode::Texture_Horizontal_Flip | Feature::Flip_Mode::Mask0_Horizontal_Flip:
									Blend555_1_TH_M0H_MAT(aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, combinedVal);
								break;
								case Feature::Blend_Mode::Blend555_2:
									Blend555_2_MAT(aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, combinedVal);
								break;
								case Feature::Blend_Mode::Blend555_2 | Feature::Flip_Mode::Texture_Horizontal_Flip:
									Blend555_2_TH_MAT(aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, combinedVal);
								break;
								case Feature::Blend_Mode::Blend555_2 | Feature::Flip_Mode::Mask0_Horizontal_Flip:
									Blend555_2_M0H_MAT(aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, combinedVal);
								break;
								case Feature::Blend_Mode::Blend555_2 | Feature::Flip_Mode::Texture_Horizontal_Flip | Feature::Flip_Mode::Mask0_Horizontal_Flip:
									Blend555_2_TH_M0H_MAT(aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, combinedVal);
								break;
								case Feature::Blend_Mode::Blend555_2 | Feature::Flip_Mode::Mask1_Horizontal_Flip:
									Blend555_2_M1H_MAT(aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, combinedVal);
								break;
								case Feature::Blend_Mode::Blend555_2 | Feature::Flip_Mode::Texture_Horizontal_Flip | Feature::Flip_Mode::Mask1_Horizontal_Flip:
									Blend555_2_TH_M1H_MAT(aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, combinedVal);
								break;
								case Feature::Blend_Mode::Blend555_2 | Feature::Flip_Mode::Mask0_Horizontal_Flip | Feature::Flip_Mode::Mask1_Horizontal_Flip:
									Blend555_2_M0H_M1H_MAT(aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, combinedVal);
								break;
								case Feature::Blend_Mode::Blend555_2 | Feature::Flip_Mode::Texture_Horizontal_Flip | Feature::Flip_Mode::Mask0_Horizontal_Flip | Feature::Flip_Mode::Mask1_Horizontal_Flip:
									Blend555_2_TH_M0H_M1H_MAT(aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, combinedVal);
								break;
								case Feature::Blend_Mode::Blend4444:
									Blend4444_MAT(aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, combinedVal);
								break;
								case Feature::Blend_Mode::Blend4444 | Feature::Flip_Mode::Texture_Horizontal_Flip:
									Blend4444_TH_MAT(aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, combinedVal);
								break;
								case Feature::Blend_Mode::StretchMultiply:
									BlendSM_MAT(aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, combinedVal);
								break;
								case Feature::Blend_Mode::StretchMultiply | Feature::Flip_Mode::Mask0_Horizontal_Flip:
									BlendSM_M0H_MAT(aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, combinedVal);
								break;
								case Feature::Blend_Mode::Blend555_1_1:
									Blend555_1_1_MAT(aelp_ptr->elp->featureInstance, pix_buf, start_span+start_i, j+start_j, start_span, end_span, combinedVal);
								break;
								case Feature::Blend_Mode::Blend555_1_1 | Feature::Flip_Mode::Texture_Horizontal_Flip:
									Blend555_1_1_TH_MAT(aelp_ptr->elp->featureInstance, pix_buf, start_span+start_i, j+start_j, start_span, end_span, combinedVal);
								break;
								case Feature::Blend_Mode::Blend555_1_1 | Feature::Flip_Mode::Mask0_Horizontal_Flip:
									Blend555_1_1_M0H_MAT(aelp_ptr->elp->featureInstance, pix_buf, start_span+start_i, j+start_j, start_span, end_span, combinedVal);
								break;
								case Feature::Blend_Mode::Blend555_1_1 | Feature::Flip_Mode::Texture_Horizontal_Flip | Feature::Flip_Mode::Mask0_Horizontal_Flip:
									Blend555_1_1_TH_M0H_MAT(aelp_ptr->elp->featureInstance, pix_buf, start_span+start_i, j+start_j, start_span, end_span, combinedVal);
								break;
								case Feature::Blend_Mode::Blend555_1_S:
									Blend555_1_S_MAT(aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, combinedVal);
								break;
								case Feature::Blend_Mode::Blend555_1_S | Feature::Flip_Mode::Texture_Horizontal_Flip:
									Blend555_1_S_TH_MAT(aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, combinedVal);
								break;
								case Feature::Blend_Mode::Blend555_1_S | Feature::Flip_Mode::Mask0_Horizontal_Flip:
									Blend555_1_S_M0H_MAT(aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, combinedVal);
								break;
								case Feature::Blend_Mode::Blend555_1_S | Feature::Flip_Mode::Texture_Horizontal_Flip | Feature::Flip_Mode::Mask0_Horizontal_Flip:
									Blend555_1_S_TH_M0H_MAT(aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, combinedVal);
								break;
								case Feature::Blend_Mode::StretchPaste:
									BlendSS_MAT(aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, combinedVal);
								break;
							}
						}
						break;
					}
					aelp_ptr = aelp_ptr->next;
				}
			}

			Mem_Copy(pix_dest, pixel_buffer, colorDepth*(gridSize>>downScale), 
				colorDepth*(gridSize>>downScale)*(gridSize>>downScale)-(j>>downScale)*(colorDepth*(gridSize>>downScale)));


			pix_dest += (gridSize>>downScale)*colorDepth;
		}

		if(aelp!=NULL)
		{
			aelp_ptr = aelp;

			while(aelp_ptr!=NULL)
			{
				aelp_ptr->counter--;

				if(aelp_ptr->counter<=0)
				{
					if(aelp_ptr==aelp)
					{
						aelp = aelp_ptr->next;
						if(aelp!=NULL)
						{
							aelp->prev = NULL;
						}
					}
					if(aelp_ptr->prev!=NULL)
					{
						aelp_ptr->prev->next = aelp_ptr->next;
					}
					if(aelp_ptr->next!=NULL)
					{
						aelp_ptr->next->prev = aelp_ptr->prev;
					}
					taelp = aelp_ptr->next;

					Unregister_Pointer(aelp_ptr);
					delete aelp_ptr;

					aelp_ptr = taelp;
				}
				else
				{
					aelp_ptr = aelp_ptr->next;
				}
			}
		}
	}

	if(aelp!=NULL)
	{
		aelp_ptr = aelp;
		
		while(aelp_ptr->next!=NULL)
		{
			aelp_ptr = aelp_ptr->next;
		}

		while(aelp_ptr->prev!=NULL)
		{
			taelp = aelp_ptr->prev;

			Unregister_Pointer(aelp_ptr);
			delete aelp_ptr;

			aelp_ptr = taelp;
			aelp_ptr->next = NULL;
		}
		Unregister_Pointer(aelp_ptr);
		delete aelp_ptr;
		aelp_ptr = NULL;
	}

	return true;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	FeatureGrid::ComposeGrid(
		int row,
		int column,
		TextureHolder *th, 
		int downScale,
		int type
	)
{
	Verify(downScale>=0 && downScale<3);
	Verify(th->pix_dest!=NULL);

	if(!(row>=0 && row<rows))
	{
		return false;
	}
	if(!(column>=0 && column<columns))
	{
		return false;
	}

	int i, j, count;
	int used;
	int start_i = (column<<gridSizeShift);	// - 2*column*(downScale==0);
	int start_j = (row<<gridSizeShift);	// - 2*row*(downScale==0);

	used = featureInstance[row*columns+column].GetLength();

	if(used==0)
	{
		return false;
	}

	static unsigned char pixel_buffer[512*colorDepth];
	unsigned char *pix_buf = NULL;

	int lineMask = (1<<downScale) - 1;

#ifdef BUG_HUNT
	int rowToWatch=9;
	int columnToWatch=19;

	static BYTE p0[258*258*4];
	static BYTE p1[130*130*4];
	if(row==rowToWatch && column==columnToWatch)
		SPEWALWAYS(("micgaert", "Row: %d Col: %d Res: %d", row, column, downScale));
#endif

	if(th->lastLine == -1)
	{
		th->elp = edgeList[row*columns+column];
		th->nextLineElp = th->elp;
		th->lastLine = 0;
	}

	int to = th->lastLine+th->linesToProcess > gridSize ? gridSize : th->lastLine+th->linesToProcess;

	for(j=th->lastLine;j<to;j++)
	{
		count = 0;
		Verify(th->pix_dest!=NULL);
		while(th->nextLineElp!=NULL && th->nextLineElp->z_pos == j)
		{
			AddToActiveEdgeList(&th->aelp, th->nextLineElp);
			count++;

			th->nextLineElp = th->nextLineElp->next;
		}

#ifdef BUG_HUNT
		if(row==rowToWatch && column==columnToWatch)
			SPEWALWAYS(("micgaert", "=== %d: %d added to active edgelist ===", j, count));
#endif

		if((j & lineMask) == 0)
		{
			pix_buf = pixel_buffer;

			count = 0;

#ifdef LAB_ONLY
			if(th->borderKey==true && j==0)
			{
				unsigned int *pix_buf_ui = (unsigned int *)pixel_buffer;

				for(i=0;i<gridSize>>downScale;i++)
				{
					*pix_buf_ui++ = th->borderColor;
				}
			}
			else
#endif
			if(th->aelp==NULL)
			{
				for(i=0;i<gridSize*colorDepth;i++)
				{
					*pix_buf++ = 0;
				}
			}
			else
			{
				th->aelp_ptr = th->aelp;
				
				while(th->aelp_ptr!=NULL)
				{
					count++;
					int start_span, end_span;

					start_span = th->aelp_ptr->elp->x_pos_start;
					end_span = th->aelp_ptr->elp->x_pos_end;
					pix_buf = pixel_buffer + colorDepth*(start_span>>downScale);

					Feature *feature;

					switch(type)
					{
						case 0:
						{
							feature = th->aelp_ptr->elp->featureInstance->feature;
#ifdef LAB_ONLY
							if(!
#endif
								th->aelp_ptr->elp->featureInstance->CalculateCurrentPtr(start_span+start_i, j+start_j, downScale)
#ifdef LAB_ONLY
							)
							{
								start_span >>= downScale;
								end_span >>= downScale;

								for(i=start_span;i<end_span;i++)
								{
									*pix_buf = 0xff;
									*(pix_buf+1) = 0;
									*(pix_buf+2) = 0;

									pix_buf += colorDepth;
								}
								th->aelp_ptr = th->aelp_ptr->next;
								continue;
							}
#else
							;
#endif


#ifdef BUG_HUNT
							if(row==rowToWatch && column==columnToWatch)
							{
								SPEWALWAYS(("micgaert", "-%s-%s", (const char *)(*((Tool_Feature*)feature)->GetName()), Feature::GetBlendModeName(feature->GetBlendMode()) ));
							}

							if(row==rowToWatch && column==columnToWatch && feature->GetBlendMode() == Feature::Blend_Mode::Blend4444)
							{
								int w = th->aelp_ptr->elp->featureInstance->feature->featureTexture->width;
								int h = th->aelp_ptr->elp->featureInstance->feature->featureTexture->height;
								unsigned char *data_ptr = th->aelp_ptr->elp->featureInstance->feature->featureTexture->data;

								WORD *data_ptr_word = (WORD *)data_ptr;

								if(downScale)
								{
									data_ptr_word += (w+2)*(h+2);
									w /= 2;
									h /= 2;

									int ii, jj, kk=0;
									for(ii=0;ii<h+2;ii++)
									{
										for(jj=0;jj<w+2;jj++)
										{
											p0[kk++] = (data_ptr_word[ii*(w+2)+jj] & 0xf) << 4;
											p0[kk++] = (data_ptr_word[ii*(w+2)+jj] & 0xf0);
											p0[kk++] = (data_ptr_word[ii*(w+2)+jj] & 0xf00)>>4;
											p0[kk++] = (data_ptr_word[ii*(w+2)+jj] & 0xf000)>>8;
										}
									}

									FILE *hd = fopen("test.raw", "wb");

									fwrite(p0, kk, 1, hd);
									fclose(hd);
								}
								else
								{
									int ii, jj, kk=0;
									for(ii=0;ii<h+2;ii++)
									{
										for(jj=0;jj<w+2;jj++)
										{
											p0[kk++] = (data_ptr_word[ii*(w+2)+jj] & 0xf) << 4;
											p0[kk++] = (data_ptr_word[ii*(w+2)+jj] & 0xf0);
											p0[kk++] = (data_ptr_word[ii*(w+2)+jj] & 0xf00)>>4;
											p0[kk++] = (data_ptr_word[ii*(w+2)+jj] & 0xf000)>>8;
										}
									}

									FILE *hd = fopen("test1.raw", "wb");

									fwrite(p0, kk, 1, hd);
									fclose(hd);
								}
							}
#endif

							unsigned char *data_ptr = th->aelp_ptr->elp->featureInstance->currentTexturePtr;
							int depth = 1;

							start_span >>= downScale;
							end_span >>= downScale;

							switch(
								feature->GetBlendMode() | 
								(feature->GetFlipMode() & ~(
									Feature::Flip_Mode::Texture_Vertical_Flip |
									Feature::Flip_Mode::Mask0_Vertical_Flip |
									Feature::Flip_Mode::Mask1_Vertical_Flip
									)
								)
							)
							{
								case Feature::Blend_Mode::Paste:
								{
									depth = feature->featureTexture->depth;
									int texture_width = depth * ((th->aelp_ptr->elp->featureInstance->feature->featureTexture->width) >> downScale);
									int count_down = th->aelp_ptr->elp->featureInstance->countDownToBorder;

									for(i=start_span;i<end_span;i++)
									{
										*pix_buf = static_cast<unsigned char>((*data_ptr & 0x1f) << 3);
										*(pix_buf+1) = static_cast<unsigned char>((*(int *)data_ptr & 0x3e0) >> 2);
										*(pix_buf+2) = static_cast<unsigned char>((*(int *)data_ptr) >> 7);

										pix_buf += colorDepth;

										data_ptr += depth;

										if(--count_down <= 0)
										{
											data_ptr -= texture_width;
											count_down = texture_width;
										}
									}
								}
								break;
								case Feature::Blend_Mode::Paste | Feature::Flip_Mode::Texture_Horizontal_Flip:
								{
									depth = feature->featureTexture->depth;
									int texture_width = depth * ((th->aelp_ptr->elp->featureInstance->feature->featureTexture->width) >> downScale);
									int count_down = th->aelp_ptr->elp->featureInstance->countDownToBorder;

									for(i=start_span;i<end_span;i++)
									{
										*pix_buf = static_cast<unsigned char>((*data_ptr & 0x1f) << 3);
										*(pix_buf+1) = static_cast<unsigned char>((*(int *)data_ptr & 0x3e0) >> 2);
										*(pix_buf+2) = static_cast<unsigned char>((*(int *)data_ptr) >> 7);

										pix_buf += colorDepth;

										data_ptr -= depth;

										if(--count_down <= 0)
										{
											data_ptr += texture_width;
											count_down = texture_width;
										}
									}
								}
								break;
								case Feature::Blend_Mode::Added:
								{
									depth = feature->featureTexture->depth;
									WORD *data_ptr_word = (WORD *)data_ptr;
									for(i=0;i<end_span-start_span;i++)
									{
										int col = *pix_buf + ((data_ptr_word[i] & 0x1f) << 3);
										*pix_buf = static_cast<unsigned char>((col & 0xffffff00) ? 0xff : col);

										col = *(pix_buf+1) + ((data_ptr_word[i] & 0x3e0) >> 2);
										*(pix_buf+1) = static_cast<unsigned char>((col & 0xffffff00) ? 0xff : col);

										col = *(pix_buf+2) + ((data_ptr_word[i] & 0x7c00) >> 7);
										*(pix_buf+2) = static_cast<unsigned char>((col & 0xffffff00) ? 0xff : col);

										pix_buf += colorDepth;
									}
								}
								break;
								case Feature::Blend_Mode::Added | Feature::Flip_Mode::Texture_Horizontal_Flip:
								{
									depth = feature->featureTexture->depth;
									for(i=start_span;i<end_span;i++)
									{
										int col = *pix_buf + ((*data_ptr & 0x1f) << 3);
										*pix_buf = static_cast<unsigned char>((col & 0xffffff00) ? 0xff : col);

										col = *(pix_buf+1) + ((*(int *)data_ptr & 0x3e0) >> 2);
										*(pix_buf+1) = static_cast<unsigned char>((col & 0xffffff00) ? 0xff : col);

										col = *(pix_buf+2) + ((*(int *)data_ptr & 0x7c00) >> 7);
										*(pix_buf+2) = static_cast<unsigned char>((col & 0xffffff00) ? 0xff : col);

										pix_buf += colorDepth;

										data_ptr -= depth;
									}
								}
								break;
								case Feature::Blend_Mode::Multiply:
								{
									depth = feature->featureTexture->depth;
									for(i=start_span;i<end_span;i++)
									{
										int col = *pix_buf * ((*data_ptr & 0x1f) << 3);
										*pix_buf = static_cast<unsigned char>(col>>8);

										col = *(pix_buf+1) * ((*(int *)data_ptr & 0x3e0) >> 2);
										*(pix_buf+1) = static_cast<unsigned char>(col>>8);

										col = *(pix_buf+2) * ((*(int *)data_ptr & 0x7c00) >> 7);
										*(pix_buf+2) = static_cast<unsigned char>(col>>8);

										pix_buf += colorDepth;

										data_ptr += depth;
									}
								}
								break;
								case Feature::Blend_Mode::Multiply | Feature::Flip_Mode::Texture_Horizontal_Flip:
								{
									depth = feature->featureTexture->depth;
									for(i=start_span;i<end_span;i++)
									{
										int col = *pix_buf * ((*data_ptr & 0x1f) << 3);
										*pix_buf = static_cast<unsigned char>(col>>8);

										col = *(pix_buf+1) * ((*(int *)data_ptr & 0x3e0) >> 2);
										*(pix_buf+1) = static_cast<unsigned char>(col>>8);

										col = *(pix_buf+2) * ((*(int *)data_ptr & 0x7c00) >> 7);
										*(pix_buf+2) = static_cast<unsigned char>(col>>8);

										pix_buf += colorDepth;

										data_ptr -= depth;
									}
								}
								break;
								case Feature::Blend_Mode::Blend555_1:
									Blend555_1(th->aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, downScale);
								break;
								case Feature::Blend_Mode::Blend555_1 | Feature::Flip_Mode::Texture_Horizontal_Flip:
									Blend555_1_TH(th->aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, downScale);
								break;
								case Feature::Blend_Mode::Blend555_1 | Feature::Flip_Mode::Mask0_Horizontal_Flip:
									Blend555_1_M0H(th->aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, downScale);
								break;
								case Feature::Blend_Mode::Blend555_1 | Feature::Flip_Mode::Texture_Horizontal_Flip | Feature::Flip_Mode::Mask0_Horizontal_Flip:
									Blend555_1_TH_M0H(th->aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, downScale);
								break;
								case Feature::Blend_Mode::Blend555_2:
									Blend555_2(th->aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, downScale);
								break;
								case Feature::Blend_Mode::Blend555_2 | Feature::Flip_Mode::Texture_Horizontal_Flip:
									Blend555_2_TH(th->aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, downScale);
								break;
								case Feature::Blend_Mode::Blend555_2 | Feature::Flip_Mode::Mask0_Horizontal_Flip:
									Blend555_2_M0H(th->aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, downScale);
								break;
								case Feature::Blend_Mode::Blend555_2 | Feature::Flip_Mode::Texture_Horizontal_Flip | Feature::Flip_Mode::Mask0_Horizontal_Flip:
									Blend555_2_TH_M0H(th->aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, downScale);
								break;
								case Feature::Blend_Mode::Blend555_2 | Feature::Flip_Mode::Mask1_Horizontal_Flip:
									Blend555_2_M1H(th->aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, downScale);
								break;
								case Feature::Blend_Mode::Blend555_2 | Feature::Flip_Mode::Texture_Horizontal_Flip | Feature::Flip_Mode::Mask1_Horizontal_Flip:
									Blend555_2_TH_M1H(th->aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, downScale);
								break;
								case Feature::Blend_Mode::Blend555_2 | Feature::Flip_Mode::Mask0_Horizontal_Flip | Feature::Flip_Mode::Mask1_Horizontal_Flip:
									Blend555_2_M0H_M1H(th->aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, downScale);
								break;
								case Feature::Blend_Mode::Blend555_2 | Feature::Flip_Mode::Texture_Horizontal_Flip | Feature::Flip_Mode::Mask0_Horizontal_Flip | Feature::Flip_Mode::Mask1_Horizontal_Flip:
									Blend555_2_TH_M0H_M1H(th->aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, downScale);
								break;
								case Feature::Blend_Mode::Blend4444:
									Blend4444(th->aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, downScale);
								break;
								case Feature::Blend_Mode::Blend4444 | Feature::Flip_Mode::Texture_Horizontal_Flip:
									Blend4444_TH(th->aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, downScale);
								break;
								case Feature::Blend_Mode::StretchMultiply:
									BlendSM(th->aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, downScale);
								break;
								case Feature::Blend_Mode::StretchMultiply | Feature::Flip_Mode::Mask0_Horizontal_Flip:
									BlendSM_M0H(th->aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, downScale);
								break;
								case Feature::Blend_Mode::Blend555_1_1:
									Blend555_1_1(th->aelp_ptr->elp->featureInstance, pix_buf, start_span+start_i, j+start_j, start_span, end_span, downScale);
								break;
								case Feature::Blend_Mode::Blend555_1_1 | Feature::Flip_Mode::Texture_Horizontal_Flip:
									Blend555_1_1_TH(th->aelp_ptr->elp->featureInstance, pix_buf, start_span+start_i, j+start_j, start_span, end_span, downScale);
								break;
								case Feature::Blend_Mode::Blend555_1_1 | Feature::Flip_Mode::Mask0_Horizontal_Flip:
									Blend555_1_1_M0H(th->aelp_ptr->elp->featureInstance, pix_buf, start_span+start_i, j+start_j, start_span, end_span, downScale);
								break;
								case Feature::Blend_Mode::Blend555_1_1 | Feature::Flip_Mode::Texture_Horizontal_Flip | Feature::Flip_Mode::Mask0_Horizontal_Flip:
									Blend555_1_1_TH_M0H(th->aelp_ptr->elp->featureInstance, pix_buf, start_span+start_i, j+start_j, start_span, end_span, downScale);
								break;
								case Feature::Blend_Mode::Blend555_1_S:
									Blend555_1_S(th->aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, downScale);
								break;
								case Feature::Blend_Mode::Blend555_1_S | Feature::Flip_Mode::Texture_Horizontal_Flip:
									Blend555_1_S_TH(th->aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, downScale);
								break;
								case Feature::Blend_Mode::Blend555_1_S | Feature::Flip_Mode::Mask0_Horizontal_Flip:
									Blend555_1_S_M0H(th->aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, downScale);
								break;
								case Feature::Blend_Mode::Blend555_1_S | Feature::Flip_Mode::Texture_Horizontal_Flip | Feature::Flip_Mode::Mask0_Horizontal_Flip:
									Blend555_1_S_TH_M0H(th->aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, downScale);
								break;
								case Feature::Blend_Mode::StretchPaste:
									BlendSS(th->aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, downScale);
								break;
							}
						}
						break;
						case 1:
						{
							Verify(count<16);

							start_span >>= downScale;
							end_span >>= downScale;

							count++;
							for(i=start_span;i<end_span;i++)
							{
								*pix_buf = depthColors[count][2];
								*(pix_buf+1) = depthColors[count][1];
								*(pix_buf+2) = depthColors[count][0];

								pix_buf += colorDepth;
							}
						}
						break;
						case 2:
						{
							feature = th->aelp_ptr->elp->featureInstance->feature;

							DWORD mat_color = 0;
							if(feature->GetName()!=NULL)
							{
								Tool_Feature *tool_fet=(Tool_Feature *)feature;

								mat_color = MaterialEntries[tool_fet->material].color;

							}
							else
							{
								break;
							}

							th->aelp_ptr->elp->featureInstance->CalculateCurrentPtr(start_span+start_i, j+start_j, downScale);

#ifdef BUG_HUNT
							if(row==rowToWatch && column==columnToWatch)
							{
								SPEWALWAYS(("micgaert", "-%s-%s", (const char *)(*((Tool_Feature*)feature)->GetName()), Feature::GetBlendModeName(feature->GetBlendMode()) ));
							}

							if(row==rowToWatch && column==columnToWatch && feature->GetBlendMode() == Feature::Blend_Mode::Blend4444)
							{
								int w = th->aelp_ptr->elp->featureInstance->feature->featureTexture->width;
								int h = th->aelp_ptr->elp->featureInstance->feature->featureTexture->height;
								unsigned char *data_ptr = th->aelp_ptr->elp->featureInstance->feature->featureTexture->data;

								WORD *data_ptr_word = (WORD *)data_ptr;

								if(downScale)
								{
									data_ptr_word += (w+2)*(h+2);
									w /= 2;
									h /= 2;

									int ii, jj, kk=0;
									for(ii=0;ii<h+2;ii++)
									{
										for(jj=0;jj<w+2;jj++)
										{
											p0[kk++] = (data_ptr_word[ii*(w+2)+jj] & 0xf) << 4;
											p0[kk++] = (data_ptr_word[ii*(w+2)+jj] & 0xf0);
											p0[kk++] = (data_ptr_word[ii*(w+2)+jj] & 0xf00)>>4;
											p0[kk++] = (data_ptr_word[ii*(w+2)+jj] & 0xf000)>>8;
										}
									}

									FILE *hd = fopen("test.raw", "wb");

									fwrite(p0, kk, 1, hd);
									fclose(hd);
								}
								else
								{
									int ii, jj, kk=0;
									for(ii=0;ii<h+2;ii++)
									{
										for(jj=0;jj<w+2;jj++)
										{
											p0[kk++] = (data_ptr_word[ii*(w+2)+jj] & 0xf) << 4;
											p0[kk++] = (data_ptr_word[ii*(w+2)+jj] & 0xf0);
											p0[kk++] = (data_ptr_word[ii*(w+2)+jj] & 0xf00)>>4;
											p0[kk++] = (data_ptr_word[ii*(w+2)+jj] & 0xf000)>>8;
										}
									}

									FILE *hd = fopen("test1.raw", "wb");

									fwrite(p0, kk, 1, hd);
									fclose(hd);
								}
							}
#endif

							unsigned char *data_ptr = th->aelp_ptr->elp->featureInstance->currentTexturePtr;
							int depth = 1;

							start_span >>= downScale;
							end_span >>= downScale;

							int combinedVal = (downScale << 24) | mat_color;
							switch(
								feature->GetBlendMode() | 
								(feature->GetFlipMode() & ~(
									Feature::Flip_Mode::Texture_Vertical_Flip |
									Feature::Flip_Mode::Mask0_Vertical_Flip |
									Feature::Flip_Mode::Mask1_Vertical_Flip
									)
								)
							)
							{
								case Feature::Blend_Mode::Paste:
								{
									depth = feature->featureTexture->depth;
									int texture_width = depth * ((th->aelp_ptr->elp->featureInstance->feature->featureTexture->width) >> downScale);
									int count_down = th->aelp_ptr->elp->featureInstance->countDownToBorder;

									for(i=start_span;i<end_span;i++)
									{
										*pix_buf = static_cast<unsigned char>((*data_ptr & 0x1f) << 3);
										*(pix_buf+1) = static_cast<unsigned char>((*(int *)data_ptr & 0x3e0) >> 2);
										*(pix_buf+2) = static_cast<unsigned char>((*(int *)data_ptr) >> 7);

										pix_buf += colorDepth;

										data_ptr += depth;

										if(--count_down <= 0)
										{
											data_ptr -= texture_width;
											count_down = texture_width;
										}
									}
								}
								break;
								case Feature::Blend_Mode::Paste | Feature::Flip_Mode::Texture_Horizontal_Flip:
								{
									depth = feature->featureTexture->depth;
									int texture_width = depth * ((th->aelp_ptr->elp->featureInstance->feature->featureTexture->width) >> downScale);
									int count_down = th->aelp_ptr->elp->featureInstance->countDownToBorder;

									for(i=start_span;i<end_span;i++)
									{
										*pix_buf = static_cast<unsigned char>((*data_ptr & 0x1f) << 3);
										*(pix_buf+1) = static_cast<unsigned char>((*(int *)data_ptr & 0x3e0) >> 2);
										*(pix_buf+2) = static_cast<unsigned char>((*(int *)data_ptr) >> 7);

										pix_buf += colorDepth;

										data_ptr -= depth;

										if(--count_down <= 0)
										{
											data_ptr += texture_width;
											count_down = texture_width;
										}
									}
								}
								break;
								case Feature::Blend_Mode::Added:
								{
									depth = feature->featureTexture->depth;
									WORD *data_ptr_word = (WORD *)data_ptr;
									for(i=0;i<end_span-start_span;i++)
									{
										int col = *pix_buf + ((data_ptr_word[i] & 0x1f) << 3);
										*pix_buf = static_cast<unsigned char>((col & 0xffffff00) ? 0xff : col);

										col = *(pix_buf+1) + ((data_ptr_word[i] & 0x3e0) >> 2);
										*(pix_buf+1) = static_cast<unsigned char>((col & 0xffffff00) ? 0xff : col);

										col = *(pix_buf+2) + ((data_ptr_word[i] & 0x7c00) >> 7);
										*(pix_buf+2) = static_cast<unsigned char>((col & 0xffffff00) ? 0xff : col);

										pix_buf += colorDepth;
									}
								}
								break;
								case Feature::Blend_Mode::Added | Feature::Flip_Mode::Texture_Horizontal_Flip:
								{
									depth = feature->featureTexture->depth;
									for(i=start_span;i<end_span;i++)
									{
										int col = *pix_buf + ((*data_ptr & 0x1f) << 3);
										*pix_buf = static_cast<unsigned char>((col & 0xffffff00) ? 0xff : col);

										col = *(pix_buf+1) + ((*(int *)data_ptr & 0x3e0) >> 2);
										*(pix_buf+1) = static_cast<unsigned char>((col & 0xffffff00) ? 0xff : col);

										col = *(pix_buf+2) + ((*(int *)data_ptr & 0x7c00) >> 7);
										*(pix_buf+2) = static_cast<unsigned char>((col & 0xffffff00) ? 0xff : col);

										pix_buf += colorDepth;

										data_ptr -= depth;
									}
								}
								break;
								case Feature::Blend_Mode::Multiply:
								{
									depth = feature->featureTexture->depth;
									for(i=start_span;i<end_span;i++)
									{
										int col = *pix_buf * ((*data_ptr & 0x1f) << 3);
										*pix_buf = static_cast<unsigned char>(col>>8);

										col = *(pix_buf+1) * ((*(int *)data_ptr & 0x3e0) >> 2);
										*(pix_buf+1) = static_cast<unsigned char>(col>>8);

										col = *(pix_buf+2) * ((*(int *)data_ptr & 0x7c00) >> 7);
										*(pix_buf+2) = static_cast<unsigned char>(col>>8);

										pix_buf += colorDepth;

										data_ptr += depth;
									}
								}
								break;
								case Feature::Blend_Mode::Multiply | Feature::Flip_Mode::Texture_Horizontal_Flip:
								{
									depth = feature->featureTexture->depth;
									for(i=start_span;i<end_span;i++)
									{
										int col = *pix_buf * ((*data_ptr & 0x1f) << 3);
										*pix_buf = static_cast<unsigned char>(col>>8);

										col = *(pix_buf+1) * ((*(int *)data_ptr & 0x3e0) >> 2);
										*(pix_buf+1) = static_cast<unsigned char>(col>>8);

										col = *(pix_buf+2) * ((*(int *)data_ptr & 0x7c00) >> 7);
										*(pix_buf+2) = static_cast<unsigned char>(col>>8);

										pix_buf += colorDepth;

										data_ptr -= depth;
									}
								}
								break;
								case Feature::Blend_Mode::Blend555_1:
									Blend555_1_MAT(th->aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, combinedVal);
								break;
								case Feature::Blend_Mode::Blend555_1 | Feature::Flip_Mode::Texture_Horizontal_Flip:
									Blend555_1_TH_MAT(th->aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, combinedVal);
								break;
								case Feature::Blend_Mode::Blend555_1 | Feature::Flip_Mode::Mask0_Horizontal_Flip:
									Blend555_1_M0H_MAT(th->aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, combinedVal);
								break;
								case Feature::Blend_Mode::Blend555_1 | Feature::Flip_Mode::Texture_Horizontal_Flip | Feature::Flip_Mode::Mask0_Horizontal_Flip:
									Blend555_1_TH_M0H_MAT(th->aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, combinedVal);
								break;
								case Feature::Blend_Mode::Blend555_2:
									Blend555_2_MAT(th->aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, combinedVal);
								break;
								case Feature::Blend_Mode::Blend555_2 | Feature::Flip_Mode::Texture_Horizontal_Flip:
									Blend555_2_TH_MAT(th->aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, combinedVal);
								break;
								case Feature::Blend_Mode::Blend555_2 | Feature::Flip_Mode::Mask0_Horizontal_Flip:
									Blend555_2_M0H_MAT(th->aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, combinedVal);
								break;
								case Feature::Blend_Mode::Blend555_2 | Feature::Flip_Mode::Texture_Horizontal_Flip | Feature::Flip_Mode::Mask0_Horizontal_Flip:
									Blend555_2_TH_M0H_MAT(th->aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, combinedVal);
								break;
								case Feature::Blend_Mode::Blend555_2 | Feature::Flip_Mode::Mask1_Horizontal_Flip:
									Blend555_2_M1H_MAT(th->aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, combinedVal);
								break;
								case Feature::Blend_Mode::Blend555_2 | Feature::Flip_Mode::Texture_Horizontal_Flip | Feature::Flip_Mode::Mask1_Horizontal_Flip:
									Blend555_2_TH_M1H_MAT(th->aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, combinedVal);
								break;
								case Feature::Blend_Mode::Blend555_2 | Feature::Flip_Mode::Mask0_Horizontal_Flip | Feature::Flip_Mode::Mask1_Horizontal_Flip:
									Blend555_2_M0H_M1H_MAT(th->aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, combinedVal);
								break;
								case Feature::Blend_Mode::Blend555_2 | Feature::Flip_Mode::Texture_Horizontal_Flip | Feature::Flip_Mode::Mask0_Horizontal_Flip | Feature::Flip_Mode::Mask1_Horizontal_Flip:
									Blend555_2_TH_M0H_M1H_MAT(th->aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, combinedVal);
								break;
								case Feature::Blend_Mode::Blend4444:
									Blend4444_MAT(th->aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, combinedVal);
								break;
								case Feature::Blend_Mode::Blend4444 | Feature::Flip_Mode::Texture_Horizontal_Flip:
									Blend4444_TH_MAT(th->aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, combinedVal);
								break;
								case Feature::Blend_Mode::StretchMultiply:
									BlendSM_MAT(th->aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, combinedVal);
								break;
								case Feature::Blend_Mode::StretchMultiply | Feature::Flip_Mode::Mask0_Horizontal_Flip:
									BlendSM_M0H_MAT(th->aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, combinedVal);
								break;
								case Feature::Blend_Mode::Blend555_1_1:
									Blend555_1_1_MAT(th->aelp_ptr->elp->featureInstance, pix_buf, start_span+start_i, j+start_j, start_span, end_span, combinedVal);
								break;
								case Feature::Blend_Mode::Blend555_1_1 | Feature::Flip_Mode::Texture_Horizontal_Flip:
									Blend555_1_1_TH_MAT(th->aelp_ptr->elp->featureInstance, pix_buf, start_span+start_i, j+start_j, start_span, end_span, combinedVal);
								break;
								case Feature::Blend_Mode::Blend555_1_1 | Feature::Flip_Mode::Mask0_Horizontal_Flip:
									Blend555_1_1_M0H_MAT(th->aelp_ptr->elp->featureInstance, pix_buf, start_span+start_i, j+start_j, start_span, end_span, combinedVal);
								break;
								case Feature::Blend_Mode::Blend555_1_1 | Feature::Flip_Mode::Texture_Horizontal_Flip | Feature::Flip_Mode::Mask0_Horizontal_Flip:
									Blend555_1_1_TH_M0H_MAT(th->aelp_ptr->elp->featureInstance, pix_buf, start_span+start_i, j+start_j, start_span, end_span, combinedVal);
								break;
								case Feature::Blend_Mode::Blend555_1_S:
									Blend555_1_S_MAT(th->aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, combinedVal);
								break;
								case Feature::Blend_Mode::Blend555_1_S | Feature::Flip_Mode::Texture_Horizontal_Flip:
									Blend555_1_S_TH_MAT(th->aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, combinedVal);
								break;
								case Feature::Blend_Mode::Blend555_1_S | Feature::Flip_Mode::Mask0_Horizontal_Flip:
									Blend555_1_S_M0H_MAT(th->aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, combinedVal);
								break;
								case Feature::Blend_Mode::Blend555_1_S | Feature::Flip_Mode::Texture_Horizontal_Flip | Feature::Flip_Mode::Mask0_Horizontal_Flip:
									Blend555_1_S_TH_M0H_MAT(th->aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, combinedVal);
								break;
								case Feature::Blend_Mode::StretchPaste:
									BlendSS_MAT(th->aelp_ptr->elp->featureInstance, pix_buf, start_span, end_span, combinedVal);
								break;
							}
						}
						break;
					}
					th->aelp_ptr = th->aelp_ptr->next;
				}
			}

#ifdef LAB_ONLY
			if(th->borderKey==true)
			{
				*(unsigned int *)pixel_buffer = th->borderColor;
			}
#endif

			Mem_Copy(th->pix_dest, pixel_buffer, colorDepth*(gridSize>>downScale), 
				colorDepth*(gridSize>>downScale)*(gridSize>>downScale)-(j>>downScale)*(colorDepth*(gridSize>>downScale)));

			th->pix_dest += th->pitch<<2;
//				(gridSize>>downScale)*colorDepth;

#ifdef BUG_HUNT
			if(row==rowToWatch && column==columnToWatch)
			{
				if(downScale)
				{
					memcpy(p1+(j>>downScale)*128*4, pixel_buffer, 128*4);
				}
				else
				{
					memcpy(p0+j*256*4, pixel_buffer, 256*4);
				}

				if(row==rowToWatch && column==columnToWatch)
				{
					SPEWALWAYS(("micgaert", "=== %d: %d executed from active edgelist ===", j, count));
				}
			}
#endif
		}

		if(th->aelp!=NULL)
		{
			th->aelp_ptr = th->aelp;

			while(th->aelp_ptr!=NULL)
			{
				th->aelp_ptr->counter--;

				if(th->aelp_ptr->counter<=0)
				{
					if(th->aelp_ptr==th->aelp)
					{
						th->aelp = th->aelp_ptr->next;
						if(th->aelp!=NULL)
						{
							th->aelp->prev = NULL;
						}
					}
					if(th->aelp_ptr->prev!=NULL)
					{
						th->aelp_ptr->prev->next = th->aelp_ptr->next;
					}
					if(th->aelp_ptr->next!=NULL)
					{
						th->aelp_ptr->next->prev = th->aelp_ptr->prev;
					}
					th->taelp = th->aelp_ptr->next;

					Unregister_Pointer(th->aelp_ptr);
					delete th->aelp_ptr;

					th->aelp_ptr = th->taelp;
				}
				else
				{
					th->aelp_ptr = th->aelp_ptr->next;
				}
			}
		}
	}

#ifdef BUG_HUNT
	if(row==rowToWatch && column==columnToWatch)
	{
		int index = th->textureHandle;

		if(index>0)
		{
			MLRTexture *texture = (*MidLevelRenderer::MLRTexturePool::Instance)[index];
			GOSImage *image = texture->GetImage();

			static int iii=0;
			char name[1024];

			sprintf(name, "i%04d_%04d.raw", iii++, j);

			FILE *hd = fopen(name, "wb");

			fwrite(image->GetImagePtr(), image->GetWidth()*image->GetHeight()*4, 1, hd);
			fclose(hd);

			if(downScale)
			{
				sprintf(name, "P1i%04d_%04d.raw", iii++, j);

				FILE *hd = fopen(name, "wb");

				fwrite(p1, 128*128*4, 1, hd);
				fclose(hd);
			}
			else
			{
				sprintf(name, "P0i%04d_%04d.raw", iii++, j);

				FILE *hd = fopen(name, "wb");

				fwrite(p0, 256*256*4, 1, hd);
				fclose(hd);
			}
		}
	}
#endif

	th->lastLine += th->linesToProcess;

	return true;
}

#define BLENDFUNCTION Blend555_1
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#include "BlendMode555_1.hpp"
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef BLENDFUNCTION

#define BLENDFUNCTION Blend555_1_TH
#define TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#include "BlendMode555_1.hpp"
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef BLENDFUNCTION

#define BLENDFUNCTION Blend555_1_M0H
#undef TEXTURE_HORIZONTAL_FLIP
#define MASK0_HORIZONTAL_FLIP
#include "BlendMode555_1.hpp"
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef BLENDFUNCTION

#define BLENDFUNCTION Blend555_1_TH_M0H
#define TEXTURE_HORIZONTAL_FLIP
#define MASK0_HORIZONTAL_FLIP
#include "BlendMode555_1.hpp"
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef BLENDFUNCTION

#define BLENDFUNCTION BlendSM
#undef MASK0_HORIZONTAL_FLIP
#include "BlendModeSM.hpp"
#undef MASK0_HORIZONTAL_FLIP
#undef BLENDFUNCTION

#define BLENDFUNCTION BlendSM_M0H
#define MASK0_HORIZONTAL_FLIP
#include "BlendModeSM.hpp"
#undef MASK0_HORIZONTAL_FLIP
#undef BLENDFUNCTION

#define BLENDFUNCTION Blend555_2
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef MASK1_HORIZONTAL_FLIP
#include "BlendMode555_2.hpp"
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef MASK1_HORIZONTAL_FLIP
#undef BLENDFUNCTION

#define BLENDFUNCTION Blend555_2_TH
#define TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef MASK1_HORIZONTAL_FLIP
#include "BlendMode555_2.hpp"
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef MASK1_HORIZONTAL_FLIP
#undef BLENDFUNCTION

#define BLENDFUNCTION Blend555_2_M0H
#undef TEXTURE_HORIZONTAL_FLIP
#define MASK0_HORIZONTAL_FLIP
#undef MASK1_HORIZONTAL_FLIP
#include "BlendMode555_2.hpp"
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef MASK1_HORIZONTAL_FLIP
#undef BLENDFUNCTION

#define BLENDFUNCTION Blend555_2_M1H
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#define MASK1_HORIZONTAL_FLIP
#include "BlendMode555_2.hpp"
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef MASK1_HORIZONTAL_FLIP
#undef BLENDFUNCTION

#define BLENDFUNCTION Blend555_2_TH_M0H
#define TEXTURE_HORIZONTAL_FLIP
#define MASK0_HORIZONTAL_FLIP
#undef MASK1_HORIZONTAL_FLIP
#include "BlendMode555_2.hpp"
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef MASK1_HORIZONTAL_FLIP
#undef BLENDFUNCTION

#define BLENDFUNCTION Blend555_2_TH_M1H
#define TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#define MASK1_HORIZONTAL_FLIP
#include "BlendMode555_2.hpp"
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef MASK1_HORIZONTAL_FLIP
#undef BLENDFUNCTION

#define BLENDFUNCTION Blend555_2_M0H_M1H
#undef TEXTURE_HORIZONTAL_FLIP
#define MASK0_HORIZONTAL_FLIP
#define MASK1_HORIZONTAL_FLIP
#include "BlendMode555_2.hpp"
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef MASK1_HORIZONTAL_FLIP
#undef BLENDFUNCTION

#define BLENDFUNCTION Blend555_2_TH_M0H_M1H
#define TEXTURE_HORIZONTAL_FLIP
#define MASK0_HORIZONTAL_FLIP
#define MASK1_HORIZONTAL_FLIP
#include "BlendMode555_2.hpp"
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef MASK1_HORIZONTAL_FLIP
#undef BLENDFUNCTION

#define BLENDFUNCTION Blend4444
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef MASK1_HORIZONTAL_FLIP
#include "BlendMode4444.hpp"
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef MASK1_HORIZONTAL_FLIP
#undef BLENDFUNCTION

#define BLENDFUNCTION Blend4444_TH
#define TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef MASK1_HORIZONTAL_FLIP
#include "BlendMode4444.hpp"
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef MASK1_HORIZONTAL_FLIP
#undef BLENDFUNCTION

#define BLENDFUNCTION Blend555_1_1
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#include "BlendMode555_1_1.hpp"
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef BLENDFUNCTION

#define BLENDFUNCTION Blend555_1_1_TH
#define TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#include "BlendMode555_1_1.hpp"
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef BLENDFUNCTION

#define BLENDFUNCTION Blend555_1_1_M0H
#undef TEXTURE_HORIZONTAL_FLIP
#define MASK0_HORIZONTAL_FLIP
#include "BlendMode555_1_1.hpp"
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef BLENDFUNCTION

#define BLENDFUNCTION Blend555_1_1_TH_M0H
#define TEXTURE_HORIZONTAL_FLIP
#define MASK0_HORIZONTAL_FLIP
#include "BlendMode555_1_1.hpp"
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef BLENDFUNCTION

#define BLENDFUNCTION BlendSS
#undef MASK0_HORIZONTAL_FLIP
#include "BlendModeSS.hpp"
#undef MASK0_HORIZONTAL_FLIP
#undef BLENDFUNCTION

#define BLENDFUNCTION Blend555_1_S
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#include "BlendMode555_1_S.hpp"
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef BLENDFUNCTION

#define BLENDFUNCTION Blend555_1_S_TH
#define TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#include "BlendMode555_1_S.hpp"
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef BLENDFUNCTION

#define BLENDFUNCTION Blend555_1_S_M0H
#undef TEXTURE_HORIZONTAL_FLIP
#define MASK0_HORIZONTAL_FLIP
#include "BlendMode555_1_S.hpp"
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef BLENDFUNCTION

#define BLENDFUNCTION Blend555_1_S_TH_M0H
#define TEXTURE_HORIZONTAL_FLIP
#define MASK0_HORIZONTAL_FLIP
#include "BlendMode555_1_S.hpp"
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef BLENDFUNCTION

//====== Material compositing functions ================


#define BLENDFUNCTION Blend555_1_MAT
#define SHOW_MATERIAL
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#include "BlendMode555_1.hpp"
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef BLENDFUNCTION
#undef SHOW_MATERIAL

#define BLENDFUNCTION Blend555_1_TH_MAT
#define SHOW_MATERIAL
#define TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#include "BlendMode555_1.hpp"
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef BLENDFUNCTION
#undef SHOW_MATERIAL

#define BLENDFUNCTION Blend555_1_M0H_MAT
#define SHOW_MATERIAL
#undef TEXTURE_HORIZONTAL_FLIP
#define MASK0_HORIZONTAL_FLIP
#include "BlendMode555_1.hpp"
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef BLENDFUNCTION
#undef SHOW_MATERIAL

#define BLENDFUNCTION Blend555_1_TH_M0H_MAT
#define SHOW_MATERIAL
#define TEXTURE_HORIZONTAL_FLIP
#define MASK0_HORIZONTAL_FLIP
#include "BlendMode555_1.hpp"
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef BLENDFUNCTION
#undef SHOW_MATERIAL

#define BLENDFUNCTION BlendSM_MAT
#define SHOW_MATERIAL
#undef MASK0_HORIZONTAL_FLIP
#include "BlendModeSM.hpp"
#undef MASK0_HORIZONTAL_FLIP
#undef BLENDFUNCTION
#undef SHOW_MATERIAL

#define BLENDFUNCTION BlendSM_M0H_MAT
#define SHOW_MATERIAL
#define MASK0_HORIZONTAL_FLIP
#include "BlendModeSM.hpp"
#undef MASK0_HORIZONTAL_FLIP
#undef BLENDFUNCTION
#undef SHOW_MATERIAL

#define BLENDFUNCTION Blend555_2_MAT
#define SHOW_MATERIAL
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef MASK1_HORIZONTAL_FLIP
#include "BlendMode555_2.hpp"
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef MASK1_HORIZONTAL_FLIP
#undef BLENDFUNCTION
#undef SHOW_MATERIAL

#define BLENDFUNCTION Blend555_2_TH_MAT
#define SHOW_MATERIAL
#define TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef MASK1_HORIZONTAL_FLIP
#include "BlendMode555_2.hpp"
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef MASK1_HORIZONTAL_FLIP
#undef BLENDFUNCTION
#undef SHOW_MATERIAL

#define BLENDFUNCTION Blend555_2_M0H_MAT
#define SHOW_MATERIAL
#undef TEXTURE_HORIZONTAL_FLIP
#define MASK0_HORIZONTAL_FLIP
#undef MASK1_HORIZONTAL_FLIP
#include "BlendMode555_2.hpp"
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef MASK1_HORIZONTAL_FLIP
#undef BLENDFUNCTION
#undef SHOW_MATERIAL

#define BLENDFUNCTION Blend555_2_M1H_MAT
#define SHOW_MATERIAL
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#define MASK1_HORIZONTAL_FLIP
#include "BlendMode555_2.hpp"
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef MASK1_HORIZONTAL_FLIP
#undef BLENDFUNCTION
#undef SHOW_MATERIAL

#define BLENDFUNCTION Blend555_2_TH_M0H_MAT
#define SHOW_MATERIAL
#define TEXTURE_HORIZONTAL_FLIP
#define MASK0_HORIZONTAL_FLIP
#undef MASK1_HORIZONTAL_FLIP
#include "BlendMode555_2.hpp"
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef MASK1_HORIZONTAL_FLIP
#undef BLENDFUNCTION
#undef SHOW_MATERIAL

#define BLENDFUNCTION Blend555_2_TH_M1H_MAT
#define SHOW_MATERIAL
#define TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#define MASK1_HORIZONTAL_FLIP
#include "BlendMode555_2.hpp"
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef MASK1_HORIZONTAL_FLIP
#undef BLENDFUNCTION
#undef SHOW_MATERIAL

#define BLENDFUNCTION Blend555_2_M0H_M1H_MAT
#define SHOW_MATERIAL
#undef TEXTURE_HORIZONTAL_FLIP
#define MASK0_HORIZONTAL_FLIP
#define MASK1_HORIZONTAL_FLIP
#include "BlendMode555_2.hpp"
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef MASK1_HORIZONTAL_FLIP
#undef BLENDFUNCTION
#undef SHOW_MATERIAL

#define BLENDFUNCTION Blend555_2_TH_M0H_M1H_MAT
#define SHOW_MATERIAL
#define TEXTURE_HORIZONTAL_FLIP
#define MASK0_HORIZONTAL_FLIP
#define MASK1_HORIZONTAL_FLIP
#include "BlendMode555_2.hpp"
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef MASK1_HORIZONTAL_FLIP
#undef BLENDFUNCTION
#undef SHOW_MATERIAL

#define BLENDFUNCTION Blend4444_MAT
#define SHOW_MATERIAL
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef MASK1_HORIZONTAL_FLIP
#include "BlendMode4444.hpp"
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef MASK1_HORIZONTAL_FLIP
#undef BLENDFUNCTION
#undef SHOW_MATERIAL

#define BLENDFUNCTION Blend4444_TH_MAT
#define SHOW_MATERIAL
#define TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef MASK1_HORIZONTAL_FLIP
#include "BlendMode4444.hpp"
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef MASK1_HORIZONTAL_FLIP
#undef BLENDFUNCTION
#undef SHOW_MATERIAL

#define BLENDFUNCTION Blend555_1_1_MAT
#define SHOW_MATERIAL
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#include "BlendMode555_1_1.hpp"
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef BLENDFUNCTION
#undef SHOW_MATERIAL

#define BLENDFUNCTION Blend555_1_1_TH_MAT
#define SHOW_MATERIAL
#define TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#include "BlendMode555_1_1.hpp"
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef BLENDFUNCTION
#undef SHOW_MATERIAL

#define BLENDFUNCTION Blend555_1_1_M0H_MAT
#define SHOW_MATERIAL
#undef TEXTURE_HORIZONTAL_FLIP
#define MASK0_HORIZONTAL_FLIP
#include "BlendMode555_1_1.hpp"
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef BLENDFUNCTION
#undef SHOW_MATERIAL

#define BLENDFUNCTION Blend555_1_1_TH_M0H_MAT
#define SHOW_MATERIAL
#define TEXTURE_HORIZONTAL_FLIP
#define MASK0_HORIZONTAL_FLIP
#include "BlendMode555_1_1.hpp"
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef BLENDFUNCTION
#undef SHOW_MATERIAL

#define BLENDFUNCTION BlendSS_MAT
#define SHOW_MATERIAL
#undef MASK0_HORIZONTAL_FLIP
#include "BlendModeSS.hpp"
#undef MASK0_HORIZONTAL_FLIP
#undef BLENDFUNCTION
#undef SHOW_MATERIAL

#define BLENDFUNCTION Blend555_1_S_MAT
#define SHOW_MATERIAL
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#include "BlendMode555_1_S.hpp"
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef BLENDFUNCTION
#undef SHOW_MATERIAL

#define BLENDFUNCTION Blend555_1_S_TH_MAT
#define SHOW_MATERIAL
#define TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#include "BlendMode555_1_S.hpp"
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef BLENDFUNCTION
#undef SHOW_MATERIAL

#define BLENDFUNCTION Blend555_1_S_M0H_MAT
#define SHOW_MATERIAL
#undef TEXTURE_HORIZONTAL_FLIP
#define MASK0_HORIZONTAL_FLIP
#include "BlendMode555_1_S.hpp"
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef BLENDFUNCTION
#undef SHOW_MATERIAL

#define BLENDFUNCTION Blend555_1_S_TH_M0H_MAT
#define SHOW_MATERIAL
#define TEXTURE_HORIZONTAL_FLIP
#define MASK0_HORIZONTAL_FLIP
#include "BlendMode555_1_S.hpp"
#undef TEXTURE_HORIZONTAL_FLIP
#undef MASK0_HORIZONTAL_FLIP
#undef BLENDFUNCTION
#undef SHOW_MATERIAL
