1 /* ______ ___ ___
2 * /\ _ \ /\_ \ /\_ \
3 * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
4 * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
5 * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
6 * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
7 * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
8 * /\____/
9 * \_/__/
10 *
11 * Polygon scanline filler helpers (gouraud shading, tmapping, etc).
12 *
13 * By Michael Bukin.
14 *
15 * Scanline subdivision in *_PTEX functions and transparency modes
16 * added by Bertrand Coconnier.
17 *
18 * See readme.txt for copyright information.
19 */
20
21 #ifndef __bma_cscan_h
22 #define __bma_cscan_h
23
24 #ifdef _bma_scan_gcol
25
26 /* _poly_scanline_gcol:
27 * Fills a single-color gouraud shaded polygon scanline.
28 */
FUNC_POLY_SCANLINE_GCOL(uintptr_t addr,int w,POLYGON_SEGMENT * info)29 void FUNC_POLY_SCANLINE_GCOL(uintptr_t addr, int w, POLYGON_SEGMENT *info)
30 {
31 int x;
32 fixed c, dc;
33 PIXEL_PTR d;
34
35 ASSERT(addr);
36 ASSERT(info);
37
38 c = info->c;
39 dc = info->dc;
40 d = (PIXEL_PTR) addr;
41
42 for (x = w - 1; x >= 0; INC_PIXEL_PTR(d), x--) {
43 PUT_PIXEL(d, (c >> 16));
44 c += dc;
45 }
46 }
47
48 #endif /* _bma_scan_gcol */
49
50
51
52 /* _poly_scanline_grgb:
53 * Fills an gouraud shaded polygon scanline.
54 */
FUNC_POLY_SCANLINE_GRGB(uintptr_t addr,int w,POLYGON_SEGMENT * info)55 void FUNC_POLY_SCANLINE_GRGB(uintptr_t addr, int w, POLYGON_SEGMENT *info)
56 {
57 int x;
58 fixed r, g, b;
59 fixed dr, dg, db;
60 PIXEL_PTR d;
61
62 ASSERT(addr);
63 ASSERT(info);
64
65 r = info->r;
66 g = info->g;
67 b = info->b;
68 dr = info->dr;
69 dg = info->dg;
70 db = info->db;
71 d = (PIXEL_PTR) addr;
72
73 for (x = w - 1; x >= 0; INC_PIXEL_PTR(d), x--) {
74 PUT_RGB(d, (r >> 16), (g >> 16), (b >> 16));
75 r += dr;
76 g += dg;
77 b += db;
78 }
79 }
80
81
82
83 /* _poly_scanline_atex:
84 * Fills an affine texture mapped polygon scanline.
85 */
FUNC_POLY_SCANLINE_ATEX(uintptr_t addr,int w,POLYGON_SEGMENT * info)86 void FUNC_POLY_SCANLINE_ATEX(uintptr_t addr, int w, POLYGON_SEGMENT *info)
87 {
88 int x;
89 int vmask, vshift, umask;
90 fixed u, v, du, dv;
91 PIXEL_PTR texture;
92 PIXEL_PTR d;
93
94 ASSERT(addr);
95 ASSERT(info);
96
97 vmask = info->vmask << info->vshift;
98 vshift = 16 - info->vshift;
99 umask = info->umask;
100 u = info->u;
101 v = info->v;
102 du = info->du;
103 dv = info->dv;
104 texture = (PIXEL_PTR) (info->texture);
105 d = (PIXEL_PTR) addr;
106
107 for (x = w - 1; x >= 0; INC_PIXEL_PTR(d), x--) {
108 PIXEL_PTR s = OFFSET_PIXEL_PTR(texture, ((v >> vshift) & vmask) + ((u >> 16) & umask));
109 unsigned long color = GET_MEMORY_PIXEL(s);
110
111 PUT_PIXEL(d, color);
112 u += du;
113 v += dv;
114 }
115 }
116
117
118
119 /* _poly_scanline_atex_mask:
120 * Fills a masked affine texture mapped polygon scanline.
121 */
FUNC_POLY_SCANLINE_ATEX_MASK(uintptr_t addr,int w,POLYGON_SEGMENT * info)122 void FUNC_POLY_SCANLINE_ATEX_MASK(uintptr_t addr, int w, POLYGON_SEGMENT *info)
123 {
124 int x;
125 int vmask, vshift, umask;
126 fixed u, v, du, dv;
127 PIXEL_PTR texture;
128 PIXEL_PTR d;
129
130 ASSERT(addr);
131 ASSERT(info);
132
133 vmask = info->vmask << info->vshift;
134 vshift = 16 - info->vshift;
135 umask = info->umask;
136 u = info->u;
137 v = info->v;
138 du = info->du;
139 dv = info->dv;
140 texture = (PIXEL_PTR) (info->texture);
141 d = (PIXEL_PTR) addr;
142
143 for (x = w - 1; x >= 0; INC_PIXEL_PTR(d), x--) {
144 PIXEL_PTR s = OFFSET_PIXEL_PTR(texture, ((v >> vshift) & vmask) + ((u >> 16) & umask));
145 unsigned long color = GET_MEMORY_PIXEL(s);
146
147 if (!IS_MASK(color)) {
148 PUT_PIXEL(d, color);
149 }
150 u += du;
151 v += dv;
152 }
153 }
154
155
156
157 /* _poly_scanline_atex_lit:
158 * Fills a lit affine texture mapped polygon scanline.
159 */
FUNC_POLY_SCANLINE_ATEX_LIT(uintptr_t addr,int w,POLYGON_SEGMENT * info)160 void FUNC_POLY_SCANLINE_ATEX_LIT(uintptr_t addr, int w, POLYGON_SEGMENT *info)
161 {
162 int x;
163 int vmask, vshift, umask;
164 fixed u, v, c, du, dv, dc;
165 PS_BLENDER blender;
166 PIXEL_PTR texture;
167 PIXEL_PTR d;
168
169 ASSERT(addr);
170 ASSERT(info);
171
172 vmask = info->vmask << info->vshift;
173 vshift = 16 - info->vshift;
174 umask = info->umask;
175 u = info->u;
176 v = info->v;
177 c = info->c;
178 du = info->du;
179 dv = info->dv;
180 dc = info->dc;
181 blender = MAKE_PS_BLENDER();
182 texture = (PIXEL_PTR) (info->texture);
183 d = (PIXEL_PTR) addr;
184
185 for (x = w - 1; x >= 0; INC_PIXEL_PTR(d), x--) {
186 PIXEL_PTR s = OFFSET_PIXEL_PTR(texture, ((v >> vshift) & vmask) + ((u >> 16) & umask));
187 unsigned long color = GET_MEMORY_PIXEL(s);
188 color = PS_BLEND(blender, (c >> 16), color);
189
190 PUT_PIXEL(d, color);
191 u += du;
192 v += dv;
193 c += dc;
194 }
195 }
196
197
198
199 /* _poly_scanline_atex_mask_lit:
200 * Fills a masked lit affine texture mapped polygon scanline.
201 */
FUNC_POLY_SCANLINE_ATEX_MASK_LIT(uintptr_t addr,int w,POLYGON_SEGMENT * info)202 void FUNC_POLY_SCANLINE_ATEX_MASK_LIT(uintptr_t addr, int w, POLYGON_SEGMENT *info)
203 {
204 int x;
205 int vmask, vshift, umask;
206 fixed u, v, c, du, dv, dc;
207 PS_BLENDER blender;
208 PIXEL_PTR texture;
209 PIXEL_PTR d;
210
211 ASSERT(addr);
212 ASSERT(info);
213
214 vmask = info->vmask << info->vshift;
215 vshift = 16 - info->vshift;
216 umask = info->umask;
217 u = info->u;
218 v = info->v;
219 c = info->c;
220 du = info->du;
221 dv = info->dv;
222 dc = info->dc;
223 blender = MAKE_PS_BLENDER();
224 texture = (PIXEL_PTR) (info->texture);
225 d = (PIXEL_PTR) addr;
226
227 for (x = w - 1; x >= 0; INC_PIXEL_PTR(d), x--) {
228 PIXEL_PTR s = OFFSET_PIXEL_PTR(texture, ((v >> vshift) & vmask) + ((u >> 16) & umask));
229 unsigned long color = GET_MEMORY_PIXEL(s);
230
231 if (!IS_MASK(color)) {
232 color = PS_BLEND(blender, (c >> 16), color);
233 PUT_PIXEL(d, color);
234 }
235 u += du;
236 v += dv;
237 c += dc;
238 }
239 }
240
241
242
243 /* _poly_scanline_ptex:
244 * Fills a perspective correct texture mapped polygon scanline.
245 */
FUNC_POLY_SCANLINE_PTEX(uintptr_t addr,int w,POLYGON_SEGMENT * info)246 void FUNC_POLY_SCANLINE_PTEX(uintptr_t addr, int w, POLYGON_SEGMENT *info)
247 {
248 int x, i, imax = 3;
249 int vmask, vshift, umask;
250 double fu, fv, fz, dfu, dfv, dfz, z1;
251 PIXEL_PTR texture;
252 PIXEL_PTR d;
253 int64_t u, v;
254
255 ASSERT(addr);
256 ASSERT(info);
257
258 vmask = info->vmask << info->vshift;
259 vshift = 16 - info->vshift;
260 umask = info->umask;
261 fu = info->fu;
262 fv = info->fv;
263 fz = info->z;
264 dfu = info->dfu * 4;
265 dfv = info->dfv * 4;
266 dfz = info->dz * 4;
267 z1 = 1. / fz;
268 texture = (PIXEL_PTR) (info->texture);
269 d = (PIXEL_PTR) addr;
270 u = fu * z1;
271 v = fv * z1;
272
273 /* update depth */
274 fz += dfz;
275 z1 = 1. / fz;
276
277 for (x = w - 1; x >= 0; x -= 4) {
278 int64_t nextu, nextv, du, dv;
279 PIXEL_PTR s;
280 unsigned long color;
281
282 fu += dfu;
283 fv += dfv;
284 fz += dfz;
285 nextu = fu * z1;
286 nextv = fv * z1;
287 z1 = 1. / fz;
288 du = (nextu - u) >> 2;
289 dv = (nextv - v) >> 2;
290
291 /* scanline subdivision */
292 if (x < 3)
293 imax = x;
294 for (i = imax; i >= 0; i--, INC_PIXEL_PTR(d)) {
295 s = OFFSET_PIXEL_PTR(texture, ((v >> vshift) & vmask) + ((u >> 16) & umask));
296 color = GET_MEMORY_PIXEL(s);
297
298 PUT_PIXEL(d, color);
299 u += du;
300 v += dv;
301 }
302 }
303 }
304
305
306
307 /* _poly_scanline_ptex_mask:
308 * Fills a masked perspective correct texture mapped polygon scanline.
309 */
FUNC_POLY_SCANLINE_PTEX_MASK(uintptr_t addr,int w,POLYGON_SEGMENT * info)310 void FUNC_POLY_SCANLINE_PTEX_MASK(uintptr_t addr, int w, POLYGON_SEGMENT *info)
311 {
312 int x, i, imax = 3;
313 int vmask, vshift, umask;
314 double fu, fv, fz, dfu, dfv, dfz, z1;
315 PIXEL_PTR texture;
316 PIXEL_PTR d;
317 int64_t u, v;
318
319 ASSERT(addr);
320 ASSERT(info);
321
322 vmask = info->vmask << info->vshift;
323 vshift = 16 - info->vshift;
324 umask = info->umask;
325 fu = info->fu;
326 fv = info->fv;
327 fz = info->z;
328 dfu = info->dfu * 4;
329 dfv = info->dfv * 4;
330 dfz = info->dz * 4;
331 z1 = 1. / fz;
332 texture = (PIXEL_PTR) (info->texture);
333 d = (PIXEL_PTR) addr;
334 u = fu * z1;
335 v = fv * z1;
336
337 /* update depth */
338 fz += dfz;
339 z1 = 1. / fz;
340
341 for (x = w - 1; x >= 0; x-= 4) {
342 int64_t nextu, nextv, du, dv;
343 PIXEL_PTR s;
344 unsigned long color;
345
346 fu += dfu;
347 fv += dfv;
348 fz += dfz;
349 nextu = fu * z1;
350 nextv = fv * z1;
351 z1 = 1. / fz;
352 du = (nextu - u) >> 2;
353 dv = (nextv - v) >> 2;
354
355 /* scanline subdivision */
356 if (x < 3)
357 imax = x;
358 for (i = imax; i >= 0; i--, INC_PIXEL_PTR(d)) {
359 s = OFFSET_PIXEL_PTR(texture, ((v >> vshift) & vmask) + ((u >> 16) & umask));
360 color = GET_MEMORY_PIXEL(s);
361
362 if (!IS_MASK(color)) {
363 PUT_PIXEL(d, color);
364 }
365 u += du;
366 v += dv;
367 }
368 }
369 }
370
371
372
373 /* _poly_scanline_ptex_lit:
374 * Fills a lit perspective correct texture mapped polygon scanline.
375 */
FUNC_POLY_SCANLINE_PTEX_LIT(uintptr_t addr,int w,POLYGON_SEGMENT * info)376 void FUNC_POLY_SCANLINE_PTEX_LIT(uintptr_t addr, int w, POLYGON_SEGMENT *info)
377 {
378 int x, i, imax = 3;
379 int vmask, vshift, umask;
380 fixed c, dc;
381 double fu, fv, fz, dfu, dfv, dfz, z1;
382 PS_BLENDER blender;
383 PIXEL_PTR texture;
384 PIXEL_PTR d;
385 int64_t u, v;
386
387 ASSERT(addr);
388 ASSERT(info);
389
390 vmask = info->vmask << info->vshift;
391 vshift = 16 - info->vshift;
392 umask = info->umask;
393 c = info->c;
394 dc = info->dc;
395 fu = info->fu;
396 fv = info->fv;
397 fz = info->z;
398 dfu = info->dfu * 4;
399 dfv = info->dfv * 4;
400 dfz = info->dz * 4;
401 z1 = 1. / fz;
402 blender = MAKE_PS_BLENDER();
403 texture = (PIXEL_PTR) (info->texture);
404 d = (PIXEL_PTR) addr;
405 u = fu * z1;
406 v = fv * z1;
407
408 /* update depth */
409 fz += dfz;
410 z1 = 1. / fz;
411
412 for (x = w - 1; x >= 0; x-= 4) {
413 int64_t nextu, nextv, du, dv;
414
415 fu += dfu;
416 fv += dfv;
417 fz += dfz;
418 nextu = fu * z1;
419 nextv = fv * z1;
420 z1 = 1. / fz;
421 du = (nextu - u) >> 2;
422 dv = (nextv - v) >> 2;
423
424 /* scanline subdivision */
425 if (x < 3)
426 imax = x;
427 for (i = imax; i >= 0; i--, INC_PIXEL_PTR(d)) {
428 PIXEL_PTR s = OFFSET_PIXEL_PTR(texture, ((v >> vshift) & vmask) + ((u >> 16) & umask));
429 unsigned long color = GET_MEMORY_PIXEL(s);
430 color = PS_BLEND(blender, (c >> 16), color);
431
432 PUT_PIXEL(d, color);
433 u += du;
434 v += dv;
435 c += dc;
436 }
437 }
438 }
439
440
441
442 /* _poly_scanline_ptex_mask_lit:
443 * Fills a masked lit perspective correct texture mapped polygon scanline.
444 */
FUNC_POLY_SCANLINE_PTEX_MASK_LIT(uintptr_t addr,int w,POLYGON_SEGMENT * info)445 void FUNC_POLY_SCANLINE_PTEX_MASK_LIT(uintptr_t addr, int w, POLYGON_SEGMENT *info)
446 {
447 int x, i, imax = 3;
448 int vmask, vshift, umask;
449 fixed c, dc;
450 double fu, fv, fz, dfu, dfv, dfz, z1;
451 PS_BLENDER blender;
452 PIXEL_PTR texture;
453 PIXEL_PTR d;
454 int64_t u, v;
455
456 ASSERT(addr);
457 ASSERT(info);
458
459 vmask = info->vmask << info->vshift;
460 vshift = 16 - info->vshift;
461 umask = info->umask;
462 c = info->c;
463 dc = info->dc;
464 fu = info->fu;
465 fv = info->fv;
466 fz = info->z;
467 dfu = info->dfu * 4;
468 dfv = info->dfv * 4;
469 dfz = info->dz * 4;
470 z1 = 1. / fz;
471 blender = MAKE_PS_BLENDER();
472 texture = (PIXEL_PTR) (info->texture);
473 d = (PIXEL_PTR) addr;
474 u = fu * z1;
475 v = fv * z1;
476
477 /* update depth */
478 fz += dfz;
479 z1 = 1. / fz;
480
481 for (x = w - 1; x >= 0; x-= 4) {
482 int64_t nextu, nextv, du, dv;
483
484 fu += dfu;
485 fv += dfv;
486 fz += dfz;
487 nextu = fu * z1;
488 nextv = fv * z1;
489 z1 = 1. / fz;
490 du = (nextu - u) >> 2;
491 dv = (nextv - v) >> 2;
492
493 /* scanline subdivision */
494 if (x < 3)
495 imax = x;
496 for (i = imax; i >= 0; i--, INC_PIXEL_PTR(d)) {
497 PIXEL_PTR s = OFFSET_PIXEL_PTR(texture, ((v >> vshift) & vmask) + ((u >> 16) & umask));
498 unsigned long color = GET_MEMORY_PIXEL(s);
499
500 if (!IS_MASK(color)) {
501 color = PS_BLEND(blender, (c >> 16), color);
502 PUT_PIXEL(d, color);
503 }
504 u += du;
505 v += dv;
506 c += dc;
507 }
508 }
509 }
510
511
512
513 /* _poly_scanline_atex_trans:
514 * Fills a trans affine texture mapped polygon scanline.
515 */
FUNC_POLY_SCANLINE_ATEX_TRANS(uintptr_t addr,int w,POLYGON_SEGMENT * info)516 void FUNC_POLY_SCANLINE_ATEX_TRANS(uintptr_t addr, int w, POLYGON_SEGMENT *info)
517 {
518 int x;
519 int vmask, vshift, umask;
520 fixed u, v, du, dv;
521 PIXEL_PTR texture;
522 PIXEL_PTR d;
523 PIXEL_PTR r;
524 PS_BLENDER blender;
525
526 ASSERT(addr);
527 ASSERT(info);
528
529 vmask = info->vmask << info->vshift;
530 vshift = 16 - info->vshift;
531 umask = info->umask;
532 u = info->u;
533 v = info->v;
534 du = info->du;
535 dv = info->dv;
536 blender = MAKE_PS_BLENDER();
537 texture = (PIXEL_PTR) (info->texture);
538 d = (PIXEL_PTR) addr;
539 r = (PIXEL_PTR) info->read_addr;
540
541 for (x = w - 1; x >= 0; INC_PIXEL_PTR(d), INC_PIXEL_PTR(r), x--) {
542 PIXEL_PTR s = OFFSET_PIXEL_PTR(texture, ((v >> vshift) & vmask) + ((u >> 16) & umask));
543 unsigned long color = GET_MEMORY_PIXEL(s);
544 color = PS_ALPHA_BLEND(blender, color, GET_PIXEL(r));
545
546 PUT_PIXEL(d, color);
547 u += du;
548 v += dv;
549 }
550 }
551
552
553
554 /* _poly_scanline_atex_mask_trans:
555 * Fills a trans masked affine texture mapped polygon scanline.
556 */
FUNC_POLY_SCANLINE_ATEX_MASK_TRANS(uintptr_t addr,int w,POLYGON_SEGMENT * info)557 void FUNC_POLY_SCANLINE_ATEX_MASK_TRANS(uintptr_t addr, int w, POLYGON_SEGMENT *info)
558 {
559 int x;
560 int vmask, vshift, umask;
561 fixed u, v, du, dv;
562 PIXEL_PTR texture;
563 PIXEL_PTR d;
564 PIXEL_PTR r;
565 PS_BLENDER blender;
566
567 ASSERT(addr);
568 ASSERT(info);
569
570 vmask = info->vmask << info->vshift;
571 vshift = 16 - info->vshift;
572 umask = info->umask;
573 u = info->u;
574 v = info->v;
575 du = info->du;
576 dv = info->dv;
577 blender = MAKE_PS_BLENDER();
578 texture = (PIXEL_PTR) (info->texture);
579 d = (PIXEL_PTR) addr;
580 r = (PIXEL_PTR) info->read_addr;
581
582 for (x = w - 1; x >= 0; INC_PIXEL_PTR(d), INC_PIXEL_PTR(r), x--) {
583 PIXEL_PTR s = OFFSET_PIXEL_PTR(texture, ((v >> vshift) & vmask) + ((u >> 16) & umask));
584 unsigned long color = GET_MEMORY_PIXEL(s);
585
586 if (!IS_MASK(color)) {
587 color = PS_ALPHA_BLEND(blender, color, GET_PIXEL(r));
588 PUT_PIXEL(d, color);
589 }
590 u += du;
591 v += dv;
592 }
593 }
594
595
596
597 /* _poly_scanline_ptex_trans:
598 * Fills a trans perspective correct texture mapped polygon scanline.
599 */
FUNC_POLY_SCANLINE_PTEX_TRANS(uintptr_t addr,int w,POLYGON_SEGMENT * info)600 void FUNC_POLY_SCANLINE_PTEX_TRANS(uintptr_t addr, int w, POLYGON_SEGMENT *info)
601 {
602 int x, i, imax = 3;
603 int vmask, vshift, umask;
604 double fu, fv, fz, dfu, dfv, dfz, z1;
605 PS_BLENDER blender;
606 PIXEL_PTR texture;
607 PIXEL_PTR d;
608 PIXEL_PTR r;
609 int64_t u, v;
610
611 ASSERT(addr);
612 ASSERT(info);
613
614 vmask = info->vmask << info->vshift;
615 vshift = 16 - info->vshift;
616 umask = info->umask;
617 fu = info->fu;
618 fv = info->fv;
619 fz = info->z;
620 dfu = info->dfu * 4;
621 dfv = info->dfv * 4;
622 dfz = info->dz * 4;
623 z1 = 1. / fz;
624 blender = MAKE_PS_BLENDER();
625 texture = (PIXEL_PTR) (info->texture);
626 d = (PIXEL_PTR) addr;
627 r = (PIXEL_PTR) info->read_addr;
628 u = fu * z1;
629 v = fv * z1;
630
631 /* update depth */
632 fz += dfz;
633 z1 = 1. / fz;
634
635 for (x = w - 1; x >= 0; x-= 4) {
636 int64_t nextu, nextv, du, dv;
637
638 fu += dfu;
639 fv += dfv;
640 fz += dfz;
641 nextu = fu * z1;
642 nextv = fv * z1;
643 z1 = 1. / fz;
644 du = (nextu - u) >> 2;
645 dv = (nextv - v) >> 2;
646
647 /* scanline subdivision */
648 if (x < 3)
649 imax = x;
650 for (i = imax; i >= 0; i--, INC_PIXEL_PTR(d), INC_PIXEL_PTR(r)) {
651 PIXEL_PTR s = OFFSET_PIXEL_PTR(texture, ((v >> vshift) & vmask) + ((u >> 16) & umask));
652 unsigned long color = GET_MEMORY_PIXEL(s);
653
654 color = PS_ALPHA_BLEND(blender, color, GET_PIXEL(r));
655 PUT_PIXEL(d, color);
656 u += du;
657 v += dv;
658 }
659 }
660 }
661
662
663
664 /* _poly_scanline_ptex_mask_trans:
665 * Fills a trans masked perspective correct texture mapped polygon scanline.
666 */
FUNC_POLY_SCANLINE_PTEX_MASK_TRANS(uintptr_t addr,int w,POLYGON_SEGMENT * info)667 void FUNC_POLY_SCANLINE_PTEX_MASK_TRANS(uintptr_t addr, int w, POLYGON_SEGMENT *info)
668 {
669 int x, i, imax = 3;
670 int vmask, vshift, umask;
671 double fu, fv, fz, dfu, dfv, dfz, z1;
672 PS_BLENDER blender;
673 PIXEL_PTR texture;
674 PIXEL_PTR d;
675 PIXEL_PTR r;
676 int64_t u, v;
677
678 ASSERT(addr);
679 ASSERT(info);
680
681 vmask = info->vmask << info->vshift;
682 vshift = 16 - info->vshift;
683 umask = info->umask;
684 fu = info->fu;
685 fv = info->fv;
686 fz = info->z;
687 dfu = info->dfu * 4;
688 dfv = info->dfv * 4;
689 dfz = info->dz * 4;
690 z1 = 1. / fz;
691 blender = MAKE_PS_BLENDER();
692 texture = (PIXEL_PTR) (info->texture);
693 d = (PIXEL_PTR) addr;
694 r = (PIXEL_PTR) info->read_addr;
695 u = fu * z1;
696 v = fv * z1;
697
698 /* update depth */
699 fz += dfz;
700 z1 = 1. / fz;
701
702 for (x = w - 1; x >= 0; x-= 4) {
703 int64_t nextu, nextv, du, dv;
704
705 fu += dfu;
706 fv += dfv;
707 fz += dfz;
708 nextu = fu * z1;
709 nextv = fv * z1;
710 z1 = 1. / fz;
711 du = (nextu - u) >> 2;
712 dv = (nextv - v) >> 2;
713
714 /* scanline subdivision */
715 if (x < 3)
716 imax = x;
717 for (i = imax; i >= 0; i--, INC_PIXEL_PTR(d), INC_PIXEL_PTR(r)) {
718 PIXEL_PTR s = OFFSET_PIXEL_PTR(texture, ((v >> vshift) & vmask) + ((u >> 16) & umask));
719 unsigned long color = GET_MEMORY_PIXEL(s);
720
721 if (!IS_MASK(color)) {
722 color = PS_ALPHA_BLEND(blender, color, GET_PIXEL(r));
723 PUT_PIXEL(d, color);
724 }
725 u += du;
726 v += dv;
727 }
728 }
729 }
730
731 #endif /* !__bma_cscan_h */
732
733