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