1// Warning: This file was created by make_scanline_drawers.py - do not edit. 2 3#if __GNUC__ 4#define _AL_EXPECT_FAIL(expr) __builtin_expect((expr), 0) 5#else 6#define _AL_EXPECT_FAIL(expr) (expr) 7#endif 8 9static void shader_solid_any_draw_shade(uintptr_t state, int x1, int y, int x2) 10{ 11 state_solid_any_2d *s = (state_solid_any_2d *) state; 12 ALLEGRO_COLOR cur_color = s->cur_color; 13 14 ALLEGRO_BITMAP *target = s->target; 15 16 if (target->parent) { 17 x1 += target->xofs; 18 x2 += target->xofs; 19 y += target->yofs; 20 target = target->parent; 21 } 22 23 x1 -= target->lock_x; 24 x2 -= target->lock_x; 25 y -= target->lock_y; 26 y--; 27 28 if (y < 0 || y >= target->lock_h) { 29 return; 30 } 31 32 if (x1 < 0) { 33 34 x1 = 0; 35 } 36 37 if (x2 > target->lock_w - 1) { 38 x2 = target->lock_w - 1; 39 } 40 41 { 42 int op, src_mode, dst_mode; 43 int op_alpha, src_alpha, dst_alpha; 44 ALLEGRO_COLOR const_color; 45 al_get_separate_bitmap_blender(&op, &src_mode, &dst_mode, &op_alpha, &src_alpha, &dst_alpha); 46 const_color = al_get_blend_color(); 47 48 { 49 { 50 const int dst_format = target->locked_region.format; 51 uint8_t *dst_data = (uint8_t *) target->lock_data + y * target->locked_region.pitch + x1 * target->locked_region.pixel_size; 52 53 if (op == ALLEGRO_ADD && src_mode == ALLEGRO_ONE && src_alpha == ALLEGRO_ONE && op_alpha == ALLEGRO_ADD && dst_mode == ALLEGRO_INVERSE_ALPHA && dst_alpha == ALLEGRO_INVERSE_ALPHA) { 54 55 { 56 { 57 for (; x1 <= x2; x1++) { 58 ALLEGRO_COLOR src_color = cur_color; 59 60 { 61 ALLEGRO_COLOR dst_color; 62 ALLEGRO_COLOR result; 63 _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); 64 _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, NULL, &result); 65 _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); 66 } 67 68 } 69 } 70 } 71 } else if (op == ALLEGRO_ADD && src_mode == ALLEGRO_ALPHA && src_alpha == ALLEGRO_ALPHA && op_alpha == ALLEGRO_ADD && dst_mode == ALLEGRO_INVERSE_ALPHA && dst_alpha == ALLEGRO_INVERSE_ALPHA) { 72 73 { 74 { 75 for (; x1 <= x2; x1++) { 76 ALLEGRO_COLOR src_color = cur_color; 77 78 { 79 ALLEGRO_COLOR dst_color; 80 ALLEGRO_COLOR result; 81 _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); 82 _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, NULL, &result); 83 _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); 84 } 85 86 } 87 } 88 } 89 } else if (op == ALLEGRO_ADD && src_mode == ALLEGRO_ONE && src_alpha == ALLEGRO_ONE && op_alpha == ALLEGRO_ADD && dst_mode == ALLEGRO_ONE && dst_alpha == ALLEGRO_ONE) { 90 91 { 92 { 93 for (; x1 <= x2; x1++) { 94 ALLEGRO_COLOR src_color = cur_color; 95 96 { 97 ALLEGRO_COLOR dst_color; 98 ALLEGRO_COLOR result; 99 _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); 100 _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, NULL, &result); 101 _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); 102 } 103 104 } 105 } 106 } 107 } else if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { 108 { 109 for (; x1 <= x2; x1++) { 110 ALLEGRO_COLOR src_color = cur_color; 111 112 { 113 ALLEGRO_COLOR dst_color; 114 ALLEGRO_COLOR result; 115 _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, dst_color, false); 116 _al_blend_inline(&src_color, &dst_color, op, src_mode, dst_mode, op_alpha, src_alpha, dst_alpha, &const_color, &result); 117 _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, result, true); 118 } 119 120 } 121 } 122 } else { 123 { 124 for (; x1 <= x2; x1++) { 125 ALLEGRO_COLOR src_color = cur_color; 126 127 { 128 ALLEGRO_COLOR dst_color; 129 ALLEGRO_COLOR result; 130 _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); 131 _al_blend_inline(&src_color, &dst_color, op, src_mode, dst_mode, op_alpha, src_alpha, dst_alpha, &const_color, &result); 132 _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); 133 } 134 135 } 136 } 137 } 138 } 139 } 140 } 141} 142 143static void shader_solid_any_draw_opaque(uintptr_t state, int x1, int y, int x2) 144{ 145 state_solid_any_2d *s = (state_solid_any_2d *) state; 146 ALLEGRO_COLOR cur_color = s->cur_color; 147 148 ALLEGRO_BITMAP *target = s->target; 149 150 if (target->parent) { 151 x1 += target->xofs; 152 x2 += target->xofs; 153 y += target->yofs; 154 target = target->parent; 155 } 156 157 x1 -= target->lock_x; 158 x2 -= target->lock_x; 159 y -= target->lock_y; 160 y--; 161 162 if (y < 0 || y >= target->lock_h) { 163 return; 164 } 165 166 if (x1 < 0) { 167 168 x1 = 0; 169 } 170 171 if (x2 > target->lock_w - 1) { 172 x2 = target->lock_w - 1; 173 } 174 175 { 176 { 177 { 178 const int dst_format = target->locked_region.format; 179 uint8_t *dst_data = (uint8_t *) target->lock_data + y * target->locked_region.pitch + x1 * target->locked_region.pixel_size; 180 181 if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { 182 { 183 for (; x1 <= x2; x1++) { 184 ALLEGRO_COLOR src_color = cur_color; 185 186 _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, src_color, true); 187 188 } 189 } 190 } else { 191 { 192 for (; x1 <= x2; x1++) { 193 ALLEGRO_COLOR src_color = cur_color; 194 195 _AL_INLINE_PUT_PIXEL(dst_format, dst_data, src_color, true); 196 197 } 198 } 199 } 200 } 201 } 202 } 203} 204 205static void shader_grad_any_draw_shade(uintptr_t state, int x1, int y, int x2) 206{ 207 state_grad_any_2d *gs = (state_grad_any_2d *) state; 208 state_solid_any_2d *s = &gs->solid; 209 ALLEGRO_COLOR cur_color = s->cur_color; 210 211 ALLEGRO_BITMAP *target = s->target; 212 213 if (target->parent) { 214 x1 += target->xofs; 215 x2 += target->xofs; 216 y += target->yofs; 217 target = target->parent; 218 } 219 220 x1 -= target->lock_x; 221 x2 -= target->lock_x; 222 y -= target->lock_y; 223 y--; 224 225 if (y < 0 || y >= target->lock_h) { 226 return; 227 } 228 229 if (x1 < 0) { 230 231 cur_color.r += gs->color_dx.r * -x1; 232 cur_color.g += gs->color_dx.g * -x1; 233 cur_color.b += gs->color_dx.b * -x1; 234 cur_color.a += gs->color_dx.a * -x1; 235 236 x1 = 0; 237 } 238 239 if (x2 > target->lock_w - 1) { 240 x2 = target->lock_w - 1; 241 } 242 243 { 244 int op, src_mode, dst_mode; 245 int op_alpha, src_alpha, dst_alpha; 246 ALLEGRO_COLOR const_color; 247 al_get_separate_bitmap_blender(&op, &src_mode, &dst_mode, &op_alpha, &src_alpha, &dst_alpha); 248 const_color = al_get_blend_color(); 249 250 { 251 { 252 const int dst_format = target->locked_region.format; 253 uint8_t *dst_data = (uint8_t *) target->lock_data + y * target->locked_region.pitch + x1 * target->locked_region.pixel_size; 254 255 if (op == ALLEGRO_ADD && src_mode == ALLEGRO_ONE && src_alpha == ALLEGRO_ONE && op_alpha == ALLEGRO_ADD && dst_mode == ALLEGRO_INVERSE_ALPHA && dst_alpha == ALLEGRO_INVERSE_ALPHA) { 256 257 { 258 { 259 for (; x1 <= x2; x1++) { 260 ALLEGRO_COLOR src_color = cur_color; 261 262 { 263 ALLEGRO_COLOR dst_color; 264 ALLEGRO_COLOR result; 265 _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); 266 _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, NULL, &result); 267 _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); 268 } 269 270 cur_color.r += gs->color_dx.r; 271 cur_color.g += gs->color_dx.g; 272 cur_color.b += gs->color_dx.b; 273 cur_color.a += gs->color_dx.a; 274 275 } 276 } 277 } 278 } else if (op == ALLEGRO_ADD && src_mode == ALLEGRO_ALPHA && src_alpha == ALLEGRO_ALPHA && op_alpha == ALLEGRO_ADD && dst_mode == ALLEGRO_INVERSE_ALPHA && dst_alpha == ALLEGRO_INVERSE_ALPHA) { 279 280 { 281 { 282 for (; x1 <= x2; x1++) { 283 ALLEGRO_COLOR src_color = cur_color; 284 285 { 286 ALLEGRO_COLOR dst_color; 287 ALLEGRO_COLOR result; 288 _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); 289 _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, NULL, &result); 290 _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); 291 } 292 293 cur_color.r += gs->color_dx.r; 294 cur_color.g += gs->color_dx.g; 295 cur_color.b += gs->color_dx.b; 296 cur_color.a += gs->color_dx.a; 297 298 } 299 } 300 } 301 } else if (op == ALLEGRO_ADD && src_mode == ALLEGRO_ONE && src_alpha == ALLEGRO_ONE && op_alpha == ALLEGRO_ADD && dst_mode == ALLEGRO_ONE && dst_alpha == ALLEGRO_ONE) { 302 303 { 304 { 305 for (; x1 <= x2; x1++) { 306 ALLEGRO_COLOR src_color = cur_color; 307 308 { 309 ALLEGRO_COLOR dst_color; 310 ALLEGRO_COLOR result; 311 _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); 312 _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, NULL, &result); 313 _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); 314 } 315 316 cur_color.r += gs->color_dx.r; 317 cur_color.g += gs->color_dx.g; 318 cur_color.b += gs->color_dx.b; 319 cur_color.a += gs->color_dx.a; 320 321 } 322 } 323 } 324 } else if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { 325 { 326 for (; x1 <= x2; x1++) { 327 ALLEGRO_COLOR src_color = cur_color; 328 329 { 330 ALLEGRO_COLOR dst_color; 331 ALLEGRO_COLOR result; 332 _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, dst_color, false); 333 _al_blend_inline(&src_color, &dst_color, op, src_mode, dst_mode, op_alpha, src_alpha, dst_alpha, &const_color, &result); 334 _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, result, true); 335 } 336 337 cur_color.r += gs->color_dx.r; 338 cur_color.g += gs->color_dx.g; 339 cur_color.b += gs->color_dx.b; 340 cur_color.a += gs->color_dx.a; 341 342 } 343 } 344 } else { 345 { 346 for (; x1 <= x2; x1++) { 347 ALLEGRO_COLOR src_color = cur_color; 348 349 { 350 ALLEGRO_COLOR dst_color; 351 ALLEGRO_COLOR result; 352 _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); 353 _al_blend_inline(&src_color, &dst_color, op, src_mode, dst_mode, op_alpha, src_alpha, dst_alpha, &const_color, &result); 354 _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); 355 } 356 357 cur_color.r += gs->color_dx.r; 358 cur_color.g += gs->color_dx.g; 359 cur_color.b += gs->color_dx.b; 360 cur_color.a += gs->color_dx.a; 361 362 } 363 } 364 } 365 } 366 } 367 } 368} 369 370static void shader_grad_any_draw_opaque(uintptr_t state, int x1, int y, int x2) 371{ 372 state_grad_any_2d *gs = (state_grad_any_2d *) state; 373 state_solid_any_2d *s = &gs->solid; 374 ALLEGRO_COLOR cur_color = s->cur_color; 375 376 ALLEGRO_BITMAP *target = s->target; 377 378 if (target->parent) { 379 x1 += target->xofs; 380 x2 += target->xofs; 381 y += target->yofs; 382 target = target->parent; 383 } 384 385 x1 -= target->lock_x; 386 x2 -= target->lock_x; 387 y -= target->lock_y; 388 y--; 389 390 if (y < 0 || y >= target->lock_h) { 391 return; 392 } 393 394 if (x1 < 0) { 395 396 cur_color.r += gs->color_dx.r * -x1; 397 cur_color.g += gs->color_dx.g * -x1; 398 cur_color.b += gs->color_dx.b * -x1; 399 cur_color.a += gs->color_dx.a * -x1; 400 401 x1 = 0; 402 } 403 404 if (x2 > target->lock_w - 1) { 405 x2 = target->lock_w - 1; 406 } 407 408 { 409 { 410 { 411 const int dst_format = target->locked_region.format; 412 uint8_t *dst_data = (uint8_t *) target->lock_data + y * target->locked_region.pitch + x1 * target->locked_region.pixel_size; 413 414 if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { 415 { 416 for (; x1 <= x2; x1++) { 417 ALLEGRO_COLOR src_color = cur_color; 418 419 _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, src_color, true); 420 421 cur_color.r += gs->color_dx.r; 422 cur_color.g += gs->color_dx.g; 423 cur_color.b += gs->color_dx.b; 424 cur_color.a += gs->color_dx.a; 425 426 } 427 } 428 } else { 429 { 430 for (; x1 <= x2; x1++) { 431 ALLEGRO_COLOR src_color = cur_color; 432 433 _AL_INLINE_PUT_PIXEL(dst_format, dst_data, src_color, true); 434 435 cur_color.r += gs->color_dx.r; 436 cur_color.g += gs->color_dx.g; 437 cur_color.b += gs->color_dx.b; 438 cur_color.a += gs->color_dx.a; 439 440 } 441 } 442 } 443 } 444 } 445 } 446} 447 448static void shader_texture_solid_any_draw_shade(uintptr_t state, int x1, int y, int x2) 449{ 450 state_texture_solid_any_2d *s = (state_texture_solid_any_2d *) state; 451 452 float u = s->u; 453 float v = s->v; 454 455 ALLEGRO_BITMAP *target = s->target; 456 457 if (target->parent) { 458 x1 += target->xofs; 459 x2 += target->xofs; 460 y += target->yofs; 461 target = target->parent; 462 } 463 464 x1 -= target->lock_x; 465 x2 -= target->lock_x; 466 y -= target->lock_y; 467 y--; 468 469 if (y < 0 || y >= target->lock_h) { 470 return; 471 } 472 473 if (x1 < 0) { 474 475 u += s->du_dx * -x1; 476 v += s->dv_dx * -x1; 477 478 x1 = 0; 479 } 480 481 if (x2 > target->lock_w - 1) { 482 x2 = target->lock_w - 1; 483 } 484 485 { 486 int op, src_mode, dst_mode; 487 int op_alpha, src_alpha, dst_alpha; 488 ALLEGRO_COLOR const_color; 489 al_get_separate_bitmap_blender(&op, &src_mode, &dst_mode, &op_alpha, &src_alpha, &dst_alpha); 490 const_color = al_get_blend_color(); 491 492 { 493 const int offset_x = s->texture->parent ? s->texture->xofs : 0; 494 const int offset_y = s->texture->parent ? s->texture->yofs : 0; 495 ALLEGRO_BITMAP *texture = s->texture->parent ? s->texture->parent : s->texture; 496 const int src_format = texture->locked_region.format; 497 const int src_size = texture->locked_region.pixel_size; 498 499 /* Ensure u in [0, s->w) and v in [0, s->h). */ 500 while (u < 0) 501 u += s->w; 502 while (v < 0) 503 v += s->h; 504 u = fmodf(u, s->w); 505 v = fmodf(v, s->h); 506 ASSERT(0 <= u); 507 ASSERT(u < s->w); 508 ASSERT(0 <= v); 509 ASSERT(v < s->h); 510 511 { 512 const int dst_format = target->locked_region.format; 513 uint8_t *dst_data = (uint8_t *) target->lock_data + y * target->locked_region.pitch + x1 * target->locked_region.pixel_size; 514 515 if (op == ALLEGRO_ADD && src_mode == ALLEGRO_ONE && src_alpha == ALLEGRO_ONE && op_alpha == ALLEGRO_ADD && dst_mode == ALLEGRO_INVERSE_ALPHA && dst_alpha == ALLEGRO_INVERSE_ALPHA) { 516 517 if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888 && src_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { 518 uint8_t *lock_data = texture->locked_region.data; 519 const int src_pitch = texture->locked_region.pitch; 520 const al_fixed du_dx = al_ftofix(s->du_dx); 521 const al_fixed dv_dx = al_ftofix(s->dv_dx); 522 523 { 524 al_fixed uu = al_ftofix(u); 525 al_fixed vv = al_ftofix(v); 526 const int uu_ofs = offset_x - texture->lock_x; 527 const int vv_ofs = offset_y - texture->lock_y; 528 const al_fixed w = al_ftofix(s->w); 529 const al_fixed h = al_ftofix(s->h); 530 531 for (; x1 <= x2; x1++) { 532 const int src_x = (uu >> 16) + uu_ofs; 533 const int src_y = (vv >> 16) + vv_ofs; 534 uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; 535 536 ALLEGRO_COLOR src_color; 537 _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, src_data, src_color, false); 538 539 SHADE_COLORS(src_color, s->cur_color); 540 541 { 542 ALLEGRO_COLOR dst_color; 543 ALLEGRO_COLOR result; 544 _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, dst_color, false); 545 _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, NULL, &result); 546 _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, result, true); 547 } 548 549 uu += du_dx; 550 vv += dv_dx; 551 552 if (_AL_EXPECT_FAIL(uu < 0)) 553 uu += w; 554 else if (_AL_EXPECT_FAIL(uu >= w)) 555 uu -= w; 556 557 if (_AL_EXPECT_FAIL(vv < 0)) 558 vv += h; 559 else if (_AL_EXPECT_FAIL(vv >= h)) 560 vv -= h; 561 562 } 563 } 564 } else { 565 uint8_t *lock_data = texture->locked_region.data; 566 const int src_pitch = texture->locked_region.pitch; 567 const al_fixed du_dx = al_ftofix(s->du_dx); 568 const al_fixed dv_dx = al_ftofix(s->dv_dx); 569 570 { 571 al_fixed uu = al_ftofix(u); 572 al_fixed vv = al_ftofix(v); 573 const int uu_ofs = offset_x - texture->lock_x; 574 const int vv_ofs = offset_y - texture->lock_y; 575 const al_fixed w = al_ftofix(s->w); 576 const al_fixed h = al_ftofix(s->h); 577 578 for (; x1 <= x2; x1++) { 579 const int src_x = (uu >> 16) + uu_ofs; 580 const int src_y = (vv >> 16) + vv_ofs; 581 uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; 582 583 ALLEGRO_COLOR src_color; 584 _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); 585 586 SHADE_COLORS(src_color, s->cur_color); 587 588 { 589 ALLEGRO_COLOR dst_color; 590 ALLEGRO_COLOR result; 591 _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); 592 _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, NULL, &result); 593 _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); 594 } 595 596 uu += du_dx; 597 vv += dv_dx; 598 599 if (_AL_EXPECT_FAIL(uu < 0)) 600 uu += w; 601 else if (_AL_EXPECT_FAIL(uu >= w)) 602 uu -= w; 603 604 if (_AL_EXPECT_FAIL(vv < 0)) 605 vv += h; 606 else if (_AL_EXPECT_FAIL(vv >= h)) 607 vv -= h; 608 609 } 610 } 611 } 612 } else if (op == ALLEGRO_ADD && src_mode == ALLEGRO_ALPHA && src_alpha == ALLEGRO_ALPHA && op_alpha == ALLEGRO_ADD && dst_mode == ALLEGRO_INVERSE_ALPHA && dst_alpha == ALLEGRO_INVERSE_ALPHA) { 613 614 if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888 && src_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { 615 uint8_t *lock_data = texture->locked_region.data; 616 const int src_pitch = texture->locked_region.pitch; 617 const al_fixed du_dx = al_ftofix(s->du_dx); 618 const al_fixed dv_dx = al_ftofix(s->dv_dx); 619 620 { 621 al_fixed uu = al_ftofix(u); 622 al_fixed vv = al_ftofix(v); 623 const int uu_ofs = offset_x - texture->lock_x; 624 const int vv_ofs = offset_y - texture->lock_y; 625 const al_fixed w = al_ftofix(s->w); 626 const al_fixed h = al_ftofix(s->h); 627 628 for (; x1 <= x2; x1++) { 629 const int src_x = (uu >> 16) + uu_ofs; 630 const int src_y = (vv >> 16) + vv_ofs; 631 uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; 632 633 ALLEGRO_COLOR src_color; 634 _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, src_data, src_color, false); 635 636 SHADE_COLORS(src_color, s->cur_color); 637 638 { 639 ALLEGRO_COLOR dst_color; 640 ALLEGRO_COLOR result; 641 _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, dst_color, false); 642 _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, NULL, &result); 643 _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, result, true); 644 } 645 646 uu += du_dx; 647 vv += dv_dx; 648 649 if (_AL_EXPECT_FAIL(uu < 0)) 650 uu += w; 651 else if (_AL_EXPECT_FAIL(uu >= w)) 652 uu -= w; 653 654 if (_AL_EXPECT_FAIL(vv < 0)) 655 vv += h; 656 else if (_AL_EXPECT_FAIL(vv >= h)) 657 vv -= h; 658 659 } 660 } 661 } else { 662 uint8_t *lock_data = texture->locked_region.data; 663 const int src_pitch = texture->locked_region.pitch; 664 const al_fixed du_dx = al_ftofix(s->du_dx); 665 const al_fixed dv_dx = al_ftofix(s->dv_dx); 666 667 { 668 al_fixed uu = al_ftofix(u); 669 al_fixed vv = al_ftofix(v); 670 const int uu_ofs = offset_x - texture->lock_x; 671 const int vv_ofs = offset_y - texture->lock_y; 672 const al_fixed w = al_ftofix(s->w); 673 const al_fixed h = al_ftofix(s->h); 674 675 for (; x1 <= x2; x1++) { 676 const int src_x = (uu >> 16) + uu_ofs; 677 const int src_y = (vv >> 16) + vv_ofs; 678 uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; 679 680 ALLEGRO_COLOR src_color; 681 _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); 682 683 SHADE_COLORS(src_color, s->cur_color); 684 685 { 686 ALLEGRO_COLOR dst_color; 687 ALLEGRO_COLOR result; 688 _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); 689 _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, NULL, &result); 690 _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); 691 } 692 693 uu += du_dx; 694 vv += dv_dx; 695 696 if (_AL_EXPECT_FAIL(uu < 0)) 697 uu += w; 698 else if (_AL_EXPECT_FAIL(uu >= w)) 699 uu -= w; 700 701 if (_AL_EXPECT_FAIL(vv < 0)) 702 vv += h; 703 else if (_AL_EXPECT_FAIL(vv >= h)) 704 vv -= h; 705 706 } 707 } 708 } 709 } else if (op == ALLEGRO_ADD && src_mode == ALLEGRO_ONE && src_alpha == ALLEGRO_ONE && op_alpha == ALLEGRO_ADD && dst_mode == ALLEGRO_ONE && dst_alpha == ALLEGRO_ONE) { 710 711 if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888 && src_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { 712 uint8_t *lock_data = texture->locked_region.data; 713 const int src_pitch = texture->locked_region.pitch; 714 const al_fixed du_dx = al_ftofix(s->du_dx); 715 const al_fixed dv_dx = al_ftofix(s->dv_dx); 716 717 { 718 al_fixed uu = al_ftofix(u); 719 al_fixed vv = al_ftofix(v); 720 const int uu_ofs = offset_x - texture->lock_x; 721 const int vv_ofs = offset_y - texture->lock_y; 722 const al_fixed w = al_ftofix(s->w); 723 const al_fixed h = al_ftofix(s->h); 724 725 for (; x1 <= x2; x1++) { 726 const int src_x = (uu >> 16) + uu_ofs; 727 const int src_y = (vv >> 16) + vv_ofs; 728 uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; 729 730 ALLEGRO_COLOR src_color; 731 _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, src_data, src_color, false); 732 733 SHADE_COLORS(src_color, s->cur_color); 734 735 { 736 ALLEGRO_COLOR dst_color; 737 ALLEGRO_COLOR result; 738 _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, dst_color, false); 739 _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, NULL, &result); 740 _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, result, true); 741 } 742 743 uu += du_dx; 744 vv += dv_dx; 745 746 if (_AL_EXPECT_FAIL(uu < 0)) 747 uu += w; 748 else if (_AL_EXPECT_FAIL(uu >= w)) 749 uu -= w; 750 751 if (_AL_EXPECT_FAIL(vv < 0)) 752 vv += h; 753 else if (_AL_EXPECT_FAIL(vv >= h)) 754 vv -= h; 755 756 } 757 } 758 } else { 759 uint8_t *lock_data = texture->locked_region.data; 760 const int src_pitch = texture->locked_region.pitch; 761 const al_fixed du_dx = al_ftofix(s->du_dx); 762 const al_fixed dv_dx = al_ftofix(s->dv_dx); 763 764 { 765 al_fixed uu = al_ftofix(u); 766 al_fixed vv = al_ftofix(v); 767 const int uu_ofs = offset_x - texture->lock_x; 768 const int vv_ofs = offset_y - texture->lock_y; 769 const al_fixed w = al_ftofix(s->w); 770 const al_fixed h = al_ftofix(s->h); 771 772 for (; x1 <= x2; x1++) { 773 const int src_x = (uu >> 16) + uu_ofs; 774 const int src_y = (vv >> 16) + vv_ofs; 775 uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; 776 777 ALLEGRO_COLOR src_color; 778 _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); 779 780 SHADE_COLORS(src_color, s->cur_color); 781 782 { 783 ALLEGRO_COLOR dst_color; 784 ALLEGRO_COLOR result; 785 _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); 786 _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, NULL, &result); 787 _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); 788 } 789 790 uu += du_dx; 791 vv += dv_dx; 792 793 if (_AL_EXPECT_FAIL(uu < 0)) 794 uu += w; 795 else if (_AL_EXPECT_FAIL(uu >= w)) 796 uu -= w; 797 798 if (_AL_EXPECT_FAIL(vv < 0)) 799 vv += h; 800 else if (_AL_EXPECT_FAIL(vv >= h)) 801 vv -= h; 802 803 } 804 } 805 } 806 } else if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888 && src_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { 807 uint8_t *lock_data = texture->locked_region.data; 808 const int src_pitch = texture->locked_region.pitch; 809 const al_fixed du_dx = al_ftofix(s->du_dx); 810 const al_fixed dv_dx = al_ftofix(s->dv_dx); 811 812 { 813 al_fixed uu = al_ftofix(u); 814 al_fixed vv = al_ftofix(v); 815 const int uu_ofs = offset_x - texture->lock_x; 816 const int vv_ofs = offset_y - texture->lock_y; 817 const al_fixed w = al_ftofix(s->w); 818 const al_fixed h = al_ftofix(s->h); 819 820 for (; x1 <= x2; x1++) { 821 const int src_x = (uu >> 16) + uu_ofs; 822 const int src_y = (vv >> 16) + vv_ofs; 823 uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; 824 825 ALLEGRO_COLOR src_color; 826 _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, src_data, src_color, false); 827 828 SHADE_COLORS(src_color, s->cur_color); 829 830 { 831 ALLEGRO_COLOR dst_color; 832 ALLEGRO_COLOR result; 833 _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, dst_color, false); 834 _al_blend_inline(&src_color, &dst_color, op, src_mode, dst_mode, op_alpha, src_alpha, dst_alpha, &const_color, &result); 835 _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, result, true); 836 } 837 838 uu += du_dx; 839 vv += dv_dx; 840 841 if (_AL_EXPECT_FAIL(uu < 0)) 842 uu += w; 843 else if (_AL_EXPECT_FAIL(uu >= w)) 844 uu -= w; 845 846 if (_AL_EXPECT_FAIL(vv < 0)) 847 vv += h; 848 else if (_AL_EXPECT_FAIL(vv >= h)) 849 vv -= h; 850 851 } 852 } 853 } else { 854 uint8_t *lock_data = texture->locked_region.data; 855 const int src_pitch = texture->locked_region.pitch; 856 const al_fixed du_dx = al_ftofix(s->du_dx); 857 const al_fixed dv_dx = al_ftofix(s->dv_dx); 858 859 { 860 al_fixed uu = al_ftofix(u); 861 al_fixed vv = al_ftofix(v); 862 const int uu_ofs = offset_x - texture->lock_x; 863 const int vv_ofs = offset_y - texture->lock_y; 864 const al_fixed w = al_ftofix(s->w); 865 const al_fixed h = al_ftofix(s->h); 866 867 for (; x1 <= x2; x1++) { 868 const int src_x = (uu >> 16) + uu_ofs; 869 const int src_y = (vv >> 16) + vv_ofs; 870 uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; 871 872 ALLEGRO_COLOR src_color; 873 _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); 874 875 SHADE_COLORS(src_color, s->cur_color); 876 877 { 878 ALLEGRO_COLOR dst_color; 879 ALLEGRO_COLOR result; 880 _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); 881 _al_blend_inline(&src_color, &dst_color, op, src_mode, dst_mode, op_alpha, src_alpha, dst_alpha, &const_color, &result); 882 _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); 883 } 884 885 uu += du_dx; 886 vv += dv_dx; 887 888 if (_AL_EXPECT_FAIL(uu < 0)) 889 uu += w; 890 else if (_AL_EXPECT_FAIL(uu >= w)) 891 uu -= w; 892 893 if (_AL_EXPECT_FAIL(vv < 0)) 894 vv += h; 895 else if (_AL_EXPECT_FAIL(vv >= h)) 896 vv -= h; 897 898 } 899 } 900 } 901 } 902 } 903 } 904} 905 906static void shader_texture_solid_any_draw_shade_white(uintptr_t state, int x1, int y, int x2) 907{ 908 state_texture_solid_any_2d *s = (state_texture_solid_any_2d *) state; 909 910 float u = s->u; 911 float v = s->v; 912 913 ALLEGRO_BITMAP *target = s->target; 914 915 if (target->parent) { 916 x1 += target->xofs; 917 x2 += target->xofs; 918 y += target->yofs; 919 target = target->parent; 920 } 921 922 x1 -= target->lock_x; 923 x2 -= target->lock_x; 924 y -= target->lock_y; 925 y--; 926 927 if (y < 0 || y >= target->lock_h) { 928 return; 929 } 930 931 if (x1 < 0) { 932 933 u += s->du_dx * -x1; 934 v += s->dv_dx * -x1; 935 936 x1 = 0; 937 } 938 939 if (x2 > target->lock_w - 1) { 940 x2 = target->lock_w - 1; 941 } 942 943 { 944 int op, src_mode, dst_mode; 945 int op_alpha, src_alpha, dst_alpha; 946 ALLEGRO_COLOR const_color; 947 al_get_separate_bitmap_blender(&op, &src_mode, &dst_mode, &op_alpha, &src_alpha, &dst_alpha); 948 const_color = al_get_blend_color(); 949 950 { 951 const int offset_x = s->texture->parent ? s->texture->xofs : 0; 952 const int offset_y = s->texture->parent ? s->texture->yofs : 0; 953 ALLEGRO_BITMAP *texture = s->texture->parent ? s->texture->parent : s->texture; 954 const int src_format = texture->locked_region.format; 955 const int src_size = texture->locked_region.pixel_size; 956 957 /* Ensure u in [0, s->w) and v in [0, s->h). */ 958 while (u < 0) 959 u += s->w; 960 while (v < 0) 961 v += s->h; 962 u = fmodf(u, s->w); 963 v = fmodf(v, s->h); 964 ASSERT(0 <= u); 965 ASSERT(u < s->w); 966 ASSERT(0 <= v); 967 ASSERT(v < s->h); 968 969 { 970 const int dst_format = target->locked_region.format; 971 uint8_t *dst_data = (uint8_t *) target->lock_data + y * target->locked_region.pitch + x1 * target->locked_region.pixel_size; 972 973 if (op == ALLEGRO_ADD && src_mode == ALLEGRO_ONE && src_alpha == ALLEGRO_ONE && op_alpha == ALLEGRO_ADD && dst_mode == ALLEGRO_INVERSE_ALPHA && dst_alpha == ALLEGRO_INVERSE_ALPHA) { 974 975 if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888 && src_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { 976 uint8_t *lock_data = texture->locked_region.data; 977 const int src_pitch = texture->locked_region.pitch; 978 const al_fixed du_dx = al_ftofix(s->du_dx); 979 const al_fixed dv_dx = al_ftofix(s->dv_dx); 980 981 { 982 al_fixed uu = al_ftofix(u); 983 al_fixed vv = al_ftofix(v); 984 const int uu_ofs = offset_x - texture->lock_x; 985 const int vv_ofs = offset_y - texture->lock_y; 986 const al_fixed w = al_ftofix(s->w); 987 const al_fixed h = al_ftofix(s->h); 988 989 for (; x1 <= x2; x1++) { 990 const int src_x = (uu >> 16) + uu_ofs; 991 const int src_y = (vv >> 16) + vv_ofs; 992 uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; 993 994 ALLEGRO_COLOR src_color; 995 _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, src_data, src_color, false); 996 997 { 998 ALLEGRO_COLOR dst_color; 999 ALLEGRO_COLOR result; 1000 _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, dst_color, false); 1001 _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, NULL, &result); 1002 _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, result, true); 1003 } 1004 1005 uu += du_dx; 1006 vv += dv_dx; 1007 1008 if (_AL_EXPECT_FAIL(uu < 0)) 1009 uu += w; 1010 else if (_AL_EXPECT_FAIL(uu >= w)) 1011 uu -= w; 1012 1013 if (_AL_EXPECT_FAIL(vv < 0)) 1014 vv += h; 1015 else if (_AL_EXPECT_FAIL(vv >= h)) 1016 vv -= h; 1017 1018 } 1019 } 1020 } else { 1021 uint8_t *lock_data = texture->locked_region.data; 1022 const int src_pitch = texture->locked_region.pitch; 1023 const al_fixed du_dx = al_ftofix(s->du_dx); 1024 const al_fixed dv_dx = al_ftofix(s->dv_dx); 1025 1026 { 1027 al_fixed uu = al_ftofix(u); 1028 al_fixed vv = al_ftofix(v); 1029 const int uu_ofs = offset_x - texture->lock_x; 1030 const int vv_ofs = offset_y - texture->lock_y; 1031 const al_fixed w = al_ftofix(s->w); 1032 const al_fixed h = al_ftofix(s->h); 1033 1034 for (; x1 <= x2; x1++) { 1035 const int src_x = (uu >> 16) + uu_ofs; 1036 const int src_y = (vv >> 16) + vv_ofs; 1037 uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; 1038 1039 ALLEGRO_COLOR src_color; 1040 _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); 1041 1042 { 1043 ALLEGRO_COLOR dst_color; 1044 ALLEGRO_COLOR result; 1045 _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); 1046 _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, NULL, &result); 1047 _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); 1048 } 1049 1050 uu += du_dx; 1051 vv += dv_dx; 1052 1053 if (_AL_EXPECT_FAIL(uu < 0)) 1054 uu += w; 1055 else if (_AL_EXPECT_FAIL(uu >= w)) 1056 uu -= w; 1057 1058 if (_AL_EXPECT_FAIL(vv < 0)) 1059 vv += h; 1060 else if (_AL_EXPECT_FAIL(vv >= h)) 1061 vv -= h; 1062 1063 } 1064 } 1065 } 1066 } else if (op == ALLEGRO_ADD && src_mode == ALLEGRO_ALPHA && src_alpha == ALLEGRO_ALPHA && op_alpha == ALLEGRO_ADD && dst_mode == ALLEGRO_INVERSE_ALPHA && dst_alpha == ALLEGRO_INVERSE_ALPHA) { 1067 1068 if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888 && src_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { 1069 uint8_t *lock_data = texture->locked_region.data; 1070 const int src_pitch = texture->locked_region.pitch; 1071 const al_fixed du_dx = al_ftofix(s->du_dx); 1072 const al_fixed dv_dx = al_ftofix(s->dv_dx); 1073 1074 { 1075 al_fixed uu = al_ftofix(u); 1076 al_fixed vv = al_ftofix(v); 1077 const int uu_ofs = offset_x - texture->lock_x; 1078 const int vv_ofs = offset_y - texture->lock_y; 1079 const al_fixed w = al_ftofix(s->w); 1080 const al_fixed h = al_ftofix(s->h); 1081 1082 for (; x1 <= x2; x1++) { 1083 const int src_x = (uu >> 16) + uu_ofs; 1084 const int src_y = (vv >> 16) + vv_ofs; 1085 uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; 1086 1087 ALLEGRO_COLOR src_color; 1088 _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, src_data, src_color, false); 1089 1090 { 1091 ALLEGRO_COLOR dst_color; 1092 ALLEGRO_COLOR result; 1093 _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, dst_color, false); 1094 _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, NULL, &result); 1095 _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, result, true); 1096 } 1097 1098 uu += du_dx; 1099 vv += dv_dx; 1100 1101 if (_AL_EXPECT_FAIL(uu < 0)) 1102 uu += w; 1103 else if (_AL_EXPECT_FAIL(uu >= w)) 1104 uu -= w; 1105 1106 if (_AL_EXPECT_FAIL(vv < 0)) 1107 vv += h; 1108 else if (_AL_EXPECT_FAIL(vv >= h)) 1109 vv -= h; 1110 1111 } 1112 } 1113 } else { 1114 uint8_t *lock_data = texture->locked_region.data; 1115 const int src_pitch = texture->locked_region.pitch; 1116 const al_fixed du_dx = al_ftofix(s->du_dx); 1117 const al_fixed dv_dx = al_ftofix(s->dv_dx); 1118 1119 { 1120 al_fixed uu = al_ftofix(u); 1121 al_fixed vv = al_ftofix(v); 1122 const int uu_ofs = offset_x - texture->lock_x; 1123 const int vv_ofs = offset_y - texture->lock_y; 1124 const al_fixed w = al_ftofix(s->w); 1125 const al_fixed h = al_ftofix(s->h); 1126 1127 for (; x1 <= x2; x1++) { 1128 const int src_x = (uu >> 16) + uu_ofs; 1129 const int src_y = (vv >> 16) + vv_ofs; 1130 uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; 1131 1132 ALLEGRO_COLOR src_color; 1133 _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); 1134 1135 { 1136 ALLEGRO_COLOR dst_color; 1137 ALLEGRO_COLOR result; 1138 _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); 1139 _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, NULL, &result); 1140 _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); 1141 } 1142 1143 uu += du_dx; 1144 vv += dv_dx; 1145 1146 if (_AL_EXPECT_FAIL(uu < 0)) 1147 uu += w; 1148 else if (_AL_EXPECT_FAIL(uu >= w)) 1149 uu -= w; 1150 1151 if (_AL_EXPECT_FAIL(vv < 0)) 1152 vv += h; 1153 else if (_AL_EXPECT_FAIL(vv >= h)) 1154 vv -= h; 1155 1156 } 1157 } 1158 } 1159 } else if (op == ALLEGRO_ADD && src_mode == ALLEGRO_ONE && src_alpha == ALLEGRO_ONE && op_alpha == ALLEGRO_ADD && dst_mode == ALLEGRO_ONE && dst_alpha == ALLEGRO_ONE) { 1160 1161 if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888 && src_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { 1162 uint8_t *lock_data = texture->locked_region.data; 1163 const int src_pitch = texture->locked_region.pitch; 1164 const al_fixed du_dx = al_ftofix(s->du_dx); 1165 const al_fixed dv_dx = al_ftofix(s->dv_dx); 1166 1167 { 1168 al_fixed uu = al_ftofix(u); 1169 al_fixed vv = al_ftofix(v); 1170 const int uu_ofs = offset_x - texture->lock_x; 1171 const int vv_ofs = offset_y - texture->lock_y; 1172 const al_fixed w = al_ftofix(s->w); 1173 const al_fixed h = al_ftofix(s->h); 1174 1175 for (; x1 <= x2; x1++) { 1176 const int src_x = (uu >> 16) + uu_ofs; 1177 const int src_y = (vv >> 16) + vv_ofs; 1178 uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; 1179 1180 ALLEGRO_COLOR src_color; 1181 _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, src_data, src_color, false); 1182 1183 { 1184 ALLEGRO_COLOR dst_color; 1185 ALLEGRO_COLOR result; 1186 _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, dst_color, false); 1187 _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, NULL, &result); 1188 _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, result, true); 1189 } 1190 1191 uu += du_dx; 1192 vv += dv_dx; 1193 1194 if (_AL_EXPECT_FAIL(uu < 0)) 1195 uu += w; 1196 else if (_AL_EXPECT_FAIL(uu >= w)) 1197 uu -= w; 1198 1199 if (_AL_EXPECT_FAIL(vv < 0)) 1200 vv += h; 1201 else if (_AL_EXPECT_FAIL(vv >= h)) 1202 vv -= h; 1203 1204 } 1205 } 1206 } else { 1207 uint8_t *lock_data = texture->locked_region.data; 1208 const int src_pitch = texture->locked_region.pitch; 1209 const al_fixed du_dx = al_ftofix(s->du_dx); 1210 const al_fixed dv_dx = al_ftofix(s->dv_dx); 1211 1212 { 1213 al_fixed uu = al_ftofix(u); 1214 al_fixed vv = al_ftofix(v); 1215 const int uu_ofs = offset_x - texture->lock_x; 1216 const int vv_ofs = offset_y - texture->lock_y; 1217 const al_fixed w = al_ftofix(s->w); 1218 const al_fixed h = al_ftofix(s->h); 1219 1220 for (; x1 <= x2; x1++) { 1221 const int src_x = (uu >> 16) + uu_ofs; 1222 const int src_y = (vv >> 16) + vv_ofs; 1223 uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; 1224 1225 ALLEGRO_COLOR src_color; 1226 _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); 1227 1228 { 1229 ALLEGRO_COLOR dst_color; 1230 ALLEGRO_COLOR result; 1231 _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); 1232 _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, NULL, &result); 1233 _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); 1234 } 1235 1236 uu += du_dx; 1237 vv += dv_dx; 1238 1239 if (_AL_EXPECT_FAIL(uu < 0)) 1240 uu += w; 1241 else if (_AL_EXPECT_FAIL(uu >= w)) 1242 uu -= w; 1243 1244 if (_AL_EXPECT_FAIL(vv < 0)) 1245 vv += h; 1246 else if (_AL_EXPECT_FAIL(vv >= h)) 1247 vv -= h; 1248 1249 } 1250 } 1251 } 1252 } else if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888 && src_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { 1253 uint8_t *lock_data = texture->locked_region.data; 1254 const int src_pitch = texture->locked_region.pitch; 1255 const al_fixed du_dx = al_ftofix(s->du_dx); 1256 const al_fixed dv_dx = al_ftofix(s->dv_dx); 1257 1258 { 1259 al_fixed uu = al_ftofix(u); 1260 al_fixed vv = al_ftofix(v); 1261 const int uu_ofs = offset_x - texture->lock_x; 1262 const int vv_ofs = offset_y - texture->lock_y; 1263 const al_fixed w = al_ftofix(s->w); 1264 const al_fixed h = al_ftofix(s->h); 1265 1266 for (; x1 <= x2; x1++) { 1267 const int src_x = (uu >> 16) + uu_ofs; 1268 const int src_y = (vv >> 16) + vv_ofs; 1269 uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; 1270 1271 ALLEGRO_COLOR src_color; 1272 _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, src_data, src_color, false); 1273 1274 { 1275 ALLEGRO_COLOR dst_color; 1276 ALLEGRO_COLOR result; 1277 _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, dst_color, false); 1278 _al_blend_inline(&src_color, &dst_color, op, src_mode, dst_mode, op_alpha, src_alpha, dst_alpha, &const_color, &result); 1279 _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, result, true); 1280 } 1281 1282 uu += du_dx; 1283 vv += dv_dx; 1284 1285 if (_AL_EXPECT_FAIL(uu < 0)) 1286 uu += w; 1287 else if (_AL_EXPECT_FAIL(uu >= w)) 1288 uu -= w; 1289 1290 if (_AL_EXPECT_FAIL(vv < 0)) 1291 vv += h; 1292 else if (_AL_EXPECT_FAIL(vv >= h)) 1293 vv -= h; 1294 1295 } 1296 } 1297 } else { 1298 uint8_t *lock_data = texture->locked_region.data; 1299 const int src_pitch = texture->locked_region.pitch; 1300 const al_fixed du_dx = al_ftofix(s->du_dx); 1301 const al_fixed dv_dx = al_ftofix(s->dv_dx); 1302 1303 { 1304 al_fixed uu = al_ftofix(u); 1305 al_fixed vv = al_ftofix(v); 1306 const int uu_ofs = offset_x - texture->lock_x; 1307 const int vv_ofs = offset_y - texture->lock_y; 1308 const al_fixed w = al_ftofix(s->w); 1309 const al_fixed h = al_ftofix(s->h); 1310 1311 for (; x1 <= x2; x1++) { 1312 const int src_x = (uu >> 16) + uu_ofs; 1313 const int src_y = (vv >> 16) + vv_ofs; 1314 uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; 1315 1316 ALLEGRO_COLOR src_color; 1317 _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); 1318 1319 { 1320 ALLEGRO_COLOR dst_color; 1321 ALLEGRO_COLOR result; 1322 _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); 1323 _al_blend_inline(&src_color, &dst_color, op, src_mode, dst_mode, op_alpha, src_alpha, dst_alpha, &const_color, &result); 1324 _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); 1325 } 1326 1327 uu += du_dx; 1328 vv += dv_dx; 1329 1330 if (_AL_EXPECT_FAIL(uu < 0)) 1331 uu += w; 1332 else if (_AL_EXPECT_FAIL(uu >= w)) 1333 uu -= w; 1334 1335 if (_AL_EXPECT_FAIL(vv < 0)) 1336 vv += h; 1337 else if (_AL_EXPECT_FAIL(vv >= h)) 1338 vv -= h; 1339 1340 } 1341 } 1342 } 1343 } 1344 } 1345 } 1346} 1347 1348static void shader_texture_solid_any_draw_opaque(uintptr_t state, int x1, int y, int x2) 1349{ 1350 state_texture_solid_any_2d *s = (state_texture_solid_any_2d *) state; 1351 1352 float u = s->u; 1353 float v = s->v; 1354 1355 ALLEGRO_BITMAP *target = s->target; 1356 1357 if (target->parent) { 1358 x1 += target->xofs; 1359 x2 += target->xofs; 1360 y += target->yofs; 1361 target = target->parent; 1362 } 1363 1364 x1 -= target->lock_x; 1365 x2 -= target->lock_x; 1366 y -= target->lock_y; 1367 y--; 1368 1369 if (y < 0 || y >= target->lock_h) { 1370 return; 1371 } 1372 1373 if (x1 < 0) { 1374 1375 u += s->du_dx * -x1; 1376 v += s->dv_dx * -x1; 1377 1378 x1 = 0; 1379 } 1380 1381 if (x2 > target->lock_w - 1) { 1382 x2 = target->lock_w - 1; 1383 } 1384 1385 { 1386 { 1387 const int offset_x = s->texture->parent ? s->texture->xofs : 0; 1388 const int offset_y = s->texture->parent ? s->texture->yofs : 0; 1389 ALLEGRO_BITMAP *texture = s->texture->parent ? s->texture->parent : s->texture; 1390 const int src_format = texture->locked_region.format; 1391 const int src_size = texture->locked_region.pixel_size; 1392 1393 /* Ensure u in [0, s->w) and v in [0, s->h). */ 1394 while (u < 0) 1395 u += s->w; 1396 while (v < 0) 1397 v += s->h; 1398 u = fmodf(u, s->w); 1399 v = fmodf(v, s->h); 1400 ASSERT(0 <= u); 1401 ASSERT(u < s->w); 1402 ASSERT(0 <= v); 1403 ASSERT(v < s->h); 1404 1405 { 1406 const int dst_format = target->locked_region.format; 1407 uint8_t *dst_data = (uint8_t *) target->lock_data + y * target->locked_region.pitch + x1 * target->locked_region.pixel_size; 1408 1409 if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888 && src_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { 1410 uint8_t *lock_data = texture->locked_region.data; 1411 const int src_pitch = texture->locked_region.pitch; 1412 const al_fixed du_dx = al_ftofix(s->du_dx); 1413 const al_fixed dv_dx = al_ftofix(s->dv_dx); 1414 1415 const float steps = x2 - x1 + 1; 1416 const float end_u = u + steps * s->du_dx; 1417 const float end_v = v + steps * s->dv_dx; 1418 if (end_u >= 0 && end_u < s->w && end_v >= 0 && end_v < s->h) { 1419 1420 { 1421 al_fixed uu = al_ftofix(u) + ((offset_x - texture->lock_x) << 16); 1422 al_fixed vv = al_ftofix(v) + ((offset_y - texture->lock_y) << 16); 1423 1424 for (; x1 <= x2; x1++) { 1425 const int src_x = (uu >> 16) + 0; 1426 const int src_y = (vv >> 16) + 0; 1427 uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; 1428 1429 ALLEGRO_COLOR src_color; 1430 _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, src_data, src_color, false); 1431 1432 SHADE_COLORS(src_color, s->cur_color); 1433 1434 _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, src_color, true); 1435 1436 uu += du_dx; 1437 vv += dv_dx; 1438 1439 } 1440 } 1441 } else { 1442 al_fixed uu = al_ftofix(u); 1443 al_fixed vv = al_ftofix(v); 1444 const int uu_ofs = offset_x - texture->lock_x; 1445 const int vv_ofs = offset_y - texture->lock_y; 1446 const al_fixed w = al_ftofix(s->w); 1447 const al_fixed h = al_ftofix(s->h); 1448 1449 for (; x1 <= x2; x1++) { 1450 const int src_x = (uu >> 16) + uu_ofs; 1451 const int src_y = (vv >> 16) + vv_ofs; 1452 uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; 1453 1454 ALLEGRO_COLOR src_color; 1455 _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, src_data, src_color, false); 1456 1457 SHADE_COLORS(src_color, s->cur_color); 1458 1459 _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, src_color, true); 1460 1461 uu += du_dx; 1462 vv += dv_dx; 1463 1464 if (_AL_EXPECT_FAIL(uu < 0)) 1465 uu += w; 1466 else if (_AL_EXPECT_FAIL(uu >= w)) 1467 uu -= w; 1468 1469 if (_AL_EXPECT_FAIL(vv < 0)) 1470 vv += h; 1471 else if (_AL_EXPECT_FAIL(vv >= h)) 1472 vv -= h; 1473 1474 } 1475 } 1476 } else { 1477 uint8_t *lock_data = texture->locked_region.data; 1478 const int src_pitch = texture->locked_region.pitch; 1479 const al_fixed du_dx = al_ftofix(s->du_dx); 1480 const al_fixed dv_dx = al_ftofix(s->dv_dx); 1481 1482 const float steps = x2 - x1 + 1; 1483 const float end_u = u + steps * s->du_dx; 1484 const float end_v = v + steps * s->dv_dx; 1485 if (end_u >= 0 && end_u < s->w && end_v >= 0 && end_v < s->h) { 1486 1487 { 1488 al_fixed uu = al_ftofix(u) + ((offset_x - texture->lock_x) << 16); 1489 al_fixed vv = al_ftofix(v) + ((offset_y - texture->lock_y) << 16); 1490 1491 for (; x1 <= x2; x1++) { 1492 const int src_x = (uu >> 16) + 0; 1493 const int src_y = (vv >> 16) + 0; 1494 uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; 1495 1496 ALLEGRO_COLOR src_color; 1497 _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); 1498 1499 SHADE_COLORS(src_color, s->cur_color); 1500 1501 _AL_INLINE_PUT_PIXEL(dst_format, dst_data, src_color, true); 1502 1503 uu += du_dx; 1504 vv += dv_dx; 1505 1506 } 1507 } 1508 } else { 1509 al_fixed uu = al_ftofix(u); 1510 al_fixed vv = al_ftofix(v); 1511 const int uu_ofs = offset_x - texture->lock_x; 1512 const int vv_ofs = offset_y - texture->lock_y; 1513 const al_fixed w = al_ftofix(s->w); 1514 const al_fixed h = al_ftofix(s->h); 1515 1516 for (; x1 <= x2; x1++) { 1517 const int src_x = (uu >> 16) + uu_ofs; 1518 const int src_y = (vv >> 16) + vv_ofs; 1519 uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; 1520 1521 ALLEGRO_COLOR src_color; 1522 _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); 1523 1524 SHADE_COLORS(src_color, s->cur_color); 1525 1526 _AL_INLINE_PUT_PIXEL(dst_format, dst_data, src_color, true); 1527 1528 uu += du_dx; 1529 vv += dv_dx; 1530 1531 if (_AL_EXPECT_FAIL(uu < 0)) 1532 uu += w; 1533 else if (_AL_EXPECT_FAIL(uu >= w)) 1534 uu -= w; 1535 1536 if (_AL_EXPECT_FAIL(vv < 0)) 1537 vv += h; 1538 else if (_AL_EXPECT_FAIL(vv >= h)) 1539 vv -= h; 1540 1541 } 1542 } 1543 } 1544 } 1545 } 1546 } 1547} 1548 1549static void shader_texture_solid_any_draw_opaque_white(uintptr_t state, int x1, int y, int x2) 1550{ 1551 state_texture_solid_any_2d *s = (state_texture_solid_any_2d *) state; 1552 1553 float u = s->u; 1554 float v = s->v; 1555 1556 ALLEGRO_BITMAP *target = s->target; 1557 1558 if (target->parent) { 1559 x1 += target->xofs; 1560 x2 += target->xofs; 1561 y += target->yofs; 1562 target = target->parent; 1563 } 1564 1565 x1 -= target->lock_x; 1566 x2 -= target->lock_x; 1567 y -= target->lock_y; 1568 y--; 1569 1570 if (y < 0 || y >= target->lock_h) { 1571 return; 1572 } 1573 1574 if (x1 < 0) { 1575 1576 u += s->du_dx * -x1; 1577 v += s->dv_dx * -x1; 1578 1579 x1 = 0; 1580 } 1581 1582 if (x2 > target->lock_w - 1) { 1583 x2 = target->lock_w - 1; 1584 } 1585 1586 { 1587 { 1588 const int offset_x = s->texture->parent ? s->texture->xofs : 0; 1589 const int offset_y = s->texture->parent ? s->texture->yofs : 0; 1590 ALLEGRO_BITMAP *texture = s->texture->parent ? s->texture->parent : s->texture; 1591 const int src_format = texture->locked_region.format; 1592 const int src_size = texture->locked_region.pixel_size; 1593 1594 /* Ensure u in [0, s->w) and v in [0, s->h). */ 1595 while (u < 0) 1596 u += s->w; 1597 while (v < 0) 1598 v += s->h; 1599 u = fmodf(u, s->w); 1600 v = fmodf(v, s->h); 1601 ASSERT(0 <= u); 1602 ASSERT(u < s->w); 1603 ASSERT(0 <= v); 1604 ASSERT(v < s->h); 1605 1606 { 1607 const int dst_format = target->locked_region.format; 1608 uint8_t *dst_data = (uint8_t *) target->lock_data + y * target->locked_region.pitch + x1 * target->locked_region.pixel_size; 1609 1610 if (dst_format == src_format && src_size == 4) { 1611 uint8_t *lock_data = texture->locked_region.data; 1612 const int src_pitch = texture->locked_region.pitch; 1613 const al_fixed du_dx = al_ftofix(s->du_dx); 1614 const al_fixed dv_dx = al_ftofix(s->dv_dx); 1615 1616 const float steps = x2 - x1 + 1; 1617 const float end_u = u + steps * s->du_dx; 1618 const float end_v = v + steps * s->dv_dx; 1619 if (end_u >= 0 && end_u < s->w && end_v >= 0 && end_v < s->h) { 1620 1621 { 1622 al_fixed uu = al_ftofix(u) + ((offset_x - texture->lock_x) << 16); 1623 al_fixed vv = al_ftofix(v) + ((offset_y - texture->lock_y) << 16); 1624 1625 for (; x1 <= x2; x1++) { 1626 const int src_x = (uu >> 16) + 0; 1627 const int src_y = (vv >> 16) + 0; 1628 uint8_t *src_data = lock_data + src_y * src_pitch + src_x * 4; 1629 1630 switch (4) { 1631 case 4: 1632 memcpy(dst_data, src_data, 4); 1633 dst_data += 4; 1634 break; 1635 case 3: 1636 memcpy(dst_data, src_data, 3); 1637 dst_data += 3; 1638 break; 1639 case 2: 1640 *dst_data++ = *src_data++; 1641 *dst_data++ = *src_data; 1642 break; 1643 case 1: 1644 *dst_data++ = *src_data; 1645 break; 1646 } 1647 1648 uu += du_dx; 1649 vv += dv_dx; 1650 1651 } 1652 } 1653 } else { 1654 al_fixed uu = al_ftofix(u); 1655 al_fixed vv = al_ftofix(v); 1656 const int uu_ofs = offset_x - texture->lock_x; 1657 const int vv_ofs = offset_y - texture->lock_y; 1658 const al_fixed w = al_ftofix(s->w); 1659 const al_fixed h = al_ftofix(s->h); 1660 1661 for (; x1 <= x2; x1++) { 1662 const int src_x = (uu >> 16) + uu_ofs; 1663 const int src_y = (vv >> 16) + vv_ofs; 1664 uint8_t *src_data = lock_data + src_y * src_pitch + src_x * 4; 1665 1666 switch (4) { 1667 case 4: 1668 memcpy(dst_data, src_data, 4); 1669 dst_data += 4; 1670 break; 1671 case 3: 1672 memcpy(dst_data, src_data, 3); 1673 dst_data += 3; 1674 break; 1675 case 2: 1676 *dst_data++ = *src_data++; 1677 *dst_data++ = *src_data; 1678 break; 1679 case 1: 1680 *dst_data++ = *src_data; 1681 break; 1682 } 1683 1684 uu += du_dx; 1685 vv += dv_dx; 1686 1687 if (_AL_EXPECT_FAIL(uu < 0)) 1688 uu += w; 1689 else if (_AL_EXPECT_FAIL(uu >= w)) 1690 uu -= w; 1691 1692 if (_AL_EXPECT_FAIL(vv < 0)) 1693 vv += h; 1694 else if (_AL_EXPECT_FAIL(vv >= h)) 1695 vv -= h; 1696 1697 } 1698 } 1699 } else if (dst_format == src_format && src_size == 3) { 1700 uint8_t *lock_data = texture->locked_region.data; 1701 const int src_pitch = texture->locked_region.pitch; 1702 const al_fixed du_dx = al_ftofix(s->du_dx); 1703 const al_fixed dv_dx = al_ftofix(s->dv_dx); 1704 1705 const float steps = x2 - x1 + 1; 1706 const float end_u = u + steps * s->du_dx; 1707 const float end_v = v + steps * s->dv_dx; 1708 if (end_u >= 0 && end_u < s->w && end_v >= 0 && end_v < s->h) { 1709 1710 { 1711 al_fixed uu = al_ftofix(u) + ((offset_x - texture->lock_x) << 16); 1712 al_fixed vv = al_ftofix(v) + ((offset_y - texture->lock_y) << 16); 1713 1714 for (; x1 <= x2; x1++) { 1715 const int src_x = (uu >> 16) + 0; 1716 const int src_y = (vv >> 16) + 0; 1717 uint8_t *src_data = lock_data + src_y * src_pitch + src_x * 3; 1718 1719 switch (3) { 1720 case 4: 1721 memcpy(dst_data, src_data, 4); 1722 dst_data += 4; 1723 break; 1724 case 3: 1725 memcpy(dst_data, src_data, 3); 1726 dst_data += 3; 1727 break; 1728 case 2: 1729 *dst_data++ = *src_data++; 1730 *dst_data++ = *src_data; 1731 break; 1732 case 1: 1733 *dst_data++ = *src_data; 1734 break; 1735 } 1736 1737 uu += du_dx; 1738 vv += dv_dx; 1739 1740 } 1741 } 1742 } else { 1743 al_fixed uu = al_ftofix(u); 1744 al_fixed vv = al_ftofix(v); 1745 const int uu_ofs = offset_x - texture->lock_x; 1746 const int vv_ofs = offset_y - texture->lock_y; 1747 const al_fixed w = al_ftofix(s->w); 1748 const al_fixed h = al_ftofix(s->h); 1749 1750 for (; x1 <= x2; x1++) { 1751 const int src_x = (uu >> 16) + uu_ofs; 1752 const int src_y = (vv >> 16) + vv_ofs; 1753 uint8_t *src_data = lock_data + src_y * src_pitch + src_x * 3; 1754 1755 switch (3) { 1756 case 4: 1757 memcpy(dst_data, src_data, 4); 1758 dst_data += 4; 1759 break; 1760 case 3: 1761 memcpy(dst_data, src_data, 3); 1762 dst_data += 3; 1763 break; 1764 case 2: 1765 *dst_data++ = *src_data++; 1766 *dst_data++ = *src_data; 1767 break; 1768 case 1: 1769 *dst_data++ = *src_data; 1770 break; 1771 } 1772 1773 uu += du_dx; 1774 vv += dv_dx; 1775 1776 if (_AL_EXPECT_FAIL(uu < 0)) 1777 uu += w; 1778 else if (_AL_EXPECT_FAIL(uu >= w)) 1779 uu -= w; 1780 1781 if (_AL_EXPECT_FAIL(vv < 0)) 1782 vv += h; 1783 else if (_AL_EXPECT_FAIL(vv >= h)) 1784 vv -= h; 1785 1786 } 1787 } 1788 } else if (dst_format == src_format && src_size == 2) { 1789 uint8_t *lock_data = texture->locked_region.data; 1790 const int src_pitch = texture->locked_region.pitch; 1791 const al_fixed du_dx = al_ftofix(s->du_dx); 1792 const al_fixed dv_dx = al_ftofix(s->dv_dx); 1793 1794 const float steps = x2 - x1 + 1; 1795 const float end_u = u + steps * s->du_dx; 1796 const float end_v = v + steps * s->dv_dx; 1797 if (end_u >= 0 && end_u < s->w && end_v >= 0 && end_v < s->h) { 1798 1799 { 1800 al_fixed uu = al_ftofix(u) + ((offset_x - texture->lock_x) << 16); 1801 al_fixed vv = al_ftofix(v) + ((offset_y - texture->lock_y) << 16); 1802 1803 for (; x1 <= x2; x1++) { 1804 const int src_x = (uu >> 16) + 0; 1805 const int src_y = (vv >> 16) + 0; 1806 uint8_t *src_data = lock_data + src_y * src_pitch + src_x * 2; 1807 1808 switch (2) { 1809 case 4: 1810 memcpy(dst_data, src_data, 4); 1811 dst_data += 4; 1812 break; 1813 case 3: 1814 memcpy(dst_data, src_data, 3); 1815 dst_data += 3; 1816 break; 1817 case 2: 1818 *dst_data++ = *src_data++; 1819 *dst_data++ = *src_data; 1820 break; 1821 case 1: 1822 *dst_data++ = *src_data; 1823 break; 1824 } 1825 1826 uu += du_dx; 1827 vv += dv_dx; 1828 1829 } 1830 } 1831 } else { 1832 al_fixed uu = al_ftofix(u); 1833 al_fixed vv = al_ftofix(v); 1834 const int uu_ofs = offset_x - texture->lock_x; 1835 const int vv_ofs = offset_y - texture->lock_y; 1836 const al_fixed w = al_ftofix(s->w); 1837 const al_fixed h = al_ftofix(s->h); 1838 1839 for (; x1 <= x2; x1++) { 1840 const int src_x = (uu >> 16) + uu_ofs; 1841 const int src_y = (vv >> 16) + vv_ofs; 1842 uint8_t *src_data = lock_data + src_y * src_pitch + src_x * 2; 1843 1844 switch (2) { 1845 case 4: 1846 memcpy(dst_data, src_data, 4); 1847 dst_data += 4; 1848 break; 1849 case 3: 1850 memcpy(dst_data, src_data, 3); 1851 dst_data += 3; 1852 break; 1853 case 2: 1854 *dst_data++ = *src_data++; 1855 *dst_data++ = *src_data; 1856 break; 1857 case 1: 1858 *dst_data++ = *src_data; 1859 break; 1860 } 1861 1862 uu += du_dx; 1863 vv += dv_dx; 1864 1865 if (_AL_EXPECT_FAIL(uu < 0)) 1866 uu += w; 1867 else if (_AL_EXPECT_FAIL(uu >= w)) 1868 uu -= w; 1869 1870 if (_AL_EXPECT_FAIL(vv < 0)) 1871 vv += h; 1872 else if (_AL_EXPECT_FAIL(vv >= h)) 1873 vv -= h; 1874 1875 } 1876 } 1877 } else { 1878 uint8_t *lock_data = texture->locked_region.data; 1879 const int src_pitch = texture->locked_region.pitch; 1880 const al_fixed du_dx = al_ftofix(s->du_dx); 1881 const al_fixed dv_dx = al_ftofix(s->dv_dx); 1882 1883 const float steps = x2 - x1 + 1; 1884 const float end_u = u + steps * s->du_dx; 1885 const float end_v = v + steps * s->dv_dx; 1886 if (end_u >= 0 && end_u < s->w && end_v >= 0 && end_v < s->h) { 1887 1888 { 1889 al_fixed uu = al_ftofix(u) + ((offset_x - texture->lock_x) << 16); 1890 al_fixed vv = al_ftofix(v) + ((offset_y - texture->lock_y) << 16); 1891 1892 for (; x1 <= x2; x1++) { 1893 const int src_x = (uu >> 16) + 0; 1894 const int src_y = (vv >> 16) + 0; 1895 uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; 1896 1897 ALLEGRO_COLOR src_color; 1898 _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); 1899 1900 _AL_INLINE_PUT_PIXEL(dst_format, dst_data, src_color, true); 1901 1902 uu += du_dx; 1903 vv += dv_dx; 1904 1905 } 1906 } 1907 } else { 1908 al_fixed uu = al_ftofix(u); 1909 al_fixed vv = al_ftofix(v); 1910 const int uu_ofs = offset_x - texture->lock_x; 1911 const int vv_ofs = offset_y - texture->lock_y; 1912 const al_fixed w = al_ftofix(s->w); 1913 const al_fixed h = al_ftofix(s->h); 1914 1915 for (; x1 <= x2; x1++) { 1916 const int src_x = (uu >> 16) + uu_ofs; 1917 const int src_y = (vv >> 16) + vv_ofs; 1918 uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; 1919 1920 ALLEGRO_COLOR src_color; 1921 _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); 1922 1923 _AL_INLINE_PUT_PIXEL(dst_format, dst_data, src_color, true); 1924 1925 uu += du_dx; 1926 vv += dv_dx; 1927 1928 if (_AL_EXPECT_FAIL(uu < 0)) 1929 uu += w; 1930 else if (_AL_EXPECT_FAIL(uu >= w)) 1931 uu -= w; 1932 1933 if (_AL_EXPECT_FAIL(vv < 0)) 1934 vv += h; 1935 else if (_AL_EXPECT_FAIL(vv >= h)) 1936 vv -= h; 1937 1938 } 1939 } 1940 } 1941 } 1942 } 1943 } 1944} 1945 1946static void shader_texture_grad_any_draw_shade(uintptr_t state, int x1, int y, int x2) 1947{ 1948 state_texture_grad_any_2d *gs = (state_texture_grad_any_2d *) state; 1949 state_texture_solid_any_2d *s = &gs->solid; 1950 ALLEGRO_COLOR cur_color = s->cur_color; 1951 1952 float u = s->u; 1953 float v = s->v; 1954 1955 ALLEGRO_BITMAP *target = s->target; 1956 1957 if (target->parent) { 1958 x1 += target->xofs; 1959 x2 += target->xofs; 1960 y += target->yofs; 1961 target = target->parent; 1962 } 1963 1964 x1 -= target->lock_x; 1965 x2 -= target->lock_x; 1966 y -= target->lock_y; 1967 y--; 1968 1969 if (y < 0 || y >= target->lock_h) { 1970 return; 1971 } 1972 1973 if (x1 < 0) { 1974 1975 u += s->du_dx * -x1; 1976 v += s->dv_dx * -x1; 1977 1978 cur_color.r += gs->color_dx.r * -x1; 1979 cur_color.g += gs->color_dx.g * -x1; 1980 cur_color.b += gs->color_dx.b * -x1; 1981 cur_color.a += gs->color_dx.a * -x1; 1982 1983 x1 = 0; 1984 } 1985 1986 if (x2 > target->lock_w - 1) { 1987 x2 = target->lock_w - 1; 1988 } 1989 1990 { 1991 int op, src_mode, dst_mode; 1992 int op_alpha, src_alpha, dst_alpha; 1993 ALLEGRO_COLOR const_color; 1994 al_get_separate_bitmap_blender(&op, &src_mode, &dst_mode, &op_alpha, &src_alpha, &dst_alpha); 1995 const_color = al_get_blend_color(); 1996 1997 { 1998 const int offset_x = s->texture->parent ? s->texture->xofs : 0; 1999 const int offset_y = s->texture->parent ? s->texture->yofs : 0; 2000 ALLEGRO_BITMAP *texture = s->texture->parent ? s->texture->parent : s->texture; 2001 const int src_format = texture->locked_region.format; 2002 const int src_size = texture->locked_region.pixel_size; 2003 2004 /* Ensure u in [0, s->w) and v in [0, s->h). */ 2005 while (u < 0) 2006 u += s->w; 2007 while (v < 0) 2008 v += s->h; 2009 u = fmodf(u, s->w); 2010 v = fmodf(v, s->h); 2011 ASSERT(0 <= u); 2012 ASSERT(u < s->w); 2013 ASSERT(0 <= v); 2014 ASSERT(v < s->h); 2015 2016 { 2017 const int dst_format = target->locked_region.format; 2018 uint8_t *dst_data = (uint8_t *) target->lock_data + y * target->locked_region.pitch + x1 * target->locked_region.pixel_size; 2019 2020 if (op == ALLEGRO_ADD && src_mode == ALLEGRO_ONE && src_alpha == ALLEGRO_ONE && op_alpha == ALLEGRO_ADD && dst_mode == ALLEGRO_INVERSE_ALPHA && dst_alpha == ALLEGRO_INVERSE_ALPHA) { 2021 2022 if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888 && src_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { 2023 uint8_t *lock_data = texture->locked_region.data; 2024 const int src_pitch = texture->locked_region.pitch; 2025 const al_fixed du_dx = al_ftofix(s->du_dx); 2026 const al_fixed dv_dx = al_ftofix(s->dv_dx); 2027 2028 { 2029 al_fixed uu = al_ftofix(u); 2030 al_fixed vv = al_ftofix(v); 2031 const int uu_ofs = offset_x - texture->lock_x; 2032 const int vv_ofs = offset_y - texture->lock_y; 2033 const al_fixed w = al_ftofix(s->w); 2034 const al_fixed h = al_ftofix(s->h); 2035 2036 for (; x1 <= x2; x1++) { 2037 const int src_x = (uu >> 16) + uu_ofs; 2038 const int src_y = (vv >> 16) + vv_ofs; 2039 uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; 2040 2041 ALLEGRO_COLOR src_color; 2042 _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, src_data, src_color, false); 2043 2044 SHADE_COLORS(src_color, cur_color); 2045 2046 { 2047 ALLEGRO_COLOR dst_color; 2048 ALLEGRO_COLOR result; 2049 _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, dst_color, false); 2050 _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, NULL, &result); 2051 _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, result, true); 2052 } 2053 2054 uu += du_dx; 2055 vv += dv_dx; 2056 2057 if (_AL_EXPECT_FAIL(uu < 0)) 2058 uu += w; 2059 else if (_AL_EXPECT_FAIL(uu >= w)) 2060 uu -= w; 2061 2062 if (_AL_EXPECT_FAIL(vv < 0)) 2063 vv += h; 2064 else if (_AL_EXPECT_FAIL(vv >= h)) 2065 vv -= h; 2066 2067 cur_color.r += gs->color_dx.r; 2068 cur_color.g += gs->color_dx.g; 2069 cur_color.b += gs->color_dx.b; 2070 cur_color.a += gs->color_dx.a; 2071 2072 } 2073 } 2074 } else { 2075 uint8_t *lock_data = texture->locked_region.data; 2076 const int src_pitch = texture->locked_region.pitch; 2077 const al_fixed du_dx = al_ftofix(s->du_dx); 2078 const al_fixed dv_dx = al_ftofix(s->dv_dx); 2079 2080 { 2081 al_fixed uu = al_ftofix(u); 2082 al_fixed vv = al_ftofix(v); 2083 const int uu_ofs = offset_x - texture->lock_x; 2084 const int vv_ofs = offset_y - texture->lock_y; 2085 const al_fixed w = al_ftofix(s->w); 2086 const al_fixed h = al_ftofix(s->h); 2087 2088 for (; x1 <= x2; x1++) { 2089 const int src_x = (uu >> 16) + uu_ofs; 2090 const int src_y = (vv >> 16) + vv_ofs; 2091 uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; 2092 2093 ALLEGRO_COLOR src_color; 2094 _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); 2095 2096 SHADE_COLORS(src_color, cur_color); 2097 2098 { 2099 ALLEGRO_COLOR dst_color; 2100 ALLEGRO_COLOR result; 2101 _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); 2102 _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, NULL, &result); 2103 _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); 2104 } 2105 2106 uu += du_dx; 2107 vv += dv_dx; 2108 2109 if (_AL_EXPECT_FAIL(uu < 0)) 2110 uu += w; 2111 else if (_AL_EXPECT_FAIL(uu >= w)) 2112 uu -= w; 2113 2114 if (_AL_EXPECT_FAIL(vv < 0)) 2115 vv += h; 2116 else if (_AL_EXPECT_FAIL(vv >= h)) 2117 vv -= h; 2118 2119 cur_color.r += gs->color_dx.r; 2120 cur_color.g += gs->color_dx.g; 2121 cur_color.b += gs->color_dx.b; 2122 cur_color.a += gs->color_dx.a; 2123 2124 } 2125 } 2126 } 2127 } else if (op == ALLEGRO_ADD && src_mode == ALLEGRO_ALPHA && src_alpha == ALLEGRO_ALPHA && op_alpha == ALLEGRO_ADD && dst_mode == ALLEGRO_INVERSE_ALPHA && dst_alpha == ALLEGRO_INVERSE_ALPHA) { 2128 2129 if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888 && src_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { 2130 uint8_t *lock_data = texture->locked_region.data; 2131 const int src_pitch = texture->locked_region.pitch; 2132 const al_fixed du_dx = al_ftofix(s->du_dx); 2133 const al_fixed dv_dx = al_ftofix(s->dv_dx); 2134 2135 { 2136 al_fixed uu = al_ftofix(u); 2137 al_fixed vv = al_ftofix(v); 2138 const int uu_ofs = offset_x - texture->lock_x; 2139 const int vv_ofs = offset_y - texture->lock_y; 2140 const al_fixed w = al_ftofix(s->w); 2141 const al_fixed h = al_ftofix(s->h); 2142 2143 for (; x1 <= x2; x1++) { 2144 const int src_x = (uu >> 16) + uu_ofs; 2145 const int src_y = (vv >> 16) + vv_ofs; 2146 uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; 2147 2148 ALLEGRO_COLOR src_color; 2149 _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, src_data, src_color, false); 2150 2151 SHADE_COLORS(src_color, cur_color); 2152 2153 { 2154 ALLEGRO_COLOR dst_color; 2155 ALLEGRO_COLOR result; 2156 _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, dst_color, false); 2157 _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, NULL, &result); 2158 _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, result, true); 2159 } 2160 2161 uu += du_dx; 2162 vv += dv_dx; 2163 2164 if (_AL_EXPECT_FAIL(uu < 0)) 2165 uu += w; 2166 else if (_AL_EXPECT_FAIL(uu >= w)) 2167 uu -= w; 2168 2169 if (_AL_EXPECT_FAIL(vv < 0)) 2170 vv += h; 2171 else if (_AL_EXPECT_FAIL(vv >= h)) 2172 vv -= h; 2173 2174 cur_color.r += gs->color_dx.r; 2175 cur_color.g += gs->color_dx.g; 2176 cur_color.b += gs->color_dx.b; 2177 cur_color.a += gs->color_dx.a; 2178 2179 } 2180 } 2181 } else { 2182 uint8_t *lock_data = texture->locked_region.data; 2183 const int src_pitch = texture->locked_region.pitch; 2184 const al_fixed du_dx = al_ftofix(s->du_dx); 2185 const al_fixed dv_dx = al_ftofix(s->dv_dx); 2186 2187 { 2188 al_fixed uu = al_ftofix(u); 2189 al_fixed vv = al_ftofix(v); 2190 const int uu_ofs = offset_x - texture->lock_x; 2191 const int vv_ofs = offset_y - texture->lock_y; 2192 const al_fixed w = al_ftofix(s->w); 2193 const al_fixed h = al_ftofix(s->h); 2194 2195 for (; x1 <= x2; x1++) { 2196 const int src_x = (uu >> 16) + uu_ofs; 2197 const int src_y = (vv >> 16) + vv_ofs; 2198 uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; 2199 2200 ALLEGRO_COLOR src_color; 2201 _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); 2202 2203 SHADE_COLORS(src_color, cur_color); 2204 2205 { 2206 ALLEGRO_COLOR dst_color; 2207 ALLEGRO_COLOR result; 2208 _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); 2209 _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, NULL, &result); 2210 _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); 2211 } 2212 2213 uu += du_dx; 2214 vv += dv_dx; 2215 2216 if (_AL_EXPECT_FAIL(uu < 0)) 2217 uu += w; 2218 else if (_AL_EXPECT_FAIL(uu >= w)) 2219 uu -= w; 2220 2221 if (_AL_EXPECT_FAIL(vv < 0)) 2222 vv += h; 2223 else if (_AL_EXPECT_FAIL(vv >= h)) 2224 vv -= h; 2225 2226 cur_color.r += gs->color_dx.r; 2227 cur_color.g += gs->color_dx.g; 2228 cur_color.b += gs->color_dx.b; 2229 cur_color.a += gs->color_dx.a; 2230 2231 } 2232 } 2233 } 2234 } else if (op == ALLEGRO_ADD && src_mode == ALLEGRO_ONE && src_alpha == ALLEGRO_ONE && op_alpha == ALLEGRO_ADD && dst_mode == ALLEGRO_ONE && dst_alpha == ALLEGRO_ONE) { 2235 2236 if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888 && src_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { 2237 uint8_t *lock_data = texture->locked_region.data; 2238 const int src_pitch = texture->locked_region.pitch; 2239 const al_fixed du_dx = al_ftofix(s->du_dx); 2240 const al_fixed dv_dx = al_ftofix(s->dv_dx); 2241 2242 { 2243 al_fixed uu = al_ftofix(u); 2244 al_fixed vv = al_ftofix(v); 2245 const int uu_ofs = offset_x - texture->lock_x; 2246 const int vv_ofs = offset_y - texture->lock_y; 2247 const al_fixed w = al_ftofix(s->w); 2248 const al_fixed h = al_ftofix(s->h); 2249 2250 for (; x1 <= x2; x1++) { 2251 const int src_x = (uu >> 16) + uu_ofs; 2252 const int src_y = (vv >> 16) + vv_ofs; 2253 uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; 2254 2255 ALLEGRO_COLOR src_color; 2256 _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, src_data, src_color, false); 2257 2258 SHADE_COLORS(src_color, cur_color); 2259 2260 { 2261 ALLEGRO_COLOR dst_color; 2262 ALLEGRO_COLOR result; 2263 _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, dst_color, false); 2264 _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, NULL, &result); 2265 _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, result, true); 2266 } 2267 2268 uu += du_dx; 2269 vv += dv_dx; 2270 2271 if (_AL_EXPECT_FAIL(uu < 0)) 2272 uu += w; 2273 else if (_AL_EXPECT_FAIL(uu >= w)) 2274 uu -= w; 2275 2276 if (_AL_EXPECT_FAIL(vv < 0)) 2277 vv += h; 2278 else if (_AL_EXPECT_FAIL(vv >= h)) 2279 vv -= h; 2280 2281 cur_color.r += gs->color_dx.r; 2282 cur_color.g += gs->color_dx.g; 2283 cur_color.b += gs->color_dx.b; 2284 cur_color.a += gs->color_dx.a; 2285 2286 } 2287 } 2288 } else { 2289 uint8_t *lock_data = texture->locked_region.data; 2290 const int src_pitch = texture->locked_region.pitch; 2291 const al_fixed du_dx = al_ftofix(s->du_dx); 2292 const al_fixed dv_dx = al_ftofix(s->dv_dx); 2293 2294 { 2295 al_fixed uu = al_ftofix(u); 2296 al_fixed vv = al_ftofix(v); 2297 const int uu_ofs = offset_x - texture->lock_x; 2298 const int vv_ofs = offset_y - texture->lock_y; 2299 const al_fixed w = al_ftofix(s->w); 2300 const al_fixed h = al_ftofix(s->h); 2301 2302 for (; x1 <= x2; x1++) { 2303 const int src_x = (uu >> 16) + uu_ofs; 2304 const int src_y = (vv >> 16) + vv_ofs; 2305 uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; 2306 2307 ALLEGRO_COLOR src_color; 2308 _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); 2309 2310 SHADE_COLORS(src_color, cur_color); 2311 2312 { 2313 ALLEGRO_COLOR dst_color; 2314 ALLEGRO_COLOR result; 2315 _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); 2316 _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, NULL, &result); 2317 _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); 2318 } 2319 2320 uu += du_dx; 2321 vv += dv_dx; 2322 2323 if (_AL_EXPECT_FAIL(uu < 0)) 2324 uu += w; 2325 else if (_AL_EXPECT_FAIL(uu >= w)) 2326 uu -= w; 2327 2328 if (_AL_EXPECT_FAIL(vv < 0)) 2329 vv += h; 2330 else if (_AL_EXPECT_FAIL(vv >= h)) 2331 vv -= h; 2332 2333 cur_color.r += gs->color_dx.r; 2334 cur_color.g += gs->color_dx.g; 2335 cur_color.b += gs->color_dx.b; 2336 cur_color.a += gs->color_dx.a; 2337 2338 } 2339 } 2340 } 2341 } else if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888 && src_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { 2342 uint8_t *lock_data = texture->locked_region.data; 2343 const int src_pitch = texture->locked_region.pitch; 2344 const al_fixed du_dx = al_ftofix(s->du_dx); 2345 const al_fixed dv_dx = al_ftofix(s->dv_dx); 2346 2347 { 2348 al_fixed uu = al_ftofix(u); 2349 al_fixed vv = al_ftofix(v); 2350 const int uu_ofs = offset_x - texture->lock_x; 2351 const int vv_ofs = offset_y - texture->lock_y; 2352 const al_fixed w = al_ftofix(s->w); 2353 const al_fixed h = al_ftofix(s->h); 2354 2355 for (; x1 <= x2; x1++) { 2356 const int src_x = (uu >> 16) + uu_ofs; 2357 const int src_y = (vv >> 16) + vv_ofs; 2358 uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; 2359 2360 ALLEGRO_COLOR src_color; 2361 _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, src_data, src_color, false); 2362 2363 SHADE_COLORS(src_color, cur_color); 2364 2365 { 2366 ALLEGRO_COLOR dst_color; 2367 ALLEGRO_COLOR result; 2368 _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, dst_color, false); 2369 _al_blend_inline(&src_color, &dst_color, op, src_mode, dst_mode, op_alpha, src_alpha, dst_alpha, &const_color, &result); 2370 _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, result, true); 2371 } 2372 2373 uu += du_dx; 2374 vv += dv_dx; 2375 2376 if (_AL_EXPECT_FAIL(uu < 0)) 2377 uu += w; 2378 else if (_AL_EXPECT_FAIL(uu >= w)) 2379 uu -= w; 2380 2381 if (_AL_EXPECT_FAIL(vv < 0)) 2382 vv += h; 2383 else if (_AL_EXPECT_FAIL(vv >= h)) 2384 vv -= h; 2385 2386 cur_color.r += gs->color_dx.r; 2387 cur_color.g += gs->color_dx.g; 2388 cur_color.b += gs->color_dx.b; 2389 cur_color.a += gs->color_dx.a; 2390 2391 } 2392 } 2393 } else { 2394 uint8_t *lock_data = texture->locked_region.data; 2395 const int src_pitch = texture->locked_region.pitch; 2396 const al_fixed du_dx = al_ftofix(s->du_dx); 2397 const al_fixed dv_dx = al_ftofix(s->dv_dx); 2398 2399 { 2400 al_fixed uu = al_ftofix(u); 2401 al_fixed vv = al_ftofix(v); 2402 const int uu_ofs = offset_x - texture->lock_x; 2403 const int vv_ofs = offset_y - texture->lock_y; 2404 const al_fixed w = al_ftofix(s->w); 2405 const al_fixed h = al_ftofix(s->h); 2406 2407 for (; x1 <= x2; x1++) { 2408 const int src_x = (uu >> 16) + uu_ofs; 2409 const int src_y = (vv >> 16) + vv_ofs; 2410 uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; 2411 2412 ALLEGRO_COLOR src_color; 2413 _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); 2414 2415 SHADE_COLORS(src_color, cur_color); 2416 2417 { 2418 ALLEGRO_COLOR dst_color; 2419 ALLEGRO_COLOR result; 2420 _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); 2421 _al_blend_inline(&src_color, &dst_color, op, src_mode, dst_mode, op_alpha, src_alpha, dst_alpha, &const_color, &result); 2422 _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); 2423 } 2424 2425 uu += du_dx; 2426 vv += dv_dx; 2427 2428 if (_AL_EXPECT_FAIL(uu < 0)) 2429 uu += w; 2430 else if (_AL_EXPECT_FAIL(uu >= w)) 2431 uu -= w; 2432 2433 if (_AL_EXPECT_FAIL(vv < 0)) 2434 vv += h; 2435 else if (_AL_EXPECT_FAIL(vv >= h)) 2436 vv -= h; 2437 2438 cur_color.r += gs->color_dx.r; 2439 cur_color.g += gs->color_dx.g; 2440 cur_color.b += gs->color_dx.b; 2441 cur_color.a += gs->color_dx.a; 2442 2443 } 2444 } 2445 } 2446 } 2447 } 2448 } 2449} 2450 2451static void shader_texture_grad_any_draw_opaque(uintptr_t state, int x1, int y, int x2) 2452{ 2453 state_texture_grad_any_2d *gs = (state_texture_grad_any_2d *) state; 2454 state_texture_solid_any_2d *s = &gs->solid; 2455 ALLEGRO_COLOR cur_color = s->cur_color; 2456 2457 float u = s->u; 2458 float v = s->v; 2459 2460 ALLEGRO_BITMAP *target = s->target; 2461 2462 if (target->parent) { 2463 x1 += target->xofs; 2464 x2 += target->xofs; 2465 y += target->yofs; 2466 target = target->parent; 2467 } 2468 2469 x1 -= target->lock_x; 2470 x2 -= target->lock_x; 2471 y -= target->lock_y; 2472 y--; 2473 2474 if (y < 0 || y >= target->lock_h) { 2475 return; 2476 } 2477 2478 if (x1 < 0) { 2479 2480 u += s->du_dx * -x1; 2481 v += s->dv_dx * -x1; 2482 2483 cur_color.r += gs->color_dx.r * -x1; 2484 cur_color.g += gs->color_dx.g * -x1; 2485 cur_color.b += gs->color_dx.b * -x1; 2486 cur_color.a += gs->color_dx.a * -x1; 2487 2488 x1 = 0; 2489 } 2490 2491 if (x2 > target->lock_w - 1) { 2492 x2 = target->lock_w - 1; 2493 } 2494 2495 { 2496 { 2497 const int offset_x = s->texture->parent ? s->texture->xofs : 0; 2498 const int offset_y = s->texture->parent ? s->texture->yofs : 0; 2499 ALLEGRO_BITMAP *texture = s->texture->parent ? s->texture->parent : s->texture; 2500 const int src_format = texture->locked_region.format; 2501 const int src_size = texture->locked_region.pixel_size; 2502 2503 /* Ensure u in [0, s->w) and v in [0, s->h). */ 2504 while (u < 0) 2505 u += s->w; 2506 while (v < 0) 2507 v += s->h; 2508 u = fmodf(u, s->w); 2509 v = fmodf(v, s->h); 2510 ASSERT(0 <= u); 2511 ASSERT(u < s->w); 2512 ASSERT(0 <= v); 2513 ASSERT(v < s->h); 2514 2515 { 2516 const int dst_format = target->locked_region.format; 2517 uint8_t *dst_data = (uint8_t *) target->lock_data + y * target->locked_region.pitch + x1 * target->locked_region.pixel_size; 2518 2519 if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888 && src_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { 2520 uint8_t *lock_data = texture->locked_region.data; 2521 const int src_pitch = texture->locked_region.pitch; 2522 const al_fixed du_dx = al_ftofix(s->du_dx); 2523 const al_fixed dv_dx = al_ftofix(s->dv_dx); 2524 2525 const float steps = x2 - x1 + 1; 2526 const float end_u = u + steps * s->du_dx; 2527 const float end_v = v + steps * s->dv_dx; 2528 if (end_u >= 0 && end_u < s->w && end_v >= 0 && end_v < s->h) { 2529 2530 { 2531 al_fixed uu = al_ftofix(u) + ((offset_x - texture->lock_x) << 16); 2532 al_fixed vv = al_ftofix(v) + ((offset_y - texture->lock_y) << 16); 2533 2534 for (; x1 <= x2; x1++) { 2535 const int src_x = (uu >> 16) + 0; 2536 const int src_y = (vv >> 16) + 0; 2537 uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; 2538 2539 ALLEGRO_COLOR src_color; 2540 _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, src_data, src_color, false); 2541 2542 SHADE_COLORS(src_color, cur_color); 2543 2544 _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, src_color, true); 2545 2546 uu += du_dx; 2547 vv += dv_dx; 2548 2549 cur_color.r += gs->color_dx.r; 2550 cur_color.g += gs->color_dx.g; 2551 cur_color.b += gs->color_dx.b; 2552 cur_color.a += gs->color_dx.a; 2553 2554 } 2555 } 2556 } else { 2557 al_fixed uu = al_ftofix(u); 2558 al_fixed vv = al_ftofix(v); 2559 const int uu_ofs = offset_x - texture->lock_x; 2560 const int vv_ofs = offset_y - texture->lock_y; 2561 const al_fixed w = al_ftofix(s->w); 2562 const al_fixed h = al_ftofix(s->h); 2563 2564 for (; x1 <= x2; x1++) { 2565 const int src_x = (uu >> 16) + uu_ofs; 2566 const int src_y = (vv >> 16) + vv_ofs; 2567 uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; 2568 2569 ALLEGRO_COLOR src_color; 2570 _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, src_data, src_color, false); 2571 2572 SHADE_COLORS(src_color, cur_color); 2573 2574 _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, src_color, true); 2575 2576 uu += du_dx; 2577 vv += dv_dx; 2578 2579 if (_AL_EXPECT_FAIL(uu < 0)) 2580 uu += w; 2581 else if (_AL_EXPECT_FAIL(uu >= w)) 2582 uu -= w; 2583 2584 if (_AL_EXPECT_FAIL(vv < 0)) 2585 vv += h; 2586 else if (_AL_EXPECT_FAIL(vv >= h)) 2587 vv -= h; 2588 2589 cur_color.r += gs->color_dx.r; 2590 cur_color.g += gs->color_dx.g; 2591 cur_color.b += gs->color_dx.b; 2592 cur_color.a += gs->color_dx.a; 2593 2594 } 2595 } 2596 } else { 2597 uint8_t *lock_data = texture->locked_region.data; 2598 const int src_pitch = texture->locked_region.pitch; 2599 const al_fixed du_dx = al_ftofix(s->du_dx); 2600 const al_fixed dv_dx = al_ftofix(s->dv_dx); 2601 2602 const float steps = x2 - x1 + 1; 2603 const float end_u = u + steps * s->du_dx; 2604 const float end_v = v + steps * s->dv_dx; 2605 if (end_u >= 0 && end_u < s->w && end_v >= 0 && end_v < s->h) { 2606 2607 { 2608 al_fixed uu = al_ftofix(u) + ((offset_x - texture->lock_x) << 16); 2609 al_fixed vv = al_ftofix(v) + ((offset_y - texture->lock_y) << 16); 2610 2611 for (; x1 <= x2; x1++) { 2612 const int src_x = (uu >> 16) + 0; 2613 const int src_y = (vv >> 16) + 0; 2614 uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; 2615 2616 ALLEGRO_COLOR src_color; 2617 _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); 2618 2619 SHADE_COLORS(src_color, cur_color); 2620 2621 _AL_INLINE_PUT_PIXEL(dst_format, dst_data, src_color, true); 2622 2623 uu += du_dx; 2624 vv += dv_dx; 2625 2626 cur_color.r += gs->color_dx.r; 2627 cur_color.g += gs->color_dx.g; 2628 cur_color.b += gs->color_dx.b; 2629 cur_color.a += gs->color_dx.a; 2630 2631 } 2632 } 2633 } else { 2634 al_fixed uu = al_ftofix(u); 2635 al_fixed vv = al_ftofix(v); 2636 const int uu_ofs = offset_x - texture->lock_x; 2637 const int vv_ofs = offset_y - texture->lock_y; 2638 const al_fixed w = al_ftofix(s->w); 2639 const al_fixed h = al_ftofix(s->h); 2640 2641 for (; x1 <= x2; x1++) { 2642 const int src_x = (uu >> 16) + uu_ofs; 2643 const int src_y = (vv >> 16) + vv_ofs; 2644 uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; 2645 2646 ALLEGRO_COLOR src_color; 2647 _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); 2648 2649 SHADE_COLORS(src_color, cur_color); 2650 2651 _AL_INLINE_PUT_PIXEL(dst_format, dst_data, src_color, true); 2652 2653 uu += du_dx; 2654 vv += dv_dx; 2655 2656 if (_AL_EXPECT_FAIL(uu < 0)) 2657 uu += w; 2658 else if (_AL_EXPECT_FAIL(uu >= w)) 2659 uu -= w; 2660 2661 if (_AL_EXPECT_FAIL(vv < 0)) 2662 vv += h; 2663 else if (_AL_EXPECT_FAIL(vv >= h)) 2664 vv -= h; 2665 2666 cur_color.r += gs->color_dx.r; 2667 cur_color.g += gs->color_dx.g; 2668 cur_color.b += gs->color_dx.b; 2669 cur_color.a += gs->color_dx.a; 2670 2671 } 2672 } 2673 } 2674 } 2675 } 2676 } 2677} 2678