//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	FeatureGrid::BLENDFUNCTION (
		FeatureInstance *featureInstance, 
		unsigned char *pix_buf,
		int x, int z,
		int start_span, 
		int end_span,
		int downScale
	)
{
	Feature *feature = featureInstance->feature;

	Verify(feature->featureMask0!=NULL);
	

#ifdef SHOW_MATERIAL
	DWORD mat_color = downScale & 0xffffff;
	downScale >>= 24;
#else
	int texture_width = (featureInstance->feature->featureTexture->width) >> downScale;
	int count_down = featureInstance->countDownToBorder;
	WORD *data_ptr_word = (WORD *)featureInstance->currentTexturePtr;
#endif

//===============================================================
	int mask0_x_off, mask0_z_off;

	int mask0_x = (x-featureInstance->feature_x_pos) >> feature->GetXMask0Scale();
	int mask0_z = (z-featureInstance->feature_z_pos) >> feature->GetZMask0Scale();
	mask0_x_off = (x-featureInstance->feature_x_pos) & ((1<<feature->GetXMask0Scale())-1);
	mask0_z_off = (z-featureInstance->feature_z_pos) & ((1<<feature->GetZMask0Scale())-1);

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

	if(! (mask0_x<feature->featureMask0->width+1) )
	{
		SPEW(("micgaert", "Whats going on in here ?"));
	}
	if(! (mask0_z<feature->featureMask0->height+1) )
	{
		SPEW(("micgaert", "Whats going on in here ?"));
	}

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

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

	int mask0_x_bit = mask0_x & 7;
#ifdef MASK0_HORIZONTAL_FLIP
	int bit_mask = 0x80>>mask0_x_bit;
#else
	int bit_mask = 1<<mask0_x_bit;
#endif

	mask0_x >>= 3;

	int pitch = (feature->featureMask0->width>>3) + 2;
	unsigned char *mask0data = feature->featureMask0->data
		+ (mask0_z+1)*pitch + mask0_x + 1;

//===============================================================

	mask0_x_off >>= downScale;
	mask0_z_off >>= downScale;

	int shifter = feature->GetZMask0Scale() + feature->GetXMask0Scale() - 2*downScale;

	int x_stretch = 1<<(feature->GetXMask0Scale()-downScale);
	int z_stretch = 1<<(feature->GetZMask0Scale()-downScale);

#ifdef MASK0_HORIZONTAL_FLIP
	int advancer = x_stretch-1;
#else
	int advancer = ~(x_stretch-1);
#endif

	int adv, mixH, mix0, mix1, mix00, mix01, mix10, mix11;

	mix00 = (*mask0data & bit_mask) ? 0xff : 0;
	mix10 = (*(mask0data + pitch) & bit_mask) ? 0xff : 0;

	int off = 0;
#ifdef MASK0_HORIZONTAL_FLIP
	bit_mask >>= 1;
	if(bit_mask == 0)
	{
		off = 1;
		bit_mask = 0x80;
	}
#else
	bit_mask <<= 1;
	if(bit_mask > 0x80)
	{
		off = 1;
		bit_mask = 1;
	}
#endif

	mix01 = (*(mask0data + off) & bit_mask) ? 0xff : 0;
	mix11 = (*(mask0data + pitch + off) & bit_mask) ? 0xff : 0;

	mix0 = (mix00*(z_stretch - mask0_z_off) + mix10*mask0_z_off);
	mix1 = (mix01*(z_stretch - mask0_z_off) + mix11*mask0_z_off);

	mixH = (mix0*(x_stretch - mask0_x_off) + mix1*mask0_x_off);

	adv = mix1 - mix0;

	int *pix_buf_int = (int *)pix_buf;
	for(int i=0;;)
	{
		int mix = mixH>>shifter;

#ifdef MASK0_HORIZONTAL_FLIP
		mixH -= adv;
#else
		mixH += adv;
#endif

#ifdef SHOW_MATERIAL
		if(mix > 0x80)
		{
			pix_buf_int[i] = mat_color;
		}
#else	// SHOW_MATERIAL
		if(mix!=0)
		{
			DWORD dst = pix_buf_int[i];
	#ifdef TEXTURE_HORIZONTAL_FLIP
			DWORD src = data_ptr_word[-i];
	#else	// TEXTURE_HORIZONTAL_FLIP
			DWORD src = data_ptr_word[i];
	#endif	// TEXTURE_HORIZONTAL_FLIP
			DWORD buf;
			DWORD srcmix = mix<<3;

			mix = 0xff-mix;

			buf = ((dst & 0xff)*mix + (src & 0x1f)*srcmix)>>8;

			buf |= (((dst>>8)&0xff)*mix + ((src & 0x3e0) >> 5)*srcmix)&0xff00;

			buf |= ((((dst>>16)&0xff)*mix + (src >> 10)*srcmix)&0xff00)<<8;

			pix_buf_int[i] = buf;
		}
#endif	// SHOW_MATERIAL

		if(++i>=end_span-start_span)
		{
			break;
		}

#ifdef MASK0_HORIZONTAL_FLIP
#ifndef SHOW_MATERIAL
		if(--count_down <= 0)
		{
			data_ptr_word += texture_width;
			count_down = texture_width;
		}
#endif
		if(--mask0_x_off < 0)
		{
			mask0_x_off = advancer;
			if(off)
			{
				mask0data--;
			}

			bit_mask >>= 1;
			off = 0;
			if(bit_mask == 0)
			{
				off = 1;
				bit_mask = 0x80;
			}

			mix01 = mix00;
			mix00 = (*(mask0data - off) & bit_mask) ? 0xff : 0;
			mix11 = mix10;
			mix10 = (*(mask0data + pitch - off) & bit_mask) ? 0xff : 0;


			mix1 = mix0;
			mix0 = (mix00*(z_stretch - mask0_z_off) + mix10*mask0_z_off);
#else
#ifndef SHOW_MATERIAL
		if(--count_down <= 0)
		{
			data_ptr_word -= texture_width;
			count_down = texture_width;
		}
#endif
		if(++mask0_x_off & advancer)
		{
			mask0_x_off = 0;
			if(off)
			{
				mask0data++;
			}

			bit_mask <<= 1;
			off = 0;
			if(bit_mask > 0x80)
			{
				off = 1;
				bit_mask = 1;
			}

			mix00 = mix01;
			mix01 = (*(mask0data + off) & bit_mask) ? 0xff : 0;
			mix10 = mix11;
			mix11 = (*(mask0data + pitch + off) & bit_mask) ? 0xff : 0;


			mix0 = mix1;
			mix1 = (mix01*(z_stretch - mask0_z_off) + mix11*mask0_z_off);
#endif

			mixH = (mix0*(x_stretch - mask0_x_off) + mix1*mask0_x_off);

			adv = mix1 - mix0;
		}
	}
}
