trunk/src/mame/video/rdpblend.c
r25448 | r25449 | |
2 | 2 | #include "includes/n64.h" |
3 | 3 | #include "video/n64.h" |
4 | 4 | |
5 | | bool N64BlenderT::Blend1Cycle(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel, rdp_span_aux *userdata, const rdp_poly_state& object) |
| 5 | N64BlenderT::N64BlenderT() |
6 | 6 | { |
7 | | INT32 r, g, b; |
| 7 | blend1[0] = &N64BlenderT::Blend1CycleNoBlendNoACVGNoDither; |
| 8 | blend1[1] = &N64BlenderT::Blend1CycleNoBlendNoACVGDither; |
| 9 | blend1[2] = &N64BlenderT::Blend1CycleNoBlendACVGNoDither; |
| 10 | blend1[3] = &N64BlenderT::Blend1CycleNoBlendACVGDither; |
| 11 | blend1[4] = &N64BlenderT::Blend1CycleBlendNoACVGNoDither; |
| 12 | blend1[5] = &N64BlenderT::Blend1CycleBlendNoACVGDither; |
| 13 | blend1[6] = &N64BlenderT::Blend1CycleBlendACVGNoDither; |
| 14 | blend1[7] = &N64BlenderT::Blend1CycleBlendACVGDither; |
8 | 15 | |
9 | | if (!object.OtherModes.alpha_cvg_select) |
10 | | { |
11 | | DitherA(&userdata->PixelColor.i.a, adseed); |
12 | | } |
| 16 | blend2[0] = &N64BlenderT::Blend2CycleNoBlendNoACVGNoDither; |
| 17 | blend2[1] = &N64BlenderT::Blend2CycleNoBlendNoACVGDither; |
| 18 | blend2[2] = &N64BlenderT::Blend2CycleNoBlendACVGNoDither; |
| 19 | blend2[3] = &N64BlenderT::Blend2CycleNoBlendACVGDither; |
| 20 | blend2[4] = &N64BlenderT::Blend2CycleBlendNoACVGNoDither; |
| 21 | blend2[5] = &N64BlenderT::Blend2CycleBlendNoACVGDither; |
| 22 | blend2[6] = &N64BlenderT::Blend2CycleBlendACVGNoDither; |
| 23 | blend2[7] = &N64BlenderT::Blend2CycleBlendACVGDither; |
13 | 24 | |
14 | | DitherA(&userdata->ShadeColor.i.a, adseed); |
| 25 | cycle0[0] = &N64BlenderT::BlendEquationCycle0NoForceNoSpecial; |
| 26 | cycle0[1] = &N64BlenderT::BlendEquationCycle0NoForceSpecial; |
| 27 | cycle0[2] = &N64BlenderT::BlendEquationCycle0ForceNoSpecial; |
| 28 | cycle0[3] = &N64BlenderT::BlendEquationCycle0ForceSpecial; |
15 | 29 | |
16 | | if (!AlphaCompare(userdata->PixelColor.i.a, userdata, object)) |
17 | | { |
18 | | return false; |
| 30 | cycle1[0] = &N64BlenderT::BlendEquationCycle1NoForceNoSpecial; |
| 31 | cycle1[1] = &N64BlenderT::BlendEquationCycle1NoForceSpecial; |
| 32 | cycle1[2] = &N64BlenderT::BlendEquationCycle1ForceNoSpecial; |
| 33 | cycle1[3] = &N64BlenderT::BlendEquationCycle1ForceSpecial; |
| 34 | } |
| 35 | |
| 36 | #define ALPHA_COMPARE() \ |
| 37 | if (!AlphaCompare(userdata->PixelColor.i.a, userdata, object)) \ |
| 38 | { \ |
| 39 | return false; \ |
19 | 40 | } |
20 | 41 | |
21 | | if (object.OtherModes.antialias_en ? (!userdata->CurrentPixCvg) : (!userdata->CurrentCvgBit)) |
22 | | { |
23 | | return false; |
| 42 | #define CVG_COMPARE() \ |
| 43 | if (object.OtherModes.antialias_en ? (!userdata->CurrentPixCvg) : (!userdata->CurrentCvgBit)) \ |
| 44 | { \ |
| 45 | return false; \ |
24 | 46 | } |
25 | 47 | |
26 | | bool dontblend = (partialreject && userdata->PixelColor.i.a >= 0xff); |
27 | | if (!userdata->BlendEnable || dontblend) |
28 | | { |
29 | | r = *userdata->ColorInputs.blender1a_r[0]; |
30 | | g = *userdata->ColorInputs.blender1a_g[0]; |
31 | | b = *userdata->ColorInputs.blender1a_b[0]; |
| 48 | #define TEST_REJECT() \ |
| 49 | ALPHA_COMPARE() \ |
| 50 | CVG_COMPARE() |
| 51 | |
| 52 | #define WRITE_OUT_NB_ND(cycle) \ |
| 53 | *fr = *userdata->ColorInputs.blender1a_r[cycle]; \ |
| 54 | *fg = *userdata->ColorInputs.blender1a_g[cycle]; \ |
| 55 | *fb = *userdata->ColorInputs.blender1a_b[cycle]; |
| 56 | |
| 57 | #define WRITE_OUT() \ |
| 58 | *fr = r; \ |
| 59 | *fg = g; \ |
| 60 | *fb = b; |
| 61 | |
| 62 | #define WRITE_BLENDED_COLOR() \ |
| 63 | userdata->BlendedPixelColor.i.r = r; \ |
| 64 | userdata->BlendedPixelColor.i.g = g; \ |
| 65 | userdata->BlendedPixelColor.i.b = b; \ |
| 66 | userdata->BlendedPixelColor.i.a = userdata->PixelColor.i.a; |
| 67 | |
| 68 | #define BLEND_CYCLE(cyc) \ |
| 69 | if (partialreject && userdata->PixelColor.i.a >= 0xff) \ |
| 70 | { \ |
| 71 | ASSIGN_OUT(cyc); \ |
| 72 | } \ |
| 73 | else \ |
| 74 | { \ |
| 75 | userdata->InvPixelColor.i.a = 0xff - *userdata->ColorInputs.blender1b_a[cyc]; \ |
| 76 | ((this)->*(cycle##cyc[((object.OtherModes.force_blend & 1) << 1) | (special_bsel##cyc & 1)]))(&r, &g, &b, userdata, object); \ |
32 | 77 | } |
33 | | else |
34 | | { |
35 | | userdata->InvPixelColor.i.a = 0xff - *userdata->ColorInputs.blender1b_a[0]; |
36 | | BlendEquationCycle0(&r, &g, &b, special_bsel, userdata, object); |
37 | | } |
38 | 78 | |
39 | | if (object.OtherModes.rgb_dither_sel < 3) |
40 | | { |
41 | | DitherRGB(&r, &g, &b, dith); |
| 79 | #define BLEND_FACTORS(cycle) \ |
| 80 | UINT8 blend1a = *userdata->ColorInputs.blender1b_a[cycle] >> 3; \ |
| 81 | UINT8 blend2a = *userdata->ColorInputs.blender2b_a[cycle] >> 3; |
| 82 | |
| 83 | #define BLEND_FACTORS_SUM(cycle) \ |
| 84 | UINT8 blend1a = *userdata->ColorInputs.blender1b_a[cycle] >> 3; \ |
| 85 | UINT8 blend2a = *userdata->ColorInputs.blender2b_a[cycle] >> 3; \ |
| 86 | UINT32 sum = ((blend1a >> 2) + (blend2a >> 2) + 1) & 0xf; |
| 87 | |
| 88 | #define BLEND_FACTORS_SPECIAL(cycle) \ |
| 89 | UINT8 blend1a = (*userdata->ColorInputs.blender1b_a[cycle] >> (3 + userdata->ShiftA)) & 0x1c; \ |
| 90 | UINT8 blend2a = (*userdata->ColorInputs.blender2b_a[cycle] >> (3 + userdata->ShiftB)) & 0x1c; |
| 91 | |
| 92 | #define BLEND_FACTORS_SPECIAL_SUM(cycle) \ |
| 93 | UINT8 blend1a = (*userdata->ColorInputs.blender1b_a[cycle] >> (3 + userdata->ShiftA)) & 0x1c; \ |
| 94 | UINT8 blend2a = (*userdata->ColorInputs.blender2b_a[cycle] >> (3 + userdata->ShiftB)) & 0x1c; \ |
| 95 | UINT32 sum = ((blend1a >> 2) + (blend2a >> 2) + 1) & 0xf; |
| 96 | |
| 97 | #define BLEND_MUL(cycle) \ |
| 98 | *r = (((int)(*userdata->ColorInputs.blender1a_r[cycle]) * (int)(blend1a))) + \ |
| 99 | (((int)(*userdata->ColorInputs.blender2a_r[cycle]) * (int)(blend2a))); \ |
| 100 | *g = (((int)(*userdata->ColorInputs.blender1a_g[cycle]) * (int)(blend1a))) + \ |
| 101 | (((int)(*userdata->ColorInputs.blender2a_g[cycle]) * (int)(blend2a))); \ |
| 102 | *b = (((int)(*userdata->ColorInputs.blender1a_b[cycle]) * (int)(blend1a))) + \ |
| 103 | (((int)(*userdata->ColorInputs.blender2a_b[cycle]) * (int)(blend2a))); |
| 104 | |
| 105 | #define BLEND_ADD_SPECIAL(cycle) \ |
| 106 | *r += (((int)*userdata->ColorInputs.blender2a_r[cycle]) << 2); \ |
| 107 | *g += (((int)*userdata->ColorInputs.blender2a_g[cycle]) << 2); \ |
| 108 | *b += (((int)*userdata->ColorInputs.blender2a_b[cycle]) << 2); |
| 109 | |
| 110 | #define BLEND_ADD(cycle) \ |
| 111 | *r += (int)*userdata->ColorInputs.blender2a_r[cycle]; \ |
| 112 | *g += (int)*userdata->ColorInputs.blender2a_g[cycle]; \ |
| 113 | *b += (int)*userdata->ColorInputs.blender2a_b[cycle]; |
| 114 | |
| 115 | #define BLEND_SHIFT(shift) \ |
| 116 | *r >>= shift; \ |
| 117 | *g >>= shift; \ |
| 118 | *b >>= shift; |
| 119 | |
| 120 | #define BLEND_CLAMP() \ |
| 121 | if (*r > 255) *r = 255; \ |
| 122 | if (*g > 255) *g = 255; \ |
| 123 | if (*b > 255) *b = 255; |
| 124 | |
| 125 | #define BLEND_SCALE() \ |
| 126 | if (sum) \ |
| 127 | { \ |
| 128 | *r /= sum; \ |
| 129 | *g /= sum; \ |
| 130 | *b /= sum; \ |
| 131 | } \ |
| 132 | else \ |
| 133 | { \ |
| 134 | *r = *g = *b = 0xff; \ |
42 | 135 | } |
43 | 136 | |
44 | | *fr = r; |
45 | | *fg = g; |
46 | | *fb = b; |
47 | 137 | |
| 138 | #define ASSIGN_OUT(cycle) \ |
| 139 | r = *userdata->ColorInputs.blender1a_r[cycle]; \ |
| 140 | g = *userdata->ColorInputs.blender1a_g[cycle]; \ |
| 141 | b = *userdata->ColorInputs.blender1a_b[cycle]; |
| 142 | |
| 143 | bool N64BlenderT::Blend1CycleNoBlendNoACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel0, rdp_span_aux *userdata, const rdp_poly_state& object) |
| 144 | { |
| 145 | DitherA(&userdata->PixelColor.i.a, adseed); |
| 146 | DitherA(&userdata->ShadeColor.i.a, adseed); |
| 147 | |
| 148 | TEST_REJECT(); |
| 149 | WRITE_OUT_NB_ND(0); |
| 150 | |
48 | 151 | return true; |
49 | 152 | } |
50 | 153 | |
51 | | bool N64BlenderT::Blend2Cycle(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel0, int special_bsel1, rdp_span_aux *userdata, const rdp_poly_state& object) |
| 154 | bool N64BlenderT::Blend1CycleNoBlendNoACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel0, rdp_span_aux *userdata, const rdp_poly_state& object) |
52 | 155 | { |
53 | | if (!object.OtherModes.alpha_cvg_select) |
54 | | { |
55 | | DitherA(&userdata->PixelColor.i.a, adseed); |
56 | | } |
| 156 | INT32 r, g, b; |
57 | 157 | |
| 158 | DitherA(&userdata->PixelColor.i.a, adseed); |
58 | 159 | DitherA(&userdata->ShadeColor.i.a, adseed); |
59 | 160 | |
60 | | if (!AlphaCompare(userdata->PixelColor.i.a, userdata, object)) |
61 | | { |
62 | | return false; |
63 | | } |
| 161 | TEST_REJECT(); |
| 162 | ASSIGN_OUT(0); |
| 163 | DitherRGB(&r, &g, &b, dith); |
| 164 | WRITE_OUT(); |
64 | 165 | |
65 | | if (object.OtherModes.antialias_en ? (!userdata->CurrentPixCvg) : (!userdata->CurrentCvgBit)) |
66 | | { |
67 | | return false; |
68 | | } |
| 166 | return true; |
| 167 | } |
69 | 168 | |
| 169 | bool N64BlenderT::Blend1CycleNoBlendACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel0, rdp_span_aux *userdata, const rdp_poly_state& object) |
| 170 | { |
| 171 | DitherA(&userdata->ShadeColor.i.a, adseed); |
| 172 | |
| 173 | TEST_REJECT(); |
| 174 | WRITE_OUT_NB_ND(0); |
| 175 | |
| 176 | return true; |
| 177 | } |
| 178 | |
| 179 | bool N64BlenderT::Blend1CycleNoBlendACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel0, rdp_span_aux *userdata, const rdp_poly_state& object) |
| 180 | { |
| 181 | INT32 r, g, b; |
| 182 | |
| 183 | DitherA(&userdata->ShadeColor.i.a, adseed); |
| 184 | |
| 185 | TEST_REJECT(); |
| 186 | ASSIGN_OUT(0); |
| 187 | DitherRGB(&r, &g, &b, dith); |
| 188 | WRITE_OUT(); |
| 189 | |
| 190 | return true; |
| 191 | } |
| 192 | |
| 193 | bool N64BlenderT::Blend1CycleBlendNoACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel0, rdp_span_aux *userdata, const rdp_poly_state& object) |
| 194 | { |
| 195 | INT32 r, g, b; |
| 196 | |
| 197 | DitherA(&userdata->PixelColor.i.a, adseed); |
| 198 | DitherA(&userdata->ShadeColor.i.a, adseed); |
| 199 | |
| 200 | TEST_REJECT(); |
| 201 | BLEND_CYCLE(0); |
| 202 | WRITE_OUT(); |
| 203 | |
| 204 | return true; |
| 205 | } |
| 206 | |
| 207 | bool N64BlenderT::Blend1CycleBlendNoACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel0, rdp_span_aux *userdata, const rdp_poly_state& object) |
| 208 | { |
| 209 | INT32 r, g, b; |
| 210 | |
| 211 | DitherA(&userdata->PixelColor.i.a, adseed); |
| 212 | DitherA(&userdata->ShadeColor.i.a, adseed); |
| 213 | |
| 214 | TEST_REJECT(); |
| 215 | BLEND_CYCLE(0); |
| 216 | DitherRGB(&r, &g, &b, dith); |
| 217 | WRITE_OUT(); |
| 218 | |
| 219 | return true; |
| 220 | } |
| 221 | |
| 222 | bool N64BlenderT::Blend1CycleBlendACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel0, rdp_span_aux *userdata, const rdp_poly_state& object) |
| 223 | { |
| 224 | INT32 r, g, b; |
| 225 | |
| 226 | DitherA(&userdata->ShadeColor.i.a, adseed); |
| 227 | |
| 228 | TEST_REJECT(); |
| 229 | BLEND_CYCLE(0); |
| 230 | WRITE_OUT(); |
| 231 | |
| 232 | return true; |
| 233 | } |
| 234 | |
| 235 | bool N64BlenderT::Blend1CycleBlendACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel0, rdp_span_aux *userdata, const rdp_poly_state& object) |
| 236 | { |
| 237 | INT32 r, g, b; |
| 238 | |
| 239 | DitherA(&userdata->ShadeColor.i.a, adseed); |
| 240 | |
| 241 | TEST_REJECT(); |
| 242 | BLEND_CYCLE(0); |
| 243 | DitherRGB(&r, &g, &b, dith); |
| 244 | WRITE_OUT(); |
| 245 | |
| 246 | return true; |
| 247 | } |
| 248 | |
| 249 | bool N64BlenderT::Blend2CycleNoBlendNoACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel0, int special_bsel1, rdp_span_aux *userdata, const rdp_poly_state& object) |
| 250 | { |
| 251 | INT32 r, g, b; |
| 252 | |
| 253 | DitherA(&userdata->PixelColor.i.a, adseed); |
| 254 | DitherA(&userdata->ShadeColor.i.a, adseed); |
| 255 | |
| 256 | TEST_REJECT(); |
70 | 257 | userdata->InvPixelColor.i.a = 0xff - *userdata->ColorInputs.blender1b_a[0]; |
| 258 | ((this)->*(cycle0[((object.OtherModes.force_blend & 1) << 1) | (special_bsel0 & 1)]))(&r, &g, &b, userdata, object); |
| 259 | WRITE_BLENDED_COLOR(); |
| 260 | WRITE_OUT_NB_ND(1); |
71 | 261 | |
| 262 | return true; |
| 263 | } |
| 264 | |
| 265 | bool N64BlenderT::Blend2CycleNoBlendNoACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel0, int special_bsel1, rdp_span_aux *userdata, const rdp_poly_state& object) |
| 266 | { |
72 | 267 | INT32 r, g, b; |
73 | | BlendEquationCycle0(&r, &g, &b, special_bsel0, userdata, object); |
74 | 268 | |
75 | | userdata->BlendedPixelColor.i.r = r; |
76 | | userdata->BlendedPixelColor.i.g = g; |
77 | | userdata->BlendedPixelColor.i.b = b; |
78 | | userdata->BlendedPixelColor.i.a = userdata->PixelColor.i.a; |
| 269 | DitherA(&userdata->PixelColor.i.a, adseed); |
| 270 | DitherA(&userdata->ShadeColor.i.a, adseed); |
79 | 271 | |
80 | | bool dontblend = (partialreject && userdata->PixelColor.i.a >= 0xff); |
81 | | if (!userdata->BlendEnable || dontblend) |
82 | | { |
83 | | r = *userdata->ColorInputs.blender1a_r[1]; |
84 | | g = *userdata->ColorInputs.blender1a_g[1]; |
85 | | b = *userdata->ColorInputs.blender1a_b[1]; |
86 | | } |
87 | | else |
88 | | { |
89 | | userdata->InvPixelColor.i.a = 0xff - *userdata->ColorInputs.blender1b_a[1]; |
90 | | BlendEquationCycle1(&r, &g, &b, special_bsel1, userdata, object); |
91 | | } |
| 272 | TEST_REJECT(); |
| 273 | userdata->InvPixelColor.i.a = 0xff - *userdata->ColorInputs.blender1b_a[0]; |
| 274 | ((this)->*(cycle0[((object.OtherModes.force_blend & 1) << 1) | (special_bsel0 & 1)]))(&r, &g, &b, userdata, object); |
| 275 | WRITE_BLENDED_COLOR(); |
| 276 | ASSIGN_OUT(1); |
| 277 | DitherRGB(&r, &g, &b, dith); |
| 278 | WRITE_OUT(); |
92 | 279 | |
93 | | if (object.OtherModes.rgb_dither_sel < 3) |
94 | | { |
95 | | DitherRGB(&r, &g, &b, dith); |
96 | | } |
| 280 | return true; |
| 281 | } |
97 | 282 | |
98 | | *fr = r; |
99 | | *fg = g; |
100 | | *fb = b; |
| 283 | bool N64BlenderT::Blend2CycleNoBlendACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel0, int special_bsel1, rdp_span_aux *userdata, const rdp_poly_state& object) |
| 284 | { |
| 285 | INT32 r, g, b; |
101 | 286 | |
| 287 | DitherA(&userdata->ShadeColor.i.a, adseed); |
| 288 | |
| 289 | TEST_REJECT(); |
| 290 | userdata->InvPixelColor.i.a = 0xff - *userdata->ColorInputs.blender1b_a[0]; |
| 291 | ((this)->*(cycle0[((object.OtherModes.force_blend & 1) << 1) | (special_bsel0 & 1)]))(&r, &g, &b, userdata, object); |
| 292 | WRITE_BLENDED_COLOR(); |
| 293 | WRITE_OUT_NB_ND(1); |
| 294 | |
102 | 295 | return true; |
103 | 296 | } |
104 | 297 | |
105 | | void N64BlenderT::BlendEquationCycle0(int* r, int* g, int* b, int bsel_special, rdp_span_aux *userdata, const rdp_poly_state& object) |
| 298 | bool N64BlenderT::Blend2CycleNoBlendACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel0, int special_bsel1, rdp_span_aux *userdata, const rdp_poly_state& object) |
106 | 299 | { |
107 | | UINT8 blend1a = *userdata->ColorInputs.blender1b_a[0] >> 3; |
108 | | UINT8 blend2a = *userdata->ColorInputs.blender2b_a[0] >> 3; |
| 300 | INT32 r, g, b; |
109 | 301 | |
110 | | if (bsel_special) |
111 | | { |
112 | | blend1a = (blend1a >> userdata->ShiftA) & 0x1C; |
113 | | blend2a = (blend2a >> userdata->ShiftB) & 0x1C; |
114 | | } |
| 302 | DitherA(&userdata->ShadeColor.i.a, adseed); |
115 | 303 | |
116 | | UINT32 sum = ((blend1a >> 2) + (blend2a >> 2) + 1) & 0xf; |
| 304 | TEST_REJECT(); |
| 305 | userdata->InvPixelColor.i.a = 0xff - *userdata->ColorInputs.blender1b_a[0]; |
| 306 | ((this)->*(cycle0[((object.OtherModes.force_blend & 1) << 1) | (special_bsel0 & 1)]))(&r, &g, &b, userdata, object); |
| 307 | WRITE_BLENDED_COLOR(); |
| 308 | ASSIGN_OUT(1); |
| 309 | DitherRGB(&r, &g, &b, dith); |
| 310 | WRITE_OUT(); |
117 | 311 | |
118 | | *r = (((int)(*userdata->ColorInputs.blender1a_r[0]) * (int)(blend1a))) + |
119 | | (((int)(*userdata->ColorInputs.blender2a_r[0]) * (int)(blend2a))); |
| 312 | return true; |
| 313 | } |
120 | 314 | |
121 | | *g = (((int)(*userdata->ColorInputs.blender1a_g[0]) * (int)(blend1a))) + |
122 | | (((int)(*userdata->ColorInputs.blender2a_g[0]) * (int)(blend2a))); |
| 315 | bool N64BlenderT::Blend2CycleBlendNoACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel0, int special_bsel1, rdp_span_aux *userdata, const rdp_poly_state& object) |
| 316 | { |
| 317 | INT32 r, g, b; |
123 | 318 | |
124 | | *b = (((int)(*userdata->ColorInputs.blender1a_b[0]) * (int)(blend1a))) + |
125 | | (((int)(*userdata->ColorInputs.blender2a_b[0]) * (int)(blend2a))); |
| 319 | DitherA(&userdata->PixelColor.i.a, adseed); |
| 320 | DitherA(&userdata->ShadeColor.i.a, adseed); |
126 | 321 | |
127 | | if (bsel_special) |
128 | | { |
129 | | *r += (((int)*userdata->ColorInputs.blender2a_r[0]) << 2); |
130 | | *g += (((int)*userdata->ColorInputs.blender2a_g[0]) << 2); |
131 | | *b += (((int)*userdata->ColorInputs.blender2a_b[0]) << 2); |
132 | | } |
133 | | else |
134 | | { |
135 | | *r += (int)*userdata->ColorInputs.blender2a_r[0]; |
136 | | *g += (int)*userdata->ColorInputs.blender2a_g[0]; |
137 | | *b += (int)*userdata->ColorInputs.blender2a_b[0]; |
138 | | } |
| 322 | TEST_REJECT(); |
| 323 | userdata->InvPixelColor.i.a = 0xff - *userdata->ColorInputs.blender1b_a[0]; |
| 324 | ((this)->*(cycle0[((object.OtherModes.force_blend & 1) << 1) | (special_bsel0 & 1)]))(&r, &g, &b, userdata, object); |
| 325 | WRITE_BLENDED_COLOR(); |
| 326 | BLEND_CYCLE(1); |
| 327 | WRITE_OUT(); |
139 | 328 | |
140 | | *r >>= 2; |
141 | | *g >>= 2; |
142 | | *b >>= 2; |
| 329 | return true; |
| 330 | } |
143 | 331 | |
144 | | if (object.OtherModes.force_blend) |
145 | | { |
146 | | *r >>= 3; |
147 | | *g >>= 3; |
148 | | *b >>= 3; |
149 | | } |
150 | | else |
151 | | { |
152 | | if (sum) |
153 | | { |
154 | | *r /= sum; |
155 | | *g /= sum; |
156 | | *b /= sum; |
157 | | } |
158 | | else |
159 | | { |
160 | | *r = *g = *b = 0xff; |
161 | | } |
162 | | } |
| 332 | bool N64BlenderT::Blend2CycleBlendNoACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel0, int special_bsel1, rdp_span_aux *userdata, const rdp_poly_state& object) |
| 333 | { |
| 334 | INT32 r, g, b; |
163 | 335 | |
164 | | if (*r > 255) *r = 255; |
165 | | if (*g > 255) *g = 255; |
166 | | if (*b > 255) *b = 255; |
| 336 | DitherA(&userdata->PixelColor.i.a, adseed); |
| 337 | DitherA(&userdata->ShadeColor.i.a, adseed); |
| 338 | |
| 339 | TEST_REJECT(); |
| 340 | userdata->InvPixelColor.i.a = 0xff - *userdata->ColorInputs.blender1b_a[0]; |
| 341 | ((this)->*(cycle0[((object.OtherModes.force_blend & 1) << 1) | (special_bsel0 & 1)]))(&r, &g, &b, userdata, object); |
| 342 | WRITE_BLENDED_COLOR(); |
| 343 | BLEND_CYCLE(1); |
| 344 | DitherRGB(&r, &g, &b, dith); |
| 345 | WRITE_OUT(); |
| 346 | |
| 347 | return true; |
167 | 348 | } |
168 | 349 | |
169 | | void N64BlenderT::BlendEquationCycle1(INT32* r, INT32* g, INT32* b, int bsel_special, rdp_span_aux *userdata, const rdp_poly_state& object) |
| 350 | bool N64BlenderT::Blend2CycleBlendACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel0, int special_bsel1, rdp_span_aux *userdata, const rdp_poly_state& object) |
170 | 351 | { |
171 | | UINT8 blend1a = *userdata->ColorInputs.blender1b_a[1] >> 3; |
172 | | UINT8 blend2a = *userdata->ColorInputs.blender2b_a[1] >> 3; |
| 352 | INT32 r, g, b; |
173 | 353 | |
174 | | if (bsel_special) |
175 | | { |
176 | | blend1a = (blend1a >> userdata->ShiftA) & 0x1C; |
177 | | blend2a = (blend2a >> userdata->ShiftB) & 0x1C; |
178 | | } |
| 354 | DitherA(&userdata->ShadeColor.i.a, adseed); |
179 | 355 | |
180 | | UINT32 sum = ((blend1a >> 2) + (blend2a >> 2) + 1) & 0xf; |
| 356 | TEST_REJECT(); |
| 357 | userdata->InvPixelColor.i.a = 0xff - *userdata->ColorInputs.blender1b_a[0]; |
| 358 | ((this)->*(cycle0[((object.OtherModes.force_blend & 1) << 1) | (special_bsel0 & 1)]))(&r, &g, &b, userdata, object); |
| 359 | WRITE_BLENDED_COLOR(); |
| 360 | BLEND_CYCLE(1); |
| 361 | WRITE_OUT(); |
181 | 362 | |
182 | | *r = (((int)(*userdata->ColorInputs.blender1a_r[1]) * (int)(blend1a))) + |
183 | | (((int)(*userdata->ColorInputs.blender2a_r[1]) * (int)(blend2a))); |
| 363 | return true; |
| 364 | } |
184 | 365 | |
185 | | *g = (((int)(*userdata->ColorInputs.blender1a_g[1]) * (int)(blend1a))) + |
186 | | (((int)(*userdata->ColorInputs.blender2a_g[1]) * (int)(blend2a))); |
| 366 | bool N64BlenderT::Blend2CycleBlendACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel0, int special_bsel1, rdp_span_aux *userdata, const rdp_poly_state& object) |
| 367 | { |
| 368 | INT32 r, g, b; |
187 | 369 | |
188 | | *b = (((int)(*userdata->ColorInputs.blender1a_b[1]) * (int)(blend1a))) + |
189 | | (((int)(*userdata->ColorInputs.blender2a_b[1]) * (int)(blend2a))); |
| 370 | DitherA(&userdata->ShadeColor.i.a, adseed); |
190 | 371 | |
191 | | if (bsel_special) |
192 | | { |
193 | | *r += (((int)*userdata->ColorInputs.blender2a_r[1]) << 2); |
194 | | *g += (((int)*userdata->ColorInputs.blender2a_g[1]) << 2); |
195 | | *b += (((int)*userdata->ColorInputs.blender2a_b[1]) << 2); |
196 | | } |
197 | | else |
198 | | { |
199 | | *r += (int)*userdata->ColorInputs.blender2a_r[1]; |
200 | | *g += (int)*userdata->ColorInputs.blender2a_g[1]; |
201 | | *b += (int)*userdata->ColorInputs.blender2a_b[1]; |
202 | | } |
| 372 | TEST_REJECT(); |
| 373 | userdata->InvPixelColor.i.a = 0xff - *userdata->ColorInputs.blender1b_a[0]; |
| 374 | ((this)->*(cycle0[((object.OtherModes.force_blend & 1) << 1) | (special_bsel0 & 1)]))(&r, &g, &b, userdata, object); |
| 375 | WRITE_BLENDED_COLOR(); |
| 376 | BLEND_CYCLE(1); |
| 377 | DitherRGB(&r, &g, &b, dith); |
| 378 | WRITE_OUT(); |
203 | 379 | |
204 | | *r >>= 2; |
205 | | *g >>= 2; |
206 | | *b >>= 2; |
| 380 | return true; |
| 381 | } |
207 | 382 | |
208 | | if (object.OtherModes.force_blend) |
209 | | { |
210 | | *r >>= 3; |
211 | | *g >>= 3; |
212 | | *b >>= 3; |
213 | | } |
214 | | else |
215 | | { |
216 | | if (sum) |
217 | | { |
218 | | *r /= sum; |
219 | | *g /= sum; |
220 | | *b /= sum; |
221 | | } |
222 | | else |
223 | | { |
224 | | *r = *g = *b = 0xff; |
225 | | } |
226 | | } |
| 383 | void N64BlenderT::BlendEquationCycle0NoForceNoSpecial(int* r, int* g, int* b, rdp_span_aux *userdata, const rdp_poly_state& object) |
| 384 | { |
| 385 | BLEND_FACTORS_SUM(0); |
| 386 | BLEND_MUL(0); |
| 387 | BLEND_ADD(0); |
| 388 | BLEND_SHIFT(2); |
| 389 | BLEND_SCALE(); |
| 390 | BLEND_CLAMP(); |
| 391 | } |
227 | 392 | |
228 | | if (*r > 255) *r = 255; |
229 | | if (*g > 255) *g = 255; |
230 | | if (*b > 255) *b = 255; |
| 393 | void N64BlenderT::BlendEquationCycle0NoForceSpecial(int* r, int* g, int* b, rdp_span_aux *userdata, const rdp_poly_state& object) |
| 394 | { |
| 395 | BLEND_FACTORS_SPECIAL_SUM(0); |
| 396 | BLEND_MUL(0); |
| 397 | BLEND_ADD_SPECIAL(0); |
| 398 | BLEND_SHIFT(2); |
| 399 | BLEND_SCALE(); |
| 400 | BLEND_CLAMP(); |
231 | 401 | } |
232 | 402 | |
| 403 | void N64BlenderT::BlendEquationCycle0ForceNoSpecial(int* r, int* g, int* b, rdp_span_aux *userdata, const rdp_poly_state& object) |
| 404 | { |
| 405 | BLEND_FACTORS(0); |
| 406 | BLEND_MUL(0); |
| 407 | BLEND_ADD(0); |
| 408 | BLEND_SHIFT(5); |
| 409 | BLEND_CLAMP(); |
| 410 | } |
| 411 | |
| 412 | void N64BlenderT::BlendEquationCycle0ForceSpecial(int* r, int* g, int* b, rdp_span_aux *userdata, const rdp_poly_state& object) |
| 413 | { |
| 414 | BLEND_FACTORS_SPECIAL(0); |
| 415 | BLEND_MUL(0); |
| 416 | BLEND_ADD_SPECIAL(0); |
| 417 | BLEND_SHIFT(5); |
| 418 | BLEND_CLAMP(); |
| 419 | } |
| 420 | |
| 421 | void N64BlenderT::BlendEquationCycle1NoForceNoSpecial(INT32* r, INT32* g, INT32* b, rdp_span_aux *userdata, const rdp_poly_state& object) |
| 422 | { |
| 423 | BLEND_FACTORS_SUM(1); |
| 424 | BLEND_MUL(1); |
| 425 | BLEND_ADD(1); |
| 426 | BLEND_SHIFT(2); |
| 427 | BLEND_SCALE(); |
| 428 | BLEND_CLAMP(); |
| 429 | } |
| 430 | |
| 431 | void N64BlenderT::BlendEquationCycle1NoForceSpecial(INT32* r, INT32* g, INT32* b, rdp_span_aux *userdata, const rdp_poly_state& object) |
| 432 | { |
| 433 | BLEND_FACTORS_SPECIAL_SUM(1); |
| 434 | BLEND_MUL(1); |
| 435 | BLEND_ADD_SPECIAL(1); |
| 436 | BLEND_SHIFT(2); |
| 437 | BLEND_SCALE(); |
| 438 | BLEND_CLAMP(); |
| 439 | } |
| 440 | |
| 441 | void N64BlenderT::BlendEquationCycle1ForceNoSpecial(INT32* r, INT32* g, INT32* b, rdp_span_aux *userdata, const rdp_poly_state& object) |
| 442 | { |
| 443 | BLEND_FACTORS(1); |
| 444 | BLEND_MUL(1); |
| 445 | BLEND_ADD(1); |
| 446 | BLEND_SHIFT(5); |
| 447 | BLEND_CLAMP(); |
| 448 | } |
| 449 | |
| 450 | void N64BlenderT::BlendEquationCycle1ForceSpecial(INT32* r, INT32* g, INT32* b, rdp_span_aux *userdata, const rdp_poly_state& object) |
| 451 | { |
| 452 | BLEND_FACTORS_SPECIAL(1); |
| 453 | BLEND_MUL(1); |
| 454 | BLEND_ADD_SPECIAL(1); |
| 455 | BLEND_SHIFT(5); |
| 456 | BLEND_CLAMP(); |
| 457 | } |
| 458 | |
233 | 459 | bool N64BlenderT::AlphaCompare(UINT8 alpha, const rdp_span_aux *userdata, const rdp_poly_state& object) |
234 | 460 | { |
235 | 461 | INT32 threshold; |
trunk/src/mame/video/rdpblend.h
r25448 | r25449 | |
13 | 13 | class N64BlenderT |
14 | 14 | { |
15 | 15 | public: |
16 | | N64BlenderT() |
17 | | { |
18 | | } |
| 16 | typedef bool (N64BlenderT::*Blender1)(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel, rdp_span_aux *userdata, const rdp_poly_state& object); |
| 17 | typedef bool (N64BlenderT::*Blender2)(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int bsel0, int bsel1, rdp_span_aux *userdata, const rdp_poly_state& object); |
| 18 | typedef void (N64BlenderT::*BlendEquation)(INT32* r, INT32* g, INT32* b, rdp_span_aux *userdata, const rdp_poly_state& object); |
| 19 | N64BlenderT(); |
19 | 20 | |
20 | | bool Blend2Cycle(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int bsel0, int bsel1, rdp_span_aux *userdata, const rdp_poly_state& object); |
21 | | bool Blend1Cycle(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel, rdp_span_aux *userdata, const rdp_poly_state& object); |
| 21 | Blender1 blend1[8]; |
| 22 | Blender2 blend2[8]; |
22 | 23 | |
23 | 24 | void SetMachine(running_machine& machine) { m_machine = &machine; } |
24 | 25 | void SetProcessor(n64_rdp* rdp) { m_rdp = rdp; } |
r25448 | r25449 | |
29 | 30 | running_machine* m_machine; |
30 | 31 | n64_rdp* m_rdp; |
31 | 32 | |
32 | | void BlendEquationCycle0(INT32* r, INT32* g, INT32* b, int bsel_special, rdp_span_aux *userdata, const rdp_poly_state& object); |
33 | | void BlendEquationCycle1(INT32* r, INT32* g, INT32* b, int bsel_special, rdp_span_aux *userdata, const rdp_poly_state& object); |
| 33 | bool Blend1CycleNoBlendNoACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel, rdp_span_aux *userdata, const rdp_poly_state& object); |
| 34 | bool Blend1CycleNoBlendNoACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel, rdp_span_aux *userdata, const rdp_poly_state& object); |
| 35 | bool Blend1CycleNoBlendACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel, rdp_span_aux *userdata, const rdp_poly_state& object); |
| 36 | bool Blend1CycleNoBlendACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel, rdp_span_aux *userdata, const rdp_poly_state& object); |
| 37 | bool Blend1CycleBlendNoACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel, rdp_span_aux *userdata, const rdp_poly_state& object); |
| 38 | bool Blend1CycleBlendNoACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel, rdp_span_aux *userdata, const rdp_poly_state& object); |
| 39 | bool Blend1CycleBlendACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel, rdp_span_aux *userdata, const rdp_poly_state& object); |
| 40 | bool Blend1CycleBlendACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel, rdp_span_aux *userdata, const rdp_poly_state& object); |
34 | 41 | |
| 42 | bool Blend2CycleNoBlendNoACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int bsel0, int bsel1, rdp_span_aux *userdata, const rdp_poly_state& object); |
| 43 | bool Blend2CycleNoBlendNoACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int bsel0, int bsel1, rdp_span_aux *userdata, const rdp_poly_state& object); |
| 44 | bool Blend2CycleNoBlendACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int bsel0, int bsel1, rdp_span_aux *userdata, const rdp_poly_state& object); |
| 45 | bool Blend2CycleNoBlendACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int bsel0, int bsel1, rdp_span_aux *userdata, const rdp_poly_state& object); |
| 46 | bool Blend2CycleBlendNoACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int bsel0, int bsel1, rdp_span_aux *userdata, const rdp_poly_state& object); |
| 47 | bool Blend2CycleBlendNoACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int bsel0, int bsel1, rdp_span_aux *userdata, const rdp_poly_state& object); |
| 48 | bool Blend2CycleBlendACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int bsel0, int bsel1, rdp_span_aux *userdata, const rdp_poly_state& object); |
| 49 | bool Blend2CycleBlendACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int bsel0, int bsel1, rdp_span_aux *userdata, const rdp_poly_state& object); |
| 50 | |
| 51 | void BlendEquationCycle0NoForceNoSpecial(INT32* r, INT32* g, INT32* b, rdp_span_aux *userdata, const rdp_poly_state& object); |
| 52 | void BlendEquationCycle0NoForceSpecial(INT32* r, INT32* g, INT32* b, rdp_span_aux *userdata, const rdp_poly_state& object); |
| 53 | void BlendEquationCycle0ForceNoSpecial(INT32* r, INT32* g, INT32* b, rdp_span_aux *userdata, const rdp_poly_state& object); |
| 54 | void BlendEquationCycle0ForceSpecial(INT32* r, INT32* g, INT32* b, rdp_span_aux *userdata, const rdp_poly_state& object); |
| 55 | |
| 56 | void BlendEquationCycle1NoForceNoSpecial(INT32* r, INT32* g, INT32* b, rdp_span_aux *userdata, const rdp_poly_state& object); |
| 57 | void BlendEquationCycle1NoForceSpecial(INT32* r, INT32* g, INT32* b, rdp_span_aux *userdata, const rdp_poly_state& object); |
| 58 | void BlendEquationCycle1ForceNoSpecial(INT32* r, INT32* g, INT32* b, rdp_span_aux *userdata, const rdp_poly_state& object); |
| 59 | void BlendEquationCycle1ForceSpecial(INT32* r, INT32* g, INT32* b, rdp_span_aux *userdata, const rdp_poly_state& object); |
| 60 | |
| 61 | BlendEquation cycle0[4]; |
| 62 | BlendEquation cycle1[4]; |
| 63 | |
35 | 64 | bool AlphaCompare(UINT8 alpha, const rdp_span_aux *userdata, const rdp_poly_state& object); |
36 | 65 | |
37 | 66 | void DitherRGB(INT32* r, INT32* g, INT32* b, int dith); |
trunk/src/mame/video/rdpspn16.c
r25448 | r25449 | |
50 | 50 | case CYCLE_TYPE_1: |
51 | 51 | render_triangle_custom(visarea, render_delegate(FUNC(n64_rdp::SpanDraw1Cycle), this), start, (end - start) + 1, Spans + offset); |
52 | 52 | break; |
| 53 | |
53 | 54 | case CYCLE_TYPE_2: |
54 | 55 | render_triangle_custom(visarea, render_delegate(FUNC(n64_rdp::SpanDraw2Cycle), this), start, (end - start) + 1, Spans + offset); |
55 | 56 | break; |
r25448 | r25449 | |
148 | 149 | bool partialreject = (userdata->ColorInputs.blender2b_a[0] == &userdata->InvPixelColor.i.a && userdata->ColorInputs.blender1b_a[0] == &userdata->PixelColor.i.a); |
149 | 150 | bool bsel0 = (userdata->ColorInputs.blender2b_a[0] == &userdata->MemoryColor.i.a); |
150 | 151 | |
151 | | int drinc = flip ? (object.SpanBase.m_span_dr) : -object.SpanBase.m_span_dr; |
152 | | int dginc = flip ? (object.SpanBase.m_span_dg) : -object.SpanBase.m_span_dg; |
153 | | int dbinc = flip ? (object.SpanBase.m_span_db) : -object.SpanBase.m_span_db; |
154 | | int dainc = flip ? (object.SpanBase.m_span_da) : -object.SpanBase.m_span_da; |
155 | | int dzinc = flip ? (object.SpanBase.m_span_dz) : -object.SpanBase.m_span_dz; |
156 | | int dsinc = flip ? (object.SpanBase.m_span_ds) : -object.SpanBase.m_span_ds; |
157 | | int dtinc = flip ? (object.SpanBase.m_span_dt) : -object.SpanBase.m_span_dt; |
158 | | int dwinc = flip ? (object.SpanBase.m_span_dw) : -object.SpanBase.m_span_dw; |
| 152 | int drinc = object.SpanBase.m_span_dr; |
| 153 | int dginc = object.SpanBase.m_span_dg; |
| 154 | int dbinc = object.SpanBase.m_span_db; |
| 155 | int dainc = object.SpanBase.m_span_da; |
| 156 | int dzinc = object.SpanBase.m_span_dz; |
| 157 | int dsinc = object.SpanBase.m_span_ds; |
| 158 | int dtinc = object.SpanBase.m_span_dt; |
| 159 | int dwinc = object.SpanBase.m_span_dw; |
| 160 | int xinc = 1; |
| 161 | if (!flip) |
| 162 | { |
| 163 | drinc = -drinc; |
| 164 | dginc = -dginc; |
| 165 | dbinc = -dbinc; |
| 166 | dainc = -dainc; |
| 167 | dzinc = -dzinc; |
| 168 | dsinc = -dsinc; |
| 169 | dtinc = -dtinc; |
| 170 | dwinc = -dwinc; |
| 171 | xinc = -xinc; |
| 172 | } |
159 | 173 | int dzpix = object.SpanBase.m_span_dzpix; |
160 | | int xinc = flip ? 1 : -1; |
161 | 174 | |
162 | 175 | int fb_index = object.MiscState.FBWidth * scanline; |
163 | 176 | |
r25448 | r25449 | |
180 | 193 | dzinc = 0; |
181 | 194 | } |
182 | 195 | |
| 196 | int blend_index = (object.OtherModes.alpha_cvg_select ? 2 : 0) | ((object.OtherModes.rgb_dither_sel < 3) ? 1 : 0); |
| 197 | int read_index = ((object.MiscState.FBSize - 2) << 1) | object.OtherModes.image_read_en; |
| 198 | int write_index = ((object.MiscState.FBSize - 2) << 3) | (object.OtherModes.cvg_dest << 1); |
183 | 199 | userdata->m_start_span = true; |
184 | 200 | for (int j = 0; j <= length; j++) |
185 | 201 | { |
r25448 | r25449 | |
233 | 249 | UINT32 zbcur = zb + curpixel; |
234 | 250 | UINT32 zhbcur = zhb + curpixel; |
235 | 251 | |
236 | | ((this)->*(_Read[((object.MiscState.FBSize - 2) << 1) | object.OtherModes.image_read_en]))(curpixel, userdata, object); |
| 252 | ((this)->*(_Read[read_index]))(curpixel, userdata, object); |
237 | 253 | |
238 | 254 | if(m_rdp->ZCompare(zbcur, zhbcur, sz, dzpix, userdata, object)) |
239 | 255 | { |
240 | 256 | m_rdp->GetDitherValues(scanline, j, &cdith, &adith, object); |
241 | 257 | |
242 | | bool rendered = m_rdp->Blender.Blend1Cycle(&fir, &fig, &fib, cdith, adith, partialreject, bsel0, userdata, object); |
| 258 | bool rendered = ((&m_rdp->Blender)->*(m_rdp->Blender.blend1[(userdata->BlendEnable << 2) | blend_index]))(&fir, &fig, &fib, cdith, adith, partialreject, bsel0, userdata, object); |
243 | 259 | |
244 | 260 | if (rendered) |
245 | 261 | { |
246 | | ((this)->*(_Write[((object.MiscState.FBSize - 2) << 3) | (object.OtherModes.cvg_dest << 1) | userdata->BlendEnable]))(curpixel, fir, fig, fib, userdata, object); |
| 262 | ((this)->*(_Write[write_index | userdata->BlendEnable]))(curpixel, fir, fig, fib, userdata, object); |
247 | 263 | |
248 | 264 | if (object.OtherModes.z_update_en) |
249 | 265 | { |
r25448 | r25449 | |
337 | 353 | dzinc = 0; |
338 | 354 | } |
339 | 355 | |
| 356 | int blend_index = (object.OtherModes.alpha_cvg_select ? 2 : 0) | ((object.OtherModes.rgb_dither_sel < 3) ? 1 : 0); |
| 357 | int read_index = ((object.MiscState.FBSize - 2) << 1) | object.OtherModes.image_read_en; |
| 358 | int write_index = ((object.MiscState.FBSize - 2) << 3) | (object.OtherModes.cvg_dest << 1); |
340 | 359 | userdata->m_start_span = true; |
341 | 360 | for (int j = 0; j <= length; j++) |
342 | 361 | { |
r25448 | r25449 | |
399 | 418 | UINT32 zbcur = zb + curpixel; |
400 | 419 | UINT32 zhbcur = zhb + curpixel; |
401 | 420 | |
402 | | ((this)->*(_Read[((object.MiscState.FBSize - 2) << 1) | object.OtherModes.image_read_en]))(curpixel, userdata, object); |
| 421 | ((this)->*(_Read[read_index]))(curpixel, userdata, object); |
403 | 422 | |
404 | 423 | if(m_rdp->ZCompare(zbcur, zhbcur, sz, dzpix, userdata, object)) |
405 | 424 | { |
406 | 425 | m_rdp->GetDitherValues(scanline, j, &cdith, &adith, object); |
407 | 426 | |
408 | | bool rendered = m_rdp->Blender.Blend2Cycle(&fir, &fig, &fib, cdith, adith, partialreject, bsel0, bsel1, userdata, object); |
| 427 | bool rendered = ((&m_rdp->Blender)->*(m_rdp->Blender.blend2[(userdata->BlendEnable << 2) | blend_index]))(&fir, &fig, &fib, cdith, adith, partialreject, bsel0, bsel1, userdata, object); |
409 | 428 | |
410 | 429 | if (rendered) |
411 | 430 | { |
412 | | ((this)->*(_Write[((object.MiscState.FBSize - 2) << 3) | (object.OtherModes.cvg_dest << 1) | userdata->BlendEnable]))(curpixel, fir, fig, fib, userdata, object); |
| 431 | ((this)->*(_Write[write_index | userdata->BlendEnable]))(curpixel, fir, fig, fib, userdata, object); |
413 | 432 | if (object.OtherModes.z_update_en) |
414 | 433 | { |
415 | 434 | m_rdp->ZStore(zbcur, zhbcur, sz, userdata->m_dzpix_enc); |