Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/quicknes/nes_emu/Nes_Ppu_Sprites.h
2 views
1
2
int sprite_2 = sprite [2];
3
4
// pixels
5
ptrdiff_t next_row = this->scanline_row_bytes;
6
byte* out = this->scanline_pixels + sprite [3] +
7
(top_minus_one + skip - begin_minus_one) * next_row;
8
cache_t const* lines = get_sprite_tile( sprite );
9
10
int dir = 1;
11
byte* scanlines = this->sprite_scanlines + 1 + top_minus_one + skip;
12
13
if ( sprite_2 & 0x80 )
14
{
15
// vertical flip
16
out -= next_row;
17
out += visible * next_row;
18
next_row = -next_row;
19
dir = -1;
20
scanlines += visible - 1;
21
#if CLIPPED
22
int height = this->sprite_height();
23
skip = height - skip - visible;
24
assert( skip + visible <= height );
25
#endif
26
}
27
28
// attributes
29
unsigned long offset = (sprite_2 & 3) * 0x04040404 + (this->palette_offset + 0x10101010);
30
31
unsigned long const mask = 0x03030303 + zero;
32
unsigned long const maskgen = 0x80808080 + zero;
33
34
#define DRAW_PAIR( shift ) { \
35
int sprite_count = *scanlines; \
36
CALC_FOUR( ((uint32_t*) out) [0], (line >> (shift + 4)), out0 ) \
37
CALC_FOUR( ((uint32_t*) out) [1], (line >> shift), out1 ) \
38
if ( sprite_count < this->max_sprites ) { \
39
((uint32_t*) out) [0] = out0; \
40
((uint32_t*) out) [1] = out1; \
41
} \
42
if ( CLIPPED ) visible--; \
43
out += next_row; \
44
*scanlines = sprite_count + 1; \
45
scanlines += dir; \
46
if ( CLIPPED && !visible ) break; \
47
}
48
49
if ( !(sprite_2 & 0x20) )
50
{
51
// front
52
unsigned long const maskgen2 = 0x7f7f7f7f + zero;
53
54
#define CALC_FOUR( in, line, out ) \
55
unsigned long out; \
56
{ \
57
unsigned long bg = in; \
58
unsigned long sp = line & mask; \
59
unsigned long bgm = maskgen2 + ((bg >> 4) & mask); \
60
unsigned long spm = (maskgen - sp) & maskgen2; \
61
unsigned long m = (bgm & spm) >> 2; \
62
out = (bg & ~m) | ((sp + offset) & m); \
63
}
64
65
#if CLIPPED
66
lines += skip >> 1;
67
unsigned long line = *lines++;
68
if ( skip & 1 )
69
goto front_skip;
70
71
while ( true )
72
{
73
DRAW_PAIR( 0 )
74
front_skip:
75
DRAW_PAIR( 2 )
76
line = *lines++;
77
}
78
#else
79
for ( int n = visible >> 1; n--; )
80
{
81
unsigned long line = *lines++;
82
DRAW_PAIR( 0 )
83
DRAW_PAIR( 2 )
84
}
85
#endif
86
87
#undef CALC_FOUR
88
}
89
else
90
{
91
// behind
92
unsigned long const omask = 0x20202020 + zero;
93
unsigned long const bg_or = 0xc3c3c3c3 + zero;
94
95
#define CALC_FOUR( in, line, out ) \
96
unsigned long out; \
97
{ \
98
unsigned long bg = in; \
99
unsigned long sp = line & mask; \
100
unsigned long bgm = maskgen - (bg & mask); \
101
unsigned long spm = maskgen - sp; \
102
out = (bg & (bgm | bg_or)) | (spm & omask) | \
103
(((offset & spm) + sp) & ~(bgm >> 2)); \
104
}
105
106
#if CLIPPED
107
lines += skip >> 1;
108
unsigned long line = *lines++;
109
if ( skip & 1 )
110
goto back_skip;
111
112
while ( true )
113
{
114
DRAW_PAIR( 0 )
115
back_skip:
116
DRAW_PAIR( 2 )
117
line = *lines++;
118
}
119
#else
120
for ( int n = visible >> 1; n--; )
121
{
122
unsigned long line = *lines++;
123
DRAW_PAIR( 0 )
124
DRAW_PAIR( 2 )
125
}
126
#endif
127
128
#undef CALC_FOUR
129
}
130
131
#undef CLIPPED
132
#undef DRAW_PAIR
133
134