
int sprite_2 = sprite [2];

// pixels
ptrdiff_t next_row = this->scanline_row_bytes;
uint8_t* out = this->scanline_pixels + sprite [3] +
		(top_minus_one + skip - begin_minus_one) * next_row;
cache_t const* lines = get_sprite_tile( sprite );

int dir = 1;
uint8_t* scanlines = this->sprite_scanlines + 1 + top_minus_one + skip;

if ( sprite_2 & 0x80 )
{
	// vertical flip
	out -= next_row;
	out += visible * next_row;
	next_row = -next_row;
	dir = -1;
	scanlines += visible - 1;
	#if CLIPPED
		int height = this->sprite_height();
		skip = height - skip - visible;
	#endif
}

// attributes
unsigned long offset = (sprite_2 & 3) * 0x04040404 + (this->palette_offset + 0x10101010);

unsigned long const mask    = 0x03030303 + zero;
unsigned long const maskgen = 0x80808080 + zero;

#define DRAW_PAIR( shift ) {                    \
	int sprite_count = *scanlines;              \
	CALC_FOUR( ((unaligned_uint32_t*) out) [0].val, (line >> (shift + 4)), out0 ) \
	CALC_FOUR( ((unaligned_uint32_t*) out) [1].val, (line >> shift), out1 )       \
	if ( sprite_count < this->max_sprites ) {   \
		((unaligned_uint32_t*) out) [0].val = out0;           \
		((unaligned_uint32_t*) out) [1].val = out1;           \
	}                                           \
	if ( CLIPPED ) visible--;                   \
	out += next_row;                            \
	*scanlines = sprite_count + 1;              \
	scanlines += dir;                           \
	if ( CLIPPED && !visible ) break;           \
}

if ( !(sprite_2 & 0x20) )
{
	// front
	unsigned long const maskgen2 = 0x7f7f7f7f + zero;

	#define CALC_FOUR( in, line, out )                          \
		unsigned long out;                                      \
		{                                                       \
			unsigned long bg = in;                              \
			unsigned long sp = line & mask;                     \
			unsigned long bgm = maskgen2 + ((bg >> 4) & mask);  \
			unsigned long spm = (maskgen - sp) & maskgen2;      \
			unsigned long m = (bgm & spm) >> 2;                 \
			out = (bg & ~m) | ((sp + offset) & m);              \
		}
	
	#if CLIPPED
		lines += skip >> 1;
		unsigned long line = *lines++;
		if ( skip & 1 )
			goto front_skip;
		
		while ( true )
		{
			DRAW_PAIR( 0 )
		front_skip:
			DRAW_PAIR( 2 )
			line = *lines++;
		}
	#else
		for ( int n = visible >> 1; n--; )
		{
			unsigned long line = *lines++;
			DRAW_PAIR( 0 )
			DRAW_PAIR( 2 )
		}
	#endif
	
	#undef CALC_FOUR
}
else
{
	// behind
	unsigned long const omask = 0x20202020 + zero;
	unsigned long const bg_or = 0xc3c3c3c3 + zero;

	#define CALC_FOUR( in, line, out )                      \
		unsigned long out;                                  \
		{                                                   \
			unsigned long bg = in;                          \
			unsigned long sp = line & mask;                 \
			unsigned long bgm = maskgen - (bg & mask);      \
			unsigned long spm = maskgen - sp;               \
			out = (bg & (bgm | bg_or)) | (spm & omask) |    \
					(((offset & spm) + sp) & ~(bgm >> 2));  \
		}
	
	#if CLIPPED
		lines += skip >> 1;
		unsigned long line = *lines++;
		if ( skip & 1 )
			goto back_skip;
		
		while ( true )
		{
			DRAW_PAIR( 0 )
		back_skip:
			DRAW_PAIR( 2 )
			line = *lines++;
		}
	#else
		for ( int n = visible >> 1; n--; )
		{
			unsigned long line = *lines++;
			DRAW_PAIR( 0 )
			DRAW_PAIR( 2 )
		}
	#endif
	
	#undef CALC_FOUR
}

#undef CLIPPED
#undef DRAW_PAIR
