1 static int32_t blenderone = 0xff;
2 
3 static uint8_t bldiv_hwaccurate_table[0x8000];
4 
set_blender_input(uint32_t wid,int cycle,int which,int32_t ** input_r,int32_t ** input_g,int32_t ** input_b,int32_t ** input_a,int a,int b)5 static INLINE void set_blender_input(uint32_t wid, int cycle, int which, int32_t **input_r, int32_t **input_g, int32_t **input_b, int32_t **input_a, int a, int b)
6 {
7 
8     switch (a & 0x3)
9     {
10         case 0:
11         {
12             if (cycle == 0)
13             {
14                 *input_r = &state[wid].pixel_color.r;
15                 *input_g = &state[wid].pixel_color.g;
16                 *input_b = &state[wid].pixel_color.b;
17             }
18             else
19             {
20                 *input_r = &state[wid].blended_pixel_color.r;
21                 *input_g = &state[wid].blended_pixel_color.g;
22                 *input_b = &state[wid].blended_pixel_color.b;
23             }
24             break;
25         }
26 
27         case 1:
28         {
29             *input_r = &state[wid].memory_color.r;
30             *input_g = &state[wid].memory_color.g;
31             *input_b = &state[wid].memory_color.b;
32             break;
33         }
34 
35         case 2:
36         {
37             *input_r = &state[wid].blend_color.r;      *input_g = &state[wid].blend_color.g;      *input_b = &state[wid].blend_color.b;
38             break;
39         }
40 
41         case 3:
42         {
43             *input_r = &state[wid].fog_color.r;        *input_g = &state[wid].fog_color.g;        *input_b = &state[wid].fog_color.b;
44             break;
45         }
46     }
47 
48     if (which == 0)
49     {
50         switch (b & 0x3)
51         {
52             case 0:     *input_a = &state[wid].pixel_color.a; break;
53             case 1:     *input_a = &state[wid].fog_color.a; break;
54             case 2:     *input_a = &state[wid].blender_shade_alpha; break;
55             case 3:     *input_a = &zero_color; break;
56         }
57     }
58     else
59     {
60         switch (b & 0x3)
61         {
62             case 0:     *input_a = &state[wid].inv_pixel_color.a; break;
63             case 1:     *input_a = &state[wid].memory_color.a; break;
64             case 2:     *input_a = &blenderone; break;
65             case 3:     *input_a = &zero_color; break;
66         }
67     }
68 }
69 
alpha_compare(uint32_t wid,int32_t comb_alpha)70 static STRICTINLINE int alpha_compare(uint32_t wid, int32_t comb_alpha)
71 {
72     int32_t threshold;
73     if (!state[wid].other_modes.alpha_compare_en)
74         return 1;
75     else
76     {
77         if (!state[wid].other_modes.dither_alpha_en)
78             threshold = state[wid].blend_color.a;
79         else
80             threshold = irand(&state[wid].rseed) & 0xff;
81 
82 
83         if (comb_alpha >= threshold)
84             return 1;
85         else
86             return 0;
87     }
88 }
89 
blender_equation_cycle0(uint32_t wid,int * r,int * g,int * b)90 static STRICTINLINE void blender_equation_cycle0(uint32_t wid, int* r, int* g, int* b)
91 {
92     int blend1a, blend2a;
93     int blr, blg, blb, sum;
94     blend1a = *state[wid].blender1b_a[0] >> 3;
95     blend2a = *state[wid].blender2b_a[0] >> 3;
96 
97     int mulb;
98 
99 
100 
101     if (state[wid].blender2b_a[0] == &state[wid].memory_color.a)
102     {
103         blend1a = (blend1a >> state[wid].blshifta) & 0x3C;
104         blend2a = (blend2a >> state[wid].blshiftb) | 3;
105     }
106 
107     mulb = blend2a + 1;
108 
109 
110     blr = (*state[wid].blender1a_r[0]) * blend1a + (*state[wid].blender2a_r[0]) * mulb;
111     blg = (*state[wid].blender1a_g[0]) * blend1a + (*state[wid].blender2a_g[0]) * mulb;
112     blb = (*state[wid].blender1a_b[0]) * blend1a + (*state[wid].blender2a_b[0]) * mulb;
113 
114 
115 
116     if (!state[wid].other_modes.force_blend)
117     {
118 
119 
120 
121 
122 
123         sum = ((blend1a & ~3) + (blend2a & ~3) + 4) << 9;
124         *r = bldiv_hwaccurate_table[sum | ((blr >> 2) & 0x7ff)];
125         *g = bldiv_hwaccurate_table[sum | ((blg >> 2) & 0x7ff)];
126         *b = bldiv_hwaccurate_table[sum | ((blb >> 2) & 0x7ff)];
127     }
128     else
129     {
130         *r = (blr >> 5) & 0xff;
131         *g = (blg >> 5) & 0xff;
132         *b = (blb >> 5) & 0xff;
133     }
134 }
135 
blender_equation_cycle0_2(uint32_t wid,int * r,int * g,int * b)136 static STRICTINLINE void blender_equation_cycle0_2(uint32_t wid, int* r, int* g, int* b)
137 {
138     int blend1a, blend2a;
139     blend1a = *state[wid].blender1b_a[0] >> 3;
140     blend2a = *state[wid].blender2b_a[0] >> 3;
141 
142     if (state[wid].blender2b_a[0] == &state[wid].memory_color.a)
143     {
144         blend1a = (blend1a >> state[wid].pastblshifta) & 0x3C;
145         blend2a = (blend2a >> state[wid].pastblshiftb) | 3;
146     }
147 
148     blend2a += 1;
149     *r = (((*state[wid].blender1a_r[0]) * blend1a + (*state[wid].blender2a_r[0]) * blend2a) >> 5) & 0xff;
150     *g = (((*state[wid].blender1a_g[0]) * blend1a + (*state[wid].blender2a_g[0]) * blend2a) >> 5) & 0xff;
151     *b = (((*state[wid].blender1a_b[0]) * blend1a + (*state[wid].blender2a_b[0]) * blend2a) >> 5) & 0xff;
152 }
153 
blender_equation_cycle1(uint32_t wid,int * r,int * g,int * b)154 static STRICTINLINE void blender_equation_cycle1(uint32_t wid, int* r, int* g, int* b)
155 {
156     int blend1a, blend2a;
157     int blr, blg, blb, sum;
158     blend1a = *state[wid].blender1b_a[1] >> 3;
159     blend2a = *state[wid].blender2b_a[1] >> 3;
160 
161     int mulb;
162     if (state[wid].blender2b_a[1] == &state[wid].memory_color.a)
163     {
164         blend1a = (blend1a >> state[wid].blshifta) & 0x3C;
165         blend2a = (blend2a >> state[wid].blshiftb) | 3;
166     }
167 
168     mulb = blend2a + 1;
169     blr = (*state[wid].blender1a_r[1]) * blend1a + (*state[wid].blender2a_r[1]) * mulb;
170     blg = (*state[wid].blender1a_g[1]) * blend1a + (*state[wid].blender2a_g[1]) * mulb;
171     blb = (*state[wid].blender1a_b[1]) * blend1a + (*state[wid].blender2a_b[1]) * mulb;
172 
173     if (!state[wid].other_modes.force_blend)
174     {
175         sum = ((blend1a & ~3) + (blend2a & ~3) + 4) << 9;
176         *r = bldiv_hwaccurate_table[sum | ((blr >> 2) & 0x7ff)];
177         *g = bldiv_hwaccurate_table[sum | ((blg >> 2) & 0x7ff)];
178         *b = bldiv_hwaccurate_table[sum | ((blb >> 2) & 0x7ff)];
179     }
180     else
181     {
182         *r = (blr >> 5) & 0xff;
183         *g = (blg >> 5) & 0xff;
184         *b = (blb >> 5) & 0xff;
185     }
186 }
187 
blender_1cycle(uint32_t wid,uint32_t * fr,uint32_t * fg,uint32_t * fb,int dith,uint32_t blend_en,uint32_t prewrap,uint32_t curpixel_cvg,uint32_t curpixel_cvbit)188 static STRICTINLINE int blender_1cycle(uint32_t wid, uint32_t* fr, uint32_t* fg, uint32_t* fb, int dith, uint32_t blend_en, uint32_t prewrap, uint32_t curpixel_cvg, uint32_t curpixel_cvbit)
189 {
190     int r, g, b, dontblend;
191 
192 
193     if (alpha_compare(wid, state[wid].pixel_color.a))
194     {
195 
196 
197 
198 
199 
200 
201         if (state[wid].other_modes.antialias_en ? curpixel_cvg : curpixel_cvbit)
202         {
203 
204             if (!state[wid].other_modes.color_on_cvg || prewrap)
205             {
206                 dontblend = (state[wid].other_modes.f.partialreject_1cycle && state[wid].pixel_color.a >= 0xff);
207                 if (!blend_en || dontblend)
208                 {
209                     r = *state[wid].blender1a_r[0];
210                     g = *state[wid].blender1a_g[0];
211                     b = *state[wid].blender1a_b[0];
212                 }
213                 else
214                 {
215                     state[wid].inv_pixel_color.a =  (~(*state[wid].blender1b_a[0])) & 0xff;
216 
217 
218 
219 
220 
221                     blender_equation_cycle0(wid, &r, &g, &b);
222                 }
223             }
224             else
225             {
226                 r = *state[wid].blender2a_r[0];
227                 g = *state[wid].blender2a_g[0];
228                 b = *state[wid].blender2a_b[0];
229             }
230 
231             if (state[wid].other_modes.rgb_dither_sel != 3)
232                 rgb_dither(state[wid].other_modes.rgb_dither_sel, &r, &g, &b, dith);
233 
234             *fr = r;
235             *fg = g;
236             *fb = b;
237             return 1;
238         }
239         else
240             return 0;
241         }
242     else
243         return 0;
244 }
245 
blender_2cycle_cycle0(uint32_t wid,uint32_t curpixel_cvg,uint32_t curpixel_cvbit)246 static STRICTINLINE int blender_2cycle_cycle0(uint32_t wid, uint32_t curpixel_cvg, uint32_t curpixel_cvbit)
247 {
248     int r, g, b;
249     int wen = (state[wid].other_modes.antialias_en ? curpixel_cvg : curpixel_cvbit) > 0 ? 1 : 0;
250 
251     if (wen)
252     {
253         state[wid].inv_pixel_color.a =  (~(*state[wid].blender1b_a[0])) & 0xff;
254 
255         blender_equation_cycle0_2(wid, &r, &g, &b);
256 
257         state[wid].blended_pixel_color.r = r;
258         state[wid].blended_pixel_color.g = g;
259         state[wid].blended_pixel_color.b = b;
260     }
261 
262     state[wid].memory_color = state[wid].pre_memory_color;
263 
264     return wen;
265 }
266 
267 
blender_2cycle_cycle1(uint32_t wid,uint32_t * fr,uint32_t * fg,uint32_t * fb,int dith,uint32_t blend_en,uint32_t prewrap)268 static STRICTINLINE void blender_2cycle_cycle1(uint32_t wid, uint32_t* fr, uint32_t* fg, uint32_t* fb, int dith, uint32_t blend_en, uint32_t prewrap)
269 {
270     int r, g, b, dontblend;
271 
272     if (!state[wid].other_modes.color_on_cvg || prewrap)
273     {
274         dontblend = (state[wid].other_modes.f.partialreject_2cycle && state[wid].pixel_color.a >= 0xff);
275         if (!blend_en || dontblend)
276         {
277             r = *state[wid].blender1a_r[1];
278             g = *state[wid].blender1a_g[1];
279             b = *state[wid].blender1a_b[1];
280         }
281         else
282         {
283             state[wid].inv_pixel_color.a =  (~(*state[wid].blender1b_a[1])) & 0xff;
284             blender_equation_cycle1(wid, &r, &g, &b);
285         }
286     }
287     else
288     {
289         r = *state[wid].blender2a_r[1];
290         g = *state[wid].blender2a_g[1];
291         b = *state[wid].blender2a_b[1];
292     }
293 
294     if (state[wid].other_modes.rgb_dither_sel != 3)
295         rgb_dither(state[wid].other_modes.rgb_dither_sel, &r, &g, &b, dith);
296 
297     *fr = r;
298     *fg = g;
299     *fb = b;
300 }
301 
blender_init_lut(void)302 static void blender_init_lut(void)
303 {
304     int i, k;
305     int d = 0, n = 0, temp = 0, res = 0, invd = 0, nbit = 0;
306     int ps[9];
307     for (i = 0; i < 0x8000; i++)
308     {
309         res = 0;
310         d = (i >> 11) & 0xf;
311         n = i & 0x7ff;
312         invd = (~d) & 0xf;
313 
314 
315         temp = invd + (n >> 8) + 1;
316         ps[0] = temp & 7;
317         for (k = 0; k < 8; k++)
318         {
319             nbit = (n >> (7 - k)) & 1;
320             if (res & (0x100 >> k))
321                 temp = invd + (ps[k] << 1) + nbit + 1;
322             else
323                 temp = d + (ps[k] << 1) + nbit;
324             ps[k + 1] = temp & 7;
325             if (temp & 0x10)
326                 res |= (1 << (7 - k));
327         }
328         bldiv_hwaccurate_table[i] = res;
329     }
330 }
331 
rdp_set_fog_color(uint32_t wid,const uint32_t * args)332 void rdp_set_fog_color(uint32_t wid, const uint32_t* args)
333 {
334     state[wid].fog_color.r = RGBA32_R(args[1]);
335     state[wid].fog_color.g = RGBA32_G(args[1]);
336     state[wid].fog_color.b = RGBA32_B(args[1]);
337     state[wid].fog_color.a = RGBA32_A(args[1]);
338 }
339 
rdp_set_blend_color(uint32_t wid,const uint32_t * args)340 void rdp_set_blend_color(uint32_t wid, const uint32_t* args)
341 {
342     state[wid].blend_color.r = RGBA32_R(args[1]);
343     state[wid].blend_color.g = RGBA32_G(args[1]);
344     state[wid].blend_color.b = RGBA32_B(args[1]);
345     state[wid].blend_color.a = RGBA32_A(args[1]);
346 }
347