1/*         ______   ___    ___
2 *        /\  _  \ /\_ \  /\_ \
3 *        \ \ \L\ \\//\ \ \//\ \      __     __   _ __   ___
4 *         \ \  __ \ \ \ \  \ \ \   /'__`\ /'_ `\/\`'__\/ __`\
5 *          \ \ \/\ \ \_\ \_ \_\ \_/\  __//\ \L\ \ \ \//\ \L\ \
6 *           \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
7 *            \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
8 *                                           /\____/
9 *                                           \_/__/
10 *
11 *      Polygon scanline filler helpers (gouraud shading, tmapping, etc).
12 *      MMX scanline fillers are defined in 'iscanmmx.s'
13 *
14 *      By Calin Andrian.
15 *
16 *      See readme.txt for copyright information.
17 */
18
19
20#include "asmdefs.inc"
21
22
23.text
24
25
26
27/* all these functions share the same parameters */
28
29#define ADDR      ARG1
30#define W         ARG2
31#define INFO      ARG3
32
33
34
35#ifdef ALLEGRO_COLOR8
36/* void _poly_scanline_gcol8(unsigned long addr, int w, POLYGON_SEGMENT *info);
37 *  Fills a single-color gouraud shaded polygon scanline.
38 */
39FUNC(_poly_scanline_gcol8)
40   pushl %ebp
41   movl %esp, %ebp
42   pushl %ebx
43   pushl %esi
44   pushl %edi
45
46   movl INFO, %edi               /* load registers */
47   movl POLYSEG_C(%edi), %eax
48   movl POLYSEG_DC(%edi), %esi
49   movl W, %ecx
50   movl ADDR, %edi
51
52   sarl $8, %eax                 /* convert 16.16 fixed into 8.8 fixed */
53   sarl $8, %esi
54   jge gcol_loop
55   incl %esi
56
57   _align_
58gcol_loop:
59   movb %ah, FSEG(%edi)
60   addl %esi, %eax
61   incl %edi
62   decl %ecx
63   jg gcol_loop
64
65   popl %edi
66   popl %esi
67   popl %ebx
68   movl %ebp, %esp
69   popl %ebp
70   ret                           /* end of _poly_scanline_gcol8() */
71
72
73
74
75/* void _poly_scanline_grgb8(unsigned long addr, int w, POLYGON_SEGMENT *info);
76 *  Fills an RGB gouraud shaded polygon scanline.
77 */
78FUNC(_poly_scanline_grgb8)
79   pushl %ebp
80   movl %esp, %ebp
81   subl $8, %esp                /* two local variables: */
82
83#define DRB    -4(%ebp)
84#define DG     -8(%ebp)
85
86   pushl %ebx
87   pushl %esi
88   pushl %edi
89grgb_entry:
90   movl INFO, %esi               /* load registers */
91
92   movl POLYSEG_DR(%esi), %eax
93   movl POLYSEG_DB(%esi), %ecx
94   sall $8, %eax
95   movl POLYSEG_DG(%esi), %ebx
96
97   sarl $8, %ecx
98   andl $0xffff0000, %eax
99   sarl $8, %ebx
100   addl %ecx, %eax
101
102   movl %ebx, DG
103   movl %eax, DRB
104
105   movl POLYSEG_R(%esi), %eax
106   movl POLYSEG_B(%esi), %ecx
107   sall $8, %eax
108   movl POLYSEG_G(%esi), %ebx
109
110   sarl $8, %ecx
111   andl $0xffff0000, %eax
112   sarl $8, %ebx
113   addl %ecx, %eax
114
115   movl ADDR, %edi
116   decl %edi
117   movl %ebx, %edx			/* green */
118
119   _align_
120grgb_loop:
121   movl %eax, %ecx			/* red and blue */
122   shrl $6, %edx
123   andl $0xf800f800, %ecx
124   addl DRB, %eax
125   shrl $11, %ecx
126   andl $0x3e0, %edx
127   movl %ecx, %esi
128   addl DG, %ebx
129   andl $0xffff, %esi			/* blue */
130   shrl $6, %ecx				/* red */
131   addl %edx, %esi			/* green and blue */
132   addl GLOBL(rgb_map), %ecx
133   movl %ebx, %edx
134
135   movb (%ecx, %esi), %cl
136   movb %cl, FSEG(%edi)          /* write the pixel */
137   incl %edi
138   decl W
139   jg grgb_loop
140
141   popl %edi
142   popl %esi
143   popl %ebx
144   movl %ebp, %esp
145   popl %ebp
146   ret                           /* end of _poly_scanline_grgb8() */
147
148#undef DRB
149#undef DG
150
151#define DU        -4(%ebp)
152#define DVL       -8(%ebp)
153#define DVH       -12(%ebp)
154#define VMASK     -16(%ebp)
155#define TEXTURE   -20(%ebp)
156#define C		-24(%ebp)
157#define DC		-28(%ebp)
158#define TMP		-32(%ebp)
159
160/* helper for setting up an affine texture mapping operation */
161#define INIT_ATEX(extra)						 \
162   pushl %ebp								;\
163   movl %esp, %ebp							;\
164   subl $32, %esp							;\
165   pushl %ebx								;\
166   pushl %esi								;\
167   pushl %edi								;\
168									;\
169   movl INFO, %esi							;\
170   movl POLYSEG_VSHIFT(%esi), %ecx					;\
171   movl POLYSEG_VMASK(%esi), %ebx					;\
172   negl %ecx								;\
173   addl $16, %ecx							;\
174   movl %ebx, VMASK							;\
175   movl POLYSEG_TEXTURE(%esi), %ebx					;\
176   movl %ebx, TEXTURE							;\
177									;\
178   extra								;\
179									;\
180   xorl %edx, %edx							;\
181   movl POLYSEG_DV(%esi), %ebx						;\
182   movl POLYSEG_DU(%esi), %eax						;\
183   shldl $16, %ebx, %edx						;\
184   shll %cl, %eax							;\
185   shll $16, %ebx							;\
186   movl %eax, DU							;\
187   movl %edx, DVH							;\
188   movl %ebx, DVL							;\
189									;\
190   xorl %edx, %edx							;\
191   movl POLYSEG_V(%esi), %ebx						;\
192   movl POLYSEG_U(%esi), %eax						;\
193   shldl $16, %ebx, %edx						;\
194   shll %cl, %eax							;\
195   shll $16, %ebx							;\
196									;\
197   movl ADDR, %edi							;\
198   addl $16, %ecx							;\
199   decl %edi								;\
200									;\
201   andl VMASK, %edx							;\
202   movl %eax, %esi							;\
203   incl %edi								;\
204   shrdl %cl, %edx, %esi						;\
205   addl DU, %eax							;\
206   addl TEXTURE, %esi
207
208
209/* void _poly_scanline_atex8(unsigned long addr, int w, POLYGON_SEGMENT *info);
210 *  Fills an affine texture mapped polygon scanline.
211 */
212FUNC(_poly_scanline_atex8)
213   INIT_ATEX(/**/)
214
215   addl DVL, %ebx
216   adcl DVH, %edx
217
218   movb (%esi), %ch
219   movb %ch, FSEG(%edi)
220   decl W
221   jz atex_done
222
223   _align_
224atex_loop:
225   andl VMASK, %edx
226   movl %eax, %esi
227   incl %edi
228   shrdl %cl, %edx, %esi
229   addl DU, %eax
230   addl TEXTURE, %esi
231   addl DVL, %ebx
232   adcl DVH, %edx
233
234   movb (%esi), %ch
235   movb %ch, FSEG(%edi)
236   decl W
237   jg atex_loop
238
239
240atex_done:
241   popl %edi
242   popl %esi
243   popl %ebx
244   movl %ebp, %esp
245   popl %ebp
246   ret                           /* end of _poly_scanline_atex8() */
247
248
249
250/* void _poly_scanline_atex_mask8(ulong addr, int w, POLYGON_SEGMENT *info);
251 *  Fills a masked affine texture mapped polygon scanline.
252 */
253FUNC(_poly_scanline_atex_mask8)
254   INIT_ATEX(/**/)
255
256   addl DVL, %ebx
257   adcl DVH, %edx
258
259   _align_
260atex_mask_loop:
261   movb (%esi), %ch
262   andl VMASK, %edx
263   movl %eax, %esi
264   incl %edi
265   shrdl %cl, %edx, %esi
266   addl DU, %eax
267   addl TEXTURE, %esi
268   addl DVL, %ebx
269   adcl DVH, %edx
270
271   orb  %ch, %ch
272   jz atex_mask_skip
273
274   movb %ch, FSEG(%edi)
275atex_mask_skip:
276   decl W
277   jg atex_mask_loop
278
279
280atex_mask_done:
281   popl %edi
282   popl %esi
283   popl %ebx
284   movl %ebp, %esp
285   popl %ebp
286   ret                           /* end of _poly_scanline_atex8() */
287
288
289
290
291/* void _poly_scanline_atex_lit8(ulong addr, int w, POLYGON_SEGMENT *info);
292 *  Fills a lit affine texture mapped polygon scanline.
293 */
294FUNC(_poly_scanline_atex_lit8)
295   #define INIT_CODE                     \
296      movl POLYSEG_C(%esi), %eax ;       \
297      movl POLYSEG_DC(%esi), %ebx ;      \
298      sarl $8, %eax ;                    \
299      sarl $8, %ebx ;                    \
300      jge atex_lit_round ;               \
301      incl %ebx ;                        \
302   atex_lit_round:                       \
303      subl %ebx, %eax ;                  \
304      movl %ebx, DC ;                    \
305      movl %eax, C
306   INIT_ATEX(INIT_CODE)
307   #undef INIT_CODE
308
309   movl %eax, TMP
310   addl DVL, %ebx
311   movl C, %eax
312   adcl DVH, %edx
313
314   addl DC, %eax
315   movzbl (%esi), %esi		   /* read texel */
316   movl %eax, C
317
318   addl GLOBL(color_map), %esi
319   andl $0x0000ff00, %eax
320   movb (%eax, %esi), %ch	   /* lookup in lighting table */
321   movl TMP, %eax
322
323   movb %ch, FSEG(%edi)
324   decl W
325   jz atex_lit_done
326
327   _align_
328atex_lit_loop:
329   andl VMASK, %edx
330   movl %eax, %esi
331   incl %edi
332   shrdl %cl, %edx, %esi
333   addl DU, %eax
334   addl TEXTURE, %esi
335   movl %eax, TMP
336   addl DVL, %ebx
337   movl C, %eax
338   adcl DVH, %edx
339
340   addl DC, %eax
341   movzbl (%esi), %esi		   /* read texel */
342   movl %eax, C
343
344   addl GLOBL(color_map), %esi
345   andl $0x0000ff00, %eax
346   movb (%eax, %esi), %ch	   /* lookup in lighting table */
347   movl TMP, %eax
348
349   movb %ch, FSEG(%edi)
350   decl W
351   jg atex_lit_loop
352
353
354atex_lit_done:
355   popl %edi
356   popl %esi
357   popl %ebx
358   movl %ebp, %esp
359   popl %ebp
360   ret                           /* end of _poly_scanline_atex_lit8() */
361
362
363
364/* void _poly_scanline_atex_mask_lit8(ulong addr, int w, POLYGON_SEGMENT *info);
365 *  Fills a masked lit affine texture mapped polygon scanline.
366 */
367FUNC(_poly_scanline_atex_mask_lit8)
368   #define INIT_CODE                     \
369      movl POLYSEG_C(%esi), %eax ;       \
370      movl POLYSEG_DC(%esi), %ebx ;      \
371      sarl $8, %eax ;                    \
372      sarl $8, %ebx ;                    \
373      jge atex_mask_lit_round ;          \
374      incl %ebx ;                        \
375   atex_mask_lit_round:                  \
376      subl %ebx, %eax ;                  \
377      movl %ebx, DC ;                    \
378      movl %eax, C
379   INIT_ATEX(INIT_CODE)
380   #undef INIT_CODE
381
382   movl %eax, TMP
383   addl DVL, %ebx
384   movl C, %eax
385   adcl DVH, %edx
386
387   addl DC, %eax
388   movzbl (%esi), %esi		   /* read texel */
389   testl $0xffffffff, %esi
390   jz atex_mask_lit_skip
391
392   movl %eax, C
393   addl GLOBL(color_map), %esi
394   andl $0x0000ff00, %eax
395   movb (%eax, %esi), %ch	   /* lookup in lighting table */
396   movl TMP, %eax
397
398   movb %ch, FSEG(%edi)
399   decl W
400   jz atex_mask_lit_done
401
402   _align_
403atex_mask_lit_loop:
404   andl VMASK, %edx
405   movl %eax, %esi
406   incl %edi
407   shrdl %cl, %edx, %esi
408   addl DU, %eax
409   addl TEXTURE, %esi
410   movl %eax, TMP
411   addl DVL, %ebx
412   movl C, %eax
413   adcl DVH, %edx
414
415   addl DC, %eax
416   movzbl (%esi), %esi		   /* read texel */
417   testl $0xffffffff, %esi
418   jz atex_mask_lit_skip
419
420   movl %eax, C
421   addl GLOBL(color_map), %esi
422   andl $0x0000ff00, %eax
423   movb (%eax, %esi), %ch	   /* lookup in lighting table */
424   movl TMP, %eax
425
426   movb %ch, FSEG(%edi)
427
428   decl W
429   jg atex_mask_lit_loop
430   jmp atex_mask_lit_done
431
432atex_mask_lit_skip:
433   movl TMP, %eax
434   decl W
435   jg atex_mask_lit_loop
436
437atex_mask_lit_done:
438   popl %edi
439   popl %esi
440   popl %ebx
441   movl %ebp, %esp
442   popl %ebp
443   ret                           /* end of _poly_scanline_atex_mask_lit8() */
444
445
446
447#undef DU
448#undef DVL
449#undef DVH
450#undef TEXTURE
451#undef VMASK
452#undef INIT_ATEX
453#undef C
454#undef DC
455#undef TMP
456
457#endif /* COLOR8 */
458
459
460
461
462#define TMP       -4(%ebp)
463#define UMASK     -8(%ebp)
464#define VMASK     -12(%ebp)
465#define VSHIFT    -16(%ebp)
466#define DU1       -20(%ebp)
467#define DV1       -24(%ebp)
468#define DZ1       -28(%ebp)
469#define DU4       -32(%ebp)
470#define DV4       -36(%ebp)
471#define DZ4       -40(%ebp)
472#define UDIFF     -44(%ebp)
473#define VDIFF     -48(%ebp)
474#define PREVU     -52(%ebp)
475#define PREVV     -56(%ebp)
476#define COUNT     -60(%ebp)
477#define C         -64(%ebp)
478#define DC        -68(%ebp)
479#define TEXTURE   -72(%ebp)
480
481
482
483
484/* helper for starting an fpu 1/z division */
485#define START_FP_DIV()                                                       \
486   fld1                                                                    ; \
487   fdiv %st(3), %st(0)
488
489
490
491/* helper for ending an fpu division, returning corrected u and v values */
492#define END_FP_DIV(ureg, vreg)                                               \
493   fld %st(0)                    /* duplicate the 1/z value */             ; \
494									   ; \
495   fmul %st(3), %st(0)           /* divide u by z */                       ; \
496   fxch %st(1)                                                             ; \
497									   ; \
498   fmul %st(2), %st(0)           /* divide v by z */                       ; \
499									   ; \
500   fistpl TMP                    /* store v */                             ; \
501   movl TMP, vreg                                                          ; \
502									   ; \
503   fistpl TMP                    /* store u */                             ; \
504   movl TMP, ureg
505
506
507
508/* helper for updating the u, v, and z values */
509#define UPDATE_FP_POS(n)                                                     \
510   fadds DV##n                   /* update v coord */                      ; \
511   fxch %st(1)                   /* swap vuz stack to uvz */               ; \
512									   ; \
513   fadds DU##n                   /* update u coord */                      ; \
514   fxch %st(2)                   /* swap uvz stack to zvu */               ; \
515									   ; \
516   fadds DZ##n                   /* update z value */                      ; \
517   fxch %st(2)                   /* swap zvu stack to uvz */               ; \
518   fxch %st(1)                   /* swap uvz stack back to vuz */
519
520
521
522
523/* main body of the perspective-correct texture mapping routine */
524#define DO_PTEX(name)                                                        \
525   pushl %ebp                                                              ; \
526   movl %esp, %ebp                                                         ; \
527   subl $72, %esp                /* eighteen local variables */            ; \
528									   ; \
529   pushl %ebx                                                              ; \
530   pushl %esi                                                              ; \
531   pushl %edi                                                              ; \
532									   ; \
533   movl INFO, %esi               /* load registers */                      ; \
534									   ; \
535   flds POLYSEG_Z(%esi)          /* z at bottom of fpu stack */            ; \
536   flds POLYSEG_FU(%esi)         /* followed by u */                       ; \
537   flds POLYSEG_FV(%esi)         /* followed by v */                       ; \
538									   ; \
539   flds POLYSEG_DFU(%esi)        /* multiply diffs by four */              ; \
540   flds POLYSEG_DFV(%esi)                                                  ; \
541   flds POLYSEG_DZ(%esi)                                                   ; \
542   fxch %st(2)                   /* u v z */                               ; \
543   fadd %st(0), %st(0)           /* 2u v z */                              ; \
544   fxch %st(1)                   /* v 2u z */                              ; \
545   fadd %st(0), %st(0)           /* 2v 2u z */                             ; \
546   fxch %st(2)                   /* z 2u 2v */                             ; \
547   fadd %st(0), %st(0)           /* 2z 2u 2v */                            ; \
548   fxch %st(1)                   /* 2u 2z 2v */                            ; \
549   fadd %st(0), %st(0)           /* 4u 2z 2v */                            ; \
550   fxch %st(2)                   /* 2v 2z 4u */                            ; \
551   fadd %st(0), %st(0)           /* 4v 2z 4u */                            ; \
552   fxch %st(1)                   /* 2z 4v 4u */                            ; \
553   fadd %st(0), %st(0)           /* 4z 4v 4u */                            ; \
554   fxch %st(2)                   /* 4u 4v 4z */                            ; \
555   fstps DU4                                                               ; \
556   fstps DV4                                                               ; \
557   fstps DZ4                                                               ; \
558									   ; \
559   START_FP_DIV()                /* prime the 1/z calculation */           ; \
560									   ; \
561   movl POLYSEG_DFU(%esi), %eax  /* copy diff values onto the stack */     ; \
562   movl POLYSEG_DFV(%esi), %ebx                                            ; \
563   movl POLYSEG_DZ(%esi), %ecx                                             ; \
564   movl %eax, DU1                                                          ; \
565   movl %ebx, DV1                                                          ; \
566   movl %ecx, DZ1                                                          ; \
567									   ; \
568   movl POLYSEG_VSHIFT(%esi), %ecx                                         ; \
569   movl POLYSEG_VMASK(%esi), %edx                                          ; \
570   movl POLYSEG_UMASK(%esi), %eax                                          ; \
571									   ; \
572   shll %cl, %edx                /* adjust v mask and shift value */       ; \
573   negl %ecx                                                               ; \
574   movl %eax, UMASK                                                        ; \
575   addl $16, %ecx                                                          ; \
576   movl %edx, VMASK                                                        ; \
577   movl %ecx, VSHIFT                                                       ; \
578									   ; \
579   INIT()                                                                  ; \
580									   ; \
581   movl ADDR, %edi                                                         ; \
582									   ; \
583   _align_                                                                 ; \
584name##_odd_byte_loop:                                                      ; \
585   testl $3, %edi                /* deal with any odd pixels */            ; \
586   jz name##_no_odd_bytes                                                  ; \
587									   ; \
588   END_FP_DIV(%ebx, %edx)        /* get corrected u/v position */          ; \
589   UPDATE_FP_POS(1)              /* update u/v/z values */                 ; \
590   START_FP_DIV()                /* start up the next divide */            ; \
591									   ; \
592   movb VSHIFT, %cl              /* shift and mask v coordinate */         ; \
593   sarl %cl, %edx                                                          ; \
594   andl VMASK, %edx                                                        ; \
595									   ; \
596   sarl $16, %ebx                /* shift and mask u coordinate */         ; \
597   andl UMASK, %ebx                                                        ; \
598   addl %ebx, %edx                                                         ; \
599									   ; \
600   SINGLE_PIXEL(1)               /* process the pixel */                   ; \
601									   ; \
602   decl W                                                                  ; \
603   jg name##_odd_byte_loop                                                 ; \
604									   ; \
605   _align_                                                                 ; \
606name##_no_odd_bytes:                                                       ; \
607   movl W, %ecx                  /* inner loop expanded 4 times */         ; \
608   movl %ecx, COUNT                                                        ; \
609   shrl $2, %ecx                                                           ; \
610   jg name##_prime_x4                                                      ; \
611									   ; \
612   END_FP_DIV(%ebx, %edx)        /* get corrected u/v position */          ; \
613   UPDATE_FP_POS(1)              /* update u/v/z values */                 ; \
614   START_FP_DIV()                /* start up the next divide */            ; \
615									   ; \
616   movl %ebx, PREVU              /* store initial u/v pos */               ; \
617   movl %edx, PREVV                                                        ; \
618									   ; \
619   jmp name##_cleanup_leftovers                                            ; \
620									   ; \
621   _align_                                                                 ; \
622name##_prime_x4:                                                           ; \
623   movl %ecx, W                                                            ; \
624									   ; \
625   END_FP_DIV(%ebx, %edx)        /* get corrected u/v position */          ; \
626   UPDATE_FP_POS(4)              /* update u/v/z values */                 ; \
627   START_FP_DIV()                /* start up the next divide */            ; \
628									   ; \
629   movl %ebx, PREVU              /* store initial u/v pos */               ; \
630   movl %edx, PREVV                                                        ; \
631									   ; \
632   jmp name##_start_loop                                                   ; \
633									   ; \
634   _align_                                                                 ; \
635name##_last_time:                                                          ; \
636   END_FP_DIV(%eax, %ecx)        /* get corrected u/v position */          ; \
637   UPDATE_FP_POS(1)              /* update u/v/z values */                 ; \
638   jmp name##_loop_contents                                                ; \
639									   ; \
640   _align_                                                                 ; \
641name##_loop:                                                               ; \
642   END_FP_DIV(%eax, %ecx)        /* get corrected u/v position */          ; \
643   UPDATE_FP_POS(4)              /* update u/v/z values */                 ; \
644									   ; \
645name##_loop_contents:                                                      ; \
646   START_FP_DIV()                /* start up the next divide */            ; \
647									   ; \
648   movl PREVU, %ebx              /* read the previous u/v pos */           ; \
649   movl PREVV, %edx                                                        ; \
650									   ; \
651   movl %eax, PREVU              /* store u/v for the next cycle */        ; \
652   movl %ecx, PREVV                                                        ; \
653									   ; \
654   subl %ebx, %eax               /* get u/v diffs for the four pixels */   ; \
655   subl %edx, %ecx                                                         ; \
656   sarl $2, %eax                                                           ; \
657   sarl $2, %ecx                                                           ; \
658   movl %eax, UDIFF                                                        ; \
659   movl %ecx, VDIFF                                                        ; \
660									   ; \
661   PREPARE_FOUR_PIXELS()                                                   ; \
662									   ; \
663   /* pixel 1 */                                                           ; \
664   movl %edx, %eax               /* shift and mask v coordinate */         ; \
665   movb VSHIFT, %cl                                                        ; \
666   sarl %cl, %eax                                                          ; \
667   andl VMASK, %eax                                                        ; \
668									   ; \
669   movl %ebx, %ecx               /* shift and mask u coordinate */         ; \
670   sarl $16, %ecx                                                          ; \
671   andl UMASK, %ecx                                                        ; \
672   addl %ecx, %eax                                                         ; \
673									   ; \
674   FOUR_PIXELS(0)                /* process pixel 1 */                     ; \
675									   ; \
676   addl UDIFF, %ebx                                                        ; \
677   addl VDIFF, %edx                                                        ; \
678									   ; \
679   /* pixel 2 */                                                           ; \
680   movl %edx, %eax               /* shift and mask v coordinate */         ; \
681   movb VSHIFT, %cl                                                        ; \
682   sarl %cl, %eax                                                          ; \
683   andl VMASK, %eax                                                        ; \
684									   ; \
685   movl %ebx, %ecx               /* shift and mask u coordinate */         ; \
686   sarl $16, %ecx                                                          ; \
687   andl UMASK, %ecx                                                        ; \
688   addl %ecx, %eax                                                         ; \
689									   ; \
690   FOUR_PIXELS(1)                /* process pixel 2 */                     ; \
691									   ; \
692   addl UDIFF, %ebx                                                        ; \
693   addl VDIFF, %edx                                                        ; \
694									   ; \
695   /* pixel 3 */                                                           ; \
696   movl %edx, %eax               /* shift and mask v coordinate */         ; \
697   movb VSHIFT, %cl                                                        ; \
698   sarl %cl, %eax                                                          ; \
699   andl VMASK, %eax                                                        ; \
700									   ; \
701   movl %ebx, %ecx               /* shift and mask u coordinate */         ; \
702   sarl $16, %ecx                                                          ; \
703   andl UMASK, %ecx                                                        ; \
704   addl %ecx, %eax                                                         ; \
705									   ; \
706   FOUR_PIXELS(2)                /* process pixel 3 */                     ; \
707									   ; \
708   addl UDIFF, %ebx                                                        ; \
709   addl VDIFF, %edx                                                        ; \
710									   ; \
711   /* pixel 4 */                                                           ; \
712   movl %edx, %eax               /* shift and mask v coordinate */         ; \
713   movb VSHIFT, %cl                                                        ; \
714   sarl %cl, %eax                                                          ; \
715   andl VMASK, %eax                                                        ; \
716									   ; \
717   movl %ebx, %ecx               /* shift and mask u coordinate */         ; \
718   sarl $16, %ecx                                                          ; \
719   andl UMASK, %ecx                                                        ; \
720   addl %ecx, %eax                                                         ; \
721									   ; \
722   FOUR_PIXELS(3)                /* process pixel 4 */                     ; \
723									   ; \
724   WRITE_FOUR_PIXELS()           /* write four pixels at a time */         ; \
725									   ; \
726name##_start_loop:                                                         ; \
727   decl W                                                                  ; \
728   jg name##_loop                                                          ; \
729   jz name##_last_time                                                     ; \
730									   ; \
731name##_cleanup_leftovers:                                                  ; \
732   movl COUNT, %ecx              /* deal with any leftover pixels */       ; \
733   andl $3, %ecx                                                           ; \
734   jz name##_done                                                          ; \
735									   ; \
736   movl %ecx, COUNT                                                        ; \
737   movl PREVU, %ebx                                                        ; \
738   movl PREVV, %edx                                                        ; \
739									   ; \
740   _align_                                                                 ; \
741name##_cleanup_loop:                                                       ; \
742   movb VSHIFT, %cl              /* shift and mask v coordinate */         ; \
743   sarl %cl, %edx                                                          ; \
744   andl VMASK, %edx                                                        ; \
745									   ; \
746   sarl $16, %ebx                /* shift and mask u coordinate */         ; \
747   andl UMASK, %ebx                                                        ; \
748   addl %ebx, %edx                                                         ; \
749									   ; \
750   SINGLE_PIXEL(2)               /* process the pixel */                   ; \
751									   ; \
752   decl COUNT                                                              ; \
753   jz name##_done                                                          ; \
754									   ; \
755   END_FP_DIV(%ebx, %edx)        /* get corrected u/v position */          ; \
756   UPDATE_FP_POS(1)              /* update u/v/z values */                 ; \
757   START_FP_DIV()                /* start up the next divide */            ; \
758   jmp name##_cleanup_loop                                                 ; \
759									   ; \
760name##_done:                                                               ; \
761   fstp %st(0)                   /* pop fpu stack */                       ; \
762   fstp %st(0)                                                             ; \
763   fstp %st(0)                                                             ; \
764   fstp %st(0)                                                             ; \
765									   ; \
766   popl %edi                                                               ; \
767   popl %esi                                                               ; \
768   popl %ebx                                                               ; \
769   movl %ebp, %esp                                                         ; \
770   popl %ebp
771
772
773
774
775#ifdef ALLEGRO_COLOR8
776/* void _poly_scanline_ptex8(ulong addr, int w, POLYGON_SEGMENT *info);
777 *  Fills a perspective correct texture mapped polygon scanline.
778 */
779FUNC(_poly_scanline_ptex8)
780
781   #define INIT()                                                            \
782      movl POLYSEG_TEXTURE(%esi), %esi
783
784
785   #define SINGLE_PIXEL(n)                                                   \
786      movb (%esi, %edx), %al     /* read texel */                          ; \
787      movb %al, FSEG(%edi)       /* write the pixel */                     ; \
788      incl %edi
789
790
791   #define PREPARE_FOUR_PIXELS()                                             \
792      /* noop */
793
794
795   #define FOUR_PIXELS(n)                                                    \
796      movb (%esi, %eax), %al     /* read texel */                          ; \
797      movb %al, n+TMP            /* store the pixel */
798
799
800   #define WRITE_FOUR_PIXELS()                                               \
801      movl TMP, %eax             /* write four pixels at a time */         ; \
802      movl %eax, FSEG(%edi)                                                ; \
803      addl $4, %edi
804
805
806   DO_PTEX(ptex)
807
808
809   #undef INIT
810   #undef SINGLE_PIXEL
811   #undef PREPARE_FOUR_PIXELS
812   #undef FOUR_PIXELS
813   #undef WRITE_FOUR_PIXELS
814
815   ret                           /* end of _poly_scanline_ptex8() */
816
817
818
819
820/* void _poly_scanline_ptex_mask8(ulong addr, int w, POLYGON_SEGMENT *info);
821 *  Fills a masked perspective correct texture mapped polygon scanline.
822 */
823FUNC(_poly_scanline_ptex_mask8)
824
825   #define INIT()                                                            \
826      movl POLYSEG_TEXTURE(%esi), %esi
827
828
829   #define SINGLE_PIXEL(n)                                                   \
830      movb (%esi, %edx), %al     /* read texel */                          ; \
831      orb %al, %al                                                         ; \
832      jz ptex_mask_skip_left_##n                                           ; \
833      movb %al, FSEG(%edi)       /* write the pixel */                     ; \
834   ptex_mask_skip_left_##n:                                                ; \
835      incl %edi
836
837
838   #define PREPARE_FOUR_PIXELS()                                             \
839      /* noop */
840
841
842   #define FOUR_PIXELS(n)                                                    \
843      movb (%esi, %eax), %al     /* read texel */                          ; \
844      orb %al, %al                                                         ; \
845      jz ptex_mask_skip_##n                                                ; \
846      movb %al, FSEG(%edi)       /* write the pixel */                     ; \
847   ptex_mask_skip_##n:                                                     ; \
848      incl %edi
849
850
851   #define WRITE_FOUR_PIXELS()                                               \
852      /* noop */
853
854
855   DO_PTEX(ptex_mask)
856
857
858   #undef INIT
859   #undef SINGLE_PIXEL
860   #undef PREPARE_FOUR_PIXELS
861   #undef FOUR_PIXELS
862   #undef WRITE_FOUR_PIXELS
863
864   ret                           /* end of _poly_scanline_ptex_mask8() */
865
866
867
868/* void _poly_scanline_ptex_lit8(ulong addr, int w, POLYGON_SEGMENT *info);
869 *  Fills a lit perspective correct texture mapped polygon scanline.
870 */
871FUNC(_poly_scanline_ptex_lit8)
872
873   #define INIT()                                                            \
874      movl POLYSEG_C(%esi), %eax                                           ; \
875      movl POLYSEG_DC(%esi), %ebx                                          ; \
876      movl POLYSEG_TEXTURE(%esi), %ecx                                     ; \
877      sarl $8, %eax                                                        ; \
878      sarl $8, %ebx                                                        ; \
879      movl %eax, C                                                         ; \
880      movl %ebx, DC                                                        ; \
881      movl %ecx, TEXTURE
882
883
884   #define SINGLE_PIXEL(n)                                                   \
885      movl TEXTURE, %esi         /* read texel */                          ; \
886      movzbl (%esi, %edx), %eax                                            ; \
887									   ; \
888      movb 1+C, %ah              /* lookup in lighting table */            ; \
889      movl GLOBL(color_map), %esi                                          ; \
890      movl DC, %ecx                                                        ; \
891      movb (%eax, %esi), %al                                               ; \
892      addl %ecx, C                                                         ; \
893									   ; \
894      movb %al, FSEG(%edi)       /* write the pixel */                     ; \
895      incl %edi
896
897
898   #define PREPARE_FOUR_PIXELS()                                             \
899      movl TEXTURE, %esi
900
901
902   #define FOUR_PIXELS(n)                                                    \
903      movl TEXTURE, %esi                                                   ; \
904      movb (%esi, %eax), %al     /* read texel */                          ; \
905      movb %al, n+TMP            /* store the pixel */
906
907
908   #define WRITE_FOUR_PIXELS()                                               \
909      movl GLOBL(color_map), %esi   /* light four pixels */                ; \
910      xorl %ecx, %ecx                                                      ; \
911      movl DC, %ebx                                                        ; \
912      movl C, %edx                                                         ; \
913									   ; \
914      movb %dh, %ch              /* light pixel 1 */                       ; \
915      movb TMP, %cl                                                        ; \
916      addl %ebx, %edx                                                      ; \
917      movb (%ecx, %esi), %al                                               ; \
918									   ; \
919      movb %dh, %ch              /* light pixel 2 */                       ; \
920      movb 1+TMP, %cl                                                      ; \
921      addl %ebx, %edx                                                      ; \
922      movb (%ecx, %esi), %ah                                               ; \
923									   ; \
924      roll $16, %eax                                                       ; \
925									   ; \
926      movb %dh, %ch              /* light pixel 3 */                       ; \
927      movb 2+TMP, %cl                                                      ; \
928      addl %ebx, %edx                                                      ; \
929      movb (%ecx, %esi), %al                                               ; \
930									   ; \
931      movb %dh, %ch              /* light pixel 4 */                       ; \
932      movb 3+TMP, %cl                                                      ; \
933      addl %ebx, %edx                                                      ; \
934      movb (%ecx, %esi), %ah                                               ; \
935									   ; \
936      movl %edx, C                                                         ; \
937      roll $16, %eax                                                       ; \
938      movl %eax, FSEG(%edi)      /* write four pixels at a time */         ; \
939      addl $4, %edi
940
941
942   DO_PTEX(ptex_lit)
943
944
945   #undef INIT
946   #undef SINGLE_PIXEL
947   #undef PREPARE_FOUR_PIXELS
948   #undef FOUR_PIXELS
949   #undef WRITE_FOUR_PIXELS
950
951   ret                           /* end of _poly_scanline_ptex_lit8() */
952
953#endif /* COLOR8 */
954#undef TMP
955#undef UMASK
956#undef VMASK
957#undef VSHIFT
958#undef DU1
959#undef DV1
960#undef DZ1
961#undef DU4
962#undef DV4
963#undef DZ4
964#undef UDIFF
965#undef VDIFF
966#undef PREVU
967#undef PREVV
968#undef COUNT
969#undef C
970#undef DC
971#undef TEXTURE
972
973#undef START_FP_DIV
974#undef END_FP_DIV
975#undef UPDATE_FP_POS
976#undef DO_PTEX
977
978
979
980#define DB      -4(%ebp)
981#define DG      -8(%ebp)
982#define DR     -12(%ebp)
983
984#define TMP4    -4(%ebp)
985#define TMP     -8(%ebp)
986#define SB     -16(%ebp)
987#define SG     -24(%ebp)
988#define SR     -32(%ebp)
989
990/* first part of a grgb routine */
991#define INIT_GRGB(depth, r_sft, g_sft, b_sft)                         \
992   pushl %ebp                                                       ; \
993   movl %esp, %ebp                                                  ; \
994   subl $12, %esp                                                   ; \
995   pushl %ebx                                                       ; \
996   pushl %esi                                                       ; \
997   pushl %edi                                                       ; \
998								    ; \
999grgb_entry_##depth:                                                 ; \
1000   movl INFO, %esi               /* load registers */               ; \
1001								    ; \
1002   movl POLYSEG_DR(%esi), %ebx   /* move delta's on stack */        ; \
1003   movl POLYSEG_DG(%esi), %edi                                      ; \
1004   movl POLYSEG_DB(%esi), %edx                                      ; \
1005   movl %ebx, DR                                                    ; \
1006   movl %edi, DG                                                    ; \
1007   movl %edx, DB                                                    ; \
1008								    ; \
1009   movl POLYSEG_R(%esi), %ebx                                       ; \
1010   movl POLYSEG_G(%esi), %edi                                       ; \
1011   movl POLYSEG_B(%esi), %edx                                       ; \
1012								    ; \
1013   _align_                                                          ; \
1014grgb_loop_##depth:                                                  ; \
1015   movl %ebx, %eax              /* red */                           ; \
1016   movb GLOBL(_rgb_r_shift_##depth), %cl                            ; \
1017   shrl $r_sft, %eax                                                ; \
1018   addl DR, %ebx                                                    ; \
1019   shll %cl, %eax                                                   ; \
1020   movl %edi, %esi              /* green */                         ; \
1021   movb GLOBL(_rgb_g_shift_##depth), %cl                            ; \
1022   shrl $g_sft, %esi                                                ; \
1023   addl DG, %edi                                                    ; \
1024   shll %cl, %esi                                                   ; \
1025   orl %esi, %eax                                                   ; \
1026   movl %edx, %esi              /* blue */                          ; \
1027   movb GLOBL(_rgb_b_shift_##depth), %cl                            ; \
1028   shrl $b_sft, %esi                                                ; \
1029   addl DB, %edx                                                    ; \
1030   shll %cl, %esi                                                   ; \
1031   orl %esi, %eax                                                   ; \
1032   movl ADDR, %esi
1033
1034/* end of grgb routine */
1035#define END_GRGB(depth)                                               \
1036   movl %esi, ADDR                                                  ; \
1037   decl W                                                           ; \
1038   jg grgb_loop_##depth                                             ; \
1039								    ; \
1040   popl %edi                                                        ; \
1041   popl %esi                                                        ; \
1042   popl %ebx                                                        ; \
1043   movl %ebp, %esp                                                  ; \
1044   popl %ebp
1045
1046
1047
1048#ifdef ALLEGRO_COLOR16
1049/* void _poly_scanline_grgb15(unsigned long addr, int w, POLYGON_SEGMENT *info);
1050 *  Fills an RGB gouraud shaded polygon scanline.
1051 */
1052FUNC(_poly_scanline_grgb15)
1053   INIT_GRGB(15, 19, 19, 19)
1054   movw %ax, FSEG(%esi)          /* write the pixel */
1055   addl $2, %esi
1056   END_GRGB(15)
1057   ret                           /* end of _poly_scanline_grgb15() */
1058
1059
1060
1061/* void _poly_scanline_grgb16(unsigned long addr, int w, POLYGON_SEGMENT *info);
1062 *  Fills an RGB gouraud shaded polygon scanline.
1063 */
1064FUNC(_poly_scanline_grgb16)
1065   INIT_GRGB(16, 19, 18, 19)
1066   movw %ax, FSEG(%esi)          /* write the pixel */
1067   addl $2, %esi
1068   END_GRGB(16)
1069   ret                           /* end of _poly_scanline_grgb16() */
1070
1071#endif /* COLOR16 */
1072
1073
1074
1075#ifdef ALLEGRO_COLOR32
1076/* void _poly_scanline_grgb32(unsigned long addr, int w, POLYGON_SEGMENT *info);
1077 *  Fills an RGB gouraud shaded polygon scanline.
1078 */
1079FUNC(_poly_scanline_grgb32)
1080   INIT_GRGB(32, 16, 16, 16)
1081   movl %eax, FSEG(%esi)         /* write the pixel */
1082   addl $4, %esi
1083   END_GRGB(32)
1084   ret                           /* end of _poly_scanline_grgb32() */
1085
1086#endif /* COLOR32 */
1087
1088#ifdef ALLEGRO_COLOR24
1089/* void _poly_scanline_grgb24(unsigned long addr, int w, POLYGON_SEGMENT *info);
1090 *  Fills an RGB gouraud shaded polygon scanline.
1091 */
1092FUNC(_poly_scanline_grgb24)
1093   INIT_GRGB(24, 16, 16, 16)
1094   movw %ax, FSEG(%esi)          /* write the pixel */
1095   shrl $16, %eax
1096   movb %al, FSEG 2(%esi)
1097   addl $3, %esi
1098   END_GRGB(24)
1099   ret                           /* end of _poly_scanline_grgb24() */
1100
1101#endif /* COLOR24 */
1102
1103#undef DR
1104#undef DG
1105#undef DB
1106#undef TMP
1107#undef TMP2
1108#undef TMP4
1109#undef TMP6
1110#undef SR
1111#undef SG
1112#undef SB
1113
1114
1115
1116#define VMASK      -8(%ebp)
1117#define VSHIFT    -16(%ebp)
1118#define DV        -20(%ebp)
1119#define DU        -24(%ebp)
1120#define ALPHA4    -28(%ebp)
1121#define ALPHA2    -30(%ebp)
1122#define ALPHA     -32(%ebp)
1123#define DALPHA4   -36(%ebp)
1124#define DALPHA    -40(%ebp)
1125#define UMASK     -44(%ebp)
1126#define READ_ADDR -48(%ebp)
1127
1128/* first part of an affine texture mapping operation */
1129#define INIT_ATEX(extra)                                              \
1130   pushl %ebp                                                       ; \
1131   movl %esp, %ebp                                                  ; \
1132   subl $48, %esp                    /* local variables */          ; \
1133   pushl %ebx                                                       ; \
1134   pushl %esi                                                       ; \
1135   pushl %edi                                                       ; \
1136								    ; \
1137   movl INFO, %esi               /* load registers */               ; \
1138   extra                                                            ; \
1139								    ; \
1140   movl POLYSEG_VSHIFT(%esi), %ecx                                  ; \
1141   movl POLYSEG_VMASK(%esi), %eax                                   ; \
1142   shll %cl, %eax           /* adjust v mask and shift value */     ; \
1143   negl %ecx                                                        ; \
1144   addl $16, %ecx                                                   ; \
1145   movl %ecx, VSHIFT                                                ; \
1146   movl %eax, VMASK                                                 ; \
1147								    ; \
1148   movl POLYSEG_UMASK(%esi), %eax                                   ; \
1149   movl POLYSEG_DU(%esi), %ebx                                      ; \
1150   movl POLYSEG_DV(%esi), %edx                                      ; \
1151   movl %eax, UMASK                                                 ; \
1152   movl %ebx, DU                                                    ; \
1153   movl %edx, DV                                                    ; \
1154								    ; \
1155   movl POLYSEG_U(%esi), %ebx                                       ; \
1156   movl POLYSEG_V(%esi), %edx                                       ; \
1157   movl ADDR, %edi                                                  ; \
1158   movl POLYSEG_TEXTURE(%esi), %esi                                 ; \
1159								    ; \
1160   _align_                                                          ; \
11611:                                                                  ; \
1162   movl %edx, %eax               /* get v */                        ; \
1163   movb VSHIFT, %cl                                                 ; \
1164   sarl %cl, %eax                                                   ; \
1165   andl VMASK, %eax                                                 ; \
1166								    ; \
1167   movl %ebx, %ecx               /* get u */                        ; \
1168   sarl $16, %ecx                                                   ; \
1169   andl UMASK, %ecx                                                 ; \
1170   addl %ecx, %eax
1171
1172/* end of atex routine */
1173#define END_ATEX()                                                  ; \
1174   addl DU, %ebx                                                    ; \
1175   addl DV, %edx                                                    ; \
1176   decl W                                                           ; \
1177   jg 1b                                                            ; \
1178   popl %edi                                                        ; \
1179   popl %esi                                                        ; \
1180   popl %ebx                                                        ; \
1181   movl %ebp, %esp                                                  ; \
1182   popl %ebp
1183
1184
1185
1186#ifdef ALLEGRO_COLOR16
1187/* void _poly_scanline_atex16(unsigned long addr, int w, POLYGON_SEGMENT *info);
1188 *  Fills an affine texture mapped polygon scanline.
1189 */
1190FUNC(_poly_scanline_atex16)
1191   INIT_ATEX(/**/)
1192   movw (%esi, %eax, 2), %ax     /* read texel */
1193   movw %ax, FSEG(%edi)          /* write the pixel */
1194   addl $2, %edi
1195   END_ATEX()
1196   ret                           /* end of _poly_scanline_atex16() */
1197
1198/* void _poly_scanline_atex_mask15(ulong addr, int w, POLYGON_SEGMENT *info);
1199 *  Fills a masked affine texture mapped polygon scanline.
1200 */
1201FUNC(_poly_scanline_atex_mask15)
1202   INIT_ATEX(/**/)
1203   movw (%esi, %eax, 2), %ax     /* read texel */
1204   cmpw $MASK_COLOR_15, %ax
1205   jz 7f
1206   movw %ax, FSEG(%edi)          /* write solid pixels */
12077: addl $2, %edi
1208   END_ATEX()
1209   ret                           /* end of _poly_scanline_atex_mask15() */
1210
1211/* void _poly_scanline_atex_mask16(ulong addr, int w, POLYGON_SEGMENT *info);
1212 *  Fills a masked affine texture mapped polygon scanline.
1213 */
1214FUNC(_poly_scanline_atex_mask16)
1215   INIT_ATEX(/**/)
1216   movw (%esi, %eax, 2), %ax     /* read texel */
1217   cmpw $MASK_COLOR_16, %ax
1218   jz 7f
1219   movw %ax, FSEG(%edi)          /* write solid pixels */
12207: addl $2, %edi
1221   END_ATEX()
1222   ret                           /* end of _poly_scanline_atex_mask16() */
1223#endif /* COLOR16 */
1224
1225
1226
1227#ifdef ALLEGRO_COLOR32
1228/* void _poly_scanline_atex32(unsigned long addr, int w, POLYGON_SEGMENT *info);
1229 *  Fills an affine texture mapped polygon scanline.
1230 */
1231FUNC(_poly_scanline_atex32)
1232   INIT_ATEX(/**/)
1233   movl (%esi, %eax, 4), %eax    /* read texel */
1234   movl %eax, FSEG(%edi)         /* write the pixel */
1235   addl $4, %edi
1236   END_ATEX()
1237   ret                           /* end of _poly_scanline_atex32() */
1238
1239/* void _poly_scanline_atex_mask32(ulong addr, int w, POLYGON_SEGMENT *info);
1240 *  Fills a masked affine texture mapped polygon scanline.
1241 */
1242FUNC(_poly_scanline_atex_mask32)
1243   INIT_ATEX(/**/)
1244   movl (%esi, %eax, 4), %eax    /* read texel */
1245   cmpl $MASK_COLOR_32, %eax
1246   jz 7f
1247   movl %eax, FSEG(%edi)         /* write solid pixels */
12487: addl $4, %edi
1249   END_ATEX()
1250   ret                           /* end of _poly_scanline_atex_mask32() */
1251#endif /* COLOR32 */
1252
1253#ifdef ALLEGRO_COLOR24
1254/* void _poly_scanline_atex24(unsigned long addr, int w, POLYGON_SEGMENT *info);
1255 *  Fills an affine texture mapped polygon scanline.
1256 */
1257FUNC(_poly_scanline_atex24)
1258   INIT_ATEX(/**/)
1259   leal (%eax, %eax, 2), %ecx
1260   movw (%esi, %ecx), %ax        /* read texel */
1261   movw %ax, FSEG(%edi)          /* write the pixel */
1262   movb 2(%esi, %ecx), %al       /* read texel */
1263   movb %al, FSEG 2(%edi)        /* write the pixel */
1264   addl $3, %edi
1265   END_ATEX()
1266   ret                           /* end of _poly_scanline_atex24() */
1267
1268/* void _poly_scanline_atex_mask24(ulong addr, int w, POLYGON_SEGMENT *info);
1269 *  Fills a masked affine texture mapped polygon scanline.
1270 */
1271FUNC(_poly_scanline_atex_mask24)
1272   INIT_ATEX(/**/)
1273   leal (%eax, %eax, 2), %ecx
1274   movzbl 2(%esi, %ecx), %eax    /* read texel */
1275   shll $16, %eax
1276   movw (%esi, %ecx), %ax
1277   cmpl $MASK_COLOR_24, %eax
1278   jz 7f
1279   movw %ax, FSEG(%edi)          /* write solid pixels */
1280   shrl $16, %eax
1281   movb %al, FSEG 2(%edi)
12827: addl $3, %edi
1283   END_ATEX()
1284   ret                           /* end of _poly_scanline_atex_mask24() */
1285#endif /* COLOR24 */
1286
1287
1288
1289#ifdef ALLEGRO_COLOR16
1290/* void _poly_scanline_atex_lit15(ulong addr, int w, POLYGON_SEGMENT *info);
1291 *  Fills a lit affine texture mapped polygon scanline.
1292 */
1293FUNC(_poly_scanline_atex_lit15)
1294   #define INIT_CODE                     \
1295     movl POLYSEG_C(%esi), %eax ;        \
1296     movl POLYSEG_DC(%esi), %edx ;       \
1297     movl %eax, ALPHA ;                  \
1298     movl %edx, DALPHA
1299   INIT_ATEX(INIT_CODE)
1300   #undef INIT_CODE
1301   pushl %edx
1302   movzbl 2+ALPHA, %edx
1303   pushl %edx
1304   movw (%esi, %eax, 2), %ax    /* read texel */
1305   pushl GLOBL(_blender_col_15)
1306   pushl %eax
1307   call *GLOBL(_blender_func15)
1308   addl $12, %esp
1309
1310   movw %ax, FSEG(%edi)         /* write the pixel */
1311   movl DALPHA, %eax
1312   addl $2, %edi
1313   addl %eax, ALPHA
1314   popl %edx
1315   END_ATEX()
1316   ret                           /* end of _poly_scanline_atex_lit15() */
1317
1318/* void _poly_scanline_atex_mask_lit15(ulong addr, int w, POLYGON_SEGMENT *info);
1319 *  Fills a lit affine texture mapped polygon scanline.
1320 */
1321FUNC(_poly_scanline_atex_mask_lit15)
1322   #define INIT_CODE                     \
1323     movl POLYSEG_C(%esi), %eax ;        \
1324     movl POLYSEG_DC(%esi), %edx ;       \
1325     movl %eax, ALPHA ;                  \
1326     movl %edx, DALPHA
1327   INIT_ATEX(INIT_CODE)
1328   #undef INIT_CODE
1329   movw (%esi, %eax, 2), %ax    /* read texel */
1330   cmpw $MASK_COLOR_15, %ax
1331   jz 7f
1332   pushl %edx
1333   movzbl 2+ALPHA, %edx
1334   pushl %edx
1335   pushl GLOBL(_blender_col_15)
1336   pushl %eax
1337   call *GLOBL(_blender_func15)
1338   addl $12, %esp
1339
1340   movw %ax, FSEG(%edi)         /* write the pixel */
1341   popl %edx
13427:
1343   movl DALPHA, %eax
1344   addl $2, %edi
1345   addl %eax, ALPHA
1346   END_ATEX()
1347   ret                           /* end of _poly_scanline_atex_mask_lit15() */
1348
1349
1350
1351/* void _poly_scanline_atex_lit16(ulong addr, int w, POLYGON_SEGMENT *info);
1352 *  Fills a lit affine texture mapped polygon scanline.
1353 */
1354FUNC(_poly_scanline_atex_lit16)
1355   #define INIT_CODE                     \
1356     movl POLYSEG_C(%esi), %eax ;        \
1357     movl POLYSEG_DC(%esi), %edx ;       \
1358     movl %eax, ALPHA ;                  \
1359     movl %edx, DALPHA
1360   INIT_ATEX(INIT_CODE)
1361   #undef INIT_CODE
1362   pushl %edx
1363   movzbl 2+ALPHA, %edx
1364   pushl %edx
1365   movw (%esi, %eax, 2), %ax     /* read texel */
1366   pushl GLOBL(_blender_col_16)
1367   pushl %eax
1368   call *GLOBL(_blender_func16)
1369   addl $12, %esp
1370
1371   movw %ax, FSEG(%edi)          /* write the pixel */
1372   movl DALPHA, %eax
1373   addl $2, %edi
1374   addl %eax, ALPHA
1375   popl %edx
1376   END_ATEX()
1377   ret                           /* end of _poly_scanline_atex_lit16() */
1378
1379/* void _poly_scanline_atex_mask_lit16(ulong addr, int w, POLYGON_SEGMENT *info);
1380 *  Fills a lit affine texture mapped polygon scanline.
1381 */
1382FUNC(_poly_scanline_atex_mask_lit16)
1383   #define INIT_CODE                     \
1384     movl POLYSEG_C(%esi), %eax ;        \
1385     movl POLYSEG_DC(%esi), %edx ;       \
1386     movl %eax, ALPHA ;                  \
1387     movl %edx, DALPHA
1388   INIT_ATEX(INIT_CODE)
1389   #undef INIT_CODE
1390   movw (%esi, %eax, 2), %ax     /* read texel */
1391   cmpw $MASK_COLOR_16, %ax
1392   jz 7f
1393   pushl %edx
1394   movzbl 2+ALPHA, %edx
1395   pushl %edx
1396   pushl GLOBL(_blender_col_16)
1397   pushl %eax
1398   call *GLOBL(_blender_func16)
1399   addl $12, %esp
1400
1401   movw %ax, FSEG(%edi)          /* write the pixel */
1402   popl %edx
14037:
1404   movl DALPHA, %eax
1405   addl $2, %edi
1406   addl %eax, ALPHA
1407   END_ATEX()
1408   ret                           /* end of _poly_scanline_atex_mask_lit16() */
1409
1410#endif /* COLOR16 */
1411
1412
1413
1414#ifdef ALLEGRO_COLOR32
1415/* void _poly_scanline_atex_lit32(ulong addr, int w, POLYGON_SEGMENT *info);
1416 *  Fills a lit affine texture mapped polygon scanline.
1417 */
1418FUNC(_poly_scanline_atex_lit32)
1419   #define INIT_CODE                     \
1420     movl POLYSEG_C(%esi), %eax ;        \
1421     movl POLYSEG_DC(%esi), %edx ;       \
1422     movl %eax, ALPHA ;                  \
1423     movl %edx, DALPHA
1424   INIT_ATEX(INIT_CODE)
1425   #undef INIT_CODE
1426   pushl %edx
1427   movzbl 2+ALPHA, %edx
1428   pushl %edx
1429   movl (%esi, %eax, 4), %eax    /* read texel */
1430   pushl GLOBL(_blender_col_32)
1431   pushl %eax
1432   call *GLOBL(_blender_func32)
1433   addl $12, %esp
1434
1435   movl %eax, FSEG(%edi)         /* write the pixel */
1436   movl DALPHA, %eax
1437   addl $4, %edi
1438   addl %eax, ALPHA
1439   popl %edx
1440   END_ATEX()
1441   ret                           /* end of _poly_scanline_atex_lit32() */
1442
1443/* void _poly_scanline_atex_mask_lit32(ulong addr, int w, POLYGON_SEGMENT *info);
1444 *  Fills a lit affine texture mapped polygon scanline.
1445 */
1446FUNC(_poly_scanline_atex_mask_lit32)
1447   #define INIT_CODE                     \
1448     movl POLYSEG_C(%esi), %eax ;        \
1449     movl POLYSEG_DC(%esi), %edx ;       \
1450     movl %eax, ALPHA ;                  \
1451     movl %edx, DALPHA
1452   INIT_ATEX(INIT_CODE)
1453   #undef INIT_CODE
1454   movl (%esi, %eax, 4), %eax    /* read texel */
1455   cmpl $MASK_COLOR_32, %eax
1456   jz 7f
1457   pushl %edx
1458   movzbl 2+ALPHA, %edx
1459   pushl %edx
1460   pushl GLOBL(_blender_col_32)
1461   pushl %eax
1462   call *GLOBL(_blender_func32)
1463   addl $12, %esp
1464
1465   movl %eax, FSEG(%edi)         /* write the pixel */
1466   popl %edx
14677:
1468   movl DALPHA, %eax
1469   addl $4, %edi
1470   addl %eax, ALPHA
1471   END_ATEX()
1472   ret                           /* end of _poly_scanline_atex_mask_lit32() */
1473
1474#endif /* COLOR32 */
1475
1476
1477
1478#ifdef ALLEGRO_COLOR24
1479/* void _poly_scanline_atex_lit24(ulong addr, int w, POLYGON_SEGMENT *info);
1480 *  Fills a lit affine texture mapped polygon scanline.
1481 */
1482FUNC(_poly_scanline_atex_lit24)
1483   #define INIT_CODE                     \
1484     movl POLYSEG_C(%esi), %eax ;        \
1485     movl POLYSEG_DC(%esi), %edx ;       \
1486     movl %eax, ALPHA ;                  \
1487     movl %edx, DALPHA
1488   INIT_ATEX(INIT_CODE)
1489   #undef INIT_CODE
1490   pushl %edx
1491   movzbl 2+ALPHA, %edx
1492   pushl %edx
1493   leal (%eax, %eax, 2), %ecx
1494   movb 2(%esi, %ecx), %al        /* read texel */
1495   shll $16, %eax
1496   movw (%esi, %ecx), %ax
1497   pushl GLOBL(_blender_col_24)
1498   pushl %eax
1499   call *GLOBL(_blender_func24)
1500   addl $12, %esp
1501
1502   movw %ax, FSEG(%edi)          /* write the pixel */
1503   shrl $16, %eax
1504   movb %al, FSEG 2(%edi)
1505   movl DALPHA, %eax
1506   addl $3, %edi
1507   addl %eax, ALPHA
1508   popl %edx
1509   END_ATEX()
1510   ret                           /* end of _poly_scanline_atex_lit24() */
1511
1512/* void _poly_scanline_atex_mask_lit24(ulong addr, int w, POLYGON_SEGMENT *info);
1513 *  Fills a lit affine texture mapped polygon scanline.
1514 */
1515FUNC(_poly_scanline_atex_mask_lit24)
1516   #define INIT_CODE                     \
1517     movl POLYSEG_C(%esi), %eax ;        \
1518     movl POLYSEG_DC(%esi), %edx ;       \
1519     movl %eax, ALPHA ;                  \
1520     movl %edx, DALPHA
1521   INIT_ATEX(INIT_CODE)
1522   #undef INIT_CODE
1523   leal (%eax, %eax, 2), %ecx
1524   movzbl 2(%esi, %ecx), %eax    /* read texel */
1525   shll $16, %eax
1526   movw (%esi, %ecx), %ax
1527   cmpl $MASK_COLOR_24, %eax
1528   jz 7f
1529   pushl %edx
1530   movzbl 2+ALPHA, %edx
1531   pushl %edx
1532   pushl GLOBL(_blender_col_24)
1533   pushl %eax
1534   call *GLOBL(_blender_func24)
1535   addl $12, %esp
1536
1537   movw %ax, FSEG(%edi)          /* write the pixel */
1538   shrl $16, %eax
1539   movb %al, FSEG 2(%edi)
1540   popl %edx
15417:
1542   movl DALPHA, %eax
1543   addl $3, %edi
1544   addl %eax, ALPHA
1545   END_ATEX()
1546   ret                           /* end of _poly_scanline_atex_mask_lit24() */
1547
1548#endif /* COLOR24 */
1549
1550
1551
1552#ifdef ALLEGRO_COLOR8
1553/* void _poly_scanline_atex_trans8(ulong addr, int w, POLYGON_SEGMENT *info);
1554 *  Fills a trans affine texture mapped polygon scanline.
1555 */
1556FUNC(_poly_scanline_atex_trans8)
1557   #define INIT_CODE                     \
1558     movl POLYSEG_RADDR(%esi), %eax ;    \
1559     movl %eax, READ_ADDR
1560   INIT_ATEX(INIT_CODE)
1561   #undef INIT_CODE
1562   pushl %edi
1563   movzbl (%esi, %eax), %eax     /* read texel */
1564   movl READ_ADDR, %edi
1565   shll $8, %eax
1566   movb FSEG (%edi), %al		 /* read pixel */
1567   movl GLOBL(color_map), %ecx
1568   popl %edi
1569   movb (%ecx, %eax), %al
1570   movb %al, FSEG(%edi)
1571   incl READ_ADDR
1572   incl %edi
1573   END_ATEX()
1574   ret                           /* end of _poly_scanline_atex_trans8() */
1575
1576/* void _poly_scanline_atex_mask_trans8(ulong addr, int w, POLYGON_SEGMENT *info);
1577 *  Fills a trans affine texture mapped polygon scanline.
1578 */
1579FUNC(_poly_scanline_atex_mask_trans8)
1580   #define INIT_CODE                     \
1581     movl POLYSEG_RADDR(%esi), %eax ;    \
1582     movl %eax, READ_ADDR
1583   INIT_ATEX(INIT_CODE)
1584   #undef INIT_CODE
1585   movzbl (%esi, %eax), %eax     /* read texel */
1586   orl %eax, %eax
1587   jz 7f
1588   shll $8, %eax
1589   pushl %edi
1590   movl READ_ADDR, %edi
1591   movb FSEG (%edi), %al
1592   popl %edi
1593   movl GLOBL(color_map), %ecx
1594   movb (%ecx, %eax), %al
1595   movb %al, FSEG(%edi)
15967:
1597   incl READ_ADDR
1598   incl %edi
1599   END_ATEX()
1600   ret                           /* end of _poly_scanline_atex_mask_trans8() */
1601#endif /* COLOR8 */
1602
1603
1604
1605#ifdef ALLEGRO_COLOR16
1606/* void _poly_scanline_atex_trans15(ulong addr, int w, POLYGON_SEGMENT *info);
1607 *  Fills a trans affine texture mapped polygon scanline.
1608 */
1609FUNC(_poly_scanline_atex_trans15)
1610   #define INIT_CODE                     \
1611     movl POLYSEG_RADDR(%esi), %eax ;    \
1612     movl %eax, READ_ADDR
1613   INIT_ATEX(INIT_CODE)
1614   #undef INIT_CODE
1615   pushl %edx
1616   pushl GLOBL(_blender_alpha)
1617   pushl %edi
1618   movl READ_ADDR, %edi
1619   movw FSEG (%edi), %cx
1620   popl %edi
1621   movw (%esi, %eax, 2), %ax    /* read texel */
1622   pushl %ecx
1623   pushl %eax
1624
1625   call *GLOBL(_blender_func15)
1626   addl $12, %esp
1627
1628   movw %ax, FSEG(%edi)         /* write the pixel */
1629   addl $2, READ_ADDR
1630   addl $2, %edi
1631   popl %edx
1632   END_ATEX()
1633   ret                           /* end of _poly_scanline_atex_trans15() */
1634
1635/* void _poly_scanline_atex_mask_trans15(ulong addr, int w, POLYGON_SEGMENT *info);
1636 *  Fills a trans affine texture mapped polygon scanline.
1637 */
1638FUNC(_poly_scanline_atex_mask_trans15)
1639   #define INIT_CODE                     \
1640     movl POLYSEG_RADDR(%esi), %eax ;    \
1641     movl %eax, READ_ADDR
1642   INIT_ATEX(INIT_CODE)
1643   #undef INIT_CODE
1644   movw (%esi, %eax, 2), %ax    /* read texel */
1645   cmpw $MASK_COLOR_15, %ax
1646   jz 7f
1647   pushl %edi
1648   movl READ_ADDR, %edi
1649   movw FSEG (%edi), %cx
1650   popl %edi
1651   pushl %edx
1652   pushl GLOBL(_blender_alpha)
1653   pushl %ecx
1654   pushl %eax
1655
1656   call *GLOBL(_blender_func15)
1657   addl $12, %esp
1658
1659   movw %ax, FSEG(%edi)         /* write the pixel */
1660   popl %edx
16617:
1662   addl $2, %edi
1663   addl $2, READ_ADDR
1664   END_ATEX()
1665   ret                           /* end of _poly_scanline_atex_mask_trans15() */
1666
1667
1668
1669/* void _poly_scanline_atex_trans16(ulong addr, int w, POLYGON_SEGMENT *info);
1670 *  Fills a trans affine texture mapped polygon scanline.
1671 */
1672FUNC(_poly_scanline_atex_trans16)
1673   #define INIT_CODE                     \
1674     movl POLYSEG_RADDR(%esi), %eax ;    \
1675     movl %eax, READ_ADDR
1676   INIT_ATEX(INIT_CODE)
1677   #undef INIT_CODE
1678   pushl %edx
1679   pushl GLOBL(_blender_alpha)
1680   pushl %edi
1681   movl READ_ADDR, %edi
1682   movw FSEG (%edi), %cx
1683   popl %edi
1684   movw (%esi, %eax, 2), %ax     /* read texel */
1685   pushl %ecx
1686   pushl %eax
1687
1688   call *GLOBL(_blender_func16)
1689   addl $12, %esp
1690
1691   movw %ax, FSEG(%edi)          /* write the pixel */
1692   addl $2, READ_ADDR
1693   addl $2, %edi
1694   popl %edx
1695   END_ATEX()
1696   ret                           /* end of _poly_scanline_atex_trans16() */
1697
1698/* void _poly_scanline_atex_mask_trans16(ulong addr, int w, POLYGON_SEGMENT *info);
1699 *  Fills a trans affine texture mapped polygon scanline.
1700 */
1701FUNC(_poly_scanline_atex_mask_trans16)
1702   #define INIT_CODE                     \
1703     movl POLYSEG_RADDR(%esi), %eax ;    \
1704     movl %eax, READ_ADDR
1705   INIT_ATEX(INIT_CODE)
1706   #undef INIT_CODE
1707   movw (%esi, %eax, 2), %ax     /* read texel */
1708   cmpw $MASK_COLOR_16, %ax
1709   jz 7f
1710   pushl %edi
1711   movl READ_ADDR, %edi
1712   movw FSEG (%edi), %cx
1713   popl %edi
1714   pushl %edx
1715   pushl GLOBL(_blender_alpha)
1716   pushl %ecx
1717   pushl %eax
1718
1719   call *GLOBL(_blender_func16)
1720   addl $12, %esp
1721
1722   movw %ax, FSEG(%edi)          /* write the pixel */
1723   popl %edx
17247:
1725   addl $2, %edi
1726   addl $2, READ_ADDR
1727   END_ATEX()
1728   ret                           /* end of _poly_scanline_atex_mask_trans16() */
1729
1730#endif /* COLOR16 */
1731
1732
1733
1734#ifdef ALLEGRO_COLOR32
1735/* void _poly_scanline_atex_trans32(ulong addr, int w, POLYGON_SEGMENT *info);
1736 *  Fills a trans affine texture mapped polygon scanline.
1737 */
1738FUNC(_poly_scanline_atex_trans32)
1739   #define INIT_CODE                     \
1740     movl POLYSEG_RADDR(%esi), %eax ;    \
1741     movl %eax, READ_ADDR
1742   INIT_ATEX(INIT_CODE)
1743   #undef INIT_CODE
1744   pushl %edx
1745   pushl GLOBL(_blender_alpha)
1746   movl %edi, ALPHA
1747   movl READ_ADDR, %edi
1748   pushl FSEG (%edi)
1749   movl ALPHA, %edi
1750   pushl (%esi, %eax, 4)
1751
1752   call *GLOBL(_blender_func32)
1753   addl $12, %esp
1754
1755   movl %eax, FSEG(%edi)         /* write the pixel */
1756   addl $4, READ_ADDR
1757   addl $4, %edi
1758   popl %edx
1759   END_ATEX()
1760   ret                           /* end of _poly_scanline_atex_trans32() */
1761
1762/* void _poly_scanline_atex_mask_trans32(ulong addr, int w, POLYGON_SEGMENT *info);
1763 *  Fills a trans affine texture mapped polygon scanline.
1764 */
1765FUNC(_poly_scanline_atex_mask_trans32)
1766   #define INIT_CODE                     \
1767     movl POLYSEG_RADDR(%esi), %eax ;    \
1768     movl %eax, READ_ADDR
1769   INIT_ATEX(INIT_CODE)
1770   #undef INIT_CODE
1771   movl (%esi, %eax, 4), %eax    /* read texel */
1772   cmpl $MASK_COLOR_32, %eax
1773   jz 7f
1774   pushl %edx
1775   pushl GLOBL(_blender_alpha)
1776   movl %edi, ALPHA
1777   movl READ_ADDR, %edi
1778   pushl FSEG (%edi)
1779   movl ALPHA, %edi
1780   pushl %eax
1781
1782   call *GLOBL(_blender_func32)
1783   addl $12, %esp
1784
1785   movl %eax, FSEG(%edi)         /* write the pixel */
1786   popl %edx
17877:
1788   addl $4, %edi
1789   addl $4, READ_ADDR
1790   END_ATEX()
1791   ret                           /* end of _poly_scanline_atex_mask_trans32() */
1792
1793#endif /* COLOR32 */
1794
1795
1796
1797#ifdef ALLEGRO_COLOR24
1798/* void _poly_scanline_atex_trans24(ulong addr, int w, POLYGON_SEGMENT *info);
1799 *  Fills a trans affine texture mapped polygon scanline.
1800 */
1801FUNC(_poly_scanline_atex_trans24)
1802   #define INIT_CODE                     \
1803     movl POLYSEG_RADDR(%esi), %eax ;    \
1804     movl %eax, READ_ADDR
1805   INIT_ATEX(INIT_CODE)
1806   #undef INIT_CODE
1807   pushl %edx
1808   pushl GLOBL(_blender_alpha)
1809   leal (%eax, %eax, 2), %ecx
1810   pushl %edi
1811   movl READ_ADDR, %edi
1812   movb FSEG 2(%edi), %dl
1813   movb 2(%esi, %ecx), %al        /* read texel */
1814   shll $16, %edx
1815   shll $16, %eax
1816   movw FSEG (%edi), %dx
1817   popl %edi
1818   movw (%esi, %ecx), %ax
1819   pushl %edx
1820   pushl %eax
1821
1822   call *GLOBL(_blender_func24)
1823   addl $12, %esp
1824
1825   movw %ax, FSEG(%edi)          /* write the pixel */
1826   shrl $16, %eax
1827   movb %al, FSEG 2(%edi)
1828   addl $3, READ_ADDR
1829   addl $3, %edi
1830   popl %edx
1831   END_ATEX()
1832   ret                           /* end of _poly_scanline_atex_trans24() */
1833
1834/* void _poly_scanline_atex_mask_trans24(ulong addr, int w, POLYGON_SEGMENT *info);
1835 *  Fills a trans affine texture mapped polygon scanline.
1836 */
1837FUNC(_poly_scanline_atex_mask_trans24)
1838   #define INIT_CODE                     \
1839     movl POLYSEG_RADDR(%esi), %eax ;    \
1840     movl %eax, READ_ADDR
1841   INIT_ATEX(INIT_CODE)
1842   #undef INIT_CODE
1843   leal (%eax, %eax, 2), %ecx
1844   movzbl 2(%esi, %ecx), %eax    /* read texel */
1845   shll $16, %eax
1846   movw (%esi, %ecx), %ax
1847   cmpl $MASK_COLOR_24, %eax
1848   jz 7f
1849   pushl %edi
1850   movl READ_ADDR, %edi
1851   movb FSEG 2(%edi), %cl
1852   shll $16, %ecx
1853   movw FSEG (%edi), %cx
1854   popl %edi
1855   pushl %edx
1856   pushl GLOBL(_blender_alpha)
1857   pushl %ecx
1858   pushl %eax
1859
1860   call *GLOBL(_blender_func24)
1861   addl $12, %esp
1862
1863   movw %ax, FSEG(%edi)          /* write the pixel */
1864   shrl $16, %eax
1865   movb %al, FSEG 2(%edi)
1866   popl %edx
18677:
1868   addl $3, %edi
1869   addl $3, READ_ADDR
1870   END_ATEX()
1871   ret                           /* end of _poly_scanline_atex_mask_trans24() */
1872
1873#endif /* COLOR24 */
1874
1875#undef VMASK
1876#undef VSHIFT
1877#undef UMASK
1878#undef DU
1879#undef DV
1880#undef ALPHA
1881#undef ALPHA2
1882#undef ALPHA4
1883#undef DALPHA
1884#undef DALPHA4
1885#undef READ_ADDR
1886
1887
1888
1889#define VMASK     -4(%ebp)
1890#define VSHIFT     -8(%ebp)
1891#define ALPHA4    -12(%ebp)
1892#define ALPHA     -16(%ebp)
1893#define DALPHA4   -20(%ebp)
1894#define DALPHA    -24(%ebp)
1895#define TMP4      -28(%ebp)
1896#define TMP2      -30(%ebp)
1897#define TMP       -32(%ebp)
1898#define BLEND4    -36(%ebp)
1899#define BLEND2    -38(%ebp)
1900#define BLEND     -40(%ebp)
1901#define U1        -44(%ebp)
1902#define V1        -48(%ebp)
1903#define DU        -52(%ebp)
1904#define DV        -56(%ebp)
1905#define DU4       -60(%ebp)
1906#define DV4       -64(%ebp)
1907#define DZ4       -68(%ebp)
1908#define UMASK     -72(%ebp)
1909#define COUNT     -76(%ebp)
1910#define SM        -80(%ebp)
1911#define SV        -84(%ebp)
1912#define SU        -88(%ebp)
1913#define SZ        -92(%ebp)
1914#define READ_ADDR -96(%ebp)
1915
1916/* helper for starting an fpu 1/z division */
1917#define START_FP_DIV()                                                \
1918   fld1                                                             ; \
1919   fdiv %st(3), %st(0)
1920
1921/* helper for ending an fpu division, returning corrected u and v values */
1922#define END_FP_DIV()                                                  \
1923   fld %st(0)                    /* duplicate the 1/z value */      ; \
1924   fmul %st(3), %st(0)           /* divide u by z */                ; \
1925   fxch %st(1)                                                      ; \
1926   fmul %st(2), %st(0)           /* divide v by z */
1927
1928#define UPDATE_FP_POS_4()                                             \
1929   fadds DV4                     /* update v coord */               ; \
1930   fxch %st(1)                   /* swap vuz stack to uvz */        ; \
1931   fadds DU4                     /* update u coord */               ; \
1932   fxch %st(2)                   /* swap uvz stack to zvu */        ; \
1933   fadds DZ4                     /* update z value */               ; \
1934   fxch %st(2)                   /* swap zvu stack to uvz */        ; \
1935   fxch %st(1)                   /* swap uvz stack back to vuz */
1936
1937/* main body of the perspective-correct texture mapping routine */
1938#define INIT_PTEX(extra)                                              \
1939   pushl %ebp                                                       ; \
1940   movl %esp, %ebp                                                  ; \
1941   subl $100, %esp               /* local variables */              ; \
1942   pushl %ebx                                                       ; \
1943   pushl %esi                                                       ; \
1944   pushl %edi                                                       ; \
1945								    ; \
1946   movl INFO, %esi               /* load registers */               ; \
1947								    ; \
1948   flds POLYSEG_Z(%esi)          /* z at bottom of fpu stack */     ; \
1949   flds POLYSEG_FU(%esi)         /* followed by u */                ; \
1950   flds POLYSEG_FV(%esi)         /* followed by v */                ; \
1951								    ; \
1952   flds POLYSEG_DFU(%esi)        /* multiply diffs by four */       ; \
1953   flds POLYSEG_DFV(%esi)                                           ; \
1954   flds POLYSEG_DZ(%esi)                                            ; \
1955   fxch %st(2)                   /* u v z */                        ; \
1956   fadd %st(0), %st(0)           /* 2u v z */                       ; \
1957   fxch %st(1)                   /* v 2u z */                       ; \
1958   fadd %st(0), %st(0)           /* 2v 2u z */                      ; \
1959   fxch %st(2)                   /* z 2u 2v */                      ; \
1960   fadd %st(0), %st(0)           /* 2z 2u 2v */                     ; \
1961   fxch %st(1)                   /* 2u 2z 2v */                     ; \
1962   fadd %st(0), %st(0)           /* 4u 2z 2v */                     ; \
1963   fxch %st(2)                   /* 2v 2z 4u */                     ; \
1964   fadd %st(0), %st(0)           /* 4v 2z 4u */                     ; \
1965   fxch %st(1)                   /* 2z 4v 4u */                     ; \
1966   fadd %st(0), %st(0)           /* 4z 4v 4u */                     ; \
1967   fxch %st(2)                   /* 4u 4v 4z */                     ; \
1968   fstps DU4                                                        ; \
1969   fstps DV4                                                        ; \
1970   fstps DZ4                                                        ; \
1971								    ; \
1972   START_FP_DIV()                                                   ; \
1973								    ; \
1974   extra                                                            ; \
1975								    ; \
1976   movl POLYSEG_VSHIFT(%esi), %ecx                                  ; \
1977   movl POLYSEG_VMASK(%esi), %eax                                   ; \
1978   movl POLYSEG_UMASK(%esi), %edx                                   ; \
1979   shll %cl, %eax           /* adjust v mask and shift value */     ; \
1980   negl %ecx                                                        ; \
1981   addl $16, %ecx                                                   ; \
1982   movl %ecx, VSHIFT                                                ; \
1983   movl %eax, VMASK                                                 ; \
1984   movl %edx, UMASK                                                 ; \
1985								    ; \
1986   END_FP_DIV()                                                     ; \
1987   fistpl V1                     /* store v */                      ; \
1988   fistpl U1                     /* store u */                      ; \
1989   UPDATE_FP_POS_4()                                                ; \
1990   START_FP_DIV()                                                   ; \
1991								    ; \
1992   movl ADDR, %edi                                                  ; \
1993   movl V1, %edx                                                    ; \
1994   movl U1, %ebx                                                    ; \
1995   movl POLYSEG_TEXTURE(%esi), %esi                                 ; \
1996   movl $0, COUNT                /* COUNT ranges from 3 to -1 */    ; \
1997   jmp 3f                                                           ; \
1998								    ; \
1999   _align_                                                          ; \
20001:                  /* step 2: compute DU, DV for next 4 steps */   ; \
2001   movl $3, COUNT                                                   ; \
2002								    ; \
2003   END_FP_DIV()                 /* finish the divide */             ; \
2004   fistpl V1                                                        ; \
2005   fistpl U1                                                        ; \
2006   UPDATE_FP_POS_4()            /* 4 pixels away */                 ; \
2007   START_FP_DIV()                                                   ; \
2008								    ; \
2009   movl V1, %eax                                                    ; \
2010   movl U1, %ecx                                                    ; \
2011   subl %edx, %eax                                                  ; \
2012   subl %ebx, %ecx                                                  ; \
2013   sarl $2, %eax                                                    ; \
2014   sarl $2, %ecx                                                    ; \
2015   movl %eax, DV                                                    ; \
2016   movl %ecx, DU                                                    ; \
20172:                              /* step 3 & 4: next U, V */         ; \
2018   addl DV, %edx                                                    ; \
2019   addl DU, %ebx                                                    ; \
20203:                              /* step 1: just use U and V */      ; \
2021   movl %edx, %eax              /* get v */                         ; \
2022   movb VSHIFT, %cl                                                 ; \
2023   sarl %cl, %eax                                                   ; \
2024   andl VMASK, %eax                                                 ; \
2025								    ; \
2026   movl %ebx, %ecx              /* get u */                         ; \
2027   sarl $16, %ecx                                                   ; \
2028   andl UMASK, %ecx                                                 ; \
2029   addl %ecx, %eax
2030
2031#define END_PTEX()                                                    \
2032   decl W                                                           ; \
2033   jle 6f                                                           ; \
2034   decl COUNT                                                       ; \
2035   jg 2b                                                            ; \
2036   nop                                                              ; \
2037   jl 1b                                                            ; \
2038   movl V1, %edx                                                    ; \
2039   movl U1, %ebx                                                    ; \
2040   jmp 3b                                                           ; \
2041   _align_                                                          ; \
20426:                                                                  ; \
2043   fstp %st(0)                   /* pop fpu stack */                ; \
2044   fstp %st(0)                                                      ; \
2045   fstp %st(0)                                                      ; \
2046   fstp %st(0)                                                      ; \
2047								    ; \
2048   popl %edi                                                        ; \
2049   popl %esi                                                        ; \
2050   popl %ebx                                                        ; \
2051   movl %ebp, %esp                                                  ; \
2052   popl %ebp
2053
2054
2055
2056
2057
2058#ifdef ALLEGRO_COLOR16
2059/* void _poly_scanline_ptex16(ulong addr, int w, POLYGON_SEGMENT *info);
2060 *  Fills a perspective correct texture mapped polygon scanline.
2061 */
2062FUNC(_poly_scanline_ptex16)
2063   INIT_PTEX(/**/)
2064   movw (%esi, %eax, 2), %ax     /* read texel */
2065   movw %ax, FSEG(%edi)          /* write the pixel */
2066   addl $2, %edi
2067   END_PTEX()
2068   ret                           /* end of _poly_scanline_ptex16() */
2069
2070/* void _poly_scanline_ptex_mask15(ulong addr, int w, POLYGON_SEGMENT *info);
2071 *  Fills a masked perspective correct texture mapped polygon scanline.
2072 */
2073FUNC(_poly_scanline_ptex_mask15)
2074   INIT_PTEX(/**/)
2075   movw (%esi, %eax, 2), %ax     /* read texel */
2076   cmpw $MASK_COLOR_15, %ax
2077   jz 7f
2078   movw %ax, FSEG(%edi)          /* write solid pixels */
20797: addl $2, %edi
2080   END_PTEX()
2081   ret                           /* end of _poly_scanline_ptex_mask15() */
2082
2083/* void _poly_scanline_ptex_mask16(ulong addr, int w, POLYGON_SEGMENT *info);
2084 *  Fills a masked perspective correct texture mapped polygon scanline.
2085 */
2086FUNC(_poly_scanline_ptex_mask16)
2087   INIT_PTEX(/**/)
2088   movw (%esi, %eax, 2), %ax     /* read texel */
2089   cmpw $MASK_COLOR_16, %ax
2090   jz 7f
2091   movw %ax, FSEG(%edi)          /* write solid pixels */
20927: addl $2, %edi
2093   END_PTEX()
2094   ret                           /* end of _poly_scanline_ptex_mask16() */
2095#endif /* COLOR16 */
2096
2097
2098
2099#ifdef ALLEGRO_COLOR32
2100/* void _poly_scanline_ptex32(ulong addr, int w, POLYGON_SEGMENT *info);
2101 *  Fills a perspective correct texture mapped polygon scanline.
2102 */
2103FUNC(_poly_scanline_ptex32)
2104   INIT_PTEX(/**/)
2105   movl (%esi, %eax, 4), %eax    /* read texel */
2106   movl %eax, FSEG(%edi)         /* write the pixel */
2107   addl $4, %edi
2108   END_PTEX()
2109   ret                           /* end of _poly_scanline_ptex32() */
2110
2111/* void _poly_scanline_ptex_mask32(ulong addr, int w, POLYGON_SEGMENT *info);
2112 *  Fills a masked perspective correct texture mapped polygon scanline.
2113 */
2114FUNC(_poly_scanline_ptex_mask32)
2115   INIT_PTEX(/**/)
2116   movl (%esi, %eax, 4), %eax    /* read texel */
2117   cmpl $MASK_COLOR_32, %eax
2118   jz 7f
2119   movl %eax, FSEG(%edi)         /* write solid pixels */
21207: addl $4, %edi
2121   END_PTEX()
2122   ret                           /* end of _poly_scanline_ptex_mask32() */
2123#endif /* COLOR32 */
2124
2125
2126
2127#ifdef ALLEGRO_COLOR24
2128/* void _poly_scanline_ptex24(ulong addr, int w, POLYGON_SEGMENT *info);
2129 *  Fills a perspective correct texture mapped polygon scanline.
2130 */
2131FUNC(_poly_scanline_ptex24)
2132   INIT_PTEX(/**/)
2133   leal (%eax, %eax, 2), %ecx
2134   movw (%esi, %ecx), %ax        /* read texel */
2135   movw %ax, FSEG(%edi)          /* write the pixel */
2136   movb 2(%esi, %ecx), %al       /* read texel */
2137   movb %al, FSEG 2(%edi)        /* write the pixel */
2138   addl $3, %edi
2139   END_PTEX()
2140   ret                           /* end of _poly_scanline_ptex24() */
2141
2142/* void _poly_scanline_ptex_mask24(ulong addr, int w, POLYGON_SEGMENT *info);
2143 *  Fills a masked perspective correct texture mapped polygon scanline.
2144 */
2145FUNC(_poly_scanline_ptex_mask24)
2146   INIT_PTEX(/**/)
2147   leal (%eax, %eax, 2), %ecx
2148   xorl %eax, %eax
2149   movb 2(%esi, %ecx), %al       /* read texel */
2150   shll $16, %eax
2151   movw (%esi, %ecx), %ax
2152   cmpl $MASK_COLOR_24, %eax
2153   jz 7f
2154   movw %ax, FSEG(%edi)          /* write solid pixels */
2155   shrl $16, %eax
2156   movb %al, FSEG 2(%edi)
21577: addl $3, %edi
2158   END_PTEX()
2159   ret                           /* end of _poly_scanline_ptex_mask24() */
2160#endif /* COLOR24 */
2161
2162
2163
2164
2165#ifdef ALLEGRO_COLOR8
2166/* void _poly_scanline_ptex_mask_lit8(ulong addr, int w, POLYGON_SEGMENT *info);
2167 *  Fills a lit perspective correct texture mapped polygon scanline.
2168 */
2169FUNC(_poly_scanline_ptex_mask_lit8)
2170   #define INIT_CODE                      \
2171     movl POLYSEG_C(%esi), %eax ;         \
2172     movl POLYSEG_DC(%esi), %edx ;        \
2173     movl %eax, ALPHA ;                   \
2174     movl %edx, DALPHA
2175   INIT_PTEX(INIT_CODE)
2176   #undef INIT_CODE
2177   movzbl (%esi, %eax), %eax     /* read texel */
2178   orl %eax, %eax
2179   jz 7f
2180   movb 2+ALPHA, %ah
2181   movl GLOBL(color_map), %ecx
2182   movb (%ecx, %eax), %al
2183   movb %al, FSEG(%edi)
21847:
2185   movl DALPHA, %eax
2186   incl %edi
2187   addl %eax, ALPHA
2188   END_PTEX()
2189   ret                           /* end of _poly_scanline_ptex_mask_lit8() */
2190#endif /* COLOR8 */
2191
2192
2193
2194#ifdef ALLEGRO_COLOR16
2195/* void _poly_scanline_ptex_lit15(ulong addr, int w, POLYGON_SEGMENT *info);
2196 *  Fills a lit perspective correct texture mapped polygon scanline.
2197 */
2198FUNC(_poly_scanline_ptex_lit15)
2199   #define INIT_CODE                      \
2200     movl POLYSEG_C(%esi), %eax ;         \
2201     movl POLYSEG_DC(%esi), %edx ;        \
2202     movl %eax, ALPHA ;                   \
2203     movl %edx, DALPHA
2204   INIT_PTEX(INIT_CODE)
2205   #undef INIT_CODE
2206   pushl %edx
2207   movzbl 2+ALPHA, %edx
2208   pushl %edx
2209   movw (%esi, %eax, 2), %ax     /* read texel */
2210   pushl GLOBL(_blender_col_15)
2211   pushl %eax
2212   call *GLOBL(_blender_func15)
2213   addl $12, %esp
2214
2215   movw %ax, FSEG(%edi)          /* write the pixel */
2216   movl DALPHA, %eax
2217   addl $2, %edi
2218   addl %eax, ALPHA
2219   popl %edx
2220   END_PTEX()
2221   ret                           /* end of _poly_scanline_ptex_lit15() */
2222
2223/* void _poly_scanline_ptex_mask_lit15(ulong addr, int w, POLYGON_SEGMENT *info);
2224 *  Fills a lit perspective correct texture mapped polygon scanline.
2225 */
2226FUNC(_poly_scanline_ptex_mask_lit15)
2227   #define INIT_CODE                      \
2228     movl POLYSEG_C(%esi), %eax ;         \
2229     movl POLYSEG_DC(%esi), %edx ;        \
2230     movl %eax, ALPHA ;                   \
2231     movl %edx, DALPHA
2232   INIT_PTEX(INIT_CODE)
2233   #undef INIT_CODE
2234   movw (%esi, %eax, 2), %ax     /* read texel */
2235   cmpw $MASK_COLOR_15, %ax
2236   jz 7f
2237   pushl %edx
2238   movzbl 2+ALPHA, %edx
2239   pushl %edx
2240   pushl GLOBL(_blender_col_15)
2241   pushl %eax
2242   call *GLOBL(_blender_func15)
2243   addl $12, %esp
2244
2245   movw %ax, FSEG(%edi)          /* write the pixel */
2246   popl %edx
22477:
2248   movl DALPHA, %eax
2249   addl $2, %edi
2250   addl %eax, ALPHA
2251   END_PTEX()
2252   ret                           /* end of _poly_scanline_ptex_mask_lit15() */
2253
2254
2255
2256/* void _poly_scanline_ptex_lit16(ulong addr, int w, POLYGON_SEGMENT *info);
2257 *  Fills a lit perspective correct texture mapped polygon scanline.
2258 */
2259FUNC(_poly_scanline_ptex_lit16)
2260   #define INIT_CODE                      \
2261     movl POLYSEG_C(%esi), %eax ;         \
2262     movl POLYSEG_DC(%esi), %edx ;        \
2263     movl %eax, ALPHA ;                   \
2264     movl %edx, DALPHA
2265   INIT_PTEX(INIT_CODE)
2266   #undef INIT_CODE
2267   pushl %edx
2268   movzbl 2+ALPHA, %edx
2269   pushl %edx
2270   movw (%esi, %eax, 2), %ax     /* read texel */
2271   pushl GLOBL(_blender_col_16)
2272   pushl %eax
2273   call *GLOBL(_blender_func16)
2274   addl $12, %esp
2275
2276   movw %ax, FSEG(%edi)          /* write the pixel */
2277   movl DALPHA, %eax
2278   addl $2, %edi
2279   addl %eax, ALPHA
2280   popl %edx
2281   END_PTEX()
2282   ret                           /* end of _poly_scanline_ptex_lit16() */
2283
2284/* void _poly_scanline_ptex_mask_lit16(ulong addr, int w, POLYGON_SEGMENT *info);
2285 *  Fills a lit perspective correct texture mapped polygon scanline.
2286 */
2287FUNC(_poly_scanline_ptex_mask_lit16)
2288   #define INIT_CODE                      \
2289     movl POLYSEG_C(%esi), %eax ;         \
2290     movl POLYSEG_DC(%esi), %edx ;        \
2291     movl %eax, ALPHA ;                   \
2292     movl %edx, DALPHA
2293   INIT_PTEX(INIT_CODE)
2294   #undef INIT_CODE
2295   movw (%esi, %eax, 2), %ax     /* read texel */
2296   cmpw $MASK_COLOR_16, %ax
2297   jz 7f
2298   pushl %edx
2299   movzbl 2+ALPHA, %edx
2300   pushl %edx
2301   pushl GLOBL(_blender_col_16)
2302   pushl %eax
2303   call *GLOBL(_blender_func16)
2304   addl $12, %esp
2305
2306   movw %ax, FSEG(%edi)          /* write the pixel */
2307   popl %edx
23087:
2309   movl DALPHA, %eax
2310   addl $2, %edi
2311   addl %eax, ALPHA
2312   END_PTEX()
2313   ret                           /* end of _poly_scanline_ptex_mask_lit16() */
2314
2315#endif /* COLOR16 */
2316
2317
2318
2319#ifdef ALLEGRO_COLOR32
2320/* void _poly_scanline_ptex_lit32(ulong addr, int w, POLYGON_SEGMENT *info);
2321 *  Fills a lit perspective correct texture mapped polygon scanline.
2322 */
2323FUNC(_poly_scanline_ptex_lit32)
2324   #define INIT_CODE                      \
2325     movl POLYSEG_C(%esi), %eax ;         \
2326     movl POLYSEG_DC(%esi), %edx ;        \
2327     movl %eax, ALPHA ;                   \
2328     movl %edx, DALPHA
2329   INIT_PTEX(INIT_CODE)
2330   #undef INIT_CODE
2331   pushl %edx
2332   movzbl 2+ALPHA, %edx
2333   pushl %edx
2334   movl (%esi, %eax, 4), %eax    /* read texel */
2335   pushl GLOBL(_blender_col_32)
2336   pushl %eax
2337   call *GLOBL(_blender_func32)
2338   addl $12, %esp
2339
2340   movl %eax, FSEG(%edi)         /* write the pixel */
2341   movl DALPHA, %eax
2342   addl $4, %edi
2343   addl %eax, ALPHA
2344   popl %edx
2345   END_PTEX()
2346   ret                           /* end of _poly_scanline_ptex_lit32() */
2347
2348/* void _poly_scanline_ptex_mask_lit32(ulong addr, int w, POLYGON_SEGMENT *info);
2349 *  Fills a lit perspective correct texture mapped polygon scanline.
2350 */
2351FUNC(_poly_scanline_ptex_mask_lit32)
2352   #define INIT_CODE                      \
2353     movl POLYSEG_C(%esi), %eax ;         \
2354     movl POLYSEG_DC(%esi), %edx ;        \
2355     movl %eax, ALPHA ;                   \
2356     movl %edx, DALPHA
2357   INIT_PTEX(INIT_CODE)
2358   #undef INIT_CODE
2359   movl (%esi, %eax, 4), %eax    /* read texel */
2360   cmpl $MASK_COLOR_32, %eax
2361   jz 7f
2362   pushl %edx
2363   movzbl 2+ALPHA, %edx
2364   pushl %edx
2365   pushl GLOBL(_blender_col_32)
2366   pushl %eax
2367   call *GLOBL(_blender_func32)
2368   addl $12, %esp
2369
2370   movl %eax, FSEG(%edi)         /* write the pixel */
2371   popl %edx
23727:
2373   movl DALPHA, %eax
2374   addl $4, %edi
2375   addl %eax, ALPHA
2376   END_PTEX()
2377   ret                           /* end of _poly_scanline_ptex_mask_lit32() */
2378
2379#endif /* COLOR32 */
2380
2381
2382
2383#ifdef ALLEGRO_COLOR24
2384/* void _poly_scanline_ptex_lit24(ulong addr, int w, POLYGON_SEGMENT *info);
2385 *  Fills a lit perspective correct texture mapped polygon scanline.
2386 */
2387FUNC(_poly_scanline_ptex_lit24)
2388   #define INIT_CODE                      \
2389     movl POLYSEG_C(%esi), %eax ;         \
2390     movl POLYSEG_DC(%esi), %edx ;        \
2391     movl %eax, ALPHA ;                   \
2392     movl %edx, DALPHA
2393   INIT_PTEX(INIT_CODE)
2394   #undef INIT_CODE
2395   pushl %edx
2396   movzbl 2+ALPHA, %edx
2397   pushl %edx
2398   leal (%eax, %eax, 2), %ecx
2399   movb 2(%esi, %ecx), %al       /* read texel */
2400   shll $16, %eax
2401   movw (%esi, %ecx), %ax
2402   pushl GLOBL(_blender_col_24)
2403   pushl %eax
2404   call *GLOBL(_blender_func24)
2405   addl $12, %esp
2406
2407   movw %ax, FSEG(%edi)          /* write the pixel */
2408   shrl $16, %eax
2409   movb %al, FSEG 2(%edi)
2410   movl DALPHA, %eax
2411   addl $3, %edi
2412   addl %eax, ALPHA
2413   popl %edx
2414   END_PTEX()
2415   ret                           /* end of _poly_scanline_ptex_lit24() */
2416
2417/* void _poly_scanline_ptex_mask_lit24(ulong addr, int w, POLYGON_SEGMENT *info);
2418 *  Fills a lit perspective correct texture mapped polygon scanline.
2419 */
2420FUNC(_poly_scanline_ptex_mask_lit24)
2421   #define INIT_CODE                      \
2422     movl POLYSEG_C(%esi), %eax ;         \
2423     movl POLYSEG_DC(%esi), %edx ;        \
2424     movl %eax, ALPHA ;                   \
2425     movl %edx, DALPHA
2426   INIT_PTEX(INIT_CODE)
2427   #undef INIT_CODE
2428   leal (%eax, %eax, 2), %ecx
2429   movzbl 2(%esi, %ecx), %eax    /* read texel */
2430   shll $16, %eax
2431   movw (%esi, %ecx), %ax
2432   cmpl $MASK_COLOR_24, %eax
2433   jz 7f
2434   pushl %edx
2435   movzbl 2+ALPHA, %edx
2436   pushl %edx
2437   pushl GLOBL(_blender_col_24)
2438   pushl %eax
2439   call *GLOBL(_blender_func24)
2440   addl $12, %esp
2441
2442   movw %ax, FSEG(%edi)          /* write the pixel */
2443   shrl $16, %eax
2444   movb %al, FSEG 2(%edi)
2445   popl %edx
24467:
2447   movl DALPHA, %eax
2448   addl $3, %edi
2449   addl %eax, ALPHA
2450   END_PTEX()
2451   ret                           /* end of _poly_scanline_ptex_mask_lit24() */
2452
2453#endif /* COLOR24 */
2454
2455
2456
2457#ifdef ALLEGRO_COLOR8
2458/* void _poly_scanline_ptex_trans8(ulong addr, int w, POLYGON_SEGMENT *info);
2459 *  Fills a trans perspective correct texture mapped polygon scanline.
2460 */
2461FUNC(_poly_scanline_ptex_trans8)
2462   #define INIT_CODE                      \
2463     movl POLYSEG_RADDR(%esi) ,%eax ;     \
2464     movl %eax, READ_ADDR
2465   INIT_PTEX(INIT_CODE)
2466   #undef INIT_CODE
2467   movzbl (%esi, %eax), %eax     /* read texel */
2468   shll $8, %eax
2469   pushl %edi
2470   movl READ_ADDR, %edi
2471   movb FSEG (%edi), %al
2472   popl %edi
2473   movl GLOBL(color_map), %ecx
2474   movb (%ecx, %eax), %al
2475   movb %al, FSEG(%edi)
2476   incl READ_ADDR
2477   incl %edi
2478   END_PTEX()
2479   ret                           /* end of _poly_scanline_ptex_trans8() */
2480
2481/* void _poly_scanline_ptex_mask_trans8(ulong addr, int w, POLYGON_SEGMENT *info);
2482 *  Fills a trans perspective correct texture mapped polygon scanline.
2483 */
2484FUNC(_poly_scanline_ptex_mask_trans8)
2485   #define INIT_CODE                      \
2486     movl POLYSEG_RADDR(%esi) ,%eax ;     \
2487     movl %eax, READ_ADDR
2488   INIT_PTEX(INIT_CODE)
2489   #undef INIT_CODE
2490   movzbl (%esi, %eax), %eax     /* read texel */
2491   orl %eax, %eax
2492   jz 7f
2493   shll $8, %eax
2494   pushl %edi
2495   movl READ_ADDR, %edi
2496   movb FSEG (%edi), %al
2497   popl %edi
2498   movl GLOBL(color_map), %ecx
2499   movb (%ecx, %eax), %al
2500   movb %al, FSEG(%edi)
25017:
2502   incl READ_ADDR
2503   incl %edi
2504   END_PTEX()
2505   ret                           /* end of _poly_scanline_ptex_mask_trans8() */
2506
2507#endif /* COLOR8 */
2508
2509
2510
2511#ifdef ALLEGRO_COLOR16
2512/* void _poly_scanline_ptex_trans15(ulong addr, int w, POLYGON_SEGMENT *info);
2513 *  Fills a trans perspective correct texture mapped polygon scanline.
2514 */
2515FUNC(_poly_scanline_ptex_trans15)
2516   #define INIT_CODE                      \
2517     movl POLYSEG_RADDR(%esi) ,%eax ;     \
2518     movl %eax, READ_ADDR
2519   INIT_PTEX(INIT_CODE)
2520   #undef INIT_CODE
2521   pushl %edx
2522   pushl GLOBL(_blender_alpha)
2523   pushl %edi
2524   movl READ_ADDR, %edi
2525   movw FSEG (%edi), %cx
2526   popl %edi
2527   movw (%esi, %eax, 2), %ax     /* read texel */
2528   pushl %ecx
2529   pushl %eax
2530
2531   call *GLOBL(_blender_func15)
2532   addl $12, %esp
2533
2534   movw %ax, FSEG(%edi)          /* write the pixel */
2535   addl $2, READ_ADDR
2536   addl $2, %edi
2537   popl %edx
2538   END_PTEX()
2539   ret                           /* end of _poly_scanline_ptex_trans15() */
2540
2541/* void _poly_scanline_ptex_mask_trans15(ulong addr, int w, POLYGON_SEGMENT *info);
2542 *  Fills a trans perspective correct texture mapped polygon scanline.
2543 */
2544FUNC(_poly_scanline_ptex_mask_trans15)
2545   #define INIT_CODE                      \
2546     movl POLYSEG_RADDR(%esi) ,%eax ;     \
2547     movl %eax, READ_ADDR
2548   INIT_PTEX(INIT_CODE)
2549   #undef INIT_CODE
2550   movw (%esi, %eax, 2), %ax     /* read texel */
2551   cmpw $MASK_COLOR_15, %ax
2552   jz 7f
2553   pushl %edi
2554   movl READ_ADDR, %edi
2555   movw FSEG (%edi), %cx
2556   popl %edi
2557   pushl %edx
2558   pushl GLOBL(_blender_alpha)
2559   pushl %ecx
2560   pushl %eax
2561
2562   call *GLOBL(_blender_func15)
2563   addl $12, %esp
2564
2565   movw %ax, FSEG(%edi)          /* write the pixel */
2566   popl %edx
25677:
2568   addl $2, %edi
2569   addl $2, READ_ADDR
2570   END_PTEX()
2571   ret                           /* end of _poly_scanline_ptex_mask_trans15() */
2572
2573
2574
2575/* void _poly_scanline_ptex_trans16(ulong addr, int w, POLYGON_SEGMENT *info);
2576 *  Fills a trans perspective correct texture mapped polygon scanline.
2577 */
2578FUNC(_poly_scanline_ptex_trans16)
2579   #define INIT_CODE                      \
2580     movl POLYSEG_RADDR(%esi) ,%eax ;     \
2581     movl %eax, READ_ADDR
2582   INIT_PTEX(INIT_CODE)
2583   #undef INIT_CODE
2584   pushl %edx
2585   pushl GLOBL(_blender_alpha)
2586   pushl %edi
2587   movl READ_ADDR, %edi
2588   movw FSEG (%edi), %cx
2589   popl %edi
2590   movw (%esi, %eax, 2), %ax     /* read texel */
2591   pushl %ecx
2592   pushl %eax
2593
2594   call *GLOBL(_blender_func16)
2595   addl $12, %esp
2596
2597   movw %ax, FSEG(%edi)          /* write the pixel */
2598   addl $2, READ_ADDR
2599   addl $2, %edi
2600   popl %edx
2601   END_PTEX()
2602   ret                           /* end of _poly_scanline_ptex_trans16() */
2603
2604/* void _poly_scanline_ptex_mask_trans16(ulong addr, int w, POLYGON_SEGMENT *info);
2605 *  Fills a trans perspective correct texture mapped polygon scanline.
2606 */
2607FUNC(_poly_scanline_ptex_mask_trans16)
2608   #define INIT_CODE                      \
2609     movl POLYSEG_RADDR(%esi) ,%eax ;     \
2610     movl %eax, READ_ADDR
2611   INIT_PTEX(INIT_CODE)
2612   #undef INIT_CODE
2613   movw (%esi, %eax, 2), %ax     /* read texel */
2614   cmpw $MASK_COLOR_16, %ax
2615   jz 7f
2616   pushl %edi
2617   movl READ_ADDR, %edi
2618   movw FSEG (%edi), %cx
2619   popl %edi
2620   pushl %edx
2621   pushl GLOBL(_blender_alpha)
2622   pushl %ecx
2623   pushl %eax
2624
2625   call *GLOBL(_blender_func16)
2626   addl $12, %esp
2627
2628   movw %ax, FSEG(%edi)          /* write the pixel */
2629   popl %edx
26307:
2631   addl $2, %edi
2632   addl $2, READ_ADDR
2633   END_PTEX()
2634   ret                           /* end of _poly_scanline_ptex_mask_trans16() */
2635
2636#endif /* COLOR16 */
2637
2638
2639
2640#ifdef ALLEGRO_COLOR32
2641/* void _poly_scanline_ptex_trans32(ulong addr, int w, POLYGON_SEGMENT *info);
2642 *  Fills a trans perspective correct texture mapped polygon scanline.
2643 */
2644FUNC(_poly_scanline_ptex_trans32)
2645   #define INIT_CODE                      \
2646     movl POLYSEG_RADDR(%esi) ,%eax ;     \
2647     movl %eax, READ_ADDR
2648   INIT_PTEX(INIT_CODE)
2649   #undef INIT_CODE
2650   pushl %edx
2651   pushl GLOBL(_blender_alpha)
2652   movl %edi, TMP
2653   movl READ_ADDR, %edi
2654   pushl FSEG (%edi)
2655   movl TMP, %edi
2656   pushl (%esi, %eax, 4)
2657
2658   call *GLOBL(_blender_func32)
2659   addl $12, %esp
2660
2661   movl %eax, FSEG(%edi)         /* write the pixel */
2662   addl $4, READ_ADDR
2663   addl $4, %edi
2664   popl %edx
2665   END_PTEX()
2666   ret                           /* end of _poly_scanline_ptex_trans32() */
2667
2668/* void _poly_scanline_ptex_mask_trans32(ulong addr, int w, POLYGON_SEGMENT *info);
2669 *  Fills a trans perspective correct texture mapped polygon scanline.
2670 */
2671FUNC(_poly_scanline_ptex_mask_trans32)
2672   #define INIT_CODE                      \
2673     movl POLYSEG_RADDR(%esi) ,%eax ;     \
2674     movl %eax, READ_ADDR
2675   INIT_PTEX(INIT_CODE)
2676   #undef INIT_CODE
2677   movl (%esi, %eax, 4), %eax    /* read texel */
2678   cmpl $MASK_COLOR_32, %eax
2679   jz 7f
2680   pushl %edx
2681   pushl GLOBL(_blender_alpha)
2682   movl %edi, TMP
2683   movl READ_ADDR, %edi
2684   pushl FSEG (%edi)
2685   movl TMP, %edi
2686   pushl %eax
2687
2688   call *GLOBL(_blender_func32)
2689   addl $12, %esp
2690
2691   movl %eax, FSEG(%edi)         /* write the pixel */
2692   popl %edx
26937:
2694   addl $4, %edi
2695   addl $4, READ_ADDR
2696   END_PTEX()
2697   ret                           /* end of _poly_scanline_ptex_mask_trans32() */
2698
2699#endif /* COLOR32 */
2700
2701
2702
2703#ifdef ALLEGRO_COLOR24
2704/* void _poly_scanline_ptex_trans24(ulong addr, int w, POLYGON_SEGMENT *info);
2705 *  Fills a trans perspective correct texture mapped polygon scanline.
2706 */
2707FUNC(_poly_scanline_ptex_trans24)
2708   #define INIT_CODE                      \
2709     movl POLYSEG_RADDR(%esi) ,%eax ;     \
2710     movl %eax, READ_ADDR
2711   INIT_PTEX(INIT_CODE)
2712   #undef INIT_CODE
2713   pushl %edx
2714   pushl GLOBL(_blender_alpha)
2715   leal (%eax, %eax, 2), %ecx
2716   pushl %edi
2717   movl READ_ADDR, %edi
2718   movb FSEG 2(%edi), %dl
2719   movb 2(%esi, %ecx), %al       /* read texel */
2720   shll $16, %edx
2721   shll $16, %eax
2722   movw FSEG (%edi), %dx
2723   popl %edi
2724   movw (%esi, %ecx), %ax
2725   pushl %edx
2726   pushl %eax
2727
2728   call *GLOBL(_blender_func24)
2729   addl $12, %esp
2730
2731   movw %ax, FSEG(%edi)          /* write the pixel */
2732   shrl $16, %eax
2733   movb %al, FSEG 2(%edi)
2734   addl $3, READ_ADDR
2735   addl $3, %edi
2736   popl %edx
2737   END_PTEX()
2738   ret                           /* end of _poly_scanline_ptex_trans24() */
2739
2740/* void _poly_scanline_ptex_mask_trans24(ulong addr, int w, POLYGON_SEGMENT *info);
2741 *  Fills a trans perspective correct texture mapped polygon scanline.
2742 */
2743FUNC(_poly_scanline_ptex_mask_trans24)
2744   #define INIT_CODE                      \
2745     movl POLYSEG_RADDR(%esi) ,%eax ;     \
2746     movl %eax, READ_ADDR
2747   INIT_PTEX(INIT_CODE)
2748   #undef INIT_CODE
2749   leal (%eax, %eax, 2), %ecx
2750   movzbl 2(%esi, %ecx), %eax    /* read texel */
2751   shll $16, %eax
2752   movw (%esi, %ecx), %ax
2753   cmpl $MASK_COLOR_24, %eax
2754   jz 7f
2755   movl %edi, TMP
2756   movl READ_ADDR, %edi
2757   movb FSEG 2(%edi), %cl
2758   pushl %edx
2759   pushl GLOBL(_blender_alpha)
2760   shll $16, %ecx
2761   movw FSEG (%edi), %cx
2762   movl TMP, %edi
2763   pushl %ecx
2764   pushl %eax
2765
2766   call *GLOBL(_blender_func24)
2767   addl $12, %esp
2768
2769   movw %ax, FSEG(%edi)          /* write the pixel */
2770   shrl $16, %eax
2771   movb %al, FSEG 2(%edi)
2772   popl %edx
27737:
2774   addl $3, %edi
2775   addl $3, READ_ADDR
2776   END_PTEX()
2777   ret                           /* end of _poly_scanline_ptex_mask_trans24() */
2778
2779#endif /* COLOR24 */
2780