132 lines
3.4 KiB
C
132 lines
3.4 KiB
C
|
|
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
|